force-3d-graph 1.0.3 → 1.2.1

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.
@@ -1,19 +1,20 @@
1
1
  var st = Object.defineProperty;
2
- var nt = (c, e, s) => e in c ? st(c, e, { enumerable: !0, configurable: !0, writable: !0, value: s }) : c[e] = s;
3
- var r = (c, e, s) => nt(c, typeof e != "symbol" ? e + "" : e, s);
4
- import * as p from "three";
5
- import { EventDispatcher as ot, Vector3 as N, MOUSE as $, TOUCH as K, Spherical as ze, Quaternion as Ne, Vector2 as k, Ray as it, Plane as at, MathUtils as rt } from "three";
6
- const I = {
2
+ var it = (h, e, s) => e in h ? st(h, e, { enumerable: !0, configurable: !0, writable: !0, value: s }) : h[e] = s;
3
+ var l = (h, e, s) => it(h, typeof e != "symbol" ? e + "" : e, s);
4
+ import * as m from "three";
5
+ import { EventDispatcher as ot, Vector3 as S, MOUSE as $, TOUCH as G, Spherical as Ne, Quaternion as Se, Vector2 as k, Ray as nt, Plane as at, MathUtils as rt } from "three";
6
+ const T = {
7
7
  backgroundColor: 657930,
8
8
  cameraPosition: { x: 0, y: 0, z: 80 },
9
9
  cameraFov: 75,
10
- repulsionStrength: 100,
11
- attractionStrength: 0.01,
12
- damping: 0.9,
13
- useBarnesHut: !1,
14
- // Auto-enabled for large graphs
10
+ repulsionStrength: 200,
11
+ attractionStrength: 8e-3,
12
+ damping: 0.95,
13
+ useBarnesHut: !0,
14
+ // Enabled by default for better performance
15
15
  barnesHutTheta: 0.5,
16
- defaultNodeColor: 4886754,
16
+ defaultNodeColor: 16750950,
17
+ // Tangerine to match the premium glass material
17
18
  nodeRadius: 2,
18
19
  nodeSegments: 32,
19
20
  enableLOD: !0,
@@ -25,101 +26,103 @@ const I = {
25
26
  showPanel: !0,
26
27
  showSearch: !0,
27
28
  searchPlaceholder: "Search nodes or relationships...",
29
+ initialViewMode: "3d",
30
+ showViewToggle: !0,
28
31
  targetFPS: 60,
29
32
  maxVisibleNodes: 1e4
30
33
  };
31
- var X = /* @__PURE__ */ ((c) => (c[c.HIGH = 0] = "HIGH", c[c.MEDIUM = 1] = "MEDIUM", c[c.LOW = 2] = "LOW", c))(X || {});
34
+ var U = /* @__PURE__ */ ((h) => (h[h.HIGH = 0] = "HIGH", h[h.MEDIUM = 1] = "MEDIUM", h[h.LOW = 2] = "LOW", h))(U || {});
32
35
  function lt() {
33
- const c = document.createElement("div");
34
- return c.id = "force-graph-3d-container", c.style.cssText = `
36
+ const h = document.createElement("div");
37
+ return h.id = "force-graph-3d-container", h.style.cssText = `
35
38
  width: 100%;
36
39
  height: 100%;
37
40
  position: absolute;
38
41
  top: 0;
39
42
  left: 0;
40
43
  overflow: hidden;
41
- `, document.body.appendChild(c), c;
44
+ `, document.body.appendChild(h), h;
42
45
  }
43
- function ct(c) {
44
- return c && c instanceof HTMLElement ? c : (console.warn("[ForceGraph3D] No container provided, creating one automatically"), lt());
46
+ function ct(h) {
47
+ return h && h instanceof HTMLElement ? h : (console.warn("[ForceGraph3D] No container provided, creating one automatically"), lt());
45
48
  }
46
- function Se(c) {
47
- const e = c.getBoundingClientRect();
49
+ function ze(h) {
50
+ const e = h.getBoundingClientRect();
48
51
  return {
49
52
  width: e.width || window.innerWidth,
50
53
  height: e.height || window.innerHeight
51
54
  };
52
55
  }
53
- function Re(c) {
54
- if (!c || typeof c != "object")
56
+ function Oe(h) {
57
+ if (!h || typeof h != "object")
55
58
  return console.warn("[ForceGraph3D] Invalid node: must be an object"), !1;
56
- const e = c;
59
+ const e = h;
57
60
  return typeof e.id != "string" || e.id.trim() === "" ? (console.warn("[ForceGraph3D] Invalid node: id must be a non-empty string"), !1) : typeof e.label != "string" ? (console.warn("[ForceGraph3D] Invalid node: label must be a string"), !1) : e.color !== void 0 && typeof e.color != "number" ? (console.warn("[ForceGraph3D] Invalid node: color must be a number (hex)"), !1) : e.position !== void 0 && !dt(e.position) ? (console.warn("[ForceGraph3D] Invalid node: position must have x, y, z numbers"), !1) : !0;
58
61
  }
59
- function Fe(c) {
60
- if (!c || typeof c != "object")
62
+ function Fe(h) {
63
+ if (!h || typeof h != "object")
61
64
  return console.warn("[ForceGraph3D] Invalid edge: must be an object"), !1;
62
- const e = c;
65
+ const e = h;
63
66
  return typeof e.source != "string" || e.source.trim() === "" ? (console.warn("[ForceGraph3D] Invalid edge: source must be a non-empty string"), !1) : typeof e.target != "string" || e.target.trim() === "" ? (console.warn("[ForceGraph3D] Invalid edge: target must be a non-empty string"), !1) : !0;
64
67
  }
65
- function ht(c) {
66
- return typeof c != "string" || c.trim() === "" ? (console.warn("[ForceGraph3D] Invalid node ID: must be a non-empty string"), !1) : !0;
68
+ function ht(h) {
69
+ return typeof h != "string" || h.trim() === "" ? (console.warn("[ForceGraph3D] Invalid node ID: must be a non-empty string"), !1) : !0;
67
70
  }
68
- function dt(c) {
69
- if (!c || typeof c != "object") return !1;
70
- const e = c;
71
+ function dt(h) {
72
+ if (!h || typeof h != "object") return !1;
73
+ const e = h;
71
74
  return typeof e.x == "number" && typeof e.y == "number" && typeof e.z == "number";
72
75
  }
73
- function A(c, e) {
74
- return c === e ? `${c}-${e}` : c < e ? `${c}-${e}` : `${e}-${c}`;
76
+ function D(h, e) {
77
+ return h === e ? `${h}-${e}` : h < e ? `${h}-${e}` : `${e}-${h}`;
75
78
  }
76
- const ke = { type: "change" }, re = { type: "start" }, Te = { type: "end" }, Q = new it(), Pe = new at(), pt = Math.cos(70 * rt.DEG2RAD);
79
+ const ke = { type: "change" }, re = { type: "start" }, Pe = { type: "end" }, Q = new nt(), Te = new at(), pt = Math.cos(70 * rt.DEG2RAD);
77
80
  class gt extends ot {
78
81
  constructor(e, s) {
79
- super(), this.object = e, this.domElement = s, this.domElement.style.touchAction = "none", this.enabled = !0, this.target = new N(), this.cursor = new N(), this.minDistance = 0, this.maxDistance = 1 / 0, this.minZoom = 0, this.maxZoom = 1 / 0, this.minTargetRadius = 0, this.maxTargetRadius = 1 / 0, this.minPolarAngle = 0, this.maxPolarAngle = Math.PI, this.minAzimuthAngle = -1 / 0, this.maxAzimuthAngle = 1 / 0, this.enableDamping = !1, this.dampingFactor = 0.05, this.enableZoom = !0, this.zoomSpeed = 1, this.enableRotate = !0, this.rotateSpeed = 1, this.enablePan = !0, this.panSpeed = 1, this.screenSpacePanning = !0, this.keyPanSpeed = 7, this.zoomToCursor = !1, this.autoRotate = !1, this.autoRotateSpeed = 2, this.keys = { LEFT: "ArrowLeft", UP: "ArrowUp", RIGHT: "ArrowRight", BOTTOM: "ArrowDown" }, this.mouseButtons = { LEFT: $.ROTATE, MIDDLE: $.DOLLY, RIGHT: $.PAN }, this.touches = { ONE: K.ROTATE, TWO: K.DOLLY_PAN }, this.target0 = this.target.clone(), this.position0 = this.object.position.clone(), this.zoom0 = this.object.zoom, this._domElementKeyEvents = null, this.getPolarAngle = function() {
80
- return l.phi;
82
+ super(), this.object = e, this.domElement = s, this.domElement.style.touchAction = "none", this.enabled = !0, this.target = new S(), this.cursor = new S(), this.minDistance = 0, this.maxDistance = 1 / 0, this.minZoom = 0, this.maxZoom = 1 / 0, this.minTargetRadius = 0, this.maxTargetRadius = 1 / 0, this.minPolarAngle = 0, this.maxPolarAngle = Math.PI, this.minAzimuthAngle = -1 / 0, this.maxAzimuthAngle = 1 / 0, this.enableDamping = !1, this.dampingFactor = 0.05, this.enableZoom = !0, this.zoomSpeed = 1, this.enableRotate = !0, this.rotateSpeed = 1, this.enablePan = !0, this.panSpeed = 1, this.screenSpacePanning = !0, this.keyPanSpeed = 7, this.zoomToCursor = !1, this.autoRotate = !1, this.autoRotateSpeed = 2, this.keys = { LEFT: "ArrowLeft", UP: "ArrowUp", RIGHT: "ArrowRight", BOTTOM: "ArrowDown" }, this.mouseButtons = { LEFT: $.ROTATE, MIDDLE: $.DOLLY, RIGHT: $.PAN }, this.touches = { ONE: G.ROTATE, TWO: G.DOLLY_PAN }, this.target0 = this.target.clone(), this.position0 = this.object.position.clone(), this.zoom0 = this.object.zoom, this._domElementKeyEvents = null, this.getPolarAngle = function() {
83
+ return r.phi;
81
84
  }, this.getAzimuthalAngle = function() {
82
- return l.theta;
85
+ return r.theta;
83
86
  }, this.getDistance = function() {
84
87
  return this.object.position.distanceTo(this.target);
85
- }, this.listenToKeyEvents = function(i) {
86
- i.addEventListener("keydown", ie), this._domElementKeyEvents = i;
88
+ }, this.listenToKeyEvents = function(n) {
89
+ n.addEventListener("keydown", ne), this._domElementKeyEvents = n;
87
90
  }, this.stopListenToKeyEvents = function() {
88
- this._domElementKeyEvents.removeEventListener("keydown", ie), this._domElementKeyEvents = null;
91
+ this._domElementKeyEvents.removeEventListener("keydown", ne), this._domElementKeyEvents = null;
89
92
  }, this.saveState = function() {
90
93
  t.target0.copy(t.target), t.position0.copy(t.object.position), t.zoom0 = t.object.zoom;
91
94
  }, this.reset = function() {
92
- t.target.copy(t.target0), t.object.position.copy(t.position0), t.object.zoom = t.zoom0, t.object.updateProjectionMatrix(), t.dispatchEvent(ke), t.update(), o = n.NONE;
95
+ t.target.copy(t.target0), t.object.position.copy(t.position0), t.object.zoom = t.zoom0, t.object.updateProjectionMatrix(), t.dispatchEvent(ke), t.update(), i = o.NONE;
93
96
  }, this.update = function() {
94
- const i = new N(), d = new Ne().setFromUnitVectors(e.up, new N(0, 1, 0)), y = d.clone().invert(), v = new N(), C = new Ne(), F = new N(), S = 2 * Math.PI;
97
+ const n = new S(), p = new Se().setFromUnitVectors(e.up, new S(0, 1, 0)), b = p.clone().invert(), w = new S(), C = new Se(), F = new S(), z = 2 * Math.PI;
95
98
  return function(tt = null) {
96
99
  const Ce = t.object.position;
97
- i.copy(Ce).sub(t.target), i.applyQuaternion(d), l.setFromVector3(i), t.autoRotate && o === n.NONE && G(He(tt)), t.enableDamping ? (l.theta += h.theta * t.dampingFactor, l.phi += h.phi * t.dampingFactor) : (l.theta += h.theta, l.phi += h.phi);
98
- let L = t.minAzimuthAngle, O = t.maxAzimuthAngle;
99
- isFinite(L) && isFinite(O) && (L < -Math.PI ? L += S : L > Math.PI && (L -= S), O < -Math.PI ? O += S : O > Math.PI && (O -= S), L <= O ? l.theta = Math.max(L, Math.min(O, l.theta)) : l.theta = l.theta > (L + O) / 2 ? Math.max(L, l.theta) : Math.min(O, l.theta)), l.phi = Math.max(t.minPolarAngle, Math.min(t.maxPolarAngle, l.phi)), l.makeSafe(), t.enableDamping === !0 ? t.target.addScaledVector(u, t.dampingFactor) : t.target.add(u), t.target.sub(t.cursor), t.target.clampLength(t.minTargetRadius, t.maxTargetRadius), t.target.add(t.cursor), t.zoomToCursor && H || t.object.isOrthographicCamera ? l.radius = ne(l.radius) : l.radius = ne(l.radius * g), i.setFromSpherical(l), i.applyQuaternion(y), Ce.copy(t.target).add(i), t.object.lookAt(t.target), t.enableDamping === !0 ? (h.theta *= 1 - t.dampingFactor, h.phi *= 1 - t.dampingFactor, u.multiplyScalar(1 - t.dampingFactor)) : (h.set(0, 0, 0), u.set(0, 0, 0));
100
+ n.copy(Ce).sub(t.target), n.applyQuaternion(p), r.setFromVector3(n), t.autoRotate && i === o.NONE && B(He(tt)), t.enableDamping ? (r.theta += c.theta * t.dampingFactor, r.phi += c.phi * t.dampingFactor) : (r.theta += c.theta, r.phi += c.phi);
101
+ let I = t.minAzimuthAngle, R = t.maxAzimuthAngle;
102
+ isFinite(I) && isFinite(R) && (I < -Math.PI ? I += z : I > Math.PI && (I -= z), R < -Math.PI ? R += z : R > Math.PI && (R -= z), I <= R ? r.theta = Math.max(I, Math.min(R, r.theta)) : r.theta = r.theta > (I + R) / 2 ? Math.max(I, r.theta) : Math.min(R, r.theta)), r.phi = Math.max(t.minPolarAngle, Math.min(t.maxPolarAngle, r.phi)), r.makeSafe(), t.enableDamping === !0 ? t.target.addScaledVector(g, t.dampingFactor) : t.target.add(g), t.target.sub(t.cursor), t.target.clampLength(t.minTargetRadius, t.maxTargetRadius), t.target.add(t.cursor), t.zoomToCursor && H || t.object.isOrthographicCamera ? r.radius = ie(r.radius) : r.radius = ie(r.radius * d), n.setFromSpherical(r), n.applyQuaternion(b), Ce.copy(t.target).add(n), t.object.lookAt(t.target), t.enableDamping === !0 ? (c.theta *= 1 - t.dampingFactor, c.phi *= 1 - t.dampingFactor, g.multiplyScalar(1 - t.dampingFactor)) : (c.set(0, 0, 0), g.set(0, 0, 0));
100
103
  let ae = !1;
101
104
  if (t.zoomToCursor && H) {
102
- let U = null;
105
+ let X = null;
103
106
  if (t.object.isPerspectiveCamera) {
104
- const _ = i.length();
105
- U = ne(_ * g);
106
- const Z = _ - U;
107
+ const V = n.length();
108
+ X = ie(V * d);
109
+ const Z = V - X;
107
110
  t.object.position.addScaledVector(Y, Z), t.object.updateMatrixWorld();
108
111
  } else if (t.object.isOrthographicCamera) {
109
- const _ = new N(T.x, T.y, 0);
110
- _.unproject(t.object), t.object.zoom = Math.max(t.minZoom, Math.min(t.maxZoom, t.object.zoom / g)), t.object.updateProjectionMatrix(), ae = !0;
111
- const Z = new N(T.x, T.y, 0);
112
- Z.unproject(t.object), t.object.position.sub(Z).add(_), t.object.updateMatrixWorld(), U = i.length();
112
+ const V = new S(P.x, P.y, 0);
113
+ V.unproject(t.object), t.object.zoom = Math.max(t.minZoom, Math.min(t.maxZoom, t.object.zoom / d)), t.object.updateProjectionMatrix(), ae = !0;
114
+ const Z = new S(P.x, P.y, 0);
115
+ Z.unproject(t.object), t.object.position.sub(Z).add(V), t.object.updateMatrixWorld(), X = n.length();
113
116
  } else
114
117
  console.warn("WARNING: OrbitControls.js encountered an unknown camera type - zoom to cursor disabled."), t.zoomToCursor = !1;
115
- U !== null && (this.screenSpacePanning ? t.target.set(0, 0, -1).transformDirection(t.object.matrix).multiplyScalar(U).add(t.object.position) : (Q.origin.copy(t.object.position), Q.direction.set(0, 0, -1).transformDirection(t.object.matrix), Math.abs(t.object.up.dot(Q.direction)) < pt ? e.lookAt(t.target) : (Pe.setFromNormalAndCoplanarPoint(t.object.up, t.target), Q.intersectPlane(Pe, t.target))));
116
- } else t.object.isOrthographicCamera && (t.object.zoom = Math.max(t.minZoom, Math.min(t.maxZoom, t.object.zoom / g)), t.object.updateProjectionMatrix(), ae = !0);
117
- return g = 1, H = !1, ae || v.distanceToSquared(t.object.position) > a || 8 * (1 - C.dot(t.object.quaternion)) > a || F.distanceToSquared(t.target) > 0 ? (t.dispatchEvent(ke), v.copy(t.object.position), C.copy(t.object.quaternion), F.copy(t.target), !0) : !1;
118
+ X !== null && (this.screenSpacePanning ? t.target.set(0, 0, -1).transformDirection(t.object.matrix).multiplyScalar(X).add(t.object.position) : (Q.origin.copy(t.object.position), Q.direction.set(0, 0, -1).transformDirection(t.object.matrix), Math.abs(t.object.up.dot(Q.direction)) < pt ? e.lookAt(t.target) : (Te.setFromNormalAndCoplanarPoint(t.object.up, t.target), Q.intersectPlane(Te, t.target))));
119
+ } else t.object.isOrthographicCamera && (t.object.zoom = Math.max(t.minZoom, Math.min(t.maxZoom, t.object.zoom / d)), t.object.updateProjectionMatrix(), ae = !0);
120
+ return d = 1, H = !1, ae || w.distanceToSquared(t.object.position) > a || 8 * (1 - C.dot(t.object.quaternion)) > a || F.distanceToSquared(t.target) > 0 ? (t.dispatchEvent(ke), w.copy(t.object.position), C.copy(t.object.quaternion), F.copy(t.target), !0) : !1;
118
121
  };
119
122
  }(), this.dispose = function() {
120
- t.domElement.removeEventListener("contextmenu", we), t.domElement.removeEventListener("pointerdown", xe), t.domElement.removeEventListener("pointercancel", B), t.domElement.removeEventListener("wheel", ve), t.domElement.removeEventListener("pointermove", oe), t.domElement.removeEventListener("pointerup", B), t._domElementKeyEvents !== null && (t._domElementKeyEvents.removeEventListener("keydown", ie), t._domElementKeyEvents = null);
123
+ t.domElement.removeEventListener("contextmenu", we), t.domElement.removeEventListener("pointerdown", be), t.domElement.removeEventListener("pointercancel", K), t.domElement.removeEventListener("wheel", ve), t.domElement.removeEventListener("pointermove", oe), t.domElement.removeEventListener("pointerup", K), t._domElementKeyEvents !== null && (t._domElementKeyEvents.removeEventListener("keydown", ne), t._domElementKeyEvents = null);
121
124
  };
122
- const t = this, n = {
125
+ const t = this, o = {
123
126
  NONE: -1,
124
127
  ROTATE: 0,
125
128
  DOLLY: 1,
@@ -129,385 +132,385 @@ class gt extends ot {
129
132
  TOUCH_DOLLY_PAN: 5,
130
133
  TOUCH_DOLLY_ROTATE: 6
131
134
  };
132
- let o = n.NONE;
133
- const a = 1e-6, l = new ze(), h = new ze();
134
- let g = 1;
135
- const u = new N(), b = new k(), x = new k(), f = new k(), m = new k(), M = new k(), E = new k(), z = new k(), R = new k(), P = new k(), Y = new N(), T = new k();
135
+ let i = o.NONE;
136
+ const a = 1e-6, r = new Ne(), c = new Ne();
137
+ let d = 1;
138
+ const g = new S(), u = new k(), y = new k(), f = new k(), x = new k(), v = new k(), M = new k(), N = new k(), O = new k(), L = new k(), Y = new S(), P = new k();
136
139
  let H = !1;
137
- const w = [], q = {};
140
+ const E = [], _ = {};
138
141
  let ee = !1;
139
- function He(i) {
140
- return i !== null ? 2 * Math.PI / 60 * t.autoRotateSpeed * i : 2 * Math.PI / 60 / 60 * t.autoRotateSpeed;
142
+ function He(n) {
143
+ return n !== null ? 2 * Math.PI / 60 * t.autoRotateSpeed * n : 2 * Math.PI / 60 / 60 * t.autoRotateSpeed;
141
144
  }
142
- function V(i) {
143
- const d = Math.abs(i * 0.01);
144
- return Math.pow(0.95, t.zoomSpeed * d);
145
+ function q(n) {
146
+ const p = Math.abs(n * 0.01);
147
+ return Math.pow(0.95, t.zoomSpeed * p);
145
148
  }
146
- function G(i) {
147
- h.theta -= i;
149
+ function B(n) {
150
+ c.theta -= n;
148
151
  }
149
- function W(i) {
150
- h.phi -= i;
152
+ function W(n) {
153
+ c.phi -= n;
151
154
  }
152
155
  const le = function() {
153
- const i = new N();
154
- return function(y, v) {
155
- i.setFromMatrixColumn(v, 0), i.multiplyScalar(-y), u.add(i);
156
+ const n = new S();
157
+ return function(b, w) {
158
+ n.setFromMatrixColumn(w, 0), n.multiplyScalar(-b), g.add(n);
156
159
  };
157
160
  }(), ce = function() {
158
- const i = new N();
159
- return function(y, v) {
160
- t.screenSpacePanning === !0 ? i.setFromMatrixColumn(v, 1) : (i.setFromMatrixColumn(v, 0), i.crossVectors(t.object.up, i)), i.multiplyScalar(y), u.add(i);
161
+ const n = new S();
162
+ return function(b, w) {
163
+ t.screenSpacePanning === !0 ? n.setFromMatrixColumn(w, 1) : (n.setFromMatrixColumn(w, 0), n.crossVectors(t.object.up, n)), n.multiplyScalar(b), g.add(n);
161
164
  };
162
- }(), j = function() {
163
- const i = new N();
164
- return function(y, v) {
165
+ }(), A = function() {
166
+ const n = new S();
167
+ return function(b, w) {
165
168
  const C = t.domElement;
166
169
  if (t.object.isPerspectiveCamera) {
167
170
  const F = t.object.position;
168
- i.copy(F).sub(t.target);
169
- let S = i.length();
170
- S *= Math.tan(t.object.fov / 2 * Math.PI / 180), le(2 * y * S / C.clientHeight, t.object.matrix), ce(2 * v * S / C.clientHeight, t.object.matrix);
171
- } else t.object.isOrthographicCamera ? (le(y * (t.object.right - t.object.left) / t.object.zoom / C.clientWidth, t.object.matrix), ce(v * (t.object.top - t.object.bottom) / t.object.zoom / C.clientHeight, t.object.matrix)) : (console.warn("WARNING: OrbitControls.js encountered an unknown camera type - pan disabled."), t.enablePan = !1);
171
+ n.copy(F).sub(t.target);
172
+ let z = n.length();
173
+ z *= Math.tan(t.object.fov / 2 * Math.PI / 180), le(2 * b * z / C.clientHeight, t.object.matrix), ce(2 * w * z / C.clientHeight, t.object.matrix);
174
+ } else t.object.isOrthographicCamera ? (le(b * (t.object.right - t.object.left) / t.object.zoom / C.clientWidth, t.object.matrix), ce(w * (t.object.top - t.object.bottom) / t.object.zoom / C.clientHeight, t.object.matrix)) : (console.warn("WARNING: OrbitControls.js encountered an unknown camera type - pan disabled."), t.enablePan = !1);
172
175
  };
173
176
  }();
174
- function te(i) {
175
- t.object.isPerspectiveCamera || t.object.isOrthographicCamera ? g /= i : (console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."), t.enableZoom = !1);
177
+ function te(n) {
178
+ t.object.isPerspectiveCamera || t.object.isOrthographicCamera ? d /= n : (console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."), t.enableZoom = !1);
176
179
  }
177
- function he(i) {
178
- t.object.isPerspectiveCamera || t.object.isOrthographicCamera ? g *= i : (console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."), t.enableZoom = !1);
180
+ function he(n) {
181
+ t.object.isPerspectiveCamera || t.object.isOrthographicCamera ? d *= n : (console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."), t.enableZoom = !1);
179
182
  }
180
- function se(i, d) {
183
+ function se(n, p) {
181
184
  if (!t.zoomToCursor)
182
185
  return;
183
186
  H = !0;
184
- const y = t.domElement.getBoundingClientRect(), v = i - y.left, C = d - y.top, F = y.width, S = y.height;
185
- T.x = v / F * 2 - 1, T.y = -(C / S) * 2 + 1, Y.set(T.x, T.y, 1).unproject(t.object).sub(t.object.position).normalize();
187
+ const b = t.domElement.getBoundingClientRect(), w = n - b.left, C = p - b.top, F = b.width, z = b.height;
188
+ P.x = w / F * 2 - 1, P.y = -(C / z) * 2 + 1, Y.set(P.x, P.y, 1).unproject(t.object).sub(t.object.position).normalize();
186
189
  }
187
- function ne(i) {
188
- return Math.max(t.minDistance, Math.min(t.maxDistance, i));
190
+ function ie(n) {
191
+ return Math.max(t.minDistance, Math.min(t.maxDistance, n));
189
192
  }
190
- function de(i) {
191
- b.set(i.clientX, i.clientY);
193
+ function de(n) {
194
+ u.set(n.clientX, n.clientY);
192
195
  }
193
- function Ae(i) {
194
- se(i.clientX, i.clientX), z.set(i.clientX, i.clientY);
196
+ function De(n) {
197
+ se(n.clientX, n.clientX), N.set(n.clientX, n.clientY);
195
198
  }
196
- function pe(i) {
197
- m.set(i.clientX, i.clientY);
199
+ function pe(n) {
200
+ x.set(n.clientX, n.clientY);
198
201
  }
199
- function je(i) {
200
- x.set(i.clientX, i.clientY), f.subVectors(x, b).multiplyScalar(t.rotateSpeed);
201
- const d = t.domElement;
202
- G(2 * Math.PI * f.x / d.clientHeight), W(2 * Math.PI * f.y / d.clientHeight), b.copy(x), t.update();
202
+ function Ae(n) {
203
+ y.set(n.clientX, n.clientY), f.subVectors(y, u).multiplyScalar(t.rotateSpeed);
204
+ const p = t.domElement;
205
+ B(2 * Math.PI * f.x / p.clientHeight), W(2 * Math.PI * f.y / p.clientHeight), u.copy(y), t.update();
203
206
  }
204
- function De(i) {
205
- R.set(i.clientX, i.clientY), P.subVectors(R, z), P.y > 0 ? te(V(P.y)) : P.y < 0 && he(V(P.y)), z.copy(R), t.update();
207
+ function je(n) {
208
+ O.set(n.clientX, n.clientY), L.subVectors(O, N), L.y > 0 ? te(q(L.y)) : L.y < 0 && he(q(L.y)), N.copy(O), t.update();
206
209
  }
207
- function $e(i) {
208
- M.set(i.clientX, i.clientY), E.subVectors(M, m).multiplyScalar(t.panSpeed), j(E.x, E.y), m.copy(M), t.update();
210
+ function $e(n) {
211
+ v.set(n.clientX, n.clientY), M.subVectors(v, x).multiplyScalar(t.panSpeed), A(M.x, M.y), x.copy(v), t.update();
209
212
  }
210
- function Ke(i) {
211
- se(i.clientX, i.clientY), i.deltaY < 0 ? he(V(i.deltaY)) : i.deltaY > 0 && te(V(i.deltaY)), t.update();
213
+ function Ge(n) {
214
+ se(n.clientX, n.clientY), n.deltaY < 0 ? he(q(n.deltaY)) : n.deltaY > 0 && te(q(n.deltaY)), t.update();
212
215
  }
213
- function Ye(i) {
214
- let d = !1;
215
- switch (i.code) {
216
+ function Ye(n) {
217
+ let p = !1;
218
+ switch (n.code) {
216
219
  case t.keys.UP:
217
- i.ctrlKey || i.metaKey || i.shiftKey ? W(2 * Math.PI * t.rotateSpeed / t.domElement.clientHeight) : j(0, t.keyPanSpeed), d = !0;
220
+ n.ctrlKey || n.metaKey || n.shiftKey ? W(2 * Math.PI * t.rotateSpeed / t.domElement.clientHeight) : A(0, t.keyPanSpeed), p = !0;
218
221
  break;
219
222
  case t.keys.BOTTOM:
220
- i.ctrlKey || i.metaKey || i.shiftKey ? W(-2 * Math.PI * t.rotateSpeed / t.domElement.clientHeight) : j(0, -t.keyPanSpeed), d = !0;
223
+ n.ctrlKey || n.metaKey || n.shiftKey ? W(-2 * Math.PI * t.rotateSpeed / t.domElement.clientHeight) : A(0, -t.keyPanSpeed), p = !0;
221
224
  break;
222
225
  case t.keys.LEFT:
223
- i.ctrlKey || i.metaKey || i.shiftKey ? G(2 * Math.PI * t.rotateSpeed / t.domElement.clientHeight) : j(t.keyPanSpeed, 0), d = !0;
226
+ n.ctrlKey || n.metaKey || n.shiftKey ? B(2 * Math.PI * t.rotateSpeed / t.domElement.clientHeight) : A(t.keyPanSpeed, 0), p = !0;
224
227
  break;
225
228
  case t.keys.RIGHT:
226
- i.ctrlKey || i.metaKey || i.shiftKey ? G(-2 * Math.PI * t.rotateSpeed / t.domElement.clientHeight) : j(-t.keyPanSpeed, 0), d = !0;
229
+ n.ctrlKey || n.metaKey || n.shiftKey ? B(-2 * Math.PI * t.rotateSpeed / t.domElement.clientHeight) : A(-t.keyPanSpeed, 0), p = !0;
227
230
  break;
228
231
  }
229
- d && (i.preventDefault(), t.update());
232
+ p && (n.preventDefault(), t.update());
230
233
  }
231
- function ge(i) {
232
- if (w.length === 1)
233
- b.set(i.pageX, i.pageY);
234
+ function ge(n) {
235
+ if (E.length === 1)
236
+ u.set(n.pageX, n.pageY);
234
237
  else {
235
- const d = D(i), y = 0.5 * (i.pageX + d.x), v = 0.5 * (i.pageY + d.y);
236
- b.set(y, v);
238
+ const p = j(n), b = 0.5 * (n.pageX + p.x), w = 0.5 * (n.pageY + p.y);
239
+ u.set(b, w);
237
240
  }
238
241
  }
239
- function ue(i) {
240
- if (w.length === 1)
241
- m.set(i.pageX, i.pageY);
242
+ function ue(n) {
243
+ if (E.length === 1)
244
+ x.set(n.pageX, n.pageY);
242
245
  else {
243
- const d = D(i), y = 0.5 * (i.pageX + d.x), v = 0.5 * (i.pageY + d.y);
244
- m.set(y, v);
246
+ const p = j(n), b = 0.5 * (n.pageX + p.x), w = 0.5 * (n.pageY + p.y);
247
+ x.set(b, w);
245
248
  }
246
249
  }
247
- function me(i) {
248
- const d = D(i), y = i.pageX - d.x, v = i.pageY - d.y, C = Math.sqrt(y * y + v * v);
249
- z.set(0, C);
250
+ function fe(n) {
251
+ const p = j(n), b = n.pageX - p.x, w = n.pageY - p.y, C = Math.sqrt(b * b + w * w);
252
+ N.set(0, C);
250
253
  }
251
- function Ge(i) {
252
- t.enableZoom && me(i), t.enablePan && ue(i);
254
+ function Be(n) {
255
+ t.enableZoom && fe(n), t.enablePan && ue(n);
253
256
  }
254
- function Be(i) {
255
- t.enableZoom && me(i), t.enableRotate && ge(i);
257
+ function Ke(n) {
258
+ t.enableZoom && fe(n), t.enableRotate && ge(n);
256
259
  }
257
- function fe(i) {
258
- if (w.length == 1)
259
- x.set(i.pageX, i.pageY);
260
+ function me(n) {
261
+ if (E.length == 1)
262
+ y.set(n.pageX, n.pageY);
260
263
  else {
261
- const y = D(i), v = 0.5 * (i.pageX + y.x), C = 0.5 * (i.pageY + y.y);
262
- x.set(v, C);
264
+ const b = j(n), w = 0.5 * (n.pageX + b.x), C = 0.5 * (n.pageY + b.y);
265
+ y.set(w, C);
263
266
  }
264
- f.subVectors(x, b).multiplyScalar(t.rotateSpeed);
265
- const d = t.domElement;
266
- G(2 * Math.PI * f.x / d.clientHeight), W(2 * Math.PI * f.y / d.clientHeight), b.copy(x);
267
+ f.subVectors(y, u).multiplyScalar(t.rotateSpeed);
268
+ const p = t.domElement;
269
+ B(2 * Math.PI * f.x / p.clientHeight), W(2 * Math.PI * f.y / p.clientHeight), u.copy(y);
267
270
  }
268
- function ye(i) {
269
- if (w.length === 1)
270
- M.set(i.pageX, i.pageY);
271
+ function ye(n) {
272
+ if (E.length === 1)
273
+ v.set(n.pageX, n.pageY);
271
274
  else {
272
- const d = D(i), y = 0.5 * (i.pageX + d.x), v = 0.5 * (i.pageY + d.y);
273
- M.set(y, v);
275
+ const p = j(n), b = 0.5 * (n.pageX + p.x), w = 0.5 * (n.pageY + p.y);
276
+ v.set(b, w);
274
277
  }
275
- E.subVectors(M, m).multiplyScalar(t.panSpeed), j(E.x, E.y), m.copy(M);
278
+ M.subVectors(v, x).multiplyScalar(t.panSpeed), A(M.x, M.y), x.copy(v);
276
279
  }
277
- function be(i) {
278
- const d = D(i), y = i.pageX - d.x, v = i.pageY - d.y, C = Math.sqrt(y * y + v * v);
279
- R.set(0, C), P.set(0, Math.pow(R.y / z.y, t.zoomSpeed)), te(P.y), z.copy(R);
280
- const F = (i.pageX + d.x) * 0.5, S = (i.pageY + d.y) * 0.5;
281
- se(F, S);
280
+ function xe(n) {
281
+ const p = j(n), b = n.pageX - p.x, w = n.pageY - p.y, C = Math.sqrt(b * b + w * w);
282
+ O.set(0, C), L.set(0, Math.pow(O.y / N.y, t.zoomSpeed)), te(L.y), N.copy(O);
283
+ const F = (n.pageX + p.x) * 0.5, z = (n.pageY + p.y) * 0.5;
284
+ se(F, z);
282
285
  }
283
- function Ue(i) {
284
- t.enableZoom && be(i), t.enablePan && ye(i);
286
+ function Xe(n) {
287
+ t.enableZoom && xe(n), t.enablePan && ye(n);
285
288
  }
286
- function _e(i) {
287
- t.enableZoom && be(i), t.enableRotate && fe(i);
289
+ function Ve(n) {
290
+ t.enableZoom && xe(n), t.enableRotate && me(n);
288
291
  }
289
- function xe(i) {
290
- t.enabled !== !1 && (w.length === 0 && (t.domElement.setPointerCapture(i.pointerId), t.domElement.addEventListener("pointermove", oe), t.domElement.addEventListener("pointerup", B)), Je(i), i.pointerType === "touch" ? Ze(i) : Xe(i));
292
+ function be(n) {
293
+ t.enabled !== !1 && (E.length === 0 && (t.domElement.setPointerCapture(n.pointerId), t.domElement.addEventListener("pointermove", oe), t.domElement.addEventListener("pointerup", K)), Je(n), n.pointerType === "touch" ? Ze(n) : Ue(n));
291
294
  }
292
- function oe(i) {
293
- t.enabled !== !1 && (i.pointerType === "touch" ? Qe(i) : qe(i));
295
+ function oe(n) {
296
+ t.enabled !== !1 && (n.pointerType === "touch" ? Qe(n) : _e(n));
294
297
  }
295
- function B(i) {
296
- et(i), w.length === 0 && (t.domElement.releasePointerCapture(i.pointerId), t.domElement.removeEventListener("pointermove", oe), t.domElement.removeEventListener("pointerup", B)), t.dispatchEvent(Te), o = n.NONE;
298
+ function K(n) {
299
+ et(n), E.length === 0 && (t.domElement.releasePointerCapture(n.pointerId), t.domElement.removeEventListener("pointermove", oe), t.domElement.removeEventListener("pointerup", K)), t.dispatchEvent(Pe), i = o.NONE;
297
300
  }
298
- function Xe(i) {
299
- let d;
300
- switch (i.button) {
301
+ function Ue(n) {
302
+ let p;
303
+ switch (n.button) {
301
304
  case 0:
302
- d = t.mouseButtons.LEFT;
305
+ p = t.mouseButtons.LEFT;
303
306
  break;
304
307
  case 1:
305
- d = t.mouseButtons.MIDDLE;
308
+ p = t.mouseButtons.MIDDLE;
306
309
  break;
307
310
  case 2:
308
- d = t.mouseButtons.RIGHT;
311
+ p = t.mouseButtons.RIGHT;
309
312
  break;
310
313
  default:
311
- d = -1;
314
+ p = -1;
312
315
  }
313
- switch (d) {
316
+ switch (p) {
314
317
  case $.DOLLY:
315
318
  if (t.enableZoom === !1) return;
316
- Ae(i), o = n.DOLLY;
319
+ De(n), i = o.DOLLY;
317
320
  break;
318
321
  case $.ROTATE:
319
- if (i.ctrlKey || i.metaKey || i.shiftKey) {
322
+ if (n.ctrlKey || n.metaKey || n.shiftKey) {
320
323
  if (t.enablePan === !1) return;
321
- pe(i), o = n.PAN;
324
+ pe(n), i = o.PAN;
322
325
  } else {
323
326
  if (t.enableRotate === !1) return;
324
- de(i), o = n.ROTATE;
327
+ de(n), i = o.ROTATE;
325
328
  }
326
329
  break;
327
330
  case $.PAN:
328
- if (i.ctrlKey || i.metaKey || i.shiftKey) {
331
+ if (n.ctrlKey || n.metaKey || n.shiftKey) {
329
332
  if (t.enableRotate === !1) return;
330
- de(i), o = n.ROTATE;
333
+ de(n), i = o.ROTATE;
331
334
  } else {
332
335
  if (t.enablePan === !1) return;
333
- pe(i), o = n.PAN;
336
+ pe(n), i = o.PAN;
334
337
  }
335
338
  break;
336
339
  default:
337
- o = n.NONE;
340
+ i = o.NONE;
338
341
  }
339
- o !== n.NONE && t.dispatchEvent(re);
342
+ i !== o.NONE && t.dispatchEvent(re);
340
343
  }
341
- function qe(i) {
342
- switch (o) {
343
- case n.ROTATE:
344
+ function _e(n) {
345
+ switch (i) {
346
+ case o.ROTATE:
344
347
  if (t.enableRotate === !1) return;
345
- je(i);
348
+ Ae(n);
346
349
  break;
347
- case n.DOLLY:
350
+ case o.DOLLY:
348
351
  if (t.enableZoom === !1) return;
349
- De(i);
352
+ je(n);
350
353
  break;
351
- case n.PAN:
354
+ case o.PAN:
352
355
  if (t.enablePan === !1) return;
353
- $e(i);
356
+ $e(n);
354
357
  break;
355
358
  }
356
359
  }
357
- function ve(i) {
358
- t.enabled === !1 || t.enableZoom === !1 || o !== n.NONE || (i.preventDefault(), t.dispatchEvent(re), Ke(Ve(i)), t.dispatchEvent(Te));
360
+ function ve(n) {
361
+ t.enabled === !1 || t.enableZoom === !1 || i !== o.NONE || (n.preventDefault(), t.dispatchEvent(re), Ge(qe(n)), t.dispatchEvent(Pe));
359
362
  }
360
- function Ve(i) {
361
- const d = i.deltaMode, y = {
362
- clientX: i.clientX,
363
- clientY: i.clientY,
364
- deltaY: i.deltaY
363
+ function qe(n) {
364
+ const p = n.deltaMode, b = {
365
+ clientX: n.clientX,
366
+ clientY: n.clientY,
367
+ deltaY: n.deltaY
365
368
  };
366
- switch (d) {
369
+ switch (p) {
367
370
  case 1:
368
- y.deltaY *= 16;
371
+ b.deltaY *= 16;
369
372
  break;
370
373
  case 2:
371
- y.deltaY *= 100;
374
+ b.deltaY *= 100;
372
375
  break;
373
376
  }
374
- return i.ctrlKey && !ee && (y.deltaY *= 10), y;
377
+ return n.ctrlKey && !ee && (b.deltaY *= 10), b;
375
378
  }
376
- function We(i) {
377
- i.key === "Control" && (ee = !0, document.addEventListener("keyup", Me, { passive: !0, capture: !0 }));
379
+ function We(n) {
380
+ n.key === "Control" && (ee = !0, document.addEventListener("keyup", Me, { passive: !0, capture: !0 }));
378
381
  }
379
- function Me(i) {
380
- i.key === "Control" && (ee = !1, document.removeEventListener("keyup", Me, { passive: !0, capture: !0 }));
382
+ function Me(n) {
383
+ n.key === "Control" && (ee = !1, document.removeEventListener("keyup", Me, { passive: !0, capture: !0 }));
381
384
  }
382
- function ie(i) {
383
- t.enabled === !1 || t.enablePan === !1 || Ye(i);
385
+ function ne(n) {
386
+ t.enabled === !1 || t.enablePan === !1 || Ye(n);
384
387
  }
385
- function Ze(i) {
386
- switch (Ee(i), w.length) {
388
+ function Ze(n) {
389
+ switch (Ee(n), E.length) {
387
390
  case 1:
388
391
  switch (t.touches.ONE) {
389
- case K.ROTATE:
392
+ case G.ROTATE:
390
393
  if (t.enableRotate === !1) return;
391
- ge(i), o = n.TOUCH_ROTATE;
394
+ ge(n), i = o.TOUCH_ROTATE;
392
395
  break;
393
- case K.PAN:
396
+ case G.PAN:
394
397
  if (t.enablePan === !1) return;
395
- ue(i), o = n.TOUCH_PAN;
398
+ ue(n), i = o.TOUCH_PAN;
396
399
  break;
397
400
  default:
398
- o = n.NONE;
401
+ i = o.NONE;
399
402
  }
400
403
  break;
401
404
  case 2:
402
405
  switch (t.touches.TWO) {
403
- case K.DOLLY_PAN:
406
+ case G.DOLLY_PAN:
404
407
  if (t.enableZoom === !1 && t.enablePan === !1) return;
405
- Ge(i), o = n.TOUCH_DOLLY_PAN;
408
+ Be(n), i = o.TOUCH_DOLLY_PAN;
406
409
  break;
407
- case K.DOLLY_ROTATE:
410
+ case G.DOLLY_ROTATE:
408
411
  if (t.enableZoom === !1 && t.enableRotate === !1) return;
409
- Be(i), o = n.TOUCH_DOLLY_ROTATE;
412
+ Ke(n), i = o.TOUCH_DOLLY_ROTATE;
410
413
  break;
411
414
  default:
412
- o = n.NONE;
415
+ i = o.NONE;
413
416
  }
414
417
  break;
415
418
  default:
416
- o = n.NONE;
419
+ i = o.NONE;
417
420
  }
418
- o !== n.NONE && t.dispatchEvent(re);
421
+ i !== o.NONE && t.dispatchEvent(re);
419
422
  }
420
- function Qe(i) {
421
- switch (Ee(i), o) {
422
- case n.TOUCH_ROTATE:
423
+ function Qe(n) {
424
+ switch (Ee(n), i) {
425
+ case o.TOUCH_ROTATE:
423
426
  if (t.enableRotate === !1) return;
424
- fe(i), t.update();
427
+ me(n), t.update();
425
428
  break;
426
- case n.TOUCH_PAN:
429
+ case o.TOUCH_PAN:
427
430
  if (t.enablePan === !1) return;
428
- ye(i), t.update();
431
+ ye(n), t.update();
429
432
  break;
430
- case n.TOUCH_DOLLY_PAN:
433
+ case o.TOUCH_DOLLY_PAN:
431
434
  if (t.enableZoom === !1 && t.enablePan === !1) return;
432
- Ue(i), t.update();
435
+ Xe(n), t.update();
433
436
  break;
434
- case n.TOUCH_DOLLY_ROTATE:
437
+ case o.TOUCH_DOLLY_ROTATE:
435
438
  if (t.enableZoom === !1 && t.enableRotate === !1) return;
436
- _e(i), t.update();
439
+ Ve(n), t.update();
437
440
  break;
438
441
  default:
439
- o = n.NONE;
442
+ i = o.NONE;
440
443
  }
441
444
  }
442
- function we(i) {
443
- t.enabled !== !1 && i.preventDefault();
445
+ function we(n) {
446
+ t.enabled !== !1 && n.preventDefault();
444
447
  }
445
- function Je(i) {
446
- w.push(i.pointerId);
448
+ function Je(n) {
449
+ E.push(n.pointerId);
447
450
  }
448
- function et(i) {
449
- delete q[i.pointerId];
450
- for (let d = 0; d < w.length; d++)
451
- if (w[d] == i.pointerId) {
452
- w.splice(d, 1);
451
+ function et(n) {
452
+ delete _[n.pointerId];
453
+ for (let p = 0; p < E.length; p++)
454
+ if (E[p] == n.pointerId) {
455
+ E.splice(p, 1);
453
456
  return;
454
457
  }
455
458
  }
456
- function Ee(i) {
457
- let d = q[i.pointerId];
458
- d === void 0 && (d = new k(), q[i.pointerId] = d), d.set(i.pageX, i.pageY);
459
+ function Ee(n) {
460
+ let p = _[n.pointerId];
461
+ p === void 0 && (p = new k(), _[n.pointerId] = p), p.set(n.pageX, n.pageY);
459
462
  }
460
- function D(i) {
461
- const d = i.pointerId === w[0] ? w[1] : w[0];
462
- return q[d];
463
+ function j(n) {
464
+ const p = n.pointerId === E[0] ? E[1] : E[0];
465
+ return _[p];
463
466
  }
464
- t.domElement.addEventListener("contextmenu", we), t.domElement.addEventListener("pointerdown", xe), t.domElement.addEventListener("pointercancel", B), t.domElement.addEventListener("wheel", ve, { passive: !1 }), document.addEventListener("keydown", We, { passive: !0, capture: !0 }), this.update();
467
+ t.domElement.addEventListener("contextmenu", we), t.domElement.addEventListener("pointerdown", be), t.domElement.addEventListener("pointercancel", K), t.domElement.addEventListener("wheel", ve, { passive: !1 }), document.addEventListener("keydown", We, { passive: !0, capture: !0 }), this.update();
465
468
  }
466
469
  }
467
470
  class ut {
468
471
  constructor(e, s) {
469
- r(this, "scene");
470
- r(this, "camera");
471
- r(this, "renderer");
472
- r(this, "controls");
473
- r(this, "container");
474
- r(this, "resizeHandler");
475
- this.container = e, this.scene = new p.Scene(), this.scene.background = new p.Color(
472
+ l(this, "scene");
473
+ l(this, "camera");
474
+ l(this, "renderer");
475
+ l(this, "controls");
476
+ l(this, "container");
477
+ l(this, "resizeHandler");
478
+ this.container = e, this.scene = new m.Scene(), this.scene.background = new m.Color(
476
479
  s.backgroundColor ?? 657930
477
480
  );
478
- const { width: t, height: n } = Se(e), o = s.cameraFov ?? 75;
479
- this.camera = new p.PerspectiveCamera(o, t / n, 0.1, 2e3);
481
+ const { width: t, height: o } = ze(e), i = s.cameraFov ?? 75;
482
+ this.camera = new m.PerspectiveCamera(i, t / o, 0.1, 2e3);
480
483
  const a = s.cameraPosition ?? { x: 0, y: 0, z: 80 };
481
- this.camera.position.set(a.x, a.y, a.z), this.renderer = new p.WebGLRenderer({
484
+ this.camera.position.set(a.x, a.y, a.z), this.renderer = new m.WebGLRenderer({
482
485
  antialias: !0,
483
486
  alpha: !0,
484
487
  powerPreference: "high-performance"
485
- }), this.renderer.setSize(t, n), this.renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)), this.renderer.toneMapping = p.ACESFilmicToneMapping, this.renderer.toneMappingExposure = 1, this.renderer.shadowMap.enabled = !0, this.renderer.shadowMap.type = p.PCFSoftShadowMap, e.appendChild(this.renderer.domElement), this.controls = new gt(this.camera, this.renderer.domElement), this.controls.enableDamping = !0, this.controls.dampingFactor = 0.05, this.controls.rotateSpeed = 0.8, this.controls.zoomSpeed = 1.2, this.controls.minDistance = 10, this.controls.maxDistance = 500, this.setupLighting(), this.resizeHandler = this.onWindowResize.bind(this), window.addEventListener("resize", this.resizeHandler);
488
+ }), this.renderer.setSize(t, o), this.renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)), this.renderer.toneMapping = m.ACESFilmicToneMapping, this.renderer.toneMappingExposure = 1, this.renderer.shadowMap.enabled = !0, this.renderer.shadowMap.type = m.PCFSoftShadowMap, e.appendChild(this.renderer.domElement), this.controls = new gt(this.camera, this.renderer.domElement), this.controls.enableDamping = !0, this.controls.dampingFactor = 0.05, this.controls.rotateSpeed = 0.8, this.controls.zoomSpeed = 1.2, this.controls.minDistance = 10, this.controls.maxDistance = 500, this.setupLighting(), this.resizeHandler = this.onWindowResize.bind(this), window.addEventListener("resize", this.resizeHandler);
486
489
  }
487
490
  /**
488
491
  * Sets up scene lighting for gradient glass on dark background
489
492
  */
490
493
  setupLighting() {
491
- const e = new p.AmbientLight(16777215, 0.4);
494
+ const e = new m.AmbientLight(16777215, 0.4);
492
495
  this.scene.add(e);
493
- const s = new p.DirectionalLight(16777215, 0.9);
496
+ const s = new m.DirectionalLight(16777215, 0.9);
494
497
  s.position.set(50, 60, 40), s.castShadow = !0, s.shadow.mapSize.width = 1024, s.shadow.mapSize.height = 1024, this.scene.add(s);
495
- const t = new p.DirectionalLight(16773344, 0.4);
498
+ const t = new m.DirectionalLight(16773344, 0.4);
496
499
  t.position.set(-50, 30, -40), this.scene.add(t);
497
- const n = new p.DirectionalLight(16777215, 0.3);
498
- n.position.set(0, -30, -50), this.scene.add(n);
499
- const o = new p.PointLight(16750950, 0.5, 150);
500
- o.position.set(40, 20, 40), this.scene.add(o);
501
- const a = new p.PointLight(16764057, 0.4, 150);
500
+ const o = new m.DirectionalLight(16777215, 0.3);
501
+ o.position.set(0, -30, -50), this.scene.add(o);
502
+ const i = new m.PointLight(16750950, 0.5, 150);
503
+ i.position.set(40, 20, 40), this.scene.add(i);
504
+ const a = new m.PointLight(16764057, 0.4, 150);
502
505
  a.position.set(-40, -20, 40), this.scene.add(a);
503
- const l = new p.PointLight(6724095, 0.2, 100);
504
- l.position.set(0, 40, -40), this.scene.add(l);
506
+ const r = new m.PointLight(6724095, 0.2, 100);
507
+ r.position.set(0, 40, -40), this.scene.add(r);
505
508
  }
506
509
  /**
507
510
  * Handle window resize
508
511
  */
509
512
  onWindowResize() {
510
- const { width: e, height: s } = Se(this.container);
513
+ const { width: e, height: s } = ze(this.container);
511
514
  this.camera.aspect = e / s, this.camera.updateProjectionMatrix(), this.renderer.setSize(e, s);
512
515
  }
513
516
  /**
@@ -542,7 +545,7 @@ class ut {
542
545
  * Gets the camera's forward direction
543
546
  */
544
547
  getCameraDirection() {
545
- const e = new p.Vector3();
548
+ const e = new m.Vector3();
546
549
  return this.camera.getWorldDirection(e), e;
547
550
  }
548
551
  /**
@@ -555,12 +558,12 @@ class ut {
555
558
  }
556
559
  }
557
560
  }
558
- class mt {
561
+ class ft {
559
562
  constructor(e, s) {
560
- r(this, "sceneManager");
561
- r(this, "nodeFactory");
562
- r(this, "nodes", /* @__PURE__ */ new Map());
563
- r(this, "nodeObjects", /* @__PURE__ */ new Map());
563
+ l(this, "sceneManager");
564
+ l(this, "nodeFactory");
565
+ l(this, "nodes", /* @__PURE__ */ new Map());
566
+ l(this, "nodeObjects", /* @__PURE__ */ new Map());
564
567
  this.sceneManager = e, this.nodeFactory = s;
565
568
  }
566
569
  /**
@@ -574,7 +577,7 @@ class mt {
574
577
  * @returns true if added, false if node already exists or invalid
575
578
  */
576
579
  addNode(e, s = 0) {
577
- if (!Re(e))
580
+ if (!Oe(e))
578
581
  return !1;
579
582
  if (this.nodes.has(e.id))
580
583
  return console.warn(`[ForceGraph3D] Node with id "${e.id}" already exists`), !1;
@@ -582,16 +585,16 @@ class mt {
582
585
  x: (Math.random() - 0.5) * 50,
583
586
  y: (Math.random() - 0.5) * 50,
584
587
  z: (Math.random() - 0.5) * 50
585
- }, n = {
588
+ }, o = {
586
589
  ...e,
587
590
  position: t,
588
591
  velocity: { x: 0, y: 0, z: 0 },
589
592
  mass: 1
590
- }, o = this.nodeFactory.createNode(
593
+ }, i = this.nodeFactory.createNode(
591
594
  { ...e, position: t },
592
595
  s
593
596
  );
594
- return this.sceneManager.add(o.group), this.nodes.set(e.id, n), this.nodeObjects.set(e.id, o), !0;
597
+ return this.sceneManager.add(i.group), this.nodes.set(e.id, o), this.nodeObjects.set(e.id, i), !0;
595
598
  }
596
599
  /**
597
600
  * Removes a node from the graph
@@ -605,17 +608,17 @@ class mt {
605
608
  * Updates a node's properties
606
609
  */
607
610
  updateNode(e, s) {
608
- const t = this.nodes.get(e), n = this.nodeObjects.get(e);
609
- return !t || !n ? (console.warn(`[ForceGraph3D] Node "${e}" not found`), !1) : (s.label !== void 0 && (t.label = s.label, this.nodeFactory.updateNodeLabel(n, s.label)), s.color !== void 0 && (t.color = s.color, this.nodeFactory.updateNodeColor(n, s.color)), Object.keys(s).forEach((o) => {
610
- o !== "id" && o !== "label" && o !== "color" && o !== "position" && (t[o] = s[o]);
611
+ const t = this.nodes.get(e), o = this.nodeObjects.get(e);
612
+ return !t || !o ? (console.warn(`[ForceGraph3D] Node "${e}" not found`), !1) : (s.label !== void 0 && (t.label = s.label, this.nodeFactory.updateNodeLabel(o, s.label)), s.color !== void 0 && (t.color = s.color, this.nodeFactory.updateNodeColor(o, s.color)), Object.keys(s).forEach((i) => {
613
+ i !== "id" && i !== "label" && i !== "color" && i !== "position" && (t[i] = s[i]);
611
614
  }), !0);
612
615
  }
613
616
  /**
614
617
  * Updates a node's position (called by physics engine)
615
618
  */
616
619
  updateNodePosition(e, s) {
617
- const t = this.nodes.get(e), n = this.nodeObjects.get(e);
618
- t && n && (t.position = s, n.group.position.set(s.x, s.y, s.z));
620
+ const t = this.nodes.get(e), o = this.nodeObjects.get(e);
621
+ t && o && (t.position = s, o.group.position.set(s.x, s.y, s.z));
619
622
  }
620
623
  /**
621
624
  * Updates a node's LOD level
@@ -681,22 +684,22 @@ class mt {
681
684
  this.clear();
682
685
  }
683
686
  }
684
- class ft {
687
+ class mt {
685
688
  constructor(e, s, t) {
686
- r(this, "sceneManager");
687
- r(this, "nodeManager");
688
- r(this, "edgeFactory");
689
- r(this, "edges", []);
690
- r(this, "edgeObjects", []);
691
- r(this, "edgeKeySet", /* @__PURE__ */ new Set());
692
- r(this, "highlightedEdgeKey", null);
689
+ l(this, "sceneManager");
690
+ l(this, "nodeManager");
691
+ l(this, "edgeFactory");
692
+ l(this, "edges", []);
693
+ l(this, "edgeObjects", []);
694
+ l(this, "edgeKeySet", /* @__PURE__ */ new Set());
695
+ l(this, "highlightedEdgeKey", null);
693
696
  this.sceneManager = e, this.nodeManager = s, this.edgeFactory = t;
694
697
  }
695
698
  /**
696
699
  * Checks if an edge exists
697
700
  */
698
701
  hasEdge(e, s) {
699
- const t = A(e, s);
702
+ const t = D(e, s);
700
703
  return this.edgeKeySet.has(t);
701
704
  }
702
705
  /**
@@ -710,44 +713,44 @@ class ft {
710
713
  return console.warn(`[ForceGraph3D] Source node "${e.source}" does not exist`), !1;
711
714
  if (!this.nodeManager.hasNode(e.target))
712
715
  return console.warn(`[ForceGraph3D] Target node "${e.target}" does not exist`), !1;
713
- const s = A(e.source, e.target);
716
+ const s = D(e.source, e.target);
714
717
  if (this.edgeKeySet.has(s))
715
718
  return console.warn(`[ForceGraph3D] Edge "${e.source}" -> "${e.target}" already exists`), !1;
716
- const t = this.nodeManager.getNode(e.source), n = this.nodeManager.getNode(e.target), o = this.edgeFactory.createEdge(
719
+ const t = this.nodeManager.getNode(e.source), o = this.nodeManager.getNode(e.target), i = this.edgeFactory.createEdge(
717
720
  e,
718
721
  t,
719
- n,
722
+ o,
720
723
  t.position,
721
- n.position
724
+ o.position
722
725
  );
723
- return this.sceneManager.add(o.line), this.edges.push(e), this.edgeObjects.push(o), this.edgeKeySet.add(s), !0;
726
+ return this.sceneManager.add(i.line), this.edges.push(e), this.edgeObjects.push(i), this.edgeKeySet.add(s), !0;
724
727
  }
725
728
  /**
726
729
  * Removes an edge from the graph
727
730
  * @returns true if removed, false if not found
728
731
  */
729
732
  removeEdge(e, s) {
730
- const t = A(e, s);
733
+ const t = D(e, s);
731
734
  if (!this.edgeKeySet.has(t))
732
735
  return !1;
733
- const n = this.edges.findIndex(
734
- (a) => A(a.source, a.target) === t
736
+ const o = this.edges.findIndex(
737
+ (a) => D(a.source, a.target) === t
735
738
  );
736
- if (n === -1)
739
+ if (o === -1)
737
740
  return !1;
738
- const o = this.edgeObjects[n];
739
- return this.sceneManager.remove(o.line), this.edgeFactory.disposeEdge(o), this.edges.splice(n, 1), this.edgeObjects.splice(n, 1), this.edgeKeySet.delete(t), this.highlightedEdgeKey === t && (this.highlightedEdgeKey = null), !0;
741
+ const i = this.edgeObjects[o];
742
+ return this.sceneManager.remove(i.line), this.edgeFactory.disposeEdge(i), this.edges.splice(o, 1), this.edgeObjects.splice(o, 1), this.edgeKeySet.delete(t), this.highlightedEdgeKey === t && (this.highlightedEdgeKey = null), !0;
740
743
  }
741
744
  /**
742
745
  * Highlights an edge
743
746
  */
744
747
  highlightEdge(e, s) {
745
- const t = A(e, s);
748
+ const t = D(e, s);
746
749
  this.highlightedEdgeKey && this.highlightedEdgeKey !== t && this.unhighlightCurrentEdge();
747
- const n = this.edges.findIndex(
748
- (o) => A(o.source, o.target) === t
750
+ const o = this.edges.findIndex(
751
+ (i) => D(i.source, i.target) === t
749
752
  );
750
- n !== -1 && (this.edgeFactory.highlightEdge(this.edgeObjects[n]), this.highlightedEdgeKey = t);
753
+ o !== -1 && (this.edgeFactory.highlightEdge(this.edgeObjects[o]), this.highlightedEdgeKey = t);
751
754
  }
752
755
  /**
753
756
  * Unhighlights the currently highlighted edge
@@ -755,7 +758,7 @@ class ft {
755
758
  unhighlightCurrentEdge() {
756
759
  if (!this.highlightedEdgeKey) return;
757
760
  const e = this.edges.findIndex(
758
- (s) => A(s.source, s.target) === this.highlightedEdgeKey
761
+ (s) => D(s.source, s.target) === this.highlightedEdgeKey
759
762
  );
760
763
  e !== -1 && this.edgeFactory.unhighlightEdge(this.edgeObjects[e]), this.highlightedEdgeKey = null;
761
764
  }
@@ -790,11 +793,11 @@ class ft {
790
793
  */
791
794
  updateEdgePositions() {
792
795
  this.edgeObjects.forEach((e, s) => {
793
- const t = this.edges[s], n = this.nodeManager.getNode(t.source), o = this.nodeManager.getNode(t.target);
794
- n && o && this.edgeFactory.updateEdgePositions(
796
+ const t = this.edges[s], o = this.nodeManager.getNode(t.source), i = this.nodeManager.getNode(t.target);
797
+ o && i && this.edgeFactory.updateEdgePositions(
795
798
  e,
796
- n.position,
797
- o.position
799
+ o.position,
800
+ i.position
798
801
  );
799
802
  });
800
803
  }
@@ -833,19 +836,19 @@ class ft {
833
836
  }
834
837
  class Le {
835
838
  constructor(e, s, t = {}) {
836
- r(this, "nodes");
837
- r(this, "edges");
839
+ l(this, "nodes");
840
+ l(this, "edges");
838
841
  // Physics parameters
839
- r(this, "repulsionStrength");
840
- r(this, "attractionStrength");
841
- r(this, "damping");
842
- r(this, "useBarnesHut");
843
- r(this, "barnesHutTheta");
842
+ l(this, "repulsionStrength");
843
+ l(this, "attractionStrength");
844
+ l(this, "damping");
845
+ l(this, "useBarnesHut");
846
+ l(this, "barnesHutTheta");
844
847
  // Simulation state
845
- r(this, "alpha", 1);
846
- r(this, "alphaDecay", 0.0228);
847
- r(this, "alphaMin", 1e-3);
848
- r(this, "alphaTarget", 0);
848
+ l(this, "alpha", 1);
849
+ l(this, "alphaDecay", 0.0228);
850
+ l(this, "alphaMin", 1e-3);
851
+ l(this, "alphaTarget", 0);
849
852
  this.nodes = e, this.edges = s, this.repulsionStrength = t.repulsionStrength ?? 100, this.attractionStrength = t.attractionStrength ?? 0.01, this.damping = t.damping ?? 0.9, this.useBarnesHut = t.useBarnesHut ?? !1, this.barnesHutTheta = t.barnesHutTheta ?? 0.5;
850
853
  }
851
854
  /**
@@ -862,13 +865,13 @@ class Le {
862
865
  calculateRepulsionBruteForce() {
863
866
  const e = Array.from(this.nodes.values()), s = e.length;
864
867
  for (let t = 0; t < s; t++) {
865
- const n = e[t];
866
- for (let o = t + 1; o < s; o++) {
867
- const a = e[o], l = a.position.x - n.position.x, h = a.position.y - n.position.y, g = a.position.z - n.position.z;
868
- let u = l * l + h * h + g * g;
869
- u < 0.01 && (u = 0.01);
870
- const b = Math.sqrt(u), x = this.repulsionStrength * this.alpha / u, f = l / b * x, m = h / b * x, M = g / b * x;
871
- n.velocity.x -= f / n.mass, n.velocity.y -= m / n.mass, n.velocity.z -= M / n.mass, a.velocity.x += f / a.mass, a.velocity.y += m / a.mass, a.velocity.z += M / a.mass;
868
+ const o = e[t];
869
+ for (let i = t + 1; i < s; i++) {
870
+ const a = e[i], r = a.position.x - o.position.x, c = a.position.y - o.position.y, d = a.position.z - o.position.z;
871
+ let g = r * r + c * c + d * d;
872
+ g < 0.01 && (g = 0.01);
873
+ const u = Math.sqrt(g), y = this.repulsionStrength * this.alpha / g, f = r / u * y, x = c / u * y, v = d / u * y;
874
+ o.velocity.x -= f / o.mass, o.velocity.y -= x / o.mass, o.velocity.z -= v / o.mass, a.velocity.x += f / a.mass, a.velocity.y += x / a.mass, a.velocity.z += v / a.mass;
872
875
  }
873
876
  }
874
877
  }
@@ -889,23 +892,23 @@ class Le {
889
892
  return;
890
893
  }
891
894
  if (s.mass === 0) return;
892
- const t = s.centerOfMass.x - e.position.x, n = s.centerOfMass.y - e.position.y, o = s.centerOfMass.z - e.position.z, a = Math.sqrt(t * t + n * n + o * o);
895
+ const t = s.centerOfMass.x - e.position.x, o = s.centerOfMass.y - e.position.y, i = s.centerOfMass.z - e.position.z, a = Math.sqrt(t * t + o * o + i * i);
893
896
  if (s.size / a < this.barnesHutTheta) {
894
- const l = Math.max(a * a, 0.01), h = this.repulsionStrength * this.alpha * s.mass / l;
895
- e.velocity.x -= t / a * h / e.mass, e.velocity.y -= n / a * h / e.mass, e.velocity.z -= o / a * h / e.mass;
897
+ const r = Math.max(a * a, 0.01), c = this.repulsionStrength * this.alpha * s.mass / r;
898
+ e.velocity.x -= t / a * c / e.mass, e.velocity.y -= o / a * c / e.mass, e.velocity.z -= i / a * c / e.mass;
896
899
  } else
897
- for (const l of s.children)
898
- l && this.calculateForceFromOctree(e, l);
900
+ for (const r of s.children)
901
+ r && this.calculateForceFromOctree(e, r);
899
902
  }
900
903
  /**
901
904
  * Apply repulsion between two nodes
902
905
  */
903
906
  applyRepulsionBetween(e, s) {
904
- const t = s.position.x - e.position.x, n = s.position.y - e.position.y, o = s.position.z - e.position.z;
905
- let a = t * t + n * n + o * o;
907
+ const t = s.position.x - e.position.x, o = s.position.y - e.position.y, i = s.position.z - e.position.z;
908
+ let a = t * t + o * o + i * i;
906
909
  a < 0.01 && (a = 0.01);
907
- const l = Math.sqrt(a), h = this.repulsionStrength * this.alpha / a;
908
- e.velocity.x -= t / l * h / e.mass, e.velocity.y -= n / l * h / e.mass, e.velocity.z -= o / l * h / e.mass;
910
+ const r = Math.sqrt(a), c = this.repulsionStrength * this.alpha / a;
911
+ e.velocity.x -= t / r * c / e.mass, e.velocity.y -= o / r * c / e.mass, e.velocity.z -= i / r * c / e.mass;
909
912
  }
910
913
  /**
911
914
  * Calculate attraction forces along edges
@@ -914,10 +917,10 @@ class Le {
914
917
  for (const e of this.edges) {
915
918
  const s = this.nodes.get(e.source), t = this.nodes.get(e.target);
916
919
  if (!s || !t) continue;
917
- const n = t.position.x - s.position.x, o = t.position.y - s.position.y, a = t.position.z - s.position.z, l = Math.sqrt(n * n + o * o + a * a);
918
- if (l < 0.01) continue;
919
- const g = (l - 15) * this.attractionStrength * this.alpha, u = n / l * g, b = o / l * g, x = a / l * g;
920
- s.velocity.x += u / s.mass, s.velocity.y += b / s.mass, s.velocity.z += x / s.mass, t.velocity.x -= u / t.mass, t.velocity.y -= b / t.mass, t.velocity.z -= x / t.mass;
920
+ const o = t.position.x - s.position.x, i = t.position.y - s.position.y, a = t.position.z - s.position.z, r = Math.sqrt(o * o + i * i + a * a);
921
+ if (r < 0.01) continue;
922
+ const d = (r - 15) * this.attractionStrength * this.alpha, g = o / r * d, u = i / r * d, y = a / r * d;
923
+ s.velocity.x += g / s.mass, s.velocity.y += u / s.mass, s.velocity.z += y / s.mass, t.velocity.x -= g / t.mass, t.velocity.y -= u / t.mass, t.velocity.z -= y / t.mass;
921
924
  }
922
925
  }
923
926
  /**
@@ -954,7 +957,7 @@ class Le {
954
957
  }
955
958
  class yt {
956
959
  constructor(e) {
957
- r(this, "root");
960
+ l(this, "root");
958
961
  const s = this.calculateBounds(e);
959
962
  this.root = this.buildTree(e, s);
960
963
  }
@@ -965,13 +968,13 @@ class yt {
965
968
  max: { x: 100, y: 100, z: 100 }
966
969
  };
967
970
  const s = { x: 1 / 0, y: 1 / 0, z: 1 / 0 }, t = { x: -1 / 0, y: -1 / 0, z: -1 / 0 };
968
- for (const o of e)
969
- s.x = Math.min(s.x, o.position.x), s.y = Math.min(s.y, o.position.y), s.z = Math.min(s.z, o.position.z), t.x = Math.max(t.x, o.position.x), t.y = Math.max(t.y, o.position.y), t.z = Math.max(t.z, o.position.z);
970
- const n = 10;
971
- return s.x -= n, s.y -= n, s.z -= n, t.x += n, t.y += n, t.z += n, { min: s, max: t };
971
+ for (const i of e)
972
+ s.x = Math.min(s.x, i.position.x), s.y = Math.min(s.y, i.position.y), s.z = Math.min(s.z, i.position.z), t.x = Math.max(t.x, i.position.x), t.y = Math.max(t.y, i.position.y), t.z = Math.max(t.z, i.position.z);
973
+ const o = 10;
974
+ return s.x -= o, s.y -= o, s.z -= o, t.x += o, t.y += o, t.z += o, { min: s, max: t };
972
975
  }
973
976
  buildTree(e, s, t = 0) {
974
- const n = Math.max(
977
+ const o = Math.max(
975
978
  s.max.x - s.min.x,
976
979
  s.max.y - s.min.y,
977
980
  s.max.z - s.min.z
@@ -979,7 +982,7 @@ class yt {
979
982
  if (e.length === 0)
980
983
  return {
981
984
  bounds: s,
982
- size: n,
985
+ size: o,
983
986
  centerOfMass: { x: 0, y: 0, z: 0 },
984
987
  mass: 0,
985
988
  isLeaf: !0,
@@ -988,70 +991,70 @@ class yt {
988
991
  };
989
992
  if (e.length === 1 || t > 20) {
990
993
  let f = 0;
991
- const m = { x: 0, y: 0, z: 0 };
992
- for (const M of e)
993
- f += M.mass, m.x += M.position.x * M.mass, m.y += M.position.y * M.mass, m.z += M.position.z * M.mass;
994
- return f > 0 && (m.x /= f, m.y /= f, m.z /= f), {
994
+ const x = { x: 0, y: 0, z: 0 };
995
+ for (const v of e)
996
+ f += v.mass, x.x += v.position.x * v.mass, x.y += v.position.y * v.mass, x.z += v.position.z * v.mass;
997
+ return f > 0 && (x.x /= f, x.y /= f, x.z /= f), {
995
998
  bounds: s,
996
- size: n,
997
- centerOfMass: m,
999
+ size: o,
1000
+ centerOfMass: x,
998
1001
  mass: f,
999
1002
  isLeaf: !0,
1000
1003
  node: e[0],
1001
1004
  children: []
1002
1005
  };
1003
1006
  }
1004
- const o = (s.min.x + s.max.x) / 2, a = (s.min.y + s.max.y) / 2, l = (s.min.z + s.max.z) / 2, h = [[], [], [], [], [], [], [], []];
1007
+ const i = (s.min.x + s.max.x) / 2, a = (s.min.y + s.max.y) / 2, r = (s.min.z + s.max.z) / 2, c = [[], [], [], [], [], [], [], []];
1005
1008
  for (const f of e) {
1006
- const m = (f.position.x >= o ? 1 : 0) + (f.position.y >= a ? 2 : 0) + (f.position.z >= l ? 4 : 0);
1007
- h[m].push(f);
1008
- }
1009
- const g = [
1010
- { min: { x: s.min.x, y: s.min.y, z: s.min.z }, max: { x: o, y: a, z: l } },
1011
- { min: { x: o, y: s.min.y, z: s.min.z }, max: { x: s.max.x, y: a, z: l } },
1012
- { min: { x: s.min.x, y: a, z: s.min.z }, max: { x: o, y: s.max.y, z: l } },
1013
- { min: { x: o, y: a, z: s.min.z }, max: { x: s.max.x, y: s.max.y, z: l } },
1014
- { min: { x: s.min.x, y: s.min.y, z: l }, max: { x: o, y: a, z: s.max.z } },
1015
- { min: { x: o, y: s.min.y, z: l }, max: { x: s.max.x, y: a, z: s.max.z } },
1016
- { min: { x: s.min.x, y: a, z: l }, max: { x: o, y: s.max.y, z: s.max.z } },
1017
- { min: { x: o, y: a, z: l }, max: { x: s.max.x, y: s.max.y, z: s.max.z } }
1018
- ], u = [];
1019
- let b = 0;
1020
- const x = { x: 0, y: 0, z: 0 };
1009
+ const x = (f.position.x >= i ? 1 : 0) + (f.position.y >= a ? 2 : 0) + (f.position.z >= r ? 4 : 0);
1010
+ c[x].push(f);
1011
+ }
1012
+ const d = [
1013
+ { min: { x: s.min.x, y: s.min.y, z: s.min.z }, max: { x: i, y: a, z: r } },
1014
+ { min: { x: i, y: s.min.y, z: s.min.z }, max: { x: s.max.x, y: a, z: r } },
1015
+ { min: { x: s.min.x, y: a, z: s.min.z }, max: { x: i, y: s.max.y, z: r } },
1016
+ { min: { x: i, y: a, z: s.min.z }, max: { x: s.max.x, y: s.max.y, z: r } },
1017
+ { min: { x: s.min.x, y: s.min.y, z: r }, max: { x: i, y: a, z: s.max.z } },
1018
+ { min: { x: i, y: s.min.y, z: r }, max: { x: s.max.x, y: a, z: s.max.z } },
1019
+ { min: { x: s.min.x, y: a, z: r }, max: { x: i, y: s.max.y, z: s.max.z } },
1020
+ { min: { x: i, y: a, z: r }, max: { x: s.max.x, y: s.max.y, z: s.max.z } }
1021
+ ], g = [];
1022
+ let u = 0;
1023
+ const y = { x: 0, y: 0, z: 0 };
1021
1024
  for (let f = 0; f < 8; f++)
1022
- if (h[f].length > 0) {
1023
- const m = this.buildTree(h[f], g[f], t + 1);
1024
- u.push(m), b += m.mass, x.x += m.centerOfMass.x * m.mass, x.y += m.centerOfMass.y * m.mass, x.z += m.centerOfMass.z * m.mass;
1025
+ if (c[f].length > 0) {
1026
+ const x = this.buildTree(c[f], d[f], t + 1);
1027
+ g.push(x), u += x.mass, y.x += x.centerOfMass.x * x.mass, y.y += x.centerOfMass.y * x.mass, y.z += x.centerOfMass.z * x.mass;
1025
1028
  } else
1026
- u.push(null);
1027
- return b > 0 && (x.x /= b, x.y /= b, x.z /= b), {
1029
+ g.push(null);
1030
+ return u > 0 && (y.x /= u, y.y /= u, y.z /= u), {
1028
1031
  bounds: s,
1029
- size: n,
1030
- centerOfMass: x,
1031
- mass: b,
1032
+ size: o,
1033
+ centerOfMass: y,
1034
+ mass: u,
1032
1035
  isLeaf: !1,
1033
1036
  node: null,
1034
- children: u
1037
+ children: g
1035
1038
  };
1036
1039
  }
1037
1040
  }
1038
- class bt {
1039
- constructor(e, s, t, n = 60) {
1040
- r(this, "sceneManager");
1041
- r(this, "animationId", null);
1042
- r(this, "isRunning", !1);
1043
- r(this, "frameInterval");
1044
- r(this, "lastFrameTime", 0);
1045
- r(this, "onSimulate");
1046
- r(this, "onRender");
1041
+ class xt {
1042
+ constructor(e, s, t, o = 60) {
1043
+ l(this, "sceneManager");
1044
+ l(this, "animationId", null);
1045
+ l(this, "isRunning", !1);
1046
+ l(this, "frameInterval");
1047
+ l(this, "lastFrameTime", 0);
1048
+ l(this, "onSimulate");
1049
+ l(this, "onRender");
1047
1050
  // Performance monitoring
1048
- r(this, "frameCount", 0);
1049
- r(this, "fpsStartTime", 0);
1050
- r(this, "currentFPS", 60);
1051
+ l(this, "frameCount", 0);
1052
+ l(this, "fpsStartTime", 0);
1053
+ l(this, "currentFPS", 60);
1051
1054
  /**
1052
1055
  * Main animation loop
1053
1056
  */
1054
- r(this, "animate", () => {
1057
+ l(this, "animate", () => {
1055
1058
  if (!this.isRunning) return;
1056
1059
  this.animationId = requestAnimationFrame(this.animate);
1057
1060
  const e = performance.now(), s = e - this.lastFrameTime;
@@ -1061,7 +1064,7 @@ class bt {
1061
1064
  const t = e - this.fpsStartTime;
1062
1065
  t >= 1e3 && (this.currentFPS = this.frameCount / (t / 1e3), this.frameCount = 0, this.fpsStartTime = e), this.onSimulate(), this.onRender(), this.sceneManager.render();
1063
1066
  });
1064
- this.sceneManager = e, this.onSimulate = s, this.onRender = t, this.frameInterval = 1e3 / n;
1067
+ this.sceneManager = e, this.onSimulate = s, this.onRender = t, this.frameInterval = 1e3 / o;
1065
1068
  }
1066
1069
  /**
1067
1070
  * Starts the animation loop
@@ -1100,12 +1103,12 @@ class bt {
1100
1103
  this.stop();
1101
1104
  }
1102
1105
  }
1103
- class xt {
1106
+ class bt {
1104
1107
  constructor() {
1105
- r(this, "envMap", null);
1106
- r(this, "materialCache", /* @__PURE__ */ new Map());
1108
+ l(this, "envMap", null);
1109
+ l(this, "materialCache", /* @__PURE__ */ new Map());
1107
1110
  // Color palette - white and tangerine
1108
- r(this, "COLORS", [
1111
+ l(this, "COLORS", [
1109
1112
  16777215,
1110
1113
  // White
1111
1114
  16750950,
@@ -1138,10 +1141,10 @@ class xt {
1138
1141
  { colors: ["#2d1a1a", "#1a0a0a", "#0f0505"] }
1139
1142
  // -z
1140
1143
  ];
1141
- for (const n of t) {
1142
- const o = document.createElement("canvas");
1143
- o.width = 256, o.height = 256;
1144
- const a = o.getContext("2d"), l = a.createRadialGradient(
1144
+ for (const o of t) {
1145
+ const i = document.createElement("canvas");
1146
+ i.width = 256, i.height = 256;
1147
+ const a = i.getContext("2d"), r = a.createRadialGradient(
1145
1148
  256 / 2,
1146
1149
  256 / 2,
1147
1150
  0,
@@ -1149,17 +1152,17 @@ class xt {
1149
1152
  256 / 2,
1150
1153
  256 * 0.8
1151
1154
  );
1152
- l.addColorStop(0, n.colors[0]), l.addColorStop(0.5, n.colors[1]), l.addColorStop(1, n.colors[2]), a.fillStyle = l, a.fillRect(0, 0, 256, 256);
1153
- const h = a.getImageData(0, 0, 256, 256);
1154
- for (let g = 0; g < h.data.length; g += 4) {
1155
- const u = (Math.random() - 0.5) * 5;
1156
- h.data[g] = Math.min(255, Math.max(0, h.data[g] + u)), h.data[g + 1] = Math.min(255, Math.max(0, h.data[g + 1] + u)), h.data[g + 2] = Math.min(255, Math.max(0, h.data[g + 2] + u));
1155
+ r.addColorStop(0, o.colors[0]), r.addColorStop(0.5, o.colors[1]), r.addColorStop(1, o.colors[2]), a.fillStyle = r, a.fillRect(0, 0, 256, 256);
1156
+ const c = a.getImageData(0, 0, 256, 256);
1157
+ for (let d = 0; d < c.data.length; d += 4) {
1158
+ const g = (Math.random() - 0.5) * 5;
1159
+ c.data[d] = Math.min(255, Math.max(0, c.data[d] + g)), c.data[d + 1] = Math.min(255, Math.max(0, c.data[d + 1] + g)), c.data[d + 2] = Math.min(255, Math.max(0, c.data[d + 2] + g));
1157
1160
  }
1158
- a.putImageData(h, 0, 0), s.push(o);
1161
+ a.putImageData(c, 0, 0), s.push(i);
1159
1162
  }
1160
- this.envMap = new p.CubeTexture(s.map((n) => {
1161
- const o = new Image();
1162
- return o.src = n.toDataURL(), o;
1163
+ this.envMap = new m.CubeTexture(s.map((o) => {
1164
+ const i = new Image();
1165
+ return i.src = o.toDataURL(), i;
1163
1166
  })), this.envMap.needsUpdate = !0;
1164
1167
  }
1165
1168
  /**
@@ -1176,11 +1179,11 @@ class xt {
1176
1179
  const t = "glass-single";
1177
1180
  if (this.materialCache.has(t))
1178
1181
  return this.materialCache.get(t).clone();
1179
- const n = new p.Color(16750950), o = new p.ShaderMaterial({
1182
+ const o = new m.Color(16750950), i = new m.ShaderMaterial({
1180
1183
  uniforms: {
1181
- uColor: { value: n },
1184
+ uColor: { value: o },
1182
1185
  uEnvMap: { value: this.envMap },
1183
- uGlowColor: { value: new p.Color(16777215) },
1186
+ uGlowColor: { value: new m.Color(16777215) },
1184
1187
  uGlowIntensity: { value: 0.8 },
1185
1188
  uReflectivity: { value: 0.4 },
1186
1189
  uFresnelPower: { value: 2.5 }
@@ -1246,17 +1249,17 @@ class xt {
1246
1249
  }
1247
1250
  `,
1248
1251
  transparent: !0,
1249
- side: p.FrontSide,
1252
+ side: m.FrontSide,
1250
1253
  depthWrite: !0,
1251
- blending: p.NormalBlending
1254
+ blending: m.NormalBlending
1252
1255
  });
1253
- return this.materialCache.set(t, o), o.clone();
1256
+ return this.materialCache.set(t, i), i.clone();
1254
1257
  }
1255
1258
  /**
1256
1259
  * Creates material for edges (light color for dark background)
1257
1260
  */
1258
1261
  createEdgeMaterial(e = 6710886, s = 0.4) {
1259
- return new p.LineBasicMaterial({
1262
+ return new m.LineBasicMaterial({
1260
1263
  color: e,
1261
1264
  transparent: !0,
1262
1265
  opacity: s,
@@ -1267,7 +1270,7 @@ class xt {
1267
1270
  * Creates highlighted edge material
1268
1271
  */
1269
1272
  createHighlightedEdgeMaterial() {
1270
- return new p.LineBasicMaterial({
1273
+ return new m.LineBasicMaterial({
1271
1274
  color: 16750950,
1272
1275
  // Tangerine highlight
1273
1276
  transparent: !1,
@@ -1279,13 +1282,13 @@ class xt {
1279
1282
  * Creates a sprite material for labels (light text for dark background)
1280
1283
  */
1281
1284
  createLabelMaterial(e, s = 24) {
1282
- const t = document.createElement("canvas"), n = t.getContext("2d");
1283
- n.font = `600 ${s}px Inter, -apple-system, sans-serif`;
1284
- const a = n.measureText(e).width;
1285
- t.width = Math.max(128, a + 24), t.height = s + 20, n.clearRect(0, 0, t.width, t.height), n.font = `600 ${s}px Inter, -apple-system, sans-serif`, n.textAlign = "center", n.textBaseline = "middle", n.shadowColor = "rgba(0, 0, 0, 0.8)", n.shadowBlur = 4, n.shadowOffsetX = 1, n.shadowOffsetY = 1, n.fillStyle = "rgba(255, 255, 255, 0.95)", n.fillText(e, t.width / 2, t.height / 2);
1286
- const l = new p.CanvasTexture(t);
1287
- return l.needsUpdate = !0, new p.SpriteMaterial({
1288
- map: l,
1285
+ const t = document.createElement("canvas"), o = t.getContext("2d");
1286
+ o.font = `600 ${s}px Inter, -apple-system, sans-serif`;
1287
+ const a = o.measureText(e).width;
1288
+ t.width = Math.max(128, a + 24), t.height = s + 20, o.clearRect(0, 0, t.width, t.height), o.font = `600 ${s}px Inter, -apple-system, sans-serif`, o.textAlign = "center", o.textBaseline = "middle", o.shadowColor = "rgba(0, 0, 0, 0.8)", o.shadowBlur = 4, o.shadowOffsetX = 1, o.shadowOffsetY = 1, o.fillStyle = "rgba(255, 255, 255, 0.95)", o.fillText(e, t.width / 2, t.height / 2);
1289
+ const r = new m.CanvasTexture(t);
1290
+ return r.needsUpdate = !0, new m.SpriteMaterial({
1291
+ map: r,
1289
1292
  transparent: !0,
1290
1293
  depthTest: !1,
1291
1294
  depthWrite: !1
@@ -1305,12 +1308,13 @@ class xt {
1305
1308
  }
1306
1309
  }
1307
1310
  class vt {
1308
- constructor(e, s = 2, t = [32, 16, 8]) {
1309
- r(this, "materialFactory");
1310
- r(this, "geometryCache", /* @__PURE__ */ new Map());
1311
- r(this, "nodeRadius");
1312
- r(this, "lodSegments");
1313
- this.materialFactory = e, this.nodeRadius = s, this.lodSegments = t, this.initGeometryCache();
1311
+ constructor(e, s = 2, t = [32, 16, 8], o = 16750950) {
1312
+ l(this, "materialFactory");
1313
+ l(this, "geometryCache", /* @__PURE__ */ new Map());
1314
+ l(this, "nodeRadius");
1315
+ l(this, "lodSegments");
1316
+ l(this, "defaultNodeColor");
1317
+ this.materialFactory = e, this.nodeRadius = s, this.lodSegments = t, this.defaultNodeColor = o, this.initGeometryCache();
1314
1318
  }
1315
1319
  /**
1316
1320
  * Pre-create geometries for each LOD level
@@ -1320,7 +1324,7 @@ class vt {
1320
1324
  const t = `lod-${s}`;
1321
1325
  this.geometryCache.set(
1322
1326
  t,
1323
- new p.SphereGeometry(this.nodeRadius, e, e)
1327
+ new m.SphereGeometry(this.nodeRadius, e, e)
1324
1328
  );
1325
1329
  });
1326
1330
  }
@@ -1335,21 +1339,21 @@ class vt {
1335
1339
  * Creates a node visual (glass ball + label)
1336
1340
  */
1337
1341
  createNode(e, s = 0) {
1338
- const t = new p.Group();
1342
+ const t = new m.Group();
1339
1343
  t.name = `node-${e.id}`, t.userData = { nodeId: e.id, nodeData: e };
1340
- const n = this.getGeometry(s), o = this.materialFactory.createGlassMaterial(
1341
- e.color ?? 4886754
1342
- ), a = new p.Mesh(n, o);
1344
+ const o = this.getGeometry(s), i = this.materialFactory.createGlassMaterial(
1345
+ e.color ?? this.defaultNodeColor
1346
+ ), a = new m.Mesh(o, i);
1343
1347
  a.castShadow = !0, a.receiveShadow = !0, t.add(a);
1344
- const l = this.materialFactory.createLabelMaterial(e.label), h = new p.Sprite(l);
1345
- return h.position.y = this.nodeRadius + 1.5, h.scale.set(4, 1, 1), t.add(h), e.position && t.position.set(
1348
+ const r = this.materialFactory.createLabelMaterial(e.label), c = new m.Sprite(r);
1349
+ return c.position.y = this.nodeRadius + 1.5, c.scale.set(4, 1, 1), t.add(c), e.position && t.position.set(
1346
1350
  e.position.x,
1347
1351
  e.position.y,
1348
1352
  e.position.z
1349
1353
  ), {
1350
1354
  group: t,
1351
1355
  sphere: a,
1352
- label: h,
1356
+ label: c,
1353
1357
  lodLevel: s
1354
1358
  };
1355
1359
  }
@@ -1365,19 +1369,19 @@ class vt {
1365
1369
  * Updates the color of a node
1366
1370
  */
1367
1371
  updateNodeColor(e, s) {
1368
- e.sphere.material instanceof p.Material && e.sphere.material.dispose(), e.sphere.material = this.materialFactory.createGlassMaterial(s);
1372
+ e.sphere.material instanceof m.Material && e.sphere.material.dispose(), e.sphere.material = this.materialFactory.createGlassMaterial(s);
1369
1373
  }
1370
1374
  /**
1371
1375
  * Updates the label of a node
1372
1376
  */
1373
1377
  updateNodeLabel(e, s) {
1374
- e.label.material instanceof p.SpriteMaterial && (e.label.material.map && e.label.material.map.dispose(), e.label.material.dispose()), e.label.material = this.materialFactory.createLabelMaterial(s);
1378
+ e.label.material instanceof m.SpriteMaterial && (e.label.material.map && e.label.material.map.dispose(), e.label.material.dispose()), e.label.material = this.materialFactory.createLabelMaterial(s);
1375
1379
  }
1376
1380
  /**
1377
1381
  * Disposes a node's resources
1378
1382
  */
1379
1383
  disposeNode(e) {
1380
- e.sphere.material instanceof p.Material && e.sphere.material.dispose(), e.label.material instanceof p.SpriteMaterial && (e.label.material.map && e.label.material.map.dispose(), e.label.material.dispose());
1384
+ e.sphere.material instanceof m.Material && e.sphere.material.dispose(), e.label.material instanceof m.SpriteMaterial && (e.label.material.map && e.label.material.map.dispose(), e.label.material.dispose());
1381
1385
  }
1382
1386
  /**
1383
1387
  * Dispose factory resources
@@ -1388,11 +1392,11 @@ class vt {
1388
1392
  }
1389
1393
  class Mt {
1390
1394
  constructor(e, s = 10066329, t = 0.5) {
1391
- r(this, "materialFactory");
1392
- r(this, "edgeColor");
1393
- r(this, "edgeOpacity");
1394
- r(this, "defaultMaterial", null);
1395
- r(this, "highlightMaterial", null);
1395
+ l(this, "materialFactory");
1396
+ l(this, "edgeColor");
1397
+ l(this, "edgeOpacity");
1398
+ l(this, "defaultMaterial", null);
1399
+ l(this, "highlightMaterial", null);
1396
1400
  this.materialFactory = e, this.edgeColor = s, this.edgeOpacity = t;
1397
1401
  }
1398
1402
  /**
@@ -1413,25 +1417,25 @@ class Mt {
1413
1417
  /**
1414
1418
  * Creates an edge line between two positions
1415
1419
  */
1416
- createEdge(e, s, t, n, o) {
1417
- const a = new p.BufferGeometry(), l = new Float32Array([
1418
- n.x,
1419
- n.y,
1420
- n.z,
1420
+ createEdge(e, s, t, o, i) {
1421
+ const a = new m.BufferGeometry(), r = new Float32Array([
1421
1422
  o.x,
1422
1423
  o.y,
1423
- o.z
1424
+ o.z,
1425
+ i.x,
1426
+ i.y,
1427
+ i.z
1424
1428
  ]);
1425
- a.setAttribute("position", new p.BufferAttribute(l, 3));
1426
- const h = this.getDefaultMaterial().clone(), g = new p.Line(a, h);
1427
- return g.name = `edge-${e.source}-${e.target}`, g.userData = {
1429
+ a.setAttribute("position", new m.BufferAttribute(r, 3));
1430
+ const c = this.getDefaultMaterial().clone(), d = new m.Line(a, c);
1431
+ return d.name = `edge-${e.source}-${e.target}`, d.userData = {
1428
1432
  source: e.source,
1429
1433
  target: e.target,
1430
1434
  edge: e,
1431
1435
  sourceNode: s,
1432
1436
  targetNode: t
1433
- }, g.frustumCulled = !0, {
1434
- line: g,
1437
+ }, d.frustumCulled = !0, {
1438
+ line: d,
1435
1439
  source: e.source,
1436
1440
  target: e.target
1437
1441
  };
@@ -1440,26 +1444,26 @@ class Mt {
1440
1444
  * Highlights an edge
1441
1445
  */
1442
1446
  highlightEdge(e) {
1443
- e.line.material instanceof p.Material && e.line.material.dispose(), e.line.material = this.getHighlightMaterial().clone();
1447
+ e.line.material instanceof m.Material && e.line.material.dispose(), e.line.material = this.getHighlightMaterial().clone();
1444
1448
  }
1445
1449
  /**
1446
1450
  * Resets an edge to default appearance
1447
1451
  */
1448
1452
  unhighlightEdge(e) {
1449
- e.line.material instanceof p.Material && e.line.material.dispose(), e.line.material = this.getDefaultMaterial().clone();
1453
+ e.line.material instanceof m.Material && e.line.material.dispose(), e.line.material = this.getDefaultMaterial().clone();
1450
1454
  }
1451
1455
  /**
1452
1456
  * Updates an edge's positions
1453
1457
  */
1454
1458
  updateEdgePositions(e, s, t) {
1455
- const n = e.line.geometry.attributes.position, o = n.array;
1456
- o[0] = s.x, o[1] = s.y, o[2] = s.z, o[3] = t.x, o[4] = t.y, o[5] = t.z, n.needsUpdate = !0, e.line.geometry.computeBoundingSphere();
1459
+ const o = e.line.geometry.attributes.position, i = o.array;
1460
+ i[0] = s.x, i[1] = s.y, i[2] = s.z, i[3] = t.x, i[4] = t.y, i[5] = t.z, o.needsUpdate = !0, e.line.geometry.computeBoundingSphere();
1457
1461
  }
1458
1462
  /**
1459
1463
  * Disposes an edge's resources
1460
1464
  */
1461
1465
  disposeEdge(e) {
1462
- e.line.geometry.dispose(), e.line.material instanceof p.Material && e.line.material.dispose();
1466
+ e.line.geometry.dispose(), e.line.material instanceof m.Material && e.line.material.dispose();
1463
1467
  }
1464
1468
  /**
1465
1469
  * Dispose factory resources
@@ -1470,9 +1474,9 @@ class Mt {
1470
1474
  }
1471
1475
  class wt {
1472
1476
  constructor(e, s = [50, 100, 200], t = !0) {
1473
- r(this, "camera");
1474
- r(this, "lodDistances");
1475
- r(this, "enabled");
1477
+ l(this, "camera");
1478
+ l(this, "lodDistances");
1479
+ l(this, "enabled");
1476
1480
  this.camera = e, this.lodDistances = s, this.enabled = t;
1477
1481
  }
1478
1482
  /**
@@ -1480,16 +1484,16 @@ class wt {
1480
1484
  */
1481
1485
  getLODLevel(e) {
1482
1486
  if (!this.enabled)
1483
- return X.HIGH;
1484
- const s = e.x - this.camera.position.x, t = e.y - this.camera.position.y, n = e.z - this.camera.position.z, o = Math.sqrt(s * s + t * t + n * n);
1485
- return o < this.lodDistances[0] ? X.HIGH : o < this.lodDistances[1] ? X.MEDIUM : X.LOW;
1487
+ return U.HIGH;
1488
+ const s = e.x - this.camera.position.x, t = e.y - this.camera.position.y, o = e.z - this.camera.position.z, i = Math.sqrt(s * s + t * t + o * o);
1489
+ return i < this.lodDistances[0] ? U.HIGH : i < this.lodDistances[1] ? U.MEDIUM : U.LOW;
1486
1490
  }
1487
1491
  /**
1488
1492
  * Checks if a node should be visible based on distance
1489
1493
  */
1490
1494
  shouldRenderNode(e, s = 500) {
1491
- const t = e.x - this.camera.position.x, n = e.y - this.camera.position.y, o = e.z - this.camera.position.z;
1492
- return Math.sqrt(t * t + n * n + o * o) < s;
1495
+ const t = e.x - this.camera.position.x, o = e.y - this.camera.position.y, i = e.z - this.camera.position.z;
1496
+ return Math.sqrt(t * t + o * o + i * i) < s;
1493
1497
  }
1494
1498
  /**
1495
1499
  * Sets the LOD distances
@@ -1506,11 +1510,11 @@ class wt {
1506
1510
  }
1507
1511
  class Et {
1508
1512
  constructor(e, s = !0) {
1509
- r(this, "camera");
1510
- r(this, "frustum");
1511
- r(this, "projScreenMatrix");
1512
- r(this, "enabled");
1513
- this.camera = e, this.frustum = new p.Frustum(), this.projScreenMatrix = new p.Matrix4(), this.enabled = s;
1513
+ l(this, "camera");
1514
+ l(this, "frustum");
1515
+ l(this, "projScreenMatrix");
1516
+ l(this, "enabled");
1517
+ this.camera = e, this.frustum = new m.Frustum(), this.projScreenMatrix = new m.Matrix4(), this.enabled = s;
1514
1518
  }
1515
1519
  /**
1516
1520
  * Updates the frustum from the camera
@@ -1526,7 +1530,7 @@ class Et {
1526
1530
  */
1527
1531
  isPointVisible(e) {
1528
1532
  if (!this.enabled) return !0;
1529
- const s = new p.Vector3(e.x, e.y, e.z);
1533
+ const s = new m.Vector3(e.x, e.y, e.z);
1530
1534
  return this.frustum.containsPoint(s);
1531
1535
  }
1532
1536
  /**
@@ -1534,8 +1538,8 @@ class Et {
1534
1538
  */
1535
1539
  isSphereVisible(e, s) {
1536
1540
  if (!this.enabled) return !0;
1537
- const t = new p.Sphere(
1538
- new p.Vector3(e.x, e.y, e.z),
1541
+ const t = new m.Sphere(
1542
+ new m.Vector3(e.x, e.y, e.z),
1539
1543
  s
1540
1544
  );
1541
1545
  return this.frustum.intersectsSphere(t);
@@ -1545,15 +1549,15 @@ class Et {
1545
1549
  */
1546
1550
  isLineVisible(e, s) {
1547
1551
  if (!this.enabled) return !0;
1548
- const t = new p.Vector3(e.x, e.y, e.z), n = new p.Vector3(s.x, s.y, s.z);
1549
- if (this.frustum.containsPoint(t) || this.frustum.containsPoint(n))
1552
+ const t = new m.Vector3(e.x, e.y, e.z), o = new m.Vector3(s.x, s.y, s.z);
1553
+ if (this.frustum.containsPoint(t) || this.frustum.containsPoint(o))
1550
1554
  return !0;
1551
- const o = new p.Vector3(
1555
+ const i = new m.Vector3(
1552
1556
  (e.x + s.x) / 2,
1553
1557
  (e.y + s.y) / 2,
1554
1558
  (e.z + s.z) / 2
1555
- ), a = o.distanceTo(t), l = new p.Sphere(o, a);
1556
- return this.frustum.intersectsSphere(l);
1559
+ ), a = i.distanceTo(t), r = new m.Sphere(i, a);
1560
+ return this.frustum.intersectsSphere(r);
1557
1561
  }
1558
1562
  /**
1559
1563
  * Enables/disables frustum culling
@@ -1564,19 +1568,19 @@ class Et {
1564
1568
  }
1565
1569
  class Ct {
1566
1570
  constructor(e, s) {
1567
- r(this, "sceneManager");
1568
- r(this, "raycaster");
1569
- r(this, "mouse");
1570
- r(this, "container");
1571
- r(this, "onNodeClick", null);
1572
- r(this, "onNodeHover", null);
1573
- r(this, "onEdgeHover", null);
1574
- r(this, "onEdgeClick", null);
1575
- r(this, "hoveredNodeId", null);
1576
- r(this, "hoveredEdgeKey", null);
1577
- r(this, "nodeObjects", []);
1578
- r(this, "edgeObjects", []);
1579
- this.sceneManager = e, this.container = s, this.raycaster = new p.Raycaster(), this.raycaster.params.Line = { threshold: 0.5 }, this.mouse = new p.Vector2(), this.handleClick = this.handleClick.bind(this), this.handleMouseMove = this.handleMouseMove.bind(this), s.addEventListener("click", this.handleClick), s.addEventListener("mousemove", this.handleMouseMove);
1571
+ l(this, "sceneManager");
1572
+ l(this, "raycaster");
1573
+ l(this, "mouse");
1574
+ l(this, "container");
1575
+ l(this, "onNodeClick", null);
1576
+ l(this, "onNodeHover", null);
1577
+ l(this, "onEdgeHover", null);
1578
+ l(this, "onEdgeClick", null);
1579
+ l(this, "hoveredNodeId", null);
1580
+ l(this, "hoveredEdgeKey", null);
1581
+ l(this, "nodeObjects", []);
1582
+ l(this, "edgeObjects", []);
1583
+ this.sceneManager = e, this.container = s, this.raycaster = new m.Raycaster(), this.raycaster.params.Line = { threshold: 0.5 }, this.mouse = new m.Vector2(), this.handleClick = this.handleClick.bind(this), this.handleMouseMove = this.handleMouseMove.bind(this), s.addEventListener("click", this.handleClick), s.addEventListener("mousemove", this.handleMouseMove);
1580
1584
  }
1581
1585
  /**
1582
1586
  * Updates the list of node objects to raycast against
@@ -1635,23 +1639,23 @@ class Ct {
1635
1639
  this.hoveredEdgeKey !== null && this.onEdgeHover && (this.hoveredEdgeKey = null, this.onEdgeHover(null)), this.container.style.cursor = "pointer";
1636
1640
  return;
1637
1641
  }
1638
- const n = this.getIntersectedEdge(e), o = n ? `${n.edge.source}-${n.edge.target}` : null;
1639
- o !== this.hoveredEdgeKey && (this.hoveredEdgeKey = o, this.onEdgeHover && this.onEdgeHover(n)), this.container.style.cursor = n ? "pointer" : "default";
1642
+ const o = this.getIntersectedEdge(e), i = o ? `${o.edge.source}-${o.edge.target}` : null;
1643
+ i !== this.hoveredEdgeKey && (this.hoveredEdgeKey = i, this.onEdgeHover && this.onEdgeHover(o)), this.container.style.cursor = o ? "pointer" : "default";
1640
1644
  }
1641
1645
  /**
1642
1646
  * Gets the intersected node from a mouse event
1643
1647
  */
1644
1648
  getIntersectedNode(e) {
1645
- var n;
1649
+ var o;
1646
1650
  const s = this.container.getBoundingClientRect();
1647
1651
  this.mouse.x = (e.clientX - s.left) / s.width * 2 - 1, this.mouse.y = -((e.clientY - s.top) / s.height) * 2 + 1, this.raycaster.setFromCamera(this.mouse, this.sceneManager.camera);
1648
1652
  const t = this.raycaster.intersectObjects(this.nodeObjects, !0);
1649
1653
  if (t.length > 0) {
1650
- let o = t[0].object;
1651
- for (; o; ) {
1652
- if ((n = o.userData) != null && n.nodeData)
1653
- return o.userData.nodeData;
1654
- o = o.parent;
1654
+ let i = t[0].object;
1655
+ for (; i; ) {
1656
+ if ((o = i.userData) != null && o.nodeData)
1657
+ return i.userData.nodeData;
1658
+ i = i.parent;
1655
1659
  }
1656
1660
  }
1657
1661
  return null;
@@ -1664,13 +1668,13 @@ class Ct {
1664
1668
  this.mouse.x = (e.clientX - s.left) / s.width * 2 - 1, this.mouse.y = -((e.clientY - s.top) / s.height) * 2 + 1, this.raycaster.setFromCamera(this.mouse, this.sceneManager.camera);
1665
1669
  const t = this.raycaster.intersectObjects(this.edgeObjects, !1);
1666
1670
  if (t.length > 0) {
1667
- const n = t[0].object, o = n.userData;
1668
- if (o != null && o.edge && (o != null && o.sourceNode) && (o != null && o.targetNode))
1671
+ const o = t[0].object, i = o.userData;
1672
+ if (i != null && i.edge && (i != null && i.sourceNode) && (i != null && i.targetNode))
1669
1673
  return {
1670
- edge: o.edge,
1671
- sourceNode: o.sourceNode,
1672
- targetNode: o.targetNode,
1673
- edgeLine: n
1674
+ edge: i.edge,
1675
+ sourceNode: i.sourceNode,
1676
+ targetNode: i.targetNode,
1677
+ edgeLine: o
1674
1678
  };
1675
1679
  }
1676
1680
  return null;
@@ -1679,14 +1683,14 @@ class Ct {
1679
1683
  * Performs a raycast and returns the intersected node ID
1680
1684
  */
1681
1685
  getIntersectedNodeId(e, s) {
1682
- var o;
1686
+ var i;
1683
1687
  const t = this.container.getBoundingClientRect();
1684
1688
  this.mouse.x = (e - t.left) / t.width * 2 - 1, this.mouse.y = -((s - t.top) / t.height) * 2 + 1, this.raycaster.setFromCamera(this.mouse, this.sceneManager.camera);
1685
- const n = this.raycaster.intersectObjects(this.nodeObjects, !0);
1686
- if (n.length > 0) {
1687
- let a = n[0].object;
1689
+ const o = this.raycaster.intersectObjects(this.nodeObjects, !0);
1690
+ if (o.length > 0) {
1691
+ let a = o[0].object;
1688
1692
  for (; a; ) {
1689
- if ((o = a.userData) != null && o.nodeId)
1693
+ if ((i = a.userData) != null && i.nodeId)
1690
1694
  return a.userData.nodeId;
1691
1695
  a = a.parent;
1692
1696
  }
@@ -1700,15 +1704,15 @@ class Ct {
1700
1704
  this.container.removeEventListener("click", this.handleClick), this.container.removeEventListener("mousemove", this.handleMouseMove);
1701
1705
  }
1702
1706
  }
1703
- class zt {
1707
+ class Nt {
1704
1708
  constructor(e) {
1705
- r(this, "container");
1706
- r(this, "panel", null);
1707
- r(this, "currentNodeId", null);
1708
- r(this, "visible", !1);
1709
- r(this, "panelTemplate", null);
1710
- r(this, "panelStyles", {});
1711
- r(this, "onExpand", null);
1709
+ l(this, "container");
1710
+ l(this, "panel", null);
1711
+ l(this, "currentNodeId", null);
1712
+ l(this, "visible", !1);
1713
+ l(this, "panelTemplate", null);
1714
+ l(this, "panelStyles", {});
1715
+ l(this, "onExpand", null);
1712
1716
  this.container = e, this.createPanel();
1713
1717
  }
1714
1718
  /**
@@ -1770,11 +1774,11 @@ class zt {
1770
1774
  this.currentNodeId = e.id;
1771
1775
  let t;
1772
1776
  this.panelTemplate ? t = this.panelTemplate(e, s) : t = this.generateDefaultContent(e, s), this.panel.innerHTML = t;
1773
- const n = this.panel.querySelector('[data-action="expand"]'), o = this.panel.querySelector("[data-depth-select]");
1774
- n && this.onExpand && n.addEventListener("click", () => {
1777
+ const o = this.panel.querySelector('[data-action="expand"]'), i = this.panel.querySelector("[data-depth-select]");
1778
+ o && this.onExpand && o.addEventListener("click", () => {
1775
1779
  if (this.currentNodeId) {
1776
- const l = o ? parseInt(o.value, 10) : 1;
1777
- this.onExpand(this.currentNodeId, l);
1780
+ const r = i ? parseInt(i.value, 10) : 1;
1781
+ this.onExpand(this.currentNodeId, r);
1778
1782
  }
1779
1783
  });
1780
1784
  const a = this.panel.querySelector('[data-action="close"]');
@@ -1932,7 +1936,7 @@ class zt {
1932
1936
  <div class="neighbors-section">
1933
1937
  <div class="neighbors-title">Connected To</div>
1934
1938
  ${s.slice(0, 5).map(
1935
- (n) => `<span class="neighbor-chip">${this.escapeHtml(n.label)}</span>`
1939
+ (o) => `<span class="neighbor-chip">${this.escapeHtml(o.label)}</span>`
1936
1940
  ).join("")}
1937
1941
  ${s.length > 5 ? `<span class="neighbor-chip">+${s.length - 5} more</span>` : ""}
1938
1942
  </div>
@@ -1986,15 +1990,15 @@ class zt {
1986
1990
  this.panel && this.panel.parentNode && this.panel.parentNode.removeChild(this.panel), this.panel = null;
1987
1991
  }
1988
1992
  }
1989
- class Nt {
1993
+ class St {
1990
1994
  constructor(e) {
1991
- r(this, "container");
1992
- r(this, "panel", null);
1993
- r(this, "currentEdgeKey", null);
1994
- r(this, "visible", !1);
1995
- r(this, "panelTemplate", null);
1996
- r(this, "onClose", null);
1997
- r(this, "onNodeClick", null);
1995
+ l(this, "container");
1996
+ l(this, "panel", null);
1997
+ l(this, "currentEdgeKey", null);
1998
+ l(this, "visible", !1);
1999
+ l(this, "panelTemplate", null);
2000
+ l(this, "onClose", null);
2001
+ l(this, "onNodeClick", null);
1998
2002
  this.container = e, this.createPanel();
1999
2003
  }
2000
2004
  /**
@@ -2050,18 +2054,18 @@ class Nt {
2050
2054
  show(e, s, t) {
2051
2055
  if (!this.panel) return;
2052
2056
  this.currentEdgeKey = `${e.source}-${e.target}`;
2053
- let n;
2054
- this.panelTemplate ? n = this.panelTemplate(e, s, t) : n = this.generateDefaultContent(e, s, t), this.panel.innerHTML = n;
2055
- const o = this.panel.querySelector('[data-action="close"]');
2056
- o && o.addEventListener("click", () => {
2057
+ let o;
2058
+ this.panelTemplate ? o = this.panelTemplate(e, s, t) : o = this.generateDefaultContent(e, s, t), this.panel.innerHTML = o;
2059
+ const i = this.panel.querySelector('[data-action="close"]');
2060
+ i && i.addEventListener("click", () => {
2057
2061
  this.hide(), this.onClose && this.onClose();
2058
2062
  });
2059
2063
  const a = this.panel.querySelector('[data-action="goto-source"]');
2060
2064
  a && this.onNodeClick && a.addEventListener("click", () => {
2061
2065
  this.onNodeClick && this.onNodeClick(e.source);
2062
2066
  });
2063
- const l = this.panel.querySelector('[data-action="goto-target"]');
2064
- l && this.onNodeClick && l.addEventListener("click", () => {
2067
+ const r = this.panel.querySelector('[data-action="goto-target"]');
2068
+ r && this.onNodeClick && r.addEventListener("click", () => {
2065
2069
  this.onNodeClick && this.onNodeClick(e.target);
2066
2070
  }), this.panel.style.opacity = "1", this.panel.style.pointerEvents = "auto", this.panel.style.transform = "translateY(-50%) translateX(0)", this.visible = !0;
2067
2071
  }
@@ -2069,7 +2073,7 @@ class Nt {
2069
2073
  * Generates default panel content
2070
2074
  */
2071
2075
  generateDefaultContent(e, s, t) {
2072
- const n = s.color ? `#${s.color.toString(16).padStart(6, "0")}` : "#ff9966", o = t.color ? `#${t.color.toString(16).padStart(6, "0")}` : "#ff9966", a = e.relationship || "connected to";
2076
+ const o = s.color ? `#${s.color.toString(16).padStart(6, "0")}` : "#ff9966", i = t.color ? `#${t.color.toString(16).padStart(6, "0")}` : "#ff9966", a = e.relationship || "connected to";
2073
2077
  return `
2074
2078
  <style>
2075
2079
  .force-graph-edge-panel .panel-header {
@@ -2179,7 +2183,7 @@ class Nt {
2179
2183
  <div class="node-card" data-action="goto-source" title="Click to focus on ${this.escapeHtml(s.label)}">
2180
2184
  <div class="node-type">Source</div>
2181
2185
  <div class="node-card-header">
2182
- <span class="color-dot" style="background: ${n}; box-shadow: 0 0 8px ${n}80;"></span>
2186
+ <span class="color-dot" style="background: ${o}; box-shadow: 0 0 8px ${o}80;"></span>
2183
2187
  <span class="node-label">${this.escapeHtml(s.label)}</span>
2184
2188
  </div>
2185
2189
  </div>
@@ -2189,7 +2193,7 @@ class Nt {
2189
2193
  <div class="node-card" data-action="goto-target" title="Click to focus on ${this.escapeHtml(t.label)}">
2190
2194
  <div class="node-type">Target</div>
2191
2195
  <div class="node-card-header">
2192
- <span class="color-dot" style="background: ${o}; box-shadow: 0 0 8px ${o}80;"></span>
2196
+ <span class="color-dot" style="background: ${i}; box-shadow: 0 0 8px ${i}80;"></span>
2193
2197
  <span class="node-label">${this.escapeHtml(t.label)}</span>
2194
2198
  </div>
2195
2199
  </div>
@@ -2231,10 +2235,10 @@ class Nt {
2231
2235
  this.panel && this.panel.parentNode && this.panel.parentNode.removeChild(this.panel), this.panel = null;
2232
2236
  }
2233
2237
  }
2234
- class St {
2238
+ class zt {
2235
2239
  constructor() {
2236
- r(this, "tooltip", null);
2237
- r(this, "visible", !1);
2240
+ l(this, "tooltip", null);
2241
+ l(this, "visible", !1);
2238
2242
  this.createTooltip(), this.setupMouseTracking();
2239
2243
  }
2240
2244
  /**
@@ -2277,14 +2281,14 @@ class St {
2277
2281
  */
2278
2282
  positionTooltip(e, s) {
2279
2283
  if (!this.tooltip) return;
2280
- const t = this.tooltip.getBoundingClientRect(), n = window.innerWidth, o = window.innerHeight;
2281
- let a = e + 15, l = s + 15;
2282
- a + t.width > n - 10 && (a = e - t.width - 15), l + t.height > o - 10 && (l = s - t.height - 15), a < 10 && (a = 10), l < 10 && (l = 10), this.tooltip.style.left = `${a}px`, this.tooltip.style.top = `${l}px`;
2284
+ const t = this.tooltip.getBoundingClientRect(), o = window.innerWidth, i = window.innerHeight;
2285
+ let a = e + 15, r = s + 15;
2286
+ a + t.width > o - 10 && (a = e - t.width - 15), r + t.height > i - 10 && (r = s - t.height - 15), a < 10 && (a = 10), r < 10 && (r = 10), this.tooltip.style.left = `${a}px`, this.tooltip.style.top = `${r}px`;
2283
2287
  }
2284
2288
  /**
2285
2289
  * Shows the tooltip with edge info
2286
2290
  */
2287
- show(e, s, t, n, o) {
2291
+ show(e, s, t, o, i) {
2288
2292
  if (!this.tooltip) return;
2289
2293
  const a = e.relationship || "connected to";
2290
2294
  this.tooltip.innerHTML = `
@@ -2299,7 +2303,7 @@ class St {
2299
2303
  <span style="font-weight: 600; color: #ff9966;">${this.escapeHtml(t.label)}</span>
2300
2304
  </div>
2301
2305
  </div>
2302
- `, this.positionTooltip(n, o), this.tooltip.style.opacity = "1", this.tooltip.style.transform = "translateY(0)", this.visible = !0;
2306
+ `, this.positionTooltip(o, i), this.tooltip.style.opacity = "1", this.tooltip.style.transform = "translateY(0)", this.visible = !0;
2303
2307
  }
2304
2308
  /**
2305
2309
  * Updates tooltip position (called externally on mouse move)
@@ -2335,14 +2339,14 @@ class St {
2335
2339
  }
2336
2340
  class kt {
2337
2341
  constructor(e, s) {
2338
- r(this, "container");
2339
- r(this, "searchContainer", null);
2340
- r(this, "searchInput", null);
2341
- r(this, "searchResults", null);
2342
- r(this, "searchTimeout", null);
2343
- r(this, "placeholder");
2344
- r(this, "onSearch");
2345
- r(this, "onResultClick");
2342
+ l(this, "container");
2343
+ l(this, "searchContainer", null);
2344
+ l(this, "searchInput", null);
2345
+ l(this, "searchResults", null);
2346
+ l(this, "searchTimeout", null);
2347
+ l(this, "placeholder");
2348
+ l(this, "onSearch");
2349
+ l(this, "onResultClick");
2346
2350
  this.container = e, this.placeholder = s.placeholder || "Search nodes or relationships...", this.onSearch = s.onSearch, this.onResultClick = s.onResultClick, this.init();
2347
2351
  }
2348
2352
  init() {
@@ -2352,7 +2356,8 @@ class kt {
2352
2356
  this.searchContainer = document.createElement("div"), this.searchContainer.className = "f3d-search-container", Object.assign(this.searchContainer.style, {
2353
2357
  position: "absolute",
2354
2358
  top: "20px",
2355
- left: "20px",
2359
+ left: "175px",
2360
+ // Adjusted to make room for view toggle
2356
2361
  zIndex: "100",
2357
2362
  width: "320px"
2358
2363
  });
@@ -2475,25 +2480,25 @@ class kt {
2475
2480
  this.searchResults.innerHTML = '<div class="f3d-no-results">No results found</div>', this.searchResults.style.display = "block";
2476
2481
  return;
2477
2482
  }
2478
- let n = "";
2479
- s.length > 0 && (n += '<div class="f3d-search-section-header">Nodes</div>', s.slice(0, 10).forEach((o) => {
2480
- const a = o.type || "Node";
2481
- n += `
2482
- <div class="f3d-search-result-item" data-node-id="${this.escapeHtml(o.id)}">
2483
- <div class="f3d-result-label">${this.escapeHtml(o.label)}</div>
2483
+ let o = "";
2484
+ s.length > 0 && (o += '<div class="f3d-search-section-header">Nodes</div>', s.slice(0, 10).forEach((i) => {
2485
+ const a = i.type || "Node";
2486
+ o += `
2487
+ <div class="f3d-search-result-item" data-node-id="${this.escapeHtml(i.id)}">
2488
+ <div class="f3d-result-label">${this.escapeHtml(i.label)}</div>
2484
2489
  <div class="f3d-result-type">${this.escapeHtml(a)}</div>
2485
2490
  </div>
2486
2491
  `;
2487
- }), s.length > 10 && (n += `<div class="f3d-no-results">+ ${s.length - 10} more nodes</div>`)), t.length > 0 && (n += '<div class="f3d-search-section-header">Relationships</div>', t.slice(0, 5).forEach(({ edge: o, sourceNode: a, targetNode: l }) => {
2488
- n += `
2489
- <div class="f3d-search-result-item" data-node-id="${this.escapeHtml(o.source)}">
2490
- <div class="f3d-result-label">${this.escapeHtml(a.label)} → ${this.escapeHtml(l.label)}</div>
2491
- <div class="f3d-result-relationship">${this.escapeHtml(o.relationship || "connected")}</div>
2492
+ }), s.length > 10 && (o += `<div class="f3d-no-results">+ ${s.length - 10} more nodes</div>`)), t.length > 0 && (o += '<div class="f3d-search-section-header">Relationships</div>', t.slice(0, 5).forEach(({ edge: i, sourceNode: a, targetNode: r }) => {
2493
+ o += `
2494
+ <div class="f3d-search-result-item" data-node-id="${this.escapeHtml(i.source)}">
2495
+ <div class="f3d-result-label">${this.escapeHtml(a.label)} → ${this.escapeHtml(r.label)}</div>
2496
+ <div class="f3d-result-relationship">${this.escapeHtml(i.relationship || "connected")}</div>
2492
2497
  </div>
2493
2498
  `;
2494
- }), t.length > 5 && (n += `<div class="f3d-no-results">+ ${t.length - 5} more relationships</div>`)), this.searchResults.innerHTML = n, this.searchResults.style.display = "block", this.searchResults.querySelectorAll(".f3d-search-result-item").forEach((o) => {
2495
- o.addEventListener("click", () => {
2496
- const a = o.dataset.nodeId;
2499
+ }), t.length > 5 && (o += `<div class="f3d-no-results">+ ${t.length - 5} more relationships</div>`)), this.searchResults.innerHTML = o, this.searchResults.style.display = "block", this.searchResults.querySelectorAll(".f3d-search-result-item").forEach((i) => {
2500
+ i.addEventListener("click", () => {
2501
+ const a = i.dataset.nodeId;
2497
2502
  a && (this.onResultClick(a), this.searchResults && (this.searchResults.style.display = "none"), this.searchInput && this.searchInput.blur());
2498
2503
  });
2499
2504
  });
@@ -2506,51 +2511,495 @@ class kt {
2506
2511
  this.searchContainer && this.searchContainer.parentNode && this.searchContainer.parentNode.removeChild(this.searchContainer);
2507
2512
  }
2508
2513
  }
2509
- class Ot {
2514
+ class Pt {
2515
+ constructor(e, s) {
2516
+ l(this, "container");
2517
+ l(this, "toggleContainer", null);
2518
+ l(this, "currentMode", "3d");
2519
+ l(this, "onViewChange");
2520
+ this.container = e, this.currentMode = s.initialMode || "3d", this.onViewChange = s.onViewChange, this.init();
2521
+ }
2522
+ init() {
2523
+ this.createToggleUI();
2524
+ }
2525
+ createToggleUI() {
2526
+ this.toggleContainer = document.createElement("div"), this.toggleContainer.className = "f3d-view-toggle", Object.assign(this.toggleContainer.style, {
2527
+ position: "absolute",
2528
+ top: "20px",
2529
+ left: "20px",
2530
+ zIndex: "100",
2531
+ display: "flex",
2532
+ gap: "0",
2533
+ background: "rgba(255, 255, 255, 0.08)",
2534
+ backdropFilter: "blur(20px)",
2535
+ WebkitBackdropFilter: "blur(20px)",
2536
+ border: "1px solid rgba(255, 255, 255, 0.12)",
2537
+ borderRadius: "12px",
2538
+ padding: "5px",
2539
+ boxShadow: "0 4px 20px rgba(0, 0, 0, 0.3)"
2540
+ });
2541
+ const e = this.createButton("2D", "2d"), s = this.createButton("3D", "3d");
2542
+ this.toggleContainer.appendChild(e), this.toggleContainer.appendChild(s), this.container.appendChild(this.toggleContainer), this.updateButtonStates();
2543
+ const t = document.createElement("style");
2544
+ t.textContent = `
2545
+ .f3d-view-btn {
2546
+ padding: 8px 16px;
2547
+ background: transparent;
2548
+ border: none;
2549
+ color: rgba(255, 255, 255, 0.5);
2550
+ font-size: 12px;
2551
+ font-weight: 600;
2552
+ font-family: inherit;
2553
+ letter-spacing: 0.5px;
2554
+ cursor: pointer;
2555
+ transition: all 0.2s ease;
2556
+ border-radius: 8px;
2557
+ min-width: 44px;
2558
+ }
2559
+ .f3d-view-btn:hover {
2560
+ color: rgba(255, 255, 255, 0.8);
2561
+ }
2562
+ .f3d-view-btn.active {
2563
+ background: linear-gradient(135deg, rgba(255, 153, 102, 0.3), rgba(255, 102, 153, 0.2));
2564
+ color: white;
2565
+ box-shadow: 0 0 15px rgba(255, 153, 102, 0.2);
2566
+ }
2567
+ .f3d-view-btn:focus {
2568
+ outline: none;
2569
+ }
2570
+ `, document.head.appendChild(t);
2571
+ }
2572
+ createButton(e, s) {
2573
+ const t = document.createElement("button");
2574
+ return t.className = "f3d-view-btn", t.dataset.mode = s, t.innerHTML = this.getIcon(s) + `<span style="margin-left: 4px;">${e}</span>`, t.style.display = "flex", t.style.alignItems = "center", t.style.justifyContent = "center", t.addEventListener("click", () => {
2575
+ this.currentMode !== s && (this.currentMode = s, this.updateButtonStates(), this.onViewChange(s));
2576
+ }), t;
2577
+ }
2578
+ getIcon(e) {
2579
+ return e === "2d" ? `<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
2580
+ <rect x="3" y="3" width="7" height="7"></rect>
2581
+ <rect x="14" y="3" width="7" height="7"></rect>
2582
+ <rect x="14" y="14" width="7" height="7"></rect>
2583
+ <rect x="3" y="14" width="7" height="7"></rect>
2584
+ </svg>` : `<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
2585
+ <path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"></path>
2586
+ <polyline points="3.27 6.96 12 12.01 20.73 6.96"></polyline>
2587
+ <line x1="12" y1="22.08" x2="12" y2="12"></line>
2588
+ </svg>`;
2589
+ }
2590
+ updateButtonStates() {
2591
+ if (!this.toggleContainer) return;
2592
+ this.toggleContainer.querySelectorAll(".f3d-view-btn").forEach((s) => {
2593
+ s.dataset.mode === this.currentMode ? s.classList.add("active") : s.classList.remove("active");
2594
+ });
2595
+ }
2596
+ setMode(e) {
2597
+ this.currentMode !== e && (this.currentMode = e, this.updateButtonStates());
2598
+ }
2599
+ getMode() {
2600
+ return this.currentMode;
2601
+ }
2602
+ dispose() {
2603
+ this.toggleContainer && this.toggleContainer.parentNode && this.toggleContainer.parentNode.removeChild(this.toggleContainer);
2604
+ }
2605
+ }
2606
+ const Tt = {
2607
+ backgroundColor: "#0a0a0a",
2608
+ gridColor: "rgba(255, 255, 255, 0.03)",
2609
+ nodeRadius: 24,
2610
+ edgeColor: "rgba(255, 255, 255, 0.15)",
2611
+ edgeOpacity: 0.4,
2612
+ repulsionStrength: 5e3,
2613
+ // Strong repulsion for spread out layout
2614
+ attractionStrength: 1e-3,
2615
+ // Very low attraction
2616
+ damping: 0.85
2617
+ // Fast energy dissipation
2618
+ };
2619
+ class Lt {
2620
+ constructor(e, s = {}) {
2621
+ l(this, "container");
2622
+ l(this, "canvas");
2623
+ l(this, "ctx");
2624
+ l(this, "options");
2625
+ // Data
2626
+ l(this, "nodes", /* @__PURE__ */ new Map());
2627
+ l(this, "edges", []);
2628
+ l(this, "nodeIdToIndex", /* @__PURE__ */ new Map());
2629
+ // Transform state
2630
+ l(this, "transform", { x: 0, y: 0, scale: 1 });
2631
+ // Interaction state
2632
+ l(this, "isDragging", !1);
2633
+ l(this, "isPanning", !1);
2634
+ l(this, "draggedNode", null);
2635
+ l(this, "hoveredNode", null);
2636
+ l(this, "hoveredEdge", null);
2637
+ l(this, "lastMousePos", { x: 0, y: 0 });
2638
+ l(this, "dragStartPos", { x: 0, y: 0 });
2639
+ // Track initial click position
2640
+ l(this, "selectedNode", null);
2641
+ // Animation
2642
+ l(this, "animationId", null);
2643
+ l(this, "isSimulating", !0);
2644
+ // Resize handler
2645
+ l(this, "resizeHandler");
2646
+ this.container = e, this.options = { ...Tt, ...s }, this.canvas = document.createElement("canvas"), this.canvas.style.position = "absolute", this.canvas.style.top = "0", this.canvas.style.left = "0", this.canvas.style.width = "100%", this.canvas.style.height = "100%", this.canvas.style.cursor = "grab", e.appendChild(this.canvas);
2647
+ const t = this.canvas.getContext("2d");
2648
+ if (!t)
2649
+ throw new Error("Failed to get 2D context");
2650
+ this.ctx = t, this.resizeHandler = this.handleResize.bind(this), window.addEventListener("resize", this.resizeHandler), this.handleResize(), this.transform.x = this.canvas.width / 2, this.transform.y = this.canvas.height / 2, this.setupInteractions(), this.startAnimation();
2651
+ }
2652
+ handleResize() {
2653
+ const e = this.container.getBoundingClientRect(), s = window.devicePixelRatio || 1;
2654
+ this.canvas.width = e.width * s, this.canvas.height = e.height * s, this.ctx.scale(s, s);
2655
+ }
2656
+ setupInteractions() {
2657
+ this.canvas.addEventListener("wheel", (e) => {
2658
+ e.preventDefault();
2659
+ const s = this.canvas.getBoundingClientRect(), t = e.clientX - s.left, o = e.clientY - s.top, i = e.deltaY > 0 ? 0.9 : 1.1, a = Math.max(0.1, Math.min(5, this.transform.scale * i)), r = a / this.transform.scale;
2660
+ this.transform.x = t - (t - this.transform.x) * r, this.transform.y = o - (o - this.transform.y) * r, this.transform.scale = a;
2661
+ }), this.canvas.addEventListener("mousedown", (e) => {
2662
+ const s = this.canvas.getBoundingClientRect(), t = e.clientX - s.left, o = e.clientY - s.top, i = this.screenToWorld(t, o), a = this.findNodeAt(i.x, i.y);
2663
+ this.dragStartPos = { x: e.clientX, y: e.clientY }, a ? (this.isDragging = !0, this.draggedNode = a, this.canvas.style.cursor = "grabbing", this.isSimulating = !0) : (this.isPanning = !0, this.canvas.style.cursor = "grabbing"), this.lastMousePos = { x: e.clientX, y: e.clientY };
2664
+ }), this.canvas.addEventListener("mousemove", (e) => {
2665
+ const s = this.canvas.getBoundingClientRect(), t = e.clientX - s.left, o = e.clientY - s.top, i = this.screenToWorld(t, o);
2666
+ if (this.isDragging && this.draggedNode)
2667
+ this.draggedNode.x = i.x, this.draggedNode.y = i.y, this.draggedNode.vx = 0, this.draggedNode.vy = 0;
2668
+ else if (this.isPanning) {
2669
+ const a = e.clientX - this.lastMousePos.x, r = e.clientY - this.lastMousePos.y;
2670
+ this.transform.x += a, this.transform.y += r, this.lastMousePos = { x: e.clientX, y: e.clientY };
2671
+ } else {
2672
+ const a = this.findNodeAt(i.x, i.y);
2673
+ if (a !== this.hoveredNode && (this.hoveredNode = a, a ? (this.hoveredEdge && (this.hoveredEdge = null, this.options.onEdgeHover && this.options.onEdgeHover(null)), this.canvas.style.cursor = "pointer", this.options.onNodeHover && this.options.onNodeHover(a.data)) : this.options.onNodeHover && this.options.onNodeHover(null)), !a) {
2674
+ const r = this.findEdgeAt(i.x, i.y);
2675
+ r !== this.hoveredEdge && (this.hoveredEdge = r, this.canvas.style.cursor = r ? "pointer" : "grab", this.options.onEdgeHover && this.options.onEdgeHover(r ? r.data : null, e));
2676
+ }
2677
+ }
2678
+ }), this.canvas.addEventListener("mouseup", (e) => {
2679
+ const s = Math.abs(e.clientX - this.dragStartPos.x), t = Math.abs(e.clientY - this.dragStartPos.y), o = s < 5 && t < 5;
2680
+ if (this.isDragging && this.draggedNode)
2681
+ o && this.options.onNodeClick && (this.selectedNode = this.draggedNode, this.options.onNodeClick(this.draggedNode.data));
2682
+ else if (o && !this.isPanning) {
2683
+ const i = this.canvas.getBoundingClientRect(), a = this.screenToWorld(e.clientX - i.left, e.clientY - i.top), r = this.findEdgeAt(a.x, a.y);
2684
+ r && this.options.onEdgeClick && this.options.onEdgeClick(r.data);
2685
+ }
2686
+ this.isDragging = !1, this.isPanning = !1, this.draggedNode = null, this.canvas.style.cursor = this.hoveredNode ? "pointer" : "grab";
2687
+ }), this.canvas.addEventListener("mouseleave", () => {
2688
+ this.isDragging = !1, this.isPanning = !1, this.draggedNode = null, this.hoveredNode = null, this.canvas.style.cursor = "grab";
2689
+ });
2690
+ }
2691
+ screenToWorld(e, s) {
2692
+ return {
2693
+ x: (e - this.transform.x) / this.transform.scale,
2694
+ y: (s - this.transform.y) / this.transform.scale
2695
+ };
2696
+ }
2697
+ findNodeAt(e, s) {
2698
+ for (const t of this.nodes.values()) {
2699
+ const o = t.x - e, i = t.y - s;
2700
+ if (Math.sqrt(o * o + i * i) < t.radius)
2701
+ return t;
2702
+ }
2703
+ return null;
2704
+ }
2705
+ findEdgeAt(e, s) {
2706
+ for (const o of this.edges) {
2707
+ const i = this.nodes.get(o.source), a = this.nodes.get(o.target);
2708
+ if (!i || !a) continue;
2709
+ const r = a.x - i.x, c = a.y - i.y, d = r * r + c * c;
2710
+ if (d === 0) continue;
2711
+ const g = Math.max(0, Math.min(1, ((e - i.x) * r + (s - i.y) * c) / d)), u = i.x + g * r, y = i.y + g * c, f = e - u, x = s - y;
2712
+ if (Math.sqrt(f * f + x * x) < 8)
2713
+ return o;
2714
+ }
2715
+ return null;
2716
+ }
2717
+ startAnimation() {
2718
+ const e = () => {
2719
+ this.isSimulating && this.simulate(), this.render(), this.animationId = requestAnimationFrame(e);
2720
+ };
2721
+ e();
2722
+ }
2723
+ simulate() {
2724
+ const e = Array.from(this.nodes.values()), s = e.length;
2725
+ if (s === 0) return;
2726
+ const t = 60, o = 5;
2727
+ let i = 0;
2728
+ for (let r = 0; r < s; r++)
2729
+ for (let c = r + 1; c < s; c++) {
2730
+ const d = e[r], g = e[c];
2731
+ let u = g.x - d.x, y = g.y - d.y, f = Math.sqrt(u * u + y * y);
2732
+ if (f < t * 3) {
2733
+ f < 1 && (f = 1);
2734
+ const x = this.options.repulsionStrength / (f * f), v = u / f * x, M = y / f * x;
2735
+ d.vx -= v, d.vy -= M, g.vx += v, g.vy += M;
2736
+ }
2737
+ }
2738
+ const a = 80;
2739
+ for (const r of this.edges) {
2740
+ const c = this.nodes.get(r.source), d = this.nodes.get(r.target);
2741
+ if (!c || !d) continue;
2742
+ let g = d.x - c.x, u = d.y - c.y, y = Math.sqrt(g * g + u * u);
2743
+ y < 1 && (y = 1);
2744
+ const x = (y - a) * this.options.attractionStrength, v = g / y * x, M = u / y * x;
2745
+ c.vx += v, c.vy += M, d.vx -= v, d.vy -= M;
2746
+ }
2747
+ for (const r of e) {
2748
+ if (this.draggedNode === r) continue;
2749
+ r.vx *= this.options.damping, r.vy *= this.options.damping;
2750
+ const c = Math.sqrt(r.vx * r.vx + r.vy * r.vy);
2751
+ c > o && (r.vx = r.vx / c * o, r.vy = r.vy / c * o), r.x += r.vx, r.y += r.vy, i += r.vx * r.vx + r.vy * r.vy;
2752
+ }
2753
+ i < 0.01 && !this.draggedNode && (this.isSimulating = !1);
2754
+ }
2755
+ render() {
2756
+ const e = this.ctx, s = this.canvas.width / (window.devicePixelRatio || 1), t = this.canvas.height / (window.devicePixelRatio || 1);
2757
+ e.fillStyle = this.options.backgroundColor, e.fillRect(0, 0, s, t), this.renderGrid(s, t), e.save(), e.translate(this.transform.x, this.transform.y), e.scale(this.transform.scale, this.transform.scale), this.renderEdges(), this.renderNodes(), e.restore();
2758
+ }
2759
+ renderGrid(e, s) {
2760
+ const t = this.ctx, o = 40 * this.transform.scale, i = 1.5, a = this.transform.x % o, r = this.transform.y % o;
2761
+ t.fillStyle = this.options.gridColor;
2762
+ for (let c = a; c < e; c += o)
2763
+ for (let d = r; d < s; d += o)
2764
+ t.beginPath(), t.arc(c, d, i, 0, Math.PI * 2), t.fill();
2765
+ }
2766
+ renderEdges() {
2767
+ const e = this.ctx;
2768
+ for (const s of this.edges) {
2769
+ const t = this.nodes.get(s.source), o = this.nodes.get(s.target);
2770
+ if (!t || !o) continue;
2771
+ const i = e.createLinearGradient(t.x, t.y, o.x, o.y);
2772
+ i.addColorStop(0, "rgba(255, 153, 102, 0.3)"), i.addColorStop(0.5, "rgba(255, 255, 255, 0.15)"), i.addColorStop(1, "rgba(102, 153, 255, 0.3)"), e.beginPath(), e.moveTo(t.x, t.y), e.lineTo(o.x, o.y), e.strokeStyle = i, e.lineWidth = 1.5, e.stroke();
2773
+ }
2774
+ }
2775
+ renderNodes() {
2776
+ const e = this.ctx;
2777
+ for (const s of this.nodes.values()) {
2778
+ const t = s === this.hoveredNode, o = s === this.selectedNode, i = s.radius * (t ? 1.1 : 1);
2779
+ if (t || o) {
2780
+ const f = e.createRadialGradient(
2781
+ s.x,
2782
+ s.y,
2783
+ i * 0.5,
2784
+ s.x,
2785
+ s.y,
2786
+ i * 2
2787
+ );
2788
+ f.addColorStop(0, "rgba(255, 153, 102, 0.4)"), f.addColorStop(1, "rgba(255, 153, 102, 0)"), e.fillStyle = f, e.beginPath(), e.arc(s.x, s.y, i * 2, 0, Math.PI * 2), e.fill();
2789
+ }
2790
+ const a = e.createRadialGradient(
2791
+ s.x - i * 0.3,
2792
+ s.y - i * 0.3,
2793
+ 0,
2794
+ s.x,
2795
+ s.y,
2796
+ i
2797
+ ), r = s.color >> 16 & 255, c = s.color >> 8 & 255, d = s.color & 255;
2798
+ a.addColorStop(0, `rgba(${Math.min(255, r + 60)}, ${Math.min(255, c + 60)}, ${Math.min(255, d + 60)}, 0.95)`), a.addColorStop(0.7, `rgba(${r}, ${c}, ${d}, 0.9)`), a.addColorStop(1, `rgba(${Math.max(0, r - 40)}, ${Math.max(0, c - 40)}, ${Math.max(0, d - 40)}, 0.85)`), e.beginPath(), e.arc(s.x, s.y, i, 0, Math.PI * 2), e.fillStyle = a, e.fill(), e.strokeStyle = "rgba(255, 255, 255, 0.2)", e.lineWidth = 1, e.stroke(), e.beginPath(), e.arc(s.x - i * 0.25, s.y - i * 0.25, i * 0.3, 0, Math.PI * 2), e.fillStyle = "rgba(255, 255, 255, 0.15)", e.fill(), e.fillStyle = "white", e.font = "600 11px Inter, -apple-system, BlinkMacSystemFont, sans-serif", e.textAlign = "center", e.textBaseline = "middle";
2799
+ const g = i * 1.6;
2800
+ let u = s.label, y = e.measureText(u).width;
2801
+ if (y > g) {
2802
+ for (; y > g && u.length > 3; )
2803
+ u = u.slice(0, -1), y = e.measureText(u + "...").width;
2804
+ u += "...";
2805
+ }
2806
+ e.shadowColor = "rgba(0, 0, 0, 0.5)", e.shadowBlur = 3, e.fillText(u, s.x, s.y), e.shadowBlur = 0;
2807
+ }
2808
+ }
2809
+ /**
2810
+ * Sets the graph data
2811
+ */
2812
+ setData(e) {
2813
+ this.nodes.clear(), this.edges = [], this.nodeIdToIndex.clear(), e.nodes.forEach((s, t) => {
2814
+ const o = s.position || {
2815
+ x: (Math.random() - 0.5) * 300,
2816
+ y: (Math.random() - 0.5) * 300
2817
+ }, i = {
2818
+ id: s.id,
2819
+ label: s.label,
2820
+ x: o.x,
2821
+ y: o.y,
2822
+ vx: 0,
2823
+ vy: 0,
2824
+ color: s.color || 16750950,
2825
+ // Match 3D tangerine color
2826
+ radius: this.options.nodeRadius,
2827
+ data: s
2828
+ };
2829
+ this.nodes.set(s.id, i), this.nodeIdToIndex.set(s.id, t);
2830
+ }), this.edges = e.edges.map((s) => ({
2831
+ source: s.source,
2832
+ target: s.target,
2833
+ relationship: s.relationship,
2834
+ data: s
2835
+ }));
2836
+ }
2837
+ /**
2838
+ * Adds a node
2839
+ */
2840
+ addNode(e) {
2841
+ const s = e.position || {
2842
+ x: (Math.random() - 0.5) * 300,
2843
+ y: (Math.random() - 0.5) * 300
2844
+ }, t = {
2845
+ id: e.id,
2846
+ label: e.label,
2847
+ x: s.x,
2848
+ y: s.y,
2849
+ vx: 0,
2850
+ vy: 0,
2851
+ color: e.color || 16750950,
2852
+ // Match 3D tangerine color
2853
+ radius: this.options.nodeRadius,
2854
+ data: e
2855
+ };
2856
+ this.nodes.set(e.id, t);
2857
+ }
2858
+ /**
2859
+ * Adds an edge
2860
+ */
2861
+ addEdge(e) {
2862
+ this.edges.push({
2863
+ source: e.source,
2864
+ target: e.target,
2865
+ relationship: e.relationship,
2866
+ data: e
2867
+ });
2868
+ }
2869
+ /**
2870
+ * Removes a node
2871
+ */
2872
+ removeNode(e) {
2873
+ this.nodes.delete(e), this.edges = this.edges.filter((s) => s.source !== e && s.target !== e);
2874
+ }
2875
+ /**
2876
+ * Gets a node by ID
2877
+ */
2878
+ getNode(e) {
2879
+ return this.nodes.get(e);
2880
+ }
2881
+ /**
2882
+ * Gets all nodes
2883
+ */
2884
+ getAllNodes() {
2885
+ return Array.from(this.nodes.values()).map((e) => e.data);
2886
+ }
2887
+ /**
2888
+ * Gets node count
2889
+ */
2890
+ getNodeCount() {
2891
+ return this.nodes.size;
2892
+ }
2893
+ /**
2894
+ * Gets edge count
2895
+ */
2896
+ getEdgeCount() {
2897
+ return this.edges.length;
2898
+ }
2899
+ /**
2900
+ * Focuses on a node
2901
+ */
2902
+ focusOnNode(e) {
2903
+ const s = this.nodes.get(e);
2904
+ if (!s) return;
2905
+ const t = this.canvas.width / 2 / (window.devicePixelRatio || 1) - s.x * this.transform.scale, o = this.canvas.height / 2 / (window.devicePixelRatio || 1) - s.y * this.transform.scale, i = this.transform.x, a = this.transform.y, r = 500, c = performance.now(), d = () => {
2906
+ const g = performance.now() - c, u = Math.min(g / r, 1), y = 1 - Math.pow(1 - u, 3);
2907
+ this.transform.x = i + (t - i) * y, this.transform.y = a + (o - a) * y, u < 1 ? requestAnimationFrame(d) : this.selectedNode = s;
2908
+ };
2909
+ d();
2910
+ }
2911
+ /**
2912
+ * Updates node positions from 3D data
2913
+ */
2914
+ syncFrom3D(e) {
2915
+ e.forEach((s, t) => {
2916
+ const o = this.nodes.get(t);
2917
+ o && (o.x = s.position.x * 3, o.y = s.position.y * 3, o.vx = 0, o.vy = 0);
2918
+ }), this.isSimulating = !1;
2919
+ }
2920
+ /**
2921
+ * Gets 2D positions for syncing to 3D
2922
+ */
2923
+ getPositions() {
2924
+ const e = /* @__PURE__ */ new Map();
2925
+ return this.nodes.forEach((s, t) => {
2926
+ e.set(t, { x: s.x, y: s.y });
2927
+ }), e;
2928
+ }
2929
+ /**
2930
+ * Show/hide the canvas
2931
+ */
2932
+ show() {
2933
+ this.canvas.style.display = "block";
2934
+ }
2935
+ hide() {
2936
+ this.canvas.style.display = "none";
2937
+ }
2938
+ /**
2939
+ * Updates physics parameters in real-time
2940
+ */
2941
+ setPhysicsParams(e) {
2942
+ e.repulsionStrength !== void 0 && (this.options.repulsionStrength = e.repulsionStrength), e.attractionStrength !== void 0 && (this.options.attractionStrength = e.attractionStrength), e.damping !== void 0 && (this.options.damping = e.damping), this.isSimulating = !0;
2943
+ }
2944
+ /**
2945
+ * Dispose resources
2946
+ */
2947
+ dispose() {
2948
+ this.animationId && cancelAnimationFrame(this.animationId), window.removeEventListener("resize", this.resizeHandler), this.canvas.parentNode && this.canvas.parentNode.removeChild(this.canvas);
2949
+ }
2950
+ }
2951
+ class Ft {
2952
+ // Store graph data for view switching
2510
2953
  constructor(e, s = {}) {
2511
2954
  // Options
2512
- r(this, "options");
2513
- r(this, "container");
2955
+ l(this, "options");
2956
+ l(this, "container");
2514
2957
  // Core components
2515
- r(this, "sceneManager");
2516
- r(this, "nodeManager");
2517
- r(this, "edgeManager");
2518
- r(this, "graphEngine");
2519
- r(this, "rendererManager");
2958
+ l(this, "sceneManager");
2959
+ l(this, "nodeManager");
2960
+ l(this, "edgeManager");
2961
+ l(this, "graphEngine");
2962
+ l(this, "rendererManager");
2520
2963
  // Factories
2521
- r(this, "materialFactory");
2522
- r(this, "nodeFactory");
2523
- r(this, "edgeFactory");
2964
+ l(this, "materialFactory");
2965
+ l(this, "nodeFactory");
2966
+ l(this, "edgeFactory");
2524
2967
  // Performance
2525
- r(this, "lodManager");
2526
- r(this, "frustumCuller");
2968
+ l(this, "lodManager");
2969
+ l(this, "frustumCuller");
2527
2970
  // Interaction
2528
- r(this, "raycasterManager");
2529
- r(this, "panelManager");
2530
- r(this, "edgePanelManager");
2531
- r(this, "edgeTooltipManager");
2532
- r(this, "searchManager", null);
2971
+ l(this, "raycasterManager");
2972
+ l(this, "panelManager");
2973
+ l(this, "edgePanelManager");
2974
+ l(this, "edgeTooltipManager");
2975
+ l(this, "searchManager", null);
2976
+ l(this, "viewToggleManager", null);
2977
+ // 2D Renderer
2978
+ l(this, "forceGraph2D", null);
2533
2979
  // Event system
2534
- r(this, "eventCallbacks", /* @__PURE__ */ new Map());
2980
+ l(this, "eventCallbacks", /* @__PURE__ */ new Map());
2535
2981
  // State
2536
- r(this, "initialized", !1);
2537
- r(this, "devControls", null);
2538
- this.options = { ...I, ...s }, this.container = ct(e), this.materialFactory = new xt(), this.nodeFactory = new vt(
2982
+ l(this, "initialized", !1);
2983
+ l(this, "devControls", null);
2984
+ l(this, "viewMode", "3d");
2985
+ l(this, "graphData", null);
2986
+ this.options = { ...T, ...s }, this.container = ct(e), this.materialFactory = new bt(), this.nodeFactory = new vt(
2539
2987
  this.materialFactory,
2540
- this.options.nodeRadius ?? I.nodeRadius,
2541
- this.options.lodSegments ?? I.lodSegments
2988
+ this.options.nodeRadius ?? T.nodeRadius,
2989
+ this.options.lodSegments ?? T.lodSegments,
2990
+ this.options.defaultNodeColor ?? T.defaultNodeColor
2542
2991
  ), this.edgeFactory = new Mt(
2543
2992
  this.materialFactory,
2544
- this.options.edgeColor ?? I.edgeColor,
2545
- this.options.edgeOpacity ?? I.edgeOpacity
2993
+ this.options.edgeColor ?? T.edgeColor,
2994
+ this.options.edgeOpacity ?? T.edgeOpacity
2546
2995
  ), this.sceneManager = new ut(this.container, this.options), this.lodManager = new wt(
2547
2996
  this.sceneManager.camera,
2548
- this.options.lodDistances ?? I.lodDistances,
2549
- this.options.enableLOD ?? I.enableLOD
2997
+ this.options.lodDistances ?? T.lodDistances,
2998
+ this.options.enableLOD ?? T.enableLOD
2550
2999
  ), this.frustumCuller = new Et(
2551
3000
  this.sceneManager.camera,
2552
- this.options.enableEdgeCulling ?? I.enableEdgeCulling
2553
- ), this.nodeManager = new mt(this.sceneManager, this.nodeFactory), this.edgeManager = new ft(this.sceneManager, this.nodeManager, this.edgeFactory), this.graphEngine = new Le(
3001
+ this.options.enableEdgeCulling ?? T.enableEdgeCulling
3002
+ ), this.nodeManager = new ft(this.sceneManager, this.nodeFactory), this.edgeManager = new mt(this.sceneManager, this.nodeManager, this.edgeFactory), this.graphEngine = new Le(
2554
3003
  this.nodeManager.getAllNodes(),
2555
3004
  this.edgeManager.getAllEdges(),
2556
3005
  {
@@ -2560,12 +3009,12 @@ class Ot {
2560
3009
  useBarnesHut: this.options.useBarnesHut,
2561
3010
  barnesHutTheta: this.options.barnesHutTheta
2562
3011
  }
2563
- ), this.rendererManager = new bt(
3012
+ ), this.rendererManager = new xt(
2564
3013
  this.sceneManager,
2565
3014
  () => this.onSimulate(),
2566
3015
  () => this.onRender(),
2567
- this.options.targetFPS ?? I.targetFPS
2568
- ), this.raycasterManager = new Ct(this.sceneManager, this.container), this.panelManager = new zt(this.container), this.edgePanelManager = new Nt(this.container), this.edgeTooltipManager = new St(), this.edgePanelManager.setNodeClickCallback((t) => {
3016
+ this.options.targetFPS ?? T.targetFPS
3017
+ ), this.raycasterManager = new Ct(this.sceneManager, this.container), this.panelManager = new Nt(this.container), this.edgePanelManager = new St(this.container), this.edgeTooltipManager = new zt(), this.edgePanelManager.setNodeClickCallback((t) => {
2569
3018
  this.edgePanelManager.hide(), this.focusOnNode(t), setTimeout(() => {
2570
3019
  this.showNodePanel(t);
2571
3020
  }, 400);
@@ -2580,6 +3029,11 @@ class Ot {
2580
3029
  this.showNodePanel(t);
2581
3030
  }, 400);
2582
3031
  }
3032
+ })), this.options.showViewToggle !== !1 && (this.viewMode = this.options.initialViewMode || "3d", this.viewToggleManager = new Pt(this.container, {
3033
+ initialMode: this.viewMode,
3034
+ onViewChange: (t) => {
3035
+ this.switchView(t);
3036
+ }
2583
3037
  })), this.setupCallbacks(), this.rendererManager.start(), this.initialized = !0, this.emit("ready");
2584
3038
  }
2585
3039
  /**
@@ -2602,8 +3056,8 @@ class Ot {
2602
3056
  onEdgeHover(e) {
2603
3057
  if (e) {
2604
3058
  this.edgeManager.highlightEdge(e.edge.source, e.edge.target);
2605
- const s = this.container.getBoundingClientRect(), t = s.left + s.width / 2, n = s.top + s.height / 2;
2606
- this.edgeTooltipManager.show(e.edge, e.sourceNode, e.targetNode, t, n), this.options.onEdgeHover && this.options.onEdgeHover(e.edge, e.sourceNode, e.targetNode), this.emit("edgeHover", e.edge, e.sourceNode, e.targetNode);
3059
+ const s = this.container.getBoundingClientRect(), t = s.left + s.width / 2, o = s.top + s.height / 2;
3060
+ this.edgeTooltipManager.show(e.edge, e.sourceNode, e.targetNode, t, o), this.options.onEdgeHover && this.options.onEdgeHover(e.edge, e.sourceNode, e.targetNode), this.emit("edgeHover", e.edge, e.sourceNode, e.targetNode);
2607
3061
  } else
2608
3062
  this.edgeManager.unhighlightCurrentEdge(), this.edgeTooltipManager.hide(), this.options.onEdgeHover && this.options.onEdgeHover(null, null, null), this.emit("edgeHover", null, null, null);
2609
3063
  }
@@ -2612,7 +3066,7 @@ class Ot {
2612
3066
  */
2613
3067
  onNodeClick(e) {
2614
3068
  this.edgePanelManager.hide();
2615
- const t = this.edgeManager.getNeighborIds(e.id).map((n) => this.nodeManager.getNode(n)).filter((n) => n !== void 0);
3069
+ const t = this.edgeManager.getNeighborIds(e.id).map((o) => this.nodeManager.getNode(o)).filter((o) => o !== void 0);
2616
3070
  this.options.showPanel !== !1 && this.panelManager.show(e, t), this.options.onNodeClick && this.options.onNodeClick(e), this.emit("nodeClick", e);
2617
3071
  }
2618
3072
  /**
@@ -2646,7 +3100,7 @@ class Ot {
2646
3100
  * Sets the graph data
2647
3101
  */
2648
3102
  setData(e) {
2649
- if (this.edgeManager.clear(), this.nodeManager.clear(), e.nodes && Array.isArray(e.nodes))
3103
+ if (this.graphData = e, this.edgeManager.clear(), this.nodeManager.clear(), e.nodes && Array.isArray(e.nodes))
2650
3104
  for (const s of e.nodes)
2651
3105
  this.addNode(s);
2652
3106
  if (e.edges && Array.isArray(e.edges))
@@ -2662,17 +3116,17 @@ class Ot {
2662
3116
  useBarnesHut: this.options.useBarnesHut,
2663
3117
  barnesHutTheta: this.options.barnesHutTheta
2664
3118
  }
2665
- ), this.graphEngine.restart();
3119
+ ), this.graphEngine.restart(), this.forceGraph2D && this.forceGraph2D.setData(e);
2666
3120
  }
2667
3121
  /**
2668
3122
  * Adds a node to the graph
2669
3123
  * @returns true if added, false if node already exists or invalid
2670
3124
  */
2671
3125
  addNode(e) {
2672
- if (!Re(e))
3126
+ if (!Oe(e))
2673
3127
  return !1;
2674
3128
  const s = this.nodeManager.addNode(e);
2675
- return s && (this.graphEngine.restart(), this.options.onNodeAdd && this.options.onNodeAdd(e), this.emit("nodeAdd", e)), s;
3129
+ return s && (this.graphEngine.restart(), this.forceGraph2D && this.forceGraph2D.addNode(e), this.options.onNodeAdd && this.options.onNodeAdd(e), this.emit("nodeAdd", e)), s;
2676
3130
  }
2677
3131
  /**
2678
3132
  * Removes a node from the graph
@@ -2699,7 +3153,7 @@ class Ot {
2699
3153
  if (!Fe(e))
2700
3154
  return !1;
2701
3155
  const s = this.edgeManager.addEdge(e);
2702
- return s && (this.graphEngine.setEdges(this.edgeManager.getAllEdges()), this.graphEngine.restart(), this.options.onEdgeAdd && this.options.onEdgeAdd(e), this.emit("edgeAdd", e)), s;
3156
+ return s && (this.graphEngine.setEdges(this.edgeManager.getAllEdges()), this.graphEngine.restart(), this.forceGraph2D && this.forceGraph2D.addEdge(e), this.options.onEdgeAdd && this.options.onEdgeAdd(e), this.emit("edgeAdd", e)), s;
2703
3157
  }
2704
3158
  /**
2705
3159
  * Removes an edge from the graph
@@ -2716,20 +3170,20 @@ class Ot {
2716
3170
  * @param fetchFn - Optional fetch function to override the default
2717
3171
  */
2718
3172
  async expandNode(e, s = 1, t) {
2719
- const n = t ?? this.options.onExpand;
2720
- if (!n)
3173
+ const o = t ?? this.options.onExpand;
3174
+ if (!o)
2721
3175
  return console.warn("[ForceGraph3D] No expand callback provided"), !1;
2722
3176
  try {
2723
- const o = await n(e, s);
2724
- if (o.nodes && Array.isArray(o.nodes))
2725
- for (const a of o.nodes)
3177
+ const i = await o(e, s);
3178
+ if (i.nodes && Array.isArray(i.nodes))
3179
+ for (const a of i.nodes)
2726
3180
  this.addNode(a);
2727
- if (o.edges && Array.isArray(o.edges))
2728
- for (const a of o.edges)
3181
+ if (i.edges && Array.isArray(i.edges))
3182
+ for (const a of i.edges)
2729
3183
  this.addEdge(a);
2730
- return this.panelManager.hide(), this.emit("expand", e, o), !0;
2731
- } catch (o) {
2732
- return console.error("[ForceGraph3D] Error expanding node:", o), !1;
3184
+ return this.panelManager.hide(), this.emit("expand", e, i), !0;
3185
+ } catch (i) {
3186
+ return console.error("[ForceGraph3D] Error expanding node:", i), !1;
2733
3187
  }
2734
3188
  }
2735
3189
  /**
@@ -2767,18 +3221,22 @@ class Ot {
2767
3221
  * Focuses the camera on a specific node with smooth animation
2768
3222
  */
2769
3223
  focusOnNode(e, s = 30) {
3224
+ if (this.viewMode === "2d" && this.forceGraph2D) {
3225
+ this.forceGraph2D.focusOnNode(e);
3226
+ return;
3227
+ }
2770
3228
  const t = this.nodeManager.getNode(e);
2771
3229
  if (!t) {
2772
3230
  console.warn(`[ForceGraph3D] Node "${e}" not found`);
2773
3231
  return;
2774
3232
  }
2775
- const n = t.position, o = this.sceneManager.camera, a = this.sceneManager.controls, l = o.position.clone().sub(a.target).normalize(), h = {
2776
- x: n.x + l.x * s,
2777
- y: n.y + l.y * s,
2778
- z: n.z + l.z * s
2779
- }, g = { x: o.position.x, y: o.position.y, z: o.position.z }, u = { x: a.target.x, y: a.target.y, z: a.target.z }, b = 800, x = performance.now(), f = () => {
2780
- const m = performance.now() - x, M = Math.min(m / b, 1), E = 1 - Math.pow(1 - M, 3);
2781
- o.position.x = g.x + (h.x - g.x) * E, o.position.y = g.y + (h.y - g.y) * E, o.position.z = g.z + (h.z - g.z) * E, a.target.x = u.x + (n.x - u.x) * E, a.target.y = u.y + (n.y - u.y) * E, a.target.z = u.z + (n.z - u.z) * E, a.update(), M < 1 && requestAnimationFrame(f);
3233
+ const o = t.position, i = this.sceneManager.camera, a = this.sceneManager.controls, r = i.position.clone().sub(a.target).normalize(), c = {
3234
+ x: o.x + r.x * s,
3235
+ y: o.y + r.y * s,
3236
+ z: o.z + r.z * s
3237
+ }, d = { x: i.position.x, y: i.position.y, z: i.position.z }, g = { x: a.target.x, y: a.target.y, z: a.target.z }, u = 800, y = performance.now(), f = () => {
3238
+ const x = performance.now() - y, v = Math.min(x / u, 1), M = 1 - Math.pow(1 - v, 3);
3239
+ i.position.x = d.x + (c.x - d.x) * M, i.position.y = d.y + (c.y - d.y) * M, i.position.z = d.z + (c.z - d.z) * M, a.target.x = g.x + (o.x - g.x) * M, a.target.y = g.y + (o.y - g.y) * M, a.target.z = g.z + (o.z - g.z) * M, a.update(), v < 1 && requestAnimationFrame(f);
2782
3240
  };
2783
3241
  f();
2784
3242
  }
@@ -2787,22 +3245,22 @@ class Ot {
2787
3245
  * Camera targets the midpoint and zooms out enough to see both nodes
2788
3246
  */
2789
3247
  focusOnEdge(e, s, t = 1.5) {
2790
- const n = this.nodeManager.getNode(e), o = this.nodeManager.getNode(s);
2791
- if (!n || !o) {
3248
+ const o = this.nodeManager.getNode(e), i = this.nodeManager.getNode(s);
3249
+ if (!o || !i) {
2792
3250
  console.warn(`[ForceGraph3D] Could not find nodes for edge "${e}" -> "${s}"`);
2793
3251
  return;
2794
3252
  }
2795
- const a = this.sceneManager.camera, l = this.sceneManager.controls, h = {
2796
- x: (n.position.x + o.position.x) / 2,
2797
- y: (n.position.y + o.position.y) / 2,
2798
- z: (n.position.z + o.position.z) / 2
2799
- }, g = o.position.x - n.position.x, u = o.position.y - n.position.y, b = o.position.z - n.position.z, x = Math.sqrt(g * g + u * u + b * b), f = Math.max(x * t, 40), m = a.position.clone().sub(l.target).normalize(), M = {
2800
- x: h.x + m.x * f,
2801
- y: h.y + m.y * f,
2802
- z: h.z + m.z * f
2803
- }, E = { x: a.position.x, y: a.position.y, z: a.position.z }, z = { x: l.target.x, y: l.target.y, z: l.target.z }, R = 800, P = performance.now(), Y = () => {
2804
- const T = performance.now() - P, H = Math.min(T / R, 1), w = 1 - Math.pow(1 - H, 3);
2805
- a.position.x = E.x + (M.x - E.x) * w, a.position.y = E.y + (M.y - E.y) * w, a.position.z = E.z + (M.z - E.z) * w, l.target.x = z.x + (h.x - z.x) * w, l.target.y = z.y + (h.y - z.y) * w, l.target.z = z.z + (h.z - z.z) * w, l.update(), H < 1 && requestAnimationFrame(Y);
3253
+ const a = this.sceneManager.camera, r = this.sceneManager.controls, c = {
3254
+ x: (o.position.x + i.position.x) / 2,
3255
+ y: (o.position.y + i.position.y) / 2,
3256
+ z: (o.position.z + i.position.z) / 2
3257
+ }, d = i.position.x - o.position.x, g = i.position.y - o.position.y, u = i.position.z - o.position.z, y = Math.sqrt(d * d + g * g + u * u), f = Math.max(y * t, 40), x = a.position.clone().sub(r.target).normalize(), v = {
3258
+ x: c.x + x.x * f,
3259
+ y: c.y + x.y * f,
3260
+ z: c.z + x.z * f
3261
+ }, M = { x: a.position.x, y: a.position.y, z: a.position.z }, N = { x: r.target.x, y: r.target.y, z: r.target.z }, O = 800, L = performance.now(), Y = () => {
3262
+ const P = performance.now() - L, H = Math.min(P / O, 1), E = 1 - Math.pow(1 - H, 3);
3263
+ a.position.x = M.x + (v.x - M.x) * E, a.position.y = M.y + (v.y - M.y) * E, a.position.z = M.z + (v.z - M.z) * E, r.target.x = N.x + (c.x - N.x) * E, r.target.y = N.y + (c.y - N.y) * E, r.target.z = N.z + (c.z - N.z) * E, r.update(), H < 1 && requestAnimationFrame(Y);
2806
3264
  };
2807
3265
  Y();
2808
3266
  }
@@ -2825,28 +3283,28 @@ class Ot {
2825
3283
  searchNodes(e) {
2826
3284
  if (!e || e.trim() === "")
2827
3285
  return [];
2828
- const s = e.toLowerCase().trim(), t = this.nodeManager.getAllNodes(), n = [];
2829
- return t.forEach((o) => {
2830
- var g, u, b;
2831
- const a = (g = o.label) == null ? void 0 : g.toLowerCase().includes(s), l = (u = o.id) == null ? void 0 : u.toLowerCase().includes(s), h = (b = o.type) == null ? void 0 : b.toLowerCase().includes(s);
2832
- (a || l || h) && n.push(o);
2833
- }), n;
3286
+ const s = e.toLowerCase().trim(), t = this.nodeManager.getAllNodes(), o = [];
3287
+ return t.forEach((i) => {
3288
+ var d, g, u;
3289
+ const a = (d = i.label) == null ? void 0 : d.toLowerCase().includes(s), r = (g = i.id) == null ? void 0 : g.toLowerCase().includes(s), c = (u = i.type) == null ? void 0 : u.toLowerCase().includes(s);
3290
+ (a || r || c) && o.push(i);
3291
+ }), o;
2834
3292
  }
2835
3293
  /**
2836
3294
  * Searches edges by relationship (case-insensitive)
2837
3295
  * @returns Array of matching edges with source/target node info
2838
3296
  */
2839
3297
  searchEdges(e) {
2840
- var o;
3298
+ var i;
2841
3299
  if (!e || e.trim() === "")
2842
3300
  return [];
2843
- const s = e.toLowerCase().trim(), t = this.edgeManager.getAllEdges(), n = [];
3301
+ const s = e.toLowerCase().trim(), t = this.edgeManager.getAllEdges(), o = [];
2844
3302
  for (const a of t)
2845
- if ((o = a.relationship) == null ? void 0 : o.toLowerCase().includes(s)) {
2846
- const h = this.nodeManager.getNode(a.source), g = this.nodeManager.getNode(a.target);
2847
- h && g && n.push({ edge: a, sourceNode: h, targetNode: g });
3303
+ if ((i = a.relationship) == null ? void 0 : i.toLowerCase().includes(s)) {
3304
+ const c = this.nodeManager.getNode(a.source), d = this.nodeManager.getNode(a.target);
3305
+ c && d && o.push({ edge: a, sourceNode: c, targetNode: d });
2848
3306
  }
2849
- return n;
3307
+ return o;
2850
3308
  }
2851
3309
  /**
2852
3310
  * Gets all nodes as an array
@@ -2867,6 +3325,44 @@ class Ot {
2867
3325
  isInitialized() {
2868
3326
  return this.initialized;
2869
3327
  }
3328
+ /**
3329
+ * Gets the current view mode
3330
+ */
3331
+ getViewMode() {
3332
+ return this.viewMode;
3333
+ }
3334
+ /**
3335
+ * Switches between 2D and 3D view modes
3336
+ */
3337
+ switchView(e) {
3338
+ this.viewMode !== e && (this.viewMode = e, this.panelManager.hide(), this.edgePanelManager.hide(), this.edgeTooltipManager.hide(), e === "2d" ? (this.sceneManager.renderer.domElement.style.display = "none", this.rendererManager.stop(), this.forceGraph2D ? (this.forceGraph2D.show(), this.forceGraph2D.syncFrom3D(this.nodeManager.getAllNodes())) : (this.forceGraph2D = new Lt(this.container, {
3339
+ backgroundColor: "#0a0a0a",
3340
+ nodeRadius: 24,
3341
+ onNodeClick: (s) => {
3342
+ this.onNodeClick(s);
3343
+ },
3344
+ onNodeHover: (s) => {
3345
+ this.options.onNodeHover && this.options.onNodeHover(s);
3346
+ },
3347
+ onEdgeHover: (s, t) => {
3348
+ if (s && t) {
3349
+ const o = this.nodeManager.getNode(s.source), i = this.nodeManager.getNode(s.target);
3350
+ o && i && this.edgeTooltipManager.show(
3351
+ s,
3352
+ o,
3353
+ i,
3354
+ t.clientX,
3355
+ t.clientY
3356
+ );
3357
+ } else
3358
+ this.edgeTooltipManager.hide();
3359
+ },
3360
+ onEdgeClick: (s) => {
3361
+ const t = this.nodeManager.getNode(s.source), o = this.nodeManager.getNode(s.target);
3362
+ t && o && this.edgePanelManager.show(s, t, o);
3363
+ }
3364
+ }), this.graphData && (this.forceGraph2D.setData(this.graphData), this.forceGraph2D.syncFrom3D(this.nodeManager.getAllNodes())))) : (this.forceGraph2D && this.forceGraph2D.hide(), this.sceneManager.renderer.domElement.style.display = "block", this.rendererManager.start()), this.emit("viewChange", e));
3365
+ }
2870
3366
  /**
2871
3367
  * Registers an event listener
2872
3368
  */
@@ -2878,13 +3374,13 @@ class Ot {
2878
3374
  */
2879
3375
  emit(e, ...s) {
2880
3376
  const t = this.eventCallbacks.get(e);
2881
- t && t.forEach((n) => n(...s));
3377
+ t && t.forEach((o) => o(...s));
2882
3378
  }
2883
3379
  /**
2884
- * Sets physics parameters
3380
+ * Sets physics parameters for both 3D and 2D views
2885
3381
  */
2886
3382
  setPhysicsParams(e) {
2887
- this.graphEngine.setPhysicsParams(e), this.graphEngine.restart();
3383
+ this.graphEngine.setPhysicsParams(e), this.graphEngine.restart(), this.forceGraph2D && this.forceGraph2D.setPhysicsParams(e);
2888
3384
  }
2889
3385
  /**
2890
3386
  * Creates dev mode controls (only in development)
@@ -2955,27 +3451,27 @@ class Ot {
2955
3451
  `, this.container.appendChild(this.devControls);
2956
3452
  const e = this.devControls.querySelector("#dev-repulsion"), s = this.devControls.querySelector("#dev-attraction"), t = this.devControls.querySelector("#dev-damping");
2957
3453
  e == null || e.addEventListener("input", () => {
2958
- const n = parseFloat(e.value);
2959
- this.setPhysicsParams({ repulsionStrength: n }), this.devControls.querySelector("#dev-repulsion-val").textContent = n.toString();
3454
+ const o = parseFloat(e.value);
3455
+ this.setPhysicsParams({ repulsionStrength: o }), this.devControls.querySelector("#dev-repulsion-val").textContent = o.toString();
2960
3456
  }), s == null || s.addEventListener("input", () => {
2961
- const n = parseFloat(s.value) / 1e3;
2962
- this.setPhysicsParams({ attractionStrength: n }), this.devControls.querySelector("#dev-attraction-val").textContent = n.toFixed(3);
3457
+ const o = parseFloat(s.value) / 1e3;
3458
+ this.setPhysicsParams({ attractionStrength: o }), this.devControls.querySelector("#dev-attraction-val").textContent = o.toFixed(3);
2963
3459
  }), t == null || t.addEventListener("input", () => {
2964
- const n = parseFloat(t.value) / 100;
2965
- this.setPhysicsParams({ damping: n }), this.devControls.querySelector("#dev-damping-val").textContent = n.toFixed(2);
3460
+ const o = parseFloat(t.value) / 100;
3461
+ this.setPhysicsParams({ damping: o }), this.devControls.querySelector("#dev-damping-val").textContent = o.toFixed(2);
2966
3462
  }), setInterval(() => {
2967
- const n = this.devControls.querySelector("#dev-node-count"), o = this.devControls.querySelector("#dev-edge-count"), a = this.devControls.querySelector("#dev-fps");
2968
- n && (n.textContent = this.getNodeCount().toString()), o && (o.textContent = this.getEdgeCount().toString()), a && (a.textContent = this.rendererManager.getFPS().toString());
3463
+ const o = this.devControls.querySelector("#dev-node-count"), i = this.devControls.querySelector("#dev-edge-count"), a = this.devControls.querySelector("#dev-fps");
3464
+ o && (o.textContent = this.getNodeCount().toString()), i && (i.textContent = this.getEdgeCount().toString()), a && (a.textContent = this.rendererManager.getFPS().toString());
2969
3465
  }, 500);
2970
3466
  }
2971
3467
  /**
2972
3468
  * Destroys the graph and releases all resources
2973
3469
  */
2974
3470
  destroy() {
2975
- this.rendererManager.dispose(), this.panelManager.dispose(), this.raycasterManager.dispose(), this.edgeTooltipManager.dispose(), this.searchManager && this.searchManager.dispose(), this.edgeManager.dispose(), this.nodeManager.dispose(), this.nodeFactory.dispose(), this.materialFactory.dispose(), this.sceneManager.dispose(), this.devControls && this.devControls.parentNode && this.devControls.parentNode.removeChild(this.devControls), this.eventCallbacks.clear(), this.initialized = !1;
3471
+ this.rendererManager.dispose(), this.panelManager.dispose(), this.raycasterManager.dispose(), this.edgeTooltipManager.dispose(), this.searchManager && this.searchManager.dispose(), this.viewToggleManager && this.viewToggleManager.dispose(), this.forceGraph2D && this.forceGraph2D.dispose(), this.edgeManager.dispose(), this.nodeManager.dispose(), this.nodeFactory.dispose(), this.materialFactory.dispose(), this.sceneManager.dispose(), this.devControls && this.devControls.parentNode && this.devControls.parentNode.removeChild(this.devControls), this.eventCallbacks.clear(), this.initialized = !1;
2976
3472
  }
2977
3473
  }
2978
- const Oe = [
3474
+ const Ie = [
2979
3475
  "Alpha",
2980
3476
  "Beta",
2981
3477
  "Gamma",
@@ -3017,7 +3513,7 @@ const Oe = [
3017
3513
  "partners with",
3018
3514
  "collaborates with",
3019
3515
  "supports"
3020
- ], Ie = [
3516
+ ], Re = [
3021
3517
  16777215,
3022
3518
  // White
3023
3519
  16750950,
@@ -3029,14 +3525,14 @@ const Oe = [
3029
3525
  16746564
3030
3526
  // Darker tangerine
3031
3527
  ];
3032
- function It(c = 30) {
3528
+ function Ht(h = 30) {
3033
3529
  const e = [], s = [];
3034
- for (let n = 0; n < c; n++) {
3035
- const o = n < Oe.length ? Oe[n] : `Node ${n + 1}`;
3530
+ for (let o = 0; o < h; o++) {
3531
+ const i = o < Ie.length ? Ie[o] : `Node ${o + 1}`;
3036
3532
  e.push({
3037
- id: `node-${n}`,
3038
- label: o,
3039
- color: Ie[n % Ie.length],
3533
+ id: `node-${o}`,
3534
+ label: i,
3535
+ color: Re[o % Re.length],
3040
3536
  position: {
3041
3537
  x: (Math.random() - 0.5) * 60,
3042
3538
  y: (Math.random() - 0.5) * 60,
@@ -3044,43 +3540,43 @@ function It(c = 30) {
3044
3540
  }
3045
3541
  });
3046
3542
  }
3047
- for (let n = 1; n < c; n++) {
3048
- const o = Math.floor(Math.random() * n);
3543
+ for (let o = 1; o < h; o++) {
3544
+ const i = Math.floor(Math.random() * o);
3049
3545
  s.push({
3050
- source: `node-${n}`,
3051
- target: `node-${o}`,
3546
+ source: `node-${o}`,
3547
+ target: `node-${i}`,
3052
3548
  relationship: J[Math.floor(Math.random() * J.length)]
3053
3549
  });
3054
3550
  }
3055
- const t = Math.floor(c * 0.5);
3056
- for (let n = 0; n < t; n++) {
3057
- const o = Math.floor(Math.random() * c);
3058
- let a = Math.floor(Math.random() * c);
3059
- o === a && (a = (a + 1) % c);
3060
- const l = `node-${o}`, h = `node-${a}`;
3551
+ const t = Math.floor(h * 0.5);
3552
+ for (let o = 0; o < t; o++) {
3553
+ const i = Math.floor(Math.random() * h);
3554
+ let a = Math.floor(Math.random() * h);
3555
+ i === a && (a = (a + 1) % h);
3556
+ const r = `node-${i}`, c = `node-${a}`;
3061
3557
  s.some(
3062
- (u) => u.source === l && u.target === h || u.source === h && u.target === l
3558
+ (g) => g.source === r && g.target === c || g.source === c && g.target === r
3063
3559
  ) || s.push({
3064
- source: l,
3065
- target: h,
3560
+ source: r,
3561
+ target: c,
3066
3562
  relationship: J[Math.floor(Math.random() * J.length)]
3067
3563
  });
3068
3564
  }
3069
3565
  return { nodes: e, edges: s };
3070
3566
  }
3071
- function Rt(c = 1e3) {
3072
- const e = [], s = [], t = Math.ceil(c / 50), n = [];
3073
- for (let o = 0; o < t; o++)
3074
- n.push({
3567
+ function Dt(h = 1e3) {
3568
+ const e = [], s = [], t = Math.ceil(h / 50), o = [];
3569
+ for (let i = 0; i < t; i++)
3570
+ o.push({
3075
3571
  x: (Math.random() - 0.5) * 200,
3076
3572
  y: (Math.random() - 0.5) * 200,
3077
3573
  z: (Math.random() - 0.5) * 200
3078
3574
  });
3079
- for (let o = 0; o < c; o++) {
3080
- const a = n[o % t];
3575
+ for (let i = 0; i < h; i++) {
3576
+ const a = o[i % t];
3081
3577
  e.push({
3082
- id: `node-${o}`,
3083
- label: `N${o}`,
3578
+ id: `node-${i}`,
3579
+ label: `N${i}`,
3084
3580
  position: {
3085
3581
  x: a.x + (Math.random() - 0.5) * 40,
3086
3582
  y: a.y + (Math.random() - 0.5) * 40,
@@ -3088,32 +3584,32 @@ function Rt(c = 1e3) {
3088
3584
  }
3089
3585
  });
3090
3586
  }
3091
- for (let o = 1; o < c; o++) {
3092
- const a = Math.floor(o / 50) * 50, l = a === 0 ? Math.floor(Math.random() * o) : a + Math.floor(Math.random() * Math.min(o - a, 50));
3587
+ for (let i = 1; i < h; i++) {
3588
+ const a = Math.floor(i / 50) * 50, r = a === 0 ? Math.floor(Math.random() * i) : a + Math.floor(Math.random() * Math.min(i - a, 50));
3093
3589
  s.push({
3094
- source: `node-${o}`,
3095
- target: `node-${Math.min(l, o - 1)}`,
3590
+ source: `node-${i}`,
3591
+ target: `node-${Math.min(r, i - 1)}`,
3096
3592
  relationship: "links to"
3097
3593
  });
3098
3594
  }
3099
- for (let o = 1; o < t; o++) {
3100
- const a = o * 50, l = (o - 1) * 50 + Math.floor(Math.random() * 50);
3595
+ for (let i = 1; i < t; i++) {
3596
+ const a = i * 50, r = (i - 1) * 50 + Math.floor(Math.random() * 50);
3101
3597
  s.push({
3102
3598
  source: `node-${a}`,
3103
- target: `node-${l}`,
3599
+ target: `node-${r}`,
3104
3600
  relationship: "bridges to"
3105
3601
  });
3106
3602
  }
3107
3603
  return { nodes: e, edges: s };
3108
3604
  }
3109
3605
  export {
3110
- I as DEFAULT_OPTIONS,
3111
- Ot as ForceGraph3D,
3112
- X as LODLevel,
3113
- A as createEdgeKey,
3114
- Rt as generateLargeSampleData,
3115
- It as generateSampleData,
3606
+ T as DEFAULT_OPTIONS,
3607
+ Ft as ForceGraph3D,
3608
+ U as LODLevel,
3609
+ D as createEdgeKey,
3610
+ Dt as generateLargeSampleData,
3611
+ Ht as generateSampleData,
3116
3612
  Fe as validateEdgeData,
3117
- Re as validateNodeData
3613
+ Oe as validateNodeData
3118
3614
  };
3119
3615
  //# sourceMappingURL=force-3d-graph.js.map