@almadar/shell-web 0.0.0-stage → 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 (274) hide show
  1. package/bundling.d.mts +18 -0
  2. package/bundling.mjs +28 -0
  3. package/dist/ArbitraryClassCompiler-Mzabq-UB.d.ts +100 -0
  4. package/dist/AvlGlyph-JKJOAH23.js +6 -0
  5. package/dist/AvlStateMachine-PI4YGREK.js +8 -0
  6. package/dist/AvlTransitionDetail-ZH7V24UG.js +12 -0
  7. package/dist/AvlTransitionExplainer-ZSRT7L6Y.js +13 -0
  8. package/dist/BehaviorValueFrame-6RUJXT4A.js +29 -0
  9. package/dist/BehaviorValueFrame-SSEMEBTG.css +1756 -0
  10. package/dist/BehaviorView-RFEE5J6E.js +10 -0
  11. package/dist/Canvas3DHost-_Y-5uLM_.d.ts +552 -0
  12. package/dist/EventBusProvider-CVwjkV_2.d.ts +284 -0
  13. package/dist/FileTree-BCFnBEuQ.d.ts +254 -0
  14. package/dist/FlowCanvas-3JRMNJLV.css +1756 -0
  15. package/dist/FlowCanvas-STDC4OWK.js +27 -0
  16. package/dist/GameAudioProvider-Cm9BnvmP.d.ts +93 -0
  17. package/dist/KaTeX_AMS-Regular-CYEKBG2K.woff +0 -0
  18. package/dist/KaTeX_AMS-Regular-JKX5W2C4.ttf +0 -0
  19. package/dist/KaTeX_AMS-Regular-U6PRYMIZ.woff2 +0 -0
  20. package/dist/KaTeX_Caligraphic-Bold-5QL5CMTE.woff2 +0 -0
  21. package/dist/KaTeX_Caligraphic-Bold-WZ3QSGD3.woff +0 -0
  22. package/dist/KaTeX_Caligraphic-Bold-ZTS3R3HK.ttf +0 -0
  23. package/dist/KaTeX_Caligraphic-Regular-3LKEU76G.woff +0 -0
  24. package/dist/KaTeX_Caligraphic-Regular-A7XRTZ5Q.ttf +0 -0
  25. package/dist/KaTeX_Caligraphic-Regular-KX5MEWCF.woff2 +0 -0
  26. package/dist/KaTeX_Fraktur-Bold-2QVFK6NQ.woff2 +0 -0
  27. package/dist/KaTeX_Fraktur-Bold-T4SWXBMT.woff +0 -0
  28. package/dist/KaTeX_Fraktur-Bold-WGHVTYOR.ttf +0 -0
  29. package/dist/KaTeX_Fraktur-Regular-2PEIFJSJ.woff2 +0 -0
  30. package/dist/KaTeX_Fraktur-Regular-5U4OPH2X.ttf +0 -0
  31. package/dist/KaTeX_Fraktur-Regular-PQMHCIK6.woff +0 -0
  32. package/dist/KaTeX_Main-Bold-2GA4IZIN.woff +0 -0
  33. package/dist/KaTeX_Main-Bold-W5FBVCZM.ttf +0 -0
  34. package/dist/KaTeX_Main-Bold-YP5VVQRP.woff2 +0 -0
  35. package/dist/KaTeX_Main-BoldItalic-4P4C7HJH.woff +0 -0
  36. package/dist/KaTeX_Main-BoldItalic-N4V3DX7S.woff2 +0 -0
  37. package/dist/KaTeX_Main-BoldItalic-ODMLBJJQ.ttf +0 -0
  38. package/dist/KaTeX_Main-Italic-I43T2HSR.ttf +0 -0
  39. package/dist/KaTeX_Main-Italic-RELBIK7M.woff2 +0 -0
  40. package/dist/KaTeX_Main-Italic-SASNQFN2.woff +0 -0
  41. package/dist/KaTeX_Main-Regular-ARRPAO67.woff2 +0 -0
  42. package/dist/KaTeX_Main-Regular-P5I74A2A.woff +0 -0
  43. package/dist/KaTeX_Main-Regular-W74P5G27.ttf +0 -0
  44. package/dist/KaTeX_Math-BoldItalic-6EBV3DK5.woff +0 -0
  45. package/dist/KaTeX_Math-BoldItalic-K4WTGH3J.woff2 +0 -0
  46. package/dist/KaTeX_Math-BoldItalic-VB447A4D.ttf +0 -0
  47. package/dist/KaTeX_Math-Italic-6KGCHLFN.woff2 +0 -0
  48. package/dist/KaTeX_Math-Italic-KKK3USB2.woff +0 -0
  49. package/dist/KaTeX_Math-Italic-SON4MRCA.ttf +0 -0
  50. package/dist/KaTeX_SansSerif-Bold-RRNVJFFW.woff2 +0 -0
  51. package/dist/KaTeX_SansSerif-Bold-STQ6RXC7.ttf +0 -0
  52. package/dist/KaTeX_SansSerif-Bold-X5M5EMOD.woff +0 -0
  53. package/dist/KaTeX_SansSerif-Italic-HMPFTM52.woff2 +0 -0
  54. package/dist/KaTeX_SansSerif-Italic-PSN4QKYX.woff +0 -0
  55. package/dist/KaTeX_SansSerif-Italic-WTBAZBGY.ttf +0 -0
  56. package/dist/KaTeX_SansSerif-Regular-2TL3USAE.ttf +0 -0
  57. package/dist/KaTeX_SansSerif-Regular-OQCII6EP.woff +0 -0
  58. package/dist/KaTeX_SansSerif-Regular-XIQ62X4E.woff2 +0 -0
  59. package/dist/KaTeX_Script-Regular-72OLXYNA.ttf +0 -0
  60. package/dist/KaTeX_Script-Regular-A5IFOEBS.woff +0 -0
  61. package/dist/KaTeX_Script-Regular-APUWIHLP.woff2 +0 -0
  62. package/dist/KaTeX_Size1-Regular-4HRHTS65.woff +0 -0
  63. package/dist/KaTeX_Size1-Regular-5LRUTBFT.woff2 +0 -0
  64. package/dist/KaTeX_Size1-Regular-7K6AASVL.ttf +0 -0
  65. package/dist/KaTeX_Size2-Regular-222HN3GT.ttf +0 -0
  66. package/dist/KaTeX_Size2-Regular-K5ZHAIS6.woff +0 -0
  67. package/dist/KaTeX_Size2-Regular-LELKET5D.woff2 +0 -0
  68. package/dist/KaTeX_Size3-Regular-TLFPAHDE.woff +0 -0
  69. package/dist/KaTeX_Size3-Regular-UFCO6WCA.ttf +0 -0
  70. package/dist/KaTeX_Size3-Regular-WQRQ47UD.woff2 +0 -0
  71. package/dist/KaTeX_Size4-Regular-7PGNVPQK.ttf +0 -0
  72. package/dist/KaTeX_Size4-Regular-CDMV7U5C.woff2 +0 -0
  73. package/dist/KaTeX_Size4-Regular-PKMWZHNC.woff +0 -0
  74. package/dist/KaTeX_Typewriter-Regular-3F5K6SQ6.ttf +0 -0
  75. package/dist/KaTeX_Typewriter-Regular-MJMFSK64.woff +0 -0
  76. package/dist/KaTeX_Typewriter-Regular-VBYJ4NRC.woff2 +0 -0
  77. package/dist/KernelEngineContext-BOCQoFwk.d.ts +43 -0
  78. package/dist/LayersPanel-BBQ54IVG.js +7 -0
  79. package/dist/ModuleCard-3TT2X7IW.js +7 -0
  80. package/dist/OrbInspector-K6T6O7GI.js +27 -0
  81. package/dist/OrbInspector-MHLJ6OEE.css +1756 -0
  82. package/dist/Select-mDZIwNqN.d.ts +199 -0
  83. package/dist/ServerBridge-Cm1On51b.d.ts +233 -0
  84. package/dist/ThemeContext-DJmO59xd.d.ts +147 -0
  85. package/dist/TraitValueFrame-2PJGLLVI.js +28 -0
  86. package/dist/TraitValueFrame-4G3KOUBR.css +1756 -0
  87. package/dist/UISlotContext-Dl_ewwCI.d.ts +79 -0
  88. package/dist/UISlotRenderer-JKFSX24W.js +27 -0
  89. package/dist/UISlotRenderer-KVFO6J7R.css +1756 -0
  90. package/dist/UserContext-DqWeZkUZ.d.ts +100 -0
  91. package/dist/auth/browser/index.d.ts +2 -0
  92. package/dist/auth/browser/index.js +1 -0
  93. package/dist/auth/react/index.d.ts +49 -0
  94. package/dist/auth/react/index.js +119 -0
  95. package/dist/avl/index.css +1756 -0
  96. package/dist/avl/index.d.ts +2238 -0
  97. package/dist/avl/index.js +2693 -0
  98. package/dist/avl-3d-context-BIRKWpaL.d.ts +204 -0
  99. package/dist/avl-schema-parser-CtJxJ9KU.d.ts +132 -0
  100. package/dist/avl-zoom-state-CKMVuBFg.d.ts +17 -0
  101. package/dist/chunk-2PY54Z44.js +227 -0
  102. package/dist/chunk-2QOH2HWM.js +95 -0
  103. package/dist/chunk-3BBUBJFF.js +339 -0
  104. package/dist/chunk-42FY4RYA.js +191 -0
  105. package/dist/chunk-5QTYQTPS.js +15 -0
  106. package/dist/chunk-6P3MWXYE.js +440 -0
  107. package/dist/chunk-73SRAB4P.js +1053 -0
  108. package/dist/chunk-A2LR6VQQ.js +349 -0
  109. package/dist/chunk-AILY3XPS.js +562 -0
  110. package/dist/chunk-B4BU77LT.js +432 -0
  111. package/dist/chunk-DFNZUYX4.js +378 -0
  112. package/dist/chunk-DJ433ET5.js +1327 -0
  113. package/dist/chunk-DLZF4PVE.js +24 -0
  114. package/dist/chunk-DYEKAA4L.js +787 -0
  115. package/dist/chunk-DZ42OJQC.js +176 -0
  116. package/dist/chunk-EOWMARUB.js +16 -0
  117. package/dist/chunk-EQAMU2ZC.js +14 -0
  118. package/dist/chunk-FAJDTHWC.js +98 -0
  119. package/dist/chunk-FIW6WN23.js +508 -0
  120. package/dist/chunk-FP3WIKTC.js +303 -0
  121. package/dist/chunk-G7DCAZ22.js +19 -0
  122. package/dist/chunk-GAR5TQ5B.js +199 -0
  123. package/dist/chunk-GKIFONTE.js +131 -0
  124. package/dist/chunk-GYTPOFVC.js +47155 -0
  125. package/dist/chunk-KVQS4GXU.js +328 -0
  126. package/dist/chunk-L2DEKY4J.js +97 -0
  127. package/dist/chunk-L677XGY3.js +701 -0
  128. package/dist/chunk-MBQAMMSE.js +11877 -0
  129. package/dist/chunk-P4LNHAFI.js +1051 -0
  130. package/dist/chunk-P4ZFUQFF.js +93 -0
  131. package/dist/chunk-PC7K4SK7.js +1384 -0
  132. package/dist/chunk-R5O5AUPI.js +573 -0
  133. package/dist/chunk-SGM3FASH.js +672 -0
  134. package/dist/chunk-SJGJJKBY.js +502 -0
  135. package/dist/chunk-TESBIVUA.js +11 -0
  136. package/dist/chunk-TZZBINQY.js +82 -0
  137. package/dist/chunk-U6QRZASX.js +280 -0
  138. package/dist/chunk-VFF5OO47.js +319 -0
  139. package/dist/chunk-YDNJLLG6.js +516 -0
  140. package/dist/chunk-YHMRX6YA.js +455 -0
  141. package/dist/chunk-ZO6MXAS3.js +69 -0
  142. package/dist/components/index.css +1756 -0
  143. package/dist/components/index.d.ts +11093 -0
  144. package/dist/components/index.js +1110 -0
  145. package/dist/context/index.d.ts +9 -0
  146. package/dist/context/index.js +7 -0
  147. package/dist/core.d.ts +2523 -0
  148. package/dist/core.js +2 -0
  149. package/dist/design-classes/index.cjs +429 -0
  150. package/dist/design-classes/index.d.cts +165 -0
  151. package/dist/design-classes/index.d.ts +165 -0
  152. package/dist/design-classes/index.js +397 -0
  153. package/dist/emojiItems-QGSNAABW.js +20 -0
  154. package/dist/fx-CmQjnHmT.d.ts +371 -0
  155. package/dist/hooks/index.d.ts +936 -0
  156. package/dist/hooks/index.js +7 -0
  157. package/dist/index.d.ts +486 -0
  158. package/dist/index.js +38 -0
  159. package/dist/katexPlugin-FA7NX4PE.css +1161 -0
  160. package/dist/katexPlugin-NCDKOOQY.js +2 -0
  161. package/dist/kernel-client-ZH4PSMCN.js +367 -0
  162. package/dist/kernel-wire-B4S8pnP3.d.ts +65 -0
  163. package/dist/lib/index.d.ts +602 -0
  164. package/dist/lib/index.js +1288 -0
  165. package/dist/paintDispatch-ChW5mVuK.d.ts +698 -0
  166. package/dist/parseLessonSegments-GpCeMrb2.d.ts +334 -0
  167. package/dist/perf-CKiBKbkw.d.ts +22 -0
  168. package/dist/perf-Dr28-AgT.d.ts +57 -0
  169. package/dist/prism-AIWGN2X5.js +134 -0
  170. package/dist/providers/index.css +1756 -0
  171. package/dist/providers/index.d.ts +340 -0
  172. package/dist/providers/index.js +30 -0
  173. package/dist/renderer/index.d.ts +467 -0
  174. package/dist/renderer/index.js +3 -0
  175. package/dist/runtime/index.css +1756 -0
  176. package/dist/runtime/index.d.ts +440 -0
  177. package/dist/runtime/index.js +31 -0
  178. package/dist/slot-host-CPzrxLo9.d.ts +48 -0
  179. package/dist/ssr/index.cjs +7631 -0
  180. package/dist/ssr/index.d.cts +487 -0
  181. package/dist/ssr/index.d.ts +487 -0
  182. package/dist/ssr/index.js +7599 -0
  183. package/dist/storage/browser/index.d.ts +1 -0
  184. package/dist/storage/browser/index.js +1 -0
  185. package/dist/test-support.d.ts +35 -0
  186. package/dist/test-support.js +114 -0
  187. package/dist/themeTokens-CRd8AEDF.d.ts +125 -0
  188. package/dist/three/index.css +503 -0
  189. package/dist/three/index.d.ts +1185 -0
  190. package/dist/three/index.js +3896 -0
  191. package/dist/useKeyboardRouter-Dsq553Ur.d.ts +42 -0
  192. package/dist/useUISlots-CiobNFGb.d.ts +211 -0
  193. package/dist/verification-C5pTeMJv.d.ts +66 -0
  194. package/dist/verificationRegistry-CabxhfTv.d.ts +122 -0
  195. package/dist/wrapCallbackForEvent-B9QLbhxX.d.ts +19 -0
  196. package/index.css +199 -0
  197. package/package.json +269 -3
  198. package/src/core/locales/ar.json +1263 -0
  199. package/src/core/locales/en.json +1263 -0
  200. package/src/core/locales/index.ts +54 -0
  201. package/src/core/locales/sl.json +1263 -0
  202. package/src/core/tokens/native-tokens.json +369 -0
  203. package/tailwind-compile.cjs +29 -0
  204. package/tailwind-preset.cjs +991 -0
  205. package/themes/_base.css +451 -0
  206. package/themes/_contract.md +307 -0
  207. package/themes/_fonts-kenney.css +11 -0
  208. package/themes/_fonts.css +12 -0
  209. package/themes/_foundation.css +105 -0
  210. package/themes/_head.css +22 -0
  211. package/themes/_presets.css +67 -0
  212. package/themes/almadar-heritage.css +455 -0
  213. package/themes/almadar-website.css +269 -0
  214. package/themes/almadar.css +269 -0
  215. package/themes/aqua.css +455 -0
  216. package/themes/arabesque.css +459 -0
  217. package/themes/art-deco.css +457 -0
  218. package/themes/art-nouveau.css +459 -0
  219. package/themes/atelier.css +463 -0
  220. package/themes/bauhaus.css +461 -0
  221. package/themes/bloomberg-dense.css +463 -0
  222. package/themes/blueprint.css +457 -0
  223. package/themes/clay.css +449 -0
  224. package/themes/comic.css +453 -0
  225. package/themes/constructivist.css +457 -0
  226. package/themes/corporate.css +449 -0
  227. package/themes/cyberpunk.css +453 -0
  228. package/themes/frutiger-aero.css +458 -0
  229. package/themes/game-adventure.css +201 -0
  230. package/themes/game-rpg.css +203 -0
  231. package/themes/game-sci-fi.css +201 -0
  232. package/themes/game-ui-pack.css +200 -0
  233. package/themes/gazette.css +449 -0
  234. package/themes/glass.css +457 -0
  235. package/themes/gothic.css +453 -0
  236. package/themes/index.css +21 -0
  237. package/themes/ink-wash.css +459 -0
  238. package/themes/kawaii.css +459 -0
  239. package/themes/kflow.css +310 -0
  240. package/themes/kiosk.css +449 -0
  241. package/themes/linear-clean.css +463 -0
  242. package/themes/luxury.css +451 -0
  243. package/themes/mac-classic.css +455 -0
  244. package/themes/material.css +463 -0
  245. package/themes/memphis.css +453 -0
  246. package/themes/mid-century.css +455 -0
  247. package/themes/minimalist.css +449 -0
  248. package/themes/mudcloth.css +459 -0
  249. package/themes/nata.css +310 -0
  250. package/themes/neon.css +453 -0
  251. package/themes/neumorphic.css +451 -0
  252. package/themes/newsprint.css +455 -0
  253. package/themes/notion-editorial.css +463 -0
  254. package/themes/orb.css +465 -0
  255. package/themes/pixel.css +449 -0
  256. package/themes/prism.css +309 -0
  257. package/themes/rawi.css +310 -0
  258. package/themes/retro.css +452 -0
  259. package/themes/risograph.css +463 -0
  260. package/themes/scandi.css +469 -0
  261. package/themes/sketch.css +455 -0
  262. package/themes/solarpunk.css +469 -0
  263. package/themes/steampunk.css +451 -0
  264. package/themes/swiss.css +455 -0
  265. package/themes/terminal.css +466 -0
  266. package/themes/trait-wars.css +487 -0
  267. package/themes/ukiyo-e.css +459 -0
  268. package/themes/vaporwave.css +455 -0
  269. package/themes/victorian.css +453 -0
  270. package/themes/wabi-sabi.css +459 -0
  271. package/themes/win95.css +455 -0
  272. package/themes/wireframe.css +439 -0
  273. package/themes/zine.css +455 -0
  274. package/README.md +0 -3
@@ -0,0 +1,2693 @@
1
+ export { AvlTransitionExplainer } from '../chunk-TESBIVUA.js';
2
+ export { LayersPanel, parseLayerId, schemaToLayerItems } from '../chunk-GKIFONTE.js';
3
+ import { AvlTransitionDetail } from '../chunk-SGM3FASH.js';
4
+ export { AvlCircuit, AvlTransitionDetail } from '../chunk-SGM3FASH.js';
5
+ import { zoomReducer, initialZoomState, getBreadcrumbs } from '../chunk-DJ433ET5.js';
6
+ export { BehaviorView } from '../chunk-DLZF4PVE.js';
7
+ export { MiniStateMachine, ModuleCard } from '../chunk-2PY54Z44.js';
8
+ import '../chunk-U6QRZASX.js';
9
+ import '../chunk-EOWMARUB.js';
10
+ import { FlowCanvas, layeredGraph } from '../chunk-GYTPOFVC.js';
11
+ export { AVL_GRAPH_NODE_TYPES, AvlGraphCanvas, CANVAS_TOOLS, CanvasDndProvider, CanvasVerifyContext, DependencyColumnNode, DependencyNode, EDITABLE, ElementEditAccessContext, EventFlowEdge, FlowCanvas, KnobField, KnobSettingRow, LIVE_STATE, OrbInspector, OrbPreviewNode, SystemBandNode, SystemMapContext, SystemNode, canvasViewGraph, dependencyReach, deriveEditFocusFromElement, dropBusEvent, flowNeighbors, hasCanvasTool, initialStateOf, layeredGraph, optionForPlayedStep, propAccessAt, schemaToDependencyGraph, schemaToOverviewGraph, stateOptionsOf, traitFlowGraph, useCanvasDraggable, useCanvasDroppable, useInlineTextEdit } from '../chunk-GYTPOFVC.js';
12
+ import '../chunk-YDNJLLG6.js';
13
+ export { AvlStateMachine } from '../chunk-KVQS4GXU.js';
14
+ import { AvlOrbital, AvlTrait, AvlEvent, AvlGuard } from '../chunk-L677XGY3.js';
15
+ export { AVL_GLYPH_KINDS, AvlApplication, AvlBinding, AvlBindingRef, AvlEvent, AvlField, AvlGlyph, AvlGuard, AvlLiteral, AvlOperator, AvlOrbital, AvlPersistence, AvlSExpr, AvlTrait, AvlTransition } from '../chunk-L677XGY3.js';
16
+ import { AvlEntity, AvlPage, AvlState } from '../chunk-FP3WIKTC.js';
17
+ export { AvlEntity, AvlFieldType, AvlPage, AvlState, FIELD_TYPE_SHAPES } from '../chunk-FP3WIKTC.js';
18
+ import { transitionPlayback } from '../chunk-42FY4RYA.js';
19
+ export { armPosition, armsOf, firedTransition, stateMachinePlayback, transitionPlayback } from '../chunk-42FY4RYA.js';
20
+ import '../chunk-FAJDTHWC.js';
21
+ import { computeTraitLayout, edgePath } from '../chunk-GAR5TQ5B.js';
22
+ export { computeTraitLayout, edgePath } from '../chunk-GAR5TQ5B.js';
23
+ export { AvlEffectChip } from '../chunk-SJGJJKBY.js';
24
+ import { AvlEffect } from '../chunk-DZ42OJQC.js';
25
+ export { AvlEffect } from '../chunk-DZ42OJQC.js';
26
+ import '../chunk-P4LNHAFI.js';
27
+ import '../chunk-TZZBINQY.js';
28
+ import '../chunk-PC7K4SK7.js';
29
+ import { parseApplicationLevel, parseOrbitalLevel, parseTraitLevel } from '../chunk-VFF5OO47.js';
30
+ export { parseApplicationLevel, parseOrbitalLevel, parseTraitLevel, parseTransitionLevel, traitLevelFromTrait } from '../chunk-VFF5OO47.js';
31
+ import { avlSeries, CONNECTION_COLORS, getStateRole, avlTint, STATE_COLORS, effectCategoryOf, EFFECT_CATEGORY_COLORS } from '../chunk-DFNZUYX4.js';
32
+ export { CONNECTION_COLORS, EFFECT_CATEGORY_COLORS, OPERATOR_CATEGORY_COLORS, STATE_COLORS, effectCategoryOf, getStateRole } from '../chunk-DFNZUYX4.js';
33
+ import '../chunk-B4BU77LT.js';
34
+ import '../chunk-6P3MWXYE.js';
35
+ import '../chunk-DYEKAA4L.js';
36
+ import '../chunk-R5O5AUPI.js';
37
+ import '../chunk-L2DEKY4J.js';
38
+ import '../chunk-AILY3XPS.js';
39
+ import '../chunk-3BBUBJFF.js';
40
+ import '../chunk-YHMRX6YA.js';
41
+ import { useTranslate, cn, Box, HStack, Typography, pressableProps, Button, RangeSlider } from '../chunk-MBQAMMSE.js';
42
+ import '../chunk-A2LR6VQQ.js';
43
+ import '../chunk-P4ZFUQFF.js';
44
+ import '../chunk-G7DCAZ22.js';
45
+ import React4, { createContext, useMemo, useContext, useState, useReducer, useEffect, useCallback } from 'react';
46
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
47
+ import { getBezierPath, BaseEdge, EdgeLabelRenderer } from '@xyflow/react';
48
+ import { createLogger } from '@almadar/logger';
49
+ import { SExprDataSchema, PatternObjectSchema } from '@almadar/core';
50
+
51
+ var avlOuId = 0;
52
+ var AvlOrbitalUnit = ({
53
+ entityName,
54
+ fields = 4,
55
+ persistence = "persistent",
56
+ traits,
57
+ pages,
58
+ className,
59
+ color = "var(--color-primary)",
60
+ animated = false
61
+ }) => {
62
+ const ids = React4.useMemo(() => {
63
+ avlOuId += 1;
64
+ const base = `avl-ou-${avlOuId}`;
65
+ return { glow: `${base}-glow`, grad: `${base}-grad` };
66
+ }, []);
67
+ const cx = 300;
68
+ const cy = 200;
69
+ const entityR = 24;
70
+ const orbitalR = 130;
71
+ const traitBaseRx = 55;
72
+ const traitBaseRy = 24;
73
+ const traitRxStep = 20;
74
+ const traitRyStep = 8;
75
+ const traitAngleStep = traits.length > 1 ? 120 / (traits.length - 1) : 0;
76
+ const traitAngleStart = traits.length > 1 ? -60 : 0;
77
+ const pageAngleStart = -Math.PI / 3;
78
+ const pageAngleStep = pages.length > 1 ? Math.PI * 0.8 / (pages.length - 1) : 0;
79
+ return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 600 400", xmlns: "http://www.w3.org/2000/svg", className, children: [
80
+ /* @__PURE__ */ jsxs("defs", { children: [
81
+ /* @__PURE__ */ jsxs("filter", { id: ids.glow, x: "-50%", y: "-50%", width: "200%", height: "200%", children: [
82
+ /* @__PURE__ */ jsx("feGaussianBlur", { in: "SourceGraphic", stdDeviation: "3", result: "blur" }),
83
+ /* @__PURE__ */ jsxs("feMerge", { children: [
84
+ /* @__PURE__ */ jsx("feMergeNode", { in: "blur" }),
85
+ /* @__PURE__ */ jsx("feMergeNode", { in: "SourceGraphic" })
86
+ ] })
87
+ ] }),
88
+ /* @__PURE__ */ jsxs("radialGradient", { id: ids.grad, cx: "50%", cy: "50%", r: "50%", children: [
89
+ /* @__PURE__ */ jsx("stop", { offset: "0%", stopColor: color, stopOpacity: 0.08 }),
90
+ /* @__PURE__ */ jsx("stop", { offset: "100%", stopColor: color, stopOpacity: 0 })
91
+ ] })
92
+ ] }),
93
+ animated && /* @__PURE__ */ jsx("style", { children: `
94
+ @keyframes avl-ou-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
95
+ ` }),
96
+ /* @__PURE__ */ jsx("circle", { cx, cy, r: orbitalR + 20, fill: `url(#${ids.grad})` }),
97
+ /* @__PURE__ */ jsx(AvlOrbital, { cx, cy, r: orbitalR, label: entityName, color }),
98
+ traits.map((trait, i) => {
99
+ const rotation = traitAngleStart + i * traitAngleStep;
100
+ const traitColor = trait.color ?? color;
101
+ return /* @__PURE__ */ jsx(
102
+ AvlTrait,
103
+ {
104
+ cx,
105
+ cy,
106
+ rx: traitBaseRx + i * traitRxStep,
107
+ ry: traitBaseRy + i * traitRyStep,
108
+ rotation,
109
+ label: trait.name,
110
+ color: traitColor,
111
+ opacity: 0.7
112
+ },
113
+ trait.name
114
+ );
115
+ }),
116
+ /* @__PURE__ */ jsx(
117
+ AvlEntity,
118
+ {
119
+ x: cx,
120
+ y: cy,
121
+ r: entityR,
122
+ fieldCount: fields,
123
+ persistence,
124
+ color
125
+ }
126
+ ),
127
+ pages.map((page, i) => {
128
+ const angle = pageAngleStart + i * pageAngleStep;
129
+ const px = cx + orbitalR * Math.cos(angle);
130
+ const py = cy + orbitalR * Math.sin(angle);
131
+ return /* @__PURE__ */ jsx(
132
+ AvlPage,
133
+ {
134
+ x: px,
135
+ y: py,
136
+ size: 10,
137
+ label: page.name,
138
+ color
139
+ },
140
+ page.name
141
+ );
142
+ })
143
+ ] });
144
+ };
145
+ AvlOrbitalUnit.displayName = "AvlOrbitalUnit";
146
+
147
+ // src/lib/avl-layout.ts
148
+ function ringPositions(cx, cy, r, count, startAngle = -Math.PI / 2) {
149
+ if (count === 0) return [];
150
+ if (count === 1) {
151
+ return [{ x: cx, y: cy, angle: 0 }];
152
+ }
153
+ if (count === 2) {
154
+ return [
155
+ { x: cx - r * 0.7, y: cy, angle: Math.PI },
156
+ { x: cx + r * 0.7, y: cy, angle: 0 }
157
+ ];
158
+ }
159
+ return Array.from({ length: count }, (_, i) => {
160
+ const angle = startAngle + Math.PI * 2 * i / count;
161
+ return {
162
+ x: cx + r * Math.cos(angle),
163
+ y: cy + r * Math.sin(angle),
164
+ angle
165
+ };
166
+ });
167
+ }
168
+ function arcPath(cx, cy, r, startAngle, endAngle) {
169
+ const x1 = cx + r * Math.cos(startAngle);
170
+ const y1 = cy + r * Math.sin(startAngle);
171
+ const x2 = cx + r * Math.cos(endAngle);
172
+ const y2 = cy + r * Math.sin(endAngle);
173
+ const largeArc = endAngle - startAngle > Math.PI ? 1 : 0;
174
+ return `M${x1},${y1} A${r},${r} 0 ${largeArc},1 ${x2},${y2}`;
175
+ }
176
+ function radialPositions(cx, cy, innerR, outerR, count, startAngle = -Math.PI / 2) {
177
+ return Array.from({ length: count }, (_, i) => {
178
+ const angle = startAngle + Math.PI * 2 * i / count;
179
+ return {
180
+ x1: cx + innerR * Math.cos(angle),
181
+ y1: cy + innerR * Math.sin(angle),
182
+ x2: cx + outerR * Math.cos(angle),
183
+ y2: cy + outerR * Math.sin(angle),
184
+ angle
185
+ };
186
+ });
187
+ }
188
+ function gridPositions(startX, startY, cols, cellWidth, cellHeight, count) {
189
+ return Array.from({ length: count }, (_, i) => {
190
+ const col = i % cols;
191
+ const row = Math.floor(i / cols);
192
+ return {
193
+ x: startX + col * cellWidth,
194
+ y: startY + row * cellHeight,
195
+ col,
196
+ row
197
+ };
198
+ });
199
+ }
200
+ function curveControlPoint(x1, y1, x2, y2, offset) {
201
+ const mx = (x1 + x2) / 2;
202
+ const my = (y1 + y2) / 2;
203
+ const dx = x2 - x1;
204
+ const dy = y2 - y1;
205
+ const len = Math.sqrt(dx * dx + dy * dy) || 1;
206
+ return {
207
+ cpx: mx + -dy / len * offset,
208
+ cpy: my + dx / len * offset
209
+ };
210
+ }
211
+ var avlCcId = 0;
212
+ var AvlClosedCircuit = ({
213
+ states,
214
+ transitions,
215
+ className,
216
+ color = "var(--color-primary)",
217
+ animated = false
218
+ }) => {
219
+ const ids = React4.useMemo(() => {
220
+ avlCcId += 1;
221
+ const base = `avl-cc-${avlCcId}`;
222
+ return { glow: `${base}-glow`, grad: `${base}-grad`, arrow: `${base}-arrow` };
223
+ }, []);
224
+ const cx = 300;
225
+ const cy = 200;
226
+ const r = 120;
227
+ const stateW = 80;
228
+ const stateH = 32;
229
+ const positions = ringPositions(cx, cy, r, states.length);
230
+ const stateIndex = new Map(states.map((s, i) => [s.name, i]));
231
+ return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 600 400", xmlns: "http://www.w3.org/2000/svg", className, children: [
232
+ /* @__PURE__ */ jsxs("defs", { children: [
233
+ /* @__PURE__ */ jsxs("filter", { id: ids.glow, x: "-50%", y: "-50%", width: "200%", height: "200%", children: [
234
+ /* @__PURE__ */ jsx("feGaussianBlur", { in: "SourceGraphic", stdDeviation: "4", result: "blur" }),
235
+ /* @__PURE__ */ jsxs("feMerge", { children: [
236
+ /* @__PURE__ */ jsx("feMergeNode", { in: "blur" }),
237
+ /* @__PURE__ */ jsx("feMergeNode", { in: "SourceGraphic" })
238
+ ] })
239
+ ] }),
240
+ /* @__PURE__ */ jsxs("linearGradient", { id: ids.grad, x1: "0%", y1: "0%", x2: "100%", y2: "100%", children: [
241
+ /* @__PURE__ */ jsx("stop", { offset: "0%", stopColor: color, stopOpacity: 0.15 }),
242
+ /* @__PURE__ */ jsx("stop", { offset: "50%", stopColor: color, stopOpacity: 0.4 }),
243
+ /* @__PURE__ */ jsx("stop", { offset: "100%", stopColor: color, stopOpacity: 0.15 })
244
+ ] }),
245
+ /* @__PURE__ */ jsx(
246
+ "marker",
247
+ {
248
+ id: ids.arrow,
249
+ markerWidth: "8",
250
+ markerHeight: "6",
251
+ refX: "7",
252
+ refY: "3",
253
+ orient: "auto",
254
+ markerUnits: "strokeWidth",
255
+ children: /* @__PURE__ */ jsx("path", { d: "M0,0 L8,3 L0,6 Z", fill: color, opacity: 0.6 })
256
+ }
257
+ )
258
+ ] }),
259
+ animated && /* @__PURE__ */ jsx("style", { children: `
260
+ @keyframes avl-cc-flow { from { stroke-dashoffset: 24; } to { stroke-dashoffset: 0; } }
261
+ ` }),
262
+ /* @__PURE__ */ jsx("circle", { cx, cy, r: r + 30, fill: "none", stroke: color, strokeWidth: 0.3, opacity: 0.06 }),
263
+ /* @__PURE__ */ jsx("circle", { cx, cy, r: 50, fill: "none", stroke: color, strokeWidth: 0.5, opacity: 0.08 }),
264
+ transitions.map((tr, i) => {
265
+ const fromIdx = stateIndex.get(tr.from);
266
+ const toIdx = stateIndex.get(tr.to);
267
+ if (fromIdx === void 0 || toIdx === void 0) return null;
268
+ const fp = positions[fromIdx];
269
+ const tp = positions[toIdx];
270
+ const dx = tp.x - fp.x;
271
+ const dy = tp.y - fp.y;
272
+ const dist = Math.sqrt(dx * dx + dy * dy) || 1;
273
+ const nx = dx / dist;
274
+ const ny = dy / dist;
275
+ const x1 = fp.x + nx * (stateW / 2 + 4);
276
+ const y1 = fp.y + ny * (stateH / 2 + 4);
277
+ const x2 = tp.x - nx * (stateW / 2 + 8);
278
+ const y2 = tp.y - ny * (stateH / 2 + 8);
279
+ const mx = (x1 + x2) / 2;
280
+ const my = (y1 + y2) / 2;
281
+ const curvature = dist * 0.25;
282
+ let perpX = -ny;
283
+ let perpY = nx;
284
+ const testX = mx + perpX * curvature;
285
+ const testY = my + perpY * curvature;
286
+ const distTest = Math.sqrt((testX - cx) ** 2 + (testY - cy) ** 2);
287
+ const distMid = Math.sqrt((mx - cx) ** 2 + (my - cy) ** 2);
288
+ if (distTest < distMid) {
289
+ perpX = -perpX;
290
+ perpY = -perpY;
291
+ }
292
+ const cpx = mx + perpX * curvature;
293
+ const cpy = my + perpY * curvature;
294
+ const d = `M${x1},${y1} Q${cpx},${cpy} ${x2},${y2}`;
295
+ return /* @__PURE__ */ jsxs("g", { children: [
296
+ /* @__PURE__ */ jsx(
297
+ "path",
298
+ {
299
+ d,
300
+ fill: "none",
301
+ stroke: `url(#${ids.grad})`,
302
+ strokeWidth: 1.5,
303
+ strokeDasharray: animated ? "8 6" : void 0,
304
+ markerEnd: `url(#${ids.arrow})`,
305
+ style: animated ? { animation: "avl-cc-flow 1.5s linear infinite" } : void 0
306
+ }
307
+ ),
308
+ tr.event && /* @__PURE__ */ jsx(
309
+ AvlEvent,
310
+ {
311
+ x: cpx,
312
+ y: cpy - 14,
313
+ size: 8,
314
+ label: tr.event,
315
+ color,
316
+ opacity: 0.8
317
+ }
318
+ ),
319
+ tr.guard && /* @__PURE__ */ jsx(
320
+ AvlGuard,
321
+ {
322
+ x: mx,
323
+ y: my - 8,
324
+ size: 10,
325
+ label: tr.guard,
326
+ color,
327
+ opacity: 0.6
328
+ }
329
+ ),
330
+ tr.effects?.map((eff, j) => /* @__PURE__ */ jsx(
331
+ AvlEffect,
332
+ {
333
+ x: mx + (j - ((tr.effects?.length ?? 1) - 1) / 2) * 14,
334
+ y: my + 14,
335
+ effectType: eff,
336
+ size: 5,
337
+ color,
338
+ opacity: 0.7
339
+ },
340
+ j
341
+ ))
342
+ ] }, `cc-tr-${i}`);
343
+ }),
344
+ states.map((state, i) => {
345
+ const pos = positions[i];
346
+ return /* @__PURE__ */ jsx(
347
+ AvlState,
348
+ {
349
+ x: pos.x - stateW / 2,
350
+ y: pos.y - stateH / 2,
351
+ width: stateW,
352
+ height: stateH,
353
+ name: state.name,
354
+ color
355
+ },
356
+ state.name
357
+ );
358
+ }),
359
+ /* @__PURE__ */ jsx("circle", { cx, cy, r: 3, fill: color, opacity: 0.4 })
360
+ ] });
361
+ };
362
+ AvlClosedCircuit.displayName = "AvlClosedCircuit";
363
+ var avlElId = 0;
364
+ var AvlEmitListen = ({
365
+ emitter,
366
+ listener,
367
+ eventName,
368
+ className,
369
+ color = "var(--color-primary)",
370
+ animated = false
371
+ }) => {
372
+ const ids = React4.useMemo(() => {
373
+ avlElId += 1;
374
+ const base = `avl-el-${avlElId}`;
375
+ return { arrow: `${base}-arrow`, grad: `${base}-grad` };
376
+ }, []);
377
+ const leftCx = 180;
378
+ const rightCx = 420;
379
+ const cy = 200;
380
+ const orbR = 80;
381
+ return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 600 400", xmlns: "http://www.w3.org/2000/svg", className, children: [
382
+ /* @__PURE__ */ jsxs("defs", { children: [
383
+ /* @__PURE__ */ jsx(
384
+ "marker",
385
+ {
386
+ id: ids.arrow,
387
+ markerWidth: "8",
388
+ markerHeight: "6",
389
+ refX: "7",
390
+ refY: "3",
391
+ orient: "auto",
392
+ markerUnits: "strokeWidth",
393
+ children: /* @__PURE__ */ jsx("path", { d: "M0,0 L8,3 L0,6 Z", fill: color, opacity: 0.6 })
394
+ }
395
+ ),
396
+ /* @__PURE__ */ jsxs("linearGradient", { id: ids.grad, x1: "0%", y1: "0%", x2: "100%", y2: "0%", children: [
397
+ /* @__PURE__ */ jsx("stop", { offset: "0%", stopColor: color, stopOpacity: 0.5 }),
398
+ /* @__PURE__ */ jsx("stop", { offset: "100%", stopColor: color, stopOpacity: 0.2 })
399
+ ] })
400
+ ] }),
401
+ animated && /* @__PURE__ */ jsx("style", { children: `
402
+ @keyframes avl-el-dash { from { stroke-dashoffset: 16; } to { stroke-dashoffset: 0; } }
403
+ ` }),
404
+ /* @__PURE__ */ jsx(AvlOrbital, { cx: leftCx, cy, r: orbR, label: emitter.name, color }),
405
+ /* @__PURE__ */ jsx(AvlEntity, { x: leftCx, y: cy, r: 18, fieldCount: emitter.fields ?? 3, color }),
406
+ /* @__PURE__ */ jsx(AvlOrbital, { cx: rightCx, cy, r: orbR, label: listener.name, color }),
407
+ /* @__PURE__ */ jsx(AvlEntity, { x: rightCx, y: cy, r: 18, fieldCount: listener.fields ?? 3, color }),
408
+ /* @__PURE__ */ jsx(
409
+ "path",
410
+ {
411
+ d: `M${leftCx + orbR + 4},${cy} L${rightCx - orbR - 8},${cy}`,
412
+ fill: "none",
413
+ stroke: `url(#${ids.grad})`,
414
+ strokeWidth: 2,
415
+ strokeDasharray: "6 4",
416
+ markerEnd: `url(#${ids.arrow})`,
417
+ style: animated ? { animation: "avl-el-dash 1s linear infinite" } : void 0
418
+ }
419
+ ),
420
+ eventName && /* @__PURE__ */ jsxs(
421
+ "text",
422
+ {
423
+ x: 300,
424
+ y: cy - 22,
425
+ textAnchor: "middle",
426
+ fill: color,
427
+ fontSize: 11,
428
+ fontFamily: "inherit",
429
+ fontWeight: "bold",
430
+ opacity: 0.8,
431
+ children: [
432
+ "~",
433
+ eventName
434
+ ]
435
+ }
436
+ ),
437
+ /* @__PURE__ */ jsx(
438
+ AvlEffect,
439
+ {
440
+ x: 300,
441
+ y: cy - 46,
442
+ effectType: "emit",
443
+ size: 7,
444
+ color,
445
+ opacity: 0.6
446
+ }
447
+ ),
448
+ /* @__PURE__ */ jsx(
449
+ "text",
450
+ {
451
+ x: 300,
452
+ y: cy + 18,
453
+ textAnchor: "middle",
454
+ fill: color,
455
+ fontSize: 12,
456
+ fontFamily: "inherit",
457
+ opacity: 0.3,
458
+ letterSpacing: 4,
459
+ children: "~ ~ ~"
460
+ }
461
+ )
462
+ ] });
463
+ };
464
+ AvlEmitListen.displayName = "AvlEmitListen";
465
+ var SLOT_PRESETS = {
466
+ header: { x: 10, y: 5, width: 340, height: 35 },
467
+ main: { x: 120, y: 50, width: 230, height: 195 },
468
+ sidebar: { x: 10, y: 50, width: 100, height: 195 },
469
+ modal: { x: 80, y: 60, width: 200, height: 140 },
470
+ drawer: { x: 220, y: 50, width: 130, height: 195 },
471
+ toast: { x: 220, y: 210, width: 130, height: 35 },
472
+ footer: { x: 10, y: 220, width: 340, height: 30 },
473
+ center: { x: 60, y: 50, width: 240, height: 195 },
474
+ "hud-top": { x: 10, y: 5, width: 340, height: 30 },
475
+ "hud-bottom": { x: 10, y: 220, width: 340, height: 30 }
476
+ };
477
+ function resolveSlot(slot, fallbackIdx) {
478
+ if (slot.x !== void 0 && slot.y !== void 0 && slot.width !== void 0 && slot.height !== void 0) {
479
+ return slot;
480
+ }
481
+ const preset = SLOT_PRESETS[slot.name];
482
+ if (preset) {
483
+ return {
484
+ name: slot.name,
485
+ x: slot.x ?? preset.x,
486
+ y: slot.y ?? preset.y,
487
+ width: slot.width ?? preset.width,
488
+ height: slot.height ?? preset.height
489
+ };
490
+ }
491
+ const col = fallbackIdx % 2;
492
+ const row = Math.floor(fallbackIdx / 2);
493
+ return {
494
+ name: slot.name,
495
+ x: 10 + col * 175,
496
+ y: 50 + row * 100,
497
+ width: 165,
498
+ height: 90
499
+ };
500
+ }
501
+ var AvlSlotMap = ({
502
+ slots,
503
+ pageWidth = 360,
504
+ pageHeight = 280,
505
+ className,
506
+ color = "var(--color-primary)",
507
+ animated = false
508
+ }) => {
509
+ const { t } = useTranslate();
510
+ const ox = (600 - pageWidth) / 2;
511
+ const oy = (400 - pageHeight) / 2;
512
+ let unknownIdx = 0;
513
+ const resolvedSlots = slots.map((slot) => {
514
+ const isUnknown = !SLOT_PRESETS[slot.name] && (slot.x === void 0 || slot.y === void 0);
515
+ const resolved = resolveSlot(slot, isUnknown ? unknownIdx : 0);
516
+ if (isUnknown) unknownIdx++;
517
+ return resolved;
518
+ });
519
+ return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 600 400", xmlns: "http://www.w3.org/2000/svg", className, children: [
520
+ animated && /* @__PURE__ */ jsx("style", { children: `
521
+ @keyframes avl-slot-pulse { 0%, 100% { opacity: 0.15; } 50% { opacity: 0.25; } }
522
+ ` }),
523
+ /* @__PURE__ */ jsx(
524
+ "rect",
525
+ {
526
+ x: ox,
527
+ y: oy,
528
+ width: pageWidth,
529
+ height: pageHeight,
530
+ rx: 4,
531
+ ry: 4,
532
+ fill: "none",
533
+ stroke: color,
534
+ strokeWidth: 2
535
+ }
536
+ ),
537
+ /* @__PURE__ */ jsx(
538
+ "rect",
539
+ {
540
+ x: ox,
541
+ y: oy,
542
+ width: pageWidth,
543
+ height: 24,
544
+ rx: 4,
545
+ ry: 4,
546
+ fill: color,
547
+ opacity: 0.1
548
+ }
549
+ ),
550
+ /* @__PURE__ */ jsx(
551
+ "text",
552
+ {
553
+ x: ox + pageWidth / 2,
554
+ y: oy + 16,
555
+ textAnchor: "middle",
556
+ fill: color,
557
+ fontSize: 10,
558
+ fontFamily: "inherit",
559
+ fontWeight: "bold",
560
+ children: t("avl.pageLayout")
561
+ }
562
+ ),
563
+ resolvedSlots.map((slot) => {
564
+ const isOverlay = ["modal", "drawer", "toast"].includes(slot.name);
565
+ return /* @__PURE__ */ jsxs("g", { children: [
566
+ isOverlay && /* @__PURE__ */ jsx(
567
+ "rect",
568
+ {
569
+ x: ox + slot.x + 3,
570
+ y: oy + 24 + slot.y + 3,
571
+ width: slot.width,
572
+ height: slot.height,
573
+ rx: 3,
574
+ ry: 3,
575
+ fill: "var(--color-foreground)",
576
+ opacity: 0.06
577
+ }
578
+ ),
579
+ /* @__PURE__ */ jsx(
580
+ "rect",
581
+ {
582
+ x: ox + slot.x,
583
+ y: oy + 24 + slot.y,
584
+ width: slot.width,
585
+ height: slot.height,
586
+ rx: 3,
587
+ ry: 3,
588
+ fill: isOverlay ? "var(--color-surface)" : color,
589
+ opacity: isOverlay ? 0.9 : 0.08,
590
+ stroke: color,
591
+ strokeWidth: isOverlay ? 1.5 : 1,
592
+ strokeDasharray: isOverlay ? "6 3" : "4 2",
593
+ style: animated ? { animation: "avl-slot-pulse 2s ease-in-out infinite" } : void 0
594
+ }
595
+ ),
596
+ /* @__PURE__ */ jsxs(
597
+ "text",
598
+ {
599
+ x: ox + slot.x + slot.width / 2,
600
+ y: oy + 24 + slot.y + slot.height / 2,
601
+ textAnchor: "middle",
602
+ dominantBaseline: "central",
603
+ fill: color,
604
+ fontSize: 9,
605
+ fontFamily: "inherit",
606
+ opacity: 0.6,
607
+ children: [
608
+ slot.name,
609
+ isOverlay ? ` ${t("avl.overlaySuffix")}` : ""
610
+ ]
611
+ }
612
+ )
613
+ ] }, slot.name);
614
+ })
615
+ ] });
616
+ };
617
+ AvlSlotMap.displayName = "AvlSlotMap";
618
+ var avlEtId = 0;
619
+ function layoutTree(node, x, y, hSpacing, vSpacing) {
620
+ const children = node.children ?? [];
621
+ if (children.length === 0) {
622
+ return { label: node.label, type: node.type, x, y, children: [] };
623
+ }
624
+ const totalWidth = (children.length - 1) * hSpacing;
625
+ const startX = x - totalWidth / 2;
626
+ const layoutChildren = children.map(
627
+ (child, i) => layoutTree(child, startX + i * hSpacing, y + vSpacing, hSpacing * 0.85, vSpacing)
628
+ );
629
+ return { label: node.label, type: node.type, x, y, children: layoutChildren };
630
+ }
631
+ function nodeColor(type, baseColor) {
632
+ switch (type) {
633
+ case "operator":
634
+ return baseColor;
635
+ case "literal":
636
+ return baseColor;
637
+ case "binding":
638
+ return baseColor;
639
+ }
640
+ }
641
+ function renderNode(node, color, glowId) {
642
+ const labelLen = node.label.length;
643
+ const baseR = node.type === "operator" ? 20 : 16;
644
+ const r = Math.max(baseR, labelLen * 3.5 + 6);
645
+ const nc = nodeColor(node.type, color);
646
+ return /* @__PURE__ */ jsxs(React4.Fragment, { children: [
647
+ node.children.map((child, i) => {
648
+ const childR = Math.max(
649
+ child.type === "operator" ? 20 : 16,
650
+ child.label.length * 3.5 + 6
651
+ );
652
+ return /* @__PURE__ */ jsx(
653
+ "line",
654
+ {
655
+ x1: node.x,
656
+ y1: node.y + (node.type === "operator" ? r * 0.7 : r),
657
+ x2: child.x,
658
+ y2: child.y - (child.type === "operator" ? childR * 0.7 : childR),
659
+ stroke: color,
660
+ strokeWidth: 1,
661
+ opacity: 0.3
662
+ },
663
+ `line-${i}`
664
+ );
665
+ }),
666
+ node.type === "operator" ? /* @__PURE__ */ jsx(
667
+ "rect",
668
+ {
669
+ x: node.x - r,
670
+ y: node.y - r * 0.6,
671
+ width: r * 2,
672
+ height: r * 1.2,
673
+ rx: 4,
674
+ ry: 4,
675
+ fill: color,
676
+ fillOpacity: 0.15,
677
+ stroke: nc,
678
+ strokeWidth: 1.5
679
+ }
680
+ ) : node.type === "binding" ? /* @__PURE__ */ jsx("circle", { cx: node.x, cy: node.y, r, fill: "none", stroke: nc, strokeWidth: 1.5, strokeDasharray: "3 2" }) : /* @__PURE__ */ jsx("circle", { cx: node.x, cy: node.y, r, fill: "none", stroke: nc, strokeWidth: 1, opacity: 0.5 }),
681
+ /* @__PURE__ */ jsx(
682
+ "text",
683
+ {
684
+ x: node.x,
685
+ y: node.y + 1,
686
+ textAnchor: "middle",
687
+ dominantBaseline: "central",
688
+ fill: nc,
689
+ fontSize: node.type === "operator" ? 11 : 10,
690
+ fontFamily: "inherit",
691
+ fontWeight: node.type === "operator" ? "bold" : "normal",
692
+ children: node.type === "binding" && !node.label.startsWith("@") ? `@${node.label}` : node.label
693
+ }
694
+ ),
695
+ node.children.map((child) => renderNode(child, color))
696
+ ] }, `${node.label}-${node.x}-${node.y}`);
697
+ }
698
+ var AvlExprTree = ({
699
+ expression,
700
+ className,
701
+ color = "var(--color-primary)"
702
+ }) => {
703
+ const ids = React4.useMemo(() => {
704
+ avlEtId += 1;
705
+ return { glow: `avl-et-${avlEtId}-glow` };
706
+ }, []);
707
+ const layout = layoutTree(expression, 400, 60, 280, 100);
708
+ return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 800 400", xmlns: "http://www.w3.org/2000/svg", className, children: [
709
+ /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("filter", { id: ids.glow, x: "-50%", y: "-50%", width: "200%", height: "200%", children: [
710
+ /* @__PURE__ */ jsx("feGaussianBlur", { in: "SourceGraphic", stdDeviation: "2", result: "blur" }),
711
+ /* @__PURE__ */ jsxs("feMerge", { children: [
712
+ /* @__PURE__ */ jsx("feMergeNode", { in: "blur" }),
713
+ /* @__PURE__ */ jsx("feMergeNode", { in: "SourceGraphic" })
714
+ ] })
715
+ ] }) }),
716
+ renderNode(layout, color, ids.glow)
717
+ ] });
718
+ };
719
+ AvlExprTree.displayName = "AvlExprTree";
720
+ var MAX_VISIBLE_EFFECTS = 6;
721
+ var AvlTransitionLane = ({
722
+ event,
723
+ guard,
724
+ effects,
725
+ width,
726
+ x = 0,
727
+ y = 0,
728
+ isBackward = false,
729
+ isSelfLoop = false,
730
+ color = "var(--color-primary)",
731
+ onTransitionClick
732
+ }) => {
733
+ const rowHeight = 22;
734
+ const padding = 8;
735
+ const eventRow = padding;
736
+ const guardRow = guard ? eventRow + rowHeight : eventRow;
737
+ const effectsRow = guard ? guardRow + rowHeight : eventRow + rowHeight;
738
+ const totalHeight = effectsRow + (effects.length > 0 ? rowHeight + padding : padding);
739
+ const connStyle = isSelfLoop ? CONNECTION_COLORS.selfLoop : isBackward ? CONNECTION_COLORS.backward : CONNECTION_COLORS.forward;
740
+ const visibleEffects = effects.slice(0, MAX_VISIBLE_EFFECTS);
741
+ const overflow = effects.length - MAX_VISIBLE_EFFECTS;
742
+ const effectSpacing = 28;
743
+ return /* @__PURE__ */ jsxs(
744
+ "g",
745
+ {
746
+ transform: `translate(${x},${y})`,
747
+ style: { cursor: onTransitionClick ? "pointer" : "default" },
748
+ onClick: onTransitionClick,
749
+ role: onTransitionClick ? "button" : void 0,
750
+ children: [
751
+ /* @__PURE__ */ jsx(
752
+ "rect",
753
+ {
754
+ x: 0,
755
+ y: 0,
756
+ width,
757
+ height: totalHeight,
758
+ rx: 6,
759
+ fill: connStyle.color,
760
+ fillOpacity: 0.03,
761
+ stroke: connStyle.color,
762
+ strokeWidth: 0.5,
763
+ strokeOpacity: 0.15,
764
+ strokeDasharray: connStyle.dash === "none" ? void 0 : connStyle.dash
765
+ }
766
+ ),
767
+ /* @__PURE__ */ jsx(
768
+ "text",
769
+ {
770
+ x: padding + 14,
771
+ y: eventRow + rowHeight * 0.65,
772
+ fontSize: 14,
773
+ fontWeight: 600,
774
+ fill: color,
775
+ fontFamily: "inherit",
776
+ children: event
777
+ }
778
+ ),
779
+ /* @__PURE__ */ jsx(
780
+ "text",
781
+ {
782
+ x: padding + 4,
783
+ y: eventRow + rowHeight * 0.65,
784
+ fontSize: 10,
785
+ fill: color,
786
+ opacity: 0.5,
787
+ children: "\u26A1"
788
+ }
789
+ ),
790
+ guard && /* @__PURE__ */ jsxs("g", { children: [
791
+ /* @__PURE__ */ jsx(
792
+ "polygon",
793
+ {
794
+ points: `${padding + 6},${guardRow + rowHeight * 0.35} ${padding + 10},${guardRow + rowHeight * 0.15} ${padding + 14},${guardRow + rowHeight * 0.35} ${padding + 10},${guardRow + rowHeight * 0.55}`,
795
+ fill: "none",
796
+ stroke: color,
797
+ strokeWidth: 1,
798
+ opacity: 0.5
799
+ }
800
+ ),
801
+ /* @__PURE__ */ jsx(
802
+ "text",
803
+ {
804
+ x: padding + 20,
805
+ y: guardRow + rowHeight * 0.6,
806
+ fontSize: 12,
807
+ fontWeight: 400,
808
+ fill: color,
809
+ opacity: 0.6,
810
+ fontFamily: "inherit",
811
+ children: guard
812
+ }
813
+ )
814
+ ] }),
815
+ visibleEffects.length > 0 && /* @__PURE__ */ jsxs("g", { children: [
816
+ visibleEffects.map((eff, i) => /* @__PURE__ */ jsx(
817
+ AvlEffect,
818
+ {
819
+ x: padding + 12 + i * effectSpacing,
820
+ y: effectsRow + rowHeight * 0.5,
821
+ effectType: eff.type,
822
+ size: 10,
823
+ showBackground: true
824
+ },
825
+ i
826
+ )),
827
+ overflow > 0 && /* @__PURE__ */ jsxs(
828
+ "text",
829
+ {
830
+ x: padding + 12 + visibleEffects.length * effectSpacing,
831
+ y: effectsRow + rowHeight * 0.6,
832
+ fontSize: 10,
833
+ fill: color,
834
+ opacity: 0.5,
835
+ fontFamily: "inherit",
836
+ children: [
837
+ "+",
838
+ overflow
839
+ ]
840
+ }
841
+ )
842
+ ] })
843
+ ]
844
+ }
845
+ );
846
+ };
847
+ AvlTransitionLane.displayName = "AvlTransitionLane";
848
+ var GUTTER_WIDTH = 120;
849
+ var EVENT_SPACING = 24;
850
+ var HEADER_Y = 16;
851
+ var EVENT_START_Y = 36;
852
+ var AvlSwimLane = ({
853
+ listenedEvents,
854
+ emittedEvents,
855
+ centerWidth,
856
+ height,
857
+ color = "var(--color-primary)",
858
+ children
859
+ }) => {
860
+ const { t, locale } = useTranslate();
861
+ const rightX = GUTTER_WIDTH + centerWidth;
862
+ const totalWidth = rightX + GUTTER_WIDTH;
863
+ const emitColor = CONNECTION_COLORS.emitListen.color;
864
+ return /* @__PURE__ */ jsxs("g", { children: [
865
+ listenedEvents.length > 0 && /* @__PURE__ */ jsxs("g", { children: [
866
+ /* @__PURE__ */ jsx(
867
+ "text",
868
+ {
869
+ x: 8,
870
+ y: HEADER_Y,
871
+ fontSize: 10,
872
+ fontWeight: 600,
873
+ fill: color,
874
+ opacity: 0.4,
875
+ fontFamily: "inherit",
876
+ children: t("avlSwimLane.listens").toLocaleUpperCase(locale)
877
+ }
878
+ ),
879
+ listenedEvents.map((evt, i) => {
880
+ const ey = EVENT_START_Y + i * EVENT_SPACING;
881
+ return /* @__PURE__ */ jsxs("g", { children: [
882
+ /* @__PURE__ */ jsx(
883
+ "polygon",
884
+ {
885
+ points: `${4},${ey} ${12},${ey - 5} ${12},${ey + 5}`,
886
+ fill: emitColor,
887
+ opacity: 0.6
888
+ }
889
+ ),
890
+ /* @__PURE__ */ jsx(
891
+ "text",
892
+ {
893
+ x: 16,
894
+ y: ey + 4,
895
+ fontSize: 11,
896
+ fontWeight: 500,
897
+ fill: color,
898
+ opacity: 0.6,
899
+ fontFamily: "inherit",
900
+ children: evt
901
+ }
902
+ ),
903
+ /* @__PURE__ */ jsx(
904
+ "line",
905
+ {
906
+ x1: GUTTER_WIDTH - 4,
907
+ y1: ey,
908
+ x2: GUTTER_WIDTH,
909
+ y2: ey,
910
+ stroke: emitColor,
911
+ strokeWidth: 1,
912
+ strokeDasharray: "3 2",
913
+ opacity: 0.4
914
+ }
915
+ )
916
+ ] }, evt + i);
917
+ })
918
+ ] }),
919
+ /* @__PURE__ */ jsx(
920
+ "line",
921
+ {
922
+ x1: GUTTER_WIDTH,
923
+ y1: 0,
924
+ x2: GUTTER_WIDTH,
925
+ y2: height,
926
+ stroke: color,
927
+ strokeWidth: 0.5,
928
+ strokeDasharray: "4 3",
929
+ opacity: 0.12
930
+ }
931
+ ),
932
+ /* @__PURE__ */ jsx("g", { transform: `translate(${GUTTER_WIDTH}, 0)`, children }),
933
+ /* @__PURE__ */ jsx(
934
+ "line",
935
+ {
936
+ x1: rightX,
937
+ y1: 0,
938
+ x2: rightX,
939
+ y2: height,
940
+ stroke: color,
941
+ strokeWidth: 0.5,
942
+ strokeDasharray: "4 3",
943
+ opacity: 0.12
944
+ }
945
+ ),
946
+ emittedEvents.length > 0 && /* @__PURE__ */ jsxs("g", { children: [
947
+ /* @__PURE__ */ jsx(
948
+ "text",
949
+ {
950
+ x: rightX + 8,
951
+ y: HEADER_Y,
952
+ fontSize: 10,
953
+ fontWeight: 600,
954
+ fill: color,
955
+ opacity: 0.4,
956
+ fontFamily: "inherit",
957
+ children: t("avlSwimLane.emits").toLocaleUpperCase(locale)
958
+ }
959
+ ),
960
+ emittedEvents.map((evt, i) => {
961
+ const ey = EVENT_START_Y + i * EVENT_SPACING;
962
+ return /* @__PURE__ */ jsxs("g", { children: [
963
+ /* @__PURE__ */ jsx(
964
+ "text",
965
+ {
966
+ x: totalWidth - 18,
967
+ y: ey + 4,
968
+ fontSize: 11,
969
+ fontWeight: 500,
970
+ fill: color,
971
+ opacity: 0.6,
972
+ fontFamily: "inherit",
973
+ textAnchor: "end",
974
+ children: evt
975
+ }
976
+ ),
977
+ /* @__PURE__ */ jsx(
978
+ "polygon",
979
+ {
980
+ points: `${totalWidth - 4},${ey} ${totalWidth - 12},${ey - 5} ${totalWidth - 12},${ey + 5}`,
981
+ fill: emitColor,
982
+ opacity: 0.6
983
+ }
984
+ ),
985
+ /* @__PURE__ */ jsx(
986
+ "line",
987
+ {
988
+ x1: rightX,
989
+ y1: ey,
990
+ x2: rightX + 4,
991
+ y2: ey,
992
+ stroke: emitColor,
993
+ strokeWidth: 1,
994
+ strokeDasharray: "3 2",
995
+ opacity: 0.4
996
+ }
997
+ )
998
+ ] }, evt + i);
999
+ })
1000
+ ] })
1001
+ ] });
1002
+ };
1003
+ AvlSwimLane.displayName = "AvlSwimLane";
1004
+ var DOMAIN_ORDER = [
1005
+ "commerce",
1006
+ "healthcare",
1007
+ "education",
1008
+ "finance",
1009
+ "scheduling",
1010
+ "workflow",
1011
+ "social",
1012
+ "media",
1013
+ "gaming",
1014
+ "iot",
1015
+ "crm",
1016
+ "analytics",
1017
+ "communication",
1018
+ "content",
1019
+ "location",
1020
+ "hr",
1021
+ "legal",
1022
+ "real-estate"
1023
+ ];
1024
+ var DOMAIN_COLORS = Object.fromEntries(DOMAIN_ORDER.map((domain, i) => [domain, avlSeries(i)]));
1025
+ var SIZE_MAP = {
1026
+ xs: 32,
1027
+ sm: 48,
1028
+ md: 120,
1029
+ lg: 200,
1030
+ xl: 300
1031
+ };
1032
+ function PersistenceCore({ cx, cy, r, persistence, color }) {
1033
+ switch (persistence) {
1034
+ case "runtime":
1035
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1036
+ /* @__PURE__ */ jsx("circle", { cx, cy, r, fill: "none", stroke: color, strokeWidth: 1.5, strokeDasharray: "4 2", opacity: 0.9 }),
1037
+ /* @__PURE__ */ jsx("circle", { cx, cy, r: r * 0.4, fill: color, opacity: 0.3, children: /* @__PURE__ */ jsx("animate", { attributeName: "opacity", values: "0.3;0.6;0.3", dur: "2s", repeatCount: "indefinite" }) })
1038
+ ] });
1039
+ case "persistent":
1040
+ default:
1041
+ return /* @__PURE__ */ jsx("circle", { cx, cy, r, fill: color, fillOpacity: 0.15, stroke: color, strokeWidth: 2 });
1042
+ }
1043
+ }
1044
+ function FieldSpokes({ cx, cy, innerR, outerR, count, color }) {
1045
+ if (count === 0) return null;
1046
+ const spokes = Array.from({ length: count }, (_, i) => {
1047
+ const angle = Math.PI * 2 * i / count - Math.PI / 2;
1048
+ return /* @__PURE__ */ jsx(
1049
+ "line",
1050
+ {
1051
+ x1: cx + innerR * Math.cos(angle),
1052
+ y1: cy + innerR * Math.sin(angle),
1053
+ x2: cx + outerR * Math.cos(angle),
1054
+ y2: cy + outerR * Math.sin(angle),
1055
+ stroke: color,
1056
+ strokeWidth: 1,
1057
+ opacity: 0.5
1058
+ },
1059
+ i
1060
+ );
1061
+ });
1062
+ return /* @__PURE__ */ jsx(Fragment, { children: spokes });
1063
+ }
1064
+ function StateRings({ cx, cy, baseR, count, color, animated }) {
1065
+ if (count === 0) return null;
1066
+ const ringCount = Math.min(count, 5);
1067
+ const ringSpacing = baseR * 0.25;
1068
+ const rings = Array.from({ length: ringCount }, (_, i) => {
1069
+ const r = baseR + (i + 1) * ringSpacing;
1070
+ const opacity = 0.6 - i * 0.1;
1071
+ const width = i === 0 ? 1.5 : 1;
1072
+ return /* @__PURE__ */ jsx(
1073
+ "circle",
1074
+ {
1075
+ cx,
1076
+ cy,
1077
+ r,
1078
+ fill: "none",
1079
+ stroke: color,
1080
+ strokeWidth: width,
1081
+ opacity,
1082
+ children: animated && /* @__PURE__ */ jsx(
1083
+ "animateTransform",
1084
+ {
1085
+ attributeName: "transform",
1086
+ type: "rotate",
1087
+ from: `0 ${cx} ${cy}`,
1088
+ to: `${i % 2 === 0 ? 360 : -360} ${cx} ${cy}`,
1089
+ dur: `${8 + i * 4}s`,
1090
+ repeatCount: "indefinite"
1091
+ }
1092
+ )
1093
+ },
1094
+ i
1095
+ );
1096
+ });
1097
+ return /* @__PURE__ */ jsx(Fragment, { children: rings });
1098
+ }
1099
+ function EffectMarkers({ cx, cy, r, effectTypes, baseColor }) {
1100
+ if (effectTypes.length === 0) return null;
1101
+ const seen = /* @__PURE__ */ new Set();
1102
+ const categories = [];
1103
+ for (const t of effectTypes) {
1104
+ const cat = effectCategoryOf(t);
1105
+ if (cat !== null && !seen.has(cat)) {
1106
+ seen.add(cat);
1107
+ categories.push({ type: t, category: cat });
1108
+ }
1109
+ }
1110
+ return /* @__PURE__ */ jsx(Fragment, { children: categories.map(({ type, category }, i) => {
1111
+ const angle = Math.PI * 2 * i / categories.length - Math.PI / 2;
1112
+ const mx = cx + r * Math.cos(angle);
1113
+ const my = cy + r * Math.sin(angle);
1114
+ const markerColor = EFFECT_CATEGORY_COLORS[category].color;
1115
+ const s = r * 0.12;
1116
+ return /* @__PURE__ */ jsxs("g", { children: [
1117
+ /* @__PURE__ */ jsx("circle", { cx: mx, cy: my, r: s + 1, fill: markerColor, fillOpacity: 0.2 }),
1118
+ /* @__PURE__ */ jsx("circle", { cx: mx, cy: my, r: s * 0.6, fill: markerColor })
1119
+ ] }, type);
1120
+ }) });
1121
+ }
1122
+ function AtomGlyph({ cx, cy, radius, fieldCount, stateCount, persistence, effectTypes, color, animated, showLabels, name }) {
1123
+ const coreR = radius * 0.25;
1124
+ const spokeInner = coreR + 2;
1125
+ const spokeOuter = coreR + radius * 0.15;
1126
+ const ringBase = coreR + radius * 0.18;
1127
+ const markerR = ringBase + Math.min(stateCount, 5) * (radius * 0.25) * 0.25 + radius * 0.08;
1128
+ return /* @__PURE__ */ jsxs("g", { children: [
1129
+ /* @__PURE__ */ jsx(PersistenceCore, { cx, cy, r: coreR, persistence, color }),
1130
+ /* @__PURE__ */ jsx(FieldSpokes, { cx, cy, innerR: spokeInner, outerR: spokeOuter, count: fieldCount, color }),
1131
+ /* @__PURE__ */ jsx(StateRings, { cx, cy, baseR: ringBase, count: stateCount, color, animated }),
1132
+ /* @__PURE__ */ jsx(EffectMarkers, { cx, cy, r: markerR, effectTypes, baseColor: color }),
1133
+ showLabels && /* @__PURE__ */ jsx(
1134
+ "text",
1135
+ {
1136
+ x: cx,
1137
+ y: cy + radius + 12,
1138
+ textAnchor: "middle",
1139
+ fill: color,
1140
+ fontSize: radius * 0.14,
1141
+ fontFamily: "Inter, sans-serif",
1142
+ fontWeight: 500,
1143
+ opacity: 0.8,
1144
+ children: name
1145
+ }
1146
+ )
1147
+ ] });
1148
+ }
1149
+ function MoleculeGlyph({ cx, cy, radius, children, color, animated, showLabels, name }) {
1150
+ const count = children.length || 1;
1151
+ const childR = radius / (count <= 3 ? 2.8 : 3.5);
1152
+ const orbitR = radius * 0.5;
1153
+ return /* @__PURE__ */ jsxs("g", { children: [
1154
+ /* @__PURE__ */ jsx("circle", { cx, cy, r: orbitR, fill: "none", stroke: color, strokeWidth: 0.8, strokeDasharray: "3 2", opacity: 0.3 }),
1155
+ children.map((child, i) => {
1156
+ const angle = Math.PI * 2 * i / count - Math.PI / 2;
1157
+ const childCx = cx + orbitR * Math.cos(angle);
1158
+ const childCy = cy + orbitR * Math.sin(angle);
1159
+ return /* @__PURE__ */ jsxs("g", { children: [
1160
+ /* @__PURE__ */ jsx("line", { x1: cx, y1: cy, x2: childCx, y2: childCy, stroke: color, strokeWidth: 0.5, opacity: 0.2 }),
1161
+ /* @__PURE__ */ jsx(
1162
+ AtomGlyph,
1163
+ {
1164
+ cx: childCx,
1165
+ cy: childCy,
1166
+ radius: childR,
1167
+ fieldCount: child.fieldCount ?? 3,
1168
+ stateCount: child.stateCount ?? 2,
1169
+ persistence: child.persistence ?? "persistent",
1170
+ effectTypes: child.effectTypes ?? ["render-ui"],
1171
+ color,
1172
+ animated,
1173
+ showLabels: false,
1174
+ name: child.name
1175
+ }
1176
+ )
1177
+ ] }, child.name);
1178
+ }),
1179
+ /* @__PURE__ */ jsx("circle", { cx, cy, r: radius * 0.04, fill: color, opacity: 0.5 }),
1180
+ showLabels && /* @__PURE__ */ jsx(
1181
+ "text",
1182
+ {
1183
+ x: cx,
1184
+ y: cy + radius + 12,
1185
+ textAnchor: "middle",
1186
+ fill: color,
1187
+ fontSize: radius * 0.12,
1188
+ fontFamily: "Inter, sans-serif",
1189
+ fontWeight: 500,
1190
+ opacity: 0.8,
1191
+ children: name
1192
+ }
1193
+ )
1194
+ ] });
1195
+ }
1196
+ function OrganismGlyph({ cx, cy, radius, children, connections, color, animated, showLabels, name }) {
1197
+ const count = children.length || 1;
1198
+ const childR = radius / (count <= 3 ? 3 : 4);
1199
+ const spreadX = radius * 0.6;
1200
+ const positions = children.map((_, i) => {
1201
+ const offset = (i - (count - 1) / 2) * (spreadX * 2 / Math.max(count - 1, 1));
1202
+ return { x: cx + offset, y: cy };
1203
+ });
1204
+ const nameToIdx = {};
1205
+ children.forEach((c, i) => {
1206
+ nameToIdx[c.name] = i;
1207
+ });
1208
+ return /* @__PURE__ */ jsxs("g", { children: [
1209
+ /* @__PURE__ */ jsx(
1210
+ "rect",
1211
+ {
1212
+ x: cx - radius,
1213
+ y: cy - radius * 0.7,
1214
+ width: radius * 2,
1215
+ height: radius * 1.4,
1216
+ rx: radius * 0.08,
1217
+ fill: color,
1218
+ fillOpacity: 0.03,
1219
+ stroke: color,
1220
+ strokeWidth: 0.8,
1221
+ strokeDasharray: "6 3",
1222
+ opacity: 0.4
1223
+ }
1224
+ ),
1225
+ connections.map((conn, i) => {
1226
+ const fromIdx = nameToIdx[conn.from];
1227
+ const toIdx = nameToIdx[conn.to];
1228
+ if (fromIdx == null || toIdx == null) return null;
1229
+ const from = positions[fromIdx];
1230
+ const to = positions[toIdx];
1231
+ return /* @__PURE__ */ jsxs("g", { children: [
1232
+ /* @__PURE__ */ jsx(
1233
+ "line",
1234
+ {
1235
+ x1: from.x + childR,
1236
+ y1: from.y,
1237
+ x2: to.x - childR,
1238
+ y2: to.y,
1239
+ stroke: color,
1240
+ strokeWidth: 1,
1241
+ opacity: 0.4,
1242
+ markerEnd: "none"
1243
+ }
1244
+ ),
1245
+ /* @__PURE__ */ jsx(
1246
+ "polygon",
1247
+ {
1248
+ points: `${to.x - childR - 4},${to.y - 3} ${to.x - childR},${to.y} ${to.x - childR - 4},${to.y + 3}`,
1249
+ fill: color,
1250
+ opacity: 0.5
1251
+ }
1252
+ ),
1253
+ showLabels && /* @__PURE__ */ jsx(
1254
+ "text",
1255
+ {
1256
+ x: (from.x + to.x) / 2,
1257
+ y: from.y - childR - 4,
1258
+ textAnchor: "middle",
1259
+ fill: color,
1260
+ fontSize: radius * 0.06,
1261
+ fontFamily: "Inter, sans-serif",
1262
+ opacity: 0.5,
1263
+ children: conn.event
1264
+ }
1265
+ )
1266
+ ] }, i);
1267
+ }),
1268
+ children.map((child, i) => {
1269
+ const pos = positions[i];
1270
+ return /* @__PURE__ */ jsx("g", { children: /* @__PURE__ */ jsx(
1271
+ AtomGlyph,
1272
+ {
1273
+ cx: pos.x,
1274
+ cy: pos.y,
1275
+ radius: childR,
1276
+ fieldCount: child.fieldCount ?? 3,
1277
+ stateCount: child.stateCount ?? 2,
1278
+ persistence: child.persistence ?? "persistent",
1279
+ effectTypes: child.effectTypes ?? ["render-ui"],
1280
+ color,
1281
+ animated,
1282
+ showLabels,
1283
+ name: child.name
1284
+ }
1285
+ ) }, child.name);
1286
+ }),
1287
+ showLabels && /* @__PURE__ */ jsx(
1288
+ "text",
1289
+ {
1290
+ x: cx,
1291
+ y: cy + radius * 0.7 + 14,
1292
+ textAnchor: "middle",
1293
+ fill: color,
1294
+ fontSize: radius * 0.1,
1295
+ fontFamily: "Inter, sans-serif",
1296
+ fontWeight: 600,
1297
+ opacity: 0.8,
1298
+ children: name
1299
+ }
1300
+ )
1301
+ ] });
1302
+ }
1303
+ var AvlBehaviorGlyph = ({
1304
+ name,
1305
+ level = "atom",
1306
+ domain,
1307
+ color: colorOverride,
1308
+ fieldCount = 4,
1309
+ stateCount = 2,
1310
+ persistence = "persistent",
1311
+ effectTypes = [],
1312
+ children: childBehaviors,
1313
+ connections = [],
1314
+ size = "md",
1315
+ showLabels = false,
1316
+ animated = false,
1317
+ className,
1318
+ onClick
1319
+ }) => {
1320
+ const { t } = useTranslate();
1321
+ const resolvedColor = colorOverride ?? (domain ? DOMAIN_COLORS[domain] ?? "var(--color-primary)" : "var(--color-primary)");
1322
+ const dim = SIZE_MAP[size];
1323
+ const radius = dim * 0.4;
1324
+ const cx = dim / 2;
1325
+ const cy = dim / 2;
1326
+ const vb = level === "organism" ? `0 0 ${dim * 1.5} ${dim}` : `0 0 ${dim} ${dim}`;
1327
+ const svgW = level === "organism" ? dim * 1.5 : dim;
1328
+ const glyphId = useMemo(() => `avl-bg-${Math.random().toString(36).slice(2, 8)}`, []);
1329
+ return /* @__PURE__ */ jsxs(
1330
+ "svg",
1331
+ {
1332
+ viewBox: vb,
1333
+ width: svgW,
1334
+ height: dim,
1335
+ xmlns: "http://www.w3.org/2000/svg",
1336
+ className: cn("inline-block", onClick && "cursor-pointer", className),
1337
+ onClick,
1338
+ role: onClick ? "button" : void 0,
1339
+ "aria-label": t("avlBehaviorGlyph.ariaLabel", { name }),
1340
+ children: [
1341
+ /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("radialGradient", { id: `${glyphId}-bg`, cx: "50%", cy: "50%", r: "50%", children: [
1342
+ /* @__PURE__ */ jsx("stop", { offset: "0%", stopColor: resolvedColor, stopOpacity: 0.06 }),
1343
+ /* @__PURE__ */ jsx("stop", { offset: "100%", stopColor: resolvedColor, stopOpacity: 0 })
1344
+ ] }) }),
1345
+ /* @__PURE__ */ jsx("circle", { cx: level === "organism" ? dim * 0.75 : cx, cy, r: radius * 1.3, fill: `url(#${glyphId}-bg)` }),
1346
+ level === "atom" && /* @__PURE__ */ jsx(
1347
+ AtomGlyph,
1348
+ {
1349
+ cx,
1350
+ cy,
1351
+ radius,
1352
+ fieldCount,
1353
+ stateCount,
1354
+ persistence,
1355
+ effectTypes,
1356
+ color: resolvedColor,
1357
+ animated,
1358
+ showLabels,
1359
+ name
1360
+ }
1361
+ ),
1362
+ level === "molecule" && /* @__PURE__ */ jsx(
1363
+ MoleculeGlyph,
1364
+ {
1365
+ cx,
1366
+ cy,
1367
+ radius,
1368
+ children: childBehaviors ?? [],
1369
+ color: resolvedColor,
1370
+ animated,
1371
+ showLabels,
1372
+ name
1373
+ }
1374
+ ),
1375
+ level === "organism" && /* @__PURE__ */ jsx(
1376
+ OrganismGlyph,
1377
+ {
1378
+ cx: dim * 0.75,
1379
+ cy,
1380
+ radius: radius * 1.5,
1381
+ children: childBehaviors ?? [],
1382
+ connections,
1383
+ color: resolvedColor,
1384
+ animated,
1385
+ showLabels,
1386
+ name
1387
+ }
1388
+ )
1389
+ ]
1390
+ }
1391
+ );
1392
+ };
1393
+ AvlBehaviorGlyph.displayName = "AvlBehaviorGlyph";
1394
+ var ZOOM_BAND_THRESHOLDS = {
1395
+ system: [0.1, 0.4],
1396
+ module: [0.4, 1],
1397
+ behavior: [1, 2.5],
1398
+ detail: [2.5, 5]
1399
+ };
1400
+ function computeZoomBand(zoom) {
1401
+ if (zoom < ZOOM_BAND_THRESHOLDS.module[0]) return "system";
1402
+ if (zoom < ZOOM_BAND_THRESHOLDS.behavior[0]) return "module";
1403
+ if (zoom < ZOOM_BAND_THRESHOLDS.detail[0]) return "behavior";
1404
+ return "detail";
1405
+ }
1406
+ function zoomProgress(zoom, band) {
1407
+ const [min, max] = ZOOM_BAND_THRESHOLDS[band];
1408
+ const clamped = Math.max(min, Math.min(max, zoom));
1409
+ const range = max - min;
1410
+ if (range === 0) return 1;
1411
+ return (clamped - min) / range;
1412
+ }
1413
+ var ZoomBandContext = createContext("module");
1414
+ function useZoomBand() {
1415
+ return useContext(ZoomBandContext);
1416
+ }
1417
+
1418
+ // src/lib/avl-flow-converter.ts
1419
+ var NODE_SPACING = 350;
1420
+ function schemaToFlowGraph(schema) {
1421
+ const appData = parseApplicationLevel(schema);
1422
+ const nodes = [];
1423
+ const edges = [];
1424
+ const count = appData.orbitals.length;
1425
+ const cols = Math.ceil(Math.sqrt(count));
1426
+ for (let i = 0; i < appData.orbitals.length; i++) {
1427
+ const orb = appData.orbitals[i];
1428
+ const orbitalDetail = parseOrbitalLevel(schema, orb.name);
1429
+ if (!orbitalDetail) continue;
1430
+ const traitDetails = {};
1431
+ for (const traitName of orb.traitNames) {
1432
+ const td = parseTraitLevel(schema, orb.name, traitName);
1433
+ if (td) traitDetails[traitName] = td;
1434
+ }
1435
+ const col = i % cols;
1436
+ const row = Math.floor(i / cols);
1437
+ nodes.push({
1438
+ id: orb.name,
1439
+ type: "orbital",
1440
+ position: { x: col * NODE_SPACING, y: row * NODE_SPACING },
1441
+ data: {
1442
+ orbitalName: orb.name,
1443
+ entityName: orb.entityName,
1444
+ persistence: orb.persistence,
1445
+ fields: orbitalDetail.entity.fields,
1446
+ traits: orbitalDetail.traits,
1447
+ pages: orbitalDetail.pages,
1448
+ traitDetails,
1449
+ externalLinks: orbitalDetail.externalLinks
1450
+ }
1451
+ });
1452
+ }
1453
+ for (const link of appData.crossLinks) {
1454
+ edges.push({
1455
+ id: `ew-${link.emitterOrbital}-${link.listenerOrbital}-${link.eventName}`,
1456
+ source: link.emitterOrbital,
1457
+ target: link.listenerOrbital,
1458
+ type: "eventWire",
1459
+ data: {
1460
+ edgeKind: "eventWire",
1461
+ event: link.eventName,
1462
+ fromTrait: link.emitterTrait ?? null,
1463
+ toTrait: link.listenerTrait ?? null
1464
+ }
1465
+ });
1466
+ }
1467
+ return { nodes, edges };
1468
+ }
1469
+ var DetailView = ({ data }) => {
1470
+ const { t } = useTranslate();
1471
+ const traitName = data.traits[0]?.name;
1472
+ const traitData = traitName ? data.traitDetails[traitName] : void 0;
1473
+ if (!traitData || traitData.transitions.length === 0) {
1474
+ return /* @__PURE__ */ jsx("div", { className: "rounded-lg border-2 border-[var(--color-border)] bg-[var(--color-card)] p-4 text-center text-[var(--color-muted-foreground)] text-sm", children: t("detailView.noTransitionData") });
1475
+ }
1476
+ const transition = traitData.transitions[0];
1477
+ const fromState = traitData.states.find((s) => s.name === transition.from);
1478
+ const toState = traitData.states.find((s) => s.name === transition.to);
1479
+ const transitionCounts = {};
1480
+ for (const s of traitData.states) transitionCounts[s.name] = 0;
1481
+ for (const t2 of traitData.transitions) {
1482
+ transitionCounts[t2.from] = (transitionCounts[t2.from] ?? 0) + 1;
1483
+ transitionCounts[t2.to] = (transitionCounts[t2.to] ?? 0) + 1;
1484
+ }
1485
+ const maxTC = Math.max(...Object.values(transitionCounts), 0);
1486
+ const fromRole = getStateRole(fromState?.isInitial ?? void 0, fromState?.isTerminal ?? void 0, transitionCounts[transition.from] ?? 0, maxTC);
1487
+ const toRole = getStateRole(toState?.isInitial ?? void 0, toState?.isTerminal ?? void 0, transitionCounts[transition.to] ?? 0, maxTC);
1488
+ const hasGuard = transition.guard != null;
1489
+ return /* @__PURE__ */ jsxs("div", { className: "rounded-lg border-2 border-[var(--color-border)] bg-[var(--color-card)] overflow-hidden", style: { minWidth: 380, maxWidth: 500 }, children: [
1490
+ /* @__PURE__ */ jsx("div", { className: "px-4 py-3 border-b border-[var(--color-border)] bg-[var(--color-background)]", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
1491
+ /* @__PURE__ */ jsx("svg", { width: 90, height: 32, viewBox: "0 0 90 32", children: /* @__PURE__ */ jsx(AvlState, { x: 0, y: 0, width: 80, height: 28, name: transition.from, role: fromRole, isInitial: fromState?.isInitial ?? void 0, isTerminal: fromState?.isTerminal ?? void 0 }) }),
1492
+ /* @__PURE__ */ jsxs("svg", { width: 24, height: 16, viewBox: "0 0 24 16", children: [
1493
+ /* @__PURE__ */ jsx("line", { x1: 0, y1: 8, x2: 18, y2: 8, stroke: "var(--color-muted-foreground)", strokeWidth: 2 }),
1494
+ /* @__PURE__ */ jsx("polygon", { points: "18,4 24,8 18,12", fill: "var(--color-muted-foreground)" })
1495
+ ] }),
1496
+ /* @__PURE__ */ jsx("svg", { width: 90, height: 32, viewBox: "0 0 90 32", children: /* @__PURE__ */ jsx(AvlState, { x: 0, y: 0, width: 80, height: 28, name: transition.to, role: toRole, isInitial: toState?.isInitial ?? void 0, isTerminal: toState?.isTerminal ?? void 0 }) })
1497
+ ] }) }),
1498
+ /* @__PURE__ */ jsxs("div", { className: "px-4 py-3 space-y-3", children: [
1499
+ /* @__PURE__ */ jsxs("div", { children: [
1500
+ /* @__PURE__ */ jsx("div", { className: "text-xs uppercase tracking-wider text-[var(--color-muted-foreground)] mb-1", children: t("avl.trigger") }),
1501
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
1502
+ /* @__PURE__ */ jsx("svg", { width: 16, height: 16, viewBox: "0 0 16 16", children: /* @__PURE__ */ jsx(AvlEvent, { x: 8, y: 8, size: 7 }) }),
1503
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold text-[var(--color-foreground)]", children: transition.event })
1504
+ ] })
1505
+ ] }),
1506
+ hasGuard && /* @__PURE__ */ jsxs("div", { children: [
1507
+ /* @__PURE__ */ jsx("div", { className: "text-xs uppercase tracking-wider text-[var(--color-muted-foreground)] mb-1", children: t("avl.guard") }),
1508
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
1509
+ /* @__PURE__ */ jsx("svg", { width: 14, height: 14, viewBox: "0 0 14 14", children: /* @__PURE__ */ jsx(AvlGuard, { x: 7, y: 7, size: 6 }) }),
1510
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-mono text-[var(--color-muted-foreground)] opacity-60", children: typeof transition.guard === "string" ? transition.guard : JSON.stringify(transition.guard) })
1511
+ ] })
1512
+ ] }),
1513
+ transition.effects.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
1514
+ /* @__PURE__ */ jsx("div", { className: "text-xs uppercase tracking-wider text-[var(--color-muted-foreground)] mb-1", children: t("avl.effects") }),
1515
+ /* @__PURE__ */ jsx("div", { className: "space-y-1.5", children: transition.effects.map((effect, i) => /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-1.5", children: [
1516
+ /* @__PURE__ */ jsxs("span", { className: "text-xs text-[var(--color-muted-foreground)] w-3 text-right mt-0.5", children: [
1517
+ i + 1,
1518
+ "."
1519
+ ] }),
1520
+ /* @__PURE__ */ jsx("svg", { width: 18, height: 18, viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx(AvlEffect, { x: 10, y: 10, effectType: effect.type, size: 8, showBackground: true }) }),
1521
+ /* @__PURE__ */ jsx("span", { className: "text-xs text-[var(--color-foreground)]", children: effect.type })
1522
+ ] }, i)) })
1523
+ ] })
1524
+ ] })
1525
+ ] });
1526
+ };
1527
+ DetailView.displayName = "DetailView";
1528
+ var AvlTransitionEdge = ({
1529
+ id,
1530
+ sourceX,
1531
+ sourceY,
1532
+ targetX,
1533
+ targetY,
1534
+ sourcePosition,
1535
+ targetPosition,
1536
+ data,
1537
+ markerEnd,
1538
+ style
1539
+ }) => {
1540
+ const { t } = useTranslate();
1541
+ const [path, labelX, labelY] = getBezierPath({
1542
+ sourceX,
1543
+ sourceY,
1544
+ targetX,
1545
+ targetY,
1546
+ sourcePosition,
1547
+ targetPosition
1548
+ });
1549
+ const isBackward = targetX < sourceX;
1550
+ const connStyle = isBackward ? CONNECTION_COLORS.backward : CONNECTION_COLORS.forward;
1551
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1552
+ /* @__PURE__ */ jsx(
1553
+ BaseEdge,
1554
+ {
1555
+ id,
1556
+ path,
1557
+ markerEnd,
1558
+ style: {
1559
+ stroke: connStyle.color,
1560
+ strokeWidth: connStyle.width,
1561
+ strokeDasharray: connStyle.dash,
1562
+ ...style
1563
+ }
1564
+ }
1565
+ ),
1566
+ /* @__PURE__ */ jsx(EdgeLabelRenderer, { children: /* @__PURE__ */ jsxs(
1567
+ "div",
1568
+ {
1569
+ className: "absolute pointer-events-all nodrag nopan flex items-center gap-1",
1570
+ style: { transform: `translate(-50%, -50%) translate(${labelX}px, ${labelY}px)` },
1571
+ children: [
1572
+ data?.hasGuard && /* @__PURE__ */ jsx("div", { className: "w-3 h-3 rotate-45 border border-warning bg-warning/10 shrink-0", title: t("avl.guard") }),
1573
+ /* @__PURE__ */ jsx("div", { className: "px-2 py-0.5 text-xs font-medium rounded-full bg-[var(--color-card)] border border-[var(--color-border)] text-[var(--color-foreground)] truncate max-w-[160px]", children: data?.event ?? "" }),
1574
+ data?.hasEffects && /* @__PURE__ */ jsx("div", { className: "w-2.5 h-2.5 rounded-full bg-primary shrink-0", title: t("avl.effects") })
1575
+ ]
1576
+ }
1577
+ ) })
1578
+ ] });
1579
+ };
1580
+ AvlTransitionEdge.displayName = "AvlTransitionEdge";
1581
+ var AvlEventWireEdge = ({
1582
+ id,
1583
+ sourceX,
1584
+ sourceY,
1585
+ targetX,
1586
+ targetY,
1587
+ sourcePosition,
1588
+ targetPosition,
1589
+ data,
1590
+ markerEnd,
1591
+ style
1592
+ }) => {
1593
+ const [path, labelX, labelY] = getBezierPath({
1594
+ sourceX,
1595
+ sourceY,
1596
+ targetX,
1597
+ targetY,
1598
+ sourcePosition,
1599
+ targetPosition
1600
+ });
1601
+ const isCompatible = data?.compatible !== false;
1602
+ const wireColor = isCompatible ? CONNECTION_COLORS.emitListen.color : "var(--color-error)";
1603
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1604
+ /* @__PURE__ */ jsx(
1605
+ BaseEdge,
1606
+ {
1607
+ id,
1608
+ path,
1609
+ markerEnd,
1610
+ style: {
1611
+ stroke: wireColor,
1612
+ strokeWidth: CONNECTION_COLORS.emitListen.width,
1613
+ strokeDasharray: CONNECTION_COLORS.emitListen.dash,
1614
+ ...style
1615
+ }
1616
+ }
1617
+ ),
1618
+ /* @__PURE__ */ jsx(EdgeLabelRenderer, { children: /* @__PURE__ */ jsx(
1619
+ "div",
1620
+ {
1621
+ className: "absolute pointer-events-all nodrag nopan",
1622
+ style: { transform: `translate(-50%, -50%) translate(${labelX}px, ${labelY}px)` },
1623
+ children: /* @__PURE__ */ jsx(
1624
+ "div",
1625
+ {
1626
+ className: "px-2 py-0.5 text-xs font-medium rounded-full border truncate max-w-[180px]",
1627
+ style: {
1628
+ color: wireColor,
1629
+ borderColor: wireColor,
1630
+ backgroundColor: avlTint(wireColor, 8)
1631
+ },
1632
+ children: data?.event ?? ""
1633
+ }
1634
+ )
1635
+ }
1636
+ ) })
1637
+ ] });
1638
+ };
1639
+ AvlEventWireEdge.displayName = "AvlEventWireEdge";
1640
+ var AvlBackwardEdge = ({
1641
+ id,
1642
+ sourceX,
1643
+ sourceY,
1644
+ targetX,
1645
+ targetY,
1646
+ sourcePosition,
1647
+ targetPosition,
1648
+ markerEnd,
1649
+ style
1650
+ }) => {
1651
+ const [path] = getBezierPath({
1652
+ sourceX,
1653
+ sourceY,
1654
+ targetX,
1655
+ targetY,
1656
+ sourcePosition,
1657
+ targetPosition
1658
+ });
1659
+ return /* @__PURE__ */ jsx(
1660
+ BaseEdge,
1661
+ {
1662
+ id,
1663
+ path,
1664
+ markerEnd,
1665
+ style: {
1666
+ stroke: CONNECTION_COLORS.backward.color,
1667
+ strokeWidth: CONNECTION_COLORS.backward.width,
1668
+ strokeDasharray: CONNECTION_COLORS.backward.dash,
1669
+ ...style
1670
+ }
1671
+ }
1672
+ );
1673
+ };
1674
+ AvlBackwardEdge.displayName = "AvlBackwardEdge";
1675
+ var PAGE_EDGE_COLOR = "var(--color-muted-foreground)";
1676
+ var AvlPageEdge = ({
1677
+ id,
1678
+ sourceX,
1679
+ sourceY,
1680
+ targetX,
1681
+ targetY,
1682
+ sourcePosition,
1683
+ targetPosition,
1684
+ markerEnd,
1685
+ style
1686
+ }) => {
1687
+ const [path] = getBezierPath({
1688
+ sourceX,
1689
+ sourceY,
1690
+ targetX,
1691
+ targetY,
1692
+ sourcePosition,
1693
+ targetPosition
1694
+ });
1695
+ return /* @__PURE__ */ jsx(
1696
+ BaseEdge,
1697
+ {
1698
+ id,
1699
+ path,
1700
+ markerEnd,
1701
+ style: {
1702
+ stroke: PAGE_EDGE_COLOR,
1703
+ strokeWidth: 1,
1704
+ ...style
1705
+ }
1706
+ }
1707
+ );
1708
+ };
1709
+ AvlPageEdge.displayName = "AvlPageEdge";
1710
+ var BINDING_COLOR = "var(--color-accent)";
1711
+ var AvlBindingEdge = ({
1712
+ id,
1713
+ sourceX,
1714
+ sourceY,
1715
+ targetX,
1716
+ targetY,
1717
+ sourcePosition,
1718
+ targetPosition,
1719
+ markerEnd,
1720
+ style
1721
+ }) => {
1722
+ const [path, labelX, labelY] = getBezierPath({
1723
+ sourceX,
1724
+ sourceY,
1725
+ targetX,
1726
+ targetY,
1727
+ sourcePosition,
1728
+ targetPosition
1729
+ });
1730
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1731
+ /* @__PURE__ */ jsx(
1732
+ BaseEdge,
1733
+ {
1734
+ id,
1735
+ path,
1736
+ markerEnd,
1737
+ style: {
1738
+ stroke: BINDING_COLOR,
1739
+ strokeWidth: 1,
1740
+ strokeDasharray: "3 2",
1741
+ ...style
1742
+ }
1743
+ }
1744
+ ),
1745
+ /* @__PURE__ */ jsx(EdgeLabelRenderer, { children: /* @__PURE__ */ jsx(
1746
+ "div",
1747
+ {
1748
+ className: "absolute pointer-events-none nodrag nopan",
1749
+ style: { transform: `translate(-50%, -50%) translate(${labelX}px, ${labelY}px)` },
1750
+ children: /* @__PURE__ */ jsx(
1751
+ "span",
1752
+ {
1753
+ className: "text-[9px] font-mono font-medium",
1754
+ style: { color: BINDING_COLOR },
1755
+ children: "@"
1756
+ }
1757
+ )
1758
+ }
1759
+ ) })
1760
+ ] });
1761
+ };
1762
+ AvlBindingEdge.displayName = "AvlBindingEdge";
1763
+ var BAND_LABEL_KEYS = {
1764
+ system: "zoomBreadcrumb.system",
1765
+ module: "zoomBreadcrumb.module",
1766
+ behavior: "zoomBreadcrumb.behavior",
1767
+ detail: "zoomBreadcrumb.detail"
1768
+ };
1769
+ var BAND_ICONS = {
1770
+ system: "\u25C9",
1771
+ // ◉ filled circle
1772
+ module: "\u25C9",
1773
+ // ◉ filled circle
1774
+ behavior: "\u25CE",
1775
+ // ◎ double circle
1776
+ detail: "\u26A1"
1777
+ // ⚡ lightning
1778
+ };
1779
+ var ZoomBreadcrumb = ({
1780
+ band,
1781
+ applicationName,
1782
+ orbitalName,
1783
+ traitName,
1784
+ eventName
1785
+ }) => {
1786
+ const { t } = useTranslate();
1787
+ const segments = [];
1788
+ if (applicationName) {
1789
+ segments.push({ icon: "\u25C9", label: applicationName });
1790
+ }
1791
+ segments.push({ icon: BAND_ICONS[band], label: t(BAND_LABEL_KEYS[band]) });
1792
+ if (orbitalName && (band === "module" || band === "behavior" || band === "detail")) {
1793
+ segments.push({ icon: "\u25C9", label: orbitalName });
1794
+ }
1795
+ if (traitName && (band === "behavior" || band === "detail")) {
1796
+ segments.push({ icon: "\u25CE", label: traitName });
1797
+ }
1798
+ if (eventName && band === "detail") {
1799
+ segments.push({ icon: "\u26A1", label: eventName });
1800
+ }
1801
+ return /* @__PURE__ */ jsx("div", { className: "absolute top-2 left-2 z-10 flex items-center gap-1 px-2 py-1 rounded-md bg-card/90 border border-border text-xs text-muted-foreground backdrop-blur-sm", children: segments.map((seg, i) => /* @__PURE__ */ jsxs(React4.Fragment, { children: [
1802
+ i > 0 && /* @__PURE__ */ jsx("span", { className: "opacity-40", children: ">" }),
1803
+ /* @__PURE__ */ jsx("span", { className: "opacity-60", children: seg.icon }),
1804
+ /* @__PURE__ */ jsx("span", { children: seg.label })
1805
+ ] }, i)) });
1806
+ };
1807
+ ZoomBreadcrumb.displayName = "ZoomBreadcrumb";
1808
+ var BAND_LEGENDS = {
1809
+ system: [
1810
+ { icon: "\u25C9", labelKey: "avl.glyph.entity" },
1811
+ { icon: "\u25CF\u25B2\u25A0\u25C6", labelKey: "zoomLegend.fieldTypes" },
1812
+ { icon: "\u25CF\u2501\u25CF", labelKey: "zoomLegend.stateChain" },
1813
+ { icon: "\u25A0", labelKey: "avl.glyph.page" },
1814
+ { icon: "\u2500 \u2500", labelKey: "zoomLegend.eventWire" }
1815
+ ],
1816
+ module: [
1817
+ { icon: "\u25C9", labelKey: "avl.glyph.entity" },
1818
+ { icon: "\u26C1", labelKey: "avl.glyph.persistence" },
1819
+ { icon: "\u25CF\u25B2\u25A0\u25C6\u25CB\u2B21\u2261", labelKey: "zoomLegend.fieldTypes" },
1820
+ { icon: "\u2501\u25CF\u2501", labelKey: "zoomLegend.stateMachine" },
1821
+ { icon: "\u229E\u270E\u26C1\u{1F4E1}", labelKey: "avl.effects" },
1822
+ { icon: "\u25A0", labelKey: "avl.glyph.page" },
1823
+ { icon: "\u25C0\u301C\u301C / \u301C\u301C\u25B6", labelKey: "zoomLegend.emitListen" }
1824
+ ],
1825
+ behavior: [
1826
+ { icon: "\u25CF", tint: "var(--color-success)", labelKey: "avlLegend.initialState" },
1827
+ { icon: "\u25CF", tint: "var(--color-error)", labelKey: "zoomLegend.terminalState" },
1828
+ { icon: "\u25CF", tint: "var(--color-info)", labelKey: "zoomLegend.hubState" },
1829
+ { icon: "\u26A1", labelKey: "avl.glyph.event" },
1830
+ { icon: "\u25C7", labelKey: "avl.glyph.guard" },
1831
+ { icon: "\u229E\u270E\u26C1\u{1F4E1}\u{1F514}", labelKey: "avl.effects" },
1832
+ { icon: "\u2500 \u2500", tint: "var(--color-warning)", labelKey: "zoomLegend.emitListen" }
1833
+ ],
1834
+ detail: [
1835
+ { icon: "\u26A1", labelKey: "zoomLegend.triggerEvent" },
1836
+ { icon: "\u25C7", labelKey: "zoomLegend.guardDiamond" },
1837
+ { icon: "\u229E", code: "render-ui" },
1838
+ { icon: "\u270E", code: "set" },
1839
+ { icon: "\u26C1", code: "persist" },
1840
+ { icon: "\u{1F4E1}", code: "emit" },
1841
+ { icon: "@", labelKey: "avl.glyph.binding" },
1842
+ { icon: "\u25CF\u25B2\u25A0", labelKey: "zoomLegend.fieldTypes" }
1843
+ ]
1844
+ };
1845
+ var ZoomLegend = ({ band }) => {
1846
+ const { t } = useTranslate();
1847
+ const [collapsed, setCollapsed] = useState(true);
1848
+ const items = BAND_LEGENDS[band];
1849
+ return /* @__PURE__ */ jsxs("div", { className: "absolute bottom-2 left-2 z-10", children: [
1850
+ /* @__PURE__ */ jsx(
1851
+ "button",
1852
+ {
1853
+ onClick: () => setCollapsed(!collapsed),
1854
+ className: "px-2 py-1 text-xs rounded-md bg-card/90 border border-border text-muted-foreground backdrop-blur-sm cursor-pointer hover:bg-card",
1855
+ children: collapsed ? t("zoomLegend.legend") : t("zoomLegend.hide")
1856
+ }
1857
+ ),
1858
+ !collapsed && /* @__PURE__ */ jsx("div", { className: "mt-1 px-2 py-1.5 rounded-md bg-card/95 border border-border backdrop-blur-sm space-y-0.5", children: items.map((item, i) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 text-xs text-muted-foreground", children: [
1859
+ /* @__PURE__ */ jsx("span", { className: "opacity-70 w-6 text-center", style: item.tint ? { color: item.tint } : void 0, children: item.icon }),
1860
+ /* @__PURE__ */ jsx("span", { children: item.labelKey ? t(item.labelKey) : item.code })
1861
+ ] }, i)) })
1862
+ ] });
1863
+ };
1864
+ ZoomLegend.displayName = "ZoomLegend";
1865
+ var AvlCosmicZoom = (props) => {
1866
+ return /* @__PURE__ */ jsx(
1867
+ FlowCanvas,
1868
+ {
1869
+ schema: props.schema,
1870
+ className: props.className,
1871
+ width: props.width,
1872
+ height: props.height ?? 400,
1873
+ initialOrbital: props.initialOrbital
1874
+ }
1875
+ );
1876
+ };
1877
+ AvlCosmicZoom.displayName = "AvlCosmicZoom";
1878
+ var LEVEL_BOX = { inset: 0, paddingTop: 56, paddingBottom: 24, paddingLeft: 24, paddingRight: 24 };
1879
+ var AvlOrbitalsCosmicZoom = ({
1880
+ schema: schemaProp,
1881
+ className,
1882
+ color = "var(--color-primary)",
1883
+ width = "100%",
1884
+ height = 450,
1885
+ highlightedOrbital,
1886
+ onOrbitalSelect,
1887
+ renderOrbitalPreview,
1888
+ openCodeEvent,
1889
+ previewEvent,
1890
+ dependencies,
1891
+ openBehaviorEvent,
1892
+ scene,
1893
+ stepEvent,
1894
+ playEvent,
1895
+ pauseEvent,
1896
+ stopEvent,
1897
+ playing = false
1898
+ }) => {
1899
+ const { t } = useTranslate();
1900
+ const parsedSchema = useMemo(() => {
1901
+ if (typeof schemaProp === "string") return JSON.parse(schemaProp);
1902
+ return schemaProp;
1903
+ }, [schemaProp]);
1904
+ const [state, dispatch] = useReducer(zoomReducer, initialZoomState);
1905
+ const [traitView, setTraitView] = useState({ lens: "flow", filter: null });
1906
+ useEffect(() => setTraitView({ lens: "flow", filter: null }), [state.selectedOrbital]);
1907
+ const breadcrumbs = useMemo(() => getBreadcrumbs(state), [state]);
1908
+ const handleSelect = useCallback(
1909
+ (name) => {
1910
+ dispatch({ type: "JUMP_TO_TRAIT_CIRCUIT", orbital: name });
1911
+ onOrbitalSelect?.(name);
1912
+ },
1913
+ [onOrbitalSelect]
1914
+ );
1915
+ const systemMap = useMemo(() => ({
1916
+ openTraits: handleSelect,
1917
+ ...renderOrbitalPreview ? { renderPreview: renderOrbitalPreview } : {},
1918
+ ...openCodeEvent ? { openCodeEvent } : {},
1919
+ ...previewEvent ? { previewEvent } : {},
1920
+ ...highlightedOrbital ? { highlighted: highlightedOrbital } : {}
1921
+ }), [handleSelect, renderOrbitalPreview, openCodeEvent, previewEvent, highlightedOrbital]);
1922
+ const handleCanvasNodeClick = useCallback(
1923
+ (ctx) => {
1924
+ if (ctx.level !== "transition" || !ctx.trait || ctx.transitionIndex === void 0) return;
1925
+ dispatch({ type: "SELECT_TRAIT", trait: ctx.trait });
1926
+ dispatch({ type: "ZOOM_INTO_TRANSITION", transitionIndex: ctx.transitionIndex, targetPosition: { x: 0, y: 0 } });
1927
+ Promise.resolve().then(() => dispatch({ type: "ANIMATION_COMPLETE" }));
1928
+ },
1929
+ []
1930
+ );
1931
+ const handleZoomOut = useCallback(() => {
1932
+ dispatch({ type: "ZOOM_OUT" });
1933
+ Promise.resolve().then(() => dispatch({ type: "ANIMATION_COMPLETE" }));
1934
+ }, []);
1935
+ const handleBreadcrumbClick = useCallback((targetLevel) => {
1936
+ const order = ["application", "orbital", "trait", "transition"];
1937
+ const currentIdx = order.indexOf(state.level);
1938
+ const targetIdx = order.indexOf(targetLevel);
1939
+ const steps2 = currentIdx - targetIdx;
1940
+ for (let i = 0; i < steps2; i++) {
1941
+ dispatch({ type: "ZOOM_OUT" });
1942
+ }
1943
+ Promise.resolve().then(() => dispatch({ type: "ANIMATION_COMPLETE" }));
1944
+ }, [state.level]);
1945
+ useEffect(() => {
1946
+ if (state.level === "application") return;
1947
+ const onKey = (e) => {
1948
+ if (e.key === "Escape") handleZoomOut();
1949
+ };
1950
+ window.addEventListener("keydown", onKey);
1951
+ return () => window.removeEventListener("keydown", onKey);
1952
+ }, [handleZoomOut, state.level]);
1953
+ const selectedTrait = useMemo(() => {
1954
+ if (!state.selectedOrbital || !state.selectedTrait) return null;
1955
+ return parseTraitLevel(parsedSchema, state.selectedOrbital, state.selectedTrait);
1956
+ }, [parsedSchema, state.selectedOrbital, state.selectedTrait]);
1957
+ const selectedTransition = state.selectedTransition === null ? void 0 : selectedTrait?.transitions[state.selectedTransition];
1958
+ const steps = useMemo(() => scene ?? [], [scene]);
1959
+ const [cursor, setCursor] = useState(steps.length - 1);
1960
+ useEffect(() => setCursor(steps.length - 1), [steps.length]);
1961
+ const sceneView = useMemo(() => ({ steps, cursor }), [steps, cursor]);
1962
+ const selectedPlayback = useMemo(
1963
+ () => selectedTrait && selectedTransition && state.selectedOrbital ? transitionPlayback(selectedTrait, state.selectedOrbital, selectedTransition, steps, cursor) : void 0,
1964
+ [selectedTrait, selectedTransition, state.selectedOrbital, steps, cursor]
1965
+ );
1966
+ const playTarget = state.selectedOrbital && state.selectedTrait ? { orbital: state.selectedOrbital, trait: state.selectedTrait } : null;
1967
+ const showSceneBar = (state.level === "trait" || state.level === "transition") && (steps.length > 0 || playTarget !== null && playEvent !== void 0 && state.level === "transition");
1968
+ const scopedSchema = useMemo(() => {
1969
+ if (!state.selectedOrbital) return null;
1970
+ const orbital = parsedSchema.orbitals?.find((o) => o.name === state.selectedOrbital);
1971
+ if (!orbital) return null;
1972
+ return { ...parsedSchema, orbitals: [orbital] };
1973
+ }, [parsedSchema, state.selectedOrbital]);
1974
+ return /* @__PURE__ */ jsxs(Box, { className, position: "relative", overflow: "visible", style: { width, height }, children: [
1975
+ /* @__PURE__ */ jsx(
1976
+ Box,
1977
+ {
1978
+ position: "absolute",
1979
+ style: {
1980
+ top: 12,
1981
+ left: 12,
1982
+ zIndex: 30,
1983
+ background: "var(--color-card)",
1984
+ padding: "4px 12px",
1985
+ borderRadius: 6,
1986
+ border: `1px solid ${color}`
1987
+ },
1988
+ children: /* @__PURE__ */ jsx(HStack, { gap: "xs", align: "center", children: breadcrumbs.map((crumb, i) => /* @__PURE__ */ jsxs(React4.Fragment, { children: [
1989
+ i > 0 && /* @__PURE__ */ jsx(Typography, { variant: "small", style: { opacity: 0.5, color }, children: "/" }),
1990
+ i < breadcrumbs.length - 1 ? /* @__PURE__ */ jsx(
1991
+ Box,
1992
+ {
1993
+ as: "span",
1994
+ ...pressableProps(() => handleBreadcrumbClick(crumb.level)),
1995
+ style: { cursor: "pointer" },
1996
+ children: /* @__PURE__ */ jsx(
1997
+ Typography,
1998
+ {
1999
+ variant: "small",
2000
+ style: { color, textDecoration: "underline" },
2001
+ children: crumb.labelKey ? t(crumb.labelKey, crumb.labelParams) : crumb.label
2002
+ }
2003
+ )
2004
+ }
2005
+ ) : /* @__PURE__ */ jsx(Typography, { variant: "small", weight: "bold", style: { color }, children: crumb.labelKey ? t(crumb.labelKey, crumb.labelParams) : crumb.label })
2006
+ ] }, crumb.level)) })
2007
+ }
2008
+ ),
2009
+ state.level !== "application" && /* @__PURE__ */ jsx(
2010
+ Box,
2011
+ {
2012
+ position: "absolute",
2013
+ style: {
2014
+ bottom: 12,
2015
+ right: 12,
2016
+ zIndex: 30,
2017
+ background: "var(--color-card)",
2018
+ padding: "2px 8px",
2019
+ borderRadius: 4,
2020
+ opacity: 0.8
2021
+ },
2022
+ children: /* @__PURE__ */ jsx(Typography, { variant: "small", style: { color }, children: t("avl.pressEscToZoomOut") })
2023
+ }
2024
+ ),
2025
+ state.level === "application" && /* @__PURE__ */ jsx(Box, { position: "absolute", style: LEVEL_BOX, children: /* @__PURE__ */ jsx(
2026
+ FlowCanvas,
2027
+ {
2028
+ schema: parsedSchema,
2029
+ initialLevel: "system",
2030
+ systemMap,
2031
+ ...dependencies ? { systemDependencies: dependencies } : {},
2032
+ ...openBehaviorEvent ? { openBehaviorEvent } : {},
2033
+ width: "100%",
2034
+ height: "100%"
2035
+ }
2036
+ ) }),
2037
+ state.level === "trait" && scopedSchema && state.selectedOrbital && /* @__PURE__ */ jsx(
2038
+ Box,
2039
+ {
2040
+ position: "absolute",
2041
+ style: {
2042
+ inset: 0,
2043
+ paddingTop: 56,
2044
+ paddingBottom: 24,
2045
+ paddingLeft: 24,
2046
+ paddingRight: 24
2047
+ },
2048
+ children: /* @__PURE__ */ jsx(
2049
+ FlowCanvas,
2050
+ {
2051
+ schema: scopedSchema,
2052
+ initialLevel: "trait-expanded",
2053
+ initialOrbital: state.selectedOrbital,
2054
+ onNodeClick: handleCanvasNodeClick,
2055
+ scene: sceneView,
2056
+ ...dependencies ? { systemDependencies: dependencies } : {},
2057
+ traitView,
2058
+ onTraitViewChange: setTraitView,
2059
+ width: "100%",
2060
+ height: "100%"
2061
+ }
2062
+ )
2063
+ }
2064
+ ),
2065
+ state.level === "transition" && selectedTransition && state.selectedOrbital && state.selectedTrait && /* @__PURE__ */ jsx(
2066
+ Box,
2067
+ {
2068
+ position: "absolute",
2069
+ style: {
2070
+ inset: 0,
2071
+ paddingTop: 56,
2072
+ paddingBottom: showSceneBar ? 72 : 24,
2073
+ paddingLeft: 24,
2074
+ paddingRight: 24,
2075
+ overflowY: "auto"
2076
+ },
2077
+ children: /* @__PURE__ */ jsx(
2078
+ AvlTransitionDetail,
2079
+ {
2080
+ orbital: state.selectedOrbital,
2081
+ trait: state.selectedTrait,
2082
+ transition: selectedTransition,
2083
+ playback: selectedPlayback,
2084
+ stepEvent
2085
+ }
2086
+ )
2087
+ }
2088
+ ),
2089
+ showSceneBar && /* @__PURE__ */ jsx(
2090
+ Box,
2091
+ {
2092
+ position: "absolute",
2093
+ "data-testid": "avl-scene-bar",
2094
+ className: "bg-card border border-border rounded-md shadow-sm",
2095
+ style: { left: "50%", transform: "translateX(-50%)", bottom: 12, zIndex: 30, padding: "6px 12px", width: "min(560px, calc(100% - 320px))" },
2096
+ children: /* @__PURE__ */ jsxs(HStack, { gap: "sm", align: "center", children: [
2097
+ playTarget && playEvent && state.level === "transition" ? playing && pauseEvent ? /* @__PURE__ */ jsx(Button, { variant: "secondary", size: "sm", action: pauseEvent, actionPayload: playTarget, leftIcon: "pause", title: t("avl.play.pause"), "data-testid": "avl-scene-pause" }) : /* @__PURE__ */ jsx(Button, { variant: "primary", size: "sm", action: playEvent, actionPayload: playTarget, leftIcon: "play", title: t("avl.play.play"), "data-testid": "avl-scene-play" }) : null,
2098
+ playTarget && stopEvent && steps.length > 0 ? /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", action: stopEvent, actionPayload: playTarget, leftIcon: "stop", title: t("avl.play.stop"), "data-testid": "avl-scene-stop" }) : null,
2099
+ steps.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
2100
+ /* @__PURE__ */ jsx(Box, { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsx(RangeSlider, { min: 0, max: Math.max(0, steps.length - 1), step: 1, value: Math.max(0, cursor), onChange: setCursor, size: "sm", "aria-label": t("avl.play.scene") }) }),
2101
+ /* @__PURE__ */ jsx(Box, { "data-testid": "avl-scene-position", children: /* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: t("avl.play.sceneStep", { n: cursor + 1, total: steps.length }) }) })
2102
+ ] }) : null
2103
+ ] })
2104
+ }
2105
+ )
2106
+ ] });
2107
+ };
2108
+ AvlOrbitalsCosmicZoom.displayName = "AvlOrbitalsCosmicZoom";
2109
+ var log = createLogger("almadar:ui:avl:trait-scene");
2110
+ var SWIM_GUTTER = 120;
2111
+ var CENTER_W = 360;
2112
+ var AvlTraitScene = ({
2113
+ data,
2114
+ color = "var(--color-primary)",
2115
+ onTransitionClick
2116
+ }) => {
2117
+ const { t } = useTranslate();
2118
+ const [layout, setLayout] = useState(null);
2119
+ const dataKey = useMemo(() => JSON.stringify(data), [data]);
2120
+ useEffect(() => {
2121
+ computeTraitLayout(data).then(setLayout).catch((error) => {
2122
+ log.error("computeTraitLayout failed", { error: error instanceof Error ? error : String(error) });
2123
+ });
2124
+ }, [dataKey]);
2125
+ if (!layout) {
2126
+ return /* @__PURE__ */ jsx("g", { children: /* @__PURE__ */ jsx("text", { x: 300, y: 200, textAnchor: "middle", fill: color, fontSize: 12, opacity: 0.5, children: t("avl.computingLayout") }) });
2127
+ }
2128
+ const hasExternal = data.listenedEvents.length > 0 || data.emittedEvents.length > 0;
2129
+ const machineOffsetX = hasExternal ? 0 : 30;
2130
+ const padding = 20;
2131
+ const availW = CENTER_W - padding * 2;
2132
+ const availH = 300;
2133
+ const scale = Math.min(1, availW / layout.width, availH / layout.height);
2134
+ const scaledW = layout.width * scale;
2135
+ const scaledH = layout.height * scale;
2136
+ const offsetX = padding + (availW - scaledW) / 2;
2137
+ const offsetY = 50 + (availH - scaledH) / 2;
2138
+ const machineHeight = scaledH + 100;
2139
+ const renderMachine = /* @__PURE__ */ jsxs("g", { children: [
2140
+ /* @__PURE__ */ jsx("text", { x: CENTER_W / 2, y: 20, textAnchor: "middle", fill: color, fontSize: 20, fontWeight: "700", fontFamily: "inherit", children: data.name }),
2141
+ /* @__PURE__ */ jsx("text", { x: CENTER_W / 2, y: 38, textAnchor: "middle", fill: color, fontSize: 11, opacity: 0.5, fontFamily: "inherit", children: t("avl.linkedTo", { entity: data.linkedEntity }) }),
2142
+ /* @__PURE__ */ jsxs("defs", { children: [
2143
+ /* @__PURE__ */ jsx("marker", { id: "traitArrowV2", viewBox: "0 0 10 10", refX: "9", refY: "5", markerWidth: "6", markerHeight: "6", orient: "auto-start-reverse", children: /* @__PURE__ */ jsx("path", { d: "M 0 0 L 10 5 L 0 10 z", fill: CONNECTION_COLORS.forward.color, opacity: 0.7 }) }),
2144
+ /* @__PURE__ */ jsx("marker", { id: "traitArrowBack", viewBox: "0 0 10 10", refX: "9", refY: "5", markerWidth: "6", markerHeight: "6", orient: "auto-start-reverse", children: /* @__PURE__ */ jsx("path", { d: "M 0 0 L 10 5 L 0 10 z", fill: CONNECTION_COLORS.backward.color, opacity: 0.5 }) })
2145
+ ] }),
2146
+ /* @__PURE__ */ jsxs("g", { transform: `translate(${offsetX},${offsetY}) scale(${scale})`, children: [
2147
+ layout.edges.map((edge) => {
2148
+ const conn = edge.isSelf ? CONNECTION_COLORS.selfLoop : edge.isBackward ? CONNECTION_COLORS.backward : CONNECTION_COLORS.forward;
2149
+ const marker = edge.isBackward || edge.isSelf ? "url(#traitArrowBack)" : "url(#traitArrowV2)";
2150
+ return /* @__PURE__ */ jsxs("g", { children: [
2151
+ /* @__PURE__ */ jsx(
2152
+ "path",
2153
+ {
2154
+ d: edgePath(edge.points),
2155
+ fill: "none",
2156
+ stroke: conn.color,
2157
+ strokeWidth: conn.width,
2158
+ strokeDasharray: conn.dash === "none" ? void 0 : conn.dash,
2159
+ opacity: 0.5,
2160
+ markerEnd: marker
2161
+ }
2162
+ ),
2163
+ /* @__PURE__ */ jsx(
2164
+ AvlTransitionLane,
2165
+ {
2166
+ x: edge.labelX,
2167
+ y: edge.labelY,
2168
+ event: edge.event,
2169
+ guard: edge.guardExpr,
2170
+ effects: edge.effects.map((e) => ({ type: e.type })),
2171
+ width: edge.labelW,
2172
+ isBackward: edge.isBackward,
2173
+ isSelfLoop: edge.isSelf,
2174
+ color,
2175
+ onTransitionClick: onTransitionClick ? () => onTransitionClick(edge.index, {
2176
+ x: edge.labelX + offsetX + (hasExternal ? SWIM_GUTTER : machineOffsetX),
2177
+ y: edge.labelY + offsetY
2178
+ }) : void 0
2179
+ }
2180
+ )
2181
+ ] }, edge.id);
2182
+ }),
2183
+ layout.nodes.map((node) => /* @__PURE__ */ jsx("g", { children: /* @__PURE__ */ jsx(
2184
+ AvlState,
2185
+ {
2186
+ x: node.x,
2187
+ y: node.y,
2188
+ width: node.width,
2189
+ height: node.height,
2190
+ name: node.id,
2191
+ isInitial: node.isInitial,
2192
+ isTerminal: node.isTerminal,
2193
+ role: node.role,
2194
+ transitionCount: node.transitionCount,
2195
+ color
2196
+ }
2197
+ ) }, node.id))
2198
+ ] })
2199
+ ] });
2200
+ if (!hasExternal) {
2201
+ return /* @__PURE__ */ jsx("g", { transform: `translate(${machineOffsetX}, 0)`, children: renderMachine });
2202
+ }
2203
+ return /* @__PURE__ */ jsx(
2204
+ AvlSwimLane,
2205
+ {
2206
+ listenedEvents: data.listenedEvents,
2207
+ emittedEvents: data.emittedEvents,
2208
+ centerWidth: CENTER_W,
2209
+ height: machineHeight,
2210
+ color,
2211
+ children: renderMachine
2212
+ }
2213
+ );
2214
+ };
2215
+ AvlTraitScene.displayName = "AvlTraitScene";
2216
+ var CX = 300;
2217
+ var CARD_W = 440;
2218
+ var CARD_X = CX - CARD_W / 2;
2219
+ var SECTION_LEFT = CARD_X + 16;
2220
+ var CONTENT_LEFT = CARD_X + 24;
2221
+ function flattenEffect(node) {
2222
+ const args = [];
2223
+ for (const child of node.children ?? []) {
2224
+ args.push(child.label);
2225
+ }
2226
+ return { type: node.label, args };
2227
+ }
2228
+ function mapEffectType(label) {
2229
+ const valid = [
2230
+ "render-ui",
2231
+ "set",
2232
+ "persist",
2233
+ "fetch",
2234
+ "emit",
2235
+ "navigate",
2236
+ "call-service",
2237
+ "spawn",
2238
+ "despawn",
2239
+ "do",
2240
+ "if",
2241
+ "log"
2242
+ ];
2243
+ return valid.includes(label) ? label : "log";
2244
+ }
2245
+ var AvlTransitionScene = ({
2246
+ data,
2247
+ color = "var(--color-primary)"
2248
+ }) => {
2249
+ const { t, locale } = useTranslate();
2250
+ const fromRole = getStateRole();
2251
+ const toRole = getStateRole();
2252
+ const fromColors = STATE_COLORS[fromRole];
2253
+ const toColors = STATE_COLORS[toRole];
2254
+ const hasGuard = !!data.guard;
2255
+ const hasEffects = data.effects.length > 0;
2256
+ const hasSlots = data.slotTargets.length > 0;
2257
+ const effects = data.effects.map(flattenEffect);
2258
+ const headerH = 52;
2259
+ const sectionGap = 8;
2260
+ const triggerH = 34;
2261
+ const guardH = hasGuard ? 30 + sectionGap : 0;
2262
+ const effectRowH = 28;
2263
+ const effectsH = hasEffects ? 24 + effects.length * effectRowH + sectionGap : 0;
2264
+ const slotsH = hasSlots ? 24 + data.slotTargets.length * 22 + sectionGap : 0;
2265
+ const cardH = headerH + triggerH + guardH + effectsH + slotsH + 16;
2266
+ const cardY = Math.max(20, (400 - cardH) / 2);
2267
+ return /* @__PURE__ */ jsxs("g", { children: [
2268
+ /* @__PURE__ */ jsx(
2269
+ "rect",
2270
+ {
2271
+ x: CARD_X,
2272
+ y: cardY,
2273
+ width: CARD_W,
2274
+ height: cardH,
2275
+ rx: 12,
2276
+ fill: "var(--color-surface, white)",
2277
+ fillOpacity: 0.97,
2278
+ stroke: color,
2279
+ strokeWidth: 0.8,
2280
+ strokeOpacity: 0.2
2281
+ }
2282
+ ),
2283
+ /* @__PURE__ */ jsx(
2284
+ "rect",
2285
+ {
2286
+ x: CARD_X,
2287
+ y: cardY,
2288
+ width: CARD_W,
2289
+ height: headerH,
2290
+ rx: 12,
2291
+ fill: color,
2292
+ fillOpacity: 0.03
2293
+ }
2294
+ ),
2295
+ /* @__PURE__ */ jsx(
2296
+ "rect",
2297
+ {
2298
+ x: CARD_X,
2299
+ y: cardY + headerH - 12,
2300
+ width: CARD_W,
2301
+ height: 12,
2302
+ fill: color,
2303
+ fillOpacity: 0.03
2304
+ }
2305
+ ),
2306
+ /* @__PURE__ */ jsx(
2307
+ "rect",
2308
+ {
2309
+ x: CARD_X + 20,
2310
+ y: cardY + 12,
2311
+ width: 140,
2312
+ height: 30,
2313
+ rx: 15,
2314
+ fill: fromColors.fill,
2315
+ stroke: fromColors.border,
2316
+ strokeWidth: 1.5
2317
+ }
2318
+ ),
2319
+ /* @__PURE__ */ jsx(
2320
+ "text",
2321
+ {
2322
+ x: CARD_X + 90,
2323
+ y: cardY + 31,
2324
+ textAnchor: "middle",
2325
+ fill: fromColors.border,
2326
+ fontSize: 14,
2327
+ fontWeight: 600,
2328
+ fontFamily: "inherit",
2329
+ children: data.from
2330
+ }
2331
+ ),
2332
+ /* @__PURE__ */ jsx(
2333
+ "text",
2334
+ {
2335
+ x: CX,
2336
+ y: cardY + 32,
2337
+ textAnchor: "middle",
2338
+ fill: color,
2339
+ fontSize: 16,
2340
+ opacity: 0.4,
2341
+ fontFamily: "inherit",
2342
+ children: "\u2192"
2343
+ }
2344
+ ),
2345
+ /* @__PURE__ */ jsx(
2346
+ "rect",
2347
+ {
2348
+ x: CARD_X + CARD_W - 160,
2349
+ y: cardY + 12,
2350
+ width: 140,
2351
+ height: 30,
2352
+ rx: 15,
2353
+ fill: toColors.fill,
2354
+ stroke: toColors.border,
2355
+ strokeWidth: 1.5
2356
+ }
2357
+ ),
2358
+ /* @__PURE__ */ jsx(
2359
+ "text",
2360
+ {
2361
+ x: CARD_X + CARD_W - 90,
2362
+ y: cardY + 31,
2363
+ textAnchor: "middle",
2364
+ fill: toColors.border,
2365
+ fontSize: 14,
2366
+ fontWeight: 600,
2367
+ fontFamily: "inherit",
2368
+ children: data.to
2369
+ }
2370
+ ),
2371
+ /* @__PURE__ */ jsx(
2372
+ "line",
2373
+ {
2374
+ x1: CARD_X + 12,
2375
+ y1: cardY + headerH,
2376
+ x2: CARD_X + CARD_W - 12,
2377
+ y2: cardY + headerH,
2378
+ stroke: color,
2379
+ strokeWidth: 0.5,
2380
+ opacity: 0.1
2381
+ }
2382
+ ),
2383
+ (() => {
2384
+ const secY = cardY + headerH + sectionGap;
2385
+ return /* @__PURE__ */ jsxs("g", { children: [
2386
+ /* @__PURE__ */ jsx("text", { x: SECTION_LEFT, y: secY + 12, fill: color, fontSize: 10, fontWeight: 600, opacity: 0.4, fontFamily: "inherit", children: t("avl.trigger").toLocaleUpperCase(locale) }),
2387
+ /* @__PURE__ */ jsx("text", { x: CONTENT_LEFT + 14, y: secY + 28, fill: color, fontSize: 14, fontWeight: 600, fontFamily: "inherit", children: data.event }),
2388
+ /* @__PURE__ */ jsx("text", { x: CONTENT_LEFT + 4, y: secY + 28, fill: color, fontSize: 10, opacity: 0.5, children: "\u26A1" })
2389
+ ] });
2390
+ })(),
2391
+ hasGuard && data.guard && (() => {
2392
+ const secY = cardY + headerH + sectionGap + triggerH;
2393
+ return /* @__PURE__ */ jsxs("g", { children: [
2394
+ /* @__PURE__ */ jsx("text", { x: SECTION_LEFT, y: secY + 12, fill: color, fontSize: 10, fontWeight: 600, opacity: 0.4, fontFamily: "inherit", children: t("avl.guard").toLocaleUpperCase(locale) }),
2395
+ /* @__PURE__ */ jsx(
2396
+ "polygon",
2397
+ {
2398
+ points: `${CONTENT_LEFT + 6},${secY + 22} ${CONTENT_LEFT + 2},${secY + 26} ${CONTENT_LEFT + 6},${secY + 30} ${CONTENT_LEFT + 10},${secY + 26}`,
2399
+ fill: "none",
2400
+ stroke: color,
2401
+ strokeWidth: 1,
2402
+ opacity: 0.5
2403
+ }
2404
+ ),
2405
+ /* @__PURE__ */ jsx("text", { x: CONTENT_LEFT + 18, y: secY + 29, fill: color, fontSize: 12, fontWeight: 400, opacity: 0.6, fontFamily: "inherit", children: data.guard.label })
2406
+ ] });
2407
+ })(),
2408
+ hasEffects && (() => {
2409
+ const secY = cardY + headerH + sectionGap + triggerH + guardH;
2410
+ return /* @__PURE__ */ jsxs("g", { children: [
2411
+ /* @__PURE__ */ jsx("text", { x: SECTION_LEFT, y: secY + 12, fill: color, fontSize: 10, fontWeight: 600, opacity: 0.4, fontFamily: "inherit", children: t("avl.effects").toLocaleUpperCase(locale) }),
2412
+ effects.map((eff, i) => {
2413
+ const rowY = secY + 22 + i * effectRowH;
2414
+ const effectType = mapEffectType(eff.type);
2415
+ const argsText = eff.args.length > 0 ? eff.args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" \xB7 ") : "";
2416
+ return /* @__PURE__ */ jsxs("g", { children: [
2417
+ /* @__PURE__ */ jsx(
2418
+ AvlEffect,
2419
+ {
2420
+ x: CONTENT_LEFT + 10,
2421
+ y: rowY + 6,
2422
+ effectType,
2423
+ size: 10,
2424
+ showBackground: true
2425
+ }
2426
+ ),
2427
+ /* @__PURE__ */ jsx("text", { x: CONTENT_LEFT + 28, y: rowY + 10, fill: color, fontSize: 12, fontWeight: 500, opacity: 0.8, fontFamily: "inherit", children: eff.type }),
2428
+ argsText && /* @__PURE__ */ jsx("text", { x: CONTENT_LEFT + 28 + eff.type.length * 7 + 8, y: rowY + 10, fill: color, fontSize: 10, fontWeight: 400, opacity: 0.5, fontFamily: "monospace", children: argsText })
2429
+ ] }, `eff-${i}`);
2430
+ })
2431
+ ] });
2432
+ })(),
2433
+ hasSlots && (() => {
2434
+ const secY = cardY + headerH + sectionGap + triggerH + guardH + effectsH;
2435
+ return /* @__PURE__ */ jsxs("g", { children: [
2436
+ /* @__PURE__ */ jsx("text", { x: SECTION_LEFT, y: secY + 12, fill: color, fontSize: 10, fontWeight: 600, opacity: 0.4, fontFamily: "inherit", children: t("avlTransitionScene.slots").toLocaleUpperCase(locale) }),
2437
+ data.slotTargets.map((slot, i) => {
2438
+ const rowY = secY + 22 + i * 22;
2439
+ return /* @__PURE__ */ jsxs("g", { children: [
2440
+ /* @__PURE__ */ jsx("rect", { x: CONTENT_LEFT, y: rowY - 4, width: CARD_W - 56, height: 18, rx: 4, fill: color, fillOpacity: 0.04 }),
2441
+ /* @__PURE__ */ jsxs("text", { x: CONTENT_LEFT + 8, y: rowY + 8, fill: color, fontSize: 11, fontFamily: "inherit", children: [
2442
+ slot.name,
2443
+ ": ",
2444
+ slot.pattern
2445
+ ] })
2446
+ ] }, `slot-${i}`);
2447
+ })
2448
+ ] });
2449
+ })()
2450
+ ] });
2451
+ };
2452
+ AvlTransitionScene.displayName = "AvlTransitionScene";
2453
+ var AvlClickTarget = ({
2454
+ x,
2455
+ y,
2456
+ width,
2457
+ height,
2458
+ onClick,
2459
+ onHover,
2460
+ cursor = "pointer",
2461
+ glowColor = "var(--color-primary)",
2462
+ label,
2463
+ children
2464
+ }) => {
2465
+ const [hovering, setHovering] = useState(false);
2466
+ const handleMouseEnter = useCallback(() => {
2467
+ setHovering(true);
2468
+ onHover?.(true);
2469
+ }, [onHover]);
2470
+ const handleMouseLeave = useCallback(() => {
2471
+ setHovering(false);
2472
+ onHover?.(false);
2473
+ }, [onHover]);
2474
+ const handleKeyDown = useCallback((e) => {
2475
+ if (e.key === "Enter" || e.key === " ") {
2476
+ e.preventDefault();
2477
+ onClick();
2478
+ }
2479
+ }, [onClick]);
2480
+ return /* @__PURE__ */ jsxs("g", { children: [
2481
+ hovering && /* @__PURE__ */ jsx(
2482
+ "rect",
2483
+ {
2484
+ x: x - 4,
2485
+ y: y - 4,
2486
+ width: width + 8,
2487
+ height: height + 8,
2488
+ rx: 8,
2489
+ fill: glowColor,
2490
+ opacity: 0.08
2491
+ }
2492
+ ),
2493
+ children,
2494
+ /* @__PURE__ */ jsx(
2495
+ "rect",
2496
+ {
2497
+ x,
2498
+ y,
2499
+ width,
2500
+ height,
2501
+ fill: "transparent",
2502
+ style: { cursor },
2503
+ pointerEvents: "all",
2504
+ onClick,
2505
+ onMouseEnter: handleMouseEnter,
2506
+ onMouseLeave: handleMouseLeave,
2507
+ onKeyDown: handleKeyDown,
2508
+ tabIndex: 0,
2509
+ role: "button",
2510
+ "aria-label": label
2511
+ }
2512
+ )
2513
+ ] });
2514
+ };
2515
+ AvlClickTarget.displayName = "AvlClickTarget";
2516
+
2517
+ // src/lib/avl-deployment-graph.ts
2518
+ var COLUMNS = ["client", "host", "service", "store", "external"];
2519
+ var WIDTH = { client: 160, host: 220, service: 200, store: 200, external: 200 };
2520
+ var DEPLOYMENT_ROW = { height: 26, gap: 8, columnGap: 160, headerHeight: 30 };
2521
+ function deploymentGraph(input) {
2522
+ return layeredGraph({
2523
+ columns: COLUMNS.map((id) => ({ id, width: WIDTH[id] ?? 200 })),
2524
+ units: input.units,
2525
+ edges: input.edges,
2526
+ row: DEPLOYMENT_ROW,
2527
+ handles: "facing"
2528
+ });
2529
+ }
2530
+ var STATE_ROLES = ["initial", "terminal", "hub", "default"];
2531
+ var STATUSES = ["idle", "running", "success", "error"];
2532
+ var FOCUS_LEVELS = ["node", "slot", "field", "effect", "trait", "page", "orbital"];
2533
+ function fail(what) {
2534
+ throw new Error(`Invalid AVL prop value: ${what}`);
2535
+ }
2536
+ function isList(value) {
2537
+ return Array.isArray(value);
2538
+ }
2539
+ function record(value, what) {
2540
+ if (value === null || value === void 0 || typeof value !== "object" || value instanceof Date || isList(value)) {
2541
+ fail(`${what} must be an object`);
2542
+ }
2543
+ return value;
2544
+ }
2545
+ function list(value, what) {
2546
+ if (!isList(value)) fail(`${what} must be a list`);
2547
+ return value;
2548
+ }
2549
+ function str(o, key) {
2550
+ const v = o[key];
2551
+ if (typeof v !== "string") fail(`${key} must be a string`);
2552
+ return v;
2553
+ }
2554
+ function optStr(o, key) {
2555
+ const v = o[key];
2556
+ if (v === void 0 || v === null) return void 0;
2557
+ if (typeof v !== "string") fail(`${key} must be a string`);
2558
+ return v;
2559
+ }
2560
+ function num(o, key) {
2561
+ const v = o[key];
2562
+ if (typeof v !== "number") fail(`${key} must be a number`);
2563
+ return v;
2564
+ }
2565
+ function optNum(o, key) {
2566
+ const v = o[key];
2567
+ if (v === void 0 || v === null) return void 0;
2568
+ if (typeof v !== "number") fail(`${key} must be a number`);
2569
+ return v;
2570
+ }
2571
+ function optStrList(o, key) {
2572
+ const v = o[key];
2573
+ if (v === void 0 || v === null) return void 0;
2574
+ return list(v, key).map((item) => {
2575
+ if (typeof item !== "string") fail(`${key} must hold strings`);
2576
+ return item;
2577
+ });
2578
+ }
2579
+ function oneOf(o, key, allowed) {
2580
+ const v = optStr(o, key);
2581
+ if (v === void 0) return void 0;
2582
+ const hit = allowed.find((a) => a === v);
2583
+ if (hit === void 0) fail(`${key} must be one of ${allowed.join(", ")}`);
2584
+ return hit;
2585
+ }
2586
+ function renderUIEntry(value) {
2587
+ const o = record(value, "pattern entry");
2588
+ return { slot: str(o, "slot"), pattern: PatternObjectSchema.parse(o.pattern) };
2589
+ }
2590
+ function eventSource(value) {
2591
+ const o = record(value, "event source");
2592
+ const fields = o.payloadFields;
2593
+ return {
2594
+ event: str(o, "event"),
2595
+ patternType: str(o, "patternType"),
2596
+ label: optStr(o, "label"),
2597
+ path: str(o, "path"),
2598
+ positionHint: num(o, "positionHint"),
2599
+ payloadFields: fields === void 0 || fields === null ? void 0 : list(fields, "payloadFields").map((f) => {
2600
+ const p = record(f, "payload field");
2601
+ const required = p.required;
2602
+ if (required !== void 0 && required !== null && typeof required !== "boolean") fail("required must be a boolean");
2603
+ return { name: str(p, "name"), type: str(p, "type"), required: typeof required === "boolean" ? required : void 0 };
2604
+ })
2605
+ };
2606
+ }
2607
+ function decodePreviewNodeData(value) {
2608
+ const o = record(value, "node");
2609
+ const label = oneOf(o, "cardLabel", ["screen"]);
2610
+ const guard = o.guard;
2611
+ return {
2612
+ orbitalName: str(o, "orbitalName"),
2613
+ traitName: optStr(o, "traitName"),
2614
+ stateName: optStr(o, "stateName"),
2615
+ transitionEvent: optStr(o, "transitionEvent"),
2616
+ fromState: optStr(o, "fromState"),
2617
+ toState: optStr(o, "toState"),
2618
+ cardWidth: optNum(o, "cardWidth"),
2619
+ cardLabel: label,
2620
+ enteredBy: optStrList(o, "enteredBy"),
2621
+ patterns: list(o.patterns, "patterns").map(renderUIEntry),
2622
+ eventSources: list(o.eventSources, "eventSources").map(eventSource),
2623
+ layer: optStr(o, "layer"),
2624
+ stateRole: oneOf(o, "stateRole", STATE_ROLES),
2625
+ effectTypes: optStrList(o, "effectTypes"),
2626
+ guard: guard === void 0 ? void 0 : guard === null ? null : SExprDataSchema.parse(guard),
2627
+ entityName: optStr(o, "entityName"),
2628
+ persistence: optStr(o, "persistence"),
2629
+ fieldCount: optNum(o, "fieldCount"),
2630
+ traitCount: optNum(o, "traitCount"),
2631
+ pageRoutes: optStrList(o, "pageRoutes"),
2632
+ status: oneOf(o, "status", STATUSES)
2633
+ };
2634
+ }
2635
+ function offsetInParent(value) {
2636
+ const o = record(value, "offsetInParent");
2637
+ return {
2638
+ left: num(o, "left"),
2639
+ top: num(o, "top"),
2640
+ right: num(o, "right"),
2641
+ bottom: num(o, "bottom"),
2642
+ parentWidth: num(o, "parentWidth"),
2643
+ parentHeight: num(o, "parentHeight")
2644
+ };
2645
+ }
2646
+ function editFocus(value) {
2647
+ const o = record(value, "focus");
2648
+ const level = oneOf(o, "level", FOCUS_LEVELS);
2649
+ if (level === void 0) fail("level is required");
2650
+ return {
2651
+ level,
2652
+ orbital: str(o, "orbital"),
2653
+ trait: optStr(o, "trait"),
2654
+ transition: optStr(o, "transition"),
2655
+ state: optStr(o, "state"),
2656
+ slot: optStr(o, "slot"),
2657
+ path: optStr(o, "path"),
2658
+ patternType: optStr(o, "patternType"),
2659
+ entity: optStr(o, "entity"),
2660
+ source: optStr(o, "source"),
2661
+ label: str(o, "label")
2662
+ };
2663
+ }
2664
+ function decodeSelectedPattern(value) {
2665
+ const o = record(value, "selected pattern");
2666
+ const rect = o.rect;
2667
+ const offset = o.offsetInParent;
2668
+ return {
2669
+ patternType: str(o, "patternType"),
2670
+ patternId: optStr(o, "patternId"),
2671
+ nodeData: decodePreviewNodeData(o.nodeData),
2672
+ sourceTrait: optStr(o, "sourceTrait"),
2673
+ rect: rect === void 0 || rect === null ? void 0 : (() => {
2674
+ const r = record(rect, "rect");
2675
+ return { top: num(r, "top"), left: num(r, "left"), width: num(r, "width"), height: num(r, "height") };
2676
+ })(),
2677
+ selection: optStrList(o, "selection"),
2678
+ offsetInParent: offset === void 0 || offset === null ? void 0 : offsetInParent(offset),
2679
+ focus: o.focus === void 0 || o.focus === null ? void 0 : editFocus(o.focus),
2680
+ elements: o.elements === void 0 || o.elements === null ? void 0 : list(o.elements, "elements").map(editFocus)
2681
+ };
2682
+ }
2683
+ function decodeNodePlacements(value) {
2684
+ const o = record(value, "nodePositions");
2685
+ const out = {};
2686
+ for (const [id, placement] of Object.entries(o)) {
2687
+ const p = record(placement, `nodePositions.${id}`);
2688
+ out[id] = { x: num(p, "x"), y: num(p, "y"), width: optNum(p, "width") };
2689
+ }
2690
+ return out;
2691
+ }
2692
+
2693
+ export { AvlBackwardEdge, AvlBehaviorGlyph, AvlBindingEdge, AvlClickTarget, AvlClosedCircuit, AvlCosmicZoom, AvlEmitListen, AvlEventWireEdge, AvlExprTree, AvlOrbitalUnit, AvlOrbitalsCosmicZoom, AvlPageEdge, AvlSlotMap, AvlSwimLane, AvlTraitScene, AvlTransitionEdge, AvlTransitionLane, AvlTransitionScene, DEPLOYMENT_ROW, DOMAIN_COLORS, DetailView, ZOOM_BAND_THRESHOLDS, ZoomBandContext, ZoomBreadcrumb, ZoomLegend, arcPath, computeZoomBand, curveControlPoint, decodeNodePlacements, decodePreviewNodeData, decodeSelectedPattern, deploymentGraph, gridPositions, radialPositions, ringPositions, schemaToFlowGraph, useZoomBand, zoomProgress };