@barefootjs/hono 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapter/hono-adapter.d.ts +141 -0
- package/dist/adapter/hono-adapter.d.ts.map +1 -0
- package/dist/adapter/index.d.ts +6 -0
- package/dist/adapter/index.d.ts.map +1 -0
- package/dist/adapter/index.js +632 -0
- package/dist/app.d.ts +131 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +139 -0
- package/dist/async.d.ts +15 -0
- package/dist/async.d.ts.map +1 -0
- package/dist/async.js +12 -0
- package/dist/build.d.ts +65 -0
- package/dist/build.d.ts.map +1 -0
- package/dist/build.js +785 -0
- package/dist/client-shim.d.ts +59 -0
- package/dist/client-shim.d.ts.map +1 -0
- package/dist/client-shim.js +90 -0
- package/dist/dev-worker.d.ts +25 -0
- package/dist/dev-worker.d.ts.map +1 -0
- package/dist/dev-worker.js +65 -0
- package/dist/dev.d.ts +36 -0
- package/dist/dev.d.ts.map +1 -0
- package/dist/dev.js +418 -0
- package/dist/dialog-context.d.ts +13 -0
- package/dist/dialog-context.d.ts.map +1 -0
- package/dist/dialog-context.js +10 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +632 -0
- package/dist/jsx/jsx-dev-runtime/index.d.ts +9 -0
- package/dist/jsx/jsx-dev-runtime/index.d.ts.map +1 -0
- package/dist/jsx/jsx-dev-runtime/index.js +6 -0
- package/dist/jsx/jsx-runtime/index.d.ts +32 -0
- package/dist/jsx/jsx-runtime/index.d.ts.map +1 -0
- package/dist/jsx/jsx-runtime/index.js +10 -0
- package/dist/portal-ssr.d.ts +22 -0
- package/dist/portal-ssr.d.ts.map +1 -0
- package/dist/portal-ssr.js +73 -0
- package/dist/portals.d.ts +26 -0
- package/dist/portals.d.ts.map +1 -0
- package/dist/portals.js +41 -0
- package/dist/preload.d.ts +56 -0
- package/dist/preload.d.ts.map +1 -0
- package/dist/preload.js +51 -0
- package/dist/scripts.d.ts +80 -0
- package/dist/scripts.d.ts.map +1 -0
- package/dist/scripts.js +198 -0
- package/dist/test-render.d.ts +28 -0
- package/dist/test-render.d.ts.map +1 -0
- package/dist/utils.d.ts +16 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +16 -0
- package/package.json +116 -0
- package/src/__tests__/async.test.tsx +106 -0
- package/src/__tests__/bfscripts-entry-roots.test.tsx +135 -0
- package/src/__tests__/build.test.ts +299 -0
- package/src/__tests__/dev.test.tsx +123 -0
- package/src/__tests__/hydration-props-type.test.ts +141 -0
- package/src/__tests__/manifest-scripts.test.ts +87 -0
- package/src/__tests__/scaffold.test.ts +209 -0
- package/src/__tests__/ssr-context-bridge.test.ts +110 -0
- package/src/__tests__/string-literal-css-var-prop.test.ts +84 -0
- package/src/__tests__/stub-deps-scripts.test.ts +183 -0
- package/src/adapter/hono-adapter.ts +1114 -0
- package/src/adapter/index.ts +6 -0
- package/src/app.ts +220 -0
- package/src/async.tsx +55 -0
- package/src/build.ts +230 -0
- package/src/client-shim.ts +164 -0
- package/src/dev-worker.ts +93 -0
- package/src/dev.tsx +146 -0
- package/src/dialog-context.tsx +44 -0
- package/src/index.ts +26 -0
- package/src/jsx/jsx-dev-runtime/index.ts +9 -0
- package/src/jsx/jsx-runtime/index.ts +40 -0
- package/src/portal-ssr.tsx +92 -0
- package/src/portals.tsx +98 -0
- package/src/preload.tsx +166 -0
- package/src/scripts.tsx +220 -0
- package/src/test-render.ts +143 -0
- package/src/utils.ts +26 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,632 @@
|
|
|
1
|
+
// src/adapter/hono-adapter.ts
|
|
2
|
+
import {
|
|
3
|
+
JsxAdapter,
|
|
4
|
+
isBooleanAttr,
|
|
5
|
+
rewriteImportsForTemplate,
|
|
6
|
+
emitIRNode,
|
|
7
|
+
emitAttrValue,
|
|
8
|
+
buildLoopChainExpr
|
|
9
|
+
} from "@barefootjs/jsx";
|
|
10
|
+
import { BF_SCOPE, BF_HOST, BF_AT, BF_ROOT, BF_PROPS } from "@barefootjs/shared";
|
|
11
|
+
function applyHonoLoopChain(loop) {
|
|
12
|
+
return buildLoopChainExpr({
|
|
13
|
+
base: loop.array,
|
|
14
|
+
sortComparator: loop.sortComparator,
|
|
15
|
+
filterPredicate: loop.filterPredicate,
|
|
16
|
+
chainOrder: loop.chainOrder
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
class HonoAdapter extends JsxAdapter {
|
|
21
|
+
name = "hono";
|
|
22
|
+
extension = ".tsx";
|
|
23
|
+
clientShimSource = "@barefootjs/hono/client-shim";
|
|
24
|
+
acceptsTemplateCall = () => true;
|
|
25
|
+
jsxConfig = { preserveTypes: true };
|
|
26
|
+
options;
|
|
27
|
+
isClientComponent = false;
|
|
28
|
+
hasClientInteractivity = false;
|
|
29
|
+
currentComponentHasProps = false;
|
|
30
|
+
rewriteRelativeImport;
|
|
31
|
+
loopKeyStack = [];
|
|
32
|
+
constructor(options = {}) {
|
|
33
|
+
super();
|
|
34
|
+
this.options = {
|
|
35
|
+
clientJsBasePath: options.clientJsBasePath ?? "/static/components/",
|
|
36
|
+
barefootJsPath: options.barefootJsPath ?? "/static/components/barefoot.js",
|
|
37
|
+
clientJsFilename: options.clientJsFilename
|
|
38
|
+
};
|
|
39
|
+
if (options.name)
|
|
40
|
+
this.name = options.name;
|
|
41
|
+
}
|
|
42
|
+
generate(ir, options) {
|
|
43
|
+
this.componentName = ir.metadata.componentName;
|
|
44
|
+
this.isClientComponent = ir.metadata.isClientComponent;
|
|
45
|
+
this.rewriteRelativeImport = options?.rewriteRelativeImport;
|
|
46
|
+
const component = this.generateComponent(ir);
|
|
47
|
+
const types = this.generateTypes(ir, component);
|
|
48
|
+
const componentCode = [types, component].filter(Boolean).join(`
|
|
49
|
+
`);
|
|
50
|
+
const imports = this.generateImports(ir, componentCode);
|
|
51
|
+
const moduleConstants = this.generateModuleLevelContextBindings(ir);
|
|
52
|
+
const defaultExport = ir.metadata.hasDefaultExport ? `
|
|
53
|
+
export default ${this.componentName}` : "";
|
|
54
|
+
const sections = {
|
|
55
|
+
imports,
|
|
56
|
+
types: types || "",
|
|
57
|
+
component,
|
|
58
|
+
defaultExport,
|
|
59
|
+
moduleConstants
|
|
60
|
+
};
|
|
61
|
+
const template = [imports, moduleConstants, types, component].filter(Boolean).join(`
|
|
62
|
+
|
|
63
|
+
`) + defaultExport;
|
|
64
|
+
const result = {
|
|
65
|
+
template,
|
|
66
|
+
sections,
|
|
67
|
+
types: types || undefined,
|
|
68
|
+
extension: this.extension
|
|
69
|
+
};
|
|
70
|
+
this.rewriteRelativeImport = undefined;
|
|
71
|
+
return result;
|
|
72
|
+
}
|
|
73
|
+
generateModuleLevelContextBindings(ir) {
|
|
74
|
+
const lines = [];
|
|
75
|
+
for (const c of ir.metadata.localConstants) {
|
|
76
|
+
if (!c.isModule)
|
|
77
|
+
continue;
|
|
78
|
+
if (c.isExported)
|
|
79
|
+
continue;
|
|
80
|
+
if (c.systemConstructKind !== "createContext")
|
|
81
|
+
continue;
|
|
82
|
+
if (!c.value)
|
|
83
|
+
continue;
|
|
84
|
+
const keyword = c.declarationKind ?? "const";
|
|
85
|
+
const value = this.jsxConfig.preserveTypes ? c.typedValue ?? c.value : c.value;
|
|
86
|
+
lines.push(`${keyword} ${c.name} = ${value}`);
|
|
87
|
+
}
|
|
88
|
+
return lines.join(`
|
|
89
|
+
`);
|
|
90
|
+
}
|
|
91
|
+
generateImports(ir, componentCode) {
|
|
92
|
+
const lines = [];
|
|
93
|
+
const utilImports = [];
|
|
94
|
+
for (const util of ["bfComment", "bfText", "bfTextEnd"]) {
|
|
95
|
+
if (new RegExp(`\\b${util}\\b`).test(componentCode)) {
|
|
96
|
+
utilImports.push(util);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (utilImports.length > 0) {
|
|
100
|
+
lines.push(`import { ${utilImports.join(", ")} } from '@barefootjs/hono/utils'`);
|
|
101
|
+
}
|
|
102
|
+
if (componentCode.includes("<Suspense")) {
|
|
103
|
+
lines.push(`import { Suspense } from 'hono/jsx/streaming'`);
|
|
104
|
+
}
|
|
105
|
+
const templateImports = rewriteImportsForTemplate(ir.metadata.templateImports, this.clientShimSource, this.rewriteRelativeImport);
|
|
106
|
+
for (const imp of templateImports) {
|
|
107
|
+
if (imp.specifiers.length === 0) {
|
|
108
|
+
if (!imp.isTypeOnly) {
|
|
109
|
+
lines.push(`import '${imp.source}'`);
|
|
110
|
+
}
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
if (imp.isTypeOnly) {
|
|
114
|
+
lines.push(`import type ${this.formatImportSpecifiers(imp.specifiers)} from '${imp.source}'`);
|
|
115
|
+
} else {
|
|
116
|
+
lines.push(`import ${this.formatImportSpecifiers(imp.specifiers)} from '${imp.source}'`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
if (/\bprovideContextSSR\(/.test(componentCode)) {
|
|
120
|
+
lines.push(`import { provideContextSSR } from '@barefootjs/hono/client-shim'`);
|
|
121
|
+
}
|
|
122
|
+
return lines.join(`
|
|
123
|
+
`);
|
|
124
|
+
}
|
|
125
|
+
generateTypes(ir, componentBody) {
|
|
126
|
+
const lines = [];
|
|
127
|
+
if (componentBody && ir.metadata.typeDefinitions.length > 0) {
|
|
128
|
+
const propsTypeName2 = this.getPropsTypeName(ir);
|
|
129
|
+
const seedText = [
|
|
130
|
+
componentBody,
|
|
131
|
+
propsTypeName2 && !ir.metadata.propsObjectName ? propsTypeName2 : "",
|
|
132
|
+
...ir.metadata.namedExports.filter((block) => block.source === null).flatMap((block) => block.specifiers.map((s) => s.name))
|
|
133
|
+
].filter(Boolean).join(`
|
|
134
|
+
`);
|
|
135
|
+
const included = new Set;
|
|
136
|
+
for (const typeDef of ir.metadata.typeDefinitions) {
|
|
137
|
+
if (new RegExp(`\\b${typeDef.name}\\b`).test(seedText)) {
|
|
138
|
+
included.add(typeDef.name);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
let changed = true;
|
|
142
|
+
while (changed) {
|
|
143
|
+
changed = false;
|
|
144
|
+
for (const typeDef of ir.metadata.typeDefinitions) {
|
|
145
|
+
if (included.has(typeDef.name))
|
|
146
|
+
continue;
|
|
147
|
+
for (const name of included) {
|
|
148
|
+
const includedDef = ir.metadata.typeDefinitions.find((t) => t.name === name);
|
|
149
|
+
if (includedDef && new RegExp(`\\b${typeDef.name}\\b`).test(includedDef.definition)) {
|
|
150
|
+
included.add(typeDef.name);
|
|
151
|
+
changed = true;
|
|
152
|
+
break;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
for (const typeDef of ir.metadata.typeDefinitions) {
|
|
158
|
+
if (included.has(typeDef.name))
|
|
159
|
+
lines.push(typeDef.definition);
|
|
160
|
+
}
|
|
161
|
+
} else {
|
|
162
|
+
for (const typeDef of ir.metadata.typeDefinitions) {
|
|
163
|
+
lines.push(typeDef.definition);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
const propsTypeName = this.getPropsTypeName(ir);
|
|
167
|
+
if (propsTypeName && !ir.metadata.propsObjectName) {
|
|
168
|
+
lines.push("");
|
|
169
|
+
lines.push(`type ${this.componentName}PropsWithHydration = ${propsTypeName} & {`);
|
|
170
|
+
lines.push(" __instanceId?: string");
|
|
171
|
+
lines.push(" __bfScope?: string");
|
|
172
|
+
lines.push(" __bfChild?: boolean");
|
|
173
|
+
lines.push(" __bfParentProps?: string");
|
|
174
|
+
lines.push(" __bfParent?: string");
|
|
175
|
+
lines.push(" __bfMount?: string");
|
|
176
|
+
lines.push(' "data-key"?: string | number');
|
|
177
|
+
lines.push("}");
|
|
178
|
+
}
|
|
179
|
+
return lines.length > 0 ? lines.join(`
|
|
180
|
+
`) : null;
|
|
181
|
+
}
|
|
182
|
+
getPropsTypeName(ir) {
|
|
183
|
+
if (ir.metadata.propsType?.raw) {
|
|
184
|
+
return ir.metadata.propsType.raw;
|
|
185
|
+
}
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
generateComponent(ir) {
|
|
189
|
+
const name = ir.metadata.componentName;
|
|
190
|
+
const propsTypeName = this.getPropsTypeName(ir);
|
|
191
|
+
const hasReactivePrimitives = ir.metadata.signals.length > 0 || ir.metadata.memos.length > 0 || ir.metadata.effects.length > 0 || ir.metadata.onMounts.length > 0;
|
|
192
|
+
if (hasReactivePrimitives && !ir.metadata.isClientComponent) {
|
|
193
|
+
throw new Error(`Component "${name}" has reactive primitives (signals, memos, effects, or onMounts) ` + `but is not marked as a client component. Add "use client" directive at the top of the file.`);
|
|
194
|
+
}
|
|
195
|
+
const needsClientInit = ir.metadata.clientAnalysis?.needsInit ?? false;
|
|
196
|
+
const hasClientInteractivity = ir.metadata.isClientComponent || needsClientInit;
|
|
197
|
+
this.hasClientInteractivity = hasClientInteractivity;
|
|
198
|
+
const propsObjectName = ir.metadata.propsObjectName;
|
|
199
|
+
let fullPropsDestructure;
|
|
200
|
+
let typeAnnotation;
|
|
201
|
+
let propsExtraction = null;
|
|
202
|
+
const HYDRATION_PROPS_TYPE = '{ __instanceId?: string; __bfScope?: string; __bfChild?: boolean; __bfParentProps?: string; __bfParent?: string; __bfMount?: string; "data-key"?: string | number }';
|
|
203
|
+
if (propsObjectName) {
|
|
204
|
+
fullPropsDestructure = `__allProps`;
|
|
205
|
+
typeAnnotation = propsTypeName ? `: ${propsTypeName} & ${HYDRATION_PROPS_TYPE}` : `: Record<string, unknown> & ${HYDRATION_PROPS_TYPE}`;
|
|
206
|
+
} else {
|
|
207
|
+
fullPropsDestructure = "";
|
|
208
|
+
typeAnnotation = propsTypeName ? `: ${name}PropsWithHydration` : `: ${HYDRATION_PROPS_TYPE}`;
|
|
209
|
+
}
|
|
210
|
+
const clientUsedProps = new Set(ir.metadata.clientAnalysis?.usedProps ?? []);
|
|
211
|
+
const needsInit = ir.metadata.clientAnalysis?.needsInit ?? false;
|
|
212
|
+
const propsToSerialize = ir.metadata.propsParams.filter((p) => {
|
|
213
|
+
return !p.name.startsWith("on") && !p.name.startsWith("__") && clientUsedProps.has(p.name);
|
|
214
|
+
});
|
|
215
|
+
const hasPropsToSerialize = propsToSerialize.length > 0 && hasClientInteractivity && needsInit;
|
|
216
|
+
const isIfStatement = ir.root.type === "if-statement";
|
|
217
|
+
const isRootComponent = ir.root.type === "component";
|
|
218
|
+
this.currentComponentHasProps = hasPropsToSerialize || hasClientInteractivity && isRootComponent;
|
|
219
|
+
let jsxBody = isIfStatement ? "" : this.renderNode(ir.root, {
|
|
220
|
+
isRootOfClientComponent: hasClientInteractivity && isRootComponent
|
|
221
|
+
});
|
|
222
|
+
if (!isIfStatement && hasClientInteractivity && isRootComponent) {
|
|
223
|
+
jsxBody = this.wrapWithScopeComment(jsxBody);
|
|
224
|
+
}
|
|
225
|
+
const ifCode = isIfStatement ? this.renderIfStatement(ir.root, { isRootOfClientComponent: true }) : "";
|
|
226
|
+
const fullBodyText = jsxBody + `
|
|
227
|
+
` + ifCode;
|
|
228
|
+
const signalInits = this.generateSignalInitializers(ir, fullBodyText);
|
|
229
|
+
const scopeIdLine = hasClientInteractivity ? `__instanceId` : `__bfScope || __instanceId`;
|
|
230
|
+
const bodyRefText = [
|
|
231
|
+
fullBodyText,
|
|
232
|
+
signalInits,
|
|
233
|
+
scopeIdLine,
|
|
234
|
+
hasPropsToSerialize || hasClientInteractivity && isRootComponent ? "__bfParentProps" : ""
|
|
235
|
+
].join(`
|
|
236
|
+
`);
|
|
237
|
+
const bfScopeAlias = /\b__bfScope\b/.test(bodyRefText) ? "__bfScope" : "__bfScope: _bfScope";
|
|
238
|
+
const bfChildAlias = /\b__bfChild\b/.test(bodyRefText) ? "__bfChild" : "__bfChild: _bfChild";
|
|
239
|
+
const bfParentPropsAlias = /\b__bfParentProps\b/.test(bodyRefText) ? "__bfParentProps" : "__bfParentProps: _bfParentProps";
|
|
240
|
+
const bfParentAlias = /\b__bfParent\b/.test(bodyRefText) ? "__bfParent" : "__bfParent: _bfParent";
|
|
241
|
+
const bfMountAlias = /\b__bfMount\b/.test(bodyRefText) ? "__bfMount" : "__bfMount: _bfMount";
|
|
242
|
+
const dataKeyAlias = /\b__dataKey\b/.test(bodyRefText) ? '"data-key": __dataKey' : '"data-key": _dataKey';
|
|
243
|
+
if (propsObjectName) {
|
|
244
|
+
propsExtraction = ` const { __instanceId, ${bfScopeAlias}, ${bfChildAlias}, ${bfParentPropsAlias}, ${bfParentAlias}, ${bfMountAlias}, ${dataKeyAlias}, ...${propsObjectName} } = __allProps`;
|
|
245
|
+
} else {
|
|
246
|
+
const hydrationProps = `__instanceId, ${bfScopeAlias}, ${bfChildAlias}, ${bfParentPropsAlias}, ${bfParentAlias}, ${bfMountAlias}, ${dataKeyAlias}`;
|
|
247
|
+
const parts = [];
|
|
248
|
+
const propsParams = ir.metadata.propsParams.map((p) => {
|
|
249
|
+
const paramName = p.name === "class" ? "className" : p.name;
|
|
250
|
+
return p.defaultValue ? `${paramName} = ${p.defaultValue}` : paramName;
|
|
251
|
+
}).join(", ");
|
|
252
|
+
if (propsParams) {
|
|
253
|
+
parts.push(propsParams);
|
|
254
|
+
}
|
|
255
|
+
parts.push(hydrationProps);
|
|
256
|
+
const restPropsName = ir.metadata.restPropsName;
|
|
257
|
+
if (restPropsName) {
|
|
258
|
+
parts.push(`...${restPropsName}`);
|
|
259
|
+
}
|
|
260
|
+
fullPropsDestructure = `{ ${parts.join(", ")} }`;
|
|
261
|
+
}
|
|
262
|
+
const lines = [];
|
|
263
|
+
const exportPrefix = ir.metadata.isExported === false ? "" : "export ";
|
|
264
|
+
lines.push(`${exportPrefix}function ${name}(${fullPropsDestructure}${typeAnnotation}) {`);
|
|
265
|
+
if (propsExtraction) {
|
|
266
|
+
lines.push(propsExtraction);
|
|
267
|
+
}
|
|
268
|
+
if (hasClientInteractivity) {
|
|
269
|
+
lines.push(` const __scopeId = __instanceId || \`${name}_\${Math.random().toString(36).slice(2, 8)}\``);
|
|
270
|
+
} else {
|
|
271
|
+
lines.push(` const __scopeId = __bfScope || __instanceId || \`${name}_\${Math.random().toString(36).slice(2, 8)}\``);
|
|
272
|
+
}
|
|
273
|
+
if (signalInits) {
|
|
274
|
+
lines.push(signalInits);
|
|
275
|
+
}
|
|
276
|
+
if (hasPropsToSerialize) {
|
|
277
|
+
lines.push("");
|
|
278
|
+
lines.push(` // Serialize props for client hydration`);
|
|
279
|
+
lines.push(` const __hydrateProps: Record<string, unknown> = {}`);
|
|
280
|
+
for (const p of propsToSerialize) {
|
|
281
|
+
const propAccess = propsObjectName ? `${propsObjectName}.${p.name}` : p.name;
|
|
282
|
+
lines.push(` if (typeof ${propAccess} !== 'function' && !(typeof ${propAccess} === 'object' && ${propAccess} !== null && 'isEscaped' in ${propAccess})) __hydrateProps['${p.name}'] = ${propAccess}`);
|
|
283
|
+
}
|
|
284
|
+
lines.push(` const __bfPropsJson = __bfParentProps || (Object.keys(__hydrateProps).length > 0 ? JSON.stringify(__hydrateProps) : undefined)`);
|
|
285
|
+
} else if (hasClientInteractivity && isRootComponent) {
|
|
286
|
+
lines.push("");
|
|
287
|
+
lines.push(` const __bfPropsJson = __bfParentProps`);
|
|
288
|
+
}
|
|
289
|
+
lines.push("");
|
|
290
|
+
if (isIfStatement) {
|
|
291
|
+
lines.push(ifCode);
|
|
292
|
+
lines.push(`}`);
|
|
293
|
+
return lines.join(`
|
|
294
|
+
`);
|
|
295
|
+
}
|
|
296
|
+
lines.push(` return (`);
|
|
297
|
+
lines.push(` ${jsxBody}`);
|
|
298
|
+
lines.push(` )`);
|
|
299
|
+
lines.push(`}`);
|
|
300
|
+
return lines.join(`
|
|
301
|
+
`);
|
|
302
|
+
}
|
|
303
|
+
renderNode(node, ctx) {
|
|
304
|
+
return emitIRNode(node, this, ctx ?? {});
|
|
305
|
+
}
|
|
306
|
+
emitElement(node, ctx, _emit) {
|
|
307
|
+
return this.renderElement(node, ctx);
|
|
308
|
+
}
|
|
309
|
+
emitText(node) {
|
|
310
|
+
return this.renderText(node);
|
|
311
|
+
}
|
|
312
|
+
emitExpression(node) {
|
|
313
|
+
return this.renderExpression(node);
|
|
314
|
+
}
|
|
315
|
+
emitConditional(node, _ctx, _emit) {
|
|
316
|
+
return this.renderConditional(node);
|
|
317
|
+
}
|
|
318
|
+
emitLoop(node, _ctx, _emit) {
|
|
319
|
+
return this.renderLoop(node);
|
|
320
|
+
}
|
|
321
|
+
emitComponent(node, ctx, _emit) {
|
|
322
|
+
return this.renderComponent(node, ctx);
|
|
323
|
+
}
|
|
324
|
+
emitFragment(node, _ctx, _emit) {
|
|
325
|
+
return this.renderFragment(node);
|
|
326
|
+
}
|
|
327
|
+
emitSlot(_node) {
|
|
328
|
+
return "{children}";
|
|
329
|
+
}
|
|
330
|
+
emitIfStatement(_node, _ctx, _emit) {
|
|
331
|
+
return "";
|
|
332
|
+
}
|
|
333
|
+
emitProvider(node, _ctx, _emit) {
|
|
334
|
+
const children = this.renderChildren(node.children);
|
|
335
|
+
const valueExpr = (() => {
|
|
336
|
+
const v = node.valueProp.value;
|
|
337
|
+
switch (v.kind) {
|
|
338
|
+
case "literal":
|
|
339
|
+
return JSON.stringify(v.value);
|
|
340
|
+
case "expression":
|
|
341
|
+
case "spread":
|
|
342
|
+
return v.expr;
|
|
343
|
+
case "template":
|
|
344
|
+
return this.renderTemplateLiteralParts(v.parts);
|
|
345
|
+
case "boolean-attr":
|
|
346
|
+
case "boolean-shorthand":
|
|
347
|
+
return "true";
|
|
348
|
+
case "jsx-children":
|
|
349
|
+
return "undefined";
|
|
350
|
+
}
|
|
351
|
+
})();
|
|
352
|
+
return `<>{provideContextSSR(${node.contextName}, ${valueExpr}, <>${children}</>)}</>`;
|
|
353
|
+
}
|
|
354
|
+
emitAsync(node, _ctx, _emit) {
|
|
355
|
+
return this.renderAsync(node);
|
|
356
|
+
}
|
|
357
|
+
renderElement(element, ctx) {
|
|
358
|
+
const tag = element.tag;
|
|
359
|
+
const attrs = this.renderAttributes(element);
|
|
360
|
+
const children = this.renderChildren(element.children);
|
|
361
|
+
let hydrationAttrs = "";
|
|
362
|
+
if (element.needsScope) {
|
|
363
|
+
hydrationAttrs += ` ${BF_SCOPE}={__scopeId}`;
|
|
364
|
+
hydrationAttrs += ` {...(__bfParent ? { "${BF_HOST}": __bfParent } : {})}`;
|
|
365
|
+
hydrationAttrs += ` {...(__bfMount ? { "${BF_AT}": __bfMount } : {})}`;
|
|
366
|
+
hydrationAttrs += ` {...(!__bfChild ? { "${BF_ROOT}": "" } : {})}`;
|
|
367
|
+
if (this.currentComponentHasProps) {
|
|
368
|
+
hydrationAttrs += ` {...(!__bfChild && __bfPropsJson ? { "${BF_PROPS}": __bfPropsJson } : {})}`;
|
|
369
|
+
}
|
|
370
|
+
hydrationAttrs += ' {...(__dataKey !== undefined ? { "data-key": __dataKey } : {})}';
|
|
371
|
+
}
|
|
372
|
+
if (ctx?.isLoopItemRoot && this.loopKeyStack.length > 0) {
|
|
373
|
+
const loop = this.loopKeyStack[this.loopKeyStack.length - 1];
|
|
374
|
+
if (loop.key) {
|
|
375
|
+
const keyAttrName = this.loopKeyStack.length === 1 ? "data-key" : `data-key-${this.loopKeyStack.length - 1}`;
|
|
376
|
+
hydrationAttrs += ` ${keyAttrName}={String(${loop.key})}`;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
if (element.slotId) {
|
|
380
|
+
hydrationAttrs += ` bf="${element.slotId}"`;
|
|
381
|
+
}
|
|
382
|
+
if (children) {
|
|
383
|
+
return `<${tag}${attrs}${hydrationAttrs}>${children}</${tag}>`;
|
|
384
|
+
} else {
|
|
385
|
+
return `<${tag}${attrs}${hydrationAttrs} />`;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
renderText(text) {
|
|
389
|
+
return text.value;
|
|
390
|
+
}
|
|
391
|
+
renderExpression(expr) {
|
|
392
|
+
if (expr.expr === "null" || expr.expr === "undefined") {
|
|
393
|
+
return "null";
|
|
394
|
+
}
|
|
395
|
+
if (expr.clientOnly && expr.slotId) {
|
|
396
|
+
return `{bfComment("client:${expr.slotId}")}`;
|
|
397
|
+
}
|
|
398
|
+
if (expr.slotId) {
|
|
399
|
+
return `{bfText("${expr.slotId}")}{${expr.expr}}{bfTextEnd()}`;
|
|
400
|
+
}
|
|
401
|
+
return `{${expr.expr}}`;
|
|
402
|
+
}
|
|
403
|
+
renderConditional(cond) {
|
|
404
|
+
if (cond.clientOnly && cond.slotId) {
|
|
405
|
+
return `{bfComment("cond-start:${cond.slotId}")}{bfComment("cond-end:${cond.slotId}")}`;
|
|
406
|
+
}
|
|
407
|
+
const whenTrue = this.renderNodeRaw(cond.whenTrue);
|
|
408
|
+
let whenFalse = this.renderNodeRaw(cond.whenFalse);
|
|
409
|
+
if (!whenFalse || whenFalse === "" || whenFalse === "null") {
|
|
410
|
+
whenFalse = "null";
|
|
411
|
+
}
|
|
412
|
+
if (cond.slotId) {
|
|
413
|
+
const trueWithMarker = this.wrapWithCondMarker(cond.whenTrue, whenTrue, cond.slotId);
|
|
414
|
+
const falseWithMarker = cond.whenFalse.type === "expression" && cond.whenFalse.expr === "null" ? `<>{bfComment("cond-start:${cond.slotId}")}{bfComment("cond-end:${cond.slotId}")}</>` : this.wrapWithCondMarker(cond.whenFalse, whenFalse, cond.slotId);
|
|
415
|
+
return `{${cond.condition} ? ${trueWithMarker} : ${falseWithMarker}}`;
|
|
416
|
+
}
|
|
417
|
+
return `{${cond.condition} ? ${whenTrue} : ${whenFalse}}`;
|
|
418
|
+
}
|
|
419
|
+
wrapWithCondMarker(node, content, condId) {
|
|
420
|
+
if (node.type === "component") {
|
|
421
|
+
return `<>{bfComment("cond-start:${condId}")}${content}{bfComment("cond-end:${condId}")}</>`;
|
|
422
|
+
}
|
|
423
|
+
if (content.startsWith("<") && node.type !== "fragment") {
|
|
424
|
+
const match = content.match(/^<(\w+)/);
|
|
425
|
+
if (match) {
|
|
426
|
+
return content.replace(`<${match[1]}`, `<${match[1]} bf-c="${condId}"`);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
if (node.type === "expression") {
|
|
430
|
+
return `<>{bfComment("cond-start:${condId}")}{${content}}{bfComment("cond-end:${condId}")}</>`;
|
|
431
|
+
}
|
|
432
|
+
return `<>{bfComment("cond-start:${condId}")}${content}{bfComment("cond-end:${condId}")}</>`;
|
|
433
|
+
}
|
|
434
|
+
renderLoop(loop) {
|
|
435
|
+
if (loop.clientOnly) {
|
|
436
|
+
return `{bfComment('loop:${loop.markerId}')}{bfComment('/loop:${loop.markerId}')}`;
|
|
437
|
+
}
|
|
438
|
+
const paramAnnotation = loop.paramType ? `: ${loop.paramType}` : "";
|
|
439
|
+
const indexAnnotation = loop.indexType ? `: ${loop.indexType}` : "";
|
|
440
|
+
const indexParam = loop.index ? `, ${loop.index}${indexAnnotation}` : "";
|
|
441
|
+
this.loopKeyStack.push({ key: loop.key, param: loop.param });
|
|
442
|
+
const children = this.renderChildrenInLoop(loop.children);
|
|
443
|
+
this.loopKeyStack.pop();
|
|
444
|
+
let mapExpr;
|
|
445
|
+
const preamble = loop.typedMapPreamble ?? loop.mapPreamble;
|
|
446
|
+
let safeChildren = children.startsWith("{") ? `<>${children}</>` : children;
|
|
447
|
+
if (loop.bodyIsMultiRoot) {
|
|
448
|
+
safeChildren = `<>{bfComment('bf-loop-i')}${children}</>`;
|
|
449
|
+
}
|
|
450
|
+
const chainedArray = applyHonoLoopChain(loop);
|
|
451
|
+
const iterMethod = loop.method ?? "map";
|
|
452
|
+
if (loop.flatMapCallback) {
|
|
453
|
+
mapExpr = `{${chainedArray}.flatMap(${loop.flatMapCallback.params} => ${loop.flatMapCallback.rawBody})}`;
|
|
454
|
+
} else if (preamble) {
|
|
455
|
+
mapExpr = `{${chainedArray}.${iterMethod}((${loop.param}${paramAnnotation}${indexParam}) => { ${preamble} return ${safeChildren} })}`;
|
|
456
|
+
} else {
|
|
457
|
+
mapExpr = `{${chainedArray}.${iterMethod}((${loop.param}${paramAnnotation}${indexParam}) => ${safeChildren})}`;
|
|
458
|
+
}
|
|
459
|
+
return `{bfComment('loop:${loop.markerId}')}${mapExpr}{bfComment('/loop:${loop.markerId}')}`;
|
|
460
|
+
}
|
|
461
|
+
renderChildrenInLoop(children) {
|
|
462
|
+
return children.map((child) => this.renderNode(child, { isInsideLoop: true, isLoopItemRoot: true })).join("");
|
|
463
|
+
}
|
|
464
|
+
renderIfStatement(ifStmt, ctx) {
|
|
465
|
+
const lines = [];
|
|
466
|
+
for (const v of ifStmt.scopeVariables) {
|
|
467
|
+
const init = this.jsxConfig.preserveTypes && v.typedInitializer || v.initializer;
|
|
468
|
+
lines.push(` const ${v.name} = ${init}`);
|
|
469
|
+
}
|
|
470
|
+
const consequent = this.renderNode(ifStmt.consequent, ctx);
|
|
471
|
+
lines.unshift(` if (${ifStmt.condition}) {`);
|
|
472
|
+
lines.push(` return (`);
|
|
473
|
+
lines.push(` ${consequent}`);
|
|
474
|
+
lines.push(` )`);
|
|
475
|
+
lines.push(` }`);
|
|
476
|
+
if (ifStmt.alternate) {
|
|
477
|
+
if (ifStmt.alternate.type === "if-statement") {
|
|
478
|
+
const elseIfCode = this.renderIfStatement(ifStmt.alternate, ctx);
|
|
479
|
+
lines.push(elseIfCode.replace(/^\s*if/, " else if"));
|
|
480
|
+
} else {
|
|
481
|
+
const alternate = this.renderNode(ifStmt.alternate, ctx);
|
|
482
|
+
lines.push(` return (`);
|
|
483
|
+
lines.push(` ${alternate}`);
|
|
484
|
+
lines.push(` )`);
|
|
485
|
+
}
|
|
486
|
+
} else {
|
|
487
|
+
lines.push(` return null`);
|
|
488
|
+
}
|
|
489
|
+
return lines.join(`
|
|
490
|
+
`);
|
|
491
|
+
}
|
|
492
|
+
renderAsync(node) {
|
|
493
|
+
const fallback = this.renderNode(node.fallback);
|
|
494
|
+
const children = this.renderChildren(node.children);
|
|
495
|
+
return `<Suspense fallback={<>${fallback}</>}>${children}</Suspense>`;
|
|
496
|
+
}
|
|
497
|
+
renderComponent(comp, ctx) {
|
|
498
|
+
const props = this.renderComponentProps(comp);
|
|
499
|
+
const children = this.renderChildren(comp.children);
|
|
500
|
+
let scopeAttr;
|
|
501
|
+
const bfChildAttr = comp.slotId && this.hasClientInteractivity ? " __bfChild={true}" : "";
|
|
502
|
+
const bfMountAttr = comp.slotId ? ` __bfParent={__scopeId} __bfMount={'${comp.slotId}'}` : "";
|
|
503
|
+
if (ctx?.isRootOfClientComponent) {
|
|
504
|
+
const propsPassAttr = this.currentComponentHasProps ? " __bfParentProps={__bfPropsJson}" : "";
|
|
505
|
+
if (comp.slotId) {
|
|
506
|
+
scopeAttr = ` __instanceId={\`\${__scopeId}_${comp.slotId}\`}${propsPassAttr}${bfMountAttr}`;
|
|
507
|
+
} else {
|
|
508
|
+
scopeAttr = ` __instanceId={__scopeId}${propsPassAttr}`;
|
|
509
|
+
}
|
|
510
|
+
scopeAttr += ` ${BF_SCOPE}={__scopeId}`;
|
|
511
|
+
} else if (ctx?.isInsideLoop) {
|
|
512
|
+
if (comp.slotId) {
|
|
513
|
+
scopeAttr = ` __bfScope={\`\${__scopeId}_${comp.slotId}\`}${bfChildAttr}${bfMountAttr}`;
|
|
514
|
+
} else {
|
|
515
|
+
scopeAttr = " __bfScope={__scopeId}";
|
|
516
|
+
}
|
|
517
|
+
} else if (comp.slotId) {
|
|
518
|
+
scopeAttr = ` __instanceId={\`\${__scopeId}_${comp.slotId}\`}${bfChildAttr}${bfMountAttr}`;
|
|
519
|
+
} else {
|
|
520
|
+
scopeAttr = " __instanceId={__scopeId}";
|
|
521
|
+
}
|
|
522
|
+
if (children) {
|
|
523
|
+
return `<${comp.name}${props}${scopeAttr}>${children}</${comp.name}>`;
|
|
524
|
+
} else {
|
|
525
|
+
return `<${comp.name}${props}${scopeAttr} />`;
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
renderFragment(fragment) {
|
|
529
|
+
const children = this.renderChildren(fragment.children);
|
|
530
|
+
if (fragment.needsScopeComment) {
|
|
531
|
+
return this.wrapWithScopeComment(children);
|
|
532
|
+
}
|
|
533
|
+
return `<>${children}</>`;
|
|
534
|
+
}
|
|
535
|
+
wrapWithScopeComment(body) {
|
|
536
|
+
const hostExpr = '${__bfParent ? `|h=${__bfParent}|m=${__bfMount}` : ""}';
|
|
537
|
+
const propsExpr = this.currentComponentHasProps ? '${__bfPropsJson ? `|${__bfPropsJson}` : ""}' : "";
|
|
538
|
+
return `<>{bfComment(\`scope:\${__scopeId}${hostExpr}${propsExpr}\`)}${body}</>`;
|
|
539
|
+
}
|
|
540
|
+
elementAttrEmitter = {
|
|
541
|
+
emitLiteral: (value, name) => `${name}="${value.value}"`,
|
|
542
|
+
emitExpression: (value, name) => {
|
|
543
|
+
if (isBooleanAttr(name) || value.presenceOrUndefined) {
|
|
544
|
+
return `${name}={(${value.expr}) || undefined}`;
|
|
545
|
+
}
|
|
546
|
+
return `${name}={${value.expr}}`;
|
|
547
|
+
},
|
|
548
|
+
emitBooleanAttr: (_value, name) => name,
|
|
549
|
+
emitBooleanShorthand: () => "",
|
|
550
|
+
emitTemplate: (value, name) => `${name}={${this.renderTemplateLiteralParts(value.parts)}}`,
|
|
551
|
+
emitSpread: (value) => `{...${value.expr}}`,
|
|
552
|
+
emitJsxChildren: () => ""
|
|
553
|
+
};
|
|
554
|
+
componentPropEmitter = {
|
|
555
|
+
emitLiteral: (value, name) => `${name}="${value.value}"`,
|
|
556
|
+
emitExpression: (value, name) => `${name}={${value.expr}}`,
|
|
557
|
+
emitBooleanAttr: (_value, name) => name,
|
|
558
|
+
emitBooleanShorthand: (_value, name) => name,
|
|
559
|
+
emitTemplate: (value, name) => `${name}={${this.renderTemplateLiteralParts(value.parts)}}`,
|
|
560
|
+
emitSpread: (value) => `{...${value.expr}}`,
|
|
561
|
+
emitJsxChildren: (value, name) => {
|
|
562
|
+
const rendered = value.children.map((c) => this.renderNode(c)).join("");
|
|
563
|
+
return `${name}={<>${rendered}</>}`;
|
|
564
|
+
}
|
|
565
|
+
};
|
|
566
|
+
renderAttributes(element) {
|
|
567
|
+
const parts = [];
|
|
568
|
+
for (const attr of element.attrs) {
|
|
569
|
+
const lowered = emitAttrValue(attr.value, this.elementAttrEmitter, attr.name);
|
|
570
|
+
if (lowered)
|
|
571
|
+
parts.push(lowered);
|
|
572
|
+
}
|
|
573
|
+
for (const event of element.events) {
|
|
574
|
+
const handlerName = event.originalAttr ?? `on${event.name.charAt(0).toUpperCase()}${event.name.slice(1)}`;
|
|
575
|
+
parts.push(`${handlerName}={() => {}}`);
|
|
576
|
+
}
|
|
577
|
+
return parts.length > 0 ? " " + parts.join(" ") : "";
|
|
578
|
+
}
|
|
579
|
+
renderComponentProps(comp) {
|
|
580
|
+
const parts = [];
|
|
581
|
+
let keyValue = null;
|
|
582
|
+
for (const prop of comp.props) {
|
|
583
|
+
if (prop.name === "key") {
|
|
584
|
+
keyValue = this.attrValueToJsExpr(prop.value);
|
|
585
|
+
continue;
|
|
586
|
+
}
|
|
587
|
+
const lowered = emitAttrValue(prop.value, this.componentPropEmitter, prop.name);
|
|
588
|
+
if (lowered)
|
|
589
|
+
parts.push(lowered);
|
|
590
|
+
}
|
|
591
|
+
if (keyValue) {
|
|
592
|
+
parts.push(`data-key={${keyValue}}`);
|
|
593
|
+
}
|
|
594
|
+
return parts.length > 0 ? " " + parts.join(" ") : "";
|
|
595
|
+
}
|
|
596
|
+
attrValueToJsExpr(value) {
|
|
597
|
+
switch (value.kind) {
|
|
598
|
+
case "literal":
|
|
599
|
+
return JSON.stringify(value.value);
|
|
600
|
+
case "expression":
|
|
601
|
+
case "spread":
|
|
602
|
+
return value.expr;
|
|
603
|
+
case "template":
|
|
604
|
+
return this.renderTemplateLiteralParts(value.parts);
|
|
605
|
+
case "boolean-shorthand":
|
|
606
|
+
case "boolean-attr":
|
|
607
|
+
return "true";
|
|
608
|
+
case "jsx-children":
|
|
609
|
+
return "undefined";
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
renderTemplateLiteralParts(parts) {
|
|
613
|
+
let output = "`";
|
|
614
|
+
for (const part of parts) {
|
|
615
|
+
if (part.type === "string") {
|
|
616
|
+
output += part.value;
|
|
617
|
+
} else if (part.type === "ternary") {
|
|
618
|
+
output += `\${${part.condition} ? '${part.whenTrue}' : '${part.whenFalse}'}`;
|
|
619
|
+
} else if (part.type === "lookup") {
|
|
620
|
+
const obj = "{" + Object.entries(part.cases).map(([k, v]) => `${JSON.stringify(k)}: ${JSON.stringify(v)}`).join(", ") + "}";
|
|
621
|
+
output += `\${(${obj})[${part.key}]}`;
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
output += "`";
|
|
625
|
+
return output;
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
var honoAdapter = new HonoAdapter;
|
|
629
|
+
export {
|
|
630
|
+
honoAdapter,
|
|
631
|
+
HonoAdapter
|
|
632
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BarefootJS Hono JSX Extension - Development Runtime
|
|
3
|
+
*
|
|
4
|
+
* Re-exports `jsxDEV` / `Fragment` from hono/jsx and surfaces the same
|
|
5
|
+
* JSX namespace as the production runtime so dev builds see identical types.
|
|
6
|
+
*/
|
|
7
|
+
export { jsxDEV, Fragment } from 'hono/jsx/jsx-dev-runtime';
|
|
8
|
+
export type { JSX } from '../jsx-runtime';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/jsx/jsx-dev-runtime/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AAC3D,YAAY,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAA"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BarefootJS Hono JSX Extension
|
|
3
|
+
*
|
|
4
|
+
* Combines hono/jsx runtime with @barefootjs/jsx type definitions.
|
|
5
|
+
* - Runtime functions from hono/jsx
|
|
6
|
+
* - Typed event handlers and IntrinsicElements from @barefootjs/jsx
|
|
7
|
+
* - JSX.Element from hono/jsx (for Suspense/streaming support)
|
|
8
|
+
*
|
|
9
|
+
* Usage in tsconfig.json:
|
|
10
|
+
* "jsxImportSource": "@barefootjs/hono/jsx"
|
|
11
|
+
*/
|
|
12
|
+
export { jsx, jsxs, Fragment, jsxAttr, jsxEscape, jsxTemplate } from 'hono/jsx/jsx-runtime';
|
|
13
|
+
import type { JSX as BaseJSX } from '@barefootjs/jsx/jsx-runtime';
|
|
14
|
+
export declare namespace JSX {
|
|
15
|
+
type Element = import('hono/jsx/jsx-runtime').JSX.Element;
|
|
16
|
+
type IntrinsicElements = BaseJSX.IntrinsicElements;
|
|
17
|
+
type IntrinsicAttributes = BaseJSX.IntrinsicAttributes;
|
|
18
|
+
type ElementChildrenAttribute = BaseJSX.ElementChildrenAttribute;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* BarefootJS compiler built-in: streaming async boundary.
|
|
22
|
+
*
|
|
23
|
+
* The compiler intercepts `<Async fallback={...}>` in JSX source and emits it
|
|
24
|
+
* as a `<Suspense>` node in the Hono adapter output (IRAsync → renderAsync).
|
|
25
|
+
* This declaration provides TypeScript types for source files; no runtime
|
|
26
|
+
* implementation is needed because the compiler replaces it before execution.
|
|
27
|
+
*/
|
|
28
|
+
export declare function Async(props: {
|
|
29
|
+
fallback: JSX.Element;
|
|
30
|
+
children: JSX.Element | JSX.Element[] | null | undefined;
|
|
31
|
+
}): JSX.Element;
|
|
32
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/jsx/jsx-runtime/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAG3F,OAAO,KAAK,EAAE,GAAG,IAAI,OAAO,EAAE,MAAM,6BAA6B,CAAA;AAEjE,MAAM,CAAC,OAAO,WAAW,GAAG,CAAC,CAAC;IAE5B,KAAK,OAAO,GAAG,OAAO,sBAAsB,EAAE,GAAG,CAAC,OAAO,CAAA;IAGzD,KAAK,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAA;IAClD,KAAK,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,CAAA;IACtD,KAAK,wBAAwB,GAAG,OAAO,CAAC,wBAAwB,CAAA;CACjE;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,OAAO,UAAU,KAAK,CAAC,KAAK,EAAE;IACnC,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAA;IACrB,QAAQ,EAAE,GAAG,CAAC,OAAO,GAAG,GAAG,CAAC,OAAO,EAAE,GAAG,IAAI,GAAG,SAAS,CAAA;CACzD,GAAG,GAAG,CAAC,OAAO,CAAA"}
|