@almadar/shell-web 0.0.0-stage → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (266) hide show
  1. package/bundling.d.mts +18 -0
  2. package/bundling.mjs +28 -0
  3. package/dist/ArbitraryClassCompiler-CO_iASBn.d.ts +195 -0
  4. package/dist/AvlGlyph-EPJKFEO3.js +6 -0
  5. package/dist/AvlStateMachine-RKZIKNGC.js +9 -0
  6. package/dist/AvlTransitionDetail-63SD6GZF.js +11 -0
  7. package/dist/AvlTransitionExplainer-ZBTLOM3T.js +12 -0
  8. package/dist/BehaviorView-YS5G4GNB.js +11 -0
  9. package/dist/Canvas3DHost-BkZQB5l2.d.ts +552 -0
  10. package/dist/EventBusProvider-BFFHfN4O.d.ts +296 -0
  11. package/dist/FileTree-BCFnBEuQ.d.ts +254 -0
  12. package/dist/FlowCanvas-3JRMNJLV.css +1756 -0
  13. package/dist/FlowCanvas-AUMTWMNG.js +26 -0
  14. package/dist/GameAudioProvider-ceM_n0ey.d.ts +90 -0
  15. package/dist/KaTeX_AMS-Regular-CYEKBG2K.woff +0 -0
  16. package/dist/KaTeX_AMS-Regular-JKX5W2C4.ttf +0 -0
  17. package/dist/KaTeX_AMS-Regular-U6PRYMIZ.woff2 +0 -0
  18. package/dist/KaTeX_Caligraphic-Bold-5QL5CMTE.woff2 +0 -0
  19. package/dist/KaTeX_Caligraphic-Bold-WZ3QSGD3.woff +0 -0
  20. package/dist/KaTeX_Caligraphic-Bold-ZTS3R3HK.ttf +0 -0
  21. package/dist/KaTeX_Caligraphic-Regular-3LKEU76G.woff +0 -0
  22. package/dist/KaTeX_Caligraphic-Regular-A7XRTZ5Q.ttf +0 -0
  23. package/dist/KaTeX_Caligraphic-Regular-KX5MEWCF.woff2 +0 -0
  24. package/dist/KaTeX_Fraktur-Bold-2QVFK6NQ.woff2 +0 -0
  25. package/dist/KaTeX_Fraktur-Bold-T4SWXBMT.woff +0 -0
  26. package/dist/KaTeX_Fraktur-Bold-WGHVTYOR.ttf +0 -0
  27. package/dist/KaTeX_Fraktur-Regular-2PEIFJSJ.woff2 +0 -0
  28. package/dist/KaTeX_Fraktur-Regular-5U4OPH2X.ttf +0 -0
  29. package/dist/KaTeX_Fraktur-Regular-PQMHCIK6.woff +0 -0
  30. package/dist/KaTeX_Main-Bold-2GA4IZIN.woff +0 -0
  31. package/dist/KaTeX_Main-Bold-W5FBVCZM.ttf +0 -0
  32. package/dist/KaTeX_Main-Bold-YP5VVQRP.woff2 +0 -0
  33. package/dist/KaTeX_Main-BoldItalic-4P4C7HJH.woff +0 -0
  34. package/dist/KaTeX_Main-BoldItalic-N4V3DX7S.woff2 +0 -0
  35. package/dist/KaTeX_Main-BoldItalic-ODMLBJJQ.ttf +0 -0
  36. package/dist/KaTeX_Main-Italic-I43T2HSR.ttf +0 -0
  37. package/dist/KaTeX_Main-Italic-RELBIK7M.woff2 +0 -0
  38. package/dist/KaTeX_Main-Italic-SASNQFN2.woff +0 -0
  39. package/dist/KaTeX_Main-Regular-ARRPAO67.woff2 +0 -0
  40. package/dist/KaTeX_Main-Regular-P5I74A2A.woff +0 -0
  41. package/dist/KaTeX_Main-Regular-W74P5G27.ttf +0 -0
  42. package/dist/KaTeX_Math-BoldItalic-6EBV3DK5.woff +0 -0
  43. package/dist/KaTeX_Math-BoldItalic-K4WTGH3J.woff2 +0 -0
  44. package/dist/KaTeX_Math-BoldItalic-VB447A4D.ttf +0 -0
  45. package/dist/KaTeX_Math-Italic-6KGCHLFN.woff2 +0 -0
  46. package/dist/KaTeX_Math-Italic-KKK3USB2.woff +0 -0
  47. package/dist/KaTeX_Math-Italic-SON4MRCA.ttf +0 -0
  48. package/dist/KaTeX_SansSerif-Bold-RRNVJFFW.woff2 +0 -0
  49. package/dist/KaTeX_SansSerif-Bold-STQ6RXC7.ttf +0 -0
  50. package/dist/KaTeX_SansSerif-Bold-X5M5EMOD.woff +0 -0
  51. package/dist/KaTeX_SansSerif-Italic-HMPFTM52.woff2 +0 -0
  52. package/dist/KaTeX_SansSerif-Italic-PSN4QKYX.woff +0 -0
  53. package/dist/KaTeX_SansSerif-Italic-WTBAZBGY.ttf +0 -0
  54. package/dist/KaTeX_SansSerif-Regular-2TL3USAE.ttf +0 -0
  55. package/dist/KaTeX_SansSerif-Regular-OQCII6EP.woff +0 -0
  56. package/dist/KaTeX_SansSerif-Regular-XIQ62X4E.woff2 +0 -0
  57. package/dist/KaTeX_Script-Regular-72OLXYNA.ttf +0 -0
  58. package/dist/KaTeX_Script-Regular-A5IFOEBS.woff +0 -0
  59. package/dist/KaTeX_Script-Regular-APUWIHLP.woff2 +0 -0
  60. package/dist/KaTeX_Size1-Regular-4HRHTS65.woff +0 -0
  61. package/dist/KaTeX_Size1-Regular-5LRUTBFT.woff2 +0 -0
  62. package/dist/KaTeX_Size1-Regular-7K6AASVL.ttf +0 -0
  63. package/dist/KaTeX_Size2-Regular-222HN3GT.ttf +0 -0
  64. package/dist/KaTeX_Size2-Regular-K5ZHAIS6.woff +0 -0
  65. package/dist/KaTeX_Size2-Regular-LELKET5D.woff2 +0 -0
  66. package/dist/KaTeX_Size3-Regular-TLFPAHDE.woff +0 -0
  67. package/dist/KaTeX_Size3-Regular-UFCO6WCA.ttf +0 -0
  68. package/dist/KaTeX_Size3-Regular-WQRQ47UD.woff2 +0 -0
  69. package/dist/KaTeX_Size4-Regular-7PGNVPQK.ttf +0 -0
  70. package/dist/KaTeX_Size4-Regular-CDMV7U5C.woff2 +0 -0
  71. package/dist/KaTeX_Size4-Regular-PKMWZHNC.woff +0 -0
  72. package/dist/KaTeX_Typewriter-Regular-3F5K6SQ6.ttf +0 -0
  73. package/dist/KaTeX_Typewriter-Regular-MJMFSK64.woff +0 -0
  74. package/dist/KaTeX_Typewriter-Regular-VBYJ4NRC.woff2 +0 -0
  75. package/dist/KernelEngineContext-CcxGYtlr.d.ts +33 -0
  76. package/dist/LayersPanel-M2LHWUFF.js +6 -0
  77. package/dist/ModuleCard-QHDGK5XK.js +7 -0
  78. package/dist/OrbInspector-MHLJ6OEE.css +1756 -0
  79. package/dist/OrbInspector-QCPEPUPH.js +26 -0
  80. package/dist/Select-B-iDdnvE.d.ts +185 -0
  81. package/dist/ServerBridge-Bqsj-lOU.d.ts +124 -0
  82. package/dist/ThemeContext-DJmO59xd.d.ts +147 -0
  83. package/dist/UISlotContext-Dl_ewwCI.d.ts +79 -0
  84. package/dist/UISlotRenderer-C7WWOK43.js +26 -0
  85. package/dist/UISlotRenderer-KVFO6J7R.css +1756 -0
  86. package/dist/auth/browser/index.d.ts +2 -0
  87. package/dist/auth/browser/index.js +2 -0
  88. package/dist/auth/react/index.d.ts +56 -0
  89. package/dist/auth/react/index.js +157 -0
  90. package/dist/avl/index.css +1756 -0
  91. package/dist/avl/index.d.ts +2248 -0
  92. package/dist/avl/index.js +2693 -0
  93. package/dist/avl-3d-context-BycmO6tG.d.ts +201 -0
  94. package/dist/avl-schema-parser-CtJxJ9KU.d.ts +132 -0
  95. package/dist/avl-zoom-state-CKMVuBFg.d.ts +17 -0
  96. package/dist/chunk-3BBUBJFF.js +339 -0
  97. package/dist/chunk-3S54FWRC.js +131 -0
  98. package/dist/chunk-3VZ36ZKO.js +775 -0
  99. package/dist/chunk-4T3P43NS.js +1133 -0
  100. package/dist/chunk-4YXBKHHM.js +11488 -0
  101. package/dist/chunk-57DC34LY.js +525 -0
  102. package/dist/chunk-5QTYQTPS.js +15 -0
  103. package/dist/chunk-A2LR6VQQ.js +349 -0
  104. package/dist/chunk-AB3X7QTE.js +505 -0
  105. package/dist/chunk-AE7VCQB6.js +561 -0
  106. package/dist/chunk-AGXD77SL.js +98 -0
  107. package/dist/chunk-AU7O65OX.js +66 -0
  108. package/dist/chunk-CPLN6NBQ.js +701 -0
  109. package/dist/chunk-DZBQA2OW.js +176 -0
  110. package/dist/chunk-E6KA4J6N.js +227 -0
  111. package/dist/chunk-EOWMARUB.js +16 -0
  112. package/dist/chunk-G7DCAZ22.js +19 -0
  113. package/dist/chunk-GFXCPUMX.js +1334 -0
  114. package/dist/chunk-HH5KSMH5.js +311 -0
  115. package/dist/chunk-ILQXJ2AR.js +280 -0
  116. package/dist/chunk-ILZ7ORX7.js +432 -0
  117. package/dist/chunk-K4MOPSEL.js +674 -0
  118. package/dist/chunk-LHP2TK7O.js +47587 -0
  119. package/dist/chunk-P4ZFUQFF.js +93 -0
  120. package/dist/chunk-PCR37T3U.js +296 -0
  121. package/dist/chunk-PRXQGGCO.js +580 -0
  122. package/dist/chunk-REXYVBUO.js +191 -0
  123. package/dist/chunk-ROICKAU7.js +24 -0
  124. package/dist/chunk-SP5CDJ6K.js +338 -0
  125. package/dist/chunk-TUPZWTRE.js +1051 -0
  126. package/dist/chunk-TXAUOLWZ.js +490 -0
  127. package/dist/chunk-TZZBINQY.js +82 -0
  128. package/dist/chunk-UTDC2NEA.js +14 -0
  129. package/dist/chunk-UU57VNS2.js +1053 -0
  130. package/dist/chunk-UXLE3IPR.js +421 -0
  131. package/dist/chunk-VO2TTLS5.js +94 -0
  132. package/dist/chunk-X3DMMX27.js +11 -0
  133. package/dist/chunk-YHMRX6YA.js +455 -0
  134. package/dist/components/index.css +1756 -0
  135. package/dist/components/index.d.ts +11299 -0
  136. package/dist/components/index.js +1110 -0
  137. package/dist/context/index.d.ts +8 -0
  138. package/dist/context/index.js +8 -0
  139. package/dist/core.d.ts +2599 -0
  140. package/dist/core.js +3 -0
  141. package/dist/design-classes/index.cjs +431 -0
  142. package/dist/design-classes/index.d.cts +165 -0
  143. package/dist/design-classes/index.d.ts +165 -0
  144. package/dist/design-classes/index.js +399 -0
  145. package/dist/emojiItems-QGSNAABW.js +20 -0
  146. package/dist/fx-CmQjnHmT.d.ts +371 -0
  147. package/dist/hooks/index.d.ts +971 -0
  148. package/dist/hooks/index.js +8 -0
  149. package/dist/index.d.ts +408 -0
  150. package/dist/index.js +178 -0
  151. package/dist/katexPlugin-FA7NX4PE.css +1161 -0
  152. package/dist/katexPlugin-NCDKOOQY.js +2 -0
  153. package/dist/kernel-client-TZKGHJRY.js +516 -0
  154. package/dist/kernel-wire-wNdAPfhJ.d.ts +88 -0
  155. package/dist/lib/index.d.ts +602 -0
  156. package/dist/lib/index.js +1289 -0
  157. package/dist/paintDispatch-CuJLsr9Y.d.ts +688 -0
  158. package/dist/parseLessonSegments-GpCeMrb2.d.ts +334 -0
  159. package/dist/perf-CKiBKbkw.d.ts +22 -0
  160. package/dist/perf-Dr28-AgT.d.ts +57 -0
  161. package/dist/prism-X5YWKXO5.js +136 -0
  162. package/dist/providers/index.css +1756 -0
  163. package/dist/providers/index.d.ts +355 -0
  164. package/dist/providers/index.js +29 -0
  165. package/dist/renderer/index.d.ts +465 -0
  166. package/dist/renderer/index.js +4 -0
  167. package/dist/runtime/index.css +1756 -0
  168. package/dist/runtime/index.d.ts +239 -0
  169. package/dist/runtime/index.js +28 -0
  170. package/dist/slot-host-CPzrxLo9.d.ts +48 -0
  171. package/dist/ssr/index.cjs +9739 -0
  172. package/dist/ssr/index.d.cts +464 -0
  173. package/dist/ssr/index.d.ts +464 -0
  174. package/dist/ssr/index.js +9703 -0
  175. package/dist/storage/browser/index.d.ts +1 -0
  176. package/dist/storage/browser/index.js +2 -0
  177. package/dist/test-support.d.ts +42 -0
  178. package/dist/test-support.js +181 -0
  179. package/dist/themeTokens-CRd8AEDF.d.ts +125 -0
  180. package/dist/three/index.css +503 -0
  181. package/dist/three/index.d.ts +1185 -0
  182. package/dist/three/index.js +3908 -0
  183. package/dist/useUISlots-CiobNFGb.d.ts +211 -0
  184. package/dist/verification-C5pTeMJv.d.ts +66 -0
  185. package/dist/verificationRegistry-CVrcxG1s.d.ts +122 -0
  186. package/dist/wrapCallbackForEvent-B9QLbhxX.d.ts +19 -0
  187. package/index.css +199 -0
  188. package/package.json +273 -3
  189. package/src/core/lib/band-shapes.json +7 -0
  190. package/src/core/locales/ar.json +1276 -0
  191. package/src/core/locales/en.json +1276 -0
  192. package/src/core/locales/index.ts +54 -0
  193. package/src/core/locales/sl.json +1276 -0
  194. package/src/core/tokens/native-tokens.json +369 -0
  195. package/tailwind-compile.cjs +29 -0
  196. package/tailwind-preset.cjs +1020 -0
  197. package/themes/_base.css +451 -0
  198. package/themes/_contract.md +307 -0
  199. package/themes/_fonts-kenney.css +11 -0
  200. package/themes/_fonts.css +12 -0
  201. package/themes/_foundation.css +105 -0
  202. package/themes/_head.css +22 -0
  203. package/themes/_presets.css +67 -0
  204. package/themes/almadar-heritage.css +455 -0
  205. package/themes/almadar-website.css +269 -0
  206. package/themes/almadar.css +269 -0
  207. package/themes/aqua.css +455 -0
  208. package/themes/arabesque.css +459 -0
  209. package/themes/art-deco.css +457 -0
  210. package/themes/art-nouveau.css +459 -0
  211. package/themes/atelier.css +463 -0
  212. package/themes/bauhaus.css +461 -0
  213. package/themes/bloomberg-dense.css +463 -0
  214. package/themes/blueprint.css +457 -0
  215. package/themes/clay.css +449 -0
  216. package/themes/comic.css +453 -0
  217. package/themes/constructivist.css +457 -0
  218. package/themes/corporate.css +449 -0
  219. package/themes/cyberpunk.css +453 -0
  220. package/themes/frutiger-aero.css +458 -0
  221. package/themes/game-adventure.css +201 -0
  222. package/themes/game-rpg.css +203 -0
  223. package/themes/game-sci-fi.css +201 -0
  224. package/themes/game-ui-pack.css +200 -0
  225. package/themes/gazette.css +449 -0
  226. package/themes/glass.css +457 -0
  227. package/themes/gothic.css +453 -0
  228. package/themes/index.css +21 -0
  229. package/themes/ink-wash.css +459 -0
  230. package/themes/kawaii.css +459 -0
  231. package/themes/kflow.css +310 -0
  232. package/themes/kiosk.css +449 -0
  233. package/themes/linear-clean.css +463 -0
  234. package/themes/luxury.css +451 -0
  235. package/themes/mac-classic.css +455 -0
  236. package/themes/material.css +463 -0
  237. package/themes/memphis.css +453 -0
  238. package/themes/mid-century.css +455 -0
  239. package/themes/minimalist.css +449 -0
  240. package/themes/mudcloth.css +459 -0
  241. package/themes/nata.css +310 -0
  242. package/themes/neon.css +453 -0
  243. package/themes/neumorphic.css +451 -0
  244. package/themes/newsprint.css +455 -0
  245. package/themes/notion-editorial.css +463 -0
  246. package/themes/orb.css +465 -0
  247. package/themes/pixel.css +449 -0
  248. package/themes/prism.css +309 -0
  249. package/themes/rawi.css +310 -0
  250. package/themes/retro.css +452 -0
  251. package/themes/risograph.css +463 -0
  252. package/themes/scandi.css +469 -0
  253. package/themes/sketch.css +455 -0
  254. package/themes/solarpunk.css +469 -0
  255. package/themes/steampunk.css +451 -0
  256. package/themes/swiss.css +455 -0
  257. package/themes/terminal.css +466 -0
  258. package/themes/trait-wars.css +487 -0
  259. package/themes/ukiyo-e.css +459 -0
  260. package/themes/vaporwave.css +455 -0
  261. package/themes/victorian.css +453 -0
  262. package/themes/wabi-sabi.css +459 -0
  263. package/themes/win95.css +455 -0
  264. package/themes/wireframe.css +439 -0
  265. package/themes/zine.css +455 -0
  266. package/README.md +0 -3
@@ -0,0 +1,490 @@
1
+ import { traitLevelFromMounted } from './chunk-PCR37T3U.js';
2
+ import { getStateRole } from './chunk-UXLE3IPR.js';
3
+ import { useState, useLayoutEffect } from 'react';
4
+
5
+ function useContainerWidth(ref) {
6
+ const [width, setWidth] = useState(null);
7
+ useLayoutEffect(() => {
8
+ const el = ref.current;
9
+ if (!el) return;
10
+ setWidth(el.clientWidth);
11
+ if (typeof ResizeObserver === "undefined") return;
12
+ const ro = new ResizeObserver(([entry]) => setWidth(entry.contentRect.width));
13
+ ro.observe(el);
14
+ return () => ro.disconnect();
15
+ }, [ref]);
16
+ return width;
17
+ }
18
+
19
+ // src/lib/avl-elk-layout.ts
20
+ function stateWidth(transitionCount) {
21
+ if (transitionCount >= 5) return 160;
22
+ if (transitionCount >= 3) return 130;
23
+ return 110;
24
+ }
25
+ var STATE_H = 40;
26
+ var elk;
27
+ function loadElk() {
28
+ elk ??= import('elkjs/lib/elk.bundled.js').then(({ default: Elk }) => new Elk());
29
+ return elk;
30
+ }
31
+ function flowOrder(data) {
32
+ const byName = new Map(data.states.map((s) => [s.name, s]));
33
+ const seen = /* @__PURE__ */ new Set();
34
+ const queue = data.states.filter((s) => s.isInitial).map((s) => s.name);
35
+ const out = [];
36
+ while (queue.length > 0) {
37
+ const name = queue.shift();
38
+ if (seen.has(name)) continue;
39
+ const state = byName.get(name);
40
+ if (!state) continue;
41
+ seen.add(name);
42
+ out.push(state);
43
+ for (const t of data.transitions) if (t.from === name && !seen.has(t.to)) queue.push(t.to);
44
+ }
45
+ for (const s of data.states) if (!seen.has(s.name)) out.push(s);
46
+ return out;
47
+ }
48
+ async function computeTraitLayout(data, metrics) {
49
+ const transitionCounts = {};
50
+ for (const s of data.states) transitionCounts[s.name] = 0;
51
+ for (const t of data.transitions) {
52
+ transitionCounts[t.from] = (transitionCounts[t.from] ?? 0) + 1;
53
+ transitionCounts[t.to] = (transitionCounts[t.to] ?? 0) + 1;
54
+ }
55
+ const maxTC = Math.max(...Object.values(transitionCounts), 0);
56
+ const LABEL_BASE_W = 100;
57
+ const LABEL_H = 44;
58
+ const states = metrics ? flowOrder(data) : data.states;
59
+ const elkGraph = {
60
+ id: "root",
61
+ layoutOptions: {
62
+ "elk.algorithm": "layered",
63
+ "elk.direction": metrics?.direction === "rtl" ? "LEFT" : "RIGHT",
64
+ "elk.spacing.nodeNode": String(metrics?.nodeSpacing ?? 80),
65
+ "elk.spacing.edgeNode": "30",
66
+ "elk.spacing.edgeEdge": "24",
67
+ "elk.spacing.edgeLabel": "10",
68
+ "elk.spacing.labelLabel": "8",
69
+ "elk.layered.spacing.nodeNodeBetweenLayers": String(metrics?.layerSpacing ?? 100),
70
+ ...metrics?.orthogonal ? { "elk.edgeRouting": "ORTHOGONAL" } : {},
71
+ ...metrics ? { "elk.layered.considerModelOrder.strategy": "NODES_AND_EDGES", "elk.layered.cycleBreaking.strategy": "MODEL_ORDER" } : {},
72
+ "elk.edgeLabels.placement": "CENTER",
73
+ "elk.layered.mergeEdges": "false",
74
+ "elk.layered.nodePlacement.strategy": "NETWORK_SIMPLEX"
75
+ },
76
+ children: states.map((s) => {
77
+ const tc = transitionCounts[s.name] ?? 0;
78
+ const size = metrics ? metrics.nodeSize(s.name) : { width: stateWidth(tc), height: STATE_H };
79
+ return {
80
+ id: s.name,
81
+ width: size.width,
82
+ height: size.height,
83
+ labels: [{ text: s.name, width: size.width - 10, height: 14 }],
84
+ ...metrics && s.isInitial ? { layoutOptions: { "elk.layered.layering.layerConstraint": "FIRST" } } : {}
85
+ };
86
+ }),
87
+ edges: data.transitions.map((t, i) => {
88
+ const textW = Math.max(t.event.length * 8, 60);
89
+ const iconsW = Math.min(t.effects.length, 6) * 28 + 20;
90
+ const label = metrics ? metrics.labelSize(t) : { width: Math.max(textW, iconsW, LABEL_BASE_W), height: LABEL_H };
91
+ return {
92
+ id: `e${i}`,
93
+ sources: [t.from],
94
+ targets: [t.to],
95
+ labels: [{
96
+ text: t.event,
97
+ width: label.width,
98
+ height: label.height,
99
+ ...metrics ? { layoutOptions: { "elk.edgeLabels.inline": "true" } } : {}
100
+ }]
101
+ };
102
+ })
103
+ };
104
+ const layout = await (await loadElk()).layout(elkGraph);
105
+ const layoutChildren = layout.children ?? [];
106
+ const layoutEdges = layout.edges ?? [];
107
+ const nodeXMap = {};
108
+ for (const n of layoutChildren) {
109
+ nodeXMap[n.id] = n.x ?? 0;
110
+ }
111
+ const nodes = layoutChildren.map((n) => {
112
+ const name = n.id;
113
+ const stateInfo = data.states.find((s) => s.name === name);
114
+ const tc = transitionCounts[name] ?? 0;
115
+ return {
116
+ id: name,
117
+ x: n.x ?? 0,
118
+ y: n.y ?? 0,
119
+ width: n.width ?? 110,
120
+ height: n.height ?? STATE_H,
121
+ isInitial: stateInfo?.isInitial ?? void 0,
122
+ isTerminal: stateInfo?.isTerminal ?? void 0,
123
+ role: getStateRole(stateInfo?.isInitial ?? void 0, stateInfo?.isTerminal ?? void 0, tc, maxTC),
124
+ transitionCount: tc
125
+ };
126
+ });
127
+ const edges = layoutEdges.map((e, i) => {
128
+ const t = data.transitions[i];
129
+ const labels = e.labels ?? [];
130
+ const label = labels[0];
131
+ const sections = e.sections ?? [];
132
+ const points = [];
133
+ for (const section of sections) {
134
+ const bendPoints = section.bendPoints ?? [];
135
+ points.push({ x: section.startPoint.x, y: section.startPoint.y });
136
+ for (const bp of bendPoints) points.push({ x: bp.x, y: bp.y });
137
+ points.push({ x: section.endPoint.x, y: section.endPoint.y });
138
+ }
139
+ const isSelf = t.from === t.to;
140
+ const toX = nodeXMap[t.to] ?? 0;
141
+ const fromX = nodeXMap[t.from] ?? 0;
142
+ const isBackward = !isSelf && (metrics?.direction === "rtl" ? toX >= fromX : toX <= fromX);
143
+ const lw = label?.width ?? LABEL_BASE_W;
144
+ const lh = label?.height ?? LABEL_H;
145
+ return {
146
+ id: e.id,
147
+ from: t.from,
148
+ to: t.to,
149
+ event: t.event,
150
+ effects: t.effects,
151
+ guard: !!t.guard,
152
+ guardExpr: typeof t.guard === "string" ? t.guard : void 0,
153
+ index: t.index,
154
+ labelX: label?.x ?? 0,
155
+ labelY: label?.y ?? 0,
156
+ labelW: lw,
157
+ labelH: lh,
158
+ points,
159
+ isSelf,
160
+ isBackward
161
+ };
162
+ });
163
+ return {
164
+ nodes,
165
+ edges,
166
+ width: layout.width ?? 600,
167
+ height: layout.height ?? 400
168
+ };
169
+ }
170
+ function roundedEdgePath(points, radius) {
171
+ if (points.length < 3) return edgePath(points);
172
+ let d = `M ${points[0].x},${points[0].y}`;
173
+ for (let i = 1; i < points.length - 1; i++) {
174
+ const prev = points[i - 1];
175
+ const cur = points[i];
176
+ const next = points[i + 1];
177
+ const inLen = Math.hypot(cur.x - prev.x, cur.y - prev.y);
178
+ const outLen = Math.hypot(next.x - cur.x, next.y - cur.y);
179
+ const r = Math.min(radius, inLen / 2, outLen / 2);
180
+ if (r <= 0) {
181
+ d += ` L ${cur.x},${cur.y}`;
182
+ continue;
183
+ }
184
+ const ax = cur.x - (cur.x - prev.x) / inLen * r;
185
+ const ay = cur.y - (cur.y - prev.y) / inLen * r;
186
+ const bx = cur.x + (next.x - cur.x) / outLen * r;
187
+ const by = cur.y + (next.y - cur.y) / outLen * r;
188
+ d += ` L ${ax},${ay} Q ${cur.x},${cur.y} ${bx},${by}`;
189
+ }
190
+ const last = points[points.length - 1];
191
+ return `${d} L ${last.x},${last.y}`;
192
+ }
193
+ function edgePath(points) {
194
+ if (points.length === 0) return "";
195
+ let d = `M ${points[0].x},${points[0].y}`;
196
+ for (let i = 1; i < points.length; i++) d += ` L ${points[i].x},${points[i].y}`;
197
+ return d;
198
+ }
199
+ var BOX_PAD = 16;
200
+ var BOX_HEAD_MACHINE = 46;
201
+ var BOX_HEAD_CONTAINER = 38;
202
+ var COLLAPSED_H = 56;
203
+ var CHIP_H = 28;
204
+ var HEAD_GLYPH = 40;
205
+ var HEAD_TOGGLE = 28;
206
+ var LOOP_FOLD = 3;
207
+ var LOOP_LINE = 18;
208
+ function loopKey(trait, state) {
209
+ return `${trait}\0${state}`;
210
+ }
211
+ var LANE_HEAD = 30;
212
+ var LANE_MARGIN = 36;
213
+ var LANE_MIN_WIDTH = 480;
214
+ var PACK_ASPECT = 1.6;
215
+ var PACK_GAP = 14;
216
+ function sectionPoints(e) {
217
+ const points = [];
218
+ for (const section of e.sections ?? []) {
219
+ points.push({ x: section.startPoint.x, y: section.startPoint.y });
220
+ for (const bp of section.bendPoints ?? []) points.push({ x: bp.x, y: bp.y });
221
+ points.push({ x: section.endPoint.x, y: section.endPoint.y });
222
+ }
223
+ return points;
224
+ }
225
+ function boxWirePath(a, b) {
226
+ const ax = a.x + a.width / 2;
227
+ const ay = a.y + a.height / 2;
228
+ const bx = b.x + b.width / 2;
229
+ const by = b.y + b.height / 2;
230
+ if (b.x >= a.x + a.width) return [{ x: a.x + a.width, y: ay }, { x: b.x, y: by }];
231
+ if (a.x >= b.x + b.width) return [{ x: a.x, y: ay }, { x: b.x + b.width, y: by }];
232
+ if (by >= ay) return [{ x: ax, y: a.y + a.height }, { x: bx, y: b.y }];
233
+ return [{ x: ax, y: a.y }, { x: bx, y: b.y + b.height }];
234
+ }
235
+ function boxKind(trait, expandDepth, open, closed) {
236
+ if (trait.states.length <= 1) return "chip";
237
+ if (open.has(trait.trait)) return "machine";
238
+ if (closed.has(trait.trait)) return "collapsed";
239
+ return trait.depth < expandDepth ? "machine" : "collapsed";
240
+ }
241
+ function compactSize(trait, kind, charWidth) {
242
+ if (kind === "chip") return { width: Math.round(trait.trait.length * charWidth + 28 + HEAD_GLYPH), height: CHIP_H };
243
+ const sub = (trait.linkedEntity ?? "").length;
244
+ return { width: Math.max(132, Math.round(Math.max(trait.trait.length, sub) * charWidth + 64 + HEAD_GLYPH + HEAD_TOGGLE)), height: COLLAPSED_H };
245
+ }
246
+ function packOptions(padding, targetWidth) {
247
+ return {
248
+ "elk.algorithm": "rectpacking",
249
+ "elk.aspectRatio": String(PACK_ASPECT),
250
+ "elk.rectpacking.orderBySize": "false",
251
+ "elk.spacing.nodeNode": String(PACK_GAP),
252
+ "elk.padding": padding,
253
+ ...targetWidth === void 0 ? {} : { "elk.rectpacking.widthApproximation.targetWidth": String(targetWidth) }
254
+ };
255
+ }
256
+ async function computeOrbitalLayout(orbital, options) {
257
+ const { metrics, expandDepth, charWidth } = options;
258
+ const byName = new Map(orbital.traits.map((t) => [t.trait, t]));
259
+ const levels = new Map(orbital.traits.map((t) => [t.trait, traitLevelFromMounted(t)]));
260
+ const lane = orbital.traits.filter((t) => !t.renders && !t.linked);
261
+ const tree = orbital.traits.filter((t) => t.renders && !t.linked);
262
+ const linkedByOrbital = /* @__PURE__ */ new Map();
263
+ for (const t of orbital.traits.filter((x) => x.linked)) {
264
+ const key = t.orbital ?? "";
265
+ linkedByOrbital.set(key, [...linkedByOrbital.get(key) ?? [], t]);
266
+ }
267
+ const effectiveParent = /* @__PURE__ */ new Map();
268
+ for (const t of tree) {
269
+ let cur = t.parent === null ? void 0 : byName.get(t.parent);
270
+ while (cur !== void 0 && !cur.renders) cur = cur.parent === null ? void 0 : byName.get(cur.parent);
271
+ effectiveParent.set(t.trait, cur === void 0 ? null : cur.trait);
272
+ }
273
+ const childrenOf = /* @__PURE__ */ new Map();
274
+ const roots = [];
275
+ for (const t of tree) {
276
+ const p = effectiveParent.get(t.trait) ?? null;
277
+ if (p === null) roots.push(t);
278
+ else childrenOf.set(p, [...childrenOf.get(p) ?? [], t]);
279
+ }
280
+ const open = options.open ?? /* @__PURE__ */ new Set();
281
+ const closed = options.closed ?? /* @__PURE__ */ new Set();
282
+ const openLoops = options.openLoops ?? /* @__PURE__ */ new Set();
283
+ const loops = [];
284
+ const kinds = new Map(orbital.traits.map((t) => [t.trait, boxKind(t, expandDepth, open, closed)]));
285
+ const wirePairs = /* @__PURE__ */ new Map();
286
+ for (const w of orbital.wires) {
287
+ if (!byName.has(w.from) || !byName.has(w.to)) continue;
288
+ const key = `${w.from}\u2192${w.to}`;
289
+ const entry = wirePairs.get(key) ?? { from: w.from, to: w.to, pairs: [] };
290
+ entry.pairs.push({ event: w.event, triggers: w.triggers });
291
+ wirePairs.set(key, entry);
292
+ }
293
+ const wireLabel = (pairs) => [...new Set(pairs.map((p) => p.event))].join(", ");
294
+ const boxNode = (t) => {
295
+ const kind = kinds.get(t.trait) ?? "chip";
296
+ const kids = childrenOf.get(t.trait) ?? [];
297
+ const level = levels.get(t.trait);
298
+ const titleWidth = Math.round(Math.max(t.trait.length, (t.linkedEntity ?? "").length) * charWidth + 32 + HEAD_GLYPH + (kind === "chip" ? 0 : HEAD_TOGGLE));
299
+ if (kind !== "machine" && kids.length === 0) {
300
+ const size = compactSize(t, kind, charWidth);
301
+ return { id: `b:${t.trait}`, width: size.width, height: size.height };
302
+ }
303
+ const head = kind === "machine" ? BOX_HEAD_MACHINE : BOX_HEAD_CONTAINER;
304
+ const padding = `[top=${head},left=${BOX_PAD},bottom=${BOX_PAD},right=${BOX_PAD}]`;
305
+ const minimum = { "elk.nodeSize.constraints": "MINIMUM_SIZE", "elk.nodeSize.minimum": `(${titleWidth}, ${head + 20})` };
306
+ const kidNodes = kids.map(boxNode);
307
+ if (kind !== "machine" || level === void 0) {
308
+ return { id: `b:${t.trait}`, children: kidNodes, layoutOptions: { ...packOptions(padding), ...minimum } };
309
+ }
310
+ const selfCount = /* @__PURE__ */ new Map();
311
+ for (const tr of level.transitions) if (tr.from === tr.to) selfCount.set(tr.from, (selfCount.get(tr.from) ?? 0) + 1);
312
+ const folds = (tr) => tr.from === tr.to && (selfCount.get(tr.from) ?? 0) >= LOOP_FOLD;
313
+ for (const [state, count] of selfCount) {
314
+ if (count < LOOP_FOLD) continue;
315
+ loops.push({
316
+ trait: t.trait,
317
+ state,
318
+ events: level.transitions.filter((tr) => tr.from === state && tr.to === state).map((tr) => ({ event: tr.event, index: tr.index })),
319
+ open: openLoops.has(loopKey(t.trait, state))
320
+ });
321
+ }
322
+ const stateNodes = flowOrder(level).map((s) => {
323
+ const size = metrics.nodeSize(s.name);
324
+ const count = (selfCount.get(s.name) ?? 0) >= LOOP_FOLD ? selfCount.get(s.name) ?? 0 : 0;
325
+ const extra = count === 0 ? 0 : openLoops.has(loopKey(t.trait, s.name)) ? LOOP_LINE * (count + 1) + 8 : LOOP_LINE;
326
+ const longest = count === 0 ? 0 : Math.max(...level.transitions.filter((tr) => tr.from === s.name && tr.to === s.name).map((tr) => tr.event.length));
327
+ return {
328
+ id: `s:${t.trait}:${s.name}`,
329
+ width: Math.max(size.width, extra > LOOP_LINE ? Math.round(longest * charWidth + 40) : size.width),
330
+ height: size.height + extra,
331
+ layoutOptions: { "elk.partitioning.partition": "0", ...s.isInitial ? { "elk.layered.layering.layerConstraint": "FIRST" } : {} }
332
+ };
333
+ });
334
+ const group = kidNodes.length === 0 ? [] : [{
335
+ id: `k:${t.trait}`,
336
+ children: kidNodes,
337
+ layoutOptions: { ...packOptions("[top=0,left=0,bottom=0,right=0]"), "elk.partitioning.partition": "1" }
338
+ }];
339
+ return {
340
+ id: `b:${t.trait}`,
341
+ children: [...stateNodes, ...group],
342
+ edges: level.transitions.flatMap((tr, i) => {
343
+ if (folds(tr)) return [];
344
+ const size = metrics.labelSize(tr);
345
+ return [{
346
+ id: `x:${t.trait}:${i}`,
347
+ sources: [`s:${t.trait}:${tr.from}`],
348
+ targets: [`s:${t.trait}:${tr.to}`],
349
+ labels: [{ text: tr.event, width: size.width, height: size.height, layoutOptions: { "elk.edgeLabels.inline": "true" } }]
350
+ }];
351
+ }),
352
+ layoutOptions: {
353
+ "elk.algorithm": "layered",
354
+ "elk.direction": metrics.direction === "rtl" ? "LEFT" : "RIGHT",
355
+ "elk.padding": padding,
356
+ "elk.partitioning.activate": "true",
357
+ "elk.spacing.nodeNode": String(metrics.nodeSpacing),
358
+ "elk.spacing.edgeNode": "30",
359
+ "elk.spacing.edgeEdge": "24",
360
+ "elk.spacing.edgeLabel": "10",
361
+ "elk.layered.spacing.nodeNodeBetweenLayers": String(metrics.layerSpacing),
362
+ "elk.edgeRouting": "ORTHOGONAL",
363
+ "elk.layered.considerModelOrder.strategy": "NODES_AND_EDGES",
364
+ "elk.layered.cycleBreaking.strategy": "MODEL_ORDER",
365
+ "elk.edgeLabels.placement": "CENTER",
366
+ "elk.layered.mergeEdges": "false",
367
+ "elk.layered.nodePlacement.strategy": "NETWORK_SIMPLEX",
368
+ ...minimum
369
+ }
370
+ };
371
+ };
372
+ const graph = {
373
+ id: "root",
374
+ layoutOptions: { ...packOptions("[top=0,left=0,bottom=0,right=0]"), "elk.hierarchyHandling": "SEPARATE_CHILDREN" },
375
+ children: roots.map(boxNode)
376
+ };
377
+ const elkEngine = await loadElk();
378
+ const result = roots.length === 0 ? { width: 0, height: 0 } : await elkEngine.layout(graph);
379
+ const boxes = [];
380
+ const groups = [];
381
+ const states = [];
382
+ const transitionEdges = [];
383
+ const walk = (node, ox, oy, parent) => {
384
+ for (const e of node.edges ?? []) {
385
+ const [, ...rest] = e.id.split(":");
386
+ const index = Number(rest[rest.length - 1]);
387
+ const trait = rest.slice(0, -1).join(":");
388
+ const tr = levels.get(trait)?.transitions[index];
389
+ if (tr === void 0) continue;
390
+ const label = (e.labels ?? [])[0];
391
+ transitionEdges.push({
392
+ id: e.id,
393
+ trait,
394
+ index: tr.index,
395
+ from: tr.from,
396
+ to: tr.to,
397
+ event: tr.event,
398
+ points: sectionPoints(e).map((p) => ({ x: p.x + ox, y: p.y + oy })),
399
+ labelX: (label?.x ?? 0) + ox,
400
+ labelY: (label?.y ?? 0) + oy,
401
+ labelW: label?.width ?? 0,
402
+ labelH: label?.height ?? 0,
403
+ isSelf: tr.from === tr.to
404
+ });
405
+ }
406
+ for (const c of node.children ?? []) {
407
+ const x = ox + (c.x ?? 0);
408
+ const y = oy + (c.y ?? 0);
409
+ if (c.id.startsWith("b:")) {
410
+ const name = c.id.slice(2);
411
+ boxes.push({ trait: name, kind: kinds.get(name) ?? "chip", lane: false, parent, container: (childrenOf.get(name) ?? []).length > 0, x, y, width: c.width ?? 0, height: c.height ?? 0 });
412
+ walk(c, x, y, name);
413
+ } else if (c.id.startsWith("g:")) {
414
+ groups.push({ orbital: c.id.slice(2), x, y, width: c.width ?? 0, height: c.height ?? 0 });
415
+ walk(c, x, y, null);
416
+ } else if (c.id.startsWith("k:")) {
417
+ walk(c, x, y, parent);
418
+ } else if (c.id.startsWith("s:")) {
419
+ const [, trait, ...rest] = c.id.split(":");
420
+ const name = rest.join(":");
421
+ const info = byName.get(trait)?.states.find((s) => s.name === name);
422
+ states.push({ trait, name, isInitial: info?.isInitial ?? false, isTerminal: info?.isTerminal ?? false, x, y, width: c.width ?? 0, height: c.height ?? 0 });
423
+ }
424
+ }
425
+ };
426
+ walk(result, 0, 0, null);
427
+ let width = result.width ?? 0;
428
+ let height = result.height ?? 0;
429
+ let laneTop = null;
430
+ if (lane.length > 0) {
431
+ laneTop = height + LANE_MARGIN;
432
+ const laneWidth = Math.max(width, LANE_MIN_WIDTH);
433
+ const chipSize = new Map(lane.map((t) => [t.trait, compactSize(t, kinds.get(t.trait) === "chip" ? "chip" : "collapsed", charWidth)]));
434
+ const packed = await elkEngine.layout({
435
+ id: "lane",
436
+ layoutOptions: packOptions("[top=0,left=0,bottom=0,right=0]", laneWidth),
437
+ children: lane.map((t) => ({ id: `b:${t.trait}`, width: chipSize.get(t.trait)?.width ?? 0, height: chipSize.get(t.trait)?.height ?? 0 }))
438
+ });
439
+ for (const c of packed.children ?? []) {
440
+ const name = c.id.slice(2);
441
+ boxes.push({ trait: name, kind: kinds.get(name) === "chip" ? "chip" : "collapsed", lane: true, parent: null, container: false, x: c.x ?? 0, y: laneTop + LANE_HEAD + (c.y ?? 0), width: c.width ?? 0, height: c.height ?? 0 });
442
+ }
443
+ width = Math.max(width, packed.width ?? 0);
444
+ height = laneTop + LANE_HEAD + (packed.height ?? 0);
445
+ }
446
+ let groupTop = null;
447
+ if (linkedByOrbital.size > 0) {
448
+ groupTop = height + LANE_MARGIN;
449
+ const padding = `[top=${BOX_HEAD_CONTAINER},left=${BOX_PAD},bottom=${BOX_PAD},right=${BOX_PAD}]`;
450
+ const packed = await elkEngine.layout({
451
+ id: "groups",
452
+ layoutOptions: { ...packOptions("[top=0,left=0,bottom=0,right=0]", Math.max(width, LANE_MIN_WIDTH)), "elk.hierarchyHandling": "SEPARATE_CHILDREN" },
453
+ children: [...linkedByOrbital].map(([name, traits]) => ({
454
+ id: `g:${name}`,
455
+ children: traits.map(boxNode),
456
+ layoutOptions: {
457
+ ...packOptions(padding),
458
+ "elk.nodeSize.constraints": "MINIMUM_SIZE",
459
+ "elk.nodeSize.minimum": `(${Math.round(name.length * charWidth + 32 + HEAD_GLYPH)}, ${BOX_HEAD_CONTAINER + 20})`
460
+ }
461
+ }))
462
+ });
463
+ walk(packed, 0, groupTop + LANE_HEAD, null);
464
+ width = Math.max(width, packed.width ?? 0);
465
+ height = groupTop + LANE_HEAD + (packed.height ?? 0);
466
+ }
467
+ const embeds = [];
468
+ for (const t of tree) {
469
+ const parent = effectiveParent.get(t.trait) ?? null;
470
+ const child = boxes.find((b) => b.trait === t.trait);
471
+ if (parent === null || child === void 0) continue;
472
+ for (const state of t.embeddedIn) {
473
+ const node = states.find((s) => s.trait === parent && s.name === state);
474
+ if (node !== void 0) embeds.push({ trait: t.trait, state, points: boxWirePath(node, child) });
475
+ }
476
+ }
477
+ const wires = [];
478
+ for (const [key, w] of wirePairs) {
479
+ const a = boxes.find((b2) => b2.trait === w.from);
480
+ const b = boxes.find((x) => x.trait === w.to);
481
+ if (a === void 0 || b === void 0) continue;
482
+ const points = boxWirePath(a, b);
483
+ const size = options.wireLabelSize(wireLabel(w.pairs));
484
+ const mid = { x: (points[0].x + points[1].x) / 2, y: (points[0].y + points[1].y) / 2 };
485
+ wires.push({ key, from: w.from, to: w.to, pairs: w.pairs, points, labelX: mid.x - size.width / 2, labelY: mid.y - size.height / 2, labelW: size.width, labelH: size.height });
486
+ }
487
+ return { boxes, loops, groups, groupTop, states, edges: transitionEdges, embeds, wires, laneTop, width, height };
488
+ }
489
+
490
+ export { LOOP_LINE, computeOrbitalLayout, computeTraitLayout, edgePath, loopKey, roundedEdgePath, useContainerWidth };
@@ -0,0 +1,82 @@
1
+ // src/lib/jazari/svg-paths.ts
2
+ function gearTeethPath(cx, cy, innerRadius, outerRadius, numTeeth) {
3
+ const parts = [];
4
+ const angleStep = Math.PI * 2 / numTeeth;
5
+ const halfTooth = angleStep * 0.25;
6
+ for (let i = 0; i < numTeeth; i++) {
7
+ const baseAngle = i * angleStep;
8
+ const x0 = cx + innerRadius * Math.cos(baseAngle - halfTooth);
9
+ const y0 = cy + innerRadius * Math.sin(baseAngle - halfTooth);
10
+ const x1 = cx + outerRadius * Math.cos(baseAngle - halfTooth * 0.4);
11
+ const y1 = cy + outerRadius * Math.sin(baseAngle - halfTooth * 0.4);
12
+ const x2 = cx + outerRadius * Math.cos(baseAngle + halfTooth * 0.4);
13
+ const y2 = cy + outerRadius * Math.sin(baseAngle + halfTooth * 0.4);
14
+ const x3 = cx + innerRadius * Math.cos(baseAngle + halfTooth);
15
+ const y3 = cy + innerRadius * Math.sin(baseAngle + halfTooth);
16
+ if (i === 0) {
17
+ parts.push(`M ${x0.toFixed(1)} ${y0.toFixed(1)}`);
18
+ } else {
19
+ parts.push(`L ${x0.toFixed(1)} ${y0.toFixed(1)}`);
20
+ }
21
+ parts.push(`L ${x1.toFixed(1)} ${y1.toFixed(1)}`);
22
+ parts.push(`L ${x2.toFixed(1)} ${y2.toFixed(1)}`);
23
+ parts.push(`L ${x3.toFixed(1)} ${y3.toFixed(1)}`);
24
+ }
25
+ parts.push("Z");
26
+ return parts.join(" ");
27
+ }
28
+ function lockIconPath(cx, cy, size) {
29
+ const bodyW = size * 0.7;
30
+ const bodyH = size * 0.5;
31
+ const bodyX = cx - bodyW / 2;
32
+ const bodyY = cy - bodyH / 4;
33
+ const body = `M ${bodyX.toFixed(1)} ${bodyY.toFixed(1)} h ${bodyW.toFixed(1)} v ${bodyH.toFixed(1)} h ${(-bodyW).toFixed(1)} Z`;
34
+ const shR = size * 0.28;
35
+ const shY = bodyY;
36
+ const shackle = `M ${(cx - shR).toFixed(1)} ${shY.toFixed(1)} A ${shR.toFixed(1)} ${(shR * 1.2).toFixed(1)} 0 1 1 ${(cx + shR).toFixed(1)} ${shY.toFixed(1)}`;
37
+ const kR = size * 0.08;
38
+ const kY = bodyY + bodyH * 0.35;
39
+ const keyhole = `M ${cx.toFixed(1)} ${(kY - kR).toFixed(1)} a ${kR.toFixed(1)} ${kR.toFixed(1)} 0 1 1 0 ${(kR * 2).toFixed(1)} a ${kR.toFixed(1)} ${kR.toFixed(1)} 0 1 1 0 ${(-kR * 2).toFixed(1)} Z`;
40
+ return `${body} ${shackle} ${keyhole}`;
41
+ }
42
+ function brainIconPath(cx, cy, size) {
43
+ const s = size / 2;
44
+ return [
45
+ `M ${cx.toFixed(1)} ${(cy - s).toFixed(1)}`,
46
+ `C ${(cx - s * 1.2).toFixed(1)} ${(cy - s).toFixed(1)}, ${(cx - s * 1.3).toFixed(1)} ${(cy + s * 0.3).toFixed(1)}, ${cx.toFixed(1)} ${(cy + s).toFixed(1)}`,
47
+ `C ${(cx + s * 1.3).toFixed(1)} ${(cy + s * 0.3).toFixed(1)}, ${(cx + s * 1.2).toFixed(1)} ${(cy - s).toFixed(1)}, ${cx.toFixed(1)} ${(cy - s).toFixed(1)}`,
48
+ "Z",
49
+ // Dividing line
50
+ `M ${cx.toFixed(1)} ${(cy - s * 0.8).toFixed(1)}`,
51
+ `C ${(cx - s * 0.2).toFixed(1)} ${(cy - s * 0.2).toFixed(1)}, ${(cx + s * 0.2).toFixed(1)} ${(cy + s * 0.2).toFixed(1)}, ${cx.toFixed(1)} ${(cy + s * 0.8).toFixed(1)}`
52
+ ].join(" ");
53
+ }
54
+ function pipeIconPath(cx, cy, size) {
55
+ const w = size * 0.6;
56
+ const h = size * 0.3;
57
+ const flangeW = size * 0.8;
58
+ const flangeH = size * 0.1;
59
+ const tube = `M ${(cx - w / 2).toFixed(1)} ${(cy - h / 2).toFixed(1)} h ${w.toFixed(1)} v ${h.toFixed(1)} h ${(-w).toFixed(1)} Z`;
60
+ const lf = `M ${(cx - flangeW / 2).toFixed(1)} ${(cy - h / 2 - flangeH).toFixed(1)} h ${flangeH.toFixed(1)} v ${(h + flangeH * 2).toFixed(1)} h ${(-flangeH).toFixed(1)} Z`;
61
+ const rf = `M ${(cx + flangeW / 2 - flangeH).toFixed(1)} ${(cy - h / 2 - flangeH).toFixed(1)} h ${flangeH.toFixed(1)} v ${(h + flangeH * 2).toFixed(1)} h ${(-flangeH).toFixed(1)} Z`;
62
+ return `${tube} ${lf} ${rf}`;
63
+ }
64
+ function eightPointedStarPath(cx, cy, outerR, innerR) {
65
+ const points = [];
66
+ const numPoints = 8;
67
+ const angleStep = Math.PI / numPoints;
68
+ for (let i = 0; i < numPoints * 2; i++) {
69
+ const angle = i * angleStep - Math.PI / 2;
70
+ const r = i % 2 === 0 ? outerR : innerR;
71
+ const x = cx + r * Math.cos(angle);
72
+ const y = cy + r * Math.sin(angle);
73
+ points.push(`${i === 0 ? "M" : "L"} ${x.toFixed(1)} ${y.toFixed(1)}`);
74
+ }
75
+ points.push("Z");
76
+ return points.join(" ");
77
+ }
78
+ function arrowheadPath(size) {
79
+ return `M 0 0 L ${size} ${size / 2} L 0 ${size} Z`;
80
+ }
81
+
82
+ export { arrowheadPath, brainIconPath, eightPointedStarPath, gearTeethPath, lockIconPath, pipeIconPath };
@@ -0,0 +1,14 @@
1
+ import { ThemeProvider, useTheme } from './chunk-4YXBKHHM.js';
2
+
3
+ // src/providers/DesignThemeContext.tsx
4
+ var DesignThemeProvider = ThemeProvider;
5
+ function useDesignTheme() {
6
+ const { theme, setTheme, availableThemes } = useTheme();
7
+ return {
8
+ designTheme: theme,
9
+ setDesignTheme: setTheme,
10
+ availableThemes: availableThemes.map((t) => t.name)
11
+ };
12
+ }
13
+
14
+ export { DesignThemeProvider, useDesignTheme };