@hyperfixi/behaviors 3.3.0 → 4.0.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 (232) hide show
  1. package/CHANGELOG.md +162 -0
  2. package/README.md +29 -9
  3. package/dist/all.browser.global.js +45 -100
  4. package/dist/all.browser.global.js.map +1 -1
  5. package/dist/autodismiss.browser.global.js +5 -11
  6. package/dist/autodismiss.browser.global.js.map +1 -1
  7. package/dist/behaviors/autodismiss.cjs +19 -22
  8. package/dist/behaviors/autodismiss.cjs.map +1 -1
  9. package/dist/behaviors/autodismiss.d.cts +4 -4
  10. package/dist/behaviors/autodismiss.d.ts +4 -4
  11. package/dist/behaviors/autodismiss.js +3 -3
  12. package/dist/behaviors/clickoutside.cjs +19 -18
  13. package/dist/behaviors/clickoutside.cjs.map +1 -1
  14. package/dist/behaviors/clickoutside.d.cts +4 -4
  15. package/dist/behaviors/clickoutside.d.ts +4 -4
  16. package/dist/behaviors/clickoutside.js +3 -3
  17. package/dist/behaviors/clipboard.cjs +18 -19
  18. package/dist/behaviors/clipboard.cjs.map +1 -1
  19. package/dist/behaviors/clipboard.d.cts +4 -4
  20. package/dist/behaviors/clipboard.d.ts +4 -4
  21. package/dist/behaviors/clipboard.js +3 -3
  22. package/dist/behaviors/draggable.cjs +20 -25
  23. package/dist/behaviors/draggable.cjs.map +1 -1
  24. package/dist/behaviors/draggable.d.cts +4 -4
  25. package/dist/behaviors/draggable.d.ts +4 -4
  26. package/dist/behaviors/draggable.js +3 -3
  27. package/dist/behaviors/focustrap.cjs +18 -19
  28. package/dist/behaviors/focustrap.cjs.map +1 -1
  29. package/dist/behaviors/focustrap.d.cts +4 -4
  30. package/dist/behaviors/focustrap.d.ts +4 -4
  31. package/dist/behaviors/focustrap.js +3 -3
  32. package/dist/behaviors/removable.cjs +18 -21
  33. package/dist/behaviors/removable.cjs.map +1 -1
  34. package/dist/behaviors/removable.d.cts +4 -3
  35. package/dist/behaviors/removable.d.ts +4 -3
  36. package/dist/behaviors/removable.js +3 -3
  37. package/dist/behaviors/resizable.cjs +19 -19
  38. package/dist/behaviors/resizable.cjs.map +1 -1
  39. package/dist/behaviors/resizable.d.cts +4 -4
  40. package/dist/behaviors/resizable.d.ts +4 -4
  41. package/dist/behaviors/resizable.js +3 -3
  42. package/dist/behaviors/scrollreveal.cjs +19 -22
  43. package/dist/behaviors/scrollreveal.cjs.map +1 -1
  44. package/dist/behaviors/scrollreveal.d.cts +4 -4
  45. package/dist/behaviors/scrollreveal.d.ts +4 -4
  46. package/dist/behaviors/scrollreveal.js +3 -3
  47. package/dist/behaviors/sortable.cjs +19 -20
  48. package/dist/behaviors/sortable.cjs.map +1 -1
  49. package/dist/behaviors/sortable.d.cts +4 -4
  50. package/dist/behaviors/sortable.d.ts +4 -4
  51. package/dist/behaviors/sortable.js +3 -3
  52. package/dist/behaviors/tabs.cjs +20 -25
  53. package/dist/behaviors/tabs.cjs.map +1 -1
  54. package/dist/behaviors/tabs.d.cts +4 -4
  55. package/dist/behaviors/tabs.d.ts +4 -4
  56. package/dist/behaviors/tabs.js +3 -3
  57. package/dist/behaviors/toggleable.cjs +25 -26
  58. package/dist/behaviors/toggleable.cjs.map +1 -1
  59. package/dist/behaviors/toggleable.d.cts +4 -4
  60. package/dist/behaviors/toggleable.d.ts +4 -4
  61. package/dist/behaviors/toggleable.js +3 -3
  62. package/dist/chunk-2GIS4DCY.js +30 -0
  63. package/dist/chunk-2GIS4DCY.js.map +1 -0
  64. package/dist/chunk-3BCBZR6R.js +30 -0
  65. package/dist/chunk-3BCBZR6R.js.map +1 -0
  66. package/dist/chunk-4YUIDZAO.js +30 -0
  67. package/dist/chunk-4YUIDZAO.js.map +1 -0
  68. package/dist/{chunk-XYZ7FOXJ.js → chunk-AQCOK5J5.js} +10 -14
  69. package/dist/chunk-AQCOK5J5.js.map +1 -0
  70. package/dist/chunk-ATGHQQC7.js +30 -0
  71. package/dist/chunk-ATGHQQC7.js.map +1 -0
  72. package/dist/{chunk-HQDYH45I.js → chunk-CWLAXLWR.js} +5 -13
  73. package/dist/chunk-CWLAXLWR.js.map +1 -0
  74. package/dist/chunk-DMWN52SV.js +30 -0
  75. package/dist/chunk-DMWN52SV.js.map +1 -0
  76. package/dist/{chunk-PDMOOWFW.js → chunk-EIVPVTUI.js} +4 -8
  77. package/dist/{chunk-PDMOOWFW.js.map → chunk-EIVPVTUI.js.map} +1 -1
  78. package/dist/chunk-HHTEMPIT.js +30 -0
  79. package/dist/chunk-HHTEMPIT.js.map +1 -0
  80. package/dist/{chunk-26IX7QU7.js → chunk-HJESSMKB.js} +4 -6
  81. package/dist/{chunk-26IX7QU7.js.map → chunk-HJESSMKB.js.map} +1 -1
  82. package/dist/{chunk-5S7WN3ZQ.js → chunk-IFAH652L.js} +4 -7
  83. package/dist/chunk-IFAH652L.js.map +1 -0
  84. package/dist/chunk-IUGJG4RA.js +30 -0
  85. package/dist/chunk-IUGJG4RA.js.map +1 -0
  86. package/dist/{chunk-ZR66E3T6.js → chunk-JNLVXPHR.js} +13 -13
  87. package/dist/chunk-KEZEGPEX.js +30 -0
  88. package/dist/chunk-KEZEGPEX.js.map +1 -0
  89. package/dist/{chunk-66U2RSYJ.js → chunk-KP4GNXYS.js} +4 -10
  90. package/dist/chunk-KP4GNXYS.js.map +1 -0
  91. package/dist/chunk-KXQMCN4O.js +30 -0
  92. package/dist/chunk-KXQMCN4O.js.map +1 -0
  93. package/dist/{chunk-YXS27XM6.js → chunk-KYBOZ7C4.js} +3 -7
  94. package/dist/chunk-KYBOZ7C4.js.map +1 -0
  95. package/dist/chunk-LBWM6TTU.js +30 -0
  96. package/dist/chunk-LBWM6TTU.js.map +1 -0
  97. package/dist/{chunk-3DVDS7CT.js → chunk-LCDONZBX.js} +5 -5
  98. package/dist/chunk-LCDONZBX.js.map +1 -0
  99. package/dist/{chunk-OJ3YWO3W.js → chunk-NE76IBV2.js} +3 -7
  100. package/dist/chunk-NE76IBV2.js.map +1 -0
  101. package/dist/{chunk-HMU342XE.js → chunk-PVO6TZCZ.js} +3 -9
  102. package/dist/{chunk-HMU342XE.js.map → chunk-PVO6TZCZ.js.map} +1 -1
  103. package/dist/{chunk-URZGNPTQ.js → chunk-RILYRQ72.js} +4 -10
  104. package/dist/chunk-RILYRQ72.js.map +1 -0
  105. package/dist/{chunk-FBQ3X3UY.js → chunk-U4QMFVAM.js} +5 -13
  106. package/dist/chunk-U4QMFVAM.js.map +1 -0
  107. package/dist/chunk-VWDTOSE3.js +26 -0
  108. package/dist/chunk-VWDTOSE3.js.map +1 -0
  109. package/dist/chunk-YRQBU2OW.js +30 -0
  110. package/dist/chunk-YRQBU2OW.js.map +1 -0
  111. package/dist/clickoutside.browser.global.js +5 -7
  112. package/dist/clickoutside.browser.global.js.map +1 -1
  113. package/dist/clipboard.browser.global.js +4 -8
  114. package/dist/clipboard.browser.global.js.map +1 -1
  115. package/dist/core.browser.global.js +13 -25
  116. package/dist/core.browser.global.js.map +1 -1
  117. package/dist/draggable.browser.global.js +5 -13
  118. package/dist/draggable.browser.global.js.map +1 -1
  119. package/dist/focustrap.browser.global.js +4 -8
  120. package/dist/focustrap.browser.global.js.map +1 -1
  121. package/dist/index.cjs +96 -271
  122. package/dist/index.cjs.map +1 -1
  123. package/dist/index.d.cts +10 -10
  124. package/dist/index.d.ts +10 -10
  125. package/dist/index.js +42 -55
  126. package/dist/index.js.map +1 -1
  127. package/dist/loaders.cjs +75 -237
  128. package/dist/loaders.cjs.map +1 -1
  129. package/dist/loaders.js +13 -13
  130. package/dist/registry.cjs +4 -4
  131. package/dist/registry.cjs.map +1 -1
  132. package/dist/registry.d.cts +5 -6
  133. package/dist/registry.d.ts +5 -6
  134. package/dist/registry.js +1 -1
  135. package/dist/removable.browser.global.js +3 -9
  136. package/dist/removable.browser.global.js.map +1 -1
  137. package/dist/resizable.browser.global.js +4 -7
  138. package/dist/resizable.browser.global.js.map +1 -1
  139. package/dist/resolver.browser.global.js +45 -100
  140. package/dist/resolver.browser.global.js.map +1 -1
  141. package/dist/schemas/index.cjs +38 -93
  142. package/dist/schemas/index.cjs.map +1 -1
  143. package/dist/schemas/index.d.cts +2 -2
  144. package/dist/schemas/index.d.ts +2 -2
  145. package/dist/schemas/index.js +11 -11
  146. package/dist/schemas/index.js.map +1 -1
  147. package/dist/scrollreveal.browser.global.js +5 -11
  148. package/dist/scrollreveal.browser.global.js.map +1 -1
  149. package/dist/sortable.browser.global.js +5 -9
  150. package/dist/sortable.browser.global.js.map +1 -1
  151. package/dist/tabs.browser.global.js +6 -14
  152. package/dist/tabs.browser.global.js.map +1 -1
  153. package/dist/toggleable.browser.global.js +9 -13
  154. package/dist/toggleable.browser.global.js.map +1 -1
  155. package/dist/{types-DCCtVQS5.d.cts → types-CbA4L8XJ.d.cts} +16 -23
  156. package/dist/{types-DCCtVQS5.d.ts → types-CbA4L8XJ.d.ts} +16 -23
  157. package/package.json +5 -5
  158. package/src/behavior-resolver.ts +24 -56
  159. package/src/behaviors/autodismiss.test.ts +12 -20
  160. package/src/behaviors/autodismiss.ts +8 -23
  161. package/src/behaviors/clickoutside.test.ts +13 -21
  162. package/src/behaviors/clickoutside.ts +8 -23
  163. package/src/behaviors/clipboard.test.ts +12 -34
  164. package/src/behaviors/clipboard.ts +8 -23
  165. package/src/behaviors/curated-runtime.test.ts +22 -24
  166. package/src/behaviors/draggable.ts +10 -24
  167. package/src/behaviors/experimental-runtime.test.ts +19 -18
  168. package/src/behaviors/focustrap.test.ts +12 -20
  169. package/src/behaviors/focustrap.ts +8 -23
  170. package/src/behaviors/integration.test.ts +19 -54
  171. package/src/behaviors/optional-runtime.test.ts +17 -22
  172. package/src/behaviors/removable.ts +6 -20
  173. package/src/behaviors/resizable.ts +9 -24
  174. package/src/behaviors/scrollreveal.test.ts +13 -21
  175. package/src/behaviors/scrollreveal.ts +8 -23
  176. package/src/behaviors/sortable.ts +7 -22
  177. package/src/behaviors/tabs.test.ts +12 -34
  178. package/src/behaviors/tabs.ts +8 -23
  179. package/src/behaviors/toggleable.ts +10 -26
  180. package/src/browser-resolver-bundle.ts +20 -30
  181. package/src/core-bundle.ts +11 -11
  182. package/src/index.test.ts +2 -2
  183. package/src/index.ts +30 -47
  184. package/src/registry.test.ts +9 -34
  185. package/src/registry.ts +7 -11
  186. package/src/schemas/autodismiss.schema.ts +3 -9
  187. package/src/schemas/clickoutside.schema.ts +3 -5
  188. package/src/schemas/clipboard.schema.ts +2 -6
  189. package/src/schemas/draggable.schema.ts +4 -12
  190. package/src/schemas/focustrap.schema.ts +2 -6
  191. package/src/schemas/index.ts +2 -1
  192. package/src/schemas/removable.schema.ts +2 -8
  193. package/src/schemas/resizable.schema.ts +3 -6
  194. package/src/schemas/scrollreveal.schema.ts +3 -9
  195. package/src/schemas/sortable.schema.ts +3 -7
  196. package/src/schemas/tabs.schema.ts +4 -12
  197. package/src/schemas/toggleable.schema.ts +10 -13
  198. package/src/schemas/types.ts +37 -30
  199. package/dist/chunk-2HUF6RMI.js +0 -40
  200. package/dist/chunk-2HUF6RMI.js.map +0 -1
  201. package/dist/chunk-3DVDS7CT.js.map +0 -1
  202. package/dist/chunk-5S7WN3ZQ.js.map +0 -1
  203. package/dist/chunk-66U2RSYJ.js.map +0 -1
  204. package/dist/chunk-6TJXDCAQ.js +0 -11
  205. package/dist/chunk-6TJXDCAQ.js.map +0 -1
  206. package/dist/chunk-7TPDLB7W.js +0 -40
  207. package/dist/chunk-7TPDLB7W.js.map +0 -1
  208. package/dist/chunk-CR3J7VV6.js +0 -40
  209. package/dist/chunk-CR3J7VV6.js.map +0 -1
  210. package/dist/chunk-EDBG2F57.js +0 -40
  211. package/dist/chunk-EDBG2F57.js.map +0 -1
  212. package/dist/chunk-FBQ3X3UY.js.map +0 -1
  213. package/dist/chunk-HQDYH45I.js.map +0 -1
  214. package/dist/chunk-HX663BJ4.js +0 -40
  215. package/dist/chunk-HX663BJ4.js.map +0 -1
  216. package/dist/chunk-KROW43CG.js +0 -40
  217. package/dist/chunk-KROW43CG.js.map +0 -1
  218. package/dist/chunk-L52AGCMP.js +0 -40
  219. package/dist/chunk-L52AGCMP.js.map +0 -1
  220. package/dist/chunk-MTI5PSRH.js +0 -40
  221. package/dist/chunk-MTI5PSRH.js.map +0 -1
  222. package/dist/chunk-OJ3YWO3W.js.map +0 -1
  223. package/dist/chunk-ORBJ7MRW.js +0 -40
  224. package/dist/chunk-ORBJ7MRW.js.map +0 -1
  225. package/dist/chunk-SLSCZV4A.js +0 -40
  226. package/dist/chunk-SLSCZV4A.js.map +0 -1
  227. package/dist/chunk-URZGNPTQ.js.map +0 -1
  228. package/dist/chunk-WKBRZGGL.js +0 -40
  229. package/dist/chunk-WKBRZGGL.js.map +0 -1
  230. package/dist/chunk-XYZ7FOXJ.js.map +0 -1
  231. package/dist/chunk-YXS27XM6.js.map +0 -1
  232. /package/dist/{chunk-ZR66E3T6.js.map → chunk-JNLVXPHR.js.map} +0 -0
package/CHANGELOG.md CHANGED
@@ -7,6 +7,168 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [4.0.0] - 2026-10-04
11
+
12
+ `@hyperfixi/core`'s own hyperscript engine is gone: its root re-exports `@hyperfixi/engine`, and
13
+ its `hyperfixi.js` is the engine's 34 KB script-tag bundle where core's ~352 KB bundle used to be.
14
+ The engine follows upstream `_hyperscript`'s grammar and is gated by upstream's own test suite, so
15
+ scripts in core-only syntax need upstream's spelling (two additions stay: `new X()` and
16
+ `toggle <element>`). Core's other bundles, its htmx layer, the core-era plugin packages and the
17
+ AOT compiler retire: htmx 4 or fixi supply hypermedia attributes beside the engine, and
18
+ `@lokascript/hyperscript-adapter` runs hyperscript written in other languages. Every package moves
19
+ to 4.0.0 together. Everything under **Removed** is breaking, as is each **Changed** item marked ⚠;
20
+ [MIGRATION.md](MIGRATION.md) names each replacement.
21
+
22
+ ### Removed
23
+
24
+ - **Core's engine and its API** (#1368). These root exports had no engine counterpart:
25
+ `hyperscript` (`compile`, `compileSync`, `compileAsync`, `eval`, `validate`), `lokascript`,
26
+ `Runtime`, `RuntimeBase`, `createContext` and the element-scope helpers, `installPlugin`,
27
+ `getParserExtensionRegistry`, `setGlobal`, `DebugController`, `validatePartialContent` and its
28
+ helpers, `fromCoreAST` / `toCoreAST`. `parse` is now the engine's. The root is ESM-only, like the
29
+ engine: `dist/index.cjs` and the UMD `dist/index.min.js` (`LokaScriptCore`) are gone, though the
30
+ kept subpaths still ship CommonJS.
31
+ - **21 of core's 29 entry points**: `/commands`, `/expressions`, `/parser/*`, `/behaviors`,
32
+ `/bundle-generator`, `/registry/*`, `/lse`, and `/browser/` `hybrid-complete`, `hybrid-hx`,
33
+ `hybrid-hx-v4`, `multilingual`, `modular` (#1343–#1368). Instead of `/commands`, import the
34
+ grammar modules from the root: `import { toggle } from '@hyperfixi/core'`.
35
+ - **Core's browser bundles** (#1348, #1350, #1352, #1368): `hyperfixi-hx.js`,
36
+ `hyperfixi-hx-v4.js`, `hyperfixi-hybrid-complete.js`, `hyperfixi-multilingual.js`,
37
+ `hyperfixi-classic-i18n.js` and the code-split `hyperfixi.mjs`, plus every alias
38
+ (`hyperfixi-browser.js`, `hyperfixi-hybrid-hx.js`, each `lokascript-*.js`). Only
39
+ `hyperfixi.js` remains. CDN URLs pinned to 3.x keep working.
40
+ - **Core's embedded htmx layer** (#1342, #1348, #1350): `hx-*` and fixi `fx-*` on core's runtime,
41
+ `hx-live`, `sse-connect` / `sse-swap`, `ws-connect` / `ws-send`. Load htmx 4 or fixi beside the
42
+ engine. `hx-live` becomes the engine's `live` block, and SSE and WebSockets are htmx 4's
43
+ `hx-sse` / `hx-ws`.
44
+ - **Core-only members of `window.hyperfixi`**: `compile`, `compileSync`, `execute`, `setLocale`,
45
+ `evalLSENode`, `debugControl`, `semanticDebug`, the `hyperfixi:semantic-parse` event,
46
+ `hyperfixi:debug` logging, `_hyperscript.behaviors.resolve`, and the deprecated
47
+ `window.lokascript` (#1352, #1355).
48
+ - **Core-only hyperscript syntax** (#1346, #1363, #1365). The engine rejects `has` / `have`,
49
+ `prepend`, `copy`, `push url` / `replace url`, `process partials`, the `pseudo` keyword, prefix
50
+ `unless`, bare `beep`, `a ? b : c`, core's `swap <strategy> of X with Y`, `set @a to v on X`,
51
+ `.debounce(n)` / `.throttle(n)`, `my?.x` and `tell X to …`. A few forms still parse but no longer
52
+ do what they did, such as `toggle .a on this` and `go forward`. MIGRATION.md gives each form's
53
+ upstream spelling. The multilingual reader still accepts them all.
54
+ - **`@hyperfixi/core/multilingual`'s class API** (#1345, #1368): `MultilingualHyperscript` (with
55
+ `parseToAST`, `getAllTranslations`, …), `getMultilingual`, `multilingual`, `LanguageInfo`,
56
+ `schemaRoleInferrer`. The entry is three async functions: `parse`, `render`, `translate`.
57
+ - **The AOT compiler** (#1364). Its output ran only on a runtime that was never published.
58
+ `@lokascript/compilation-service` loses `compile()`, `POST /compile`, `CompileResponse`, the
59
+ compile cache (`SemanticCache`, `getCacheStats`, `clearCache`, `/cache`), `generateTests`'
60
+ `executionMode` and `generate()`'s `'js'` target. `generate()` now requires `target`
61
+ (`react` | `vue` | `svelte` | `intent-element`). `@hyperfixi/mcp-server` loses
62
+ `compile_hyperscript`, `execute_lse`, `lse_to_hyperscript`'s `compile` option and
63
+ `generate_tests`' `executionMode`, leaving 106 tools. The loop is now `validate_and_compile`
64
+ (name kept), then repair, then the hyperscript as is in `_="…"`.
65
+ - **`@hyperfixi/vite-plugin`'s compile mode** (#1360). `mode: 'compile'` warns and builds the
66
+ engine bundle. The exports `CompiledHandler`, `CompileOptions` and
67
+ `set/clear/hasSemanticParser` are removed.
68
+ - **Smaller removals.** `@hyperfixi/core/reference` loses `availability`, `BundleAvailability`
69
+ and `getCommandsByAvailability` (#1363). `@hyperfixi/speech` loses `speechPlugin`,
70
+ `speakCommand`, `askCommand` and `answerCommand`; the engine has `ask` / `answer` (#1358).
71
+ `@hyperfixi/intent-element` loses its `evalLSENode` fallback (#1356).
72
+ `@hyperfixi/patterns-reference` loses four rows that held only retired htmx attributes, and
73
+ `hx-live-with-mutator` is renamed `live-with-handler` (#1348). Of the never-published VS Code
74
+ extensions, the LokaScript one loses its debugger and the standalone `_hyperscript` one is
75
+ retired (#1361).
76
+
77
+ ### Deprecated
78
+
79
+ - **`@hyperfixi/reactivity`, `@hyperfixi/realtime`, `@hyperfixi/components`**: deprecated on npm,
80
+ last version 3.3.0 (#1358). Use the engine's built-in `live` / `when` / `bind`, htmx 4's
81
+ `hx-sse` / `hx-ws`, and upstream's component extension.
82
+ - **`@hyperfixi/types-browser`'s `LokaScriptCoreAPI`**: a deprecated alias of `HyperfixiAPI`
83
+ (#1356).
84
+
85
+ ### Changed
86
+
87
+ - ⚠ **`@hyperfixi/core` is the engine plus tooling** (#1368). The root is
88
+ `export * from '@hyperfixi/engine'` and `VERSION`: `register`, `everything` and each grammar
89
+ module, `api`, `parse`, `evaluate`, `processNode`, `boot`, and the AST types. The engine stays
90
+ external, so both packages share one grammar. Kept: `/multilingual`, `/ast-utils`,
91
+ `/reference`, `/metadata`, `/lsp-metadata`, `/browser`.
92
+ - ⚠ **`hyperfixi.js` (`@hyperfixi/core/browser`) is the engine's `hyperfixi-hs.js`**, byte for
93
+ byte: 34 KB gzipped instead of ~352 KB (#1355). `window.hyperfixi` is `window._hyperscript`,
94
+ upstream-shaped (`evaluate`, `parse`, `process`, `use`, `config`, `addSourceTransform`). Parse
95
+ errors are a `hyperscript:parse-error` event on the element plus a `console.error` (#1354).
96
+ - ⚠ **Runtime semantics follow upstream** wherever core's differed. `swap #a with #b` exchanges
97
+ the elements; `show` / `hide … with *opacity` honour the strategy; `tell` binds `you`, not `me`;
98
+ `set` on a selector sets every match; and `no ""` is true. MIGRATION.md has the full list.
99
+ - ⚠ **`@hyperfixi/vite-plugin` emits a bundle on `@hyperfixi/engine`** (#1343). There is one
100
+ tier: the grammar modules the scan finds. It weighs 17.9 KB gzipped for three commands (3.x lite:
101
+ 3.9 KB) and 34.4 KB for everything; 3.x fell back to 352 KB on `fetch`. htmx is not bundled.
102
+ Non-English scripts are translated as the engine reads them. `devFallback: 'everything'` is new,
103
+ and `'full'` / `'hybrid-complete'` mean the same. The plugin no longer depends on core.
104
+ - ⚠ **`@hyperfixi/behaviors` runs on the engine** (peer `@hyperfixi/engine`; upstream works too).
105
+ Each behavior is defined with `host.evaluate(source)` and written in upstream's idioms.
106
+ Toggleable's `target` parameter is now `targetEl`. `LokaScriptInstance` / `LokaScriptWindow`
107
+ are now `HyperscriptHost` / `HyperscriptWindow` (#1338).
108
+ - ⚠ **`@hyperfixi/speech` is an engine module** (#1358). Install it with
109
+ `register(...everything, speak)`. It is ESM-only and peers on the engine. `speak` takes
110
+ upstream's syntax (`speak <text> [with voice|rate|pitch|volume <x>]…`) and waits for the
111
+ utterance to end.
112
+ - ⚠ **The localized htmx vocabulary moved** from `@hyperfixi/core/vocab/htmx/{lang}.js` to
113
+ `@lokascript/htmx-adapter/vocab/{lang}.js`; the data is unchanged (#1349).
114
+ - **`@hyperfixi/intent-element`** renders an intent to English with the page's semantic bundle
115
+ and runs it through the host's `evaluate` (`NO_RENDERER` without one). It peers on
116
+ `@hyperfixi/engine` and `@lokascript/semantic` (#1339, #1356).
117
+ - **`@lokascript/semantic` writes upstream's spelling in English** for core-only forms (#1346).
118
+ For example, `has` becomes `matches`, `prepend` becomes `put … at start of`, and swap strategies
119
+ become `put … into` / `before` / `after`. This reaches `translate(…, 'en')`,
120
+ `render(node, 'en')`, both adapters and MCP `translate_to_english`. In `fromSemanticAST`, a
121
+ handler's `then` chain is now its body (#1359).
122
+ - **The language tools read the engine's parse** (#1356, #1359, #1365).
123
+ `@lokascript/language-server` and MCP `validate_hyperscript` report the engine's errors
124
+ (`source: 'engine'`). Hover and symbols come from `@lokascript/semantic`, and some long handlers
125
+ show fewer commands than in 3.x. Hyperscript mode flags exactly `new X()` and `toggle <element>`.
126
+ `@lokascript/compilation-service` rejects natural-language input the engine cannot read
127
+ (`ENGINE_PARSE_ERROR`), and its generated Playwright tests load `hyperfixi-hs.js`. The language
128
+ server, the MCP server and the compilation service now peer on `@hyperfixi/engine`.
129
+ - **MCP**: `get_bundle_config` recommends `hyperfixi-hs.js`, plus an `adapter` field for
130
+ non-English. `analyze_complexity` / `analyze_metrics` no longer count every comparison as a
131
+ decision. The `debug_*` tools point to `log` and `breakpoint`. `UNSUPPORTED_QUERY_LITERAL` is
132
+ gone (#1350, #1352, #1359, #1361, #1364).
133
+ - **`@hyperfixi/core/reference`, `/lsp-metadata`, `/metadata` describe the engine** (#1355,
134
+ #1363). They cover its 53 commands, adding `for`, `ask`, `answer` and `beep!`. Examples are in
135
+ upstream spelling and each is checked to parse; descriptions of core-only semantics (`pick`,
136
+ `beep`, `swap`) are fixed. `FEATURE_KEYWORDS` gains `install`, `when`, `live` and `bind`, and
137
+ `bundleInfo` holds one row.
138
+ - **Dependencies.** `@lokascript/i18n`, `@hyperfixi/testing-framework`, `@hyperfixi/vite-plugin`,
139
+ `@hyperfixi/behaviors`, `@hyperfixi/speech` and `@hyperfixi/intent-element` no longer depend
140
+ on core. Core drops `@lokascript/intent`, morphlex, tslib and its optional peers. Versions are
141
+ lockstep, so upgrade `@hyperfixi/*` and `@lokascript/*` together. `@hyperfixi/mcp-server`,
142
+ `@lokascript/framework` (tests) and `@hyperfixi/server-bridge` (tests) range on
143
+ `@lokascript/domains ^3.0.1`, the first domains release whose peers accept framework,
144
+ semantic and intent 4.x (`^3.1.0 || ^4.0.0`).
145
+
146
+ ### Added
147
+
148
+ - **`@hyperfixi/engine` exports `expr`**, so a grammar module can live in another package
149
+ (#1358).
150
+ - **`@hyperfixi/core/ast-utils`'s `withEnginePositions`** gives interchange nodes the source
151
+ spans of the engine's parse (#1359).
152
+
153
+ ### Fixed
154
+
155
+ - **`@hyperfixi/engine`** accepts upstream's `beep!` command (`beep! a, b`); 3.3.0 rejected it
156
+ (#1362).
157
+ - **`@hyperfixi/types-browser`** types `window.hyperfixi` / `window._hyperscript` as the engine's
158
+ `HyperfixiAPI`. 3.3.0 re-exported a `./globals` it never emitted, so `window.hyperfixi` was
159
+ untyped (#1356).
160
+ - **Semantic browser bundles** (#1351). Single-language and regional bundles (es, ja,
161
+ east-asian, …) registered no English, so the hyperscript adapter left scripts untranslated. They
162
+ now register it (+~2.2 KB gzipped) and export `translate`. The lite adapter finds any
163
+ `LokaScriptSemantic*` global.
164
+ - **`@lokascript/semantic`** (#1338, #1343, #1347). `/core` plus a language module no longer
165
+ throws "No patterns registered". `on click from (x or me)` parses in th and zh. A `js … end`
166
+ block no longer ends its handler in ja / ko / hi / tr / qu / bn. An options object's `}` is no
167
+ longer read as an SOV event name.
168
+ - **Language server and MCP** (#1359, #1363, #1365). `beep!` has hover docs. `set X to`
169
+ completions offer values. Hyperscript-mode errors land on the form, not line 0. Hover no longer
170
+ shows a second `on click`.
171
+
10
172
  ## [3.3.0] - 2026-10-02
11
173
 
12
174
  The first publication of `@hyperfixi/engine`, the hyperscript engine meant to replace the one
package/README.md CHANGED
@@ -1,16 +1,36 @@
1
1
  # @hyperfixi/behaviors
2
2
 
3
- Reusable hyperscript behaviors for HyperFixi / LokaScript. A behavior is installed
4
- on any element with `_="install BehaviorName(params)"` and is defined in **pure
5
- hyperscript** (its `source`), compiled on demand.
3
+ Reusable hyperscript behaviors. A behavior is installed on any element with
4
+ `_="install BehaviorName(params)"` and is defined in **pure hyperscript** (its `source`),
5
+ in upstream `_hyperscript`'s own idioms. The host is `@hyperfixi/engine` (the
6
+ `hyperfixi-hs.js` script-tag bundle); every source also runs, unchanged, on upstream
7
+ `_hyperscript` 0.9.93.
6
8
 
7
9
  ```html
8
- <script src="hyperfixi.js"></script>
10
+ <script src="hyperfixi-hs.js"></script>
9
11
  <script src="resolver.browser.global.js"></script>
10
- <!-- install X just works — behaviors compile on first use -->
12
+ <!-- install X just works — the bundle defines every behavior on the host -->
11
13
  <button _="install Toggleable(cls: 'active')">Toggle</button>
12
14
  ```
13
15
 
16
+ ## Hosts
17
+
18
+ The bundle (and the npm `register*()` functions) define each behavior with the host's
19
+ `evaluate(source)`, exactly as a page's `<script type="text/hyperscript">` would. Anything
20
+ shaped like upstream's `_hyperscript` object is a host; `window.hyperfixi` is tried first,
21
+ then `window._hyperscript`.
22
+
23
+ - **`@hyperfixi/engine`** (`hyperfixi-hs.js`): the peer dependency, and what the tests run
24
+ on. `install Toggleable` with no arguments works.
25
+ - **upstream `_hyperscript`** (0.9.93): every source runs the same, measured in a browser
26
+ (2026-10-03). One difference, upstream's: `install Toggleable` _without parentheses_ throws
27
+ there, so write `install Toggleable()` (or give an argument) on upstream.
28
+
29
+ Two things the sources never do, because no hyperscript engine reads them that way: default a
30
+ parameter with a bare `set cls to "active"` (it makes a local the handlers never see — the
31
+ sources write `set element's cls to …`), and name a parameter `target` (that is hyperscript's
32
+ own name for the event target, so Toggleable's is `targetEl`).
33
+
14
34
  ## The boundary rule — what a behavior _is_
15
35
 
16
36
  > **A behavior is a named, parameterized, _reusable inline script_ — `on event →
@@ -22,10 +42,10 @@ This rule is why the set is small and tiered. Most "behaviors" people reach for
22
42
  really just short inline scripts — see [Recipes](#recipes--most-things-are-inline-scripts).
23
43
 
24
44
  A single source of truth drives every consumer: the hyperscript `source` string in
25
- each `src/schemas/*.schema.ts`. The npm `register*()` functions, the CDN
26
- `resolver.browser.global.js` bundle, and `@hyperfixi/patterns-reference` all compile
45
+ each `src/schemas/*.schema.ts`. The npm `register*()` functions, the browser
46
+ `resolver.browser.global.js` bundle, and `@hyperfixi/patterns-reference` all define
27
47
  that **same source** — one runtime path, identical in the browser and Node. **Every
28
- behavior compiles from `source`; there is no imperative-JS installer.** (An earlier
48
+ behavior is defined from `source`; there is no imperative-JS installer.** (An earlier
29
49
  imperative-installer experiment forked a second, diverging path; it has been removed
30
50
  for all tiers — including the three experimental components, which now run their
31
51
  pointer loops from `source` like everything else.)
@@ -87,7 +107,7 @@ recipe to an installed behavior only when it is genuinely reusable and parameter
87
107
 
88
108
  ```javascript
89
109
  import { registerAll } from '@hyperfixi/behaviors';
90
- await registerAll(); // registers every behavior with window.hyperfixi
110
+ await registerAll(); // defines every behavior on window.hyperfixi (or window._hyperscript)
91
111
 
92
112
  import { registerToggleable } from '@hyperfixi/behaviors/toggleable';
93
113
  await registerToggleable(); // tree-shakeable single behavior
@@ -1,17 +1,10 @@
1
- "use strict";var HyperFixiBehaviors=(()=>{var G=Object.defineProperty;var Mt=Object.getOwnPropertyDescriptor;var It=Object.getOwnPropertyNames;var Ft=Object.prototype.hasOwnProperty;var i=(t,e)=>()=>(t&&(e=t(t=0)),e);var l=(t,e)=>{for(var r in e)G(t,r,{get:e[r],enumerable:!0})},Ot=(t,e,r,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let m of It(e))!Ft.call(t,m)&&m!==r&&G(t,m,{get:()=>e[m],enumerable:!(o=Mt(e,m))||o.enumerable});return t};var Dt=t=>Ot(G({},"__esModule",{value:!0}),t);var u,K=i(()=>{"use strict";u={name:"Draggable",category:"ui",tier:"core",version:"1.0.0",description:"Makes elements draggable with pointer events (EXPERIMENTAL \u2014 stateful async component, beyond the inline-scripting boundary; not part of the curated set)",parameters:[{name:"dragHandle",type:"selector",optional:!0,default:"me",description:"CSS selector for the drag handle element"}],events:[{name:"draggable:start",description:"Fired when drag begins"},{name:"draggable:move",description:"Fired during each movement"},{name:"draggable:end",description:"Fired when drag completes"}],requirements:["position: absolute or position: fixed on the element"],source:`
1
+ "use strict";var HyperFixiBehaviors=(()=>{var K=Object.defineProperty;var Ot=Object.getOwnPropertyDescriptor;var Mt=Object.getOwnPropertyNames;var Dt=Object.prototype.hasOwnProperty;var i=(e,t)=>()=>(e&&(t=e(e=0)),t);var d=(e,t)=>{for(var r in t)K(e,r,{get:t[r],enumerable:!0})},It=(e,t,r,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let p of Mt(t))!Dt.call(e,p)&&p!==r&&K(e,p,{get:()=>t[p],enumerable:!(s=Ot(t,p))||s.enumerable});return e};var Lt=e=>It(K({},"__esModule",{value:!0}),e);var u,J=i(()=>{"use strict";u={name:"Draggable",category:"ui",tier:"core",version:"1.0.0",description:"Makes elements draggable with pointer events (EXPERIMENTAL \u2014 stateful async component, beyond the inline-scripting boundary; not part of the curated set)",parameters:[{name:"dragHandle",type:"selector",optional:!0,default:"me",description:"CSS selector for the drag handle element"}],events:[{name:"draggable:start",description:"Fired when drag begins"},{name:"draggable:move",description:"Fired during each movement"},{name:"draggable:end",description:"Fired when drag completes"}],requirements:["position: absolute or position: fixed on the element"],source:`
2
2
  behavior Draggable(dragHandle)
3
- init
4
- if no dragHandle set dragHandle to me
5
- end
6
- on pointerdown(clientX, clientY) from dragHandle
3
+ on pointerdown(clientX, clientY) from (dragHandle or me)
7
4
  halt the event
8
5
  trigger draggable:start
9
- measure x
10
- set startX to it
11
- measure y
12
- set startY to it
13
- set xoff to clientX - startX
14
- set yoff to clientY - startY
6
+ set xoff to clientX - my offsetLeft
7
+ set yoff to clientY - my offsetTop
15
8
  repeat until event pointerup from document
16
9
  wait for pointermove(clientX, clientY) or
17
10
  pointerup(clientX, clientY) from document
@@ -20,15 +13,9 @@ behavior Draggable(dragHandle)
20
13
  end
21
14
  trigger draggable:end
22
15
  end
23
- end
24
- `.trim()}});function a(){if(typeof window>"u")return null;let t=window;return t.lokascript||t.hyperfixi||null}var c=i(()=>{"use strict"});var Ke={};l(Ke,{default:()=>ee,draggableMetadata:()=>Z,draggableSource:()=>Q,registerDraggable:()=>E});async function E(t){let e=t||a();if(!e)throw new Error("LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors.");let r=e.compileSync(u.source,{traditional:!0});if(!r.ok)throw new Error(`Failed to compile Draggable behavior: ${JSON.stringify(r.errors)}`);let o=e.createContext?e.createContext():{locals:new Map,globals:new Map};await e.execute(r.ast,o)}var Q,Z,ee,_=i(()=>{"use strict";K();c();Q=u.source,Z=u;a()&&E().catch(console.error);ee={source:u.source,metadata:u,register:E}});var p,te=i(()=>{"use strict";p={name:"Removable",category:"data",tier:"common",version:"1.2.0",description:"Makes elements removable on click",parameters:[{name:"triggerEl",type:"selector",optional:!0,default:"me",description:"Element that triggers removal (e.g., a close button)"},{name:"confirmRemoval",type:"boolean",optional:!0,default:!1,description:"Show confirmation dialog before removal"},{name:"effect",type:"string",optional:!0,default:"none",enum:["fade","none"],description:'Transition effect: "fade" or "none"'}],events:[{name:"removable:before",description:"Fired before removal (cancelable)"},{name:"removable:removed",description:"Fired after removal"}],source:`
16
+ end`.trim()}});function o(){if(typeof window>"u")return null;let e=window,t=e.hyperfixi??e._hyperscript;return t&&typeof t.evaluate=="function"?t:null}function a(e,t){let r=t??o();if(!r)throw new Error(`No hyperscript host found: load @hyperfixi/engine (hyperfixi-hs.js) before defining ${e.name}.`);try{r.evaluate(e.source)}catch(s){throw new Error(`Failed to define ${e.name} behavior: ${s.message}`)}}var l=i(()=>{"use strict"});var Je={};d(Je,{default:()=>ee,draggableMetadata:()=>Z,draggableSource:()=>Q,registerDraggable:()=>A});async function A(e){a(u,e)}var Q,Z,ee,z=i(()=>{"use strict";J();l();Q=u.source,Z=u;o()&&A().catch(console.error);ee={source:u.source,metadata:u,register:A}});var f,te=i(()=>{"use strict";f={name:"Removable",category:"data",tier:"common",version:"1.2.0",description:"Makes elements removable on click",parameters:[{name:"triggerEl",type:"selector",optional:!0,default:"me",description:"Element that triggers removal (e.g., a close button)"},{name:"confirmRemoval",type:"boolean",optional:!0,default:!1,description:"Show confirmation dialog before removal"},{name:"effect",type:"string",optional:!0,default:"none",enum:["fade","none"],description:'Transition effect: "fade" or "none"'}],events:[{name:"removable:before",description:"Fired before removal (cancelable)"},{name:"removable:removed",description:"Fired after removal"}],source:`
25
17
  behavior Removable(triggerEl, confirmRemoval, effect)
26
- init
27
- if triggerEl is undefined
28
- set triggerEl to me
29
- end
30
- end
31
- on click from triggerEl
18
+ on click from (triggerEl or me)
32
19
  if confirmRemoval
33
20
  js(me)
34
21
  if (!window.confirm("Are you sure?")) return "cancel";
@@ -44,55 +31,44 @@ behavior Removable(triggerEl, confirmRemoval, effect)
44
31
  trigger removable:removed
45
32
  remove me
46
33
  end
47
- end
48
- `.trim()}});var Qe={};l(Qe,{default:()=>ae,registerRemovable:()=>C,removableMetadata:()=>oe,removableSource:()=>re});async function C(t){let e=t||a();if(!e)throw new Error("LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors.");let r=e.compileSync(p.source,{traditional:!0});if(!r.ok)throw new Error(`Failed to compile Removable behavior: ${JSON.stringify(r.errors)}`);let o=e.createContext?e.createContext():{locals:new Map,globals:new Map};await e.execute(r.ast,o)}var re,oe,ae,H=i(()=>{"use strict";te();c();re=p.source,oe=p;a()&&C().catch(console.error);ae={source:p.source,metadata:p,register:C}});var f,ie=i(()=>{"use strict";f={name:"Toggleable",category:"form",tier:"core",version:"1.0.0",description:"Toggles a CSS class on click",parameters:[{name:"cls",type:"string",optional:!0,default:"active",description:"CSS class to toggle"},{name:"target",type:"selector",optional:!0,default:"me",description:"Element to toggle the class on"}],events:[{name:"toggleable:on",description:"Fired when class is added"},{name:"toggleable:off",description:"Fired when class is removed"}],source:`
49
- behavior Toggleable(cls, target)
34
+ end`.trim()}});var Qe={};d(Qe,{default:()=>ie,registerRemovable:()=>R,removableMetadata:()=>oe,removableSource:()=>re});async function R(e){a(f,e)}var re,oe,ie,W=i(()=>{"use strict";te();l();re=f.source,oe=f;o()&&R().catch(console.error);ie={source:f.source,metadata:f,register:R}});var v,ae=i(()=>{"use strict";v={name:"Toggleable",category:"form",tier:"core",version:"1.0.0",description:"Toggles a CSS class on click",parameters:[{name:"cls",type:"string",optional:!0,default:"active",description:"CSS class to toggle"},{name:"targetEl",type:"selector",optional:!0,default:"me",description:"Element to toggle the class on (not `target`: that is hyperscript's name for the event target)"}],events:[{name:"toggleable:on",description:"Fired when class is added"},{name:"toggleable:off",description:"Fired when class is removed"}],source:`
35
+ behavior Toggleable(cls, targetEl)
50
36
  init
51
- if cls is undefined
52
- set cls to "active"
53
- end
54
- if target is undefined
55
- set target to me
56
- end
37
+ if cls is undefined set element's cls to "active" end
38
+ if targetEl is undefined set element's targetEl to me end
57
39
  end
58
40
  on click
59
- toggle .{cls} on target
60
- js(target, cls)
61
- var eventName = target.classList.contains(cls) ? 'toggleable:on' : 'toggleable:off';
62
- target.dispatchEvent(new CustomEvent(eventName, { bubbles: true }));
41
+ toggle .{cls} on targetEl
42
+ js(targetEl, cls)
43
+ var eventName = targetEl.classList.contains(cls) ? 'toggleable:on' : 'toggleable:off';
44
+ targetEl.dispatchEvent(new CustomEvent(eventName, { bubbles: true }));
63
45
  end
64
46
  end
65
- end`.trim()}});var Ze={};l(Ze,{default:()=>ce,registerToggleable:()=>A,toggleableMetadata:()=>ne,toggleableSource:()=>se});async function A(t){let e=t||a();if(!e)throw new Error("LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors.");let r=e.compileSync(f.source,{traditional:!0});if(!r.ok)throw new Error(`Failed to compile Toggleable behavior: ${JSON.stringify(r.errors)}`);let o=e.createContext?e.createContext():{locals:new Map,globals:new Map};await e.execute(r.ast,o)}var se,ne,ce,z=i(()=>{"use strict";ie();c();se=f.source,ne=f;a()&&A().catch(console.error);ce={source:f.source,metadata:f,register:A}});var h,le=i(()=>{"use strict";h={name:"Sortable",category:"ui",tier:"common",version:"1.0.0",description:"Makes child elements reorderable via drag-and-drop (EXPERIMENTAL \u2014 stateful async component, beyond the inline-scripting boundary; not part of the curated set)",parameters:[{name:"dragClass",type:"string",optional:!0,default:"sorting",description:"CSS class added to item during drag"}],events:[{name:"sortable:start",description:"Fired when drag begins"},{name:"sortable:move",description:"Fired during drag \u2014 handle this event to reorder DOM elements"},{name:"sortable:end",description:"Fired when drag completes"}],requirements:["Users must handle DOM reordering in sortable:move event handlers"],source:`
47
+ end`.trim()}});var Ze={};d(Ze,{default:()=>ce,registerToggleable:()=>H,toggleableMetadata:()=>ne,toggleableSource:()=>se});async function H(e){a(v,e)}var se,ne,ce,N=i(()=>{"use strict";ae();l();se=v.source,ne=v;o()&&H().catch(console.error);ce={source:v.source,metadata:v,register:H}});var h,le=i(()=>{"use strict";h={name:"Sortable",category:"ui",tier:"common",version:"1.0.0",description:"Makes child elements reorderable via drag-and-drop (EXPERIMENTAL \u2014 stateful async component, beyond the inline-scripting boundary; not part of the curated set)",parameters:[{name:"dragClass",type:"string",optional:!0,default:"sorting",description:"CSS class added to item during drag"}],events:[{name:"sortable:start",description:"Fired when drag begins"},{name:"sortable:move",description:"Fired during drag \u2014 handle this event to reorder DOM elements"},{name:"sortable:end",description:"Fired when drag completes"}],requirements:["Users must handle DOM reordering in sortable:move event handlers"],source:`
66
48
  behavior Sortable(dragClass)
67
- init
68
- if dragClass is undefined
69
- set dragClass to "sorting"
70
- end
71
- end
72
49
  on pointerdown(clientY) from me
73
50
  set item to the target.closest("li")
74
51
  if item is null
75
52
  exit
76
53
  end
77
54
  halt the event
78
- add .{dragClass} to item
55
+ set cls to dragClass or "sorting"
56
+ add .{cls} to item
79
57
  trigger sortable:start on me
80
58
  repeat until event pointerup from document
81
59
  wait for pointermove(clientY) or pointerup(clientY) from document
82
60
  trigger sortable:move on me
83
61
  end
84
- remove .{dragClass} from item
62
+ remove .{cls} from item
85
63
  trigger sortable:end on me
86
64
  end
87
- end`.trim()}});var et={};l(et,{default:()=>ue,registerSortable:()=>B,sortableMetadata:()=>me,sortableSource:()=>de});async function B(t){let e=t||a();if(!e)throw new Error("LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors.");let r=e.compileSync(h.source,{traditional:!0});if(!r.ok)throw new Error(`Failed to compile Sortable behavior: ${JSON.stringify(r.errors)}`);let o=e.createContext?e.createContext():{locals:new Map,globals:new Map};await e.execute(r.ast,o)}var de,me,ue,N=i(()=>{"use strict";le();c();de=h.source,me=h;a()&&B().catch(console.error);ue={source:h.source,metadata:h,register:B}});var v,pe=i(()=>{"use strict";v={name:"Resizable",category:"ui",tier:"optional",version:"1.0.0",description:"Makes elements resizable by dragging (EXPERIMENTAL \u2014 stateful async component, beyond the inline-scripting boundary; not part of the curated set)",parameters:[{name:"minWidth",type:"number",optional:!0,default:50,description:"Minimum width in pixels"},{name:"minHeight",type:"number",optional:!0,default:50,description:"Minimum height in pixels"},{name:"maxWidth",type:"number",optional:!0,default:9999,description:"Maximum width in pixels"},{name:"maxHeight",type:"number",optional:!0,default:9999,description:"Maximum height in pixels"}],events:[{name:"resizable:start",description:"Fired when resize begins"},{name:"resizable:resize",description:"Fired during resize"},{name:"resizable:end",description:"Fired when resize completes"}],source:`
65
+ end`.trim()}});var et={};d(et,{default:()=>pe,registerSortable:()=>T,sortableMetadata:()=>me,sortableSource:()=>de});async function T(e){a(h,e)}var de,me,pe,_=i(()=>{"use strict";le();l();de=h.source,me=h;o()&&T().catch(console.error);pe={source:h.source,metadata:h,register:T}});var b,ue=i(()=>{"use strict";b={name:"Resizable",category:"ui",tier:"optional",version:"1.0.0",description:"Makes elements resizable by dragging (EXPERIMENTAL \u2014 stateful async component, beyond the inline-scripting boundary; not part of the curated set)",parameters:[{name:"minWidth",type:"number",optional:!0,default:50,description:"Minimum width in pixels"},{name:"minHeight",type:"number",optional:!0,default:50,description:"Minimum height in pixels"},{name:"maxWidth",type:"number",optional:!0,default:9999,description:"Maximum width in pixels"},{name:"maxHeight",type:"number",optional:!0,default:9999,description:"Maximum height in pixels"}],events:[{name:"resizable:start",description:"Fired when resize begins"},{name:"resizable:resize",description:"Fired during resize"},{name:"resizable:end",description:"Fired when resize completes"}],source:`
88
66
  behavior Resizable(minWidth, minHeight, maxWidth, maxHeight)
89
67
  on pointerdown(clientX, clientY) from me
90
68
  halt the event
91
69
  trigger resizable:start
92
- measure width
93
- set startWidth to it
94
- measure height
95
- set startHeight to it
70
+ set startWidth to my offsetWidth
71
+ set startHeight to my offsetHeight
96
72
  set startX to clientX
97
73
  set startY to clientY
98
74
  repeat until event pointerup from document
@@ -109,16 +85,11 @@ behavior Resizable(minWidth, minHeight, maxWidth, maxHeight)
109
85
  end
110
86
  trigger resizable:end
111
87
  end
112
- end
113
- `.trim()}});var tt={};l(tt,{default:()=>ve,registerResizable:()=>R,resizableMetadata:()=>he,resizableSource:()=>fe});async function R(t){let e=t||a();if(!e)throw new Error("LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors.");let r=e.compileSync(v.source,{traditional:!0});if(!r.ok)throw new Error(`Failed to compile Resizable behavior: ${JSON.stringify(r.errors)}`);let o=e.createContext?e.createContext():{locals:new Map,globals:new Map};await e.execute(r.ast,o)}var fe,he,ve,W=i(()=>{"use strict";pe();c();fe=v.source,he=v;a()&&R().catch(console.error);ve={source:v.source,metadata:v,register:R}});var b,be=i(()=>{"use strict";b={name:"Clipboard",category:"ui",tier:"core",version:"1.0.0",description:"Copies text to clipboard on click with visual feedback",parameters:[{name:"text",type:"string",optional:!0,description:"Literal text to copy (takes priority over source)"},{name:"source",type:"selector",optional:!0,default:"me",description:"Element whose textContent or value is copied"},{name:"feedback",type:"selector",optional:!0,description:"Element to show .copied feedback on (defaults to the installed element)"},{name:"feedbackDuration",type:"number",optional:!0,default:2e3,description:"Duration in ms to show .copied class feedback"}],events:[{name:"clipboard:copied",description:"Fired after text is copied successfully"},{name:"clipboard:error",description:"Fired when clipboard write fails"}],requirements:["navigator.clipboard.writeText() requires HTTPS or localhost",'Falls back to document.execCommand("copy") for older browsers'],source:`
88
+ end`.trim()}});var tt={};d(tt,{default:()=>he,registerResizable:()=>C,resizableMetadata:()=>ve,resizableSource:()=>fe});async function C(e){a(b,e)}var fe,ve,he,j=i(()=>{"use strict";ue();l();fe=b.source,ve=b;o()&&C().catch(console.error);he={source:b.source,metadata:b,register:C}});var g,be=i(()=>{"use strict";g={name:"Clipboard",category:"ui",tier:"core",version:"1.0.0",description:"Copies text to clipboard on click with visual feedback",parameters:[{name:"text",type:"string",optional:!0,description:"Literal text to copy (takes priority over source)"},{name:"source",type:"selector",optional:!0,default:"me",description:"Element whose textContent or value is copied"},{name:"feedback",type:"selector",optional:!0,description:"Element to show .copied feedback on (defaults to the installed element)"},{name:"feedbackDuration",type:"number",optional:!0,default:2e3,description:"Duration in ms to show .copied class feedback"}],events:[{name:"clipboard:copied",description:"Fired after text is copied successfully"},{name:"clipboard:error",description:"Fired when clipboard write fails"}],requirements:["navigator.clipboard.writeText() requires HTTPS or localhost",'Falls back to document.execCommand("copy") for older browsers'],source:`
114
89
  behavior Clipboard(text, source, feedback, feedbackDuration)
115
90
  init
116
- if feedbackDuration is undefined
117
- set feedbackDuration to 2000
118
- end
119
- if source is undefined
120
- set source to me
121
- end
91
+ if feedbackDuration is undefined set element's feedbackDuration to 2000 end
92
+ if source is undefined set element's source to me end
122
93
  end
123
94
  on click
124
95
  if text is not undefined
@@ -155,18 +126,12 @@ behavior Clipboard(text, source, feedback, feedbackDuration)
155
126
  })();
156
127
  end
157
128
  end
158
- end`.trim()}});var rt={};l(rt,{clipboardMetadata:()=>ye,clipboardSource:()=>ge,default:()=>xe,registerClipboard:()=>T});async function T(t){let e=t||a();if(!e)throw new Error("LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors.");let r=e.compileSync(b.source,{traditional:!0});if(!r.ok)throw new Error(`Failed to compile Clipboard behavior: ${JSON.stringify(r.errors)}`);let o=e.createContext?e.createContext():{locals:new Map,globals:new Map};await e.execute(r.ast,o)}var ge,ye,xe,$=i(()=>{"use strict";be();c();ge=b.source,ye=b;a()&&T().catch(console.error);xe={source:b.source,metadata:b,register:T}});var g,Se=i(()=>{"use strict";g={name:"AutoDismiss",category:"ui",tier:"core",version:"1.0.0",description:"Auto-removes elements after a delay with optional pause-on-hover",parameters:[{name:"delay",type:"number",optional:!0,default:5e3,description:"Time in ms before the element is removed"},{name:"pauseOnHover",type:"boolean",optional:!0,default:!0,description:"Pause the countdown when the mouse hovers over the element"},{name:"effect",type:"string",optional:!0,default:"none",enum:["fade","none"],description:'Transition effect before removal: "fade" or "none"'}],events:[{name:"autodismiss:start",description:"Fired when the countdown timer starts"},{name:"autodismiss:dismissed",description:"Fired before removal (cancelable via preventDefault)"},{name:"autodismiss:paused",description:"Fired when the timer is paused on hover"},{name:"autodismiss:resumed",description:"Fired when the timer resumes on mouseleave"}],source:`
129
+ end`.trim()}});var rt={};d(rt,{clipboardMetadata:()=>ye,clipboardSource:()=>ge,default:()=>xe,registerClipboard:()=>k});async function k(e){a(g,e)}var ge,ye,xe,Y=i(()=>{"use strict";be();l();ge=g.source,ye=g;o()&&k().catch(console.error);xe={source:g.source,metadata:g,register:k}});var y,Se=i(()=>{"use strict";y={name:"AutoDismiss",category:"ui",tier:"core",version:"1.0.0",description:"Auto-removes elements after a delay with optional pause-on-hover",parameters:[{name:"delay",type:"number",optional:!0,default:5e3,description:"Time in ms before the element is removed"},{name:"pauseOnHover",type:"boolean",optional:!0,default:!0,description:"Pause the countdown when the mouse hovers over the element"},{name:"effect",type:"string",optional:!0,default:"none",enum:["fade","none"],description:'Transition effect before removal: "fade" or "none"'}],events:[{name:"autodismiss:start",description:"Fired when the countdown timer starts"},{name:"autodismiss:dismissed",description:"Fired before removal (cancelable via preventDefault)"},{name:"autodismiss:paused",description:"Fired when the timer is paused on hover"},{name:"autodismiss:resumed",description:"Fired when the timer resumes on mouseleave"}],source:`
159
130
  behavior AutoDismiss(delay, pauseOnHover, effect)
160
131
  init
161
- if delay is undefined
162
- set delay to 5000
163
- end
164
- if pauseOnHover is undefined
165
- set pauseOnHover to true
166
- end
167
- if effect is undefined
168
- set effect to "none"
169
- end
132
+ if delay is undefined set element's delay to 5000 end
133
+ if pauseOnHover is undefined set element's pauseOnHover to true end
134
+ if effect is undefined set element's effect to "none" end
170
135
  js(me, delay, effect, pauseOnHover)
171
136
  me.dispatchEvent(new CustomEvent('autodismiss:start', { bubbles: true }));
172
137
  var remaining = delay;
@@ -208,12 +173,10 @@ behavior AutoDismiss(delay, pauseOnHover, effect)
208
173
  }
209
174
  end
210
175
  end
211
- end`.trim()}});var ot={};l(ot,{autoDismissMetadata:()=>ke,autoDismissSource:()=>we,default:()=>Ee,registerAutoDismiss:()=>L});async function L(t){let e=t||a();if(!e)throw new Error("LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors.");let r=e.compileSync(g.source,{traditional:!0});if(!r.ok)throw new Error(`Failed to compile AutoDismiss behavior: ${JSON.stringify(r.errors)}`);let o=e.createContext?e.createContext():{locals:new Map,globals:new Map};await e.execute(r.ast,o)}var we,ke,Ee,Y=i(()=>{"use strict";Se();c();we=g.source,ke=g;a()&&L().catch(console.error);Ee={source:g.source,metadata:g,register:L}});var y,Ce=i(()=>{"use strict";y={name:"ClickOutside",category:"ui",tier:"core",version:"1.0.0",description:"Fires an event when the user clicks outside the element",parameters:[{name:"active",type:"boolean",optional:!0,default:!0,description:"Whether the listener is active (can be toggled programmatically)"}],events:[{name:"clickoutside",description:"Fired when a pointer press occurs outside the element"},{name:"clickoutside:activate",description:"Listen for this event to programmatically activate detection"},{name:"clickoutside:deactivate",description:"Listen for this event to programmatically deactivate detection"}],requirements:["Uses pointerdown instead of click to avoid timing issues with removed elements"],source:`
176
+ end`.trim()}});var ot={};d(ot,{autoDismissMetadata:()=>Be,autoDismissSource:()=>we,default:()=>Ee,registerAutoDismiss:()=>F});async function F(e){a(y,e)}var we,Be,Ee,X=i(()=>{"use strict";Se();l();we=y.source,Be=y;o()&&F().catch(console.error);Ee={source:y.source,metadata:y,register:F}});var x,Ae=i(()=>{"use strict";x={name:"ClickOutside",category:"ui",tier:"core",version:"1.0.0",description:"Fires an event when the user clicks outside the element",parameters:[{name:"active",type:"boolean",optional:!0,default:!0,description:"Whether the listener is active (can be toggled programmatically)"}],events:[{name:"clickoutside",description:"Fired when a pointer press occurs outside the element"},{name:"clickoutside:activate",description:"Listen for this event to programmatically activate detection"},{name:"clickoutside:deactivate",description:"Listen for this event to programmatically deactivate detection"}],requirements:["Uses pointerdown instead of click to avoid timing issues with removed elements"],source:`
212
177
  behavior ClickOutside(active)
213
178
  init
214
- if active is undefined
215
- set active to true
216
- end
179
+ if active is undefined set element's active to true end
217
180
  end
218
181
  on pointerdown from document
219
182
  js(me, active, event)
@@ -224,20 +187,16 @@ behavior ClickOutside(active)
224
187
  end
225
188
  end
226
189
  on clickoutside:activate
227
- set active to true
190
+ set element's active to true
228
191
  end
229
192
  on clickoutside:deactivate
230
- set active to false
193
+ set element's active to false
231
194
  end
232
- end`.trim()}});var at={};l(at,{clickOutsideMetadata:()=>Be,clickOutsideSource:()=>Ae,default:()=>Re,registerClickOutside:()=>M});async function M(t){let e=t||a();if(!e)throw new Error("LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors.");let r=e.compileSync(y.source,{traditional:!0});if(!r.ok)throw new Error(`Failed to compile ClickOutside behavior: ${JSON.stringify(r.errors)}`);let o=e.createContext?e.createContext():{locals:new Map,globals:new Map};await e.execute(r.ast,o)}var Ae,Be,Re,j=i(()=>{"use strict";Ce();c();Ae=y.source,Be=y;a()&&M().catch(console.error);Re={source:y.source,metadata:y,register:M}});var x,Te=i(()=>{"use strict";x={name:"FocusTrap",category:"ui",tier:"core",version:"1.0.0",description:"Confines Tab navigation inside an element with ARIA support",parameters:[{name:"active",type:"boolean",optional:!0,default:!0,description:"Whether the trap is active on install"},{name:"initialFocus",type:"selector",optional:!0,description:"Element to focus when the trap activates"},{name:"returnFocus",type:"boolean",optional:!0,default:!0,description:"Restore focus to the previously focused element on deactivation"}],events:[{name:"focustrap:activated",description:"Fired when the trap is activated"},{name:"focustrap:deactivated",description:"Fired when the trap is deactivated"}],requirements:['Sets aria-modal="true" on the element when active',"Listens for focustrap:activate and focustrap:deactivate custom events for programmatic control"],source:`
195
+ end`.trim()}});var it={};d(it,{clickOutsideMetadata:()=>He,clickOutsideSource:()=>Re,default:()=>Te,registerClickOutside:()=>O});async function O(e){a(x,e)}var Re,He,Te,$=i(()=>{"use strict";Ae();l();Re=x.source,He=x;o()&&O().catch(console.error);Te={source:x.source,metadata:x,register:O}});var S,Ce=i(()=>{"use strict";S={name:"FocusTrap",category:"ui",tier:"core",version:"1.0.0",description:"Confines Tab navigation inside an element with ARIA support",parameters:[{name:"active",type:"boolean",optional:!0,default:!0,description:"Whether the trap is active on install"},{name:"initialFocus",type:"selector",optional:!0,description:"Element to focus when the trap activates"},{name:"returnFocus",type:"boolean",optional:!0,default:!0,description:"Restore focus to the previously focused element on deactivation"}],events:[{name:"focustrap:activated",description:"Fired when the trap is activated"},{name:"focustrap:deactivated",description:"Fired when the trap is deactivated"}],requirements:['Sets aria-modal="true" on the element when active',"Listens for focustrap:activate and focustrap:deactivate custom events for programmatic control"],source:`
233
196
  behavior FocusTrap(active, initialFocus, returnFocus)
234
197
  init
235
- if active is undefined
236
- set active to true
237
- end
238
- if returnFocus is undefined
239
- set returnFocus to true
240
- end
198
+ if active is undefined set element's active to true end
199
+ if returnFocus is undefined set element's returnFocus to true end
241
200
  js(me, active, initialFocus, returnFocus)
242
201
  var FOCUSABLE = 'a[href],button:not(:disabled),input:not(:disabled),select:not(:disabled),textarea:not(:disabled),[tabindex]:not([tabindex="-1"])';
243
202
  var isActive = false;
@@ -277,18 +236,12 @@ behavior FocusTrap(active, initialFocus, returnFocus)
277
236
  if (active) activate();
278
237
  end
279
238
  end
280
- end`.trim()}});var it={};l(it,{default:()=>Ie,focusTrapMetadata:()=>Me,focusTrapSource:()=>Le,registerFocusTrap:()=>I});async function I(t){let e=t||a();if(!e)throw new Error("LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors.");let r=e.compileSync(x.source,{traditional:!0});if(!r.ok)throw new Error(`Failed to compile FocusTrap behavior: ${JSON.stringify(r.errors)}`);let o=e.createContext?e.createContext():{locals:new Map,globals:new Map};await e.execute(r.ast,o)}var Le,Me,Ie,X=i(()=>{"use strict";Te();c();Le=x.source,Me=x;a()&&I().catch(console.error);Ie={source:x.source,metadata:x,register:I}});var S,Fe=i(()=>{"use strict";S={name:"ScrollReveal",category:"layout",tier:"common",version:"1.0.0",description:"Adds a class when the element enters the viewport via IntersectionObserver",parameters:[{name:"cls",type:"string",optional:!0,default:"revealed",description:"CSS class added when element enters viewport"},{name:"threshold",type:"number",optional:!0,default:.1,description:"Intersection ratio threshold (0-1) for triggering"},{name:"once",type:"boolean",optional:!0,default:!0,description:"If true, disconnect observer after first intersection"}],events:[{name:"scrollreveal:enter",description:"Fired when the element enters the viewport"},{name:"scrollreveal:exit",description:"Fired when the element exits the viewport"}],requirements:["Uses IntersectionObserver API (supported in all modern browsers)"],source:`
239
+ end`.trim()}});var at={};d(at,{default:()=>Oe,focusTrapMetadata:()=>Fe,focusTrapSource:()=>ke,registerFocusTrap:()=>M});async function M(e){a(S,e)}var ke,Fe,Oe,U=i(()=>{"use strict";Ce();l();ke=S.source,Fe=S;o()&&M().catch(console.error);Oe={source:S.source,metadata:S,register:M}});var w,Me=i(()=>{"use strict";w={name:"ScrollReveal",category:"layout",tier:"common",version:"1.0.0",description:"Adds a class when the element enters the viewport via IntersectionObserver",parameters:[{name:"cls",type:"string",optional:!0,default:"revealed",description:"CSS class added when element enters viewport"},{name:"threshold",type:"number",optional:!0,default:.1,description:"Intersection ratio threshold (0-1) for triggering"},{name:"once",type:"boolean",optional:!0,default:!0,description:"If true, disconnect observer after first intersection"}],events:[{name:"scrollreveal:enter",description:"Fired when the element enters the viewport"},{name:"scrollreveal:exit",description:"Fired when the element exits the viewport"}],requirements:["Uses IntersectionObserver API (supported in all modern browsers)"],source:`
281
240
  behavior ScrollReveal(cls, threshold, once)
282
241
  init
283
- if cls is undefined
284
- set cls to "revealed"
285
- end
286
- if threshold is undefined
287
- set threshold to 0.1
288
- end
289
- if once is undefined
290
- set once to true
291
- end
242
+ if cls is undefined set element's cls to "revealed" end
243
+ if threshold is undefined set element's threshold to 0.1 end
244
+ if once is undefined set element's once to true end
292
245
  js(me, cls, threshold, once)
293
246
  var obs = new IntersectionObserver(function(entries) {
294
247
  for (var i = 0; i < entries.length; i++) {
@@ -305,21 +258,13 @@ behavior ScrollReveal(cls, threshold, once)
305
258
  obs.observe(me);
306
259
  end
307
260
  end
308
- end`.trim()}});var st={};l(st,{default:()=>Pe,registerScrollReveal:()=>F,scrollRevealMetadata:()=>De,scrollRevealSource:()=>Oe});async function F(t){let e=t||a();if(!e)throw new Error("LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors.");let r=e.compileSync(S.source,{traditional:!0});if(!r.ok)throw new Error(`Failed to compile ScrollReveal behavior: ${JSON.stringify(r.errors)}`);let o=e.createContext?e.createContext():{locals:new Map,globals:new Map};await e.execute(r.ast,o)}var Oe,De,Pe,U=i(()=>{"use strict";Fe();c();Oe=S.source,De=S;a()&&F().catch(console.error);Pe={source:S.source,metadata:S,register:F}});var w,_e=i(()=>{"use strict";w={name:"Tabs",category:"ui",tier:"core",version:"1.0.0",description:"WAI-ARIA compliant tabs with roving tabindex keyboard navigation. Auto-wires role, aria-selected, aria-controls, and aria-labelledby attributes.",parameters:[{name:"orientation",type:"string",optional:!0,default:"horizontal",enum:["horizontal","vertical"],description:"Arrow key direction: horizontal (Left/Right) or vertical (Up/Down)"},{name:"activeTab",type:"number",optional:!0,default:0,description:"Initial active tab index (zero-based)"},{name:"wrap",type:"boolean",optional:!0,default:!0,description:"Wrap to first/last tab when navigating past the end"},{name:"activeClass",type:"string",optional:!0,default:"active",description:"CSS class applied to the active tab and its panel"}],events:[{name:"tabs:change",description:"Fired before tab selection changes (cancelable via preventDefault)"},{name:"tabs:changed",description:"Fired after tab selection has changed"}],requirements:['Sets role="tablist" on the tab container','Sets role="tab" on tab buttons and role="tabpanel" on content panels',"Manages aria-selected, aria-controls, aria-labelledby, and tabindex","Keyboard: Arrow keys navigate, Home/End jump to first/last, Tab exits tablist"],source:`
261
+ end`.trim()}});var st={};d(st,{default:()=>Le,registerScrollReveal:()=>D,scrollRevealMetadata:()=>Ie,scrollRevealSource:()=>De});async function D(e){a(w,e)}var De,Ie,Le,V=i(()=>{"use strict";Me();l();De=w.source,Ie=w;o()&&D().catch(console.error);Le={source:w.source,metadata:w,register:D}});var B,Pe=i(()=>{"use strict";B={name:"Tabs",category:"ui",tier:"core",version:"1.0.0",description:"WAI-ARIA compliant tabs with roving tabindex keyboard navigation. Auto-wires role, aria-selected, aria-controls, and aria-labelledby attributes.",parameters:[{name:"orientation",type:"string",optional:!0,default:"horizontal",enum:["horizontal","vertical"],description:"Arrow key direction: horizontal (Left/Right) or vertical (Up/Down)"},{name:"activeTab",type:"number",optional:!0,default:0,description:"Initial active tab index (zero-based)"},{name:"wrap",type:"boolean",optional:!0,default:!0,description:"Wrap to first/last tab when navigating past the end"},{name:"activeClass",type:"string",optional:!0,default:"active",description:"CSS class applied to the active tab and its panel"}],events:[{name:"tabs:change",description:"Fired before tab selection changes (cancelable via preventDefault)"},{name:"tabs:changed",description:"Fired after tab selection has changed"}],requirements:['Sets role="tablist" on the tab container','Sets role="tab" on tab buttons and role="tabpanel" on content panels',"Manages aria-selected, aria-controls, aria-labelledby, and tabindex","Keyboard: Arrow keys navigate, Home/End jump to first/last, Tab exits tablist"],source:`
309
262
  behavior Tabs(orientation, activeTab, wrap, activeClass)
310
263
  init
311
- if orientation is undefined
312
- set orientation to "horizontal"
313
- end
314
- if activeTab is undefined
315
- set activeTab to 0
316
- end
317
- if wrap is undefined
318
- set wrap to true
319
- end
320
- if activeClass is undefined
321
- set activeClass to "active"
322
- end
264
+ if orientation is undefined set element's orientation to "horizontal" end
265
+ if activeTab is undefined set element's activeTab to 0 end
266
+ if wrap is undefined set element's wrap to true end
267
+ if activeClass is undefined set element's activeClass to "active" end
323
268
  js(me, orientation, activeTab, wrap, activeClass)
324
269
  var tabs = Array.from(me.querySelectorAll('[role="tab"]'));
325
270
  var panels = Array.from(me.querySelectorAll('[role="tabpanel"]'));
@@ -384,5 +329,5 @@ behavior Tabs(orientation, activeTab, wrap, activeClass)
384
329
  });
385
330
  end
386
331
  end
387
- end`.trim()}});var nt={};l(nt,{default:()=>Ne,registerTabs:()=>O,tabsMetadata:()=>ze,tabsSource:()=>He});async function O(t){let e=t||a();if(!e)throw new Error("LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors.");let r=e.compileSync(w.source,{traditional:!0});if(!r.ok)throw new Error(`Failed to compile Tabs behavior: ${JSON.stringify(r.errors)}`);let o=e.createContext?e.createContext():{locals:new Map,globals:new Map};await e.execute(r.ast,o)}var He,ze,Ne,V=i(()=>{"use strict";_e();c();He=w.source,ze=w;a()&&O().catch(console.error);Ne={source:w.source,metadata:w,register:O}});var Pt={};l(Pt,{ALL_BEHAVIOR_NAMES:()=>wt,AutoDismiss:()=>Ee,BEHAVIORS_BY_CATEGORY:()=>kt,BEHAVIORS_BY_TIER:()=>Et,BEHAVIOR_CATEGORIES:()=>Ct,BEHAVIOR_TIERS:()=>At,CURATED_BEHAVIORS:()=>Ue,CURATION_STATUS:()=>q,ClickOutside:()=>Re,Clipboard:()=>xe,Draggable:()=>ee,EXPERIMENTAL_BEHAVIORS:()=>qe,FocusTrap:()=>Ie,OPTIONAL_BEHAVIORS:()=>Ve,Removable:()=>ae,Resizable:()=>ve,ScrollReveal:()=>Pe,Sortable:()=>ue,Tabs:()=>Ne,Toggleable:()=>ce,autoDismissMetadata:()=>ke,autoDismissSource:()=>we,clickOutsideMetadata:()=>Be,clickOutsideSource:()=>Ae,clipboardMetadata:()=>ye,clipboardSource:()=>ge,curationStatusOf:()=>Bt,draggableMetadata:()=>Z,draggableSource:()=>Q,focusTrapMetadata:()=>Me,focusTrapSource:()=>Le,getAllSchemas:()=>ht,getAllSchemasRecord:()=>vt,getAvailableBehaviors:()=>Ye,getBehavior:()=>ct,getBehaviorsByCategory:()=>je,getBehaviorsByTier:()=>Xe,getRegisteredBehaviors:()=>ft,getSchema:()=>dt,hasLoader:()=>pt,isCurated:()=>Rt,isRegistered:()=>ut,loadAll:()=>yt,loadBehavior:()=>D,preloadCategory:()=>gt,preloadTier:()=>bt,ready:()=>J,registerAll:()=>Tt,registerAllWithRuntime:()=>St,registerAutoDismiss:()=>L,registerBehavior:()=>$e,registerClickOutside:()=>M,registerClipboard:()=>T,registerDraggable:()=>E,registerFocusTrap:()=>I,registerLoader:()=>n,registerRemovable:()=>C,registerResizable:()=>R,registerSchema:()=>s,registerScrollReveal:()=>F,registerSortable:()=>B,registerTabs:()=>O,registerToggleable:()=>A,registerWithRuntime:()=>xt,removableMetadata:()=>oe,removableSource:()=>re,resizableMetadata:()=>he,resizableSource:()=>fe,scrollRevealMetadata:()=>De,scrollRevealSource:()=>Oe,sortableMetadata:()=>me,sortableSource:()=>de,tabsMetadata:()=>ze,tabsSource:()=>He,toggleableMetadata:()=>ne,toggleableSource:()=>se,tryGetBehavior:()=>lt,tryGetSchema:()=>mt});_();H();z();N();W();$();Y();j();X();U();V();var d=new Map,k=new Map,P=new Map,We=new Map;function $e(t,e){d.set(t,e),e.metadata&&k.set(t,e.metadata)}function s(t){k.set(t.name,t)}function n(t,e){P.set(t,e)}function ct(t){let e=d.get(t);if(!e){let r=Array.from(d.keys()).join(", ");throw new Error(`Behavior '${t}' is not registered. Registered behaviors: ${r||"none"}. Use loadBehavior('${t}') to lazy load it.`)}return e}function lt(t){return d.get(t)}function dt(t){let e=k.get(t);if(!e)throw new Error(`Schema for behavior '${t}' is not registered. Use tryGetSchema('${t}') for a non-throwing alternative.`);return e}function mt(t){return k.get(t)}function ut(t){return d.has(t)}function pt(t){return P.has(t)}function ft(){return Array.from(d.keys())}function Ye(){let t=new Set([...d.keys(),...P.keys()]);return Array.from(t)}function je(t){let e=[];for(let[r,o]of k)o.category===t&&e.push(r);return e}function Xe(t){let e=[];for(let[r,o]of k)o.tier===t&&e.push(r);return e}function ht(){return Array.from(k.values())}function vt(){let t={};for(let[e,r]of k)t[e]=r;return t}async function D(t){let e=d.get(t);if(e)return e;let r=We.get(t);if(r)return r;let o=P.get(t);if(!o)throw new Error(`No loader registered for behavior '${t}'. Available loaders: ${Array.from(P.keys()).join(", ")||"none"}`);let m=o().then(Lt=>{let Ge=Lt.default;return $e(t,Ge),We.delete(t),Ge});return We.set(t,m),m}async function bt(t){let e=Xe(t);await Promise.all(e.map(r=>D(r).catch(o=>{console.warn(`[behaviors] Failed to preload '${r}' (tier: ${t}):`,o)})))}async function gt(t){let e=je(t);await Promise.all(e.map(r=>D(r).catch(o=>{console.warn(`[behaviors] Failed to preload '${r}' (category: ${t}):`,o)})))}async function yt(){let t=Ye();await Promise.all(t.map(e=>D(e).catch(r=>{console.warn(`[behaviors] Failed to load '${e}':`,r)})))}async function xt(t,e){await(await D(t)).register(e)}async function St(t){let e=Array.from(d.values()).map(r=>r.register(t));await Promise.all(e)}K();le();pe();te();ie();be();Se();Ce();Te();Fe();_e();s(u);s(h);s(v);s(p);s(f);s(b);s(g);s(y);s(x);s(S);s(w);n("Draggable",()=>Promise.resolve().then(()=>(_(),Ke)));n("Sortable",()=>Promise.resolve().then(()=>(N(),et)));n("Resizable",()=>Promise.resolve().then(()=>(W(),tt)));n("Removable",()=>Promise.resolve().then(()=>(H(),Qe)));n("Toggleable",()=>Promise.resolve().then(()=>(z(),Ze)));n("Clipboard",()=>Promise.resolve().then(()=>($(),rt)));n("AutoDismiss",()=>Promise.resolve().then(()=>(Y(),ot)));n("ClickOutside",()=>Promise.resolve().then(()=>(j(),at)));n("FocusTrap",()=>Promise.resolve().then(()=>(X(),it)));n("ScrollReveal",()=>Promise.resolve().then(()=>(U(),st)));n("Tabs",()=>Promise.resolve().then(()=>(V(),nt)));var wt=["Draggable","Sortable","Resizable","Removable","Toggleable","Clipboard","AutoDismiss","ClickOutside","FocusTrap","ScrollReveal","Tabs"],kt={ui:["Draggable","Sortable","Resizable","Clipboard","AutoDismiss","ClickOutside","FocusTrap","Tabs"],data:["Removable"],animation:[],form:["Toggleable"],layout:["ScrollReveal"]},Et={core:["Draggable","Toggleable","Clipboard","AutoDismiss","ClickOutside","FocusTrap","Tabs"],common:["Sortable","Removable","ScrollReveal"],optional:["Resizable"]},Ct={Draggable:"ui",Sortable:"ui",Resizable:"ui",Removable:"data",Toggleable:"form",Clipboard:"ui",AutoDismiss:"ui",ClickOutside:"ui",FocusTrap:"ui",ScrollReveal:"layout",Tabs:"ui"},At={Draggable:"core",Sortable:"common",Resizable:"optional",Removable:"common",Toggleable:"core",Clipboard:"core",AutoDismiss:"core",ClickOutside:"core",FocusTrap:"core",ScrollReveal:"common",Tabs:"core"};var Ue=["Toggleable","Removable","ClickOutside","Clipboard","AutoDismiss"],Ve=["FocusTrap","ScrollReveal","Tabs"],qe=["Draggable","Sortable","Resizable"],q={...Object.fromEntries(Ue.map(t=>[t,"curated"])),...Object.fromEntries(Ve.map(t=>[t,"optional"])),...Object.fromEntries(qe.map(t=>[t,"experimental"]))};function Bt(t){return q[t]}function Rt(t){return q[t]==="curated"}_();H();z();N();W();$();Y();j();X();U();V();c();async function Tt(t){await Promise.all([E(t),C(t),A(t),B(t),R(t),T(t),L(t),M(t),I(t),F(t),O(t)])}var J=null,Je=a();if(Je){let t=window;J=Tt(Je),t.__hyperfixi_behaviors_ready=J,J.then(()=>{let e=Je,r=t.__hyperfixi_behaviors_ready;delete t.__hyperfixi_behaviors_ready,e.attributeProcessor?.scanAndProcessAll?e.attributeProcessor.scanAndProcessAll().finally(()=>{t.__hyperfixi_behaviors_ready=r}):e.processNode&&(e.processNode(document),t.__hyperfixi_behaviors_ready=r)}).catch(e=>{console.error("[behaviors] Auto-registration failed:",e)})}return Dt(Pt);})();
332
+ end`.trim()}});var nt={};d(nt,{default:()=>Ne,registerTabs:()=>I,tabsMetadata:()=>We,tabsSource:()=>ze});async function I(e){a(B,e)}var ze,We,Ne,q=i(()=>{"use strict";Pe();l();ze=B.source,We=B;o()&&I().catch(console.error);Ne={source:B.source,metadata:B,register:I}});var Pt={};d(Pt,{ALL_BEHAVIOR_NAMES:()=>wt,AutoDismiss:()=>Ee,BEHAVIORS_BY_CATEGORY:()=>Bt,BEHAVIORS_BY_TIER:()=>Et,BEHAVIOR_CATEGORIES:()=>At,BEHAVIOR_TIERS:()=>Rt,CURATED_BEHAVIORS:()=>Ue,CURATION_STATUS:()=>G,ClickOutside:()=>Te,Clipboard:()=>xe,Draggable:()=>ee,EXPERIMENTAL_BEHAVIORS:()=>qe,FocusTrap:()=>Oe,OPTIONAL_BEHAVIORS:()=>Ve,Removable:()=>ie,Resizable:()=>he,ScrollReveal:()=>Le,Sortable:()=>pe,Tabs:()=>Ne,Toggleable:()=>ce,autoDismissMetadata:()=>Be,autoDismissSource:()=>we,clickOutsideMetadata:()=>He,clickOutsideSource:()=>Re,clipboardMetadata:()=>ye,clipboardSource:()=>ge,curationStatusOf:()=>Ht,draggableMetadata:()=>Z,draggableSource:()=>Q,focusTrapMetadata:()=>Fe,focusTrapSource:()=>ke,getAllSchemas:()=>vt,getAllSchemasRecord:()=>ht,getAvailableBehaviors:()=>Ye,getBehavior:()=>ct,getBehaviorsByCategory:()=>Xe,getBehaviorsByTier:()=>$e,getRegisteredBehaviors:()=>ft,getSchema:()=>dt,hasLoader:()=>ut,isCurated:()=>Tt,isRegistered:()=>pt,loadAll:()=>yt,loadBehavior:()=>L,preloadCategory:()=>gt,preloadTier:()=>bt,ready:()=>kt,registerAll:()=>Ct,registerAllWithRuntime:()=>St,registerAutoDismiss:()=>F,registerBehavior:()=>je,registerClickOutside:()=>O,registerClipboard:()=>k,registerDraggable:()=>A,registerFocusTrap:()=>M,registerLoader:()=>c,registerRemovable:()=>R,registerResizable:()=>C,registerSchema:()=>n,registerScrollReveal:()=>D,registerSortable:()=>T,registerTabs:()=>I,registerToggleable:()=>H,registerWithRuntime:()=>xt,removableMetadata:()=>oe,removableSource:()=>re,resizableMetadata:()=>ve,resizableSource:()=>fe,scrollRevealMetadata:()=>Ie,scrollRevealSource:()=>De,sortableMetadata:()=>me,sortableSource:()=>de,tabsMetadata:()=>We,tabsSource:()=>ze,toggleableMetadata:()=>ne,toggleableSource:()=>se,tryGetBehavior:()=>lt,tryGetSchema:()=>mt});z();W();N();_();j();Y();X();$();U();V();q();var m=new Map,E=new Map,P=new Map,_e=new Map;function je(e,t){m.set(e,t),t.metadata&&E.set(e,t.metadata)}function n(e){E.set(e.name,e)}function c(e,t){P.set(e,t)}function ct(e){let t=m.get(e);if(!t){let r=Array.from(m.keys()).join(", ");throw new Error(`Behavior '${e}' is not registered. Registered behaviors: ${r||"none"}. Use loadBehavior('${e}') to lazy load it.`)}return t}function lt(e){return m.get(e)}function dt(e){let t=E.get(e);if(!t)throw new Error(`Schema for behavior '${e}' is not registered. Use tryGetSchema('${e}') for a non-throwing alternative.`);return t}function mt(e){return E.get(e)}function pt(e){return m.has(e)}function ut(e){return P.has(e)}function ft(){return Array.from(m.keys())}function Ye(){let e=new Set([...m.keys(),...P.keys()]);return Array.from(e)}function Xe(e){let t=[];for(let[r,s]of E)s.category===e&&t.push(r);return t}function $e(e){let t=[];for(let[r,s]of E)s.tier===e&&t.push(r);return t}function vt(){return Array.from(E.values())}function ht(){let e={};for(let[t,r]of E)e[t]=r;return e}async function L(e){let t=m.get(e);if(t)return t;let r=_e.get(e);if(r)return r;let s=P.get(e);if(!s)throw new Error(`No loader registered for behavior '${e}'. Available loaders: ${Array.from(P.keys()).join(", ")||"none"}`);let p=s().then(Ft=>{let Ke=Ft.default;return je(e,Ke),_e.delete(e),Ke});return _e.set(e,p),p}async function bt(e){let t=$e(e);await Promise.all(t.map(r=>L(r).catch(s=>{console.warn(`[behaviors] Failed to preload '${r}' (tier: ${e}):`,s)})))}async function gt(e){let t=Xe(e);await Promise.all(t.map(r=>L(r).catch(s=>{console.warn(`[behaviors] Failed to preload '${r}' (category: ${e}):`,s)})))}async function yt(){let e=Ye();await Promise.all(e.map(t=>L(t).catch(r=>{console.warn(`[behaviors] Failed to load '${t}':`,r)})))}async function xt(e,t){await(await L(e)).register(t)}async function St(e){let t=Array.from(m.values()).map(r=>r.register(e));await Promise.all(t)}J();le();ue();te();ae();be();Se();Ae();Ce();Me();Pe();n(u);n(h);n(b);n(f);n(v);n(g);n(y);n(x);n(S);n(w);n(B);c("Draggable",()=>Promise.resolve().then(()=>(z(),Je)));c("Sortable",()=>Promise.resolve().then(()=>(_(),et)));c("Resizable",()=>Promise.resolve().then(()=>(j(),tt)));c("Removable",()=>Promise.resolve().then(()=>(W(),Qe)));c("Toggleable",()=>Promise.resolve().then(()=>(N(),Ze)));c("Clipboard",()=>Promise.resolve().then(()=>(Y(),rt)));c("AutoDismiss",()=>Promise.resolve().then(()=>(X(),ot)));c("ClickOutside",()=>Promise.resolve().then(()=>($(),it)));c("FocusTrap",()=>Promise.resolve().then(()=>(U(),at)));c("ScrollReveal",()=>Promise.resolve().then(()=>(V(),st)));c("Tabs",()=>Promise.resolve().then(()=>(q(),nt)));var wt=["Draggable","Sortable","Resizable","Removable","Toggleable","Clipboard","AutoDismiss","ClickOutside","FocusTrap","ScrollReveal","Tabs"],Bt={ui:["Draggable","Sortable","Resizable","Clipboard","AutoDismiss","ClickOutside","FocusTrap","Tabs"],data:["Removable"],animation:[],form:["Toggleable"],layout:["ScrollReveal"]},Et={core:["Draggable","Toggleable","Clipboard","AutoDismiss","ClickOutside","FocusTrap","Tabs"],common:["Sortable","Removable","ScrollReveal"],optional:["Resizable"]},At={Draggable:"ui",Sortable:"ui",Resizable:"ui",Removable:"data",Toggleable:"form",Clipboard:"ui",AutoDismiss:"ui",ClickOutside:"ui",FocusTrap:"ui",ScrollReveal:"layout",Tabs:"ui"},Rt={Draggable:"core",Sortable:"common",Resizable:"optional",Removable:"common",Toggleable:"core",Clipboard:"core",AutoDismiss:"core",ClickOutside:"core",FocusTrap:"core",ScrollReveal:"common",Tabs:"core"};var Ue=["Toggleable","Removable","ClickOutside","Clipboard","AutoDismiss"],Ve=["FocusTrap","ScrollReveal","Tabs"],qe=["Draggable","Sortable","Resizable"],G={...Object.fromEntries(Ue.map(e=>[e,"curated"])),...Object.fromEntries(Ve.map(e=>[e,"optional"])),...Object.fromEntries(qe.map(e=>[e,"experimental"]))};function Ht(e){return G[e]}function Tt(e){return G[e]==="curated"}z();W();N();_();j();Y();X();$();U();V();q();l();async function Ct(e){await Promise.all([A(e),R(e),H(e),T(e),C(e),k(e),F(e),O(e),M(e),D(e),I(e)])}var kt=null,Ge=o();Ge&&(kt=Ct(Ge).then(()=>{document.readyState!=="loading"&&Ge.processNode?.(document.body)}).catch(e=>{console.error("[behaviors] Auto-definition failed:",e)}));return Lt(Pt);})();
388
333
  //# sourceMappingURL=all.browser.global.js.map