@barefootjs/blade 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.
Files changed (72) hide show
  1. package/README.md +73 -0
  2. package/dist/adapter/analysis/component-tree.d.ts +26 -0
  3. package/dist/adapter/analysis/component-tree.d.ts.map +1 -0
  4. package/dist/adapter/blade-adapter.d.ts +537 -0
  5. package/dist/adapter/blade-adapter.d.ts.map +1 -0
  6. package/dist/adapter/boolean-result.d.ts +76 -0
  7. package/dist/adapter/boolean-result.d.ts.map +1 -0
  8. package/dist/adapter/emit-context.d.ts +105 -0
  9. package/dist/adapter/emit-context.d.ts.map +1 -0
  10. package/dist/adapter/expr/array-method.d.ts +74 -0
  11. package/dist/adapter/expr/array-method.d.ts.map +1 -0
  12. package/dist/adapter/expr/emitters.d.ts +176 -0
  13. package/dist/adapter/expr/emitters.d.ts.map +1 -0
  14. package/dist/adapter/expr/operand.d.ts +25 -0
  15. package/dist/adapter/expr/operand.d.ts.map +1 -0
  16. package/dist/adapter/index.d.ts +6 -0
  17. package/dist/adapter/index.d.ts.map +1 -0
  18. package/dist/adapter/index.js +189060 -0
  19. package/dist/adapter/lib/blade-naming.d.ts +128 -0
  20. package/dist/adapter/lib/blade-naming.d.ts.map +1 -0
  21. package/dist/adapter/lib/constants.d.ts +21 -0
  22. package/dist/adapter/lib/constants.d.ts.map +1 -0
  23. package/dist/adapter/lib/ir-scope.d.ts +48 -0
  24. package/dist/adapter/lib/ir-scope.d.ts.map +1 -0
  25. package/dist/adapter/lib/types.d.ts +27 -0
  26. package/dist/adapter/lib/types.d.ts.map +1 -0
  27. package/dist/adapter/memo/seed.d.ts +84 -0
  28. package/dist/adapter/memo/seed.d.ts.map +1 -0
  29. package/dist/adapter/props/prop-classes.d.ts +34 -0
  30. package/dist/adapter/props/prop-classes.d.ts.map +1 -0
  31. package/dist/adapter/spread/spread-codegen.d.ts +72 -0
  32. package/dist/adapter/spread/spread-codegen.d.ts.map +1 -0
  33. package/dist/adapter/value/parsed-literal.d.ts +27 -0
  34. package/dist/adapter/value/parsed-literal.d.ts.map +1 -0
  35. package/dist/build.d.ts +28 -0
  36. package/dist/build.d.ts.map +1 -0
  37. package/dist/build.js +189080 -0
  38. package/dist/conformance-pins.d.ts +12 -0
  39. package/dist/conformance-pins.d.ts.map +1 -0
  40. package/dist/index.d.ts +9 -0
  41. package/dist/index.d.ts.map +1 -0
  42. package/dist/index.js +189079 -0
  43. package/package.json +67 -0
  44. package/php/composer.json +32 -0
  45. package/php/src/BladeBackend.php +197 -0
  46. package/php/src/naming.php +84 -0
  47. package/php/tests/test_render.php +159 -0
  48. package/src/__tests__/blade-adapter-unit.test.ts +392 -0
  49. package/src/__tests__/blade-adapter.test.ts +52 -0
  50. package/src/__tests__/blade-counter.test.ts +63 -0
  51. package/src/__tests__/blade-query-href.test.ts +113 -0
  52. package/src/__tests__/blade-spread-attrs.test.ts +235 -0
  53. package/src/adapter/analysis/component-tree.ts +119 -0
  54. package/src/adapter/blade-adapter.ts +1912 -0
  55. package/src/adapter/boolean-result.ts +168 -0
  56. package/src/adapter/emit-context.ts +117 -0
  57. package/src/adapter/expr/array-method.ts +345 -0
  58. package/src/adapter/expr/emitters.ts +636 -0
  59. package/src/adapter/expr/operand.ts +35 -0
  60. package/src/adapter/index.ts +6 -0
  61. package/src/adapter/lib/blade-naming.ts +180 -0
  62. package/src/adapter/lib/constants.ts +33 -0
  63. package/src/adapter/lib/ir-scope.ts +83 -0
  64. package/src/adapter/lib/types.ts +30 -0
  65. package/src/adapter/memo/seed.ts +135 -0
  66. package/src/adapter/props/prop-classes.ts +66 -0
  67. package/src/adapter/spread/spread-codegen.ts +179 -0
  68. package/src/adapter/value/parsed-literal.ts +75 -0
  69. package/src/build.ts +37 -0
  70. package/src/conformance-pins.ts +86 -0
  71. package/src/index.ts +9 -0
  72. package/src/test-render.ts +782 -0
package/README.md ADDED
@@ -0,0 +1,73 @@
1
+ # @barefootjs/blade
2
+
3
+ Laravel Blade (PHP) adapter for BarefootJS: compiles the BarefootJS IR
4
+ (JSX → IR, see `spec/compiler.md`) into `.blade.php` template files plus the
5
+ client JS bundle every other adapter produces, and ships a PHP rendering
6
+ runtime (`php/src/`) that renders those templates through `illuminate/view`
7
+ used standalone — no Laravel application/container is required.
8
+
9
+ Near-mechanical port of `@barefootjs/twig` (the Twig adapter) to Blade
10
+ syntax. See `src/adapter/blade-adapter.ts`'s header comment for the full
11
+ Twig↔Blade syntax-mapping table and the JS/PHP semantics divergences this
12
+ port handles uniformly (truthiness, stringification, reserved-word
13
+ identifier mangling, `$bf->eq`/`$bf->neq` for JS strict equality, `data_get`
14
+ for polymorphic member/index access, and the evaluator-only higher-order-
15
+ callback lowering since Blade has no lambda expression).
16
+
17
+ ## Template output shape
18
+
19
+ - `name: 'blade'`, `extension: '.blade.php'`, `templatesPerComponent: true` —
20
+ one `.blade.php` file per component, named by snake-casing the PascalCase
21
+ component name (`UserCard` → `user_card.blade.php`).
22
+ - Hydration markers (`bf-s`, `bf-h`/`bf-m`/`bf-r`, `bf-p`, slot/conditional
23
+ comment markers, loop boundary comments) use the SAME runtime method
24
+ names as every other adapter's `bf.*` calls, spelled as PHP method calls
25
+ on the `$bf` variable (`$bf->scope_attr()`, `$bf->hydration_attrs()`,
26
+ `$bf->text_start`/`text_end`, `$bf->comment(...)`, …) — see
27
+ `spec/template-helpers.md` for the shared helper contract.
28
+ - Every text/attribute interpolation of a possibly-non-string value is
29
+ routed through `$bf->string(...)` (or `$bf->bool_str(...)` for
30
+ boolean-shaped values); every non-comparison condition position is
31
+ routed through `$bf->truthy(...)`; every JS `===`/`!==` comparison routes
32
+ through `$bf->eq(...)`/`$bf->neq(...)` (PHP's own `==`/`===` are either
33
+ loose or number-representation-sensitive in ways that diverge from JS
34
+ strict equality). All are pure PHP-runtime helpers — see the PHP runtime
35
+ pointer below.
36
+
37
+ ## PHP runtime
38
+
39
+ `php/src/` is a self-contained PHP package (dependencies: `illuminate/view`
40
+ and `barefootjs/runtime`) implementing the engine-agnostic `bf` object
41
+ every emitted template calls into: hydration markers, context propagation
42
+ (`provide_context`/`use_context`), child-component rendering
43
+ (`render_child`), script registration, and the JS-compatible helper
44
+ library (`string`, `bool_str`, `truthy`, `number`, `floor`/`ceil`/`round`,
45
+ array/string helpers, the `*_eval` evaluator helpers, `spread_attrs`,
46
+ `query`, `eq`/`neq`, …). It mirrors the layering of
47
+ `packages/adapter-perl/lib/` (an engine-agnostic core plus a thin
48
+ per-engine backend) — see `spec/template-helpers.md` for the semantic
49
+ contract each helper must satisfy, and the package's own tests under
50
+ `php/tests/`.
51
+
52
+ ## Usage
53
+
54
+ ```ts
55
+ // barefoot.config.ts
56
+ import { createConfig } from '@barefootjs/blade/build'
57
+
58
+ export default createConfig({
59
+ components: ['./src/components'],
60
+ outDir: './dist',
61
+ })
62
+ ```
63
+
64
+ `bf build` then emits `.blade.php` templates + client JS under `outDir`. A
65
+ PHP host renders a component by constructing an `illuminate/view` `Factory`
66
+ standalone (`Filesystem` + event `Dispatcher` + `EngineResolver` registering
67
+ a `blade` engine over a `BladeCompiler` + `FileViewFinder`, all wired
68
+ together by the `Factory` — see `php/src/BladeBackend.php`'s constructor)
69
+ pointed at the emitted templates, wiring in the PHP `BladeBackend` as the
70
+ render backend. Blade's `{{ }}` echo (`Illuminate\Support\e()`) emits named
71
+ HTML entity forms (`"`/`'` via `ENT_QUOTES`) where Perl/Go/
72
+ markupsafe emit the numeric `"`/`'` forms — see the adapter header
73
+ comment for how that byte-form difference is handled.
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Component-tree analysis for the Blade template adapter.
3
+ *
4
+ * Ported from `packages/adapter-jinja/src/adapter/analysis/component-tree.ts`.
5
+ * Pure functions over the IR — they read no adapter instance state.
6
+ * `collectImportedLoopChildComponentErrors` returns its diagnostics instead
7
+ * of pushing onto the adapter's error list, so the adapter stays the sole
8
+ * owner of `errors`.
9
+ */
10
+ import type { ComponentIR, CompilerError } from '@barefootjs/jsx';
11
+ /**
12
+ * Whether the component needs the client runtime — it owns reactive state
13
+ * (signals / effects / onMount) or the analyzer flagged it as needing init.
14
+ */
15
+ export declare function hasClientInteractivity(ir: ComponentIR): boolean;
16
+ /**
17
+ * Build a `BF103` diagnostic for every component reference inside a loop body
18
+ * whose name is imported from a relative-path module. Mirror of the Go /
19
+ * Jinja adapter's check — the Blade adapter has the same
20
+ * cross-template-registration constraint at request time (each `.blade.php`
21
+ * component file must be registered with the shared Blade `Environment`
22
+ * loader alongside the parent). Returns the diagnostics so the caller pushes
23
+ * them onto its own error list.
24
+ */
25
+ export declare function collectImportedLoopChildComponentErrors(ir: ComponentIR, componentName: string): CompilerError[];
26
+ //# sourceMappingURL=component-tree.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component-tree.d.ts","sourceRoot":"","sources":["../../../src/adapter/analysis/component-tree.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,WAAW,EAUX,aAAa,EACd,MAAM,iBAAiB,CAAA;AAExB;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,WAAW,GAAG,OAAO,CAO/D;AAED;;;;;;;;GAQG;AACH,wBAAgB,uCAAuC,CACrD,EAAE,EAAE,WAAW,EACf,aAAa,EAAE,MAAM,GACpB,aAAa,EAAE,CAqEjB"}
@@ -0,0 +1,537 @@
1
+ /**
2
+ * BarefootJS Blade (PHP) Template Adapter
3
+ *
4
+ * Generates Laravel Blade template files (.blade.php) from BarefootJS IR.
5
+ *
6
+ * Near-mechanical port of the Twig (PHP) adapter
7
+ * (packages/adapter-twig/src/adapter/twig-adapter.ts) — itself a
8
+ * near-mechanical port of the Jinja2 adapter — from Twig syntax to Blade
9
+ * syntax. Both Twig and Blade render through PHP, so most of the JS/PHP
10
+ * semantic divergences documented in the Twig port CARRY OVER unchanged
11
+ * (truthiness, stringification, `bf`→`$bf->`-method-call routing, evaluator-
12
+ * JSON callbacks, `===`/`!==` via `eq`/`neq`, reserved-word mangling,
13
+ * in-template self-reference seeding). What's DIFFERENT is the surrounding
14
+ * template syntax — Blade compiles straight to raw PHP rather than its own
15
+ * expression language, so there is no `strict_variables: false` engine-wide
16
+ * forgiveness, no polymorphic `.`/`[]`, and every variable carries PHP's `$`
17
+ * sigil:
18
+ *
19
+ * Twig `{{ EXPR }}` (escaped) → Blade `{!! e(EXPR) !!}` — NOT bare `{{ EXPR }}` (see divergence 0 below: Blade's OWN `{{ }}` would be the natural mapping and DOES compile to `echo e(EXPR)`, but its compiler's regex-based tag matching breaks on evaluator-JSON payload text, so every escaped interpolation in THIS adapter's output explicitly spells out the same `e(...)` call under the `{!! !!}` delimiter instead)
20
+ * Twig `{{ EXPR | raw }}` → Blade `{!! EXPR !!}`
21
+ * Twig `bf.method(args)` → Blade `$bf->method(args)`
22
+ * Twig bare var `name` → Blade `$name` (mangled via `bladeIdent`/`bladeVar` — see divergence 1)
23
+ * Twig `{% if C %}…{% elseif %}…{% else %}…{% endif %}` → Blade `@if(C)…@elseif(…)…@else…@endif`
24
+ * Twig `{% for x in arr %}…{% endfor %}` → Blade `@foreach((arr ?? []) as $x)…@endforeach` (see divergence 2: raw PHP `foreach` over `null` warns, Twig's `strict_variables: false` didn't)
25
+ * Twig `{% set x = e %}` → Blade `@php($x = e)`
26
+ * Twig `{'k': v}` hash → Blade `['k' => v]` PHP array literal (still ALWAYS-quoted keys — see `lib/blade-naming.ts`)
27
+ * Twig `~` concat → Blade `.` concat (same `$bf->string(...)` routing policy)
28
+ * Twig `(t ? a : b)` ternary → Blade same (PHP ternary, unchanged syntax)
29
+ * Twig `l ?? r` → Blade same (PHP `??` also silences undefined-variable/index — see divergence 3)
30
+ * Twig `bf.eq`/`bf.neq` for `===`/`!==` → Blade `$bf->eq`/`$bf->neq` — NEVER PHP `==` (loose) nor `===` (`1 === 1.0` is `false` in PHP)
31
+ * Twig `bf.truthy` in test positions → Blade `$bf->truthy(...)` — same policy (PHP falsiness diverges from JS)
32
+ * Twig `{% set NAME %}…{% endset %}` capture → Blade output buffering: `@php(ob_start())` … content … `@php($NAME = $bf->backend->mark_raw(preg_replace('/\n\z/', '', ob_get_clean(), 1)))` (see divergence 4)
33
+ * Twig `.twig` files, `<snake_case>.twig` → Blade `.blade.php` files, `<snake_case>.blade.php` (`extension = '.blade.php'`)
34
+ * Twig `a.b` / `a[i]` member/index access → Blade `data_get($a, 'b')` / `data_get($a, $i)` (see divergence 5 — the one place Twig's polymorphic `.` has no raw-PHP equivalent)
35
+ * Twig evaluator-JSON `*_eval` payloads for callbacks → UNCHANGED — same mechanism, same shared `Barefoot\Evaluator`
36
+ *
37
+ * The render harness this adapter's output assumes: a Blade `Factory` wired
38
+ * from illuminate/view standalone (`Filesystem`, event `Dispatcher`,
39
+ * `EngineResolver` registering a `blade` engine over a `BladeCompiler`, a
40
+ * `FileViewFinder`, tied together by the `Factory`) — see
41
+ * `php/src/BladeBackend.php`'s constructor and file header for the exact
42
+ * wiring and the `Illuminate\Support\e()`/`Htmlable` escaping contract.
43
+ * Templates are named `<snake_case_component>.blade.php` (same convention as
44
+ * Twig's `.twig` files).
45
+ *
46
+ * **Whitespace policy.** Blade directives compile to raw `<?php … ?>` tags
47
+ * spliced into the surrounding template text — e.g. `@if(C)` compiles to
48
+ * `<?php if(C): ?>`. PHP itself has a well-known parser quirk: a `?>`
49
+ * closing tag immediately followed by exactly one newline has that ONE
50
+ * newline SWALLOWED (never emitted), independent of Blade. Verified
51
+ * empirically (`packages/adapter-blade/php`, standalone illuminate/view):
52
+ * rendering a template with `@if`/`@elseif`/`@else`/`@endif`,
53
+ * `@foreach`/`@endforeach`, and `@php(...)` lines EACH on their own source
54
+ * line at column 0 produces NO leaked blank lines around the directives —
55
+ * byte-identical in shape to Twig's `trim_blocks` behavior, but achieved for
56
+ * free via PHP's own tag-adjacent-newline rule rather than a Blade-specific
57
+ * feature. This gives the exact same uniform policy the Twig port already
58
+ * follows: **emit every directive at column 0 of its own source line, never
59
+ * introduce leading indentation before `@`.** No Blade-specific whitespace-
60
+ * control syntax is needed anywhere in this adapter.
61
+ *
62
+ * Divergences beyond the syntax table above (all uniform, not per-fixture —
63
+ * see the individual definition sites for the full rationale):
64
+ *
65
+ * 0. **CRITICAL — every escaped interpolation uses `{!! e(EXPR) !!}`, NEVER
66
+ * Blade's own `{{ EXPR }}`.** Discovered empirically while porting the
67
+ * evaluator-JSON callback fixtures (`.reduce`/`.sort`/`.filter` etc. —
68
+ * divergence 8 below): `Illuminate\View\Compilers\Concerns\
69
+ * CompilesEchos::compileRegularEchos` finds a `{{ … }}` pair with the
70
+ * regex `/\{\{\s*(.+?)\s*\}\}(\r?\n)?/s` — a NON-GREEDY match against
71
+ * the RAW TEMPLATE TEXT, with NO awareness of PHP string-literal
72
+ * quoting. A serialized-`ParsedExpr` JSON payload for a NESTED
73
+ * expression (e.g. `x => acc * x.qty`'s AST) routinely contains a
74
+ * literal `}}` substring where one JSON object closes immediately
75
+ * inside another (`...,"property":"qty"}}`) — even though that `}}` is
76
+ * safely inside a single-quoted PHP string literal, Blade's regex does
77
+ * not know that and terminates the `{{ … }}` tag AT THE FIRST `}}` IT
78
+ * SEES, truncating the compiled PHP expression mid-string and producing
79
+ * a syntax error (verified empirically — `BladeCompiler::compileString`
80
+ * on `{{ $bf->string($bf->reduce_eval($items, '{"kind":"binary",
81
+ * ...,"property":"qty"}}', ...)) }}` compiles to an unclosed-paren
82
+ * fragment ending right after the first `}}`, confirmed via
83
+ * `php -l` on the compiled output). Blade's raw-echo delimiter
84
+ * (`{!! … !!}`) uses `!!}` as its closer, which this adapter's payload
85
+ * text never produces (JSON output only ever contains `{`/`}`/quotes/
86
+ * alphanumerics/punctuation, never `!`), so it is IMMUNE to this
87
+ * failure mode. This adapter therefore NEVER emits Blade's own
88
+ * escaped-echo delimiter — every position that needs HTML-escaped
89
+ * output calls PHP's global `e()` helper (the SAME function `{{ }}`
90
+ * would have called internally, imported for free via
91
+ * `illuminate/support`'s composer "files" autoload — see
92
+ * `BladeBackend.php`'s header for the `Htmlable` pass-through
93
+ * contract, identical either way) explicitly under `{!! !!}` instead.
94
+ * This is NOT a narrow, evaluator-only special case — it is applied
95
+ * UNIFORMLY at every interpolation site in this file (text
96
+ * expressions, attribute values, boolean-attribute ternaries, style
97
+ * object values, the scope-id marker, template-literal attrs, provider
98
+ * value propagation), because any one of them could in principle carry
99
+ * an evaluator-JSON payload transitively, and a single missed
100
+ * `{{ }}` site would silently reintroduce this failure mode for
101
+ * whatever future fixture happens to nest two callback bodies deep
102
+ * enough to trigger it.
103
+ * 1. **`$` sigil on every variable reference.** Twig identifiers have no
104
+ * sigil; Blade compiles to raw PHP, where every variable — read OR
105
+ * `@php(...)` assignment target — is `$name`. `bladeIdent(name)`
106
+ * (`lib/blade-naming.ts`) mirrors `twigIdent`'s mangling-only role
107
+ * (bare name, no `$`); `bladeVar(name)` is the NEW wrapper used at
108
+ * every actual variable-reference emission site. See
109
+ * `expr/emitters.ts`'s file header for the full rundown of every
110
+ * emitter call site this affects.
111
+ * 2. **`@foreach` needs an explicit null/undefined guard Twig didn't.**
112
+ * Twig's `{% for %}` over `strict_variables: false` tolerated an
113
+ * unbound/`null` array (zero iterations, no error). Raw PHP's
114
+ * `foreach (null as $x)` raises a `TypeError` (PHP 8) /
115
+ * `Warning: Invalid argument` (older PHP) — verified empirically. This
116
+ * adapter therefore ALWAYS wraps the loop array in `(EXPR ?? [])`,
117
+ * matching Twig's tolerance uniformly rather than per-fixture.
118
+ * 3. **`??` is PHP-native and REPLACES Twig's `strict_variables: false`
119
+ * forgiveness with a per-use-site policy.** PHP's `??` silences BOTH
120
+ * an undefined-variable/-array-index notice AND a real `null` in ONE
121
+ * operator (verified empirically: `$missing ?? 'fb'` and `$x ?? 'fb'`
122
+ * with `$x = null` both yield `'fb'`, no warning) — same coverage
123
+ * Twig's native `??` gave (this adapter's divergence 3 in the Twig
124
+ * port), but Blade has no engine-wide switch equivalent to
125
+ * `strict_variables: false`; every place a possibly-unbound var is
126
+ * read (nullable-optional-prop guards, the `Record[key]` lookup
127
+ * fallback) uses `??`/`isset()` explicitly at that site instead — see
128
+ * divergence 6 below for the SEPARATE "omit the attribute entirely"
129
+ * case `??` alone doesn't cover.
130
+ * 4. **Children/fallback capture via output buffering, not a set-block —
131
+ * and NEVER Blade's bare `@php … @endphp` block form.** Blade has no
132
+ * Twig-set-block equivalent that captures arbitrary rendered TEMPLATE
133
+ * OUTPUT (as opposed to a single PHP expression's value) into a
134
+ * variable. This adapter uses ONE uniform mechanism instead — PHP's
135
+ * own output buffering: `@php(ob_start())` … the captured body,
136
+ * rendered normally (so any interpolation inside is escaped exactly as
137
+ * if it rendered inline) …
138
+ * `@php($NAME = $bf->backend->mark_raw(preg_replace('/\n\z/', '', ob_get_clean(), 1)))`.
139
+ * Two things beyond the ob_start/ob_get_clean shape itself:
140
+ * (a) the trailing `preg_replace('/\n\z/', '', …, 1)` strips exactly
141
+ * the ONE newline this adapter's own template-string builder
142
+ * inserts between the captured body and the closing `@php(...)`
143
+ * line (needed so the directive is preceded by a non-word
144
+ * character — Blade's directive regex is `\B@word`, which
145
+ * requires the '@' NOT be glued directly onto a preceding word
146
+ * character) — without this trim, that synthetic newline is
147
+ * itself part of the captured buffer and leaks into the
148
+ * rendered HTML as extra whitespace right before the next
149
+ * sibling/closing tag (caught by the adapter-conformance suite:
150
+ * `<h2>Create New Task</h2>` rendering as `...Task </h2>` — a
151
+ * newline that `normalizeHTML` collapses to a visible trailing
152
+ * space). The trim is bounded to exactly one synthetic
153
+ * newline, not `rtrim`-style — content the caller genuinely
154
+ * renders with real trailing newlines keeps them.
155
+ * (b) this adapter uses ONLY the single-expression `@php(EXPR)`
156
+ * directive form, NEVER the bare `@php` / `@endphp` BLOCK form,
157
+ * anywhere in its emitted templates — verified empirically that
158
+ * `BladeCompiler::compileString` mishandles a `@php(EXPR)`
159
+ * occurrence EARLIER in the same template when a bare
160
+ * `@php ... @endphp` block appears LATER in it (the directive-
161
+ * matching regex's paren-balancing recovery walk gets confused
162
+ * by the later bare `@php` token, leaving `@php(EXPR)` OR its
163
+ * inner expression malformed/uncompiled). Since this adapter
164
+ * cannot control what OTHER templates its output might be
165
+ * concatenated/co-rendered alongside, every capture site stays
166
+ * on the single-expression form exclusively, sidestepping the
167
+ * whole class of mixed-form parsing quirks.
168
+ * `mark_raw` wraps the captured string in an `HtmlString`, so a later
169
+ * plain `{{ $NAME }}` echo does NOT re-escape it (verified empirically
170
+ * — same "capture once, emit raw once" contract Twig's set-block gave,
171
+ * see `BladeBackend.php`'s header for why `Illuminate\Support\e()`
172
+ * makes this work). Every set-block capture site in the Twig port
173
+ * (`renderComponent`'s children forward, `renderAsync`'s fallback)
174
+ * maps onto this ONE mechanism here too — always invoked immediately,
175
+ * in place, with zero arguments, never reused/invoked lazily.
176
+ * 5. **Member/index access lowers to `data_get(...)`, not `.`/`[]`.**
177
+ * Twig's `.`/`[]` are polymorphic over {stdClass, array, null} under
178
+ * `strict_variables: false`; raw PHP has NO single operator with that
179
+ * property (`$x->prop` fatals on a non-object, `$x['key']` warns on
180
+ * `null`/scalar). This adapter uses Laravel's `data_get($target, $key)`
181
+ * (from `illuminate/support`, already a transitive dependency of
182
+ * `illuminate/view` — no NEW runtime dependency, no change to
183
+ * `packages/adapter-php`) uniformly for both member access (`a.b` →
184
+ * `data_get($a, 'b')`) and index access (`a[i]` → `data_get($a, $i)`)
185
+ * — verified null-safe over the SAME {stdClass, array, null} value
186
+ * shapes Twig's dot/bracket cover (see `lib/blade-naming.ts`'s
187
+ * `bladeMemberAccess`/`bladeIndexAccess` docstrings for the verification
188
+ * transcript). This is the ONE place this port required a genuinely new
189
+ * lowering strategy rather than a mechanical syntax substitution.
190
+ * 6. **Nullable-optional-prop attribute omission uses `isset($x)`, a
191
+ * SINGLE check — simpler than Twig's TWO-part `is defined and is not
192
+ * null`.** Twig needed both tests because `is defined` and `is not
193
+ * none` are separate concerns under `strict_variables: false`. PHP's
194
+ * `isset($x)` already returns `false` for BOTH "never extracted into
195
+ * scope" AND "extracted as `null`" in one call (verified empirically —
196
+ * `isset($rows)` is `false` whether `$rows` was omitted from the
197
+ * render-vars array entirely or passed as `null`; `true` only when
198
+ * bound to a non-null value) — so this adapter's `elementAttrEmitter`
199
+ * guards with `@if(isset($x)) … @endif` instead of a two-part test.
200
+ * 7. **`===`/`!==` route through `$bf->eq`/`$bf->neq`, NEVER PHP's own
201
+ * `==`/`!=`/`===`/`!==`.** Unchanged from the Twig port's divergence 4
202
+ * — PHP's `==` is loose (`'1' == 1` is `true`), and PHP's OWN `===` is
203
+ * wrong the OTHER direction (`1 === 1.0` is `false` in PHP; JS has one
204
+ * number type, so `1 === 1.0` is `true`). See `expr/emitters.ts`'s file
205
+ * header for the full rationale.
206
+ * 8. **No Blade lambda** (`expr/emitters.ts` header, divergence 9).
207
+ * Unchanged from Twig — every higher-order callback routes through the
208
+ * evaluator-JSON `*_eval` payload; an unserializable predicate surfaces
209
+ * `BF101`. `.sort`'s non-lambda STRUCTURED fallback (`$bf->sort` with a
210
+ * `['keys' => […]]` descriptor) is unaffected and ports unchanged.
211
+ * 9. **Reserved-word mangling set is COMPLETELY DIFFERENT from Twig's, for
212
+ * a different reason** (`lib/blade-naming.ts`). Twig keywords (`for`,
213
+ * `filter`, `if`, …) collide with TWIG'S OWN grammar — irrelevant here,
214
+ * since Blade template vars are real PHP variables bound via
215
+ * `extract()` (`$for`, `$filter` are perfectly legal). What collides
216
+ * instead is the Blade/illuminate RENDER-TIME PHP SCOPE: `bf` (the
217
+ * runtime binding), `this` (PHP forbids `$this` reassignment),
218
+ * `__env`/`__data`/`__path` (illuminate/view internals), `app`
219
+ * (conventional container binding), `loop` (Blade's own `@foreach`
220
+ * `$loop`). `blade_ident()` in PHP (`php/src/naming.php`);
221
+ * `BladeBackend::ident()` delegates to it. Mirrored exactly by
222
+ * `bladeIdent`/`RESERVED_WORDS` on the TS side, with a parity test on
223
+ * each side (port of the Twig adapter's parity test).
224
+ * 10. **Blade's own `$loop->index`, not `loop.index0`.** Both engines
225
+ * expose a 0-based per-iteration index via a builtin loop object —
226
+ * verified empirically Blade's is `$loop->index` (property, not a
227
+ * method), coincidentally same 0-based numbering as Twig's
228
+ * `loop.index0`, just a different property name and `->` access.
229
+ * 11. **`array_merge(...)`, not a chained `|merge` filter, for ordered
230
+ * component-prop segments.** Twig has no hash-splat syntax, so the
231
+ * Twig port folds `{...before, ...spread, after: 1}` JSX spread
232
+ * semantics through repeated `{a}|merge({b})|merge({c})` filter calls.
233
+ * PHP's `array_merge` is natively variadic AND already resolves later-
234
+ * argument-wins on string-key conflict (verified empirically — same
235
+ * semantics `Object.assign`/JSX spread order needs), so this adapter
236
+ * folds the segment list into ONE `array_merge($seg1, $seg2, …)` call
237
+ * instead of a chain — simpler, not just a syntax reshuffle.
238
+ */
239
+ import type { ComponentIR, IRNode, IRElement, IRText, IRExpression, IRConditional, IRLoop, IRComponent, IRFragment, IRSlot, IRIfStatement, IRProvider, IRAsync, TemplatePrimitiveRegistry } from '@barefootjs/jsx';
240
+ import { BaseAdapter, type AdapterOutput, type AdapterGenerateOptions, type IRNodeEmitter, type EmitIRNode } from '@barefootjs/jsx';
241
+ import type { BladeRenderCtx } from './lib/types.ts';
242
+ export type { BladeAdapterOptions } from './lib/types.ts';
243
+ import type { BladeAdapterOptions } from './lib/types.ts';
244
+ export declare class BladeAdapter extends BaseAdapter implements IRNodeEmitter<BladeRenderCtx> {
245
+ name: string;
246
+ extension: string;
247
+ templatesPerComponent: boolean;
248
+ importMapInjection: 'html-snippet';
249
+ /**
250
+ * Identifier-path callees the Blade runtime can render in template scope.
251
+ * The relocate pass consults this map to mark matching calls as
252
+ * template-safe; the SSR template emitter substitutes the JS call with the
253
+ * registered `$bf->NAME(...)` helper invocation.
254
+ */
255
+ templatePrimitives: TemplatePrimitiveRegistry;
256
+ private componentName;
257
+ /** Component root scope element(s) — each carries `data-key` for a keyed loop
258
+ * item (set by the child renderer from the JSX `key` prop). A plain element
259
+ * root is one node; an `if-statement` (early-return) root contributes the
260
+ * top element of every branch. */
261
+ private rootScopeNodes;
262
+ private options;
263
+ private errors;
264
+ private inLoop;
265
+ /**
266
+ * SolidJS-style props identifier (`function(props: P)`) and the
267
+ * analyzer-extracted prop names. Stashed at `generate()` entry so the
268
+ * per-attribute `emitSpread` callback can build a propsObject spread bag as
269
+ * an inline PHP array literal without re-walking the IR.
270
+ */
271
+ private propsObjectName;
272
+ private propsParams;
273
+ private booleanTypedProps;
274
+ /**
275
+ * Names (signal getters + props) whose value is a string. Carried for
276
+ * parity with the Perl-family adapters (Mojo needs it for `eq`/`ne`
277
+ * selection); the Blade emitters don't consume it — `===`/`!==` always
278
+ * routes through `$bf->eq`/`$bf->neq` regardless of operand type (see
279
+ * `blade-adapter.ts`'s file header, divergence 7).
280
+ */
281
+ private stringValueNames;
282
+ /**
283
+ * Module-scope pure-string consts (`const x = 'literal'`), keyed by name →
284
+ * unescaped value. A className template literal that references such a const
285
+ * (`className={`${x} ${className}`}`) must inline the literal: the const is
286
+ * module-scope, so it never reaches the per-render context, and a bare
287
+ * reference to `x` would resolve to an undefined variable.
288
+ */
289
+ private moduleStringConsts;
290
+ /**
291
+ * (#1922) Local binding names the request-scoped `searchParams()` env signal
292
+ * is imported under (handles `import { searchParams as sp }`). When non-empty
293
+ * the emitter lowers a `<binding>().get(k)` call to a real method call on the
294
+ * per-request `searchParams` reader (`$searchParams->get('sort')`) instead of
295
+ * the generic `data_get` deref. Set at `generate()` entry from
296
+ * `ir.metadata.imports`; read by the top-level ParsedExpr emitter.
297
+ */
298
+ private _searchParamsLocals;
299
+ /**
300
+ * Call-lowering matchers active for this component (#2057). Bound at
301
+ * `generate()` entry via `prepareLoweringMatchers` and read by the top-level
302
+ * emitter. Covers both userland plugins and the compiler's built-in plugins
303
+ * (e.g. `queryHref` → `$bf->query`, #2042) — one uniform path, no per-API branch.
304
+ */
305
+ private _loweringMatchers;
306
+ /**
307
+ * Local + module constants from the IR, used by the conditional-spread and
308
+ * `Record<staticKeys, scalar>[propKey]` lowering paths (#textarea / #checkbox).
309
+ * Stashed at `generate()` entry so `emitSpread` can resolve a bare local
310
+ * const (`const sizeAttrs = size ? {…} : {}`) to its initializer text.
311
+ */
312
+ private localConstants;
313
+ /**
314
+ * Optional, no-default props that are `None` when the caller omits them.
315
+ * Their bare-reference attribute emission is guarded with a Blade
316
+ * `isset($x)` test so the attribute DROPS rather than rendering `attr=""`
317
+ * (Hono-style nullish omission, e.g. textarea's `rows`; see this file's
318
+ * header, divergence 6). The filter excludes destructure-defaulted, rest,
319
+ * and concrete-primitive props.
320
+ */
321
+ private nullableOptionalProps;
322
+ constructor(options?: BladeAdapterOptions);
323
+ generate(ir: ComponentIR, options?: AdapterGenerateOptions): AdapterOutput;
324
+ private generateScriptRegistrations;
325
+ /**
326
+ * Public entry point for node rendering. Delegates to the shared
327
+ * `IRNodeEmitter` dispatcher; per-kind logic lives in the `IRNodeEmitter`
328
+ * methods below.
329
+ */
330
+ renderNode(node: IRNode): string;
331
+ emitElement(node: IRElement, _ctx: BladeRenderCtx, _emit: EmitIRNode<BladeRenderCtx>): string;
332
+ emitText(node: IRText): string;
333
+ emitExpression(node: IRExpression): string;
334
+ emitConditional(node: IRConditional, _ctx: BladeRenderCtx, _emit: EmitIRNode<BladeRenderCtx>): string;
335
+ emitLoop(node: IRLoop, _ctx: BladeRenderCtx, _emit: EmitIRNode<BladeRenderCtx>): string;
336
+ emitComponent(node: IRComponent, _ctx: BladeRenderCtx, _emit: EmitIRNode<BladeRenderCtx>): string;
337
+ emitFragment(node: IRFragment, _ctx: BladeRenderCtx, _emit: EmitIRNode<BladeRenderCtx>): string;
338
+ emitSlot(node: IRSlot): string;
339
+ emitIfStatement(node: IRIfStatement, _ctx: BladeRenderCtx, _emit: EmitIRNode<BladeRenderCtx>): string;
340
+ emitProvider(node: IRProvider, _ctx: BladeRenderCtx, _emit: EmitIRNode<BladeRenderCtx>): string;
341
+ /** Lower a `<Ctx.Provider value>` value prop to a Blade expression. */
342
+ private providerValueBlade;
343
+ /**
344
+ * Lower an object-literal provider value (`value={{ open: () => props.open
345
+ * ?? false, onOpenChange: … }}`) to a PHP array literal (#1897). The
346
+ * SSR lowering is a per-member snapshot of what a consumer would READ
347
+ * during the same render:
348
+ *
349
+ * - zero-param expression-body arrows are getters — lower the body (the
350
+ * value is fixed for the render, so the call-time indirection drops out)
351
+ * - `on[A-Z]`-named members and function-shaped values are client-only
352
+ * behavior SSR never invokes — lower to `null`
353
+ * - anything else lowers through the normal expression pipeline (so an
354
+ * unsupported getter body still refuses loudly with BF101)
355
+ *
356
+ * Keys keep their JS names verbatim so a consumer-side `ctx.open` access
357
+ * maps onto the same array key. Returns `null` when the expression is not a
358
+ * plain object literal (spread / computed key) — the caller falls back to
359
+ * the whole-expression path, which refuses those shapes with BF101.
360
+ */
361
+ private providerObjectLiteralBlade;
362
+ emitAsync(node: IRAsync, _ctx: BladeRenderCtx, _emit: EmitIRNode<BladeRenderCtx>): string;
363
+ renderElement(element: IRElement): string;
364
+ renderExpression(expr: IRExpression): string;
365
+ renderConditional(cond: IRConditional): string;
366
+ private renderNodeOrNull;
367
+ /**
368
+ * Add bf-c attribute to the first HTML element in a branch.
369
+ * If no element found, wrap with comment markers.
370
+ */
371
+ private addCondMarkerToFirstElement;
372
+ renderLoop(loop: IRLoop): string;
373
+ /**
374
+ * AttrValue lowering for component invocation props (Blade array-entry
375
+ * form). Blade/PHP CANNOT splat an array into positional args, so every
376
+ * prop is emitted as a `'key' => value` entry that the caller collects
377
+ * into ONE array literal passed to `$bf->render_child(name, [ ... ])`.
378
+ *
379
+ * `jsx-children` returns empty — children are captured via the output-
380
+ * buffering mechanism below, not threaded through the entry list.
381
+ */
382
+ private readonly componentPropEmitter;
383
+ /**
384
+ * A `renderComponent` props array, built as an ORDERED sequence of
385
+ * segments so `{...before, ...spread, after: 1}` JSX spread semantics
386
+ * (later entries win) survive the trip through Blade/PHP, which has no
387
+ * array-splat call syntax. Each `'entries'` segment is a literal PHP
388
+ * array `[k => v, ...]`; each `'spread'` segment is an arbitrary
389
+ * expression lowered from a `{...expr}` prop. `combineComponentPropSegments`
390
+ * folds the sequence into ONE expression via `array_merge(...)` (later
391
+ * segment wins on key conflict, matching `Object.assign`/JSX order — see
392
+ * this file's header, divergence 11).
393
+ */
394
+ private componentPropSegmentEntries;
395
+ /**
396
+ * Fold ordered prop segments into a single PHP expression via ONE
397
+ * variadic `array_merge(...)` call — later argument wins on string-key
398
+ * conflict, exactly like `{...a, ...b}` (verified empirically). Empty
399
+ * `'entries'` segments are dropped so a leading/trailing spread doesn't
400
+ * drag in a needless `[]` argument. Returns `'[]'` when every segment is
401
+ * empty (no props at all); returns the lone segment directly (no
402
+ * `array_merge` wrapper) when there is exactly one.
403
+ */
404
+ private combineComponentPropSegments;
405
+ renderComponent(comp: IRComponent): string;
406
+ private childrenCaptureCounter;
407
+ /** Uniquifies the `presenceOrUndefined` temp binding (`bf_puN`) so two
408
+ * presence-folded attrs in one template don't collide. */
409
+ private presenceVarCounter;
410
+ private toTemplateName;
411
+ private renderIfStatement;
412
+ private renderFragment;
413
+ private renderSlot;
414
+ renderAsync(node: IRAsync): string;
415
+ /**
416
+ * AttrValue lowering for intrinsic-element attributes (Blade).
417
+ */
418
+ private readonly elementAttrEmitter;
419
+ /**
420
+ * Lower a `style={{ … }}` object literal to a CSS string with dynamic values
421
+ * interpolated as Blade expressions, e.g. `{ backgroundColor: color }` →
422
+ * `background-color:{{ $bf->string($color) }}`. Returns null when the shape
423
+ * is unsupported or any value can't be lowered (caller falls through to
424
+ * BF101). (#1322)
425
+ */
426
+ private tryLowerStyleObject;
427
+ /** HTML-attribute escape for static text inlined into a `"..."` attribute. */
428
+ private escapeAttrText;
429
+ private renderAttributes;
430
+ renderScopeMarker(_instanceIdExpr: string): string;
431
+ renderSlotMarker(slotId: string): string;
432
+ renderCondMarker(condId: string): string;
433
+ /**
434
+ * Convert a ParsedExpr AST to a Blade expression string for filter
435
+ * predicates. Wraps the shared ParsedExpr dispatcher with a
436
+ * `BladeFilterEmitter` carrying the predicate's loop param and any
437
+ * block-body local var aliases.
438
+ */
439
+ private renderBladeFilterExpr;
440
+ private convertTemplateLiteralPartsToBlade;
441
+ /**
442
+ * Translate `${EXPR}` interpolations in a static template-part string into
443
+ * Blade variable references and concatenate them with the surrounding
444
+ * literal text. Each interpolated (non-literal) segment routes through
445
+ * `$bf->string(...)` — see the file header, "Stringification".
446
+ */
447
+ private substituteJsInterpolationsToBlade;
448
+ /**
449
+ * Refuse JS expression shapes that have no idiomatic Blade representation:
450
+ * object literals (`style={{...}}`) and tagged-template-literal call
451
+ * expressions (`cn\`base \${tone()}\``). Records `BF101`. Returns `true`
452
+ * when the shape was rejected (caller should drop the attribute).
453
+ */
454
+ private refuseUnsupportedAttrExpression;
455
+ /**
456
+ * Build the EmitContext seam the top-level `ParsedExpr` emitter depends on.
457
+ * Built as a private object (the adapter does NOT `implements BladeEmitContext`)
458
+ * so the wrapped bookkeeping — `_searchParamsLocals`, the const/record
459
+ * resolvers, BF101 recording, the filter-predicate entry — stays private and
460
+ * off the exported adapter's public type, matching the Go adapter's
461
+ * `emitCtx` and the `spreadCtx` / `memoCtx` seams below.
462
+ */
463
+ private get emitCtx();
464
+ /**
465
+ * Build the narrow context the extracted spread lowering depends on. Passing
466
+ * a purpose-built object (rather than `this`) keeps the adapter's bookkeeping
467
+ * members private — they stay internal implementation detail, not part of the
468
+ * exported class's public surface.
469
+ */
470
+ private get spreadCtx();
471
+ /** Build the narrow context the extracted memo seeding depends on. */
472
+ private get memoCtx();
473
+ private convertExpressionToBlade;
474
+ /**
475
+ * Convert a JS condition (an `if` / ternary / loop-filter test) to a Blade
476
+ * boolean expression, routing through `$bf->truthy(...)` unless the
477
+ * expression is structurally already boolean-shaped. See the file header,
478
+ * "JS truthiness".
479
+ */
480
+ private convertConditionToBlade;
481
+ /**
482
+ * Shared helper: given the ORIGINAL JS expression (or its already-parsed
483
+ * tree) and its ALREADY-RENDERED Blade text, wrap the rendered text with
484
+ * `$bf->truthy(...)` unless the expression is structurally boolean-shaped.
485
+ * Split from `convertConditionToBlade` so a caller that already lowered the
486
+ * expression for another purpose (e.g. the `presenceOrUndefined` temp bind)
487
+ * doesn't lower it twice.
488
+ */
489
+ private wrapConditionExpr;
490
+ /**
491
+ * Render a full ParsedExpr tree to Blade for top-level (non-filter)
492
+ * expressions where identifiers are signals / template vars.
493
+ */
494
+ private renderParsedExprToBlade;
495
+ /** Whether `name` (a signal getter or prop) holds a string value. Carried
496
+ * for parity with the Perl-family adapters; the Blade emitters don't
497
+ * consume it (`===`/`!==` always routes through `$bf->eq`/`$bf->neq`
498
+ * regardless of operand type). */
499
+ private _isStringValueName;
500
+ /**
501
+ * Parse `cond ? value : undefined` (or `: null`), returning the
502
+ * condition/consequent source spans, else `null`. Used for the
503
+ * attribute-omission rule (#1897).
504
+ */
505
+ parseUndefinedAlternateTernary(expr: string): {
506
+ condition: string;
507
+ consequent: string;
508
+ } | null;
509
+ isBooleanTypedPropRef(expr: string): boolean;
510
+ /**
511
+ * Whether an attribute-value expression should route through
512
+ * `$bf->bool_str` (vs. plain `$bf->string`) at its interpolation site.
513
+ * `isExplicitStringCall` is checked FIRST and short-circuits the other
514
+ * three: an explicit `String(x)` call already lowers to `$bf->string(x)`,
515
+ * which correctly stringifies a real boolean on its own (see the PHP
516
+ * runtime's `string()` helper's bool branch), so layering `$bf->bool_str`
517
+ * on top would run PHP truthiness over the ALREADY-STRINGIFIED text
518
+ * instead of the original boolean. See `isExplicitStringCall`'s docstring
519
+ * in `boolean-result.ts` for the full double-wrap failure mode this
520
+ * guards against.
521
+ */
522
+ private shouldBoolStr;
523
+ /**
524
+ * Inline a const (any scope) whose initializer is a pure numeric or
525
+ * single-quoted string literal (`const totalPages = 5`, #1897
526
+ * pagination) — function-scope consts never reach the per-render
527
+ * context, so a bare reference would resolve to an undefined variable.
528
+ */
529
+ private _resolveLiteralConst;
530
+ private _resolveStaticRecordLiteral;
531
+ private _resolveModuleStringConst;
532
+ private _recordExprBF101;
533
+ /** Internal hook for higher-order: predicate body re-uses the filter emitter. */
534
+ private _renderBladeFilterExprPublic;
535
+ }
536
+ export declare const bladeAdapter: BladeAdapter;
537
+ //# sourceMappingURL=blade-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blade-adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/blade-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6OG;AAEH,OAAO,KAAK,EACV,WAAW,EACX,MAAM,EACN,SAAS,EACT,MAAM,EACN,YAAY,EACZ,aAAa,EACb,MAAM,EACN,WAAW,EACX,UAAU,EACV,MAAM,EACN,aAAa,EACb,UAAU,EACV,OAAO,EAKP,yBAAyB,EAE1B,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,WAAW,EACX,KAAK,aAAa,EAClB,KAAK,sBAAsB,EAE3B,KAAK,aAAa,EAClB,KAAK,UAAU,EAyBhB,MAAM,iBAAiB,CAAA;AAKxB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAkCpD,YAAY,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AACzD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AAEzD,qBAAa,YAAa,SAAQ,WAAY,YAAW,aAAa,CAAC,cAAc,CAAC;IACpF,IAAI,SAAU;IACd,SAAS,SAAe;IACxB,qBAAqB,UAAO;IAG5B,kBAAkB,EAAG,cAAc,CAAS;IAE5C;;;;;OAKG;IACH,kBAAkB,EAAE,yBAAyB,CAA2B;IAExE,OAAO,CAAC,aAAa,CAAa;IAClC;;;uCAGmC;IACnC,OAAO,CAAC,cAAc,CAAyB;IAC/C,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,MAAM,CAAiB;IAC/B;;;;;OAKG;IACH,OAAO,CAAC,eAAe,CAAsB;IAC7C,OAAO,CAAC,WAAW,CAAyB;IAC5C,OAAO,CAAC,iBAAiB,CAAyB;IAClD;;;;;;OAMG;IACH,OAAO,CAAC,gBAAgB,CAAyB;IAEjD;;;;;;OAMG;IACH,OAAO,CAAC,kBAAkB,CAAiC;IAE3D;;;;;;;OAOG;IACH,OAAO,CAAC,mBAAmB,CAAyB;IAEpD;;;;;OAKG;IACH,OAAO,CAAC,iBAAiB,CAAwB;IAEjD;;;;;OAKG;IACH,OAAO,CAAC,cAAc,CAAmC;IAEzD;;;;;;;OAOG;IACH,OAAO,CAAC,qBAAqB,CAAyB;IAEtD,YAAY,OAAO,GAAE,mBAAwB,EAM5C;IAED,QAAQ,CAAC,EAAE,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,sBAAsB,GAAG,aAAa,CA4EzE;IAMD,OAAO,CAAC,2BAA2B;IAuBnC;;;;OAIG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/B;IAMD,WAAW,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC,GAAG,MAAM,CAE5F;IAED,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE7B;IAED,cAAc,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAEzC;IAED,eAAe,CAAC,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC,GAAG,MAAM,CAEpG;IAED,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC,GAAG,MAAM,CAEtF;IAED,aAAa,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC,GAAG,MAAM,CAEhG;IAED,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC,GAAG,MAAM,CAE9F;IAED,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE7B;IAED,eAAe,CAAC,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC,GAAG,MAAM,CAEpG;IAED,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC,GAAG,MAAM,CAe9F;IAED,uEAAuE;IACvE,OAAO,CAAC,kBAAkB;IAmB1B;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,CAAC,0BAA0B;IAYlC,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC,GAAG,MAAM,CAExF;IAMD,aAAa,CAAC,OAAO,EAAE,SAAS,GAAG,MAAM,CAoCxC;IAMD,gBAAgB,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAiB3C;IAMD,iBAAiB,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,CAuC7C;IAED,OAAO,CAAC,gBAAgB;IAOxB;;;OAGG;IACH,OAAO,CAAC,2BAA2B;IAcnC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAkO/B;IAMD;;;;;;;;OAQG;IACH,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAmCpC;IAED;;;;;;;;;;OAUG;IACH,OAAO,CAAC,2BAA2B;IAUnC;;;;;;;;OAQG;IACH,OAAO,CAAC,4BAA4B;IAepC,eAAe,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CA4FzC;IAED,OAAO,CAAC,sBAAsB,CAAI;IAElC;+DAC2D;IAC3D,OAAO,CAAC,kBAAkB,CAAI;IAE9B,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,iBAAiB;IA0BzB,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,UAAU;IAYT,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAa1C;IAMD;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CA2JlC;IAED;;;;;;OAMG;IACH,OAAO,CAAC,mBAAmB;IAmB3B,8EAA8E;IAC9E,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,gBAAgB;IA2BxB,iBAAiB,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAIjD;IAED,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEvC;IAED,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEvC;IAMD;;;;;OAKG;IACH,OAAO,CAAC,qBAAqB;IAuB7B,OAAO,CAAC,kCAAkC;IAkC1C;;;;;OAKG;IACH,OAAO,CAAC,iCAAiC;IAmBzC;;;;;OAKG;IACH,OAAO,CAAC,+BAA+B;IAuBvC;;;;;;;OAOG;IACH,OAAO,KAAK,OAAO,GASlB;IAED;;;;;OAKG;IACH,OAAO,KAAK,SAAS,GASpB;IAED,sEAAsE;IACtE,OAAO,KAAK,OAAO,GAKlB;IAED,OAAO,CAAC,wBAAwB;IAyEhC;;;;;OAKG;IACH,OAAO,CAAC,uBAAuB;IAK/B;;;;;;;OAOG;IACH,OAAO,CAAC,iBAAiB;IAOzB;;;OAGG;IACH,OAAO,CAAC,uBAAuB;IAI/B;;;uCAGmC;IACnC,OAAO,CAAC,kBAAkB;IAI1B;;;;OAIG;IACH,8BAA8B,CAC5B,IAAI,EAAE,MAAM,GACX;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAgBlD;IAED,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAO3C;IAED;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,aAAa;IAKrB;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;IAU5B,OAAO,CAAC,2BAA2B;IAQnC,OAAO,CAAC,yBAAyB;IAUjC,OAAO,CAAC,gBAAgB;IAcxB,iFAAiF;IACjF,OAAO,CAAC,4BAA4B;CAGrC;AAED,eAAO,MAAM,YAAY,cAAqB,CAAA"}