@almadar/ui 2.20.0 → 2.20.6

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 (41) hide show
  1. package/LICENSE +72 -21
  2. package/dist/avl/index.cjs +1437 -1328
  3. package/dist/avl/index.d.cts +51 -47
  4. package/dist/avl/index.js +1408 -1299
  5. package/dist/components/atoms/avl/Avl3DLabel.d.ts +23 -0
  6. package/dist/components/atoms/avl/Avl3DTooltip.d.ts +25 -0
  7. package/dist/components/atoms/avl/index.d.ts +2 -0
  8. package/dist/components/index.cjs +3 -1
  9. package/dist/components/index.js +3 -1
  10. package/dist/components/molecules/avl/Avl3DCrossWire.d.ts +22 -0
  11. package/dist/components/molecules/avl/Avl3DEntityCore.d.ts +26 -0
  12. package/dist/components/molecules/avl/Avl3DExprTree.d.ts +21 -0
  13. package/dist/components/molecules/avl/Avl3DOrbitalNode.d.ts +29 -0
  14. package/dist/components/molecules/avl/Avl3DStateNode.d.ts +34 -0
  15. package/dist/components/molecules/avl/Avl3DTransitionArc.d.ts +38 -0
  16. package/dist/components/molecules/avl/index.d.ts +6 -0
  17. package/dist/components/organisms/avl/Avl3DApplicationScene.d.ts +19 -0
  18. package/dist/components/organisms/avl/Avl3DEffects.d.ts +18 -0
  19. package/dist/components/organisms/avl/Avl3DOrbitalScene.d.ts +23 -0
  20. package/dist/components/organisms/avl/Avl3DTraitScene.d.ts +19 -0
  21. package/dist/components/organisms/avl/Avl3DTransitionScene.d.ts +17 -0
  22. package/dist/components/organisms/avl/Avl3DViewer.d.ts +40 -0
  23. package/dist/components/organisms/avl/AvlOrbitalScene.d.ts +4 -0
  24. package/dist/components/organisms/avl/avl-3d-context.d.ts +32 -0
  25. package/dist/components/organisms/avl/avl-3d-layout.d.ts +116 -0
  26. package/dist/components/organisms/avl/avl-zoom-state.d.ts +3 -0
  27. package/dist/components/organisms/game/three/index.cjs +2549 -120
  28. package/dist/components/organisms/game/three/index.d.ts +8 -0
  29. package/dist/components/organisms/game/three/index.js +2419 -5
  30. package/dist/illustrations/index.cjs +2880 -109
  31. package/dist/illustrations/index.js +2879 -108
  32. package/dist/providers/OrbitalProvider.d.ts +4 -2
  33. package/dist/providers/index.cjs +263 -284
  34. package/dist/providers/index.js +189 -210
  35. package/dist/runtime/OrbPreview.d.ts +9 -6
  36. package/dist/runtime/ServerBridge.d.ts +23 -0
  37. package/dist/runtime/enrichFromResponse.d.ts +21 -0
  38. package/dist/runtime/index.cjs +31754 -2587
  39. package/dist/runtime/index.d.ts +2 -0
  40. package/dist/runtime/index.js +31735 -2571
  41. package/package.json +5 -2
@@ -1,12 +1,15 @@
1
1
  'use strict';
2
2
 
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
- var React6 = require('react');
4
+ var React8 = require('react');
5
+ require('@react-three/drei');
6
+ require('@react-three/fiber');
7
+ require('three');
5
8
  var ELK = require('elkjs/lib/elk.bundled.js');
6
9
 
7
10
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
8
11
 
9
- var React6__default = /*#__PURE__*/_interopDefault(React6);
12
+ var React8__default = /*#__PURE__*/_interopDefault(React8);
10
13
  var ELK__default = /*#__PURE__*/_interopDefault(ELK);
11
14
 
12
15
  // components/atoms/avl/types.ts
@@ -381,7 +384,7 @@ var AvlTransition = ({
381
384
  opacity = 1,
382
385
  className
383
386
  }) => {
384
- const ids = React6__default.default.useMemo(() => {
387
+ const ids = React8__default.default.useMemo(() => {
385
388
  avlTransitionId += 1;
386
389
  return { arrow: `avl-tr-${avlTransitionId}-arrow` };
387
390
  }, []);
@@ -1055,1024 +1058,183 @@ var AvlBindingRef = ({
1055
1058
  };
1056
1059
  AvlBindingRef.displayName = "AvlBindingRef";
1057
1060
 
1058
- // components/molecules/avl/avl-layout.ts
1059
- function ringPositions(cx, cy, r2, count, startAngle = -Math.PI / 2) {
1060
- if (count === 0) return [];
1061
- if (count === 1) {
1062
- return [{ x: cx, y: cy, angle: 0 }];
1061
+ // node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs
1062
+ function r(e) {
1063
+ var t, f, n = "";
1064
+ if ("string" == typeof e || "number" == typeof e) n += e;
1065
+ else if ("object" == typeof e) if (Array.isArray(e)) {
1066
+ var o = e.length;
1067
+ for (t = 0; t < o; t++) e[t] && (f = r(e[t])) && (n && (n += " "), n += f);
1068
+ } else for (f in e) e[f] && (n && (n += " "), n += f);
1069
+ return n;
1070
+ }
1071
+ function clsx() {
1072
+ for (var e, t, f = 0, n = "", o = arguments.length; f < o; f++) (e = arguments[f]) && (t = r(e)) && (n && (n += " "), n += t);
1073
+ return n;
1074
+ }
1075
+
1076
+ // node_modules/.pnpm/tailwind-merge@2.6.1/node_modules/tailwind-merge/dist/bundle-mjs.mjs
1077
+ var CLASS_PART_SEPARATOR = "-";
1078
+ var createClassGroupUtils = (config) => {
1079
+ const classMap = createClassMap(config);
1080
+ const {
1081
+ conflictingClassGroups,
1082
+ conflictingClassGroupModifiers
1083
+ } = config;
1084
+ const getClassGroupId = (className) => {
1085
+ const classParts = className.split(CLASS_PART_SEPARATOR);
1086
+ if (classParts[0] === "" && classParts.length !== 1) {
1087
+ classParts.shift();
1088
+ }
1089
+ return getGroupRecursive(classParts, classMap) || getGroupIdForArbitraryProperty(className);
1090
+ };
1091
+ const getConflictingClassGroupIds = (classGroupId, hasPostfixModifier) => {
1092
+ const conflicts = conflictingClassGroups[classGroupId] || [];
1093
+ if (hasPostfixModifier && conflictingClassGroupModifiers[classGroupId]) {
1094
+ return [...conflicts, ...conflictingClassGroupModifiers[classGroupId]];
1095
+ }
1096
+ return conflicts;
1097
+ };
1098
+ return {
1099
+ getClassGroupId,
1100
+ getConflictingClassGroupIds
1101
+ };
1102
+ };
1103
+ var getGroupRecursive = (classParts, classPartObject) => {
1104
+ if (classParts.length === 0) {
1105
+ return classPartObject.classGroupId;
1063
1106
  }
1064
- if (count === 2) {
1065
- return [
1066
- { x: cx - r2 * 0.7, y: cy, angle: Math.PI },
1067
- { x: cx + r2 * 0.7, y: cy, angle: 0 }
1068
- ];
1107
+ const currentClassPart = classParts[0];
1108
+ const nextClassPartObject = classPartObject.nextPart.get(currentClassPart);
1109
+ const classGroupFromNextClassPart = nextClassPartObject ? getGroupRecursive(classParts.slice(1), nextClassPartObject) : void 0;
1110
+ if (classGroupFromNextClassPart) {
1111
+ return classGroupFromNextClassPart;
1069
1112
  }
1070
- return Array.from({ length: count }, (_, i) => {
1071
- const angle = startAngle + Math.PI * 2 * i / count;
1072
- return {
1073
- x: cx + r2 * Math.cos(angle),
1074
- y: cy + r2 * Math.sin(angle),
1075
- angle
1076
- };
1113
+ if (classPartObject.validators.length === 0) {
1114
+ return void 0;
1115
+ }
1116
+ const classRest = classParts.join(CLASS_PART_SEPARATOR);
1117
+ return classPartObject.validators.find(({
1118
+ validator
1119
+ }) => validator(classRest))?.classGroupId;
1120
+ };
1121
+ var arbitraryPropertyRegex = /^\[(.+)\]$/;
1122
+ var getGroupIdForArbitraryProperty = (className) => {
1123
+ if (arbitraryPropertyRegex.test(className)) {
1124
+ const arbitraryPropertyClassName = arbitraryPropertyRegex.exec(className)[1];
1125
+ const property = arbitraryPropertyClassName?.substring(0, arbitraryPropertyClassName.indexOf(":"));
1126
+ if (property) {
1127
+ return "arbitrary.." + property;
1128
+ }
1129
+ }
1130
+ };
1131
+ var createClassMap = (config) => {
1132
+ const {
1133
+ theme,
1134
+ prefix
1135
+ } = config;
1136
+ const classMap = {
1137
+ nextPart: /* @__PURE__ */ new Map(),
1138
+ validators: []
1139
+ };
1140
+ const prefixedClassGroupEntries = getPrefixedClassGroupEntries(Object.entries(config.classGroups), prefix);
1141
+ prefixedClassGroupEntries.forEach(([classGroupId, classGroup]) => {
1142
+ processClassesRecursively(classGroup, classMap, classGroupId, theme);
1077
1143
  });
1078
- }
1079
- function arcPath(cx, cy, r2, startAngle, endAngle) {
1080
- const x1 = cx + r2 * Math.cos(startAngle);
1081
- const y1 = cy + r2 * Math.sin(startAngle);
1082
- const x2 = cx + r2 * Math.cos(endAngle);
1083
- const y2 = cy + r2 * Math.sin(endAngle);
1084
- const largeArc = endAngle - startAngle > Math.PI ? 1 : 0;
1085
- return `M${x1},${y1} A${r2},${r2} 0 ${largeArc},1 ${x2},${y2}`;
1086
- }
1087
- function radialPositions(cx, cy, innerR, outerR, count, startAngle = -Math.PI / 2) {
1088
- return Array.from({ length: count }, (_, i) => {
1089
- const angle = startAngle + Math.PI * 2 * i / count;
1090
- return {
1091
- x1: cx + innerR * Math.cos(angle),
1092
- y1: cy + innerR * Math.sin(angle),
1093
- x2: cx + outerR * Math.cos(angle),
1094
- y2: cy + outerR * Math.sin(angle),
1095
- angle
1096
- };
1144
+ return classMap;
1145
+ };
1146
+ var processClassesRecursively = (classGroup, classPartObject, classGroupId, theme) => {
1147
+ classGroup.forEach((classDefinition) => {
1148
+ if (typeof classDefinition === "string") {
1149
+ const classPartObjectToEdit = classDefinition === "" ? classPartObject : getPart(classPartObject, classDefinition);
1150
+ classPartObjectToEdit.classGroupId = classGroupId;
1151
+ return;
1152
+ }
1153
+ if (typeof classDefinition === "function") {
1154
+ if (isThemeGetter(classDefinition)) {
1155
+ processClassesRecursively(classDefinition(theme), classPartObject, classGroupId, theme);
1156
+ return;
1157
+ }
1158
+ classPartObject.validators.push({
1159
+ validator: classDefinition,
1160
+ classGroupId
1161
+ });
1162
+ return;
1163
+ }
1164
+ Object.entries(classDefinition).forEach(([key, classGroup2]) => {
1165
+ processClassesRecursively(classGroup2, getPart(classPartObject, key), classGroupId, theme);
1166
+ });
1097
1167
  });
1098
- }
1099
- function gridPositions(startX, startY, cols, cellWidth, cellHeight, count) {
1100
- return Array.from({ length: count }, (_, i) => {
1101
- const col = i % cols;
1102
- const row = Math.floor(i / cols);
1168
+ };
1169
+ var getPart = (classPartObject, path) => {
1170
+ let currentClassPartObject = classPartObject;
1171
+ path.split(CLASS_PART_SEPARATOR).forEach((pathPart) => {
1172
+ if (!currentClassPartObject.nextPart.has(pathPart)) {
1173
+ currentClassPartObject.nextPart.set(pathPart, {
1174
+ nextPart: /* @__PURE__ */ new Map(),
1175
+ validators: []
1176
+ });
1177
+ }
1178
+ currentClassPartObject = currentClassPartObject.nextPart.get(pathPart);
1179
+ });
1180
+ return currentClassPartObject;
1181
+ };
1182
+ var isThemeGetter = (func) => func.isThemeGetter;
1183
+ var getPrefixedClassGroupEntries = (classGroupEntries, prefix) => {
1184
+ if (!prefix) {
1185
+ return classGroupEntries;
1186
+ }
1187
+ return classGroupEntries.map(([classGroupId, classGroup]) => {
1188
+ const prefixedClassGroup = classGroup.map((classDefinition) => {
1189
+ if (typeof classDefinition === "string") {
1190
+ return prefix + classDefinition;
1191
+ }
1192
+ if (typeof classDefinition === "object") {
1193
+ return Object.fromEntries(Object.entries(classDefinition).map(([key, value]) => [prefix + key, value]));
1194
+ }
1195
+ return classDefinition;
1196
+ });
1197
+ return [classGroupId, prefixedClassGroup];
1198
+ });
1199
+ };
1200
+ var createLruCache = (maxCacheSize) => {
1201
+ if (maxCacheSize < 1) {
1103
1202
  return {
1104
- x: startX + col * cellWidth,
1105
- y: startY + row * cellHeight,
1106
- col,
1107
- row
1203
+ get: () => void 0,
1204
+ set: () => {
1205
+ }
1108
1206
  };
1109
- });
1110
- }
1111
- function curveControlPoint(x1, y1, x2, y2, offset) {
1112
- const mx = (x1 + x2) / 2;
1113
- const my = (y1 + y2) / 2;
1114
- const dx = x2 - x1;
1115
- const dy = y2 - y1;
1116
- const len = Math.sqrt(dx * dx + dy * dy) || 1;
1207
+ }
1208
+ let cacheSize = 0;
1209
+ let cache = /* @__PURE__ */ new Map();
1210
+ let previousCache = /* @__PURE__ */ new Map();
1211
+ const update = (key, value) => {
1212
+ cache.set(key, value);
1213
+ cacheSize++;
1214
+ if (cacheSize > maxCacheSize) {
1215
+ cacheSize = 0;
1216
+ previousCache = cache;
1217
+ cache = /* @__PURE__ */ new Map();
1218
+ }
1219
+ };
1117
1220
  return {
1118
- cpx: mx + -dy / len * offset,
1119
- cpy: my + dx / len * offset
1120
- };
1121
- }
1122
- var avlSmId = 0;
1123
- var AvlStateMachine = ({
1124
- states,
1125
- transitions,
1126
- className,
1127
- color = "var(--color-primary)",
1128
- animated = false
1129
- }) => {
1130
- const ids = React6__default.default.useMemo(() => {
1131
- avlSmId += 1;
1132
- const base = `avl-sm-${avlSmId}`;
1133
- return { glow: `${base}-glow`, grad: `${base}-grad` };
1134
- }, []);
1135
- const cx = 300;
1136
- const cy = 200;
1137
- const r2 = 150;
1138
- const stateWidth = 90;
1139
- const stateHeight = 36;
1140
- const positions = ringPositions(cx, cy, r2, states.length);
1141
- const stateIndex = new Map(states.map((s, i) => [s.name, i]));
1142
- const pairCount = /* @__PURE__ */ new Map();
1143
- const pairSeen = /* @__PURE__ */ new Map();
1144
- for (const tr of transitions) {
1145
- const key = [tr.from, tr.to].sort().join("|");
1146
- pairCount.set(key, (pairCount.get(key) ?? 0) + 1);
1147
- }
1148
- return /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 600 400", xmlns: "http://www.w3.org/2000/svg", className, children: [
1149
- /* @__PURE__ */ jsxRuntime.jsxs("defs", { children: [
1150
- /* @__PURE__ */ jsxRuntime.jsxs("filter", { id: ids.glow, x: "-50%", y: "-50%", width: "200%", height: "200%", children: [
1151
- /* @__PURE__ */ jsxRuntime.jsx("feGaussianBlur", { in: "SourceGraphic", stdDeviation: "3", result: "blur" }),
1152
- /* @__PURE__ */ jsxRuntime.jsxs("feMerge", { children: [
1153
- /* @__PURE__ */ jsxRuntime.jsx("feMergeNode", { in: "blur" }),
1154
- /* @__PURE__ */ jsxRuntime.jsx("feMergeNode", { in: "SourceGraphic" })
1155
- ] })
1156
- ] }),
1157
- /* @__PURE__ */ jsxRuntime.jsxs("linearGradient", { id: ids.grad, x1: "0%", y1: "0%", x2: "100%", y2: "100%", children: [
1158
- /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "0%", stopColor: color, stopOpacity: 0.1 }),
1159
- /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "100%", stopColor: color, stopOpacity: 0.05 })
1160
- ] })
1161
- ] }),
1162
- animated && /* @__PURE__ */ jsxRuntime.jsx("style", { children: `
1163
- @keyframes avl-sm-dash { from { stroke-dashoffset: 20; } to { stroke-dashoffset: 0; } }
1164
- ` }),
1165
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx, cy, r: r2 + 30, fill: `url(#${ids.grad})` }),
1166
- transitions.map((tr, i) => {
1167
- if (tr.from !== tr.to) return null;
1168
- const idx = stateIndex.get(tr.from);
1169
- if (idx === void 0) return null;
1170
- const pos = positions[idx];
1171
- const loopR = 20;
1172
- const loopY = pos.y - stateHeight / 2 - 4;
1173
- const d = `M${pos.x - 14},${loopY} C${pos.x - 14},${loopY - loopR * 2} ${pos.x + 14},${loopY - loopR * 2} ${pos.x + 14},${loopY}`;
1174
- return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
1175
- /* @__PURE__ */ jsxRuntime.jsx(
1176
- "path",
1177
- {
1178
- d,
1179
- fill: "none",
1180
- stroke: color,
1181
- strokeWidth: 1.5,
1182
- opacity: 0.7,
1183
- markerEnd: `url(#${ids.grad})`
1184
- }
1185
- ),
1186
- tr.event && /* @__PURE__ */ jsxRuntime.jsx(
1187
- "text",
1188
- {
1189
- x: pos.x,
1190
- y: loopY - loopR * 2 + 4,
1191
- textAnchor: "middle",
1192
- fill: color,
1193
- fontSize: 9,
1194
- fontFamily: "inherit",
1195
- fontWeight: "bold",
1196
- opacity: 0.8,
1197
- children: tr.event
1198
- }
1199
- )
1200
- ] }, `self-${i}`);
1201
- }),
1202
- transitions.map((tr, i) => {
1203
- if (tr.from === tr.to) return null;
1204
- const fromIdx = stateIndex.get(tr.from);
1205
- const toIdx = stateIndex.get(tr.to);
1206
- if (fromIdx === void 0 || toIdx === void 0) return null;
1207
- const fp = positions[fromIdx];
1208
- const tp = positions[toIdx];
1209
- const dx = tp.x - fp.x;
1210
- const dy = tp.y - fp.y;
1211
- const dist = Math.sqrt(dx * dx + dy * dy) || 1;
1212
- const nx = dx / dist;
1213
- const ny = dy / dist;
1214
- const pairKey = [tr.from, tr.to].sort().join("|");
1215
- const totalForPair = pairCount.get(pairKey) ?? 1;
1216
- const seenIdx = pairSeen.get(pairKey) ?? 0;
1217
- pairSeen.set(pairKey, seenIdx + 1);
1218
- const pairOffset = totalForPair > 1 ? (seenIdx - (totalForPair - 1) / 2) * 24 : 0;
1219
- const x1 = fp.x + nx * (stateWidth / 2 + 4);
1220
- const y1 = fp.y + ny * (stateHeight / 2 + 4);
1221
- const x2 = tp.x - nx * (stateWidth / 2 + 8);
1222
- const y2 = tp.y - ny * (stateHeight / 2 + 8);
1223
- const t = 0.3;
1224
- const labelX = x1 * (1 - t) + x2 * t;
1225
- const labelY = y1 * (1 - t) + y2 * t;
1226
- const perpX = -ny * (20 + Math.abs(pairOffset));
1227
- const perpY = nx * (20 + Math.abs(pairOffset));
1228
- const midToCenter = Math.sqrt((labelX - cx) ** 2 + (labelY - cy) ** 2);
1229
- const testX = labelX + perpX;
1230
- const testY = labelY + perpY;
1231
- const testToCenter = Math.sqrt((testX - cx) ** 2 + (testY - cy) ** 2);
1232
- const outSign = testToCenter > midToCenter ? 1 : -1;
1233
- const lx = labelX + perpX * outSign + -ny * pairOffset;
1234
- const ly = labelY + perpY * outSign + nx * pairOffset;
1235
- return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
1236
- /* @__PURE__ */ jsxRuntime.jsx(
1237
- AvlTransition,
1238
- {
1239
- x1: x1 + -ny * pairOffset,
1240
- y1: y1 + nx * pairOffset,
1241
- x2: x2 + -ny * pairOffset,
1242
- y2: y2 + nx * pairOffset,
1243
- curved: states.length > 2,
1244
- curveAwayFrom: { x: cx, y: cy },
1245
- color,
1246
- opacity: 0.7
1247
- }
1248
- ),
1249
- tr.event && /* @__PURE__ */ jsxRuntime.jsx(
1250
- "text",
1251
- {
1252
- x: lx,
1253
- y: ly,
1254
- textAnchor: "middle",
1255
- fill: color,
1256
- fontSize: 9,
1257
- fontFamily: "inherit",
1258
- fontWeight: "bold",
1259
- opacity: 0.8,
1260
- children: tr.event
1261
- }
1262
- ),
1263
- tr.guard && /* @__PURE__ */ jsxRuntime.jsxs(
1264
- "text",
1265
- {
1266
- x: lx,
1267
- y: ly + 12,
1268
- textAnchor: "middle",
1269
- fill: color,
1270
- fontSize: 8,
1271
- fontFamily: "inherit",
1272
- opacity: 0.6,
1273
- children: [
1274
- "[",
1275
- tr.guard,
1276
- "]"
1277
- ]
1278
- }
1279
- ),
1280
- tr.effects?.map((eff, j) => /* @__PURE__ */ jsxRuntime.jsx(
1281
- AvlEffect,
1282
- {
1283
- x: lx + (j - ((tr.effects?.length ?? 1) - 1) / 2) * 14,
1284
- y: ly + (tr.guard ? 22 : 12),
1285
- effectType: eff,
1286
- size: 5,
1287
- color,
1288
- opacity: 0.7
1289
- },
1290
- j
1291
- ))
1292
- ] }, `tr-${i}`);
1293
- }),
1294
- states.map((state, i) => {
1295
- const pos = positions[i];
1296
- return /* @__PURE__ */ jsxRuntime.jsx(
1297
- AvlState,
1298
- {
1299
- x: pos.x - stateWidth / 2,
1300
- y: pos.y - stateHeight / 2,
1301
- width: stateWidth,
1302
- height: stateHeight,
1303
- name: state.name,
1304
- isInitial: state.isInitial,
1305
- isTerminal: state.isTerminal,
1306
- color
1307
- },
1308
- state.name
1309
- );
1310
- })
1311
- ] });
1312
- };
1313
- AvlStateMachine.displayName = "AvlStateMachine";
1314
- var avlOuId = 0;
1315
- var AvlOrbitalUnit = ({
1316
- entityName,
1317
- fields = 4,
1318
- persistence = "persistent",
1319
- traits,
1320
- pages,
1321
- className,
1322
- color = "var(--color-primary)",
1323
- animated = false
1324
- }) => {
1325
- const ids = React6__default.default.useMemo(() => {
1326
- avlOuId += 1;
1327
- const base = `avl-ou-${avlOuId}`;
1328
- return { glow: `${base}-glow`, grad: `${base}-grad` };
1329
- }, []);
1330
- const cx = 300;
1331
- const cy = 200;
1332
- const entityR = 24;
1333
- const orbitalR = 130;
1334
- const traitBaseRx = 55;
1335
- const traitBaseRy = 24;
1336
- const traitRxStep = 20;
1337
- const traitRyStep = 8;
1338
- const traitAngleStep = traits.length > 1 ? 120 / (traits.length - 1) : 0;
1339
- const traitAngleStart = traits.length > 1 ? -60 : 0;
1340
- const pageAngleStart = -Math.PI / 3;
1341
- const pageAngleStep = pages.length > 1 ? Math.PI * 0.8 / (pages.length - 1) : 0;
1342
- return /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 600 400", xmlns: "http://www.w3.org/2000/svg", className, children: [
1343
- /* @__PURE__ */ jsxRuntime.jsxs("defs", { children: [
1344
- /* @__PURE__ */ jsxRuntime.jsxs("filter", { id: ids.glow, x: "-50%", y: "-50%", width: "200%", height: "200%", children: [
1345
- /* @__PURE__ */ jsxRuntime.jsx("feGaussianBlur", { in: "SourceGraphic", stdDeviation: "3", result: "blur" }),
1346
- /* @__PURE__ */ jsxRuntime.jsxs("feMerge", { children: [
1347
- /* @__PURE__ */ jsxRuntime.jsx("feMergeNode", { in: "blur" }),
1348
- /* @__PURE__ */ jsxRuntime.jsx("feMergeNode", { in: "SourceGraphic" })
1349
- ] })
1350
- ] }),
1351
- /* @__PURE__ */ jsxRuntime.jsxs("radialGradient", { id: ids.grad, cx: "50%", cy: "50%", r: "50%", children: [
1352
- /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "0%", stopColor: color, stopOpacity: 0.08 }),
1353
- /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "100%", stopColor: color, stopOpacity: 0 })
1354
- ] })
1355
- ] }),
1356
- animated && /* @__PURE__ */ jsxRuntime.jsx("style", { children: `
1357
- @keyframes avl-ou-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
1358
- ` }),
1359
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx, cy, r: orbitalR + 20, fill: `url(#${ids.grad})` }),
1360
- /* @__PURE__ */ jsxRuntime.jsx(AvlOrbital, { cx, cy, r: orbitalR, label: entityName, color }),
1361
- traits.map((trait, i) => {
1362
- const rotation = traitAngleStart + i * traitAngleStep;
1363
- const traitColor = trait.color ?? color;
1364
- return /* @__PURE__ */ jsxRuntime.jsx(
1365
- AvlTrait,
1366
- {
1367
- cx,
1368
- cy,
1369
- rx: traitBaseRx + i * traitRxStep,
1370
- ry: traitBaseRy + i * traitRyStep,
1371
- rotation,
1372
- label: trait.name,
1373
- color: traitColor,
1374
- opacity: 0.7
1375
- },
1376
- trait.name
1377
- );
1378
- }),
1379
- /* @__PURE__ */ jsxRuntime.jsx(
1380
- AvlEntity,
1381
- {
1382
- x: cx,
1383
- y: cy,
1384
- r: entityR,
1385
- fieldCount: fields,
1386
- persistence,
1387
- color
1388
- }
1389
- ),
1390
- pages.map((page, i) => {
1391
- const angle = pageAngleStart + i * pageAngleStep;
1392
- const px = cx + orbitalR * Math.cos(angle);
1393
- const py = cy + orbitalR * Math.sin(angle);
1394
- return /* @__PURE__ */ jsxRuntime.jsx(
1395
- AvlPage,
1396
- {
1397
- x: px,
1398
- y: py,
1399
- size: 10,
1400
- label: page.name,
1401
- color
1402
- },
1403
- page.name
1404
- );
1405
- })
1406
- ] });
1407
- };
1408
- AvlOrbitalUnit.displayName = "AvlOrbitalUnit";
1409
- var avlCcId = 0;
1410
- var AvlClosedCircuit = ({
1411
- states,
1412
- transitions,
1413
- className,
1414
- color = "var(--color-primary)",
1415
- animated = false
1416
- }) => {
1417
- const ids = React6__default.default.useMemo(() => {
1418
- avlCcId += 1;
1419
- const base = `avl-cc-${avlCcId}`;
1420
- return { glow: `${base}-glow`, grad: `${base}-grad`, arrow: `${base}-arrow` };
1421
- }, []);
1422
- const cx = 300;
1423
- const cy = 200;
1424
- const r2 = 120;
1425
- const stateW = 80;
1426
- const stateH = 32;
1427
- const positions = ringPositions(cx, cy, r2, states.length);
1428
- const stateIndex = new Map(states.map((s, i) => [s.name, i]));
1429
- return /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 600 400", xmlns: "http://www.w3.org/2000/svg", className, children: [
1430
- /* @__PURE__ */ jsxRuntime.jsxs("defs", { children: [
1431
- /* @__PURE__ */ jsxRuntime.jsxs("filter", { id: ids.glow, x: "-50%", y: "-50%", width: "200%", height: "200%", children: [
1432
- /* @__PURE__ */ jsxRuntime.jsx("feGaussianBlur", { in: "SourceGraphic", stdDeviation: "4", result: "blur" }),
1433
- /* @__PURE__ */ jsxRuntime.jsxs("feMerge", { children: [
1434
- /* @__PURE__ */ jsxRuntime.jsx("feMergeNode", { in: "blur" }),
1435
- /* @__PURE__ */ jsxRuntime.jsx("feMergeNode", { in: "SourceGraphic" })
1436
- ] })
1437
- ] }),
1438
- /* @__PURE__ */ jsxRuntime.jsxs("linearGradient", { id: ids.grad, x1: "0%", y1: "0%", x2: "100%", y2: "100%", children: [
1439
- /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "0%", stopColor: color, stopOpacity: 0.15 }),
1440
- /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "50%", stopColor: color, stopOpacity: 0.4 }),
1441
- /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "100%", stopColor: color, stopOpacity: 0.15 })
1442
- ] }),
1443
- /* @__PURE__ */ jsxRuntime.jsx(
1444
- "marker",
1445
- {
1446
- id: ids.arrow,
1447
- markerWidth: "8",
1448
- markerHeight: "6",
1449
- refX: "7",
1450
- refY: "3",
1451
- orient: "auto",
1452
- markerUnits: "strokeWidth",
1453
- children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M0,0 L8,3 L0,6 Z", fill: color, opacity: 0.6 })
1454
- }
1455
- )
1456
- ] }),
1457
- animated && /* @__PURE__ */ jsxRuntime.jsx("style", { children: `
1458
- @keyframes avl-cc-flow { from { stroke-dashoffset: 24; } to { stroke-dashoffset: 0; } }
1459
- ` }),
1460
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx, cy, r: r2 + 30, fill: "none", stroke: color, strokeWidth: 0.3, opacity: 0.06 }),
1461
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx, cy, r: 50, fill: "none", stroke: color, strokeWidth: 0.5, opacity: 0.08 }),
1462
- transitions.map((tr, i) => {
1463
- const fromIdx = stateIndex.get(tr.from);
1464
- const toIdx = stateIndex.get(tr.to);
1465
- if (fromIdx === void 0 || toIdx === void 0) return null;
1466
- const fp = positions[fromIdx];
1467
- const tp = positions[toIdx];
1468
- const dx = tp.x - fp.x;
1469
- const dy = tp.y - fp.y;
1470
- const dist = Math.sqrt(dx * dx + dy * dy) || 1;
1471
- const nx = dx / dist;
1472
- const ny = dy / dist;
1473
- const x1 = fp.x + nx * (stateW / 2 + 4);
1474
- const y1 = fp.y + ny * (stateH / 2 + 4);
1475
- const x2 = tp.x - nx * (stateW / 2 + 8);
1476
- const y2 = tp.y - ny * (stateH / 2 + 8);
1477
- const mx = (x1 + x2) / 2;
1478
- const my = (y1 + y2) / 2;
1479
- const curvature = dist * 0.25;
1480
- let perpX = -ny;
1481
- let perpY = nx;
1482
- const testX = mx + perpX * curvature;
1483
- const testY = my + perpY * curvature;
1484
- const distTest = Math.sqrt((testX - cx) ** 2 + (testY - cy) ** 2);
1485
- const distMid = Math.sqrt((mx - cx) ** 2 + (my - cy) ** 2);
1486
- if (distTest < distMid) {
1487
- perpX = -perpX;
1488
- perpY = -perpY;
1489
- }
1490
- const cpx = mx + perpX * curvature;
1491
- const cpy = my + perpY * curvature;
1492
- const d = `M${x1},${y1} Q${cpx},${cpy} ${x2},${y2}`;
1493
- return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
1494
- /* @__PURE__ */ jsxRuntime.jsx(
1495
- "path",
1496
- {
1497
- d,
1498
- fill: "none",
1499
- stroke: `url(#${ids.grad})`,
1500
- strokeWidth: 1.5,
1501
- strokeDasharray: animated ? "8 6" : void 0,
1502
- markerEnd: `url(#${ids.arrow})`,
1503
- style: animated ? { animation: "avl-cc-flow 1.5s linear infinite" } : void 0
1504
- }
1505
- ),
1506
- tr.event && /* @__PURE__ */ jsxRuntime.jsx(
1507
- AvlEvent,
1508
- {
1509
- x: cpx,
1510
- y: cpy - 14,
1511
- size: 8,
1512
- label: tr.event,
1513
- color,
1514
- opacity: 0.8
1515
- }
1516
- ),
1517
- tr.guard && /* @__PURE__ */ jsxRuntime.jsx(
1518
- AvlGuard,
1519
- {
1520
- x: mx,
1521
- y: my - 8,
1522
- size: 10,
1523
- label: tr.guard,
1524
- color,
1525
- opacity: 0.6
1526
- }
1527
- ),
1528
- tr.effects?.map((eff, j) => /* @__PURE__ */ jsxRuntime.jsx(
1529
- AvlEffect,
1530
- {
1531
- x: mx + (j - ((tr.effects?.length ?? 1) - 1) / 2) * 14,
1532
- y: my + 14,
1533
- effectType: eff,
1534
- size: 5,
1535
- color,
1536
- opacity: 0.7
1537
- },
1538
- j
1539
- ))
1540
- ] }, `cc-tr-${i}`);
1541
- }),
1542
- states.map((state, i) => {
1543
- const pos = positions[i];
1544
- return /* @__PURE__ */ jsxRuntime.jsx(
1545
- AvlState,
1546
- {
1547
- x: pos.x - stateW / 2,
1548
- y: pos.y - stateH / 2,
1549
- width: stateW,
1550
- height: stateH,
1551
- name: state.name,
1552
- color
1553
- },
1554
- state.name
1555
- );
1556
- }),
1557
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx, cy, r: 3, fill: color, opacity: 0.4 })
1558
- ] });
1559
- };
1560
- AvlClosedCircuit.displayName = "AvlClosedCircuit";
1561
- var avlElId = 0;
1562
- var AvlEmitListen = ({
1563
- emitter,
1564
- listener,
1565
- eventName,
1566
- className,
1567
- color = "var(--color-primary)",
1568
- animated = false
1569
- }) => {
1570
- const ids = React6__default.default.useMemo(() => {
1571
- avlElId += 1;
1572
- const base = `avl-el-${avlElId}`;
1573
- return { arrow: `${base}-arrow`, grad: `${base}-grad` };
1574
- }, []);
1575
- const leftCx = 180;
1576
- const rightCx = 420;
1577
- const cy = 200;
1578
- const orbR = 80;
1579
- return /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 600 400", xmlns: "http://www.w3.org/2000/svg", className, children: [
1580
- /* @__PURE__ */ jsxRuntime.jsxs("defs", { children: [
1581
- /* @__PURE__ */ jsxRuntime.jsx(
1582
- "marker",
1583
- {
1584
- id: ids.arrow,
1585
- markerWidth: "8",
1586
- markerHeight: "6",
1587
- refX: "7",
1588
- refY: "3",
1589
- orient: "auto",
1590
- markerUnits: "strokeWidth",
1591
- children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M0,0 L8,3 L0,6 Z", fill: color, opacity: 0.6 })
1592
- }
1593
- ),
1594
- /* @__PURE__ */ jsxRuntime.jsxs("linearGradient", { id: ids.grad, x1: "0%", y1: "0%", x2: "100%", y2: "0%", children: [
1595
- /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "0%", stopColor: color, stopOpacity: 0.5 }),
1596
- /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "100%", stopColor: color, stopOpacity: 0.2 })
1597
- ] })
1598
- ] }),
1599
- animated && /* @__PURE__ */ jsxRuntime.jsx("style", { children: `
1600
- @keyframes avl-el-dash { from { stroke-dashoffset: 16; } to { stroke-dashoffset: 0; } }
1601
- ` }),
1602
- /* @__PURE__ */ jsxRuntime.jsx(AvlOrbital, { cx: leftCx, cy, r: orbR, label: emitter.name, color }),
1603
- /* @__PURE__ */ jsxRuntime.jsx(AvlEntity, { x: leftCx, y: cy, r: 18, fieldCount: emitter.fields ?? 3, color }),
1604
- /* @__PURE__ */ jsxRuntime.jsx(AvlOrbital, { cx: rightCx, cy, r: orbR, label: listener.name, color }),
1605
- /* @__PURE__ */ jsxRuntime.jsx(AvlEntity, { x: rightCx, y: cy, r: 18, fieldCount: listener.fields ?? 3, color }),
1606
- /* @__PURE__ */ jsxRuntime.jsx(
1607
- "path",
1608
- {
1609
- d: `M${leftCx + orbR + 4},${cy} L${rightCx - orbR - 8},${cy}`,
1610
- fill: "none",
1611
- stroke: `url(#${ids.grad})`,
1612
- strokeWidth: 2,
1613
- strokeDasharray: "6 4",
1614
- markerEnd: `url(#${ids.arrow})`,
1615
- style: animated ? { animation: "avl-el-dash 1s linear infinite" } : void 0
1616
- }
1617
- ),
1618
- /* @__PURE__ */ jsxRuntime.jsx(
1619
- AvlEffect,
1620
- {
1621
- x: leftCx + orbR + 20,
1622
- y: cy - 20,
1623
- effectType: "emit",
1624
- size: 6,
1625
- color,
1626
- opacity: 0.8
1627
- }
1628
- ),
1629
- eventName && /* @__PURE__ */ jsxRuntime.jsxs(
1630
- "text",
1631
- {
1632
- x: 300,
1633
- y: cy - 18,
1634
- textAnchor: "middle",
1635
- fill: color,
1636
- fontSize: 11,
1637
- fontFamily: "inherit",
1638
- fontWeight: "bold",
1639
- opacity: 0.8,
1640
- children: [
1641
- "~",
1642
- eventName
1643
- ]
1644
- }
1645
- ),
1646
- /* @__PURE__ */ jsxRuntime.jsx(
1647
- "text",
1648
- {
1649
- x: 300,
1650
- y: cy + 18,
1651
- textAnchor: "middle",
1652
- fill: color,
1653
- fontSize: 12,
1654
- fontFamily: "inherit",
1655
- opacity: 0.3,
1656
- letterSpacing: 4,
1657
- children: "~ ~ ~"
1658
- }
1659
- )
1660
- ] });
1661
- };
1662
- AvlEmitListen.displayName = "AvlEmitListen";
1663
- var SLOT_PRESETS = {
1664
- header: { x: 10, y: 5, width: 340, height: 35 },
1665
- main: { x: 120, y: 50, width: 230, height: 195 },
1666
- sidebar: { x: 10, y: 50, width: 100, height: 195 },
1667
- modal: { x: 80, y: 60, width: 200, height: 140 },
1668
- drawer: { x: 220, y: 50, width: 130, height: 195 },
1669
- toast: { x: 220, y: 210, width: 130, height: 35 },
1670
- footer: { x: 10, y: 220, width: 340, height: 30 },
1671
- center: { x: 60, y: 50, width: 240, height: 195 },
1672
- "hud-top": { x: 10, y: 5, width: 340, height: 30 },
1673
- "hud-bottom": { x: 10, y: 220, width: 340, height: 30 }
1674
- };
1675
- function resolveSlot(slot, fallbackIdx) {
1676
- if (slot.x !== void 0 && slot.y !== void 0 && slot.width !== void 0 && slot.height !== void 0) {
1677
- return slot;
1678
- }
1679
- const preset = SLOT_PRESETS[slot.name];
1680
- if (preset) {
1681
- return {
1682
- name: slot.name,
1683
- x: slot.x ?? preset.x,
1684
- y: slot.y ?? preset.y,
1685
- width: slot.width ?? preset.width,
1686
- height: slot.height ?? preset.height
1687
- };
1688
- }
1689
- const col = fallbackIdx % 2;
1690
- const row = Math.floor(fallbackIdx / 2);
1691
- return {
1692
- name: slot.name,
1693
- x: 10 + col * 175,
1694
- y: 50 + row * 100,
1695
- width: 165,
1696
- height: 90
1697
- };
1698
- }
1699
- var AvlSlotMap = ({
1700
- slots,
1701
- pageWidth = 360,
1702
- pageHeight = 280,
1703
- className,
1704
- color = "var(--color-primary)",
1705
- animated = false
1706
- }) => {
1707
- const ox = (600 - pageWidth) / 2;
1708
- const oy = (400 - pageHeight) / 2;
1709
- let unknownIdx = 0;
1710
- const resolvedSlots = slots.map((slot) => {
1711
- const isUnknown = !SLOT_PRESETS[slot.name] && (slot.x === void 0 || slot.y === void 0);
1712
- const resolved = resolveSlot(slot, isUnknown ? unknownIdx : 0);
1713
- if (isUnknown) unknownIdx++;
1714
- return resolved;
1715
- });
1716
- return /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 600 400", xmlns: "http://www.w3.org/2000/svg", className, children: [
1717
- animated && /* @__PURE__ */ jsxRuntime.jsx("style", { children: `
1718
- @keyframes avl-slot-pulse { 0%, 100% { opacity: 0.15; } 50% { opacity: 0.25; } }
1719
- ` }),
1720
- /* @__PURE__ */ jsxRuntime.jsx(
1721
- "rect",
1722
- {
1723
- x: ox,
1724
- y: oy,
1725
- width: pageWidth,
1726
- height: pageHeight,
1727
- rx: 4,
1728
- ry: 4,
1729
- fill: "none",
1730
- stroke: color,
1731
- strokeWidth: 2
1732
- }
1733
- ),
1734
- /* @__PURE__ */ jsxRuntime.jsx(
1735
- "rect",
1736
- {
1737
- x: ox,
1738
- y: oy,
1739
- width: pageWidth,
1740
- height: 24,
1741
- rx: 4,
1742
- ry: 4,
1743
- fill: color,
1744
- opacity: 0.1
1745
- }
1746
- ),
1747
- /* @__PURE__ */ jsxRuntime.jsx(
1748
- "text",
1749
- {
1750
- x: ox + pageWidth / 2,
1751
- y: oy + 16,
1752
- textAnchor: "middle",
1753
- fill: color,
1754
- fontSize: 10,
1755
- fontFamily: "inherit",
1756
- fontWeight: "bold",
1757
- children: "Page Layout"
1758
- }
1759
- ),
1760
- resolvedSlots.map((slot) => /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
1761
- /* @__PURE__ */ jsxRuntime.jsx(
1762
- "rect",
1763
- {
1764
- x: ox + slot.x,
1765
- y: oy + 24 + slot.y,
1766
- width: slot.width,
1767
- height: slot.height,
1768
- rx: 3,
1769
- ry: 3,
1770
- fill: color,
1771
- opacity: 0.08,
1772
- stroke: color,
1773
- strokeWidth: 1,
1774
- strokeDasharray: "4 2",
1775
- style: animated ? { animation: "avl-slot-pulse 2s ease-in-out infinite" } : void 0
1776
- }
1777
- ),
1778
- /* @__PURE__ */ jsxRuntime.jsx(
1779
- "text",
1780
- {
1781
- x: ox + slot.x + slot.width / 2,
1782
- y: oy + 24 + slot.y + slot.height / 2,
1783
- textAnchor: "middle",
1784
- dominantBaseline: "central",
1785
- fill: color,
1786
- fontSize: 9,
1787
- fontFamily: "inherit",
1788
- opacity: 0.6,
1789
- children: slot.name
1790
- }
1791
- )
1792
- ] }, slot.name))
1793
- ] });
1794
- };
1795
- AvlSlotMap.displayName = "AvlSlotMap";
1796
- var avlEtId = 0;
1797
- function layoutTree(node, x, y, hSpacing, vSpacing) {
1798
- const children = node.children ?? [];
1799
- if (children.length === 0) {
1800
- return { label: node.label, type: node.type, x, y, children: [] };
1801
- }
1802
- const totalWidth = (children.length - 1) * hSpacing;
1803
- const startX = x - totalWidth / 2;
1804
- const layoutChildren = children.map(
1805
- (child, i) => layoutTree(child, startX + i * hSpacing, y + vSpacing, hSpacing * 0.65, vSpacing)
1806
- );
1807
- return { label: node.label, type: node.type, x, y, children: layoutChildren };
1808
- }
1809
- function nodeColor(type, baseColor) {
1810
- switch (type) {
1811
- case "operator":
1812
- return baseColor;
1813
- case "literal":
1814
- return baseColor;
1815
- case "binding":
1816
- return baseColor;
1817
- }
1818
- }
1819
- function renderNode(node, color, glowId) {
1820
- const labelLen = node.label.length;
1821
- const baseR = node.type === "operator" ? 20 : 16;
1822
- const r2 = Math.max(baseR, labelLen * 3.5 + 6);
1823
- const nc = nodeColor(node.type, color);
1824
- return /* @__PURE__ */ jsxRuntime.jsxs(React6__default.default.Fragment, { children: [
1825
- node.children.map((child, i) => {
1826
- const childR = Math.max(
1827
- child.type === "operator" ? 20 : 16,
1828
- child.label.length * 3.5 + 6
1829
- );
1830
- return /* @__PURE__ */ jsxRuntime.jsx(
1831
- "line",
1832
- {
1833
- x1: node.x,
1834
- y1: node.y + (node.type === "operator" ? r2 * 0.7 : r2),
1835
- x2: child.x,
1836
- y2: child.y - (child.type === "operator" ? childR * 0.7 : childR),
1837
- stroke: color,
1838
- strokeWidth: 1,
1839
- opacity: 0.3
1840
- },
1841
- `line-${i}`
1842
- );
1843
- }),
1844
- node.type === "operator" ? /* @__PURE__ */ jsxRuntime.jsx(
1845
- "rect",
1846
- {
1847
- x: node.x - r2,
1848
- y: node.y - r2 * 0.6,
1849
- width: r2 * 2,
1850
- height: r2 * 1.2,
1851
- rx: 4,
1852
- ry: 4,
1853
- fill: color,
1854
- fillOpacity: 0.15,
1855
- stroke: nc,
1856
- strokeWidth: 1.5
1857
- }
1858
- ) : node.type === "binding" ? /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: node.x, cy: node.y, r: r2, fill: "none", stroke: nc, strokeWidth: 1.5, strokeDasharray: "3 2" }) : /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: node.x, cy: node.y, r: r2, fill: "none", stroke: nc, strokeWidth: 1, opacity: 0.5 }),
1859
- /* @__PURE__ */ jsxRuntime.jsx(
1860
- "text",
1861
- {
1862
- x: node.x,
1863
- y: node.y + 1,
1864
- textAnchor: "middle",
1865
- dominantBaseline: "central",
1866
- fill: nc,
1867
- fontSize: node.type === "operator" ? 11 : 10,
1868
- fontFamily: "inherit",
1869
- fontWeight: node.type === "operator" ? "bold" : "normal",
1870
- children: node.type === "binding" ? `@${node.label}` : node.label
1871
- }
1872
- ),
1873
- node.children.map((child) => renderNode(child, color))
1874
- ] }, `${node.label}-${node.x}-${node.y}`);
1875
- }
1876
- var AvlExprTree = ({
1877
- expression,
1878
- className,
1879
- color = "var(--color-primary)"
1880
- }) => {
1881
- const ids = React6__default.default.useMemo(() => {
1882
- avlEtId += 1;
1883
- return { glow: `avl-et-${avlEtId}-glow` };
1884
- }, []);
1885
- const layout = layoutTree(expression, 300, 70, 150, 85);
1886
- return /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 600 400", xmlns: "http://www.w3.org/2000/svg", className, children: [
1887
- /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsxs("filter", { id: ids.glow, x: "-50%", y: "-50%", width: "200%", height: "200%", children: [
1888
- /* @__PURE__ */ jsxRuntime.jsx("feGaussianBlur", { in: "SourceGraphic", stdDeviation: "2", result: "blur" }),
1889
- /* @__PURE__ */ jsxRuntime.jsxs("feMerge", { children: [
1890
- /* @__PURE__ */ jsxRuntime.jsx("feMergeNode", { in: "blur" }),
1891
- /* @__PURE__ */ jsxRuntime.jsx("feMergeNode", { in: "SourceGraphic" })
1892
- ] })
1893
- ] }) }),
1894
- renderNode(layout, color, ids.glow)
1895
- ] });
1896
- };
1897
- AvlExprTree.displayName = "AvlExprTree";
1898
-
1899
- // node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs
1900
- function r(e) {
1901
- var t, f, n = "";
1902
- if ("string" == typeof e || "number" == typeof e) n += e;
1903
- else if ("object" == typeof e) if (Array.isArray(e)) {
1904
- var o = e.length;
1905
- for (t = 0; t < o; t++) e[t] && (f = r(e[t])) && (n && (n += " "), n += f);
1906
- } else for (f in e) e[f] && (n && (n += " "), n += f);
1907
- return n;
1908
- }
1909
- function clsx() {
1910
- for (var e, t, f = 0, n = "", o = arguments.length; f < o; f++) (e = arguments[f]) && (t = r(e)) && (n && (n += " "), n += t);
1911
- return n;
1912
- }
1913
-
1914
- // node_modules/.pnpm/tailwind-merge@2.6.1/node_modules/tailwind-merge/dist/bundle-mjs.mjs
1915
- var CLASS_PART_SEPARATOR = "-";
1916
- var createClassGroupUtils = (config) => {
1917
- const classMap = createClassMap(config);
1918
- const {
1919
- conflictingClassGroups,
1920
- conflictingClassGroupModifiers
1921
- } = config;
1922
- const getClassGroupId = (className) => {
1923
- const classParts = className.split(CLASS_PART_SEPARATOR);
1924
- if (classParts[0] === "" && classParts.length !== 1) {
1925
- classParts.shift();
1926
- }
1927
- return getGroupRecursive(classParts, classMap) || getGroupIdForArbitraryProperty(className);
1928
- };
1929
- const getConflictingClassGroupIds = (classGroupId, hasPostfixModifier) => {
1930
- const conflicts = conflictingClassGroups[classGroupId] || [];
1931
- if (hasPostfixModifier && conflictingClassGroupModifiers[classGroupId]) {
1932
- return [...conflicts, ...conflictingClassGroupModifiers[classGroupId]];
1933
- }
1934
- return conflicts;
1935
- };
1936
- return {
1937
- getClassGroupId,
1938
- getConflictingClassGroupIds
1939
- };
1940
- };
1941
- var getGroupRecursive = (classParts, classPartObject) => {
1942
- if (classParts.length === 0) {
1943
- return classPartObject.classGroupId;
1944
- }
1945
- const currentClassPart = classParts[0];
1946
- const nextClassPartObject = classPartObject.nextPart.get(currentClassPart);
1947
- const classGroupFromNextClassPart = nextClassPartObject ? getGroupRecursive(classParts.slice(1), nextClassPartObject) : void 0;
1948
- if (classGroupFromNextClassPart) {
1949
- return classGroupFromNextClassPart;
1950
- }
1951
- if (classPartObject.validators.length === 0) {
1952
- return void 0;
1953
- }
1954
- const classRest = classParts.join(CLASS_PART_SEPARATOR);
1955
- return classPartObject.validators.find(({
1956
- validator
1957
- }) => validator(classRest))?.classGroupId;
1958
- };
1959
- var arbitraryPropertyRegex = /^\[(.+)\]$/;
1960
- var getGroupIdForArbitraryProperty = (className) => {
1961
- if (arbitraryPropertyRegex.test(className)) {
1962
- const arbitraryPropertyClassName = arbitraryPropertyRegex.exec(className)[1];
1963
- const property = arbitraryPropertyClassName?.substring(0, arbitraryPropertyClassName.indexOf(":"));
1964
- if (property) {
1965
- return "arbitrary.." + property;
1966
- }
1967
- }
1968
- };
1969
- var createClassMap = (config) => {
1970
- const {
1971
- theme,
1972
- prefix
1973
- } = config;
1974
- const classMap = {
1975
- nextPart: /* @__PURE__ */ new Map(),
1976
- validators: []
1977
- };
1978
- const prefixedClassGroupEntries = getPrefixedClassGroupEntries(Object.entries(config.classGroups), prefix);
1979
- prefixedClassGroupEntries.forEach(([classGroupId, classGroup]) => {
1980
- processClassesRecursively(classGroup, classMap, classGroupId, theme);
1981
- });
1982
- return classMap;
1983
- };
1984
- var processClassesRecursively = (classGroup, classPartObject, classGroupId, theme) => {
1985
- classGroup.forEach((classDefinition) => {
1986
- if (typeof classDefinition === "string") {
1987
- const classPartObjectToEdit = classDefinition === "" ? classPartObject : getPart(classPartObject, classDefinition);
1988
- classPartObjectToEdit.classGroupId = classGroupId;
1989
- return;
1990
- }
1991
- if (typeof classDefinition === "function") {
1992
- if (isThemeGetter(classDefinition)) {
1993
- processClassesRecursively(classDefinition(theme), classPartObject, classGroupId, theme);
1994
- return;
1995
- }
1996
- classPartObject.validators.push({
1997
- validator: classDefinition,
1998
- classGroupId
1999
- });
2000
- return;
2001
- }
2002
- Object.entries(classDefinition).forEach(([key, classGroup2]) => {
2003
- processClassesRecursively(classGroup2, getPart(classPartObject, key), classGroupId, theme);
2004
- });
2005
- });
2006
- };
2007
- var getPart = (classPartObject, path) => {
2008
- let currentClassPartObject = classPartObject;
2009
- path.split(CLASS_PART_SEPARATOR).forEach((pathPart) => {
2010
- if (!currentClassPartObject.nextPart.has(pathPart)) {
2011
- currentClassPartObject.nextPart.set(pathPart, {
2012
- nextPart: /* @__PURE__ */ new Map(),
2013
- validators: []
2014
- });
2015
- }
2016
- currentClassPartObject = currentClassPartObject.nextPart.get(pathPart);
2017
- });
2018
- return currentClassPartObject;
2019
- };
2020
- var isThemeGetter = (func) => func.isThemeGetter;
2021
- var getPrefixedClassGroupEntries = (classGroupEntries, prefix) => {
2022
- if (!prefix) {
2023
- return classGroupEntries;
2024
- }
2025
- return classGroupEntries.map(([classGroupId, classGroup]) => {
2026
- const prefixedClassGroup = classGroup.map((classDefinition) => {
2027
- if (typeof classDefinition === "string") {
2028
- return prefix + classDefinition;
2029
- }
2030
- if (typeof classDefinition === "object") {
2031
- return Object.fromEntries(Object.entries(classDefinition).map(([key, value]) => [prefix + key, value]));
2032
- }
2033
- return classDefinition;
2034
- });
2035
- return [classGroupId, prefixedClassGroup];
2036
- });
2037
- };
2038
- var createLruCache = (maxCacheSize) => {
2039
- if (maxCacheSize < 1) {
2040
- return {
2041
- get: () => void 0,
2042
- set: () => {
2043
- }
2044
- };
2045
- }
2046
- let cacheSize = 0;
2047
- let cache = /* @__PURE__ */ new Map();
2048
- let previousCache = /* @__PURE__ */ new Map();
2049
- const update = (key, value) => {
2050
- cache.set(key, value);
2051
- cacheSize++;
2052
- if (cacheSize > maxCacheSize) {
2053
- cacheSize = 0;
2054
- previousCache = cache;
2055
- cache = /* @__PURE__ */ new Map();
2056
- }
2057
- };
2058
- return {
2059
- get(key) {
2060
- let value = cache.get(key);
2061
- if (value !== void 0) {
2062
- return value;
2063
- }
2064
- if ((value = previousCache.get(key)) !== void 0) {
2065
- update(key, value);
2066
- return value;
2067
- }
2068
- },
2069
- set(key, value) {
2070
- if (cache.has(key)) {
2071
- cache.set(key, value);
2072
- } else {
2073
- update(key, value);
2074
- }
2075
- }
1221
+ get(key) {
1222
+ let value = cache.get(key);
1223
+ if (value !== void 0) {
1224
+ return value;
1225
+ }
1226
+ if ((value = previousCache.get(key)) !== void 0) {
1227
+ update(key, value);
1228
+ return value;
1229
+ }
1230
+ },
1231
+ set(key, value) {
1232
+ if (cache.has(key)) {
1233
+ cache.set(key, value);
1234
+ } else {
1235
+ update(key, value);
1236
+ }
1237
+ }
2076
1238
  };
2077
1239
  };
2078
1240
  var IMPORTANT_MODIFIER = "!";
@@ -4369,13 +3531,120 @@ var getDefaultConfig = () => {
4369
3531
  }
4370
3532
  };
4371
3533
  };
4372
- var twMerge = /* @__PURE__ */ createTailwindMerge(getDefaultConfig);
4373
-
4374
- // lib/cn.ts
4375
- function cn(...inputs) {
4376
- return twMerge(clsx(inputs));
4377
- }
4378
- var EventBusContext = React6.createContext(null);
3534
+ var twMerge = /* @__PURE__ */ createTailwindMerge(getDefaultConfig);
3535
+
3536
+ // lib/cn.ts
3537
+ function cn(...inputs) {
3538
+ return twMerge(clsx(inputs));
3539
+ }
3540
+ var variantStyles = {
3541
+ h1: "text-4xl font-bold tracking-tight text-[var(--color-foreground)]",
3542
+ h2: "text-3xl font-bold tracking-tight text-[var(--color-foreground)]",
3543
+ h3: "text-2xl font-bold text-[var(--color-foreground)]",
3544
+ h4: "text-xl font-bold text-[var(--color-foreground)]",
3545
+ h5: "text-lg font-bold text-[var(--color-foreground)]",
3546
+ h6: "text-base font-bold text-[var(--color-foreground)]",
3547
+ heading: "text-2xl font-bold text-[var(--color-foreground)]",
3548
+ subheading: "text-lg font-semibold text-[var(--color-foreground)]",
3549
+ body1: "text-base font-normal text-[var(--color-foreground)]",
3550
+ body2: "text-sm font-normal text-[var(--color-foreground)]",
3551
+ body: "text-base font-normal text-[var(--color-foreground)]",
3552
+ caption: "text-xs font-normal text-[var(--color-muted-foreground)]",
3553
+ overline: "text-xs uppercase tracking-wide font-bold text-[var(--color-muted-foreground)]",
3554
+ small: "text-sm font-normal text-[var(--color-foreground)]",
3555
+ large: "text-lg font-medium text-[var(--color-foreground)]",
3556
+ label: "text-sm font-medium text-[var(--color-foreground)]"
3557
+ };
3558
+ var colorStyles = {
3559
+ primary: "text-[var(--color-foreground)]",
3560
+ secondary: "text-[var(--color-muted-foreground)]",
3561
+ muted: "text-[var(--color-muted-foreground)]",
3562
+ error: "text-[var(--color-error)]",
3563
+ success: "text-[var(--color-success)]",
3564
+ warning: "text-[var(--color-warning)]",
3565
+ inherit: "text-inherit"
3566
+ };
3567
+ var weightStyles = {
3568
+ light: "font-light",
3569
+ normal: "font-normal",
3570
+ medium: "font-medium",
3571
+ semibold: "font-semibold",
3572
+ bold: "font-bold"
3573
+ };
3574
+ var defaultElements = {
3575
+ h1: "h1",
3576
+ h2: "h2",
3577
+ h3: "h3",
3578
+ h4: "h4",
3579
+ h5: "h5",
3580
+ h6: "h6",
3581
+ heading: "h2",
3582
+ subheading: "h3",
3583
+ body1: "p",
3584
+ body2: "p",
3585
+ body: "p",
3586
+ caption: "span",
3587
+ overline: "span",
3588
+ small: "span",
3589
+ large: "p",
3590
+ label: "span"
3591
+ };
3592
+ var typographySizeStyles = {
3593
+ xs: "text-xs",
3594
+ sm: "text-sm",
3595
+ md: "text-base",
3596
+ lg: "text-lg",
3597
+ xl: "text-xl",
3598
+ "2xl": "text-2xl",
3599
+ "3xl": "text-3xl"
3600
+ };
3601
+ var overflowStyles = {
3602
+ visible: "overflow-visible",
3603
+ hidden: "overflow-hidden",
3604
+ wrap: "break-words overflow-hidden",
3605
+ "clamp-2": "overflow-hidden line-clamp-2",
3606
+ "clamp-3": "overflow-hidden line-clamp-3"
3607
+ };
3608
+ var Typography = ({
3609
+ variant: variantProp,
3610
+ level,
3611
+ color = "primary",
3612
+ align,
3613
+ weight,
3614
+ size,
3615
+ truncate = false,
3616
+ overflow,
3617
+ as,
3618
+ id,
3619
+ className,
3620
+ style,
3621
+ content,
3622
+ children
3623
+ }) => {
3624
+ const variant = variantProp ?? (level ? `h${level}` : "body1");
3625
+ const Component = as || defaultElements[variant];
3626
+ const Comp = Component;
3627
+ return /* @__PURE__ */ jsxRuntime.jsx(
3628
+ Comp,
3629
+ {
3630
+ id,
3631
+ className: cn(
3632
+ variantStyles[variant],
3633
+ colorStyles[color],
3634
+ weight && weightStyles[weight],
3635
+ size && typographySizeStyles[size],
3636
+ align && `text-${align}`,
3637
+ truncate && "truncate overflow-hidden text-ellipsis",
3638
+ overflow && overflowStyles[overflow],
3639
+ className
3640
+ ),
3641
+ style,
3642
+ children: children ?? content
3643
+ }
3644
+ );
3645
+ };
3646
+ Typography.displayName = "Typography";
3647
+ var EventBusContext = React8.createContext(null);
4379
3648
 
4380
3649
  // hooks/useEventBus.ts
4381
3650
  function getGlobalEventBus() {
@@ -4445,7 +3714,7 @@ var fallbackEventBus = {
4445
3714
  }
4446
3715
  };
4447
3716
  function useEventBus() {
4448
- const context = React6.useContext(EventBusContext);
3717
+ const context = React8.useContext(EventBusContext);
4449
3718
  return context ?? getGlobalEventBus() ?? fallbackEventBus;
4450
3719
  }
4451
3720
  var paddingStyles = {
@@ -4538,296 +3807,1049 @@ var displayStyles = {
4538
3807
  "inline-flex": "inline-flex",
4539
3808
  grid: "grid"
4540
3809
  };
4541
- var overflowStyles = {
4542
- auto: "overflow-auto",
4543
- hidden: "overflow-hidden",
4544
- visible: "overflow-visible",
4545
- scroll: "overflow-scroll"
3810
+ var overflowStyles2 = {
3811
+ auto: "overflow-auto",
3812
+ hidden: "overflow-hidden",
3813
+ visible: "overflow-visible",
3814
+ scroll: "overflow-scroll"
3815
+ };
3816
+ var positionStyles = {
3817
+ relative: "relative",
3818
+ absolute: "absolute",
3819
+ fixed: "fixed",
3820
+ sticky: "sticky"
3821
+ };
3822
+ var Box = React8__default.default.forwardRef(
3823
+ ({
3824
+ padding,
3825
+ paddingX,
3826
+ paddingY,
3827
+ margin,
3828
+ marginX,
3829
+ marginY,
3830
+ bg = "transparent",
3831
+ border = false,
3832
+ rounded = "none",
3833
+ shadow = "none",
3834
+ display,
3835
+ fullWidth = false,
3836
+ fullHeight = false,
3837
+ overflow,
3838
+ position,
3839
+ className,
3840
+ children,
3841
+ as: Component = "div",
3842
+ action,
3843
+ actionPayload,
3844
+ hoverEvent,
3845
+ onClick,
3846
+ onMouseEnter,
3847
+ onMouseLeave,
3848
+ ...rest
3849
+ }, ref) => {
3850
+ const eventBus = useEventBus();
3851
+ const handleClick = React8.useCallback((e) => {
3852
+ if (action) {
3853
+ e.stopPropagation();
3854
+ eventBus.emit(`UI:${action}`, actionPayload ?? {});
3855
+ }
3856
+ onClick?.(e);
3857
+ }, [action, actionPayload, eventBus, onClick]);
3858
+ const handleMouseEnter = React8.useCallback((e) => {
3859
+ if (hoverEvent) {
3860
+ eventBus.emit(`UI:${hoverEvent}`, { hovered: true });
3861
+ }
3862
+ onMouseEnter?.(e);
3863
+ }, [hoverEvent, eventBus, onMouseEnter]);
3864
+ const handleMouseLeave = React8.useCallback((e) => {
3865
+ if (hoverEvent) {
3866
+ eventBus.emit(`UI:${hoverEvent}`, { hovered: false });
3867
+ }
3868
+ onMouseLeave?.(e);
3869
+ }, [hoverEvent, eventBus, onMouseLeave]);
3870
+ const isClickable = action || onClick;
3871
+ const Comp = Component;
3872
+ return /* @__PURE__ */ jsxRuntime.jsx(
3873
+ Comp,
3874
+ {
3875
+ ref,
3876
+ className: cn(
3877
+ // Padding
3878
+ padding && paddingStyles[padding],
3879
+ paddingX && paddingXStyles[paddingX],
3880
+ paddingY && paddingYStyles[paddingY],
3881
+ // Margin
3882
+ margin && marginStyles[margin],
3883
+ marginX && marginXStyles[marginX],
3884
+ marginY && marginYStyles[marginY],
3885
+ // Background
3886
+ bgStyles[bg],
3887
+ // Border - uses theme variables
3888
+ border && "border-[length:var(--border-width)] border-[var(--color-border)]",
3889
+ // Rounded
3890
+ roundedStyles[rounded],
3891
+ // Shadow
3892
+ shadowStyles[shadow],
3893
+ // Display
3894
+ display && displayStyles[display],
3895
+ // Dimensions
3896
+ fullWidth && "w-full",
3897
+ fullHeight && "h-full",
3898
+ // Overflow
3899
+ overflow && overflowStyles2[overflow],
3900
+ // Position
3901
+ position && positionStyles[position],
3902
+ // Cursor for clickable
3903
+ isClickable && "cursor-pointer",
3904
+ className
3905
+ ),
3906
+ onClick: isClickable ? handleClick : void 0,
3907
+ onMouseEnter: hoverEvent || onMouseEnter ? handleMouseEnter : void 0,
3908
+ onMouseLeave: hoverEvent || onMouseLeave ? handleMouseLeave : void 0,
3909
+ ...rest,
3910
+ children
3911
+ }
3912
+ );
3913
+ }
3914
+ );
3915
+ Box.displayName = "Box";
3916
+ var gapStyles = {
3917
+ none: "gap-0",
3918
+ xs: "gap-1",
3919
+ sm: "gap-2",
3920
+ md: "gap-4",
3921
+ lg: "gap-6",
3922
+ xl: "gap-8",
3923
+ "2xl": "gap-12"
3924
+ };
3925
+ var alignStyles = {
3926
+ start: "items-start",
3927
+ center: "items-center",
3928
+ end: "items-end",
3929
+ stretch: "items-stretch",
3930
+ baseline: "items-baseline"
3931
+ };
3932
+ var justifyStyles = {
3933
+ start: "justify-start",
3934
+ center: "justify-center",
3935
+ end: "justify-end",
3936
+ between: "justify-between",
3937
+ around: "justify-around",
3938
+ evenly: "justify-evenly"
3939
+ };
3940
+ var Stack = ({
3941
+ direction = "vertical",
3942
+ gap = "md",
3943
+ align = "stretch",
3944
+ justify = "start",
3945
+ wrap = false,
3946
+ reverse = false,
3947
+ flex = false,
3948
+ className,
3949
+ style,
3950
+ children,
3951
+ as: Component = "div",
3952
+ onClick,
3953
+ onKeyDown,
3954
+ role,
3955
+ tabIndex,
3956
+ action,
3957
+ actionPayload,
3958
+ responsive = false
3959
+ }) => {
3960
+ const eventBus = useEventBus();
3961
+ const handleClick = (e) => {
3962
+ if (action) {
3963
+ eventBus.emit(`UI:${action}`, actionPayload ?? {});
3964
+ }
3965
+ onClick?.(e);
3966
+ };
3967
+ const isHorizontal = direction === "horizontal";
3968
+ const directionClass = responsive && isHorizontal ? reverse ? "flex-col-reverse md:flex-row-reverse" : "flex-col md:flex-row" : isHorizontal ? reverse ? "flex-row-reverse" : "flex-row" : reverse ? "flex-col-reverse" : "flex-col";
3969
+ const Comp = Component;
3970
+ return /* @__PURE__ */ jsxRuntime.jsx(
3971
+ Comp,
3972
+ {
3973
+ className: cn(
3974
+ "flex",
3975
+ directionClass,
3976
+ gapStyles[gap],
3977
+ alignStyles[align],
3978
+ justifyStyles[justify],
3979
+ wrap && "flex-wrap",
3980
+ flex && "flex-1",
3981
+ className
3982
+ ),
3983
+ style,
3984
+ onClick: action || onClick ? handleClick : void 0,
3985
+ onKeyDown,
3986
+ role,
3987
+ tabIndex,
3988
+ children
3989
+ }
3990
+ );
3991
+ };
3992
+ var HStack = (props) => /* @__PURE__ */ jsxRuntime.jsx(Stack, { direction: "horizontal", ...props });
3993
+
3994
+ // components/molecules/avl/avl-layout.ts
3995
+ function ringPositions(cx, cy, r2, count, startAngle = -Math.PI / 2) {
3996
+ if (count === 0) return [];
3997
+ if (count === 1) {
3998
+ return [{ x: cx, y: cy, angle: 0 }];
3999
+ }
4000
+ if (count === 2) {
4001
+ return [
4002
+ { x: cx - r2 * 0.7, y: cy, angle: Math.PI },
4003
+ { x: cx + r2 * 0.7, y: cy, angle: 0 }
4004
+ ];
4005
+ }
4006
+ return Array.from({ length: count }, (_, i) => {
4007
+ const angle = startAngle + Math.PI * 2 * i / count;
4008
+ return {
4009
+ x: cx + r2 * Math.cos(angle),
4010
+ y: cy + r2 * Math.sin(angle),
4011
+ angle
4012
+ };
4013
+ });
4014
+ }
4015
+ function arcPath(cx, cy, r2, startAngle, endAngle) {
4016
+ const x1 = cx + r2 * Math.cos(startAngle);
4017
+ const y1 = cy + r2 * Math.sin(startAngle);
4018
+ const x2 = cx + r2 * Math.cos(endAngle);
4019
+ const y2 = cy + r2 * Math.sin(endAngle);
4020
+ const largeArc = endAngle - startAngle > Math.PI ? 1 : 0;
4021
+ return `M${x1},${y1} A${r2},${r2} 0 ${largeArc},1 ${x2},${y2}`;
4022
+ }
4023
+ function radialPositions(cx, cy, innerR, outerR, count, startAngle = -Math.PI / 2) {
4024
+ return Array.from({ length: count }, (_, i) => {
4025
+ const angle = startAngle + Math.PI * 2 * i / count;
4026
+ return {
4027
+ x1: cx + innerR * Math.cos(angle),
4028
+ y1: cy + innerR * Math.sin(angle),
4029
+ x2: cx + outerR * Math.cos(angle),
4030
+ y2: cy + outerR * Math.sin(angle),
4031
+ angle
4032
+ };
4033
+ });
4034
+ }
4035
+ function gridPositions(startX, startY, cols, cellWidth, cellHeight, count) {
4036
+ return Array.from({ length: count }, (_, i) => {
4037
+ const col = i % cols;
4038
+ const row = Math.floor(i / cols);
4039
+ return {
4040
+ x: startX + col * cellWidth,
4041
+ y: startY + row * cellHeight,
4042
+ col,
4043
+ row
4044
+ };
4045
+ });
4046
+ }
4047
+ function curveControlPoint(x1, y1, x2, y2, offset) {
4048
+ const mx = (x1 + x2) / 2;
4049
+ const my = (y1 + y2) / 2;
4050
+ const dx = x2 - x1;
4051
+ const dy = y2 - y1;
4052
+ const len = Math.sqrt(dx * dx + dy * dy) || 1;
4053
+ return {
4054
+ cpx: mx + -dy / len * offset,
4055
+ cpy: my + dx / len * offset
4056
+ };
4057
+ }
4058
+ var avlSmId = 0;
4059
+ var AvlStateMachine = ({
4060
+ states,
4061
+ transitions,
4062
+ className,
4063
+ color = "var(--color-primary)",
4064
+ animated = false
4065
+ }) => {
4066
+ const ids = React8__default.default.useMemo(() => {
4067
+ avlSmId += 1;
4068
+ const base = `avl-sm-${avlSmId}`;
4069
+ return { glow: `${base}-glow`, grad: `${base}-grad` };
4070
+ }, []);
4071
+ const cx = 300;
4072
+ const cy = 200;
4073
+ const r2 = 150;
4074
+ const stateWidth = 90;
4075
+ const stateHeight = 36;
4076
+ const positions = ringPositions(cx, cy, r2, states.length);
4077
+ const stateIndex = new Map(states.map((s, i) => [s.name, i]));
4078
+ const pairCount = /* @__PURE__ */ new Map();
4079
+ const pairSeen = /* @__PURE__ */ new Map();
4080
+ for (const tr of transitions) {
4081
+ const key = [tr.from, tr.to].sort().join("|");
4082
+ pairCount.set(key, (pairCount.get(key) ?? 0) + 1);
4083
+ }
4084
+ return /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 600 400", xmlns: "http://www.w3.org/2000/svg", className, children: [
4085
+ /* @__PURE__ */ jsxRuntime.jsxs("defs", { children: [
4086
+ /* @__PURE__ */ jsxRuntime.jsxs("filter", { id: ids.glow, x: "-50%", y: "-50%", width: "200%", height: "200%", children: [
4087
+ /* @__PURE__ */ jsxRuntime.jsx("feGaussianBlur", { in: "SourceGraphic", stdDeviation: "3", result: "blur" }),
4088
+ /* @__PURE__ */ jsxRuntime.jsxs("feMerge", { children: [
4089
+ /* @__PURE__ */ jsxRuntime.jsx("feMergeNode", { in: "blur" }),
4090
+ /* @__PURE__ */ jsxRuntime.jsx("feMergeNode", { in: "SourceGraphic" })
4091
+ ] })
4092
+ ] }),
4093
+ /* @__PURE__ */ jsxRuntime.jsxs("linearGradient", { id: ids.grad, x1: "0%", y1: "0%", x2: "100%", y2: "100%", children: [
4094
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "0%", stopColor: color, stopOpacity: 0.1 }),
4095
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "100%", stopColor: color, stopOpacity: 0.05 })
4096
+ ] })
4097
+ ] }),
4098
+ animated && /* @__PURE__ */ jsxRuntime.jsx("style", { children: `
4099
+ @keyframes avl-sm-dash { from { stroke-dashoffset: 20; } to { stroke-dashoffset: 0; } }
4100
+ ` }),
4101
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx, cy, r: r2 + 30, fill: `url(#${ids.grad})` }),
4102
+ transitions.map((tr, i) => {
4103
+ if (tr.from !== tr.to) return null;
4104
+ const idx = stateIndex.get(tr.from);
4105
+ if (idx === void 0) return null;
4106
+ const pos = positions[idx];
4107
+ const loopR = 20;
4108
+ const loopY = pos.y - stateHeight / 2 - 4;
4109
+ const d = `M${pos.x - 14},${loopY} C${pos.x - 14},${loopY - loopR * 2} ${pos.x + 14},${loopY - loopR * 2} ${pos.x + 14},${loopY}`;
4110
+ return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
4111
+ /* @__PURE__ */ jsxRuntime.jsx(
4112
+ "path",
4113
+ {
4114
+ d,
4115
+ fill: "none",
4116
+ stroke: color,
4117
+ strokeWidth: 1.5,
4118
+ opacity: 0.7,
4119
+ markerEnd: `url(#${ids.grad})`
4120
+ }
4121
+ ),
4122
+ tr.event && /* @__PURE__ */ jsxRuntime.jsx(
4123
+ "text",
4124
+ {
4125
+ x: pos.x,
4126
+ y: loopY - loopR * 2 + 4,
4127
+ textAnchor: "middle",
4128
+ fill: color,
4129
+ fontSize: 9,
4130
+ fontFamily: "inherit",
4131
+ fontWeight: "bold",
4132
+ opacity: 0.8,
4133
+ children: tr.event
4134
+ }
4135
+ )
4136
+ ] }, `self-${i}`);
4137
+ }),
4138
+ transitions.map((tr, i) => {
4139
+ if (tr.from === tr.to) return null;
4140
+ const fromIdx = stateIndex.get(tr.from);
4141
+ const toIdx = stateIndex.get(tr.to);
4142
+ if (fromIdx === void 0 || toIdx === void 0) return null;
4143
+ const fp = positions[fromIdx];
4144
+ const tp = positions[toIdx];
4145
+ const dx = tp.x - fp.x;
4146
+ const dy = tp.y - fp.y;
4147
+ const dist = Math.sqrt(dx * dx + dy * dy) || 1;
4148
+ const nx = dx / dist;
4149
+ const ny = dy / dist;
4150
+ const pairKey = [tr.from, tr.to].sort().join("|");
4151
+ const totalForPair = pairCount.get(pairKey) ?? 1;
4152
+ const seenIdx = pairSeen.get(pairKey) ?? 0;
4153
+ pairSeen.set(pairKey, seenIdx + 1);
4154
+ const pairOffset = totalForPair > 1 ? (seenIdx - (totalForPair - 1) / 2) * 24 : 0;
4155
+ const x1 = fp.x + nx * (stateWidth / 2 + 4);
4156
+ const y1 = fp.y + ny * (stateHeight / 2 + 4);
4157
+ const x2 = tp.x - nx * (stateWidth / 2 + 8);
4158
+ const y2 = tp.y - ny * (stateHeight / 2 + 8);
4159
+ const t = 0.3;
4160
+ const labelX = x1 * (1 - t) + x2 * t;
4161
+ const labelY = y1 * (1 - t) + y2 * t;
4162
+ const perpX = -ny * (20 + Math.abs(pairOffset));
4163
+ const perpY = nx * (20 + Math.abs(pairOffset));
4164
+ const midToCenter = Math.sqrt((labelX - cx) ** 2 + (labelY - cy) ** 2);
4165
+ const testX = labelX + perpX;
4166
+ const testY = labelY + perpY;
4167
+ const testToCenter = Math.sqrt((testX - cx) ** 2 + (testY - cy) ** 2);
4168
+ const outSign = testToCenter > midToCenter ? 1 : -1;
4169
+ const lx = labelX + perpX * outSign + -ny * pairOffset;
4170
+ const ly = labelY + perpY * outSign + nx * pairOffset;
4171
+ return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
4172
+ /* @__PURE__ */ jsxRuntime.jsx(
4173
+ AvlTransition,
4174
+ {
4175
+ x1: x1 + -ny * pairOffset,
4176
+ y1: y1 + nx * pairOffset,
4177
+ x2: x2 + -ny * pairOffset,
4178
+ y2: y2 + nx * pairOffset,
4179
+ curved: states.length > 2,
4180
+ curveAwayFrom: { x: cx, y: cy },
4181
+ color,
4182
+ opacity: 0.7
4183
+ }
4184
+ ),
4185
+ tr.event && /* @__PURE__ */ jsxRuntime.jsx(
4186
+ "text",
4187
+ {
4188
+ x: lx,
4189
+ y: ly,
4190
+ textAnchor: "middle",
4191
+ fill: color,
4192
+ fontSize: 9,
4193
+ fontFamily: "inherit",
4194
+ fontWeight: "bold",
4195
+ opacity: 0.8,
4196
+ children: tr.event
4197
+ }
4198
+ ),
4199
+ tr.guard && /* @__PURE__ */ jsxRuntime.jsxs(
4200
+ "text",
4201
+ {
4202
+ x: lx,
4203
+ y: ly + 12,
4204
+ textAnchor: "middle",
4205
+ fill: color,
4206
+ fontSize: 8,
4207
+ fontFamily: "inherit",
4208
+ opacity: 0.6,
4209
+ children: [
4210
+ "[",
4211
+ tr.guard,
4212
+ "]"
4213
+ ]
4214
+ }
4215
+ ),
4216
+ tr.effects?.map((eff, j) => /* @__PURE__ */ jsxRuntime.jsx(
4217
+ AvlEffect,
4218
+ {
4219
+ x: lx + (j - ((tr.effects?.length ?? 1) - 1) / 2) * 14,
4220
+ y: ly + (tr.guard ? 22 : 12),
4221
+ effectType: eff,
4222
+ size: 5,
4223
+ color,
4224
+ opacity: 0.7
4225
+ },
4226
+ j
4227
+ ))
4228
+ ] }, `tr-${i}`);
4229
+ }),
4230
+ states.map((state, i) => {
4231
+ const pos = positions[i];
4232
+ return /* @__PURE__ */ jsxRuntime.jsx(
4233
+ AvlState,
4234
+ {
4235
+ x: pos.x - stateWidth / 2,
4236
+ y: pos.y - stateHeight / 2,
4237
+ width: stateWidth,
4238
+ height: stateHeight,
4239
+ name: state.name,
4240
+ isInitial: state.isInitial,
4241
+ isTerminal: state.isTerminal,
4242
+ color
4243
+ },
4244
+ state.name
4245
+ );
4246
+ })
4247
+ ] });
4248
+ };
4249
+ AvlStateMachine.displayName = "AvlStateMachine";
4250
+ var avlOuId = 0;
4251
+ var AvlOrbitalUnit = ({
4252
+ entityName,
4253
+ fields = 4,
4254
+ persistence = "persistent",
4255
+ traits,
4256
+ pages,
4257
+ className,
4258
+ color = "var(--color-primary)",
4259
+ animated = false
4260
+ }) => {
4261
+ const ids = React8__default.default.useMemo(() => {
4262
+ avlOuId += 1;
4263
+ const base = `avl-ou-${avlOuId}`;
4264
+ return { glow: `${base}-glow`, grad: `${base}-grad` };
4265
+ }, []);
4266
+ const cx = 300;
4267
+ const cy = 200;
4268
+ const entityR = 24;
4269
+ const orbitalR = 130;
4270
+ const traitBaseRx = 55;
4271
+ const traitBaseRy = 24;
4272
+ const traitRxStep = 20;
4273
+ const traitRyStep = 8;
4274
+ const traitAngleStep = traits.length > 1 ? 120 / (traits.length - 1) : 0;
4275
+ const traitAngleStart = traits.length > 1 ? -60 : 0;
4276
+ const pageAngleStart = -Math.PI / 3;
4277
+ const pageAngleStep = pages.length > 1 ? Math.PI * 0.8 / (pages.length - 1) : 0;
4278
+ return /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 600 400", xmlns: "http://www.w3.org/2000/svg", className, children: [
4279
+ /* @__PURE__ */ jsxRuntime.jsxs("defs", { children: [
4280
+ /* @__PURE__ */ jsxRuntime.jsxs("filter", { id: ids.glow, x: "-50%", y: "-50%", width: "200%", height: "200%", children: [
4281
+ /* @__PURE__ */ jsxRuntime.jsx("feGaussianBlur", { in: "SourceGraphic", stdDeviation: "3", result: "blur" }),
4282
+ /* @__PURE__ */ jsxRuntime.jsxs("feMerge", { children: [
4283
+ /* @__PURE__ */ jsxRuntime.jsx("feMergeNode", { in: "blur" }),
4284
+ /* @__PURE__ */ jsxRuntime.jsx("feMergeNode", { in: "SourceGraphic" })
4285
+ ] })
4286
+ ] }),
4287
+ /* @__PURE__ */ jsxRuntime.jsxs("radialGradient", { id: ids.grad, cx: "50%", cy: "50%", r: "50%", children: [
4288
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "0%", stopColor: color, stopOpacity: 0.08 }),
4289
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "100%", stopColor: color, stopOpacity: 0 })
4290
+ ] })
4291
+ ] }),
4292
+ animated && /* @__PURE__ */ jsxRuntime.jsx("style", { children: `
4293
+ @keyframes avl-ou-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
4294
+ ` }),
4295
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx, cy, r: orbitalR + 20, fill: `url(#${ids.grad})` }),
4296
+ /* @__PURE__ */ jsxRuntime.jsx(AvlOrbital, { cx, cy, r: orbitalR, label: entityName, color }),
4297
+ traits.map((trait, i) => {
4298
+ const rotation = traitAngleStart + i * traitAngleStep;
4299
+ const traitColor = trait.color ?? color;
4300
+ return /* @__PURE__ */ jsxRuntime.jsx(
4301
+ AvlTrait,
4302
+ {
4303
+ cx,
4304
+ cy,
4305
+ rx: traitBaseRx + i * traitRxStep,
4306
+ ry: traitBaseRy + i * traitRyStep,
4307
+ rotation,
4308
+ label: trait.name,
4309
+ color: traitColor,
4310
+ opacity: 0.7
4311
+ },
4312
+ trait.name
4313
+ );
4314
+ }),
4315
+ /* @__PURE__ */ jsxRuntime.jsx(
4316
+ AvlEntity,
4317
+ {
4318
+ x: cx,
4319
+ y: cy,
4320
+ r: entityR,
4321
+ fieldCount: fields,
4322
+ persistence,
4323
+ color
4324
+ }
4325
+ ),
4326
+ pages.map((page, i) => {
4327
+ const angle = pageAngleStart + i * pageAngleStep;
4328
+ const px = cx + orbitalR * Math.cos(angle);
4329
+ const py = cy + orbitalR * Math.sin(angle);
4330
+ return /* @__PURE__ */ jsxRuntime.jsx(
4331
+ AvlPage,
4332
+ {
4333
+ x: px,
4334
+ y: py,
4335
+ size: 10,
4336
+ label: page.name,
4337
+ color
4338
+ },
4339
+ page.name
4340
+ );
4341
+ })
4342
+ ] });
4546
4343
  };
4547
- var positionStyles = {
4548
- relative: "relative",
4549
- absolute: "absolute",
4550
- fixed: "fixed",
4551
- sticky: "sticky"
4344
+ AvlOrbitalUnit.displayName = "AvlOrbitalUnit";
4345
+ var avlCcId = 0;
4346
+ var AvlClosedCircuit = ({
4347
+ states,
4348
+ transitions,
4349
+ className,
4350
+ color = "var(--color-primary)",
4351
+ animated = false
4352
+ }) => {
4353
+ const ids = React8__default.default.useMemo(() => {
4354
+ avlCcId += 1;
4355
+ const base = `avl-cc-${avlCcId}`;
4356
+ return { glow: `${base}-glow`, grad: `${base}-grad`, arrow: `${base}-arrow` };
4357
+ }, []);
4358
+ const cx = 300;
4359
+ const cy = 200;
4360
+ const r2 = 120;
4361
+ const stateW = 80;
4362
+ const stateH = 32;
4363
+ const positions = ringPositions(cx, cy, r2, states.length);
4364
+ const stateIndex = new Map(states.map((s, i) => [s.name, i]));
4365
+ return /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 600 400", xmlns: "http://www.w3.org/2000/svg", className, children: [
4366
+ /* @__PURE__ */ jsxRuntime.jsxs("defs", { children: [
4367
+ /* @__PURE__ */ jsxRuntime.jsxs("filter", { id: ids.glow, x: "-50%", y: "-50%", width: "200%", height: "200%", children: [
4368
+ /* @__PURE__ */ jsxRuntime.jsx("feGaussianBlur", { in: "SourceGraphic", stdDeviation: "4", result: "blur" }),
4369
+ /* @__PURE__ */ jsxRuntime.jsxs("feMerge", { children: [
4370
+ /* @__PURE__ */ jsxRuntime.jsx("feMergeNode", { in: "blur" }),
4371
+ /* @__PURE__ */ jsxRuntime.jsx("feMergeNode", { in: "SourceGraphic" })
4372
+ ] })
4373
+ ] }),
4374
+ /* @__PURE__ */ jsxRuntime.jsxs("linearGradient", { id: ids.grad, x1: "0%", y1: "0%", x2: "100%", y2: "100%", children: [
4375
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "0%", stopColor: color, stopOpacity: 0.15 }),
4376
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "50%", stopColor: color, stopOpacity: 0.4 }),
4377
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "100%", stopColor: color, stopOpacity: 0.15 })
4378
+ ] }),
4379
+ /* @__PURE__ */ jsxRuntime.jsx(
4380
+ "marker",
4381
+ {
4382
+ id: ids.arrow,
4383
+ markerWidth: "8",
4384
+ markerHeight: "6",
4385
+ refX: "7",
4386
+ refY: "3",
4387
+ orient: "auto",
4388
+ markerUnits: "strokeWidth",
4389
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M0,0 L8,3 L0,6 Z", fill: color, opacity: 0.6 })
4390
+ }
4391
+ )
4392
+ ] }),
4393
+ animated && /* @__PURE__ */ jsxRuntime.jsx("style", { children: `
4394
+ @keyframes avl-cc-flow { from { stroke-dashoffset: 24; } to { stroke-dashoffset: 0; } }
4395
+ ` }),
4396
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx, cy, r: r2 + 30, fill: "none", stroke: color, strokeWidth: 0.3, opacity: 0.06 }),
4397
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx, cy, r: 50, fill: "none", stroke: color, strokeWidth: 0.5, opacity: 0.08 }),
4398
+ transitions.map((tr, i) => {
4399
+ const fromIdx = stateIndex.get(tr.from);
4400
+ const toIdx = stateIndex.get(tr.to);
4401
+ if (fromIdx === void 0 || toIdx === void 0) return null;
4402
+ const fp = positions[fromIdx];
4403
+ const tp = positions[toIdx];
4404
+ const dx = tp.x - fp.x;
4405
+ const dy = tp.y - fp.y;
4406
+ const dist = Math.sqrt(dx * dx + dy * dy) || 1;
4407
+ const nx = dx / dist;
4408
+ const ny = dy / dist;
4409
+ const x1 = fp.x + nx * (stateW / 2 + 4);
4410
+ const y1 = fp.y + ny * (stateH / 2 + 4);
4411
+ const x2 = tp.x - nx * (stateW / 2 + 8);
4412
+ const y2 = tp.y - ny * (stateH / 2 + 8);
4413
+ const mx = (x1 + x2) / 2;
4414
+ const my = (y1 + y2) / 2;
4415
+ const curvature = dist * 0.25;
4416
+ let perpX = -ny;
4417
+ let perpY = nx;
4418
+ const testX = mx + perpX * curvature;
4419
+ const testY = my + perpY * curvature;
4420
+ const distTest = Math.sqrt((testX - cx) ** 2 + (testY - cy) ** 2);
4421
+ const distMid = Math.sqrt((mx - cx) ** 2 + (my - cy) ** 2);
4422
+ if (distTest < distMid) {
4423
+ perpX = -perpX;
4424
+ perpY = -perpY;
4425
+ }
4426
+ const cpx = mx + perpX * curvature;
4427
+ const cpy = my + perpY * curvature;
4428
+ const d = `M${x1},${y1} Q${cpx},${cpy} ${x2},${y2}`;
4429
+ return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
4430
+ /* @__PURE__ */ jsxRuntime.jsx(
4431
+ "path",
4432
+ {
4433
+ d,
4434
+ fill: "none",
4435
+ stroke: `url(#${ids.grad})`,
4436
+ strokeWidth: 1.5,
4437
+ strokeDasharray: animated ? "8 6" : void 0,
4438
+ markerEnd: `url(#${ids.arrow})`,
4439
+ style: animated ? { animation: "avl-cc-flow 1.5s linear infinite" } : void 0
4440
+ }
4441
+ ),
4442
+ tr.event && /* @__PURE__ */ jsxRuntime.jsx(
4443
+ AvlEvent,
4444
+ {
4445
+ x: cpx,
4446
+ y: cpy - 14,
4447
+ size: 8,
4448
+ label: tr.event,
4449
+ color,
4450
+ opacity: 0.8
4451
+ }
4452
+ ),
4453
+ tr.guard && /* @__PURE__ */ jsxRuntime.jsx(
4454
+ AvlGuard,
4455
+ {
4456
+ x: mx,
4457
+ y: my - 8,
4458
+ size: 10,
4459
+ label: tr.guard,
4460
+ color,
4461
+ opacity: 0.6
4462
+ }
4463
+ ),
4464
+ tr.effects?.map((eff, j) => /* @__PURE__ */ jsxRuntime.jsx(
4465
+ AvlEffect,
4466
+ {
4467
+ x: mx + (j - ((tr.effects?.length ?? 1) - 1) / 2) * 14,
4468
+ y: my + 14,
4469
+ effectType: eff,
4470
+ size: 5,
4471
+ color,
4472
+ opacity: 0.7
4473
+ },
4474
+ j
4475
+ ))
4476
+ ] }, `cc-tr-${i}`);
4477
+ }),
4478
+ states.map((state, i) => {
4479
+ const pos = positions[i];
4480
+ return /* @__PURE__ */ jsxRuntime.jsx(
4481
+ AvlState,
4482
+ {
4483
+ x: pos.x - stateW / 2,
4484
+ y: pos.y - stateH / 2,
4485
+ width: stateW,
4486
+ height: stateH,
4487
+ name: state.name,
4488
+ color
4489
+ },
4490
+ state.name
4491
+ );
4492
+ }),
4493
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx, cy, r: 3, fill: color, opacity: 0.4 })
4494
+ ] });
4552
4495
  };
4553
- var Box = React6__default.default.forwardRef(
4554
- ({
4555
- padding,
4556
- paddingX,
4557
- paddingY,
4558
- margin,
4559
- marginX,
4560
- marginY,
4561
- bg = "transparent",
4562
- border = false,
4563
- rounded = "none",
4564
- shadow = "none",
4565
- display,
4566
- fullWidth = false,
4567
- fullHeight = false,
4568
- overflow,
4569
- position,
4570
- className,
4571
- children,
4572
- as: Component = "div",
4573
- action,
4574
- actionPayload,
4575
- hoverEvent,
4576
- onClick,
4577
- onMouseEnter,
4578
- onMouseLeave,
4579
- ...rest
4580
- }, ref) => {
4581
- const eventBus = useEventBus();
4582
- const handleClick = React6.useCallback((e) => {
4583
- if (action) {
4584
- e.stopPropagation();
4585
- eventBus.emit(`UI:${action}`, actionPayload ?? {});
4496
+ AvlClosedCircuit.displayName = "AvlClosedCircuit";
4497
+ var avlElId = 0;
4498
+ var AvlEmitListen = ({
4499
+ emitter,
4500
+ listener,
4501
+ eventName,
4502
+ className,
4503
+ color = "var(--color-primary)",
4504
+ animated = false
4505
+ }) => {
4506
+ const ids = React8__default.default.useMemo(() => {
4507
+ avlElId += 1;
4508
+ const base = `avl-el-${avlElId}`;
4509
+ return { arrow: `${base}-arrow`, grad: `${base}-grad` };
4510
+ }, []);
4511
+ const leftCx = 180;
4512
+ const rightCx = 420;
4513
+ const cy = 200;
4514
+ const orbR = 80;
4515
+ return /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 600 400", xmlns: "http://www.w3.org/2000/svg", className, children: [
4516
+ /* @__PURE__ */ jsxRuntime.jsxs("defs", { children: [
4517
+ /* @__PURE__ */ jsxRuntime.jsx(
4518
+ "marker",
4519
+ {
4520
+ id: ids.arrow,
4521
+ markerWidth: "8",
4522
+ markerHeight: "6",
4523
+ refX: "7",
4524
+ refY: "3",
4525
+ orient: "auto",
4526
+ markerUnits: "strokeWidth",
4527
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M0,0 L8,3 L0,6 Z", fill: color, opacity: 0.6 })
4528
+ }
4529
+ ),
4530
+ /* @__PURE__ */ jsxRuntime.jsxs("linearGradient", { id: ids.grad, x1: "0%", y1: "0%", x2: "100%", y2: "0%", children: [
4531
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "0%", stopColor: color, stopOpacity: 0.5 }),
4532
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "100%", stopColor: color, stopOpacity: 0.2 })
4533
+ ] })
4534
+ ] }),
4535
+ animated && /* @__PURE__ */ jsxRuntime.jsx("style", { children: `
4536
+ @keyframes avl-el-dash { from { stroke-dashoffset: 16; } to { stroke-dashoffset: 0; } }
4537
+ ` }),
4538
+ /* @__PURE__ */ jsxRuntime.jsx(AvlOrbital, { cx: leftCx, cy, r: orbR, label: emitter.name, color }),
4539
+ /* @__PURE__ */ jsxRuntime.jsx(AvlEntity, { x: leftCx, y: cy, r: 18, fieldCount: emitter.fields ?? 3, color }),
4540
+ /* @__PURE__ */ jsxRuntime.jsx(AvlOrbital, { cx: rightCx, cy, r: orbR, label: listener.name, color }),
4541
+ /* @__PURE__ */ jsxRuntime.jsx(AvlEntity, { x: rightCx, y: cy, r: 18, fieldCount: listener.fields ?? 3, color }),
4542
+ /* @__PURE__ */ jsxRuntime.jsx(
4543
+ "path",
4544
+ {
4545
+ d: `M${leftCx + orbR + 4},${cy} L${rightCx - orbR - 8},${cy}`,
4546
+ fill: "none",
4547
+ stroke: `url(#${ids.grad})`,
4548
+ strokeWidth: 2,
4549
+ strokeDasharray: "6 4",
4550
+ markerEnd: `url(#${ids.arrow})`,
4551
+ style: animated ? { animation: "avl-el-dash 1s linear infinite" } : void 0
4586
4552
  }
4587
- onClick?.(e);
4588
- }, [action, actionPayload, eventBus, onClick]);
4589
- const handleMouseEnter = React6.useCallback((e) => {
4590
- if (hoverEvent) {
4591
- eventBus.emit(`UI:${hoverEvent}`, { hovered: true });
4553
+ ),
4554
+ /* @__PURE__ */ jsxRuntime.jsx(
4555
+ AvlEffect,
4556
+ {
4557
+ x: leftCx + orbR + 20,
4558
+ y: cy - 20,
4559
+ effectType: "emit",
4560
+ size: 6,
4561
+ color,
4562
+ opacity: 0.8
4592
4563
  }
4593
- onMouseEnter?.(e);
4594
- }, [hoverEvent, eventBus, onMouseEnter]);
4595
- const handleMouseLeave = React6.useCallback((e) => {
4596
- if (hoverEvent) {
4597
- eventBus.emit(`UI:${hoverEvent}`, { hovered: false });
4564
+ ),
4565
+ eventName && /* @__PURE__ */ jsxRuntime.jsxs(
4566
+ "text",
4567
+ {
4568
+ x: 300,
4569
+ y: cy - 18,
4570
+ textAnchor: "middle",
4571
+ fill: color,
4572
+ fontSize: 11,
4573
+ fontFamily: "inherit",
4574
+ fontWeight: "bold",
4575
+ opacity: 0.8,
4576
+ children: [
4577
+ "~",
4578
+ eventName
4579
+ ]
4598
4580
  }
4599
- onMouseLeave?.(e);
4600
- }, [hoverEvent, eventBus, onMouseLeave]);
4601
- const isClickable = action || onClick;
4602
- const Comp = Component;
4603
- return /* @__PURE__ */ jsxRuntime.jsx(
4604
- Comp,
4581
+ ),
4582
+ /* @__PURE__ */ jsxRuntime.jsx(
4583
+ "text",
4605
4584
  {
4606
- ref,
4607
- className: cn(
4608
- // Padding
4609
- padding && paddingStyles[padding],
4610
- paddingX && paddingXStyles[paddingX],
4611
- paddingY && paddingYStyles[paddingY],
4612
- // Margin
4613
- margin && marginStyles[margin],
4614
- marginX && marginXStyles[marginX],
4615
- marginY && marginYStyles[marginY],
4616
- // Background
4617
- bgStyles[bg],
4618
- // Border - uses theme variables
4619
- border && "border-[length:var(--border-width)] border-[var(--color-border)]",
4620
- // Rounded
4621
- roundedStyles[rounded],
4622
- // Shadow
4623
- shadowStyles[shadow],
4624
- // Display
4625
- display && displayStyles[display],
4626
- // Dimensions
4627
- fullWidth && "w-full",
4628
- fullHeight && "h-full",
4629
- // Overflow
4630
- overflow && overflowStyles[overflow],
4631
- // Position
4632
- position && positionStyles[position],
4633
- // Cursor for clickable
4634
- isClickable && "cursor-pointer",
4635
- className
4636
- ),
4637
- onClick: isClickable ? handleClick : void 0,
4638
- onMouseEnter: hoverEvent || onMouseEnter ? handleMouseEnter : void 0,
4639
- onMouseLeave: hoverEvent || onMouseLeave ? handleMouseLeave : void 0,
4640
- ...rest,
4641
- children
4585
+ x: 300,
4586
+ y: cy + 18,
4587
+ textAnchor: "middle",
4588
+ fill: color,
4589
+ fontSize: 12,
4590
+ fontFamily: "inherit",
4591
+ opacity: 0.3,
4592
+ letterSpacing: 4,
4593
+ children: "~ ~ ~"
4642
4594
  }
4643
- );
4644
- }
4645
- );
4646
- Box.displayName = "Box";
4647
- var variantStyles = {
4648
- h1: "text-4xl font-bold tracking-tight text-[var(--color-foreground)]",
4649
- h2: "text-3xl font-bold tracking-tight text-[var(--color-foreground)]",
4650
- h3: "text-2xl font-bold text-[var(--color-foreground)]",
4651
- h4: "text-xl font-bold text-[var(--color-foreground)]",
4652
- h5: "text-lg font-bold text-[var(--color-foreground)]",
4653
- h6: "text-base font-bold text-[var(--color-foreground)]",
4654
- heading: "text-2xl font-bold text-[var(--color-foreground)]",
4655
- subheading: "text-lg font-semibold text-[var(--color-foreground)]",
4656
- body1: "text-base font-normal text-[var(--color-foreground)]",
4657
- body2: "text-sm font-normal text-[var(--color-foreground)]",
4658
- body: "text-base font-normal text-[var(--color-foreground)]",
4659
- caption: "text-xs font-normal text-[var(--color-muted-foreground)]",
4660
- overline: "text-xs uppercase tracking-wide font-bold text-[var(--color-muted-foreground)]",
4661
- small: "text-sm font-normal text-[var(--color-foreground)]",
4662
- large: "text-lg font-medium text-[var(--color-foreground)]",
4663
- label: "text-sm font-medium text-[var(--color-foreground)]"
4664
- };
4665
- var colorStyles = {
4666
- primary: "text-[var(--color-foreground)]",
4667
- secondary: "text-[var(--color-muted-foreground)]",
4668
- muted: "text-[var(--color-muted-foreground)]",
4669
- error: "text-[var(--color-error)]",
4670
- success: "text-[var(--color-success)]",
4671
- warning: "text-[var(--color-warning)]",
4672
- inherit: "text-inherit"
4673
- };
4674
- var weightStyles = {
4675
- light: "font-light",
4676
- normal: "font-normal",
4677
- medium: "font-medium",
4678
- semibold: "font-semibold",
4679
- bold: "font-bold"
4680
- };
4681
- var defaultElements = {
4682
- h1: "h1",
4683
- h2: "h2",
4684
- h3: "h3",
4685
- h4: "h4",
4686
- h5: "h5",
4687
- h6: "h6",
4688
- heading: "h2",
4689
- subheading: "h3",
4690
- body1: "p",
4691
- body2: "p",
4692
- body: "p",
4693
- caption: "span",
4694
- overline: "span",
4695
- small: "span",
4696
- large: "p",
4697
- label: "span"
4595
+ )
4596
+ ] });
4698
4597
  };
4699
- var typographySizeStyles = {
4700
- xs: "text-xs",
4701
- sm: "text-sm",
4702
- md: "text-base",
4703
- lg: "text-lg",
4704
- xl: "text-xl",
4705
- "2xl": "text-2xl",
4706
- "3xl": "text-3xl"
4598
+ AvlEmitListen.displayName = "AvlEmitListen";
4599
+ var SLOT_PRESETS = {
4600
+ header: { x: 10, y: 5, width: 340, height: 35 },
4601
+ main: { x: 120, y: 50, width: 230, height: 195 },
4602
+ sidebar: { x: 10, y: 50, width: 100, height: 195 },
4603
+ modal: { x: 80, y: 60, width: 200, height: 140 },
4604
+ drawer: { x: 220, y: 50, width: 130, height: 195 },
4605
+ toast: { x: 220, y: 210, width: 130, height: 35 },
4606
+ footer: { x: 10, y: 220, width: 340, height: 30 },
4607
+ center: { x: 60, y: 50, width: 240, height: 195 },
4608
+ "hud-top": { x: 10, y: 5, width: 340, height: 30 },
4609
+ "hud-bottom": { x: 10, y: 220, width: 340, height: 30 }
4707
4610
  };
4708
- var overflowStyles2 = {
4709
- visible: "overflow-visible",
4710
- hidden: "overflow-hidden",
4711
- wrap: "break-words overflow-hidden",
4712
- "clamp-2": "overflow-hidden line-clamp-2",
4713
- "clamp-3": "overflow-hidden line-clamp-3"
4611
+ function resolveSlot(slot, fallbackIdx) {
4612
+ if (slot.x !== void 0 && slot.y !== void 0 && slot.width !== void 0 && slot.height !== void 0) {
4613
+ return slot;
4614
+ }
4615
+ const preset = SLOT_PRESETS[slot.name];
4616
+ if (preset) {
4617
+ return {
4618
+ name: slot.name,
4619
+ x: slot.x ?? preset.x,
4620
+ y: slot.y ?? preset.y,
4621
+ width: slot.width ?? preset.width,
4622
+ height: slot.height ?? preset.height
4623
+ };
4624
+ }
4625
+ const col = fallbackIdx % 2;
4626
+ const row = Math.floor(fallbackIdx / 2);
4627
+ return {
4628
+ name: slot.name,
4629
+ x: 10 + col * 175,
4630
+ y: 50 + row * 100,
4631
+ width: 165,
4632
+ height: 90
4633
+ };
4634
+ }
4635
+ var AvlSlotMap = ({
4636
+ slots,
4637
+ pageWidth = 360,
4638
+ pageHeight = 280,
4639
+ className,
4640
+ color = "var(--color-primary)",
4641
+ animated = false
4642
+ }) => {
4643
+ const ox = (600 - pageWidth) / 2;
4644
+ const oy = (400 - pageHeight) / 2;
4645
+ let unknownIdx = 0;
4646
+ const resolvedSlots = slots.map((slot) => {
4647
+ const isUnknown = !SLOT_PRESETS[slot.name] && (slot.x === void 0 || slot.y === void 0);
4648
+ const resolved = resolveSlot(slot, isUnknown ? unknownIdx : 0);
4649
+ if (isUnknown) unknownIdx++;
4650
+ return resolved;
4651
+ });
4652
+ return /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 600 400", xmlns: "http://www.w3.org/2000/svg", className, children: [
4653
+ animated && /* @__PURE__ */ jsxRuntime.jsx("style", { children: `
4654
+ @keyframes avl-slot-pulse { 0%, 100% { opacity: 0.15; } 50% { opacity: 0.25; } }
4655
+ ` }),
4656
+ /* @__PURE__ */ jsxRuntime.jsx(
4657
+ "rect",
4658
+ {
4659
+ x: ox,
4660
+ y: oy,
4661
+ width: pageWidth,
4662
+ height: pageHeight,
4663
+ rx: 4,
4664
+ ry: 4,
4665
+ fill: "none",
4666
+ stroke: color,
4667
+ strokeWidth: 2
4668
+ }
4669
+ ),
4670
+ /* @__PURE__ */ jsxRuntime.jsx(
4671
+ "rect",
4672
+ {
4673
+ x: ox,
4674
+ y: oy,
4675
+ width: pageWidth,
4676
+ height: 24,
4677
+ rx: 4,
4678
+ ry: 4,
4679
+ fill: color,
4680
+ opacity: 0.1
4681
+ }
4682
+ ),
4683
+ /* @__PURE__ */ jsxRuntime.jsx(
4684
+ "text",
4685
+ {
4686
+ x: ox + pageWidth / 2,
4687
+ y: oy + 16,
4688
+ textAnchor: "middle",
4689
+ fill: color,
4690
+ fontSize: 10,
4691
+ fontFamily: "inherit",
4692
+ fontWeight: "bold",
4693
+ children: "Page Layout"
4694
+ }
4695
+ ),
4696
+ resolvedSlots.map((slot) => {
4697
+ const isOverlay = ["modal", "drawer", "toast"].includes(slot.name);
4698
+ return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
4699
+ isOverlay && /* @__PURE__ */ jsxRuntime.jsx(
4700
+ "rect",
4701
+ {
4702
+ x: ox + slot.x + 3,
4703
+ y: oy + 24 + slot.y + 3,
4704
+ width: slot.width,
4705
+ height: slot.height,
4706
+ rx: 3,
4707
+ ry: 3,
4708
+ fill: "black",
4709
+ opacity: 0.06
4710
+ }
4711
+ ),
4712
+ /* @__PURE__ */ jsxRuntime.jsx(
4713
+ "rect",
4714
+ {
4715
+ x: ox + slot.x,
4716
+ y: oy + 24 + slot.y,
4717
+ width: slot.width,
4718
+ height: slot.height,
4719
+ rx: 3,
4720
+ ry: 3,
4721
+ fill: isOverlay ? "var(--color-surface, #fff)" : color,
4722
+ opacity: isOverlay ? 0.9 : 0.08,
4723
+ stroke: color,
4724
+ strokeWidth: isOverlay ? 1.5 : 1,
4725
+ strokeDasharray: isOverlay ? "6 3" : "4 2",
4726
+ style: animated ? { animation: "avl-slot-pulse 2s ease-in-out infinite" } : void 0
4727
+ }
4728
+ ),
4729
+ /* @__PURE__ */ jsxRuntime.jsxs(
4730
+ "text",
4731
+ {
4732
+ x: ox + slot.x + slot.width / 2,
4733
+ y: oy + 24 + slot.y + slot.height / 2,
4734
+ textAnchor: "middle",
4735
+ dominantBaseline: "central",
4736
+ fill: color,
4737
+ fontSize: 9,
4738
+ fontFamily: "inherit",
4739
+ opacity: 0.6,
4740
+ children: [
4741
+ slot.name,
4742
+ isOverlay ? " (overlay)" : ""
4743
+ ]
4744
+ }
4745
+ )
4746
+ ] }, slot.name);
4747
+ })
4748
+ ] });
4714
4749
  };
4715
- var Typography = ({
4716
- variant: variantProp,
4717
- level,
4718
- color = "primary",
4719
- align,
4720
- weight,
4721
- size,
4722
- truncate = false,
4723
- overflow,
4724
- as,
4725
- id,
4726
- className,
4727
- style,
4728
- content,
4729
- children
4730
- }) => {
4731
- const variant = variantProp ?? (level ? `h${level}` : "body1");
4732
- const Component = as || defaultElements[variant];
4733
- const Comp = Component;
4734
- return /* @__PURE__ */ jsxRuntime.jsx(
4735
- Comp,
4736
- {
4737
- id,
4738
- className: cn(
4739
- variantStyles[variant],
4740
- colorStyles[color],
4741
- weight && weightStyles[weight],
4742
- size && typographySizeStyles[size],
4743
- align && `text-${align}`,
4744
- truncate && "truncate overflow-hidden text-ellipsis",
4745
- overflow && overflowStyles2[overflow],
4746
- className
4747
- ),
4748
- style,
4749
- children: children ?? content
4750
- }
4750
+ AvlSlotMap.displayName = "AvlSlotMap";
4751
+ var avlEtId = 0;
4752
+ function layoutTree(node, x, y, hSpacing, vSpacing) {
4753
+ const children = node.children ?? [];
4754
+ if (children.length === 0) {
4755
+ return { label: node.label, type: node.type, x, y, children: [] };
4756
+ }
4757
+ const totalWidth = (children.length - 1) * hSpacing;
4758
+ const startX = x - totalWidth / 2;
4759
+ const layoutChildren = children.map(
4760
+ (child, i) => layoutTree(child, startX + i * hSpacing, y + vSpacing, hSpacing * 0.75, vSpacing)
4751
4761
  );
4752
- };
4753
- Typography.displayName = "Typography";
4754
- var gapStyles = {
4755
- none: "gap-0",
4756
- xs: "gap-1",
4757
- sm: "gap-2",
4758
- md: "gap-4",
4759
- lg: "gap-6",
4760
- xl: "gap-8",
4761
- "2xl": "gap-12"
4762
- };
4763
- var alignStyles = {
4764
- start: "items-start",
4765
- center: "items-center",
4766
- end: "items-end",
4767
- stretch: "items-stretch",
4768
- baseline: "items-baseline"
4769
- };
4770
- var justifyStyles = {
4771
- start: "justify-start",
4772
- center: "justify-center",
4773
- end: "justify-end",
4774
- between: "justify-between",
4775
- around: "justify-around",
4776
- evenly: "justify-evenly"
4777
- };
4778
- var Stack = ({
4779
- direction = "vertical",
4780
- gap = "md",
4781
- align = "stretch",
4782
- justify = "start",
4783
- wrap = false,
4784
- reverse = false,
4785
- flex = false,
4762
+ return { label: node.label, type: node.type, x, y, children: layoutChildren };
4763
+ }
4764
+ function nodeColor(type, baseColor) {
4765
+ switch (type) {
4766
+ case "operator":
4767
+ return baseColor;
4768
+ case "literal":
4769
+ return baseColor;
4770
+ case "binding":
4771
+ return baseColor;
4772
+ }
4773
+ }
4774
+ function renderNode(node, color, glowId) {
4775
+ const labelLen = node.label.length;
4776
+ const baseR = node.type === "operator" ? 20 : 16;
4777
+ const r2 = Math.max(baseR, labelLen * 3.5 + 6);
4778
+ const nc = nodeColor(node.type, color);
4779
+ return /* @__PURE__ */ jsxRuntime.jsxs(React8__default.default.Fragment, { children: [
4780
+ node.children.map((child, i) => {
4781
+ const childR = Math.max(
4782
+ child.type === "operator" ? 20 : 16,
4783
+ child.label.length * 3.5 + 6
4784
+ );
4785
+ return /* @__PURE__ */ jsxRuntime.jsx(
4786
+ "line",
4787
+ {
4788
+ x1: node.x,
4789
+ y1: node.y + (node.type === "operator" ? r2 * 0.7 : r2),
4790
+ x2: child.x,
4791
+ y2: child.y - (child.type === "operator" ? childR * 0.7 : childR),
4792
+ stroke: color,
4793
+ strokeWidth: 1,
4794
+ opacity: 0.3
4795
+ },
4796
+ `line-${i}`
4797
+ );
4798
+ }),
4799
+ node.type === "operator" ? /* @__PURE__ */ jsxRuntime.jsx(
4800
+ "rect",
4801
+ {
4802
+ x: node.x - r2,
4803
+ y: node.y - r2 * 0.6,
4804
+ width: r2 * 2,
4805
+ height: r2 * 1.2,
4806
+ rx: 4,
4807
+ ry: 4,
4808
+ fill: color,
4809
+ fillOpacity: 0.15,
4810
+ stroke: nc,
4811
+ strokeWidth: 1.5
4812
+ }
4813
+ ) : node.type === "binding" ? /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: node.x, cy: node.y, r: r2, fill: "none", stroke: nc, strokeWidth: 1.5, strokeDasharray: "3 2" }) : /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: node.x, cy: node.y, r: r2, fill: "none", stroke: nc, strokeWidth: 1, opacity: 0.5 }),
4814
+ /* @__PURE__ */ jsxRuntime.jsx(
4815
+ "text",
4816
+ {
4817
+ x: node.x,
4818
+ y: node.y + 1,
4819
+ textAnchor: "middle",
4820
+ dominantBaseline: "central",
4821
+ fill: nc,
4822
+ fontSize: node.type === "operator" ? 11 : 10,
4823
+ fontFamily: "inherit",
4824
+ fontWeight: node.type === "operator" ? "bold" : "normal",
4825
+ children: node.type === "binding" ? `@${node.label}` : node.label
4826
+ }
4827
+ ),
4828
+ node.children.map((child) => renderNode(child, color))
4829
+ ] }, `${node.label}-${node.x}-${node.y}`);
4830
+ }
4831
+ var AvlExprTree = ({
4832
+ expression,
4786
4833
  className,
4787
- style,
4788
- children,
4789
- as: Component = "div",
4790
- onClick,
4791
- onKeyDown,
4792
- role,
4793
- tabIndex,
4794
- action,
4795
- actionPayload,
4796
- responsive = false
4834
+ color = "var(--color-primary)"
4797
4835
  }) => {
4798
- const eventBus = useEventBus();
4799
- const handleClick = (e) => {
4800
- if (action) {
4801
- eventBus.emit(`UI:${action}`, actionPayload ?? {});
4802
- }
4803
- onClick?.(e);
4804
- };
4805
- const isHorizontal = direction === "horizontal";
4806
- const directionClass = responsive && isHorizontal ? reverse ? "flex-col-reverse md:flex-row-reverse" : "flex-col md:flex-row" : isHorizontal ? reverse ? "flex-row-reverse" : "flex-row" : reverse ? "flex-col-reverse" : "flex-col";
4807
- const Comp = Component;
4808
- return /* @__PURE__ */ jsxRuntime.jsx(
4809
- Comp,
4810
- {
4811
- className: cn(
4812
- "flex",
4813
- directionClass,
4814
- gapStyles[gap],
4815
- alignStyles[align],
4816
- justifyStyles[justify],
4817
- wrap && "flex-wrap",
4818
- flex && "flex-1",
4819
- className
4820
- ),
4821
- style,
4822
- onClick: action || onClick ? handleClick : void 0,
4823
- onKeyDown,
4824
- role,
4825
- tabIndex,
4826
- children
4827
- }
4828
- );
4836
+ const ids = React8__default.default.useMemo(() => {
4837
+ avlEtId += 1;
4838
+ return { glow: `avl-et-${avlEtId}-glow` };
4839
+ }, []);
4840
+ const layout = layoutTree(expression, 300, 60, 200, 90);
4841
+ return /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 600 400", xmlns: "http://www.w3.org/2000/svg", className, children: [
4842
+ /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsxs("filter", { id: ids.glow, x: "-50%", y: "-50%", width: "200%", height: "200%", children: [
4843
+ /* @__PURE__ */ jsxRuntime.jsx("feGaussianBlur", { in: "SourceGraphic", stdDeviation: "2", result: "blur" }),
4844
+ /* @__PURE__ */ jsxRuntime.jsxs("feMerge", { children: [
4845
+ /* @__PURE__ */ jsxRuntime.jsx("feMergeNode", { in: "blur" }),
4846
+ /* @__PURE__ */ jsxRuntime.jsx("feMergeNode", { in: "SourceGraphic" })
4847
+ ] })
4848
+ ] }) }),
4849
+ renderNode(layout, color, ids.glow)
4850
+ ] });
4829
4851
  };
4830
- var HStack = (props) => /* @__PURE__ */ jsxRuntime.jsx(Stack, { direction: "horizontal", ...props });
4852
+ AvlExprTree.displayName = "AvlExprTree";
4831
4853
 
4832
4854
  // components/organisms/avl/avl-schema-parser.ts
4833
4855
  function getEntity(orbital) {
@@ -5171,6 +5193,14 @@ function zoomReducer(state, action) {
5171
5193
  }
5172
5194
  return state;
5173
5195
  }
5196
+ case "SWITCH_TRAIT": {
5197
+ if (state.level !== "trait" || state.animating) return state;
5198
+ return {
5199
+ ...state,
5200
+ selectedTrait: action.trait,
5201
+ selectedTransition: null
5202
+ };
5203
+ }
5174
5204
  case "RESET": {
5175
5205
  return initialZoomState;
5176
5206
  }
@@ -5203,16 +5233,16 @@ var AvlClickTarget = ({
5203
5233
  label,
5204
5234
  children
5205
5235
  }) => {
5206
- const [hovering, setHovering] = React6.useState(false);
5207
- const handleMouseEnter = React6.useCallback(() => {
5236
+ const [hovering, setHovering] = React8.useState(false);
5237
+ const handleMouseEnter = React8.useCallback(() => {
5208
5238
  setHovering(true);
5209
5239
  onHover?.(true);
5210
5240
  }, [onHover]);
5211
- const handleMouseLeave = React6.useCallback(() => {
5241
+ const handleMouseLeave = React8.useCallback(() => {
5212
5242
  setHovering(false);
5213
5243
  onHover?.(false);
5214
5244
  }, [onHover]);
5215
- const handleKeyDown = React6.useCallback((e) => {
5245
+ const handleKeyDown = React8.useCallback((e) => {
5216
5246
  if (e.key === "Enter" || e.key === " ") {
5217
5247
  e.preventDefault();
5218
5248
  onClick();
@@ -5378,12 +5408,15 @@ var AvlApplicationScene = ({
5378
5408
  AvlApplicationScene.displayName = "AvlApplicationScene";
5379
5409
  var CX = 300;
5380
5410
  var CY = 200;
5411
+ var VIEWBOX_H = 400;
5381
5412
  var ORBITAL_R2 = 130;
5382
5413
  var ENTITY_R2 = 24;
5383
5414
  var AvlOrbitalScene = ({
5384
5415
  data,
5385
5416
  color = "var(--color-primary)",
5386
- onTraitClick
5417
+ highlightedTrait,
5418
+ onTraitClick,
5419
+ onTraitHighlight
5387
5420
  }) => {
5388
5421
  const traitAngleStart = -Math.PI / 3;
5389
5422
  const traitAngleStep = data.traits.length > 1 ? Math.PI * 1.2 / (data.traits.length - 1) : 0;
@@ -5409,7 +5442,7 @@ var AvlOrbitalScene = ({
5409
5442
  rotation: rotationDeg,
5410
5443
  label: trait.name,
5411
5444
  color,
5412
- opacity: 0.7
5445
+ opacity: highlightedTrait ? highlightedTrait === trait.name ? 1 : 0.25 : 0.7
5413
5446
  }
5414
5447
  ),
5415
5448
  onTraitClick && /* @__PURE__ */ jsxRuntime.jsx(
@@ -5482,6 +5515,54 @@ var AvlOrbitalScene = ({
5482
5515
  const py = CY + (ORBITAL_R2 + 15) * Math.sin(angle);
5483
5516
  return /* @__PURE__ */ jsxRuntime.jsx(AvlPage, { x: px, y: py, label: page.route, color }, page.name);
5484
5517
  }),
5518
+ data.traits.length > 1 && /* @__PURE__ */ jsxRuntime.jsx("g", { children: data.traits.map((trait, i) => {
5519
+ const pillW = 70;
5520
+ const gap = 8;
5521
+ const totalW = data.traits.length * pillW + (data.traits.length - 1) * gap;
5522
+ const startX = CX - totalW / 2;
5523
+ const px = startX + i * (pillW + gap);
5524
+ const py = VIEWBOX_H - 30;
5525
+ const isHighlighted = highlightedTrait === trait.name;
5526
+ return /* @__PURE__ */ jsxRuntime.jsxs(
5527
+ "g",
5528
+ {
5529
+ style: { cursor: "pointer" },
5530
+ onClick: () => onTraitClick?.(trait.name, { x: CX, y: CY }),
5531
+ onMouseEnter: () => onTraitHighlight?.(trait.name),
5532
+ onMouseLeave: () => onTraitHighlight?.(null),
5533
+ children: [
5534
+ /* @__PURE__ */ jsxRuntime.jsx(
5535
+ "rect",
5536
+ {
5537
+ x: px,
5538
+ y: py,
5539
+ width: pillW,
5540
+ height: 22,
5541
+ rx: 11,
5542
+ fill: isHighlighted ? color : "transparent",
5543
+ stroke: color,
5544
+ strokeWidth: isHighlighted ? 1.5 : 0.8,
5545
+ opacity: isHighlighted ? 0.15 : 0.3
5546
+ }
5547
+ ),
5548
+ /* @__PURE__ */ jsxRuntime.jsx(
5549
+ "text",
5550
+ {
5551
+ x: px + pillW / 2,
5552
+ y: py + 14,
5553
+ textAnchor: "middle",
5554
+ fill: color,
5555
+ fontSize: 8,
5556
+ fontWeight: isHighlighted ? "bold" : "normal",
5557
+ opacity: isHighlighted ? 1 : 0.6,
5558
+ children: trait.name.length > 10 ? trait.name.slice(0, 9) + "\u2026" : trait.name
5559
+ }
5560
+ )
5561
+ ]
5562
+ },
5563
+ `tab-${trait.name}`
5564
+ );
5565
+ }) }),
5485
5566
  data.externalLinks.map((link, i) => {
5486
5567
  const isOut = link.direction === "out";
5487
5568
  const edgeX = isOut ? 580 : 20;
@@ -5644,9 +5725,9 @@ var AvlTraitScene = ({
5644
5725
  color = "var(--color-primary)",
5645
5726
  onTransitionClick
5646
5727
  }) => {
5647
- const [layout, setLayout] = React6.useState(null);
5648
- const dataKey = React6.useMemo(() => JSON.stringify(data), [data]);
5649
- React6.useEffect(() => {
5728
+ const [layout, setLayout] = React8.useState(null);
5729
+ const dataKey = React8.useMemo(() => JSON.stringify(data), [data]);
5730
+ React8.useEffect(() => {
5650
5731
  computeLayout(data).then(setLayout).catch(console.error);
5651
5732
  }, [dataKey]);
5652
5733
  if (!layout) {
@@ -6147,7 +6228,7 @@ var AvlLegend = ({
6147
6228
  };
6148
6229
  AvlLegend.displayName = "AvlLegend";
6149
6230
  var VIEWBOX_W = 600;
6150
- var VIEWBOX_H = 400;
6231
+ var VIEWBOX_H2 = 400;
6151
6232
  var ANIMATION_DURATION = 600;
6152
6233
  var AvlCosmicZoom = ({
6153
6234
  schema: schemaProp,
@@ -6161,7 +6242,7 @@ var AvlCosmicZoom = ({
6161
6242
  height = 400,
6162
6243
  stateCoverage
6163
6244
  }) => {
6164
- const schema = React6.useMemo(() => {
6245
+ const schema = React8.useMemo(() => {
6165
6246
  if (typeof schemaProp === "string") {
6166
6247
  try {
6167
6248
  return JSON.parse(schemaProp);
@@ -6171,28 +6252,28 @@ var AvlCosmicZoom = ({
6171
6252
  }
6172
6253
  return schemaProp;
6173
6254
  }, [schemaProp]);
6174
- const [state, dispatch] = React6.useReducer(zoomReducer, initialZoomState);
6175
- const sceneRef = React6.useRef(null);
6176
- const [transitionStyle, setTransitionStyle] = React6.useState({});
6177
- React6.useEffect(() => {
6255
+ const [state, dispatch] = React8.useReducer(zoomReducer, initialZoomState);
6256
+ const sceneRef = React8.useRef(null);
6257
+ const [transitionStyle, setTransitionStyle] = React8.useState({});
6258
+ React8.useEffect(() => {
6178
6259
  if (initialOrbital) {
6179
- dispatch({ type: "ZOOM_INTO_ORBITAL", orbital: initialOrbital, targetPosition: { x: VIEWBOX_W / 2, y: VIEWBOX_H / 2 } });
6260
+ dispatch({ type: "ZOOM_INTO_ORBITAL", orbital: initialOrbital, targetPosition: { x: VIEWBOX_W / 2, y: VIEWBOX_H2 / 2 } });
6180
6261
  setTimeout(() => dispatch({ type: "ANIMATION_COMPLETE" }), 0);
6181
6262
  if (initialTrait) {
6182
6263
  setTimeout(() => {
6183
- dispatch({ type: "ZOOM_INTO_TRAIT", trait: initialTrait, targetPosition: { x: VIEWBOX_W / 2, y: VIEWBOX_H / 2 } });
6264
+ dispatch({ type: "ZOOM_INTO_TRAIT", trait: initialTrait, targetPosition: { x: VIEWBOX_W / 2, y: VIEWBOX_H2 / 2 } });
6184
6265
  setTimeout(() => dispatch({ type: "ANIMATION_COMPLETE" }), 0);
6185
6266
  }, 10);
6186
6267
  }
6187
6268
  }
6188
6269
  }, [initialOrbital, initialTrait]);
6189
- React6.useEffect(() => {
6270
+ React8.useEffect(() => {
6190
6271
  onZoomChange?.(state.level, {
6191
6272
  orbital: state.selectedOrbital ?? void 0,
6192
6273
  trait: state.selectedTrait ?? void 0
6193
6274
  });
6194
6275
  }, [state.level, state.selectedOrbital, state.selectedTrait, onZoomChange]);
6195
- React6.useEffect(() => {
6276
+ React8.useEffect(() => {
6196
6277
  if (!state.animating || !animated) {
6197
6278
  if (state.animating) {
6198
6279
  dispatch({ type: "ANIMATION_COMPLETE" });
@@ -6204,7 +6285,7 @@ var AvlCosmicZoom = ({
6204
6285
  if (!target) return;
6205
6286
  if (state.animationDirection === "in") {
6206
6287
  setTransitionStyle({
6207
- transform: `scale(${target.scale}) translate(${-(target.x - VIEWBOX_W / 2)}px, ${-(target.y - VIEWBOX_H / 2)}px)`,
6288
+ transform: `scale(${target.scale}) translate(${-(target.x - VIEWBOX_W / 2)}px, ${-(target.y - VIEWBOX_H2 / 2)}px)`,
6208
6289
  transformOrigin: `${target.x}px ${target.y}px`,
6209
6290
  transition: `transform ${ANIMATION_DURATION}ms cubic-bezier(0.4, 0, 0.2, 1), opacity ${ANIMATION_DURATION}ms ease`,
6210
6291
  opacity: 0.3
@@ -6223,21 +6304,25 @@ var AvlCosmicZoom = ({
6223
6304
  }, ANIMATION_DURATION);
6224
6305
  return () => clearTimeout(timer);
6225
6306
  }, [state.animating, state.animationDirection, state.animationTarget, animated]);
6226
- const handleKeyDown = React6.useCallback((e) => {
6307
+ const handleKeyDown = React8.useCallback((e) => {
6227
6308
  if (e.key === "Escape") {
6228
6309
  dispatch({ type: "ZOOM_OUT" });
6229
6310
  }
6230
6311
  }, []);
6231
- const handleOrbitalClick = React6.useCallback((name, pos) => {
6312
+ const handleOrbitalClick = React8.useCallback((name, pos) => {
6232
6313
  dispatch({ type: "ZOOM_INTO_ORBITAL", orbital: name, targetPosition: pos });
6233
6314
  }, []);
6234
- const handleTraitClick = React6.useCallback((name, pos) => {
6315
+ const handleTraitClick = React8.useCallback((name, pos) => {
6235
6316
  dispatch({ type: "ZOOM_INTO_TRAIT", trait: name, targetPosition: pos });
6236
6317
  }, []);
6237
- const handleTransitionClick = React6.useCallback((index, pos) => {
6318
+ const handleTraitSwitch = React8.useCallback((name) => {
6319
+ dispatch({ type: "SWITCH_TRAIT", trait: name });
6320
+ }, []);
6321
+ const [highlightedTrait, setHighlightedTrait] = React8__default.default.useState(null);
6322
+ const handleTransitionClick = React8.useCallback((index, pos) => {
6238
6323
  dispatch({ type: "ZOOM_INTO_TRANSITION", transitionIndex: index, targetPosition: pos });
6239
6324
  }, []);
6240
- const handleBreadcrumbClick = React6.useCallback((targetLevel) => {
6325
+ const handleBreadcrumbClick = React8.useCallback((targetLevel) => {
6241
6326
  const levelOrder = ["application", "orbital", "trait", "transition"];
6242
6327
  const currentIdx = levelOrder.indexOf(state.level);
6243
6328
  const targetIdx = levelOrder.indexOf(targetLevel);
@@ -6245,7 +6330,7 @@ var AvlCosmicZoom = ({
6245
6330
  dispatch({ type: "ZOOM_OUT" });
6246
6331
  }
6247
6332
  }, [state.level]);
6248
- const sceneContent = React6.useMemo(() => {
6333
+ const sceneContent = React8.useMemo(() => {
6249
6334
  switch (state.level) {
6250
6335
  case "application": {
6251
6336
  const data = parseApplicationLevel(schema);
@@ -6267,7 +6352,9 @@ var AvlCosmicZoom = ({
6267
6352
  {
6268
6353
  data,
6269
6354
  color,
6270
- onTraitClick: handleTraitClick
6355
+ highlightedTrait,
6356
+ onTraitClick: handleTraitClick,
6357
+ onTraitHighlight: setHighlightedTrait
6271
6358
  }
6272
6359
  );
6273
6360
  }
@@ -6299,7 +6386,7 @@ var AvlCosmicZoom = ({
6299
6386
  default:
6300
6387
  return null;
6301
6388
  }
6302
- }, [state.level, state.selectedOrbital, state.selectedTrait, state.selectedTransition, schema, color, handleOrbitalClick, handleTraitClick, handleTransitionClick]);
6389
+ }, [state.level, state.selectedOrbital, state.selectedTrait, state.selectedTransition, schema, color, handleOrbitalClick, handleTraitClick, handleTransitionClick, highlightedTrait, setHighlightedTrait]);
6303
6390
  const breadcrumbs = getBreadcrumbs(state);
6304
6391
  return /* @__PURE__ */ jsxRuntime.jsxs(
6305
6392
  Box,
@@ -6315,7 +6402,7 @@ var AvlCosmicZoom = ({
6315
6402
  gap: "xs",
6316
6403
  align: "center",
6317
6404
  className: "absolute top-2 left-2 z-10 bg-[var(--color-surface)]/80 backdrop-blur rounded-md px-3 py-1.5",
6318
- children: breadcrumbs.map((crumb, i) => /* @__PURE__ */ jsxRuntime.jsxs(React6__default.default.Fragment, { children: [
6405
+ children: breadcrumbs.map((crumb, i) => /* @__PURE__ */ jsxRuntime.jsxs(React8__default.default.Fragment, { children: [
6319
6406
  i > 0 && /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", color: "muted", className: "mx-1", children: "/" }),
6320
6407
  i < breadcrumbs.length - 1 ? /* @__PURE__ */ jsxRuntime.jsx(
6321
6408
  Box,
@@ -6329,6 +6416,28 @@ var AvlCosmicZoom = ({
6329
6416
  ] }, crumb.level))
6330
6417
  }
6331
6418
  ),
6419
+ state.level === "trait" && state.selectedOrbital && (() => {
6420
+ const orbData = parseOrbitalLevel(schema, state.selectedOrbital);
6421
+ if (!orbData || orbData.traits.length <= 1) return null;
6422
+ return /* @__PURE__ */ jsxRuntime.jsx(
6423
+ HStack,
6424
+ {
6425
+ gap: "xs",
6426
+ align: "center",
6427
+ className: "absolute top-2 right-2 z-10 bg-[var(--color-surface)]/80 backdrop-blur rounded-md px-1.5 py-1",
6428
+ children: orbData.traits.map((t) => /* @__PURE__ */ jsxRuntime.jsx(
6429
+ Box,
6430
+ {
6431
+ as: "button",
6432
+ className: `px-2.5 py-1 rounded-md text-xs font-medium transition-all cursor-pointer border-none ${t.name === state.selectedTrait ? "bg-[var(--color-primary)] text-[var(--color-primary-foreground)]" : "bg-transparent text-[var(--color-muted-foreground)] hover:text-[var(--color-foreground)] hover:bg-[var(--color-surface)]"}`,
6433
+ onClick: () => handleTraitSwitch(t.name),
6434
+ children: t.name
6435
+ },
6436
+ t.name
6437
+ ))
6438
+ }
6439
+ );
6440
+ })(),
6332
6441
  state.level !== "application" && /* @__PURE__ */ jsxRuntime.jsx(
6333
6442
  Typography,
6334
6443
  {
@@ -6341,7 +6450,7 @@ var AvlCosmicZoom = ({
6341
6450
  /* @__PURE__ */ jsxRuntime.jsxs(
6342
6451
  "svg",
6343
6452
  {
6344
- viewBox: `0 0 ${VIEWBOX_W} ${VIEWBOX_H}`,
6453
+ viewBox: `0 0 ${VIEWBOX_W} ${VIEWBOX_H2}`,
6345
6454
  xmlns: "http://www.w3.org/2000/svg",
6346
6455
  className: "w-full h-full",
6347
6456
  role: "img",