@pyreon/compiler 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/LICENSE +21 -0
- package/README.md +67 -0
- package/lib/analysis/index.js.html +5406 -0
- package/lib/index.js +547 -0
- package/lib/index.js.map +1 -0
- package/lib/types/index.d.ts +537 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/index2.d.ts +57 -0
- package/lib/types/index2.d.ts.map +1 -0
- package/package.json +43 -0
- package/src/index.ts +4 -0
- package/src/jsx.ts +772 -0
- package/src/tests/jsx.test.ts +1009 -0
|
@@ -0,0 +1,537 @@
|
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
|
|
3
|
+
//#region src/jsx.ts
|
|
4
|
+
/**
|
|
5
|
+
* JSX transform — wraps dynamic JSX expressions in `() =>` so the Pyreon runtime
|
|
6
|
+
* receives reactive getters instead of eagerly-evaluated snapshot values.
|
|
7
|
+
*
|
|
8
|
+
* Rules:
|
|
9
|
+
* - `<div>{expr}</div>` → `<div>{() => expr}</div>` (child)
|
|
10
|
+
* - `<div class={expr}>` → `<div class={() => expr}>` (prop)
|
|
11
|
+
* - `<button onClick={fn}>` → unchanged (event handler)
|
|
12
|
+
* - `<div>{() => expr}</div>` → unchanged (already wrapped)
|
|
13
|
+
* - `<div>{"literal"}</div>` → unchanged (static)
|
|
14
|
+
*
|
|
15
|
+
* Static VNode hoisting:
|
|
16
|
+
* - Fully static JSX in expression containers is hoisted to module scope:
|
|
17
|
+
* `{<span>Hello</span>}` → `const _$h0 = <span>Hello</span>` + `{_$h0}`
|
|
18
|
+
* - Hoisted nodes are created ONCE at module initialisation, not per-instance.
|
|
19
|
+
* - A JSX node is static if: all props are string literals / booleans / static
|
|
20
|
+
* values, and all children are text nodes or other static JSX nodes.
|
|
21
|
+
*
|
|
22
|
+
* Template emission:
|
|
23
|
+
* - JSX element trees with ≥ 2 DOM elements (no components, no spread attrs)
|
|
24
|
+
* are compiled to `_tpl(html, bindFn)` calls instead of nested `h()` calls.
|
|
25
|
+
* - The HTML string is parsed once via <template>.innerHTML, then cloneNode(true)
|
|
26
|
+
* for each instance (~5-10x faster than sequential createElement calls).
|
|
27
|
+
* - Static attributes are baked into the HTML string; dynamic attributes and
|
|
28
|
+
* text content use renderEffect in the bind function.
|
|
29
|
+
*
|
|
30
|
+
* Implementation: TypeScript parser for positions + magic-string replacements.
|
|
31
|
+
* No extra runtime dependencies — `typescript` is already in devDependencies.
|
|
32
|
+
*
|
|
33
|
+
* Known limitation (v0): expressions inside *nested* JSX within a child
|
|
34
|
+
* expression container are not individually wrapped. They are still reactive
|
|
35
|
+
* because the outer wrapper re-evaluates the whole subtree, just at a coarser
|
|
36
|
+
* granularity. Fine-grained nested wrapping is planned for a future pass.
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
function transformJSX(code, filename = "input.tsx") {
|
|
40
|
+
const scriptKind = filename.endsWith(".tsx") || filename.endsWith(".jsx") ? ts.ScriptKind.TSX : ts.ScriptKind.TSX;
|
|
41
|
+
const sf = ts.createSourceFile(filename, code, ts.ScriptTarget.ESNext, true, scriptKind);
|
|
42
|
+
const replacements = [];
|
|
43
|
+
const warnings = [];
|
|
44
|
+
function warn(node, message, warnCode) {
|
|
45
|
+
const {
|
|
46
|
+
line,
|
|
47
|
+
character
|
|
48
|
+
} = sf.getLineAndCharacterOfPosition(node.getStart(sf));
|
|
49
|
+
warnings.push({
|
|
50
|
+
message,
|
|
51
|
+
line: line + 1,
|
|
52
|
+
column: character,
|
|
53
|
+
code: warnCode
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
const hoists = [];
|
|
57
|
+
let hoistIdx = 0;
|
|
58
|
+
let needsTplImport = false;
|
|
59
|
+
/**
|
|
60
|
+
* If `node` is a fully-static JSX element/fragment, register a module-scope
|
|
61
|
+
* hoist for it and return the generated variable name. Otherwise return null.
|
|
62
|
+
*/
|
|
63
|
+
function maybeHoist(node) {
|
|
64
|
+
if ((ts.isJsxElement(node) || ts.isJsxSelfClosingElement(node) || ts.isJsxFragment(node)) && isStaticJSXNode(node)) {
|
|
65
|
+
const name = `_$h${hoistIdx++}`;
|
|
66
|
+
const text = code.slice(node.getStart(sf), node.getEnd());
|
|
67
|
+
hoists.push({
|
|
68
|
+
name,
|
|
69
|
+
text
|
|
70
|
+
});
|
|
71
|
+
return name;
|
|
72
|
+
}
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
function wrap(expr) {
|
|
76
|
+
const start = expr.getStart(sf);
|
|
77
|
+
const end = expr.getEnd();
|
|
78
|
+
replacements.push({
|
|
79
|
+
start,
|
|
80
|
+
end,
|
|
81
|
+
text: `() => ${code.slice(start, end)}`
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
/** Try to hoist or wrap an expression, pushing a replacement if needed. */
|
|
85
|
+
function hoistOrWrap(expr) {
|
|
86
|
+
const hoistName = maybeHoist(expr);
|
|
87
|
+
if (hoistName) replacements.push({
|
|
88
|
+
start: expr.getStart(sf),
|
|
89
|
+
end: expr.getEnd(),
|
|
90
|
+
text: hoistName
|
|
91
|
+
});else if (shouldWrap(expr)) wrap(expr);
|
|
92
|
+
}
|
|
93
|
+
/** Try to emit a template for a JsxElement. Returns true if handled. */
|
|
94
|
+
function tryTemplateEmit(node) {
|
|
95
|
+
if (templateElementCount(node) < 1) return false;
|
|
96
|
+
const tplCall = buildTemplateCall(node);
|
|
97
|
+
if (!tplCall) return false;
|
|
98
|
+
const start = node.getStart(sf);
|
|
99
|
+
const end = node.getEnd();
|
|
100
|
+
const parent = node.parent;
|
|
101
|
+
const needsBraces = parent && (ts.isJsxElement(parent) || ts.isJsxFragment(parent));
|
|
102
|
+
replacements.push({
|
|
103
|
+
start,
|
|
104
|
+
end,
|
|
105
|
+
text: needsBraces ? `{${tplCall}}` : tplCall
|
|
106
|
+
});
|
|
107
|
+
needsTplImport = true;
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
/** Emit warnings for common JSX mistakes (e.g. <For> without by). */
|
|
111
|
+
function checkForWarnings(node) {
|
|
112
|
+
const opening = ts.isJsxElement(node) ? node.openingElement : node;
|
|
113
|
+
if ((ts.isIdentifier(opening.tagName) ? opening.tagName.text : "") !== "For") return;
|
|
114
|
+
if (!opening.attributes.properties.some(p => ts.isJsxAttribute(p) && ts.isIdentifier(p.name) && p.name.text === "by")) warn(opening.tagName, `<For> without a "by" prop will use index-based diffing, which is slower and may cause bugs with stateful children. Add by={(item) => item.id} for efficient keyed reconciliation.`, "missing-key-on-for");
|
|
115
|
+
}
|
|
116
|
+
/** Handle a JSX attribute node — wrap or hoist its value if needed. */
|
|
117
|
+
function handleJsxAttribute(node) {
|
|
118
|
+
const name = ts.isIdentifier(node.name) ? node.name.text : "";
|
|
119
|
+
const openingEl = node.parent.parent;
|
|
120
|
+
const tagName = ts.isIdentifier(openingEl.tagName) ? openingEl.tagName.text : "";
|
|
121
|
+
if (tagName.length > 0 && tagName.charAt(0) !== tagName.charAt(0).toLowerCase()) return;
|
|
122
|
+
if (SKIP_PROPS.has(name) || EVENT_RE.test(name)) return;
|
|
123
|
+
if (!node.initializer || !ts.isJsxExpression(node.initializer)) return;
|
|
124
|
+
const expr = node.initializer.expression;
|
|
125
|
+
if (expr) hoistOrWrap(expr);
|
|
126
|
+
}
|
|
127
|
+
/** Handle a JSX expression in child position — wrap or hoist. */
|
|
128
|
+
function handleJsxExpression(node) {
|
|
129
|
+
const expr = node.expression;
|
|
130
|
+
if (expr) hoistOrWrap(expr);
|
|
131
|
+
}
|
|
132
|
+
function walk(node) {
|
|
133
|
+
if (ts.isJsxElement(node) && tryTemplateEmit(node)) return;
|
|
134
|
+
if (ts.isJsxSelfClosingElement(node) || ts.isJsxElement(node)) checkForWarnings(node);
|
|
135
|
+
if (ts.isJsxAttribute(node)) {
|
|
136
|
+
handleJsxAttribute(node);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
if (ts.isJsxExpression(node)) {
|
|
140
|
+
handleJsxExpression(node);
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
ts.forEachChild(node, walk);
|
|
144
|
+
}
|
|
145
|
+
walk(sf);
|
|
146
|
+
if (replacements.length === 0 && hoists.length === 0) return {
|
|
147
|
+
code,
|
|
148
|
+
warnings
|
|
149
|
+
};
|
|
150
|
+
replacements.sort((a, b) => b.start - a.start);
|
|
151
|
+
let result = code;
|
|
152
|
+
for (const r of replacements) result = result.slice(0, r.start) + r.text + result.slice(r.end);
|
|
153
|
+
if (hoists.length > 0) result = hoists.map(h => `const ${h.name} = /*@__PURE__*/ ${h.text}\n`).join("") + result;
|
|
154
|
+
if (needsTplImport) result = `import { _tpl } from "@pyreon/runtime-dom";\nimport { _bind } from "@pyreon/reactivity";\n` + result;
|
|
155
|
+
return {
|
|
156
|
+
code: result,
|
|
157
|
+
usesTemplates: needsTplImport,
|
|
158
|
+
warnings
|
|
159
|
+
};
|
|
160
|
+
/** Check if a single attribute would prevent template emission. */
|
|
161
|
+
function hasBailAttr(node) {
|
|
162
|
+
for (const attr of jsxAttrs(node)) {
|
|
163
|
+
if (ts.isJsxSpreadAttribute(attr)) return true;
|
|
164
|
+
if (ts.isJsxAttribute(attr) && ts.isIdentifier(attr.name) && attr.name.text === "key") return true;
|
|
165
|
+
}
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Count template-eligible elements for a single JSX child.
|
|
170
|
+
* Returns 0 for skippable children, -1 for bail, positive for element count.
|
|
171
|
+
*/
|
|
172
|
+
function countChildForTemplate(child) {
|
|
173
|
+
if (ts.isJsxText(child)) return 0;
|
|
174
|
+
if (ts.isJsxElement(child) || ts.isJsxSelfClosingElement(child)) return templateElementCount(child);
|
|
175
|
+
if (ts.isJsxExpression(child)) {
|
|
176
|
+
if (!child.expression) return 0;
|
|
177
|
+
return containsJSXInExpr(child.expression) ? -1 : 0;
|
|
178
|
+
}
|
|
179
|
+
if (ts.isJsxFragment(child)) return templateFragmentCount(child);
|
|
180
|
+
return -1;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Count DOM elements in a JSX subtree. Returns -1 if the tree is not
|
|
184
|
+
* eligible for template emission.
|
|
185
|
+
*/
|
|
186
|
+
function templateElementCount(node) {
|
|
187
|
+
const tag = jsxTagName(node);
|
|
188
|
+
if (!tag || !isLowerCase(tag)) return -1;
|
|
189
|
+
if (hasBailAttr(node)) return -1;
|
|
190
|
+
if (!ts.isJsxElement(node)) return 1;
|
|
191
|
+
let count = 1;
|
|
192
|
+
for (const child of node.children) {
|
|
193
|
+
const c = countChildForTemplate(child);
|
|
194
|
+
if (c === -1) return -1;
|
|
195
|
+
count += c;
|
|
196
|
+
}
|
|
197
|
+
return count;
|
|
198
|
+
}
|
|
199
|
+
/** Count template-eligible elements inside a fragment. */
|
|
200
|
+
function templateFragmentCount(frag) {
|
|
201
|
+
let count = 0;
|
|
202
|
+
for (const child of frag.children) {
|
|
203
|
+
const c = countChildForTemplate(child);
|
|
204
|
+
if (c === -1) return -1;
|
|
205
|
+
count += c;
|
|
206
|
+
}
|
|
207
|
+
return count;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Build the complete `_tpl("html", (__root) => { ... })` call string
|
|
211
|
+
* for a template-eligible JSX element tree. Returns null if codegen fails.
|
|
212
|
+
*/
|
|
213
|
+
function buildTemplateCall(node) {
|
|
214
|
+
const bindLines = [];
|
|
215
|
+
const disposerNames = [];
|
|
216
|
+
let varIdx = 0;
|
|
217
|
+
let dispIdx = 0;
|
|
218
|
+
function nextVar() {
|
|
219
|
+
return `__e${varIdx++}`;
|
|
220
|
+
}
|
|
221
|
+
function nextDisp() {
|
|
222
|
+
const name = `__d${dispIdx++}`;
|
|
223
|
+
disposerNames.push(name);
|
|
224
|
+
return name;
|
|
225
|
+
}
|
|
226
|
+
function nextTextVar() {
|
|
227
|
+
return `__t${varIdx++}`;
|
|
228
|
+
}
|
|
229
|
+
/** Resolve the variable name for an element given its accessor path. */
|
|
230
|
+
function resolveElementVar(accessor, hasDynamic) {
|
|
231
|
+
if (accessor === "__root") return "__root";
|
|
232
|
+
if (hasDynamic) {
|
|
233
|
+
const v = nextVar();
|
|
234
|
+
bindLines.push(`const ${v} = ${accessor}`);
|
|
235
|
+
return v;
|
|
236
|
+
}
|
|
237
|
+
return accessor;
|
|
238
|
+
}
|
|
239
|
+
/** Emit bind line for a ref attribute. */
|
|
240
|
+
function emitRef(attr, varName) {
|
|
241
|
+
if (!attr.initializer || !ts.isJsxExpression(attr.initializer)) return;
|
|
242
|
+
if (!attr.initializer.expression) return;
|
|
243
|
+
bindLines.push(`${sliceExpr(attr.initializer.expression)}.current = ${varName}`);
|
|
244
|
+
}
|
|
245
|
+
/** Emit addEventListener bind line for an event handler attribute. */
|
|
246
|
+
function emitEventListener(attr, attrName, varName) {
|
|
247
|
+
const eventName = (attrName[2] ?? "").toLowerCase() + attrName.slice(3);
|
|
248
|
+
if (!attr.initializer || !ts.isJsxExpression(attr.initializer)) return;
|
|
249
|
+
if (!attr.initializer.expression) return;
|
|
250
|
+
bindLines.push(`${varName}.addEventListener("${eventName}", ${sliceExpr(attr.initializer.expression)})`);
|
|
251
|
+
}
|
|
252
|
+
/** Return HTML string for a static attribute expression, or null if not static. */
|
|
253
|
+
function staticAttrToHtml(exprNode, htmlAttrName) {
|
|
254
|
+
if (!isStatic(exprNode)) return null;
|
|
255
|
+
if (ts.isStringLiteral(exprNode)) return ` ${htmlAttrName}="${escapeHtmlAttr(exprNode.text)}"`;
|
|
256
|
+
if (ts.isNumericLiteral(exprNode)) return ` ${htmlAttrName}="${exprNode.text}"`;
|
|
257
|
+
if (exprNode.kind === ts.SyntaxKind.TrueKeyword) return ` ${htmlAttrName}`;
|
|
258
|
+
return "";
|
|
259
|
+
}
|
|
260
|
+
/** Unwrap a reactive accessor expression for use inside _bind(). */
|
|
261
|
+
function unwrapAccessor(exprNode) {
|
|
262
|
+
if (ts.isArrowFunction(exprNode) && !ts.isBlock(exprNode.body)) return {
|
|
263
|
+
expr: sliceExpr(exprNode.body),
|
|
264
|
+
isReactive: true
|
|
265
|
+
};
|
|
266
|
+
if (ts.isArrowFunction(exprNode) || ts.isFunctionExpression(exprNode)) return {
|
|
267
|
+
expr: `(${sliceExpr(exprNode)})()`,
|
|
268
|
+
isReactive: true
|
|
269
|
+
};
|
|
270
|
+
return {
|
|
271
|
+
expr: sliceExpr(exprNode),
|
|
272
|
+
isReactive: containsCall(exprNode)
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
/** Emit bind line for a dynamic (non-static) attribute. */
|
|
276
|
+
function emitDynamicAttr(_expr, exprNode, htmlAttrName, varName) {
|
|
277
|
+
const {
|
|
278
|
+
expr,
|
|
279
|
+
isReactive
|
|
280
|
+
} = unwrapAccessor(exprNode);
|
|
281
|
+
const setter = htmlAttrName === "class" ? `${varName}.className = ${expr}` : `${varName}.setAttribute("${htmlAttrName}", ${expr})`;
|
|
282
|
+
if (isReactive) {
|
|
283
|
+
const d = nextDisp();
|
|
284
|
+
bindLines.push(`const ${d} = _bind(() => { ${setter} })`);
|
|
285
|
+
} else bindLines.push(setter);
|
|
286
|
+
}
|
|
287
|
+
/** Emit bind line or HTML for an expression attribute value. */
|
|
288
|
+
function emitAttrExpression(exprNode, htmlAttrName, varName) {
|
|
289
|
+
const staticHtml = staticAttrToHtml(exprNode, htmlAttrName);
|
|
290
|
+
if (staticHtml !== null) return staticHtml;
|
|
291
|
+
emitDynamicAttr(sliceExpr(exprNode), exprNode, htmlAttrName, varName);
|
|
292
|
+
return "";
|
|
293
|
+
}
|
|
294
|
+
/** Emit side-effects for special attrs (ref, event). Returns true if handled. */
|
|
295
|
+
function tryEmitSpecialAttr(attr, attrName, varName) {
|
|
296
|
+
if (attrName === "ref") {
|
|
297
|
+
emitRef(attr, varName);
|
|
298
|
+
return true;
|
|
299
|
+
}
|
|
300
|
+
if (EVENT_RE.test(attrName)) {
|
|
301
|
+
emitEventListener(attr, attrName, varName);
|
|
302
|
+
return true;
|
|
303
|
+
}
|
|
304
|
+
return false;
|
|
305
|
+
}
|
|
306
|
+
/** Convert an attribute initializer to HTML. Returns empty string for side-effect-only attrs. */
|
|
307
|
+
function attrInitializerToHtml(attr, htmlAttrName, varName) {
|
|
308
|
+
if (!attr.initializer) return ` ${htmlAttrName}`;
|
|
309
|
+
if (ts.isStringLiteral(attr.initializer)) return ` ${htmlAttrName}="${escapeHtmlAttr(attr.initializer.text)}"`;
|
|
310
|
+
if (ts.isJsxExpression(attr.initializer) && attr.initializer.expression) return emitAttrExpression(attr.initializer.expression, htmlAttrName, varName);
|
|
311
|
+
return "";
|
|
312
|
+
}
|
|
313
|
+
/** Process a single attribute, returning HTML to append. */
|
|
314
|
+
function processOneAttr(attr, varName) {
|
|
315
|
+
if (!ts.isJsxAttribute(attr)) return "";
|
|
316
|
+
const attrName = ts.isIdentifier(attr.name) ? attr.name.text : "";
|
|
317
|
+
if (attrName === "key") return "";
|
|
318
|
+
if (tryEmitSpecialAttr(attr, attrName, varName)) return "";
|
|
319
|
+
return attrInitializerToHtml(attr, JSX_TO_HTML_ATTR[attrName] ?? attrName, varName);
|
|
320
|
+
}
|
|
321
|
+
/** Process all attributes on an element, returning the HTML attribute string. */
|
|
322
|
+
function processAttrs(el, varName) {
|
|
323
|
+
let htmlAttrs = "";
|
|
324
|
+
for (const attr of jsxAttrs(el)) htmlAttrs += processOneAttr(attr, varName);
|
|
325
|
+
return htmlAttrs;
|
|
326
|
+
}
|
|
327
|
+
/** Emit bind lines for a reactive text expression child. */
|
|
328
|
+
function emitReactiveTextChild(expr, varName, parentRef, childNodeIdx, needsPlaceholder) {
|
|
329
|
+
const tVar = nextTextVar();
|
|
330
|
+
const d = nextDisp();
|
|
331
|
+
bindLines.push(`const ${tVar} = document.createTextNode("")`);
|
|
332
|
+
if (needsPlaceholder) bindLines.push(`${parentRef}.replaceChild(${tVar}, ${parentRef}.childNodes[${childNodeIdx}])`);else bindLines.push(`${varName}.appendChild(${tVar})`);
|
|
333
|
+
bindLines.push(`const ${d} = _bind(() => { ${tVar}.data = ${expr} })`);
|
|
334
|
+
return needsPlaceholder ? "<!>" : "";
|
|
335
|
+
}
|
|
336
|
+
/** Emit bind lines for a static text expression child. */
|
|
337
|
+
function emitStaticTextChild(expr, varName, parentRef, childNodeIdx, needsPlaceholder) {
|
|
338
|
+
if (needsPlaceholder) {
|
|
339
|
+
const tVar = nextTextVar();
|
|
340
|
+
bindLines.push(`const ${tVar} = document.createTextNode(${expr})`);
|
|
341
|
+
bindLines.push(`${parentRef}.replaceChild(${tVar}, ${parentRef}.childNodes[${childNodeIdx}])`);
|
|
342
|
+
return "<!>";
|
|
343
|
+
}
|
|
344
|
+
bindLines.push(`${varName}.textContent = ${expr}`);
|
|
345
|
+
return "";
|
|
346
|
+
}
|
|
347
|
+
/** Process a single flat child, returning the HTML contribution or null on failure. */
|
|
348
|
+
function processOneChild(child, varName, parentRef, useMixed, useMultiExpr, childNodeIdx) {
|
|
349
|
+
if (child.kind === "text") return escapeHtmlText(child.text);
|
|
350
|
+
if (child.kind === "element") {
|
|
351
|
+
const childAccessor = useMixed ? `${parentRef}.childNodes[${childNodeIdx}]` : `${parentRef}.children[${child.elemIdx}]`;
|
|
352
|
+
return processElement(child.node, childAccessor);
|
|
353
|
+
}
|
|
354
|
+
const needsPlaceholder = useMixed || useMultiExpr;
|
|
355
|
+
const {
|
|
356
|
+
expr,
|
|
357
|
+
isReactive
|
|
358
|
+
} = unwrapAccessor(child.expression);
|
|
359
|
+
if (isReactive) return emitReactiveTextChild(expr, varName, parentRef, childNodeIdx, needsPlaceholder);
|
|
360
|
+
return emitStaticTextChild(expr, varName, parentRef, childNodeIdx, needsPlaceholder);
|
|
361
|
+
}
|
|
362
|
+
/** Process children of a JsxElement, returning the children HTML. */
|
|
363
|
+
function processChildren(el, varName, accessor) {
|
|
364
|
+
const flatChildren = flattenChildren(el.children);
|
|
365
|
+
const {
|
|
366
|
+
useMixed,
|
|
367
|
+
useMultiExpr
|
|
368
|
+
} = analyzeChildren(flatChildren);
|
|
369
|
+
const parentRef = accessor === "__root" ? "__root" : varName;
|
|
370
|
+
let html = "";
|
|
371
|
+
let childNodeIdx = 0;
|
|
372
|
+
for (const child of flatChildren) {
|
|
373
|
+
const childHtml = processOneChild(child, varName, parentRef, useMixed, useMultiExpr, childNodeIdx);
|
|
374
|
+
if (childHtml === null) return null;
|
|
375
|
+
html += childHtml;
|
|
376
|
+
childNodeIdx++;
|
|
377
|
+
}
|
|
378
|
+
return html;
|
|
379
|
+
}
|
|
380
|
+
/** Process a single DOM element for template emission. Returns the HTML string or null. */
|
|
381
|
+
function processElement(el, accessor) {
|
|
382
|
+
const tag = jsxTagName(el);
|
|
383
|
+
if (!tag) return null;
|
|
384
|
+
const varName = resolveElementVar(accessor, elementHasDynamic(el));
|
|
385
|
+
let html = `<${tag}${processAttrs(el, varName)}>`;
|
|
386
|
+
if (ts.isJsxElement(el)) {
|
|
387
|
+
const childHtml = processChildren(el, varName, accessor);
|
|
388
|
+
if (childHtml === null) return null;
|
|
389
|
+
html += childHtml;
|
|
390
|
+
}
|
|
391
|
+
if (!VOID_ELEMENTS.has(tag)) html += `</${tag}>`;
|
|
392
|
+
return html;
|
|
393
|
+
}
|
|
394
|
+
const html = processElement(node, "__root");
|
|
395
|
+
if (html === null) return null;
|
|
396
|
+
const escaped = html.replace(/\\/g, "\\\\").replace(/"/g, "\\\"");
|
|
397
|
+
if (bindLines.length === 0 && disposerNames.length === 0) return `_tpl("${escaped}", () => null)`;
|
|
398
|
+
let body = bindLines.map(l => ` ${l}`).join("\n");
|
|
399
|
+
if (disposerNames.length > 0) body += `\n return () => { ${disposerNames.map(d => `${d}()`).join("; ")} }`;else body += "\n return null";
|
|
400
|
+
return `_tpl("${escaped}", (__root) => {\n${body}\n})`;
|
|
401
|
+
}
|
|
402
|
+
/** Classify a single JSX child into a FlatChild descriptor. */
|
|
403
|
+
function classifyJsxChild(child, out, elemIdxRef, recurse) {
|
|
404
|
+
if (ts.isJsxText(child)) {
|
|
405
|
+
const trimmed = child.text.replace(/\n\s*/g, "").trim();
|
|
406
|
+
if (trimmed) out.push({
|
|
407
|
+
kind: "text",
|
|
408
|
+
text: trimmed
|
|
409
|
+
});
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
if (ts.isJsxElement(child) || ts.isJsxSelfClosingElement(child)) {
|
|
413
|
+
out.push({
|
|
414
|
+
kind: "element",
|
|
415
|
+
node: child,
|
|
416
|
+
elemIdx: elemIdxRef.value++
|
|
417
|
+
});
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
if (ts.isJsxExpression(child)) {
|
|
421
|
+
if (child.expression) out.push({
|
|
422
|
+
kind: "expression",
|
|
423
|
+
expression: child.expression
|
|
424
|
+
});
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
if (ts.isJsxFragment(child)) recurse(child.children);
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Flatten JSX children, inlining fragment children and stripping whitespace-only text.
|
|
431
|
+
* Returns a flat array of child descriptors with element indices pre-computed.
|
|
432
|
+
*/
|
|
433
|
+
function flattenChildren(children) {
|
|
434
|
+
const flatList = [];
|
|
435
|
+
const elemIdxRef = {
|
|
436
|
+
value: 0
|
|
437
|
+
};
|
|
438
|
+
function addChildren(kids) {
|
|
439
|
+
for (const child of kids) classifyJsxChild(child, flatList, elemIdxRef, addChildren);
|
|
440
|
+
}
|
|
441
|
+
addChildren(children);
|
|
442
|
+
return flatList;
|
|
443
|
+
}
|
|
444
|
+
/** Analyze flat children to determine indexing strategy. */
|
|
445
|
+
function analyzeChildren(flatChildren) {
|
|
446
|
+
const hasElem = flatChildren.some(c => c.kind === "element");
|
|
447
|
+
const hasNonElem = flatChildren.some(c => c.kind !== "element");
|
|
448
|
+
const exprCount = flatChildren.filter(c => c.kind === "expression").length;
|
|
449
|
+
return {
|
|
450
|
+
useMixed: hasElem && hasNonElem,
|
|
451
|
+
useMultiExpr: exprCount > 1
|
|
452
|
+
};
|
|
453
|
+
}
|
|
454
|
+
/** Check if a single attribute is dynamic (has ref, event, or non-static expression). */
|
|
455
|
+
function attrIsDynamic(attr) {
|
|
456
|
+
if (!ts.isJsxAttribute(attr)) return false;
|
|
457
|
+
const name = ts.isIdentifier(attr.name) ? attr.name.text : "";
|
|
458
|
+
if (name === "ref") return true;
|
|
459
|
+
if (EVENT_RE.test(name)) return true;
|
|
460
|
+
if (!attr.initializer || !ts.isJsxExpression(attr.initializer)) return false;
|
|
461
|
+
const expr = attr.initializer.expression;
|
|
462
|
+
return expr ? !isStatic(expr) : false;
|
|
463
|
+
}
|
|
464
|
+
/** Check if an element has any dynamic attributes, events, ref, or expression children */
|
|
465
|
+
function elementHasDynamic(node) {
|
|
466
|
+
if (jsxAttrs(node).some(attrIsDynamic)) return true;
|
|
467
|
+
if (ts.isJsxElement(node)) return node.children.some(c => ts.isJsxExpression(c) && c.expression !== void 0);
|
|
468
|
+
return false;
|
|
469
|
+
}
|
|
470
|
+
/** Slice expression source from the original code */
|
|
471
|
+
function sliceExpr(expr) {
|
|
472
|
+
return code.slice(expr.getStart(sf), expr.getEnd());
|
|
473
|
+
}
|
|
474
|
+
/** Get tag name string */
|
|
475
|
+
function jsxTagName(node) {
|
|
476
|
+
const tag = ts.isJsxElement(node) ? node.openingElement.tagName : node.tagName;
|
|
477
|
+
return ts.isIdentifier(tag) ? tag.text : "";
|
|
478
|
+
}
|
|
479
|
+
/** Get attribute list */
|
|
480
|
+
function jsxAttrs(node) {
|
|
481
|
+
return ts.isJsxElement(node) ? node.openingElement.attributes.properties : node.attributes.properties;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
function isLowerCase(s) {
|
|
485
|
+
return s.length > 0 && s[0] === s[0]?.toLowerCase();
|
|
486
|
+
}
|
|
487
|
+
/** Check if an expression subtree contains JSX nodes */
|
|
488
|
+
function containsJSXInExpr(node) {
|
|
489
|
+
if (ts.isJsxElement(node) || ts.isJsxSelfClosingElement(node) || ts.isJsxFragment(node)) return true;
|
|
490
|
+
return ts.forEachChild(node, containsJSXInExpr) ?? false;
|
|
491
|
+
}
|
|
492
|
+
function escapeHtmlAttr(s) {
|
|
493
|
+
return s.replace(/&/g, "&").replace(/"/g, """);
|
|
494
|
+
}
|
|
495
|
+
function escapeHtmlText(s) {
|
|
496
|
+
return s.replace(/&/g, "&").replace(/</g, "<");
|
|
497
|
+
}
|
|
498
|
+
function isStaticJSXNode(node) {
|
|
499
|
+
if (ts.isJsxSelfClosingElement(node)) return isStaticAttrs(node.attributes);
|
|
500
|
+
if (ts.isJsxFragment(node)) return node.children.every(isStaticChild);
|
|
501
|
+
return isStaticAttrs(node.openingElement.attributes) && node.children.every(isStaticChild);
|
|
502
|
+
}
|
|
503
|
+
function isStaticAttrs(attrs) {
|
|
504
|
+
return attrs.properties.every(prop => {
|
|
505
|
+
if (!ts.isJsxAttribute(prop)) return false;
|
|
506
|
+
if (!prop.initializer) return true;
|
|
507
|
+
if (ts.isStringLiteral(prop.initializer)) return true;
|
|
508
|
+
const expr = prop.initializer.expression;
|
|
509
|
+
return expr ? isStatic(expr) : true;
|
|
510
|
+
});
|
|
511
|
+
}
|
|
512
|
+
function isStaticChild(child) {
|
|
513
|
+
if (ts.isJsxText(child)) return true;
|
|
514
|
+
if (ts.isJsxSelfClosingElement(child)) return isStaticJSXNode(child);
|
|
515
|
+
if (ts.isJsxElement(child)) return isStaticJSXNode(child);
|
|
516
|
+
if (ts.isJsxFragment(child)) return isStaticJSXNode(child);
|
|
517
|
+
const expr = child.expression;
|
|
518
|
+
return expr ? isStatic(expr) : true;
|
|
519
|
+
}
|
|
520
|
+
function isStatic(node) {
|
|
521
|
+
return ts.isStringLiteral(node) || ts.isNumericLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node) || node.kind === ts.SyntaxKind.TrueKeyword || node.kind === ts.SyntaxKind.FalseKeyword || node.kind === ts.SyntaxKind.NullKeyword || node.kind === ts.SyntaxKind.UndefinedKeyword;
|
|
522
|
+
}
|
|
523
|
+
function shouldWrap(node) {
|
|
524
|
+
if (ts.isArrowFunction(node) || ts.isFunctionExpression(node)) return false;
|
|
525
|
+
if (isStatic(node)) return false;
|
|
526
|
+
return containsCall(node);
|
|
527
|
+
}
|
|
528
|
+
function containsCall(node) {
|
|
529
|
+
if (ts.isCallExpression(node)) return true;
|
|
530
|
+
if (ts.isTaggedTemplateExpression(node)) return true;
|
|
531
|
+
if (ts.isArrowFunction(node) || ts.isFunctionExpression(node)) return false;
|
|
532
|
+
return ts.forEachChild(node, containsCall) ?? false;
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
//#endregion
|
|
536
|
+
export { transformJSX };
|
|
537
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/jsx.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8DA,SAAgB,YAAA,CAAa,IAAA,EAAc,QAAA,GAAW,WAAA,EAA8B;EAClF,MAAM,UAAA,GACJ,QAAA,CAAS,QAAA,CAAS,MAAA,CAAO,IAAI,QAAA,CAAS,QAAA,CAAS,MAAA,CAAO,GAAG,EAAA,CAAG,UAAA,CAAW,GAAA,GAAM,EAAA,CAAG,UAAA,CAAW,GAAA;EAE7F,MAAM,EAAA,GAAK,EAAA,CAAG,gBAAA,CACZ,QAAA,EACA,IAAA,EACA,EAAA,CAAG,YAAA,CAAa,MAAA,EACK,IAAA,EACrB,UAAA,CACD;EAGD,MAAM,YAAA,GAA8B,EAAE;EACtC,MAAM,QAAA,GAA8B,EAAE;EAEtC,SAAS,IAAA,CAAK,IAAA,EAAe,OAAA,EAAiB,QAAA,EAAyC;IACrF,MAAM;MAAE,IAAA;MAAM;IAAA,CAAA,GAAc,EAAA,CAAG,6BAAA,CAA8B,IAAA,CAAK,QAAA,CAAS,EAAA,CAAG,CAAC;IAC/E,QAAA,CAAS,IAAA,CAAK;MAAE,OAAA;MAAS,IAAA,EAAM,IAAA,GAAO,CAAA;MAAG,MAAA,EAAQ,SAAA;MAAW,IAAA,EAAM;KAAU,CAAC;;EAK/E,MAAM,MAAA,GAAkB,EAAE;EAC1B,IAAI,QAAA,GAAW,CAAA;EACf,IAAI,cAAA,GAAiB,KAAA;;;;;EAMrB,SAAS,UAAA,CAAW,IAAA,EAA8B;IAChD,IAAA,CACG,EAAA,CAAG,YAAA,CAAa,IAAA,CAAK,IAAI,EAAA,CAAG,uBAAA,CAAwB,IAAA,CAAK,IAAI,EAAA,CAAG,aAAA,CAAc,IAAA,CAAK,KACpF,eAAA,CAAgB,IAAA,CAAkE,EAClF;MACA,MAAM,IAAA,GAAO,MAAM,QAAA,EAAA,EAAA;MACnB,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,QAAA,CAAS,EAAA,CAAG,EAAE,IAAA,CAAK,MAAA,CAAA,CAAQ,CAAC;MACzD,MAAA,CAAO,IAAA,CAAK;QAAE,IAAA;QAAM;OAAM,CAAC;MAC3B,OAAO,IAAA;;IAET,OAAO,IAAA;;EAGT,SAAS,IAAA,CAAK,IAAA,EAA2B;IACvC,MAAM,KAAA,GAAQ,IAAA,CAAK,QAAA,CAAS,EAAA,CAAG;IAC/B,MAAM,GAAA,GAAM,IAAA,CAAK,MAAA,CAAA,CAAQ;IACzB,YAAA,CAAa,IAAA,CAAK;MAAE,KAAA;MAAO,GAAA;MAAK,IAAA,EAAM,SAAS,IAAA,CAAK,KAAA,CAAM,KAAA,EAAO,GAAA,CAAI;KAAI,CAAC;;;EAI5E,SAAS,WAAA,CAAY,IAAA,EAA2B;IAC9C,MAAM,SAAA,GAAY,UAAA,CAAW,IAAA,CAAK;IAClC,IAAI,SAAA,EACF,YAAA,CAAa,IAAA,CAAK;MAAE,KAAA,EAAO,IAAA,CAAK,QAAA,CAAS,EAAA,CAAG;MAAE,GAAA,EAAK,IAAA,CAAK,MAAA,CAAA,CAAQ;MAAE,IAAA,EAAM;KAAW,CAAC,CAAA,SAC3E,UAAA,CAAW,IAAA,CAAK,EACzB,IAAA,CAAK,IAAA,CAAK;;;EAOd,SAAS,eAAA,CAAgB,IAAA,EAA8B;IAErD,IADkB,oBAAA,CAAqB,IAAA,CAAK,GAC5B,CAAA,EAAG,OAAO,KAAA;IAC1B,MAAM,OAAA,GAAU,iBAAA,CAAkB,IAAA,CAAK;IACvC,IAAI,CAAC,OAAA,EAAS,OAAO,KAAA;IACrB,MAAM,KAAA,GAAQ,IAAA,CAAK,QAAA,CAAS,EAAA,CAAG;IAC/B,MAAM,GAAA,GAAM,IAAA,CAAK,MAAA,CAAA,CAAQ;IACzB,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA;IACpB,MAAM,WAAA,GAAc,MAAA,KAAW,EAAA,CAAG,YAAA,CAAa,MAAA,CAAO,IAAI,EAAA,CAAG,aAAA,CAAc,MAAA,CAAO,CAAA;IAClF,YAAA,CAAa,IAAA,CAAK;MAAE,KAAA;MAAO,GAAA;MAAK,IAAA,EAAM,WAAA,GAAc,IAAI,OAAA,GAAQ,GAAK;KAAS,CAAC;IAC/E,cAAA,GAAiB,IAAA;IACjB,OAAO,IAAA;;;EAIT,SAAS,gBAAA,CAAiB,IAAA,EAAsD;IAC9E,MAAM,OAAA,GAAU,EAAA,CAAG,YAAA,CAAa,IAAA,CAAK,GAAG,IAAA,CAAK,cAAA,GAAiB,IAAA;IAE9D,IAAA,CADgB,EAAA,CAAG,YAAA,CAAa,OAAA,CAAQ,OAAA,CAAQ,GAAG,OAAA,CAAQ,OAAA,CAAQ,IAAA,GAAO,EAAA,MAC1D,KAAA,EAAO;IAIvB,IAAI,CAHU,OAAA,CAAQ,UAAA,CAAW,UAAA,CAAW,IAAA,CACzC,CAAA,IAAM,EAAA,CAAG,cAAA,CAAe,CAAA,CAAE,IAAI,EAAA,CAAG,YAAA,CAAa,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA,CAAE,IAAA,CAAK,IAAA,KAAS,IAAA,CAC3E,EAEC,IAAA,CACE,OAAA,CAAQ,OAAA,EACR,mLAAA,EACA,oBAAA,CACD;;;EAKL,SAAS,kBAAA,CAAmB,IAAA,EAA6B;IACvD,MAAM,IAAA,GAAO,EAAA,CAAG,YAAA,CAAa,IAAA,CAAK,IAAA,CAAK,GAAG,IAAA,CAAK,IAAA,CAAK,IAAA,GAAO,EAAA;IAC3D,MAAM,SAAA,GAAY,IAAA,CAAK,MAAA,CAAO,MAAA;IAC9B,MAAM,OAAA,GAAU,EAAA,CAAG,YAAA,CAAa,SAAA,CAAU,OAAA,CAAQ,GAAG,SAAA,CAAU,OAAA,CAAQ,IAAA,GAAO,EAAA;IAG9E,IADE,OAAA,CAAQ,MAAA,GAAS,CAAA,IAAK,OAAA,CAAQ,MAAA,CAAO,CAAA,CAAE,KAAK,OAAA,CAAQ,MAAA,CAAO,CAAA,CAAE,CAAC,WAAA,CAAA,CAAa,EACrD;IACxB,IAAI,UAAA,CAAW,GAAA,CAAI,IAAA,CAAK,IAAI,QAAA,CAAS,IAAA,CAAK,IAAA,CAAK,EAAE;IACjD,IAAI,CAAC,IAAA,CAAK,WAAA,IAAe,CAAC,EAAA,CAAG,eAAA,CAAgB,IAAA,CAAK,WAAA,CAAY,EAAE;IAChE,MAAM,IAAA,GAAO,IAAA,CAAK,WAAA,CAAY,UAAA;IAC9B,IAAI,IAAA,EAAM,WAAA,CAAY,IAAA,CAAK;;;EAI7B,SAAS,mBAAA,CAAoB,IAAA,EAA8B;IACzD,MAAM,IAAA,GAAO,IAAA,CAAK,UAAA;IAClB,IAAI,IAAA,EAAM,WAAA,CAAY,IAAA,CAAK;;EAG7B,SAAS,IAAA,CAAK,IAAA,EAAqB;IACjC,IAAI,EAAA,CAAG,YAAA,CAAa,IAAA,CAAK,IAAI,eAAA,CAAgB,IAAA,CAAK,EAAE;IACpD,IAAI,EAAA,CAAG,uBAAA,CAAwB,IAAA,CAAK,IAAI,EAAA,CAAG,YAAA,CAAa,IAAA,CAAK,EAAE,gBAAA,CAAiB,IAAA,CAAK;IACrF,IAAI,EAAA,CAAG,cAAA,CAAe,IAAA,CAAK,EAAE;MAC3B,kBAAA,CAAmB,IAAA,CAAK;MACxB;;IAEF,IAAI,EAAA,CAAG,eAAA,CAAgB,IAAA,CAAK,EAAE;MAC5B,mBAAA,CAAoB,IAAA,CAAK;MACzB;;IAEF,EAAA,CAAG,YAAA,CAAa,IAAA,EAAM,IAAA,CAAK;;EAG7B,IAAA,CAAK,EAAA,CAAG;EAER,IAAI,YAAA,CAAa,MAAA,KAAW,CAAA,IAAK,MAAA,CAAO,MAAA,KAAW,CAAA,EAAG,OAAO;IAAE,IAAA;IAAM;GAAU;EAG/E,YAAA,CAAa,IAAA,CAAA,CAAM,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,KAAA,GAAQ,CAAA,CAAE,KAAA,CAAM;EAE9C,IAAI,MAAA,GAAS,IAAA;EACb,KAAK,MAAM,CAAA,IAAK,YAAA,EACd,MAAA,GAAS,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,CAAA,CAAE,KAAA,CAAM,GAAG,CAAA,CAAE,IAAA,GAAO,MAAA,CAAO,KAAA,CAAM,CAAA,CAAE,GAAA,CAAI;EAIlE,IAAI,MAAA,CAAO,MAAA,GAAS,CAAA,EAElB,MAAA,GADiB,MAAA,CAAO,GAAA,CAAK,CAAA,IAAM,SAAS,CAAA,CAAE,IAAA,oBAAwB,CAAA,CAAE,IAAA,IAAK,CAAI,CAAC,IAAA,CAAK,EAAA,CAAG,GACtE,MAAA;EAItB,IAAI,cAAA,EACF,MAAA,GACE,4FAAA,GACA,MAAA;EAGJ,OAAO;IAAE,IAAA,EAAM,MAAA;IAAQ,aAAA,EAAe,cAAA;IAAgB;GAAU;;EAKhE,SAAS,WAAA,CAAY,IAAA,EAAyD;IAC5E,KAAK,MAAM,IAAA,IAAQ,QAAA,CAAS,IAAA,CAAK,EAAE;MACjC,IAAI,EAAA,CAAG,oBAAA,CAAqB,IAAA,CAAK,EAAE,OAAO,IAAA;MAC1C,IAAI,EAAA,CAAG,cAAA,CAAe,IAAA,CAAK,IAAI,EAAA,CAAG,YAAA,CAAa,IAAA,CAAK,IAAA,CAAK,IAAI,IAAA,CAAK,IAAA,CAAK,IAAA,KAAS,KAAA,EAC9E,OAAO,IAAA;;IAEX,OAAO,KAAA;;;;;;EAOT,SAAS,qBAAA,CAAsB,KAAA,EAA4B;IACzD,IAAI,EAAA,CAAG,SAAA,CAAU,KAAA,CAAM,EAAE,OAAO,CAAA;IAChC,IAAI,EAAA,CAAG,YAAA,CAAa,KAAA,CAAM,IAAI,EAAA,CAAG,uBAAA,CAAwB,KAAA,CAAM,EAC7D,OAAO,oBAAA,CAAqB,KAAA,CAAM;IACpC,IAAI,EAAA,CAAG,eAAA,CAAgB,KAAA,CAAM,EAAE;MAC7B,IAAI,CAAC,KAAA,CAAM,UAAA,EAAY,OAAO,CAAA;MAC9B,OAAO,iBAAA,CAAkB,KAAA,CAAM,UAAA,CAAW,GAAG,CAAA,CAAA,GAAK,CAAA;;IAEpD,IAAI,EAAA,CAAG,aAAA,CAAc,KAAA,CAAM,EAAE,OAAO,qBAAA,CAAsB,KAAA,CAAM;IAChE,OAAO,CAAA,CAAA;;;;;;EAOT,SAAS,oBAAA,CAAqB,IAAA,EAAwD;IACpF,MAAM,GAAA,GAAM,UAAA,CAAW,IAAA,CAAK;IAC5B,IAAI,CAAC,GAAA,IAAO,CAAC,WAAA,CAAY,GAAA,CAAI,EAAE,OAAO,CAAA,CAAA;IACtC,IAAI,WAAA,CAAY,IAAA,CAAK,EAAE,OAAO,CAAA,CAAA;IAC9B,IAAI,CAAC,EAAA,CAAG,YAAA,CAAa,IAAA,CAAK,EAAE,OAAO,CAAA;IAEnC,IAAI,KAAA,GAAQ,CAAA;IACZ,KAAK,MAAM,KAAA,IAAS,IAAA,CAAK,QAAA,EAAU;MACjC,MAAM,CAAA,GAAI,qBAAA,CAAsB,KAAA,CAAM;MACtC,IAAI,CAAA,KAAM,CAAA,CAAA,EAAI,OAAO,CAAA,CAAA;MACrB,KAAA,IAAS,CAAA;;IAEX,OAAO,KAAA;;;EAIT,SAAS,qBAAA,CAAsB,IAAA,EAA8B;IAC3D,IAAI,KAAA,GAAQ,CAAA;IACZ,KAAK,MAAM,KAAA,IAAS,IAAA,CAAK,QAAA,EAAU;MACjC,MAAM,CAAA,GAAI,qBAAA,CAAsB,KAAA,CAAM;MACtC,IAAI,CAAA,KAAM,CAAA,CAAA,EAAI,OAAO,CAAA,CAAA;MACrB,KAAA,IAAS,CAAA;;IAEX,OAAO,KAAA;;;;;;EAOT,SAAS,iBAAA,CAAkB,IAAA,EAA+D;IACxF,MAAM,SAAA,GAAsB,EAAE;IAC9B,MAAM,aAAA,GAA0B,EAAE;IAClC,IAAI,MAAA,GAAS,CAAA;IACb,IAAI,OAAA,GAAU,CAAA;IAEd,SAAS,OAAA,CAAA,EAAkB;MACzB,OAAO,MAAM,MAAA,EAAA,EAAA;;IAEf,SAAS,QAAA,CAAA,EAAmB;MAC1B,MAAM,IAAA,GAAO,MAAM,OAAA,EAAA,EAAA;MACnB,aAAA,CAAc,IAAA,CAAK,IAAA,CAAK;MACxB,OAAO,IAAA;;IAET,SAAS,WAAA,CAAA,EAAsB;MAC7B,OAAO,MAAM,MAAA,EAAA,EAAA;;;IAIf,SAAS,iBAAA,CAAkB,QAAA,EAAkB,UAAA,EAA6B;MACxE,IAAI,QAAA,KAAa,QAAA,EAAU,OAAO,QAAA;MAClC,IAAI,UAAA,EAAY;QACd,MAAM,CAAA,GAAI,OAAA,CAAA,CAAS;QACnB,SAAA,CAAU,IAAA,CAAK,SAAS,CAAA,MAAO,QAAA,EAAA,CAAW;QAC1C,OAAO,CAAA;;MAET,OAAO,QAAA;;;IAIT,SAAS,OAAA,CAAQ,IAAA,EAAuB,OAAA,EAAuB;MAC7D,IAAI,CAAC,IAAA,CAAK,WAAA,IAAe,CAAC,EAAA,CAAG,eAAA,CAAgB,IAAA,CAAK,WAAA,CAAY,EAAE;MAChE,IAAI,CAAC,IAAA,CAAK,WAAA,CAAY,UAAA,EAAY;MAClC,SAAA,CAAU,IAAA,CAAK,GAAG,SAAA,CAAU,IAAA,CAAK,WAAA,CAAY,UAAA,CAAW,cAAc,OAAA,EAAA,CAAU;;;IAIlF,SAAS,iBAAA,CAAkB,IAAA,EAAuB,QAAA,EAAkB,OAAA,EAAuB;MACzF,MAAM,SAAA,GAAA,CAAa,QAAA,CAAS,CAAA,CAAA,IAAM,EAAA,EAAI,WAAA,CAAA,CAAa,GAAG,QAAA,CAAS,KAAA,CAAM,CAAA,CAAE;MACvE,IAAI,CAAC,IAAA,CAAK,WAAA,IAAe,CAAC,EAAA,CAAG,eAAA,CAAgB,IAAA,CAAK,WAAA,CAAY,EAAE;MAChE,IAAI,CAAC,IAAA,CAAK,WAAA,CAAY,UAAA,EAAY;MAClC,SAAA,CAAU,IAAA,CACR,GAAG,OAAA,sBAA6B,SAAA,MAAe,SAAA,CAAU,IAAA,CAAK,WAAA,CAAY,UAAA,CAAW,GAAC,CACvF;;;IAIH,SAAS,gBAAA,CAAiB,QAAA,EAAyB,YAAA,EAAqC;MACtF,IAAI,CAAC,QAAA,CAAS,QAAA,CAAS,EAAE,OAAO,IAAA;MAChC,IAAI,EAAA,CAAG,eAAA,CAAgB,QAAA,CAAS,EAAE,OAAO,IAAI,YAAA,KAAiB,cAAA,CAAe,QAAA,CAAS,IAAA,CAAK,GAAC;MAC5F,IAAI,EAAA,CAAG,gBAAA,CAAiB,QAAA,CAAS,EAAE,OAAO,IAAI,YAAA,KAAiB,QAAA,CAAS,IAAA,GAAK;MAC7E,IAAI,QAAA,CAAS,IAAA,KAAS,EAAA,CAAG,UAAA,CAAW,WAAA,EAAa,OAAO,IAAI,YAAA,EAAA;MAC5D,OAAO,EAAA;;;IAIT,SAAS,cAAA,CAAe,QAAA,EAAgE;MAEtF,IAAI,EAAA,CAAG,eAAA,CAAgB,QAAA,CAAS,IAAI,CAAC,EAAA,CAAG,OAAA,CAAQ,QAAA,CAAS,IAAA,CAAK,EAC5D,OAAO;QAAE,IAAA,EAAM,SAAA,CAAU,QAAA,CAAS,IAAA,CAAsB;QAAE,UAAA,EAAY;OAAM;MAG9E,IAAI,EAAA,CAAG,eAAA,CAAgB,QAAA,CAAS,IAAI,EAAA,CAAG,oBAAA,CAAqB,QAAA,CAAS,EACnE,OAAO;QAAE,IAAA,EAAM,IAAI,SAAA,CAAU,QAAA,CAAS,KAAC;QAAM,UAAA,EAAY;OAAM;MAEjE,OAAO;QAAE,IAAA,EAAM,SAAA,CAAU,QAAA,CAAS;QAAE,UAAA,EAAY,YAAA,CAAa,QAAA;OAAW;;;IAI1E,SAAS,eAAA,CACP,KAAA,EACA,QAAA,EACA,YAAA,EACA,OAAA,EACM;MACN,MAAM;QAAE,IAAA;QAAM;MAAA,CAAA,GAAe,cAAA,CAAe,QAAA,CAAS;MACrD,MAAM,MAAA,GACJ,YAAA,KAAiB,OAAA,GACb,GAAG,OAAA,gBAAuB,IAAA,EAAA,GAC1B,GAAG,OAAA,kBAAyB,YAAA,MAAkB,IAAA,GAAK;MAEzD,IAAI,UAAA,EAAY;QACd,MAAM,CAAA,GAAI,QAAA,CAAA,CAAU;QACpB,SAAA,CAAU,IAAA,CAAK,SAAS,CAAA,oBAAqB,MAAA,KAAO,CAAK;aAEzD,SAAA,CAAU,IAAA,CAAK,MAAA,CAAO;;;IAK1B,SAAS,kBAAA,CACP,QAAA,EACA,YAAA,EACA,OAAA,EACQ;MACR,MAAM,UAAA,GAAa,gBAAA,CAAiB,QAAA,EAAU,YAAA,CAAa;MAC3D,IAAI,UAAA,KAAe,IAAA,EAAM,OAAO,UAAA;MAChC,eAAA,CAAgB,SAAA,CAAU,QAAA,CAAS,EAAE,QAAA,EAAU,YAAA,EAAc,OAAA,CAAQ;MACrE,OAAO,EAAA;;;IAIT,SAAS,kBAAA,CAAmB,IAAA,EAAuB,QAAA,EAAkB,OAAA,EAA0B;MAC7F,IAAI,QAAA,KAAa,KAAA,EAAO;QACtB,OAAA,CAAQ,IAAA,EAAM,OAAA,CAAQ;QACtB,OAAO,IAAA;;MAET,IAAI,QAAA,CAAS,IAAA,CAAK,QAAA,CAAS,EAAE;QAC3B,iBAAA,CAAkB,IAAA,EAAM,QAAA,EAAU,OAAA,CAAQ;QAC1C,OAAO,IAAA;;MAET,OAAO,KAAA;;;IAIT,SAAS,qBAAA,CACP,IAAA,EACA,YAAA,EACA,OAAA,EACQ;MACR,IAAI,CAAC,IAAA,CAAK,WAAA,EAAa,OAAO,IAAI,YAAA,EAAA;MAClC,IAAI,EAAA,CAAG,eAAA,CAAgB,IAAA,CAAK,WAAA,CAAY,EACtC,OAAO,IAAI,YAAA,KAAiB,cAAA,CAAe,IAAA,CAAK,WAAA,CAAY,IAAA,CAAK,GAAC;MACpE,IAAI,EAAA,CAAG,eAAA,CAAgB,IAAA,CAAK,WAAA,CAAY,IAAI,IAAA,CAAK,WAAA,CAAY,UAAA,EAC3D,OAAO,kBAAA,CAAmB,IAAA,CAAK,WAAA,CAAY,UAAA,EAAY,YAAA,EAAc,OAAA,CAAQ;MAC/E,OAAO,EAAA;;;IAIT,SAAS,cAAA,CAAe,IAAA,EAA2B,OAAA,EAAyB;MAC1E,IAAI,CAAC,EAAA,CAAG,cAAA,CAAe,IAAA,CAAK,EAAE,OAAO,EAAA;MACrC,MAAM,QAAA,GAAW,EAAA,CAAG,YAAA,CAAa,IAAA,CAAK,IAAA,CAAK,GAAG,IAAA,CAAK,IAAA,CAAK,IAAA,GAAO,EAAA;MAC/D,IAAI,QAAA,KAAa,KAAA,EAAO,OAAO,EAAA;MAC/B,IAAI,kBAAA,CAAmB,IAAA,EAAM,QAAA,EAAU,OAAA,CAAQ,EAAE,OAAO,EAAA;MACxD,OAAO,qBAAA,CAAsB,IAAA,EAAM,gBAAA,CAAiB,QAAA,CAAA,IAAa,QAAA,EAAU,OAAA,CAAQ;;;IAIrF,SAAS,YAAA,CAAa,EAAA,EAA8C,OAAA,EAAyB;MAC3F,IAAI,SAAA,GAAY,EAAA;MAChB,KAAK,MAAM,IAAA,IAAQ,QAAA,CAAS,EAAA,CAAG,EAAE,SAAA,IAAa,cAAA,CAAe,IAAA,EAAM,OAAA,CAAQ;MAC3E,OAAO,SAAA;;;IAIT,SAAS,qBAAA,CACP,IAAA,EACA,OAAA,EACA,SAAA,EACA,YAAA,EACA,gBAAA,EACQ;MACR,MAAM,IAAA,GAAO,WAAA,CAAA,CAAa;MAC1B,MAAM,CAAA,GAAI,QAAA,CAAA,CAAU;MACpB,SAAA,CAAU,IAAA,CAAK,SAAS,IAAA,gCAAK,CAAgC;MAC7D,IAAI,gBAAA,EACF,SAAA,CAAU,IAAA,CACR,GAAG,SAAA,iBAA0B,IAAA,KAAS,SAAA,eAAwB,YAAA,IAAa,CAC5E,CAAA,KAED,SAAA,CAAU,IAAA,CAAK,GAAG,OAAA,gBAAuB,IAAA,GAAK,CAAG;MAEnD,SAAA,CAAU,IAAA,CAAK,SAAS,CAAA,oBAAqB,IAAA,WAAe,IAAA,KAAK,CAAK;MACtE,OAAO,gBAAA,GAAmB,KAAA,GAAQ,EAAA;;;IAIpC,SAAS,mBAAA,CACP,IAAA,EACA,OAAA,EACA,SAAA,EACA,YAAA,EACA,gBAAA,EACQ;MACR,IAAI,gBAAA,EAAkB;QACpB,MAAM,IAAA,GAAO,WAAA,CAAA,CAAa;QAC1B,SAAA,CAAU,IAAA,CAAK,SAAS,IAAA,8BAAkC,IAAA,GAAK,CAAG;QAClE,SAAA,CAAU,IAAA,CACR,GAAG,SAAA,iBAA0B,IAAA,KAAS,SAAA,eAAwB,YAAA,IAAa,CAC5E;QACD,OAAO,KAAA;;MAET,SAAA,CAAU,IAAA,CAAK,GAAG,OAAA,kBAAyB,IAAA,EAAA,CAAO;MAClD,OAAO,EAAA;;;IAIT,SAAS,eAAA,CACP,KAAA,EACA,OAAA,EACA,SAAA,EACA,QAAA,EACA,YAAA,EACA,YAAA,EACe;MACf,IAAI,KAAA,CAAM,IAAA,KAAS,MAAA,EAAQ,OAAO,cAAA,CAAe,KAAA,CAAM,IAAA,CAAK;MAC5D,IAAI,KAAA,CAAM,IAAA,KAAS,SAAA,EAAW;QAC5B,MAAM,aAAA,GAAgB,QAAA,GAClB,GAAG,SAAA,eAAwB,YAAA,GAAa,GACxC,GAAG,SAAA,aAAsB,KAAA,CAAM,OAAA,GAAQ;QAC3C,OAAO,cAAA,CAAe,KAAA,CAAM,IAAA,EAAM,aAAA,CAAc;;MAGlD,MAAM,gBAAA,GAAmB,QAAA,IAAY,YAAA;MACrC,MAAM;QAAE,IAAA;QAAM;MAAA,CAAA,GAAe,cAAA,CAAe,KAAA,CAAM,UAAA,CAAW;MAC7D,IAAI,UAAA,EACF,OAAO,qBAAA,CAAsB,IAAA,EAAM,OAAA,EAAS,SAAA,EAAW,YAAA,EAAc,gBAAA,CAAiB;MAExF,OAAO,mBAAA,CAAoB,IAAA,EAAM,OAAA,EAAS,SAAA,EAAW,YAAA,EAAc,gBAAA,CAAiB;;;IAItF,SAAS,eAAA,CAAgB,EAAA,EAAmB,OAAA,EAAiB,QAAA,EAAiC;MAC5F,MAAM,YAAA,GAAe,eAAA,CAAgB,EAAA,CAAG,QAAA,CAAS;MACjD,MAAM;QAAE,QAAA;QAAU;MAAA,CAAA,GAAiB,eAAA,CAAgB,YAAA,CAAa;MAChE,MAAM,SAAA,GAAY,QAAA,KAAa,QAAA,GAAW,QAAA,GAAW,OAAA;MAErD,IAAI,IAAA,GAAO,EAAA;MACX,IAAI,YAAA,GAAe,CAAA;MAEnB,KAAK,MAAM,KAAA,IAAS,YAAA,EAAc;QAChC,MAAM,SAAA,GAAY,eAAA,CAChB,KAAA,EACA,OAAA,EACA,SAAA,EACA,QAAA,EACA,YAAA,EACA,YAAA,CACD;QACD,IAAI,SAAA,KAAc,IAAA,EAAM,OAAO,IAAA;QAC/B,IAAA,IAAQ,SAAA;QACR,YAAA,EAAA;;MAGF,OAAO,IAAA;;;IAIT,SAAS,cAAA,CACP,EAAA,EACA,QAAA,EACe;MACf,MAAM,GAAA,GAAM,UAAA,CAAW,EAAA,CAAG;MAC1B,IAAI,CAAC,GAAA,EAAK,OAAO,IAAA;MAEjB,MAAM,OAAA,GAAU,iBAAA,CAAkB,QAAA,EAAU,iBAAA,CAAkB,EAAA,CAAG,CAAC;MAElE,IAAI,IAAA,GAAO,IAAI,GAAA,GADG,YAAA,CAAa,EAAA,EAAI,OAAA,CAAQ,GACZ;MAE/B,IAAI,EAAA,CAAG,YAAA,CAAa,EAAA,CAAG,EAAE;QACvB,MAAM,SAAA,GAAY,eAAA,CAAgB,EAAA,EAAI,OAAA,EAAS,QAAA,CAAS;QACxD,IAAI,SAAA,KAAc,IAAA,EAAM,OAAO,IAAA;QAC/B,IAAA,IAAQ,SAAA;;MAGV,IAAI,CAAC,aAAA,CAAc,GAAA,CAAI,GAAA,CAAI,EAAE,IAAA,IAAQ,KAAK,GAAA,GAAI;MAC9C,OAAO,IAAA;;IAGT,MAAM,IAAA,GAAO,cAAA,CAAe,IAAA,EAAM,QAAA,CAAS;IAC3C,IAAI,IAAA,KAAS,IAAA,EAAM,OAAO,IAAA;IAG1B,MAAM,OAAA,GAAU,IAAA,CAAK,OAAA,CAAQ,KAAA,EAAO,MAAA,CAAO,CAAC,OAAA,CAAQ,IAAA,EAAM,MAAA,CAAM;IAEhE,IAAI,SAAA,CAAU,MAAA,KAAW,CAAA,IAAK,aAAA,CAAc,MAAA,KAAW,CAAA,EACrD,OAAO,SAAS,OAAA,gBAAQ;IAG1B,IAAI,IAAA,GAAO,SAAA,CAAU,GAAA,CAAK,CAAA,IAAM,KAAK,CAAA,EAAA,CAAI,CAAC,IAAA,CAAK,IAAA,CAAK;IACpD,IAAI,aAAA,CAAc,MAAA,GAAS,CAAA,EACzB,IAAA,IAAQ,sBAAsB,aAAA,CAAc,GAAA,CAAK,CAAA,IAAM,GAAG,CAAA,IAAE,CAAI,CAAC,IAAA,CAAK,IAAA,CAAK,IAAC,CAAA,KAE5E,IAAA,IAAQ,iBAAA;IAGV,OAAO,SAAS,OAAA,qBAA4B,IAAA,MAAK;;;EAUnD,SAAS,gBAAA,CACP,KAAA,EACA,GAAA,EACA,UAAA,EACA,OAAA,EACM;IACN,IAAI,EAAA,CAAG,SAAA,CAAU,KAAA,CAAM,EAAE;MACvB,MAAM,OAAA,GAAU,KAAA,CAAM,IAAA,CAAK,OAAA,CAAQ,QAAA,EAAU,EAAA,CAAG,CAAC,IAAA,CAAA,CAAM;MACvD,IAAI,OAAA,EAAS,GAAA,CAAI,IAAA,CAAK;QAAE,IAAA,EAAM,MAAA;QAAQ,IAAA,EAAM;OAAS,CAAC;MACtD;;IAEF,IAAI,EAAA,CAAG,YAAA,CAAa,KAAA,CAAM,IAAI,EAAA,CAAG,uBAAA,CAAwB,KAAA,CAAM,EAAE;MAC/D,GAAA,CAAI,IAAA,CAAK;QAAE,IAAA,EAAM,SAAA;QAAW,IAAA,EAAM,KAAA;QAAO,OAAA,EAAS,UAAA,CAAW,KAAA;OAAS,CAAC;MACvE;;IAEF,IAAI,EAAA,CAAG,eAAA,CAAgB,KAAA,CAAM,EAAE;MAC7B,IAAI,KAAA,CAAM,UAAA,EAAY,GAAA,CAAI,IAAA,CAAK;QAAE,IAAA,EAAM,YAAA;QAAc,UAAA,EAAY,KAAA,CAAM;OAAY,CAAC;MACpF;;IAEF,IAAI,EAAA,CAAG,aAAA,CAAc,KAAA,CAAM,EAAE,OAAA,CAAQ,KAAA,CAAM,QAAA,CAAS;;;;;;EAOtD,SAAS,eAAA,CAAgB,QAAA,EAAkD;IACzE,MAAM,QAAA,GAAwB,EAAE;IAChC,MAAM,UAAA,GAAa;MAAE,KAAA,EAAO;IAAA,CAAG;IAE/B,SAAS,WAAA,CAAY,IAAA,EAAuC;MAC1D,KAAK,MAAM,KAAA,IAAS,IAAA,EAAM,gBAAA,CAAiB,KAAA,EAAO,QAAA,EAAU,UAAA,EAAY,WAAA,CAAY;;IAGtF,WAAA,CAAY,QAAA,CAAS;IACrB,OAAO,QAAA;;;EAIT,SAAS,eAAA,CAAgB,YAAA,EAGvB;IACA,MAAM,OAAA,GAAU,YAAA,CAAa,IAAA,CAAM,CAAA,IAAM,CAAA,CAAE,IAAA,KAAS,SAAA,CAAU;IAC9D,MAAM,UAAA,GAAa,YAAA,CAAa,IAAA,CAAM,CAAA,IAAM,CAAA,CAAE,IAAA,KAAS,SAAA,CAAU;IACjE,MAAM,SAAA,GAAY,YAAA,CAAa,MAAA,CAAQ,CAAA,IAAM,CAAA,CAAE,IAAA,KAAS,YAAA,CAAa,CAAC,MAAA;IACtE,OAAO;MAAE,QAAA,EAAU,OAAA,IAAW,UAAA;MAAY,YAAA,EAAc,SAAA,GAAY;KAAG;;;EAIzE,SAAS,aAAA,CAAc,IAAA,EAAoC;IACzD,IAAI,CAAC,EAAA,CAAG,cAAA,CAAe,IAAA,CAAK,EAAE,OAAO,KAAA;IACrC,MAAM,IAAA,GAAO,EAAA,CAAG,YAAA,CAAa,IAAA,CAAK,IAAA,CAAK,GAAG,IAAA,CAAK,IAAA,CAAK,IAAA,GAAO,EAAA;IAC3D,IAAI,IAAA,KAAS,KAAA,EAAO,OAAO,IAAA;IAC3B,IAAI,QAAA,CAAS,IAAA,CAAK,IAAA,CAAK,EAAE,OAAO,IAAA;IAChC,IAAI,CAAC,IAAA,CAAK,WAAA,IAAe,CAAC,EAAA,CAAG,eAAA,CAAgB,IAAA,CAAK,WAAA,CAAY,EAAE,OAAO,KAAA;IACvE,MAAM,IAAA,GAAO,IAAA,CAAK,WAAA,CAAY,UAAA;IAC9B,OAAO,IAAA,GAAO,CAAC,QAAA,CAAS,IAAA,CAAK,GAAG,KAAA;;;EAIlC,SAAS,iBAAA,CAAkB,IAAA,EAAyD;IAClF,IAAI,QAAA,CAAS,IAAA,CAAK,CAAC,IAAA,CAAK,aAAA,CAAc,EAAE,OAAO,IAAA;IAC/C,IAAI,EAAA,CAAG,YAAA,CAAa,IAAA,CAAK,EACvB,OAAO,IAAA,CAAK,QAAA,CAAS,IAAA,CAAM,CAAA,IAAM,EAAA,CAAG,eAAA,CAAgB,CAAA,CAAE,IAAI,CAAA,CAAE,UAAA,KAAe,KAAA,CAAA,CAAU;IAEvF,OAAO,KAAA;;;EAIT,SAAS,SAAA,CAAU,IAAA,EAA6B;IAC9C,OAAO,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,QAAA,CAAS,EAAA,CAAG,EAAE,IAAA,CAAK,MAAA,CAAA,CAAQ,CAAC;;;EAIrD,SAAS,UAAA,CAAW,IAAA,EAAwD;IAC1E,MAAM,GAAA,GAAM,EAAA,CAAG,YAAA,CAAa,IAAA,CAAK,GAAG,IAAA,CAAK,cAAA,CAAe,OAAA,GAAU,IAAA,CAAK,OAAA;IACvE,OAAO,EAAA,CAAG,YAAA,CAAa,GAAA,CAAI,GAAG,GAAA,CAAI,IAAA,GAAO,EAAA;;;EAI3C,SAAS,QAAA,CACP,IAAA,EACmC;IACnC,OAAO,EAAA,CAAG,YAAA,CAAa,IAAA,CAAK,GACxB,IAAA,CAAK,cAAA,CAAe,UAAA,CAAW,UAAA,GAC/B,IAAA,CAAK,UAAA,CAAW,UAAA;;;AA4BxB,SAAS,WAAA,CAAY,CAAA,EAAoB;EACvC,OAAO,CAAA,CAAE,MAAA,GAAS,CAAA,IAAK,CAAA,CAAE,CAAA,CAAA,KAAO,CAAA,CAAE,CAAA,CAAA,EAAI,WAAA,CAAA,CAAa;;;AAIrD,SAAS,iBAAA,CAAkB,IAAA,EAAwB;EACjD,IAAI,EAAA,CAAG,YAAA,CAAa,IAAA,CAAK,IAAI,EAAA,CAAG,uBAAA,CAAwB,IAAA,CAAK,IAAI,EAAA,CAAG,aAAA,CAAc,IAAA,CAAK,EACrF,OAAO,IAAA;EACT,OAAO,EAAA,CAAG,YAAA,CAAa,IAAA,EAAM,iBAAA,CAAkB,IAAI,KAAA;;AAGrD,SAAS,cAAA,CAAe,CAAA,EAAmB;EACzC,OAAO,CAAA,CAAE,OAAA,CAAQ,IAAA,EAAM,OAAA,CAAQ,CAAC,OAAA,CAAQ,IAAA,EAAM,QAAA,CAAS;;AAGzD,SAAS,cAAA,CAAe,CAAA,EAAmB;EACzC,OAAO,CAAA,CAAE,OAAA,CAAQ,IAAA,EAAM,OAAA,CAAQ,CAAC,OAAA,CAAQ,IAAA,EAAM,MAAA,CAAO;;AAOvD,SAAS,eAAA,CAAgB,IAAA,EAA8B;EACrD,IAAI,EAAA,CAAG,uBAAA,CAAwB,IAAA,CAAK,EAClC,OAAO,aAAA,CAAc,IAAA,CAAK,UAAA,CAAW;EAEvC,IAAI,EAAA,CAAG,aAAA,CAAc,IAAA,CAAK,EACxB,OAAO,IAAA,CAAK,QAAA,CAAS,KAAA,CAAM,aAAA,CAAc;EAG3C,OAAO,aAAA,CAAc,IAAA,CAAK,cAAA,CAAe,UAAA,CAAW,IAAI,IAAA,CAAK,QAAA,CAAS,KAAA,CAAM,aAAA,CAAc;;AAG5F,SAAS,aAAA,CAAc,KAAA,EAAkC;EACvD,OAAO,KAAA,CAAM,UAAA,CAAW,KAAA,CAAO,IAAA,IAAS;IAEtC,IAAI,CAAC,EAAA,CAAG,cAAA,CAAe,IAAA,CAAK,EAAE,OAAO,KAAA;IAErC,IAAI,CAAC,IAAA,CAAK,WAAA,EAAa,OAAO,IAAA;IAE9B,IAAI,EAAA,CAAG,eAAA,CAAgB,IAAA,CAAK,WAAA,CAAY,EAAE,OAAO,IAAA;IAEjD,MAAM,IAAA,GAAQ,IAAA,CAAK,WAAA,CAAiC,UAAA;IACpD,OAAO,IAAA,GAAO,QAAA,CAAS,IAAA,CAAK,GAAG,IAAA;IAC/B;;AAGJ,SAAS,aAAA,CAAc,KAAA,EAA6B;EAElD,IAAI,EAAA,CAAG,SAAA,CAAU,KAAA,CAAM,EAAE,OAAO,IAAA;EAEhC,IAAI,EAAA,CAAG,uBAAA,CAAwB,KAAA,CAAM,EAAE,OAAO,eAAA,CAAgB,KAAA,CAAM;EACpE,IAAI,EAAA,CAAG,YAAA,CAAa,KAAA,CAAM,EAAE,OAAO,eAAA,CAAgB,KAAA,CAAM;EACzD,IAAI,EAAA,CAAG,aAAA,CAAc,KAAA,CAAM,EAAE,OAAO,eAAA,CAAgB,KAAA,CAAM;EAE1D,MAAM,IAAA,GAAQ,KAAA,CAA2B,UAAA;EACzC,OAAO,IAAA,GAAO,QAAA,CAAS,IAAA,CAAK,GAAG,IAAA;;AAKjC,SAAS,QAAA,CAAS,IAAA,EAA8B;EAC9C,OACE,EAAA,CAAG,eAAA,CAAgB,IAAA,CAAK,IACxB,EAAA,CAAG,gBAAA,CAAiB,IAAA,CAAK,IACzB,EAAA,CAAG,+BAAA,CAAgC,IAAA,CAAK,IACxC,IAAA,CAAK,IAAA,KAAS,EAAA,CAAG,UAAA,CAAW,WAAA,IAC5B,IAAA,CAAK,IAAA,KAAS,EAAA,CAAG,UAAA,CAAW,YAAA,IAC5B,IAAA,CAAK,IAAA,KAAS,EAAA,CAAG,UAAA,CAAW,WAAA,IAC5B,IAAA,CAAK,IAAA,KAAS,EAAA,CAAG,UAAA,CAAW,gBAAA;;AAIhC,SAAS,UAAA,CAAW,IAAA,EAA8B;EAEhD,IAAI,EAAA,CAAG,eAAA,CAAgB,IAAA,CAAK,IAAI,EAAA,CAAG,oBAAA,CAAqB,IAAA,CAAK,EAAE,OAAO,KAAA;EAEtE,IAAI,QAAA,CAAS,IAAA,CAAK,EAAE,OAAO,KAAA;EAK3B,OAAO,YAAA,CAAa,IAAA,CAAK;;AAG3B,SAAS,YAAA,CAAa,IAAA,EAAwB;EAC5C,IAAI,EAAA,CAAG,gBAAA,CAAiB,IAAA,CAAK,EAAE,OAAO,IAAA;EACtC,IAAI,EAAA,CAAG,0BAAA,CAA2B,IAAA,CAAK,EAAE,OAAO,IAAA;EAEhD,IAAI,EAAA,CAAG,eAAA,CAAgB,IAAA,CAAK,IAAI,EAAA,CAAG,oBAAA,CAAqB,IAAA,CAAK,EAAE,OAAO,KAAA;EACtE,OAAO,EAAA,CAAG,YAAA,CAAa,IAAA,EAAM,YAAA,CAAa,IAAI,KAAA"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
//#region src/jsx.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* JSX transform — wraps dynamic JSX expressions in `() =>` so the Pyreon runtime
|
|
4
|
+
* receives reactive getters instead of eagerly-evaluated snapshot values.
|
|
5
|
+
*
|
|
6
|
+
* Rules:
|
|
7
|
+
* - `<div>{expr}</div>` → `<div>{() => expr}</div>` (child)
|
|
8
|
+
* - `<div class={expr}>` → `<div class={() => expr}>` (prop)
|
|
9
|
+
* - `<button onClick={fn}>` → unchanged (event handler)
|
|
10
|
+
* - `<div>{() => expr}</div>` → unchanged (already wrapped)
|
|
11
|
+
* - `<div>{"literal"}</div>` → unchanged (static)
|
|
12
|
+
*
|
|
13
|
+
* Static VNode hoisting:
|
|
14
|
+
* - Fully static JSX in expression containers is hoisted to module scope:
|
|
15
|
+
* `{<span>Hello</span>}` → `const _$h0 = <span>Hello</span>` + `{_$h0}`
|
|
16
|
+
* - Hoisted nodes are created ONCE at module initialisation, not per-instance.
|
|
17
|
+
* - A JSX node is static if: all props are string literals / booleans / static
|
|
18
|
+
* values, and all children are text nodes or other static JSX nodes.
|
|
19
|
+
*
|
|
20
|
+
* Template emission:
|
|
21
|
+
* - JSX element trees with ≥ 2 DOM elements (no components, no spread attrs)
|
|
22
|
+
* are compiled to `_tpl(html, bindFn)` calls instead of nested `h()` calls.
|
|
23
|
+
* - The HTML string is parsed once via <template>.innerHTML, then cloneNode(true)
|
|
24
|
+
* for each instance (~5-10x faster than sequential createElement calls).
|
|
25
|
+
* - Static attributes are baked into the HTML string; dynamic attributes and
|
|
26
|
+
* text content use renderEffect in the bind function.
|
|
27
|
+
*
|
|
28
|
+
* Implementation: TypeScript parser for positions + magic-string replacements.
|
|
29
|
+
* No extra runtime dependencies — `typescript` is already in devDependencies.
|
|
30
|
+
*
|
|
31
|
+
* Known limitation (v0): expressions inside *nested* JSX within a child
|
|
32
|
+
* expression container are not individually wrapped. They are still reactive
|
|
33
|
+
* because the outer wrapper re-evaluates the whole subtree, just at a coarser
|
|
34
|
+
* granularity. Fine-grained nested wrapping is planned for a future pass.
|
|
35
|
+
*/
|
|
36
|
+
interface CompilerWarning {
|
|
37
|
+
/** Warning message */
|
|
38
|
+
message: string;
|
|
39
|
+
/** Source file line number (1-based) */
|
|
40
|
+
line: number;
|
|
41
|
+
/** Source file column number (0-based) */
|
|
42
|
+
column: number;
|
|
43
|
+
/** Warning code for filtering */
|
|
44
|
+
code: "signal-call-in-jsx" | "missing-key-on-for" | "signal-in-static-prop";
|
|
45
|
+
}
|
|
46
|
+
interface TransformResult {
|
|
47
|
+
/** Transformed source code (JSX preserved, only expression containers modified) */
|
|
48
|
+
code: string;
|
|
49
|
+
/** Whether the output uses _tpl/_re template helpers (needs auto-import) */
|
|
50
|
+
usesTemplates?: boolean;
|
|
51
|
+
/** Compiler warnings for common mistakes */
|
|
52
|
+
warnings: CompilerWarning[];
|
|
53
|
+
}
|
|
54
|
+
declare function transformJSX(code: string, filename?: string): TransformResult;
|
|
55
|
+
//#endregion
|
|
56
|
+
export { type CompilerWarning, type TransformResult, transformJSX };
|
|
57
|
+
//# sourceMappingURL=index2.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index2.d.ts","names":[],"sources":["../../src/jsx.ts"],"mappings":";;AAqCA;;;;;;;;;;AAWA;;;;;;;;;;AAcA;;;;;;;;;;;;;UAzBiB,eAAA;;EAEf,OAAA;;EAEA,IAAA;;EAEA,MAAA;;EAEA,IAAA;AAAA;AAAA,UAGe,eAAA;;EAEf,IAAA;;EAEA,aAAA;;EAEA,QAAA,EAAU,eAAA;AAAA;AAAA,iBAQI,YAAA,CAAa,IAAA,UAAc,QAAA,YAAyB,eAAA"}
|