@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/resolver.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,7 +111,7 @@ var init_theme = __esm({
111
111
  }
112
112
  });
113
113
  function useTheme() {
114
- return React41.useContext(GenUIThemeContext);
114
+ return React45.useContext(GenUIThemeContext);
115
115
  }
116
116
  var DEFAULT_TOKENS, GenUIThemeContext;
117
117
  var init_ThemeContext = __esm({
@@ -127,7 +127,7 @@ var init_ThemeContext = __esm({
127
127
  SECONDARY,
128
128
  CHART_PALETTE: [...CHART_PALETTE]
129
129
  };
130
- GenUIThemeContext = React41.createContext(DEFAULT_TOKENS);
130
+ GenUIThemeContext = React45.createContext(DEFAULT_TOKENS);
131
131
  }
132
132
  });
133
133
  function renderInline(text) {
@@ -857,11 +857,11 @@ async function getMermaid(t) {
857
857
  }
858
858
  function MermaidFallback({ diagram, title }) {
859
859
  const tokens = useTheme();
860
- const [svg, setSvg] = React41.useState("");
861
- const [err, setErr] = React41.useState(false);
862
- const [full, setFull] = React41.useState(false);
863
- const idRef = React41.useRef(0);
864
- React41.useEffect(() => {
860
+ const [svg, setSvg] = React45.useState("");
861
+ const [err, setErr] = React45.useState(false);
862
+ const [full, setFull] = React45.useState(false);
863
+ const idRef = React45.useRef(0);
864
+ React45.useEffect(() => {
865
865
  const id = ++renderSeq;
866
866
  idRef.current = id;
867
867
  setErr(false);
@@ -930,7 +930,7 @@ function FullscreenModalInner({ nodes, edges, title, onClose }) {
930
930
  ] }) });
931
931
  }
932
932
  function FullscreenModal({ nodes, edges, title, onClose }) {
933
- React41.useEffect(() => {
933
+ React45.useEffect(() => {
934
934
  const h = (e) => {
935
935
  if (e.key === "Escape") onClose();
936
936
  };
@@ -943,8 +943,8 @@ function FullscreenModal({ nodes, edges, title, onClose }) {
943
943
  );
944
944
  }
945
945
  function usePrefersReducedMotion() {
946
- const [reduced, setReduced] = React41.useState(false);
947
- React41.useEffect(() => {
946
+ const [reduced, setReduced] = React45.useState(false);
947
+ React45.useEffect(() => {
948
948
  var _a;
949
949
  if (typeof matchMedia === "undefined") return;
950
950
  const mq = matchMedia("(prefers-reduced-motion: reduce)");
@@ -988,9 +988,9 @@ function topoOrder(nodeIds, edges) {
988
988
  }
989
989
  function useAutoplay(order, enabled) {
990
990
  const reduced = usePrefersReducedMotion();
991
- const [step, setStep] = React41.useState(0);
991
+ const [step, setStep] = React45.useState(0);
992
992
  const key = order.join("|");
993
- React41.useEffect(() => {
993
+ React45.useEffect(() => {
994
994
  if (!enabled || reduced || order.length === 0) {
995
995
  setStep(0);
996
996
  return;
@@ -1012,7 +1012,7 @@ function useAutoplay(order, enabled) {
1012
1012
  timer = setTimeout(tick, 850);
1013
1013
  return () => clearTimeout(timer);
1014
1014
  }, [enabled, reduced, key]);
1015
- return React41.useMemo(() => {
1015
+ return React45.useMemo(() => {
1016
1016
  const m = {};
1017
1017
  order.forEach((id, i) => {
1018
1018
  m[id] = i < step ? "done" : i === step ? "active" : "pending";
@@ -1034,13 +1034,13 @@ function resolveStates(nodes, nodeStates) {
1034
1034
  }
1035
1035
  function Inner({ diagram, title, autoplay, nodeStates }) {
1036
1036
  const tokens = useTheme();
1037
- const [full, setFull] = React41.useState(false);
1038
- const [focused, setFocused] = React41.useState(false);
1039
- const [boxW, setBoxW] = React41.useState(640);
1040
- const containerRef = React41.useRef(null);
1041
- const parsed = React41.useMemo(() => parseMermaidFlow(diagram), [diagram]);
1042
- const layout = React41.useMemo(() => parsed ? computeLayout(parsed) : null, [parsed]);
1043
- const themedEdges = React41.useMemo(
1037
+ const [full, setFull] = React45.useState(false);
1038
+ const [focused, setFocused] = React45.useState(false);
1039
+ const [boxW, setBoxW] = React45.useState(640);
1040
+ const containerRef = React45.useRef(null);
1041
+ const parsed = React45.useMemo(() => parseMermaidFlow(diagram), [diagram]);
1042
+ const layout = React45.useMemo(() => parsed ? computeLayout(parsed) : null, [parsed]);
1043
+ const themedEdges = React45.useMemo(
1044
1044
  () => {
1045
1045
  var _a;
1046
1046
  return ((_a = layout == null ? void 0 : layout.edges) != null ? _a : []).map((e) => __spreadProps(__spreadValues({}, e), {
@@ -1052,7 +1052,7 @@ function Inner({ diagram, title, autoplay, nodeStates }) {
1052
1052
  },
1053
1053
  [layout, tokens.ACCENT, tokens.MUTED]
1054
1054
  );
1055
- const order = React41.useMemo(
1055
+ const order = React45.useMemo(
1056
1056
  () => {
1057
1057
  var _a, _b;
1058
1058
  return topoOrder(((_a = layout == null ? void 0 : layout.nodes) != null ? _a : []).map((n) => n.id), (_b = layout == null ? void 0 : layout.edges) != null ? _b : []);
@@ -1060,19 +1060,19 @@ function Inner({ diagram, title, autoplay, nodeStates }) {
1060
1060
  [layout]
1061
1061
  );
1062
1062
  const autoStatus = useAutoplay(order, !!autoplay);
1063
- const staticStatus = React41.useMemo(() => {
1063
+ const staticStatus = React45.useMemo(() => {
1064
1064
  var _a;
1065
1065
  return resolveStates((_a = layout == null ? void 0 : layout.nodes) != null ? _a : [], nodeStates);
1066
1066
  }, [layout, nodeStates]);
1067
1067
  const statusMap = autoplay ? autoStatus : staticStatus;
1068
- const displayNodes = React41.useMemo(
1068
+ const displayNodes = React45.useMemo(
1069
1069
  () => {
1070
1070
  var _a;
1071
1071
  return ((_a = layout == null ? void 0 : layout.nodes) != null ? _a : []).map((n) => __spreadProps(__spreadValues({}, n), { data: __spreadProps(__spreadValues({}, n.data), { status: statusMap[n.id] }) }));
1072
1072
  },
1073
1073
  [layout, statusMap]
1074
1074
  );
1075
- const displayEdges = React41.useMemo(
1075
+ const displayEdges = React45.useMemo(
1076
1076
  () => themedEdges.map((e) => {
1077
1077
  const ss = statusMap[e.source];
1078
1078
  const ts = statusMap[e.target];
@@ -1092,13 +1092,13 @@ function Inner({ diagram, title, autoplay, nodeStates }) {
1092
1092
  const [nodes, setNodes, onNC] = react.useNodesState(displayNodes);
1093
1093
  const [edges, setEdges, onEC] = react.useEdgesState(displayEdges);
1094
1094
  const rf = react.useReactFlow();
1095
- React41.useEffect(() => {
1095
+ React45.useEffect(() => {
1096
1096
  setNodes(displayNodes);
1097
1097
  }, [displayNodes, setNodes]);
1098
- React41.useEffect(() => {
1098
+ React45.useEffect(() => {
1099
1099
  setEdges(displayEdges);
1100
1100
  }, [displayEdges, setEdges]);
1101
- React41.useEffect(() => {
1101
+ React45.useEffect(() => {
1102
1102
  const id = requestAnimationFrame(() => {
1103
1103
  try {
1104
1104
  rf.fitView({ padding: 0.1 });
@@ -1107,14 +1107,14 @@ function Inner({ diagram, title, autoplay, nodeStates }) {
1107
1107
  });
1108
1108
  return () => cancelAnimationFrame(id);
1109
1109
  }, [layout, rf]);
1110
- const handleClickOutside = React41.useCallback((e) => {
1110
+ const handleClickOutside = React45.useCallback((e) => {
1111
1111
  if (containerRef.current && !containerRef.current.contains(e.target)) setFocused(false);
1112
1112
  }, []);
1113
- React41.useEffect(() => {
1113
+ React45.useEffect(() => {
1114
1114
  document.addEventListener("mousedown", handleClickOutside);
1115
1115
  return () => document.removeEventListener("mousedown", handleClickOutside);
1116
1116
  }, [handleClickOutside]);
1117
- React41.useEffect(() => {
1117
+ React45.useEffect(() => {
1118
1118
  const el = containerRef.current;
1119
1119
  if (!el) return;
1120
1120
  let raf = 0;
@@ -1273,15 +1273,15 @@ __export(PdfViewer_exports, {
1273
1273
  PdfViewer: () => PdfViewer
1274
1274
  });
1275
1275
  function PdfViewer({ url, base64, onLoadSuccess }) {
1276
- const [numPages, setNumPages] = React41.useState(0);
1277
- const [currentPage, setCurrentPage] = React41.useState(1);
1278
- const [loading, setLoading] = React41.useState(true);
1279
- const handleLoad = React41.useCallback(({ numPages: n }) => {
1276
+ const [numPages, setNumPages] = React45.useState(0);
1277
+ const [currentPage, setCurrentPage] = React45.useState(1);
1278
+ const [loading, setLoading] = React45.useState(true);
1279
+ const handleLoad = React45.useCallback(({ numPages: n }) => {
1280
1280
  setNumPages(n);
1281
1281
  setLoading(false);
1282
1282
  onLoadSuccess == null ? void 0 : onLoadSuccess(n);
1283
1283
  }, [onLoadSuccess]);
1284
- React41.useEffect(() => {
1284
+ React45.useEffect(() => {
1285
1285
  if (numPages <= 1) return;
1286
1286
  const handler = (e) => {
1287
1287
  var _a;
@@ -1377,13 +1377,13 @@ __export(ExcelViewer_exports, {
1377
1377
  ExcelViewer: () => ExcelViewer
1378
1378
  });
1379
1379
  function ExcelViewer({ url, base64, onLoadSuccess }) {
1380
- const [sheetNames, setSheetNames] = React41.useState([]);
1381
- const [activeSheet, setActiveSheet] = React41.useState(0);
1382
- const [data, setData] = React41.useState([]);
1383
- const [loading, setLoading] = React41.useState(true);
1384
- const [error, setError] = React41.useState(null);
1385
- const wbRef = React41.useRef(null);
1386
- React41.useEffect(() => {
1380
+ const [sheetNames, setSheetNames] = React45.useState([]);
1381
+ const [activeSheet, setActiveSheet] = React45.useState(0);
1382
+ const [data, setData] = React45.useState([]);
1383
+ const [loading, setLoading] = React45.useState(true);
1384
+ const [error, setError] = React45.useState(null);
1385
+ const wbRef = React45.useRef(null);
1386
+ React45.useEffect(() => {
1387
1387
  let cancelled = false;
1388
1388
  setLoading(true);
1389
1389
  setError(null);
@@ -1441,7 +1441,7 @@ function ExcelViewer({ url, base64, onLoadSuccess }) {
1441
1441
  const rows = XLSX__namespace.utils.sheet_to_json(wbRef.current.Sheets[wbRef.current.SheetNames[idx]], { header: 1 });
1442
1442
  setData(rows);
1443
1443
  };
1444
- React41.useEffect(() => {
1444
+ React45.useEffect(() => {
1445
1445
  if (sheetNames.length <= 1) return;
1446
1446
  const handler = (e) => {
1447
1447
  var _a;
@@ -1566,10 +1566,10 @@ __export(CsvViewer_exports, {
1566
1566
  });
1567
1567
  function CsvViewer({ url, base64, delimiter, maxRows }) {
1568
1568
  const { BORDER: BORDER4, MUTED: MUTED2, PAPER: PAPER2 } = useTheme();
1569
- const [rows, setRows] = React41.useState([]);
1570
- const [loading, setLoading] = React41.useState(true);
1571
- const [error, setError] = React41.useState(null);
1572
- React41.useEffect(() => {
1569
+ const [rows, setRows] = React45.useState([]);
1570
+ const [loading, setLoading] = React45.useState(true);
1571
+ const [error, setError] = React45.useState(null);
1572
+ React45.useEffect(() => {
1573
1573
  let cancelled = false;
1574
1574
  setLoading(true);
1575
1575
  setError(null);
@@ -1688,10 +1688,10 @@ __export(TextViewer_exports, {
1688
1688
  });
1689
1689
  function TextViewer({ url, base64, markdown = false, maxLines }) {
1690
1690
  const { MUTED: MUTED2 } = useTheme();
1691
- const [text, setText] = React41.useState("");
1692
- const [loading, setLoading] = React41.useState(true);
1693
- const [error, setError] = React41.useState(null);
1694
- React41.useEffect(() => {
1691
+ const [text, setText] = React45.useState("");
1692
+ const [loading, setLoading] = React45.useState(true);
1693
+ const [error, setError] = React45.useState(null);
1694
+ React45.useEffect(() => {
1695
1695
  let cancelled = false;
1696
1696
  setLoading(true);
1697
1697
  setError(null);
@@ -1789,10 +1789,10 @@ function sanitize(html) {
1789
1789
  }
1790
1790
  function DocxViewer({ url, base64 }) {
1791
1791
  const { MUTED: MUTED2, BORDER: BORDER4 } = useTheme();
1792
- const [html, setHtml] = React41.useState("");
1793
- const [loading, setLoading] = React41.useState(true);
1794
- const [error, setError] = React41.useState(null);
1795
- React41.useEffect(() => {
1792
+ const [html, setHtml] = React45.useState("");
1793
+ const [loading, setLoading] = React45.useState(true);
1794
+ const [error, setError] = React45.useState(null);
1795
+ React45.useEffect(() => {
1796
1796
  let cancelled = false;
1797
1797
  setLoading(true);
1798
1798
  setError(null);
@@ -5305,6 +5305,286 @@ var workflowStepperTool = {
5305
5305
  required: ["type", "title", "steps"]
5306
5306
  }
5307
5307
  };
5308
+ var bbox = zod.z.tuple([zod.z.number(), zod.z.number(), zod.z.number(), zod.z.number()]);
5309
+ var fieldSchema = zod.z.object({
5310
+ field_key: zod.z.string(),
5311
+ label: zod.z.string(),
5312
+ value: zod.z.string(),
5313
+ page: zod.z.number(),
5314
+ // 0-indexed, matches PageDimension.page
5315
+ bbox: bbox.nullable().optional(),
5316
+ confidence: zod.z.number().optional(),
5317
+ confidence_tier: zod.z.enum(["green", "amber", "red"]).optional(),
5318
+ badge: zod.z.enum(["SC", "CN", "AB", "SW"]).optional(),
5319
+ state: zod.z.enum(["ok", "corrected", "missing", "warn"]).optional(),
5320
+ entity_type: zod.z.string().optional(),
5321
+ is_primary: zod.z.boolean().optional(),
5322
+ // Set after a human correction (extractor output, or an optimistic in-card
5323
+ // edit) so the editable field card can show old → new and who changed it.
5324
+ previous_value: zod.z.string().nullable().optional(),
5325
+ corrected_by: zod.z.string().nullable().optional()
5326
+ });
5327
+ var pageSchema = zod.z.object({
5328
+ page: zod.z.number(),
5329
+ // 0-indexed
5330
+ imageUrl: zod.z.string().optional(),
5331
+ // host-resolved from the durable image_ref
5332
+ width_pt: zod.z.number(),
5333
+ height_pt: zod.z.number()
5334
+ });
5335
+ var summaryStatSchema = zod.z.object({
5336
+ field_key: zod.z.string(),
5337
+ label: zod.z.string(),
5338
+ value: zod.z.string(),
5339
+ caption: zod.z.string().nullable().optional()
5340
+ });
5341
+ var summaryFactSchema = zod.z.object({
5342
+ field_key: zod.z.string(),
5343
+ label: zod.z.string(),
5344
+ value: zod.z.string(),
5345
+ badge: zod.z.string().nullable().optional()
5346
+ });
5347
+ var summarySchema = zod.z.object({
5348
+ display_name: zod.z.string().nullable().optional(),
5349
+ short_name: zod.z.string().nullable().optional(),
5350
+ organization: zod.z.string().nullable().optional(),
5351
+ domain: zod.z.string().nullable().optional(),
5352
+ domain_group: zod.z.string().nullable().optional(),
5353
+ tax_year: zod.z.union([zod.z.string(), zod.z.number()]).nullable().optional(),
5354
+ crumbs: zod.z.array(zod.z.string()).optional(),
5355
+ tags: zod.z.array(zod.z.string()).optional(),
5356
+ stats: zod.z.array(summaryStatSchema).optional(),
5357
+ facts: zod.z.array(summaryFactSchema).optional()
5358
+ });
5359
+ var documentFieldExtractionSchema = zod.z.object({
5360
+ type: zod.z.literal("document-field-extraction"),
5361
+ doc_type: zod.z.string().optional(),
5362
+ // Original uploaded filename (e.g. "2024_gl.pdf"); preferred over doc_type for
5363
+ // the card title since doc_type is often the "generic_fallback" schema name.
5364
+ file_name: zod.z.string().optional(),
5365
+ // Server-side token; resolved by the host into pages/fields before render.
5366
+ payload_ref: zod.z.string().optional(),
5367
+ // Present for persisted workstream docs; absent for pre-existing cards.
5368
+ store_id: zod.z.string().optional(),
5369
+ doc_id: zod.z.string().optional(),
5370
+ pages: zod.z.array(pageSchema).max(100).optional(),
5371
+ fields: zod.z.array(fieldSchema).max(1e3).optional(),
5372
+ // Page-count metadata for the Details tab ("N of M pages extracted").
5373
+ page_count: zod.z.number().optional(),
5374
+ pages_processed: zod.z.number().optional(),
5375
+ // Deterministic document summary for the Details tab.
5376
+ summary: summarySchema.nullable().optional()
5377
+ });
5378
+ var documentFieldExtractionTool = {
5379
+ name: "render_document_field_extraction",
5380
+ 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.",
5381
+ input_schema: {
5382
+ type: "object",
5383
+ properties: {
5384
+ type: { type: "string", enum: ["document-field-extraction"] },
5385
+ doc_type: { type: "string" },
5386
+ file_name: {
5387
+ type: "string",
5388
+ description: "Original uploaded filename; shown as the card title."
5389
+ },
5390
+ payload_ref: {
5391
+ type: "string",
5392
+ 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."
5393
+ },
5394
+ store_id: {
5395
+ type: "string",
5396
+ description: "Docstore store id; present for persisted workstream docs. The host uses this to open the editable viewer."
5397
+ },
5398
+ doc_id: {
5399
+ type: "string",
5400
+ description: "Docstore document id; present for persisted workstream docs. Required for the editable viewer."
5401
+ },
5402
+ pages: {
5403
+ type: "array",
5404
+ items: {
5405
+ type: "object",
5406
+ properties: {
5407
+ page: { type: "number", description: "0-indexed page number" },
5408
+ imageUrl: { type: "string" },
5409
+ width_pt: { type: "number" },
5410
+ height_pt: { type: "number" }
5411
+ },
5412
+ required: ["page", "width_pt", "height_pt"]
5413
+ }
5414
+ },
5415
+ fields: {
5416
+ type: "array",
5417
+ items: {
5418
+ type: "object",
5419
+ properties: {
5420
+ field_key: { type: "string" },
5421
+ label: { type: "string" },
5422
+ value: { type: "string" },
5423
+ page: { type: "number", description: "0-indexed page number" },
5424
+ bbox: {
5425
+ type: "array",
5426
+ items: { type: "number" },
5427
+ description: "[x0,y0,x1,y1] PDF points, origin bottom-left; null if unlocated"
5428
+ },
5429
+ confidence: { type: "number" },
5430
+ confidence_tier: { type: "string", enum: ["green", "amber", "red"] },
5431
+ badge: { type: "string", enum: ["SC", "CN", "AB", "SW"] },
5432
+ state: { type: "string", enum: ["ok", "corrected", "missing", "warn"] },
5433
+ entity_type: { type: "string" },
5434
+ is_primary: { type: "boolean" }
5435
+ },
5436
+ required: ["field_key", "label", "value", "page"]
5437
+ }
5438
+ },
5439
+ page_count: { type: "number" },
5440
+ pages_processed: { type: "number" },
5441
+ summary: {
5442
+ type: "object",
5443
+ description: "Deterministic document summary for the Details tab (display_name, organization, domain, stats, facts, tags). Produced by the extractor \u2014 pass through verbatim.",
5444
+ properties: {
5445
+ display_name: { type: "string" },
5446
+ short_name: { type: "string" },
5447
+ organization: { type: "string" },
5448
+ domain: { type: "string" },
5449
+ domain_group: { type: "string" },
5450
+ tax_year: { type: "string" },
5451
+ crumbs: { type: "array", items: { type: "string" } },
5452
+ tags: { type: "array", items: { type: "string" } },
5453
+ stats: {
5454
+ type: "array",
5455
+ items: {
5456
+ type: "object",
5457
+ properties: {
5458
+ field_key: { type: "string" },
5459
+ label: { type: "string" },
5460
+ value: { type: "string" },
5461
+ caption: { type: "string" }
5462
+ },
5463
+ required: ["field_key", "label", "value"]
5464
+ }
5465
+ },
5466
+ facts: {
5467
+ type: "array",
5468
+ items: {
5469
+ type: "object",
5470
+ properties: {
5471
+ field_key: { type: "string" },
5472
+ label: { type: "string" },
5473
+ value: { type: "string" },
5474
+ badge: { type: "string" }
5475
+ },
5476
+ required: ["field_key", "label", "value"]
5477
+ }
5478
+ }
5479
+ }
5480
+ }
5481
+ },
5482
+ required: ["type"]
5483
+ }
5484
+ };
5485
+ var decisionCardSchema = zod.z.object({
5486
+ type: zod.z.literal("decision-card"),
5487
+ id: zod.z.string().optional(),
5488
+ decision_type: zod.z.string().optional(),
5489
+ title: zod.z.string(),
5490
+ question: zod.z.string(),
5491
+ amount: zod.z.number().optional(),
5492
+ currency: zod.z.string().optional(),
5493
+ amount_label: zod.z.string().optional(),
5494
+ severity: zod.z.enum(["low", "medium", "high"]).optional(),
5495
+ flags: zod.z.array(
5496
+ zod.z.object({
5497
+ field: zod.z.string().optional(),
5498
+ issue: zod.z.string(),
5499
+ severity: zod.z.enum(["low", "medium", "high"]).optional()
5500
+ })
5501
+ ).max(6).optional(),
5502
+ options: zod.z.array(
5503
+ zod.z.object({
5504
+ id: zod.z.string().optional(),
5505
+ label: zod.z.string(),
5506
+ recommended: zod.z.boolean().optional()
5507
+ })
5508
+ ).min(1).max(5),
5509
+ source: zod.z.object({
5510
+ label: zod.z.string().optional(),
5511
+ url: zod.z.string().optional()
5512
+ }).optional(),
5513
+ resolved: zod.z.object({
5514
+ option: zod.z.string()
5515
+ }).optional()
5516
+ });
5517
+ var decisionCardTool = {
5518
+ name: "render_decision_card",
5519
+ 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).",
5520
+ input_schema: {
5521
+ type: "object",
5522
+ properties: {
5523
+ type: { type: "string", enum: ["decision-card"] },
5524
+ id: { type: "string", description: "Stable id for update-in-place rendering" },
5525
+ decision_type: {
5526
+ type: "string",
5527
+ description: "Short category shown in the eyebrow, e.g. 'Cross-check', 'Allocation', 'Reserve'"
5528
+ },
5529
+ title: { type: "string", description: "The decision headline, e.g. 'AR reserve adequacy'" },
5530
+ question: { type: "string", description: "The full question / context the user must judge" },
5531
+ amount: { type: "number", description: "Dollar value at stake, e.g. 27100" },
5532
+ currency: { type: "string", description: "ISO currency code; defaults to USD" },
5533
+ amount_label: { type: "string", description: "Caption above the amount, e.g. 'At stake'" },
5534
+ severity: {
5535
+ type: "string",
5536
+ enum: ["low", "medium", "high"],
5537
+ description: "Severity of the decision; tints the accent rail"
5538
+ },
5539
+ flags: {
5540
+ type: "array",
5541
+ maxItems: 6,
5542
+ description: "Optional data-quality flags surfaced on the card",
5543
+ items: {
5544
+ type: "object",
5545
+ properties: {
5546
+ field: { type: "string" },
5547
+ issue: { type: "string" },
5548
+ severity: { type: "string", enum: ["low", "medium", "high"] }
5549
+ },
5550
+ required: ["issue"]
5551
+ }
5552
+ },
5553
+ options: {
5554
+ type: "array",
5555
+ minItems: 1,
5556
+ maxItems: 5,
5557
+ description: "Mutually-exclusive resolution choices; mark one `recommended` to make it primary",
5558
+ items: {
5559
+ type: "object",
5560
+ properties: {
5561
+ id: { type: "string" },
5562
+ label: { type: "string" },
5563
+ recommended: { type: "boolean" }
5564
+ },
5565
+ required: ["label"]
5566
+ }
5567
+ },
5568
+ source: {
5569
+ type: "object",
5570
+ description: "Optional provenance link for the figure",
5571
+ properties: {
5572
+ label: { type: "string" },
5573
+ url: { type: "string" }
5574
+ }
5575
+ },
5576
+ resolved: {
5577
+ type: "object",
5578
+ description: "Pre-resolved state for transcript replay",
5579
+ properties: {
5580
+ option: { type: "string" }
5581
+ },
5582
+ required: ["option"]
5583
+ }
5584
+ },
5585
+ required: ["type", "title", "question", "options"]
5586
+ }
5587
+ };
5308
5588
 
5309
5589
  // src/schemas/index.ts
5310
5590
  var schemaRegistry = {
@@ -5364,7 +5644,9 @@ var schemaRegistry = {
5364
5644
  "connect-integration": { schema: connectIntegrationSchema, tool: connectIntegrationTool },
5365
5645
  "integrations-list": { schema: integrationsListSchema, tool: integrationsListTool },
5366
5646
  "pipeline-preview": { schema: pipelinePreviewSchema, tool: pipelinePreviewTool },
5367
- "workflow-stepper": { schema: workflowStepperSchema, tool: workflowStepperTool }
5647
+ "workflow-stepper": { schema: workflowStepperSchema, tool: workflowStepperTool },
5648
+ "document-field-extraction": { schema: documentFieldExtractionSchema, tool: documentFieldExtractionTool },
5649
+ "decision-card": { schema: decisionCardSchema, tool: decisionCardTool }
5368
5650
  };
5369
5651
 
5370
5652
  // src/schemas/coercePayload.ts
@@ -5446,16 +5728,16 @@ init_theme();
5446
5728
  var DOT_COLOR = "#aaaaaa";
5447
5729
  var DOT_HOVER = "#555555";
5448
5730
  function ComponentActions({ children, onDownloadCSV, columnConfig, filename = "component" }) {
5449
- const [open, setOpen] = React41.useState(false);
5450
- const [view, setView] = React41.useState("main");
5451
- const contentRef = React41.useRef(null);
5452
- const menuRef = React41.useRef(null);
5453
- const btnRef = React41.useRef(null);
5454
- const close = React41.useCallback(() => {
5731
+ const [open, setOpen] = React45.useState(false);
5732
+ const [view, setView] = React45.useState("main");
5733
+ const contentRef = React45.useRef(null);
5734
+ const menuRef = React45.useRef(null);
5735
+ const btnRef = React45.useRef(null);
5736
+ const close = React45.useCallback(() => {
5455
5737
  setOpen(false);
5456
5738
  setView("main");
5457
5739
  }, []);
5458
- React41.useEffect(() => {
5740
+ React45.useEffect(() => {
5459
5741
  if (!open) return;
5460
5742
  const handler = (e) => {
5461
5743
  var _a, _b;
@@ -5466,7 +5748,7 @@ function ComponentActions({ children, onDownloadCSV, columnConfig, filename = "c
5466
5748
  document.addEventListener("mousedown", handler);
5467
5749
  return () => document.removeEventListener("mousedown", handler);
5468
5750
  }, [open, close]);
5469
- const handleDownloadPNG = React41.useCallback(async () => {
5751
+ const handleDownloadPNG = React45.useCallback(async () => {
5470
5752
  if (!contentRef.current) return;
5471
5753
  try {
5472
5754
  const url = await htmlToImage.toPng(contentRef.current, { backgroundColor: "white", pixelRatio: 2 });
@@ -5478,7 +5760,7 @@ function ComponentActions({ children, onDownloadCSV, columnConfig, filename = "c
5478
5760
  }
5479
5761
  close();
5480
5762
  }, [filename, close]);
5481
- const handleCSV = React41.useCallback(() => {
5763
+ const handleCSV = React45.useCallback(() => {
5482
5764
  onDownloadCSV == null ? void 0 : onDownloadCSV();
5483
5765
  close();
5484
5766
  }, [onDownloadCSV, close]);
@@ -5590,12 +5872,12 @@ function MenuButton({ label, onClick }) {
5590
5872
  );
5591
5873
  }
5592
5874
  function useColumnVisibility(columns) {
5593
- const [hidden, setHidden] = React41.useState(/* @__PURE__ */ new Set());
5594
- const visibleColumns = React41.useMemo(
5875
+ const [hidden, setHidden] = React45.useState(/* @__PURE__ */ new Set());
5876
+ const visibleColumns = React45.useMemo(
5595
5877
  () => columns.filter((c) => !hidden.has(c.key)),
5596
5878
  [columns, hidden]
5597
5879
  );
5598
- const toggle = React41.useCallback((key) => {
5880
+ const toggle = React45.useCallback((key) => {
5599
5881
  setHidden((prev) => {
5600
5882
  const next = new Set(prev);
5601
5883
  if (next.has(key)) next.delete(key);
@@ -5603,8 +5885,8 @@ function useColumnVisibility(columns) {
5603
5885
  return next;
5604
5886
  });
5605
5887
  }, []);
5606
- const showAll = React41.useCallback(() => setHidden(/* @__PURE__ */ new Set()), []);
5607
- const hideAll = React41.useCallback(
5888
+ const showAll = React45.useCallback(() => setHidden(/* @__PURE__ */ new Set()), []);
5889
+ const hideAll = React45.useCallback(
5608
5890
  () => setHidden(new Set(columns.map((c) => c.key))),
5609
5891
  [columns]
5610
5892
  );
@@ -5855,9 +6137,9 @@ function AlertResolver(p) {
5855
6137
  // src/composites/stat-grid/resolver.tsx
5856
6138
  init_Markdown();
5857
6139
  function FitText({ children, max = 22, min = 13, title, className, style }) {
5858
- const ref = React41.useRef(null);
5859
- const [size, setSize] = React41.useState(max);
5860
- React41.useLayoutEffect(() => {
6140
+ const ref = React45.useRef(null);
6141
+ const [size, setSize] = React45.useState(max);
6142
+ React45.useLayoutEffect(() => {
5861
6143
  const el = ref.current;
5862
6144
  if (!el) return void 0;
5863
6145
  const fit = () => {
@@ -5944,7 +6226,7 @@ init_ThemeContext();
5944
6226
  function TabsPanelResolver(p) {
5945
6227
  var _a;
5946
6228
  const { BORDER: BORDER4, MUTED: MUTED2, PAPER: PAPER2, ACCENT: ACCENT2 } = useTheme();
5947
- const [activeIdx, setActiveIdx] = React41.useState(0);
6229
+ const [activeIdx, setActiveIdx] = React45.useState(0);
5948
6230
  const activeTab = p.tabs[activeIdx];
5949
6231
  return /* @__PURE__ */ jsxRuntime.jsx(ComponentActions, { filename: "tabs-panel", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { width: "100%", display: "flex", flexDirection: "column", gap: "0" }, children: [
5950
6232
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -6102,17 +6384,17 @@ function SparklineTableResolver(p) {
6102
6384
  // src/composites/heatmap-table/resolver.tsx
6103
6385
  init_theme();
6104
6386
  init_ThemeContext();
6105
- function heatColor(z58) {
6106
- const clamped = Math.max(-3, Math.min(3, z58));
6387
+ function heatColor(z60) {
6388
+ const clamped = Math.max(-3, Math.min(3, z60));
6107
6389
  const abs = Math.abs(clamped);
6108
6390
  const lightness = 95 - abs * 8;
6109
6391
  const hue = clamped >= 0 ? 142 : 0;
6110
6392
  return `hsl(${hue} 60% ${lightness}%)`;
6111
6393
  }
6112
- function heatTextColor(z58) {
6113
- const abs = Math.abs(z58);
6114
- if (abs > 2) return z58 >= 0 ? "#14532d" : "#7f1d1d";
6115
- if (abs > 1) return z58 >= 0 ? "#166534" : "#991b1b";
6394
+ function heatTextColor(z60) {
6395
+ const abs = Math.abs(z60);
6396
+ if (abs > 2) return z60 >= 0 ? "#14532d" : "#7f1d1d";
6397
+ if (abs > 1) return z60 >= 0 ? "#166534" : "#991b1b";
6116
6398
  return "var(--foreground)";
6117
6399
  }
6118
6400
  var th2 = {
@@ -6210,7 +6492,7 @@ var thStyle2 = {
6210
6492
  function ScreenerTableResolver(p) {
6211
6493
  var _a, _b, _c, _d, _e, _f;
6212
6494
  const { ACCENT: ACCENT2, BORDER: BORDER4, MUTED: MUTED2, PAPER: PAPER2 } = useTheme();
6213
- const [activeFilters, setActiveFilters] = React41.useState(new Set((_a = p.activeFilters) != null ? _a : []));
6495
+ const [activeFilters, setActiveFilters] = React45.useState(new Set((_a = p.activeFilters) != null ? _a : []));
6214
6496
  const { visibleColumns, hidden, toggle, showAll, hideAll, allColumns } = useColumnVisibility((_b = p.columns) != null ? _b : []);
6215
6497
  const toggleFilter = (f) => setActiveFilters((prev) => {
6216
6498
  const next = new Set(prev);
@@ -6280,7 +6562,7 @@ var th3 = {
6280
6562
  };
6281
6563
  function GroupRows({ group, columns, depth }) {
6282
6564
  var _a, _b;
6283
- const [open, setOpen] = React41.useState(true);
6565
+ const [open, setOpen] = React45.useState(true);
6284
6566
  const indent = depth * 14;
6285
6567
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
6286
6568
  /* @__PURE__ */ jsxRuntime.jsxs(
@@ -6385,7 +6667,7 @@ var dotColor = {
6385
6667
  function NewsFeedResolver(p) {
6386
6668
  var _a, _b;
6387
6669
  const { ACCENT: ACCENT2, MUTED: MUTED2 } = useTheme();
6388
- const [filter, setFilter] = React41.useState(null);
6670
+ const [filter, setFilter] = React45.useState(null);
6389
6671
  const sentiments = ["positive", "neutral", "negative"].filter(
6390
6672
  (s) => {
6391
6673
  var _a2;
@@ -6427,9 +6709,9 @@ function NewsFeedResolver(p) {
6427
6709
  ] }) });
6428
6710
  }
6429
6711
  function useSeriesToggle(seriesKeys) {
6430
- const [hidden, setHidden] = React41.useState(/* @__PURE__ */ new Set());
6431
- const isVisible = React41.useCallback((key) => !hidden.has(key), [hidden]);
6432
- const toggle = React41.useCallback((key) => {
6712
+ const [hidden, setHidden] = React45.useState(/* @__PURE__ */ new Set());
6713
+ const isVisible = React45.useCallback((key) => !hidden.has(key), [hidden]);
6714
+ const toggle = React45.useCallback((key) => {
6433
6715
  setHidden((prev) => {
6434
6716
  const next = new Set(prev);
6435
6717
  if (next.has(key)) next.delete(key);
@@ -6437,7 +6719,7 @@ function useSeriesToggle(seriesKeys) {
6437
6719
  return next;
6438
6720
  });
6439
6721
  }, []);
6440
- const showAll = React41.useCallback(() => setHidden(/* @__PURE__ */ new Set()), []);
6722
+ const showAll = React45.useCallback(() => setHidden(/* @__PURE__ */ new Set()), []);
6441
6723
  return { hidden, isVisible, toggle, showAll, allKeys: seriesKeys };
6442
6724
  }
6443
6725
 
@@ -6746,7 +7028,7 @@ function WaterfallChartResolver(p) {
6746
7028
  ] }) });
6747
7029
  }
6748
7030
  init_ThemeContext();
6749
- var FlowGraph2 = React41__default.default.lazy(
7031
+ var FlowGraph2 = React45__default.default.lazy(
6750
7032
  () => Promise.resolve().then(() => (init_FlowGraph(), FlowGraph_exports)).then((m) => ({ default: m.FlowGraph }))
6751
7033
  );
6752
7034
  function FlowCanvasRenderer({
@@ -6787,7 +7069,7 @@ function FlowCanvasRenderer({
6787
7069
  overflow: "hidden",
6788
7070
  background: "#ffffff",
6789
7071
  position: "relative"
6790
- }, 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: {
7072
+ }, 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: {
6791
7073
  position: "absolute",
6792
7074
  inset: 0,
6793
7075
  display: "flex",
@@ -7020,7 +7302,7 @@ function TrialBalanceResolver(p) {
7020
7302
  gDebit += a.debit;
7021
7303
  gCredit += a.credit;
7022
7304
  });
7023
- return /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
7305
+ return /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
7024
7306
  /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsx("td", { colSpan: 4, style: {
7025
7307
  padding: "8px 12px",
7026
7308
  fontSize: "12px",
@@ -7557,7 +7839,7 @@ function ItemRow({ item }) {
7557
7839
  ] });
7558
7840
  }
7559
7841
  function Section({ section }) {
7560
- const [open, setOpen] = React41.useState(true);
7842
+ const [open, setOpen] = React45.useState(true);
7561
7843
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
7562
7844
  /* @__PURE__ */ jsxRuntime.jsxs(
7563
7845
  "button",
@@ -7679,7 +7961,7 @@ function ReconciliationViewResolver(p) {
7679
7961
  const { BORDER: BORDER4, MUTED: MUTED2, PAPER: PAPER2, ACCENT: ACCENT2 } = useTheme();
7680
7962
  const sourceA = (_a = p.sourceA) != null ? _a : { label: "Source A" };
7681
7963
  const sourceB = (_b = p.sourceB) != null ? _b : { label: "Source B" };
7682
- const [activeTab, setActiveTab] = React41.useState("matched");
7964
+ const [activeTab, setActiveTab] = React45.useState("matched");
7683
7965
  const balanceA = (_d = (_c = p.summary) == null ? void 0 : _c.balanceA) != null ? _d : 0;
7684
7966
  const balanceB = (_f = (_e = p.summary) == null ? void 0 : _e.balanceB) != null ? _f : 0;
7685
7967
  const difference = (_h = (_g = p.summary) == null ? void 0 : _g.difference) != null ? _h : balanceA - balanceB;
@@ -8322,7 +8604,7 @@ function ChangesView({ changes }) {
8322
8604
  }
8323
8605
  function EventCard({ event }) {
8324
8606
  var _a;
8325
- const [showChanges, setShowChanges] = React41.useState(false);
8607
+ const [showChanges, setShowChanges] = React45.useState(false);
8326
8608
  const ac = (_a = actionConfig[event.action]) != null ? _a : actionConfig.commented;
8327
8609
  const hasChanges = event.changes && event.changes.length > 0;
8328
8610
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", gap: "12px", position: "relative" }, children: [
@@ -8380,23 +8662,23 @@ function AuditTrailResolver(p) {
8380
8662
  }
8381
8663
  init_Markdown();
8382
8664
  function useFullscreen(ref) {
8383
- const [isFullscreen, setIsFullscreen] = React41.useState(false);
8384
- React41.useEffect(() => {
8665
+ const [isFullscreen, setIsFullscreen] = React45.useState(false);
8666
+ React45.useEffect(() => {
8385
8667
  const handler = () => {
8386
8668
  setIsFullscreen(!!document.fullscreenElement);
8387
8669
  };
8388
8670
  document.addEventListener("fullscreenchange", handler);
8389
8671
  return () => document.removeEventListener("fullscreenchange", handler);
8390
8672
  }, []);
8391
- const enter = React41.useCallback(() => {
8673
+ const enter = React45.useCallback(() => {
8392
8674
  var _a, _b;
8393
8675
  (_b = (_a = ref.current) == null ? void 0 : _a.requestFullscreen) == null ? void 0 : _b.call(_a);
8394
8676
  }, [ref]);
8395
- const exit = React41.useCallback(() => {
8677
+ const exit = React45.useCallback(() => {
8396
8678
  var _a;
8397
8679
  if (document.fullscreenElement) (_a = document.exitFullscreen) == null ? void 0 : _a.call(document);
8398
8680
  }, []);
8399
- const toggle = React41.useCallback(() => {
8681
+ const toggle = React45.useCallback(() => {
8400
8682
  if (isFullscreen) exit();
8401
8683
  else enter();
8402
8684
  }, [isFullscreen, enter, exit]);
@@ -8406,10 +8688,10 @@ function useFullscreen(ref) {
8406
8688
  // src/composites/document-preview/resolver.tsx
8407
8689
  init_theme();
8408
8690
  init_ThemeContext();
8409
- var PdfViewer2 = React41__default.default.lazy(
8691
+ var PdfViewer2 = React45__default.default.lazy(
8410
8692
  () => Promise.resolve().then(() => (init_PdfViewer(), PdfViewer_exports)).then((m) => ({ default: m.PdfViewer }))
8411
8693
  );
8412
- var ExcelViewer2 = React41__default.default.lazy(
8694
+ var ExcelViewer2 = React45__default.default.lazy(
8413
8695
  () => Promise.resolve().then(() => (init_ExcelViewer(), ExcelViewer_exports)).then((m) => ({ default: m.ExcelViewer }))
8414
8696
  );
8415
8697
  var highlightColors = {
@@ -8459,8 +8741,8 @@ function DownloadIcon() {
8459
8741
  function DocumentPreviewResolver(p) {
8460
8742
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u;
8461
8743
  const { BORDER: BORDER4, MUTED: MUTED2, PAPER: PAPER2, ACCENT: ACCENT2 } = useTheme();
8462
- const [currentPage, setCurrentPage] = React41.useState(0);
8463
- const containerRef = React41.useRef(null);
8744
+ const [currentPage, setCurrentPage] = React45.useState(0);
8745
+ const containerRef = React45.useRef(null);
8464
8746
  const { isFullscreen, toggle } = useFullscreen(containerRef);
8465
8747
  const hasRealFile = !!(((_a = p.source) == null ? void 0 : _a.url) || ((_b = p.source) == null ? void 0 : _b.base64));
8466
8748
  const isPdf = p.documentType === "pdf";
@@ -8468,9 +8750,9 @@ function DocumentPreviewResolver(p) {
8468
8750
  const totalPages = ((_c = p.pages) != null ? _c : []).length;
8469
8751
  const page = p.pages[currentPage];
8470
8752
  const pageHighlights = ((_d = p.highlights) != null ? _d : []).filter((h) => h.pageIndex === currentPage);
8471
- const handlePdfLoad = React41.useCallback(() => {
8753
+ const handlePdfLoad = React45.useCallback(() => {
8472
8754
  }, []);
8473
- const handleExcelLoad = React41.useCallback(() => {
8755
+ const handleExcelLoad = React45.useCallback(() => {
8474
8756
  }, []);
8475
8757
  return /* @__PURE__ */ jsxRuntime.jsx(ComponentActions, { filename: (_e = p.title) != null ? _e : "document-preview", children: /* @__PURE__ */ jsxRuntime.jsxs(
8476
8758
  "div",
@@ -8583,7 +8865,7 @@ function DocumentPreviewResolver(p) {
8583
8865
  display: "flex",
8584
8866
  flexDirection: "column"
8585
8867
  }, children: [
8586
- 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: [
8868
+ 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: [
8587
8869
  "No content available for ",
8588
8870
  (_u = page == null ? void 0 : page.label) != null ? _u : "this page"
8589
8871
  ] }),
@@ -8646,7 +8928,7 @@ function ConfidenceBar({ confidence, height = 6 }) {
8646
8928
  }
8647
8929
  function StepCard({ step, isLast }) {
8648
8930
  var _a;
8649
- const [expanded, setExpanded] = React41.useState(false);
8931
+ const [expanded, setExpanded] = React45.useState(false);
8650
8932
  const cfg = stepTypeConfig[step.stepType];
8651
8933
  const detail = (_a = step.detail) != null ? _a : "";
8652
8934
  const isLong = detail.length > 100;
@@ -9151,7 +9433,7 @@ function ExampleRow({ example }) {
9151
9433
  );
9152
9434
  }
9153
9435
  function PartSection({ part, defaultOpen }) {
9154
- const [open, setOpen] = React41.useState(defaultOpen);
9436
+ const [open, setOpen] = React45.useState(defaultOpen);
9155
9437
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
9156
9438
  /* @__PURE__ */ jsxRuntime.jsxs(
9157
9439
  "button",
@@ -9281,7 +9563,7 @@ function EngagementPipelineResolver(p) {
9281
9563
  const defaultActive = phases.findIndex(
9282
9564
  (ph) => ph.status === "in-progress" || ph.status === "blocked"
9283
9565
  );
9284
- const [activeIdx, setActiveIdx] = React41.useState(defaultActive >= 0 ? defaultActive : 0);
9566
+ const [activeIdx, setActiveIdx] = React45.useState(defaultActive >= 0 ? defaultActive : 0);
9285
9567
  const activePhase = phases[activeIdx];
9286
9568
  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: [
9287
9569
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "4px" }, children: [
@@ -9365,7 +9647,7 @@ function EngagementPipelineResolver(p) {
9365
9647
  const color = (_a2 = statusColor2[phase.status]) != null ? _a2 : "#d6d3d1";
9366
9648
  const isCurrent = i === activeIdx;
9367
9649
  const size = isCurrent ? 28 : 20;
9368
- return /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
9650
+ return /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
9369
9651
  i > 0 && /* @__PURE__ */ jsxRuntime.jsx(
9370
9652
  "div",
9371
9653
  {
@@ -9672,7 +9954,7 @@ function Avatar({ name, avatar, hovered }) {
9672
9954
  function EntityCardGridResolver(p) {
9673
9955
  var _a, _b;
9674
9956
  const { BORDER: BORDER4, MUTED: MUTED2, ACCENT: ACCENT2 } = useTheme();
9675
- const [hoveredId, setHoveredId] = React41.useState(null);
9957
+ const [hoveredId, setHoveredId] = React45.useState(null);
9676
9958
  return /* @__PURE__ */ jsxRuntime.jsx(ComponentActions, { filename: (_a = p.title) != null ? _a : "entity-card-grid", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { width: "100%", display: "flex", flexDirection: "column", gap: "10px" }, children: [
9677
9959
  p.title && /* @__PURE__ */ jsxRuntime.jsx(
9678
9960
  "p",
@@ -9928,7 +10210,7 @@ function StepRow({ step }) {
9928
10210
  function JobTrackerResolver(p) {
9929
10211
  var _a, _b, _c, _d, _e, _f, _g;
9930
10212
  const { BORDER: BORDER4, MUTED: MUTED2, ACCENT: ACCENT2, PAPER: PAPER2 } = useTheme();
9931
- const [stepsOpen, setStepsOpen] = React41.useState(true);
10213
+ const [stepsOpen, setStepsOpen] = React45.useState(true);
9932
10214
  const barColor = (_a = statusColors2[p.status]) != null ? _a : MUTED2;
9933
10215
  const badge = (_b = statusBadgeConfig[p.status]) != null ? _b : statusBadgeConfig.queued;
9934
10216
  const progress = (_c = p.progress) != null ? _c : p.status === "completed" ? 100 : 0;
@@ -10368,7 +10650,7 @@ function CitationCard({
10368
10650
  );
10369
10651
  }
10370
10652
  function FollowUpItem({ text }) {
10371
- const [hovered, setHovered] = React41.useState(false);
10653
+ const [hovered, setHovered] = React45.useState(false);
10372
10654
  return /* @__PURE__ */ jsxRuntime.jsxs(
10373
10655
  "span",
10374
10656
  {
@@ -10393,7 +10675,7 @@ function CitationMarker({
10393
10675
  index,
10394
10676
  onClick
10395
10677
  }) {
10396
- const [hovered, setHovered] = React41.useState(false);
10678
+ const [hovered, setHovered] = React45.useState(false);
10397
10679
  return /* @__PURE__ */ jsxRuntime.jsx(
10398
10680
  "sup",
10399
10681
  {
@@ -10422,7 +10704,7 @@ function CitationMarker({
10422
10704
  function CitedAnswerResolver(p) {
10423
10705
  var _a, _b, _c, _d, _e;
10424
10706
  const { BORDER: BORDER4, MUTED: MUTED2, ACCENT: ACCENT2, SECONDARY: SECONDARY2 } = useTheme();
10425
- const [expandedIds, setExpandedIds] = React41.useState(/* @__PURE__ */ new Set());
10707
+ const [expandedIds, setExpandedIds] = React45.useState(/* @__PURE__ */ new Set());
10426
10708
  const toggleCitation = (id) => {
10427
10709
  setExpandedIds((prev) => {
10428
10710
  const next = new Set(prev);
@@ -10726,7 +11008,7 @@ function TransactionFeedResolver(p) {
10726
11008
  var _a, _b, _c, _d, _e;
10727
11009
  const { BORDER: BORDER4, MUTED: MUTED2 } = useTheme();
10728
11010
  const currency = (_a = p.currency) != null ? _a : "USD";
10729
- const [hoveredIndex, setHoveredIndex] = React41.useState(null);
11011
+ const [hoveredIndex, setHoveredIndex] = React45.useState(null);
10730
11012
  const hasBalance = ((_b = p.transactions) != null ? _b : []).some((tx) => tx.balance != null);
10731
11013
  const totalInflows = p.transactions.filter((tx) => tx.amount > 0 && tx.status !== "reversed").reduce((sum, tx) => sum + tx.amount, 0);
10732
11014
  const totalOutflows = p.transactions.filter((tx) => tx.amount < 0 && tx.status !== "reversed").reduce((sum, tx) => sum + tx.amount, 0);
@@ -10883,7 +11165,7 @@ function formatDate2(dateStr) {
10883
11165
  }
10884
11166
  function FileRow({ item }) {
10885
11167
  var _a;
10886
- const [hovered, setHovered] = React41.useState(false);
11168
+ const [hovered, setHovered] = React45.useState(false);
10887
11169
  const cfg = getDocConfig(item.docType);
10888
11170
  return /* @__PURE__ */ jsxRuntime.jsxs(
10889
11171
  "div",
@@ -10959,8 +11241,8 @@ function FileRow({ item }) {
10959
11241
  );
10960
11242
  }
10961
11243
  function GroupSection({ groupName, items }) {
10962
- const [open, setOpen] = React41.useState(true);
10963
- const [headerHovered, setHeaderHovered] = React41.useState(false);
11244
+ const [open, setOpen] = React45.useState(true);
11245
+ const [headerHovered, setHeaderHovered] = React45.useState(false);
10964
11246
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10965
11247
  /* @__PURE__ */ jsxRuntime.jsxs(
10966
11248
  "button",
@@ -11146,15 +11428,15 @@ function isExpirySoon(expiresAt) {
11146
11428
 
11147
11429
  // src/shared/viewers/PreviewHost.tsx
11148
11430
  init_ThemeContext();
11149
- var PdfViewer3 = React41.lazy(
11431
+ var PdfViewer3 = React45.lazy(
11150
11432
  () => Promise.resolve().then(() => (init_PdfViewer(), PdfViewer_exports)).then((m) => ({ default: m.PdfViewer }))
11151
11433
  );
11152
- var ExcelViewer3 = React41.lazy(
11434
+ var ExcelViewer3 = React45.lazy(
11153
11435
  () => Promise.resolve().then(() => (init_ExcelViewer(), ExcelViewer_exports)).then((m) => ({ default: m.ExcelViewer }))
11154
11436
  );
11155
- var CsvViewer2 = React41.lazy(() => Promise.resolve().then(() => (init_CsvViewer(), CsvViewer_exports)).then((m) => ({ default: m.CsvViewer })));
11156
- var TextViewer2 = React41.lazy(() => Promise.resolve().then(() => (init_TextViewer(), TextViewer_exports)).then((m) => ({ default: m.TextViewer })));
11157
- var DocxViewer2 = React41.lazy(() => Promise.resolve().then(() => (init_DocxViewer(), DocxViewer_exports)).then((m) => ({ default: m.DocxViewer })));
11437
+ var CsvViewer2 = React45.lazy(() => Promise.resolve().then(() => (init_CsvViewer(), CsvViewer_exports)).then((m) => ({ default: m.CsvViewer })));
11438
+ var TextViewer2 = React45.lazy(() => Promise.resolve().then(() => (init_TextViewer(), TextViewer_exports)).then((m) => ({ default: m.TextViewer })));
11439
+ var DocxViewer2 = React45.lazy(() => Promise.resolve().then(() => (init_DocxViewer(), DocxViewer_exports)).then((m) => ({ default: m.DocxViewer })));
11158
11440
  var PEEK_ROWS = 20;
11159
11441
  var PEEK_LINES = 40;
11160
11442
  function PreviewHost({ kind, source, mode = "full" }) {
@@ -11184,7 +11466,7 @@ function PreviewHost({ kind, source, mode = "full" }) {
11184
11466
  default:
11185
11467
  return null;
11186
11468
  }
11187
- return /* @__PURE__ */ jsxRuntime.jsx(React41.Suspense, { fallback, children: viewer });
11469
+ return /* @__PURE__ */ jsxRuntime.jsx(React45.Suspense, { fallback, children: viewer });
11188
11470
  }
11189
11471
 
11190
11472
  // src/shared/PreviewModal.tsx
@@ -11200,7 +11482,7 @@ function PreviewModal({
11200
11482
  onDownload
11201
11483
  }) {
11202
11484
  const { BORDER: BORDER4, MUTED: MUTED2, ACCENT: ACCENT2 } = useTheme();
11203
- React41.useEffect(() => {
11485
+ React45.useEffect(() => {
11204
11486
  if (!open) return;
11205
11487
  const onKey = (e) => {
11206
11488
  if (e.key === "Escape") onClose();
@@ -11373,17 +11655,17 @@ function FileCard({
11373
11655
  previewDisabled = false
11374
11656
  }) {
11375
11657
  const { BORDER: BORDER4, MUTED: MUTED2, ACCENT: ACCENT2 } = useTheme();
11376
- const [cardHover, setCardHover] = React41.useState(false);
11377
- const [btnHover, setBtnHover] = React41.useState(false);
11378
- const [pvHover, setPvHover] = React41.useState(false);
11658
+ const [cardHover, setCardHover] = React45.useState(false);
11659
+ const [btnHover, setBtnHover] = React45.useState(false);
11660
+ const [pvHover, setPvHover] = React45.useState(false);
11379
11661
  const previewKind = previewKindFor(fileType, filename);
11380
11662
  const canPreview = !previewDisabled && previewKind !== null && (!!previewUrl || !!fetchPreviewBlob);
11381
- const [peekOpen, setPeekOpen] = React41.useState(false);
11382
- const [modalOpen, setModalOpen] = React41.useState(false);
11383
- const [source, setSource] = React41.useState(previewUrl ? { url: previewUrl } : null);
11384
- const [pvLoading, setPvLoading] = React41.useState(false);
11385
- const [pvError, setPvError] = React41.useState(null);
11386
- const ensureSource = React41.useCallback(async () => {
11663
+ const [peekOpen, setPeekOpen] = React45.useState(false);
11664
+ const [modalOpen, setModalOpen] = React45.useState(false);
11665
+ const [source, setSource] = React45.useState(previewUrl ? { url: previewUrl } : null);
11666
+ const [pvLoading, setPvLoading] = React45.useState(false);
11667
+ const [pvError, setPvError] = React45.useState(null);
11668
+ const ensureSource = React45.useCallback(async () => {
11387
11669
  if (source) return source;
11388
11670
  if (previewUrl) {
11389
11671
  const s = { url: previewUrl };
@@ -11405,7 +11687,7 @@ function FileCard({
11405
11687
  setPvLoading(false);
11406
11688
  }
11407
11689
  }, [source, previewUrl, fetchPreviewBlob]);
11408
- const togglePeek = React41.useCallback(async () => {
11690
+ const togglePeek = React45.useCallback(async () => {
11409
11691
  if (peekOpen) {
11410
11692
  setPeekOpen(false);
11411
11693
  return;
@@ -11413,7 +11695,7 @@ function FileCard({
11413
11695
  setPeekOpen(true);
11414
11696
  await ensureSource();
11415
11697
  }, [peekOpen, ensureSource]);
11416
- const openModal = React41.useCallback(async () => {
11698
+ const openModal = React45.useCallback(async () => {
11417
11699
  const s = await ensureSource();
11418
11700
  if (s) setModalOpen(true);
11419
11701
  }, [ensureSource]);
@@ -11528,7 +11810,7 @@ function FileCard({
11528
11810
  whiteSpace: "nowrap"
11529
11811
  },
11530
11812
  children: [
11531
- metaTokens.map((t, i) => /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
11813
+ metaTokens.map((t, i) => /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
11532
11814
  i > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#c4c4c4" }, children: "\xB7" }),
11533
11815
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: t })
11534
11816
  ] }, i)),
@@ -11872,7 +12154,7 @@ function ServiceCard({ item, isHovered, onHover, onLeave: onLeave2 }) {
11872
12154
  function OpsDashboardResolver(p) {
11873
12155
  var _a, _b, _c;
11874
12156
  const { BORDER: BORDER4, MUTED: MUTED2 } = useTheme();
11875
- const [hoveredId, setHoveredId] = React41.useState(null);
12157
+ const [hoveredId, setHoveredId] = React45.useState(null);
11876
12158
  const hasRunning = ((_a = p.items) != null ? _a : []).some((item) => item.state === "running");
11877
12159
  return /* @__PURE__ */ jsxRuntime.jsxs(ComponentActions, { filename: (_b = p.title) != null ? _b : "ops-dashboard", children: [
11878
12160
  hasRunning && /* @__PURE__ */ jsxRuntime.jsx("style", { children: PULSE_KEYFRAMES }),
@@ -11925,8 +12207,8 @@ function formatDate3(value) {
11925
12207
  }
11926
12208
  }
11927
12209
  function CopyButton({ value, rowHovered }) {
11928
- const [copied, setCopied] = React41.useState(false);
11929
- const [btnHovered, setBtnHovered] = React41.useState(false);
12210
+ const [copied, setCopied] = React45.useState(false);
12211
+ const [btnHovered, setBtnHovered] = React45.useState(false);
11930
12212
  const handleCopy = () => {
11931
12213
  navigator.clipboard.writeText(value).then(() => {
11932
12214
  setCopied(true);
@@ -12018,7 +12300,7 @@ function ValueCell({ item }) {
12018
12300
  }
12019
12301
  }
12020
12302
  function KVRow({ item, isLast, index }) {
12021
- const [hovered, setHovered] = React41.useState(false);
12303
+ const [hovered, setHovered] = React45.useState(false);
12022
12304
  const altBg = index % 2 === 1 ? "#fcfcfc" : "white";
12023
12305
  return /* @__PURE__ */ jsxRuntime.jsxs(
12024
12306
  "div",
@@ -12103,7 +12385,7 @@ function KeyValueListResolver(p) {
12103
12385
  var _a3;
12104
12386
  return sum + ((_a3 = g.items) != null ? _a3 : []).length;
12105
12387
  }, 0);
12106
- return /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
12388
+ return /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
12107
12389
  /* @__PURE__ */ jsxRuntime.jsxs(
12108
12390
  "div",
12109
12391
  {
@@ -12281,7 +12563,7 @@ function BalanceSheetResolver(p) {
12281
12563
  /* @__PURE__ */ jsxRuntime.jsxs("tbody", { children: [
12282
12564
  ((_p = p.sections) != null ? _p : []).map((section) => {
12283
12565
  var _a2;
12284
- return /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
12566
+ return /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
12285
12567
  /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsx("td", { colSpan, style: {
12286
12568
  padding: "8px 12px",
12287
12569
  fontSize: "12px",
@@ -12294,7 +12576,7 @@ function BalanceSheetResolver(p) {
12294
12576
  }, children: (_a2 = categoryLabels2[section.category]) != null ? _a2 : section.category }) }),
12295
12577
  section.subsections.map((sub, si) => {
12296
12578
  var _a3;
12297
- return /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
12579
+ return /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
12298
12580
  /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsx("td", { colSpan, style: {
12299
12581
  padding: "6px 10px 6px 24px",
12300
12582
  fontSize: "12px",
@@ -12470,7 +12752,7 @@ function IncomeStatementResolver(p) {
12470
12752
  textAlign: "left",
12471
12753
  whiteSpace: "nowrap"
12472
12754
  }, children: "\xA0" }),
12473
- periods.map((period) => /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
12755
+ periods.map((period) => /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
12474
12756
  /* @__PURE__ */ jsxRuntime.jsx("th", { style: {
12475
12757
  fontSize: "11px",
12476
12758
  fontWeight: 500,
@@ -12501,7 +12783,7 @@ function IncomeStatementResolver(p) {
12501
12783
  sections.map((section, si) => {
12502
12784
  var _a2;
12503
12785
  const isSubtotal = section.sectionType === "subtotal";
12504
- return /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
12786
+ return /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
12505
12787
  /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsx("td", { colSpan: colCount, style: {
12506
12788
  padding: "8px 12px",
12507
12789
  fontSize: "12px",
@@ -12532,7 +12814,7 @@ function IncomeStatementResolver(p) {
12532
12814
  var _a4;
12533
12815
  const val = (_a4 = amounts[pi]) != null ? _a4 : 0;
12534
12816
  const isNeg = val < 0;
12535
- return /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
12817
+ return /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
12536
12818
  /* @__PURE__ */ jsxRuntime.jsx("td", { style: {
12537
12819
  padding: "6px 10px",
12538
12820
  fontSize: "13px",
@@ -12567,7 +12849,7 @@ function IncomeStatementResolver(p) {
12567
12849
  var _a2;
12568
12850
  const val = (_a2 = grossProfit[pi]) != null ? _a2 : 0;
12569
12851
  const isNeg = val < 0;
12570
- return /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
12852
+ return /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
12571
12853
  /* @__PURE__ */ jsxRuntime.jsx("td", { style: {
12572
12854
  padding: "8px 10px",
12573
12855
  fontSize: "12px",
@@ -12602,7 +12884,7 @@ function IncomeStatementResolver(p) {
12602
12884
  var _a2;
12603
12885
  const val = (_a2 = operatingIncome[pi]) != null ? _a2 : 0;
12604
12886
  const isNeg = val < 0;
12605
- return /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
12887
+ return /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
12606
12888
  /* @__PURE__ */ jsxRuntime.jsx("td", { style: {
12607
12889
  padding: "8px 10px",
12608
12890
  fontSize: "12px",
@@ -12636,7 +12918,7 @@ function IncomeStatementResolver(p) {
12636
12918
  var _a2;
12637
12919
  const val = (_a2 = netIncome[pi]) != null ? _a2 : 0;
12638
12920
  const isNeg = val < 0;
12639
- return /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
12921
+ return /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
12640
12922
  /* @__PURE__ */ jsxRuntime.jsx("td", { style: {
12641
12923
  padding: "10px 10px",
12642
12924
  fontSize: "13px",
@@ -12856,7 +13138,7 @@ function CashFlowStatementResolver(p) {
12856
13138
  /* @__PURE__ */ jsxRuntime.jsxs("tbody", { children: [
12857
13139
  activities.map((activity, ai) => {
12858
13140
  var _a2, _b2, _c2;
12859
- return /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
13141
+ return /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
12860
13142
  ai > 0 && /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsx(
12861
13143
  "td",
12862
13144
  {
@@ -15269,8 +15551,8 @@ var PRIORITY_STYLES = {
15269
15551
  function EscalationCardResolver(p) {
15270
15552
  var _a, _b, _c, _d;
15271
15553
  const { BORDER: BORDER4, MUTED: MUTED2, ACCENT: ACCENT2, ACCENT_SOFT: ACCENT_SOFT2 } = useTheme();
15272
- const [cardHovered, setCardHovered] = React41.useState(false);
15273
- const [btnHovered, setBtnHovered] = React41.useState(false);
15554
+ const [cardHovered, setCardHovered] = React45.useState(false);
15555
+ const [btnHovered, setBtnHovered] = React45.useState(false);
15274
15556
  const priorityStyle = p.priority ? PRIORITY_STYLES[p.priority] : null;
15275
15557
  const railColor = (_a = priorityStyle == null ? void 0 : priorityStyle.color) != null ? _a : ACCENT2;
15276
15558
  const iconBg = (_b = priorityStyle == null ? void 0 : priorityStyle.bg) != null ? _b : "#fff2ec";
@@ -16117,9 +16399,9 @@ var CONNECTED_GREEN = "#15803d";
16117
16399
  function ConnectIntegrationResolver(p) {
16118
16400
  var _a;
16119
16401
  const { BORDER: BORDER4, MUTED: MUTED2, ACCENT: ACCENT2, ACCENT_SOFT: ACCENT_SOFT2 } = useTheme();
16120
- const [cardHovered, setCardHovered] = React41.useState(false);
16121
- const [btnHovered, setBtnHovered] = React41.useState(false);
16122
- const [imgFailed, setImgFailed] = React41.useState(false);
16402
+ const [cardHovered, setCardHovered] = React45.useState(false);
16403
+ const [btnHovered, setBtnHovered] = React45.useState(false);
16404
+ const [imgFailed, setImgFailed] = React45.useState(false);
16123
16405
  const name = (p.integrationName || "Integration").trim();
16124
16406
  const initial = name.charAt(0).toUpperCase();
16125
16407
  const iconSrc = p.iconUrl || brandIconUrl(name);
@@ -16281,9 +16563,9 @@ function IntegrationsListResolver(p) {
16281
16563
  var _a, _b;
16282
16564
  const { BORDER: BORDER4, MUTED: MUTED2, PAPER: PAPER2, ACCENT: ACCENT2, ACCENT_SOFT: ACCENT_SOFT2 } = useTheme();
16283
16565
  const integrations = Array.isArray(p.integrations) ? p.integrations : [];
16284
- const [rowHover, setRowHover] = React41.useState(null);
16285
- const [btnHover, setBtnHover] = React41.useState(null);
16286
- const [failed, setFailed] = React41.useState({});
16566
+ const [rowHover, setRowHover] = React45.useState(null);
16567
+ const [btnHover, setBtnHover] = React45.useState(null);
16568
+ const [failed, setFailed] = React45.useState({});
16287
16569
  const connectedCount = integrations.filter((i) => i.status === "connected").length;
16288
16570
  return /* @__PURE__ */ jsxRuntime.jsx(ComponentActions, { filename: (_a = p.title) != null ? _a : "integrations", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { width: "100%", display: "flex", flexDirection: "column", gap: "11px" }, children: [
16289
16571
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "2px" }, children: [
@@ -16766,13 +17048,13 @@ var ellipsis = {
16766
17048
  function PipelinePreviewResolver(p) {
16767
17049
  var _a, _b, _c, _d, _e, _f, _g;
16768
17050
  const { MUTED: MUTED2, PAPER: PAPER2, BORDER: BORDER4, ACCENT: ACCENT2, ACCENT_SOFT: ACCENT_SOFT2 } = useTheme();
16769
- const [btnHovered, setBtnHovered] = React41.useState(false);
17051
+ const [btnHovered, setBtnHovered] = React45.useState(false);
16770
17052
  const stateCfg = STATE_CONFIG[(_a = p.state) != null ? _a : "draft"];
16771
17053
  const destinations = (_b = p.destinations) != null ? _b : [];
16772
17054
  const steps = (_c = p.steps) != null ? _c : [];
16773
17055
  const workstreams = (_d = p.workstreams) != null ? _d : [];
16774
17056
  const scheduleLabel = p.schedule ? p.schedule.type === "manual" ? "Manual" : (_f = (_e = p.schedule.label) != null ? _e : p.schedule.cron) != null ? _f : "Scheduled" : null;
16775
- const { nodes, edges, viewBox, vbW, vbH } = React41.useMemo(() => {
17057
+ const { nodes, edges, viewBox, vbW, vbH } = React45.useMemo(() => {
16776
17058
  const res = layoutGraph(steps);
16777
17059
  const b = layoutBounds(res.nodes);
16778
17060
  const pad = 24;
@@ -16786,7 +17068,7 @@ function PipelinePreviewResolver(p) {
16786
17068
  vbH: h
16787
17069
  };
16788
17070
  }, [steps]);
16789
- const nodeMap = React41.useMemo(() => {
17071
+ const nodeMap = React45.useMemo(() => {
16790
17072
  const m = {};
16791
17073
  nodes.forEach((n) => m[n.id] = n);
16792
17074
  return m;
@@ -17157,11 +17439,14 @@ function PipelinePreviewResolver(p) {
17157
17439
  init_ThemeContext();
17158
17440
  var DEFAULT_INTERACTION = {
17159
17441
  selectedStepId: null,
17160
- onStepSelect: void 0
17442
+ onStepSelect: void 0,
17443
+ resolvedDecisions: void 0,
17444
+ onDecisionResolve: void 0,
17445
+ onDecisionSource: void 0
17161
17446
  };
17162
- var GenUIInteractionContext = React41.createContext(DEFAULT_INTERACTION);
17447
+ var GenUIInteractionContext = React45.createContext(DEFAULT_INTERACTION);
17163
17448
  function useGenUIInteraction() {
17164
- return React41.useContext(GenUIInteractionContext);
17449
+ return React45.useContext(GenUIInteractionContext);
17165
17450
  }
17166
17451
  var STATUS_COLORS3 = {
17167
17452
  done: "#15803d",
@@ -17290,8 +17575,8 @@ var CARD_MIN = 132;
17290
17575
  var CARD_GAP = 16;
17291
17576
  var AUTO_COMPACT_BELOW = 360;
17292
17577
  function useContainerWidth(ref) {
17293
- const [w, setW] = React41__default.default.useState(0);
17294
- React41__default.default.useLayoutEffect(() => {
17578
+ const [w, setW] = React45__default.default.useState(0);
17579
+ React45__default.default.useLayoutEffect(() => {
17295
17580
  const el = ref.current;
17296
17581
  if (!el || typeof ResizeObserver === "undefined") return;
17297
17582
  const ro = new ResizeObserver((entries) => {
@@ -17392,15 +17677,15 @@ function WorkflowStepperRenderer({
17392
17677
  const interactive = typeof onSelectStep === "function";
17393
17678
  const statusColor3 = (s) => s === "active" ? ACCENT2 : STATUS_COLORS3[s];
17394
17679
  const doneCount = steps.filter((s) => s.status === "done").length;
17395
- const rootRef = React41__default.default.useRef(null);
17680
+ const rootRef = React45__default.default.useRef(null);
17396
17681
  const containerW = useContainerWidth(rootRef);
17397
17682
  let resolved = density === "auto" ? "full" : density;
17398
17683
  if (density === "auto" && containerW > 0) {
17399
17684
  const needed = steps.length * CARD_MIN + Math.max(0, steps.length - 1) * CARD_GAP;
17400
17685
  resolved = containerW < AUTO_COMPACT_BELOW || needed > containerW * 1.6 ? "compact" : "full";
17401
17686
  }
17402
- const scrollerRef = React41__default.default.useRef(null);
17403
- React41__default.default.useEffect(() => {
17687
+ const scrollerRef = React45__default.default.useRef(null);
17688
+ React45__default.default.useEffect(() => {
17404
17689
  if (resolved !== "full" || loading) return;
17405
17690
  const sc = scrollerRef.current;
17406
17691
  if (!sc) return;
@@ -17411,11 +17696,11 @@ function WorkflowStepperRenderer({
17411
17696
  el.scrollIntoView({ inline: "center", block: "nearest", behavior: "smooth" });
17412
17697
  }
17413
17698
  }, [resolved, loading, selectedStep, activeStepId]);
17414
- const [edges, setEdges] = React41__default.default.useState({
17699
+ const [edges, setEdges] = React45__default.default.useState({
17415
17700
  left: false,
17416
17701
  right: false
17417
17702
  });
17418
- const updateEdges = React41__default.default.useCallback(() => {
17703
+ const updateEdges = React45__default.default.useCallback(() => {
17419
17704
  const sc = scrollerRef.current;
17420
17705
  if (!sc) return;
17421
17706
  const max = sc.scrollWidth - sc.clientWidth;
@@ -17424,7 +17709,7 @@ function WorkflowStepperRenderer({
17424
17709
  const right = sl < max - 1;
17425
17710
  setEdges((prev) => prev.left === left && prev.right === right ? prev : { left, right });
17426
17711
  }, []);
17427
- React41__default.default.useLayoutEffect(() => {
17712
+ React45__default.default.useLayoutEffect(() => {
17428
17713
  if (resolved !== "full" || loading) return;
17429
17714
  updateEdges();
17430
17715
  const sc = scrollerRef.current;
@@ -17480,7 +17765,7 @@ function WorkflowStepperRenderer({
17480
17765
  const reached = s.status !== "pending";
17481
17766
  const clickable = interactive && reached;
17482
17767
  const size = act ? 11 : done ? 9 : 8;
17483
- return /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
17768
+ return /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
17484
17769
  i > 0 && /* @__PURE__ */ jsxRuntime.jsx(
17485
17770
  "span",
17486
17771
  {
@@ -17623,7 +17908,7 @@ function WorkflowStepperRenderer({
17623
17908
  const color = statusColor3(step.status);
17624
17909
  const humans = ((_a2 = step.assignees) != null ? _a2 : []).filter((a) => a.kind === "human");
17625
17910
  const roleCaption = humans.map((h) => h.role).filter(Boolean).slice(0, 2).join(" \xB7 ");
17626
- return /* @__PURE__ */ jsxRuntime.jsxs(React41__default.default.Fragment, { children: [
17911
+ return /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
17627
17912
  i > 0 && /* @__PURE__ */ jsxRuntime.jsx(
17628
17913
  "div",
17629
17914
  {
@@ -17876,6 +18161,1949 @@ function WorkflowStepperResolver(p) {
17876
18161
  )
17877
18162
  ] }) });
17878
18163
  }
18164
+ init_ThemeContext();
18165
+
18166
+ // src/composites/document-field-extraction/bboxTransform.ts
18167
+ function bboxToRect(bbox2, page, px) {
18168
+ if (!bbox2 || bbox2.length !== 4) return null;
18169
+ const { wPts, hPts } = page;
18170
+ const { wPx, hPx } = px;
18171
+ if (!wPts || !hPts || !wPx || !hPx) return null;
18172
+ const [x0, y0, x1, y1] = bbox2;
18173
+ const sx = wPx / wPts;
18174
+ const sy = hPx / hPts;
18175
+ return {
18176
+ left: x0 * sx,
18177
+ width: (x1 - x0) * sx,
18178
+ // Flip Y: the box's TOP in screen space is the page height minus its upper
18179
+ // PDF-point edge (y1), because PDF y grows upward from the bottom.
18180
+ top: (hPts - y1) * sy,
18181
+ height: (y1 - y0) * sy
18182
+ };
18183
+ }
18184
+
18185
+ // src/composites/document-field-extraction/FieldDetail.tsx
18186
+ init_ThemeContext();
18187
+
18188
+ // src/composites/document-field-extraction/fieldLabels.ts
18189
+ var LABEL_DISPLAY = {
18190
+ "employer identification number": "Employer ID (EIN)",
18191
+ "company or business name": "Company Name",
18192
+ "total revenue": "Total Revenue",
18193
+ "net income": "Net Income",
18194
+ "tax year": "Tax Year",
18195
+ "invoice number": "Invoice Number",
18196
+ "invoice date": "Invoice Date",
18197
+ "total amount due": "Total Amount Due",
18198
+ "vendor name": "Vendor Name",
18199
+ "receipt total": "Receipt Total",
18200
+ "transaction date": "Transaction Date",
18201
+ "merchant name": "Merchant Name"
18202
+ };
18203
+ function prettyLabel(label) {
18204
+ var _a;
18205
+ return (_a = LABEL_DISPLAY[label]) != null ? _a : label.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
18206
+ }
18207
+ var TIER_COLORS = {
18208
+ green: "#15803d",
18209
+ amber: "#f59e0b",
18210
+ red: "#dc2626"
18211
+ };
18212
+ var BADGE_TITLE = {
18213
+ SC: "High confidence",
18214
+ CN: "Medium confidence",
18215
+ AB: "Low confidence",
18216
+ SW: "Very low confidence"
18217
+ };
18218
+ var BADGE_STYLE = {
18219
+ SC: { bg: "#dcfce7", fg: "#15803d" },
18220
+ CN: { bg: "#eff6ff", fg: "#0364ff" },
18221
+ AB: { bg: "#fff7ed", fg: "#92400e" },
18222
+ SW: { bg: "#fef2f2", fg: "#dc2626" }
18223
+ };
18224
+ var STATE_DOT = {
18225
+ ok: "#15803d",
18226
+ corrected: "#0364ff",
18227
+ missing: "#dc2626",
18228
+ warn: "#f59e0b"
18229
+ };
18230
+ function hexToRgba(hex, alpha) {
18231
+ const h = hex.replace("#", "");
18232
+ const r = parseInt(h.slice(0, 2), 16);
18233
+ const g = parseInt(h.slice(2, 4), 16);
18234
+ const b = parseInt(h.slice(4, 6), 16);
18235
+ return `rgba(${r}, ${g}, ${b}, ${alpha})`;
18236
+ }
18237
+ function badgeStyle(f) {
18238
+ var _a, _b;
18239
+ return (_b = BADGE_STYLE[(_a = f.badge) != null ? _a : ""]) != null ? _b : { bg: "#f6f6f6", fg: "#777777" };
18240
+ }
18241
+ function dotColor2(f) {
18242
+ var _a, _b;
18243
+ return (_b = STATE_DOT[(_a = f.state) != null ? _a : "ok"]) != null ? _b : "#15803d";
18244
+ }
18245
+ function fieldColor(f, secondary) {
18246
+ var _a, _b;
18247
+ if (f.state === "corrected") return secondary;
18248
+ return (_b = TIER_COLORS[(_a = f.confidence_tier) != null ? _a : "amber"]) != null ? _b : TIER_COLORS.amber;
18249
+ }
18250
+ function confidenceLabel(f) {
18251
+ var _a;
18252
+ if (typeof f.confidence === "number" && !Number.isNaN(f.confidence)) {
18253
+ return `${Math.round(f.confidence * 100)}%`;
18254
+ }
18255
+ return (_a = f.badge) != null ? _a : "\u2014";
18256
+ }
18257
+ function FieldDetail({
18258
+ field,
18259
+ selected,
18260
+ onSelect,
18261
+ onSave,
18262
+ correctionCount = 0,
18263
+ cardRef
18264
+ }) {
18265
+ var _a, _b, _c, _d;
18266
+ const { BORDER: BORDER4, MUTED: MUTED2, PAPER: PAPER2, SECONDARY: SECONDARY2 } = useTheme();
18267
+ const [editing, setEditing] = React45__default.default.useState(false);
18268
+ const [draft, setDraft] = React45__default.default.useState("");
18269
+ const [saving, setSaving] = React45__default.default.useState(false);
18270
+ const [saveError, setSaveError] = React45__default.default.useState(null);
18271
+ const textareaRef = React45__default.default.useRef(null);
18272
+ const color = fieldColor(field, SECONDARY2);
18273
+ const corrected = field.state === "corrected";
18274
+ const startEdit = (e) => {
18275
+ e.stopPropagation();
18276
+ setDraft(field.value || "");
18277
+ setSaveError(null);
18278
+ setEditing(true);
18279
+ setTimeout(() => {
18280
+ var _a2, _b2;
18281
+ (_a2 = textareaRef.current) == null ? void 0 : _a2.focus();
18282
+ (_b2 = textareaRef.current) == null ? void 0 : _b2.select();
18283
+ }, 0);
18284
+ };
18285
+ const cancelEdit = (e) => {
18286
+ e.stopPropagation();
18287
+ setEditing(false);
18288
+ setSaveError(null);
18289
+ };
18290
+ const save = async (e) => {
18291
+ var _a2, _b2;
18292
+ e.stopPropagation();
18293
+ if (!onSave || draft === field.value) {
18294
+ setEditing(false);
18295
+ return;
18296
+ }
18297
+ setSaving(true);
18298
+ setSaveError(null);
18299
+ try {
18300
+ await onSave(field.field_key, draft);
18301
+ setEditing(false);
18302
+ } catch (err) {
18303
+ const msg = ((_b2 = (_a2 = err == null ? void 0 : err.response) == null ? void 0 : _a2.data) == null ? void 0 : _b2.detail) || "Save failed. Try again.";
18304
+ setSaveError(msg);
18305
+ } finally {
18306
+ setSaving(false);
18307
+ }
18308
+ };
18309
+ const handleKeyDown = (e) => {
18310
+ if (e.key === "Escape") cancelEdit(e);
18311
+ if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) void save(e);
18312
+ };
18313
+ return /* @__PURE__ */ jsxRuntime.jsxs(
18314
+ "div",
18315
+ {
18316
+ ref: cardRef,
18317
+ "data-testid": "field-card",
18318
+ "data-field-key": field.field_key,
18319
+ "data-selected": selected ? "true" : "false",
18320
+ role: "button",
18321
+ tabIndex: 0,
18322
+ onClick: () => !editing && onSelect(selected ? null : field.field_key),
18323
+ onKeyDown: (e) => {
18324
+ if (!editing && e.key === "Enter") onSelect(selected ? null : field.field_key);
18325
+ },
18326
+ style: {
18327
+ display: "flex",
18328
+ flexDirection: "column",
18329
+ gap: "4px",
18330
+ padding: "8px 10px",
18331
+ borderRadius: "0.5rem",
18332
+ border: `1px solid ${selected ? color : BORDER4}`,
18333
+ background: selected ? hexToRgba(color, 0.06) : "white",
18334
+ cursor: editing ? "default" : "pointer",
18335
+ transition: "background 0.15s, border-color 0.15s"
18336
+ },
18337
+ children: [
18338
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "8px", minWidth: 0 }, children: [
18339
+ /* @__PURE__ */ jsxRuntime.jsx(
18340
+ "span",
18341
+ {
18342
+ title: (_c = (_b = BADGE_TITLE[(_a = field.badge) != null ? _a : ""]) != null ? _b : field.badge) != null ? _c : "",
18343
+ style: {
18344
+ fontSize: "10px",
18345
+ fontWeight: 700,
18346
+ padding: "2px 6px",
18347
+ borderRadius: "4px",
18348
+ flexShrink: 0,
18349
+ letterSpacing: "0.02em",
18350
+ minWidth: "34px",
18351
+ textAlign: "center",
18352
+ fontVariantNumeric: "tabular-nums",
18353
+ background: badgeStyle(field).bg,
18354
+ color: badgeStyle(field).fg
18355
+ },
18356
+ children: confidenceLabel(field)
18357
+ }
18358
+ ),
18359
+ /* @__PURE__ */ jsxRuntime.jsx(
18360
+ "span",
18361
+ {
18362
+ title: prettyLabel(field.label),
18363
+ style: {
18364
+ fontSize: "12.5px",
18365
+ fontWeight: 600,
18366
+ color: "var(--foreground)",
18367
+ flex: 1,
18368
+ minWidth: 0,
18369
+ whiteSpace: "nowrap",
18370
+ overflow: "hidden",
18371
+ textOverflow: "ellipsis"
18372
+ },
18373
+ children: prettyLabel(field.label)
18374
+ }
18375
+ ),
18376
+ field.is_primary && /* @__PURE__ */ jsxRuntime.jsx(
18377
+ "span",
18378
+ {
18379
+ style: {
18380
+ fontSize: "9px",
18381
+ fontWeight: 600,
18382
+ textTransform: "uppercase",
18383
+ letterSpacing: "0.04em",
18384
+ color: MUTED2,
18385
+ flexShrink: 0
18386
+ },
18387
+ children: "Primary"
18388
+ }
18389
+ ),
18390
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { fontSize: "11px", color: MUTED2, flexShrink: 0 }, children: [
18391
+ "p.",
18392
+ field.page + 1
18393
+ ] }),
18394
+ !editing && onSave && /* @__PURE__ */ jsxRuntime.jsx(
18395
+ "button",
18396
+ {
18397
+ type: "button",
18398
+ onClick: startEdit,
18399
+ title: "Edit value",
18400
+ "aria-label": "Edit value",
18401
+ style: {
18402
+ border: `1px solid ${BORDER4}`,
18403
+ borderRadius: "6px",
18404
+ background: "white",
18405
+ cursor: "pointer",
18406
+ padding: "3px 5px",
18407
+ lineHeight: 1,
18408
+ flexShrink: 0,
18409
+ display: "inline-flex",
18410
+ alignItems: "center",
18411
+ justifyContent: "center"
18412
+ },
18413
+ 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: [
18414
+ /* @__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" }),
18415
+ /* @__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" })
18416
+ ] })
18417
+ }
18418
+ )
18419
+ ] }),
18420
+ editing ? /* @__PURE__ */ jsxRuntime.jsxs("div", { onClick: (e) => e.stopPropagation(), style: { display: "flex", flexDirection: "column", gap: "5px" }, children: [
18421
+ /* @__PURE__ */ jsxRuntime.jsx(
18422
+ "textarea",
18423
+ {
18424
+ ref: textareaRef,
18425
+ value: draft,
18426
+ onChange: (e) => setDraft(e.target.value),
18427
+ onKeyDown: handleKeyDown,
18428
+ rows: 3,
18429
+ placeholder: "Enter value\u2026",
18430
+ style: {
18431
+ width: "100%",
18432
+ boxSizing: "border-box",
18433
+ resize: "vertical",
18434
+ fontSize: "13px",
18435
+ fontFamily: "var(--font-sans)",
18436
+ color: "var(--foreground)",
18437
+ padding: "6px 8px",
18438
+ borderRadius: "0.4rem",
18439
+ border: `1px solid ${BORDER4}`
18440
+ }
18441
+ }
18442
+ ),
18443
+ saveError && /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "11px", color: TIER_COLORS.red }, children: saveError }),
18444
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", gap: "6px" }, children: [
18445
+ /* @__PURE__ */ jsxRuntime.jsx(
18446
+ "button",
18447
+ {
18448
+ type: "button",
18449
+ onClick: save,
18450
+ disabled: saving,
18451
+ title: "Save (\u2318\u21B5)",
18452
+ style: {
18453
+ display: "inline-flex",
18454
+ alignItems: "center",
18455
+ gap: "4px",
18456
+ fontSize: "11px",
18457
+ fontWeight: 600,
18458
+ padding: "4px 10px",
18459
+ borderRadius: "0.4rem",
18460
+ border: "none",
18461
+ background: "var(--foreground)",
18462
+ color: "white",
18463
+ cursor: saving ? "default" : "pointer",
18464
+ opacity: saving ? 0.7 : 1
18465
+ },
18466
+ children: saving ? "Saving\u2026" : "Save"
18467
+ }
18468
+ ),
18469
+ /* @__PURE__ */ jsxRuntime.jsx(
18470
+ "button",
18471
+ {
18472
+ type: "button",
18473
+ onClick: cancelEdit,
18474
+ disabled: saving,
18475
+ title: "Cancel (Esc)",
18476
+ style: {
18477
+ fontSize: "11px",
18478
+ fontWeight: 600,
18479
+ padding: "4px 10px",
18480
+ borderRadius: "0.4rem",
18481
+ border: `1px solid ${BORDER4}`,
18482
+ background: "white",
18483
+ color: MUTED2,
18484
+ cursor: saving ? "default" : "pointer"
18485
+ },
18486
+ children: "Cancel"
18487
+ }
18488
+ )
18489
+ ] })
18490
+ ] }) : corrected ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "2px", paddingLeft: "2px" }, children: [
18491
+ field.previous_value != null && field.previous_value !== "" && /* @__PURE__ */ jsxRuntime.jsx(
18492
+ "span",
18493
+ {
18494
+ style: {
18495
+ fontSize: "11.5px",
18496
+ color: MUTED2,
18497
+ textDecoration: "line-through",
18498
+ fontFamily: "ui-monospace, 'Cascadia Code', monospace",
18499
+ wordBreak: "break-word"
18500
+ },
18501
+ children: field.previous_value
18502
+ }
18503
+ ),
18504
+ /* @__PURE__ */ jsxRuntime.jsx(
18505
+ "span",
18506
+ {
18507
+ style: {
18508
+ fontSize: "12.5px",
18509
+ fontWeight: 600,
18510
+ color: "var(--foreground)",
18511
+ fontFamily: "ui-monospace, 'Cascadia Code', monospace",
18512
+ wordBreak: "break-word"
18513
+ },
18514
+ children: field.value || "\u2014"
18515
+ }
18516
+ ),
18517
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "6px", flexWrap: "wrap" }, children: [
18518
+ field.corrected_by && /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "11px", color: SECONDARY2 }, title: `Corrected by ${field.corrected_by}`, children: field.corrected_by }),
18519
+ correctionCount > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
18520
+ "span",
18521
+ {
18522
+ style: {
18523
+ fontSize: "10.5px",
18524
+ fontWeight: 600,
18525
+ color: MUTED2,
18526
+ background: PAPER2,
18527
+ borderRadius: "9999px",
18528
+ padding: "1px 7px"
18529
+ },
18530
+ children: [
18531
+ correctionCount,
18532
+ " ",
18533
+ correctionCount === 1 ? "event" : "events"
18534
+ ]
18535
+ }
18536
+ )
18537
+ ] })
18538
+ ] }) : (
18539
+ // Bottom row: monospace value + right-edge validation dot (file explorer).
18540
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "8px", paddingLeft: "2px" }, children: [
18541
+ /* @__PURE__ */ jsxRuntime.jsx(
18542
+ "span",
18543
+ {
18544
+ style: {
18545
+ fontSize: "12.5px",
18546
+ color: MUTED2,
18547
+ fontFamily: "ui-monospace, 'Cascadia Code', monospace",
18548
+ flex: 1,
18549
+ minWidth: 0,
18550
+ whiteSpace: "nowrap",
18551
+ overflow: "hidden",
18552
+ textOverflow: "ellipsis"
18553
+ },
18554
+ title: field.value || "\u2014",
18555
+ children: field.value || "\u2014"
18556
+ }
18557
+ ),
18558
+ /* @__PURE__ */ jsxRuntime.jsx(
18559
+ "span",
18560
+ {
18561
+ title: (_d = field.state) != null ? _d : "ok",
18562
+ style: {
18563
+ width: "8px",
18564
+ height: "8px",
18565
+ borderRadius: "9999px",
18566
+ flexShrink: 0,
18567
+ background: dotColor2(field)
18568
+ }
18569
+ }
18570
+ )
18571
+ ] })
18572
+ )
18573
+ ]
18574
+ }
18575
+ );
18576
+ }
18577
+
18578
+ // src/composites/document-field-extraction/FieldDetails.tsx
18579
+ init_ThemeContext();
18580
+ var BADGE_DOT = {
18581
+ // gen-ui semantic dot colors
18582
+ ok: "#15803d",
18583
+ green: "#15803d",
18584
+ warn: "#f59e0b",
18585
+ amber: "#f59e0b",
18586
+ missing: "#dc2626",
18587
+ red: "#dc2626",
18588
+ corrected: "#0364ff"
18589
+ };
18590
+ function FieldDetails({
18591
+ summary,
18592
+ fileName,
18593
+ pageCount,
18594
+ pagesProcessed
18595
+ }) {
18596
+ var _a, _b, _c, _d, _e, _f;
18597
+ const { BORDER: BORDER4, MUTED: MUTED2, PAPER: PAPER2, SECONDARY: SECONDARY2 } = useTheme();
18598
+ if (!summary) {
18599
+ return /* @__PURE__ */ jsxRuntime.jsxs(
18600
+ "div",
18601
+ {
18602
+ style: {
18603
+ height: "100%",
18604
+ display: "flex",
18605
+ flexDirection: "column",
18606
+ alignItems: "center",
18607
+ justifyContent: "center",
18608
+ gap: "6px",
18609
+ color: MUTED2,
18610
+ textAlign: "center",
18611
+ padding: "24px"
18612
+ },
18613
+ children: [
18614
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "26px", lineHeight: 1 }, children: "\u{1F4C4}" }),
18615
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0, fontSize: "14px", fontWeight: 600, color: "var(--foreground)" }, children: "No summary yet" }),
18616
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0, fontSize: "12px", maxWidth: "280px" }, children: "This document has no extracted summary." })
18617
+ ]
18618
+ }
18619
+ );
18620
+ }
18621
+ const header = buildHeader(summary);
18622
+ const crumb = buildCrumbLine(summary);
18623
+ const facts = buildFacts(summary, fileName, pageCount, pagesProcessed);
18624
+ 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: [
18625
+ /* @__PURE__ */ jsxRuntime.jsxs("header", { style: { display: "flex", flexDirection: "column", gap: "3px" }, children: [
18626
+ /* @__PURE__ */ jsxRuntime.jsx(
18627
+ "h2",
18628
+ {
18629
+ title: header.title,
18630
+ style: {
18631
+ margin: 0,
18632
+ fontFamily: "var(--font-serif)",
18633
+ fontSize: "20px",
18634
+ fontWeight: 400,
18635
+ letterSpacing: "-0.01em",
18636
+ color: "var(--foreground)",
18637
+ overflow: "hidden",
18638
+ textOverflow: "ellipsis",
18639
+ whiteSpace: "nowrap"
18640
+ },
18641
+ children: header.title
18642
+ }
18643
+ ),
18644
+ header.subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0, fontSize: "12px", color: MUTED2 }, children: header.subtitle })
18645
+ ] }),
18646
+ (summary.domain || summary.display_name || summary.domain_group || ((_b = (_a = summary.tags) == null ? void 0 : _a.length) != null ? _b : 0) > 0) && /* @__PURE__ */ jsxRuntime.jsxs(
18647
+ "section",
18648
+ {
18649
+ style: {
18650
+ display: "flex",
18651
+ flexDirection: "column",
18652
+ gap: "6px",
18653
+ padding: "12px 14px",
18654
+ borderRadius: "0.75rem",
18655
+ border: `1px solid ${BORDER4}`,
18656
+ background: PAPER2
18657
+ },
18658
+ children: [
18659
+ summary.domain_group && /* @__PURE__ */ jsxRuntime.jsx(
18660
+ "span",
18661
+ {
18662
+ style: {
18663
+ fontSize: "10px",
18664
+ fontWeight: 600,
18665
+ textTransform: "uppercase",
18666
+ letterSpacing: "0.06em",
18667
+ color: MUTED2
18668
+ },
18669
+ children: summary.domain_group
18670
+ }
18671
+ ),
18672
+ /* @__PURE__ */ jsxRuntime.jsx(
18673
+ "h3",
18674
+ {
18675
+ style: {
18676
+ margin: 0,
18677
+ fontSize: "14px",
18678
+ fontWeight: 600,
18679
+ color: "var(--foreground)"
18680
+ },
18681
+ children: summary.domain || summary.display_name
18682
+ }
18683
+ ),
18684
+ crumb && /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0, fontSize: "12px", color: MUTED2 }, children: crumb }),
18685
+ ((_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(
18686
+ "span",
18687
+ {
18688
+ style: {
18689
+ fontSize: "10px",
18690
+ fontWeight: 600,
18691
+ padding: "2px 8px",
18692
+ borderRadius: "9999px",
18693
+ background: "white",
18694
+ border: `1px solid ${BORDER4}`,
18695
+ color: MUTED2
18696
+ },
18697
+ children: t
18698
+ },
18699
+ t
18700
+ )) })
18701
+ ]
18702
+ }
18703
+ ),
18704
+ ((_f = (_e = summary.stats) == null ? void 0 : _e.length) != null ? _f : 0) > 0 && /* @__PURE__ */ jsxRuntime.jsx(
18705
+ "div",
18706
+ {
18707
+ style: {
18708
+ display: "grid",
18709
+ gridTemplateColumns: "repeat(auto-fit, minmax(130px, 1fr))",
18710
+ gap: "8px"
18711
+ },
18712
+ children: summary.stats.map((s) => /* @__PURE__ */ jsxRuntime.jsxs(
18713
+ "div",
18714
+ {
18715
+ style: {
18716
+ display: "flex",
18717
+ flexDirection: "column",
18718
+ gap: "2px",
18719
+ padding: "10px 12px",
18720
+ borderRadius: "0.6rem",
18721
+ border: `1px solid ${BORDER4}`,
18722
+ background: "white"
18723
+ },
18724
+ children: [
18725
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "11px", color: MUTED2 }, children: s.label }),
18726
+ /* @__PURE__ */ jsxRuntime.jsx(
18727
+ "span",
18728
+ {
18729
+ title: s.value,
18730
+ style: {
18731
+ fontSize: "15px",
18732
+ fontWeight: 600,
18733
+ color: "var(--foreground)",
18734
+ overflow: "hidden",
18735
+ textOverflow: "ellipsis",
18736
+ whiteSpace: "nowrap"
18737
+ },
18738
+ children: s.value
18739
+ }
18740
+ ),
18741
+ s.caption && /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "10px", color: MUTED2 }, children: s.caption })
18742
+ ]
18743
+ },
18744
+ s.field_key
18745
+ ))
18746
+ }
18747
+ ),
18748
+ facts.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("section", { style: { display: "flex", flexDirection: "column", gap: "6px" }, children: [
18749
+ /* @__PURE__ */ jsxRuntime.jsxs(
18750
+ "div",
18751
+ {
18752
+ style: {
18753
+ display: "flex",
18754
+ alignItems: "center",
18755
+ gap: "6px",
18756
+ fontSize: "11px",
18757
+ fontWeight: 600,
18758
+ textTransform: "uppercase",
18759
+ letterSpacing: "0.04em",
18760
+ color: MUTED2
18761
+ },
18762
+ children: [
18763
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "\u25A4" }),
18764
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Document details" })
18765
+ ]
18766
+ }
18767
+ ),
18768
+ /* @__PURE__ */ jsxRuntime.jsx(
18769
+ "dl",
18770
+ {
18771
+ style: {
18772
+ margin: 0,
18773
+ display: "grid",
18774
+ gridTemplateColumns: "minmax(110px, auto) 1fr",
18775
+ rowGap: "6px",
18776
+ columnGap: "14px"
18777
+ },
18778
+ children: facts.map((f) => {
18779
+ var _a2;
18780
+ return /* @__PURE__ */ jsxRuntime.jsxs(React45__default.default.Fragment, { children: [
18781
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { style: { fontSize: "12px", color: MUTED2 }, children: f.label }),
18782
+ /* @__PURE__ */ jsxRuntime.jsxs(
18783
+ "dd",
18784
+ {
18785
+ title: typeof f.value === "string" ? f.value : void 0,
18786
+ style: {
18787
+ margin: 0,
18788
+ fontSize: "12px",
18789
+ color: "var(--foreground)",
18790
+ display: "flex",
18791
+ alignItems: "center",
18792
+ gap: "6px",
18793
+ wordBreak: "break-word"
18794
+ },
18795
+ children: [
18796
+ f.badge && /* @__PURE__ */ jsxRuntime.jsx(
18797
+ "span",
18798
+ {
18799
+ style: {
18800
+ width: "7px",
18801
+ height: "7px",
18802
+ borderRadius: "9999px",
18803
+ flexShrink: 0,
18804
+ background: (_a2 = BADGE_DOT[f.badge]) != null ? _a2 : SECONDARY2
18805
+ }
18806
+ }
18807
+ ),
18808
+ f.value
18809
+ ]
18810
+ }
18811
+ )
18812
+ ] }, f.key);
18813
+ })
18814
+ }
18815
+ )
18816
+ ] })
18817
+ ] }) });
18818
+ }
18819
+ function buildHeader(summary) {
18820
+ const form = [summary.short_name, summary.display_name].filter(Boolean);
18821
+ const title = summary.organization || form.shift() || summary.domain || "Document";
18822
+ const parts = summary.organization ? [...form] : form;
18823
+ if (summary.tax_year) parts.push(`TY ${summary.tax_year}`);
18824
+ return { title, subtitle: parts.join(" \xB7 ") };
18825
+ }
18826
+ function buildCrumbLine(summary) {
18827
+ const parts = [...summary.crumbs || [], summary.short_name].filter(Boolean);
18828
+ if (parts.length > 0) return parts.join(" \xB7 ");
18829
+ return summary.domain && summary.display_name ? summary.display_name : "";
18830
+ }
18831
+ function buildFacts(summary, fileName, pageCount, pagesProcessed) {
18832
+ const rows = [];
18833
+ if (fileName) rows.push({ key: "file", label: "File", value: fileName });
18834
+ if (summary.display_name) {
18835
+ rows.push({ key: "doctype", label: "Document type", value: summary.display_name });
18836
+ }
18837
+ if (summary.tax_year != null && summary.tax_year !== "") {
18838
+ rows.push({ key: "year", label: "Tax year", value: String(summary.tax_year) });
18839
+ }
18840
+ for (const f of summary.facts || []) {
18841
+ rows.push({ key: f.field_key, label: f.label, value: f.value, badge: f.badge });
18842
+ }
18843
+ if (pageCount) {
18844
+ rows.push({
18845
+ key: "pages",
18846
+ label: "Pages processed",
18847
+ value: `${pagesProcessed != null ? pagesProcessed : pageCount} / ${pageCount}`
18848
+ });
18849
+ }
18850
+ return rows;
18851
+ }
18852
+
18853
+ // src/composites/document-field-extraction/FieldAuditLog.tsx
18854
+ init_ThemeContext();
18855
+ function initials(name) {
18856
+ return name.trim().split(/\s+/).slice(0, 2).map((w) => {
18857
+ var _a;
18858
+ return ((_a = w[0]) != null ? _a : "").toUpperCase();
18859
+ }).join("");
18860
+ }
18861
+ function formatTs(ts) {
18862
+ if (!ts) return "\u2014";
18863
+ const d = new Date(ts);
18864
+ if (Number.isNaN(d.getTime())) return ts;
18865
+ return d.toLocaleString(void 0, {
18866
+ month: "short",
18867
+ day: "numeric",
18868
+ hour: "2-digit",
18869
+ minute: "2-digit"
18870
+ });
18871
+ }
18872
+ function FieldAuditLog({
18873
+ events = [],
18874
+ loading = false,
18875
+ fields = []
18876
+ }) {
18877
+ const { BORDER: BORDER4, MUTED: MUTED2, PAPER: PAPER2, SECONDARY: SECONDARY2 } = useTheme();
18878
+ const fieldLabelMap = React45__default.default.useMemo(() => {
18879
+ var _a;
18880
+ const map = {};
18881
+ for (const f of fields) map[f.field_key] = (_a = f.label) != null ? _a : f.field_key;
18882
+ return map;
18883
+ }, [fields]);
18884
+ if (loading) {
18885
+ return /* @__PURE__ */ jsxRuntime.jsx(
18886
+ "div",
18887
+ {
18888
+ style: {
18889
+ flex: 1,
18890
+ display: "flex",
18891
+ alignItems: "center",
18892
+ justifyContent: "center",
18893
+ padding: "32px 20px",
18894
+ fontSize: "13px",
18895
+ color: MUTED2
18896
+ },
18897
+ children: "Loading audit trail\u2026"
18898
+ }
18899
+ );
18900
+ }
18901
+ if (events.length === 0) {
18902
+ return /* @__PURE__ */ jsxRuntime.jsxs(
18903
+ "div",
18904
+ {
18905
+ style: {
18906
+ flex: 1,
18907
+ display: "flex",
18908
+ flexDirection: "column",
18909
+ alignItems: "center",
18910
+ justifyContent: "center",
18911
+ gap: "6px",
18912
+ padding: "32px 20px",
18913
+ textAlign: "center"
18914
+ },
18915
+ children: [
18916
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0, fontSize: "13.5px", fontWeight: 600, color: "var(--foreground)" }, children: "No changes yet" }),
18917
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0, fontSize: "12px", color: MUTED2, maxWidth: "240px", lineHeight: 1.5 }, children: "Field corrections will appear here." })
18918
+ ]
18919
+ }
18920
+ );
18921
+ }
18922
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", flex: 1, minHeight: 0, overflow: "hidden" }, children: [
18923
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "8px 14px 6px", flexShrink: 0 }, children: /* @__PURE__ */ jsxRuntime.jsxs(
18924
+ "span",
18925
+ {
18926
+ style: {
18927
+ fontSize: "11.5px",
18928
+ fontWeight: 600,
18929
+ color: MUTED2,
18930
+ textTransform: "uppercase",
18931
+ letterSpacing: "0.04em"
18932
+ },
18933
+ children: [
18934
+ events.length,
18935
+ " ",
18936
+ events.length === 1 ? "change" : "changes"
18937
+ ]
18938
+ }
18939
+ ) }),
18940
+ /* @__PURE__ */ jsxRuntime.jsx("ol", { style: { listStyle: "none", margin: 0, padding: "0 0 16px", overflowY: "auto", flex: 1, minHeight: 0 }, children: events.map((ev) => {
18941
+ var _a, _b;
18942
+ const rawLabel = (_a = fieldLabelMap[ev.field_key]) != null ? _a : ev.field_key;
18943
+ const label = prettyLabel(rawLabel);
18944
+ const isAI = ev.actor_type === "system" || ev.event_type === "ai_corrected" || ev.event_type === "ai_extracted";
18945
+ const actor = isAI ? "AI" : ev.actor_name || "Unknown";
18946
+ const eventLabel = isAI ? "Re-extracted" : "Corrected";
18947
+ return /* @__PURE__ */ jsxRuntime.jsxs(
18948
+ "li",
18949
+ {
18950
+ "data-testid": "audit-row",
18951
+ style: { display: "flex", gap: "10px", padding: "10px 14px", borderBottom: `1px solid ${BORDER4}` },
18952
+ children: [
18953
+ /* @__PURE__ */ jsxRuntime.jsx(
18954
+ "div",
18955
+ {
18956
+ title: isAI ? "AI extraction" : actor,
18957
+ style: {
18958
+ flexShrink: 0,
18959
+ width: "28px",
18960
+ height: "28px",
18961
+ borderRadius: "50%",
18962
+ background: isAI ? "#dcfce7" : "#eff6ff",
18963
+ color: isAI ? "#15803d" : SECONDARY2,
18964
+ fontSize: "10.5px",
18965
+ fontWeight: 700,
18966
+ display: "flex",
18967
+ alignItems: "center",
18968
+ justifyContent: "center",
18969
+ marginTop: "1px"
18970
+ },
18971
+ children: isAI ? "\u2728" : initials(actor)
18972
+ }
18973
+ ),
18974
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "3px", flex: 1, minWidth: 0 }, children: [
18975
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "baseline", gap: "6px", flexWrap: "wrap" }, children: [
18976
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "12.5px", fontWeight: 600, color: isAI ? "#15803d" : "var(--foreground)" }, children: actor }),
18977
+ /* @__PURE__ */ jsxRuntime.jsx(
18978
+ "span",
18979
+ {
18980
+ style: {
18981
+ fontSize: "10.5px",
18982
+ fontWeight: 600,
18983
+ color: MUTED2,
18984
+ background: PAPER2,
18985
+ borderRadius: "4px",
18986
+ padding: "1px 6px",
18987
+ whiteSpace: "nowrap",
18988
+ flexShrink: 0
18989
+ },
18990
+ children: eventLabel
18991
+ }
18992
+ ),
18993
+ /* @__PURE__ */ jsxRuntime.jsx(
18994
+ "span",
18995
+ {
18996
+ style: {
18997
+ fontSize: "12px",
18998
+ color: MUTED2,
18999
+ flex: 1,
19000
+ minWidth: 0,
19001
+ whiteSpace: "nowrap",
19002
+ overflow: "hidden",
19003
+ textOverflow: "ellipsis"
19004
+ },
19005
+ children: label
19006
+ }
19007
+ ),
19008
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "11px", color: MUTED2, flexShrink: 0 }, children: formatTs(ev.created_at) })
19009
+ ] }),
19010
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "6px", flexWrap: "wrap" }, children: [
19011
+ ev.previous_value != null && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
19012
+ /* @__PURE__ */ jsxRuntime.jsx(
19013
+ "span",
19014
+ {
19015
+ style: {
19016
+ fontSize: "12px",
19017
+ fontFamily: "ui-monospace, monospace",
19018
+ color: MUTED2,
19019
+ textDecoration: "line-through"
19020
+ },
19021
+ children: ev.previous_value
19022
+ }
19023
+ ),
19024
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "11px", color: BORDER4 }, children: "\u2192" })
19025
+ ] }),
19026
+ /* @__PURE__ */ jsxRuntime.jsx(
19027
+ "span",
19028
+ {
19029
+ style: {
19030
+ fontSize: "12px",
19031
+ fontFamily: "ui-monospace, monospace",
19032
+ fontWeight: 600,
19033
+ color: "var(--foreground)"
19034
+ },
19035
+ children: (_b = ev.new_value) != null ? _b : "\u2014"
19036
+ }
19037
+ )
19038
+ ] }),
19039
+ ev.reason && /* @__PURE__ */ jsxRuntime.jsxs("p", { style: { margin: "2px 0 0", fontSize: "11.5px", color: MUTED2, fontStyle: "italic" }, children: [
19040
+ "\u201C",
19041
+ ev.reason,
19042
+ "\u201D"
19043
+ ] })
19044
+ ] })
19045
+ ]
19046
+ },
19047
+ ev.id
19048
+ );
19049
+ }) })
19050
+ ] });
19051
+ }
19052
+ var TIER_COLORS2 = {
19053
+ green: "#15803d",
19054
+ amber: "#f59e0b",
19055
+ red: "#dc2626"
19056
+ };
19057
+ function fieldColor2(f, secondary) {
19058
+ var _a, _b;
19059
+ if (f.state === "corrected") return secondary;
19060
+ return (_b = TIER_COLORS2[(_a = f.confidence_tier) != null ? _a : "amber"]) != null ? _b : TIER_COLORS2.amber;
19061
+ }
19062
+ function hexToRgba2(hex, alpha) {
19063
+ const h = hex.replace("#", "");
19064
+ const r = parseInt(h.slice(0, 2), 16);
19065
+ const g = parseInt(h.slice(2, 4), 16);
19066
+ const b = parseInt(h.slice(4, 6), 16);
19067
+ return `rgba(${r}, ${g}, ${b}, ${alpha})`;
19068
+ }
19069
+ function PageOverlay({
19070
+ page,
19071
+ fields,
19072
+ selectedKey,
19073
+ onSelect,
19074
+ secondary
19075
+ }) {
19076
+ const { PAPER: PAPER2, MUTED: MUTED2 } = useTheme();
19077
+ const imgRef = React45__default.default.useRef(null);
19078
+ const selectedBoxRef = React45__default.default.useRef(null);
19079
+ const [px, setPx] = React45__default.default.useState(null);
19080
+ React45__default.default.useEffect(() => {
19081
+ const el = imgRef.current;
19082
+ if (!el) return;
19083
+ const measure = () => {
19084
+ if (el.clientWidth && el.clientHeight) {
19085
+ setPx({ wPx: el.clientWidth, hPx: el.clientHeight });
19086
+ }
19087
+ };
19088
+ measure();
19089
+ if (typeof ResizeObserver === "undefined") return;
19090
+ const ro = new ResizeObserver(measure);
19091
+ ro.observe(el);
19092
+ return () => ro.disconnect();
19093
+ }, [page.imageUrl]);
19094
+ React45__default.default.useEffect(() => {
19095
+ if (!selectedKey) return;
19096
+ if (!fields.some((f) => f.field_key === selectedKey && f.bbox)) return;
19097
+ const el = selectedBoxRef.current;
19098
+ if (el && typeof el.scrollIntoView === "function") {
19099
+ el.scrollIntoView({ behavior: "smooth", block: "center", inline: "nearest" });
19100
+ }
19101
+ }, [selectedKey, fields, px]);
19102
+ const pagePts = { wPts: page.width_pt, hPts: page.height_pt };
19103
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { position: "relative", width: "100%", lineHeight: 0 }, children: [
19104
+ page.imageUrl ? /* @__PURE__ */ jsxRuntime.jsx(
19105
+ "img",
19106
+ {
19107
+ ref: imgRef,
19108
+ src: page.imageUrl,
19109
+ alt: `Page ${page.page + 1}`,
19110
+ onLoad: () => {
19111
+ const el = imgRef.current;
19112
+ if (el && el.clientWidth && el.clientHeight) {
19113
+ setPx({ wPx: el.clientWidth, hPx: el.clientHeight });
19114
+ }
19115
+ },
19116
+ style: { display: "block", width: "100%", height: "auto" }
19117
+ }
19118
+ ) : (
19119
+ // No resolved image (host couldn't resolve the raster) — keep the
19120
+ // aspect box so cards still make sense, but show nothing to overlay on.
19121
+ /* @__PURE__ */ jsxRuntime.jsxs(
19122
+ "div",
19123
+ {
19124
+ style: {
19125
+ width: "100%",
19126
+ aspectRatio: `${page.width_pt} / ${page.height_pt}`,
19127
+ background: PAPER2,
19128
+ display: "flex",
19129
+ alignItems: "center",
19130
+ justifyContent: "center",
19131
+ fontSize: "12px",
19132
+ color: MUTED2,
19133
+ lineHeight: 1.4
19134
+ },
19135
+ children: [
19136
+ "Page ",
19137
+ page.page + 1,
19138
+ " image unavailable"
19139
+ ]
19140
+ }
19141
+ )
19142
+ ),
19143
+ px && page.imageUrl && fields.map((f) => {
19144
+ var _a;
19145
+ const rect = bboxToRect((_a = f.bbox) != null ? _a : null, pagePts, px);
19146
+ if (!rect) return null;
19147
+ const color = fieldColor2(f, secondary);
19148
+ const selected = selectedKey === f.field_key;
19149
+ return /* @__PURE__ */ jsxRuntime.jsx(
19150
+ "div",
19151
+ {
19152
+ ref: selected ? selectedBoxRef : null,
19153
+ "data-testid": "bbox-rect",
19154
+ "data-field-key": f.field_key,
19155
+ "data-selected": selected ? "true" : "false",
19156
+ onClick: () => onSelect(selected ? null : f.field_key),
19157
+ title: `${f.label}: ${f.value}`,
19158
+ style: {
19159
+ position: "absolute",
19160
+ left: `${rect.left}px`,
19161
+ top: `${rect.top}px`,
19162
+ width: `${rect.width}px`,
19163
+ height: `${rect.height}px`,
19164
+ border: `1px solid ${color}`,
19165
+ background: hexToRgba2(color, selected ? 0.28 : 0.12),
19166
+ boxShadow: selected ? `0 0 0 2px ${hexToRgba2(color, 0.5)}` : "none",
19167
+ borderRadius: "2px",
19168
+ cursor: "pointer",
19169
+ transition: "background 0.15s, box-shadow 0.15s"
19170
+ }
19171
+ },
19172
+ f.field_key
19173
+ );
19174
+ })
19175
+ ] });
19176
+ }
19177
+ function ExtractionDetail({
19178
+ pages,
19179
+ orderedFields,
19180
+ fieldsByPage,
19181
+ selectedKey,
19182
+ setSelectedKey,
19183
+ onFieldSave,
19184
+ correctionCounts,
19185
+ tab,
19186
+ setTab,
19187
+ editable,
19188
+ summary,
19189
+ fileName,
19190
+ pageCount,
19191
+ pagesProcessed,
19192
+ auditEvents,
19193
+ auditLoading
19194
+ }) {
19195
+ const { BORDER: BORDER4, MUTED: MUTED2, PAPER: PAPER2, SECONDARY: SECONDARY2 } = useTheme();
19196
+ const selectedCardRef = React45__default.default.useRef(null);
19197
+ React45__default.default.useEffect(() => {
19198
+ if (!selectedKey || tab !== "fields") return;
19199
+ const el = selectedCardRef.current;
19200
+ if (el && typeof el.scrollIntoView === "function") {
19201
+ el.scrollIntoView({ behavior: "smooth", block: "nearest" });
19202
+ }
19203
+ }, [selectedKey, tab]);
19204
+ const tabs = [
19205
+ { key: "details", label: "Details" },
19206
+ { key: "fields", label: "Fields", count: orderedFields.length }
19207
+ ];
19208
+ if (editable) tabs.push({ key: "audit", label: "Audit Trails", count: (auditEvents == null ? void 0 : auditEvents.length) || void 0 });
19209
+ return /* @__PURE__ */ jsxRuntime.jsxs(
19210
+ "div",
19211
+ {
19212
+ style: {
19213
+ display: "grid",
19214
+ gridTemplateColumns: "minmax(0, 3fr) minmax(260px, 1fr)",
19215
+ gap: "12px",
19216
+ height: "100%",
19217
+ minHeight: 0
19218
+ },
19219
+ children: [
19220
+ /* @__PURE__ */ jsxRuntime.jsx(
19221
+ "div",
19222
+ {
19223
+ style: {
19224
+ display: "flex",
19225
+ flexDirection: "column",
19226
+ gap: "10px",
19227
+ borderRadius: "0.75rem",
19228
+ border: `1px solid ${BORDER4}`,
19229
+ overflowY: "auto",
19230
+ minHeight: 0
19231
+ },
19232
+ children: pages.map((pg) => /* @__PURE__ */ jsxRuntime.jsx(
19233
+ PageOverlay,
19234
+ {
19235
+ page: pg,
19236
+ fields: fieldsByPage(pg.page),
19237
+ selectedKey,
19238
+ onSelect: (key) => {
19239
+ setSelectedKey(key);
19240
+ if (key) setTab("fields");
19241
+ },
19242
+ secondary: SECONDARY2
19243
+ },
19244
+ pg.page
19245
+ ))
19246
+ }
19247
+ ),
19248
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", minWidth: 0, minHeight: 0 }, children: [
19249
+ /* @__PURE__ */ jsxRuntime.jsx(
19250
+ "div",
19251
+ {
19252
+ style: {
19253
+ display: "flex",
19254
+ gap: "16px",
19255
+ borderBottom: `1px solid ${BORDER4}`,
19256
+ flexShrink: 0,
19257
+ marginBottom: "10px"
19258
+ },
19259
+ children: tabs.map((t) => {
19260
+ const active = tab === t.key;
19261
+ return /* @__PURE__ */ jsxRuntime.jsxs(
19262
+ "button",
19263
+ {
19264
+ type: "button",
19265
+ onClick: () => setTab(t.key),
19266
+ "data-testid": `tab-${t.key}`,
19267
+ style: {
19268
+ appearance: "none",
19269
+ background: "transparent",
19270
+ borderTop: "none",
19271
+ borderLeft: "none",
19272
+ borderRight: "none",
19273
+ borderBottom: `2px solid ${active ? SECONDARY2 : "transparent"}`,
19274
+ padding: "6px 2px",
19275
+ marginBottom: "-1px",
19276
+ cursor: "pointer",
19277
+ fontSize: "13px",
19278
+ fontWeight: 600,
19279
+ color: active ? SECONDARY2 : MUTED2,
19280
+ display: "inline-flex",
19281
+ alignItems: "center",
19282
+ gap: "6px"
19283
+ },
19284
+ children: [
19285
+ t.label,
19286
+ typeof t.count === "number" && /* @__PURE__ */ jsxRuntime.jsx(
19287
+ "span",
19288
+ {
19289
+ style: {
19290
+ fontSize: "11px",
19291
+ fontWeight: 600,
19292
+ padding: "1px 7px",
19293
+ borderRadius: "9999px",
19294
+ background: active ? "#eff6ff" : PAPER2,
19295
+ color: active ? SECONDARY2 : MUTED2
19296
+ },
19297
+ children: t.count
19298
+ }
19299
+ )
19300
+ ]
19301
+ },
19302
+ t.key
19303
+ );
19304
+ })
19305
+ }
19306
+ ),
19307
+ tab === "details" ? /* @__PURE__ */ jsxRuntime.jsx(
19308
+ FieldDetails,
19309
+ {
19310
+ summary,
19311
+ fileName,
19312
+ pageCount,
19313
+ pagesProcessed
19314
+ }
19315
+ ) : tab === "audit" ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { minHeight: 0, overflowY: "auto" }, children: /* @__PURE__ */ jsxRuntime.jsx(
19316
+ FieldAuditLog,
19317
+ {
19318
+ events: auditEvents != null ? auditEvents : [],
19319
+ loading: auditLoading != null ? auditLoading : false,
19320
+ fields: orderedFields.map((f) => ({ field_key: f.field_key, label: f.label }))
19321
+ }
19322
+ ) }) : /* @__PURE__ */ jsxRuntime.jsxs(
19323
+ "div",
19324
+ {
19325
+ style: {
19326
+ display: "flex",
19327
+ flexDirection: "column",
19328
+ minHeight: 0,
19329
+ overflowY: "auto",
19330
+ paddingRight: "4px"
19331
+ },
19332
+ children: [
19333
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { fontSize: "12px", color: MUTED2, padding: "0 0 8px 2px", flexShrink: 0 }, children: [
19334
+ orderedFields.length,
19335
+ " extracted"
19336
+ ] }),
19337
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: "6px" }, children: orderedFields.map((f) => {
19338
+ var _a;
19339
+ const selected = selectedKey === f.field_key;
19340
+ return /* @__PURE__ */ jsxRuntime.jsx(
19341
+ FieldDetail,
19342
+ {
19343
+ field: f,
19344
+ selected,
19345
+ onSelect: setSelectedKey,
19346
+ onSave: onFieldSave,
19347
+ correctionCount: (_a = correctionCounts == null ? void 0 : correctionCounts[f.field_key]) != null ? _a : 0,
19348
+ cardRef: selected ? selectedCardRef : void 0
19349
+ },
19350
+ f.field_key
19351
+ );
19352
+ }) })
19353
+ ]
19354
+ }
19355
+ )
19356
+ ] })
19357
+ ]
19358
+ }
19359
+ );
19360
+ }
19361
+ function ExtractionModal({
19362
+ open,
19363
+ onClose,
19364
+ title,
19365
+ children
19366
+ }) {
19367
+ const { BORDER: BORDER4, MUTED: MUTED2 } = useTheme();
19368
+ React45__default.default.useEffect(() => {
19369
+ if (!open) return;
19370
+ const onKey = (e) => {
19371
+ if (e.key === "Escape") onClose();
19372
+ };
19373
+ window.addEventListener("keydown", onKey);
19374
+ const prev = document.body.style.overflow;
19375
+ document.body.style.overflow = "hidden";
19376
+ return () => {
19377
+ window.removeEventListener("keydown", onKey);
19378
+ document.body.style.overflow = prev;
19379
+ };
19380
+ }, [open, onClose]);
19381
+ if (!open || typeof document === "undefined") return null;
19382
+ return reactDom.createPortal(
19383
+ /* @__PURE__ */ jsxRuntime.jsx(
19384
+ "div",
19385
+ {
19386
+ role: "dialog",
19387
+ "aria-modal": "true",
19388
+ "aria-label": title,
19389
+ onClick: onClose,
19390
+ style: {
19391
+ position: "fixed",
19392
+ inset: 0,
19393
+ zIndex: 2147483e3,
19394
+ background: "rgba(0,0,0,0.5)",
19395
+ display: "flex",
19396
+ alignItems: "center",
19397
+ justifyContent: "center",
19398
+ padding: "4vh 4vw",
19399
+ backdropFilter: "blur(2px)"
19400
+ },
19401
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
19402
+ "div",
19403
+ {
19404
+ onClick: (e) => e.stopPropagation(),
19405
+ style: {
19406
+ width: "90vw",
19407
+ height: "90vh",
19408
+ background: "white",
19409
+ borderRadius: "0.875rem",
19410
+ border: `1px solid ${BORDER4}`,
19411
+ boxShadow: "0 20px 60px rgba(0,0,0,0.30)",
19412
+ display: "flex",
19413
+ flexDirection: "column",
19414
+ overflow: "hidden"
19415
+ },
19416
+ children: [
19417
+ /* @__PURE__ */ jsxRuntime.jsxs(
19418
+ "div",
19419
+ {
19420
+ style: {
19421
+ display: "flex",
19422
+ alignItems: "center",
19423
+ gap: "10px",
19424
+ padding: "11px 16px",
19425
+ borderBottom: `1px solid ${BORDER4}`,
19426
+ flexShrink: 0
19427
+ },
19428
+ children: [
19429
+ /* @__PURE__ */ jsxRuntime.jsx(
19430
+ "span",
19431
+ {
19432
+ style: {
19433
+ flex: 1,
19434
+ minWidth: 0,
19435
+ fontFamily: "var(--font-serif)",
19436
+ fontSize: "16px",
19437
+ fontWeight: 400,
19438
+ letterSpacing: "-0.01em",
19439
+ color: "var(--foreground)",
19440
+ overflow: "hidden",
19441
+ textOverflow: "ellipsis",
19442
+ whiteSpace: "nowrap"
19443
+ },
19444
+ children: title
19445
+ }
19446
+ ),
19447
+ /* @__PURE__ */ jsxRuntime.jsx(
19448
+ "button",
19449
+ {
19450
+ type: "button",
19451
+ "aria-label": "Close",
19452
+ onClick: onClose,
19453
+ style: {
19454
+ border: `1px solid ${BORDER4}`,
19455
+ borderRadius: "8px",
19456
+ background: "white",
19457
+ cursor: "pointer",
19458
+ padding: "5px 9px",
19459
+ fontSize: "13px",
19460
+ color: MUTED2,
19461
+ lineHeight: 1
19462
+ },
19463
+ children: "\u2715"
19464
+ }
19465
+ )
19466
+ ]
19467
+ }
19468
+ ),
19469
+ /* @__PURE__ */ jsxRuntime.jsx(
19470
+ "div",
19471
+ {
19472
+ style: {
19473
+ flex: 1,
19474
+ minHeight: 0,
19475
+ overflow: "hidden",
19476
+ display: "flex",
19477
+ flexDirection: "column",
19478
+ padding: "14px 16px"
19479
+ },
19480
+ children
19481
+ }
19482
+ )
19483
+ ]
19484
+ }
19485
+ )
19486
+ }
19487
+ ),
19488
+ document.body
19489
+ );
19490
+ }
19491
+ function DocumentFieldExtractionResolver(p) {
19492
+ var _a, _b;
19493
+ const { BORDER: BORDER4, MUTED: MUTED2, PAPER: PAPER2 } = useTheme();
19494
+ const [selectedKey, setSelectedKey] = React45__default.default.useState(null);
19495
+ const [open, setOpen] = React45__default.default.useState(false);
19496
+ const [tab, setTab] = React45__default.default.useState("fields");
19497
+ const pages = (_a = p.pages) != null ? _a : [];
19498
+ const fields = (_b = p.fields) != null ? _b : [];
19499
+ const editable = typeof p.onFieldSave === "function";
19500
+ const onLoadAudit = p.onLoadAudit;
19501
+ React45__default.default.useEffect(() => {
19502
+ if (tab === "audit" && onLoadAudit) {
19503
+ onLoadAudit();
19504
+ }
19505
+ }, [tab, onLoadAudit]);
19506
+ const correctionCounts = React45__default.default.useMemo(() => {
19507
+ var _a2, _b2;
19508
+ const counts = {};
19509
+ for (const ev of (_a2 = p.auditEvents) != null ? _a2 : []) {
19510
+ const human = ev.actor_type !== "system" && ev.event_type !== "ai_extracted";
19511
+ if (human) counts[ev.field_key] = ((_b2 = counts[ev.field_key]) != null ? _b2 : 0) + 1;
19512
+ }
19513
+ return counts;
19514
+ }, [p.auditEvents]);
19515
+ const orderedFields = [...fields].sort((a, b) => {
19516
+ var _a2, _b2;
19517
+ if (!!a.is_primary !== !!b.is_primary) return a.is_primary ? -1 : 1;
19518
+ return ((_a2 = b.confidence) != null ? _a2 : 0) - ((_b2 = a.confidence) != null ? _b2 : 0);
19519
+ });
19520
+ const fieldsByPage = (pageNo) => fields.filter((f) => f.page === pageNo);
19521
+ const csvCols = [
19522
+ { key: "label", label: "Field" },
19523
+ { key: "value", label: "Value" },
19524
+ { key: "page", label: "Page" },
19525
+ { key: "confidence", label: "Confidence" },
19526
+ { key: "badge", label: "Badge" },
19527
+ { key: "state", label: "State" }
19528
+ ];
19529
+ const csvRows = orderedFields.map((f) => {
19530
+ var _a2, _b2, _c;
19531
+ return {
19532
+ label: f.label,
19533
+ value: f.value,
19534
+ page: f.page + 1,
19535
+ confidence: (_a2 = f.confidence) != null ? _a2 : "",
19536
+ badge: (_b2 = f.badge) != null ? _b2 : "",
19537
+ state: (_c = f.state) != null ? _c : ""
19538
+ };
19539
+ });
19540
+ const title = p.file_name || (p.doc_type ? `${p.doc_type} \u2014 extracted fields` : "Extracted fields");
19541
+ const tierCounts = fields.reduce(
19542
+ (acc, f) => {
19543
+ var _a2;
19544
+ const t = (_a2 = f.confidence_tier) != null ? _a2 : "amber";
19545
+ if (t === "green") acc.high += 1;
19546
+ else if (t === "red") acc.low += 1;
19547
+ else acc.med += 1;
19548
+ return acc;
19549
+ },
19550
+ { high: 0, med: 0, low: 0 }
19551
+ );
19552
+ const chips = [
19553
+ { n: tierCounts.high, label: "high", color: TIER_COLORS2.green },
19554
+ { n: tierCounts.med, label: "medium", color: TIER_COLORS2.amber },
19555
+ { n: tierCounts.low, label: "low", color: TIER_COLORS2.red }
19556
+ ].filter((c) => c.n > 0);
19557
+ const thumb = pages.find((pg) => pg.imageUrl);
19558
+ return /* @__PURE__ */ jsxRuntime.jsxs(
19559
+ ComponentActions,
19560
+ {
19561
+ filename: "document-fields",
19562
+ onDownloadCSV: () => downloadCSV(csvCols, csvRows, "document-fields"),
19563
+ children: [
19564
+ /* @__PURE__ */ jsxRuntime.jsxs(
19565
+ "div",
19566
+ {
19567
+ role: "button",
19568
+ tabIndex: 0,
19569
+ onClick: () => setOpen(true),
19570
+ onKeyDown: (e) => {
19571
+ if (e.key === "Enter" || e.key === " ") {
19572
+ e.preventDefault();
19573
+ setOpen(true);
19574
+ }
19575
+ },
19576
+ style: {
19577
+ display: "flex",
19578
+ alignItems: "stretch",
19579
+ gap: "12px",
19580
+ padding: "12px",
19581
+ width: "100%",
19582
+ maxWidth: "440px",
19583
+ borderRadius: "0.75rem",
19584
+ border: `1px solid ${BORDER4}`,
19585
+ background: "white",
19586
+ cursor: "pointer",
19587
+ textAlign: "left",
19588
+ boxShadow: "0 1px 2px rgba(0,0,0,0.03), 0 4px 12px rgba(0,0,0,0.05)"
19589
+ },
19590
+ children: [
19591
+ /* @__PURE__ */ jsxRuntime.jsx(
19592
+ "div",
19593
+ {
19594
+ style: {
19595
+ width: "64px",
19596
+ flexShrink: 0,
19597
+ borderRadius: "0.5rem",
19598
+ border: `1px solid ${BORDER4}`,
19599
+ background: PAPER2,
19600
+ overflow: "hidden",
19601
+ display: "flex",
19602
+ alignItems: "center",
19603
+ justifyContent: "center"
19604
+ },
19605
+ children: (thumb == null ? void 0 : thumb.imageUrl) ? /* @__PURE__ */ jsxRuntime.jsx(
19606
+ "img",
19607
+ {
19608
+ src: thumb.imageUrl,
19609
+ alt: "Document preview",
19610
+ style: { width: "100%", height: "auto", display: "block" }
19611
+ }
19612
+ ) : /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "22px", lineHeight: 1, padding: "16px 0" }, children: "\u{1F4C4}" })
19613
+ }
19614
+ ),
19615
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { flex: 1, minWidth: 0, display: "flex", flexDirection: "column", gap: "6px" }, children: [
19616
+ /* @__PURE__ */ jsxRuntime.jsx(
19617
+ "p",
19618
+ {
19619
+ style: {
19620
+ fontFamily: "var(--font-serif)",
19621
+ fontSize: "15px",
19622
+ fontWeight: 400,
19623
+ color: "var(--foreground)",
19624
+ letterSpacing: "-0.01em",
19625
+ margin: 0,
19626
+ overflow: "hidden",
19627
+ textOverflow: "ellipsis",
19628
+ whiteSpace: "nowrap"
19629
+ },
19630
+ children: p.file_name || p.doc_type || "Document"
19631
+ }
19632
+ ),
19633
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { fontSize: "12px", color: MUTED2 }, children: [
19634
+ fields.length,
19635
+ " field",
19636
+ fields.length === 1 ? "" : "s",
19637
+ " extracted \xB7 ",
19638
+ pages.length,
19639
+ " page",
19640
+ pages.length === 1 ? "" : "s"
19641
+ ] }),
19642
+ chips.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexWrap: "wrap", gap: "5px" }, children: chips.map((c) => /* @__PURE__ */ jsxRuntime.jsxs(
19643
+ "span",
19644
+ {
19645
+ style: {
19646
+ display: "inline-flex",
19647
+ alignItems: "center",
19648
+ gap: "4px",
19649
+ fontSize: "10px",
19650
+ fontWeight: 600,
19651
+ padding: "2px 7px",
19652
+ borderRadius: "9999px",
19653
+ background: hexToRgba2(c.color, 0.12),
19654
+ color: c.color
19655
+ },
19656
+ children: [
19657
+ /* @__PURE__ */ jsxRuntime.jsx(
19658
+ "span",
19659
+ {
19660
+ style: {
19661
+ width: "6px",
19662
+ height: "6px",
19663
+ borderRadius: "9999px",
19664
+ background: c.color
19665
+ }
19666
+ }
19667
+ ),
19668
+ c.n,
19669
+ " ",
19670
+ c.label
19671
+ ]
19672
+ },
19673
+ c.label
19674
+ )) }),
19675
+ /* @__PURE__ */ jsxRuntime.jsx(
19676
+ "span",
19677
+ {
19678
+ style: {
19679
+ marginTop: "2px",
19680
+ alignSelf: "flex-start",
19681
+ fontSize: "12px",
19682
+ fontWeight: 600,
19683
+ padding: "6px 12px",
19684
+ borderRadius: "0.5rem",
19685
+ background: "var(--foreground)",
19686
+ color: "white"
19687
+ },
19688
+ children: "View & edit fields"
19689
+ }
19690
+ )
19691
+ ] })
19692
+ ]
19693
+ }
19694
+ ),
19695
+ /* @__PURE__ */ jsxRuntime.jsx(ExtractionModal, { open, onClose: () => setOpen(false), title, children: /* @__PURE__ */ jsxRuntime.jsx(
19696
+ ExtractionDetail,
19697
+ {
19698
+ pages,
19699
+ orderedFields,
19700
+ fieldsByPage,
19701
+ selectedKey,
19702
+ setSelectedKey,
19703
+ onFieldSave: p.onFieldSave,
19704
+ correctionCounts,
19705
+ tab,
19706
+ setTab,
19707
+ editable,
19708
+ summary: p.summary,
19709
+ fileName: p.file_name,
19710
+ pageCount: p.page_count,
19711
+ pagesProcessed: p.pages_processed,
19712
+ auditEvents: p.auditEvents,
19713
+ auditLoading: p.auditLoading
19714
+ }
19715
+ ) })
19716
+ ]
19717
+ }
19718
+ );
19719
+ }
19720
+ init_ThemeContext();
19721
+ var SEVERITY_COLORS = {
19722
+ high: { color: "#dc2626", bg: "#fef2f2" },
19723
+ medium: { color: "#f59e0b", bg: "#fff7ed" },
19724
+ low: { color: "#777777", bg: "#f2f2f2" }
19725
+ };
19726
+ var GREEN3 = "#15803d";
19727
+ var GREEN_SOFT = "#dcfce7";
19728
+ var STACK_BELOW = 380;
19729
+ function formatAmount2(amount, currency = "USD") {
19730
+ var _a, _b;
19731
+ const abs = Math.abs(amount);
19732
+ const sign = amount < 0 ? "-" : "";
19733
+ let body;
19734
+ if (abs >= 1e6) body = `${(abs / 1e6).toFixed(abs >= 1e7 ? 0 : 1)}M`;
19735
+ else if (abs >= 1e3) body = `${(abs / 1e3).toFixed(abs >= 1e4 ? 0 : 1)}K`;
19736
+ else body = `${abs}`;
19737
+ let symbol = "$";
19738
+ try {
19739
+ const parts = new Intl.NumberFormat("en-US", {
19740
+ style: "currency",
19741
+ currency,
19742
+ maximumFractionDigits: 0
19743
+ }).formatToParts(0);
19744
+ symbol = (_b = (_a = parts.find((p) => p.type === "currency")) == null ? void 0 : _a.value) != null ? _b : "$";
19745
+ } catch (e) {
19746
+ symbol = "$";
19747
+ }
19748
+ return `${sign}${symbol}${body}`;
19749
+ }
19750
+ function useContainerWidth2(ref) {
19751
+ const [w, setW] = React45__default.default.useState(0);
19752
+ React45__default.default.useLayoutEffect(() => {
19753
+ const el = ref.current;
19754
+ if (!el || typeof ResizeObserver === "undefined") return;
19755
+ const ro = new ResizeObserver((entries) => {
19756
+ var _a;
19757
+ const cr = (_a = entries[0]) == null ? void 0 : _a.contentRect;
19758
+ if (cr) setW(cr.width);
19759
+ });
19760
+ ro.observe(el);
19761
+ setW(el.getBoundingClientRect().width);
19762
+ return () => ro.disconnect();
19763
+ }, [ref]);
19764
+ return w;
19765
+ }
19766
+ var KEYFRAMES2 = `
19767
+ @keyframes dcRise{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}
19768
+ .dc-rise{animation:dcRise 0.28s cubic-bezier(0.22,1,0.36,1) both}
19769
+ @media (prefers-reduced-motion: reduce){
19770
+ .dc-rise{animation:none !important;opacity:1 !important;transform:none !important}
19771
+ }`;
19772
+ function SparkCheck({ size, color }) {
19773
+ return /* @__PURE__ */ jsxRuntime.jsx("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx(
19774
+ "path",
19775
+ {
19776
+ d: "M5 13l4 4L19 7",
19777
+ stroke: color,
19778
+ strokeWidth: 2.5,
19779
+ strokeLinecap: "round",
19780
+ strokeLinejoin: "round"
19781
+ }
19782
+ ) });
19783
+ }
19784
+ function FlagPill({ flag }) {
19785
+ var _a;
19786
+ const sev = (_a = flag.severity) != null ? _a : "medium";
19787
+ const { color, bg } = SEVERITY_COLORS[sev];
19788
+ return /* @__PURE__ */ jsxRuntime.jsxs(
19789
+ "span",
19790
+ {
19791
+ style: {
19792
+ display: "inline-flex",
19793
+ alignItems: "center",
19794
+ gap: 5,
19795
+ fontSize: 11,
19796
+ fontWeight: 600,
19797
+ padding: "3px 9px",
19798
+ borderRadius: 9999,
19799
+ background: bg,
19800
+ color,
19801
+ lineHeight: 1.2
19802
+ },
19803
+ children: [
19804
+ /* @__PURE__ */ jsxRuntime.jsx(
19805
+ "span",
19806
+ {
19807
+ "aria-hidden": "true",
19808
+ style: { width: 6, height: 6, borderRadius: "50%", background: color, flexShrink: 0 }
19809
+ }
19810
+ ),
19811
+ flag.field ? `${flag.field}: ${flag.issue}` : flag.issue
19812
+ ]
19813
+ }
19814
+ );
19815
+ }
19816
+ function DecisionCardRenderer({
19817
+ data,
19818
+ resolved = null,
19819
+ onResolve,
19820
+ onOpenSource
19821
+ }) {
19822
+ var _a, _b;
19823
+ const { BORDER: BORDER4, MUTED: MUTED2, ACCENT: ACCENT2, ACCENT_SOFT: ACCENT_SOFT2 } = useTheme();
19824
+ const rootRef = React45__default.default.useRef(null);
19825
+ const width = useContainerWidth2(rootRef);
19826
+ const stacked = width > 0 && width < STACK_BELOW;
19827
+ const options = (_a = data.options) != null ? _a : [];
19828
+ const recommendedIdx = Math.max(
19829
+ 0,
19830
+ options.findIndex((o) => o.recommended)
19831
+ );
19832
+ const railColor = data.severity ? SEVERITY_COLORS[data.severity].color : ACCENT2;
19833
+ const isResolved = Boolean(resolved);
19834
+ const amountNode = typeof data.amount === "number" ? /* @__PURE__ */ jsxRuntime.jsxs(
19835
+ "div",
19836
+ {
19837
+ style: {
19838
+ display: "flex",
19839
+ flexDirection: "column",
19840
+ alignItems: stacked ? "flex-start" : "flex-end",
19841
+ gap: 1,
19842
+ flexShrink: 0
19843
+ },
19844
+ children: [
19845
+ data.amount_label && /* @__PURE__ */ jsxRuntime.jsx(
19846
+ "span",
19847
+ {
19848
+ style: {
19849
+ fontSize: 10,
19850
+ textTransform: "uppercase",
19851
+ letterSpacing: "0.07em",
19852
+ fontWeight: 700,
19853
+ color: MUTED2
19854
+ },
19855
+ children: data.amount_label
19856
+ }
19857
+ ),
19858
+ /* @__PURE__ */ jsxRuntime.jsx(
19859
+ "span",
19860
+ {
19861
+ style: {
19862
+ fontSize: 18,
19863
+ fontWeight: 700,
19864
+ color: "var(--foreground)",
19865
+ fontVariantNumeric: "tabular-nums",
19866
+ letterSpacing: "-0.01em",
19867
+ lineHeight: 1.1
19868
+ },
19869
+ children: formatAmount2(data.amount, data.currency)
19870
+ }
19871
+ )
19872
+ ]
19873
+ }
19874
+ ) : null;
19875
+ return /* @__PURE__ */ jsxRuntime.jsxs(
19876
+ "div",
19877
+ {
19878
+ ref: rootRef,
19879
+ className: "dc-rise",
19880
+ "data-testid": "decision-card",
19881
+ "data-resolved": isResolved || void 0,
19882
+ style: {
19883
+ position: "relative",
19884
+ width: "100%",
19885
+ minWidth: 0,
19886
+ boxSizing: "border-box",
19887
+ borderRadius: "0.75rem",
19888
+ border: `1px solid ${isResolved ? GREEN_SOFT : BORDER4}`,
19889
+ background: isResolved ? "#f6fef9" : "white",
19890
+ boxShadow: "0 1px 2px rgba(0,0,0,0.03), 0 4px 12px rgba(0,0,0,0.04)",
19891
+ padding: "16px 18px 16px 20px",
19892
+ display: "flex",
19893
+ flexDirection: "column",
19894
+ gap: 12,
19895
+ overflow: "hidden"
19896
+ },
19897
+ children: [
19898
+ /* @__PURE__ */ jsxRuntime.jsx("style", { children: KEYFRAMES2 }),
19899
+ /* @__PURE__ */ jsxRuntime.jsx(
19900
+ "div",
19901
+ {
19902
+ "aria-hidden": "true",
19903
+ style: {
19904
+ position: "absolute",
19905
+ top: 0,
19906
+ left: 0,
19907
+ bottom: 0,
19908
+ width: 4,
19909
+ background: isResolved ? GREEN3 : railColor
19910
+ }
19911
+ }
19912
+ ),
19913
+ /* @__PURE__ */ jsxRuntime.jsxs(
19914
+ "div",
19915
+ {
19916
+ style: {
19917
+ display: "flex",
19918
+ flexDirection: stacked ? "column" : "row",
19919
+ alignItems: stacked ? "flex-start" : "flex-start",
19920
+ justifyContent: "space-between",
19921
+ gap: stacked ? 6 : 12
19922
+ },
19923
+ children: [
19924
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { minWidth: 0, display: "flex", flexDirection: "column", gap: 4 }, children: [
19925
+ /* @__PURE__ */ jsxRuntime.jsx(
19926
+ "span",
19927
+ {
19928
+ style: {
19929
+ fontSize: 10.5,
19930
+ textTransform: "uppercase",
19931
+ letterSpacing: "0.07em",
19932
+ fontWeight: 700,
19933
+ color: ACCENT2
19934
+ },
19935
+ children: data.decision_type ? `Decision needs you \xB7 ${data.decision_type}` : "Decision needs you"
19936
+ }
19937
+ ),
19938
+ /* @__PURE__ */ jsxRuntime.jsx(
19939
+ "p",
19940
+ {
19941
+ style: {
19942
+ fontFamily: "var(--font-serif)",
19943
+ fontSize: 17,
19944
+ fontWeight: 400,
19945
+ color: "var(--foreground)",
19946
+ letterSpacing: "-0.01em",
19947
+ margin: 0,
19948
+ lineHeight: 1.2
19949
+ },
19950
+ children: data.title
19951
+ }
19952
+ )
19953
+ ] }),
19954
+ amountNode
19955
+ ]
19956
+ }
19957
+ ),
19958
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: 13, lineHeight: 1.5, color: MUTED2, margin: 0 }, children: data.question }),
19959
+ data.flags && data.flags.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexWrap: "wrap", gap: 6 }, children: data.flags.map((flag, i) => {
19960
+ var _a2;
19961
+ return /* @__PURE__ */ jsxRuntime.jsx(FlagPill, { flag }, `${(_a2 = flag.field) != null ? _a2 : "flag"}-${i}`);
19962
+ }) }),
19963
+ isResolved ? /* @__PURE__ */ jsxRuntime.jsxs(
19964
+ "div",
19965
+ {
19966
+ style: {
19967
+ display: "inline-flex",
19968
+ alignItems: "center",
19969
+ gap: 7,
19970
+ fontSize: 13,
19971
+ fontWeight: 600,
19972
+ color: GREEN3
19973
+ },
19974
+ children: [
19975
+ /* @__PURE__ */ jsxRuntime.jsx(SparkCheck, { size: 16, color: GREEN3 }),
19976
+ "Resolved \xB7 ",
19977
+ resolved
19978
+ ]
19979
+ }
19980
+ ) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
19981
+ /* @__PURE__ */ jsxRuntime.jsx(
19982
+ "div",
19983
+ {
19984
+ style: {
19985
+ display: "flex",
19986
+ flexDirection: stacked ? "column" : "row",
19987
+ flexWrap: stacked ? "nowrap" : "wrap",
19988
+ gap: 8
19989
+ },
19990
+ children: options.map((opt, idx) => {
19991
+ var _a2;
19992
+ const primary = idx === recommendedIdx;
19993
+ return /* @__PURE__ */ jsxRuntime.jsx(
19994
+ "button",
19995
+ {
19996
+ type: "button",
19997
+ onClick: () => onResolve == null ? void 0 : onResolve(opt.label),
19998
+ style: {
19999
+ width: stacked ? "100%" : "auto",
20000
+ textAlign: stacked ? "left" : "center",
20001
+ border: `1px solid ${primary ? ACCENT2 : BORDER4}`,
20002
+ background: primary ? ACCENT2 : "white",
20003
+ color: primary ? "white" : "var(--foreground)",
20004
+ borderRadius: 8,
20005
+ fontSize: 13,
20006
+ fontWeight: 600,
20007
+ padding: "9px 14px",
20008
+ cursor: "pointer",
20009
+ transition: "background 0.15s, border-color 0.15s, color 0.15s"
20010
+ },
20011
+ onMouseEnter: (e) => {
20012
+ if (primary) {
20013
+ e.currentTarget.style.background = ACCENT_SOFT2;
20014
+ } else {
20015
+ e.currentTarget.style.borderColor = ACCENT2;
20016
+ e.currentTarget.style.background = "#fafafa";
20017
+ }
20018
+ },
20019
+ onMouseLeave: (e) => {
20020
+ if (primary) {
20021
+ e.currentTarget.style.background = ACCENT2;
20022
+ } else {
20023
+ e.currentTarget.style.borderColor = BORDER4;
20024
+ e.currentTarget.style.background = "white";
20025
+ }
20026
+ },
20027
+ children: opt.label
20028
+ },
20029
+ (_a2 = opt.id) != null ? _a2 : opt.label
20030
+ );
20031
+ })
20032
+ }
20033
+ ),
20034
+ data.source && /* @__PURE__ */ jsxRuntime.jsxs(
20035
+ "button",
20036
+ {
20037
+ type: "button",
20038
+ onClick: onOpenSource,
20039
+ style: {
20040
+ alignSelf: "flex-start",
20041
+ display: "inline-flex",
20042
+ alignItems: "center",
20043
+ gap: 5,
20044
+ border: "none",
20045
+ background: "none",
20046
+ padding: 0,
20047
+ cursor: "pointer",
20048
+ fontSize: 12,
20049
+ fontWeight: 600,
20050
+ color: MUTED2,
20051
+ transition: "color 0.15s"
20052
+ },
20053
+ onMouseEnter: (e) => e.currentTarget.style.color = ACCENT2,
20054
+ onMouseLeave: (e) => e.currentTarget.style.color = MUTED2,
20055
+ children: [
20056
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { width: 13, height: 13, viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx(
20057
+ "path",
20058
+ {
20059
+ d: "M14 3v4a1 1 0 001 1h4M5 4a1 1 0 011-1h8l5 5v11a1 1 0 01-1 1H6a1 1 0 01-1-1V4z",
20060
+ stroke: "currentColor",
20061
+ strokeWidth: 1.8,
20062
+ strokeLinecap: "round",
20063
+ strokeLinejoin: "round"
20064
+ }
20065
+ ) }),
20066
+ (_b = data.source.label) != null ? _b : "View source for this figure"
20067
+ ]
20068
+ }
20069
+ )
20070
+ ] })
20071
+ ]
20072
+ }
20073
+ );
20074
+ }
20075
+ function DecisionCardResolver(p) {
20076
+ var _a, _b, _c, _d;
20077
+ const { resolvedDecisions, onDecisionResolve, onDecisionSource } = useGenUIInteraction();
20078
+ const decisionId = (_a = p.id) != null ? _a : p.title;
20079
+ const hostResolved = resolvedDecisions == null ? void 0 : resolvedDecisions[decisionId];
20080
+ const initial = (_c = hostResolved != null ? hostResolved : (_b = p.resolved) == null ? void 0 : _b.option) != null ? _c : null;
20081
+ const [localResolved, setLocalResolved] = React45__default.default.useState(initial);
20082
+ React45__default.default.useEffect(() => {
20083
+ if (hostResolved !== void 0) setLocalResolved(hostResolved);
20084
+ }, [hostResolved]);
20085
+ const resolved = hostResolved != null ? hostResolved : localResolved;
20086
+ const handleResolve = (option) => {
20087
+ setLocalResolved(option);
20088
+ onDecisionResolve == null ? void 0 : onDecisionResolve(decisionId, option);
20089
+ };
20090
+ const handleSource = () => {
20091
+ var _a2;
20092
+ onDecisionSource == null ? void 0 : onDecisionSource(decisionId, p.source);
20093
+ if (!onDecisionSource && ((_a2 = p.source) == null ? void 0 : _a2.url) && typeof window !== "undefined") {
20094
+ window.open(p.source.url, "_blank", "noopener,noreferrer");
20095
+ }
20096
+ };
20097
+ return /* @__PURE__ */ jsxRuntime.jsx(ComponentActions, { filename: (_d = p.title) != null ? _d : "decision-card", children: /* @__PURE__ */ jsxRuntime.jsx(
20098
+ DecisionCardRenderer,
20099
+ {
20100
+ data: p,
20101
+ resolved,
20102
+ onResolve: handleResolve,
20103
+ onOpenSource: handleSource
20104
+ }
20105
+ ) });
20106
+ }
17879
20107
  function resolveUI(rawPayload) {
17880
20108
  const payload = coercePayload(rawPayload);
17881
20109
  switch (payload.type) {
@@ -17993,6 +20221,10 @@ function resolveUI(rawPayload) {
17993
20221
  return /* @__PURE__ */ jsxRuntime.jsx(PipelinePreviewResolver, __spreadValues({}, payload));
17994
20222
  case "workflow-stepper":
17995
20223
  return /* @__PURE__ */ jsxRuntime.jsx(WorkflowStepperResolver, __spreadValues({}, payload));
20224
+ case "document-field-extraction":
20225
+ return /* @__PURE__ */ jsxRuntime.jsx(DocumentFieldExtractionResolver, __spreadValues({}, payload));
20226
+ case "decision-card":
20227
+ return /* @__PURE__ */ jsxRuntime.jsx(DecisionCardResolver, __spreadValues({}, payload));
17996
20228
  default: {
17997
20229
  return /* @__PURE__ */ jsxRuntime.jsx(
17998
20230
  "div",