@dudousxd/nestjs-agent-react 0.32.0 → 0.34.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/README.md +7 -0
- package/dist/{client-C7eu9WMJ.d.cts → client-BdHUuqy-.d.cts} +36 -1
- package/dist/{client-C7eu9WMJ.d.ts → client-BdHUuqy-.d.ts} +36 -1
- package/dist/{generative-ui-VTZ1EADD.d.cts → generative-ui-CyHY8Lh1.d.cts} +32 -101
- package/dist/{generative-ui-VTZ1EADD.d.ts → generative-ui-DdUZPCXX.d.ts} +32 -101
- package/dist/genui-json-render.cjs +51 -8
- package/dist/genui-json-render.cjs.map +1 -1
- package/dist/genui-json-render.d.cts +2 -1
- package/dist/genui-json-render.d.ts +2 -1
- package/dist/genui-json-render.js +51 -8
- package/dist/genui-json-render.js.map +1 -1
- package/dist/genui-server-playwright.cjs +199 -0
- package/dist/genui-server-playwright.cjs.map +1 -0
- package/dist/genui-server-playwright.d.cts +18 -0
- package/dist/genui-server-playwright.d.ts +18 -0
- package/dist/genui-server-playwright.js +162 -0
- package/dist/genui-server-playwright.js.map +1 -0
- package/dist/genui-server.cjs +188 -0
- package/dist/genui-server.cjs.map +1 -0
- package/dist/genui-server.d.cts +36 -0
- package/dist/genui-server.d.ts +36 -0
- package/dist/genui-server.js +163 -0
- package/dist/genui-server.js.map +1 -0
- package/dist/genui.cjs +127 -8
- package/dist/genui.cjs.map +1 -1
- package/dist/genui.d.cts +5 -2
- package/dist/genui.d.ts +5 -2
- package/dist/genui.js +128 -8
- package/dist/genui.js.map +1 -1
- package/dist/index.cjs +559 -123
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +35 -10
- package/dist/index.d.ts +35 -10
- package/dist/index.js +552 -120
- package/dist/index.js.map +1 -1
- package/dist/media.cjs.map +1 -1
- package/dist/media.d.cts +1 -1
- package/dist/media.d.ts +1 -1
- package/dist/media.js.map +1 -1
- package/dist/react-registry-Di4IVrw-.d.cts +25 -0
- package/dist/react-registry-z9GFbTm9.d.ts +25 -0
- package/dist/types-DZtFsWec.d.cts +99 -0
- package/dist/types-DZtFsWec.d.ts +99 -0
- package/package.json +35 -5
package/dist/genui.js
CHANGED
|
@@ -39,6 +39,10 @@ function toGenerativeUIItem(part) {
|
|
|
39
39
|
return {
|
|
40
40
|
id,
|
|
41
41
|
component: source.component,
|
|
42
|
+
...isRecord(source.componentVersions) && Object.values(source.componentVersions).every(
|
|
43
|
+
(version) => typeof version === "number" && Number.isSafeInteger(version) && version > 0
|
|
44
|
+
) ? { componentVersions: { ...source.componentVersions } } : {},
|
|
45
|
+
...typeof source.fallbackText === "string" ? { fallbackText: source.fallbackText } : {},
|
|
42
46
|
props: isRecord(source.props) ? source.props : {},
|
|
43
47
|
version: typeof source.version === "number" ? source.version : null,
|
|
44
48
|
toolCallId: typeof source.toolCallId === "string" ? source.toolCallId : null
|
|
@@ -144,20 +148,29 @@ function useValidatedProps(catalog, name, props) {
|
|
|
144
148
|
function useGenerativeUIState(part, options, fallbackTree) {
|
|
145
149
|
const item = useMemo(() => toGenerativeUIItem(part), [part]);
|
|
146
150
|
const name = item?.component ?? "";
|
|
151
|
+
const definition = options.catalog?.get?.(name);
|
|
152
|
+
const incompatible = item?.fallbackText !== void 0 && item.version !== null && definition !== void 0 && item.version !== (definition.version ?? 1);
|
|
147
153
|
const resolution = useResolvedComponent(
|
|
148
154
|
name,
|
|
149
155
|
item?.version ?? null,
|
|
150
|
-
options.registry,
|
|
156
|
+
incompatible ? {} : options.registry,
|
|
151
157
|
item === null ? void 0 : options.resolveComponent,
|
|
152
158
|
fallbackTree
|
|
153
159
|
);
|
|
154
160
|
const empty = useMemo(() => ({}), []);
|
|
155
161
|
const validation = useValidatedProps(
|
|
156
|
-
item === null || name === GENUI_TREE_COMPONENT ? void 0 : options.catalog,
|
|
162
|
+
item === null || name === GENUI_TREE_COMPONENT || incompatible ? void 0 : options.catalog,
|
|
157
163
|
name,
|
|
158
164
|
item?.props ?? empty
|
|
159
165
|
);
|
|
160
166
|
if (item === null) return null;
|
|
167
|
+
if (name === GENUI_TREE_COMPONENT && item.fallbackText !== void 0 && (!isRecord(item.props.root) || typeof item.props.root.type !== "string"))
|
|
168
|
+
return {
|
|
169
|
+
status: "problem",
|
|
170
|
+
reason: "invalid",
|
|
171
|
+
item,
|
|
172
|
+
issues: [{ path: ["root"], message: "Invalid UI tree root" }]
|
|
173
|
+
};
|
|
161
174
|
if (resolution.status === "loading") return { status: "loading", item };
|
|
162
175
|
if (resolution.status === "unknown") return { status: "problem", reason: "unknown", item };
|
|
163
176
|
if (resolution.status === "error") {
|
|
@@ -175,7 +188,8 @@ import { jsx } from "react/jsx-runtime";
|
|
|
175
188
|
var TreeScopeContext = createContext2(null);
|
|
176
189
|
function renderFallback(fallback, problem) {
|
|
177
190
|
if (typeof fallback === "function") return fallback(problem);
|
|
178
|
-
|
|
191
|
+
if (fallback !== void 0) return fallback;
|
|
192
|
+
return problem.item.fallbackText !== void 0 ? /* @__PURE__ */ jsx("span", { style: { whiteSpace: "pre-wrap" }, children: problem.item.fallbackText }) : null;
|
|
179
193
|
}
|
|
180
194
|
var ItemBoundary = class extends Component {
|
|
181
195
|
state = { error: void 0, failed: false };
|
|
@@ -207,28 +221,42 @@ function nodeItem(node, id) {
|
|
|
207
221
|
function TreeNode({ node, id }) {
|
|
208
222
|
const scope = useContext2(TreeScopeContext);
|
|
209
223
|
const item = useMemo2(() => nodeItem(node, id), [node, id]);
|
|
224
|
+
const storedVersion = scope?.componentVersions?.[node.type];
|
|
225
|
+
const definition = scope?.options.catalog?.get?.(node.type);
|
|
226
|
+
const incompatible = storedVersion !== void 0 && definition !== void 0 && storedVersion !== (definition.version ?? 1);
|
|
210
227
|
const resolution = useResolvedComponent(
|
|
211
228
|
node.type,
|
|
212
|
-
null,
|
|
213
|
-
scope?.options.registry ?? {},
|
|
229
|
+
storedVersion ?? null,
|
|
230
|
+
incompatible ? {} : scope?.options.registry ?? {},
|
|
214
231
|
scope?.options.resolveComponent
|
|
215
232
|
);
|
|
216
|
-
const validation = useValidatedProps(
|
|
233
|
+
const validation = useValidatedProps(
|
|
234
|
+
incompatible ? void 0 : scope?.options.catalog,
|
|
235
|
+
node.type,
|
|
236
|
+
item.props
|
|
237
|
+
);
|
|
217
238
|
if (scope === null) return null;
|
|
218
239
|
if (resolution.status === "loading" || validation.status === "pending") return scope.loading;
|
|
219
240
|
if (resolution.status === "unknown") {
|
|
241
|
+
if (scope.fallback === void 0 && scope.fallbackText !== void 0)
|
|
242
|
+
throw new Error("Unknown tree component");
|
|
220
243
|
return renderFallback(scope.fallback, { reason: "unknown", item });
|
|
221
244
|
}
|
|
222
245
|
if (resolution.status === "error") {
|
|
246
|
+
if (scope.fallback === void 0 && scope.fallbackText !== void 0) throw resolution.error;
|
|
223
247
|
return renderFallback(scope.fallback, { reason: "error", item, error: resolution.error });
|
|
224
248
|
}
|
|
225
249
|
if (validation.status === "invalid") {
|
|
250
|
+
if (scope.fallback === void 0 && scope.fallbackText !== void 0)
|
|
251
|
+
throw new Error("Invalid tree component");
|
|
226
252
|
return renderFallback(scope.fallback, { reason: "invalid", item, issues: validation.issues });
|
|
227
253
|
}
|
|
228
254
|
const Renderer = resolution.Component;
|
|
229
255
|
const children = Array.isArray(node.children) ? node.children : [];
|
|
230
256
|
return /* @__PURE__ */ jsx(Renderer, { ...validation.props, children: children.length > 0 ? children.map((child, index) => {
|
|
231
257
|
const childId = `${id}.${index}`;
|
|
258
|
+
if (scope.fallback === void 0 && scope.fallbackText !== void 0)
|
|
259
|
+
return /* @__PURE__ */ jsx(TreeNode, { node: child, id: childId }, childId);
|
|
232
260
|
return /* @__PURE__ */ jsx(
|
|
233
261
|
ItemBoundary,
|
|
234
262
|
{
|
|
@@ -250,6 +278,8 @@ function GenerativeUIScope({
|
|
|
250
278
|
catalog,
|
|
251
279
|
resolveComponent,
|
|
252
280
|
fallback,
|
|
281
|
+
fallbackText,
|
|
282
|
+
componentVersions,
|
|
253
283
|
loading = null,
|
|
254
284
|
onError,
|
|
255
285
|
children
|
|
@@ -262,10 +292,21 @@ function GenerativeUIScope({
|
|
|
262
292
|
...resolveComponent !== void 0 ? { resolveComponent } : {}
|
|
263
293
|
},
|
|
264
294
|
fallback,
|
|
295
|
+
...componentVersions !== void 0 ? { componentVersions } : {},
|
|
296
|
+
...fallbackText !== void 0 ? { fallbackText } : {},
|
|
265
297
|
loading,
|
|
266
298
|
onError
|
|
267
299
|
}),
|
|
268
|
-
[
|
|
300
|
+
[
|
|
301
|
+
registry,
|
|
302
|
+
catalog,
|
|
303
|
+
resolveComponent,
|
|
304
|
+
fallback,
|
|
305
|
+
fallbackText,
|
|
306
|
+
componentVersions,
|
|
307
|
+
loading,
|
|
308
|
+
onError
|
|
309
|
+
]
|
|
269
310
|
);
|
|
270
311
|
return /* @__PURE__ */ jsx(TreeScopeContext.Provider, { value: scope, children });
|
|
271
312
|
}
|
|
@@ -332,7 +373,7 @@ function GenerativeUI({
|
|
|
332
373
|
onError: ownOnError
|
|
333
374
|
}) {
|
|
334
375
|
const provided = useContext2(GenuiContext);
|
|
335
|
-
const fallback = ownFallback
|
|
376
|
+
const fallback = ownFallback !== void 0 ? ownFallback : provided?.fallback;
|
|
336
377
|
const loading = ownLoading ?? provided?.loading ?? null;
|
|
337
378
|
const onError = ownOnError ?? provided?.onError;
|
|
338
379
|
const options = useMergedOptions({
|
|
@@ -357,6 +398,8 @@ function GenerativeUI({
|
|
|
357
398
|
GenerativeUIScope,
|
|
358
399
|
{
|
|
359
400
|
...options,
|
|
401
|
+
...state.item.componentVersions !== void 0 ? { componentVersions: state.item.componentVersions } : {},
|
|
402
|
+
...state.item.fallbackText !== void 0 ? { fallbackText: state.item.fallbackText } : {},
|
|
360
403
|
fallback,
|
|
361
404
|
loading,
|
|
362
405
|
...onError !== void 0 ? { onError } : {},
|
|
@@ -364,12 +407,89 @@ function GenerativeUI({
|
|
|
364
407
|
}
|
|
365
408
|
);
|
|
366
409
|
}
|
|
410
|
+
|
|
411
|
+
// src/genui/react-registry.ts
|
|
412
|
+
import {
|
|
413
|
+
createComponentRegistry
|
|
414
|
+
} from "@dudousxd/nestjs-agent-core/genui";
|
|
415
|
+
import { createElement } from "react";
|
|
416
|
+
function createReactComponentRegistry(options) {
|
|
417
|
+
const registry = createComponentRegistry(options);
|
|
418
|
+
const components = /* @__PURE__ */ Object.create(null);
|
|
419
|
+
const texts = /* @__PURE__ */ new Map();
|
|
420
|
+
const paginators = /* @__PURE__ */ new Map();
|
|
421
|
+
const adapter = {
|
|
422
|
+
get catalog() {
|
|
423
|
+
return registry.catalog;
|
|
424
|
+
},
|
|
425
|
+
get manifest() {
|
|
426
|
+
return registry.manifest;
|
|
427
|
+
},
|
|
428
|
+
get components() {
|
|
429
|
+
return { ...components };
|
|
430
|
+
},
|
|
431
|
+
prepare: (presentation) => registry.prepare({ ...presentation, props: presentation.props }),
|
|
432
|
+
render: (presentation, channel) => registry.render(
|
|
433
|
+
{ ...presentation, props: presentation.props },
|
|
434
|
+
channel
|
|
435
|
+
),
|
|
436
|
+
register(definition, renderers) {
|
|
437
|
+
const ReactComponent = renderers.react;
|
|
438
|
+
registry.register(definition, {
|
|
439
|
+
...ReactComponent ? { react: (props) => createElement(ReactComponent, props) } : {},
|
|
440
|
+
...renderers.text ? { text: renderers.text } : {}
|
|
441
|
+
});
|
|
442
|
+
if (renderers.react) components[definition.name] = renderers.react;
|
|
443
|
+
if (renderers.text) {
|
|
444
|
+
const text = renderers.text;
|
|
445
|
+
texts.set(definition.name, (props) => text(props));
|
|
446
|
+
}
|
|
447
|
+
if (renderers.paginate) {
|
|
448
|
+
const paginate = renderers.paginate;
|
|
449
|
+
paginators.set(
|
|
450
|
+
definition.name,
|
|
451
|
+
async (props, size) => await paginate(props, size)
|
|
452
|
+
);
|
|
453
|
+
}
|
|
454
|
+
return adapter;
|
|
455
|
+
},
|
|
456
|
+
async renderPages(presentation, size) {
|
|
457
|
+
const pages = await adapter.paginate(presentation, size);
|
|
458
|
+
return Promise.all(
|
|
459
|
+
pages.map(async (page) => {
|
|
460
|
+
const ReactComponent = components[page.component];
|
|
461
|
+
if (ReactComponent) return createElement(ReactComponent, page.props);
|
|
462
|
+
return texts.get(page.component)?.(page.props) ?? page.fallbackText;
|
|
463
|
+
})
|
|
464
|
+
);
|
|
465
|
+
},
|
|
466
|
+
async paginate(presentation, size) {
|
|
467
|
+
if (!Number.isInteger(size) || size < 1 || size > 500)
|
|
468
|
+
throw new RangeError("genui: rowsPerPage must be 1\u2013500");
|
|
469
|
+
const prepared = await registry.prepare({
|
|
470
|
+
...presentation,
|
|
471
|
+
props: presentation.props
|
|
472
|
+
});
|
|
473
|
+
const custom = paginators.get(prepared.component);
|
|
474
|
+
const rows = prepared.props.rows;
|
|
475
|
+
const pages = custom ? await custom(prepared.props, size) : prepared.component === "DataTable" && Array.isArray(rows) && rows.length > size ? Array.from({ length: Math.ceil(rows.length / size) }, (_, index) => ({
|
|
476
|
+
...prepared.props,
|
|
477
|
+
rows: rows.slice(index * size, (index + 1) * size)
|
|
478
|
+
})) : [prepared.props];
|
|
479
|
+
if (!pages.length || pages.length > 100)
|
|
480
|
+
throw new RangeError("genui: capture requires 1\u2013100 pages");
|
|
481
|
+
return Promise.all(pages.map((props) => registry.prepare({ ...prepared, props })));
|
|
482
|
+
}
|
|
483
|
+
};
|
|
484
|
+
return adapter;
|
|
485
|
+
}
|
|
367
486
|
export {
|
|
368
487
|
GENUI_TREE_COMPONENT,
|
|
369
488
|
GenerativeUI,
|
|
370
489
|
GenerativeUIScope,
|
|
371
490
|
GenuiProvider,
|
|
372
491
|
GenuiTree,
|
|
492
|
+
createReactComponentRegistry,
|
|
373
493
|
toGenerativeUIItem,
|
|
374
494
|
useGenerativeUI,
|
|
375
495
|
useGenuiProvider
|
package/dist/genui.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/genui/generative-ui.tsx","../src/components/ambient-ui.ts","../src/genui/use-generative-ui.ts","../src/genui/types.ts"],"sourcesContent":["import {\n Component,\n type Context,\n type ErrorInfo,\n type ReactNode,\n createContext,\n useCallback,\n useContext,\n useMemo,\n} from 'react';\nimport { AmbientRenderUiContext, sharedContext } from '../components/ambient-ui.js';\nimport type { TranscriptUiBlock } from '../transcript/model.js';\nimport type {\n GenerativeUIElement,\n GenerativeUIItem,\n GenerativeUIOptions,\n GenerativeUIProblem,\n GenerativeUIState,\n GenuiRegistry,\n GenuiRenderer,\n} from './types.js';\nimport {\n useGenerativeUIState,\n useResolvedComponent,\n useValidatedProps,\n} from './use-generative-ui.js';\n\n/** What to draw instead of a component that did not render. Default: nothing. */\nexport type GenerativeUIFallback = ReactNode | ((problem: GenerativeUIProblem) => ReactNode);\n\ninterface TreeScope {\n options: GenerativeUIOptions;\n fallback: GenerativeUIFallback | undefined;\n loading: ReactNode;\n onError: ((error: unknown, item: GenerativeUIItem) => void) | undefined;\n}\n\nconst TreeScopeContext = createContext<TreeScope | null>(null);\n\nfunction renderFallback(fallback: GenerativeUIFallback | undefined, problem: GenerativeUIProblem) {\n if (typeof fallback === 'function') return fallback(problem);\n return fallback ?? null;\n}\n\ninterface BoundaryProps {\n item: GenerativeUIItem;\n fallback: GenerativeUIFallback | undefined;\n onError: ((error: unknown, item: GenerativeUIItem) => void) | undefined;\n children: ReactNode;\n}\n\n/** One failing renderer takes down its own item, never the message around it. */\nclass ItemBoundary extends Component<BoundaryProps, { error: unknown; failed: boolean }> {\n override state = { error: undefined as unknown, failed: false };\n\n static getDerivedStateFromError(error: unknown) {\n return { error, failed: true };\n }\n\n override componentDidCatch(error: unknown, _info: ErrorInfo) {\n this.props.onError?.(error, this.props.item);\n }\n\n override componentDidUpdate(previous: BoundaryProps) {\n // New props for the same item (a streamed update) get a fresh chance to render.\n if (this.state.failed && previous.item !== this.props.item) {\n this.setState({ error: undefined, failed: false });\n }\n }\n\n override render() {\n if (this.state.failed) {\n return renderFallback(this.props.fallback, {\n reason: 'error',\n item: this.props.item,\n error: this.state.error,\n });\n }\n return this.props.children;\n }\n}\n\nfunction nodeItem(node: GenerativeUIElement, id: string): GenerativeUIItem {\n return { id, component: node.type, props: node.props ?? {}, version: null, toolCallId: null };\n}\n\n/** One tree node: resolved and validated like a top-level item, children rendered as its `children`. */\nfunction TreeNode({ node, id }: { node: GenerativeUIElement; id: string }) {\n const scope = useContext(TreeScopeContext);\n const item = useMemo(() => nodeItem(node, id), [node, id]);\n const resolution = useResolvedComponent(\n node.type,\n null,\n scope?.options.registry ?? {},\n scope?.options.resolveComponent,\n );\n const validation = useValidatedProps(scope?.options.catalog, node.type, item.props);\n if (scope === null) return null;\n if (resolution.status === 'loading' || validation.status === 'pending') return scope.loading;\n if (resolution.status === 'unknown') {\n return renderFallback(scope.fallback, { reason: 'unknown', item });\n }\n if (resolution.status === 'error') {\n return renderFallback(scope.fallback, { reason: 'error', item, error: resolution.error });\n }\n if (validation.status === 'invalid') {\n return renderFallback(scope.fallback, { reason: 'invalid', item, issues: validation.issues });\n }\n const Renderer = resolution.Component;\n const children = Array.isArray(node.children) ? node.children : [];\n return (\n <Renderer {...validation.props}>\n {children.length > 0\n ? children.map((child, index) => {\n const childId = `${id}.${index}`;\n return (\n <ItemBoundary\n key={childId}\n item={nodeItem(child, childId)}\n fallback={scope.fallback}\n onError={scope.onError}\n >\n <TreeNode node={child} id={childId} />\n </ItemBoundary>\n );\n })\n : undefined}\n </Renderer>\n );\n}\n\n/**\n * Renders a `genui:tree` frame's `{ root }` node by node through the same registry, catalog and\n * resolver as top-level components. Used automatically for tree frames unless a `treeRenderer`\n * (e.g. the json-render one) or a registry entry for `genui:tree` takes over.\n */\nexport function GenuiTree({ root }: { root?: GenerativeUIElement }) {\n if (root === undefined || root === null || typeof root.type !== 'string') return null;\n return <TreeNode node={root} id=\"root\" />;\n}\n\nexport interface GenerativeUIScopeProps extends GenerativeUIOptions {\n fallback?: GenerativeUIFallback;\n loading?: ReactNode;\n onError?: (error: unknown, item: GenerativeUIItem) => void;\n children?: ReactNode;\n}\n\n/**\n * The registry, catalog and fallbacks tree nodes render with. `<GenerativeUI>` provides it; wrap\n * your own chrome in it when you draw `useGenerativeUI`'s `Component` yourself and it may be a tree.\n */\nexport function GenerativeUIScope({\n registry,\n catalog,\n resolveComponent,\n fallback,\n loading = null,\n onError,\n children,\n}: GenerativeUIScopeProps) {\n const scope = useMemo<TreeScope>(\n () => ({\n options: {\n registry,\n ...(catalog !== undefined ? { catalog } : {}),\n ...(resolveComponent !== undefined ? { resolveComponent } : {}),\n },\n fallback,\n loading,\n onError,\n }),\n [registry, catalog, resolveComponent, fallback, loading, onError],\n );\n return <TreeScopeContext.Provider value={scope}>{children}</TreeScopeContext.Provider>;\n}\n\n/** What `<GenuiProvider>` hands every `<GenerativeUI>` / `useGenerativeUI` below it. */\nexport interface GenuiProviderValue extends Partial<GenerativeUIOptions> {\n fallback?: GenerativeUIFallback;\n loading?: ReactNode;\n onError?: (error: unknown, item: GenerativeUIItem) => void;\n}\n\n// Shared by key: `/genui` and `/genui/json-render` are separate bundles, and a provider from one\n// must reach a `<GenerativeUI>` from the other.\nconst GenuiContext: Context<GenuiProviderValue | null> = sharedContext<GenuiProviderValue>(\n '@dudousxd/nestjs-agent-react:genui-provider',\n);\n\n/** The enclosing `<GenuiProvider>`'s settings, or `null` outside one. */\nexport function useGenuiProvider(): GenuiProviderValue | null {\n return useContext(GenuiContext);\n}\n\nexport interface GenuiProviderProps extends GenuiProviderValue {\n children?: ReactNode;\n}\n\n/**\n * Set generative UI up once, at the app root: the registry of your renderers, the catalog to\n * validate against, a resolver for components the registry lacks, and what to draw when one does\n * not render. Every `<GenerativeUI>` below reads it (its own props still win), and `MessageItem` /\n * `MessageList` draw pushed components with it — no `renderUi` per message.\n *\n * ```tsx\n * <GenuiProvider registry={registry} catalog={catalog} fallback={({ item }) => <Unknown name={item.component} />}>\n * <App />\n * </GenuiProvider>\n * ```\n */\nexport function GenuiProvider({\n registry,\n catalog,\n resolveComponent,\n treeRenderer,\n fallback,\n loading,\n onError,\n children,\n}: GenuiProviderProps) {\n const value = useMemo<GenuiProviderValue>(\n () => ({\n ...(registry !== undefined ? { registry } : {}),\n ...(catalog !== undefined ? { catalog } : {}),\n ...(resolveComponent !== undefined ? { resolveComponent } : {}),\n ...(treeRenderer !== undefined ? { treeRenderer } : {}),\n ...(fallback !== undefined ? { fallback } : {}),\n ...(loading !== undefined ? { loading } : {}),\n ...(onError !== undefined ? { onError } : {}),\n }),\n [registry, catalog, resolveComponent, treeRenderer, fallback, loading, onError],\n );\n const renderUi = useCallback((block: TranscriptUiBlock) => <GenerativeUI part={block} />, []);\n return (\n <GenuiContext.Provider value={value}>\n <AmbientRenderUiContext.Provider value={renderUi}>{children}</AmbientRenderUiContext.Provider>\n </GenuiContext.Provider>\n );\n}\n\nconst NO_REGISTRY: GenuiRegistry = {};\n\n/** Provider settings overlaid with explicit ones (explicit wins), memoized on their parts. */\nfunction useMergedOptions(own: Partial<GenerativeUIOptions>): GenerativeUIOptions {\n const provided = useContext(GenuiContext);\n const registry = own.registry ?? provided?.registry ?? NO_REGISTRY;\n const catalog = own.catalog ?? provided?.catalog;\n const resolveComponent = own.resolveComponent ?? provided?.resolveComponent;\n const treeRenderer = own.treeRenderer ?? provided?.treeRenderer;\n return useMemo(\n () => ({\n registry,\n ...(catalog !== undefined ? { catalog } : {}),\n ...(resolveComponent !== undefined ? { resolveComponent } : {}),\n ...(treeRenderer !== undefined ? { treeRenderer } : {}),\n }),\n [registry, catalog, resolveComponent, treeRenderer],\n );\n}\n\n/**\n * The headless half of {@link GenerativeUI}: what to draw for one pushed component, or `null` when\n * `part` is not one. Options default to the enclosing `<GenuiProvider>`'s.\n */\nexport function useGenerativeUI(\n part: unknown,\n options: Partial<GenerativeUIOptions> = {},\n): GenerativeUIState | null {\n const merged = useMergedOptions(options);\n return useGenerativeUIState(part, merged, merged.treeRenderer ?? (GenuiTree as GenuiRenderer));\n}\n\nexport interface GenerativeUIProps extends Partial<GenerativeUIOptions> {\n /** A transcript `ui` block, a `data-ui` message part, or a stored `{ id, component, props, version? }`. */\n part: TranscriptUiBlock | GenerativeUIItem | unknown;\n /** Drawn for an unknown component, invalid props, or a renderer that threw. Default: the provider's, else nothing. */\n fallback?: GenerativeUIFallback;\n /** Drawn while a resolver or an async validation is pending. Default: the provider's, else nothing. */\n loading?: ReactNode;\n /** A renderer threw (the item shows `fallback`). */\n onError?: (error: unknown, item: GenerativeUIItem) => void;\n}\n\n/**\n * Draws one server-pushed component with the app's own renderer. Headless: it adds no element and\n * no style of its own — only what the registry's component renders (and whatever `fallback` /\n * `loading` you pass). Everything but `part` defaults to the enclosing `<GenuiProvider>`.\n *\n * ```tsx\n * <GenerativeUI part={block} />\n * ```\n */\nexport function GenerativeUI({\n part,\n registry,\n catalog,\n resolveComponent,\n treeRenderer,\n fallback: ownFallback,\n loading: ownLoading,\n onError: ownOnError,\n}: GenerativeUIProps) {\n const provided = useContext(GenuiContext);\n const fallback = ownFallback ?? provided?.fallback;\n const loading = ownLoading ?? provided?.loading ?? null;\n const onError = ownOnError ?? provided?.onError;\n const options = useMergedOptions({\n ...(registry !== undefined ? { registry } : {}),\n ...(catalog !== undefined ? { catalog } : {}),\n ...(resolveComponent !== undefined ? { resolveComponent } : {}),\n ...(treeRenderer !== undefined ? { treeRenderer } : {}),\n });\n const state = useGenerativeUIState(\n part,\n options,\n options.treeRenderer ?? (GenuiTree as GenuiRenderer),\n );\n if (state === null) return null;\n if (state.status === 'loading') return loading;\n if (state.status === 'problem') {\n const { status: _status, ...problem } = state;\n return renderFallback(fallback, problem);\n }\n const Renderer = state.Component;\n return (\n <GenerativeUIScope\n {...options}\n fallback={fallback}\n loading={loading}\n {...(onError !== undefined ? { onError } : {})}\n >\n <ItemBoundary item={state.item} fallback={fallback} onError={onError}>\n <Renderer {...state.props} />\n </ItemBoundary>\n </GenerativeUIScope>\n );\n}\n","import { type Context, type ReactNode, createContext, useContext } from 'react';\nimport type { TranscriptUiBlock } from '../transcript/model.js';\n\n/** Draws a server-pushed component block. */\nexport type AmbientRenderUi = (block: TranscriptUiBlock) => ReactNode;\n\n/**\n * A context stored on `globalThis` under a registered symbol. Each entry point (`.`, `/genui`,\n * `/genui/json-render`) is its own bundle with its own copy of every module, so a context one entry\n * provides and another reads has to be found by key, not by module identity.\n */\nexport function sharedContext<T>(key: string): Context<T | null> {\n const symbol = Symbol.for(key);\n const holder = globalThis as Record<symbol, Context<T | null> | undefined>;\n const existing = holder[symbol];\n if (existing !== undefined) return existing;\n const created = createContext<T | null>(null);\n holder[symbol] = created;\n return created;\n}\n\n/**\n * How pushed components are drawn when no `renderUi` is passed — set by `<GenuiProvider>` (the\n * `/genui` subpath) and read by `MessageItem`.\n */\nexport const AmbientRenderUiContext: Context<AmbientRenderUi | null> =\n sharedContext<AmbientRenderUi>('@dudousxd/nestjs-agent-react:ambient-render-ui');\n\n/**\n * The renderer `<GenuiProvider>` installed for pushed components, or `null` outside one. For a\n * custom transcript built on `useTranscriptItem`: draw a `ui` block with it and you get what\n * `MessageItem` draws.\n */\nexport function useAmbientRenderUi(): AmbientRenderUi | null {\n return useContext(AmbientRenderUiContext);\n}\n","import { useEffect, useMemo, useState } from 'react';\nimport {\n GENUI_TREE_COMPONENT,\n type GenerativeUIItem,\n type GenerativeUIOptions,\n type GenerativeUIState,\n type GenuiCatalogLike,\n type GenuiIssueLike,\n type GenuiRegistry,\n type GenuiRenderer,\n type ResolveComponent,\n} from './types.js';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * Normalize whatever carries a pushed component: a transcript `ui` block, a `data-ui` message part\n * (`{ type: 'data-ui', id, data }`), a stored `{ id, component, props, version? }` entry. `null` for\n * anything else.\n */\nexport function toGenerativeUIItem(part: unknown): GenerativeUIItem | null {\n if (!isRecord(part)) return null;\n const source = part.type === 'data-ui' && isRecord(part.data) ? part.data : part;\n if (typeof source.component !== 'string') return null;\n const id =\n typeof source.id === 'string' ? source.id : typeof part.id === 'string' ? part.id : null;\n if (id === null) return null;\n return {\n id,\n component: source.component,\n props: isRecord(source.props) ? source.props : {},\n version: typeof source.version === 'number' ? source.version : null,\n toolCallId: typeof source.toolCallId === 'string' ? source.toolCallId : null,\n };\n}\n\ntype Resolution =\n | { status: 'ready'; Component: GenuiRenderer }\n | { status: 'loading' }\n | { status: 'unknown' }\n | { status: 'error'; error: unknown };\n\ninterface CacheEntry {\n resolution: Resolution;\n settled: Promise<void> | null;\n}\n\nconst resolverCaches = new WeakMap<ResolveComponent, Map<string, CacheEntry>>();\n\nfunction resolveCached(\n resolve: ResolveComponent,\n name: string,\n version: number | null,\n): CacheEntry {\n let cache = resolverCaches.get(resolve);\n if (cache === undefined) {\n cache = new Map();\n resolverCaches.set(resolve, cache);\n }\n const key = `${name}@${version ?? ''}`;\n const hit = cache.get(key);\n if (hit !== undefined) return hit;\n let entry: CacheEntry;\n try {\n const result = resolve(name, version);\n if (result instanceof Promise) {\n entry = { resolution: { status: 'loading' }, settled: null };\n entry.settled = result.then(\n (Component) => {\n entry.resolution = Component ? { status: 'ready', Component } : { status: 'unknown' };\n },\n (error: unknown) => {\n entry.resolution = { status: 'error', error };\n },\n );\n } else {\n entry = {\n resolution: result ? { status: 'ready', Component: result } : { status: 'unknown' },\n settled: null,\n };\n }\n } catch (error) {\n entry = { resolution: { status: 'error', error }, settled: null };\n }\n cache.set(key, entry);\n return entry;\n}\n\n/**\n * Which renderer draws `name`: the registry first, then `resolveComponent` (cached; async results\n * re-render the caller when they land). `fallbackTree` answers the tree component when the\n * registry does not override it.\n */\nexport function useResolvedComponent(\n name: string,\n version: number | null,\n registry: GenuiRegistry,\n resolve: ResolveComponent | undefined,\n fallbackTree?: GenuiRenderer,\n): Resolution {\n const [, setTick] = useState(0);\n const own = registry[name];\n const entry =\n own !== undefined || resolve === undefined ? null : resolveCached(resolve, name, version);\n const pending = entry?.resolution.status === 'loading' ? entry.settled : null;\n useEffect(() => {\n if (pending === null) return;\n let live = true;\n void pending.then(() => {\n if (live) setTick((tick) => tick + 1);\n });\n return () => {\n live = false;\n };\n }, [pending]);\n if (own !== undefined) return { status: 'ready', Component: own };\n if (entry !== null && entry.resolution.status !== 'unknown') return entry.resolution;\n if (name === GENUI_TREE_COMPONENT && fallbackTree !== undefined) {\n return { status: 'ready', Component: fallbackTree };\n }\n return { status: 'unknown' };\n}\n\ntype Validation =\n | { status: 'ok'; props: Record<string, unknown> }\n | { status: 'pending' }\n | { status: 'invalid'; issues: GenuiIssueLike[] };\n\n/**\n * Props checked against the catalog: synchronously when the catalog can (`validateSync`), else\n * after the async check settles. A component the catalog does not know passes through unchecked.\n */\nexport function useValidatedProps(\n catalog: GenuiCatalogLike | undefined,\n name: string,\n props: Record<string, unknown>,\n): Validation {\n const checked = catalog?.has(name) === true;\n const immediate = useMemo<Validation | null>(() => {\n if (!checked || catalog === undefined) return { status: 'ok', props };\n const result = catalog.validateSync?.(name, props);\n if (result === undefined) return null;\n return result.ok\n ? { status: 'ok', props: result.value }\n : { status: 'invalid', issues: result.issues };\n }, [checked, catalog, name, props]);\n const [late, setLate] = useState<{ props: Record<string, unknown>; result: Validation } | null>(\n null,\n );\n useEffect(() => {\n if (immediate !== null || catalog === undefined) return;\n let live = true;\n catalog.validate(name, props).then(\n (result) => {\n if (!live) return;\n setLate({\n props,\n result: result.ok\n ? { status: 'ok', props: result.value }\n : { status: 'invalid', issues: result.issues },\n });\n },\n (error: unknown) => {\n if (!live) return;\n setLate({\n props,\n result: {\n status: 'invalid',\n issues: [{ path: [], message: error instanceof Error ? error.message : String(error) }],\n },\n });\n },\n );\n return () => {\n live = false;\n };\n }, [immediate, catalog, name, props]);\n if (immediate !== null) return immediate;\n return late !== null && late.props === props ? late.result : { status: 'pending' };\n}\n\n/** {@link import('./generative-ui.js').useGenerativeUI}, with the tree renderer handed in (avoids an import cycle). */\nexport function useGenerativeUIState(\n part: unknown,\n options: GenerativeUIOptions,\n fallbackTree: GenuiRenderer | undefined,\n): GenerativeUIState | null {\n const item = useMemo(() => toGenerativeUIItem(part), [part]);\n const name = item?.component ?? '';\n const resolution = useResolvedComponent(\n name,\n item?.version ?? null,\n options.registry,\n item === null ? undefined : options.resolveComponent,\n fallbackTree,\n );\n const empty = useMemo<Record<string, unknown>>(() => ({}), []);\n // A tree is validated node by node as it renders, not as one component.\n const validation = useValidatedProps(\n item === null || name === GENUI_TREE_COMPONENT ? undefined : options.catalog,\n name,\n item?.props ?? empty,\n );\n if (item === null) return null;\n if (resolution.status === 'loading') return { status: 'loading', item };\n if (resolution.status === 'unknown') return { status: 'problem', reason: 'unknown', item };\n if (resolution.status === 'error') {\n return { status: 'problem', reason: 'error', item, error: resolution.error };\n }\n if (validation.status === 'pending') return { status: 'loading', item };\n if (validation.status === 'invalid') {\n return { status: 'problem', reason: 'invalid', item, issues: validation.issues };\n }\n return { status: 'ready', item, Component: resolution.Component, props: validation.props };\n}\n","import type { ComponentType, ReactNode } from 'react';\n\n/** The `ui` frame component a composed tree is pushed under (`GENUI_TREE_COMPONENT` of `@dudousxd/nestjs-agent-core/genui`). */\nexport const GENUI_TREE_COMPONENT = 'genui:tree';\n\n/** One pushed component, normalized from whatever carried it (a transcript block, a `data-ui` part, a stored entry). */\nexport interface GenerativeUIItem {\n id: string;\n component: string;\n props: Record<string, unknown>;\n version: number | null;\n toolCallId: string | null;\n}\n\n/** A node of a composed tree (`genui:tree` frames): `{ type, props, children? }`. */\nexport interface GenerativeUIElement {\n type: string;\n props: Record<string, unknown>;\n children?: GenerativeUIElement[];\n}\n\n/**\n * An app's renderer for one component: it receives the component's props spread, plus `children`\n * when it is a layout node in a tree. Any React component — the library never styles anything.\n */\nexport type GenuiRenderer<P = any> = ComponentType<P & { children?: ReactNode }>;\n\n/** Component name → the app's renderer. */\nexport type GenuiRegistry = Record<string, GenuiRenderer>;\n\n/**\n * Resolve a component the registry does not have — typically a tenant's own component, fetched for\n * the exact `version` a message was rendered with. Return `null`/`undefined` for \"no such\n * component\". May be async; results are cached per resolver, name and version.\n */\nexport type ResolveComponent = (\n name: string,\n version: number | null,\n) => GenuiRenderer | null | undefined | Promise<GenuiRenderer | null | undefined>;\n\nexport interface GenuiIssueLike {\n path: (string | number)[];\n message: string;\n}\n\ntype ValidationLike =\n | { ok: true; value: Record<string, unknown> }\n | { ok: false; issues: GenuiIssueLike[] };\n\n/**\n * What the renderer needs from a catalog to validate props before drawing them. A `Catalog` from\n * `@dudousxd/nestjs-agent-core/genui` satisfies it; declared structurally so any catalog-shaped\n * object does too.\n */\nexport interface GenuiCatalogLike {\n has(name: string): boolean;\n validate(name: string, props: unknown): Promise<ValidationLike>;\n validateSync?(name: string, props: unknown): ValidationLike | undefined;\n}\n\nexport interface GenerativeUIOptions {\n registry: GenuiRegistry;\n /** Validate props against it before rendering. Components the catalog does not know render unvalidated. */\n catalog?: GenuiCatalogLike;\n resolveComponent?: ResolveComponent;\n /**\n * Draws a composed tree frame (`genui:tree`) whole — e.g. through json-render (see the\n * `/genui/json-render` subpath's `GenuiProvider`). Omitted → trees render node by node through\n * `registry`.\n */\n treeRenderer?: GenuiRenderer<{ root?: GenerativeUIElement }>;\n}\n\n/** Why an item did not render. */\nexport type GenerativeUIProblem =\n | { reason: 'unknown'; item: GenerativeUIItem }\n | { reason: 'invalid'; item: GenerativeUIItem; issues: GenuiIssueLike[] }\n | { reason: 'error'; item: GenerativeUIItem; error: unknown };\n\nexport type GenerativeUIState =\n | {\n status: 'ready';\n item: GenerativeUIItem;\n Component: GenuiRenderer;\n props: Record<string, unknown>;\n }\n | { status: 'loading'; item: GenerativeUIItem }\n | ({ status: 'problem' } & GenerativeUIProblem);\n"],"mappings":"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","names":["createContext","useContext","useMemo","Component","createContext","useContext","useMemo"]}
|
|
1
|
+
{"version":3,"sources":["../src/genui/generative-ui.tsx","../src/components/ambient-ui.ts","../src/genui/use-generative-ui.ts","../src/genui/types.ts","../src/genui/react-registry.ts"],"sourcesContent":["import {\n Component,\n type Context,\n type ErrorInfo,\n type ReactNode,\n createContext,\n useCallback,\n useContext,\n useMemo,\n} from 'react';\nimport { AmbientRenderUiContext, sharedContext } from '../components/ambient-ui.js';\nimport type { TranscriptUiBlock } from '../transcript/model.js';\nimport type {\n GenerativeUIElement,\n GenerativeUIItem,\n GenerativeUIOptions,\n GenerativeUIProblem,\n GenerativeUIState,\n GenuiRegistry,\n GenuiRenderer,\n} from './types.js';\nimport {\n useGenerativeUIState,\n useResolvedComponent,\n useValidatedProps,\n} from './use-generative-ui.js';\n\n/** What to draw instead of a component that did not render. Default: nothing. */\nexport type GenerativeUIFallback = ReactNode | ((problem: GenerativeUIProblem) => ReactNode);\n\ninterface TreeScope {\n fallbackText?: string;\n componentVersions?: Record<string, number>;\n options: GenerativeUIOptions;\n fallback: GenerativeUIFallback | undefined;\n loading: ReactNode;\n onError: ((error: unknown, item: GenerativeUIItem) => void) | undefined;\n}\n\nconst TreeScopeContext = createContext<TreeScope | null>(null);\n\nfunction renderFallback(fallback: GenerativeUIFallback | undefined, problem: GenerativeUIProblem) {\n if (typeof fallback === 'function') return fallback(problem);\n if (fallback !== undefined) return fallback;\n return problem.item.fallbackText !== undefined ? (\n <span style={{ whiteSpace: 'pre-wrap' }}>{problem.item.fallbackText}</span>\n ) : null;\n}\n\ninterface BoundaryProps {\n item: GenerativeUIItem;\n fallback: GenerativeUIFallback | undefined;\n onError: ((error: unknown, item: GenerativeUIItem) => void) | undefined;\n children: ReactNode;\n}\n\n/** One failing renderer takes down its own item, never the message around it. */\nclass ItemBoundary extends Component<BoundaryProps, { error: unknown; failed: boolean }> {\n override state = { error: undefined as unknown, failed: false };\n\n static getDerivedStateFromError(error: unknown) {\n return { error, failed: true };\n }\n\n override componentDidCatch(error: unknown, _info: ErrorInfo) {\n this.props.onError?.(error, this.props.item);\n }\n\n override componentDidUpdate(previous: BoundaryProps) {\n // New props for the same item (a streamed update) get a fresh chance to render.\n if (this.state.failed && previous.item !== this.props.item) {\n this.setState({ error: undefined, failed: false });\n }\n }\n\n override render() {\n if (this.state.failed) {\n return renderFallback(this.props.fallback, {\n reason: 'error',\n item: this.props.item,\n error: this.state.error,\n });\n }\n return this.props.children;\n }\n}\n\nfunction nodeItem(node: GenerativeUIElement, id: string): GenerativeUIItem {\n return { id, component: node.type, props: node.props ?? {}, version: null, toolCallId: null };\n}\n\n/** One tree node: resolved and validated like a top-level item, children rendered as its `children`. */\nfunction TreeNode({ node, id }: { node: GenerativeUIElement; id: string }) {\n const scope = useContext(TreeScopeContext);\n const item = useMemo(() => nodeItem(node, id), [node, id]);\n const storedVersion = scope?.componentVersions?.[node.type];\n const definition = scope?.options.catalog?.get?.(node.type);\n const incompatible =\n storedVersion !== undefined &&\n definition !== undefined &&\n storedVersion !== (definition.version ?? 1);\n const resolution = useResolvedComponent(\n node.type,\n storedVersion ?? null,\n incompatible ? {} : (scope?.options.registry ?? {}),\n scope?.options.resolveComponent,\n );\n const validation = useValidatedProps(\n incompatible ? undefined : scope?.options.catalog,\n node.type,\n item.props,\n );\n if (scope === null) return null;\n if (resolution.status === 'loading' || validation.status === 'pending') return scope.loading;\n if (resolution.status === 'unknown') {\n if (scope.fallback === undefined && scope.fallbackText !== undefined)\n throw new Error('Unknown tree component');\n return renderFallback(scope.fallback, { reason: 'unknown', item });\n }\n if (resolution.status === 'error') {\n if (scope.fallback === undefined && scope.fallbackText !== undefined) throw resolution.error;\n return renderFallback(scope.fallback, { reason: 'error', item, error: resolution.error });\n }\n if (validation.status === 'invalid') {\n if (scope.fallback === undefined && scope.fallbackText !== undefined)\n throw new Error('Invalid tree component');\n return renderFallback(scope.fallback, { reason: 'invalid', item, issues: validation.issues });\n }\n const Renderer = resolution.Component;\n const children = Array.isArray(node.children) ? node.children : [];\n return (\n <Renderer {...validation.props}>\n {children.length > 0\n ? children.map((child, index) => {\n const childId = `${id}.${index}`;\n if (scope.fallback === undefined && scope.fallbackText !== undefined)\n return <TreeNode key={childId} node={child} id={childId} />;\n return (\n <ItemBoundary\n key={childId}\n item={nodeItem(child, childId)}\n fallback={scope.fallback}\n onError={scope.onError}\n >\n <TreeNode node={child} id={childId} />\n </ItemBoundary>\n );\n })\n : undefined}\n </Renderer>\n );\n}\n\n/**\n * Renders a `genui:tree` frame's `{ root }` node by node through the same registry, catalog and\n * resolver as top-level components. Used automatically for tree frames unless a `treeRenderer`\n * (e.g. the json-render one) or a registry entry for `genui:tree` takes over.\n */\nexport function GenuiTree({ root }: { root?: GenerativeUIElement }) {\n if (root === undefined || root === null || typeof root.type !== 'string') return null;\n return <TreeNode node={root} id=\"root\" />;\n}\n\nexport interface GenerativeUIScopeProps extends GenerativeUIOptions {\n fallbackText?: string;\n componentVersions?: Record<string, number>;\n fallback?: GenerativeUIFallback;\n loading?: ReactNode;\n onError?: (error: unknown, item: GenerativeUIItem) => void;\n children?: ReactNode;\n}\n\n/**\n * The registry, catalog and fallbacks tree nodes render with. `<GenerativeUI>` provides it; wrap\n * your own chrome in it when you draw `useGenerativeUI`'s `Component` yourself and it may be a tree.\n */\nexport function GenerativeUIScope({\n registry,\n catalog,\n resolveComponent,\n fallback,\n fallbackText,\n componentVersions,\n loading = null,\n onError,\n children,\n}: GenerativeUIScopeProps) {\n const scope = useMemo<TreeScope>(\n () => ({\n options: {\n registry,\n ...(catalog !== undefined ? { catalog } : {}),\n ...(resolveComponent !== undefined ? { resolveComponent } : {}),\n },\n fallback,\n ...(componentVersions !== undefined ? { componentVersions } : {}),\n ...(fallbackText !== undefined ? { fallbackText } : {}),\n loading,\n onError,\n }),\n [\n registry,\n catalog,\n resolveComponent,\n fallback,\n fallbackText,\n componentVersions,\n loading,\n onError,\n ],\n );\n return <TreeScopeContext.Provider value={scope}>{children}</TreeScopeContext.Provider>;\n}\n\n/** What `<GenuiProvider>` hands every `<GenerativeUI>` / `useGenerativeUI` below it. */\nexport interface GenuiProviderValue extends Partial<GenerativeUIOptions> {\n fallback?: GenerativeUIFallback;\n loading?: ReactNode;\n onError?: (error: unknown, item: GenerativeUIItem) => void;\n}\n\n// Shared by key: `/genui` and `/genui/json-render` are separate bundles, and a provider from one\n// must reach a `<GenerativeUI>` from the other.\nconst GenuiContext: Context<GenuiProviderValue | null> = sharedContext<GenuiProviderValue>(\n '@dudousxd/nestjs-agent-react:genui-provider',\n);\n\n/** The enclosing `<GenuiProvider>`'s settings, or `null` outside one. */\nexport function useGenuiProvider(): GenuiProviderValue | null {\n return useContext(GenuiContext);\n}\n\nexport interface GenuiProviderProps extends GenuiProviderValue {\n children?: ReactNode;\n}\n\n/**\n * Set generative UI up once, at the app root: the registry of your renderers, the catalog to\n * validate against, a resolver for components the registry lacks, and what to draw when one does\n * not render. Every `<GenerativeUI>` below reads it (its own props still win), and `MessageItem` /\n * `MessageList` draw pushed components with it — no `renderUi` per message.\n *\n * ```tsx\n * <GenuiProvider registry={registry} catalog={catalog} fallback={({ item }) => <Unknown name={item.component} />}>\n * <App />\n * </GenuiProvider>\n * ```\n */\nexport function GenuiProvider({\n registry,\n catalog,\n resolveComponent,\n treeRenderer,\n fallback,\n loading,\n onError,\n children,\n}: GenuiProviderProps) {\n const value = useMemo<GenuiProviderValue>(\n () => ({\n ...(registry !== undefined ? { registry } : {}),\n ...(catalog !== undefined ? { catalog } : {}),\n ...(resolveComponent !== undefined ? { resolveComponent } : {}),\n ...(treeRenderer !== undefined ? { treeRenderer } : {}),\n ...(fallback !== undefined ? { fallback } : {}),\n ...(loading !== undefined ? { loading } : {}),\n ...(onError !== undefined ? { onError } : {}),\n }),\n [registry, catalog, resolveComponent, treeRenderer, fallback, loading, onError],\n );\n const renderUi = useCallback((block: TranscriptUiBlock) => <GenerativeUI part={block} />, []);\n return (\n <GenuiContext.Provider value={value}>\n <AmbientRenderUiContext.Provider value={renderUi}>{children}</AmbientRenderUiContext.Provider>\n </GenuiContext.Provider>\n );\n}\n\nconst NO_REGISTRY: GenuiRegistry = {};\n\n/** Provider settings overlaid with explicit ones (explicit wins), memoized on their parts. */\nfunction useMergedOptions(own: Partial<GenerativeUIOptions>): GenerativeUIOptions {\n const provided = useContext(GenuiContext);\n const registry = own.registry ?? provided?.registry ?? NO_REGISTRY;\n const catalog = own.catalog ?? provided?.catalog;\n const resolveComponent = own.resolveComponent ?? provided?.resolveComponent;\n const treeRenderer = own.treeRenderer ?? provided?.treeRenderer;\n return useMemo(\n () => ({\n registry,\n ...(catalog !== undefined ? { catalog } : {}),\n ...(resolveComponent !== undefined ? { resolveComponent } : {}),\n ...(treeRenderer !== undefined ? { treeRenderer } : {}),\n }),\n [registry, catalog, resolveComponent, treeRenderer],\n );\n}\n\n/**\n * The headless half of {@link GenerativeUI}: what to draw for one pushed component, or `null` when\n * `part` is not one. Options default to the enclosing `<GenuiProvider>`'s.\n */\nexport function useGenerativeUI(\n part: unknown,\n options: Partial<GenerativeUIOptions> = {},\n): GenerativeUIState | null {\n const merged = useMergedOptions(options);\n return useGenerativeUIState(part, merged, merged.treeRenderer ?? (GenuiTree as GenuiRenderer));\n}\n\nexport interface GenerativeUIProps extends Partial<GenerativeUIOptions> {\n /** A transcript `ui` block, a `data-ui` message part, or a stored `{ id, component, props, version? }`. */\n part: TranscriptUiBlock | GenerativeUIItem | unknown;\n /** Drawn for an unknown component, invalid props, or a renderer that threw. Default: the provider's, then the item's persisted text. */\n fallback?: GenerativeUIFallback;\n /** Drawn while a resolver or an async validation is pending. Default: the provider's, else nothing. */\n loading?: ReactNode;\n /** A renderer threw (the item shows `fallback`). */\n onError?: (error: unknown, item: GenerativeUIItem) => void;\n}\n\n/**\n * Draws one server-pushed component with the app's own renderer. Headless: it adds no element and\n * no style of its own — only what the registry's component renders (and whatever `fallback` /\n * `loading` you pass). Everything but `part` defaults to the enclosing `<GenuiProvider>`.\n *\n * ```tsx\n * <GenerativeUI part={block} />\n * ```\n */\nexport function GenerativeUI({\n part,\n registry,\n catalog,\n resolveComponent,\n treeRenderer,\n fallback: ownFallback,\n loading: ownLoading,\n onError: ownOnError,\n}: GenerativeUIProps) {\n const provided = useContext(GenuiContext);\n const fallback = ownFallback !== undefined ? ownFallback : provided?.fallback;\n const loading = ownLoading ?? provided?.loading ?? null;\n const onError = ownOnError ?? provided?.onError;\n const options = useMergedOptions({\n ...(registry !== undefined ? { registry } : {}),\n ...(catalog !== undefined ? { catalog } : {}),\n ...(resolveComponent !== undefined ? { resolveComponent } : {}),\n ...(treeRenderer !== undefined ? { treeRenderer } : {}),\n });\n const state = useGenerativeUIState(\n part,\n options,\n options.treeRenderer ?? (GenuiTree as GenuiRenderer),\n );\n if (state === null) return null;\n if (state.status === 'loading') return loading;\n if (state.status === 'problem') {\n const { status: _status, ...problem } = state;\n return renderFallback(fallback, problem);\n }\n const Renderer = state.Component;\n return (\n <GenerativeUIScope\n {...options}\n {...(state.item.componentVersions !== undefined\n ? { componentVersions: state.item.componentVersions }\n : {})}\n {...(state.item.fallbackText !== undefined ? { fallbackText: state.item.fallbackText } : {})}\n fallback={fallback}\n loading={loading}\n {...(onError !== undefined ? { onError } : {})}\n >\n <ItemBoundary item={state.item} fallback={fallback} onError={onError}>\n <Renderer {...state.props} />\n </ItemBoundary>\n </GenerativeUIScope>\n );\n}\n","import { type Context, type ReactNode, createContext, useContext } from 'react';\nimport type { TranscriptUiBlock } from '../transcript/model.js';\n\n/** Draws a server-pushed component block. */\nexport type AmbientRenderUi = (block: TranscriptUiBlock) => ReactNode;\n\n/**\n * A context stored on `globalThis` under a registered symbol. Each entry point (`.`, `/genui`,\n * `/genui/json-render`) is its own bundle with its own copy of every module, so a context one entry\n * provides and another reads has to be found by key, not by module identity.\n */\nexport function sharedContext<T>(key: string): Context<T | null> {\n const symbol = Symbol.for(key);\n const holder = globalThis as Record<symbol, Context<T | null> | undefined>;\n const existing = holder[symbol];\n if (existing !== undefined) return existing;\n const created = createContext<T | null>(null);\n holder[symbol] = created;\n return created;\n}\n\n/**\n * How pushed components are drawn when no `renderUi` is passed — set by `<GenuiProvider>` (the\n * `/genui` subpath) and read by `MessageItem`.\n */\nexport const AmbientRenderUiContext: Context<AmbientRenderUi | null> =\n sharedContext<AmbientRenderUi>('@dudousxd/nestjs-agent-react:ambient-render-ui');\n\n/**\n * The renderer `<GenuiProvider>` installed for pushed components, or `null` outside one. For a\n * custom transcript built on `useTranscriptItem`: draw a `ui` block with it and you get what\n * `MessageItem` draws.\n */\nexport function useAmbientRenderUi(): AmbientRenderUi | null {\n return useContext(AmbientRenderUiContext);\n}\n","import { useEffect, useMemo, useState } from 'react';\nimport {\n GENUI_TREE_COMPONENT,\n type GenerativeUIItem,\n type GenerativeUIOptions,\n type GenerativeUIState,\n type GenuiCatalogLike,\n type GenuiIssueLike,\n type GenuiRegistry,\n type GenuiRenderer,\n type ResolveComponent,\n} from './types.js';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * Normalize whatever carries a pushed component: a transcript `ui` block, a `data-ui` message part\n * (`{ type: 'data-ui', id, data }`), a stored `{ id, component, props, version? }` entry. `null` for\n * anything else.\n */\nexport function toGenerativeUIItem(part: unknown): GenerativeUIItem | null {\n if (!isRecord(part)) return null;\n const source = part.type === 'data-ui' && isRecord(part.data) ? part.data : part;\n if (typeof source.component !== 'string') return null;\n const id =\n typeof source.id === 'string' ? source.id : typeof part.id === 'string' ? part.id : null;\n if (id === null) return null;\n return {\n id,\n component: source.component,\n ...(isRecord(source.componentVersions) &&\n Object.values(source.componentVersions).every(\n (version) => typeof version === 'number' && Number.isSafeInteger(version) && version > 0,\n )\n ? { componentVersions: { ...source.componentVersions } as Record<string, number> }\n : {}),\n ...(typeof source.fallbackText === 'string' ? { fallbackText: source.fallbackText } : {}),\n props: isRecord(source.props) ? source.props : {},\n version: typeof source.version === 'number' ? source.version : null,\n toolCallId: typeof source.toolCallId === 'string' ? source.toolCallId : null,\n };\n}\n\ntype Resolution =\n | { status: 'ready'; Component: GenuiRenderer }\n | { status: 'loading' }\n | { status: 'unknown' }\n | { status: 'error'; error: unknown };\n\ninterface CacheEntry {\n resolution: Resolution;\n settled: Promise<void> | null;\n}\n\nconst resolverCaches = new WeakMap<ResolveComponent, Map<string, CacheEntry>>();\n\nfunction resolveCached(\n resolve: ResolveComponent,\n name: string,\n version: number | null,\n): CacheEntry {\n let cache = resolverCaches.get(resolve);\n if (cache === undefined) {\n cache = new Map();\n resolverCaches.set(resolve, cache);\n }\n const key = `${name}@${version ?? ''}`;\n const hit = cache.get(key);\n if (hit !== undefined) return hit;\n let entry: CacheEntry;\n try {\n const result = resolve(name, version);\n if (result instanceof Promise) {\n entry = { resolution: { status: 'loading' }, settled: null };\n entry.settled = result.then(\n (Component) => {\n entry.resolution = Component ? { status: 'ready', Component } : { status: 'unknown' };\n },\n (error: unknown) => {\n entry.resolution = { status: 'error', error };\n },\n );\n } else {\n entry = {\n resolution: result ? { status: 'ready', Component: result } : { status: 'unknown' },\n settled: null,\n };\n }\n } catch (error) {\n entry = { resolution: { status: 'error', error }, settled: null };\n }\n cache.set(key, entry);\n return entry;\n}\n\n/**\n * Which renderer draws `name`: the registry first, then `resolveComponent` (cached; async results\n * re-render the caller when they land). `fallbackTree` answers the tree component when the\n * registry does not override it.\n */\nexport function useResolvedComponent(\n name: string,\n version: number | null,\n registry: GenuiRegistry,\n resolve: ResolveComponent | undefined,\n fallbackTree?: GenuiRenderer,\n): Resolution {\n const [, setTick] = useState(0);\n const own = registry[name];\n const entry =\n own !== undefined || resolve === undefined ? null : resolveCached(resolve, name, version);\n const pending = entry?.resolution.status === 'loading' ? entry.settled : null;\n useEffect(() => {\n if (pending === null) return;\n let live = true;\n void pending.then(() => {\n if (live) setTick((tick) => tick + 1);\n });\n return () => {\n live = false;\n };\n }, [pending]);\n if (own !== undefined) return { status: 'ready', Component: own };\n if (entry !== null && entry.resolution.status !== 'unknown') return entry.resolution;\n if (name === GENUI_TREE_COMPONENT && fallbackTree !== undefined) {\n return { status: 'ready', Component: fallbackTree };\n }\n return { status: 'unknown' };\n}\n\ntype Validation =\n | { status: 'ok'; props: Record<string, unknown> }\n | { status: 'pending' }\n | { status: 'invalid'; issues: GenuiIssueLike[] };\n\n/**\n * Props checked against the catalog: synchronously when the catalog can (`validateSync`), else\n * after the async check settles. A component the catalog does not know passes through unchecked.\n */\nexport function useValidatedProps(\n catalog: GenuiCatalogLike | undefined,\n name: string,\n props: Record<string, unknown>,\n): Validation {\n const checked = catalog?.has(name) === true;\n const immediate = useMemo<Validation | null>(() => {\n if (!checked || catalog === undefined) return { status: 'ok', props };\n const result = catalog.validateSync?.(name, props);\n if (result === undefined) return null;\n return result.ok\n ? { status: 'ok', props: result.value }\n : { status: 'invalid', issues: result.issues };\n }, [checked, catalog, name, props]);\n const [late, setLate] = useState<{ props: Record<string, unknown>; result: Validation } | null>(\n null,\n );\n useEffect(() => {\n if (immediate !== null || catalog === undefined) return;\n let live = true;\n catalog.validate(name, props).then(\n (result) => {\n if (!live) return;\n setLate({\n props,\n result: result.ok\n ? { status: 'ok', props: result.value }\n : { status: 'invalid', issues: result.issues },\n });\n },\n (error: unknown) => {\n if (!live) return;\n setLate({\n props,\n result: {\n status: 'invalid',\n issues: [{ path: [], message: error instanceof Error ? error.message : String(error) }],\n },\n });\n },\n );\n return () => {\n live = false;\n };\n }, [immediate, catalog, name, props]);\n if (immediate !== null) return immediate;\n return late !== null && late.props === props ? late.result : { status: 'pending' };\n}\n\n/** {@link import('./generative-ui.js').useGenerativeUI}, with the tree renderer handed in (avoids an import cycle). */\nexport function useGenerativeUIState(\n part: unknown,\n options: GenerativeUIOptions,\n fallbackTree: GenuiRenderer | undefined,\n): GenerativeUIState | null {\n const item = useMemo(() => toGenerativeUIItem(part), [part]);\n const name = item?.component ?? '';\n const definition = options.catalog?.get?.(name);\n const incompatible =\n item?.fallbackText !== undefined &&\n item.version !== null &&\n definition !== undefined &&\n item.version !== (definition.version ?? 1);\n const resolution = useResolvedComponent(\n name,\n item?.version ?? null,\n incompatible ? {} : options.registry,\n item === null ? undefined : options.resolveComponent,\n fallbackTree,\n );\n const empty = useMemo<Record<string, unknown>>(() => ({}), []);\n // A tree is validated node by node as it renders, not as one component.\n const validation = useValidatedProps(\n item === null || name === GENUI_TREE_COMPONENT || incompatible ? undefined : options.catalog,\n name,\n item?.props ?? empty,\n );\n if (item === null) return null;\n if (\n name === GENUI_TREE_COMPONENT &&\n item.fallbackText !== undefined &&\n (!isRecord(item.props.root) || typeof item.props.root.type !== 'string')\n )\n return {\n status: 'problem',\n reason: 'invalid',\n item,\n issues: [{ path: ['root'], message: 'Invalid UI tree root' }],\n };\n if (resolution.status === 'loading') return { status: 'loading', item };\n if (resolution.status === 'unknown') return { status: 'problem', reason: 'unknown', item };\n if (resolution.status === 'error') {\n return { status: 'problem', reason: 'error', item, error: resolution.error };\n }\n if (validation.status === 'pending') return { status: 'loading', item };\n if (validation.status === 'invalid') {\n return { status: 'problem', reason: 'invalid', item, issues: validation.issues };\n }\n return { status: 'ready', item, Component: resolution.Component, props: validation.props };\n}\n","import type { ComponentType, ReactNode } from 'react';\n\n/** The `ui` frame component a composed tree is pushed under (`GENUI_TREE_COMPONENT` of `@dudousxd/nestjs-agent-core/genui`). */\nexport const GENUI_TREE_COMPONENT = 'genui:tree';\n\n/** One pushed component, normalized from whatever carried it (a transcript block, a `data-ui` part, a stored entry). */\nexport interface GenerativeUIItem {\n fallbackText?: string;\n componentVersions?: Record<string, number>;\n id: string;\n component: string;\n props: Record<string, unknown>;\n version: number | null;\n toolCallId: string | null;\n}\n\n/** A node of a composed tree (`genui:tree` frames): `{ type, props, children? }`. */\nexport interface GenerativeUIElement {\n type: string;\n props: Record<string, unknown>;\n children?: GenerativeUIElement[];\n}\n\n/**\n * An app's renderer for one component: it receives the component's props spread, plus `children`\n * when it is a layout node in a tree. Any React component — the library never styles anything.\n */\nexport type GenuiRenderer<P = any> = ComponentType<P & { children?: ReactNode }>;\n\n/** Component name → the app's renderer. */\nexport type GenuiRegistry = Record<string, GenuiRenderer>;\n\n/**\n * Resolve a component the registry does not have — typically a tenant's own component, fetched for\n * the exact `version` a message was rendered with. Return `null`/`undefined` for \"no such\n * component\". May be async; results are cached per resolver, name and version.\n */\nexport type ResolveComponent = (\n name: string,\n version: number | null,\n) => GenuiRenderer | null | undefined | Promise<GenuiRenderer | null | undefined>;\n\nexport interface GenuiIssueLike {\n path: (string | number)[];\n message: string;\n}\n\ntype ValidationLike =\n | { ok: true; value: Record<string, unknown> }\n | { ok: false; issues: GenuiIssueLike[] };\n\n/**\n * What the renderer needs from a catalog to validate props before drawing them. A `Catalog` from\n * `@dudousxd/nestjs-agent-core/genui` satisfies it; declared structurally so any catalog-shaped\n * object does too.\n */\nexport interface GenuiCatalogLike {\n get?(name: string): { version?: number } | undefined;\n has(name: string): boolean;\n validate(name: string, props: unknown): Promise<ValidationLike>;\n validateSync?(name: string, props: unknown): ValidationLike | undefined;\n}\n\nexport interface GenerativeUIOptions {\n registry: GenuiRegistry;\n /** Validate props against it before rendering. Components the catalog does not know render unvalidated. */\n catalog?: GenuiCatalogLike;\n resolveComponent?: ResolveComponent;\n /**\n * Draws a composed tree frame (`genui:tree`) whole — e.g. through json-render (see the\n * `/genui/json-render` subpath's `GenuiProvider`). Omitted → trees render node by node through\n * `registry`.\n */\n treeRenderer?: GenuiRenderer<{ root?: GenerativeUIElement }>;\n}\n\n/** Why an item did not render. */\nexport type GenerativeUIProblem =\n | { reason: 'unknown'; item: GenerativeUIItem }\n | { reason: 'invalid'; item: GenerativeUIItem; issues: GenuiIssueLike[] }\n | { reason: 'error'; item: GenerativeUIItem; error: unknown };\n\nexport type GenerativeUIState =\n | {\n status: 'ready';\n item: GenerativeUIItem;\n Component: GenuiRenderer;\n props: Record<string, unknown>;\n }\n | { status: 'loading'; item: GenerativeUIItem }\n | ({ status: 'problem' } & GenerativeUIProblem);\n","import {\n type CatalogOptions,\n type ComponentDefinition,\n type ComponentPresentation,\n createComponentRegistry,\n} from '@dudousxd/nestjs-agent-core/genui';\nimport { type ComponentType, type ReactNode, createElement } from 'react';\nimport type { GenuiRegistry } from './types.js';\n\nexport interface ReactComponentRenderers<P extends object> {\n react?: ComponentType<P>;\n text?: (props: P) => string | Promise<string>;\n /** Return each page's complete props. Each page is validated again before SSR. */\n paginate?: (props: P, rowsPerPage: number) => readonly P[] | Promise<readonly P[]>;\n}\n\n/** App-scoped registry shared by GenuiProvider and static server rendering. */\nexport function createReactComponentRegistry(options?: CatalogOptions) {\n const registry = createComponentRegistry(options);\n const components: GenuiRegistry = Object.create(null);\n const texts = new Map<string, (props: Record<string, unknown>) => string | Promise<string>>();\n const paginators = new Map<\n string,\n (props: Record<string, unknown>, size: number) => Promise<readonly Record<string, unknown>[]>\n >();\n const adapter = {\n get catalog() {\n return registry.catalog;\n },\n get manifest() {\n return registry.manifest;\n },\n get components(): GenuiRegistry {\n return { ...components };\n },\n prepare: (presentation: ComponentPresentation<object>) =>\n registry.prepare({ ...presentation, props: presentation.props as Record<string, unknown> }),\n render: (presentation: ComponentPresentation<object>, channel: string) =>\n registry.render(\n { ...presentation, props: presentation.props as Record<string, unknown> },\n channel,\n ),\n register<P extends object>(\n definition: ComponentDefinition<P>,\n renderers: ReactComponentRenderers<P>,\n ) {\n const ReactComponent = renderers.react;\n registry.register(definition, {\n ...(ReactComponent ? { react: (props: P) => createElement(ReactComponent, props) } : {}),\n ...(renderers.text ? { text: renderers.text } : {}),\n });\n if (renderers.react) components[definition.name] = renderers.react;\n if (renderers.text) {\n const text = renderers.text;\n texts.set(definition.name, (props) => text(props as P));\n }\n if (renderers.paginate) {\n const paginate = renderers.paginate;\n paginators.set(\n definition.name,\n async (props, size) =>\n (await paginate(props as P, size)) as readonly Record<string, unknown>[],\n );\n }\n return adapter;\n },\n async renderPages(\n presentation: ComponentPresentation<object>,\n size: number,\n ): Promise<ReactNode[]> {\n const pages = await adapter.paginate(presentation, size);\n return Promise.all(\n pages.map(async (page) => {\n const ReactComponent = components[page.component];\n if (ReactComponent) return createElement(ReactComponent, page.props);\n return texts.get(page.component)?.(page.props) ?? page.fallbackText;\n }),\n );\n },\n async paginate(\n presentation: ComponentPresentation<object>,\n size: number,\n ): Promise<ComponentPresentation[]> {\n if (!Number.isInteger(size) || size < 1 || size > 500)\n throw new RangeError('genui: rowsPerPage must be 1–500');\n const prepared = await registry.prepare({\n ...presentation,\n props: presentation.props as Record<string, unknown>,\n });\n const custom = paginators.get(prepared.component);\n const rows = prepared.props.rows;\n const pages = custom\n ? await custom(prepared.props, size)\n : prepared.component === 'DataTable' && Array.isArray(rows) && rows.length > size\n ? Array.from({ length: Math.ceil(rows.length / size) }, (_, index) => ({\n ...prepared.props,\n rows: rows.slice(index * size, (index + 1) * size),\n }))\n : [prepared.props];\n if (!pages.length || pages.length > 100)\n throw new RangeError('genui: capture requires 1–100 pages');\n return Promise.all(pages.map((props) => registry.prepare({ ...prepared, props })));\n },\n };\n return adapter;\n}\nexport type ReactComponentRegistry = ReturnType<typeof createReactComponentRegistry>;\n"],"mappings":";AAAA;AAAA,EACE;AAAA,EAIA,iBAAAA;AAAA,EACA;AAAA,EACA,cAAAC;AAAA,EACA,WAAAC;AAAA,OACK;;;ACTP,SAAuC,eAAe,kBAAkB;AAWjE,SAAS,cAAiB,KAAgC;AAC/D,QAAM,SAAS,OAAO,IAAI,GAAG;AAC7B,QAAM,SAAS;AACf,QAAM,WAAW,OAAO,MAAM;AAC9B,MAAI,aAAa,OAAW,QAAO;AACnC,QAAM,UAAU,cAAwB,IAAI;AAC5C,SAAO,MAAM,IAAI;AACjB,SAAO;AACT;AAMO,IAAM,yBACX,cAA+B,gDAAgD;;;AC1BjF,SAAS,WAAW,SAAS,gBAAgB;;;ACGtC,IAAM,uBAAuB;;;ADUpC,SAAS,SAAS,OAAkD;AAClE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAOO,SAAS,mBAAmB,MAAwC;AACzE,MAAI,CAAC,SAAS,IAAI,EAAG,QAAO;AAC5B,QAAM,SAAS,KAAK,SAAS,aAAa,SAAS,KAAK,IAAI,IAAI,KAAK,OAAO;AAC5E,MAAI,OAAO,OAAO,cAAc,SAAU,QAAO;AACjD,QAAM,KACJ,OAAO,OAAO,OAAO,WAAW,OAAO,KAAK,OAAO,KAAK,OAAO,WAAW,KAAK,KAAK;AACtF,MAAI,OAAO,KAAM,QAAO;AACxB,SAAO;AAAA,IACL;AAAA,IACA,WAAW,OAAO;AAAA,IAClB,GAAI,SAAS,OAAO,iBAAiB,KACrC,OAAO,OAAO,OAAO,iBAAiB,EAAE;AAAA,MACtC,CAAC,YAAY,OAAO,YAAY,YAAY,OAAO,cAAc,OAAO,KAAK,UAAU;AAAA,IACzF,IACI,EAAE,mBAAmB,EAAE,GAAG,OAAO,kBAAkB,EAA4B,IAC/E,CAAC;AAAA,IACL,GAAI,OAAO,OAAO,iBAAiB,WAAW,EAAE,cAAc,OAAO,aAAa,IAAI,CAAC;AAAA,IACvF,OAAO,SAAS,OAAO,KAAK,IAAI,OAAO,QAAQ,CAAC;AAAA,IAChD,SAAS,OAAO,OAAO,YAAY,WAAW,OAAO,UAAU;AAAA,IAC/D,YAAY,OAAO,OAAO,eAAe,WAAW,OAAO,aAAa;AAAA,EAC1E;AACF;AAaA,IAAM,iBAAiB,oBAAI,QAAmD;AAE9E,SAAS,cACP,SACA,MACA,SACY;AACZ,MAAI,QAAQ,eAAe,IAAI,OAAO;AACtC,MAAI,UAAU,QAAW;AACvB,YAAQ,oBAAI,IAAI;AAChB,mBAAe,IAAI,SAAS,KAAK;AAAA,EACnC;AACA,QAAM,MAAM,GAAG,IAAI,IAAI,WAAW,EAAE;AACpC,QAAM,MAAM,MAAM,IAAI,GAAG;AACzB,MAAI,QAAQ,OAAW,QAAO;AAC9B,MAAI;AACJ,MAAI;AACF,UAAM,SAAS,QAAQ,MAAM,OAAO;AACpC,QAAI,kBAAkB,SAAS;AAC7B,cAAQ,EAAE,YAAY,EAAE,QAAQ,UAAU,GAAG,SAAS,KAAK;AAC3D,YAAM,UAAU,OAAO;AAAA,QACrB,CAACC,eAAc;AACb,gBAAM,aAAaA,aAAY,EAAE,QAAQ,SAAS,WAAAA,WAAU,IAAI,EAAE,QAAQ,UAAU;AAAA,QACtF;AAAA,QACA,CAAC,UAAmB;AAClB,gBAAM,aAAa,EAAE,QAAQ,SAAS,MAAM;AAAA,QAC9C;AAAA,MACF;AAAA,IACF,OAAO;AACL,cAAQ;AAAA,QACN,YAAY,SAAS,EAAE,QAAQ,SAAS,WAAW,OAAO,IAAI,EAAE,QAAQ,UAAU;AAAA,QAClF,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,EAAE,YAAY,EAAE,QAAQ,SAAS,MAAM,GAAG,SAAS,KAAK;AAAA,EAClE;AACA,QAAM,IAAI,KAAK,KAAK;AACpB,SAAO;AACT;AAOO,SAAS,qBACd,MACA,SACA,UACA,SACA,cACY;AACZ,QAAM,CAAC,EAAE,OAAO,IAAI,SAAS,CAAC;AAC9B,QAAM,MAAM,SAAS,IAAI;AACzB,QAAM,QACJ,QAAQ,UAAa,YAAY,SAAY,OAAO,cAAc,SAAS,MAAM,OAAO;AAC1F,QAAM,UAAU,OAAO,WAAW,WAAW,YAAY,MAAM,UAAU;AACzE,YAAU,MAAM;AACd,QAAI,YAAY,KAAM;AACtB,QAAI,OAAO;AACX,SAAK,QAAQ,KAAK,MAAM;AACtB,UAAI,KAAM,SAAQ,CAAC,SAAS,OAAO,CAAC;AAAA,IACtC,CAAC;AACD,WAAO,MAAM;AACX,aAAO;AAAA,IACT;AAAA,EACF,GAAG,CAAC,OAAO,CAAC;AACZ,MAAI,QAAQ,OAAW,QAAO,EAAE,QAAQ,SAAS,WAAW,IAAI;AAChE,MAAI,UAAU,QAAQ,MAAM,WAAW,WAAW,UAAW,QAAO,MAAM;AAC1E,MAAI,SAAS,wBAAwB,iBAAiB,QAAW;AAC/D,WAAO,EAAE,QAAQ,SAAS,WAAW,aAAa;AAAA,EACpD;AACA,SAAO,EAAE,QAAQ,UAAU;AAC7B;AAWO,SAAS,kBACd,SACA,MACA,OACY;AACZ,QAAM,UAAU,SAAS,IAAI,IAAI,MAAM;AACvC,QAAM,YAAY,QAA2B,MAAM;AACjD,QAAI,CAAC,WAAW,YAAY,OAAW,QAAO,EAAE,QAAQ,MAAM,MAAM;AACpE,UAAM,SAAS,QAAQ,eAAe,MAAM,KAAK;AACjD,QAAI,WAAW,OAAW,QAAO;AACjC,WAAO,OAAO,KACV,EAAE,QAAQ,MAAM,OAAO,OAAO,MAAM,IACpC,EAAE,QAAQ,WAAW,QAAQ,OAAO,OAAO;AAAA,EACjD,GAAG,CAAC,SAAS,SAAS,MAAM,KAAK,CAAC;AAClC,QAAM,CAAC,MAAM,OAAO,IAAI;AAAA,IACtB;AAAA,EACF;AACA,YAAU,MAAM;AACd,QAAI,cAAc,QAAQ,YAAY,OAAW;AACjD,QAAI,OAAO;AACX,YAAQ,SAAS,MAAM,KAAK,EAAE;AAAA,MAC5B,CAAC,WAAW;AACV,YAAI,CAAC,KAAM;AACX,gBAAQ;AAAA,UACN;AAAA,UACA,QAAQ,OAAO,KACX,EAAE,QAAQ,MAAM,OAAO,OAAO,MAAM,IACpC,EAAE,QAAQ,WAAW,QAAQ,OAAO,OAAO;AAAA,QACjD,CAAC;AAAA,MACH;AAAA,MACA,CAAC,UAAmB;AAClB,YAAI,CAAC,KAAM;AACX,gBAAQ;AAAA,UACN;AAAA,UACA,QAAQ;AAAA,YACN,QAAQ;AAAA,YACR,QAAQ,CAAC,EAAE,MAAM,CAAC,GAAG,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAAE,CAAC;AAAA,UACxF;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AACA,WAAO,MAAM;AACX,aAAO;AAAA,IACT;AAAA,EACF,GAAG,CAAC,WAAW,SAAS,MAAM,KAAK,CAAC;AACpC,MAAI,cAAc,KAAM,QAAO;AAC/B,SAAO,SAAS,QAAQ,KAAK,UAAU,QAAQ,KAAK,SAAS,EAAE,QAAQ,UAAU;AACnF;AAGO,SAAS,qBACd,MACA,SACA,cAC0B;AAC1B,QAAM,OAAO,QAAQ,MAAM,mBAAmB,IAAI,GAAG,CAAC,IAAI,CAAC;AAC3D,QAAM,OAAO,MAAM,aAAa;AAChC,QAAM,aAAa,QAAQ,SAAS,MAAM,IAAI;AAC9C,QAAM,eACJ,MAAM,iBAAiB,UACvB,KAAK,YAAY,QACjB,eAAe,UACf,KAAK,aAAa,WAAW,WAAW;AAC1C,QAAM,aAAa;AAAA,IACjB;AAAA,IACA,MAAM,WAAW;AAAA,IACjB,eAAe,CAAC,IAAI,QAAQ;AAAA,IAC5B,SAAS,OAAO,SAAY,QAAQ;AAAA,IACpC;AAAA,EACF;AACA,QAAM,QAAQ,QAAiC,OAAO,CAAC,IAAI,CAAC,CAAC;AAE7D,QAAM,aAAa;AAAA,IACjB,SAAS,QAAQ,SAAS,wBAAwB,eAAe,SAAY,QAAQ;AAAA,IACrF;AAAA,IACA,MAAM,SAAS;AAAA,EACjB;AACA,MAAI,SAAS,KAAM,QAAO;AAC1B,MACE,SAAS,wBACT,KAAK,iBAAiB,WACrB,CAAC,SAAS,KAAK,MAAM,IAAI,KAAK,OAAO,KAAK,MAAM,KAAK,SAAS;AAE/D,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR;AAAA,MACA,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,GAAG,SAAS,uBAAuB,CAAC;AAAA,IAC9D;AACF,MAAI,WAAW,WAAW,UAAW,QAAO,EAAE,QAAQ,WAAW,KAAK;AACtE,MAAI,WAAW,WAAW,UAAW,QAAO,EAAE,QAAQ,WAAW,QAAQ,WAAW,KAAK;AACzF,MAAI,WAAW,WAAW,SAAS;AACjC,WAAO,EAAE,QAAQ,WAAW,QAAQ,SAAS,MAAM,OAAO,WAAW,MAAM;AAAA,EAC7E;AACA,MAAI,WAAW,WAAW,UAAW,QAAO,EAAE,QAAQ,WAAW,KAAK;AACtE,MAAI,WAAW,WAAW,WAAW;AACnC,WAAO,EAAE,QAAQ,WAAW,QAAQ,WAAW,MAAM,QAAQ,WAAW,OAAO;AAAA,EACjF;AACA,SAAO,EAAE,QAAQ,SAAS,MAAM,WAAW,WAAW,WAAW,OAAO,WAAW,MAAM;AAC3F;;;AFnMI;AANJ,IAAM,mBAAmBC,eAAgC,IAAI;AAE7D,SAAS,eAAe,UAA4C,SAA8B;AAChG,MAAI,OAAO,aAAa,WAAY,QAAO,SAAS,OAAO;AAC3D,MAAI,aAAa,OAAW,QAAO;AACnC,SAAO,QAAQ,KAAK,iBAAiB,SACnC,oBAAC,UAAK,OAAO,EAAE,YAAY,WAAW,GAAI,kBAAQ,KAAK,cAAa,IAClE;AACN;AAUA,IAAM,eAAN,cAA2B,UAA8D;AAAA,EAC9E,QAAQ,EAAE,OAAO,QAAsB,QAAQ,MAAM;AAAA,EAE9D,OAAO,yBAAyB,OAAgB;AAC9C,WAAO,EAAE,OAAO,QAAQ,KAAK;AAAA,EAC/B;AAAA,EAES,kBAAkB,OAAgB,OAAkB;AAC3D,SAAK,MAAM,UAAU,OAAO,KAAK,MAAM,IAAI;AAAA,EAC7C;AAAA,EAES,mBAAmB,UAAyB;AAEnD,QAAI,KAAK,MAAM,UAAU,SAAS,SAAS,KAAK,MAAM,MAAM;AAC1D,WAAK,SAAS,EAAE,OAAO,QAAW,QAAQ,MAAM,CAAC;AAAA,IACnD;AAAA,EACF;AAAA,EAES,SAAS;AAChB,QAAI,KAAK,MAAM,QAAQ;AACrB,aAAO,eAAe,KAAK,MAAM,UAAU;AAAA,QACzC,QAAQ;AAAA,QACR,MAAM,KAAK,MAAM;AAAA,QACjB,OAAO,KAAK,MAAM;AAAA,MACpB,CAAC;AAAA,IACH;AACA,WAAO,KAAK,MAAM;AAAA,EACpB;AACF;AAEA,SAAS,SAAS,MAA2B,IAA8B;AACzE,SAAO,EAAE,IAAI,WAAW,KAAK,MAAM,OAAO,KAAK,SAAS,CAAC,GAAG,SAAS,MAAM,YAAY,KAAK;AAC9F;AAGA,SAAS,SAAS,EAAE,MAAM,GAAG,GAA8C;AACzE,QAAM,QAAQC,YAAW,gBAAgB;AACzC,QAAM,OAAOC,SAAQ,MAAM,SAAS,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;AACzD,QAAM,gBAAgB,OAAO,oBAAoB,KAAK,IAAI;AAC1D,QAAM,aAAa,OAAO,QAAQ,SAAS,MAAM,KAAK,IAAI;AAC1D,QAAM,eACJ,kBAAkB,UAClB,eAAe,UACf,mBAAmB,WAAW,WAAW;AAC3C,QAAM,aAAa;AAAA,IACjB,KAAK;AAAA,IACL,iBAAiB;AAAA,IACjB,eAAe,CAAC,IAAK,OAAO,QAAQ,YAAY,CAAC;AAAA,IACjD,OAAO,QAAQ;AAAA,EACjB;AACA,QAAM,aAAa;AAAA,IACjB,eAAe,SAAY,OAAO,QAAQ;AAAA,IAC1C,KAAK;AAAA,IACL,KAAK;AAAA,EACP;AACA,MAAI,UAAU,KAAM,QAAO;AAC3B,MAAI,WAAW,WAAW,aAAa,WAAW,WAAW,UAAW,QAAO,MAAM;AACrF,MAAI,WAAW,WAAW,WAAW;AACnC,QAAI,MAAM,aAAa,UAAa,MAAM,iBAAiB;AACzD,YAAM,IAAI,MAAM,wBAAwB;AAC1C,WAAO,eAAe,MAAM,UAAU,EAAE,QAAQ,WAAW,KAAK,CAAC;AAAA,EACnE;AACA,MAAI,WAAW,WAAW,SAAS;AACjC,QAAI,MAAM,aAAa,UAAa,MAAM,iBAAiB,OAAW,OAAM,WAAW;AACvF,WAAO,eAAe,MAAM,UAAU,EAAE,QAAQ,SAAS,MAAM,OAAO,WAAW,MAAM,CAAC;AAAA,EAC1F;AACA,MAAI,WAAW,WAAW,WAAW;AACnC,QAAI,MAAM,aAAa,UAAa,MAAM,iBAAiB;AACzD,YAAM,IAAI,MAAM,wBAAwB;AAC1C,WAAO,eAAe,MAAM,UAAU,EAAE,QAAQ,WAAW,MAAM,QAAQ,WAAW,OAAO,CAAC;AAAA,EAC9F;AACA,QAAM,WAAW,WAAW;AAC5B,QAAM,WAAW,MAAM,QAAQ,KAAK,QAAQ,IAAI,KAAK,WAAW,CAAC;AACjE,SACE,oBAAC,YAAU,GAAG,WAAW,OACtB,mBAAS,SAAS,IACf,SAAS,IAAI,CAAC,OAAO,UAAU;AAC7B,UAAM,UAAU,GAAG,EAAE,IAAI,KAAK;AAC9B,QAAI,MAAM,aAAa,UAAa,MAAM,iBAAiB;AACzD,aAAO,oBAAC,YAAuB,MAAM,OAAO,IAAI,WAA1B,OAAmC;AAC3D,WACE;AAAA,MAAC;AAAA;AAAA,QAEC,MAAM,SAAS,OAAO,OAAO;AAAA,QAC7B,UAAU,MAAM;AAAA,QAChB,SAAS,MAAM;AAAA,QAEf,8BAAC,YAAS,MAAM,OAAO,IAAI,SAAS;AAAA;AAAA,MAL/B;AAAA,IAMP;AAAA,EAEJ,CAAC,IACD,QACN;AAEJ;AAOO,SAAS,UAAU,EAAE,KAAK,GAAmC;AAClE,MAAI,SAAS,UAAa,SAAS,QAAQ,OAAO,KAAK,SAAS,SAAU,QAAO;AACjF,SAAO,oBAAC,YAAS,MAAM,MAAM,IAAG,QAAO;AACzC;AAeO,SAAS,kBAAkB;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV;AAAA,EACA;AACF,GAA2B;AACzB,QAAM,QAAQA;AAAA,IACZ,OAAO;AAAA,MACL,SAAS;AAAA,QACP;AAAA,QACA,GAAI,YAAY,SAAY,EAAE,QAAQ,IAAI,CAAC;AAAA,QAC3C,GAAI,qBAAqB,SAAY,EAAE,iBAAiB,IAAI,CAAC;AAAA,MAC/D;AAAA,MACA;AAAA,MACA,GAAI,sBAAsB,SAAY,EAAE,kBAAkB,IAAI,CAAC;AAAA,MAC/D,GAAI,iBAAiB,SAAY,EAAE,aAAa,IAAI,CAAC;AAAA,MACrD;AAAA,MACA;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,SAAO,oBAAC,iBAAiB,UAAjB,EAA0B,OAAO,OAAQ,UAAS;AAC5D;AAWA,IAAM,eAAmD;AAAA,EACvD;AACF;AAGO,SAAS,mBAA8C;AAC5D,SAAOD,YAAW,YAAY;AAChC;AAkBO,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAuB;AACrB,QAAM,QAAQC;AAAA,IACZ,OAAO;AAAA,MACL,GAAI,aAAa,SAAY,EAAE,SAAS,IAAI,CAAC;AAAA,MAC7C,GAAI,YAAY,SAAY,EAAE,QAAQ,IAAI,CAAC;AAAA,MAC3C,GAAI,qBAAqB,SAAY,EAAE,iBAAiB,IAAI,CAAC;AAAA,MAC7D,GAAI,iBAAiB,SAAY,EAAE,aAAa,IAAI,CAAC;AAAA,MACrD,GAAI,aAAa,SAAY,EAAE,SAAS,IAAI,CAAC;AAAA,MAC7C,GAAI,YAAY,SAAY,EAAE,QAAQ,IAAI,CAAC;AAAA,MAC3C,GAAI,YAAY,SAAY,EAAE,QAAQ,IAAI,CAAC;AAAA,IAC7C;AAAA,IACA,CAAC,UAAU,SAAS,kBAAkB,cAAc,UAAU,SAAS,OAAO;AAAA,EAChF;AACA,QAAM,WAAW,YAAY,CAAC,UAA6B,oBAAC,gBAAa,MAAM,OAAO,GAAI,CAAC,CAAC;AAC5F,SACE,oBAAC,aAAa,UAAb,EAAsB,OACrB,8BAAC,uBAAuB,UAAvB,EAAgC,OAAO,UAAW,UAAS,GAC9D;AAEJ;AAEA,IAAM,cAA6B,CAAC;AAGpC,SAAS,iBAAiB,KAAwD;AAChF,QAAM,WAAWD,YAAW,YAAY;AACxC,QAAM,WAAW,IAAI,YAAY,UAAU,YAAY;AACvD,QAAM,UAAU,IAAI,WAAW,UAAU;AACzC,QAAM,mBAAmB,IAAI,oBAAoB,UAAU;AAC3D,QAAM,eAAe,IAAI,gBAAgB,UAAU;AACnD,SAAOC;AAAA,IACL,OAAO;AAAA,MACL;AAAA,MACA,GAAI,YAAY,SAAY,EAAE,QAAQ,IAAI,CAAC;AAAA,MAC3C,GAAI,qBAAqB,SAAY,EAAE,iBAAiB,IAAI,CAAC;AAAA,MAC7D,GAAI,iBAAiB,SAAY,EAAE,aAAa,IAAI,CAAC;AAAA,IACvD;AAAA,IACA,CAAC,UAAU,SAAS,kBAAkB,YAAY;AAAA,EACpD;AACF;AAMO,SAAS,gBACd,MACA,UAAwC,CAAC,GACf;AAC1B,QAAM,SAAS,iBAAiB,OAAO;AACvC,SAAO,qBAAqB,MAAM,QAAQ,OAAO,gBAAiB,SAA2B;AAC/F;AAsBO,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,SAAS;AAAA,EACT,SAAS;AACX,GAAsB;AACpB,QAAM,WAAWD,YAAW,YAAY;AACxC,QAAM,WAAW,gBAAgB,SAAY,cAAc,UAAU;AACrE,QAAM,UAAU,cAAc,UAAU,WAAW;AACnD,QAAM,UAAU,cAAc,UAAU;AACxC,QAAM,UAAU,iBAAiB;AAAA,IAC/B,GAAI,aAAa,SAAY,EAAE,SAAS,IAAI,CAAC;AAAA,IAC7C,GAAI,YAAY,SAAY,EAAE,QAAQ,IAAI,CAAC;AAAA,IAC3C,GAAI,qBAAqB,SAAY,EAAE,iBAAiB,IAAI,CAAC;AAAA,IAC7D,GAAI,iBAAiB,SAAY,EAAE,aAAa,IAAI,CAAC;AAAA,EACvD,CAAC;AACD,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,IACA,QAAQ,gBAAiB;AAAA,EAC3B;AACA,MAAI,UAAU,KAAM,QAAO;AAC3B,MAAI,MAAM,WAAW,UAAW,QAAO;AACvC,MAAI,MAAM,WAAW,WAAW;AAC9B,UAAM,EAAE,QAAQ,SAAS,GAAG,QAAQ,IAAI;AACxC,WAAO,eAAe,UAAU,OAAO;AAAA,EACzC;AACA,QAAM,WAAW,MAAM;AACvB,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACH,GAAI,MAAM,KAAK,sBAAsB,SAClC,EAAE,mBAAmB,MAAM,KAAK,kBAAkB,IAClD,CAAC;AAAA,MACJ,GAAI,MAAM,KAAK,iBAAiB,SAAY,EAAE,cAAc,MAAM,KAAK,aAAa,IAAI,CAAC;AAAA,MAC1F;AAAA,MACA;AAAA,MACC,GAAI,YAAY,SAAY,EAAE,QAAQ,IAAI,CAAC;AAAA,MAE5C,8BAAC,gBAAa,MAAM,MAAM,MAAM,UAAoB,SAClD,8BAAC,YAAU,GAAG,MAAM,OAAO,GAC7B;AAAA;AAAA,EACF;AAEJ;;;AI1XA;AAAA,EAIE;AAAA,OACK;AACP,SAA6C,qBAAqB;AAW3D,SAAS,6BAA6B,SAA0B;AACrE,QAAM,WAAW,wBAAwB,OAAO;AAChD,QAAM,aAA4B,uBAAO,OAAO,IAAI;AACpD,QAAM,QAAQ,oBAAI,IAA0E;AAC5F,QAAM,aAAa,oBAAI,IAGrB;AACF,QAAM,UAAU;AAAA,IACd,IAAI,UAAU;AACZ,aAAO,SAAS;AAAA,IAClB;AAAA,IACA,IAAI,WAAW;AACb,aAAO,SAAS;AAAA,IAClB;AAAA,IACA,IAAI,aAA4B;AAC9B,aAAO,EAAE,GAAG,WAAW;AAAA,IACzB;AAAA,IACA,SAAS,CAAC,iBACR,SAAS,QAAQ,EAAE,GAAG,cAAc,OAAO,aAAa,MAAiC,CAAC;AAAA,IAC5F,QAAQ,CAAC,cAA6C,YACpD,SAAS;AAAA,MACP,EAAE,GAAG,cAAc,OAAO,aAAa,MAAiC;AAAA,MACxE;AAAA,IACF;AAAA,IACF,SACE,YACA,WACA;AACA,YAAM,iBAAiB,UAAU;AACjC,eAAS,SAAS,YAAY;AAAA,QAC5B,GAAI,iBAAiB,EAAE,OAAO,CAAC,UAAa,cAAc,gBAAgB,KAAK,EAAE,IAAI,CAAC;AAAA,QACtF,GAAI,UAAU,OAAO,EAAE,MAAM,UAAU,KAAK,IAAI,CAAC;AAAA,MACnD,CAAC;AACD,UAAI,UAAU,MAAO,YAAW,WAAW,IAAI,IAAI,UAAU;AAC7D,UAAI,UAAU,MAAM;AAClB,cAAM,OAAO,UAAU;AACvB,cAAM,IAAI,WAAW,MAAM,CAAC,UAAU,KAAK,KAAU,CAAC;AAAA,MACxD;AACA,UAAI,UAAU,UAAU;AACtB,cAAM,WAAW,UAAU;AAC3B,mBAAW;AAAA,UACT,WAAW;AAAA,UACX,OAAO,OAAO,SACX,MAAM,SAAS,OAAY,IAAI;AAAA,QACpC;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA,IACA,MAAM,YACJ,cACA,MACsB;AACtB,YAAM,QAAQ,MAAM,QAAQ,SAAS,cAAc,IAAI;AACvD,aAAO,QAAQ;AAAA,QACb,MAAM,IAAI,OAAO,SAAS;AACxB,gBAAM,iBAAiB,WAAW,KAAK,SAAS;AAChD,cAAI,eAAgB,QAAO,cAAc,gBAAgB,KAAK,KAAK;AACnE,iBAAO,MAAM,IAAI,KAAK,SAAS,IAAI,KAAK,KAAK,KAAK,KAAK;AAAA,QACzD,CAAC;AAAA,MACH;AAAA,IACF;AAAA,IACA,MAAM,SACJ,cACA,MACkC;AAClC,UAAI,CAAC,OAAO,UAAU,IAAI,KAAK,OAAO,KAAK,OAAO;AAChD,cAAM,IAAI,WAAW,uCAAkC;AACzD,YAAM,WAAW,MAAM,SAAS,QAAQ;AAAA,QACtC,GAAG;AAAA,QACH,OAAO,aAAa;AAAA,MACtB,CAAC;AACD,YAAM,SAAS,WAAW,IAAI,SAAS,SAAS;AAChD,YAAM,OAAO,SAAS,MAAM;AAC5B,YAAM,QAAQ,SACV,MAAM,OAAO,SAAS,OAAO,IAAI,IACjC,SAAS,cAAc,eAAe,MAAM,QAAQ,IAAI,KAAK,KAAK,SAAS,OACzE,MAAM,KAAK,EAAE,QAAQ,KAAK,KAAK,KAAK,SAAS,IAAI,EAAE,GAAG,CAAC,GAAG,WAAW;AAAA,QACnE,GAAG,SAAS;AAAA,QACZ,MAAM,KAAK,MAAM,QAAQ,OAAO,QAAQ,KAAK,IAAI;AAAA,MACnD,EAAE,IACF,CAAC,SAAS,KAAK;AACrB,UAAI,CAAC,MAAM,UAAU,MAAM,SAAS;AAClC,cAAM,IAAI,WAAW,0CAAqC;AAC5D,aAAO,QAAQ,IAAI,MAAM,IAAI,CAAC,UAAU,SAAS,QAAQ,EAAE,GAAG,UAAU,MAAM,CAAC,CAAC,CAAC;AAAA,IACnF;AAAA,EACF;AACA,SAAO;AACT;","names":["createContext","useContext","useMemo","Component","createContext","useContext","useMemo"]}
|