@seed-ship/mcp-ui-solid 1.0.39 → 1.0.40

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.
@@ -6,7 +6,7 @@ const solidJs = require("solid-js");
6
6
  const validation = require("../services/validation.cjs");
7
7
  const GenerativeUIErrorBoundary = require("./GenerativeUIErrorBoundary.cjs");
8
8
  const marked_esm = require("../node_modules/.pnpm/marked@16.4.2/node_modules/marked/lib/marked.esm.cjs");
9
- var _tmpl$ = ["<div", ' class="absolute inset-0 flex items-center justify-center"><div class="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600"></div></div>'], _tmpl$2 = ["<div", ' class="absolute inset-0 flex items-center justify-center p-4"><div class="text-center"><p class="text-red-600 dark:text-red-400 text-sm font-medium">Chart Error</p><p class="text-gray-600 dark:text-gray-400 text-xs mt-1">', "</p></div></div>"], _tmpl$3 = ["<h3", ' class="text-sm font-semibold text-gray-900 dark:text-white mb-3">', "</h3>"], _tmpl$4 = ["<div", ' class="w-full h-full p-4"><!--$-->', '<!--/--><div class="w-full h-full"><img', ' alt="Chart visualization" class="w-full h-auto max-h-[300px] object-contain"></div></div>'], _tmpl$5 = ["<div", ' class="relative w-full h-full min-h-[300px] bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden"><!--$-->', "<!--/--><!--$-->", "<!--/--><!--$-->", "<!--/--></div>"], _tmpl$6 = ["<div", ' class="mt-3 flex items-center justify-between text-xs text-gray-500 dark:text-gray-400"><span>Showing <!--$-->', "<!--/--> - <!--$-->", "<!--/--> of <!--$-->", "<!--/--></span></div>"], _tmpl$7 = ["<div", ' class="w-full h-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden"><div class="p-4"><!--$-->', '<!--/--><div class="overflow-x-auto"><table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700 border-separate border-spacing-0"><thead class="bg-gray-50 dark:bg-gray-900/50"><tr>', '</tr></thead><tbody class="bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700">', "</tbody></table></div><!--$-->", "<!--/--></div></div>"], _tmpl$8 = ["<th", ' scope="col" class="px-6 py-3 text-left text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wider border-b border-gray-200 dark:border-gray-700 first:pl-6 last:pr-6" style="', '">', "</th>"], _tmpl$9 = ["<tr", ' class="', '">', "</tr>"], _tmpl$0 = ["<td", ' class="px-6 py-4 text-sm text-gray-700 dark:text-gray-200 whitespace-normal break-words leading-relaxed first:pl-6 last:pr-6"><div>', "</div></td>"], _tmpl$1 = ["<span", ' class="ml-2 text-sm font-medium text-gray-500 dark:text-gray-400">', "</span>"], _tmpl$10 = ["<div", ' class="mt-3 flex items-center"><span class="', '"><!--$-->', "<!--/--> <!--$-->", "<!--/-->%</span></div>"], _tmpl$11 = ["<p", ' class="mt-2 text-xs text-gray-500 dark:text-gray-400">', "</p>"], _tmpl$12 = ["<div", ' class="w-full h-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-4"><div class="flex flex-col h-full justify-between"><div><p class="text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wide">', '</p><div class="mt-2 flex items-baseline"><p class="text-2xl font-semibold text-gray-900 dark:text-white">', "</p><!--$-->", "<!--/--></div></div><!--$-->", "<!--/--><!--$-->", "<!--/--></div></div>"], _tmpl$13 = ["<div", ' class="w-full h-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-4"><div class="', '">', "</div></div>"], _tmpl$14 = ["<div", ' class="px-4 py-2 border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900"><h3 class="text-sm font-semibold text-gray-900 dark:text-white">', "</h3></div>"], _tmpl$15 = ["<div", ' class="w-full h-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden flex flex-col"><!--$-->', "<!--/--><iframe", ' class="w-full border-0 flex-1" style="', '" sandbox="allow-scripts allow-same-origin allow-popups allow-forms" loading="lazy"></iframe></div>'], _tmpl$16 = ["<div", ' class="p-3 border-t border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800"><p class="text-sm text-gray-600 dark:text-gray-400 text-center">', "</p></div>"], _tmpl$17 = ["<div", ' class="w-full h-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden flex flex-col"><div class="flex-1 flex items-center justify-center p-4 bg-gray-50 dark:bg-gray-900 min-h-[200px]"><a', ' target="_blank" rel="noopener noreferrer" class="cursor-zoom-in"><img', ' class="max-w-full max-h-[500px] object-contain rounded shadow-sm hover:opacity-95 transition-opacity" loading="lazy"></a></div><!--$-->', "<!--/--></div>"], _tmpl$18 = ["<p", ' class="text-xs text-gray-500 dark:text-gray-400 truncate">', "</p>"], _tmpl$19 = ["<a", ' target="_blank" rel="noopener noreferrer" class="flex items-center gap-3 p-4 bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors group h-full"><div class="p-2 bg-blue-50 dark:bg-blue-900/30 rounded-full text-blue-600 dark:text-blue-400 group-hover:bg-blue-100 dark:group-hover:bg-blue-900/50 shrink-0 transition-colors"><svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg></div><div class="flex-1 min-w-0"><h4 class="text-sm font-medium text-gray-900 dark:text-white truncate group-hover:text-blue-600 dark:group-hover:text-blue-400 transition-colors">', "</h4><!--$-->", '<!--/--></div><svg xmlns="http://www.w3.org/2000/svg" class="w-4 h-4 text-gray-400 group-hover:text-gray-600 dark:group-hover:text-gray-300 shrink-0 transition-colors" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path><polyline points="15 3 21 3 21 9"></polyline><line x1="10" y1="14" x2="21" y2="3"></line></svg></a>'], _tmpl$20 = ["<div", ' class="w-full h-full bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg p-4"><p class="text-sm font-medium text-red-900 dark:text-red-100">Validation Error</p><p class="text-xs text-red-700 dark:text-red-300 mt-1">', "</p></div>"], _tmpl$21 = ["<span", ">", "</span>"], _tmpl$22 = ["<a", ' rel="noopener noreferrer" class="', '"><!--$-->', "<!--/--><!--$-->", "<!--/--></a>"], _tmpl$23 = ["<button", "", ' class="', '"><!--$-->', "<!--/--><!--$-->", "<!--/--></button>"], _tmpl$24 = ["<div", ' class="', '"><div class="grid gap-4" style="', '">', "</div></div>"], _tmpl$25 = ["<div", ' style="', '">', "</div>"];
9
+ var _tmpl$ = ["<div", ' class="absolute inset-0 flex items-center justify-center"><div class="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600"></div></div>'], _tmpl$2 = ["<div", ' class="absolute inset-0 flex items-center justify-center p-4"><div class="text-center"><p class="text-red-600 dark:text-red-400 text-sm font-medium">Chart Error</p><p class="text-gray-600 dark:text-gray-400 text-xs mt-1">', "</p></div></div>"], _tmpl$3 = ["<h3", ' class="text-sm font-semibold text-gray-900 dark:text-white mb-3">', "</h3>"], _tmpl$4 = ["<div", ' class="w-full h-full p-4"><!--$-->', '<!--/--><div class="w-full h-full"><img', ' alt="Chart visualization" class="w-full h-auto max-h-[300px] object-contain"></div></div>'], _tmpl$5 = ["<div", ' class="relative w-full h-full min-h-[300px] bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden"><!--$-->', "<!--/--><!--$-->", "<!--/--><!--$-->", "<!--/--></div>"], _tmpl$6 = ["<div", ' class="mt-3 flex items-center justify-between text-xs text-gray-500 dark:text-gray-400"><span>Showing <!--$-->', "<!--/--> - <!--$-->", "<!--/--> of <!--$-->", "<!--/--></span></div>"], _tmpl$7 = ["<div", ' class="w-full h-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden"><div class="p-4"><!--$-->', '<!--/--><div class="overflow-x-auto"><table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700 border-separate border-spacing-0"><thead class="bg-gray-50 dark:bg-gray-900/50"><tr>', '</tr></thead><tbody class="bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700">', "</tbody></table></div><!--$-->", "<!--/--></div></div>"], _tmpl$8 = ["<th", ' scope="col" class="px-6 py-3 text-left text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wider border-b border-gray-200 dark:border-gray-700 first:pl-6 last:pr-6" style="', '">', "</th>"], _tmpl$9 = ["<tr", ' class="', '">', "</tr>"], _tmpl$0 = ["<td", ' class="px-6 py-4 text-sm text-gray-700 dark:text-gray-200 whitespace-normal break-words leading-relaxed first:pl-6 last:pr-6"><div>', "</div></td>"], _tmpl$1 = ["<span", ' class="ml-2 text-sm font-medium text-gray-500 dark:text-gray-400">', "</span>"], _tmpl$10 = ["<div", ' class="mt-3 flex items-center"><span class="', '"><!--$-->', "<!--/--> <!--$-->", "<!--/-->%</span></div>"], _tmpl$11 = ["<p", ' class="mt-2 text-xs text-gray-500 dark:text-gray-400">', "</p>"], _tmpl$12 = ["<div", ' class="w-full h-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-4"><div class="flex flex-col h-full justify-between"><div><p class="text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wide">', '</p><div class="mt-2 flex items-baseline"><p class="text-2xl font-semibold text-gray-900 dark:text-white">', "</p><!--$-->", "<!--/--></div></div><!--$-->", "<!--/--><!--$-->", "<!--/--></div></div>"], _tmpl$13 = ["<div", ' class="w-full h-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-4"><div class="', '">', "</div></div>"], _tmpl$14 = ["<div", ' class="w-full h-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden flex flex-col"><div class="flex-1 flex items-center justify-center p-4 bg-gray-50 dark:bg-gray-900 min-h-[200px]"><a', ' target="_blank" rel="noopener noreferrer" class="cursor-zoom-in"><img', ' class="max-w-full max-h-[400px] object-contain rounded shadow-sm hover:opacity-90 transition-opacity" loading="lazy"></a></div><div class="p-3 border-t border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800"><p class="text-sm text-gray-600 dark:text-gray-400 text-center italic">', "</p></div></div>"], _tmpl$15 = ["<div", ' class="px-4 py-2 border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900"><h3 class="text-sm font-semibold text-gray-900 dark:text-white">', "</h3></div>"], _tmpl$16 = ["<div", ' class="w-full h-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden flex flex-col"><!--$-->', "<!--/--><iframe", ' class="w-full border-0 flex-1" style="', '" sandbox="allow-scripts allow-same-origin allow-popups allow-forms" loading="lazy"></iframe></div>'], _tmpl$17 = ["<div", ' class="p-3 border-t border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800"><p class="text-sm text-gray-600 dark:text-gray-400 text-center">', "</p></div>"], _tmpl$18 = ["<div", ' class="w-full h-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden flex flex-col"><div class="flex-1 flex items-center justify-center p-4 bg-gray-50 dark:bg-gray-900 min-h-[200px]"><a', ' target="_blank" rel="noopener noreferrer" class="cursor-zoom-in"><img', ' class="max-w-full max-h-[500px] object-contain rounded shadow-sm hover:opacity-95 transition-opacity" loading="lazy"></a></div><!--$-->', "<!--/--></div>"], _tmpl$19 = ["<p", ' class="text-xs text-gray-500 dark:text-gray-400 truncate">', "</p>"], _tmpl$20 = ["<a", ' target="_blank" rel="noopener noreferrer" class="flex items-center gap-3 p-4 bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors group h-full"><div class="p-2 bg-blue-50 dark:bg-blue-900/30 rounded-full text-blue-600 dark:text-blue-400 group-hover:bg-blue-100 dark:group-hover:bg-blue-900/50 shrink-0 transition-colors"><svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg></div><div class="flex-1 min-w-0"><h4 class="text-sm font-medium text-gray-900 dark:text-white truncate group-hover:text-blue-600 dark:group-hover:text-blue-400 transition-colors">', "</h4><!--$-->", '<!--/--></div><svg xmlns="http://www.w3.org/2000/svg" class="w-4 h-4 text-gray-400 group-hover:text-gray-600 dark:group-hover:text-gray-300 shrink-0 transition-colors" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path><polyline points="15 3 21 3 21 9"></polyline><line x1="10" y1="14" x2="21" y2="3"></line></svg></a>'], _tmpl$21 = ["<div", ' class="w-full h-full bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg p-4"><p class="text-sm font-medium text-red-900 dark:text-red-100">Validation Error</p><p class="text-xs text-red-700 dark:text-red-300 mt-1">', "</p></div>"], _tmpl$22 = ["<span", ">", "</span>"], _tmpl$23 = ["<a", ' rel="noopener noreferrer" class="', '"><!--$-->', "<!--/--><!--$-->", "<!--/--></a>"], _tmpl$24 = ["<button", "", ' class="', '"><!--$-->', "<!--/--><!--$-->", "<!--/--></button>"], _tmpl$25 = ["<div", ' class="', '"><div class="grid gap-4" style="', '">', "</div></div>"], _tmpl$26 = ["<div", ' style="', '">', "</div>"];
10
10
  function ChartRenderer(props) {
11
11
  const [iframeUrl, setIframeUrl] = solidJs.createSignal();
12
12
  const [isLoading, setIsLoading] = solidJs.createSignal(true);
@@ -58,6 +58,37 @@ function ChartRenderer(props) {
58
58
  }
59
59
  })));
60
60
  }
61
+ function renderCellValue(value) {
62
+ if (value === null || value === void 0) {
63
+ return "-";
64
+ }
65
+ let strValue = String(value);
66
+ strValue = strValue.replace(/\s*[–-]\s*undefined\s*$/gi, "");
67
+ strValue = strValue.replace(/^undefined\s*[–-]\s*/gi, "");
68
+ if (strValue.trim().toLowerCase() === "undefined") {
69
+ return "-";
70
+ }
71
+ if (strValue.trim() === "") {
72
+ return "-";
73
+ }
74
+ const markdownLinkRegex = /\[([^\]]+)\]\(([^)]+)\)/g;
75
+ if (markdownLinkRegex.test(strValue)) {
76
+ const htmlValue = strValue.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2" target="_blank" rel="noopener noreferrer" class="text-blue-600 dark:text-blue-400 hover:underline">$1</a>');
77
+ return purify_es.sanitize(htmlValue, {
78
+ ADD_ATTR: ["target", "rel"]
79
+ });
80
+ }
81
+ const hasMarkdown = /[*_`\[\]#]/.test(strValue);
82
+ if (hasMarkdown) {
83
+ const parsed = marked_esm.marked.parse(strValue, {
84
+ async: false
85
+ });
86
+ return purify_es.sanitize(parsed, {
87
+ ADD_ATTR: ["target", "rel"]
88
+ });
89
+ }
90
+ return strValue;
91
+ }
61
92
  function TableRenderer(props) {
62
93
  const tableParams = props.component.params;
63
94
  return web.ssr(_tmpl$7, web.ssrHydrationKey(), web.escape(web.createComponent(solidJs.Show, {
@@ -82,11 +113,7 @@ function TableRenderer(props) {
82
113
  get each() {
83
114
  return tableParams.columns;
84
115
  },
85
- children: (column) => web.ssr(_tmpl$0, web.ssrHydrationKey(), typeof row[column.key] === "string" && (row[column.key].includes("[") || row[column.key].includes("**") || row[column.key].includes("`")) ? purify_es.sanitize(marked_esm.marked.parse(row[column.key], {
86
- async: false
87
- }), {
88
- ADD_ATTR: ["target", "rel"]
89
- }) : row[column.key] || "-")
116
+ children: (column) => web.ssr(_tmpl$0, web.ssrHydrationKey(), renderCellValue(row[column.key]))
90
117
  })))
91
118
  })), web.escape(web.createComponent(solidJs.Show, {
92
119
  get when() {
@@ -122,48 +149,75 @@ function MetricRenderer(props) {
122
149
  }
123
150
  })));
124
151
  }
152
+ function extractImageFromMarkdown(content) {
153
+ const imagePattern = /\[!\[([^\]]*)\]\(([^)]+)\)\]\(([^)]+)\)\s*\*([^*]+)\*/;
154
+ const match = content.match(imagePattern);
155
+ if (match) {
156
+ return {
157
+ alt: match[1] || "Image",
158
+ imageUrl: match[2],
159
+ linkUrl: match[3],
160
+ credit: match[4].trim()
161
+ };
162
+ }
163
+ return null;
164
+ }
125
165
  function TextRenderer(props) {
126
166
  const textParams = props.component.params;
167
+ const imageData = solidJs.createMemo(() => {
168
+ if (textParams.markdown && textParams.content) {
169
+ return extractImageFromMarkdown(textParams.content);
170
+ }
171
+ return null;
172
+ });
127
173
  const htmlContent = solidJs.createMemo(() => {
128
- if (textParams.markdown) {
174
+ if (textParams.markdown && !imageData()) {
129
175
  return marked_esm.marked.parse(textParams.content, {
130
176
  async: false
131
177
  });
132
178
  }
133
179
  return textParams.content;
134
180
  });
135
- return web.ssr(_tmpl$13, web.ssrHydrationKey(), `prose prose-sm dark:prose-invert max-w-none ${web.escape(textParams.className, true) || ""}`, htmlContent());
181
+ return web.createComponent(solidJs.Show, {
182
+ get when() {
183
+ return imageData();
184
+ },
185
+ get fallback() {
186
+ return web.ssr(_tmpl$13, web.ssrHydrationKey(), `prose prose-sm dark:prose-invert max-w-none ${web.escape(textParams.className, true) || ""}`, htmlContent());
187
+ },
188
+ children: (data) => web.ssr(_tmpl$14, web.ssrHydrationKey(), web.ssrAttribute("href", web.escape(data().linkUrl, true), false), web.ssrAttribute("src", web.escape(data().imageUrl, true), false) + web.ssrAttribute("alt", web.escape(data().alt, true), false), web.escape(data().credit))
189
+ });
136
190
  }
137
191
  function IframeRenderer(props) {
138
192
  const params = props.component.params;
139
- return web.ssr(_tmpl$15, web.ssrHydrationKey(), web.escape(web.createComponent(solidJs.Show, {
193
+ return web.ssr(_tmpl$16, web.ssrHydrationKey(), web.escape(web.createComponent(solidJs.Show, {
140
194
  get when() {
141
195
  return params.title;
142
196
  },
143
197
  get children() {
144
- return web.ssr(_tmpl$14, web.ssrHydrationKey(), web.escape(params.title));
198
+ return web.ssr(_tmpl$15, web.ssrHydrationKey(), web.escape(params.title));
145
199
  }
146
200
  })), web.ssrAttribute("src", web.escape(params.url, true), false) + web.ssrAttribute("title", web.escape(params.title, true) || "Embedded content", false), web.ssrStyle(`height: ${params.height || "400px"}; min-height: 300px;`));
147
201
  }
148
202
  function ImageRenderer(props) {
149
203
  const params = props.component.params;
150
- return web.ssr(_tmpl$17, web.ssrHydrationKey(), web.ssrAttribute("href", web.escape(params.url, true), false), web.ssrAttribute("src", web.escape(params.url, true), false) + web.ssrAttribute("alt", web.escape(params.alt, true) || "Image", false), web.escape(web.createComponent(solidJs.Show, {
204
+ return web.ssr(_tmpl$18, web.ssrHydrationKey(), web.ssrAttribute("href", web.escape(params.url, true), false), web.ssrAttribute("src", web.escape(params.url, true), false) + web.ssrAttribute("alt", web.escape(params.alt, true) || "Image", false), web.escape(web.createComponent(solidJs.Show, {
151
205
  get when() {
152
206
  return params.caption;
153
207
  },
154
208
  get children() {
155
- return web.ssr(_tmpl$16, web.ssrHydrationKey(), web.escape(params.caption));
209
+ return web.ssr(_tmpl$17, web.ssrHydrationKey(), web.escape(params.caption));
156
210
  }
157
211
  })));
158
212
  }
159
213
  function LinkRenderer(props) {
160
214
  const params = props.component.params;
161
- return web.ssr(_tmpl$19, web.ssrHydrationKey() + web.ssrAttribute("href", web.escape(params.url, true), false), web.escape(params.label) || web.escape(params.url), web.escape(web.createComponent(solidJs.Show, {
215
+ return web.ssr(_tmpl$20, web.ssrHydrationKey() + web.ssrAttribute("href", web.escape(params.url, true), false), web.escape(params.label) || web.escape(params.url), web.escape(web.createComponent(solidJs.Show, {
162
216
  get when() {
163
217
  return params.description;
164
218
  },
165
219
  get children() {
166
- return web.ssr(_tmpl$18, web.ssrHydrationKey(), web.escape(params.description));
220
+ return web.ssr(_tmpl$19, web.ssrHydrationKey(), web.escape(params.description));
167
221
  }
168
222
  })));
169
223
  }
@@ -177,7 +231,7 @@ function ComponentRenderer(props) {
177
231
  componentId: props.component.id,
178
232
  details: validation$1.errors
179
233
  });
180
- return web.ssr(_tmpl$20, web.ssrHydrationKey(), web.escape((_c = (_b = validation$1.errors) == null ? void 0 : _b[0]) == null ? void 0 : _c.message) || "Unknown validation error");
234
+ return web.ssr(_tmpl$21, web.ssrHydrationKey(), web.escape((_c = (_b = validation$1.errors) == null ? void 0 : _b[0]) == null ? void 0 : _c.message) || "Unknown validation error");
181
235
  }
182
236
  return web.createComponent(GenerativeUIErrorBoundary.GenerativeUIErrorBoundary, {
183
237
  get componentId() {
@@ -294,17 +348,17 @@ function ActionRenderer(props) {
294
348
  solidJs.createEffect(() => {
295
349
  });
296
350
  if (params.type === "link" || params.action === "link") {
297
- return web.ssr(_tmpl$22, web.ssrHydrationKey() + web.ssrAttribute("href", web.escape(params.url, true) || "#", false) + web.ssrAttribute("target", params.url ? "_blank" : web.escape(void 0, true), false), `inline-flex items-center gap-2 px-4 py-2 rounded-md text-sm font-medium transition-colors
351
+ return web.ssr(_tmpl$23, web.ssrHydrationKey() + web.ssrAttribute("href", web.escape(params.url, true) || "#", false) + web.ssrAttribute("target", params.url ? "_blank" : web.escape(void 0, true), false), `inline-flex items-center gap-2 px-4 py-2 rounded-md text-sm font-medium transition-colors
298
352
  ${params.variant === "primary" ? "bg-blue-600 text-white hover:bg-blue-700" : params.variant === "outline" ? "border border-gray-300 text-gray-700 hover:bg-gray-50 dark:border-gray-600 dark:text-gray-300 dark:hover:bg-gray-800" : "text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300"}`, web.escape(web.createComponent(solidJs.Show, {
299
353
  get when() {
300
354
  return params.icon;
301
355
  },
302
356
  get children() {
303
- return web.ssr(_tmpl$21, web.ssrHydrationKey(), web.escape(params.icon));
357
+ return web.ssr(_tmpl$22, web.ssrHydrationKey(), web.escape(params.icon));
304
358
  }
305
359
  })), web.escape(params.label));
306
360
  }
307
- return web.ssr(_tmpl$23, web.ssrHydrationKey() + web.ssrAttribute("type", params.action === "submit" ? "submit" : "button", false), web.ssrAttribute("disabled", params.disabled, true), `inline-flex items-center gap-2 px-4 py-2 rounded-md text-sm font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500
361
+ return web.ssr(_tmpl$24, web.ssrHydrationKey() + web.ssrAttribute("type", params.action === "submit" ? "submit" : "button", false), web.ssrAttribute("disabled", params.disabled, true), `inline-flex items-center gap-2 px-4 py-2 rounded-md text-sm font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500
308
362
  ${params.variant === "primary" ? "bg-blue-600 text-white hover:bg-blue-700 shadow-sm" : params.variant === "secondary" ? "bg-gray-100 text-gray-900 hover:bg-gray-200 dark:bg-gray-700 dark:text-white dark:hover:bg-gray-600" : params.variant === "outline" ? "border border-gray-300 text-gray-700 hover:bg-gray-50 dark:border-gray-600 dark:text-gray-300 dark:hover:bg-gray-800" : params.variant === "danger" ? "bg-red-600 text-white hover:bg-red-700" : "bg-transparent text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-800"}
309
363
  ${params.disabled ? "opacity-50 cursor-not-allowed" : ""}
310
364
  ${params.size === "sm" ? "px-3 py-1.5 text-xs" : params.size === "lg" ? "px-6 py-3 text-base" : ""}`, web.escape(web.createComponent(solidJs.Show, {
@@ -312,7 +366,7 @@ function ActionRenderer(props) {
312
366
  return params.icon;
313
367
  },
314
368
  get children() {
315
- return web.ssr(_tmpl$21, web.ssrHydrationKey(), web.escape(params.icon));
369
+ return web.ssr(_tmpl$22, web.ssrHydrationKey(), web.escape(params.icon));
316
370
  }
317
371
  })), web.escape(params.label));
318
372
  }
@@ -330,10 +384,12 @@ const UIResourceRenderer = (props) => {
330
384
  }
331
385
  return props.content;
332
386
  };
333
- const gridContainerStyle = () => `grid-template-columns: repeat(${layout().grid.columns}, 1fr); gap: ${layout().grid.gap}`;
387
+ const gridContainerStyle = () => {
388
+ const layoutData2 = layout();
389
+ return `grid-template-columns: repeat(${layoutData2.grid.columns}, 1fr); gap: ${layoutData2.grid.gap}`;
390
+ };
334
391
  const getGridStyleString = (component) => {
335
392
  if (!component.position) {
336
- console.error("[UIResourceRenderer] Component missing position field:", component);
337
393
  return "grid-column: 1 / span 12; grid-row: auto";
338
394
  }
339
395
  const {
@@ -344,11 +400,12 @@ const UIResourceRenderer = (props) => {
344
400
  } = component.position;
345
401
  return `grid-column: ${colStart} / span ${colSpan}; grid-row: ${rowStart ? `${rowStart} / span ${rowSpan}` : "auto"}`;
346
402
  };
347
- return web.ssr(_tmpl$24, web.ssrHydrationKey(), `w-full ${web.escape(props.class, true) || ""}`, web.ssrStyle(gridContainerStyle()), web.escape(web.createComponent(solidJs.For, {
403
+ const layoutData = layout();
404
+ return web.ssr(_tmpl$25, web.ssrHydrationKey(), `w-full ${web.escape(props.class, true) || ""}`, web.ssrStyle(gridContainerStyle()), web.escape(web.createComponent(solidJs.For, {
348
405
  get each() {
349
- return layout().components;
406
+ return layoutData.components;
350
407
  },
351
- children: (component) => web.ssr(_tmpl$25, web.ssrHydrationKey(), web.ssrStyle(getGridStyleString(component)), web.escape(web.createComponent(ComponentRenderer, {
408
+ children: (component) => web.ssr(_tmpl$26, web.ssrHydrationKey(), web.ssrStyle(getGridStyleString(component)), web.escape(web.createComponent(ComponentRenderer, {
352
409
  component,
353
410
  get onError() {
354
411
  return props.onError;
@@ -1 +1 @@
1
- {"version":3,"file":"UIResourceRenderer.cjs","sources":["../../src/components/UIResourceRenderer.tsx"],"sourcesContent":["/**\n * UI Resource Renderer Component\n * Phase 0: Foundation with iframe sandbox and composite grid support\n */\n\nimport DOMPurify from 'dompurify'\nimport { Component, createSignal, Show, For, createMemo, createEffect } from 'solid-js'\nimport { isServer } from 'solid-js/web'\nimport type { UIComponent, UILayout, RendererError, ComponentType } from '../types'\nimport { validateComponent, DEFAULT_RESOURCE_LIMITS } from '../services/validation'\nimport { GenerativeUIErrorBoundary } from './GenerativeUIErrorBoundary'\nimport { marked } from 'marked'\n\n/**\n * Props for UIResourceRenderer\n */\nexport interface UIResourceRendererProps {\n /**\n * Single component or full layout to render\n */\n content: UIComponent | UILayout\n\n /**\n * Lazy loading (default: true)\n */\n lazyLoad?: boolean\n\n /**\n * Error callback\n */\n onError?: (error: RendererError) => void\n\n /**\n * Custom CSS class\n */\n class?: string\n}\n\n/**\n * Render a single chart component in a sandboxed iframe\n */\nfunction ChartRenderer(props: {\n component: UIComponent\n onError?: (error: RendererError) => void\n}) {\n const [iframeUrl, setIframeUrl] = createSignal<string>()\n const [isLoading, setIsLoading] = createSignal(true)\n const [error, setError] = createSignal<string>()\n\n // Use createEffect instead of onMount for SSR compatibility\n // createEffect runs after hydration on client-side\n createEffect(() => {\n const chartParams = props.component.params as any\n if (!chartParams) return\n\n // Build Quickchart URL\n const chartConfig = {\n type: chartParams.type,\n data: chartParams.data,\n options: {\n ...chartParams.options,\n responsive: true,\n maintainAspectRatio: false,\n },\n }\n\n // Encode chart configuration for Quickchart API\n const configStr = encodeURIComponent(JSON.stringify(chartConfig))\n const url = `https://quickchart.io/chart?c=${configStr}&width=500&height=300&devicePixelRatio=2`\n\n // Validate domain (should always pass for quickchart.io)\n setIframeUrl(url)\n setIsLoading(false)\n })\n\n return (\n <div class=\"relative w-full h-full min-h-[300px] bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden\">\n <Show when={isLoading()}>\n <div class=\"absolute inset-0 flex items-center justify-center\">\n <div class=\"animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600\" />\n </div>\n </Show>\n\n <Show when={error()}>\n <div class=\"absolute inset-0 flex items-center justify-center p-4\">\n <div class=\"text-center\">\n <p class=\"text-red-600 dark:text-red-400 text-sm font-medium\">Chart Error</p>\n <p class=\"text-gray-600 dark:text-gray-400 text-xs mt-1\">{error()}</p>\n </div>\n </div>\n </Show>\n\n <Show when={iframeUrl() && !error()}>\n <div class=\"w-full h-full p-4\">\n <Show when={(props.component.params as any).title}>\n <h3 class=\"text-sm font-semibold text-gray-900 dark:text-white mb-3\">\n {(props.component.params as any).title}\n </h3>\n </Show>\n <div class=\"w-full h-full\">\n <img\n src={iframeUrl()}\n alt=\"Chart visualization\"\n class=\"w-full h-auto max-h-[300px] object-contain\"\n onError={() => {\n setError('Failed to load chart')\n props.onError?.({\n type: 'render',\n message: 'Chart rendering failed',\n componentId: props.component.id,\n })\n }}\n />\n </div>\n </div>\n </Show>\n </div>\n )\n}\n\n/**\n * Render a table component\n */\nfunction TableRenderer(props: {\n component: UIComponent\n onError?: (error: RendererError) => void\n}) {\n const tableParams = props.component.params as any\n\n return (\n <div class=\"w-full h-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden\">\n <div class=\"p-4\">\n <Show when={tableParams.title}>\n <h3 class=\"text-sm font-semibold text-gray-900 dark:text-white mb-3\">\n {tableParams.title}\n </h3>\n </Show>\n\n <div class=\"overflow-x-auto\">\n <table class=\"min-w-full divide-y divide-gray-200 dark:divide-gray-700 border-separate border-spacing-0\">\n <thead class=\"bg-gray-50 dark:bg-gray-900/50\">\n <tr>\n <For each={tableParams.columns}>\n {(column: any) => (\n <th\n scope=\"col\"\n class=\"px-6 py-3 text-left text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wider border-b border-gray-200 dark:border-gray-700 first:pl-6 last:pr-6\"\n style={column.width ? { width: column.width } : {}}\n >\n {column.label}\n </th>\n )}\n </For>\n </tr>\n </thead>\n <tbody class=\"bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700\">\n <For each={tableParams.rows.slice(0, DEFAULT_RESOURCE_LIMITS.maxTableRows)}>\n {(row: any, i) => (\n <tr class={`hover:bg-gray-50 dark:hover:bg-gray-700/50 transition-colors ${i() % 2 === 0 ? 'bg-white dark:bg-gray-800' : 'bg-gray-50/30 dark:bg-gray-800/50'}`}>\n <For each={tableParams.columns}>\n {(column: any) => (\n <td class=\"px-6 py-4 text-sm text-gray-700 dark:text-gray-200 whitespace-normal break-words leading-relaxed first:pl-6 last:pr-6\">\n <div\n innerHTML={\n typeof row[column.key] === 'string' && (row[column.key].includes('[') || row[column.key].includes('**') || row[column.key].includes('`'))\n ? DOMPurify.sanitize(marked.parse(row[column.key], { async: false }) as string, { ADD_ATTR: ['target', 'rel'] })\n : (row[column.key] || '-')\n }\n />\n </td>\n )}\n </For>\n </tr>\n )}\n </For>\n </tbody>\n </table>\n </div>\n\n <Show when={tableParams.pagination}>\n <div class=\"mt-3 flex items-center justify-between text-xs text-gray-500 dark:text-gray-400\">\n <span>\n Showing {tableParams.pagination.currentPage * tableParams.pagination.pageSize + 1} -{' '}\n {Math.min(\n (tableParams.pagination.currentPage + 1) * tableParams.pagination.pageSize,\n tableParams.pagination.totalRows\n )}{' '}\n of {tableParams.pagination.totalRows}\n </span>\n </div>\n </Show>\n </div>\n </div>\n )\n}\n\n/**\n * Render a metric card component\n */\nfunction MetricRenderer(props: { component: UIComponent }) {\n const metricParams = props.component.params as any\n\n return (\n <div class=\"w-full h-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-4\">\n <div class=\"flex flex-col h-full justify-between\">\n <div>\n <p class=\"text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wide\">\n {metricParams.title}\n </p>\n <div class=\"mt-2 flex items-baseline\">\n <p class=\"text-2xl font-semibold text-gray-900 dark:text-white\">{metricParams.value}</p>\n <Show when={metricParams.unit}>\n <span class=\"ml-2 text-sm font-medium text-gray-500 dark:text-gray-400\">\n {metricParams.unit}\n </span>\n </Show>\n </div>\n </div>\n\n <Show when={metricParams.trend}>\n <div class=\"mt-3 flex items-center\">\n <span\n class={`text-sm font-medium ${metricParams.trend.direction === 'up'\n ? 'text-green-600 dark:text-green-400'\n : metricParams.trend.direction === 'down'\n ? 'text-red-600 dark:text-red-400'\n : 'text-gray-600 dark:text-gray-400'\n }`}\n >\n {metricParams.trend.direction === 'up'\n ? '�'\n : metricParams.trend.direction === 'down'\n ? '�'\n : '�'}{' '}\n {Math.abs(metricParams.trend.value)}%\n </span>\n </div>\n </Show>\n\n <Show when={metricParams.subtitle}>\n <p class=\"mt-2 text-xs text-gray-500 dark:text-gray-400\">{metricParams.subtitle}</p>\n </Show>\n </div>\n </div>\n )\n}\n\n/**\n * Render a text component (with optional markdown)\n */\nfunction TextRenderer(props: { component: UIComponent }) {\n const textParams = props.component.params as any\n\n // Convert markdown to HTML if markdown flag is true\n const htmlContent = createMemo(() => {\n if (textParams.markdown) {\n return marked.parse(textParams.content, { async: false }) as string\n }\n return textParams.content\n })\n\n return (\n <div class=\"w-full h-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-4\">\n <div\n class={`prose prose-sm dark:prose-invert max-w-none ${textParams.className || ''}`}\n innerHTML={htmlContent()}\n />\n </div>\n )\n}\n\n/**\n * Render an iframe component\n */\nfunction IframeRenderer(props: { component: UIComponent }) {\n const params = props.component.params as any\n return (\n <div class=\"w-full h-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden flex flex-col\">\n <Show when={params.title}>\n <div class=\"px-4 py-2 border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900\">\n <h3 class=\"text-sm font-semibold text-gray-900 dark:text-white\">{params.title}</h3>\n </div>\n </Show>\n <iframe\n src={params.url}\n title={params.title || 'Embedded content'}\n class=\"w-full border-0 flex-1\"\n style={`height: ${params.height || '400px'}; min-height: 300px;`}\n sandbox=\"allow-scripts allow-same-origin allow-popups allow-forms\"\n loading=\"lazy\"\n />\n </div>\n )\n}\n\n/**\n * Render an image component\n */\nfunction ImageRenderer(props: { component: UIComponent }) {\n const params = props.component.params as any\n return (\n <div class=\"w-full h-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden flex flex-col\">\n <div class=\"flex-1 flex items-center justify-center p-4 bg-gray-50 dark:bg-gray-900 min-h-[200px]\">\n <a href={params.url} target=\"_blank\" rel=\"noopener noreferrer\" class=\"cursor-zoom-in\">\n <img\n src={params.url}\n alt={params.alt || 'Image'}\n class=\"max-w-full max-h-[500px] object-contain rounded shadow-sm hover:opacity-95 transition-opacity\"\n loading=\"lazy\"\n />\n </a>\n </div>\n <Show when={params.caption}>\n <div class=\"p-3 border-t border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800\">\n <p class=\"text-sm text-gray-600 dark:text-gray-400 text-center\">{params.caption}</p>\n </div>\n </Show>\n </div>\n )\n}\n\n/**\n * Render a link component\n */\n/**\n * Render a link component\n */\nfunction LinkRenderer(props: { component: UIComponent }) {\n const params = props.component.params as any\n return (\n <a\n href={params.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"flex items-center gap-3 p-4 bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors group h-full\"\n onClick={(e) => e.stopPropagation()}\n >\n <div class=\"p-2 bg-blue-50 dark:bg-blue-900/30 rounded-full text-blue-600 dark:text-blue-400 group-hover:bg-blue-100 dark:group-hover:bg-blue-900/50 shrink-0 transition-colors\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"w-5 h-5\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\" />\n <path d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\" />\n </svg>\n </div>\n <div class=\"flex-1 min-w-0\">\n <h4 class=\"text-sm font-medium text-gray-900 dark:text-white truncate group-hover:text-blue-600 dark:group-hover:text-blue-400 transition-colors\">\n {params.label || params.url}\n </h4>\n <Show when={params.description}>\n <p class=\"text-xs text-gray-500 dark:text-gray-400 truncate\">{params.description}</p>\n </Show>\n </div>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"w-4 h-4 text-gray-400 group-hover:text-gray-600 dark:group-hover:text-gray-300 shrink-0 transition-colors\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\" />\n <polyline points=\"15 3 21 3 21 9\" />\n <line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\" />\n </svg>\n </a>\n )\n}\n\n/**\n * Render a single component with error boundary\n */\nfunction ComponentRenderer(props: {\n component: UIComponent\n onError?: (error: RendererError) => void\n}) {\n // Validate component before rendering\n const validation = validateComponent(props.component)\n if (!validation.valid) {\n props.onError?.({\n type: 'validation',\n message: 'Component validation failed',\n componentId: props.component.id,\n details: validation.errors,\n })\n\n return (\n <div class=\"w-full h-full bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg p-4\">\n <p class=\"text-sm font-medium text-red-900 dark:text-red-100\">Validation Error</p>\n <p class=\"text-xs text-red-700 dark:text-red-300 mt-1\">\n {validation.errors?.[0]?.message || 'Unknown validation error'}\n </p>\n </div>\n )\n }\n\n // Render based on component type with enhanced error boundary\n return (\n <GenerativeUIErrorBoundary\n componentId={props.component.id}\n componentType={props.component.type}\n onError={props.onError}\n allowRetry={true}\n >\n <Show when={props.component.type === 'chart'}>\n <ChartRenderer component={props.component} onError={props.onError} />\n </Show>\n <Show when={props.component.type === 'table'}>\n <TableRenderer component={props.component} onError={props.onError} />\n </Show>\n <Show when={props.component.type === 'metric'}>\n <MetricRenderer component={props.component} />\n </Show>\n <Show when={props.component.type === 'text'}>\n <TextRenderer component={props.component} />\n </Show>\n <Show when={props.component.type === 'iframe'}>\n <IframeRenderer component={props.component} />\n </Show>\n <Show when={props.component.type === 'image'}>\n <ImageRenderer component={props.component} />\n </Show>\n <Show when={props.component.type === 'link'}>\n <LinkRenderer component={props.component} />\n </Show>\n <Show when={props.component.type === 'action'}>\n <ActionRenderer component={props.component} />\n </Show>\n </GenerativeUIErrorBoundary>\n )\n}\n\n/**\n * Render an action component (button or link)\n */\nfunction ActionRenderer(props: { component: UIComponent }) {\n const params = props.component.params as any\n let dispatchAction: ((toolName: string, toolParams: any) => void) | null = null\n\n // Initialize CustomEvent dispatcher only on client-side\n // Use createEffect instead of onMount for SSR compatibility\n createEffect(() => {\n if (typeof window !== 'undefined') {\n dispatchAction = (toolName: string, toolParams: any) => {\n const event = new CustomEvent('mcp-action', {\n detail: {\n toolName,\n params: toolParams,\n },\n bubbles: true,\n })\n window.dispatchEvent(event)\n }\n }\n })\n\n // Handle click to execute tool via window event\n const handleClick = (e: MouseEvent) => {\n if (params.action === 'tool-call' && params.toolName) {\n e.preventDefault()\n // SSR-safe: Only call if dispatcher was initialized client-side\n dispatchAction?.(params.toolName, params.params || {})\n }\n }\n\n if (params.type === 'link' || params.action === 'link') {\n return (\n <a\n href={params.url || '#'}\n target={params.url ? '_blank' : undefined}\n rel=\"noopener noreferrer\"\n class={`inline-flex items-center gap-2 px-4 py-2 rounded-md text-sm font-medium transition-colors\n ${params.variant === 'primary' ? 'bg-blue-600 text-white hover:bg-blue-700' :\n params.variant === 'outline' ? 'border border-gray-300 text-gray-700 hover:bg-gray-50 dark:border-gray-600 dark:text-gray-300 dark:hover:bg-gray-800' :\n 'text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300'}`}\n onClick={handleClick}\n >\n <Show when={params.icon}>\n <span>{params.icon}</span>\n </Show>\n {params.label}\n </a>\n )\n }\n\n return (\n <button\n type={params.action === 'submit' ? 'submit' : 'button'}\n disabled={params.disabled}\n class={`inline-flex items-center gap-2 px-4 py-2 rounded-md text-sm font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500\n ${params.variant === 'primary' ? 'bg-blue-600 text-white hover:bg-blue-700 shadow-sm' :\n params.variant === 'secondary' ? 'bg-gray-100 text-gray-900 hover:bg-gray-200 dark:bg-gray-700 dark:text-white dark:hover:bg-gray-600' :\n params.variant === 'outline' ? 'border border-gray-300 text-gray-700 hover:bg-gray-50 dark:border-gray-600 dark:text-gray-300 dark:hover:bg-gray-800' :\n params.variant === 'danger' ? 'bg-red-600 text-white hover:bg-red-700' :\n 'bg-transparent text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-800'}\n ${params.disabled ? 'opacity-50 cursor-not-allowed' : ''}\n ${params.size === 'sm' ? 'px-3 py-1.5 text-xs' : params.size === 'lg' ? 'px-6 py-3 text-base' : ''}`}\n onClick={handleClick}\n >\n <Show when={params.icon}>\n <span>{params.icon}</span>\n </Show>\n {params.label}\n </button>\n )\n}\n\n/**\n * Main UIResourceRenderer component\n */\nexport const UIResourceRenderer: Component<UIResourceRendererProps> = (props) => {\n const layout = () => {\n // ✅ PHASE 3.3 FIX: Check if content is a UIComponent (non-composite) vs UILayout (composite)\n // UILayout has type='composite', UIComponent has type='chart'|'table'|'metric'|'text'\n if ('type' in props.content && (props.content as any).type !== 'composite') {\n return {\n id: 'single-component',\n components: [props.content as UIComponent],\n grid: {\n columns: 12,\n gap: '1rem',\n },\n } as UILayout\n }\n return props.content as UILayout\n }\n\n // Grid position to CSS Grid styles\n const getGridStyles = (component: UIComponent) => {\n // ✅ PHASE 3 FIX: Defensive check for position field\n if (!component.position) {\n console.error('[UIResourceRenderer] Component missing position field:', component)\n return {\n 'grid-column': '1 / span 12',\n 'grid-row': 'auto',\n }\n }\n\n const { colStart, colSpan, rowStart, rowSpan = 1 } = component.position\n\n return {\n 'grid-column': `${colStart} / span ${colSpan}`,\n 'grid-row': rowStart ? `${rowStart} / span ${rowSpan}` : 'auto',\n }\n }\n\n // Convert grid styles to CSS string to avoid setStyleProperty\n const gridContainerStyle = () =>\n `grid-template-columns: repeat(${layout().grid.columns}, 1fr); gap: ${layout().grid.gap}`\n\n // Convert component grid styles to CSS string\n const getGridStyleString = (component: UIComponent) => {\n // ✅ PHASE 3 FIX: Defensive check for position field\n if (!component.position) {\n console.error('[UIResourceRenderer] Component missing position field:', component)\n return 'grid-column: 1 / span 12; grid-row: auto' // Default to full width\n }\n\n const { colStart, colSpan, rowStart, rowSpan = 1 } = component.position\n return `grid-column: ${colStart} / span ${colSpan}; grid-row: ${rowStart ? `${rowStart} / span ${rowSpan}` : 'auto'}`\n }\n\n return (\n <div class={`w-full ${props.class || ''}`}>\n <div class=\"grid gap-4\" style={gridContainerStyle()}>\n <For each={layout().components}>\n {(component) => (\n <div style={getGridStyleString(component)}>\n <ComponentRenderer component={component} onError={props.onError} />\n </div>\n )}\n </For>\n </div>\n </div>\n )\n}\n"],"names":["ChartRenderer","props","iframeUrl","setIframeUrl","createSignal","isLoading","setIsLoading","error","setError","createEffect","chartParams","component","params","chartConfig","type","data","options","responsive","maintainAspectRatio","configStr","encodeURIComponent","JSON","stringify","url","_$ssr","_tmpl$5","_$ssrHydrationKey","_$escape","_$createComponent","Show","when","children","_tmpl$","_tmpl$2","_tmpl$4","title","_tmpl$3","_$ssrAttribute","TableRenderer","tableParams","_tmpl$7","For","each","columns","column","_tmpl$8","_$ssrStyle","width","label","rows","slice","DEFAULT_RESOURCE_LIMITS","maxTableRows","row","i","_tmpl$9","_tmpl$0","key","includes","DOMPurify","sanitize","marked","parse","async","ADD_ATTR","pagination","_tmpl$6","currentPage","pageSize","Math","min","totalRows","MetricRenderer","metricParams","_tmpl$12","value","unit","_tmpl$1","trend","_tmpl$10","direction","abs","subtitle","_tmpl$11","TextRenderer","textParams","htmlContent","createMemo","markdown","content","_tmpl$13","className","IframeRenderer","_tmpl$15","_tmpl$14","height","ImageRenderer","_tmpl$17","alt","caption","_tmpl$16","LinkRenderer","_tmpl$19","description","_tmpl$18","ComponentRenderer","validation","validateComponent","valid","onError","message","componentId","id","details","errors","_tmpl$20","GenerativeUIErrorBoundary","componentType","allowRetry","ActionRenderer","action","_tmpl$22","undefined","variant","icon","_tmpl$21","_tmpl$23","disabled","size","UIResourceRenderer","layout","components","grid","gap","gridContainerStyle","getGridStyleString","position","console","colStart","colSpan","rowStart","rowSpan","_tmpl$24","class","_tmpl$25"],"mappings":"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"}
1
+ {"version":3,"file":"UIResourceRenderer.cjs","sources":["../../src/components/UIResourceRenderer.tsx"],"sourcesContent":["/**\n * UI Resource Renderer Component\n * Phase 0: Foundation with iframe sandbox and composite grid support\n */\n\nimport DOMPurify from 'dompurify'\nimport { Component, createSignal, Show, For, createMemo, createEffect } from 'solid-js'\nimport { isServer } from 'solid-js/web'\nimport type { UIComponent, UILayout, RendererError, ComponentType } from '../types'\nimport { validateComponent, DEFAULT_RESOURCE_LIMITS } from '../services/validation'\nimport { GenerativeUIErrorBoundary } from './GenerativeUIErrorBoundary'\nimport { marked } from 'marked'\n\n/**\n * Props for UIResourceRenderer\n */\nexport interface UIResourceRendererProps {\n /**\n * Single component or full layout to render\n */\n content: UIComponent | UILayout\n\n /**\n * Lazy loading (default: true)\n */\n lazyLoad?: boolean\n\n /**\n * Error callback\n */\n onError?: (error: RendererError) => void\n\n /**\n * Custom CSS class\n */\n class?: string\n}\n\n/**\n * Render a single chart component in a sandboxed iframe\n */\nfunction ChartRenderer(props: {\n component: UIComponent\n onError?: (error: RendererError) => void\n}) {\n const [iframeUrl, setIframeUrl] = createSignal<string>()\n const [isLoading, setIsLoading] = createSignal(true)\n const [error, setError] = createSignal<string>()\n\n // Use createEffect instead of onMount for SSR compatibility\n // createEffect runs after hydration on client-side\n createEffect(() => {\n const chartParams = props.component.params as any\n if (!chartParams) return\n\n // Build Quickchart URL\n const chartConfig = {\n type: chartParams.type,\n data: chartParams.data,\n options: {\n ...chartParams.options,\n responsive: true,\n maintainAspectRatio: false,\n },\n }\n\n // Encode chart configuration for Quickchart API\n const configStr = encodeURIComponent(JSON.stringify(chartConfig))\n const url = `https://quickchart.io/chart?c=${configStr}&width=500&height=300&devicePixelRatio=2`\n\n // Validate domain (should always pass for quickchart.io)\n setIframeUrl(url)\n setIsLoading(false)\n })\n\n return (\n <div class=\"relative w-full h-full min-h-[300px] bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden\">\n <Show when={isLoading()}>\n <div class=\"absolute inset-0 flex items-center justify-center\">\n <div class=\"animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600\" />\n </div>\n </Show>\n\n <Show when={error()}>\n <div class=\"absolute inset-0 flex items-center justify-center p-4\">\n <div class=\"text-center\">\n <p class=\"text-red-600 dark:text-red-400 text-sm font-medium\">Chart Error</p>\n <p class=\"text-gray-600 dark:text-gray-400 text-xs mt-1\">{error()}</p>\n </div>\n </div>\n </Show>\n\n <Show when={iframeUrl() && !error()}>\n <div class=\"w-full h-full p-4\">\n <Show when={(props.component.params as any).title}>\n <h3 class=\"text-sm font-semibold text-gray-900 dark:text-white mb-3\">\n {(props.component.params as any).title}\n </h3>\n </Show>\n <div class=\"w-full h-full\">\n <img\n src={iframeUrl()}\n alt=\"Chart visualization\"\n class=\"w-full h-auto max-h-[300px] object-contain\"\n onError={() => {\n setError('Failed to load chart')\n props.onError?.({\n type: 'render',\n message: 'Chart rendering failed',\n componentId: props.component.id,\n })\n }}\n />\n </div>\n </div>\n </Show>\n </div>\n )\n}\n\n/**\n * Smart cell value renderer that handles markdown links and other formats\n */\nfunction renderCellValue(value: any): string {\n // Handle null/undefined\n if (value === null || value === undefined) {\n return '-'\n }\n\n // Convert to string\n let strValue = String(value)\n\n // Clean up \"undefined\" patterns from backend data\n // Pattern 1: \"Text – undefined\" or \"Text - undefined\" → \"Text\"\n strValue = strValue.replace(/\\s*[–-]\\s*undefined\\s*$/gi, '')\n // Pattern 2: \"undefined – Text\" or \"undefined - Text\" → \"Text\"\n strValue = strValue.replace(/^undefined\\s*[–-]\\s*/gi, '')\n // Pattern 3: standalone \"undefined\" → \"-\"\n if (strValue.trim().toLowerCase() === 'undefined') {\n return '-'\n }\n // Pattern 4: empty string after cleanup → \"-\"\n if (strValue.trim() === '') {\n return '-'\n }\n\n // Detect and convert markdown links: [text](url)\n const markdownLinkRegex = /\\[([^\\]]+)\\]\\(([^)]+)\\)/g\n if (markdownLinkRegex.test(strValue)) {\n // Replace all markdown links with HTML links\n const htmlValue = strValue.replace(\n /\\[([^\\]]+)\\]\\(([^)]+)\\)/g,\n '<a href=\"$2\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"text-blue-600 dark:text-blue-400 hover:underline\">$1</a>'\n )\n return DOMPurify.sanitize(htmlValue, { ADD_ATTR: ['target', 'rel'] })\n }\n\n // Check if value contains markdown formatting (bold, italic, code, etc.)\n const hasMarkdown = /[*_`\\[\\]#]/.test(strValue)\n if (hasMarkdown) {\n // Parse with marked and sanitize\n const parsed = marked.parse(strValue, { async: false }) as string\n return DOMPurify.sanitize(parsed, { ADD_ATTR: ['target', 'rel'] })\n }\n\n // Plain text\n return strValue\n}\n\n/**\n * Render a table component\n */\nfunction TableRenderer(props: {\n component: UIComponent\n onError?: (error: RendererError) => void\n}) {\n const tableParams = props.component.params as any\n\n return (\n <div class=\"w-full h-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden\">\n <div class=\"p-4\">\n <Show when={tableParams.title}>\n <h3 class=\"text-sm font-semibold text-gray-900 dark:text-white mb-3\">\n {tableParams.title}\n </h3>\n </Show>\n\n <div class=\"overflow-x-auto\">\n <table class=\"min-w-full divide-y divide-gray-200 dark:divide-gray-700 border-separate border-spacing-0\">\n <thead class=\"bg-gray-50 dark:bg-gray-900/50\">\n <tr>\n <For each={tableParams.columns}>\n {(column: any) => (\n <th\n scope=\"col\"\n class=\"px-6 py-3 text-left text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wider border-b border-gray-200 dark:border-gray-700 first:pl-6 last:pr-6\"\n style={column.width ? { width: column.width } : {}}\n >\n {column.label}\n </th>\n )}\n </For>\n </tr>\n </thead>\n <tbody class=\"bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700\">\n <For each={tableParams.rows.slice(0, DEFAULT_RESOURCE_LIMITS.maxTableRows)}>\n {(row: any, i) => (\n <tr class={`hover:bg-gray-50 dark:hover:bg-gray-700/50 transition-colors ${i() % 2 === 0 ? 'bg-white dark:bg-gray-800' : 'bg-gray-50/30 dark:bg-gray-800/50'}`}>\n <For each={tableParams.columns}>\n {(column: any) => (\n <td class=\"px-6 py-4 text-sm text-gray-700 dark:text-gray-200 whitespace-normal break-words leading-relaxed first:pl-6 last:pr-6\">\n <div innerHTML={renderCellValue(row[column.key])} />\n </td>\n )}\n </For>\n </tr>\n )}\n </For>\n </tbody>\n </table>\n </div>\n\n <Show when={tableParams.pagination}>\n <div class=\"mt-3 flex items-center justify-between text-xs text-gray-500 dark:text-gray-400\">\n <span>\n Showing {tableParams.pagination.currentPage * tableParams.pagination.pageSize + 1} -{' '}\n {Math.min(\n (tableParams.pagination.currentPage + 1) * tableParams.pagination.pageSize,\n tableParams.pagination.totalRows\n )}{' '}\n of {tableParams.pagination.totalRows}\n </span>\n </div>\n </Show>\n </div>\n </div>\n )\n}\n\n/**\n * Render a metric card component\n */\nfunction MetricRenderer(props: { component: UIComponent }) {\n const metricParams = props.component.params as any\n\n return (\n <div class=\"w-full h-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-4\">\n <div class=\"flex flex-col h-full justify-between\">\n <div>\n <p class=\"text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wide\">\n {metricParams.title}\n </p>\n <div class=\"mt-2 flex items-baseline\">\n <p class=\"text-2xl font-semibold text-gray-900 dark:text-white\">{metricParams.value}</p>\n <Show when={metricParams.unit}>\n <span class=\"ml-2 text-sm font-medium text-gray-500 dark:text-gray-400\">\n {metricParams.unit}\n </span>\n </Show>\n </div>\n </div>\n\n <Show when={metricParams.trend}>\n <div class=\"mt-3 flex items-center\">\n <span\n class={`text-sm font-medium ${metricParams.trend.direction === 'up'\n ? 'text-green-600 dark:text-green-400'\n : metricParams.trend.direction === 'down'\n ? 'text-red-600 dark:text-red-400'\n : 'text-gray-600 dark:text-gray-400'\n }`}\n >\n {metricParams.trend.direction === 'up'\n ? '�'\n : metricParams.trend.direction === 'down'\n ? '�'\n : '�'}{' '}\n {Math.abs(metricParams.trend.value)}%\n </span>\n </div>\n </Show>\n\n <Show when={metricParams.subtitle}>\n <p class=\"mt-2 text-xs text-gray-500 dark:text-gray-400\">{metricParams.subtitle}</p>\n </Show>\n </div>\n </div>\n )\n}\n\n/**\n * Extract image data from markdown image link format\n * Pattern: [![alt](image-url)](link-url)\\n*Photo by Author*\n */\nfunction extractImageFromMarkdown(content: string): { alt: string; imageUrl: string; linkUrl: string; credit: string } | null {\n // Pattern: [![alt text](image-url)](link-url) followed by optional credit line\n const imagePattern = /\\[!\\[([^\\]]*)\\]\\(([^)]+)\\)\\]\\(([^)]+)\\)\\s*\\*([^*]+)\\*/\n const match = content.match(imagePattern)\n\n if (match) {\n return {\n alt: match[1] || 'Image',\n imageUrl: match[2],\n linkUrl: match[3],\n credit: match[4].trim()\n }\n }\n\n return null\n}\n\n/**\n * Render a text component (with optional markdown)\n */\nfunction TextRenderer(props: { component: UIComponent }) {\n const textParams = props.component.params as any\n\n // Check if this is an image markdown that should be rendered as image component\n const imageData = createMemo(() => {\n if (textParams.markdown && textParams.content) {\n return extractImageFromMarkdown(textParams.content)\n }\n return null\n })\n\n // Convert markdown to HTML if markdown flag is true (and not an image component)\n const htmlContent = createMemo(() => {\n if (textParams.markdown && !imageData()) {\n return marked.parse(textParams.content, { async: false }) as string\n }\n return textParams.content\n })\n\n // Render as image component if we extracted image data\n return (\n <Show\n when={imageData()}\n fallback={\n <div class=\"w-full h-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-4\">\n <div\n class={`prose prose-sm dark:prose-invert max-w-none ${textParams.className || ''}`}\n innerHTML={htmlContent()}\n />\n </div>\n }\n >\n {(data) => (\n <div class=\"w-full h-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden flex flex-col\">\n <div class=\"flex-1 flex items-center justify-center p-4 bg-gray-50 dark:bg-gray-900 min-h-[200px]\">\n <a href={data().linkUrl} target=\"_blank\" rel=\"noopener noreferrer\" class=\"cursor-zoom-in\">\n <img\n src={data().imageUrl}\n alt={data().alt}\n class=\"max-w-full max-h-[400px] object-contain rounded shadow-sm hover:opacity-90 transition-opacity\"\n loading=\"lazy\"\n />\n </a>\n </div>\n <div class=\"p-3 border-t border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800\">\n <p class=\"text-sm text-gray-600 dark:text-gray-400 text-center italic\">{data().credit}</p>\n </div>\n </div>\n )}\n </Show>\n )\n}\n\n/**\n * Render an iframe component\n */\nfunction IframeRenderer(props: { component: UIComponent }) {\n const params = props.component.params as any\n return (\n <div class=\"w-full h-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden flex flex-col\">\n <Show when={params.title}>\n <div class=\"px-4 py-2 border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900\">\n <h3 class=\"text-sm font-semibold text-gray-900 dark:text-white\">{params.title}</h3>\n </div>\n </Show>\n <iframe\n src={params.url}\n title={params.title || 'Embedded content'}\n class=\"w-full border-0 flex-1\"\n style={`height: ${params.height || '400px'}; min-height: 300px;`}\n sandbox=\"allow-scripts allow-same-origin allow-popups allow-forms\"\n loading=\"lazy\"\n />\n </div>\n )\n}\n\n/**\n * Render an image component\n */\nfunction ImageRenderer(props: { component: UIComponent }) {\n const params = props.component.params as any\n\n return (\n <div class=\"w-full h-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden flex flex-col\">\n <div class=\"flex-1 flex items-center justify-center p-4 bg-gray-50 dark:bg-gray-900 min-h-[200px]\">\n <a href={params.url} target=\"_blank\" rel=\"noopener noreferrer\" class=\"cursor-zoom-in\">\n <img\n src={params.url}\n alt={params.alt || 'Image'}\n class=\"max-w-full max-h-[500px] object-contain rounded shadow-sm hover:opacity-95 transition-opacity\"\n loading=\"lazy\"\n />\n </a>\n </div>\n <Show when={params.caption}>\n <div class=\"p-3 border-t border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800\">\n <p class=\"text-sm text-gray-600 dark:text-gray-400 text-center\">{params.caption}</p>\n </div>\n </Show>\n </div>\n )\n}\n\n/**\n * Render a link component\n */\n/**\n * Render a link component\n */\nfunction LinkRenderer(props: { component: UIComponent }) {\n const params = props.component.params as any\n\n return (\n <a\n href={params.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"flex items-center gap-3 p-4 bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors group h-full\"\n onClick={(e) => e.stopPropagation()}\n >\n <div class=\"p-2 bg-blue-50 dark:bg-blue-900/30 rounded-full text-blue-600 dark:text-blue-400 group-hover:bg-blue-100 dark:group-hover:bg-blue-900/50 shrink-0 transition-colors\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"w-5 h-5\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\" />\n <path d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\" />\n </svg>\n </div>\n <div class=\"flex-1 min-w-0\">\n <h4 class=\"text-sm font-medium text-gray-900 dark:text-white truncate group-hover:text-blue-600 dark:group-hover:text-blue-400 transition-colors\">\n {params.label || params.url}\n </h4>\n <Show when={params.description}>\n <p class=\"text-xs text-gray-500 dark:text-gray-400 truncate\">{params.description}</p>\n </Show>\n </div>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"w-4 h-4 text-gray-400 group-hover:text-gray-600 dark:group-hover:text-gray-300 shrink-0 transition-colors\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\" />\n <polyline points=\"15 3 21 3 21 9\" />\n <line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\" />\n </svg>\n </a>\n )\n}\n\n/**\n * Render a single component with error boundary\n */\nfunction ComponentRenderer(props: {\n component: UIComponent\n onError?: (error: RendererError) => void\n}) {\n // Validate component before rendering\n const validation = validateComponent(props.component)\n if (!validation.valid) {\n props.onError?.({\n type: 'validation',\n message: 'Component validation failed',\n componentId: props.component.id,\n details: validation.errors,\n })\n\n return (\n <div class=\"w-full h-full bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg p-4\">\n <p class=\"text-sm font-medium text-red-900 dark:text-red-100\">Validation Error</p>\n <p class=\"text-xs text-red-700 dark:text-red-300 mt-1\">\n {validation.errors?.[0]?.message || 'Unknown validation error'}\n </p>\n </div>\n )\n }\n\n // Render based on component type with enhanced error boundary\n return (\n <GenerativeUIErrorBoundary\n componentId={props.component.id}\n componentType={props.component.type}\n onError={props.onError}\n allowRetry={true}\n >\n <Show when={props.component.type === 'chart'}>\n <ChartRenderer component={props.component} onError={props.onError} />\n </Show>\n <Show when={props.component.type === 'table'}>\n <TableRenderer component={props.component} onError={props.onError} />\n </Show>\n <Show when={props.component.type === 'metric'}>\n <MetricRenderer component={props.component} />\n </Show>\n <Show when={props.component.type === 'text'}>\n <TextRenderer component={props.component} />\n </Show>\n <Show when={props.component.type === 'iframe'}>\n <IframeRenderer component={props.component} />\n </Show>\n <Show when={props.component.type === 'image'}>\n <ImageRenderer component={props.component} />\n </Show>\n <Show when={props.component.type === 'link'}>\n <LinkRenderer component={props.component} />\n </Show>\n <Show when={props.component.type === 'action'}>\n <ActionRenderer component={props.component} />\n </Show>\n </GenerativeUIErrorBoundary>\n )\n}\n\n/**\n * Render an action component (button or link)\n */\nfunction ActionRenderer(props: { component: UIComponent }) {\n const params = props.component.params as any\n let dispatchAction: ((toolName: string, toolParams: any) => void) | null = null\n\n // Initialize CustomEvent dispatcher only on client-side\n // Use createEffect instead of onMount for SSR compatibility\n createEffect(() => {\n if (typeof window !== 'undefined') {\n dispatchAction = (toolName: string, toolParams: any) => {\n const event = new CustomEvent('mcp-action', {\n detail: {\n toolName,\n params: toolParams,\n },\n bubbles: true,\n })\n window.dispatchEvent(event)\n }\n }\n })\n\n // Handle click to execute tool via window event\n const handleClick = (e: MouseEvent) => {\n if (params.action === 'tool-call' && params.toolName) {\n e.preventDefault()\n // SSR-safe: Only call if dispatcher was initialized client-side\n dispatchAction?.(params.toolName, params.params || {})\n }\n }\n\n if (params.type === 'link' || params.action === 'link') {\n return (\n <a\n href={params.url || '#'}\n target={params.url ? '_blank' : undefined}\n rel=\"noopener noreferrer\"\n class={`inline-flex items-center gap-2 px-4 py-2 rounded-md text-sm font-medium transition-colors\n ${params.variant === 'primary' ? 'bg-blue-600 text-white hover:bg-blue-700' :\n params.variant === 'outline' ? 'border border-gray-300 text-gray-700 hover:bg-gray-50 dark:border-gray-600 dark:text-gray-300 dark:hover:bg-gray-800' :\n 'text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300'}`}\n onClick={handleClick}\n >\n <Show when={params.icon}>\n <span>{params.icon}</span>\n </Show>\n {params.label}\n </a>\n )\n }\n\n return (\n <button\n type={params.action === 'submit' ? 'submit' : 'button'}\n disabled={params.disabled}\n class={`inline-flex items-center gap-2 px-4 py-2 rounded-md text-sm font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500\n ${params.variant === 'primary' ? 'bg-blue-600 text-white hover:bg-blue-700 shadow-sm' :\n params.variant === 'secondary' ? 'bg-gray-100 text-gray-900 hover:bg-gray-200 dark:bg-gray-700 dark:text-white dark:hover:bg-gray-600' :\n params.variant === 'outline' ? 'border border-gray-300 text-gray-700 hover:bg-gray-50 dark:border-gray-600 dark:text-gray-300 dark:hover:bg-gray-800' :\n params.variant === 'danger' ? 'bg-red-600 text-white hover:bg-red-700' :\n 'bg-transparent text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-800'}\n ${params.disabled ? 'opacity-50 cursor-not-allowed' : ''}\n ${params.size === 'sm' ? 'px-3 py-1.5 text-xs' : params.size === 'lg' ? 'px-6 py-3 text-base' : ''}`}\n onClick={handleClick}\n >\n <Show when={params.icon}>\n <span>{params.icon}</span>\n </Show>\n {params.label}\n </button>\n )\n}\n\n/**\n * Main UIResourceRenderer component\n */\nexport const UIResourceRenderer: Component<UIResourceRendererProps> = (props) => {\n const layout = () => {\n // Check if content is a UIComponent (non-composite) vs UILayout (composite)\n if ('type' in props.content && (props.content as any).type !== 'composite') {\n return {\n id: 'single-component',\n components: [props.content as UIComponent],\n grid: {\n columns: 12,\n gap: '1rem',\n },\n } as UILayout\n }\n return props.content as UILayout\n }\n\n // Convert grid styles to CSS string\n const gridContainerStyle = () => {\n const layoutData = layout()\n return `grid-template-columns: repeat(${layoutData.grid.columns}, 1fr); gap: ${layoutData.grid.gap}`\n }\n\n // Convert component grid styles to CSS string\n const getGridStyleString = (component: UIComponent) => {\n // Defensive check for position field - default to full width\n if (!component.position) {\n return 'grid-column: 1 / span 12; grid-row: auto'\n }\n const { colStart, colSpan, rowStart, rowSpan = 1 } = component.position\n return `grid-column: ${colStart} / span ${colSpan}; grid-row: ${rowStart ? `${rowStart} / span ${rowSpan}` : 'auto'}`\n }\n\n const layoutData = layout()\n\n return (\n <div class={`w-full ${props.class || ''}`}>\n <div class=\"grid gap-4\" style={gridContainerStyle()}>\n <For each={layoutData.components}>\n {(component) => (\n <div style={getGridStyleString(component)}>\n <ComponentRenderer component={component} onError={props.onError} />\n </div>\n )}\n </For>\n </div>\n </div>\n )\n}\n"],"names":["ChartRenderer","props","iframeUrl","setIframeUrl","createSignal","isLoading","setIsLoading","error","setError","createEffect","chartParams","component","params","chartConfig","type","data","options","responsive","maintainAspectRatio","configStr","encodeURIComponent","JSON","stringify","url","_$ssr","_tmpl$5","_$ssrHydrationKey","_$escape","_$createComponent","Show","when","children","_tmpl$","_tmpl$2","_tmpl$4","title","_tmpl$3","_$ssrAttribute","renderCellValue","value","undefined","strValue","String","replace","trim","toLowerCase","markdownLinkRegex","test","htmlValue","DOMPurify","sanitize","ADD_ATTR","hasMarkdown","parsed","marked","parse","async","TableRenderer","tableParams","_tmpl$7","For","each","columns","column","_tmpl$8","_$ssrStyle","width","label","rows","slice","DEFAULT_RESOURCE_LIMITS","maxTableRows","row","i","_tmpl$9","_tmpl$0","key","pagination","_tmpl$6","currentPage","pageSize","Math","min","totalRows","MetricRenderer","metricParams","_tmpl$12","unit","_tmpl$1","trend","_tmpl$10","direction","abs","subtitle","_tmpl$11","extractImageFromMarkdown","content","imagePattern","match","alt","imageUrl","linkUrl","credit","TextRenderer","textParams","imageData","createMemo","markdown","htmlContent","fallback","_tmpl$13","className","_tmpl$14","IframeRenderer","_tmpl$16","_tmpl$15","height","ImageRenderer","_tmpl$18","caption","_tmpl$17","LinkRenderer","_tmpl$20","description","_tmpl$19","ComponentRenderer","validation","validateComponent","valid","onError","message","componentId","id","details","errors","_tmpl$21","GenerativeUIErrorBoundary","componentType","allowRetry","ActionRenderer","action","_tmpl$23","variant","icon","_tmpl$22","_tmpl$24","disabled","size","UIResourceRenderer","layout","components","grid","gap","gridContainerStyle","layoutData","getGridStyleString","position","colStart","colSpan","rowStart","rowSpan","_tmpl$25","class","_tmpl$26"],"mappings":";;;;;;;;;AAyCA,SAASA,cAAcC,OAGpB;AACD,QAAM,CAACC,WAAWC,YAAY,IAAIC,qBAAAA;AAClC,QAAM,CAACC,WAAWC,YAAY,IAAIF,QAAAA,aAAa,IAAI;AACnD,QAAM,CAACG,OAAOC,QAAQ,IAAIJ,qBAAAA;AAI1BK,UAAAA,aAAa,MAAM;AACjB,UAAMC,cAAcT,MAAMU,UAAUC;AACpC,QAAI,CAACF,YAAa;AAGlB,UAAMG,cAAc;AAAA,MAClBC,MAAMJ,YAAYI;AAAAA,MAClBC,MAAML,YAAYK;AAAAA,MAClBC,SAAS;AAAA,QACP,GAAGN,YAAYM;AAAAA,QACfC,YAAY;AAAA,QACZC,qBAAqB;AAAA,MAAA;AAAA,IACvB;AAIF,UAAMC,YAAYC,mBAAmBC,KAAKC,UAAUT,WAAW,CAAC;AAChE,UAAMU,MAAM,iCAAiCJ,SAAS;AAGtDhB,iBAAaoB,GAAG;AAChBjB,iBAAa,KAAK;AAAA,EACpB,CAAC;AAED,SAAAkB,IAAAA,IAAAC,SAAAC,IAAAA,gBAAAA,GAAAC,IAAAA,OAAAC,IAAAA,gBAEKC,cAAI;AAAA,IAAA,IAACC,OAAI;AAAA,aAAEzB,UAAAA;AAAAA,IAAW;AAAA,IAAA,IAAA0B,WAAA;AAAA,aAAAP,IAAAA,IAAAQ,QAAAN,IAAAA,iBAAA;AAAA,IAAA;AAAA,EAAA,CAAA,CAAA,GAAAC,IAAAA,OAAAC,IAAAA,gBAMtBC,cAAI;AAAA,IAAA,IAACC,OAAI;AAAA,aAAEvB,MAAAA;AAAAA,IAAO;AAAA,IAAA,IAAAwB,WAAA;AAAA,aAAAP,IAAAA,IAAAS,SAAAP,IAAAA,gBAAAA,GAAAC,IAAAA,OAI6CpB,MAAAA,CAAO,CAAA;AAAA,IAAA;AAAA,EAAA,CAAA,CAAA,GAAAoB,IAAAA,OAAAC,IAAAA,gBAKtEC,cAAI;AAAA,IAAA,IAACC,OAAI;AAAA,aAAE5B,UAAAA,KAAe,CAACK,MAAAA;AAAAA,IAAO;AAAA,IAAA,IAAAwB,WAAA;AAAA,aAAAP,IAAAA,IAAAU,SAAAR,IAAAA,gBAAAA,GAAAC,IAAAA,OAAAC,IAAAA,gBAE9BC,cAAI;AAAA,QAAA,IAACC,OAAI;AAAA,iBAAG7B,MAAMU,UAAUC,OAAeuB;AAAAA,QAAK;AAAA,QAAA,IAAAJ,WAAA;AAAA,iBAAAP,IAAAA,IAAAY,SAAAV,IAAAA,mBAAAC,IAAAA,OAE3C1B,MAAMU,UAAUC,OAAeuB,KAAK,CAAA;AAAA,QAAA;AAAA,MAAA,CAAA,CAAA,GAAAE,IAAAA,aAAA,OAAAV,IAAAA,OAKjCzB,aAAW,IAAA,GAAA,KAAA,CAAA;AAAA,IAAA;AAAA,EAAA,CAAA,CAAA,CAAA;AAiB9B;AAKA,SAASoC,gBAAgBC,OAAoB;AAE3C,MAAIA,UAAU,QAAQA,UAAUC,QAAW;AACzC,WAAO;AAAA,EACT;AAGA,MAAIC,WAAWC,OAAOH,KAAK;AAI3BE,aAAWA,SAASE,QAAQ,6BAA6B,EAAE;AAE3DF,aAAWA,SAASE,QAAQ,0BAA0B,EAAE;AAExD,MAAIF,SAASG,KAAAA,EAAOC,YAAAA,MAAkB,aAAa;AACjD,WAAO;AAAA,EACT;AAEA,MAAIJ,SAASG,KAAAA,MAAW,IAAI;AAC1B,WAAO;AAAA,EACT;AAGA,QAAME,oBAAoB;AAC1B,MAAIA,kBAAkBC,KAAKN,QAAQ,GAAG;AAEpC,UAAMO,YAAYP,SAASE,QACzB,4BACA,wHACF;AACA,WAAOM,UAAUC,SAASF,WAAW;AAAA,MAAEG,UAAU,CAAC,UAAU,KAAK;AAAA,IAAA,CAAG;AAAA,EACtE;AAGA,QAAMC,cAAc,aAAaL,KAAKN,QAAQ;AAC9C,MAAIW,aAAa;AAEf,UAAMC,SAASC,WAAAA,OAAOC,MAAMd,UAAU;AAAA,MAAEe,OAAO;AAAA,IAAA,CAAO;AACtD,WAAOP,UAAUC,SAASG,QAAQ;AAAA,MAAEF,UAAU,CAAC,UAAU,KAAK;AAAA,IAAA,CAAG;AAAA,EACnE;AAGA,SAAOV;AACT;AAKA,SAASgB,cAAcxD,OAGpB;AACD,QAAMyD,cAAczD,MAAMU,UAAUC;AAEpC,SAAAY,IAAAA,IAAAmC,SAAAjC,IAAAA,gBAAAA,GAAAC,IAAAA,OAAAC,IAAAA,gBAGOC,cAAI;AAAA,IAAA,IAACC,OAAI;AAAA,aAAE4B,YAAYvB;AAAAA,IAAK;AAAA,IAAA,IAAAJ,WAAA;AAAA,aAAAP,IAAAA,IAAAY,SAAAV,IAAAA,gBAAAA,GAAAC,IAAAA,OAExB+B,YAAYvB,KAAK,CAAA;AAAA,IAAA;AAAA,EAAA,CAAA,CAAA,GAAAR,IAAAA,OAAAC,IAAAA,gBAQbgC,aAAG;AAAA,IAAA,IAACC,OAAI;AAAA,aAAEH,YAAYI;AAAAA,IAAO;AAAA,IAAA/B,UAC3BA,CAACgC,WAAWvC,QAAAwC,SAAAtC,IAAAA,mBAAAuC,IAAAA,SAIFF,OAAOG,QAAQ;AAAA,MAAEA,OAAOH,OAAOG;AAAAA,IAAAA,IAAU,EAAE,GAAAvC,WAEjDoC,OAAOI,KAAK,CAAA;AAAA,EAAA,CAEhB,CAAA,GAAAxC,IAAAA,OAAAC,IAAAA,gBAKJgC,aAAG;AAAA,IAAA,IAACC,OAAI;AAAA,aAAEH,YAAYU,KAAKC,MAAM,GAAGC,WAAAA,wBAAwBC,YAAY;AAAA,IAAC;AAAA,IAAAxC,UACvEA,CAACyC,KAAUC,MAACjD,IAAAA,IAAAkD,SAAAhD,IAAAA,mBACA,gEAAgE+C,EAAAA,IAAM,MAAM,IAAI,8BAA8B,mCAAmC,IAAE9C,IAAAA,OAAAC,IAAAA,gBAC3JgC,aAAG;AAAA,MAAA,IAACC,OAAI;AAAA,eAAEH,YAAYI;AAAAA,MAAO;AAAA,MAAA/B,UAC3BA,CAACgC,WAAWvC,IAAAA,IAAAmD,SAAAjD,IAAAA,mBAEOY,gBAAgBkC,IAAIT,OAAOa,GAAG,CAAC,CAAC;AAAA,IAAA,CAEnD,CAAA,CAAA;AAAA,EAAA,CAGN,CAAA,GAAAjD,IAAAA,OAAAC,IAAAA,gBAMRC,cAAI;AAAA,IAAA,IAACC,OAAI;AAAA,aAAE4B,YAAYmB;AAAAA,IAAU;AAAA,IAAA,IAAA9C,WAAA;AAAA,aAAAP,IAAAA,IAAAsD,SAAApD,IAAAA,gBAAAA,GAGnBC,IAAAA,OAAA+B,YAAYmB,WAAWE,WAAW,IAAApD,IAAAA,OAAG+B,YAAYmB,WAAWG,QAAQ,IAAG,GAACrD,IAAAA,OAChFsD,KAAKC,KACHxB,YAAYmB,WAAWE,cAAc,KAAKrB,YAAYmB,WAAWG,UAClEtB,YAAYmB,WAAWM,SACzB,CAAC,GAAAxD,IAAAA,OACG+B,YAAYmB,WAAWM,SAAS,CAAA;AAAA,IAAA;AAAA,EAAA,CAAA,CAAA,CAAA;AAOlD;AAKA,SAASC,eAAenF,OAAmC;AACzD,QAAMoF,eAAepF,MAAMU,UAAUC;AAErC,SAAAY,IAAAA,IAAA8D,UAAA5D,IAAAA,gBAAAA,GAAAC,IAAAA,OAKW0D,aAAalD,KAAK,GAAAR,IAAAA,OAG8C0D,aAAa9C,KAAK,GAAAZ,IAAAA,OAAAC,IAAAA,gBAClFC,QAAAA,MAAI;AAAA,IAAA,IAACC,OAAI;AAAA,aAAEuD,aAAaE;AAAAA,IAAI;AAAA,IAAA,IAAAxD,WAAA;AAAA,aAAAP,IAAAA,IAAAgE,SAAA9D,IAAAA,gBAAAA,GAAAC,IAAAA,OAExB0D,aAAaE,IAAI,CAAA;AAAA,IAAA;AAAA,EAAA,CAAA,CAAA,GAAA5D,IAAAA,OAAAC,IAAAA,gBAMzBC,cAAI;AAAA,IAAA,IAACC,OAAI;AAAA,aAAEuD,aAAaI;AAAAA,IAAK;AAAA,IAAA,IAAA1D,WAAA;AAAA,aAAAP,IAAAA,IAAAkE,UAAAhE,IAAAA,gBAAAA,GAGjB,uBAAuB2D,aAAaI,MAAME,cAAc,OAC3D,uCACAN,aAAaI,MAAME,cAAc,SAC/B,mCACA,kCAAkC,IAGvCN,aAAaI,MAAME,cAAc,OAC9B,MACAN,aAAaI,MAAME,cAAc,SAC/B,MACA,KAAGhE,IAAAA,OACRsD,KAAKW,IAAIP,aAAaI,MAAMlD,KAAK,CAAC,CAAA;AAAA,IAAA;AAAA,EAAA,CAAA,CAAA,GAAAZ,IAAAA,OAAAC,IAAAA,gBAKxCC,cAAI;AAAA,IAAA,IAACC,OAAI;AAAA,aAAEuD,aAAaQ;AAAAA,IAAQ;AAAA,IAAA,IAAA9D,WAAA;AAAA,aAAAP,IAAAA,IAAAsE,UAAApE,IAAAA,gBAAAA,GAAAC,IAAAA,OAC2B0D,aAAaQ,QAAQ,CAAA;AAAA,IAAA;AAAA,EAAA,CAAA,CAAA,CAAA;AAKzF;AAMA,SAASE,yBAAyBC,SAA4F;AAE5H,QAAMC,eAAe;AACrB,QAAMC,QAAQF,QAAQE,MAAMD,YAAY;AAExC,MAAIC,OAAO;AACT,WAAO;AAAA,MACLC,KAAKD,MAAM,CAAC,KAAK;AAAA,MACjBE,UAAUF,MAAM,CAAC;AAAA,MACjBG,SAASH,MAAM,CAAC;AAAA,MAChBI,QAAQJ,MAAM,CAAC,EAAEtD,KAAAA;AAAAA,IAAK;AAAA,EAE1B;AAEA,SAAO;AACT;AAKA,SAAS2D,aAAatG,OAAmC;AACvD,QAAMuG,aAAavG,MAAMU,UAAUC;AAGnC,QAAM6F,YAAYC,QAAAA,WAAW,MAAM;AACjC,QAAIF,WAAWG,YAAYH,WAAWR,SAAS;AAC7C,aAAOD,yBAAyBS,WAAWR,OAAO;AAAA,IACpD;AACA,WAAO;AAAA,EACT,CAAC;AAGD,QAAMY,cAAcF,QAAAA,WAAW,MAAM;AACnC,QAAIF,WAAWG,YAAY,CAACF,aAAa;AACvC,aAAOnD,kBAAOC,MAAMiD,WAAWR,SAAS;AAAA,QAAExC,OAAO;AAAA,MAAA,CAAO;AAAA,IAC1D;AACA,WAAOgD,WAAWR;AAAAA,EACpB,CAAC;AAGD,SAAApE,IAAAA,gBACGC,QAAAA,MAAI;AAAA,IAAA,IACHC,OAAI;AAAA,aAAE2E,UAAAA;AAAAA,IAAW;AAAA,IAAA,IACjBI,WAAQ;AAAA,aAAArF,IAAAA,IAAAsF,UAAApF,IAAAA,gBAAAA,GAGK,+CAA+CC,IAAAA,OAAA6E,WAAWO,WAAS,IAAA,KAAI,EAAE,IACrEH,aAAa;AAAA,IAAA;AAAA,IAAA7E,UAK5BhB,CAAAA,SAAIS,IAAAA,IAAAwF,UAAAtF,IAAAA,gBAAAA,GAAAW,IAAAA,qBAAAV,IAAAA,OAGSZ,KAAAA,EAAOsF,SAAO,IAAA,GAAA,KAAA,GAAAhE,IAAAA,aAAA,OAAAV,IAAAA,OAEdZ,KAAAA,EAAOqF,0BAAQ/D,IAAAA,aAAA,OAAAV,IAAAA,OACfZ,KAAAA,EAAOoF,KAAG,IAAA,GAAA,KAAA,GAAAxE,WAOqDZ,KAAAA,EAAOuF,MAAM,CAAA;AAAA,EAAA,CAG1F;AAGP;AAKA,SAASW,eAAehH,OAAmC;AACzD,QAAMW,SAASX,MAAMU,UAAUC;AAC/B,SAAAY,IAAAA,IAAA0F,UAAAxF,IAAAA,gBAAAA,GAAAC,IAAAA,OAAAC,IAAAA,gBAEKC,cAAI;AAAA,IAAA,IAACC,OAAI;AAAA,aAAElB,OAAOuB;AAAAA,IAAK;AAAA,IAAA,IAAAJ,WAAA;AAAA,aAAAP,IAAAA,IAAA2F,UAAAzF,IAAAA,gBAAAA,GAAAC,IAAAA,OAE6Cf,OAAOuB,KAAK,CAAA;AAAA,IAAA;AAAA,EAAA,CAAA,CAAA,GAAAE,IAAAA,aAAA,OAAAV,IAAAA,OAI1Ef,OAAOW,KAAG,IAAA,GAAA,KAAA,IAAAc,IAAAA,aAAA,SACRV,IAAAA,OAAAf,OAAOuB,OAAK,IAAA,KAAI,oBAAkB,KAAA,GAAA8B,IAAAA,SAElC,WAAWrD,OAAOwG,UAAU,OAAO,sBAAsB,CAAA;AAMxE;AAKA,SAASC,cAAcpH,OAAmC;AACxD,QAAMW,SAASX,MAAMU,UAAUC;AAE/B,SAAAY,IAAAA,IAAA8F,UAAA5F,IAAAA,gBAAAA,GAAAW,IAAAA,aAAA,QAAAV,IAAAA,OAGef,OAAOW,KAAG,IAAA,GAAA,KAAA,GAAAc,IAAAA,oBAAAV,WAEVf,OAAOW,KAAG,IAAA,GAAA,KAAA,IAAAc,IAAAA,aAAA,OACVV,IAAAA,OAAAf,OAAOuF,KAAG,IAAA,KAAI,SAAO,KAAA,GAAAxE,IAAAA,OAAAC,IAAAA,gBAM/BC,cAAI;AAAA,IAAA,IAACC,OAAI;AAAA,aAAElB,OAAO2G;AAAAA,IAAO;AAAA,IAAA,IAAAxF,WAAA;AAAA,aAAAP,IAAAA,IAAAgG,UAAA9F,IAAAA,gBAAAA,GAAAC,IAAAA,OAE2Cf,OAAO2G,OAAO,CAAA;AAAA,IAAA;AAAA,EAAA,CAAA,CAAA,CAAA;AAKzF;AAQA,SAASE,aAAaxH,OAAmC;AACvD,QAAMW,SAASX,MAAMU,UAAUC;AAE/B,SAAAY,IAAAA,IAAAkG,UAAAhG,IAAAA,oBAAAW,IAAAA,aAAA,QAAAV,WAEUf,OAAOW,KAAG,IAAA,GAAA,KAAA,GAuBXI,WAAAf,OAAOuD,KAAK,KAAAxC,IAAAA,OAAIf,OAAOW,GAAG,GAAAI,IAAAA,OAAAC,IAAAA,gBAE5BC,cAAI;AAAA,IAAA,IAACC,OAAI;AAAA,aAAElB,OAAO+G;AAAAA,IAAW;AAAA,IAAA,IAAA5F,WAAA;AAAA,aAAAP,IAAAA,IAAAoG,UAAAlG,IAAAA,gBAAAA,GAAAC,IAAAA,OACkCf,OAAO+G,WAAW,CAAA;AAAA,IAAA;AAAA,EAAA,CAAA,CAAA,CAAA;AAmB1F;AAKA,SAASE,kBAAkB5H,OAGxB;;AAED,QAAM6H,eAAaC,WAAAA,kBAAkB9H,MAAMU,SAAS;AACpD,MAAI,CAACmH,aAAWE,OAAO;AACrB/H,gBAAMgI,YAANhI,+BAAgB;AAAA,MACda,MAAM;AAAA,MACNoH,SAAS;AAAA,MACTC,aAAalI,MAAMU,UAAUyH;AAAAA,MAC7BC,SAASP,aAAWQ;AAAAA,IAAAA;AAGtB,WAAA9G,QAAA+G,UAAA7G,IAAAA,gBAAAA,GAIOC,IAAAA,QAAAmG,wBAAWQ,WAAXR,mBAAoB,OAApBA,mBAAwBI,OAAO,KAAI,0BAA0B;AAAA,EAItE;AAGA,SAAAtG,IAAAA,gBACG4G,0BAAAA,2BAAyB;AAAA,IAAA,IACxBL,cAAW;AAAA,aAAElI,MAAMU,UAAUyH;AAAAA,IAAE;AAAA,IAAA,IAC/BK,gBAAa;AAAA,aAAExI,MAAMU,UAAUG;AAAAA,IAAI;AAAA,IAAA,IACnCmH,UAAO;AAAA,aAAEhI,MAAMgI;AAAAA,IAAO;AAAA,IACtBS,YAAY;AAAA,IAAI,IAAA3G,WAAA;AAAA,aAAA,CAAAH,IAAAA,gBAEfC,cAAI;AAAA,QAAA,IAACC,OAAI;AAAA,iBAAE7B,MAAMU,UAAUG,SAAS;AAAA,QAAO;AAAA,QAAA,IAAAiB,WAAA;AAAA,iBAAAH,IAAAA,gBACzC5B,eAAa;AAAA,YAAA,IAACW,YAAS;AAAA,qBAAEV,MAAMU;AAAAA,YAAS;AAAA,YAAA,IAAEsH,UAAO;AAAA,qBAAEhI,MAAMgI;AAAAA,YAAO;AAAA,UAAA,CAAA;AAAA,QAAA;AAAA,MAAA,CAAA,GAAArG,IAAAA,gBAElEC,cAAI;AAAA,QAAA,IAACC,OAAI;AAAA,iBAAE7B,MAAMU,UAAUG,SAAS;AAAA,QAAO;AAAA,QAAA,IAAAiB,WAAA;AAAA,iBAAAH,IAAAA,gBACzC6B,eAAa;AAAA,YAAA,IAAC9C,YAAS;AAAA,qBAAEV,MAAMU;AAAAA,YAAS;AAAA,YAAA,IAAEsH,UAAO;AAAA,qBAAEhI,MAAMgI;AAAAA,YAAO;AAAA,UAAA,CAAA;AAAA,QAAA;AAAA,MAAA,CAAA,GAAArG,IAAAA,gBAElEC,cAAI;AAAA,QAAA,IAACC,OAAI;AAAA,iBAAE7B,MAAMU,UAAUG,SAAS;AAAA,QAAQ;AAAA,QAAA,IAAAiB,WAAA;AAAA,iBAAAH,IAAAA,gBAC1CwD,gBAAc;AAAA,YAAA,IAACzE,YAAS;AAAA,qBAAEV,MAAMU;AAAAA,YAAS;AAAA,UAAA,CAAA;AAAA,QAAA;AAAA,MAAA,CAAA,GAAAiB,IAAAA,gBAE3CC,cAAI;AAAA,QAAA,IAACC,OAAI;AAAA,iBAAE7B,MAAMU,UAAUG,SAAS;AAAA,QAAM;AAAA,QAAA,IAAAiB,WAAA;AAAA,iBAAAH,IAAAA,gBACxC2E,cAAY;AAAA,YAAA,IAAC5F,YAAS;AAAA,qBAAEV,MAAMU;AAAAA,YAAS;AAAA,UAAA,CAAA;AAAA,QAAA;AAAA,MAAA,CAAA,GAAAiB,IAAAA,gBAEzCC,cAAI;AAAA,QAAA,IAACC,OAAI;AAAA,iBAAE7B,MAAMU,UAAUG,SAAS;AAAA,QAAQ;AAAA,QAAA,IAAAiB,WAAA;AAAA,iBAAAH,IAAAA,gBAC1CqF,gBAAc;AAAA,YAAA,IAACtG,YAAS;AAAA,qBAAEV,MAAMU;AAAAA,YAAS;AAAA,UAAA,CAAA;AAAA,QAAA;AAAA,MAAA,CAAA,GAAAiB,IAAAA,gBAE3CC,cAAI;AAAA,QAAA,IAACC,OAAI;AAAA,iBAAE7B,MAAMU,UAAUG,SAAS;AAAA,QAAO;AAAA,QAAA,IAAAiB,WAAA;AAAA,iBAAAH,IAAAA,gBACzCyF,eAAa;AAAA,YAAA,IAAC1G,YAAS;AAAA,qBAAEV,MAAMU;AAAAA,YAAS;AAAA,UAAA,CAAA;AAAA,QAAA;AAAA,MAAA,CAAA,GAAAiB,IAAAA,gBAE1CC,cAAI;AAAA,QAAA,IAACC,OAAI;AAAA,iBAAE7B,MAAMU,UAAUG,SAAS;AAAA,QAAM;AAAA,QAAA,IAAAiB,WAAA;AAAA,iBAAAH,IAAAA,gBACxC6F,cAAY;AAAA,YAAA,IAAC9G,YAAS;AAAA,qBAAEV,MAAMU;AAAAA,YAAS;AAAA,UAAA,CAAA;AAAA,QAAA;AAAA,MAAA,CAAA,GAAAiB,IAAAA,gBAEzCC,cAAI;AAAA,QAAA,IAACC,OAAI;AAAA,iBAAE7B,MAAMU,UAAUG,SAAS;AAAA,QAAQ;AAAA,QAAA,IAAAiB,WAAA;AAAA,iBAAAH,IAAAA,gBAC1C+G,gBAAc;AAAA,YAAA,IAAChI,YAAS;AAAA,qBAAEV,MAAMU;AAAAA,YAAS;AAAA,UAAA,CAAA;AAAA,QAAA;AAAA,MAAA,CAAA,CAAA;AAAA,IAAA;AAAA,EAAA,CAAA;AAIlD;AAKA,SAASgI,eAAe1I,OAAmC;AACzD,QAAMW,SAASX,MAAMU,UAAUC;AAK/BH,UAAAA,aAAa,MAAM;AAAA,EAanB,CAAC;AAWD,MAAIG,OAAOE,SAAS,UAAUF,OAAOgI,WAAW,QAAQ;AACtD,WAAApH,QAAAqH,UAAAnH,IAAAA,gBAAAA,IAAAW,IAAAA,aAAA,QAEUV,IAAAA,OAAAf,OAAOW,KAAG,IAAA,KAAI,KAAG,KAAA,IAAAc,iBAAA,UACfzB,OAAOW,MAAM,WAAQI,IAAAA,OAAGa,QAAS,IAAA,GAAA,KAAA,GAElC;AAAA,YACH5B,OAAOkI,YAAY,YAAY,6CAC/BlI,OAAOkI,YAAY,YAAY,yHAC7B,+EAA+E,IAAEnH,IAAAA,OAAAC,IAAAA,gBAGtFC,QAAAA,MAAI;AAAA,MAAA,IAACC,OAAI;AAAA,eAAElB,OAAOmI;AAAAA,MAAI;AAAA,MAAA,IAAAhH,WAAA;AAAA,eAAAP,IAAAA,IAAAwH,UAAAtH,IAAAA,gBAAAA,GAAAC,IAAAA,OACdf,OAAOmI,IAAI,CAAA;AAAA,MAAA;AAAA,IAAA,CAAA,CAAA,GAAApH,IAAAA,OAEnBf,OAAOuD,KAAK,CAAA;AAAA,EAGnB;AAEA,SAAA3C,IAAAA,IAAAyH,UAAAvH,oBAAAA,IAAAW,IAAAA,aAAA,QAEUzB,OAAOgI,WAAW,WAAW,WAAW,UAAQ,KAAA,GAAAvG,iBAAA,YAC5CzB,OAAOsI,UAAQ,IAAA,GAClB;AAAA,UACHtI,OAAOkI,YAAY,YAAY,uDAC/BlI,OAAOkI,YAAY,cAAc,wGAC/BlI,OAAOkI,YAAY,YAAY,yHAC7BlI,OAAOkI,YAAY,WAAW,2CAC5B,0FAA0F;AAAA,UAChGlI,OAAOsI,WAAW,kCAAkC,EAAE;AAAA,UACtDtI,OAAOuI,SAAS,OAAO,wBAAwBvI,OAAOuI,SAAS,OAAO,wBAAwB,EAAE,IAAExH,IAAAA,OAAAC,IAAAA,gBAGrGC,QAAAA,MAAI;AAAA,IAAA,IAACC,OAAI;AAAA,aAAElB,OAAOmI;AAAAA,IAAI;AAAA,IAAA,IAAAhH,WAAA;AAAA,aAAAP,IAAAA,IAAAwH,UAAAtH,IAAAA,gBAAAA,GAAAC,IAAAA,OACdf,OAAOmI,IAAI,CAAA;AAAA,IAAA;AAAA,EAAA,CAAA,CAAA,GAAApH,IAAAA,OAEnBf,OAAOuD,KAAK,CAAA;AAGnB;AAKO,MAAMiF,qBAA0DnJ,CAAAA,UAAU;AAC/E,QAAMoJ,SAASA,MAAM;AAEnB,QAAI,UAAUpJ,MAAM+F,WAAY/F,MAAM+F,QAAgBlF,SAAS,aAAa;AAC1E,aAAO;AAAA,QACLsH,IAAI;AAAA,QACJkB,YAAY,CAACrJ,MAAM+F,OAAsB;AAAA,QACzCuD,MAAM;AAAA,UACJzF,SAAS;AAAA,UACT0F,KAAK;AAAA,QAAA;AAAA,MACP;AAAA,IAEJ;AACA,WAAOvJ,MAAM+F;AAAAA,EACf;AAGA,QAAMyD,qBAAqBA,MAAM;AAC/B,UAAMC,cAAaL,OAAAA;AACnB,WAAO,iCAAiCK,YAAWH,KAAKzF,OAAO,gBAAgB4F,YAAWH,KAAKC,GAAG;AAAA,EACpG;AAGA,QAAMG,qBAAqBA,CAAChJ,cAA2B;AAErD,QAAI,CAACA,UAAUiJ,UAAU;AACvB,aAAO;AAAA,IACT;AACA,UAAM;AAAA,MAAEC;AAAAA,MAAUC;AAAAA,MAASC;AAAAA,MAAUC,UAAU;AAAA,IAAA,IAAMrJ,UAAUiJ;AAC/D,WAAO,gBAAgBC,QAAQ,WAAWC,OAAO,eAAeC,WAAW,GAAGA,QAAQ,WAAWC,OAAO,KAAK,MAAM;AAAA,EACrH;AAEA,QAAMN,aAAaL,OAAAA;AAEnB,SAAA7H,IAAAA,IAAAyI,UAAAvI,IAAAA,gBAAAA,GACc,UAAUC,IAAAA,OAAA1B,MAAMiK,OAAK,IAAA,KAAI,EAAE,IAAEjG,aACRwF,mBAAAA,CAAoB,GAAA9H,IAAAA,OAAAC,IAAAA,gBAChDgC,aAAG;AAAA,IAAA,IAACC,OAAI;AAAA,aAAE6F,WAAWJ;AAAAA,IAAU;AAAA,IAAAvH,UAC5BpB,CAAAA,cAASa,QAAA2I,UAAAzI,IAAAA,gBAAAA,GAAAuC,aACG0F,mBAAmBhJ,SAAS,CAAC,GAAAgB,IAAAA,OAAAC,IAAAA,gBACtCiG,mBAAiB;AAAA,MAAClH;AAAAA,MAAoB,IAAEsH,UAAO;AAAA,eAAEhI,MAAMgI;AAAAA,MAAO;AAAA,IAAA,CAAA,CAAA,CAAA;AAAA,EAAA,CAElE,CAAA,CAAA;AAKX;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"UIResourceRenderer.d.ts","sourceRoot":"","sources":["../../src/components/UIResourceRenderer.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,SAAS,EAAqD,MAAM,UAAU,CAAA;AAEvF,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,aAAa,EAAiB,MAAM,UAAU,CAAA;AAKnF;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC;;OAEG;IACH,OAAO,EAAE,WAAW,GAAG,QAAQ,CAAA;IAE/B;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAElB;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAA;IAExC;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAgeD;;GAEG;AACH,eAAO,MAAM,kBAAkB,EAAE,SAAS,CAAC,uBAAuB,CAiEjE,CAAA"}
1
+ {"version":3,"file":"UIResourceRenderer.d.ts","sourceRoot":"","sources":["../../src/components/UIResourceRenderer.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,SAAS,EAAqD,MAAM,UAAU,CAAA;AAEvF,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,aAAa,EAAiB,MAAM,UAAU,CAAA;AAKnF;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC;;OAEG;IACH,OAAO,EAAE,WAAW,GAAG,QAAQ,CAAA;IAE/B;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAElB;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAA;IAExC;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAkkBD;;GAEG;AACH,eAAO,MAAM,kBAAkB,EAAE,SAAS,CAAC,uBAAuB,CA+CjE,CAAA"}