@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.
- package/dist/ai-elements.cjs +3 -1
- package/dist/ai-elements.cjs.map +1 -1
- package/dist/ai-elements.js +4 -4
- package/dist/artifacts.cjs +963 -34
- package/dist/artifacts.cjs.map +1 -1
- package/dist/artifacts.d.cts +20 -3
- package/dist/artifacts.d.ts +20 -3
- package/dist/artifacts.js +13 -5
- package/dist/blocks.cjs +677 -50
- package/dist/blocks.cjs.map +1 -1
- package/dist/blocks.css +1 -1
- package/dist/blocks.d.cts +3 -3
- package/dist/blocks.d.ts +3 -3
- package/dist/blocks.js +5 -5
- package/dist/button.cjs +3 -1
- package/dist/button.cjs.map +1 -1
- package/dist/button.js +2 -2
- package/dist/capture.cjs +3 -1
- package/dist/capture.cjs.map +1 -1
- package/dist/capture.js +2 -2
- package/dist/chart.cjs +3 -1
- package/dist/chart.cjs.map +1 -1
- package/dist/chart.js +2 -2
- package/dist/chat.cjs +701 -74
- package/dist/chat.cjs.map +1 -1
- package/dist/chat.d.cts +2 -2
- package/dist/chat.d.ts +2 -2
- package/dist/chat.js +6 -6
- package/dist/{chunk-46ZYTBX5.js → chunk-7MY4X4YL.js} +3 -3
- package/dist/chunk-BHHJOG5X.js +1 -0
- package/dist/{chunk-B6GAPZ2R.js → chunk-CATIRDZP.js} +5 -5
- package/dist/{chunk-B4U37WIH.js → chunk-CFCLVJIO.js} +2 -2
- package/dist/{chunk-PYDVANWI.js → chunk-E36VI2HA.js} +2 -2
- package/dist/{chunk-PUVZ2S3F.js → chunk-G4NXVFXU.js} +2 -2
- package/dist/{chunk-JAGNXEWK.js → chunk-GK4XW4BC.js} +2 -2
- package/dist/{chunk-4VE6ZXXW.js → chunk-MQP57DOP.js} +3 -3
- package/dist/{chunk-6YZ65KPW.js → chunk-QR4VBGK4.js} +673 -42
- package/dist/chunk-QR4VBGK4.js.map +1 -0
- package/dist/{chunk-JF3P66JF.js → chunk-SN3ORQSJ.js} +4 -2
- package/dist/{chunk-JF3P66JF.js.map → chunk-SN3ORQSJ.js.map} +1 -1
- package/dist/{chunk-PGR2MDDU.js → chunk-W66OJM55.js} +2 -2
- package/dist/{chunk-7OYIDM42.js → chunk-XKURJ72I.js} +2 -2
- package/dist/{dom-to-image-NATF3446.js → dom-to-image-QB7KMTAE.js} +3 -3
- package/dist/icon.cjs +3 -1
- package/dist/icon.cjs.map +1 -1
- package/dist/icon.js +2 -2
- package/dist/index.cjs +767 -132
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +19 -11
- package/dist/keyboard-shortcut.cjs +3 -1
- package/dist/keyboard-shortcut.cjs.map +1 -1
- package/dist/keyboard-shortcut.js +2 -2
- package/dist/text-area.cjs +3 -1
- package/dist/text-area.cjs.map +1 -1
- package/dist/text-area.js +2 -2
- package/dist/tokens.cjs +3 -1
- package/dist/tokens.cjs.map +1 -1
- package/dist/tokens.d.cts +1 -0
- package/dist/tokens.d.ts +1 -0
- package/dist/tokens.js +1 -1
- package/dist/{types-CW45GBXl.d.cts → types-BDYPVP2N.d.cts} +1 -1
- package/dist/{types-D1b8v7EY.d.ts → types-BMwa4bPW.d.ts} +1 -1
- package/dist/{types-GCkXbyFm.d.ts → types-C8JtnwNY.d.ts} +200 -4
- package/dist/{types-BzXPBy6s.d.cts → types-DTdDFU3O.d.cts} +200 -4
- package/package.json +1 -1
- package/dist/chunk-6YZ65KPW.js.map +0 -1
- package/dist/chunk-RSRNSWJN.js +0 -1
- /package/dist/{chunk-46ZYTBX5.js.map → chunk-7MY4X4YL.js.map} +0 -0
- /package/dist/{chunk-RSRNSWJN.js.map → chunk-BHHJOG5X.js.map} +0 -0
- /package/dist/{chunk-B6GAPZ2R.js.map → chunk-CATIRDZP.js.map} +0 -0
- /package/dist/{chunk-B4U37WIH.js.map → chunk-CFCLVJIO.js.map} +0 -0
- /package/dist/{chunk-PYDVANWI.js.map → chunk-E36VI2HA.js.map} +0 -0
- /package/dist/{chunk-PUVZ2S3F.js.map → chunk-G4NXVFXU.js.map} +0 -0
- /package/dist/{chunk-JAGNXEWK.js.map → chunk-GK4XW4BC.js.map} +0 -0
- /package/dist/{chunk-4VE6ZXXW.js.map → chunk-MQP57DOP.js.map} +0 -0
- /package/dist/{chunk-PGR2MDDU.js.map → chunk-W66OJM55.js.map} +0 -0
- /package/dist/{chunk-7OYIDM42.js.map → chunk-XKURJ72I.js.map} +0 -0
- /package/dist/{dom-to-image-NATF3446.js.map → dom-to-image-QB7KMTAE.js.map} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
IconButton
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-E36VI2HA.js";
|
|
4
4
|
import {
|
|
5
5
|
CAPTURE_EXCLUDE_ATTRIBUTE
|
|
6
6
|
} from "./chunk-LXYCT4YO.js";
|
|
@@ -8,7 +8,10 @@ import {
|
|
|
8
8
|
BarChart,
|
|
9
9
|
LineChart,
|
|
10
10
|
PieChart
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-G4NXVFXU.js";
|
|
12
|
+
import {
|
|
13
|
+
fontFamilies
|
|
14
|
+
} from "./chunk-UXT2H3FM.js";
|
|
12
15
|
import {
|
|
13
16
|
Table,
|
|
14
17
|
TableBody,
|
|
@@ -25,7 +28,8 @@ import {
|
|
|
25
28
|
// src/components/artifacts/artifact-base.ts
|
|
26
29
|
var artifactTypes = {
|
|
27
30
|
TABLE: "TABLE",
|
|
28
|
-
CHART: "CHART"
|
|
31
|
+
CHART: "CHART",
|
|
32
|
+
DECK: "DECK"
|
|
29
33
|
};
|
|
30
34
|
|
|
31
35
|
// src/components/artifacts/chart-artifact/types.ts
|
|
@@ -50,6 +54,34 @@ var DEFAULT_TABLE_ARTIFACT_LABELS = {
|
|
|
50
54
|
empty: "No rows to display."
|
|
51
55
|
};
|
|
52
56
|
|
|
57
|
+
// src/components/artifacts/deck-artifact/types.ts
|
|
58
|
+
var deckBlockTypes = {
|
|
59
|
+
TEXT: "TEXT",
|
|
60
|
+
CHART: "CHART",
|
|
61
|
+
TABLE: "TABLE"
|
|
62
|
+
};
|
|
63
|
+
var deckSlideKinds = {
|
|
64
|
+
TITLE: "TITLE",
|
|
65
|
+
AGENDA: "AGENDA",
|
|
66
|
+
SECTION: "SECTION",
|
|
67
|
+
CONTENT: "CONTENT",
|
|
68
|
+
CLOSING: "CLOSING"
|
|
69
|
+
};
|
|
70
|
+
var DEFAULT_DECK_ARTIFACT_LABELS = {
|
|
71
|
+
previous: "Previous slide",
|
|
72
|
+
next: "Next slide",
|
|
73
|
+
position: "Slide {current} of {total}",
|
|
74
|
+
download: "Download",
|
|
75
|
+
unavailable: "Deck content is unavailable.",
|
|
76
|
+
enterFullscreen: "Fullscreen",
|
|
77
|
+
exitFullscreen: "Exit fullscreen",
|
|
78
|
+
thankYou: "Thank you",
|
|
79
|
+
questions: "Questions?",
|
|
80
|
+
agenda: "Agenda",
|
|
81
|
+
chart: DEFAULT_CHART_ARTIFACT_LABELS,
|
|
82
|
+
table: DEFAULT_TABLE_ARTIFACT_LABELS
|
|
83
|
+
};
|
|
84
|
+
|
|
53
85
|
// node_modules/@tabler/icons-react/dist/esm/createReactComponent.mjs
|
|
54
86
|
import { forwardRef, createElement } from "react";
|
|
55
87
|
|
|
@@ -110,37 +142,53 @@ var createReactComponent = (type, iconName, iconNamePascal, iconNode) => {
|
|
|
110
142
|
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" }]];
|
|
111
143
|
var IconAlertCircle = createReactComponent("outline", "alert-circle", "AlertCircle", __iconNode);
|
|
112
144
|
|
|
145
|
+
// node_modules/@tabler/icons-react/dist/esm/icons/IconArrowsMaximize.mjs
|
|
146
|
+
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" }]];
|
|
147
|
+
var IconArrowsMaximize = createReactComponent("outline", "arrows-maximize", "ArrowsMaximize", __iconNode2);
|
|
148
|
+
|
|
149
|
+
// node_modules/@tabler/icons-react/dist/esm/icons/IconArrowsMinimize.mjs
|
|
150
|
+
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" }]];
|
|
151
|
+
var IconArrowsMinimize = createReactComponent("outline", "arrows-minimize", "ArrowsMinimize", __iconNode3);
|
|
152
|
+
|
|
113
153
|
// node_modules/@tabler/icons-react/dist/esm/icons/IconCheck.mjs
|
|
114
|
-
var
|
|
115
|
-
var IconCheck = createReactComponent("outline", "check", "Check",
|
|
154
|
+
var __iconNode4 = [["path", { "d": "M5 12l5 5l10 -10", "key": "svg-0" }]];
|
|
155
|
+
var IconCheck = createReactComponent("outline", "check", "Check", __iconNode4);
|
|
156
|
+
|
|
157
|
+
// node_modules/@tabler/icons-react/dist/esm/icons/IconChevronLeft.mjs
|
|
158
|
+
var __iconNode5 = [["path", { "d": "M15 6l-6 6l6 6", "key": "svg-0" }]];
|
|
159
|
+
var IconChevronLeft = createReactComponent("outline", "chevron-left", "ChevronLeft", __iconNode5);
|
|
160
|
+
|
|
161
|
+
// node_modules/@tabler/icons-react/dist/esm/icons/IconChevronRight.mjs
|
|
162
|
+
var __iconNode6 = [["path", { "d": "M9 6l6 6l-6 6", "key": "svg-0" }]];
|
|
163
|
+
var IconChevronRight = createReactComponent("outline", "chevron-right", "ChevronRight", __iconNode6);
|
|
116
164
|
|
|
117
165
|
// node_modules/@tabler/icons-react/dist/esm/icons/IconCopy.mjs
|
|
118
|
-
var
|
|
119
|
-
var IconCopy = createReactComponent("outline", "copy", "Copy",
|
|
166
|
+
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" }]];
|
|
167
|
+
var IconCopy = createReactComponent("outline", "copy", "Copy", __iconNode7);
|
|
120
168
|
|
|
121
169
|
// node_modules/@tabler/icons-react/dist/esm/icons/IconDownload.mjs
|
|
122
|
-
var
|
|
123
|
-
var IconDownload = createReactComponent("outline", "download", "Download",
|
|
170
|
+
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" }]];
|
|
171
|
+
var IconDownload = createReactComponent("outline", "download", "Download", __iconNode8);
|
|
124
172
|
|
|
125
173
|
// node_modules/@tabler/icons-react/dist/esm/icons/IconFileSpreadsheet.mjs
|
|
126
|
-
var
|
|
127
|
-
var IconFileSpreadsheet = createReactComponent("outline", "file-spreadsheet", "FileSpreadsheet",
|
|
174
|
+
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" }]];
|
|
175
|
+
var IconFileSpreadsheet = createReactComponent("outline", "file-spreadsheet", "FileSpreadsheet", __iconNode9);
|
|
128
176
|
|
|
129
177
|
// node_modules/@tabler/icons-react/dist/esm/icons/IconLoader2.mjs
|
|
130
|
-
var
|
|
131
|
-
var IconLoader2 = createReactComponent("outline", "loader-2", "Loader2",
|
|
178
|
+
var __iconNode10 = [["path", { "d": "M12 3a9 9 0 1 0 9 9", "key": "svg-0" }]];
|
|
179
|
+
var IconLoader2 = createReactComponent("outline", "loader-2", "Loader2", __iconNode10);
|
|
132
180
|
|
|
133
181
|
// node_modules/@tabler/icons-react/dist/esm/icons/IconPhoto.mjs
|
|
134
|
-
var
|
|
135
|
-
var IconPhoto = createReactComponent("outline", "photo", "Photo",
|
|
182
|
+
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" }]];
|
|
183
|
+
var IconPhoto = createReactComponent("outline", "photo", "Photo", __iconNode11);
|
|
136
184
|
|
|
137
185
|
// node_modules/@tabler/icons-react/dist/esm/icons/IconThumbDown.mjs
|
|
138
|
-
var
|
|
139
|
-
var IconThumbDown = createReactComponent("outline", "thumb-down", "ThumbDown",
|
|
186
|
+
var __iconNode12 = [["path", { "d": "M7 13v-8a1 1 0 0 0 -1 -1h-2a1 1 0 0 0 -1 1v7a1 1 0 0 0 1 1h3a4 4 0 0 1 4 4v1a2 2 0 0 0 4 0v-5h3a2 2 0 0 0 2 -2l-1 -5a2 3 0 0 0 -2 -2h-7a3 3 0 0 0 -3 3", "key": "svg-0" }]];
|
|
187
|
+
var IconThumbDown = createReactComponent("outline", "thumb-down", "ThumbDown", __iconNode12);
|
|
140
188
|
|
|
141
189
|
// node_modules/@tabler/icons-react/dist/esm/icons/IconThumbUp.mjs
|
|
142
|
-
var
|
|
143
|
-
var IconThumbUp = createReactComponent("outline", "thumb-up", "ThumbUp",
|
|
190
|
+
var __iconNode13 = [["path", { "d": "M7 11v8a1 1 0 0 1 -1 1h-2a1 1 0 0 1 -1 -1v-7a1 1 0 0 1 1 -1h3a4 4 0 0 0 4 -4v-1a2 2 0 0 1 4 0v5h3a2 2 0 0 1 2 2l-1 5a2 3 0 0 1 -2 2h-7a3 3 0 0 1 -3 -3", "key": "svg-0" }]];
|
|
191
|
+
var IconThumbUp = createReactComponent("outline", "thumb-up", "ThumbUp", __iconNode13);
|
|
144
192
|
|
|
145
193
|
// src/components/artifacts/artifact-copy-as-image-button/artifact-copy-as-image-button.tsx
|
|
146
194
|
import { useCallback as useCallback2 } from "react";
|
|
@@ -203,7 +251,7 @@ function useCopyAsImage(targetRef, options = {}) {
|
|
|
203
251
|
setError(null);
|
|
204
252
|
setStatus("working");
|
|
205
253
|
try {
|
|
206
|
-
const { copyNodeAsPng } = await import("./dom-to-image-
|
|
254
|
+
const { copyNodeAsPng } = await import("./dom-to-image-QB7KMTAE.js");
|
|
207
255
|
await copyNodeAsPng(node, nodeOptions);
|
|
208
256
|
setStatus("success");
|
|
209
257
|
scheduleReset();
|
|
@@ -382,7 +430,7 @@ function ArtifactDownloadMenu({
|
|
|
382
430
|
if (!node) return;
|
|
383
431
|
const filename = `${png.filename ?? DEFAULT_PNG_BASENAME}.png`;
|
|
384
432
|
try {
|
|
385
|
-
const { downloadNodeAsPng } = await import("./dom-to-image-
|
|
433
|
+
const { downloadNodeAsPng } = await import("./dom-to-image-QB7KMTAE.js");
|
|
386
434
|
await downloadNodeAsPng(node, filename);
|
|
387
435
|
} catch (err) {
|
|
388
436
|
console.warn("[clay] ArtifactDownloadMenu: PNG download failed", err);
|
|
@@ -762,8 +810,12 @@ function renderBody(validConfig, artifact, data, labels) {
|
|
|
762
810
|
return /* @__PURE__ */ jsx11(ChartArtifactContent, { config: artifact.config, rows: data.rows, labels });
|
|
763
811
|
}
|
|
764
812
|
|
|
765
|
-
// src/components/artifacts/
|
|
766
|
-
import { useEffect as useEffect4, useMemo as useMemo3 } from "react";
|
|
813
|
+
// src/components/artifacts/deck-artifact/deck-artifact.tsx
|
|
814
|
+
import { useEffect as useEffect4, useMemo as useMemo3, useState as useState5 } from "react";
|
|
815
|
+
import { createPortal } from "react-dom";
|
|
816
|
+
|
|
817
|
+
// src/components/artifacts/deck-artifact/deck-artifact-content.tsx
|
|
818
|
+
import { useCallback as useCallback4, useLayoutEffect as useLayoutEffect2, useRef as useRef4, useState as useState4 } from "react";
|
|
767
819
|
|
|
768
820
|
// src/components/artifacts/table-artifact/table-artifact-content.constants.ts
|
|
769
821
|
var TABLE_STATUS = {
|
|
@@ -833,9 +885,333 @@ function renderEmptyRow(colSpan, emptyMessage) {
|
|
|
833
885
|
return /* @__PURE__ */ jsx12(TableRow, { className: "hover:bg-transparent", children: /* @__PURE__ */ jsx12(TableCell, { colSpan, className: "py-6 text-center text-sm text-muted-foreground", children: emptyMessage }) });
|
|
834
886
|
}
|
|
835
887
|
|
|
836
|
-
// src/components/artifacts/
|
|
837
|
-
|
|
838
|
-
|
|
888
|
+
// src/components/artifacts/deck-artifact/deck-markdown.tsx
|
|
889
|
+
import ReactMarkdown from "react-markdown";
|
|
890
|
+
import remarkBreaks from "remark-breaks";
|
|
891
|
+
import remarkGfm from "remark-gfm";
|
|
892
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
893
|
+
function sanitize(text) {
|
|
894
|
+
return text.split("\n").filter((line) => {
|
|
895
|
+
const t = line.trim();
|
|
896
|
+
return !(t.startsWith("<!-- table-title:") && t.endsWith("-->"));
|
|
897
|
+
}).join("\n");
|
|
898
|
+
}
|
|
899
|
+
var MARKDOWN_COMPONENTS = {
|
|
900
|
+
h1: ({ node: _node, ...props }) => /* @__PURE__ */ jsx13("h1", { className: "text-[30px] font-semibold leading-tight text-foreground mb-3", ...props }),
|
|
901
|
+
h2: ({ node: _node, ...props }) => /* @__PURE__ */ jsx13("h2", { className: "text-[26px] font-semibold leading-tight text-foreground mb-2", ...props }),
|
|
902
|
+
h3: ({ node: _node, ...props }) => /* @__PURE__ */ jsx13("h3", { className: "text-[24px] font-semibold leading-tight text-foreground mb-2", ...props }),
|
|
903
|
+
h4: ({ node: _node, ...props }) => /* @__PURE__ */ jsx13("h4", { className: "text-[24px] font-semibold leading-tight text-foreground mb-2", ...props }),
|
|
904
|
+
h5: ({ node: _node, ...props }) => /* @__PURE__ */ jsx13("h5", { className: "text-[24px] font-semibold leading-tight text-foreground mb-2", ...props }),
|
|
905
|
+
h6: ({ node: _node, ...props }) => /* @__PURE__ */ jsx13("h6", { className: "text-[24px] font-semibold leading-tight text-foreground mb-2", ...props }),
|
|
906
|
+
p: ({ node: _node, ...props }) => /* @__PURE__ */ jsx13("p", { className: "text-[22px] leading-relaxed text-foreground my-2", ...props }),
|
|
907
|
+
ul: ({ node: _node, ...props }) => /* @__PURE__ */ jsx13("ul", { className: "list-disc pl-7 text-[22px] leading-relaxed text-foreground my-2", ...props }),
|
|
908
|
+
ol: ({ node: _node, ...props }) => /* @__PURE__ */ jsx13("ol", { className: "list-decimal pl-7 text-[22px] leading-relaxed text-foreground my-2", ...props }),
|
|
909
|
+
// react-markdown injects list metadata (`ordered` / `index` / `checked`) that must not leak to the DOM.
|
|
910
|
+
li: ({ node: _node, ordered: _ordered, index: _index, checked: _checked, ...props }) => /* @__PURE__ */ jsx13("li", { className: "my-1", ...props }),
|
|
911
|
+
strong: ({ node: _node, ...props }) => /* @__PURE__ */ jsx13("strong", { className: "font-semibold", ...props }),
|
|
912
|
+
em: ({ node: _node, ...props }) => /* @__PURE__ */ jsx13("em", { className: "italic", ...props }),
|
|
913
|
+
// Gate `<img src>` against an http(s) allowlist. react-markdown v8 percent-encodes the URL but
|
|
914
|
+
// does NOT protocol-filter image src (unlike link href), so an LLM-authored
|
|
915
|
+
// `` / `` or a tracking-pixel `` would otherwise render
|
|
916
|
+
// with the raw URL. Unsafe src → render nothing.
|
|
917
|
+
img: ({ node: _node, src, ...props }) => typeof src === "string" && isSafeDownloadUrl(src) ? /* @__PURE__ */ jsx13("img", { src, className: "max-w-full", ...props }) : null,
|
|
918
|
+
a: ({ node: _node, ...props }) => (
|
|
919
|
+
// `rel` is forced AFTER `{...props}` so it can't be overridden — if a consumer ever adds
|
|
920
|
+
// `linkTarget="_blank"`, LLM-authored links still can't reach `window.opener`.
|
|
921
|
+
/* @__PURE__ */ jsx13("a", { className: "underline underline-offset-2", ...props, rel: "noopener noreferrer" })
|
|
922
|
+
),
|
|
923
|
+
// react-markdown passes `inline` to distinguish inline code from fenced blocks — strip it from the DOM.
|
|
924
|
+
code: ({ node: _node, inline: _inline, ...props }) => /* @__PURE__ */ jsx13("code", { className: "rounded bg-muted px-1.5 py-0.5 font-mono text-[18px]", ...props }),
|
|
925
|
+
blockquote: ({ node: _node, ...props }) => /* @__PURE__ */ jsx13("blockquote", { className: "border-l-2 border-brown-alpha-12 pl-4 text-[22px] text-muted-foreground", ...props }),
|
|
926
|
+
hr: ({ node: _node, ...props }) => /* @__PURE__ */ jsx13("hr", { className: "my-4 border-brown-alpha-12", ...props }),
|
|
927
|
+
table: ({ node: _node, ...props }) => /* @__PURE__ */ jsx13("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsx13("table", { className: "w-full border-collapse text-[20px]", ...props }) }),
|
|
928
|
+
// react-markdown passes `isHeader` to cell renderers — strip it so it never reaches the DOM.
|
|
929
|
+
th: ({ node: _node, isHeader: _isHeader, ...props }) => /* @__PURE__ */ jsx13("th", { className: "border-b border-brown-alpha-12 px-3 py-1.5 text-left font-medium", ...props }),
|
|
930
|
+
td: ({ node: _node, isHeader: _isHeader, ...props }) => /* @__PURE__ */ jsx13("td", { className: "border-b border-brown-alpha-12 px-3 py-1.5", ...props })
|
|
931
|
+
};
|
|
932
|
+
function DeckMarkdown({ markdown }) {
|
|
933
|
+
return /* @__PURE__ */ jsx13(ReactMarkdown, { remarkPlugins: [remarkGfm, remarkBreaks], components: MARKDOWN_COMPONENTS, children: sanitize(markdown) });
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
// src/components/artifacts/deck-artifact/slide-renderers.tsx
|
|
937
|
+
import { useLayoutEffect, useRef as useRef3, useState as useState3 } from "react";
|
|
938
|
+
import { jsx as jsx14, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
939
|
+
function safeLogoUrl(meta) {
|
|
940
|
+
return meta?.logoUrl && isSafeDownloadUrl(meta.logoUrl) ? meta.logoUrl : null;
|
|
941
|
+
}
|
|
942
|
+
var DESIGN_W = 1280;
|
|
943
|
+
var DESIGN_H = 720;
|
|
944
|
+
var EYEBROW_H = 84;
|
|
945
|
+
var CANVAS_LOGO_MAX_H = 48;
|
|
946
|
+
var ACCENT_FONT = { fontFamily: `"${fontFamilies.CRIMSON_PRO}", serif`, fontStyle: "italic" };
|
|
947
|
+
function SlideFrame({ meta, children, accent = false, bare = false }) {
|
|
948
|
+
const frameRef = useRef3(null);
|
|
949
|
+
const [scale, setScale] = useState3(null);
|
|
950
|
+
useLayoutEffect(() => {
|
|
951
|
+
const el = frameRef.current;
|
|
952
|
+
if (!el) return;
|
|
953
|
+
const apply = (width) => {
|
|
954
|
+
if (width > 0) setScale(width / DESIGN_W);
|
|
955
|
+
};
|
|
956
|
+
apply(el.clientWidth);
|
|
957
|
+
const ro = new ResizeObserver((entries) => apply(entries[0]?.contentRect.width ?? 0));
|
|
958
|
+
ro.observe(el);
|
|
959
|
+
return () => ro.disconnect();
|
|
960
|
+
}, []);
|
|
961
|
+
const bg = accent ? "bg-indigo-600" : "bg-deck-canvas";
|
|
962
|
+
const eyebrowColor = accent ? "text-white/70" : "text-brown-60";
|
|
963
|
+
const borderColor = accent ? "border-white/20" : "border-brown-alpha-12";
|
|
964
|
+
const logoSrc = safeLogoUrl(meta);
|
|
965
|
+
return /* @__PURE__ */ jsx14("div", { ref: frameRef, className: `relative aspect-[16/9] w-full overflow-hidden rounded-lg ${bg}`, children: /* @__PURE__ */ jsxs6(
|
|
966
|
+
"div",
|
|
967
|
+
{
|
|
968
|
+
className: "absolute left-0 top-0 origin-top-left",
|
|
969
|
+
style: {
|
|
970
|
+
width: DESIGN_W,
|
|
971
|
+
height: DESIGN_H,
|
|
972
|
+
transform: `scale(${scale ?? 0})`,
|
|
973
|
+
visibility: scale === null ? "hidden" : "visible"
|
|
974
|
+
},
|
|
975
|
+
children: [
|
|
976
|
+
!bare ? /* @__PURE__ */ jsxs6(
|
|
977
|
+
"div",
|
|
978
|
+
{
|
|
979
|
+
className: `absolute inset-x-0 top-0 flex items-center justify-between border-b px-16 ${borderColor}`,
|
|
980
|
+
style: { height: EYEBROW_H },
|
|
981
|
+
children: [
|
|
982
|
+
meta?.eyebrow ? /* @__PURE__ */ jsx14("span", { className: eyebrowColor, style: { ...ACCENT_FONT, fontSize: 22 }, children: meta.eyebrow }) : /* @__PURE__ */ jsx14("span", {}),
|
|
983
|
+
logoSrc ? /* @__PURE__ */ jsx14("img", { src: logoSrc, alt: "", className: "object-contain", style: { maxHeight: CANVAS_LOGO_MAX_H } }) : null
|
|
984
|
+
]
|
|
985
|
+
}
|
|
986
|
+
) : null,
|
|
987
|
+
/* @__PURE__ */ jsx14("div", { className: "absolute inset-x-0 bottom-0 overflow-hidden", style: { top: bare ? 0 : EYEBROW_H }, children })
|
|
988
|
+
]
|
|
989
|
+
}
|
|
990
|
+
) });
|
|
991
|
+
}
|
|
992
|
+
function TitleSlide({ slide, meta }) {
|
|
993
|
+
const logoSrc = safeLogoUrl(meta);
|
|
994
|
+
return /* @__PURE__ */ jsx14(SlideFrame, { meta, bare: true, children: /* @__PURE__ */ jsxs6("div", { className: "flex h-full flex-col justify-center px-24 py-16", children: [
|
|
995
|
+
logoSrc ? /* @__PURE__ */ jsx14(
|
|
996
|
+
"img",
|
|
997
|
+
{
|
|
998
|
+
src: logoSrc,
|
|
999
|
+
alt: "",
|
|
1000
|
+
className: "mb-16 object-contain object-left",
|
|
1001
|
+
style: { maxHeight: 56, maxWidth: 380 }
|
|
1002
|
+
}
|
|
1003
|
+
) : null,
|
|
1004
|
+
/* @__PURE__ */ jsx14(
|
|
1005
|
+
"h1",
|
|
1006
|
+
{
|
|
1007
|
+
className: "font-bold tracking-tight text-brown-100",
|
|
1008
|
+
style: { fontSize: 92, lineHeight: 1.04, maxWidth: 1060 },
|
|
1009
|
+
children: slide.title
|
|
1010
|
+
}
|
|
1011
|
+
),
|
|
1012
|
+
slide.subtitle ? /* @__PURE__ */ jsx14("p", { className: "mt-7 text-brown-70", style: { ...ACCENT_FONT, fontSize: 34 }, children: slide.subtitle }) : null,
|
|
1013
|
+
slide.description ? /* @__PURE__ */ jsx14("p", { className: "mt-4 leading-relaxed text-brown-70", style: { fontSize: 24, maxWidth: 880 }, children: slide.description }) : null,
|
|
1014
|
+
meta?.date ? /* @__PURE__ */ jsx14("p", { className: "mt-10 text-brown-70", style: { ...ACCENT_FONT, fontSize: 30 }, children: meta.date }) : null
|
|
1015
|
+
] }) });
|
|
1016
|
+
}
|
|
1017
|
+
function AgendaSlide({ slide, meta, labels }) {
|
|
1018
|
+
const items = slide.items ?? [];
|
|
1019
|
+
return /* @__PURE__ */ jsx14(SlideFrame, { meta, children: /* @__PURE__ */ jsxs6("div", { className: "h-full px-24 py-14", children: [
|
|
1020
|
+
/* @__PURE__ */ jsx14("h2", { className: "mb-10 font-bold text-brown-90", style: { fontSize: 40 }, children: slide.title || labels.agenda }),
|
|
1021
|
+
/* @__PURE__ */ jsx14("div", { className: "flex flex-col", children: items.map((item, i) => /* @__PURE__ */ jsxs6("div", { className: "flex items-baseline gap-6 border-b border-brown-alpha-12 py-5", children: [
|
|
1022
|
+
/* @__PURE__ */ jsx14("span", { className: "shrink-0 text-indigo-600", style: { ...ACCENT_FONT, fontSize: 28, width: 64 }, children: String(i + 1).padStart(2, "0") }),
|
|
1023
|
+
/* @__PURE__ */ jsx14("span", { className: "text-brown-90", style: { fontSize: 28 }, children: item })
|
|
1024
|
+
] }, i)) })
|
|
1025
|
+
] }) });
|
|
1026
|
+
}
|
|
1027
|
+
function SectionSlide({ slide, meta }) {
|
|
1028
|
+
return /* @__PURE__ */ jsx14(SlideFrame, { meta, accent: true, children: /* @__PURE__ */ jsxs6("div", { className: "flex h-full flex-col justify-center gap-6 px-24", children: [
|
|
1029
|
+
/* @__PURE__ */ jsx14("h2", { className: "font-bold text-white", style: { fontSize: 72, lineHeight: 1.05, maxWidth: 940 }, children: slide.title }),
|
|
1030
|
+
/* @__PURE__ */ jsx14("div", { className: "mt-2 bg-white/50", style: { width: 96, height: 5 } })
|
|
1031
|
+
] }) });
|
|
1032
|
+
}
|
|
1033
|
+
function ClosingSlide({ meta, labels }) {
|
|
1034
|
+
return /* @__PURE__ */ jsx14(SlideFrame, { meta, children: /* @__PURE__ */ jsxs6("div", { className: "flex h-full flex-col items-center justify-center gap-6 px-24 text-center", children: [
|
|
1035
|
+
/* @__PURE__ */ jsx14("h1", { className: "font-bold text-brown-100", style: { fontSize: 72 }, children: labels.thankYou }),
|
|
1036
|
+
/* @__PURE__ */ jsx14("p", { className: "text-indigo-600", style: { ...ACCENT_FONT, fontSize: 36 }, children: labels.questions })
|
|
1037
|
+
] }) });
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
// src/components/artifacts/deck-artifact/deck-artifact-content.tsx
|
|
1041
|
+
import { jsx as jsx15, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1042
|
+
var TABLE_BLOCK_MAX_SHIMMER_ROWS = 10;
|
|
1043
|
+
var TABLE_CHROME_RESERVE = 56;
|
|
1044
|
+
var VISUAL_FALLBACK_HEIGHT = 360;
|
|
1045
|
+
function DeckArtifactContent({
|
|
1046
|
+
slides,
|
|
1047
|
+
labels,
|
|
1048
|
+
onNavigate,
|
|
1049
|
+
meta,
|
|
1050
|
+
onDark = false,
|
|
1051
|
+
currentSlide,
|
|
1052
|
+
onSlideChange
|
|
1053
|
+
}) {
|
|
1054
|
+
const navBtnClass = onDark ? "[&_svg]:!text-white hover:!bg-white/20 disabled:opacity-40" : void 0;
|
|
1055
|
+
const navBtnSize = onDark ? "medium" : "small";
|
|
1056
|
+
const isControlled = currentSlide !== void 0;
|
|
1057
|
+
const [internalIndex, setInternalIndex] = useState4(0);
|
|
1058
|
+
const index = isControlled ? currentSlide : internalIndex;
|
|
1059
|
+
const current = Math.min(index, slides.length - 1);
|
|
1060
|
+
const slide = slides[current];
|
|
1061
|
+
const goTo = useCallback4(
|
|
1062
|
+
(next) => {
|
|
1063
|
+
const clamped = Math.max(0, Math.min(next, slides.length - 1));
|
|
1064
|
+
if (isControlled) onSlideChange?.(clamped);
|
|
1065
|
+
else setInternalIndex(clamped);
|
|
1066
|
+
onNavigate?.(clamped);
|
|
1067
|
+
},
|
|
1068
|
+
[slides.length, onNavigate, isControlled, onSlideChange]
|
|
1069
|
+
);
|
|
1070
|
+
const position = labels.position.replace("{current}", String(current + 1)).replace("{total}", String(slides.length));
|
|
1071
|
+
return /* @__PURE__ */ jsxs7("div", { className: "flex flex-col gap-3 p-4", children: [
|
|
1072
|
+
/* @__PURE__ */ jsx15(SlideDispatch, { slide, labels, meta }),
|
|
1073
|
+
/* @__PURE__ */ jsxs7(
|
|
1074
|
+
"div",
|
|
1075
|
+
{
|
|
1076
|
+
className: `flex items-center justify-between border-t pt-2 ${onDark ? "border-white/20" : "border-brown-alpha-12"}`,
|
|
1077
|
+
children: [
|
|
1078
|
+
/* @__PURE__ */ jsx15(
|
|
1079
|
+
IconButton,
|
|
1080
|
+
{
|
|
1081
|
+
icon: IconChevronLeft,
|
|
1082
|
+
size: navBtnSize,
|
|
1083
|
+
className: navBtnClass,
|
|
1084
|
+
"aria-label": labels.previous,
|
|
1085
|
+
disabled: current === 0,
|
|
1086
|
+
onClick: () => goTo(current - 1)
|
|
1087
|
+
}
|
|
1088
|
+
),
|
|
1089
|
+
/* @__PURE__ */ jsx15("span", { className: `text-xs font-medium ${onDark ? "text-white/70" : "text-brown-70"}`, children: position }),
|
|
1090
|
+
/* @__PURE__ */ jsx15(
|
|
1091
|
+
IconButton,
|
|
1092
|
+
{
|
|
1093
|
+
icon: IconChevronRight,
|
|
1094
|
+
size: navBtnSize,
|
|
1095
|
+
className: navBtnClass,
|
|
1096
|
+
"aria-label": labels.next,
|
|
1097
|
+
disabled: current === slides.length - 1,
|
|
1098
|
+
onClick: () => goTo(current + 1)
|
|
1099
|
+
}
|
|
1100
|
+
)
|
|
1101
|
+
]
|
|
1102
|
+
}
|
|
1103
|
+
)
|
|
1104
|
+
] });
|
|
1105
|
+
}
|
|
1106
|
+
function SlideDispatch({ slide, labels, meta }) {
|
|
1107
|
+
const kind = slide.kind ?? deckSlideKinds.CONTENT;
|
|
1108
|
+
switch (kind) {
|
|
1109
|
+
case deckSlideKinds.TITLE:
|
|
1110
|
+
return /* @__PURE__ */ jsx15(TitleSlide, { slide, meta });
|
|
1111
|
+
case deckSlideKinds.AGENDA:
|
|
1112
|
+
return /* @__PURE__ */ jsx15(AgendaSlide, { slide, meta, labels });
|
|
1113
|
+
case deckSlideKinds.SECTION:
|
|
1114
|
+
return /* @__PURE__ */ jsx15(SectionSlide, { slide, meta });
|
|
1115
|
+
case deckSlideKinds.CLOSING:
|
|
1116
|
+
return /* @__PURE__ */ jsx15(ClosingSlide, { meta, labels });
|
|
1117
|
+
case deckSlideKinds.CONTENT:
|
|
1118
|
+
default:
|
|
1119
|
+
return /* @__PURE__ */ jsx15(ContentSlide, { slide, meta, labels });
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
function isVisualBlock(block) {
|
|
1123
|
+
return block.type === deckBlockTypes.CHART || block.type === deckBlockTypes.TABLE;
|
|
1124
|
+
}
|
|
1125
|
+
function ContentSlide({ slide, meta, labels }) {
|
|
1126
|
+
const content = slide.content ?? [];
|
|
1127
|
+
const visuals = content.filter(isVisualBlock);
|
|
1128
|
+
const texts = content.filter(
|
|
1129
|
+
(b) => b.type === deckBlockTypes.TEXT
|
|
1130
|
+
);
|
|
1131
|
+
if (visuals.length === 1 && texts.length > 0) {
|
|
1132
|
+
return /* @__PURE__ */ jsx15(SlideFrame, { meta, children: /* @__PURE__ */ jsxs7("div", { className: "flex h-full items-stretch gap-12 px-16 py-12", children: [
|
|
1133
|
+
/* @__PURE__ */ jsx15("div", { className: "flex w-[42%] shrink-0 flex-col overflow-hidden", children: /* @__PURE__ */ jsxs7(AutoFit, { children: [
|
|
1134
|
+
/* @__PURE__ */ jsx15("h3", { className: "mb-5 font-bold leading-tight text-foreground", style: { fontSize: 34 }, children: slide.title }),
|
|
1135
|
+
texts.map((block, i) => /* @__PURE__ */ jsx15(DeckMarkdown, { markdown: block.markdown }, i))
|
|
1136
|
+
] }) }),
|
|
1137
|
+
/* @__PURE__ */ jsx15("div", { className: "min-h-0 min-w-0 flex-1", children: /* @__PURE__ */ jsx15(FillVisual, { block: visuals[0], labels }) })
|
|
1138
|
+
] }) });
|
|
1139
|
+
}
|
|
1140
|
+
if (visuals.length > 0) {
|
|
1141
|
+
return /* @__PURE__ */ jsx15(SlideFrame, { meta, children: /* @__PURE__ */ jsxs7("div", { className: "flex h-full flex-col gap-5 px-16 py-10", children: [
|
|
1142
|
+
/* @__PURE__ */ jsx15("h3", { className: "shrink-0 font-bold leading-tight text-foreground", style: { fontSize: 32 }, children: slide.title }),
|
|
1143
|
+
content.map(
|
|
1144
|
+
(block, i) => isVisualBlock(block) ? /* @__PURE__ */ jsx15("div", { className: "min-h-0 min-w-0 flex-1", children: /* @__PURE__ */ jsx15(FillVisual, { block, labels }) }, i) : /* @__PURE__ */ jsx15("div", { className: "shrink-0 overflow-hidden", children: /* @__PURE__ */ jsx15(DeckMarkdown, { markdown: block.markdown }) }, i)
|
|
1145
|
+
)
|
|
1146
|
+
] }) });
|
|
1147
|
+
}
|
|
1148
|
+
return /* @__PURE__ */ jsx15(SlideFrame, { meta, children: /* @__PURE__ */ jsx15("div", { className: "h-full px-24 py-12", children: /* @__PURE__ */ jsxs7(AutoFit, { children: [
|
|
1149
|
+
/* @__PURE__ */ jsx15("h3", { className: "mb-6 font-bold leading-tight text-foreground", style: { fontSize: 38 }, children: slide.title }),
|
|
1150
|
+
texts.map((block, i) => /* @__PURE__ */ jsx15(DeckMarkdown, { markdown: block.markdown }, i))
|
|
1151
|
+
] }) }) });
|
|
1152
|
+
}
|
|
1153
|
+
function AutoFit({ children }) {
|
|
1154
|
+
const boxRef = useRef4(null);
|
|
1155
|
+
const contentRef = useRef4(null);
|
|
1156
|
+
const [fit, setFit] = useState4({ scale: 1, height: 0 });
|
|
1157
|
+
useLayoutEffect2(() => {
|
|
1158
|
+
const boxEl = boxRef.current;
|
|
1159
|
+
const contentEl = contentRef.current;
|
|
1160
|
+
if (!boxEl || !contentEl) return;
|
|
1161
|
+
const measure = () => {
|
|
1162
|
+
const avail = boxEl.clientHeight;
|
|
1163
|
+
const natural = contentEl.offsetHeight;
|
|
1164
|
+
const scale = avail > 0 && natural > avail ? avail / natural : 1;
|
|
1165
|
+
setFit({ scale, height: natural * scale });
|
|
1166
|
+
};
|
|
1167
|
+
measure();
|
|
1168
|
+
const ro = new ResizeObserver(measure);
|
|
1169
|
+
ro.observe(boxEl);
|
|
1170
|
+
ro.observe(contentEl);
|
|
1171
|
+
return () => ro.disconnect();
|
|
1172
|
+
}, []);
|
|
1173
|
+
const scaled = fit.scale < 1;
|
|
1174
|
+
return /* @__PURE__ */ jsx15("div", { ref: boxRef, className: "flex h-full min-h-0 w-full flex-col justify-center overflow-hidden", children: /* @__PURE__ */ jsx15("div", { style: scaled ? { height: fit.height } : void 0, children: /* @__PURE__ */ jsx15(
|
|
1175
|
+
"div",
|
|
1176
|
+
{
|
|
1177
|
+
ref: contentRef,
|
|
1178
|
+
className: "w-full origin-top-left",
|
|
1179
|
+
style: scaled ? { transform: `scale(${fit.scale})` } : void 0,
|
|
1180
|
+
children
|
|
1181
|
+
}
|
|
1182
|
+
) }) });
|
|
1183
|
+
}
|
|
1184
|
+
function FillVisual({ block, labels }) {
|
|
1185
|
+
const ref = useRef4(null);
|
|
1186
|
+
const [height, setHeight] = useState4(VISUAL_FALLBACK_HEIGHT);
|
|
1187
|
+
useLayoutEffect2(() => {
|
|
1188
|
+
const el = ref.current;
|
|
1189
|
+
if (!el) return;
|
|
1190
|
+
const apply = (h) => {
|
|
1191
|
+
if (h > 0) setHeight(h);
|
|
1192
|
+
};
|
|
1193
|
+
apply(el.clientHeight);
|
|
1194
|
+
const ro = new ResizeObserver((entries) => apply(entries[0]?.contentRect.height ?? 0));
|
|
1195
|
+
ro.observe(el);
|
|
1196
|
+
return () => ro.disconnect();
|
|
1197
|
+
}, []);
|
|
1198
|
+
const chartLabels = labels.chart ?? DEFAULT_CHART_ARTIFACT_LABELS;
|
|
1199
|
+
return /* @__PURE__ */ jsx15("div", { ref, className: "h-full min-h-0 w-full overflow-hidden", children: block.type === deckBlockTypes.CHART ? (
|
|
1200
|
+
// ChartArtifactContent assumes a non-empty rowset (the standalone ChartArtifact guards
|
|
1201
|
+
// `rows.length > 0` upstream); mirror that guard here so an empty inline chart shows the
|
|
1202
|
+
// localized empty status instead of a blank chart area.
|
|
1203
|
+
block.rows.length === 0 ? /* @__PURE__ */ jsx15(StatusMessage, { $tone: "info", children: chartLabels.empty }) : /* @__PURE__ */ jsx15("div", { style: { height }, children: /* @__PURE__ */ jsx15(ChartArtifactContent, { config: block.config, rows: block.rows, labels: chartLabels }) })
|
|
1204
|
+
) : /* @__PURE__ */ jsx15(
|
|
1205
|
+
TableArtifactContent,
|
|
1206
|
+
{
|
|
1207
|
+
columns: block.config.columns,
|
|
1208
|
+
data: { status: "ready", rows: block.rows, error: null },
|
|
1209
|
+
knownRowCount: block.config.stats?.rowCount ?? block.rows.length,
|
|
1210
|
+
maxShimmerRows: TABLE_BLOCK_MAX_SHIMMER_ROWS,
|
|
1211
|
+
maxBodyHeight: Math.max(0, height - TABLE_CHROME_RESERVE),
|
|
1212
|
+
labels: labels.table ?? DEFAULT_TABLE_ARTIFACT_LABELS
|
|
1213
|
+
}
|
|
1214
|
+
) });
|
|
839
1215
|
}
|
|
840
1216
|
|
|
841
1217
|
// src/components/artifacts/table-artifact/validate.ts
|
|
@@ -854,19 +1230,206 @@ function isValidTableColumn(column) {
|
|
|
854
1230
|
return true;
|
|
855
1231
|
}
|
|
856
1232
|
|
|
857
|
-
// src/components/artifacts/
|
|
858
|
-
|
|
1233
|
+
// src/components/artifacts/deck-artifact/validate.ts
|
|
1234
|
+
function isValidDeckConfig(config) {
|
|
1235
|
+
if (!config || typeof config !== "object") return false;
|
|
1236
|
+
const candidate = config;
|
|
1237
|
+
if (!Array.isArray(candidate.slides)) return false;
|
|
1238
|
+
if (candidate.slides.length === 0) return false;
|
|
1239
|
+
return candidate.slides.every(isValidDeckSlide);
|
|
1240
|
+
}
|
|
1241
|
+
function isValidDeckSlide(slide) {
|
|
1242
|
+
if (!slide || typeof slide !== "object") return false;
|
|
1243
|
+
const candidate = slide;
|
|
1244
|
+
if (typeof candidate.title !== "string") return false;
|
|
1245
|
+
const kind = typeof candidate.kind === "string" ? candidate.kind : deckSlideKinds.CONTENT;
|
|
1246
|
+
if (kind === deckSlideKinds.CONTENT && !Array.isArray(candidate.content)) return false;
|
|
1247
|
+
const content = Array.isArray(candidate.content) ? candidate.content : [];
|
|
1248
|
+
if (candidate.items != null) {
|
|
1249
|
+
if (!Array.isArray(candidate.items)) return false;
|
|
1250
|
+
if (!candidate.items.every((item) => typeof item === "string")) return false;
|
|
1251
|
+
}
|
|
1252
|
+
return content.every(isValidDeckBlock);
|
|
1253
|
+
}
|
|
1254
|
+
function isValidDeckBlock(block) {
|
|
1255
|
+
if (!block || typeof block !== "object") return false;
|
|
1256
|
+
const candidate = block;
|
|
1257
|
+
switch (candidate.type) {
|
|
1258
|
+
case deckBlockTypes.TEXT:
|
|
1259
|
+
return typeof candidate.markdown === "string";
|
|
1260
|
+
case deckBlockTypes.CHART:
|
|
1261
|
+
return isValidChartConfig(candidate.config) && Array.isArray(candidate.rows);
|
|
1262
|
+
case deckBlockTypes.TABLE:
|
|
1263
|
+
return isValidTableConfig(candidate.config) && Array.isArray(candidate.rows);
|
|
1264
|
+
default:
|
|
1265
|
+
return false;
|
|
1266
|
+
}
|
|
1267
|
+
}
|
|
1268
|
+
|
|
1269
|
+
// src/components/artifacts/deck-artifact/deck-artifact.tsx
|
|
1270
|
+
import { Fragment, jsx as jsx16, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
859
1271
|
var TITLE_CLASSES2 = "text-sm font-semibold text-foreground";
|
|
1272
|
+
function DeckArtifact({ artifact, labels, callbacks }) {
|
|
1273
|
+
const validConfig = isValidDeckConfig(artifact.config);
|
|
1274
|
+
const [isFullscreen, setIsFullscreen] = useState5(false);
|
|
1275
|
+
const [currentSlide, setCurrentSlide] = useState5(0);
|
|
1276
|
+
useEffect4(() => {
|
|
1277
|
+
if (validConfig) return;
|
|
1278
|
+
console.warn("[clay] DeckArtifact: malformed `config` \u2014 skipping render.");
|
|
1279
|
+
}, [validConfig]);
|
|
1280
|
+
useEffect4(() => {
|
|
1281
|
+
if (!isFullscreen) return;
|
|
1282
|
+
const handleKey = (e) => {
|
|
1283
|
+
if (e.key === "Escape") setIsFullscreen(false);
|
|
1284
|
+
};
|
|
1285
|
+
document.addEventListener("keydown", handleKey);
|
|
1286
|
+
const previousOverflow = document.documentElement.style.overflow;
|
|
1287
|
+
document.documentElement.style.overflow = "hidden";
|
|
1288
|
+
return () => {
|
|
1289
|
+
document.removeEventListener("keydown", handleKey);
|
|
1290
|
+
document.documentElement.style.overflow = previousOverflow;
|
|
1291
|
+
};
|
|
1292
|
+
}, [isFullscreen]);
|
|
1293
|
+
const resolvedLabels = useMemo3(
|
|
1294
|
+
() => ({
|
|
1295
|
+
...DEFAULT_DECK_ARTIFACT_LABELS,
|
|
1296
|
+
...labels ?? {},
|
|
1297
|
+
chart: { ...DEFAULT_CHART_ARTIFACT_LABELS, ...labels?.chart ?? {} },
|
|
1298
|
+
table: { ...DEFAULT_TABLE_ARTIFACT_LABELS, ...labels?.table ?? {} }
|
|
1299
|
+
}),
|
|
1300
|
+
[labels]
|
|
1301
|
+
);
|
|
1302
|
+
const onNavigate = callbacks?.onNavigate;
|
|
1303
|
+
const handleNavigate = onNavigate ? (slideIndex) => onNavigate(artifact, slideIndex) : void 0;
|
|
1304
|
+
const onDownload = callbacks?.onDownload;
|
|
1305
|
+
const handleDownload = onDownload ? () => onDownload(artifact) : void 0;
|
|
1306
|
+
const presignedUrl = artifact.protectedAsset?.presignedUrl ?? null;
|
|
1307
|
+
const showDownload = presignedUrl !== null && isSafeDownloadUrl(presignedUrl);
|
|
1308
|
+
const meta = artifact.config?.meta;
|
|
1309
|
+
const handleOpenFullscreen = () => setIsFullscreen(true);
|
|
1310
|
+
const handleCloseFullscreen = () => setIsFullscreen(false);
|
|
1311
|
+
const actions = /* @__PURE__ */ jsxs8(ArtifactActions, { ...{ [CAPTURE_EXCLUDE_ATTRIBUTE]: "" }, children: [
|
|
1312
|
+
showDownload ? /* @__PURE__ */ jsx16(ArtifactDownloadButton, { href: presignedUrl ?? "", label: resolvedLabels.download, onClick: handleDownload }) : null,
|
|
1313
|
+
validConfig ? /* @__PURE__ */ jsx16(
|
|
1314
|
+
IconButton,
|
|
1315
|
+
{
|
|
1316
|
+
icon: IconArrowsMaximize,
|
|
1317
|
+
size: "small",
|
|
1318
|
+
"aria-label": resolvedLabels.enterFullscreen,
|
|
1319
|
+
onClick: handleOpenFullscreen
|
|
1320
|
+
}
|
|
1321
|
+
) : null
|
|
1322
|
+
] });
|
|
1323
|
+
if (!validConfig) {
|
|
1324
|
+
return /* @__PURE__ */ jsxs8(Artifact, { className: "shadow-none w-full rounded-2xl bg-background/70", children: [
|
|
1325
|
+
/* @__PURE__ */ jsxs8(ArtifactHeader, { className: "bg-background/70", children: [
|
|
1326
|
+
artifact.title ? /* @__PURE__ */ jsx16(ArtifactTitle, { className: TITLE_CLASSES2, children: artifact.title }) : /* @__PURE__ */ jsx16("span", {}),
|
|
1327
|
+
actions
|
|
1328
|
+
] }),
|
|
1329
|
+
/* @__PURE__ */ jsx16(ArtifactContent, { className: "p-0", children: /* @__PURE__ */ jsx16(StatusMessage, { $tone: "info", children: resolvedLabels.unavailable }) })
|
|
1330
|
+
] });
|
|
1331
|
+
}
|
|
1332
|
+
return /* @__PURE__ */ jsxs8(Fragment, { children: [
|
|
1333
|
+
/* @__PURE__ */ jsxs8(Artifact, { className: "shadow-none w-full rounded-2xl bg-background/70", children: [
|
|
1334
|
+
/* @__PURE__ */ jsxs8(ArtifactHeader, { className: "bg-background/70", children: [
|
|
1335
|
+
artifact.title ? /* @__PURE__ */ jsx16(ArtifactTitle, { className: TITLE_CLASSES2, children: artifact.title }) : /* @__PURE__ */ jsx16("span", {}),
|
|
1336
|
+
actions
|
|
1337
|
+
] }),
|
|
1338
|
+
/* @__PURE__ */ jsx16(ArtifactContent, { className: "p-0", children: /* @__PURE__ */ jsx16(
|
|
1339
|
+
DeckArtifactContent,
|
|
1340
|
+
{
|
|
1341
|
+
slides: artifact.config.slides,
|
|
1342
|
+
labels: resolvedLabels,
|
|
1343
|
+
onNavigate: handleNavigate,
|
|
1344
|
+
meta,
|
|
1345
|
+
currentSlide,
|
|
1346
|
+
onSlideChange: setCurrentSlide
|
|
1347
|
+
}
|
|
1348
|
+
) })
|
|
1349
|
+
] }),
|
|
1350
|
+
isFullscreen && createPortal(
|
|
1351
|
+
/* @__PURE__ */ jsx16(
|
|
1352
|
+
FullscreenOverlay,
|
|
1353
|
+
{
|
|
1354
|
+
artifact,
|
|
1355
|
+
resolvedLabels,
|
|
1356
|
+
onNavigate: handleNavigate,
|
|
1357
|
+
currentSlide,
|
|
1358
|
+
onSlideChange: setCurrentSlide,
|
|
1359
|
+
onClose: handleCloseFullscreen
|
|
1360
|
+
}
|
|
1361
|
+
),
|
|
1362
|
+
document.body
|
|
1363
|
+
)
|
|
1364
|
+
] });
|
|
1365
|
+
}
|
|
1366
|
+
function FullscreenOverlay({
|
|
1367
|
+
artifact,
|
|
1368
|
+
resolvedLabels,
|
|
1369
|
+
onNavigate,
|
|
1370
|
+
currentSlide,
|
|
1371
|
+
onSlideChange,
|
|
1372
|
+
onClose
|
|
1373
|
+
}) {
|
|
1374
|
+
const meta = artifact.config?.meta;
|
|
1375
|
+
return /* @__PURE__ */ jsx16(
|
|
1376
|
+
"div",
|
|
1377
|
+
{
|
|
1378
|
+
className: "fixed inset-0 z-[2147483647] flex items-center justify-center bg-black/80",
|
|
1379
|
+
role: "dialog",
|
|
1380
|
+
"aria-modal": "true",
|
|
1381
|
+
"aria-label": resolvedLabels.exitFullscreen,
|
|
1382
|
+
children: /* @__PURE__ */ jsxs8("div", { className: "relative", style: { width: "min(94vw, calc(82vh * 16 / 9))" }, children: [
|
|
1383
|
+
/* @__PURE__ */ jsx16(
|
|
1384
|
+
DeckArtifactContent,
|
|
1385
|
+
{
|
|
1386
|
+
slides: artifact.config.slides,
|
|
1387
|
+
labels: resolvedLabels,
|
|
1388
|
+
onNavigate,
|
|
1389
|
+
meta,
|
|
1390
|
+
currentSlide,
|
|
1391
|
+
onSlideChange,
|
|
1392
|
+
onDark: true
|
|
1393
|
+
}
|
|
1394
|
+
),
|
|
1395
|
+
/* @__PURE__ */ jsxs8(
|
|
1396
|
+
"button",
|
|
1397
|
+
{
|
|
1398
|
+
className: "absolute -top-10 right-6 flex items-center gap-1.5 text-sm text-white/80 hover:text-white",
|
|
1399
|
+
"aria-label": resolvedLabels.exitFullscreen,
|
|
1400
|
+
onClick: onClose,
|
|
1401
|
+
children: [
|
|
1402
|
+
/* @__PURE__ */ jsx16(IconArrowsMinimize, { size: 16 }),
|
|
1403
|
+
/* @__PURE__ */ jsx16("span", { children: resolvedLabels.exitFullscreen })
|
|
1404
|
+
]
|
|
1405
|
+
}
|
|
1406
|
+
)
|
|
1407
|
+
] })
|
|
1408
|
+
}
|
|
1409
|
+
);
|
|
1410
|
+
}
|
|
1411
|
+
|
|
1412
|
+
// src/components/artifacts/table-artifact/table-artifact.tsx
|
|
1413
|
+
import { useEffect as useEffect5, useMemo as useMemo4 } from "react";
|
|
1414
|
+
|
|
1415
|
+
// src/components/artifacts/table-artifact/use-table-artifact-data.ts
|
|
1416
|
+
function useTableArtifactData(presignedUrl, columns) {
|
|
1417
|
+
return useRowsArtifactData(presignedUrl, columns, parseCsv);
|
|
1418
|
+
}
|
|
1419
|
+
|
|
1420
|
+
// src/components/artifacts/table-artifact/table-artifact.tsx
|
|
1421
|
+
import { jsx as jsx17, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1422
|
+
var TITLE_CLASSES3 = "text-sm font-semibold text-foreground";
|
|
860
1423
|
var TABLE_MAX_BODY_HEIGHT = 480;
|
|
861
1424
|
var MAX_SHIMMER_ROWS = 10;
|
|
862
1425
|
function TableArtifact({ artifact, labels, callbacks }) {
|
|
863
1426
|
const validConfig = isValidTableConfig(artifact.config);
|
|
864
1427
|
const validColumns = validConfig ? artifact.config.columns : null;
|
|
865
|
-
|
|
1428
|
+
useEffect5(() => {
|
|
866
1429
|
if (validConfig) return;
|
|
867
1430
|
console.warn("[clay] TableArtifact: malformed `config` \u2014 skipping render.");
|
|
868
1431
|
}, [validConfig]);
|
|
869
|
-
const resolvedLabels =
|
|
1432
|
+
const resolvedLabels = useMemo4(
|
|
870
1433
|
() => ({ ...DEFAULT_TABLE_ARTIFACT_LABELS, ...labels ?? {} }),
|
|
871
1434
|
[labels]
|
|
872
1435
|
);
|
|
@@ -878,10 +1441,10 @@ function TableArtifact({ artifact, labels, callbacks }) {
|
|
|
878
1441
|
const onDownload = callbacks?.onDownload;
|
|
879
1442
|
const handleDownloadClick = onDownload ? () => onDownload(artifact) : void 0;
|
|
880
1443
|
if (!validConfig || !validColumns) {
|
|
881
|
-
return /* @__PURE__ */
|
|
882
|
-
/* @__PURE__ */
|
|
883
|
-
artifact.title ? /* @__PURE__ */
|
|
884
|
-
presignedUrl ? /* @__PURE__ */
|
|
1444
|
+
return /* @__PURE__ */ jsxs9(Artifact, { className: "shadow-none w-full rounded-2xl bg-background/70", children: [
|
|
1445
|
+
/* @__PURE__ */ jsxs9(ArtifactHeader, { className: "bg-background/70", children: [
|
|
1446
|
+
artifact.title ? /* @__PURE__ */ jsx17(ArtifactTitle, { className: TITLE_CLASSES3, children: artifact.title }) : /* @__PURE__ */ jsx17("span", {}),
|
|
1447
|
+
presignedUrl ? /* @__PURE__ */ jsx17(ArtifactActions, { children: /* @__PURE__ */ jsx17(
|
|
885
1448
|
ArtifactDownloadButton,
|
|
886
1449
|
{
|
|
887
1450
|
href: presignedUrl,
|
|
@@ -890,17 +1453,17 @@ function TableArtifact({ artifact, labels, callbacks }) {
|
|
|
890
1453
|
}
|
|
891
1454
|
) }) : null
|
|
892
1455
|
] }),
|
|
893
|
-
/* @__PURE__ */
|
|
1456
|
+
/* @__PURE__ */ jsx17(ArtifactContent, { className: "p-0 overflow-auto", style: { maxHeight: TABLE_MAX_BODY_HEIGHT }, children: /* @__PURE__ */ jsx17(StatusMessage, { $tone: "info", children: resolvedLabels.unavailable }) })
|
|
894
1457
|
] });
|
|
895
1458
|
}
|
|
896
1459
|
return (
|
|
897
1460
|
// The table body owns its own scroll container (`ArtifactTable` inside `TableArtifactContent`).
|
|
898
1461
|
// Disable the outer overflow container so only one scroll context exists — this prevents
|
|
899
1462
|
// double-scroll nesting and lets `useScrollShadow` find the correct scroll ancestor.
|
|
900
|
-
/* @__PURE__ */
|
|
901
|
-
/* @__PURE__ */
|
|
902
|
-
artifact.title ? /* @__PURE__ */
|
|
903
|
-
/* @__PURE__ */
|
|
1463
|
+
/* @__PURE__ */ jsxs9(Artifact, { className: "shadow-none w-full rounded-2xl bg-background/70", children: [
|
|
1464
|
+
/* @__PURE__ */ jsxs9(ArtifactHeader, { className: "bg-background/70", children: [
|
|
1465
|
+
artifact.title ? /* @__PURE__ */ jsx17(ArtifactTitle, { className: TITLE_CLASSES3, children: artifact.title }) : /* @__PURE__ */ jsx17("span", {}),
|
|
1466
|
+
/* @__PURE__ */ jsx17(ArtifactActions, { children: /* @__PURE__ */ jsx17(
|
|
904
1467
|
ArtifactDownloadButton,
|
|
905
1468
|
{
|
|
906
1469
|
href: presignedUrl ?? "",
|
|
@@ -909,7 +1472,7 @@ function TableArtifact({ artifact, labels, callbacks }) {
|
|
|
909
1472
|
}
|
|
910
1473
|
) })
|
|
911
1474
|
] }),
|
|
912
|
-
/* @__PURE__ */
|
|
1475
|
+
/* @__PURE__ */ jsx17(ArtifactContent, { className: "p-0 overflow-visible", style: { maxHeight: "none" }, children: /* @__PURE__ */ jsx17(
|
|
913
1476
|
TableArtifactContent,
|
|
914
1477
|
{
|
|
915
1478
|
columns: validColumns,
|
|
@@ -937,6 +1500,65 @@ var ChartArtifactService = {
|
|
|
937
1500
|
toClipboardText: chartArtifactToClipboardText
|
|
938
1501
|
};
|
|
939
1502
|
|
|
1503
|
+
// src/components/artifacts/deck-artifact/to-clipboard-text.ts
|
|
1504
|
+
function deckArtifactToClipboardText(artifact) {
|
|
1505
|
+
const header = artifact.title?.trim() || "Deck";
|
|
1506
|
+
const slides = artifact.config?.slides ?? [];
|
|
1507
|
+
const body = slides.map((slide, i) => slideToText(slide, i)).join("\n\n");
|
|
1508
|
+
return body ? `${header}
|
|
1509
|
+
|
|
1510
|
+
${body}` : header;
|
|
1511
|
+
}
|
|
1512
|
+
function slideToText(slide, index) {
|
|
1513
|
+
const kind = slide.kind ?? deckSlideKinds.CONTENT;
|
|
1514
|
+
const prefix = `Slide ${index + 1}: `;
|
|
1515
|
+
switch (kind) {
|
|
1516
|
+
case deckSlideKinds.TITLE: {
|
|
1517
|
+
const parts = [slide.title];
|
|
1518
|
+
if (slide.subtitle) parts.push(slide.subtitle);
|
|
1519
|
+
if (slide.description) parts.push(slide.description);
|
|
1520
|
+
return `${prefix}${parts.join(" \u2014 ")}`.trim();
|
|
1521
|
+
}
|
|
1522
|
+
case deckSlideKinds.AGENDA: {
|
|
1523
|
+
const items = (slide.items ?? []).map((item, i) => ` ${String(i + 1).padStart(2, "0")}. ${item}`).join("\n");
|
|
1524
|
+
return `${prefix}${slide.title || "Agenda"}${items ? `
|
|
1525
|
+
${items}` : ""}`.trim();
|
|
1526
|
+
}
|
|
1527
|
+
case deckSlideKinds.SECTION:
|
|
1528
|
+
return `${prefix}${slide.title}`.trim();
|
|
1529
|
+
case deckSlideKinds.CLOSING:
|
|
1530
|
+
return `${prefix}Thank you`.trim();
|
|
1531
|
+
case deckSlideKinds.CONTENT:
|
|
1532
|
+
default: {
|
|
1533
|
+
const blocks = (slide.content ?? []).map(blockToText).filter(Boolean).join("\n\n");
|
|
1534
|
+
return `${prefix}${slide.title}${blocks ? `
|
|
1535
|
+
${blocks}` : ""}`.trim();
|
|
1536
|
+
}
|
|
1537
|
+
}
|
|
1538
|
+
}
|
|
1539
|
+
function blockToText(block) {
|
|
1540
|
+
switch (block.type) {
|
|
1541
|
+
case deckBlockTypes.TEXT:
|
|
1542
|
+
return block.markdown.trim();
|
|
1543
|
+
case deckBlockTypes.CHART:
|
|
1544
|
+
return `[Chart: ${block.config.variant}]`;
|
|
1545
|
+
case deckBlockTypes.TABLE: {
|
|
1546
|
+
const columnCount = block.config.columns.length;
|
|
1547
|
+
const rowCount = block.rows.length;
|
|
1548
|
+
return `[Table: ${columnCount} column${columnCount === 1 ? "" : "s"} \xD7 ${rowCount} row${rowCount === 1 ? "" : "s"}]`;
|
|
1549
|
+
}
|
|
1550
|
+
default:
|
|
1551
|
+
return "";
|
|
1552
|
+
}
|
|
1553
|
+
}
|
|
1554
|
+
|
|
1555
|
+
// src/components/artifacts/artifact-services/deck-artifact-service.ts
|
|
1556
|
+
var DeckArtifactService = {
|
|
1557
|
+
type: artifactTypes.DECK,
|
|
1558
|
+
Component: DeckArtifact,
|
|
1559
|
+
toClipboardText: deckArtifactToClipboardText
|
|
1560
|
+
};
|
|
1561
|
+
|
|
940
1562
|
// src/components/artifacts/table-artifact/to-clipboard-text.ts
|
|
941
1563
|
function tableArtifactToClipboardText(artifact) {
|
|
942
1564
|
const trimmedTitle = artifact.title?.trim();
|
|
@@ -953,7 +1575,8 @@ var TableArtifactService = {
|
|
|
953
1575
|
// src/components/artifacts/artifact-services/index.ts
|
|
954
1576
|
var ArtifactServices = {
|
|
955
1577
|
[artifactTypes.TABLE]: TableArtifactService,
|
|
956
|
-
[artifactTypes.CHART]: ChartArtifactService
|
|
1578
|
+
[artifactTypes.CHART]: ChartArtifactService,
|
|
1579
|
+
[artifactTypes.DECK]: DeckArtifactService
|
|
957
1580
|
};
|
|
958
1581
|
function artifactToClipboardText(artifact) {
|
|
959
1582
|
const entry = ArtifactServices[artifact.type];
|
|
@@ -967,6 +1590,9 @@ export {
|
|
|
967
1590
|
artifactTypes,
|
|
968
1591
|
DEFAULT_CHART_ARTIFACT_LABELS,
|
|
969
1592
|
DEFAULT_TABLE_ARTIFACT_LABELS,
|
|
1593
|
+
deckBlockTypes,
|
|
1594
|
+
deckSlideKinds,
|
|
1595
|
+
DEFAULT_DECK_ARTIFACT_LABELS,
|
|
970
1596
|
IconCheck,
|
|
971
1597
|
IconCopy,
|
|
972
1598
|
IconThumbDown,
|
|
@@ -976,6 +1602,7 @@ export {
|
|
|
976
1602
|
isSafeDownloadUrl,
|
|
977
1603
|
ArtifactDownloadMenu,
|
|
978
1604
|
ChartArtifact,
|
|
1605
|
+
DeckArtifact,
|
|
979
1606
|
TableArtifact,
|
|
980
1607
|
ArtifactServices,
|
|
981
1608
|
artifactToClipboardText
|
|
@@ -985,7 +1612,11 @@ export {
|
|
|
985
1612
|
@tabler/icons-react/dist/esm/defaultAttributes.mjs:
|
|
986
1613
|
@tabler/icons-react/dist/esm/createReactComponent.mjs:
|
|
987
1614
|
@tabler/icons-react/dist/esm/icons/IconAlertCircle.mjs:
|
|
1615
|
+
@tabler/icons-react/dist/esm/icons/IconArrowsMaximize.mjs:
|
|
1616
|
+
@tabler/icons-react/dist/esm/icons/IconArrowsMinimize.mjs:
|
|
988
1617
|
@tabler/icons-react/dist/esm/icons/IconCheck.mjs:
|
|
1618
|
+
@tabler/icons-react/dist/esm/icons/IconChevronLeft.mjs:
|
|
1619
|
+
@tabler/icons-react/dist/esm/icons/IconChevronRight.mjs:
|
|
989
1620
|
@tabler/icons-react/dist/esm/icons/IconCopy.mjs:
|
|
990
1621
|
@tabler/icons-react/dist/esm/icons/IconDownload.mjs:
|
|
991
1622
|
@tabler/icons-react/dist/esm/icons/IconFileSpreadsheet.mjs:
|
|
@@ -1001,4 +1632,4 @@ export {
|
|
|
1001
1632
|
* See the LICENSE file in the root directory of this source tree.
|
|
1002
1633
|
*)
|
|
1003
1634
|
*/
|
|
1004
|
-
//# sourceMappingURL=chunk-
|
|
1635
|
+
//# sourceMappingURL=chunk-QR4VBGK4.js.map
|