@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,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var React7 = require('react');
3
+ var React21 = require('react');
4
4
  var fiber = require('@react-three/fiber');
5
5
  var THREE6 = require('three');
6
6
  var jsxRuntime = require('react/jsx-runtime');
@@ -12,6 +12,7 @@ var OBJLoader_js = require('three/examples/jsm/loaders/OBJLoader.js');
12
12
  var providers = require('@almadar/ui/providers');
13
13
  var clsx = require('clsx');
14
14
  var tailwindMerge = require('tailwind-merge');
15
+ var postprocessing = require('@react-three/postprocessing');
15
16
 
16
17
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
17
18
 
@@ -33,7 +34,7 @@ function _interopNamespace(e) {
33
34
  return Object.freeze(n);
34
35
  }
35
36
 
36
- var React7__default = /*#__PURE__*/_interopDefault(React7);
37
+ var React21__default = /*#__PURE__*/_interopDefault(React21);
37
38
  var THREE6__namespace = /*#__PURE__*/_interopNamespace(THREE6);
38
39
 
39
40
  var __defProp = Object.defineProperty;
@@ -41,8 +42,8 @@ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { en
41
42
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
42
43
  function Scene3D({ background = "#1a1a2e", fog, children }) {
43
44
  const { scene } = fiber.useThree();
44
- const initializedRef = React7.useRef(false);
45
- React7.useEffect(() => {
45
+ const initializedRef = React21.useRef(false);
46
+ React21.useEffect(() => {
46
47
  if (initializedRef.current) return;
47
48
  initializedRef.current = true;
48
49
  if (background.startsWith("#") || background.startsWith("rgb")) {
@@ -63,7 +64,7 @@ function Scene3D({ background = "#1a1a2e", fog, children }) {
63
64
  }, [scene, background, fog]);
64
65
  return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
65
66
  }
66
- var Camera3D = React7.forwardRef(
67
+ var Camera3D = React21.forwardRef(
67
68
  ({
68
69
  mode = "isometric",
69
70
  position = [10, 10, 10],
@@ -76,10 +77,10 @@ var Camera3D = React7.forwardRef(
76
77
  onChange
77
78
  }, ref) => {
78
79
  const { camera, set, viewport } = fiber.useThree();
79
- const controlsRef = React7.useRef(null);
80
- const initialPosition = React7.useRef(new THREE6__namespace.Vector3(...position));
81
- const initialTarget = React7.useRef(new THREE6__namespace.Vector3(...target));
82
- React7.useEffect(() => {
80
+ const controlsRef = React21.useRef(null);
81
+ const initialPosition = React21.useRef(new THREE6__namespace.Vector3(...position));
82
+ const initialTarget = React21.useRef(new THREE6__namespace.Vector3(...target));
83
+ React21.useEffect(() => {
83
84
  let newCamera;
84
85
  if (mode === "isometric") {
85
86
  const aspect = viewport.aspect;
@@ -110,7 +111,7 @@ var Camera3D = React7.forwardRef(
110
111
  onChange(camera);
111
112
  }
112
113
  });
113
- React7.useImperativeHandle(ref, () => ({
114
+ React21.useImperativeHandle(ref, () => ({
114
115
  getCamera: () => camera,
115
116
  setPosition: (x, y, z) => {
116
117
  camera.position.set(x, y, z);
@@ -251,7 +252,7 @@ function Canvas3DLoadingState({
251
252
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "canvas-3d-loading__background", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg__grid" }) })
252
253
  ] });
253
254
  }
254
- var Canvas3DErrorBoundary = class extends React7.Component {
255
+ var Canvas3DErrorBoundary = class extends React21.Component {
255
256
  constructor(props) {
256
257
  super(props);
257
258
  __publicField(this, "handleReset", () => {
@@ -330,12 +331,12 @@ function detectAssetRoot(modelUrl) {
330
331
  return modelUrl.substring(0, modelUrl.lastIndexOf("/") + 1);
331
332
  }
332
333
  function useGLTFModel(url, resourceBasePath) {
333
- const [state, setState] = React7.useState({
334
+ const [state, setState] = React21.useState({
334
335
  model: null,
335
336
  isLoading: false,
336
337
  error: null
337
338
  });
338
- React7.useEffect(() => {
339
+ React21.useEffect(() => {
339
340
  if (!url) {
340
341
  setState({ model: null, isLoading: false, error: null });
341
342
  return;
@@ -384,7 +385,7 @@ function ModelLoader({
384
385
  resourceBasePath
385
386
  }) {
386
387
  const { model: loadedModel, isLoading, error } = useGLTFModel(url, resourceBasePath);
387
- const model = React7.useMemo(() => {
388
+ const model = React21.useMemo(() => {
388
389
  if (!loadedModel) return null;
389
390
  const cloned = loadedModel.clone();
390
391
  cloned.traverse((child) => {
@@ -395,13 +396,13 @@ function ModelLoader({
395
396
  });
396
397
  return cloned;
397
398
  }, [loadedModel, castShadow, receiveShadow]);
398
- const scaleArray = React7.useMemo(() => {
399
+ const scaleArray = React21.useMemo(() => {
399
400
  if (typeof scale === "number") {
400
401
  return [scale, scale, scale];
401
402
  }
402
403
  return scale;
403
404
  }, [scale]);
404
- const rotationRad = React7.useMemo(() => {
405
+ const rotationRad = React21.useMemo(() => {
405
406
  return [
406
407
  rotation[0] * Math.PI / 180,
407
408
  rotation[1] * Math.PI / 180,
@@ -487,8 +488,8 @@ function PhysicsObject3D({
487
488
  onGroundHit,
488
489
  onCollision
489
490
  }) {
490
- const groupRef = React7.useRef(null);
491
- const physicsStateRef = React7.useRef({
491
+ const groupRef = React21.useRef(null);
492
+ const physicsStateRef = React21.useRef({
492
493
  id: entityId,
493
494
  x: initialPosition[0],
494
495
  y: initialPosition[1],
@@ -505,8 +506,8 @@ function PhysicsObject3D({
505
506
  mass,
506
507
  state: "Active"
507
508
  });
508
- const groundHitRef = React7.useRef(false);
509
- React7.useEffect(() => {
509
+ const groundHitRef = React21.useRef(false);
510
+ React21.useEffect(() => {
510
511
  if (groupRef.current) {
511
512
  groupRef.current.position.set(
512
513
  initialPosition[0],
@@ -787,21 +788,21 @@ var DEFAULT_OPTIONS = {
787
788
  };
788
789
  function useThree3(options = {}) {
789
790
  const opts = { ...DEFAULT_OPTIONS, ...options };
790
- const containerRef = React7.useRef(null);
791
- const canvasRef = React7.useRef(null);
792
- const rendererRef = React7.useRef(null);
793
- const sceneRef = React7.useRef(null);
794
- const cameraRef = React7.useRef(null);
795
- const controlsRef = React7.useRef(null);
796
- const gridHelperRef = React7.useRef(null);
797
- const rafRef = React7.useRef(0);
798
- const [isReady, setIsReady] = React7.useState(false);
799
- const [dimensions, setDimensions] = React7.useState({ width: 0, height: 0 });
800
- const initialCameraPosition = React7.useMemo(
791
+ const containerRef = React21.useRef(null);
792
+ const canvasRef = React21.useRef(null);
793
+ const rendererRef = React21.useRef(null);
794
+ const sceneRef = React21.useRef(null);
795
+ const cameraRef = React21.useRef(null);
796
+ const controlsRef = React21.useRef(null);
797
+ const gridHelperRef = React21.useRef(null);
798
+ const rafRef = React21.useRef(0);
799
+ const [isReady, setIsReady] = React21.useState(false);
800
+ const [dimensions, setDimensions] = React21.useState({ width: 0, height: 0 });
801
+ const initialCameraPosition = React21.useMemo(
801
802
  () => new THREE6__namespace.Vector3(...opts.cameraPosition),
802
803
  []
803
804
  );
804
- React7.useEffect(() => {
805
+ React21.useEffect(() => {
805
806
  if (!containerRef.current) return;
806
807
  const container = containerRef.current;
807
808
  const { clientWidth, clientHeight } = container;
@@ -894,7 +895,7 @@ function useThree3(options = {}) {
894
895
  scene.clear();
895
896
  };
896
897
  }, []);
897
- React7.useEffect(() => {
898
+ React21.useEffect(() => {
898
899
  if (!cameraRef.current || !containerRef.current) return;
899
900
  const container = containerRef.current;
900
901
  const { clientWidth, clientHeight } = container;
@@ -929,20 +930,20 @@ function useThree3(options = {}) {
929
930
  animate();
930
931
  }
931
932
  }, [opts.cameraMode]);
932
- const setCameraPosition = React7.useCallback((x, y, z) => {
933
+ const setCameraPosition = React21.useCallback((x, y, z) => {
933
934
  if (cameraRef.current) {
934
935
  cameraRef.current.position.set(x, y, z);
935
936
  controlsRef.current?.update();
936
937
  }
937
938
  }, []);
938
- const lookAt = React7.useCallback((x, y, z) => {
939
+ const lookAt = React21.useCallback((x, y, z) => {
939
940
  if (cameraRef.current) {
940
941
  cameraRef.current.lookAt(x, y, z);
941
942
  controlsRef.current?.target.set(x, y, z);
942
943
  controlsRef.current?.update();
943
944
  }
944
945
  }, []);
945
- const resetCamera = React7.useCallback(() => {
946
+ const resetCamera = React21.useCallback(() => {
946
947
  if (cameraRef.current) {
947
948
  cameraRef.current.position.copy(initialCameraPosition);
948
949
  cameraRef.current.lookAt(0, 0, 0);
@@ -952,7 +953,7 @@ function useThree3(options = {}) {
952
953
  }
953
954
  }
954
955
  }, [initialCameraPosition]);
955
- const fitView = React7.useCallback(
956
+ const fitView = React21.useCallback(
956
957
  (bounds) => {
957
958
  if (!cameraRef.current) return;
958
959
  const centerX = (bounds.minX + bounds.maxX) / 2;
@@ -983,20 +984,20 @@ function useThree3(options = {}) {
983
984
  }
984
985
  function useAssetLoader(options = {}) {
985
986
  const { preloadUrls = [], loader: customLoader } = options;
986
- const loaderRef = React7.useRef(customLoader || new AssetLoader());
987
- const [state, setState] = React7.useState({
987
+ const loaderRef = React21.useRef(customLoader || new AssetLoader());
988
+ const [state, setState] = React21.useState({
988
989
  isLoading: false,
989
990
  progress: 0,
990
991
  loaded: 0,
991
992
  total: 0,
992
993
  errors: []
993
994
  });
994
- React7.useEffect(() => {
995
+ React21.useEffect(() => {
995
996
  if (preloadUrls.length > 0) {
996
997
  preload(preloadUrls);
997
998
  }
998
999
  }, []);
999
- const updateProgress = React7.useCallback((loaded, total) => {
1000
+ const updateProgress = React21.useCallback((loaded, total) => {
1000
1001
  setState((prev) => ({
1001
1002
  ...prev,
1002
1003
  loaded,
@@ -1004,7 +1005,7 @@ function useAssetLoader(options = {}) {
1004
1005
  progress: total > 0 ? Math.round(loaded / total * 100) : 0
1005
1006
  }));
1006
1007
  }, []);
1007
- const loadModel = React7.useCallback(
1008
+ const loadModel = React21.useCallback(
1008
1009
  async (url) => {
1009
1010
  setState((prev) => ({ ...prev, isLoading: true }));
1010
1011
  try {
@@ -1027,7 +1028,7 @@ function useAssetLoader(options = {}) {
1027
1028
  },
1028
1029
  []
1029
1030
  );
1030
- const loadOBJ = React7.useCallback(
1031
+ const loadOBJ = React21.useCallback(
1031
1032
  async (url) => {
1032
1033
  setState((prev) => ({ ...prev, isLoading: true }));
1033
1034
  try {
@@ -1050,7 +1051,7 @@ function useAssetLoader(options = {}) {
1050
1051
  },
1051
1052
  []
1052
1053
  );
1053
- const loadTexture = React7.useCallback(
1054
+ const loadTexture = React21.useCallback(
1054
1055
  async (url) => {
1055
1056
  setState((prev) => ({ ...prev, isLoading: true }));
1056
1057
  try {
@@ -1073,7 +1074,7 @@ function useAssetLoader(options = {}) {
1073
1074
  },
1074
1075
  []
1075
1076
  );
1076
- const preload = React7.useCallback(
1077
+ const preload = React21.useCallback(
1077
1078
  async (urls) => {
1078
1079
  setState((prev) => ({
1079
1080
  ...prev,
@@ -1112,27 +1113,27 @@ function useAssetLoader(options = {}) {
1112
1113
  },
1113
1114
  [updateProgress]
1114
1115
  );
1115
- const hasModel = React7.useCallback((url) => {
1116
+ const hasModel = React21.useCallback((url) => {
1116
1117
  return loaderRef.current.hasModel(url);
1117
1118
  }, []);
1118
- const hasTexture = React7.useCallback((url) => {
1119
+ const hasTexture = React21.useCallback((url) => {
1119
1120
  return loaderRef.current.hasTexture(url);
1120
1121
  }, []);
1121
- const getModel = React7.useCallback((url) => {
1122
+ const getModel = React21.useCallback((url) => {
1122
1123
  try {
1123
1124
  return loaderRef.current.getModel(url);
1124
1125
  } catch {
1125
1126
  return void 0;
1126
1127
  }
1127
1128
  }, []);
1128
- const getTexture = React7.useCallback((url) => {
1129
+ const getTexture = React21.useCallback((url) => {
1129
1130
  try {
1130
1131
  return loaderRef.current.getTexture(url);
1131
1132
  } catch {
1132
1133
  return void 0;
1133
1134
  }
1134
1135
  }, []);
1135
- const clearCache = React7.useCallback(() => {
1136
+ const clearCache = React21.useCallback(() => {
1136
1137
  loaderRef.current.clearCache();
1137
1138
  setState({
1138
1139
  isLoading: false,
@@ -1156,25 +1157,25 @@ function useAssetLoader(options = {}) {
1156
1157
  };
1157
1158
  }
1158
1159
  function useSceneGraph() {
1159
- const nodesRef = React7.useRef(/* @__PURE__ */ new Map());
1160
- const addNode = React7.useCallback((node) => {
1160
+ const nodesRef = React21.useRef(/* @__PURE__ */ new Map());
1161
+ const addNode = React21.useCallback((node) => {
1161
1162
  const existing = nodesRef.current.get(node.id);
1162
1163
  if (existing) {
1163
1164
  existing.mesh.removeFromParent();
1164
1165
  }
1165
1166
  nodesRef.current.set(node.id, node);
1166
1167
  }, []);
1167
- const removeNode = React7.useCallback((id) => {
1168
+ const removeNode = React21.useCallback((id) => {
1168
1169
  const node = nodesRef.current.get(id);
1169
1170
  if (node) {
1170
1171
  node.mesh.removeFromParent();
1171
1172
  nodesRef.current.delete(id);
1172
1173
  }
1173
1174
  }, []);
1174
- const getNode = React7.useCallback((id) => {
1175
+ const getNode = React21.useCallback((id) => {
1175
1176
  return nodesRef.current.get(id);
1176
1177
  }, []);
1177
- const updateNodePosition = React7.useCallback(
1178
+ const updateNodePosition = React21.useCallback(
1178
1179
  (id, x, y, z) => {
1179
1180
  const node = nodesRef.current.get(id);
1180
1181
  if (node) {
@@ -1184,7 +1185,7 @@ function useSceneGraph() {
1184
1185
  },
1185
1186
  []
1186
1187
  );
1187
- const updateNodeGridPosition = React7.useCallback(
1188
+ const updateNodeGridPosition = React21.useCallback(
1188
1189
  (id, gridX, gridZ) => {
1189
1190
  const node = nodesRef.current.get(id);
1190
1191
  if (node) {
@@ -1193,7 +1194,7 @@ function useSceneGraph() {
1193
1194
  },
1194
1195
  []
1195
1196
  );
1196
- const getNodeAtGrid = React7.useCallback(
1197
+ const getNodeAtGrid = React21.useCallback(
1197
1198
  (x, z, type) => {
1198
1199
  return Array.from(nodesRef.current.values()).find((node) => {
1199
1200
  const matchesGrid = node.gridPosition.x === x && node.gridPosition.z === z;
@@ -1202,10 +1203,10 @@ function useSceneGraph() {
1202
1203
  },
1203
1204
  []
1204
1205
  );
1205
- const getNodesByType = React7.useCallback((type) => {
1206
+ const getNodesByType = React21.useCallback((type) => {
1206
1207
  return Array.from(nodesRef.current.values()).filter((node) => node.type === type);
1207
1208
  }, []);
1208
- const getNodesInBounds = React7.useCallback(
1209
+ const getNodesInBounds = React21.useCallback(
1209
1210
  (minX, maxX, minZ, maxZ) => {
1210
1211
  return Array.from(nodesRef.current.values()).filter((node) => {
1211
1212
  const { x, z } = node.gridPosition;
@@ -1214,13 +1215,13 @@ function useSceneGraph() {
1214
1215
  },
1215
1216
  []
1216
1217
  );
1217
- const clearNodes = React7.useCallback(() => {
1218
+ const clearNodes = React21.useCallback(() => {
1218
1219
  nodesRef.current.forEach((node) => {
1219
1220
  node.mesh.removeFromParent();
1220
1221
  });
1221
1222
  nodesRef.current.clear();
1222
1223
  }, []);
1223
- const countNodes = React7.useCallback((type) => {
1224
+ const countNodes = React21.useCallback((type) => {
1224
1225
  if (!type) {
1225
1226
  return nodesRef.current.size;
1226
1227
  }
@@ -1242,9 +1243,9 @@ function useSceneGraph() {
1242
1243
  }
1243
1244
  function useRaycaster(options) {
1244
1245
  const { camera, canvas, cellSize = 1, offsetX = 0, offsetZ = 0 } = options;
1245
- const raycaster = React7.useRef(new THREE6__namespace.Raycaster());
1246
- const mouse = React7.useRef(new THREE6__namespace.Vector2());
1247
- const clientToNDC = React7.useCallback(
1246
+ const raycaster = React21.useRef(new THREE6__namespace.Raycaster());
1247
+ const mouse = React21.useRef(new THREE6__namespace.Vector2());
1248
+ const clientToNDC = React21.useCallback(
1248
1249
  (clientX, clientY) => {
1249
1250
  if (!canvas) {
1250
1251
  return { x: 0, y: 0 };
@@ -1257,7 +1258,7 @@ function useRaycaster(options) {
1257
1258
  },
1258
1259
  [canvas]
1259
1260
  );
1260
- const isWithinCanvas = React7.useCallback(
1261
+ const isWithinCanvas = React21.useCallback(
1261
1262
  (clientX, clientY) => {
1262
1263
  if (!canvas) return false;
1263
1264
  const rect = canvas.getBoundingClientRect();
@@ -1265,7 +1266,7 @@ function useRaycaster(options) {
1265
1266
  },
1266
1267
  [canvas]
1267
1268
  );
1268
- const getIntersection = React7.useCallback(
1269
+ const getIntersection = React21.useCallback(
1269
1270
  (clientX, clientY, objects) => {
1270
1271
  if (!camera || !canvas) return null;
1271
1272
  const ndc = clientToNDC(clientX, clientY);
@@ -1288,7 +1289,7 @@ function useRaycaster(options) {
1288
1289
  },
1289
1290
  [camera, canvas, clientToNDC]
1290
1291
  );
1291
- const getAllIntersections = React7.useCallback(
1292
+ const getAllIntersections = React21.useCallback(
1292
1293
  (clientX, clientY, objects) => {
1293
1294
  if (!camera || !canvas) return [];
1294
1295
  const ndc = clientToNDC(clientX, clientY);
@@ -1307,7 +1308,7 @@ function useRaycaster(options) {
1307
1308
  },
1308
1309
  [camera, canvas, clientToNDC]
1309
1310
  );
1310
- const getGridCoordinates = React7.useCallback(
1311
+ const getGridCoordinates = React21.useCallback(
1311
1312
  (clientX, clientY) => {
1312
1313
  if (!camera || !canvas) return null;
1313
1314
  const ndc = clientToNDC(clientX, clientY);
@@ -1325,7 +1326,7 @@ function useRaycaster(options) {
1325
1326
  },
1326
1327
  [camera, canvas, cellSize, offsetX, offsetZ, clientToNDC]
1327
1328
  );
1328
- const getTileAtPosition = React7.useCallback(
1329
+ const getTileAtPosition = React21.useCallback(
1329
1330
  (clientX, clientY, scene) => {
1330
1331
  if (!camera || !canvas) return null;
1331
1332
  const tileMeshes = [];
@@ -1441,12 +1442,12 @@ var fallbackEventBus = {
1441
1442
  }
1442
1443
  };
1443
1444
  function useEventBus() {
1444
- const context = React7.useContext(providers.EventBusContext);
1445
+ const context = React21.useContext(providers.EventBusContext);
1445
1446
  return context ?? getGlobalEventBus() ?? fallbackEventBus;
1446
1447
  }
1447
1448
  function useEmitEvent() {
1448
1449
  const eventBus = useEventBus();
1449
- return React7.useCallback(
1450
+ return React21.useCallback(
1450
1451
  (type, payload) => {
1451
1452
  eventBus.emit(type, payload);
1452
1453
  },
@@ -1473,9 +1474,9 @@ function useGameCanvas3DEvents(options) {
1473
1474
  onUnitAnimation
1474
1475
  } = options;
1475
1476
  const emit = useEmitEvent();
1476
- const optionsRef = React7.useRef(options);
1477
+ const optionsRef = React21.useRef(options);
1477
1478
  optionsRef.current = options;
1478
- const handleTileClick = React7.useCallback(
1479
+ const handleTileClick = React21.useCallback(
1479
1480
  (tile, event) => {
1480
1481
  if (tileClickEvent) {
1481
1482
  emit(tileClickEvent, {
@@ -1491,7 +1492,7 @@ function useGameCanvas3DEvents(options) {
1491
1492
  },
1492
1493
  [tileClickEvent, emit]
1493
1494
  );
1494
- const handleUnitClick = React7.useCallback(
1495
+ const handleUnitClick = React21.useCallback(
1495
1496
  (unit, event) => {
1496
1497
  if (unitClickEvent) {
1497
1498
  emit(unitClickEvent, {
@@ -1510,7 +1511,7 @@ function useGameCanvas3DEvents(options) {
1510
1511
  },
1511
1512
  [unitClickEvent, emit]
1512
1513
  );
1513
- const handleFeatureClick = React7.useCallback(
1514
+ const handleFeatureClick = React21.useCallback(
1514
1515
  (feature, event) => {
1515
1516
  if (featureClickEvent) {
1516
1517
  emit(featureClickEvent, {
@@ -1525,7 +1526,7 @@ function useGameCanvas3DEvents(options) {
1525
1526
  },
1526
1527
  [featureClickEvent, emit]
1527
1528
  );
1528
- const handleCanvasClick = React7.useCallback(
1529
+ const handleCanvasClick = React21.useCallback(
1529
1530
  (event) => {
1530
1531
  if (canvasClickEvent) {
1531
1532
  emit(canvasClickEvent, {
@@ -1538,7 +1539,7 @@ function useGameCanvas3DEvents(options) {
1538
1539
  },
1539
1540
  [canvasClickEvent, emit]
1540
1541
  );
1541
- const handleTileHover = React7.useCallback(
1542
+ const handleTileHover = React21.useCallback(
1542
1543
  (tile, event) => {
1543
1544
  if (tile) {
1544
1545
  if (tileHoverEvent) {
@@ -1558,7 +1559,7 @@ function useGameCanvas3DEvents(options) {
1558
1559
  },
1559
1560
  [tileHoverEvent, tileLeaveEvent, emit]
1560
1561
  );
1561
- const handleUnitAnimation = React7.useCallback(
1562
+ const handleUnitAnimation = React21.useCallback(
1562
1563
  (unitId, state) => {
1563
1564
  if (unitAnimationEvent) {
1564
1565
  emit(unitAnimationEvent, {
@@ -1571,7 +1572,7 @@ function useGameCanvas3DEvents(options) {
1571
1572
  },
1572
1573
  [unitAnimationEvent, emit]
1573
1574
  );
1574
- const handleCameraChange = React7.useCallback(
1575
+ const handleCameraChange = React21.useCallback(
1575
1576
  (position) => {
1576
1577
  if (cameraChangeEvent) {
1577
1578
  emit(cameraChangeEvent, {
@@ -1617,17 +1618,17 @@ function TileRenderer({
1617
1618
  validMoves = [],
1618
1619
  attackTargets = []
1619
1620
  }) {
1620
- const meshRef = React7.useRef(null);
1621
- const geometry = React7.useMemo(() => {
1621
+ const meshRef = React21.useRef(null);
1622
+ const geometry = React21.useMemo(() => {
1622
1623
  return new THREE6__namespace.BoxGeometry(cellSize * 0.95, 0.2, cellSize * 0.95);
1623
1624
  }, [cellSize]);
1624
- const material = React7.useMemo(() => {
1625
+ const material = React21.useMemo(() => {
1625
1626
  return new THREE6__namespace.MeshStandardMaterial({
1626
1627
  roughness: 0.8,
1627
1628
  metalness: 0.1
1628
1629
  });
1629
1630
  }, []);
1630
- const { positions, colors, tileMap } = React7.useMemo(() => {
1631
+ const { positions, colors, tileMap } = React21.useMemo(() => {
1631
1632
  const pos = [];
1632
1633
  const cols = [];
1633
1634
  const map = /* @__PURE__ */ new Map();
@@ -1657,7 +1658,7 @@ function TileRenderer({
1657
1658
  });
1658
1659
  return { positions: pos, colors: cols, tileMap: map };
1659
1660
  }, [tiles, cellSize, offsetX, offsetZ, terrainColors, selectedTileIds, validMoves, attackTargets]);
1660
- React7.useEffect(() => {
1661
+ React21.useEffect(() => {
1661
1662
  if (!meshRef.current || !useInstancing) return;
1662
1663
  const mesh = meshRef.current;
1663
1664
  mesh.count = positions.length;
@@ -1761,10 +1762,10 @@ function TileRenderer({
1761
1762
  return /* @__PURE__ */ jsxRuntime.jsx("group", { children: renderIndividualTiles() });
1762
1763
  }
1763
1764
  function UnitVisual({ unit, position, isSelected, onClick }) {
1764
- const groupRef = React7.useRef(null);
1765
- const [animationState, setAnimationState] = React7.useState("idle");
1766
- const [isHovered, setIsHovered] = React7.useState(false);
1767
- const teamColor = React7.useMemo(() => {
1765
+ const groupRef = React21.useRef(null);
1766
+ const [animationState, setAnimationState] = React21.useState("idle");
1767
+ const [isHovered, setIsHovered] = React21.useState(false);
1768
+ const teamColor = React21.useMemo(() => {
1768
1769
  if (unit.faction === "player" || unit.team === "player") return 4491519;
1769
1770
  if (unit.faction === "enemy" || unit.team === "enemy") return 16729156;
1770
1771
  if (unit.faction === "neutral" || unit.team === "neutral") return 16777028;
@@ -1776,11 +1777,11 @@ function UnitVisual({ unit, position, isSelected, onClick }) {
1776
1777
  groupRef.current.position.y = y;
1777
1778
  }
1778
1779
  });
1779
- const healthPercent = React7.useMemo(() => {
1780
+ const healthPercent = React21.useMemo(() => {
1780
1781
  if (unit.health === void 0 || unit.maxHealth === void 0) return 1;
1781
1782
  return Math.max(0, Math.min(1, unit.health / unit.maxHealth));
1782
1783
  }, [unit.health, unit.maxHealth]);
1783
- const healthColor = React7.useMemo(() => {
1784
+ const healthColor = React21.useMemo(() => {
1784
1785
  if (healthPercent > 0.5) return "#44aa44";
1785
1786
  if (healthPercent > 0.25) return "#aaaa44";
1786
1787
  return "#ff4444";
@@ -1841,7 +1842,7 @@ function UnitRenderer({
1841
1842
  onAnimationStateChange,
1842
1843
  animationSpeed = 1
1843
1844
  }) {
1844
- const handleUnitClick = React7__default.default.useCallback(
1845
+ const handleUnitClick = React21__default.default.useCallback(
1845
1846
  (unit) => {
1846
1847
  onUnitClick?.(unit);
1847
1848
  },
@@ -2054,10 +2055,10 @@ function detectAssetRoot3(modelUrl) {
2054
2055
  return modelUrl.substring(0, modelUrl.lastIndexOf("/") + 1);
2055
2056
  }
2056
2057
  function useGLTFModel2(url) {
2057
- const [model, setModel] = React7.useState(null);
2058
- const [isLoading, setIsLoading] = React7.useState(false);
2059
- const [error, setError] = React7.useState(null);
2060
- React7.useEffect(() => {
2058
+ const [model, setModel] = React21.useState(null);
2059
+ const [isLoading, setIsLoading] = React21.useState(false);
2060
+ const [error, setError] = React21.useState(null);
2061
+ React21.useEffect(() => {
2061
2062
  if (!url) {
2062
2063
  setModel(null);
2063
2064
  return;
@@ -2089,9 +2090,9 @@ function FeatureModel({
2089
2090
  onClick,
2090
2091
  onHover
2091
2092
  }) {
2092
- const groupRef = React7.useRef(null);
2093
+ const groupRef = React21.useRef(null);
2093
2094
  const { model: loadedModel, isLoading } = useGLTFModel2(feature.assetUrl);
2094
- const model = React7.useMemo(() => {
2095
+ const model = React21.useMemo(() => {
2095
2096
  if (!loadedModel) return null;
2096
2097
  const cloned = loadedModel.clone();
2097
2098
  cloned.scale.setScalar(0.3);
@@ -2209,7 +2210,7 @@ function CameraController({
2209
2210
  onCameraChange
2210
2211
  }) {
2211
2212
  const { camera } = fiber.useThree();
2212
- React7.useEffect(() => {
2213
+ React21.useEffect(() => {
2213
2214
  if (onCameraChange) {
2214
2215
  onCameraChange({
2215
2216
  x: camera.position.x,
@@ -2220,7 +2221,7 @@ function CameraController({
2220
2221
  }, [camera.position, onCameraChange]);
2221
2222
  return null;
2222
2223
  }
2223
- var GameCanvas3D = React7.forwardRef(
2224
+ var GameCanvas3D = React21.forwardRef(
2224
2225
  ({
2225
2226
  tiles = [],
2226
2227
  units = [],
@@ -2265,10 +2266,10 @@ var GameCanvas3D = React7.forwardRef(
2265
2266
  selectedUnitId = null,
2266
2267
  children
2267
2268
  }, ref) => {
2268
- const containerRef = React7.useRef(null);
2269
- const controlsRef = React7.useRef(null);
2270
- const [hoveredTile, setHoveredTile] = React7.useState(null);
2271
- const [internalError, setInternalError] = React7.useState(null);
2269
+ const containerRef = React21.useRef(null);
2270
+ const controlsRef = React21.useRef(null);
2271
+ const [hoveredTile, setHoveredTile] = React21.useState(null);
2272
+ const [internalError, setInternalError] = React21.useState(null);
2272
2273
  const { isLoading: assetsLoading, progress, loaded, total } = useAssetLoader({
2273
2274
  preloadUrls: preloadAssets,
2274
2275
  loader: customAssetLoader
@@ -2289,7 +2290,7 @@ var GameCanvas3D = React7.forwardRef(
2289
2290
  onTileHover,
2290
2291
  onUnitAnimation
2291
2292
  });
2292
- const gridBounds = React7.useMemo(() => {
2293
+ const gridBounds = React21.useMemo(() => {
2293
2294
  if (tiles.length === 0) {
2294
2295
  return { minX: 0, maxX: 10, minZ: 0, maxZ: 10 };
2295
2296
  }
@@ -2302,14 +2303,14 @@ var GameCanvas3D = React7.forwardRef(
2302
2303
  maxZ: Math.max(...zs)
2303
2304
  };
2304
2305
  }, [tiles]);
2305
- const cameraTarget = React7.useMemo(() => {
2306
+ const cameraTarget = React21.useMemo(() => {
2306
2307
  return [
2307
2308
  (gridBounds.minX + gridBounds.maxX) / 2,
2308
2309
  0,
2309
2310
  (gridBounds.minZ + gridBounds.maxZ) / 2
2310
2311
  ];
2311
2312
  }, [gridBounds]);
2312
- const gridConfig = React7.useMemo(
2313
+ const gridConfig = React21.useMemo(
2313
2314
  () => ({
2314
2315
  ...DEFAULT_GRID_CONFIG,
2315
2316
  offsetX: -(gridBounds.maxX - gridBounds.minX) / 2,
@@ -2317,7 +2318,7 @@ var GameCanvas3D = React7.forwardRef(
2317
2318
  }),
2318
2319
  [gridBounds]
2319
2320
  );
2320
- const gridToWorld2 = React7.useCallback(
2321
+ const gridToWorld2 = React21.useCallback(
2321
2322
  (x, z, y = 0) => {
2322
2323
  const worldX = (x - gridBounds.minX) * gridConfig.cellSize;
2323
2324
  const worldZ = (z - gridBounds.minZ) * gridConfig.cellSize;
@@ -2325,7 +2326,7 @@ var GameCanvas3D = React7.forwardRef(
2325
2326
  },
2326
2327
  [gridBounds, gridConfig]
2327
2328
  );
2328
- React7.useImperativeHandle(ref, () => ({
2329
+ React21.useImperativeHandle(ref, () => ({
2329
2330
  getCameraPosition: () => {
2330
2331
  if (controlsRef.current) {
2331
2332
  const pos = controlsRef.current.object.position;
@@ -2363,19 +2364,19 @@ var GameCanvas3D = React7.forwardRef(
2363
2364
  features
2364
2365
  })
2365
2366
  }));
2366
- const handleTileClick = React7.useCallback(
2367
+ const handleTileClick = React21.useCallback(
2367
2368
  (tile, event) => {
2368
2369
  eventHandlers.handleTileClick(tile, event);
2369
2370
  },
2370
2371
  [eventHandlers]
2371
2372
  );
2372
- const handleUnitClick = React7.useCallback(
2373
+ const handleUnitClick = React21.useCallback(
2373
2374
  (unit, event) => {
2374
2375
  eventHandlers.handleUnitClick(unit, event);
2375
2376
  },
2376
2377
  [eventHandlers]
2377
2378
  );
2378
- const handleFeatureClick = React7.useCallback(
2379
+ const handleFeatureClick = React21.useCallback(
2379
2380
  (feature, event) => {
2380
2381
  if (event) {
2381
2382
  eventHandlers.handleFeatureClick(feature, event);
@@ -2383,7 +2384,7 @@ var GameCanvas3D = React7.forwardRef(
2383
2384
  },
2384
2385
  [eventHandlers]
2385
2386
  );
2386
- const handleTileHover = React7.useCallback(
2387
+ const handleTileHover = React21.useCallback(
2387
2388
  (tile, event) => {
2388
2389
  setHoveredTile(tile);
2389
2390
  if (event) {
@@ -2392,7 +2393,7 @@ var GameCanvas3D = React7.forwardRef(
2392
2393
  },
2393
2394
  [eventHandlers]
2394
2395
  );
2395
- const cameraConfig = React7.useMemo(() => {
2396
+ const cameraConfig = React21.useMemo(() => {
2396
2397
  const size = Math.max(
2397
2398
  gridBounds.maxX - gridBounds.minX,
2398
2399
  gridBounds.maxZ - gridBounds.minZ
@@ -2417,7 +2418,7 @@ var GameCanvas3D = React7.forwardRef(
2417
2418
  };
2418
2419
  }
2419
2420
  }, [cameraMode, gridBounds]);
2420
- const DefaultTileRenderer = React7.useCallback(
2421
+ const DefaultTileRenderer = React21.useCallback(
2421
2422
  ({ tile, position }) => {
2422
2423
  const isSelected = tile.id ? selectedTileIds.includes(tile.id) : false;
2423
2424
  const isHovered = hoveredTile?.id === tile.id;
@@ -2455,7 +2456,7 @@ var GameCanvas3D = React7.forwardRef(
2455
2456
  },
2456
2457
  [selectedTileIds, hoveredTile, validMoves, attackTargets, handleTileClick, handleTileHover]
2457
2458
  );
2458
- const DefaultUnitRenderer = React7.useCallback(
2459
+ const DefaultUnitRenderer = React21.useCallback(
2459
2460
  ({ unit, position }) => {
2460
2461
  const isSelected = selectedUnitId === unit.id;
2461
2462
  const color = unit.faction === "player" ? 4491519 : unit.faction === "enemy" ? 16729156 : 16777028;
@@ -2513,7 +2514,7 @@ var GameCanvas3D = React7.forwardRef(
2513
2514
  },
2514
2515
  [selectedUnitId, handleUnitClick]
2515
2516
  );
2516
- const DefaultFeatureRenderer = React7.useCallback(
2517
+ const DefaultFeatureRenderer = React21.useCallback(
2517
2518
  ({
2518
2519
  feature,
2519
2520
  position
@@ -2820,7 +2821,7 @@ var positionStyles = {
2820
2821
  fixed: "fixed",
2821
2822
  sticky: "sticky"
2822
2823
  };
2823
- var Box = React7__default.default.forwardRef(
2824
+ var Box = React21__default.default.forwardRef(
2824
2825
  ({
2825
2826
  padding,
2826
2827
  paddingX,
@@ -2849,20 +2850,20 @@ var Box = React7__default.default.forwardRef(
2849
2850
  ...rest
2850
2851
  }, ref) => {
2851
2852
  const eventBus = useEventBus();
2852
- const handleClick = React7.useCallback((e) => {
2853
+ const handleClick = React21.useCallback((e) => {
2853
2854
  if (action) {
2854
2855
  e.stopPropagation();
2855
2856
  eventBus.emit(`UI:${action}`, actionPayload ?? {});
2856
2857
  }
2857
2858
  onClick?.(e);
2858
2859
  }, [action, actionPayload, eventBus, onClick]);
2859
- const handleMouseEnter = React7.useCallback((e) => {
2860
+ const handleMouseEnter = React21.useCallback((e) => {
2860
2861
  if (hoverEvent) {
2861
2862
  eventBus.emit(`UI:${hoverEvent}`, { hovered: true });
2862
2863
  }
2863
2864
  onMouseEnter?.(e);
2864
2865
  }, [hoverEvent, eventBus, onMouseEnter]);
2865
- const handleMouseLeave = React7.useCallback((e) => {
2866
+ const handleMouseLeave = React21.useCallback((e) => {
2866
2867
  if (hoverEvent) {
2867
2868
  eventBus.emit(`UI:${hoverEvent}`, { hovered: false });
2868
2869
  }
@@ -3364,6 +3365,2418 @@ function normalizeMouseCoordinates(clientX, clientY, element) {
3364
3365
  y: -((clientY - rect.top) / rect.height) * 2 + 1
3365
3366
  };
3366
3367
  }
3368
+
3369
+ // components/organisms/avl/avl-schema-parser.ts
3370
+ function getEntity(orbital) {
3371
+ const entity = orbital.entity;
3372
+ if (typeof entity === "string") {
3373
+ return { name: entity, fields: [], persistence: "runtime" };
3374
+ }
3375
+ const e = entity;
3376
+ return {
3377
+ name: e.name ?? orbital.name,
3378
+ fields: e.fields ?? [],
3379
+ persistence: e.persistence ?? "runtime"
3380
+ };
3381
+ }
3382
+ function getTraits(orbital) {
3383
+ if (!orbital.traits) return [];
3384
+ return orbital.traits.map((t) => {
3385
+ if (typeof t === "string") return { name: t };
3386
+ return t;
3387
+ });
3388
+ }
3389
+ function getPages(orbital) {
3390
+ if (!orbital.pages) return [];
3391
+ return orbital.pages.map((p) => {
3392
+ if (typeof p === "string") return { name: p, path: `/${p.toLowerCase()}` };
3393
+ return p;
3394
+ });
3395
+ }
3396
+ function getStateMachine(trait) {
3397
+ return trait.stateMachine ?? null;
3398
+ }
3399
+ function getStates(sm) {
3400
+ return sm.states ?? [];
3401
+ }
3402
+ function getTransitions(sm) {
3403
+ return sm.transitions ?? [];
3404
+ }
3405
+ function getEvents(sm) {
3406
+ return sm.events ?? [];
3407
+ }
3408
+ function getEmits(trait) {
3409
+ const emits = trait.emits;
3410
+ if (!emits) return [];
3411
+ return emits.map((e) => typeof e === "string" ? e : e.event ?? e.name ?? "");
3412
+ }
3413
+ function getListens(trait) {
3414
+ const listens = trait.listens;
3415
+ if (!listens) return [];
3416
+ return listens.map((l) => typeof l === "string" ? l : l.event ?? "");
3417
+ }
3418
+ function parseEffectType(effect) {
3419
+ if (Array.isArray(effect)) {
3420
+ const [type, ...args] = effect;
3421
+ return { type: String(type), args };
3422
+ }
3423
+ return { type: "unknown", args: [] };
3424
+ }
3425
+ function exprToTree(expr) {
3426
+ if (Array.isArray(expr)) {
3427
+ const [op, ...args] = expr;
3428
+ return {
3429
+ label: String(op),
3430
+ type: "operator",
3431
+ children: args.map((a) => exprToTree(a))
3432
+ };
3433
+ }
3434
+ if (typeof expr === "string") {
3435
+ if (expr.startsWith("@")) {
3436
+ return { label: expr, type: "binding" };
3437
+ }
3438
+ return { label: expr, type: "literal" };
3439
+ }
3440
+ return { label: String(expr), type: "literal" };
3441
+ }
3442
+ function parseApplicationLevel(schema) {
3443
+ const orbitals = [];
3444
+ const crossLinks = [];
3445
+ const count = schema.orbitals.length;
3446
+ const cols = Math.ceil(Math.sqrt(count));
3447
+ const rows = Math.ceil(count / cols);
3448
+ const spacing = 200;
3449
+ const gridW = cols * spacing;
3450
+ const gridH = rows * spacing;
3451
+ const originX = (600 - gridW) / 2 + spacing / 2;
3452
+ const originY = (400 - gridH) / 2 + spacing / 2;
3453
+ schema.orbitals.forEach((orbital, i) => {
3454
+ const entity = getEntity(orbital);
3455
+ const traits = getTraits(orbital);
3456
+ const pages = getPages(orbital);
3457
+ orbitals.push({
3458
+ name: orbital.name,
3459
+ entityName: entity.name,
3460
+ fieldCount: entity.fields.length,
3461
+ persistence: entity.persistence,
3462
+ traitNames: traits.map((t) => t.name ?? ""),
3463
+ pageNames: pages.map((p) => p.name ?? ""),
3464
+ position: {
3465
+ x: originX + i % cols * spacing,
3466
+ y: originY + Math.floor(i / cols) * spacing
3467
+ }
3468
+ });
3469
+ });
3470
+ const emitMap = [];
3471
+ const listenMap = [];
3472
+ for (const orbital of schema.orbitals) {
3473
+ for (const traitRef of getTraits(orbital)) {
3474
+ const traitName = traitRef.name ?? "";
3475
+ for (const event of getEmits(traitRef)) {
3476
+ emitMap.push({ orbital: orbital.name, trait: traitName, event });
3477
+ }
3478
+ for (const event of getListens(traitRef)) {
3479
+ listenMap.push({ orbital: orbital.name, trait: traitName, event });
3480
+ }
3481
+ }
3482
+ }
3483
+ for (const emit of emitMap) {
3484
+ for (const listen of listenMap) {
3485
+ if (emit.event === listen.event && emit.orbital !== listen.orbital) {
3486
+ crossLinks.push({
3487
+ emitterOrbital: emit.orbital,
3488
+ listenerOrbital: listen.orbital,
3489
+ eventName: emit.event,
3490
+ emitterTrait: emit.trait,
3491
+ listenerTrait: listen.trait
3492
+ });
3493
+ }
3494
+ }
3495
+ }
3496
+ return { orbitals, crossLinks };
3497
+ }
3498
+ function parseOrbitalLevel(schema, orbitalName) {
3499
+ const orbital = schema.orbitals.find((o) => o.name === orbitalName);
3500
+ if (!orbital) return null;
3501
+ const entity = getEntity(orbital);
3502
+ const traits = getTraits(orbital);
3503
+ const pages = getPages(orbital);
3504
+ const fields = entity.fields.map((f) => ({
3505
+ name: f.name ?? "",
3506
+ type: f.type ?? "string",
3507
+ required: f.required ?? false,
3508
+ hasDefault: f.default !== void 0
3509
+ }));
3510
+ const traitInfos = traits.map((t) => {
3511
+ const sm = getStateMachine(t);
3512
+ return {
3513
+ name: t.name ?? "",
3514
+ stateCount: sm ? getStates(sm).length : 0,
3515
+ eventCount: sm ? getEvents(sm).length : 0,
3516
+ transitionCount: sm ? getTransitions(sm).length : 0,
3517
+ emits: getEmits(t),
3518
+ listens: getListens(t)
3519
+ };
3520
+ });
3521
+ const pageInfos = pages.map((p) => ({
3522
+ name: p.name ?? "",
3523
+ route: p.path ?? `/${(p.name ?? "").toLowerCase()}`
3524
+ }));
3525
+ const externalLinks = [];
3526
+ const thisTraitEmits = traits.flatMap((t) => getEmits(t).map((e) => ({ trait: t.name ?? "", event: e })));
3527
+ const thisTraitListens = traits.flatMap((t) => getListens(t).map((e) => ({ trait: t.name ?? "", event: e })));
3528
+ for (const other of schema.orbitals) {
3529
+ if (other.name === orbitalName) continue;
3530
+ const otherTraits = getTraits(other);
3531
+ const otherListens = otherTraits.flatMap((t) => getListens(t));
3532
+ const otherEmits = otherTraits.flatMap((t) => getEmits(t));
3533
+ for (const emit of thisTraitEmits) {
3534
+ if (otherListens.includes(emit.event)) {
3535
+ externalLinks.push({
3536
+ targetOrbital: other.name,
3537
+ eventName: emit.event,
3538
+ direction: "out",
3539
+ traitName: emit.trait
3540
+ });
3541
+ }
3542
+ }
3543
+ for (const listen of thisTraitListens) {
3544
+ if (otherEmits.includes(listen.event)) {
3545
+ externalLinks.push({
3546
+ targetOrbital: other.name,
3547
+ eventName: listen.event,
3548
+ direction: "in",
3549
+ traitName: listen.trait
3550
+ });
3551
+ }
3552
+ }
3553
+ }
3554
+ return {
3555
+ name: orbital.name,
3556
+ entity: {
3557
+ name: entity.name,
3558
+ fields,
3559
+ persistence: entity.persistence
3560
+ },
3561
+ traits: traitInfos,
3562
+ pages: pageInfos,
3563
+ externalLinks
3564
+ };
3565
+ }
3566
+ function parseTraitLevel(schema, orbitalName, traitName) {
3567
+ const orbital = schema.orbitals.find((o) => o.name === orbitalName);
3568
+ if (!orbital) return null;
3569
+ const traits = getTraits(orbital);
3570
+ const trait = traits.find((t) => t.name === traitName);
3571
+ if (!trait) return null;
3572
+ const sm = getStateMachine(trait);
3573
+ if (!sm) return null;
3574
+ const states = getStates(sm).map((s) => ({
3575
+ name: s.name ?? "",
3576
+ isInitial: s.isInitial ?? false,
3577
+ isTerminal: s.isTerminal ?? false
3578
+ }));
3579
+ const transitions = getTransitions(sm).map((t, i) => ({
3580
+ from: t.from ?? "",
3581
+ to: t.to ?? "",
3582
+ event: t.event ?? "",
3583
+ guard: t.guard,
3584
+ effects: (t.effects ?? []).map(parseEffectType),
3585
+ index: i
3586
+ }));
3587
+ const entity = getEntity(orbital);
3588
+ return {
3589
+ name: traitName,
3590
+ linkedEntity: entity.name,
3591
+ states,
3592
+ transitions,
3593
+ emittedEvents: getEmits(trait),
3594
+ listenedEvents: getListens(trait)
3595
+ };
3596
+ }
3597
+ function parseTransitionLevel(schema, orbitalName, traitName, transitionIndex) {
3598
+ const traitData = parseTraitLevel(schema, orbitalName, traitName);
3599
+ if (!traitData) return null;
3600
+ const transition = traitData.transitions[transitionIndex];
3601
+ if (!transition) return null;
3602
+ const guard = transition.guard ? exprToTree(transition.guard) : null;
3603
+ const effects = transition.effects.map(
3604
+ (e) => exprToTree([e.type, ...e.args])
3605
+ );
3606
+ const slotTargets = transition.effects.filter((e) => e.type === "render-ui").map((e) => ({
3607
+ name: String(e.args[0] ?? "main"),
3608
+ pattern: typeof e.args[1] === "object" && e.args[1] !== null ? e.args[1].type ?? "unknown" : String(e.args[1] ?? "unknown")
3609
+ }));
3610
+ return {
3611
+ from: transition.from,
3612
+ to: transition.to,
3613
+ event: transition.event,
3614
+ guard,
3615
+ effects,
3616
+ slotTargets
3617
+ };
3618
+ }
3619
+
3620
+ // components/organisms/avl/avl-zoom-state.ts
3621
+ var initialZoomState = {
3622
+ level: "application",
3623
+ selectedOrbital: null,
3624
+ selectedTrait: null,
3625
+ selectedTransition: null,
3626
+ animating: false,
3627
+ animationDirection: "in",
3628
+ animationTarget: null
3629
+ };
3630
+ function zoomReducer(state, action) {
3631
+ switch (action.type) {
3632
+ case "ZOOM_INTO_ORBITAL": {
3633
+ if (state.level !== "application" || state.animating) return state;
3634
+ return {
3635
+ ...state,
3636
+ animating: true,
3637
+ animationDirection: "in",
3638
+ animationTarget: { x: action.targetPosition.x, y: action.targetPosition.y, scale: 3 },
3639
+ selectedOrbital: action.orbital
3640
+ };
3641
+ }
3642
+ case "ZOOM_INTO_TRAIT": {
3643
+ if (state.level !== "orbital" || state.animating) return state;
3644
+ return {
3645
+ ...state,
3646
+ animating: true,
3647
+ animationDirection: "in",
3648
+ animationTarget: { x: action.targetPosition.x, y: action.targetPosition.y, scale: 3 },
3649
+ selectedTrait: action.trait
3650
+ };
3651
+ }
3652
+ case "ZOOM_INTO_TRANSITION": {
3653
+ if (state.level !== "trait" || state.animating) return state;
3654
+ return {
3655
+ ...state,
3656
+ animating: true,
3657
+ animationDirection: "in",
3658
+ animationTarget: { x: action.targetPosition.x, y: action.targetPosition.y, scale: 3 },
3659
+ selectedTransition: action.transitionIndex
3660
+ };
3661
+ }
3662
+ case "ZOOM_OUT": {
3663
+ if (state.level === "application" || state.animating) return state;
3664
+ return {
3665
+ ...state,
3666
+ animating: true,
3667
+ animationDirection: "out",
3668
+ animationTarget: { x: 300, y: 200, scale: 0.3 }
3669
+ };
3670
+ }
3671
+ case "ANIMATION_COMPLETE": {
3672
+ if (!state.animating) return state;
3673
+ if (state.animationDirection === "in") {
3674
+ const nextLevel = state.level === "application" ? "orbital" : state.level === "orbital" ? "trait" : "transition";
3675
+ return {
3676
+ ...state,
3677
+ level: nextLevel,
3678
+ animating: false,
3679
+ animationTarget: null
3680
+ };
3681
+ }
3682
+ if (state.level === "transition") {
3683
+ return {
3684
+ ...state,
3685
+ level: "trait",
3686
+ selectedTransition: null,
3687
+ animating: false,
3688
+ animationTarget: null
3689
+ };
3690
+ }
3691
+ if (state.level === "trait") {
3692
+ return {
3693
+ ...state,
3694
+ level: "orbital",
3695
+ selectedTrait: null,
3696
+ animating: false,
3697
+ animationTarget: null
3698
+ };
3699
+ }
3700
+ if (state.level === "orbital") {
3701
+ return {
3702
+ ...state,
3703
+ level: "application",
3704
+ selectedOrbital: null,
3705
+ animating: false,
3706
+ animationTarget: null
3707
+ };
3708
+ }
3709
+ return state;
3710
+ }
3711
+ case "SWITCH_TRAIT": {
3712
+ if (state.level !== "trait" || state.animating) return state;
3713
+ return {
3714
+ ...state,
3715
+ selectedTrait: action.trait,
3716
+ selectedTransition: null
3717
+ };
3718
+ }
3719
+ case "RESET": {
3720
+ return initialZoomState;
3721
+ }
3722
+ default:
3723
+ return state;
3724
+ }
3725
+ }
3726
+ function getBreadcrumbs(state) {
3727
+ const crumbs = [{ label: "Application", level: "application" }];
3728
+ if (state.selectedOrbital) {
3729
+ crumbs.push({ label: state.selectedOrbital, level: "orbital" });
3730
+ }
3731
+ if (state.selectedTrait) {
3732
+ crumbs.push({ label: state.selectedTrait, level: "trait" });
3733
+ }
3734
+ if (state.selectedTransition !== null) {
3735
+ crumbs.push({ label: `Transition #${state.selectedTransition}`, level: "transition" });
3736
+ }
3737
+ return crumbs;
3738
+ }
3739
+ var AVL_3D_COLORS = {
3740
+ // Orbital node: deep indigo body with soft cyan-blue rim glow
3741
+ orbitalSphere: "#161b2e",
3742
+ orbitalRim: "#5b9bd5",
3743
+ // Entity core: warm amber-gold (slightly desaturated for dark bg)
3744
+ entityCore: "#f0c040",
3745
+ entityCoreGlow: "#ffd866",
3746
+ // Trait orbit ring
3747
+ traitOrbit: "#5b9bd5",
3748
+ traitOrbitHighlight: "#7ab8f5",
3749
+ // State nodes
3750
+ stateIdle: "#1e2a3a",
3751
+ stateEdge: "#5b9bd5",
3752
+ stateActive: "#4ecb71",
3753
+ // Transitions: warm copper-orange
3754
+ transitionArc: "#e0944a",
3755
+ transitionArcHover: "#f0a860",
3756
+ // Guards
3757
+ guardPass: "#4ecb71",
3758
+ guardFail: "#f06060",
3759
+ // Cross-orbital wires: soft lavender
3760
+ crossWire: "#a78bda",
3761
+ crossWireGlow: "#c4a8f0",
3762
+ // Page portals: soft teal
3763
+ pagePortal: "#40c8aa",
3764
+ // Background: deep navy with blue undertone (not pure black)
3765
+ background: "#0c1222",
3766
+ backgroundSurface: "#111a2e",
3767
+ // Fog: matches background for seamless fade
3768
+ fog: "#0c1222",
3769
+ // Sparkle/particle accent
3770
+ sparkle: "#7ab8f5",
3771
+ sparkleWarm: "#f0c040"
3772
+ };
3773
+ var GOLDEN_ANGLE = Math.PI * (3 - Math.sqrt(5));
3774
+ function goldenSpiralPositions(count, baseRadius) {
3775
+ if (count === 0) return [];
3776
+ if (count === 1) return [{ x: 0, y: 0, z: 0 }];
3777
+ const positions = [];
3778
+ for (let i = 0; i < count; i++) {
3779
+ const angle = i * GOLDEN_ANGLE;
3780
+ const r = baseRadius * Math.sqrt(i / count);
3781
+ positions.push({
3782
+ x: r * Math.cos(angle),
3783
+ y: 0,
3784
+ z: r * Math.sin(angle)
3785
+ });
3786
+ }
3787
+ return positions;
3788
+ }
3789
+ function forceDirectedPositions(count, edges, baseRadius, iterations = 80) {
3790
+ if (count === 0) return [];
3791
+ if (count === 1) return [{ x: 0, y: 0, z: 0 }];
3792
+ const positions = goldenSpiralPositions(count, baseRadius);
3793
+ const repulsionStrength = baseRadius * baseRadius * 0.5;
3794
+ const attractionStrength = 0.15;
3795
+ const damping = 0.85;
3796
+ const velocities = positions.map(() => ({ x: 0, y: 0, z: 0 }));
3797
+ for (let iter = 0; iter < iterations; iter++) {
3798
+ for (let i = 0; i < count; i++) {
3799
+ for (let j = i + 1; j < count; j++) {
3800
+ const dx = positions[i].x - positions[j].x;
3801
+ const dz = positions[i].z - positions[j].z;
3802
+ const distSq = dx * dx + dz * dz + 0.01;
3803
+ const force = repulsionStrength / distSq;
3804
+ const dist = Math.sqrt(distSq);
3805
+ const fx = dx / dist * force;
3806
+ const fz = dz / dist * force;
3807
+ velocities[i].x += fx;
3808
+ velocities[i].z += fz;
3809
+ velocities[j].x -= fx;
3810
+ velocities[j].z -= fz;
3811
+ }
3812
+ }
3813
+ for (const edge of edges) {
3814
+ const dx = positions[edge.to].x - positions[edge.from].x;
3815
+ const dz = positions[edge.to].z - positions[edge.from].z;
3816
+ const dist = Math.sqrt(dx * dx + dz * dz + 0.01);
3817
+ const force = dist * attractionStrength;
3818
+ const fx = dx / dist * force;
3819
+ const fz = dz / dist * force;
3820
+ velocities[edge.from].x += fx;
3821
+ velocities[edge.from].z += fz;
3822
+ velocities[edge.to].x -= fx;
3823
+ velocities[edge.to].z -= fz;
3824
+ }
3825
+ for (let i = 0; i < count; i++) {
3826
+ positions[i].x += velocities[i].x * 0.1;
3827
+ positions[i].z += velocities[i].z * 0.1;
3828
+ velocities[i].x *= damping;
3829
+ velocities[i].z *= damping;
3830
+ }
3831
+ }
3832
+ let cx = 0, cz = 0;
3833
+ for (const p of positions) {
3834
+ cx += p.x;
3835
+ cz += p.z;
3836
+ }
3837
+ cx /= count;
3838
+ cz /= count;
3839
+ for (const p of positions) {
3840
+ p.x -= cx;
3841
+ p.z -= cz;
3842
+ }
3843
+ return positions;
3844
+ }
3845
+ function fibonacciSpherePositions(count, radius) {
3846
+ if (count === 0) return [];
3847
+ if (count === 1) return [{ x: 0, y: 0, z: 0 }];
3848
+ const positions = [];
3849
+ for (let i = 0; i < count; i++) {
3850
+ const y = 1 - 2 * i / (count - 1);
3851
+ const radiusAtY = Math.sqrt(1 - y * y);
3852
+ const theta = GOLDEN_ANGLE * i;
3853
+ positions.push({
3854
+ x: radius * radiusAtY * Math.cos(theta),
3855
+ y: radius * y,
3856
+ z: radius * radiusAtY * Math.sin(theta)
3857
+ });
3858
+ }
3859
+ return positions;
3860
+ }
3861
+ function orbitRingPositions(count, radius, tilt) {
3862
+ if (count === 0) return [];
3863
+ const positions = [];
3864
+ const step = 2 * Math.PI / count;
3865
+ for (let i = 0; i < count; i++) {
3866
+ const angle = i * step;
3867
+ const x = radius * Math.cos(angle);
3868
+ const flatZ = radius * Math.sin(angle);
3869
+ const y = flatZ * Math.sin(tilt);
3870
+ const z = flatZ * Math.cos(tilt);
3871
+ positions.push({ x, y, z });
3872
+ }
3873
+ return positions;
3874
+ }
3875
+ function arcCurve3D(from, to, offset) {
3876
+ const start = new THREE6.Vector3(...from);
3877
+ const end = new THREE6.Vector3(...to);
3878
+ const mid = new THREE6.Vector3().addVectors(start, end).multiplyScalar(0.5);
3879
+ const dir = new THREE6.Vector3().subVectors(end, start).normalize();
3880
+ const up = new THREE6.Vector3(0, 1, 0);
3881
+ const perp = new THREE6.Vector3().crossVectors(dir, up).normalize();
3882
+ if (perp.length() < 1e-3) {
3883
+ perp.crossVectors(dir, new THREE6.Vector3(1, 0, 0)).normalize();
3884
+ }
3885
+ const control = mid.clone().add(perp.multiplyScalar(offset));
3886
+ control.y += Math.abs(offset) * 0.3;
3887
+ return new THREE6.QuadraticBezierCurve3(start, control, end);
3888
+ }
3889
+ function selfLoopCurve3D(position, loopRadius) {
3890
+ const base = new THREE6.Vector3(...position);
3891
+ const start = base.clone().add(new THREE6.Vector3(-loopRadius * 0.3, 0, 0));
3892
+ const end = base.clone().add(new THREE6.Vector3(loopRadius * 0.3, 0, 0));
3893
+ const control = base.clone().add(new THREE6.Vector3(0, loopRadius, 0));
3894
+ return new THREE6.QuadraticBezierCurve3(start, control, end);
3895
+ }
3896
+ function treeLayout3D(node, origin, horizontalSpacing, verticalSpacing = 2) {
3897
+ const results = [];
3898
+ function layoutNode(n, pos, depth) {
3899
+ results.push({ node: n, position: pos });
3900
+ if (!n.children || n.children.length === 0) return;
3901
+ const childCount = n.children.length;
3902
+ const totalWidth = (childCount - 1) * horizontalSpacing / (depth + 1);
3903
+ const startX = pos.x - totalWidth / 2;
3904
+ for (let i = 0; i < childCount; i++) {
3905
+ const childPos = {
3906
+ x: startX + i * totalWidth / Math.max(childCount - 1, 1),
3907
+ y: pos.y - verticalSpacing,
3908
+ z: pos.z
3909
+ };
3910
+ layoutNode(n.children[i], childPos, depth + 1);
3911
+ }
3912
+ }
3913
+ layoutNode(node, origin, 0);
3914
+ return results;
3915
+ }
3916
+ var CAMERA_POSITIONS = {
3917
+ application: { position: [0, 20, 30], target: [0, 0, 0] },
3918
+ orbital: { position: [0, 8, 12], target: [0, 0, 0] },
3919
+ trait: { position: [0, 6, 10], target: [0, 0, 0] },
3920
+ transition: { position: [0, 4, 8], target: [0, 0, 0] }
3921
+ };
3922
+ var Avl3DLabel = ({
3923
+ position,
3924
+ text,
3925
+ color = "#ffffff",
3926
+ fontSize = 12,
3927
+ className,
3928
+ occlude = false
3929
+ }) => {
3930
+ return /* @__PURE__ */ jsxRuntime.jsx(
3931
+ drei.Html,
3932
+ {
3933
+ position,
3934
+ center: true,
3935
+ distanceFactor: 10,
3936
+ occlude: occlude ? "blending" : void 0,
3937
+ className,
3938
+ style: { pointerEvents: "none" },
3939
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3940
+ Typography,
3941
+ {
3942
+ variant: "small",
3943
+ style: {
3944
+ color,
3945
+ fontSize: `${fontSize}px`,
3946
+ whiteSpace: "nowrap",
3947
+ textShadow: "0 0 4px rgba(0,0,0,0.8)",
3948
+ userSelect: "none"
3949
+ },
3950
+ children: text
3951
+ }
3952
+ )
3953
+ }
3954
+ );
3955
+ };
3956
+ Avl3DLabel.displayName = "Avl3DLabel";
3957
+ var Avl3DTooltip = ({
3958
+ position,
3959
+ title,
3960
+ rows,
3961
+ accentColor = "#5b9bd5"
3962
+ }) => {
3963
+ return /* @__PURE__ */ jsxRuntime.jsx(
3964
+ drei.Html,
3965
+ {
3966
+ position,
3967
+ center: true,
3968
+ distanceFactor: 8,
3969
+ style: { pointerEvents: "none" },
3970
+ zIndexRange: [100, 0],
3971
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3972
+ Box,
3973
+ {
3974
+ style: {
3975
+ background: "rgba(12, 18, 34, 0.92)",
3976
+ backdropFilter: "blur(8px)",
3977
+ borderLeft: `3px solid ${accentColor}`,
3978
+ borderRadius: "6px",
3979
+ padding: "8px 12px",
3980
+ minWidth: "140px",
3981
+ maxWidth: "220px",
3982
+ boxShadow: "0 4px 20px rgba(0,0,0,0.4)"
3983
+ },
3984
+ children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "xs", children: [
3985
+ /* @__PURE__ */ jsxRuntime.jsx(
3986
+ Typography,
3987
+ {
3988
+ variant: "small",
3989
+ style: {
3990
+ color: "#ffffff",
3991
+ fontWeight: 600,
3992
+ fontSize: "12px",
3993
+ lineHeight: 1.3
3994
+ },
3995
+ children: title
3996
+ }
3997
+ ),
3998
+ rows.map((row) => /* @__PURE__ */ jsxRuntime.jsxs(
3999
+ Box,
4000
+ {
4001
+ style: {
4002
+ display: "flex",
4003
+ justifyContent: "space-between",
4004
+ gap: "12px"
4005
+ },
4006
+ children: [
4007
+ /* @__PURE__ */ jsxRuntime.jsx(
4008
+ Typography,
4009
+ {
4010
+ variant: "small",
4011
+ style: {
4012
+ color: "#8899bb",
4013
+ fontSize: "10px",
4014
+ whiteSpace: "nowrap"
4015
+ },
4016
+ children: row.label
4017
+ }
4018
+ ),
4019
+ /* @__PURE__ */ jsxRuntime.jsx(
4020
+ Typography,
4021
+ {
4022
+ variant: "small",
4023
+ style: {
4024
+ color: "#ccddf0",
4025
+ fontSize: "10px",
4026
+ fontWeight: 500,
4027
+ textAlign: "right"
4028
+ },
4029
+ children: row.value
4030
+ }
4031
+ )
4032
+ ]
4033
+ },
4034
+ row.label
4035
+ ))
4036
+ ] })
4037
+ }
4038
+ )
4039
+ }
4040
+ );
4041
+ };
4042
+ Avl3DTooltip.displayName = "Avl3DTooltip";
4043
+ var Avl3DOrbitalNode = ({
4044
+ name,
4045
+ entityName,
4046
+ traitCount,
4047
+ pageCount = 0,
4048
+ persistence = "persistent",
4049
+ position,
4050
+ onClick
4051
+ }) => {
4052
+ const groupRef = React21.useRef(null);
4053
+ const [hovered, setHovered] = React21.useState(false);
4054
+ const scale = React21.useMemo(() => 0.6 + Math.min(traitCount, 8) * 0.3, [traitCount]);
4055
+ const currentScale = React21.useRef(scale);
4056
+ const targetScale = hovered ? scale * 1.06 : scale;
4057
+ fiber.useFrame((_, delta) => {
4058
+ if (!groupRef.current) return;
4059
+ groupRef.current.rotation.y += delta * (hovered ? 0.4 : 0.2);
4060
+ groupRef.current.rotation.x += delta * 0.05;
4061
+ currentScale.current = THREE6.MathUtils.damp(currentScale.current, targetScale, 6, delta);
4062
+ });
4063
+ const baseBrightness = 0.3 + Math.min(pageCount, 5) * 0.05;
4064
+ const emissiveIntensity = hovered ? 0.8 : baseBrightness;
4065
+ return /* @__PURE__ */ jsxRuntime.jsxs("group", { position, children: [
4066
+ /* @__PURE__ */ jsxRuntime.jsxs("mesh", { scale: scale * 1.3, children: [
4067
+ /* @__PURE__ */ jsxRuntime.jsx("sphereGeometry", { args: [1, 16, 16] }),
4068
+ /* @__PURE__ */ jsxRuntime.jsx(
4069
+ "meshStandardMaterial",
4070
+ {
4071
+ color: AVL_3D_COLORS.orbitalRim,
4072
+ emissive: AVL_3D_COLORS.orbitalRim,
4073
+ emissiveIntensity: hovered ? 0.2 : 0.06,
4074
+ transparent: true,
4075
+ opacity: hovered ? 0.08 : 0.03,
4076
+ depthWrite: false
4077
+ }
4078
+ )
4079
+ ] }),
4080
+ /* @__PURE__ */ jsxRuntime.jsxs("group", { ref: groupRef, children: [
4081
+ /* @__PURE__ */ jsxRuntime.jsxs(
4082
+ "mesh",
4083
+ {
4084
+ onClick: (e) => {
4085
+ e.stopPropagation();
4086
+ onClick?.();
4087
+ },
4088
+ onPointerOver: (e) => {
4089
+ e.stopPropagation();
4090
+ setHovered(true);
4091
+ document.body.style.cursor = "pointer";
4092
+ },
4093
+ onPointerOut: () => {
4094
+ setHovered(false);
4095
+ document.body.style.cursor = "auto";
4096
+ },
4097
+ scale: currentScale.current,
4098
+ rotation: [Math.PI / 4, 0, 0],
4099
+ children: [
4100
+ /* @__PURE__ */ jsxRuntime.jsx("torusGeometry", { args: [1, 0.18, 24, 64] }),
4101
+ /* @__PURE__ */ jsxRuntime.jsx(
4102
+ "meshStandardMaterial",
4103
+ {
4104
+ color: AVL_3D_COLORS.orbitalSphere,
4105
+ emissive: AVL_3D_COLORS.orbitalRim,
4106
+ emissiveIntensity,
4107
+ roughness: 0.2,
4108
+ metalness: 0.7
4109
+ }
4110
+ )
4111
+ ]
4112
+ }
4113
+ ),
4114
+ /* @__PURE__ */ jsxRuntime.jsxs(
4115
+ "mesh",
4116
+ {
4117
+ scale: scale * 0.9,
4118
+ rotation: [Math.PI / 2 + 0.3, Math.PI / 5, 0],
4119
+ children: [
4120
+ /* @__PURE__ */ jsxRuntime.jsx("torusGeometry", { args: [1, 0.06, 12, 64] }),
4121
+ /* @__PURE__ */ jsxRuntime.jsx(
4122
+ "meshStandardMaterial",
4123
+ {
4124
+ color: AVL_3D_COLORS.traitOrbit,
4125
+ emissive: AVL_3D_COLORS.traitOrbit,
4126
+ emissiveIntensity: 0.25,
4127
+ transparent: true,
4128
+ opacity: 0.4
4129
+ }
4130
+ )
4131
+ ]
4132
+ }
4133
+ )
4134
+ ] }),
4135
+ /* @__PURE__ */ jsxRuntime.jsxs("mesh", { scale: scale * 0.25, children: [
4136
+ /* @__PURE__ */ jsxRuntime.jsx("icosahedronGeometry", { args: [1, 1] }),
4137
+ /* @__PURE__ */ jsxRuntime.jsx(
4138
+ "meshStandardMaterial",
4139
+ {
4140
+ color: AVL_3D_COLORS.entityCore,
4141
+ emissive: AVL_3D_COLORS.entityCoreGlow,
4142
+ emissiveIntensity: 2,
4143
+ roughness: 0.1
4144
+ }
4145
+ )
4146
+ ] }),
4147
+ /* @__PURE__ */ jsxRuntime.jsx(
4148
+ "pointLight",
4149
+ {
4150
+ color: AVL_3D_COLORS.entityCoreGlow,
4151
+ intensity: 0.5,
4152
+ distance: 3,
4153
+ decay: 2
4154
+ }
4155
+ ),
4156
+ /* @__PURE__ */ jsxRuntime.jsx(
4157
+ Avl3DLabel,
4158
+ {
4159
+ position: [0, scale + 0.6, 0],
4160
+ text: name,
4161
+ color: "#ffffff",
4162
+ fontSize: hovered ? 14 : 12
4163
+ }
4164
+ ),
4165
+ /* @__PURE__ */ jsxRuntime.jsx(
4166
+ Avl3DLabel,
4167
+ {
4168
+ position: [0, -(scale + 0.4), 0],
4169
+ text: entityName,
4170
+ color: "#999999",
4171
+ fontSize: 10
4172
+ }
4173
+ ),
4174
+ hovered && /* @__PURE__ */ jsxRuntime.jsx(
4175
+ Avl3DTooltip,
4176
+ {
4177
+ position: [scale + 1.2, 0.3, 0],
4178
+ title: name,
4179
+ accentColor: AVL_3D_COLORS.orbitalRim,
4180
+ rows: [
4181
+ { label: "Entity", value: entityName },
4182
+ { label: "Persistence", value: persistence },
4183
+ { label: "Traits", value: String(traitCount) },
4184
+ { label: "Pages", value: String(pageCount) }
4185
+ ]
4186
+ }
4187
+ )
4188
+ ] });
4189
+ };
4190
+ Avl3DOrbitalNode.displayName = "Avl3DOrbitalNode";
4191
+ var Avl3DCrossWire = ({
4192
+ from,
4193
+ to,
4194
+ eventName,
4195
+ color = AVL_3D_COLORS.crossWire
4196
+ }) => {
4197
+ const { tubeArgs, midpoint } = React21.useMemo(() => {
4198
+ const curve = arcCurve3D(from, to, 2);
4199
+ const mid = curve.getPoint(0.5);
4200
+ return {
4201
+ tubeArgs: [curve, 32, 0.03, 8, false],
4202
+ midpoint: [mid.x, mid.y, mid.z]
4203
+ };
4204
+ }, [from, to]);
4205
+ return /* @__PURE__ */ jsxRuntime.jsxs("group", { children: [
4206
+ /* @__PURE__ */ jsxRuntime.jsxs("mesh", { children: [
4207
+ /* @__PURE__ */ jsxRuntime.jsx("tubeGeometry", { args: [...tubeArgs] }),
4208
+ /* @__PURE__ */ jsxRuntime.jsx(
4209
+ "meshStandardMaterial",
4210
+ {
4211
+ color,
4212
+ emissive: color,
4213
+ emissiveIntensity: 0.4,
4214
+ transparent: true,
4215
+ opacity: 0.6,
4216
+ roughness: 0.5
4217
+ }
4218
+ )
4219
+ ] }),
4220
+ /* @__PURE__ */ jsxRuntime.jsx(
4221
+ Avl3DLabel,
4222
+ {
4223
+ position: midpoint,
4224
+ text: eventName,
4225
+ color,
4226
+ fontSize: 9
4227
+ }
4228
+ )
4229
+ ] });
4230
+ };
4231
+ Avl3DCrossWire.displayName = "Avl3DCrossWire";
4232
+ var Avl3DApplicationScene = ({
4233
+ data,
4234
+ onOrbitalClick
4235
+ }) => {
4236
+ const groupRef = React21.useRef(null);
4237
+ const [, setHoverTrigger] = React21.useState(0);
4238
+ const orbitalPositions = React21.useMemo(() => {
4239
+ const baseRadius = Math.max(4, data.orbitals.length * 1.5);
4240
+ if (data.crossLinks.length === 0) {
4241
+ return goldenSpiralPositions(data.orbitals.length, baseRadius);
4242
+ }
4243
+ const nameToIdx = /* @__PURE__ */ new Map();
4244
+ data.orbitals.forEach((o, i) => nameToIdx.set(o.name, i));
4245
+ const edges = data.crossLinks.map((link) => ({
4246
+ from: nameToIdx.get(link.emitterOrbital) ?? -1,
4247
+ to: nameToIdx.get(link.listenerOrbital) ?? -1
4248
+ })).filter((e) => e.from >= 0 && e.to >= 0);
4249
+ return forceDirectedPositions(data.orbitals.length, edges, baseRadius);
4250
+ }, [data.orbitals, data.crossLinks]);
4251
+ const positionByName = React21.useMemo(() => {
4252
+ const map = /* @__PURE__ */ new Map();
4253
+ data.orbitals.forEach((orb, i) => {
4254
+ const pos = orbitalPositions[i];
4255
+ map.set(orb.name, [pos.x, pos.y, pos.z]);
4256
+ });
4257
+ return map;
4258
+ }, [data.orbitals, orbitalPositions]);
4259
+ fiber.useFrame((_, delta) => {
4260
+ if (!groupRef.current) return;
4261
+ groupRef.current.rotation.y += delta * 0.03;
4262
+ });
4263
+ return /* @__PURE__ */ jsxRuntime.jsxs("group", { ref: groupRef, children: [
4264
+ data.orbitals.map((orbital, i) => {
4265
+ const pos = orbitalPositions[i];
4266
+ return /* @__PURE__ */ jsxRuntime.jsx(
4267
+ Avl3DOrbitalNode,
4268
+ {
4269
+ name: orbital.name,
4270
+ entityName: orbital.entityName,
4271
+ traitCount: orbital.traitNames.length,
4272
+ pageCount: orbital.pageNames.length,
4273
+ persistence: orbital.persistence,
4274
+ position: [pos.x, pos.y, pos.z],
4275
+ onClick: () => {
4276
+ onOrbitalClick?.(orbital.name);
4277
+ setHoverTrigger((v) => v + 1);
4278
+ }
4279
+ },
4280
+ orbital.name
4281
+ );
4282
+ }),
4283
+ data.crossLinks.map((link, i) => {
4284
+ const fromPos = positionByName.get(link.emitterOrbital);
4285
+ const toPos = positionByName.get(link.listenerOrbital);
4286
+ if (!fromPos || !toPos) return null;
4287
+ return /* @__PURE__ */ jsxRuntime.jsx(
4288
+ Avl3DCrossWire,
4289
+ {
4290
+ from: fromPos,
4291
+ to: toPos,
4292
+ eventName: link.eventName
4293
+ },
4294
+ `${link.emitterOrbital}-${link.eventName}-${link.listenerOrbital}-${i}`
4295
+ );
4296
+ })
4297
+ ] });
4298
+ };
4299
+ Avl3DApplicationScene.displayName = "Avl3DApplicationScene";
4300
+ function fieldPositions(count, radius) {
4301
+ const positions = [];
4302
+ const goldenAngle = Math.PI * (3 - Math.sqrt(5));
4303
+ for (let i = 0; i < Math.min(count, 12); i++) {
4304
+ const y = 1 - 2 * i / Math.max(count - 1, 1);
4305
+ const r = Math.sqrt(1 - y * y);
4306
+ const theta = goldenAngle * i;
4307
+ positions.push([
4308
+ radius * r * Math.cos(theta),
4309
+ radius * y,
4310
+ radius * r * Math.sin(theta)
4311
+ ]);
4312
+ }
4313
+ return positions;
4314
+ }
4315
+ function persistenceColor(persistence) {
4316
+ switch (persistence) {
4317
+ case "persistent":
4318
+ return "#4A90D9";
4319
+ case "runtime":
4320
+ return "#27AE60";
4321
+ case "singleton":
4322
+ return "#E8913A";
4323
+ default:
4324
+ return "#999999";
4325
+ }
4326
+ }
4327
+ var Avl3DEntityCore = ({
4328
+ name,
4329
+ fieldCount,
4330
+ persistence,
4331
+ position,
4332
+ fields
4333
+ }) => {
4334
+ const coreRef = React21.useRef(null);
4335
+ fiber.useFrame((_, delta) => {
4336
+ if (!coreRef.current) return;
4337
+ coreRef.current.rotation.y += delta * 0.3;
4338
+ coreRef.current.rotation.x += delta * 0.1;
4339
+ });
4340
+ const fieldPos = fieldPositions(fieldCount, 1.4);
4341
+ const pColor = persistenceColor(persistence);
4342
+ return /* @__PURE__ */ jsxRuntime.jsxs("group", { position, children: [
4343
+ /* @__PURE__ */ jsxRuntime.jsxs("mesh", { ref: coreRef, children: [
4344
+ /* @__PURE__ */ jsxRuntime.jsx("icosahedronGeometry", { args: [1, 2] }),
4345
+ /* @__PURE__ */ jsxRuntime.jsx(
4346
+ "meshStandardMaterial",
4347
+ {
4348
+ color: AVL_3D_COLORS.entityCore,
4349
+ emissive: AVL_3D_COLORS.entityCoreGlow,
4350
+ emissiveIntensity: 2,
4351
+ roughness: 0.15,
4352
+ metalness: 0.85
4353
+ }
4354
+ )
4355
+ ] }),
4356
+ /* @__PURE__ */ jsxRuntime.jsxs("mesh", { scale: 1.2, children: [
4357
+ /* @__PURE__ */ jsxRuntime.jsx("sphereGeometry", { args: [1, 24, 24] }),
4358
+ /* @__PURE__ */ jsxRuntime.jsx(
4359
+ "meshStandardMaterial",
4360
+ {
4361
+ color: AVL_3D_COLORS.entityCoreGlow,
4362
+ emissive: AVL_3D_COLORS.entityCoreGlow,
4363
+ emissiveIntensity: 0.6,
4364
+ transparent: true,
4365
+ opacity: 0.1,
4366
+ depthWrite: false
4367
+ }
4368
+ )
4369
+ ] }),
4370
+ /* @__PURE__ */ jsxRuntime.jsxs("mesh", { scale: 1.6, children: [
4371
+ /* @__PURE__ */ jsxRuntime.jsx("sphereGeometry", { args: [1, 16, 16] }),
4372
+ /* @__PURE__ */ jsxRuntime.jsx(
4373
+ "meshStandardMaterial",
4374
+ {
4375
+ color: AVL_3D_COLORS.entityCore,
4376
+ emissive: AVL_3D_COLORS.entityCore,
4377
+ emissiveIntensity: 0.2,
4378
+ transparent: true,
4379
+ opacity: 0.04,
4380
+ depthWrite: false
4381
+ }
4382
+ )
4383
+ ] }),
4384
+ /* @__PURE__ */ jsxRuntime.jsx(
4385
+ "pointLight",
4386
+ {
4387
+ color: AVL_3D_COLORS.entityCoreGlow,
4388
+ intensity: 2.5,
4389
+ distance: 10,
4390
+ decay: 2
4391
+ }
4392
+ ),
4393
+ fieldPos.map((pos, i) => {
4394
+ const fieldType = fields?.[i];
4395
+ return /* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: pos, scale: 0.08, rotation: [Math.PI / 6, Math.PI / 4, 0], children: [
4396
+ fieldType === "number" ? /* @__PURE__ */ jsxRuntime.jsx("tetrahedronGeometry", { args: [1, 0] }) : fieldType === "boolean" ? /* @__PURE__ */ jsxRuntime.jsx("boxGeometry", { args: [1.2, 1.2, 1.2] }) : fieldType === "date" ? /* @__PURE__ */ jsxRuntime.jsx("octahedronGeometry", { args: [1, 0] }) : fieldType === "enum" ? /* @__PURE__ */ jsxRuntime.jsx("torusGeometry", { args: [0.8, 0.3, 6, 12] }) : fieldType === "object" ? /* @__PURE__ */ jsxRuntime.jsx("dodecahedronGeometry", { args: [1, 0] }) : fieldType === "array" ? /* @__PURE__ */ jsxRuntime.jsx("cylinderGeometry", { args: [0.8, 0.8, 1.5, 6] }) : (
4397
+ // string (default): sphere
4398
+ /* @__PURE__ */ jsxRuntime.jsx("sphereGeometry", { args: [1, 8, 8] })
4399
+ ),
4400
+ /* @__PURE__ */ jsxRuntime.jsx(
4401
+ "meshStandardMaterial",
4402
+ {
4403
+ color: "#ffffff",
4404
+ emissive: "#ffffff",
4405
+ emissiveIntensity: 0.8,
4406
+ transparent: true,
4407
+ opacity: 0.7
4408
+ }
4409
+ )
4410
+ ] }, i);
4411
+ }),
4412
+ persistence === "singleton" ? (
4413
+ // Singleton: double concentric rings (thick outer + thin inner)
4414
+ /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4415
+ /* @__PURE__ */ jsxRuntime.jsxs("mesh", { rotation: [Math.PI / 2, 0, 0], children: [
4416
+ /* @__PURE__ */ jsxRuntime.jsx("torusGeometry", { args: [1.6, 0.04, 8, 64] }),
4417
+ /* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color: pColor, emissive: pColor, emissiveIntensity: 0.6, transparent: true, opacity: 0.6 })
4418
+ ] }),
4419
+ /* @__PURE__ */ jsxRuntime.jsxs("mesh", { rotation: [Math.PI / 2, 0, 0], children: [
4420
+ /* @__PURE__ */ jsxRuntime.jsx("torusGeometry", { args: [1.4, 0.02, 8, 64] }),
4421
+ /* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color: pColor, emissive: pColor, emissiveIntensity: 0.4, transparent: true, opacity: 0.4 })
4422
+ ] })
4423
+ ] })
4424
+ ) : persistence === "runtime" ? (
4425
+ // Runtime: segmented ring (8 arc segments with gaps)
4426
+ /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: Array.from({ length: 8 }).map((_, i) => {
4427
+ const angle = i / 8 * Math.PI * 2;
4428
+ const x = 1.6 * Math.cos(angle);
4429
+ const z = 1.6 * Math.sin(angle);
4430
+ return /* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [x, 0, z], rotation: [Math.PI / 2, 0, angle], children: [
4431
+ /* @__PURE__ */ jsxRuntime.jsx("torusGeometry", { args: [0.25, 0.025, 6, 12, Math.PI * 0.7] }),
4432
+ /* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color: pColor, emissive: pColor, emissiveIntensity: 0.6, transparent: true, opacity: 0.6 })
4433
+ ] }, i);
4434
+ }) })
4435
+ ) : persistence === "instance" ? (
4436
+ // Instance: dotted ring (small spheres in a circle)
4437
+ /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: Array.from({ length: 16 }).map((_, i) => {
4438
+ const angle = i / 16 * Math.PI * 2;
4439
+ const x = 1.6 * Math.cos(angle);
4440
+ const z = 1.6 * Math.sin(angle);
4441
+ return /* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [x, 0, z], scale: 0.04, children: [
4442
+ /* @__PURE__ */ jsxRuntime.jsx("sphereGeometry", { args: [1, 6, 6] }),
4443
+ /* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color: pColor, emissive: pColor, emissiveIntensity: 0.8 })
4444
+ ] }, i);
4445
+ }) })
4446
+ ) : (
4447
+ // Persistent (default): solid torus ring
4448
+ /* @__PURE__ */ jsxRuntime.jsxs("mesh", { rotation: [Math.PI / 2, 0, 0], children: [
4449
+ /* @__PURE__ */ jsxRuntime.jsx("torusGeometry", { args: [1.6, 0.03, 8, 64] }),
4450
+ /* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color: pColor, emissive: pColor, emissiveIntensity: 0.6, transparent: true, opacity: 0.6 })
4451
+ ] })
4452
+ ),
4453
+ /* @__PURE__ */ jsxRuntime.jsx(
4454
+ Avl3DLabel,
4455
+ {
4456
+ position: [0, -1.8, 0],
4457
+ text: name,
4458
+ color: AVL_3D_COLORS.entityCore,
4459
+ fontSize: 14
4460
+ }
4461
+ ),
4462
+ /* @__PURE__ */ jsxRuntime.jsx(
4463
+ Avl3DLabel,
4464
+ {
4465
+ position: [0, -2.3, 0],
4466
+ text: `${fieldCount} fields`,
4467
+ color: "#999999",
4468
+ fontSize: 10
4469
+ }
4470
+ )
4471
+ ] });
4472
+ };
4473
+ Avl3DEntityCore.displayName = "Avl3DEntityCore";
4474
+ function TraitOrbit({
4475
+ name,
4476
+ radius,
4477
+ tilt,
4478
+ speed,
4479
+ highlighted,
4480
+ dimmed,
4481
+ stateCount = 0,
4482
+ eventCount = 0,
4483
+ transitionCount = 0,
4484
+ onClick,
4485
+ onHover
4486
+ }) {
4487
+ const groupRef = React21.useRef(null);
4488
+ const angleRef = React21.useRef(Math.random() * Math.PI * 2);
4489
+ fiber.useFrame((_, delta) => {
4490
+ angleRef.current += delta * speed;
4491
+ if (!groupRef.current) return;
4492
+ const x = radius * Math.cos(angleRef.current);
4493
+ const flatZ = radius * Math.sin(angleRef.current);
4494
+ const y = flatZ * Math.sin(tilt);
4495
+ const z = flatZ * Math.cos(tilt);
4496
+ groupRef.current.position.set(x, y, z);
4497
+ });
4498
+ const opacity = dimmed ? 0.2 : 0.5;
4499
+ const emissiveIntensity = highlighted ? 0.8 : 0.4;
4500
+ return /* @__PURE__ */ jsxRuntime.jsxs("group", { children: [
4501
+ /* @__PURE__ */ jsxRuntime.jsxs("mesh", { rotation: [tilt, 0, 0], children: [
4502
+ /* @__PURE__ */ jsxRuntime.jsx("torusGeometry", { args: [radius, 0.015, 8, 64] }),
4503
+ /* @__PURE__ */ jsxRuntime.jsx(
4504
+ "meshStandardMaterial",
4505
+ {
4506
+ color: AVL_3D_COLORS.traitOrbit,
4507
+ emissive: AVL_3D_COLORS.traitOrbit,
4508
+ emissiveIntensity,
4509
+ transparent: true,
4510
+ opacity
4511
+ }
4512
+ )
4513
+ ] }),
4514
+ /* @__PURE__ */ jsxRuntime.jsxs("group", { ref: groupRef, children: [
4515
+ /* @__PURE__ */ jsxRuntime.jsxs(
4516
+ "mesh",
4517
+ {
4518
+ onClick: (e) => {
4519
+ e.stopPropagation();
4520
+ onClick?.();
4521
+ },
4522
+ onPointerOver: (e) => {
4523
+ e.stopPropagation();
4524
+ onHover?.(true);
4525
+ document.body.style.cursor = "pointer";
4526
+ },
4527
+ onPointerOut: () => {
4528
+ onHover?.(false);
4529
+ document.body.style.cursor = "auto";
4530
+ },
4531
+ scale: highlighted ? 1.3 : 1,
4532
+ children: [
4533
+ /* @__PURE__ */ jsxRuntime.jsx("sphereGeometry", { args: [0.25, 16, 16] }),
4534
+ /* @__PURE__ */ jsxRuntime.jsx(
4535
+ "meshStandardMaterial",
4536
+ {
4537
+ color: AVL_3D_COLORS.traitOrbit,
4538
+ emissive: AVL_3D_COLORS.traitOrbit,
4539
+ emissiveIntensity: highlighted ? 1.2 : 0.6,
4540
+ transparent: true,
4541
+ opacity: dimmed ? 0.3 : 0.9
4542
+ }
4543
+ )
4544
+ ]
4545
+ }
4546
+ ),
4547
+ /* @__PURE__ */ jsxRuntime.jsx(
4548
+ Avl3DLabel,
4549
+ {
4550
+ position: [0, 0.5, 0],
4551
+ text: name,
4552
+ color: dimmed ? "#666666" : "#ffffff",
4553
+ fontSize: highlighted ? 13 : 11
4554
+ }
4555
+ ),
4556
+ highlighted && /* @__PURE__ */ jsxRuntime.jsx(
4557
+ Avl3DTooltip,
4558
+ {
4559
+ position: [0.8, 0.8, 0],
4560
+ title: name,
4561
+ accentColor: AVL_3D_COLORS.traitOrbitHighlight,
4562
+ rows: [
4563
+ { label: "States", value: String(stateCount) },
4564
+ { label: "Events", value: String(eventCount) },
4565
+ { label: "Transitions", value: String(transitionCount) }
4566
+ ]
4567
+ }
4568
+ )
4569
+ ] })
4570
+ ] });
4571
+ }
4572
+ function PagePortal({ name, position }) {
4573
+ return /* @__PURE__ */ jsxRuntime.jsxs("group", { position, children: [
4574
+ /* @__PURE__ */ jsxRuntime.jsxs("mesh", { rotation: [Math.PI / 2, 0, 0], children: [
4575
+ /* @__PURE__ */ jsxRuntime.jsx("cylinderGeometry", { args: [0.35, 0.35, 0.12, 6] }),
4576
+ /* @__PURE__ */ jsxRuntime.jsx(
4577
+ "meshStandardMaterial",
4578
+ {
4579
+ color: AVL_3D_COLORS.pagePortal,
4580
+ emissive: AVL_3D_COLORS.pagePortal,
4581
+ emissiveIntensity: 0.5,
4582
+ transparent: true,
4583
+ opacity: 0.7,
4584
+ roughness: 0.3
4585
+ }
4586
+ )
4587
+ ] }),
4588
+ /* @__PURE__ */ jsxRuntime.jsxs("mesh", { rotation: [Math.PI / 2, 0, 0], children: [
4589
+ /* @__PURE__ */ jsxRuntime.jsx("cylinderGeometry", { args: [0.25, 0.25, 0.14, 6] }),
4590
+ /* @__PURE__ */ jsxRuntime.jsx(
4591
+ "meshStandardMaterial",
4592
+ {
4593
+ color: AVL_3D_COLORS.pagePortal,
4594
+ emissive: AVL_3D_COLORS.pagePortal,
4595
+ emissiveIntensity: 0.8,
4596
+ transparent: true,
4597
+ opacity: 0.2,
4598
+ depthWrite: false
4599
+ }
4600
+ )
4601
+ ] }),
4602
+ /* @__PURE__ */ jsxRuntime.jsx(
4603
+ Avl3DLabel,
4604
+ {
4605
+ position: [0, -0.5, 0],
4606
+ text: name,
4607
+ color: AVL_3D_COLORS.pagePortal,
4608
+ fontSize: 9
4609
+ }
4610
+ )
4611
+ ] });
4612
+ }
4613
+ var Avl3DOrbitalScene = ({
4614
+ data,
4615
+ onTraitClick,
4616
+ highlightedTrait,
4617
+ onTraitHighlight
4618
+ }) => {
4619
+ const [localHighlight, setLocalHighlight] = React21.useState(null);
4620
+ const activeHighlight = highlightedTrait ?? localHighlight;
4621
+ const traitOrbits = React21.useMemo(() => {
4622
+ return data.traits.map((trait, i) => ({
4623
+ name: trait.name,
4624
+ radius: 3 + i * 1.2,
4625
+ tilt: i * Math.PI / (data.traits.length + 1) - Math.PI / 4,
4626
+ speed: 0.3 - i * 0.04,
4627
+ stateCount: trait.stateCount,
4628
+ eventCount: trait.eventCount,
4629
+ transitionCount: trait.transitionCount
4630
+ }));
4631
+ }, [data.traits]);
4632
+ const pagePositions = React21.useMemo(() => {
4633
+ const outerRadius = 3 + data.traits.length * 1.2 + 1.5;
4634
+ return data.pages.map((_, i) => {
4635
+ const angle = 2 * Math.PI * i / data.pages.length - Math.PI / 2;
4636
+ return [
4637
+ outerRadius * Math.cos(angle),
4638
+ 0,
4639
+ outerRadius * Math.sin(angle)
4640
+ ];
4641
+ });
4642
+ }, [data.pages, data.traits.length]);
4643
+ return /* @__PURE__ */ jsxRuntime.jsxs("group", { children: [
4644
+ /* @__PURE__ */ jsxRuntime.jsx(
4645
+ Avl3DEntityCore,
4646
+ {
4647
+ name: data.entity.name,
4648
+ fieldCount: data.entity.fields.length,
4649
+ persistence: data.entity.persistence,
4650
+ position: [0, 0, 0],
4651
+ fields: data.entity.fields.map((f) => f.type)
4652
+ }
4653
+ ),
4654
+ traitOrbits.map((orbit) => /* @__PURE__ */ jsxRuntime.jsx(
4655
+ TraitOrbit,
4656
+ {
4657
+ name: orbit.name,
4658
+ radius: orbit.radius,
4659
+ tilt: orbit.tilt,
4660
+ speed: orbit.speed,
4661
+ highlighted: activeHighlight === orbit.name,
4662
+ dimmed: activeHighlight !== null && activeHighlight !== orbit.name,
4663
+ stateCount: orbit.stateCount,
4664
+ eventCount: orbit.eventCount,
4665
+ transitionCount: orbit.transitionCount,
4666
+ onClick: () => onTraitClick?.(orbit.name),
4667
+ onHover: (h) => {
4668
+ const value = h ? orbit.name : null;
4669
+ onTraitHighlight?.(value);
4670
+ setLocalHighlight(value);
4671
+ }
4672
+ },
4673
+ orbit.name
4674
+ )),
4675
+ data.pages.map((page, i) => /* @__PURE__ */ jsxRuntime.jsx(
4676
+ PagePortal,
4677
+ {
4678
+ name: page.name,
4679
+ position: pagePositions[i]
4680
+ },
4681
+ page.name
4682
+ ))
4683
+ ] });
4684
+ };
4685
+ Avl3DOrbitalScene.displayName = "Avl3DOrbitalScene";
4686
+ var Avl3DStateNode = ({
4687
+ name,
4688
+ isInitial = false,
4689
+ isTerminal = false,
4690
+ position,
4691
+ active = false,
4692
+ incomingCount = 0,
4693
+ outgoingCount = 0,
4694
+ onClick
4695
+ }) => {
4696
+ const [hovered, setHovered] = React21.useState(false);
4697
+ const baseColor = active ? AVL_3D_COLORS.stateActive : AVL_3D_COLORS.stateIdle;
4698
+ const emissiveColor = active ? AVL_3D_COLORS.stateActive : AVL_3D_COLORS.stateEdge;
4699
+ const emissiveIntensity = active ? 2 : hovered ? 0.8 : 0.3;
4700
+ const targetScale = hovered ? 1.08 : 1;
4701
+ const currentScale = React21.useRef(1);
4702
+ fiber.useFrame((_, delta) => {
4703
+ currentScale.current = THREE6.MathUtils.damp(currentScale.current, targetScale, 6, delta);
4704
+ });
4705
+ const scale = currentScale.current;
4706
+ return /* @__PURE__ */ jsxRuntime.jsxs("group", { position, children: [
4707
+ /* @__PURE__ */ jsxRuntime.jsxs("mesh", { scale: scale * 1.4, children: [
4708
+ /* @__PURE__ */ jsxRuntime.jsx("boxGeometry", { args: [1.2, 0.7, 0.5] }),
4709
+ /* @__PURE__ */ jsxRuntime.jsx(
4710
+ "meshStandardMaterial",
4711
+ {
4712
+ color: emissiveColor,
4713
+ emissive: emissiveColor,
4714
+ emissiveIntensity: active ? 0.3 : hovered ? 0.1 : 0.03,
4715
+ transparent: true,
4716
+ opacity: active ? 0.08 : 0.03,
4717
+ depthWrite: false
4718
+ }
4719
+ )
4720
+ ] }),
4721
+ /* @__PURE__ */ jsxRuntime.jsx(
4722
+ drei.RoundedBox,
4723
+ {
4724
+ args: [1, 0.55, 0.35],
4725
+ radius: 0.12,
4726
+ smoothness: 4,
4727
+ scale,
4728
+ onClick: (e) => {
4729
+ e.stopPropagation();
4730
+ onClick?.();
4731
+ },
4732
+ onPointerOver: (e) => {
4733
+ e.stopPropagation();
4734
+ setHovered(true);
4735
+ document.body.style.cursor = "pointer";
4736
+ },
4737
+ onPointerOut: () => {
4738
+ setHovered(false);
4739
+ document.body.style.cursor = "auto";
4740
+ },
4741
+ children: /* @__PURE__ */ jsxRuntime.jsx(
4742
+ "meshStandardMaterial",
4743
+ {
4744
+ color: baseColor,
4745
+ emissive: emissiveColor,
4746
+ emissiveIntensity,
4747
+ roughness: 0.35,
4748
+ metalness: 0.5
4749
+ }
4750
+ )
4751
+ }
4752
+ ),
4753
+ isInitial && /* @__PURE__ */ jsxRuntime.jsxs("group", { position: [-0.75, 0, 0], children: [
4754
+ /* @__PURE__ */ jsxRuntime.jsxs("mesh", { rotation: [0, 0, -Math.PI / 2], children: [
4755
+ /* @__PURE__ */ jsxRuntime.jsx("coneGeometry", { args: [0.12, 0.25, 8] }),
4756
+ /* @__PURE__ */ jsxRuntime.jsx(
4757
+ "meshStandardMaterial",
4758
+ {
4759
+ color: AVL_3D_COLORS.stateActive,
4760
+ emissive: AVL_3D_COLORS.stateActive,
4761
+ emissiveIntensity: 1
4762
+ }
4763
+ )
4764
+ ] }),
4765
+ /* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [-0.2, 0, 0], rotation: [0, 0, Math.PI / 2], children: [
4766
+ /* @__PURE__ */ jsxRuntime.jsx("cylinderGeometry", { args: [0.02, 0.02, 0.25, 6] }),
4767
+ /* @__PURE__ */ jsxRuntime.jsx(
4768
+ "meshStandardMaterial",
4769
+ {
4770
+ color: AVL_3D_COLORS.stateActive,
4771
+ emissive: AVL_3D_COLORS.stateActive,
4772
+ emissiveIntensity: 0.6
4773
+ }
4774
+ )
4775
+ ] })
4776
+ ] }),
4777
+ isTerminal && /* @__PURE__ */ jsxRuntime.jsxs("group", { position: [0.75, 0, 0], children: [
4778
+ /* @__PURE__ */ jsxRuntime.jsxs("mesh", { scale: 0.15, children: [
4779
+ /* @__PURE__ */ jsxRuntime.jsx("octahedronGeometry", { args: [1, 0] }),
4780
+ /* @__PURE__ */ jsxRuntime.jsx(
4781
+ "meshStandardMaterial",
4782
+ {
4783
+ color: AVL_3D_COLORS.guardFail,
4784
+ emissive: AVL_3D_COLORS.guardFail,
4785
+ emissiveIntensity: 1
4786
+ }
4787
+ )
4788
+ ] }),
4789
+ /* @__PURE__ */ jsxRuntime.jsxs("mesh", { rotation: [Math.PI / 2, 0, 0], children: [
4790
+ /* @__PURE__ */ jsxRuntime.jsx("torusGeometry", { args: [0.2, 0.015, 8, 24] }),
4791
+ /* @__PURE__ */ jsxRuntime.jsx(
4792
+ "meshStandardMaterial",
4793
+ {
4794
+ color: AVL_3D_COLORS.guardFail,
4795
+ emissive: AVL_3D_COLORS.guardFail,
4796
+ emissiveIntensity: 0.5
4797
+ }
4798
+ )
4799
+ ] })
4800
+ ] }),
4801
+ active && /* @__PURE__ */ jsxRuntime.jsx(
4802
+ "pointLight",
4803
+ {
4804
+ color: AVL_3D_COLORS.stateActive,
4805
+ intensity: 1.5,
4806
+ distance: 4,
4807
+ decay: 2
4808
+ }
4809
+ ),
4810
+ /* @__PURE__ */ jsxRuntime.jsx(
4811
+ Avl3DLabel,
4812
+ {
4813
+ position: [0, -0.55, 0],
4814
+ text: name,
4815
+ color: active ? AVL_3D_COLORS.stateActive : "#ffffff",
4816
+ fontSize: 11
4817
+ }
4818
+ ),
4819
+ hovered && /* @__PURE__ */ jsxRuntime.jsx(
4820
+ Avl3DTooltip,
4821
+ {
4822
+ position: [0.9, 0.3, 0],
4823
+ title: name,
4824
+ accentColor: active ? AVL_3D_COLORS.stateActive : AVL_3D_COLORS.stateEdge,
4825
+ rows: [
4826
+ { label: "Type", value: isInitial ? "Initial" : isTerminal ? "Terminal" : "Standard" },
4827
+ { label: "Incoming", value: String(incomingCount) },
4828
+ { label: "Outgoing", value: String(outgoingCount) },
4829
+ ...active ? [{ label: "Status", value: "Active" }] : []
4830
+ ]
4831
+ }
4832
+ )
4833
+ ] });
4834
+ };
4835
+ Avl3DStateNode.displayName = "Avl3DStateNode";
4836
+ function effectTypeColor(type) {
4837
+ switch (type) {
4838
+ case "render-ui":
4839
+ return "#5b9bd5";
4840
+ case "set":
4841
+ return "#e0944a";
4842
+ case "persist":
4843
+ return "#4ecb71";
4844
+ case "fetch":
4845
+ return "#5b9bd5";
4846
+ case "emit":
4847
+ return "#a78bda";
4848
+ case "navigate":
4849
+ return "#40c8aa";
4850
+ case "notify":
4851
+ return "#f0c040";
4852
+ case "call-service":
4853
+ return "#a78bda";
4854
+ case "spawn":
4855
+ return "#4ecb71";
4856
+ case "despawn":
4857
+ return "#f06060";
4858
+ default:
4859
+ return "#888888";
4860
+ }
4861
+ }
4862
+ var Avl3DTransitionArc = ({
4863
+ from,
4864
+ to,
4865
+ event,
4866
+ hasGuard = false,
4867
+ effectTypes,
4868
+ index,
4869
+ isSelf = false,
4870
+ fromState,
4871
+ toState,
4872
+ onClick,
4873
+ color = AVL_3D_COLORS.transitionArc
4874
+ }) => {
4875
+ const [hovered, setHovered] = React21.useState(false);
4876
+ const { tubeArgs, labelPos, guardPos, arrowPos, arrowQuat, effectPositions } = React21.useMemo(() => {
4877
+ const offset = 1.5 + index * 0.8;
4878
+ const curve = isSelf ? selfLoopCurve3D(from, 1.2) : arcCurve3D(from, to, offset);
4879
+ const mid = curve.getPoint(0.5);
4880
+ const guardPt = curve.getPoint(0.3);
4881
+ const arrowPt = curve.getPoint(0.9);
4882
+ const arrowTangent = curve.getTangent(0.9);
4883
+ const upVec = new THREE6.Vector3(0, 1, 0);
4884
+ const tangentVec = new THREE6.Vector3(arrowTangent.x, arrowTangent.y, arrowTangent.z).normalize();
4885
+ const quat = new THREE6.Quaternion().setFromUnitVectors(upVec, tangentVec);
4886
+ const effectPositions2 = [];
4887
+ for (let ei = 0; ei < 4; ei++) {
4888
+ const t = 0.7 + ei * 0.05;
4889
+ const ep = curve.getPoint(t);
4890
+ effectPositions2.push([ep.x, ep.y + 0.2, ep.z]);
4891
+ }
4892
+ return {
4893
+ tubeArgs: [curve, 48, 0.02, 8, false],
4894
+ labelPos: [mid.x, mid.y + 0.3, mid.z],
4895
+ guardPos: [guardPt.x, guardPt.y, guardPt.z],
4896
+ arrowPos: [arrowPt.x, arrowPt.y, arrowPt.z],
4897
+ arrowQuat: [quat.x, quat.y, quat.z, quat.w],
4898
+ effectPositions: effectPositions2
4899
+ };
4900
+ }, [from, to, index, isSelf]);
4901
+ const emissiveIntensity = hovered ? 0.8 : 0.4;
4902
+ return /* @__PURE__ */ jsxRuntime.jsxs("group", { children: [
4903
+ /* @__PURE__ */ jsxRuntime.jsxs(
4904
+ "mesh",
4905
+ {
4906
+ onClick: (e) => {
4907
+ e.stopPropagation();
4908
+ onClick?.();
4909
+ },
4910
+ onPointerOver: (e) => {
4911
+ e.stopPropagation();
4912
+ setHovered(true);
4913
+ document.body.style.cursor = "pointer";
4914
+ },
4915
+ onPointerOut: () => {
4916
+ setHovered(false);
4917
+ document.body.style.cursor = "auto";
4918
+ },
4919
+ children: [
4920
+ /* @__PURE__ */ jsxRuntime.jsx("tubeGeometry", { args: [...tubeArgs] }),
4921
+ /* @__PURE__ */ jsxRuntime.jsx(
4922
+ "meshStandardMaterial",
4923
+ {
4924
+ color,
4925
+ emissive: color,
4926
+ emissiveIntensity,
4927
+ transparent: true,
4928
+ opacity: hovered ? 0.9 : 0.7
4929
+ }
4930
+ )
4931
+ ]
4932
+ }
4933
+ ),
4934
+ hasGuard && /* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: guardPos, scale: 0.15, children: [
4935
+ /* @__PURE__ */ jsxRuntime.jsx("octahedronGeometry", { args: [1, 0] }),
4936
+ /* @__PURE__ */ jsxRuntime.jsx(
4937
+ "meshStandardMaterial",
4938
+ {
4939
+ color: AVL_3D_COLORS.guardPass,
4940
+ emissive: AVL_3D_COLORS.guardPass,
4941
+ emissiveIntensity: 0.8
4942
+ }
4943
+ )
4944
+ ] }),
4945
+ /* @__PURE__ */ jsxRuntime.jsxs(
4946
+ "mesh",
4947
+ {
4948
+ position: arrowPos,
4949
+ quaternion: arrowQuat,
4950
+ scale: 0.08,
4951
+ children: [
4952
+ /* @__PURE__ */ jsxRuntime.jsx("coneGeometry", { args: [1, 2, 8] }),
4953
+ /* @__PURE__ */ jsxRuntime.jsx(
4954
+ "meshStandardMaterial",
4955
+ {
4956
+ color,
4957
+ emissive: color,
4958
+ emissiveIntensity: 0.6
4959
+ }
4960
+ )
4961
+ ]
4962
+ }
4963
+ ),
4964
+ /* @__PURE__ */ jsxRuntime.jsx(
4965
+ Avl3DLabel,
4966
+ {
4967
+ position: labelPos,
4968
+ text: event,
4969
+ color: hovered ? "#ffffff" : color,
4970
+ fontSize: hovered ? 11 : 9
4971
+ }
4972
+ ),
4973
+ hovered && /* @__PURE__ */ jsxRuntime.jsx(
4974
+ Avl3DTooltip,
4975
+ {
4976
+ position: [labelPos[0], labelPos[1] + 0.6, labelPos[2]],
4977
+ title: event,
4978
+ accentColor: AVL_3D_COLORS.transitionArc,
4979
+ rows: [
4980
+ ...fromState && toState ? [{ label: "Transition", value: `${fromState} \u2192 ${toState}` }] : [],
4981
+ ...hasGuard ? [{ label: "Guard", value: "Yes" }] : [],
4982
+ ...effectTypes && effectTypes.length > 0 ? [{ label: "Effects", value: effectTypes.slice(0, 3).join(", ") + (effectTypes.length > 3 ? ` +${effectTypes.length - 3}` : "") }] : []
4983
+ ]
4984
+ }
4985
+ ),
4986
+ effectTypes && effectTypes.length > 0 && effectTypes.slice(0, 4).map((effectType, ei) => {
4987
+ const pt = effectPositions[ei];
4988
+ if (!pt) return null;
4989
+ const eColor = effectTypeColor(effectType);
4990
+ return /* @__PURE__ */ jsxRuntime.jsx("group", { position: pt, children: /* @__PURE__ */ jsxRuntime.jsxs("mesh", { scale: 0.06, children: [
4991
+ effectType === "render-ui" ? /* @__PURE__ */ jsxRuntime.jsx("boxGeometry", { args: [1.5, 1.5, 0.3] }) : effectType === "persist" ? /* @__PURE__ */ jsxRuntime.jsx("cylinderGeometry", { args: [0.6, 0.6, 1.5, 8] }) : effectType === "emit" ? /* @__PURE__ */ jsxRuntime.jsx("sphereGeometry", { args: [1, 8, 8] }) : effectType === "navigate" ? /* @__PURE__ */ jsxRuntime.jsx("coneGeometry", { args: [0.8, 1.5, 6] }) : effectType === "set" ? /* @__PURE__ */ jsxRuntime.jsx("tetrahedronGeometry", { args: [1, 0] }) : effectType === "notify" ? /* @__PURE__ */ jsxRuntime.jsx("dodecahedronGeometry", { args: [0.8, 0] }) : effectType === "call-service" ? /* @__PURE__ */ jsxRuntime.jsx("torusGeometry", { args: [0.8, 0.3, 6, 12] }) : /* @__PURE__ */ jsxRuntime.jsx("octahedronGeometry", { args: [0.8, 0] }),
4992
+ /* @__PURE__ */ jsxRuntime.jsx(
4993
+ "meshStandardMaterial",
4994
+ {
4995
+ color: eColor,
4996
+ emissive: eColor,
4997
+ emissiveIntensity: 0.8
4998
+ }
4999
+ )
5000
+ ] }) }, ei);
5001
+ })
5002
+ ] });
5003
+ };
5004
+ Avl3DTransitionArc.displayName = "Avl3DTransitionArc";
5005
+ var Avl3DTraitScene = ({
5006
+ data,
5007
+ onTransitionClick
5008
+ }) => {
5009
+ const statePositions = React21.useMemo(() => {
5010
+ const radius = Math.max(3, data.states.length * 0.8);
5011
+ const positions = fibonacciSpherePositions(data.states.length, radius);
5012
+ const posMap = /* @__PURE__ */ new Map();
5013
+ data.states.forEach((state, i) => {
5014
+ const pos = positions[i];
5015
+ posMap.set(state.name, [pos.x, pos.y, pos.z]);
5016
+ });
5017
+ return posMap;
5018
+ }, [data.states]);
5019
+ const transitionIndices = React21.useMemo(() => {
5020
+ const pairCount = /* @__PURE__ */ new Map();
5021
+ return data.transitions.map((t) => {
5022
+ const key = `${t.from}->${t.to}`;
5023
+ const idx = pairCount.get(key) ?? 0;
5024
+ pairCount.set(key, idx + 1);
5025
+ return idx;
5026
+ });
5027
+ }, [data.transitions]);
5028
+ const transitionCounts = React21.useMemo(() => {
5029
+ const incoming = /* @__PURE__ */ new Map();
5030
+ const outgoing = /* @__PURE__ */ new Map();
5031
+ for (const t of data.transitions) {
5032
+ outgoing.set(t.from, (outgoing.get(t.from) ?? 0) + 1);
5033
+ incoming.set(t.to, (incoming.get(t.to) ?? 0) + 1);
5034
+ }
5035
+ return { incoming, outgoing };
5036
+ }, [data.transitions]);
5037
+ return /* @__PURE__ */ jsxRuntime.jsxs("group", { children: [
5038
+ /* @__PURE__ */ jsxRuntime.jsx(
5039
+ Avl3DLabel,
5040
+ {
5041
+ position: [0, 5, 0],
5042
+ text: `${data.name} (${data.linkedEntity})`,
5043
+ color: "#ffffff",
5044
+ fontSize: 14
5045
+ }
5046
+ ),
5047
+ data.states.map((state) => {
5048
+ const pos = statePositions.get(state.name);
5049
+ if (!pos) return null;
5050
+ return /* @__PURE__ */ jsxRuntime.jsx(
5051
+ Avl3DStateNode,
5052
+ {
5053
+ name: state.name,
5054
+ isInitial: state.isInitial,
5055
+ isTerminal: state.isTerminal,
5056
+ position: pos,
5057
+ incomingCount: transitionCounts.incoming.get(state.name) ?? 0,
5058
+ outgoingCount: transitionCounts.outgoing.get(state.name) ?? 0
5059
+ },
5060
+ state.name
5061
+ );
5062
+ }),
5063
+ data.transitions.map((transition, i) => {
5064
+ const fromPos = statePositions.get(transition.from);
5065
+ const toPos = statePositions.get(transition.to);
5066
+ if (!fromPos || !toPos) return null;
5067
+ const isSelf = transition.from === transition.to;
5068
+ return /* @__PURE__ */ jsxRuntime.jsx(
5069
+ Avl3DTransitionArc,
5070
+ {
5071
+ from: fromPos,
5072
+ to: toPos,
5073
+ event: transition.event,
5074
+ hasGuard: !!transition.guard,
5075
+ effectCount: transition.effects?.length ?? 0,
5076
+ effectTypes: transition.effects?.map((e) => {
5077
+ if (Array.isArray(e)) return String(e[0]);
5078
+ return typeof e === "string" ? e : "unknown";
5079
+ }),
5080
+ index: transitionIndices[i],
5081
+ isSelf,
5082
+ fromState: transition.from,
5083
+ toState: transition.to,
5084
+ onClick: () => onTransitionClick?.(i)
5085
+ },
5086
+ `${transition.from}-${transition.event}-${transition.to}-${i}`
5087
+ );
5088
+ })
5089
+ ] });
5090
+ };
5091
+ Avl3DTraitScene.displayName = "Avl3DTraitScene";
5092
+
5093
+ // components/atoms/avl/types.ts
5094
+ var AVL_OPERATOR_COLORS = {
5095
+ arithmetic: "#4A90D9",
5096
+ comparison: "#E8913A",
5097
+ logic: "#9B59B6",
5098
+ string: "#27AE60",
5099
+ collection: "#1ABC9C"};
5100
+ function operatorColor(label) {
5101
+ if (["+", "-", "*", "/", "%", "mod"].includes(label)) return AVL_OPERATOR_COLORS.arithmetic;
5102
+ if (["=", "!=", "<", ">", "<=", ">=", "eq", "neq", "lt", "gt"].includes(label)) return AVL_OPERATOR_COLORS.comparison;
5103
+ if (["and", "or", "not", "if", "cond"].includes(label)) return AVL_OPERATOR_COLORS.logic;
5104
+ if (["concat", "upper", "lower", "trim", "substr"].includes(label)) return AVL_OPERATOR_COLORS.string;
5105
+ if (["map", "filter", "reduce", "find", "count", "sum"].includes(label)) return AVL_OPERATOR_COLORS.collection;
5106
+ return "#4A90D9";
5107
+ }
5108
+ function edgeGeometry(parent, child) {
5109
+ const p = new THREE6.Vector3(parent.x, parent.y, parent.z);
5110
+ const c = new THREE6.Vector3(child.x, child.y, child.z);
5111
+ const mid = new THREE6.Vector3().addVectors(p, c).multiplyScalar(0.5);
5112
+ const dir = new THREE6.Vector3().subVectors(c, p);
5113
+ const length = dir.length();
5114
+ const yAxis = new THREE6.Vector3(0, 1, 0);
5115
+ const angle = yAxis.angleTo(dir.normalize());
5116
+ const axis = new THREE6.Vector3().crossVectors(yAxis, dir).normalize();
5117
+ if (axis.length() < 1e-3) {
5118
+ return {
5119
+ position: [mid.x, mid.y, mid.z],
5120
+ rotation: [0, 0, 0],
5121
+ length
5122
+ };
5123
+ }
5124
+ return {
5125
+ position: [mid.x, mid.y, mid.z],
5126
+ rotation: [
5127
+ axis.x * angle,
5128
+ axis.y * angle,
5129
+ axis.z * angle
5130
+ ],
5131
+ length
5132
+ };
5133
+ }
5134
+ var Avl3DExprTree = ({
5135
+ expression,
5136
+ position
5137
+ }) => {
5138
+ const layoutResults = React21.useMemo(() => {
5139
+ const origin = { x: position[0], y: position[1], z: position[2] };
5140
+ return treeLayout3D(expression, origin, 2.5, 1.5);
5141
+ }, [expression, position]);
5142
+ const edges = React21.useMemo(() => {
5143
+ const result = [];
5144
+ function collectEdges(node, parentPos) {
5145
+ const entry = layoutResults.find((r) => r.node === node);
5146
+ if (!entry) return;
5147
+ if (parentPos) {
5148
+ result.push({
5149
+ parent: parentPos,
5150
+ child: entry.position,
5151
+ key: `${parentPos.x}-${parentPos.y}-${entry.position.x}-${entry.position.y}`
5152
+ });
5153
+ }
5154
+ if (node.children) {
5155
+ for (const child of node.children) {
5156
+ collectEdges(child, entry.position);
5157
+ }
5158
+ }
5159
+ }
5160
+ collectEdges(expression, null);
5161
+ return result;
5162
+ }, [expression, layoutResults]);
5163
+ return /* @__PURE__ */ jsxRuntime.jsxs("group", { children: [
5164
+ edges.map((edge) => {
5165
+ const geo = edgeGeometry(edge.parent, edge.child);
5166
+ return /* @__PURE__ */ jsxRuntime.jsxs(
5167
+ "mesh",
5168
+ {
5169
+ position: geo.position,
5170
+ rotation: geo.rotation,
5171
+ children: [
5172
+ /* @__PURE__ */ jsxRuntime.jsx("cylinderGeometry", { args: [0.015, 0.015, geo.length, 6] }),
5173
+ /* @__PURE__ */ jsxRuntime.jsx(
5174
+ "meshStandardMaterial",
5175
+ {
5176
+ color: "#555555",
5177
+ transparent: true,
5178
+ opacity: 0.5
5179
+ }
5180
+ )
5181
+ ]
5182
+ },
5183
+ edge.key
5184
+ );
5185
+ }),
5186
+ layoutResults.map((entry, i) => {
5187
+ const pos = [
5188
+ entry.position.x,
5189
+ entry.position.y,
5190
+ entry.position.z
5191
+ ];
5192
+ if (entry.node.type === "operator") {
5193
+ const opColor = operatorColor(entry.node.label);
5194
+ return /* @__PURE__ */ jsxRuntime.jsxs("group", { position: pos, children: [
5195
+ /* @__PURE__ */ jsxRuntime.jsxs("mesh", { children: [
5196
+ /* @__PURE__ */ jsxRuntime.jsx("boxGeometry", { args: [0.6, 0.4, 0.3] }),
5197
+ /* @__PURE__ */ jsxRuntime.jsx(
5198
+ "meshStandardMaterial",
5199
+ {
5200
+ color: opColor,
5201
+ emissive: opColor,
5202
+ emissiveIntensity: 0.4,
5203
+ roughness: 0.3
5204
+ }
5205
+ )
5206
+ ] }),
5207
+ /* @__PURE__ */ jsxRuntime.jsx(
5208
+ Avl3DLabel,
5209
+ {
5210
+ position: [0, -0.4, 0],
5211
+ text: entry.node.label,
5212
+ color: opColor,
5213
+ fontSize: 10
5214
+ }
5215
+ )
5216
+ ] }, i);
5217
+ }
5218
+ if (entry.node.type === "binding") {
5219
+ return /* @__PURE__ */ jsxRuntime.jsxs("group", { position: pos, children: [
5220
+ /* @__PURE__ */ jsxRuntime.jsxs("mesh", { scale: 0.08, children: [
5221
+ /* @__PURE__ */ jsxRuntime.jsx("torusKnotGeometry", { args: [2, 0.6, 48, 8, 2, 3] }),
5222
+ /* @__PURE__ */ jsxRuntime.jsx(
5223
+ "meshStandardMaterial",
5224
+ {
5225
+ color: "#4A90D9",
5226
+ emissive: "#4A90D9",
5227
+ emissiveIntensity: 0.4,
5228
+ transparent: true,
5229
+ opacity: 0.85,
5230
+ roughness: 0.3
5231
+ }
5232
+ )
5233
+ ] }),
5234
+ /* @__PURE__ */ jsxRuntime.jsx(
5235
+ Avl3DLabel,
5236
+ {
5237
+ position: [0, -0.35, 0],
5238
+ text: entry.node.label,
5239
+ color: "#4A90D9",
5240
+ fontSize: 9
5241
+ }
5242
+ )
5243
+ ] }, i);
5244
+ }
5245
+ return /* @__PURE__ */ jsxRuntime.jsxs("group", { position: pos, children: [
5246
+ /* @__PURE__ */ jsxRuntime.jsxs("mesh", { rotation: [Math.PI / 6, Math.PI / 4, 0], children: [
5247
+ /* @__PURE__ */ jsxRuntime.jsx("boxGeometry", { args: [0.2, 0.2, 0.2] }),
5248
+ /* @__PURE__ */ jsxRuntime.jsx(
5249
+ "meshStandardMaterial",
5250
+ {
5251
+ color: "#888888",
5252
+ emissive: "#666666",
5253
+ emissiveIntensity: 0.2,
5254
+ roughness: 0.5
5255
+ }
5256
+ )
5257
+ ] }),
5258
+ /* @__PURE__ */ jsxRuntime.jsx(
5259
+ Avl3DLabel,
5260
+ {
5261
+ position: [0, -0.3, 0],
5262
+ text: entry.node.label,
5263
+ color: "#999999",
5264
+ fontSize: 8
5265
+ }
5266
+ )
5267
+ ] }, i);
5268
+ })
5269
+ ] });
5270
+ };
5271
+ Avl3DExprTree.displayName = "Avl3DExprTree";
5272
+ var Avl3DTransitionScene = ({
5273
+ data
5274
+ }) => {
5275
+ return /* @__PURE__ */ jsxRuntime.jsxs("group", { children: [
5276
+ /* @__PURE__ */ jsxRuntime.jsx(
5277
+ Avl3DStateNode,
5278
+ {
5279
+ name: data.from,
5280
+ position: [0, 4, 0]
5281
+ }
5282
+ ),
5283
+ /* @__PURE__ */ jsxRuntime.jsxs("group", { position: [0, 2.2, 0], children: [
5284
+ /* @__PURE__ */ jsxRuntime.jsxs("mesh", { children: [
5285
+ /* @__PURE__ */ jsxRuntime.jsx("boxGeometry", { args: [2, 0.6, 0.4] }),
5286
+ /* @__PURE__ */ jsxRuntime.jsx(
5287
+ "meshStandardMaterial",
5288
+ {
5289
+ color: AVL_3D_COLORS.transitionArc,
5290
+ emissive: AVL_3D_COLORS.transitionArc,
5291
+ emissiveIntensity: 0.5,
5292
+ roughness: 0.3
5293
+ }
5294
+ )
5295
+ ] }),
5296
+ /* @__PURE__ */ jsxRuntime.jsx(
5297
+ Avl3DLabel,
5298
+ {
5299
+ position: [0, 0, 0.3],
5300
+ text: data.event,
5301
+ color: "#ffffff",
5302
+ fontSize: 13
5303
+ }
5304
+ )
5305
+ ] }),
5306
+ /* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, 3.1, 0], children: [
5307
+ /* @__PURE__ */ jsxRuntime.jsx("cylinderGeometry", { args: [0.02, 0.02, 1.2, 6] }),
5308
+ /* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color: "#555555", transparent: true, opacity: 0.5 })
5309
+ ] }),
5310
+ data.guard && /* @__PURE__ */ jsxRuntime.jsxs("group", { position: [0, 1, 0], children: [
5311
+ /* @__PURE__ */ jsxRuntime.jsxs("mesh", { rotation: [0, 0, Math.PI / 4], children: [
5312
+ /* @__PURE__ */ jsxRuntime.jsx("boxGeometry", { args: [0.5, 0.5, 0.3] }),
5313
+ /* @__PURE__ */ jsxRuntime.jsx(
5314
+ "meshStandardMaterial",
5315
+ {
5316
+ color: AVL_3D_COLORS.guardPass,
5317
+ emissive: AVL_3D_COLORS.guardPass,
5318
+ emissiveIntensity: 0.6
5319
+ }
5320
+ )
5321
+ ] }),
5322
+ /* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, 0.7, 0], children: [
5323
+ /* @__PURE__ */ jsxRuntime.jsx("cylinderGeometry", { args: [0.02, 0.02, 0.8, 6] }),
5324
+ /* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color: "#555555", transparent: true, opacity: 0.5 })
5325
+ ] }),
5326
+ /* @__PURE__ */ jsxRuntime.jsx(
5327
+ Avl3DExprTree,
5328
+ {
5329
+ expression: data.guard,
5330
+ position: [3, 0, 0]
5331
+ }
5332
+ ),
5333
+ /* @__PURE__ */ jsxRuntime.jsx(
5334
+ Avl3DLabel,
5335
+ {
5336
+ position: [1.5, 0.3, 0],
5337
+ text: "guard",
5338
+ color: AVL_3D_COLORS.guardPass,
5339
+ fontSize: 9
5340
+ }
5341
+ )
5342
+ ] }),
5343
+ data.effects.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("group", { position: [0, data.guard ? -0.5 : 0.5, 0], children: [
5344
+ /* @__PURE__ */ jsxRuntime.jsx(
5345
+ Avl3DLabel,
5346
+ {
5347
+ position: [0, 0.4, 0],
5348
+ text: `${data.effects.length} effect${data.effects.length > 1 ? "s" : ""}`,
5349
+ color: "#E8913A",
5350
+ fontSize: 10
5351
+ }
5352
+ ),
5353
+ data.effects.map((effect, i) => {
5354
+ const xOffset = (i - (data.effects.length - 1) / 2) * 3;
5355
+ return /* @__PURE__ */ jsxRuntime.jsx(
5356
+ Avl3DExprTree,
5357
+ {
5358
+ expression: effect,
5359
+ position: [xOffset, -1, 0]
5360
+ },
5361
+ i
5362
+ );
5363
+ })
5364
+ ] }),
5365
+ /* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, data.guard ? -2.5 : -1.5, 0], children: [
5366
+ /* @__PURE__ */ jsxRuntime.jsx("cylinderGeometry", { args: [0.02, 0.02, 1.2, 6] }),
5367
+ /* @__PURE__ */ jsxRuntime.jsx("meshStandardMaterial", { color: "#555555", transparent: true, opacity: 0.5 })
5368
+ ] }),
5369
+ /* @__PURE__ */ jsxRuntime.jsx(
5370
+ Avl3DStateNode,
5371
+ {
5372
+ name: data.to,
5373
+ position: [0, data.guard ? -3.5 : -2.5, 0]
5374
+ }
5375
+ )
5376
+ ] });
5377
+ };
5378
+ Avl3DTransitionScene.displayName = "Avl3DTransitionScene";
5379
+ var BLOOM_CONFIG = {
5380
+ application: { intensity: 0.4, luminanceThreshold: 0.88, luminanceSmoothing: 0.95 },
5381
+ orbital: { intensity: 0.5, luminanceThreshold: 0.85, luminanceSmoothing: 0.9 },
5382
+ trait: { intensity: 0.3, luminanceThreshold: 0.92, luminanceSmoothing: 0.9 },
5383
+ transition: { intensity: 0.35, luminanceThreshold: 0.9, luminanceSmoothing: 0.9 }
5384
+ };
5385
+ var DOF_CONFIG = {
5386
+ application: null,
5387
+ orbital: { focusDistance: 0.02, focalLength: 0.02, bokehScale: 1.5 },
5388
+ trait: null,
5389
+ transition: null
5390
+ };
5391
+ var SPARKLE_CONFIGS = {
5392
+ application: [
5393
+ { count: 60, size: 1.2, speed: 0.2, opacity: 0.35, scale: 35, color: AVL_3D_COLORS.sparkle },
5394
+ { count: 15, size: 1.8, speed: 0.1, opacity: 0.2, scale: 25, color: AVL_3D_COLORS.sparkleWarm }
5395
+ ],
5396
+ orbital: [
5397
+ { count: 30, size: 0.8, speed: 0.15, opacity: 0.25, scale: 18, color: AVL_3D_COLORS.sparkle },
5398
+ { count: 8, size: 1.2, speed: 0.08, opacity: 0.15, scale: 12, color: AVL_3D_COLORS.sparkleWarm }
5399
+ ],
5400
+ trait: [
5401
+ { count: 15, size: 0.6, speed: 0.1, opacity: 0.2, scale: 12, color: AVL_3D_COLORS.sparkle }
5402
+ ],
5403
+ transition: [
5404
+ { count: 8, size: 0.4, speed: 0.08, opacity: 0.15, scale: 8, color: AVL_3D_COLORS.sparkle }
5405
+ ]
5406
+ };
5407
+ var STARS_CONFIG = {
5408
+ application: { radius: 80, count: 3e3, factor: 5, fade: true },
5409
+ orbital: { radius: 60, count: 1500, factor: 4, fade: true },
5410
+ trait: { radius: 40, count: 800, factor: 3, fade: true },
5411
+ transition: { radius: 30, count: 400, factor: 2, fade: true }
5412
+ };
5413
+ var Avl3DEffects = ({
5414
+ level,
5415
+ enabled = true
5416
+ }) => {
5417
+ if (!enabled) return null;
5418
+ const bloom = BLOOM_CONFIG[level];
5419
+ const dof = DOF_CONFIG[level];
5420
+ const sparkles = SPARKLE_CONFIGS[level];
5421
+ const stars = STARS_CONFIG[level];
5422
+ const starsKey = React21.useMemo(() => `stars-${level}`, [level]);
5423
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
5424
+ /* @__PURE__ */ jsxRuntime.jsx(
5425
+ drei.Stars,
5426
+ {
5427
+ radius: stars.radius,
5428
+ count: stars.count,
5429
+ factor: stars.factor,
5430
+ saturation: 0.1,
5431
+ fade: stars.fade,
5432
+ speed: 0.3
5433
+ },
5434
+ starsKey
5435
+ ),
5436
+ sparkles.map((cfg, i) => /* @__PURE__ */ jsxRuntime.jsx(
5437
+ drei.Sparkles,
5438
+ {
5439
+ count: cfg.count,
5440
+ size: cfg.size,
5441
+ speed: cfg.speed,
5442
+ opacity: cfg.opacity,
5443
+ scale: cfg.scale,
5444
+ color: cfg.color
5445
+ },
5446
+ `sparkle-${level}-${i}`
5447
+ )),
5448
+ dof ? /* @__PURE__ */ jsxRuntime.jsxs(postprocessing.EffectComposer, { children: [
5449
+ /* @__PURE__ */ jsxRuntime.jsx(
5450
+ postprocessing.Bloom,
5451
+ {
5452
+ intensity: bloom.intensity,
5453
+ luminanceThreshold: bloom.luminanceThreshold,
5454
+ luminanceSmoothing: bloom.luminanceSmoothing,
5455
+ mipmapBlur: true
5456
+ }
5457
+ ),
5458
+ /* @__PURE__ */ jsxRuntime.jsx(
5459
+ postprocessing.DepthOfField,
5460
+ {
5461
+ focusDistance: dof.focusDistance,
5462
+ focalLength: dof.focalLength,
5463
+ bokehScale: dof.bokehScale
5464
+ }
5465
+ ),
5466
+ /* @__PURE__ */ jsxRuntime.jsx(postprocessing.Vignette, { eskil: false, offset: 0.2, darkness: 0.35 })
5467
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(postprocessing.EffectComposer, { children: [
5468
+ /* @__PURE__ */ jsxRuntime.jsx(
5469
+ postprocessing.Bloom,
5470
+ {
5471
+ intensity: bloom.intensity,
5472
+ luminanceThreshold: bloom.luminanceThreshold,
5473
+ luminanceSmoothing: bloom.luminanceSmoothing,
5474
+ mipmapBlur: true
5475
+ }
5476
+ ),
5477
+ /* @__PURE__ */ jsxRuntime.jsx(postprocessing.Vignette, { eskil: false, offset: 0.2, darkness: 0.35 })
5478
+ ] })
5479
+ ] });
5480
+ };
5481
+ Avl3DEffects.displayName = "Avl3DEffects";
5482
+ var DEFAULT_CONFIG2 = {
5483
+ modelOverrides: {},
5484
+ effectsEnabled: true
5485
+ };
5486
+ var Avl3DContext = React21.createContext(DEFAULT_CONFIG2);
5487
+ function useAvl3DConfig() {
5488
+ return React21.useContext(Avl3DContext);
5489
+ }
5490
+ function CameraController2({ targetPosition, targetLookAt, animated }) {
5491
+ const { camera } = fiber.useThree();
5492
+ const targetPosVec = React21.useRef(new THREE6__namespace.Vector3(...targetPosition));
5493
+ const targetLookVec = React21.useRef(new THREE6__namespace.Vector3(...targetLookAt));
5494
+ const isAnimating = React21.useRef(false);
5495
+ React21.useEffect(() => {
5496
+ const newTarget = new THREE6__namespace.Vector3(...targetPosition);
5497
+ const newLookAt = new THREE6__namespace.Vector3(...targetLookAt);
5498
+ if (!newTarget.equals(targetPosVec.current) || !newLookAt.equals(targetLookVec.current)) {
5499
+ targetPosVec.current.copy(newTarget);
5500
+ targetLookVec.current.copy(newLookAt);
5501
+ if (animated) {
5502
+ isAnimating.current = true;
5503
+ } else {
5504
+ camera.position.copy(targetPosVec.current);
5505
+ camera.lookAt(targetLookVec.current);
5506
+ }
5507
+ }
5508
+ }, [targetPosition, targetLookAt, animated, camera]);
5509
+ fiber.useFrame((_, delta) => {
5510
+ if (!isAnimating.current) return;
5511
+ const speed = 3;
5512
+ camera.position.x = THREE6__namespace.MathUtils.damp(camera.position.x, targetPosVec.current.x, speed, delta);
5513
+ camera.position.y = THREE6__namespace.MathUtils.damp(camera.position.y, targetPosVec.current.y, speed, delta);
5514
+ camera.position.z = THREE6__namespace.MathUtils.damp(camera.position.z, targetPosVec.current.z, speed, delta);
5515
+ camera.lookAt(targetLookVec.current);
5516
+ const dist = camera.position.distanceTo(targetPosVec.current);
5517
+ if (dist < 0.05) {
5518
+ isAnimating.current = false;
5519
+ }
5520
+ });
5521
+ return null;
5522
+ }
5523
+ function SceneFade({ animating, children }) {
5524
+ const groupRef = React21.useRef(null);
5525
+ const opacityRef = React21.useRef(1);
5526
+ fiber.useFrame((_, delta) => {
5527
+ if (!groupRef.current) return;
5528
+ const target = animating ? 0 : 1;
5529
+ opacityRef.current = THREE6__namespace.MathUtils.damp(opacityRef.current, target, 5, delta);
5530
+ groupRef.current.visible = opacityRef.current > 0.05;
5531
+ const s = 0.9 + opacityRef.current * 0.1;
5532
+ groupRef.current.scale.setScalar(s);
5533
+ });
5534
+ return /* @__PURE__ */ jsxRuntime.jsx("group", { ref: groupRef, children });
5535
+ }
5536
+ var Avl3DViewer = ({
5537
+ schema: schemaProp,
5538
+ className,
5539
+ animated = true,
5540
+ initialOrbital,
5541
+ initialTrait,
5542
+ onZoomChange,
5543
+ width = "100%",
5544
+ height = 500,
5545
+ effects = true,
5546
+ modelOverrides = {}
5547
+ }) => {
5548
+ const schema = React21.useMemo(() => {
5549
+ if (typeof schemaProp === "string") {
5550
+ try {
5551
+ return JSON.parse(schemaProp);
5552
+ } catch {
5553
+ return { name: "Error", orbitals: [] };
5554
+ }
5555
+ }
5556
+ return schemaProp;
5557
+ }, [schemaProp]);
5558
+ const configValue = React21.useMemo(() => ({
5559
+ modelOverrides,
5560
+ effectsEnabled: effects
5561
+ }), [modelOverrides, effects]);
5562
+ const [state, dispatch] = React21.useReducer(zoomReducer, initialZoomState);
5563
+ React21.useEffect(() => {
5564
+ if (initialOrbital) {
5565
+ dispatch({ type: "ZOOM_INTO_ORBITAL", orbital: initialOrbital, targetPosition: { x: 0, y: 0 } });
5566
+ setTimeout(() => dispatch({ type: "ANIMATION_COMPLETE" }), 0);
5567
+ if (initialTrait) {
5568
+ setTimeout(() => {
5569
+ dispatch({ type: "ZOOM_INTO_TRAIT", trait: initialTrait, targetPosition: { x: 0, y: 0 } });
5570
+ setTimeout(() => dispatch({ type: "ANIMATION_COMPLETE" }), 0);
5571
+ }, 10);
5572
+ }
5573
+ }
5574
+ }, [initialOrbital, initialTrait]);
5575
+ React21.useEffect(() => {
5576
+ onZoomChange?.(state.level, {
5577
+ orbital: state.selectedOrbital ?? void 0,
5578
+ trait: state.selectedTrait ?? void 0
5579
+ });
5580
+ }, [state.level, state.selectedOrbital, state.selectedTrait, onZoomChange]);
5581
+ React21.useEffect(() => {
5582
+ if (!state.animating) return;
5583
+ const timer = setTimeout(() => {
5584
+ dispatch({ type: "ANIMATION_COMPLETE" });
5585
+ }, 800);
5586
+ return () => clearTimeout(timer);
5587
+ }, [state.animating]);
5588
+ const handleKeyDown = React21.useCallback((e) => {
5589
+ if (e.key === "Escape") {
5590
+ dispatch({ type: "ZOOM_OUT" });
5591
+ }
5592
+ }, []);
5593
+ const handleOrbitalClick = React21.useCallback((name) => {
5594
+ dispatch({ type: "ZOOM_INTO_ORBITAL", orbital: name, targetPosition: { x: 0, y: 0 } });
5595
+ }, []);
5596
+ const handleTraitClick = React21.useCallback((name) => {
5597
+ dispatch({ type: "ZOOM_INTO_TRAIT", trait: name, targetPosition: { x: 0, y: 0 } });
5598
+ }, []);
5599
+ const [highlightedTrait, setHighlightedTrait] = React21__default.default.useState(null);
5600
+ const handleTransitionClick = React21.useCallback((index) => {
5601
+ dispatch({ type: "ZOOM_INTO_TRANSITION", transitionIndex: index, targetPosition: { x: 0, y: 0 } });
5602
+ }, []);
5603
+ const handleBreadcrumbClick = React21.useCallback((targetLevel) => {
5604
+ const levelOrder = ["application", "orbital", "trait", "transition"];
5605
+ const currentIdx = levelOrder.indexOf(state.level);
5606
+ const targetIdx = levelOrder.indexOf(targetLevel);
5607
+ if (targetIdx < currentIdx) {
5608
+ dispatch({ type: "ZOOM_OUT" });
5609
+ }
5610
+ }, [state.level]);
5611
+ const cameraConfig = CAMERA_POSITIONS[state.level];
5612
+ const sceneContent = React21.useMemo(() => {
5613
+ switch (state.level) {
5614
+ case "application": {
5615
+ const data = parseApplicationLevel(schema);
5616
+ return /* @__PURE__ */ jsxRuntime.jsx(
5617
+ Avl3DApplicationScene,
5618
+ {
5619
+ data,
5620
+ onOrbitalClick: handleOrbitalClick
5621
+ }
5622
+ );
5623
+ }
5624
+ case "orbital": {
5625
+ if (!state.selectedOrbital) return null;
5626
+ const orbData = parseOrbitalLevel(schema, state.selectedOrbital);
5627
+ if (!orbData) return null;
5628
+ return /* @__PURE__ */ jsxRuntime.jsx(
5629
+ Avl3DOrbitalScene,
5630
+ {
5631
+ data: orbData,
5632
+ onTraitClick: handleTraitClick,
5633
+ highlightedTrait,
5634
+ onTraitHighlight: setHighlightedTrait
5635
+ }
5636
+ );
5637
+ }
5638
+ case "trait": {
5639
+ if (!state.selectedOrbital || !state.selectedTrait) return null;
5640
+ const traitData = parseTraitLevel(schema, state.selectedOrbital, state.selectedTrait);
5641
+ if (!traitData) return null;
5642
+ return /* @__PURE__ */ jsxRuntime.jsx(
5643
+ Avl3DTraitScene,
5644
+ {
5645
+ data: traitData,
5646
+ onTransitionClick: handleTransitionClick
5647
+ }
5648
+ );
5649
+ }
5650
+ case "transition": {
5651
+ if (!state.selectedOrbital || !state.selectedTrait || state.selectedTransition === null) return null;
5652
+ const transData = parseTransitionLevel(schema, state.selectedOrbital, state.selectedTrait, state.selectedTransition);
5653
+ if (!transData) return null;
5654
+ return /* @__PURE__ */ jsxRuntime.jsx(
5655
+ Avl3DTransitionScene,
5656
+ {
5657
+ data: transData
5658
+ }
5659
+ );
5660
+ }
5661
+ default:
5662
+ return null;
5663
+ }
5664
+ }, [state.level, state.selectedOrbital, state.selectedTrait, state.selectedTransition, schema, handleOrbitalClick, handleTraitClick, handleTransitionClick, highlightedTrait, setHighlightedTrait]);
5665
+ const breadcrumbs = getBreadcrumbs(state);
5666
+ return /* @__PURE__ */ jsxRuntime.jsxs(
5667
+ Box,
5668
+ {
5669
+ className: `relative ${className ?? ""}`,
5670
+ style: {
5671
+ width,
5672
+ height: typeof height === "number" ? `${height}px` : height,
5673
+ backgroundColor: AVL_3D_COLORS.background,
5674
+ borderRadius: "8px",
5675
+ overflow: "hidden"
5676
+ },
5677
+ onKeyDown: handleKeyDown,
5678
+ tabIndex: 0,
5679
+ children: [
5680
+ /* @__PURE__ */ jsxRuntime.jsx(
5681
+ HStack,
5682
+ {
5683
+ gap: "xs",
5684
+ align: "center",
5685
+ className: "absolute top-2 left-2 z-10 bg-[var(--color-surface)]/80 backdrop-blur rounded-md px-3 py-1.5",
5686
+ children: breadcrumbs.map((crumb, i) => /* @__PURE__ */ jsxRuntime.jsxs(React21__default.default.Fragment, { children: [
5687
+ i > 0 && /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", color: "muted", className: "mx-1", children: "/" }),
5688
+ i < breadcrumbs.length - 1 ? /* @__PURE__ */ jsxRuntime.jsx(
5689
+ Box,
5690
+ {
5691
+ as: "span",
5692
+ className: "cursor-pointer hover:underline",
5693
+ onClick: () => handleBreadcrumbClick(crumb.level),
5694
+ children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", color: "muted", children: crumb.label })
5695
+ }
5696
+ ) : /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", color: "primary", className: "font-bold", children: crumb.label })
5697
+ ] }, crumb.level))
5698
+ }
5699
+ ),
5700
+ state.level !== "application" && /* @__PURE__ */ jsxRuntime.jsx(
5701
+ Typography,
5702
+ {
5703
+ variant: "small",
5704
+ color: "muted",
5705
+ className: "absolute bottom-2 right-2 z-10 bg-[var(--color-surface)]/60 backdrop-blur rounded px-2 py-1",
5706
+ children: "Press Esc to zoom out"
5707
+ }
5708
+ ),
5709
+ /* @__PURE__ */ jsxRuntime.jsx(
5710
+ fiber.Canvas,
5711
+ {
5712
+ style: { width: "100%", height: "100%" },
5713
+ camera: {
5714
+ position: cameraConfig.position,
5715
+ fov: 60,
5716
+ near: 0.1,
5717
+ far: 200
5718
+ },
5719
+ onCreated: ({ gl }) => {
5720
+ gl.setClearColor(AVL_3D_COLORS.background);
5721
+ },
5722
+ children: /* @__PURE__ */ jsxRuntime.jsx(Avl3DContext.Provider, { value: configValue, children: /* @__PURE__ */ jsxRuntime.jsxs(
5723
+ Scene3D,
5724
+ {
5725
+ background: AVL_3D_COLORS.background,
5726
+ fog: { color: AVL_3D_COLORS.fog, near: 30, far: 80 },
5727
+ children: [
5728
+ /* @__PURE__ */ jsxRuntime.jsx(
5729
+ Camera3D,
5730
+ {
5731
+ mode: "perspective",
5732
+ position: cameraConfig.position,
5733
+ target: cameraConfig.target,
5734
+ enableOrbit: true,
5735
+ minDistance: 3,
5736
+ maxDistance: 80
5737
+ }
5738
+ ),
5739
+ /* @__PURE__ */ jsxRuntime.jsx(
5740
+ Lighting3D,
5741
+ {
5742
+ ambientIntensity: 0.35,
5743
+ ambientColor: "#8090c0",
5744
+ directionalIntensity: 0.5,
5745
+ directionalColor: "#c0d0f0",
5746
+ directionalPosition: [8, 15, 12],
5747
+ shadows: false
5748
+ }
5749
+ ),
5750
+ /* @__PURE__ */ jsxRuntime.jsx(
5751
+ "pointLight",
5752
+ {
5753
+ position: [0, -10, 0],
5754
+ color: "#2040a0",
5755
+ intensity: 0.15,
5756
+ distance: 50,
5757
+ decay: 2
5758
+ }
5759
+ ),
5760
+ /* @__PURE__ */ jsxRuntime.jsx(
5761
+ CameraController2,
5762
+ {
5763
+ targetPosition: cameraConfig.position,
5764
+ targetLookAt: cameraConfig.target,
5765
+ animated
5766
+ }
5767
+ ),
5768
+ /* @__PURE__ */ jsxRuntime.jsx(SceneFade, { animating: state.animating, children: sceneContent }),
5769
+ /* @__PURE__ */ jsxRuntime.jsx(Avl3DEffects, { level: state.level, enabled: effects })
5770
+ ]
5771
+ }
5772
+ ) })
5773
+ }
5774
+ )
5775
+ ]
5776
+ }
5777
+ );
5778
+ };
5779
+ Avl3DViewer.displayName = "Avl3DViewer";
3367
5780
  function isInFrustum(position, camera, padding = 0) {
3368
5781
  const frustum = new THREE6__namespace.Frustum();
3369
5782
  const projScreenMatrix = new THREE6__namespace.Matrix4();
@@ -3546,7 +5959,16 @@ var SpatialHashGrid = class {
3546
5959
  }
3547
5960
  };
3548
5961
 
5962
+ exports.AVL_3D_COLORS = AVL_3D_COLORS;
3549
5963
  exports.AssetLoader = AssetLoader;
5964
+ exports.Avl3DApplicationScene = Avl3DApplicationScene;
5965
+ exports.Avl3DContext = Avl3DContext;
5966
+ exports.Avl3DEffects = Avl3DEffects;
5967
+ exports.Avl3DOrbitalScene = Avl3DOrbitalScene;
5968
+ exports.Avl3DTraitScene = Avl3DTraitScene;
5969
+ exports.Avl3DTransitionScene = Avl3DTransitionScene;
5970
+ exports.Avl3DViewer = Avl3DViewer;
5971
+ exports.CAMERA_POSITIONS = CAMERA_POSITIONS;
3550
5972
  exports.Camera3D = Camera3D;
3551
5973
  exports.Canvas3DErrorBoundary = Canvas3DErrorBoundary;
3552
5974
  exports.Canvas3DLoadingState = Canvas3DLoadingState;
@@ -3563,25 +5985,32 @@ exports.Scene3D = Scene3D;
3563
5985
  exports.SpatialHashGrid = SpatialHashGrid;
3564
5986
  exports.TileRenderer = TileRenderer;
3565
5987
  exports.UnitRenderer = UnitRenderer;
5988
+ exports.arcCurve3D = arcCurve3D;
3566
5989
  exports.assetLoader = assetLoader;
3567
5990
  exports.calculateLODLevel = calculateLODLevel;
3568
5991
  exports.createGridHighlight = createGridHighlight;
3569
5992
  exports.cullInstancedMesh = cullInstancedMesh;
5993
+ exports.fibonacciSpherePositions = fibonacciSpherePositions;
3570
5994
  exports.filterByFrustum = filterByFrustum;
3571
5995
  exports.getCellsInRadius = getCellsInRadius;
3572
5996
  exports.getNeighbors = getNeighbors;
3573
5997
  exports.getVisibleIndices = getVisibleIndices;
5998
+ exports.goldenSpiralPositions = goldenSpiralPositions;
3574
5999
  exports.gridDistance = gridDistance;
3575
6000
  exports.gridManhattanDistance = gridManhattanDistance;
3576
6001
  exports.gridToWorld = gridToWorld;
3577
6002
  exports.isInBounds = isInBounds;
3578
6003
  exports.isInFrustum = isInFrustum;
3579
6004
  exports.normalizeMouseCoordinates = normalizeMouseCoordinates;
6005
+ exports.orbitRingPositions = orbitRingPositions;
3580
6006
  exports.preloadFeatures = preloadFeatures;
3581
6007
  exports.raycastToObjects = raycastToObjects;
3582
6008
  exports.raycastToPlane = raycastToPlane;
6009
+ exports.selfLoopCurve3D = selfLoopCurve3D;
6010
+ exports.treeLayout3D = treeLayout3D;
3583
6011
  exports.updateInstanceLOD = updateInstanceLOD;
3584
6012
  exports.useAssetLoader = useAssetLoader;
6013
+ exports.useAvl3DConfig = useAvl3DConfig;
3585
6014
  exports.useGameCanvas3DEvents = useGameCanvas3DEvents;
3586
6015
  exports.usePhysics3DController = usePhysics3DController;
3587
6016
  exports.useRaycaster = useRaycaster;