@shapesos/clay 0.17.0 → 0.18.0

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 (80) hide show
  1. package/dist/ai-elements.cjs +3 -1
  2. package/dist/ai-elements.cjs.map +1 -1
  3. package/dist/ai-elements.js +4 -4
  4. package/dist/artifacts.cjs +963 -34
  5. package/dist/artifacts.cjs.map +1 -1
  6. package/dist/artifacts.d.cts +20 -3
  7. package/dist/artifacts.d.ts +20 -3
  8. package/dist/artifacts.js +13 -5
  9. package/dist/blocks.cjs +677 -50
  10. package/dist/blocks.cjs.map +1 -1
  11. package/dist/blocks.css +1 -1
  12. package/dist/blocks.d.cts +3 -3
  13. package/dist/blocks.d.ts +3 -3
  14. package/dist/blocks.js +5 -5
  15. package/dist/button.cjs +3 -1
  16. package/dist/button.cjs.map +1 -1
  17. package/dist/button.js +2 -2
  18. package/dist/capture.cjs +3 -1
  19. package/dist/capture.cjs.map +1 -1
  20. package/dist/capture.js +2 -2
  21. package/dist/chart.cjs +3 -1
  22. package/dist/chart.cjs.map +1 -1
  23. package/dist/chart.js +2 -2
  24. package/dist/chat.cjs +701 -74
  25. package/dist/chat.cjs.map +1 -1
  26. package/dist/chat.d.cts +2 -2
  27. package/dist/chat.d.ts +2 -2
  28. package/dist/chat.js +6 -6
  29. package/dist/{chunk-46ZYTBX5.js → chunk-7MY4X4YL.js} +3 -3
  30. package/dist/chunk-BHHJOG5X.js +1 -0
  31. package/dist/{chunk-B6GAPZ2R.js → chunk-CATIRDZP.js} +5 -5
  32. package/dist/{chunk-B4U37WIH.js → chunk-CFCLVJIO.js} +2 -2
  33. package/dist/{chunk-PYDVANWI.js → chunk-E36VI2HA.js} +2 -2
  34. package/dist/{chunk-PUVZ2S3F.js → chunk-G4NXVFXU.js} +2 -2
  35. package/dist/{chunk-JAGNXEWK.js → chunk-GK4XW4BC.js} +2 -2
  36. package/dist/{chunk-4VE6ZXXW.js → chunk-MQP57DOP.js} +3 -3
  37. package/dist/{chunk-6YZ65KPW.js → chunk-QR4VBGK4.js} +673 -42
  38. package/dist/chunk-QR4VBGK4.js.map +1 -0
  39. package/dist/{chunk-JF3P66JF.js → chunk-SN3ORQSJ.js} +4 -2
  40. package/dist/{chunk-JF3P66JF.js.map → chunk-SN3ORQSJ.js.map} +1 -1
  41. package/dist/{chunk-PGR2MDDU.js → chunk-W66OJM55.js} +2 -2
  42. package/dist/{chunk-7OYIDM42.js → chunk-XKURJ72I.js} +2 -2
  43. package/dist/{dom-to-image-NATF3446.js → dom-to-image-QB7KMTAE.js} +3 -3
  44. package/dist/icon.cjs +3 -1
  45. package/dist/icon.cjs.map +1 -1
  46. package/dist/icon.js +2 -2
  47. package/dist/index.cjs +767 -132
  48. package/dist/index.cjs.map +1 -1
  49. package/dist/index.d.cts +3 -3
  50. package/dist/index.d.ts +3 -3
  51. package/dist/index.js +19 -11
  52. package/dist/keyboard-shortcut.cjs +3 -1
  53. package/dist/keyboard-shortcut.cjs.map +1 -1
  54. package/dist/keyboard-shortcut.js +2 -2
  55. package/dist/text-area.cjs +3 -1
  56. package/dist/text-area.cjs.map +1 -1
  57. package/dist/text-area.js +2 -2
  58. package/dist/tokens.cjs +3 -1
  59. package/dist/tokens.cjs.map +1 -1
  60. package/dist/tokens.d.cts +1 -0
  61. package/dist/tokens.d.ts +1 -0
  62. package/dist/tokens.js +1 -1
  63. package/dist/{types-CW45GBXl.d.cts → types-BDYPVP2N.d.cts} +1 -1
  64. package/dist/{types-D1b8v7EY.d.ts → types-BMwa4bPW.d.ts} +1 -1
  65. package/dist/{types-GCkXbyFm.d.ts → types-C8JtnwNY.d.ts} +200 -4
  66. package/dist/{types-BzXPBy6s.d.cts → types-DTdDFU3O.d.cts} +200 -4
  67. package/package.json +1 -1
  68. package/dist/chunk-6YZ65KPW.js.map +0 -1
  69. package/dist/chunk-RSRNSWJN.js +0 -1
  70. /package/dist/{chunk-46ZYTBX5.js.map → chunk-7MY4X4YL.js.map} +0 -0
  71. /package/dist/{chunk-RSRNSWJN.js.map → chunk-BHHJOG5X.js.map} +0 -0
  72. /package/dist/{chunk-B6GAPZ2R.js.map → chunk-CATIRDZP.js.map} +0 -0
  73. /package/dist/{chunk-B4U37WIH.js.map → chunk-CFCLVJIO.js.map} +0 -0
  74. /package/dist/{chunk-PYDVANWI.js.map → chunk-E36VI2HA.js.map} +0 -0
  75. /package/dist/{chunk-PUVZ2S3F.js.map → chunk-G4NXVFXU.js.map} +0 -0
  76. /package/dist/{chunk-JAGNXEWK.js.map → chunk-GK4XW4BC.js.map} +0 -0
  77. /package/dist/{chunk-4VE6ZXXW.js.map → chunk-MQP57DOP.js.map} +0 -0
  78. /package/dist/{chunk-PGR2MDDU.js.map → chunk-W66OJM55.js.map} +0 -0
  79. /package/dist/{chunk-7OYIDM42.js.map → chunk-XKURJ72I.js.map} +0 -0
  80. /package/dist/{dom-to-image-NATF3446.js.map → dom-to-image-QB7KMTAE.js.map} +0 -0
package/dist/blocks.cjs CHANGED
@@ -128,7 +128,9 @@ var init_colors = __esm({
128
128
  "red-200": "#FECACA",
129
129
  "red-400": "#F7776C",
130
130
  "red-500": "#EF4444",
131
- "red-600": "#DC2626"
131
+ "red-600": "#DC2626",
132
+ // Deck
133
+ "deck-canvas": "#faf8f5"
132
134
  };
133
135
  }
134
136
  });
@@ -286,7 +288,8 @@ var blockTypes = {
286
288
  // src/components/artifacts/artifact-base.ts
287
289
  var artifactTypes = {
288
290
  TABLE: "TABLE",
289
- CHART: "CHART"
291
+ CHART: "CHART",
292
+ DECK: "DECK"
290
293
  };
291
294
 
292
295
  // src/components/artifacts/chart-artifact/types.ts
@@ -311,6 +314,34 @@ var DEFAULT_TABLE_ARTIFACT_LABELS = {
311
314
  empty: "No rows to display."
312
315
  };
313
316
 
317
+ // src/components/artifacts/deck-artifact/types.ts
318
+ var deckBlockTypes = {
319
+ TEXT: "TEXT",
320
+ CHART: "CHART",
321
+ TABLE: "TABLE"
322
+ };
323
+ var deckSlideKinds = {
324
+ TITLE: "TITLE",
325
+ AGENDA: "AGENDA",
326
+ SECTION: "SECTION",
327
+ CONTENT: "CONTENT",
328
+ CLOSING: "CLOSING"
329
+ };
330
+ var DEFAULT_DECK_ARTIFACT_LABELS = {
331
+ previous: "Previous slide",
332
+ next: "Next slide",
333
+ position: "Slide {current} of {total}",
334
+ download: "Download",
335
+ unavailable: "Deck content is unavailable.",
336
+ enterFullscreen: "Fullscreen",
337
+ exitFullscreen: "Exit fullscreen",
338
+ thankYou: "Thank you",
339
+ questions: "Questions?",
340
+ agenda: "Agenda",
341
+ chart: DEFAULT_CHART_ARTIFACT_LABELS,
342
+ table: DEFAULT_TABLE_ARTIFACT_LABELS
343
+ };
344
+
314
345
  // src/components/artifacts/chart-artifact/chart-artifact.tsx
315
346
  var import_react13 = require("react");
316
347
 
@@ -403,29 +434,45 @@ var createReactComponent = (type, iconName, iconNamePascal, iconNode) => {
403
434
  var __iconNode = [["path", { "d": "M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0", "key": "svg-0" }], ["path", { "d": "M12 8v4", "key": "svg-1" }], ["path", { "d": "M12 16h.01", "key": "svg-2" }]];
404
435
  var IconAlertCircle = createReactComponent("outline", "alert-circle", "AlertCircle", __iconNode);
405
436
 
437
+ // node_modules/@tabler/icons-react/dist/esm/icons/IconArrowsMaximize.mjs
438
+ var __iconNode2 = [["path", { "d": "M16 4l4 0l0 4", "key": "svg-0" }], ["path", { "d": "M14 10l6 -6", "key": "svg-1" }], ["path", { "d": "M8 20l-4 0l0 -4", "key": "svg-2" }], ["path", { "d": "M4 20l6 -6", "key": "svg-3" }], ["path", { "d": "M16 20l4 0l0 -4", "key": "svg-4" }], ["path", { "d": "M14 14l6 6", "key": "svg-5" }], ["path", { "d": "M8 4l-4 0l0 4", "key": "svg-6" }], ["path", { "d": "M4 4l6 6", "key": "svg-7" }]];
439
+ var IconArrowsMaximize = createReactComponent("outline", "arrows-maximize", "ArrowsMaximize", __iconNode2);
440
+
441
+ // node_modules/@tabler/icons-react/dist/esm/icons/IconArrowsMinimize.mjs
442
+ var __iconNode3 = [["path", { "d": "M5 9l4 0l0 -4", "key": "svg-0" }], ["path", { "d": "M3 3l6 6", "key": "svg-1" }], ["path", { "d": "M5 15l4 0l0 4", "key": "svg-2" }], ["path", { "d": "M3 21l6 -6", "key": "svg-3" }], ["path", { "d": "M19 9l-4 0l0 -4", "key": "svg-4" }], ["path", { "d": "M15 9l6 -6", "key": "svg-5" }], ["path", { "d": "M19 15l-4 0l0 4", "key": "svg-6" }], ["path", { "d": "M15 15l6 6", "key": "svg-7" }]];
443
+ var IconArrowsMinimize = createReactComponent("outline", "arrows-minimize", "ArrowsMinimize", __iconNode3);
444
+
406
445
  // node_modules/@tabler/icons-react/dist/esm/icons/IconCheck.mjs
407
- var __iconNode2 = [["path", { "d": "M5 12l5 5l10 -10", "key": "svg-0" }]];
408
- var IconCheck = createReactComponent("outline", "check", "Check", __iconNode2);
446
+ var __iconNode4 = [["path", { "d": "M5 12l5 5l10 -10", "key": "svg-0" }]];
447
+ var IconCheck = createReactComponent("outline", "check", "Check", __iconNode4);
448
+
449
+ // node_modules/@tabler/icons-react/dist/esm/icons/IconChevronLeft.mjs
450
+ var __iconNode5 = [["path", { "d": "M15 6l-6 6l6 6", "key": "svg-0" }]];
451
+ var IconChevronLeft = createReactComponent("outline", "chevron-left", "ChevronLeft", __iconNode5);
452
+
453
+ // node_modules/@tabler/icons-react/dist/esm/icons/IconChevronRight.mjs
454
+ var __iconNode6 = [["path", { "d": "M9 6l6 6l-6 6", "key": "svg-0" }]];
455
+ var IconChevronRight = createReactComponent("outline", "chevron-right", "ChevronRight", __iconNode6);
409
456
 
410
457
  // node_modules/@tabler/icons-react/dist/esm/icons/IconCopy.mjs
411
- var __iconNode3 = [["path", { "d": "M7 9.667a2.667 2.667 0 0 1 2.667 -2.667h8.666a2.667 2.667 0 0 1 2.667 2.667v8.666a2.667 2.667 0 0 1 -2.667 2.667h-8.666a2.667 2.667 0 0 1 -2.667 -2.667l0 -8.666", "key": "svg-0" }], ["path", { "d": "M4.012 16.737a2.005 2.005 0 0 1 -1.012 -1.737v-10c0 -1.1 .9 -2 2 -2h10c.75 0 1.158 .385 1.5 1", "key": "svg-1" }]];
412
- var IconCopy = createReactComponent("outline", "copy", "Copy", __iconNode3);
458
+ var __iconNode7 = [["path", { "d": "M7 9.667a2.667 2.667 0 0 1 2.667 -2.667h8.666a2.667 2.667 0 0 1 2.667 2.667v8.666a2.667 2.667 0 0 1 -2.667 2.667h-8.666a2.667 2.667 0 0 1 -2.667 -2.667l0 -8.666", "key": "svg-0" }], ["path", { "d": "M4.012 16.737a2.005 2.005 0 0 1 -1.012 -1.737v-10c0 -1.1 .9 -2 2 -2h10c.75 0 1.158 .385 1.5 1", "key": "svg-1" }]];
459
+ var IconCopy = createReactComponent("outline", "copy", "Copy", __iconNode7);
413
460
 
414
461
  // node_modules/@tabler/icons-react/dist/esm/icons/IconDownload.mjs
415
- var __iconNode4 = [["path", { "d": "M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2 -2v-2", "key": "svg-0" }], ["path", { "d": "M7 11l5 5l5 -5", "key": "svg-1" }], ["path", { "d": "M12 4l0 12", "key": "svg-2" }]];
416
- var IconDownload = createReactComponent("outline", "download", "Download", __iconNode4);
462
+ var __iconNode8 = [["path", { "d": "M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2 -2v-2", "key": "svg-0" }], ["path", { "d": "M7 11l5 5l5 -5", "key": "svg-1" }], ["path", { "d": "M12 4l0 12", "key": "svg-2" }]];
463
+ var IconDownload = createReactComponent("outline", "download", "Download", __iconNode8);
417
464
 
418
465
  // node_modules/@tabler/icons-react/dist/esm/icons/IconFileSpreadsheet.mjs
419
- var __iconNode5 = [["path", { "d": "M14 3v4a1 1 0 0 0 1 1h4", "key": "svg-0" }], ["path", { "d": "M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2", "key": "svg-1" }], ["path", { "d": "M8 11h8v7h-8l0 -7", "key": "svg-2" }], ["path", { "d": "M8 15h8", "key": "svg-3" }], ["path", { "d": "M11 11v7", "key": "svg-4" }]];
420
- var IconFileSpreadsheet = createReactComponent("outline", "file-spreadsheet", "FileSpreadsheet", __iconNode5);
466
+ var __iconNode9 = [["path", { "d": "M14 3v4a1 1 0 0 0 1 1h4", "key": "svg-0" }], ["path", { "d": "M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2", "key": "svg-1" }], ["path", { "d": "M8 11h8v7h-8l0 -7", "key": "svg-2" }], ["path", { "d": "M8 15h8", "key": "svg-3" }], ["path", { "d": "M11 11v7", "key": "svg-4" }]];
467
+ var IconFileSpreadsheet = createReactComponent("outline", "file-spreadsheet", "FileSpreadsheet", __iconNode9);
421
468
 
422
469
  // node_modules/@tabler/icons-react/dist/esm/icons/IconLoader2.mjs
423
- var __iconNode6 = [["path", { "d": "M12 3a9 9 0 1 0 9 9", "key": "svg-0" }]];
424
- var IconLoader2 = createReactComponent("outline", "loader-2", "Loader2", __iconNode6);
470
+ var __iconNode10 = [["path", { "d": "M12 3a9 9 0 1 0 9 9", "key": "svg-0" }]];
471
+ var IconLoader2 = createReactComponent("outline", "loader-2", "Loader2", __iconNode10);
425
472
 
426
473
  // node_modules/@tabler/icons-react/dist/esm/icons/IconPhoto.mjs
427
- var __iconNode7 = [["path", { "d": "M15 8h.01", "key": "svg-0" }], ["path", { "d": "M3 6a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v12a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3v-12", "key": "svg-1" }], ["path", { "d": "M3 16l5 -5c.928 -.893 2.072 -.893 3 0l5 5", "key": "svg-2" }], ["path", { "d": "M14 14l1 -1c.928 -.893 2.072 -.893 3 0l3 3", "key": "svg-3" }]];
428
- var IconPhoto = createReactComponent("outline", "photo", "Photo", __iconNode7);
474
+ var __iconNode11 = [["path", { "d": "M15 8h.01", "key": "svg-0" }], ["path", { "d": "M3 6a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v12a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3v-12", "key": "svg-1" }], ["path", { "d": "M3 16l5 -5c.928 -.893 2.072 -.893 3 0l5 5", "key": "svg-2" }], ["path", { "d": "M14 14l1 -1c.928 -.893 2.072 -.893 3 0l3 3", "key": "svg-3" }]];
475
+ var IconPhoto = createReactComponent("outline", "photo", "Photo", __iconNode11);
429
476
 
430
477
  // src/components/artifacts/artifact-copy-as-image-button/artifact-copy-as-image-button.tsx
431
478
  var import_react6 = require("react");
@@ -1998,8 +2045,13 @@ var ChartArtifactService = {
1998
2045
  toClipboardText: chartArtifactToClipboardText
1999
2046
  };
2000
2047
 
2001
- // src/components/artifacts/table-artifact/table-artifact.tsx
2002
- var import_react15 = require("react");
2048
+ // src/components/artifacts/deck-artifact/deck-artifact.tsx
2049
+ var import_react17 = require("react");
2050
+ var import_react_dom = require("react-dom");
2051
+ init_capture_exclude_attribute();
2052
+
2053
+ // src/components/artifacts/deck-artifact/deck-artifact-content.tsx
2054
+ var import_react16 = require("react");
2003
2055
 
2004
2056
  // src/components/ui/table.tsx
2005
2057
  var React3 = __toESM(require("react"), 1);
@@ -2146,9 +2198,333 @@ function renderEmptyRow(colSpan, emptyMessage) {
2146
2198
  return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TableRow, { className: "hover:bg-transparent", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TableCell, { colSpan, className: "py-6 text-center text-sm text-muted-foreground", children: emptyMessage }) });
2147
2199
  }
2148
2200
 
2149
- // src/components/artifacts/table-artifact/use-table-artifact-data.ts
2150
- function useTableArtifactData(presignedUrl, columns) {
2151
- return useRowsArtifactData(presignedUrl, columns, parseCsv);
2201
+ // src/components/artifacts/deck-artifact/deck-markdown.tsx
2202
+ var import_react_markdown = __toESM(require("react-markdown"), 1);
2203
+ var import_remark_breaks = __toESM(require("remark-breaks"), 1);
2204
+ var import_remark_gfm = __toESM(require("remark-gfm"), 1);
2205
+ var import_jsx_runtime22 = require("react/jsx-runtime");
2206
+ function sanitize(text) {
2207
+ return text.split("\n").filter((line) => {
2208
+ const t = line.trim();
2209
+ return !(t.startsWith("<!-- table-title:") && t.endsWith("-->"));
2210
+ }).join("\n");
2211
+ }
2212
+ var MARKDOWN_COMPONENTS = {
2213
+ h1: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h1", { className: "text-[30px] font-semibold leading-tight text-foreground mb-3", ...props }),
2214
+ h2: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h2", { className: "text-[26px] font-semibold leading-tight text-foreground mb-2", ...props }),
2215
+ h3: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h3", { className: "text-[24px] font-semibold leading-tight text-foreground mb-2", ...props }),
2216
+ h4: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h4", { className: "text-[24px] font-semibold leading-tight text-foreground mb-2", ...props }),
2217
+ h5: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h5", { className: "text-[24px] font-semibold leading-tight text-foreground mb-2", ...props }),
2218
+ h6: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h6", { className: "text-[24px] font-semibold leading-tight text-foreground mb-2", ...props }),
2219
+ p: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "text-[22px] leading-relaxed text-foreground my-2", ...props }),
2220
+ ul: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("ul", { className: "list-disc pl-7 text-[22px] leading-relaxed text-foreground my-2", ...props }),
2221
+ ol: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("ol", { className: "list-decimal pl-7 text-[22px] leading-relaxed text-foreground my-2", ...props }),
2222
+ // react-markdown injects list metadata (`ordered` / `index` / `checked`) that must not leak to the DOM.
2223
+ li: ({ node: _node, ordered: _ordered, index: _index, checked: _checked, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("li", { className: "my-1", ...props }),
2224
+ strong: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("strong", { className: "font-semibold", ...props }),
2225
+ em: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("em", { className: "italic", ...props }),
2226
+ // Gate `<img src>` against an http(s) allowlist. react-markdown v8 percent-encodes the URL but
2227
+ // does NOT protocol-filter image src (unlike link href), so an LLM-authored
2228
+ // `![](javascript:…)` / `![](data:…)` or a tracking-pixel `![](http://…)` would otherwise render
2229
+ // with the raw URL. Unsafe src → render nothing.
2230
+ img: ({ node: _node, src, ...props }) => typeof src === "string" && isSafeDownloadUrl(src) ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("img", { src, className: "max-w-full", ...props }) : null,
2231
+ a: ({ node: _node, ...props }) => (
2232
+ // `rel` is forced AFTER `{...props}` so it can't be overridden — if a consumer ever adds
2233
+ // `linkTarget="_blank"`, LLM-authored links still can't reach `window.opener`.
2234
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("a", { className: "underline underline-offset-2", ...props, rel: "noopener noreferrer" })
2235
+ ),
2236
+ // react-markdown passes `inline` to distinguish inline code from fenced blocks — strip it from the DOM.
2237
+ code: ({ node: _node, inline: _inline, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("code", { className: "rounded bg-muted px-1.5 py-0.5 font-mono text-[18px]", ...props }),
2238
+ blockquote: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("blockquote", { className: "border-l-2 border-brown-alpha-12 pl-4 text-[22px] text-muted-foreground", ...props }),
2239
+ hr: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("hr", { className: "my-4 border-brown-alpha-12", ...props }),
2240
+ table: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "overflow-x-auto", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("table", { className: "w-full border-collapse text-[20px]", ...props }) }),
2241
+ // react-markdown passes `isHeader` to cell renderers — strip it so it never reaches the DOM.
2242
+ th: ({ node: _node, isHeader: _isHeader, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("th", { className: "border-b border-brown-alpha-12 px-3 py-1.5 text-left font-medium", ...props }),
2243
+ td: ({ node: _node, isHeader: _isHeader, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("td", { className: "border-b border-brown-alpha-12 px-3 py-1.5", ...props })
2244
+ };
2245
+ function DeckMarkdown({ markdown }) {
2246
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_markdown.default, { remarkPlugins: [import_remark_gfm.default, import_remark_breaks.default], components: MARKDOWN_COMPONENTS, children: sanitize(markdown) });
2247
+ }
2248
+
2249
+ // src/components/artifacts/deck-artifact/slide-renderers.tsx
2250
+ var import_react15 = require("react");
2251
+ var import_jsx_runtime23 = require("react/jsx-runtime");
2252
+ function safeLogoUrl(meta) {
2253
+ return meta?.logoUrl && isSafeDownloadUrl(meta.logoUrl) ? meta.logoUrl : null;
2254
+ }
2255
+ var DESIGN_W = 1280;
2256
+ var DESIGN_H = 720;
2257
+ var EYEBROW_H = 84;
2258
+ var CANVAS_LOGO_MAX_H = 48;
2259
+ var ACCENT_FONT = { fontFamily: `"${fontFamilies.CRIMSON_PRO}", serif`, fontStyle: "italic" };
2260
+ function SlideFrame({ meta, children, accent = false, bare = false }) {
2261
+ const frameRef = (0, import_react15.useRef)(null);
2262
+ const [scale, setScale] = (0, import_react15.useState)(null);
2263
+ (0, import_react15.useLayoutEffect)(() => {
2264
+ const el = frameRef.current;
2265
+ if (!el) return;
2266
+ const apply = (width) => {
2267
+ if (width > 0) setScale(width / DESIGN_W);
2268
+ };
2269
+ apply(el.clientWidth);
2270
+ const ro = new ResizeObserver((entries) => apply(entries[0]?.contentRect.width ?? 0));
2271
+ ro.observe(el);
2272
+ return () => ro.disconnect();
2273
+ }, []);
2274
+ const bg = accent ? "bg-indigo-600" : "bg-deck-canvas";
2275
+ const eyebrowColor = accent ? "text-white/70" : "text-brown-60";
2276
+ const borderColor = accent ? "border-white/20" : "border-brown-alpha-12";
2277
+ const logoSrc = safeLogoUrl(meta);
2278
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { ref: frameRef, className: `relative aspect-[16/9] w-full overflow-hidden rounded-lg ${bg}`, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
2279
+ "div",
2280
+ {
2281
+ className: "absolute left-0 top-0 origin-top-left",
2282
+ style: {
2283
+ width: DESIGN_W,
2284
+ height: DESIGN_H,
2285
+ transform: `scale(${scale ?? 0})`,
2286
+ visibility: scale === null ? "hidden" : "visible"
2287
+ },
2288
+ children: [
2289
+ !bare ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
2290
+ "div",
2291
+ {
2292
+ className: `absolute inset-x-0 top-0 flex items-center justify-between border-b px-16 ${borderColor}`,
2293
+ style: { height: EYEBROW_H },
2294
+ children: [
2295
+ meta?.eyebrow ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: eyebrowColor, style: { ...ACCENT_FONT, fontSize: 22 }, children: meta.eyebrow }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", {}),
2296
+ logoSrc ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("img", { src: logoSrc, alt: "", className: "object-contain", style: { maxHeight: CANVAS_LOGO_MAX_H } }) : null
2297
+ ]
2298
+ }
2299
+ ) : null,
2300
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "absolute inset-x-0 bottom-0 overflow-hidden", style: { top: bare ? 0 : EYEBROW_H }, children })
2301
+ ]
2302
+ }
2303
+ ) });
2304
+ }
2305
+ function TitleSlide({ slide, meta }) {
2306
+ const logoSrc = safeLogoUrl(meta);
2307
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SlideFrame, { meta, bare: true, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex h-full flex-col justify-center px-24 py-16", children: [
2308
+ logoSrc ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
2309
+ "img",
2310
+ {
2311
+ src: logoSrc,
2312
+ alt: "",
2313
+ className: "mb-16 object-contain object-left",
2314
+ style: { maxHeight: 56, maxWidth: 380 }
2315
+ }
2316
+ ) : null,
2317
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
2318
+ "h1",
2319
+ {
2320
+ className: "font-bold tracking-tight text-brown-100",
2321
+ style: { fontSize: 92, lineHeight: 1.04, maxWidth: 1060 },
2322
+ children: slide.title
2323
+ }
2324
+ ),
2325
+ slide.subtitle ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "mt-7 text-brown-70", style: { ...ACCENT_FONT, fontSize: 34 }, children: slide.subtitle }) : null,
2326
+ slide.description ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "mt-4 leading-relaxed text-brown-70", style: { fontSize: 24, maxWidth: 880 }, children: slide.description }) : null,
2327
+ meta?.date ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "mt-10 text-brown-70", style: { ...ACCENT_FONT, fontSize: 30 }, children: meta.date }) : null
2328
+ ] }) });
2329
+ }
2330
+ function AgendaSlide({ slide, meta, labels }) {
2331
+ const items = slide.items ?? [];
2332
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SlideFrame, { meta, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "h-full px-24 py-14", children: [
2333
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h2", { className: "mb-10 font-bold text-brown-90", style: { fontSize: 40 }, children: slide.title || labels.agenda }),
2334
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex flex-col", children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-baseline gap-6 border-b border-brown-alpha-12 py-5", children: [
2335
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "shrink-0 text-indigo-600", style: { ...ACCENT_FONT, fontSize: 28, width: 64 }, children: String(i + 1).padStart(2, "0") }),
2336
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-brown-90", style: { fontSize: 28 }, children: item })
2337
+ ] }, i)) })
2338
+ ] }) });
2339
+ }
2340
+ function SectionSlide({ slide, meta }) {
2341
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SlideFrame, { meta, accent: true, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex h-full flex-col justify-center gap-6 px-24", children: [
2342
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h2", { className: "font-bold text-white", style: { fontSize: 72, lineHeight: 1.05, maxWidth: 940 }, children: slide.title }),
2343
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "mt-2 bg-white/50", style: { width: 96, height: 5 } })
2344
+ ] }) });
2345
+ }
2346
+ function ClosingSlide({ meta, labels }) {
2347
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SlideFrame, { meta, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex h-full flex-col items-center justify-center gap-6 px-24 text-center", children: [
2348
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h1", { className: "font-bold text-brown-100", style: { fontSize: 72 }, children: labels.thankYou }),
2349
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-indigo-600", style: { ...ACCENT_FONT, fontSize: 36 }, children: labels.questions })
2350
+ ] }) });
2351
+ }
2352
+
2353
+ // src/components/artifacts/deck-artifact/deck-artifact-content.tsx
2354
+ var import_jsx_runtime24 = require("react/jsx-runtime");
2355
+ var TABLE_BLOCK_MAX_SHIMMER_ROWS = 10;
2356
+ var TABLE_CHROME_RESERVE = 56;
2357
+ var VISUAL_FALLBACK_HEIGHT = 360;
2358
+ function DeckArtifactContent({
2359
+ slides,
2360
+ labels,
2361
+ onNavigate,
2362
+ meta,
2363
+ onDark = false,
2364
+ currentSlide,
2365
+ onSlideChange
2366
+ }) {
2367
+ const navBtnClass = onDark ? "[&_svg]:!text-white hover:!bg-white/20 disabled:opacity-40" : void 0;
2368
+ const navBtnSize = onDark ? "medium" : "small";
2369
+ const isControlled = currentSlide !== void 0;
2370
+ const [internalIndex, setInternalIndex] = (0, import_react16.useState)(0);
2371
+ const index = isControlled ? currentSlide : internalIndex;
2372
+ const current = Math.min(index, slides.length - 1);
2373
+ const slide = slides[current];
2374
+ const goTo = (0, import_react16.useCallback)(
2375
+ (next) => {
2376
+ const clamped = Math.max(0, Math.min(next, slides.length - 1));
2377
+ if (isControlled) onSlideChange?.(clamped);
2378
+ else setInternalIndex(clamped);
2379
+ onNavigate?.(clamped);
2380
+ },
2381
+ [slides.length, onNavigate, isControlled, onSlideChange]
2382
+ );
2383
+ const position = labels.position.replace("{current}", String(current + 1)).replace("{total}", String(slides.length));
2384
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-col gap-3 p-4", children: [
2385
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SlideDispatch, { slide, labels, meta }),
2386
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
2387
+ "div",
2388
+ {
2389
+ className: `flex items-center justify-between border-t pt-2 ${onDark ? "border-white/20" : "border-brown-alpha-12"}`,
2390
+ children: [
2391
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2392
+ IconButton,
2393
+ {
2394
+ icon: IconChevronLeft,
2395
+ size: navBtnSize,
2396
+ className: navBtnClass,
2397
+ "aria-label": labels.previous,
2398
+ disabled: current === 0,
2399
+ onClick: () => goTo(current - 1)
2400
+ }
2401
+ ),
2402
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: `text-xs font-medium ${onDark ? "text-white/70" : "text-brown-70"}`, children: position }),
2403
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2404
+ IconButton,
2405
+ {
2406
+ icon: IconChevronRight,
2407
+ size: navBtnSize,
2408
+ className: navBtnClass,
2409
+ "aria-label": labels.next,
2410
+ disabled: current === slides.length - 1,
2411
+ onClick: () => goTo(current + 1)
2412
+ }
2413
+ )
2414
+ ]
2415
+ }
2416
+ )
2417
+ ] });
2418
+ }
2419
+ function SlideDispatch({ slide, labels, meta }) {
2420
+ const kind = slide.kind ?? deckSlideKinds.CONTENT;
2421
+ switch (kind) {
2422
+ case deckSlideKinds.TITLE:
2423
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(TitleSlide, { slide, meta });
2424
+ case deckSlideKinds.AGENDA:
2425
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(AgendaSlide, { slide, meta, labels });
2426
+ case deckSlideKinds.SECTION:
2427
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SectionSlide, { slide, meta });
2428
+ case deckSlideKinds.CLOSING:
2429
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ClosingSlide, { meta, labels });
2430
+ case deckSlideKinds.CONTENT:
2431
+ default:
2432
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ContentSlide, { slide, meta, labels });
2433
+ }
2434
+ }
2435
+ function isVisualBlock(block) {
2436
+ return block.type === deckBlockTypes.CHART || block.type === deckBlockTypes.TABLE;
2437
+ }
2438
+ function ContentSlide({ slide, meta, labels }) {
2439
+ const content = slide.content ?? [];
2440
+ const visuals = content.filter(isVisualBlock);
2441
+ const texts = content.filter(
2442
+ (b) => b.type === deckBlockTypes.TEXT
2443
+ );
2444
+ if (visuals.length === 1 && texts.length > 0) {
2445
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SlideFrame, { meta, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex h-full items-stretch gap-12 px-16 py-12", children: [
2446
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "flex w-[42%] shrink-0 flex-col overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(AutoFit, { children: [
2447
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h3", { className: "mb-5 font-bold leading-tight text-foreground", style: { fontSize: 34 }, children: slide.title }),
2448
+ texts.map((block, i) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(DeckMarkdown, { markdown: block.markdown }, i))
2449
+ ] }) }),
2450
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "min-h-0 min-w-0 flex-1", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(FillVisual, { block: visuals[0], labels }) })
2451
+ ] }) });
2452
+ }
2453
+ if (visuals.length > 0) {
2454
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SlideFrame, { meta, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex h-full flex-col gap-5 px-16 py-10", children: [
2455
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h3", { className: "shrink-0 font-bold leading-tight text-foreground", style: { fontSize: 32 }, children: slide.title }),
2456
+ content.map(
2457
+ (block, i) => isVisualBlock(block) ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "min-h-0 min-w-0 flex-1", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(FillVisual, { block, labels }) }, i) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "shrink-0 overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(DeckMarkdown, { markdown: block.markdown }) }, i)
2458
+ )
2459
+ ] }) });
2460
+ }
2461
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SlideFrame, { meta, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "h-full px-24 py-12", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(AutoFit, { children: [
2462
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h3", { className: "mb-6 font-bold leading-tight text-foreground", style: { fontSize: 38 }, children: slide.title }),
2463
+ texts.map((block, i) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(DeckMarkdown, { markdown: block.markdown }, i))
2464
+ ] }) }) });
2465
+ }
2466
+ function AutoFit({ children }) {
2467
+ const boxRef = (0, import_react16.useRef)(null);
2468
+ const contentRef = (0, import_react16.useRef)(null);
2469
+ const [fit, setFit] = (0, import_react16.useState)({ scale: 1, height: 0 });
2470
+ (0, import_react16.useLayoutEffect)(() => {
2471
+ const boxEl = boxRef.current;
2472
+ const contentEl = contentRef.current;
2473
+ if (!boxEl || !contentEl) return;
2474
+ const measure = () => {
2475
+ const avail = boxEl.clientHeight;
2476
+ const natural = contentEl.offsetHeight;
2477
+ const scale = avail > 0 && natural > avail ? avail / natural : 1;
2478
+ setFit({ scale, height: natural * scale });
2479
+ };
2480
+ measure();
2481
+ const ro = new ResizeObserver(measure);
2482
+ ro.observe(boxEl);
2483
+ ro.observe(contentEl);
2484
+ return () => ro.disconnect();
2485
+ }, []);
2486
+ const scaled = fit.scale < 1;
2487
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { ref: boxRef, className: "flex h-full min-h-0 w-full flex-col justify-center overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { style: scaled ? { height: fit.height } : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2488
+ "div",
2489
+ {
2490
+ ref: contentRef,
2491
+ className: "w-full origin-top-left",
2492
+ style: scaled ? { transform: `scale(${fit.scale})` } : void 0,
2493
+ children
2494
+ }
2495
+ ) }) });
2496
+ }
2497
+ function FillVisual({ block, labels }) {
2498
+ const ref = (0, import_react16.useRef)(null);
2499
+ const [height, setHeight] = (0, import_react16.useState)(VISUAL_FALLBACK_HEIGHT);
2500
+ (0, import_react16.useLayoutEffect)(() => {
2501
+ const el = ref.current;
2502
+ if (!el) return;
2503
+ const apply = (h) => {
2504
+ if (h > 0) setHeight(h);
2505
+ };
2506
+ apply(el.clientHeight);
2507
+ const ro = new ResizeObserver((entries) => apply(entries[0]?.contentRect.height ?? 0));
2508
+ ro.observe(el);
2509
+ return () => ro.disconnect();
2510
+ }, []);
2511
+ const chartLabels = labels.chart ?? DEFAULT_CHART_ARTIFACT_LABELS;
2512
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { ref, className: "h-full min-h-0 w-full overflow-hidden", children: block.type === deckBlockTypes.CHART ? (
2513
+ // ChartArtifactContent assumes a non-empty rowset (the standalone ChartArtifact guards
2514
+ // `rows.length > 0` upstream); mirror that guard here so an empty inline chart shows the
2515
+ // localized empty status instead of a blank chart area.
2516
+ block.rows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(StatusMessage, { $tone: "info", children: chartLabels.empty }) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { style: { height }, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ChartArtifactContent, { config: block.config, rows: block.rows, labels: chartLabels }) })
2517
+ ) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2518
+ TableArtifactContent,
2519
+ {
2520
+ columns: block.config.columns,
2521
+ data: { status: "ready", rows: block.rows, error: null },
2522
+ knownRowCount: block.config.stats?.rowCount ?? block.rows.length,
2523
+ maxShimmerRows: TABLE_BLOCK_MAX_SHIMMER_ROWS,
2524
+ maxBodyHeight: Math.max(0, height - TABLE_CHROME_RESERVE),
2525
+ labels: labels.table ?? DEFAULT_TABLE_ARTIFACT_LABELS
2526
+ }
2527
+ ) });
2152
2528
  }
2153
2529
 
2154
2530
  // src/components/artifacts/table-artifact/validate.ts
@@ -2167,19 +2543,265 @@ function isValidTableColumn(column) {
2167
2543
  return true;
2168
2544
  }
2169
2545
 
2170
- // src/components/artifacts/table-artifact/table-artifact.tsx
2171
- var import_jsx_runtime22 = require("react/jsx-runtime");
2546
+ // src/components/artifacts/deck-artifact/validate.ts
2547
+ function isValidDeckConfig(config) {
2548
+ if (!config || typeof config !== "object") return false;
2549
+ const candidate = config;
2550
+ if (!Array.isArray(candidate.slides)) return false;
2551
+ if (candidate.slides.length === 0) return false;
2552
+ return candidate.slides.every(isValidDeckSlide);
2553
+ }
2554
+ function isValidDeckSlide(slide) {
2555
+ if (!slide || typeof slide !== "object") return false;
2556
+ const candidate = slide;
2557
+ if (typeof candidate.title !== "string") return false;
2558
+ const kind = typeof candidate.kind === "string" ? candidate.kind : deckSlideKinds.CONTENT;
2559
+ if (kind === deckSlideKinds.CONTENT && !Array.isArray(candidate.content)) return false;
2560
+ const content = Array.isArray(candidate.content) ? candidate.content : [];
2561
+ if (candidate.items != null) {
2562
+ if (!Array.isArray(candidate.items)) return false;
2563
+ if (!candidate.items.every((item) => typeof item === "string")) return false;
2564
+ }
2565
+ return content.every(isValidDeckBlock);
2566
+ }
2567
+ function isValidDeckBlock(block) {
2568
+ if (!block || typeof block !== "object") return false;
2569
+ const candidate = block;
2570
+ switch (candidate.type) {
2571
+ case deckBlockTypes.TEXT:
2572
+ return typeof candidate.markdown === "string";
2573
+ case deckBlockTypes.CHART:
2574
+ return isValidChartConfig(candidate.config) && Array.isArray(candidate.rows);
2575
+ case deckBlockTypes.TABLE:
2576
+ return isValidTableConfig(candidate.config) && Array.isArray(candidate.rows);
2577
+ default:
2578
+ return false;
2579
+ }
2580
+ }
2581
+
2582
+ // src/components/artifacts/deck-artifact/deck-artifact.tsx
2583
+ var import_jsx_runtime25 = require("react/jsx-runtime");
2172
2584
  var TITLE_CLASSES2 = "text-sm font-semibold text-foreground";
2585
+ function DeckArtifact({ artifact, labels, callbacks }) {
2586
+ const validConfig = isValidDeckConfig(artifact.config);
2587
+ const [isFullscreen, setIsFullscreen] = (0, import_react17.useState)(false);
2588
+ const [currentSlide, setCurrentSlide] = (0, import_react17.useState)(0);
2589
+ (0, import_react17.useEffect)(() => {
2590
+ if (validConfig) return;
2591
+ console.warn("[clay] DeckArtifact: malformed `config` \u2014 skipping render.");
2592
+ }, [validConfig]);
2593
+ (0, import_react17.useEffect)(() => {
2594
+ if (!isFullscreen) return;
2595
+ const handleKey = (e) => {
2596
+ if (e.key === "Escape") setIsFullscreen(false);
2597
+ };
2598
+ document.addEventListener("keydown", handleKey);
2599
+ const previousOverflow = document.documentElement.style.overflow;
2600
+ document.documentElement.style.overflow = "hidden";
2601
+ return () => {
2602
+ document.removeEventListener("keydown", handleKey);
2603
+ document.documentElement.style.overflow = previousOverflow;
2604
+ };
2605
+ }, [isFullscreen]);
2606
+ const resolvedLabels = (0, import_react17.useMemo)(
2607
+ () => ({
2608
+ ...DEFAULT_DECK_ARTIFACT_LABELS,
2609
+ ...labels ?? {},
2610
+ chart: { ...DEFAULT_CHART_ARTIFACT_LABELS, ...labels?.chart ?? {} },
2611
+ table: { ...DEFAULT_TABLE_ARTIFACT_LABELS, ...labels?.table ?? {} }
2612
+ }),
2613
+ [labels]
2614
+ );
2615
+ const onNavigate = callbacks?.onNavigate;
2616
+ const handleNavigate = onNavigate ? (slideIndex) => onNavigate(artifact, slideIndex) : void 0;
2617
+ const onDownload = callbacks?.onDownload;
2618
+ const handleDownload = onDownload ? () => onDownload(artifact) : void 0;
2619
+ const presignedUrl = artifact.protectedAsset?.presignedUrl ?? null;
2620
+ const showDownload = presignedUrl !== null && isSafeDownloadUrl(presignedUrl);
2621
+ const meta = artifact.config?.meta;
2622
+ const handleOpenFullscreen = () => setIsFullscreen(true);
2623
+ const handleCloseFullscreen = () => setIsFullscreen(false);
2624
+ const actions = /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(ArtifactActions, { ...{ [CAPTURE_EXCLUDE_ATTRIBUTE]: "" }, children: [
2625
+ showDownload ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ArtifactDownloadButton, { href: presignedUrl ?? "", label: resolvedLabels.download, onClick: handleDownload }) : null,
2626
+ validConfig ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2627
+ IconButton,
2628
+ {
2629
+ icon: IconArrowsMaximize,
2630
+ size: "small",
2631
+ "aria-label": resolvedLabels.enterFullscreen,
2632
+ onClick: handleOpenFullscreen
2633
+ }
2634
+ ) : null
2635
+ ] });
2636
+ if (!validConfig) {
2637
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Artifact, { className: "shadow-none w-full rounded-2xl bg-background/70", children: [
2638
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(ArtifactHeader, { className: "bg-background/70", children: [
2639
+ artifact.title ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ArtifactTitle, { className: TITLE_CLASSES2, children: artifact.title }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", {}),
2640
+ actions
2641
+ ] }),
2642
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ArtifactContent, { className: "p-0", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(StatusMessage, { $tone: "info", children: resolvedLabels.unavailable }) })
2643
+ ] });
2644
+ }
2645
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
2646
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Artifact, { className: "shadow-none w-full rounded-2xl bg-background/70", children: [
2647
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(ArtifactHeader, { className: "bg-background/70", children: [
2648
+ artifact.title ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ArtifactTitle, { className: TITLE_CLASSES2, children: artifact.title }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", {}),
2649
+ actions
2650
+ ] }),
2651
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ArtifactContent, { className: "p-0", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2652
+ DeckArtifactContent,
2653
+ {
2654
+ slides: artifact.config.slides,
2655
+ labels: resolvedLabels,
2656
+ onNavigate: handleNavigate,
2657
+ meta,
2658
+ currentSlide,
2659
+ onSlideChange: setCurrentSlide
2660
+ }
2661
+ ) })
2662
+ ] }),
2663
+ isFullscreen && (0, import_react_dom.createPortal)(
2664
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2665
+ FullscreenOverlay,
2666
+ {
2667
+ artifact,
2668
+ resolvedLabels,
2669
+ onNavigate: handleNavigate,
2670
+ currentSlide,
2671
+ onSlideChange: setCurrentSlide,
2672
+ onClose: handleCloseFullscreen
2673
+ }
2674
+ ),
2675
+ document.body
2676
+ )
2677
+ ] });
2678
+ }
2679
+ function FullscreenOverlay({
2680
+ artifact,
2681
+ resolvedLabels,
2682
+ onNavigate,
2683
+ currentSlide,
2684
+ onSlideChange,
2685
+ onClose
2686
+ }) {
2687
+ const meta = artifact.config?.meta;
2688
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2689
+ "div",
2690
+ {
2691
+ className: "fixed inset-0 z-[2147483647] flex items-center justify-center bg-black/80",
2692
+ role: "dialog",
2693
+ "aria-modal": "true",
2694
+ "aria-label": resolvedLabels.exitFullscreen,
2695
+ children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "relative", style: { width: "min(94vw, calc(82vh * 16 / 9))" }, children: [
2696
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2697
+ DeckArtifactContent,
2698
+ {
2699
+ slides: artifact.config.slides,
2700
+ labels: resolvedLabels,
2701
+ onNavigate,
2702
+ meta,
2703
+ currentSlide,
2704
+ onSlideChange,
2705
+ onDark: true
2706
+ }
2707
+ ),
2708
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
2709
+ "button",
2710
+ {
2711
+ className: "absolute -top-10 right-6 flex items-center gap-1.5 text-sm text-white/80 hover:text-white",
2712
+ "aria-label": resolvedLabels.exitFullscreen,
2713
+ onClick: onClose,
2714
+ children: [
2715
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(IconArrowsMinimize, { size: 16 }),
2716
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { children: resolvedLabels.exitFullscreen })
2717
+ ]
2718
+ }
2719
+ )
2720
+ ] })
2721
+ }
2722
+ );
2723
+ }
2724
+
2725
+ // src/components/artifacts/deck-artifact/to-clipboard-text.ts
2726
+ function deckArtifactToClipboardText(artifact) {
2727
+ const header = artifact.title?.trim() || "Deck";
2728
+ const slides = artifact.config?.slides ?? [];
2729
+ const body = slides.map((slide, i) => slideToText(slide, i)).join("\n\n");
2730
+ return body ? `${header}
2731
+
2732
+ ${body}` : header;
2733
+ }
2734
+ function slideToText(slide, index) {
2735
+ const kind = slide.kind ?? deckSlideKinds.CONTENT;
2736
+ const prefix = `Slide ${index + 1}: `;
2737
+ switch (kind) {
2738
+ case deckSlideKinds.TITLE: {
2739
+ const parts = [slide.title];
2740
+ if (slide.subtitle) parts.push(slide.subtitle);
2741
+ if (slide.description) parts.push(slide.description);
2742
+ return `${prefix}${parts.join(" \u2014 ")}`.trim();
2743
+ }
2744
+ case deckSlideKinds.AGENDA: {
2745
+ const items = (slide.items ?? []).map((item, i) => ` ${String(i + 1).padStart(2, "0")}. ${item}`).join("\n");
2746
+ return `${prefix}${slide.title || "Agenda"}${items ? `
2747
+ ${items}` : ""}`.trim();
2748
+ }
2749
+ case deckSlideKinds.SECTION:
2750
+ return `${prefix}${slide.title}`.trim();
2751
+ case deckSlideKinds.CLOSING:
2752
+ return `${prefix}Thank you`.trim();
2753
+ case deckSlideKinds.CONTENT:
2754
+ default: {
2755
+ const blocks = (slide.content ?? []).map(blockToText).filter(Boolean).join("\n\n");
2756
+ return `${prefix}${slide.title}${blocks ? `
2757
+ ${blocks}` : ""}`.trim();
2758
+ }
2759
+ }
2760
+ }
2761
+ function blockToText(block) {
2762
+ switch (block.type) {
2763
+ case deckBlockTypes.TEXT:
2764
+ return block.markdown.trim();
2765
+ case deckBlockTypes.CHART:
2766
+ return `[Chart: ${block.config.variant}]`;
2767
+ case deckBlockTypes.TABLE: {
2768
+ const columnCount = block.config.columns.length;
2769
+ const rowCount = block.rows.length;
2770
+ return `[Table: ${columnCount} column${columnCount === 1 ? "" : "s"} \xD7 ${rowCount} row${rowCount === 1 ? "" : "s"}]`;
2771
+ }
2772
+ default:
2773
+ return "";
2774
+ }
2775
+ }
2776
+
2777
+ // src/components/artifacts/artifact-services/deck-artifact-service.ts
2778
+ var DeckArtifactService = {
2779
+ type: artifactTypes.DECK,
2780
+ Component: DeckArtifact,
2781
+ toClipboardText: deckArtifactToClipboardText
2782
+ };
2783
+
2784
+ // src/components/artifacts/table-artifact/table-artifact.tsx
2785
+ var import_react18 = require("react");
2786
+
2787
+ // src/components/artifacts/table-artifact/use-table-artifact-data.ts
2788
+ function useTableArtifactData(presignedUrl, columns) {
2789
+ return useRowsArtifactData(presignedUrl, columns, parseCsv);
2790
+ }
2791
+
2792
+ // src/components/artifacts/table-artifact/table-artifact.tsx
2793
+ var import_jsx_runtime26 = require("react/jsx-runtime");
2794
+ var TITLE_CLASSES3 = "text-sm font-semibold text-foreground";
2173
2795
  var TABLE_MAX_BODY_HEIGHT = 480;
2174
2796
  var MAX_SHIMMER_ROWS = 10;
2175
2797
  function TableArtifact({ artifact, labels, callbacks }) {
2176
2798
  const validConfig = isValidTableConfig(artifact.config);
2177
2799
  const validColumns = validConfig ? artifact.config.columns : null;
2178
- (0, import_react15.useEffect)(() => {
2800
+ (0, import_react18.useEffect)(() => {
2179
2801
  if (validConfig) return;
2180
2802
  console.warn("[clay] TableArtifact: malformed `config` \u2014 skipping render.");
2181
2803
  }, [validConfig]);
2182
- const resolvedLabels = (0, import_react15.useMemo)(
2804
+ const resolvedLabels = (0, import_react18.useMemo)(
2183
2805
  () => ({ ...DEFAULT_TABLE_ARTIFACT_LABELS, ...labels ?? {} }),
2184
2806
  [labels]
2185
2807
  );
@@ -2191,10 +2813,10 @@ function TableArtifact({ artifact, labels, callbacks }) {
2191
2813
  const onDownload = callbacks?.onDownload;
2192
2814
  const handleDownloadClick = onDownload ? () => onDownload(artifact) : void 0;
2193
2815
  if (!validConfig || !validColumns) {
2194
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(Artifact, { className: "shadow-none w-full rounded-2xl bg-background/70", children: [
2195
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(ArtifactHeader, { className: "bg-background/70", children: [
2196
- artifact.title ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ArtifactTitle, { className: TITLE_CLASSES2, children: artifact.title }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", {}),
2197
- presignedUrl ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ArtifactActions, { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2816
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(Artifact, { className: "shadow-none w-full rounded-2xl bg-background/70", children: [
2817
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(ArtifactHeader, { className: "bg-background/70", children: [
2818
+ artifact.title ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ArtifactTitle, { className: TITLE_CLASSES3, children: artifact.title }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", {}),
2819
+ presignedUrl ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ArtifactActions, { children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2198
2820
  ArtifactDownloadButton,
2199
2821
  {
2200
2822
  href: presignedUrl,
@@ -2203,17 +2825,17 @@ function TableArtifact({ artifact, labels, callbacks }) {
2203
2825
  }
2204
2826
  ) }) : null
2205
2827
  ] }),
2206
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ArtifactContent, { className: "p-0 overflow-auto", style: { maxHeight: TABLE_MAX_BODY_HEIGHT }, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(StatusMessage, { $tone: "info", children: resolvedLabels.unavailable }) })
2828
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ArtifactContent, { className: "p-0 overflow-auto", style: { maxHeight: TABLE_MAX_BODY_HEIGHT }, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(StatusMessage, { $tone: "info", children: resolvedLabels.unavailable }) })
2207
2829
  ] });
2208
2830
  }
2209
2831
  return (
2210
2832
  // The table body owns its own scroll container (`ArtifactTable` inside `TableArtifactContent`).
2211
2833
  // Disable the outer overflow container so only one scroll context exists — this prevents
2212
2834
  // double-scroll nesting and lets `useScrollShadow` find the correct scroll ancestor.
2213
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(Artifact, { className: "shadow-none w-full rounded-2xl bg-background/70", children: [
2214
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(ArtifactHeader, { className: "bg-background/70", children: [
2215
- artifact.title ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ArtifactTitle, { className: TITLE_CLASSES2, children: artifact.title }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", {}),
2216
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ArtifactActions, { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2835
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(Artifact, { className: "shadow-none w-full rounded-2xl bg-background/70", children: [
2836
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(ArtifactHeader, { className: "bg-background/70", children: [
2837
+ artifact.title ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ArtifactTitle, { className: TITLE_CLASSES3, children: artifact.title }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", {}),
2838
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ArtifactActions, { children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2217
2839
  ArtifactDownloadButton,
2218
2840
  {
2219
2841
  href: presignedUrl ?? "",
@@ -2222,7 +2844,7 @@ function TableArtifact({ artifact, labels, callbacks }) {
2222
2844
  }
2223
2845
  ) })
2224
2846
  ] }),
2225
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ArtifactContent, { className: "p-0 overflow-visible", style: { maxHeight: "none" }, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2847
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ArtifactContent, { className: "p-0 overflow-visible", style: { maxHeight: "none" }, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2226
2848
  TableArtifactContent,
2227
2849
  {
2228
2850
  columns: validColumns,
@@ -2253,7 +2875,8 @@ var TableArtifactService = {
2253
2875
  // src/components/artifacts/artifact-services/index.ts
2254
2876
  var ArtifactServices = {
2255
2877
  [artifactTypes.TABLE]: TableArtifactService,
2256
- [artifactTypes.CHART]: ChartArtifactService
2878
+ [artifactTypes.CHART]: ChartArtifactService,
2879
+ [artifactTypes.DECK]: DeckArtifactService
2257
2880
  };
2258
2881
  function artifactToClipboardText(artifact) {
2259
2882
  const entry = ArtifactServices[artifact.type];
@@ -2264,13 +2887,13 @@ function artifactToClipboardText(artifact) {
2264
2887
  }
2265
2888
 
2266
2889
  // src/components/blocks/artifact-ref-block/artifact-ref-block.tsx
2267
- var import_jsx_runtime23 = require("react/jsx-runtime");
2890
+ var import_jsx_runtime27 = require("react/jsx-runtime");
2268
2891
  function ArtifactRefBlock({ block }) {
2269
2892
  const { artifact, labels, callbacks } = block.payload;
2270
2893
  const entry = ArtifactServices[artifact.type];
2271
2894
  if (!entry) return null;
2272
2895
  const Component = entry.Component;
2273
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Component, { artifact, labels, callbacks });
2896
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Component, { artifact, labels, callbacks });
2274
2897
  }
2275
2898
 
2276
2899
  // src/components/blocks/block-services/artifact-ref-block-service.ts
@@ -2305,9 +2928,9 @@ function markdownToPlainText(markdown) {
2305
2928
  }
2306
2929
 
2307
2930
  // src/components/blocks/text-block/text-block.tsx
2308
- var import_react_markdown = __toESM(require("react-markdown"), 1);
2309
- var import_remark_breaks = __toESM(require("remark-breaks"), 1);
2310
- var import_remark_gfm = __toESM(require("remark-gfm"), 1);
2931
+ var import_react_markdown2 = __toESM(require("react-markdown"), 1);
2932
+ var import_remark_breaks2 = __toESM(require("remark-breaks"), 1);
2933
+ var import_remark_gfm2 = __toESM(require("remark-gfm"), 1);
2311
2934
 
2312
2935
  // src/components/blocks/scrollable-table/scrollable-table-styles.ts
2313
2936
  var import_styled_components3 = __toESM(require("styled-components"), 1);
@@ -2322,13 +2945,13 @@ var TableScroll = import_styled_components3.default.div`
2322
2945
  `;
2323
2946
 
2324
2947
  // src/components/blocks/scrollable-table/scrollable-table.tsx
2325
- var import_jsx_runtime24 = require("react/jsx-runtime");
2948
+ var import_jsx_runtime28 = require("react/jsx-runtime");
2326
2949
  function ScrollableTable({ node: _node, ...props }) {
2327
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(TableContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(TableScroll, { children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("table", { ...props }) }) });
2950
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(TableContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(TableScroll, { children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("table", { ...props }) }) });
2328
2951
  }
2329
2952
 
2330
2953
  // src/components/blocks/text-block/sanitize.ts
2331
- function sanitize(text) {
2954
+ function sanitize2(text) {
2332
2955
  return text.split("\n").filter((line) => {
2333
2956
  const t = line.trim();
2334
2957
  return !(t.startsWith("<!-- table-title:") && t.endsWith("-->"));
@@ -2468,12 +3091,12 @@ var TextBlockWrapper = import_styled_components4.default.div`
2468
3091
  `;
2469
3092
 
2470
3093
  // src/components/blocks/text-block/text-block.tsx
2471
- var import_jsx_runtime25 = require("react/jsx-runtime");
3094
+ var import_jsx_runtime29 = require("react/jsx-runtime");
2472
3095
  var markdownComponents = {
2473
- table: ((tableProps) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ScrollableTable, { ...tableProps }))
3096
+ table: ((tableProps) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(ScrollableTable, { ...tableProps }))
2474
3097
  };
2475
3098
  function TextBlock({ block }) {
2476
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TextBlockWrapper, { children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react_markdown.default, { remarkPlugins: [import_remark_gfm.default, import_remark_breaks.default], components: markdownComponents, children: sanitize(block.payload.text) }) });
3099
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(TextBlockWrapper, { children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_react_markdown2.default, { remarkPlugins: [import_remark_gfm2.default, import_remark_breaks2.default], components: markdownComponents, children: sanitize2(block.payload.text) }) });
2477
3100
  }
2478
3101
 
2479
3102
  // src/components/blocks/block-services/text-block-service.ts
@@ -2495,19 +3118,19 @@ var BlockServices = {
2495
3118
  };
2496
3119
 
2497
3120
  // src/components/blocks/block/block.tsx
2498
- var import_jsx_runtime26 = require("react/jsx-runtime");
3121
+ var import_jsx_runtime30 = require("react/jsx-runtime");
2499
3122
  function Block({ block }) {
2500
3123
  const service = BlockServices[block.type];
2501
3124
  if (!service) return null;
2502
3125
  const { Component } = service;
2503
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Component, { block });
3126
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(Component, { block });
2504
3127
  }
2505
3128
 
2506
3129
  // src/components/blocks/block-context/block-context.tsx
2507
- var import_react16 = require("react");
2508
- var BlockContext = (0, import_react16.createContext)(null);
3130
+ var import_react19 = require("react");
3131
+ var BlockContext = (0, import_react19.createContext)(null);
2509
3132
  function useBlockContext() {
2510
- return (0, import_react16.useContext)(BlockContext) ?? {};
3133
+ return (0, import_react19.useContext)(BlockContext) ?? {};
2511
3134
  }
2512
3135
  // Annotate the CommonJS export names for ESM import in node:
2513
3136
  0 && (module.exports = {
@@ -2525,7 +3148,11 @@ function useBlockContext() {
2525
3148
  @tabler/icons-react/dist/esm/defaultAttributes.mjs:
2526
3149
  @tabler/icons-react/dist/esm/createReactComponent.mjs:
2527
3150
  @tabler/icons-react/dist/esm/icons/IconAlertCircle.mjs:
3151
+ @tabler/icons-react/dist/esm/icons/IconArrowsMaximize.mjs:
3152
+ @tabler/icons-react/dist/esm/icons/IconArrowsMinimize.mjs:
2528
3153
  @tabler/icons-react/dist/esm/icons/IconCheck.mjs:
3154
+ @tabler/icons-react/dist/esm/icons/IconChevronLeft.mjs:
3155
+ @tabler/icons-react/dist/esm/icons/IconChevronRight.mjs:
2529
3156
  @tabler/icons-react/dist/esm/icons/IconCopy.mjs:
2530
3157
  @tabler/icons-react/dist/esm/icons/IconDownload.mjs:
2531
3158
  @tabler/icons-react/dist/esm/icons/IconFileSpreadsheet.mjs: