force-3d-graph 1.0.2 → 1.0.3

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,9 +1,9 @@
1
1
  var st = Object.defineProperty;
2
- var it = (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) => it(c, typeof e != "symbol" ? e + "" : e, s);
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
4
  import * as p from "three";
5
- import { EventDispatcher as nt, Vector3 as N, MOUSE as D, TOUCH as $, Spherical as Ne, Quaternion as Se, Vector2 as z, Ray as ot, Plane as at, MathUtils as rt } from "three";
6
- const L = {
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 = {
7
7
  backgroundColor: 657930,
8
8
  cameraPosition: { x: 0, y: 0, z: 80 },
9
9
  cameraFov: 75,
@@ -28,7 +28,7 @@ const L = {
28
28
  targetFPS: 60,
29
29
  maxVisibleNodes: 1e4
30
30
  };
31
- var U = /* @__PURE__ */ ((c) => (c[c.HIGH = 0] = "HIGH", c[c.MEDIUM = 1] = "MEDIUM", c[c.LOW = 2] = "LOW", c))(U || {});
31
+ var X = /* @__PURE__ */ ((c) => (c[c.HIGH = 0] = "HIGH", c[c.MEDIUM = 1] = "MEDIUM", c[c.LOW = 2] = "LOW", c))(X || {});
32
32
  function lt() {
33
33
  const c = document.createElement("div");
34
34
  return c.id = "force-graph-3d-container", c.style.cssText = `
@@ -43,7 +43,7 @@ function lt() {
43
43
  function ct(c) {
44
44
  return c && c instanceof HTMLElement ? c : (console.warn("[ForceGraph3D] No container provided, creating one automatically"), lt());
45
45
  }
46
- function ze(c) {
46
+ function Se(c) {
47
47
  const e = c.getBoundingClientRect();
48
48
  return {
49
49
  width: e.width || window.innerWidth,
@@ -70,56 +70,56 @@ function dt(c) {
70
70
  const e = c;
71
71
  return typeof e.x == "number" && typeof e.y == "number" && typeof e.z == "number";
72
72
  }
73
- function R(c, e) {
73
+ function A(c, e) {
74
74
  return c === e ? `${c}-${e}` : c < e ? `${c}-${e}` : `${e}-${c}`;
75
75
  }
76
- const Te = { type: "change" }, ae = { type: "start" }, Pe = { type: "end" }, Z = new ot(), Le = new at(), pt = Math.cos(70 * rt.DEG2RAD);
77
- class ut extends nt {
76
+ const ke = { type: "change" }, re = { type: "start" }, Te = { type: "end" }, Q = new it(), Pe = new at(), pt = Math.cos(70 * rt.DEG2RAD);
77
+ class gt extends ot {
78
78
  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: D.ROTATE, MIDDLE: D.DOLLY, RIGHT: D.PAN }, this.touches = { ONE: $.ROTATE, TWO: $.DOLLY_PAN }, this.target0 = this.target.clone(), this.position0 = this.object.position.clone(), this.zoom0 = this.object.zoom, this._domElementKeyEvents = null, this.getPolarAngle = function() {
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
80
  return l.phi;
81
81
  }, this.getAzimuthalAngle = function() {
82
82
  return l.theta;
83
83
  }, this.getDistance = function() {
84
84
  return this.object.position.distanceTo(this.target);
85
- }, this.listenToKeyEvents = function(o) {
86
- o.addEventListener("keydown", ne), this._domElementKeyEvents = o;
85
+ }, this.listenToKeyEvents = function(i) {
86
+ i.addEventListener("keydown", ie), this._domElementKeyEvents = i;
87
87
  }, this.stopListenToKeyEvents = function() {
88
- this._domElementKeyEvents.removeEventListener("keydown", ne), this._domElementKeyEvents = null;
88
+ this._domElementKeyEvents.removeEventListener("keydown", ie), this._domElementKeyEvents = null;
89
89
  }, this.saveState = function() {
90
90
  t.target0.copy(t.target), t.position0.copy(t.object.position), t.zoom0 = t.object.zoom;
91
91
  }, 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(Te), t.update(), n = i.NONE;
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;
93
93
  }, this.update = function() {
94
- const o = new N(), h = new Se().setFromUnitVectors(e.up, new N(0, 1, 0)), m = h.clone().invert(), x = new N(), w = new Se(), k = new N(), S = 2 * Math.PI;
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;
95
95
  return function(tt = null) {
96
96
  const Ce = t.object.position;
97
- o.copy(Ce).sub(t.target), o.applyQuaternion(h), l.setFromVector3(o), t.autoRotate && n === i.NONE && K(He(tt)), t.enableDamping ? (l.theta += d.theta * t.dampingFactor, l.phi += d.phi * t.dampingFactor) : (l.theta += d.theta, l.phi += d.phi);
98
- let T = t.minAzimuthAngle, P = t.maxAzimuthAngle;
99
- isFinite(T) && isFinite(P) && (T < -Math.PI ? T += S : T > Math.PI && (T -= S), P < -Math.PI ? P += S : P > Math.PI && (P -= S), T <= P ? l.theta = Math.max(T, Math.min(P, l.theta)) : l.theta = l.theta > (T + P) / 2 ? Math.max(T, l.theta) : Math.min(P, l.theta)), l.phi = Math.max(t.minPolarAngle, Math.min(t.maxPolarAngle, l.phi)), l.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 && _ || t.object.isOrthographicCamera ? l.radius = se(l.radius) : l.radius = se(l.radius * u), o.setFromSpherical(l), o.applyQuaternion(m), Ce.copy(t.target).add(o), t.object.lookAt(t.target), t.enableDamping === !0 ? (d.theta *= 1 - t.dampingFactor, d.phi *= 1 - t.dampingFactor, g.multiplyScalar(1 - t.dampingFactor)) : (d.set(0, 0, 0), g.set(0, 0, 0));
100
- let oe = !1;
101
- if (t.zoomToCursor && _) {
102
- let Y = null;
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
+ let ae = !1;
101
+ if (t.zoomToCursor && H) {
102
+ let U = null;
103
103
  if (t.object.isPerspectiveCamera) {
104
- const B = o.length();
105
- Y = se(B * u);
106
- const q = B - Y;
107
- t.object.position.addScaledVector(re, q), t.object.updateMatrixWorld();
104
+ const _ = i.length();
105
+ U = ne(_ * g);
106
+ const Z = _ - U;
107
+ t.object.position.addScaledVector(Y, Z), t.object.updateMatrixWorld();
108
108
  } else if (t.object.isOrthographicCamera) {
109
- const B = new N(O.x, O.y, 0);
110
- B.unproject(t.object), t.object.zoom = Math.max(t.minZoom, Math.min(t.maxZoom, t.object.zoom / u)), t.object.updateProjectionMatrix(), oe = !0;
111
- const q = new N(O.x, O.y, 0);
112
- q.unproject(t.object), t.object.position.sub(q).add(B), t.object.updateMatrixWorld(), Y = o.length();
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();
113
113
  } else
114
114
  console.warn("WARNING: OrbitControls.js encountered an unknown camera type - zoom to cursor disabled."), t.zoomToCursor = !1;
115
- Y !== null && (this.screenSpacePanning ? t.target.set(0, 0, -1).transformDirection(t.object.matrix).multiplyScalar(Y).add(t.object.position) : (Z.origin.copy(t.object.position), Z.direction.set(0, 0, -1).transformDirection(t.object.matrix), Math.abs(t.object.up.dot(Z.direction)) < pt ? e.lookAt(t.target) : (Le.setFromNormalAndCoplanarPoint(t.object.up, t.target), Z.intersectPlane(Le, t.target))));
116
- } else t.object.isOrthographicCamera && (t.object.zoom = Math.max(t.minZoom, Math.min(t.maxZoom, t.object.zoom / u)), t.object.updateProjectionMatrix(), oe = !0);
117
- return u = 1, _ = !1, oe || x.distanceToSquared(t.object.position) > a || 8 * (1 - w.dot(t.object.quaternion)) > a || k.distanceToSquared(t.target) > 0 ? (t.dispatchEvent(Te), x.copy(t.object.position), w.copy(t.object.quaternion), k.copy(t.target), !0) : !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
118
  };
119
119
  }(), this.dispose = function() {
120
- t.domElement.removeEventListener("contextmenu", we), t.domElement.removeEventListener("pointerdown", xe), t.domElement.removeEventListener("pointercancel", G), t.domElement.removeEventListener("wheel", ve), t.domElement.removeEventListener("pointermove", ie), t.domElement.removeEventListener("pointerup", G), t._domElementKeyEvents !== null && (t._domElementKeyEvents.removeEventListener("keydown", ne), t._domElementKeyEvents = null);
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);
121
121
  };
122
- const t = this, i = {
122
+ const t = this, n = {
123
123
  NONE: -1,
124
124
  ROTATE: 0,
125
125
  DOLLY: 1,
@@ -129,342 +129,342 @@ class ut extends nt {
129
129
  TOUCH_DOLLY_PAN: 5,
130
130
  TOUCH_DOLLY_ROTATE: 6
131
131
  };
132
- let n = i.NONE;
133
- const a = 1e-6, l = new Ne(), d = new Ne();
134
- let u = 1;
135
- const g = new N(), b = new z(), v = new z(), y = new z(), f = new z(), M = new z(), C = new z(), F = new z(), H = new z(), I = new z(), re = new N(), O = new z();
136
- let _ = !1;
137
- const E = [], V = {};
138
- let J = !1;
139
- function He(o) {
140
- return o !== null ? 2 * Math.PI / 60 * t.autoRotateSpeed * o : 2 * Math.PI / 60 / 60 * t.autoRotateSpeed;
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();
136
+ let H = !1;
137
+ const w = [], q = {};
138
+ 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;
141
141
  }
142
- function X(o) {
143
- const h = Math.abs(o * 0.01);
144
- return Math.pow(0.95, t.zoomSpeed * h);
142
+ function V(i) {
143
+ const d = Math.abs(i * 0.01);
144
+ return Math.pow(0.95, t.zoomSpeed * d);
145
145
  }
146
- function K(o) {
147
- d.theta -= o;
146
+ function G(i) {
147
+ h.theta -= i;
148
148
  }
149
- function W(o) {
150
- d.phi -= o;
149
+ function W(i) {
150
+ h.phi -= i;
151
151
  }
152
152
  const le = function() {
153
- const o = new N();
154
- return function(m, x) {
155
- o.setFromMatrixColumn(x, 0), o.multiplyScalar(-m), g.add(o);
153
+ const i = new N();
154
+ return function(y, v) {
155
+ i.setFromMatrixColumn(v, 0), i.multiplyScalar(-y), u.add(i);
156
156
  };
157
157
  }(), ce = function() {
158
- const o = new N();
159
- return function(m, x) {
160
- t.screenSpacePanning === !0 ? o.setFromMatrixColumn(x, 1) : (o.setFromMatrixColumn(x, 0), o.crossVectors(t.object.up, o)), o.multiplyScalar(m), g.add(o);
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
161
  };
162
- }(), A = function() {
163
- const o = new N();
164
- return function(m, x) {
165
- const w = t.domElement;
162
+ }(), j = function() {
163
+ const i = new N();
164
+ return function(y, v) {
165
+ const C = t.domElement;
166
166
  if (t.object.isPerspectiveCamera) {
167
- const k = t.object.position;
168
- o.copy(k).sub(t.target);
169
- let S = o.length();
170
- S *= Math.tan(t.object.fov / 2 * Math.PI / 180), le(2 * m * S / w.clientHeight, t.object.matrix), ce(2 * x * S / w.clientHeight, t.object.matrix);
171
- } else t.object.isOrthographicCamera ? (le(m * (t.object.right - t.object.left) / t.object.zoom / w.clientWidth, t.object.matrix), ce(x * (t.object.top - t.object.bottom) / t.object.zoom / w.clientHeight, t.object.matrix)) : (console.warn("WARNING: OrbitControls.js encountered an unknown camera type - pan disabled."), t.enablePan = !1);
167
+ 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);
172
172
  };
173
173
  }();
174
- function ee(o) {
175
- t.object.isPerspectiveCamera || t.object.isOrthographicCamera ? u /= o : (console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."), t.enableZoom = !1);
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);
176
176
  }
177
- function he(o) {
178
- t.object.isPerspectiveCamera || t.object.isOrthographicCamera ? u *= o : (console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."), t.enableZoom = !1);
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);
179
179
  }
180
- function te(o, h) {
180
+ function se(i, d) {
181
181
  if (!t.zoomToCursor)
182
182
  return;
183
- _ = !0;
184
- const m = t.domElement.getBoundingClientRect(), x = o - m.left, w = h - m.top, k = m.width, S = m.height;
185
- O.x = x / k * 2 - 1, O.y = -(w / S) * 2 + 1, re.set(O.x, O.y, 1).unproject(t.object).sub(t.object.position).normalize();
183
+ 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();
186
186
  }
187
- function se(o) {
188
- return Math.max(t.minDistance, Math.min(t.maxDistance, o));
187
+ function ne(i) {
188
+ return Math.max(t.minDistance, Math.min(t.maxDistance, i));
189
189
  }
190
- function de(o) {
191
- b.set(o.clientX, o.clientY);
190
+ function de(i) {
191
+ b.set(i.clientX, i.clientY);
192
192
  }
193
- function Ae(o) {
194
- te(o.clientX, o.clientX), F.set(o.clientX, o.clientY);
193
+ function Ae(i) {
194
+ se(i.clientX, i.clientX), z.set(i.clientX, i.clientY);
195
195
  }
196
- function pe(o) {
197
- f.set(o.clientX, o.clientY);
196
+ function pe(i) {
197
+ m.set(i.clientX, i.clientY);
198
198
  }
199
- function je(o) {
200
- v.set(o.clientX, o.clientY), y.subVectors(v, b).multiplyScalar(t.rotateSpeed);
201
- const h = t.domElement;
202
- K(2 * Math.PI * y.x / h.clientHeight), W(2 * Math.PI * y.y / h.clientHeight), b.copy(v), t.update();
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();
203
203
  }
204
- function De(o) {
205
- H.set(o.clientX, o.clientY), I.subVectors(H, F), I.y > 0 ? ee(X(I.y)) : I.y < 0 && he(X(I.y)), F.copy(H), t.update();
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();
206
206
  }
207
- function $e(o) {
208
- M.set(o.clientX, o.clientY), C.subVectors(M, f).multiplyScalar(t.panSpeed), A(C.x, C.y), f.copy(M), t.update();
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();
209
209
  }
210
- function Ke(o) {
211
- te(o.clientX, o.clientY), o.deltaY < 0 ? he(X(o.deltaY)) : o.deltaY > 0 && ee(X(o.deltaY)), t.update();
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();
212
212
  }
213
- function Ge(o) {
214
- let h = !1;
215
- switch (o.code) {
213
+ function Ye(i) {
214
+ let d = !1;
215
+ switch (i.code) {
216
216
  case t.keys.UP:
217
- o.ctrlKey || o.metaKey || o.shiftKey ? W(2 * Math.PI * t.rotateSpeed / t.domElement.clientHeight) : A(0, t.keyPanSpeed), h = !0;
217
+ i.ctrlKey || i.metaKey || i.shiftKey ? W(2 * Math.PI * t.rotateSpeed / t.domElement.clientHeight) : j(0, t.keyPanSpeed), d = !0;
218
218
  break;
219
219
  case t.keys.BOTTOM:
220
- o.ctrlKey || o.metaKey || o.shiftKey ? W(-2 * Math.PI * t.rotateSpeed / t.domElement.clientHeight) : A(0, -t.keyPanSpeed), h = !0;
220
+ i.ctrlKey || i.metaKey || i.shiftKey ? W(-2 * Math.PI * t.rotateSpeed / t.domElement.clientHeight) : j(0, -t.keyPanSpeed), d = !0;
221
221
  break;
222
222
  case t.keys.LEFT:
223
- o.ctrlKey || o.metaKey || o.shiftKey ? K(2 * Math.PI * t.rotateSpeed / t.domElement.clientHeight) : A(t.keyPanSpeed, 0), h = !0;
223
+ i.ctrlKey || i.metaKey || i.shiftKey ? G(2 * Math.PI * t.rotateSpeed / t.domElement.clientHeight) : j(t.keyPanSpeed, 0), d = !0;
224
224
  break;
225
225
  case t.keys.RIGHT:
226
- o.ctrlKey || o.metaKey || o.shiftKey ? K(-2 * Math.PI * t.rotateSpeed / t.domElement.clientHeight) : A(-t.keyPanSpeed, 0), h = !0;
226
+ i.ctrlKey || i.metaKey || i.shiftKey ? G(-2 * Math.PI * t.rotateSpeed / t.domElement.clientHeight) : j(-t.keyPanSpeed, 0), d = !0;
227
227
  break;
228
228
  }
229
- h && (o.preventDefault(), t.update());
229
+ d && (i.preventDefault(), t.update());
230
230
  }
231
- function ue(o) {
232
- if (E.length === 1)
233
- b.set(o.pageX, o.pageY);
231
+ function ge(i) {
232
+ if (w.length === 1)
233
+ b.set(i.pageX, i.pageY);
234
234
  else {
235
- const h = j(o), m = 0.5 * (o.pageX + h.x), x = 0.5 * (o.pageY + h.y);
236
- b.set(m, x);
235
+ const d = D(i), y = 0.5 * (i.pageX + d.x), v = 0.5 * (i.pageY + d.y);
236
+ b.set(y, v);
237
237
  }
238
238
  }
239
- function ge(o) {
240
- if (E.length === 1)
241
- f.set(o.pageX, o.pageY);
239
+ function ue(i) {
240
+ if (w.length === 1)
241
+ m.set(i.pageX, i.pageY);
242
242
  else {
243
- const h = j(o), m = 0.5 * (o.pageX + h.x), x = 0.5 * (o.pageY + h.y);
244
- f.set(m, x);
243
+ const d = D(i), y = 0.5 * (i.pageX + d.x), v = 0.5 * (i.pageY + d.y);
244
+ m.set(y, v);
245
245
  }
246
246
  }
247
- function me(o) {
248
- const h = j(o), m = o.pageX - h.x, x = o.pageY - h.y, w = Math.sqrt(m * m + x * x);
249
- F.set(0, w);
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
250
  }
251
- function Ye(o) {
252
- t.enableZoom && me(o), t.enablePan && ge(o);
251
+ function Ge(i) {
252
+ t.enableZoom && me(i), t.enablePan && ue(i);
253
253
  }
254
- function Be(o) {
255
- t.enableZoom && me(o), t.enableRotate && ue(o);
254
+ function Be(i) {
255
+ t.enableZoom && me(i), t.enableRotate && ge(i);
256
256
  }
257
- function fe(o) {
258
- if (E.length == 1)
259
- v.set(o.pageX, o.pageY);
257
+ function fe(i) {
258
+ if (w.length == 1)
259
+ x.set(i.pageX, i.pageY);
260
260
  else {
261
- const m = j(o), x = 0.5 * (o.pageX + m.x), w = 0.5 * (o.pageY + m.y);
262
- v.set(x, w);
261
+ const y = D(i), v = 0.5 * (i.pageX + y.x), C = 0.5 * (i.pageY + y.y);
262
+ x.set(v, C);
263
263
  }
264
- y.subVectors(v, b).multiplyScalar(t.rotateSpeed);
265
- const h = t.domElement;
266
- K(2 * Math.PI * y.x / h.clientHeight), W(2 * Math.PI * y.y / h.clientHeight), b.copy(v);
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
267
  }
268
- function ye(o) {
269
- if (E.length === 1)
270
- M.set(o.pageX, o.pageY);
268
+ function ye(i) {
269
+ if (w.length === 1)
270
+ M.set(i.pageX, i.pageY);
271
271
  else {
272
- const h = j(o), m = 0.5 * (o.pageX + h.x), x = 0.5 * (o.pageY + h.y);
273
- M.set(m, x);
272
+ const d = D(i), y = 0.5 * (i.pageX + d.x), v = 0.5 * (i.pageY + d.y);
273
+ M.set(y, v);
274
274
  }
275
- C.subVectors(M, f).multiplyScalar(t.panSpeed), A(C.x, C.y), f.copy(M);
275
+ E.subVectors(M, m).multiplyScalar(t.panSpeed), j(E.x, E.y), m.copy(M);
276
276
  }
277
- function be(o) {
278
- const h = j(o), m = o.pageX - h.x, x = o.pageY - h.y, w = Math.sqrt(m * m + x * x);
279
- H.set(0, w), I.set(0, Math.pow(H.y / F.y, t.zoomSpeed)), ee(I.y), F.copy(H);
280
- const k = (o.pageX + h.x) * 0.5, S = (o.pageY + h.y) * 0.5;
281
- te(k, S);
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);
282
282
  }
283
- function Ue(o) {
284
- t.enableZoom && be(o), t.enablePan && ye(o);
283
+ function Ue(i) {
284
+ t.enableZoom && be(i), t.enablePan && ye(i);
285
285
  }
286
- function _e(o) {
287
- t.enableZoom && be(o), t.enableRotate && fe(o);
286
+ function _e(i) {
287
+ t.enableZoom && be(i), t.enableRotate && fe(i);
288
288
  }
289
- function xe(o) {
290
- t.enabled !== !1 && (E.length === 0 && (t.domElement.setPointerCapture(o.pointerId), t.domElement.addEventListener("pointermove", ie), t.domElement.addEventListener("pointerup", G)), Je(o), o.pointerType === "touch" ? Ze(o) : Ve(o));
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));
291
291
  }
292
- function ie(o) {
293
- t.enabled !== !1 && (o.pointerType === "touch" ? Qe(o) : Xe(o));
292
+ function oe(i) {
293
+ t.enabled !== !1 && (i.pointerType === "touch" ? Qe(i) : qe(i));
294
294
  }
295
- function G(o) {
296
- et(o), E.length === 0 && (t.domElement.releasePointerCapture(o.pointerId), t.domElement.removeEventListener("pointermove", ie), t.domElement.removeEventListener("pointerup", G)), t.dispatchEvent(Pe), n = i.NONE;
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;
297
297
  }
298
- function Ve(o) {
299
- let h;
300
- switch (o.button) {
298
+ function Xe(i) {
299
+ let d;
300
+ switch (i.button) {
301
301
  case 0:
302
- h = t.mouseButtons.LEFT;
302
+ d = t.mouseButtons.LEFT;
303
303
  break;
304
304
  case 1:
305
- h = t.mouseButtons.MIDDLE;
305
+ d = t.mouseButtons.MIDDLE;
306
306
  break;
307
307
  case 2:
308
- h = t.mouseButtons.RIGHT;
308
+ d = t.mouseButtons.RIGHT;
309
309
  break;
310
310
  default:
311
- h = -1;
311
+ d = -1;
312
312
  }
313
- switch (h) {
314
- case D.DOLLY:
313
+ switch (d) {
314
+ case $.DOLLY:
315
315
  if (t.enableZoom === !1) return;
316
- Ae(o), n = i.DOLLY;
316
+ Ae(i), o = n.DOLLY;
317
317
  break;
318
- case D.ROTATE:
319
- if (o.ctrlKey || o.metaKey || o.shiftKey) {
318
+ case $.ROTATE:
319
+ if (i.ctrlKey || i.metaKey || i.shiftKey) {
320
320
  if (t.enablePan === !1) return;
321
- pe(o), n = i.PAN;
321
+ pe(i), o = n.PAN;
322
322
  } else {
323
323
  if (t.enableRotate === !1) return;
324
- de(o), n = i.ROTATE;
324
+ de(i), o = n.ROTATE;
325
325
  }
326
326
  break;
327
- case D.PAN:
328
- if (o.ctrlKey || o.metaKey || o.shiftKey) {
327
+ case $.PAN:
328
+ if (i.ctrlKey || i.metaKey || i.shiftKey) {
329
329
  if (t.enableRotate === !1) return;
330
- de(o), n = i.ROTATE;
330
+ de(i), o = n.ROTATE;
331
331
  } else {
332
332
  if (t.enablePan === !1) return;
333
- pe(o), n = i.PAN;
333
+ pe(i), o = n.PAN;
334
334
  }
335
335
  break;
336
336
  default:
337
- n = i.NONE;
337
+ o = n.NONE;
338
338
  }
339
- n !== i.NONE && t.dispatchEvent(ae);
339
+ o !== n.NONE && t.dispatchEvent(re);
340
340
  }
341
- function Xe(o) {
342
- switch (n) {
343
- case i.ROTATE:
341
+ function qe(i) {
342
+ switch (o) {
343
+ case n.ROTATE:
344
344
  if (t.enableRotate === !1) return;
345
- je(o);
345
+ je(i);
346
346
  break;
347
- case i.DOLLY:
347
+ case n.DOLLY:
348
348
  if (t.enableZoom === !1) return;
349
- De(o);
349
+ De(i);
350
350
  break;
351
- case i.PAN:
351
+ case n.PAN:
352
352
  if (t.enablePan === !1) return;
353
- $e(o);
353
+ $e(i);
354
354
  break;
355
355
  }
356
356
  }
357
- function ve(o) {
358
- t.enabled === !1 || t.enableZoom === !1 || n !== i.NONE || (o.preventDefault(), t.dispatchEvent(ae), Ke(We(o)), t.dispatchEvent(Pe));
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));
359
359
  }
360
- function We(o) {
361
- const h = o.deltaMode, m = {
362
- clientX: o.clientX,
363
- clientY: o.clientY,
364
- deltaY: o.deltaY
360
+ function Ve(i) {
361
+ const d = i.deltaMode, y = {
362
+ clientX: i.clientX,
363
+ clientY: i.clientY,
364
+ deltaY: i.deltaY
365
365
  };
366
- switch (h) {
366
+ switch (d) {
367
367
  case 1:
368
- m.deltaY *= 16;
368
+ y.deltaY *= 16;
369
369
  break;
370
370
  case 2:
371
- m.deltaY *= 100;
371
+ y.deltaY *= 100;
372
372
  break;
373
373
  }
374
- return o.ctrlKey && !J && (m.deltaY *= 10), m;
374
+ return i.ctrlKey && !ee && (y.deltaY *= 10), y;
375
375
  }
376
- function qe(o) {
377
- o.key === "Control" && (J = !0, document.addEventListener("keyup", Me, { passive: !0, capture: !0 }));
376
+ function We(i) {
377
+ i.key === "Control" && (ee = !0, document.addEventListener("keyup", Me, { passive: !0, capture: !0 }));
378
378
  }
379
- function Me(o) {
380
- o.key === "Control" && (J = !1, document.removeEventListener("keyup", Me, { passive: !0, capture: !0 }));
379
+ function Me(i) {
380
+ i.key === "Control" && (ee = !1, document.removeEventListener("keyup", Me, { passive: !0, capture: !0 }));
381
381
  }
382
- function ne(o) {
383
- t.enabled === !1 || t.enablePan === !1 || Ge(o);
382
+ function ie(i) {
383
+ t.enabled === !1 || t.enablePan === !1 || Ye(i);
384
384
  }
385
- function Ze(o) {
386
- switch (Ee(o), E.length) {
385
+ function Ze(i) {
386
+ switch (Ee(i), w.length) {
387
387
  case 1:
388
388
  switch (t.touches.ONE) {
389
- case $.ROTATE:
389
+ case K.ROTATE:
390
390
  if (t.enableRotate === !1) return;
391
- ue(o), n = i.TOUCH_ROTATE;
391
+ ge(i), o = n.TOUCH_ROTATE;
392
392
  break;
393
- case $.PAN:
393
+ case K.PAN:
394
394
  if (t.enablePan === !1) return;
395
- ge(o), n = i.TOUCH_PAN;
395
+ ue(i), o = n.TOUCH_PAN;
396
396
  break;
397
397
  default:
398
- n = i.NONE;
398
+ o = n.NONE;
399
399
  }
400
400
  break;
401
401
  case 2:
402
402
  switch (t.touches.TWO) {
403
- case $.DOLLY_PAN:
403
+ case K.DOLLY_PAN:
404
404
  if (t.enableZoom === !1 && t.enablePan === !1) return;
405
- Ye(o), n = i.TOUCH_DOLLY_PAN;
405
+ Ge(i), o = n.TOUCH_DOLLY_PAN;
406
406
  break;
407
- case $.DOLLY_ROTATE:
407
+ case K.DOLLY_ROTATE:
408
408
  if (t.enableZoom === !1 && t.enableRotate === !1) return;
409
- Be(o), n = i.TOUCH_DOLLY_ROTATE;
409
+ Be(i), o = n.TOUCH_DOLLY_ROTATE;
410
410
  break;
411
411
  default:
412
- n = i.NONE;
412
+ o = n.NONE;
413
413
  }
414
414
  break;
415
415
  default:
416
- n = i.NONE;
416
+ o = n.NONE;
417
417
  }
418
- n !== i.NONE && t.dispatchEvent(ae);
418
+ o !== n.NONE && t.dispatchEvent(re);
419
419
  }
420
- function Qe(o) {
421
- switch (Ee(o), n) {
422
- case i.TOUCH_ROTATE:
420
+ function Qe(i) {
421
+ switch (Ee(i), o) {
422
+ case n.TOUCH_ROTATE:
423
423
  if (t.enableRotate === !1) return;
424
- fe(o), t.update();
424
+ fe(i), t.update();
425
425
  break;
426
- case i.TOUCH_PAN:
426
+ case n.TOUCH_PAN:
427
427
  if (t.enablePan === !1) return;
428
- ye(o), t.update();
428
+ ye(i), t.update();
429
429
  break;
430
- case i.TOUCH_DOLLY_PAN:
430
+ case n.TOUCH_DOLLY_PAN:
431
431
  if (t.enableZoom === !1 && t.enablePan === !1) return;
432
- Ue(o), t.update();
432
+ Ue(i), t.update();
433
433
  break;
434
- case i.TOUCH_DOLLY_ROTATE:
434
+ case n.TOUCH_DOLLY_ROTATE:
435
435
  if (t.enableZoom === !1 && t.enableRotate === !1) return;
436
- _e(o), t.update();
436
+ _e(i), t.update();
437
437
  break;
438
438
  default:
439
- n = i.NONE;
439
+ o = n.NONE;
440
440
  }
441
441
  }
442
- function we(o) {
443
- t.enabled !== !1 && o.preventDefault();
442
+ function we(i) {
443
+ t.enabled !== !1 && i.preventDefault();
444
444
  }
445
- function Je(o) {
446
- E.push(o.pointerId);
445
+ function Je(i) {
446
+ w.push(i.pointerId);
447
447
  }
448
- function et(o) {
449
- delete V[o.pointerId];
450
- for (let h = 0; h < E.length; h++)
451
- if (E[h] == o.pointerId) {
452
- E.splice(h, 1);
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);
453
453
  return;
454
454
  }
455
455
  }
456
- function Ee(o) {
457
- let h = V[o.pointerId];
458
- h === void 0 && (h = new z(), V[o.pointerId] = h), h.set(o.pageX, o.pageY);
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
459
  }
460
- function j(o) {
461
- const h = o.pointerId === E[0] ? E[1] : E[0];
462
- return V[h];
460
+ function D(i) {
461
+ const d = i.pointerId === w[0] ? w[1] : w[0];
462
+ return q[d];
463
463
  }
464
- t.domElement.addEventListener("contextmenu", we), t.domElement.addEventListener("pointerdown", xe), t.domElement.addEventListener("pointercancel", G), t.domElement.addEventListener("wheel", ve, { passive: !1 }), document.addEventListener("keydown", qe, { passive: !0, capture: !0 }), this.update();
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();
465
465
  }
466
466
  }
467
- class gt {
467
+ class ut {
468
468
  constructor(e, s) {
469
469
  r(this, "scene");
470
470
  r(this, "camera");
@@ -475,14 +475,14 @@ class gt {
475
475
  this.container = e, this.scene = new p.Scene(), this.scene.background = new p.Color(
476
476
  s.backgroundColor ?? 657930
477
477
  );
478
- const { width: t, height: i } = ze(e), n = s.cameraFov ?? 75;
479
- this.camera = new p.PerspectiveCamera(n, t / i, 0.1, 2e3);
478
+ const { width: t, height: n } = Se(e), o = s.cameraFov ?? 75;
479
+ this.camera = new p.PerspectiveCamera(o, t / n, 0.1, 2e3);
480
480
  const a = s.cameraPosition ?? { x: 0, y: 0, z: 80 };
481
481
  this.camera.position.set(a.x, a.y, a.z), this.renderer = new p.WebGLRenderer({
482
482
  antialias: !0,
483
483
  alpha: !0,
484
484
  powerPreference: "high-performance"
485
- }), this.renderer.setSize(t, i), 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 ut(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);
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);
486
486
  }
487
487
  /**
488
488
  * Sets up scene lighting for gradient glass on dark background
@@ -494,10 +494,10 @@ class gt {
494
494
  s.position.set(50, 60, 40), s.castShadow = !0, s.shadow.mapSize.width = 1024, s.shadow.mapSize.height = 1024, this.scene.add(s);
495
495
  const t = new p.DirectionalLight(16773344, 0.4);
496
496
  t.position.set(-50, 30, -40), this.scene.add(t);
497
- const i = new p.DirectionalLight(16777215, 0.3);
498
- i.position.set(0, -30, -50), this.scene.add(i);
499
- const n = new p.PointLight(16750950, 0.5, 150);
500
- n.position.set(40, 20, 40), this.scene.add(n);
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
501
  const a = new p.PointLight(16764057, 0.4, 150);
502
502
  a.position.set(-40, -20, 40), this.scene.add(a);
503
503
  const l = new p.PointLight(6724095, 0.2, 100);
@@ -507,7 +507,7 @@ class gt {
507
507
  * Handle window resize
508
508
  */
509
509
  onWindowResize() {
510
- const { width: e, height: s } = ze(this.container);
510
+ const { width: e, height: s } = Se(this.container);
511
511
  this.camera.aspect = e / s, this.camera.updateProjectionMatrix(), this.renderer.setSize(e, s);
512
512
  }
513
513
  /**
@@ -582,16 +582,16 @@ class mt {
582
582
  x: (Math.random() - 0.5) * 50,
583
583
  y: (Math.random() - 0.5) * 50,
584
584
  z: (Math.random() - 0.5) * 50
585
- }, i = {
585
+ }, n = {
586
586
  ...e,
587
587
  position: t,
588
588
  velocity: { x: 0, y: 0, z: 0 },
589
589
  mass: 1
590
- }, n = this.nodeFactory.createNode(
590
+ }, o = this.nodeFactory.createNode(
591
591
  { ...e, position: t },
592
592
  s
593
593
  );
594
- return this.sceneManager.add(n.group), this.nodes.set(e.id, i), this.nodeObjects.set(e.id, n), !0;
594
+ return this.sceneManager.add(o.group), this.nodes.set(e.id, n), this.nodeObjects.set(e.id, o), !0;
595
595
  }
596
596
  /**
597
597
  * Removes a node from the graph
@@ -605,17 +605,17 @@ class mt {
605
605
  * Updates a node's properties
606
606
  */
607
607
  updateNode(e, s) {
608
- const t = this.nodes.get(e), i = this.nodeObjects.get(e);
609
- return !t || !i ? (console.warn(`[ForceGraph3D] Node "${e}" not found`), !1) : (s.label !== void 0 && (t.label = s.label, this.nodeFactory.updateNodeLabel(i, s.label)), s.color !== void 0 && (t.color = s.color, this.nodeFactory.updateNodeColor(i, s.color)), Object.keys(s).forEach((n) => {
610
- n !== "id" && n !== "label" && n !== "color" && n !== "position" && (t[n] = s[n]);
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
611
  }), !0);
612
612
  }
613
613
  /**
614
614
  * Updates a node's position (called by physics engine)
615
615
  */
616
616
  updateNodePosition(e, s) {
617
- const t = this.nodes.get(e), i = this.nodeObjects.get(e);
618
- t && i && (t.position = s, i.group.position.set(s.x, s.y, s.z));
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));
619
619
  }
620
620
  /**
621
621
  * Updates a node's LOD level
@@ -696,7 +696,7 @@ class ft {
696
696
  * Checks if an edge exists
697
697
  */
698
698
  hasEdge(e, s) {
699
- const t = R(e, s);
699
+ const t = A(e, s);
700
700
  return this.edgeKeySet.has(t);
701
701
  }
702
702
  /**
@@ -710,44 +710,44 @@ class ft {
710
710
  return console.warn(`[ForceGraph3D] Source node "${e.source}" does not exist`), !1;
711
711
  if (!this.nodeManager.hasNode(e.target))
712
712
  return console.warn(`[ForceGraph3D] Target node "${e.target}" does not exist`), !1;
713
- const s = R(e.source, e.target);
713
+ const s = A(e.source, e.target);
714
714
  if (this.edgeKeySet.has(s))
715
715
  return console.warn(`[ForceGraph3D] Edge "${e.source}" -> "${e.target}" already exists`), !1;
716
- const t = this.nodeManager.getNode(e.source), i = this.nodeManager.getNode(e.target), n = this.edgeFactory.createEdge(
716
+ const t = this.nodeManager.getNode(e.source), n = this.nodeManager.getNode(e.target), o = this.edgeFactory.createEdge(
717
717
  e,
718
718
  t,
719
- i,
719
+ n,
720
720
  t.position,
721
- i.position
721
+ n.position
722
722
  );
723
- return this.sceneManager.add(n.line), this.edges.push(e), this.edgeObjects.push(n), this.edgeKeySet.add(s), !0;
723
+ return this.sceneManager.add(o.line), this.edges.push(e), this.edgeObjects.push(o), this.edgeKeySet.add(s), !0;
724
724
  }
725
725
  /**
726
726
  * Removes an edge from the graph
727
727
  * @returns true if removed, false if not found
728
728
  */
729
729
  removeEdge(e, s) {
730
- const t = R(e, s);
730
+ const t = A(e, s);
731
731
  if (!this.edgeKeySet.has(t))
732
732
  return !1;
733
- const i = this.edges.findIndex(
734
- (a) => R(a.source, a.target) === t
733
+ const n = this.edges.findIndex(
734
+ (a) => A(a.source, a.target) === t
735
735
  );
736
- if (i === -1)
736
+ if (n === -1)
737
737
  return !1;
738
- const n = this.edgeObjects[i];
739
- return this.sceneManager.remove(n.line), this.edgeFactory.disposeEdge(n), this.edges.splice(i, 1), this.edgeObjects.splice(i, 1), this.edgeKeySet.delete(t), this.highlightedEdgeKey === t && (this.highlightedEdgeKey = null), !0;
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;
740
740
  }
741
741
  /**
742
742
  * Highlights an edge
743
743
  */
744
744
  highlightEdge(e, s) {
745
- const t = R(e, s);
745
+ const t = A(e, s);
746
746
  this.highlightedEdgeKey && this.highlightedEdgeKey !== t && this.unhighlightCurrentEdge();
747
- const i = this.edges.findIndex(
748
- (n) => R(n.source, n.target) === t
747
+ const n = this.edges.findIndex(
748
+ (o) => A(o.source, o.target) === t
749
749
  );
750
- i !== -1 && (this.edgeFactory.highlightEdge(this.edgeObjects[i]), this.highlightedEdgeKey = t);
750
+ n !== -1 && (this.edgeFactory.highlightEdge(this.edgeObjects[n]), this.highlightedEdgeKey = t);
751
751
  }
752
752
  /**
753
753
  * Unhighlights the currently highlighted edge
@@ -755,7 +755,7 @@ class ft {
755
755
  unhighlightCurrentEdge() {
756
756
  if (!this.highlightedEdgeKey) return;
757
757
  const e = this.edges.findIndex(
758
- (s) => R(s.source, s.target) === this.highlightedEdgeKey
758
+ (s) => A(s.source, s.target) === this.highlightedEdgeKey
759
759
  );
760
760
  e !== -1 && this.edgeFactory.unhighlightEdge(this.edgeObjects[e]), this.highlightedEdgeKey = null;
761
761
  }
@@ -790,11 +790,11 @@ class ft {
790
790
  */
791
791
  updateEdgePositions() {
792
792
  this.edgeObjects.forEach((e, s) => {
793
- const t = this.edges[s], i = this.nodeManager.getNode(t.source), n = this.nodeManager.getNode(t.target);
794
- i && n && this.edgeFactory.updateEdgePositions(
793
+ const t = this.edges[s], n = this.nodeManager.getNode(t.source), o = this.nodeManager.getNode(t.target);
794
+ n && o && this.edgeFactory.updateEdgePositions(
795
795
  e,
796
- i.position,
797
- n.position
796
+ n.position,
797
+ o.position
798
798
  );
799
799
  });
800
800
  }
@@ -831,7 +831,7 @@ class ft {
831
831
  this.clear();
832
832
  }
833
833
  }
834
- class Oe {
834
+ class Le {
835
835
  constructor(e, s, t = {}) {
836
836
  r(this, "nodes");
837
837
  r(this, "edges");
@@ -862,13 +862,13 @@ class Oe {
862
862
  calculateRepulsionBruteForce() {
863
863
  const e = Array.from(this.nodes.values()), s = e.length;
864
864
  for (let t = 0; t < s; t++) {
865
- const i = e[t];
866
- for (let n = t + 1; n < s; n++) {
867
- const a = e[n], l = a.position.x - i.position.x, d = a.position.y - i.position.y, u = a.position.z - i.position.z;
868
- let g = l * l + d * d + u * u;
869
- g < 0.01 && (g = 0.01);
870
- const b = Math.sqrt(g), v = this.repulsionStrength * this.alpha / g, y = l / b * v, f = d / b * v, M = u / b * v;
871
- i.velocity.x -= y / i.mass, i.velocity.y -= f / i.mass, i.velocity.z -= M / i.mass, a.velocity.x += y / a.mass, a.velocity.y += f / a.mass, a.velocity.z += M / a.mass;
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;
872
872
  }
873
873
  }
874
874
  }
@@ -889,10 +889,10 @@ class Oe {
889
889
  return;
890
890
  }
891
891
  if (s.mass === 0) return;
892
- const t = s.centerOfMass.x - e.position.x, i = s.centerOfMass.y - e.position.y, n = s.centerOfMass.z - e.position.z, a = Math.sqrt(t * t + i * i + n * n);
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);
893
893
  if (s.size / a < this.barnesHutTheta) {
894
- const l = Math.max(a * a, 0.01), d = this.repulsionStrength * this.alpha * s.mass / l;
895
- e.velocity.x -= t / a * d / e.mass, e.velocity.y -= i / a * d / e.mass, e.velocity.z -= n / a * d / e.mass;
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;
896
896
  } else
897
897
  for (const l of s.children)
898
898
  l && this.calculateForceFromOctree(e, l);
@@ -901,11 +901,11 @@ class Oe {
901
901
  * Apply repulsion between two nodes
902
902
  */
903
903
  applyRepulsionBetween(e, s) {
904
- const t = s.position.x - e.position.x, i = s.position.y - e.position.y, n = s.position.z - e.position.z;
905
- let a = t * t + i * i + n * n;
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;
906
906
  a < 0.01 && (a = 0.01);
907
- const l = Math.sqrt(a), d = this.repulsionStrength * this.alpha / a;
908
- e.velocity.x -= t / l * d / e.mass, e.velocity.y -= i / l * d / e.mass, e.velocity.z -= n / l * d / e.mass;
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;
909
909
  }
910
910
  /**
911
911
  * Calculate attraction forces along edges
@@ -914,10 +914,10 @@ class Oe {
914
914
  for (const e of this.edges) {
915
915
  const s = this.nodes.get(e.source), t = this.nodes.get(e.target);
916
916
  if (!s || !t) continue;
917
- const i = t.position.x - s.position.x, n = t.position.y - s.position.y, a = t.position.z - s.position.z, l = Math.sqrt(i * i + n * n + a * a);
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
918
  if (l < 0.01) continue;
919
- const u = (l - 15) * this.attractionStrength * this.alpha, g = i / l * u, b = n / l * u, v = a / l * u;
920
- s.velocity.x += g / s.mass, s.velocity.y += b / s.mass, s.velocity.z += v / s.mass, t.velocity.x -= g / t.mass, t.velocity.y -= b / t.mass, t.velocity.z -= v / t.mass;
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;
921
921
  }
922
922
  }
923
923
  /**
@@ -965,13 +965,13 @@ class yt {
965
965
  max: { x: 100, y: 100, z: 100 }
966
966
  };
967
967
  const s = { x: 1 / 0, y: 1 / 0, z: 1 / 0 }, t = { x: -1 / 0, y: -1 / 0, z: -1 / 0 };
968
- for (const n of e)
969
- s.x = Math.min(s.x, n.position.x), s.y = Math.min(s.y, n.position.y), s.z = Math.min(s.z, n.position.z), t.x = Math.max(t.x, n.position.x), t.y = Math.max(t.y, n.position.y), t.z = Math.max(t.z, n.position.z);
970
- const i = 10;
971
- return s.x -= i, s.y -= i, s.z -= i, t.x += i, t.y += i, t.z += i, { min: s, max: t };
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 };
972
972
  }
973
973
  buildTree(e, s, t = 0) {
974
- const i = Math.max(
974
+ const n = Math.max(
975
975
  s.max.x - s.min.x,
976
976
  s.max.y - s.min.y,
977
977
  s.max.z - s.min.z
@@ -979,7 +979,7 @@ class yt {
979
979
  if (e.length === 0)
980
980
  return {
981
981
  bounds: s,
982
- size: i,
982
+ size: n,
983
983
  centerOfMass: { x: 0, y: 0, z: 0 },
984
984
  mass: 0,
985
985
  isLeaf: !0,
@@ -987,56 +987,56 @@ class yt {
987
987
  children: []
988
988
  };
989
989
  if (e.length === 1 || t > 20) {
990
- let y = 0;
991
- const f = { x: 0, y: 0, z: 0 };
990
+ let f = 0;
991
+ const m = { x: 0, y: 0, z: 0 };
992
992
  for (const M of e)
993
- y += M.mass, f.x += M.position.x * M.mass, f.y += M.position.y * M.mass, f.z += M.position.z * M.mass;
994
- return y > 0 && (f.x /= y, f.y /= y, f.z /= y), {
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), {
995
995
  bounds: s,
996
- size: i,
997
- centerOfMass: f,
998
- mass: y,
996
+ size: n,
997
+ centerOfMass: m,
998
+ mass: f,
999
999
  isLeaf: !0,
1000
1000
  node: e[0],
1001
1001
  children: []
1002
1002
  };
1003
1003
  }
1004
- const n = (s.min.x + s.max.x) / 2, a = (s.min.y + s.max.y) / 2, l = (s.min.z + s.max.z) / 2, d = [[], [], [], [], [], [], [], []];
1005
- for (const y of e) {
1006
- const f = (y.position.x >= n ? 1 : 0) + (y.position.y >= a ? 2 : 0) + (y.position.z >= l ? 4 : 0);
1007
- d[f].push(y);
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 = [[], [], [], [], [], [], [], []];
1005
+ 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
1008
  }
1009
- const u = [
1010
- { min: { x: s.min.x, y: s.min.y, z: s.min.z }, max: { x: n, y: a, z: l } },
1011
- { min: { x: n, 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: n, y: s.max.y, z: l } },
1013
- { min: { x: n, 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: n, y: a, z: s.max.z } },
1015
- { min: { x: n, 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: n, y: s.max.y, z: s.max.z } },
1017
- { min: { x: n, y: a, z: l }, max: { x: s.max.x, y: s.max.y, z: s.max.z } }
1018
- ], g = [];
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
1019
  let b = 0;
1020
- const v = { x: 0, y: 0, z: 0 };
1021
- for (let y = 0; y < 8; y++)
1022
- if (d[y].length > 0) {
1023
- const f = this.buildTree(d[y], u[y], t + 1);
1024
- g.push(f), b += f.mass, v.x += f.centerOfMass.x * f.mass, v.y += f.centerOfMass.y * f.mass, v.z += f.centerOfMass.z * f.mass;
1020
+ const x = { x: 0, y: 0, z: 0 };
1021
+ 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
1025
  } else
1026
- g.push(null);
1027
- return b > 0 && (v.x /= b, v.y /= b, v.z /= b), {
1026
+ u.push(null);
1027
+ return b > 0 && (x.x /= b, x.y /= b, x.z /= b), {
1028
1028
  bounds: s,
1029
- size: i,
1030
- centerOfMass: v,
1029
+ size: n,
1030
+ centerOfMass: x,
1031
1031
  mass: b,
1032
1032
  isLeaf: !1,
1033
1033
  node: null,
1034
- children: g
1034
+ children: u
1035
1035
  };
1036
1036
  }
1037
1037
  }
1038
1038
  class bt {
1039
- constructor(e, s, t, i = 60) {
1039
+ constructor(e, s, t, n = 60) {
1040
1040
  r(this, "sceneManager");
1041
1041
  r(this, "animationId", null);
1042
1042
  r(this, "isRunning", !1);
@@ -1061,7 +1061,7 @@ class bt {
1061
1061
  const t = e - this.fpsStartTime;
1062
1062
  t >= 1e3 && (this.currentFPS = this.frameCount / (t / 1e3), this.frameCount = 0, this.fpsStartTime = e), this.onSimulate(), this.onRender(), this.sceneManager.render();
1063
1063
  });
1064
- this.sceneManager = e, this.onSimulate = s, this.onRender = t, this.frameInterval = 1e3 / i;
1064
+ this.sceneManager = e, this.onSimulate = s, this.onRender = t, this.frameInterval = 1e3 / n;
1065
1065
  }
1066
1066
  /**
1067
1067
  * Starts the animation loop
@@ -1138,10 +1138,10 @@ class xt {
1138
1138
  { colors: ["#2d1a1a", "#1a0a0a", "#0f0505"] }
1139
1139
  // -z
1140
1140
  ];
1141
- for (const i of t) {
1142
- const n = document.createElement("canvas");
1143
- n.width = 256, n.height = 256;
1144
- const a = n.getContext("2d"), l = a.createRadialGradient(
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(
1145
1145
  256 / 2,
1146
1146
  256 / 2,
1147
1147
  0,
@@ -1149,17 +1149,17 @@ class xt {
1149
1149
  256 / 2,
1150
1150
  256 * 0.8
1151
1151
  );
1152
- l.addColorStop(0, i.colors[0]), l.addColorStop(0.5, i.colors[1]), l.addColorStop(1, i.colors[2]), a.fillStyle = l, a.fillRect(0, 0, 256, 256);
1153
- const d = a.getImageData(0, 0, 256, 256);
1154
- for (let u = 0; u < d.data.length; u += 4) {
1155
- const g = (Math.random() - 0.5) * 5;
1156
- d.data[u] = Math.min(255, Math.max(0, d.data[u] + g)), d.data[u + 1] = Math.min(255, Math.max(0, d.data[u + 1] + g)), d.data[u + 2] = Math.min(255, Math.max(0, d.data[u + 2] + g));
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));
1157
1157
  }
1158
- a.putImageData(d, 0, 0), s.push(n);
1158
+ a.putImageData(h, 0, 0), s.push(o);
1159
1159
  }
1160
- this.envMap = new p.CubeTexture(s.map((i) => {
1161
- const n = new Image();
1162
- return n.src = i.toDataURL(), n;
1160
+ this.envMap = new p.CubeTexture(s.map((n) => {
1161
+ const o = new Image();
1162
+ return o.src = n.toDataURL(), o;
1163
1163
  })), this.envMap.needsUpdate = !0;
1164
1164
  }
1165
1165
  /**
@@ -1176,9 +1176,9 @@ class xt {
1176
1176
  const t = "glass-single";
1177
1177
  if (this.materialCache.has(t))
1178
1178
  return this.materialCache.get(t).clone();
1179
- const i = new p.Color(16750950), n = new p.ShaderMaterial({
1179
+ const n = new p.Color(16750950), o = new p.ShaderMaterial({
1180
1180
  uniforms: {
1181
- uColor: { value: i },
1181
+ uColor: { value: n },
1182
1182
  uEnvMap: { value: this.envMap },
1183
1183
  uGlowColor: { value: new p.Color(16777215) },
1184
1184
  uGlowIntensity: { value: 0.8 },
@@ -1250,7 +1250,7 @@ class xt {
1250
1250
  depthWrite: !0,
1251
1251
  blending: p.NormalBlending
1252
1252
  });
1253
- return this.materialCache.set(t, n), n.clone();
1253
+ return this.materialCache.set(t, o), o.clone();
1254
1254
  }
1255
1255
  /**
1256
1256
  * Creates material for edges (light color for dark background)
@@ -1279,10 +1279,10 @@ class xt {
1279
1279
  * Creates a sprite material for labels (light text for dark background)
1280
1280
  */
1281
1281
  createLabelMaterial(e, s = 24) {
1282
- const t = document.createElement("canvas"), i = t.getContext("2d");
1283
- i.font = `600 ${s}px Inter, -apple-system, sans-serif`;
1284
- const a = i.measureText(e).width;
1285
- t.width = Math.max(128, a + 24), t.height = s + 20, i.clearRect(0, 0, t.width, t.height), i.font = `600 ${s}px Inter, -apple-system, sans-serif`, i.textAlign = "center", i.textBaseline = "middle", i.shadowColor = "rgba(0, 0, 0, 0.8)", i.shadowBlur = 4, i.shadowOffsetX = 1, i.shadowOffsetY = 1, i.fillStyle = "rgba(255, 255, 255, 0.95)", i.fillText(e, t.width / 2, t.height / 2);
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
1286
  const l = new p.CanvasTexture(t);
1287
1287
  return l.needsUpdate = !0, new p.SpriteMaterial({
1288
1288
  map: l,
@@ -1337,19 +1337,19 @@ class vt {
1337
1337
  createNode(e, s = 0) {
1338
1338
  const t = new p.Group();
1339
1339
  t.name = `node-${e.id}`, t.userData = { nodeId: e.id, nodeData: e };
1340
- const i = this.getGeometry(s), n = this.materialFactory.createGlassMaterial(
1340
+ const n = this.getGeometry(s), o = this.materialFactory.createGlassMaterial(
1341
1341
  e.color ?? 4886754
1342
- ), a = new p.Mesh(i, n);
1342
+ ), a = new p.Mesh(n, o);
1343
1343
  a.castShadow = !0, a.receiveShadow = !0, t.add(a);
1344
- const l = this.materialFactory.createLabelMaterial(e.label), d = new p.Sprite(l);
1345
- return d.position.y = this.nodeRadius + 1.5, d.scale.set(4, 1, 1), t.add(d), e.position && t.position.set(
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(
1346
1346
  e.position.x,
1347
1347
  e.position.y,
1348
1348
  e.position.z
1349
1349
  ), {
1350
1350
  group: t,
1351
1351
  sphere: a,
1352
- label: d,
1352
+ label: h,
1353
1353
  lodLevel: s
1354
1354
  };
1355
1355
  }
@@ -1413,25 +1413,25 @@ class Mt {
1413
1413
  /**
1414
1414
  * Creates an edge line between two positions
1415
1415
  */
1416
- createEdge(e, s, t, i, n) {
1416
+ createEdge(e, s, t, n, o) {
1417
1417
  const a = new p.BufferGeometry(), l = new Float32Array([
1418
- i.x,
1419
- i.y,
1420
- i.z,
1421
1418
  n.x,
1422
1419
  n.y,
1423
- n.z
1420
+ n.z,
1421
+ o.x,
1422
+ o.y,
1423
+ o.z
1424
1424
  ]);
1425
1425
  a.setAttribute("position", new p.BufferAttribute(l, 3));
1426
- const d = this.getDefaultMaterial().clone(), u = new p.Line(a, d);
1427
- return u.name = `edge-${e.source}-${e.target}`, u.userData = {
1426
+ const h = this.getDefaultMaterial().clone(), g = new p.Line(a, h);
1427
+ return g.name = `edge-${e.source}-${e.target}`, g.userData = {
1428
1428
  source: e.source,
1429
1429
  target: e.target,
1430
1430
  edge: e,
1431
1431
  sourceNode: s,
1432
1432
  targetNode: t
1433
- }, u.frustumCulled = !0, {
1434
- line: u,
1433
+ }, g.frustumCulled = !0, {
1434
+ line: g,
1435
1435
  source: e.source,
1436
1436
  target: e.target
1437
1437
  };
@@ -1452,8 +1452,8 @@ class Mt {
1452
1452
  * Updates an edge's positions
1453
1453
  */
1454
1454
  updateEdgePositions(e, s, t) {
1455
- const i = e.line.geometry.attributes.position, n = i.array;
1456
- n[0] = s.x, n[1] = s.y, n[2] = s.z, n[3] = t.x, n[4] = t.y, n[5] = t.z, i.needsUpdate = !0, e.line.geometry.computeBoundingSphere();
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();
1457
1457
  }
1458
1458
  /**
1459
1459
  * Disposes an edge's resources
@@ -1480,16 +1480,16 @@ class wt {
1480
1480
  */
1481
1481
  getLODLevel(e) {
1482
1482
  if (!this.enabled)
1483
- return U.HIGH;
1484
- const s = e.x - this.camera.position.x, t = e.y - this.camera.position.y, i = e.z - this.camera.position.z, n = Math.sqrt(s * s + t * t + i * i);
1485
- return n < this.lodDistances[0] ? U.HIGH : n < this.lodDistances[1] ? U.MEDIUM : U.LOW;
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;
1486
1486
  }
1487
1487
  /**
1488
1488
  * Checks if a node should be visible based on distance
1489
1489
  */
1490
1490
  shouldRenderNode(e, s = 500) {
1491
- const t = e.x - this.camera.position.x, i = e.y - this.camera.position.y, n = e.z - this.camera.position.z;
1492
- return Math.sqrt(t * t + i * i + n * n) < s;
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;
1493
1493
  }
1494
1494
  /**
1495
1495
  * Sets the LOD distances
@@ -1545,14 +1545,14 @@ class Et {
1545
1545
  */
1546
1546
  isLineVisible(e, s) {
1547
1547
  if (!this.enabled) return !0;
1548
- const t = new p.Vector3(e.x, e.y, e.z), i = new p.Vector3(s.x, s.y, s.z);
1549
- if (this.frustum.containsPoint(t) || this.frustum.containsPoint(i))
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))
1550
1550
  return !0;
1551
- const n = new p.Vector3(
1551
+ const o = new p.Vector3(
1552
1552
  (e.x + s.x) / 2,
1553
1553
  (e.y + s.y) / 2,
1554
1554
  (e.z + s.z) / 2
1555
- ), a = n.distanceTo(t), l = new p.Sphere(n, a);
1555
+ ), a = o.distanceTo(t), l = new p.Sphere(o, a);
1556
1556
  return this.frustum.intersectsSphere(l);
1557
1557
  }
1558
1558
  /**
@@ -1571,6 +1571,7 @@ class Ct {
1571
1571
  r(this, "onNodeClick", null);
1572
1572
  r(this, "onNodeHover", null);
1573
1573
  r(this, "onEdgeHover", null);
1574
+ r(this, "onEdgeClick", null);
1574
1575
  r(this, "hoveredNodeId", null);
1575
1576
  r(this, "hoveredEdgeKey", null);
1576
1577
  r(this, "nodeObjects", []);
@@ -1607,12 +1608,23 @@ class Ct {
1607
1608
  setEdgeHoverCallback(e) {
1608
1609
  this.onEdgeHover = e;
1609
1610
  }
1611
+ /**
1612
+ * Sets the edge click callback
1613
+ */
1614
+ setEdgeClickCallback(e) {
1615
+ this.onEdgeClick = e;
1616
+ }
1610
1617
  /**
1611
1618
  * Handles click events
1612
1619
  */
1613
1620
  handleClick(e) {
1614
1621
  const s = this.getIntersectedNode(e);
1615
- s && this.onNodeClick && this.onNodeClick(s);
1622
+ if (s && this.onNodeClick) {
1623
+ this.onNodeClick(s);
1624
+ return;
1625
+ }
1626
+ const t = this.getIntersectedEdge(e);
1627
+ t && this.onEdgeClick && this.onEdgeClick(t);
1616
1628
  }
1617
1629
  /**
1618
1630
  * Handles mouse move events for hover detection
@@ -1623,23 +1635,23 @@ class Ct {
1623
1635
  this.hoveredEdgeKey !== null && this.onEdgeHover && (this.hoveredEdgeKey = null, this.onEdgeHover(null)), this.container.style.cursor = "pointer";
1624
1636
  return;
1625
1637
  }
1626
- const i = this.getIntersectedEdge(e), n = i ? `${i.edge.source}-${i.edge.target}` : null;
1627
- n !== this.hoveredEdgeKey && (this.hoveredEdgeKey = n, this.onEdgeHover && this.onEdgeHover(i)), this.container.style.cursor = i ? "pointer" : "default";
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";
1628
1640
  }
1629
1641
  /**
1630
1642
  * Gets the intersected node from a mouse event
1631
1643
  */
1632
1644
  getIntersectedNode(e) {
1633
- var i;
1645
+ var n;
1634
1646
  const s = this.container.getBoundingClientRect();
1635
1647
  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);
1636
1648
  const t = this.raycaster.intersectObjects(this.nodeObjects, !0);
1637
1649
  if (t.length > 0) {
1638
- let n = t[0].object;
1639
- for (; n; ) {
1640
- if ((i = n.userData) != null && i.nodeData)
1641
- return n.userData.nodeData;
1642
- n = n.parent;
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;
1643
1655
  }
1644
1656
  }
1645
1657
  return null;
@@ -1652,13 +1664,13 @@ class Ct {
1652
1664
  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);
1653
1665
  const t = this.raycaster.intersectObjects(this.edgeObjects, !1);
1654
1666
  if (t.length > 0) {
1655
- const i = t[0].object, n = i.userData;
1656
- if (n != null && n.edge && (n != null && n.sourceNode) && (n != null && n.targetNode))
1667
+ const n = t[0].object, o = n.userData;
1668
+ if (o != null && o.edge && (o != null && o.sourceNode) && (o != null && o.targetNode))
1657
1669
  return {
1658
- edge: n.edge,
1659
- sourceNode: n.sourceNode,
1660
- targetNode: n.targetNode,
1661
- edgeLine: i
1670
+ edge: o.edge,
1671
+ sourceNode: o.sourceNode,
1672
+ targetNode: o.targetNode,
1673
+ edgeLine: n
1662
1674
  };
1663
1675
  }
1664
1676
  return null;
@@ -1667,14 +1679,14 @@ class Ct {
1667
1679
  * Performs a raycast and returns the intersected node ID
1668
1680
  */
1669
1681
  getIntersectedNodeId(e, s) {
1670
- var n;
1682
+ var o;
1671
1683
  const t = this.container.getBoundingClientRect();
1672
1684
  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);
1673
- const i = this.raycaster.intersectObjects(this.nodeObjects, !0);
1674
- if (i.length > 0) {
1675
- let a = i[0].object;
1685
+ const n = this.raycaster.intersectObjects(this.nodeObjects, !0);
1686
+ if (n.length > 0) {
1687
+ let a = n[0].object;
1676
1688
  for (; a; ) {
1677
- if ((n = a.userData) != null && n.nodeId)
1689
+ if ((o = a.userData) != null && o.nodeId)
1678
1690
  return a.userData.nodeId;
1679
1691
  a = a.parent;
1680
1692
  }
@@ -1688,7 +1700,7 @@ class Ct {
1688
1700
  this.container.removeEventListener("click", this.handleClick), this.container.removeEventListener("mousemove", this.handleMouseMove);
1689
1701
  }
1690
1702
  }
1691
- class Nt {
1703
+ class zt {
1692
1704
  constructor(e) {
1693
1705
  r(this, "container");
1694
1706
  r(this, "panel", null);
@@ -1758,10 +1770,10 @@ class Nt {
1758
1770
  this.currentNodeId = e.id;
1759
1771
  let t;
1760
1772
  this.panelTemplate ? t = this.panelTemplate(e, s) : t = this.generateDefaultContent(e, s), this.panel.innerHTML = t;
1761
- const i = this.panel.querySelector('[data-action="expand"]'), n = this.panel.querySelector("[data-depth-select]");
1762
- i && this.onExpand && i.addEventListener("click", () => {
1773
+ const n = this.panel.querySelector('[data-action="expand"]'), o = this.panel.querySelector("[data-depth-select]");
1774
+ n && this.onExpand && n.addEventListener("click", () => {
1763
1775
  if (this.currentNodeId) {
1764
- const l = n ? parseInt(n.value, 10) : 1;
1776
+ const l = o ? parseInt(o.value, 10) : 1;
1765
1777
  this.onExpand(this.currentNodeId, l);
1766
1778
  }
1767
1779
  });
@@ -1920,7 +1932,7 @@ class Nt {
1920
1932
  <div class="neighbors-section">
1921
1933
  <div class="neighbors-title">Connected To</div>
1922
1934
  ${s.slice(0, 5).map(
1923
- (i) => `<span class="neighbor-chip">${this.escapeHtml(i.label)}</span>`
1935
+ (n) => `<span class="neighbor-chip">${this.escapeHtml(n.label)}</span>`
1924
1936
  ).join("")}
1925
1937
  ${s.length > 5 ? `<span class="neighbor-chip">+${s.length - 5} more</span>` : ""}
1926
1938
  </div>
@@ -1974,6 +1986,251 @@ class Nt {
1974
1986
  this.panel && this.panel.parentNode && this.panel.parentNode.removeChild(this.panel), this.panel = null;
1975
1987
  }
1976
1988
  }
1989
+ class Nt {
1990
+ 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);
1998
+ this.container = e, this.createPanel();
1999
+ }
2000
+ /**
2001
+ * Creates the panel element
2002
+ */
2003
+ createPanel() {
2004
+ this.panel = document.createElement("div"), this.panel.className = "force-graph-edge-panel", this.panel.style.cssText = `
2005
+ position: absolute;
2006
+ right: 20px;
2007
+ top: 50%;
2008
+ transform: translateY(-50%);
2009
+ width: 300px;
2010
+ max-height: 80vh;
2011
+ overflow-y: auto;
2012
+ background: rgba(15, 15, 25, 0.85);
2013
+ backdrop-filter: blur(20px);
2014
+ -webkit-backdrop-filter: blur(20px);
2015
+ border: 1px solid rgba(255, 255, 255, 0.1);
2016
+ border-radius: 16px;
2017
+ padding: 24px;
2018
+ color: white;
2019
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
2020
+ box-shadow:
2021
+ 0 8px 32px rgba(0, 0, 0, 0.4),
2022
+ inset 0 0 0 1px rgba(255, 255, 255, 0.05);
2023
+ z-index: 1000;
2024
+ opacity: 0;
2025
+ pointer-events: none;
2026
+ transition: opacity 0.3s ease, transform 0.3s ease;
2027
+ `, this.container.appendChild(this.panel);
2028
+ }
2029
+ /**
2030
+ * Sets the panel template function
2031
+ */
2032
+ setPanelTemplate(e) {
2033
+ this.panelTemplate = e;
2034
+ }
2035
+ /**
2036
+ * Sets the close callback
2037
+ */
2038
+ setCloseCallback(e) {
2039
+ this.onClose = e;
2040
+ }
2041
+ /**
2042
+ * Sets the node click callback (for navigating to nodes from edge panel)
2043
+ */
2044
+ setNodeClickCallback(e) {
2045
+ this.onNodeClick = e;
2046
+ }
2047
+ /**
2048
+ * Shows the panel with edge/relationship information
2049
+ */
2050
+ show(e, s, t) {
2051
+ if (!this.panel) return;
2052
+ 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
+ this.hide(), this.onClose && this.onClose();
2058
+ });
2059
+ const a = this.panel.querySelector('[data-action="goto-source"]');
2060
+ a && this.onNodeClick && a.addEventListener("click", () => {
2061
+ this.onNodeClick && this.onNodeClick(e.source);
2062
+ });
2063
+ const l = this.panel.querySelector('[data-action="goto-target"]');
2064
+ l && this.onNodeClick && l.addEventListener("click", () => {
2065
+ this.onNodeClick && this.onNodeClick(e.target);
2066
+ }), this.panel.style.opacity = "1", this.panel.style.pointerEvents = "auto", this.panel.style.transform = "translateY(-50%) translateX(0)", this.visible = !0;
2067
+ }
2068
+ /**
2069
+ * Generates default panel content
2070
+ */
2071
+ 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";
2073
+ return `
2074
+ <style>
2075
+ .force-graph-edge-panel .panel-header {
2076
+ display: flex;
2077
+ align-items: center;
2078
+ justify-content: space-between;
2079
+ margin-bottom: 20px;
2080
+ }
2081
+ .force-graph-edge-panel .panel-title {
2082
+ font-size: 14px;
2083
+ text-transform: uppercase;
2084
+ letter-spacing: 1px;
2085
+ color: rgba(255, 255, 255, 0.6);
2086
+ margin: 0;
2087
+ }
2088
+ .force-graph-edge-panel .relationship-section {
2089
+ background: rgba(255, 255, 255, 0.05);
2090
+ border-radius: 12px;
2091
+ padding: 16px;
2092
+ text-align: center;
2093
+ margin-bottom: 20px;
2094
+ }
2095
+ .force-graph-edge-panel .relationship-label {
2096
+ font-size: 18px;
2097
+ font-weight: 600;
2098
+ color: #a78bfa;
2099
+ letter-spacing: 0.5px;
2100
+ }
2101
+ .force-graph-edge-panel .node-card {
2102
+ background: rgba(255, 255, 255, 0.05);
2103
+ border: 1px solid rgba(255, 255, 255, 0.1);
2104
+ border-radius: 12px;
2105
+ padding: 14px;
2106
+ margin-bottom: 12px;
2107
+ cursor: pointer;
2108
+ transition: all 0.2s ease;
2109
+ }
2110
+ .force-graph-edge-panel .node-card:hover {
2111
+ background: rgba(255, 255, 255, 0.1);
2112
+ border-color: rgba(255, 255, 255, 0.2);
2113
+ transform: translateX(4px);
2114
+ }
2115
+ .force-graph-edge-panel .node-card-header {
2116
+ display: flex;
2117
+ align-items: center;
2118
+ gap: 10px;
2119
+ margin-bottom: 6px;
2120
+ }
2121
+ .force-graph-edge-panel .node-type {
2122
+ font-size: 10px;
2123
+ text-transform: uppercase;
2124
+ letter-spacing: 1px;
2125
+ color: rgba(255, 255, 255, 0.5);
2126
+ }
2127
+ .force-graph-edge-panel .color-dot {
2128
+ width: 10px;
2129
+ height: 10px;
2130
+ border-radius: 50%;
2131
+ flex-shrink: 0;
2132
+ }
2133
+ .force-graph-edge-panel .node-label {
2134
+ font-size: 15px;
2135
+ font-weight: 500;
2136
+ color: rgba(255, 255, 255, 0.95);
2137
+ white-space: nowrap;
2138
+ overflow: hidden;
2139
+ text-overflow: ellipsis;
2140
+ }
2141
+ .force-graph-edge-panel .connection-arrow {
2142
+ text-align: center;
2143
+ color: rgba(255, 255, 255, 0.4);
2144
+ font-size: 18px;
2145
+ margin: 8px 0;
2146
+ }
2147
+ .force-graph-edge-panel .btn-close {
2148
+ width: 100%;
2149
+ padding: 12px 16px;
2150
+ border: none;
2151
+ border-radius: 8px;
2152
+ font-size: 13px;
2153
+ font-weight: 500;
2154
+ cursor: pointer;
2155
+ transition: all 0.2s ease;
2156
+ background: rgba(255, 255, 255, 0.1);
2157
+ color: rgba(255, 255, 255, 0.8);
2158
+ margin-top: 16px;
2159
+ }
2160
+ .force-graph-edge-panel .btn-close:hover {
2161
+ background: rgba(255, 255, 255, 0.15);
2162
+ }
2163
+ .force-graph-edge-panel .hint-text {
2164
+ font-size: 11px;
2165
+ color: rgba(255, 255, 255, 0.4);
2166
+ text-align: center;
2167
+ margin-top: 8px;
2168
+ }
2169
+ </style>
2170
+
2171
+ <div class="panel-header">
2172
+ <h3 class="panel-title">Relationship</h3>
2173
+ </div>
2174
+
2175
+ <div class="relationship-section">
2176
+ <span class="relationship-label">${this.escapeHtml(a)}</span>
2177
+ </div>
2178
+
2179
+ <div class="node-card" data-action="goto-source" title="Click to focus on ${this.escapeHtml(s.label)}">
2180
+ <div class="node-type">Source</div>
2181
+ <div class="node-card-header">
2182
+ <span class="color-dot" style="background: ${n}; box-shadow: 0 0 8px ${n}80;"></span>
2183
+ <span class="node-label">${this.escapeHtml(s.label)}</span>
2184
+ </div>
2185
+ </div>
2186
+
2187
+ <div class="connection-arrow">↓</div>
2188
+
2189
+ <div class="node-card" data-action="goto-target" title="Click to focus on ${this.escapeHtml(t.label)}">
2190
+ <div class="node-type">Target</div>
2191
+ <div class="node-card-header">
2192
+ <span class="color-dot" style="background: ${o}; box-shadow: 0 0 8px ${o}80;"></span>
2193
+ <span class="node-label">${this.escapeHtml(t.label)}</span>
2194
+ </div>
2195
+ </div>
2196
+
2197
+ <p class="hint-text">Click on a node to focus on it</p>
2198
+
2199
+ <button class="btn-close" data-action="close">Close</button>
2200
+ `;
2201
+ }
2202
+ /**
2203
+ * Escapes HTML to prevent XSS
2204
+ */
2205
+ escapeHtml(e) {
2206
+ const s = document.createElement("div");
2207
+ return s.textContent = e, s.innerHTML;
2208
+ }
2209
+ /**
2210
+ * Hides the panel
2211
+ */
2212
+ hide() {
2213
+ this.panel && (this.panel.style.opacity = "0", this.panel.style.pointerEvents = "none", this.panel.style.transform = "translateY(-50%) translateX(20px)", this.visible = !1, this.currentEdgeKey = null);
2214
+ }
2215
+ /**
2216
+ * Checks if the panel is visible
2217
+ */
2218
+ isVisible() {
2219
+ return this.visible;
2220
+ }
2221
+ /**
2222
+ * Gets the currently displayed edge key
2223
+ */
2224
+ getCurrentEdgeKey() {
2225
+ return this.currentEdgeKey;
2226
+ }
2227
+ /**
2228
+ * Dispose the panel
2229
+ */
2230
+ dispose() {
2231
+ this.panel && this.panel.parentNode && this.panel.parentNode.removeChild(this.panel), this.panel = null;
2232
+ }
2233
+ }
1977
2234
  class St {
1978
2235
  constructor() {
1979
2236
  r(this, "tooltip", null);
@@ -2020,14 +2277,14 @@ class St {
2020
2277
  */
2021
2278
  positionTooltip(e, s) {
2022
2279
  if (!this.tooltip) return;
2023
- const t = this.tooltip.getBoundingClientRect(), i = window.innerWidth, n = window.innerHeight;
2280
+ const t = this.tooltip.getBoundingClientRect(), n = window.innerWidth, o = window.innerHeight;
2024
2281
  let a = e + 15, l = s + 15;
2025
- a + t.width > i - 10 && (a = e - t.width - 15), l + t.height > n - 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`;
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`;
2026
2283
  }
2027
2284
  /**
2028
2285
  * Shows the tooltip with edge info
2029
2286
  */
2030
- show(e, s, t, i, n) {
2287
+ show(e, s, t, n, o) {
2031
2288
  if (!this.tooltip) return;
2032
2289
  const a = e.relationship || "connected to";
2033
2290
  this.tooltip.innerHTML = `
@@ -2042,7 +2299,7 @@ class St {
2042
2299
  <span style="font-weight: 600; color: #ff9966;">${this.escapeHtml(t.label)}</span>
2043
2300
  </div>
2044
2301
  </div>
2045
- `, this.positionTooltip(i, n), this.tooltip.style.opacity = "1", this.tooltip.style.transform = "translateY(0)", this.visible = !0;
2302
+ `, this.positionTooltip(n, o), this.tooltip.style.opacity = "1", this.tooltip.style.transform = "translateY(0)", this.visible = !0;
2046
2303
  }
2047
2304
  /**
2048
2305
  * Updates tooltip position (called externally on mouse move)
@@ -2076,7 +2333,7 @@ class St {
2076
2333
  this.tooltip && this.tooltip.parentNode && this.tooltip.parentNode.removeChild(this.tooltip), this.tooltip = null;
2077
2334
  }
2078
2335
  }
2079
- class zt {
2336
+ class kt {
2080
2337
  constructor(e, s) {
2081
2338
  r(this, "container");
2082
2339
  r(this, "searchContainer", null);
@@ -2218,25 +2475,25 @@ class zt {
2218
2475
  this.searchResults.innerHTML = '<div class="f3d-no-results">No results found</div>', this.searchResults.style.display = "block";
2219
2476
  return;
2220
2477
  }
2221
- let i = "";
2222
- s.length > 0 && (i += '<div class="f3d-search-section-header">Nodes</div>', s.slice(0, 10).forEach((n) => {
2223
- const a = n.type || "Node";
2224
- i += `
2225
- <div class="f3d-search-result-item" data-node-id="${this.escapeHtml(n.id)}">
2226
- <div class="f3d-result-label">${this.escapeHtml(n.label)}</div>
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>
2227
2484
  <div class="f3d-result-type">${this.escapeHtml(a)}</div>
2228
2485
  </div>
2229
2486
  `;
2230
- }), s.length > 10 && (i += `<div class="f3d-no-results">+ ${s.length - 10} more nodes</div>`)), t.length > 0 && (i += '<div class="f3d-search-section-header">Relationships</div>', t.slice(0, 5).forEach(({ edge: n, sourceNode: a, targetNode: l }) => {
2231
- i += `
2232
- <div class="f3d-search-result-item" data-node-id="${this.escapeHtml(n.source)}">
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)}">
2233
2490
  <div class="f3d-result-label">${this.escapeHtml(a.label)} → ${this.escapeHtml(l.label)}</div>
2234
- <div class="f3d-result-relationship">${this.escapeHtml(n.relationship || "connected")}</div>
2491
+ <div class="f3d-result-relationship">${this.escapeHtml(o.relationship || "connected")}</div>
2235
2492
  </div>
2236
2493
  `;
2237
- }), t.length > 5 && (i += `<div class="f3d-no-results">+ ${t.length - 5} more relationships</div>`)), this.searchResults.innerHTML = i, this.searchResults.style.display = "block", this.searchResults.querySelectorAll(".f3d-search-result-item").forEach((n) => {
2238
- n.addEventListener("click", () => {
2239
- const a = n.dataset.nodeId;
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;
2240
2497
  a && (this.onResultClick(a), this.searchResults && (this.searchResults.style.display = "none"), this.searchInput && this.searchInput.blur());
2241
2498
  });
2242
2499
  });
@@ -2270,6 +2527,7 @@ class Ot {
2270
2527
  // Interaction
2271
2528
  r(this, "raycasterManager");
2272
2529
  r(this, "panelManager");
2530
+ r(this, "edgePanelManager");
2273
2531
  r(this, "edgeTooltipManager");
2274
2532
  r(this, "searchManager", null);
2275
2533
  // Event system
@@ -2277,22 +2535,22 @@ class Ot {
2277
2535
  // State
2278
2536
  r(this, "initialized", !1);
2279
2537
  r(this, "devControls", null);
2280
- this.options = { ...L, ...s }, this.container = ct(e), this.materialFactory = new xt(), this.nodeFactory = new vt(
2538
+ this.options = { ...I, ...s }, this.container = ct(e), this.materialFactory = new xt(), this.nodeFactory = new vt(
2281
2539
  this.materialFactory,
2282
- this.options.nodeRadius ?? L.nodeRadius,
2283
- this.options.lodSegments ?? L.lodSegments
2540
+ this.options.nodeRadius ?? I.nodeRadius,
2541
+ this.options.lodSegments ?? I.lodSegments
2284
2542
  ), this.edgeFactory = new Mt(
2285
2543
  this.materialFactory,
2286
- this.options.edgeColor ?? L.edgeColor,
2287
- this.options.edgeOpacity ?? L.edgeOpacity
2288
- ), this.sceneManager = new gt(this.container, this.options), this.lodManager = new wt(
2544
+ this.options.edgeColor ?? I.edgeColor,
2545
+ this.options.edgeOpacity ?? I.edgeOpacity
2546
+ ), this.sceneManager = new ut(this.container, this.options), this.lodManager = new wt(
2289
2547
  this.sceneManager.camera,
2290
- this.options.lodDistances ?? L.lodDistances,
2291
- this.options.enableLOD ?? L.enableLOD
2548
+ this.options.lodDistances ?? I.lodDistances,
2549
+ this.options.enableLOD ?? I.enableLOD
2292
2550
  ), this.frustumCuller = new Et(
2293
2551
  this.sceneManager.camera,
2294
- this.options.enableEdgeCulling ?? L.enableEdgeCulling
2295
- ), this.nodeManager = new mt(this.sceneManager, this.nodeFactory), this.edgeManager = new ft(this.sceneManager, this.nodeManager, this.edgeFactory), this.graphEngine = new Oe(
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(
2296
2554
  this.nodeManager.getAllNodes(),
2297
2555
  this.edgeManager.getAllEdges(),
2298
2556
  {
@@ -2306,8 +2564,12 @@ class Ot {
2306
2564
  this.sceneManager,
2307
2565
  () => this.onSimulate(),
2308
2566
  () => this.onRender(),
2309
- this.options.targetFPS ?? L.targetFPS
2310
- ), this.raycasterManager = new Ct(this.sceneManager, this.container), this.panelManager = new Nt(this.container), this.edgeTooltipManager = new St(), this.options.showSearch !== !1 && (this.searchManager = new zt(this.container, {
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) => {
2569
+ this.edgePanelManager.hide(), this.focusOnNode(t), setTimeout(() => {
2570
+ this.showNodePanel(t);
2571
+ }, 400);
2572
+ }), this.options.showSearch !== !1 && (this.searchManager = new kt(this.container, {
2311
2573
  placeholder: this.options.searchPlaceholder,
2312
2574
  onSearch: (t) => ({
2313
2575
  nodeResults: this.searchNodes(t),
@@ -2330,6 +2592,8 @@ class Ot {
2330
2592
  this.expandNode(e, s);
2331
2593
  }), this.options.panelTemplate && this.panelManager.setPanelTemplate(this.options.panelTemplate), this.options.panelStyles && this.panelManager.setPanelStyles(this.options.panelStyles), this.raycasterManager.setEdgeHoverCallback((e) => {
2332
2594
  this.onEdgeHover(e);
2595
+ }), this.raycasterManager.setEdgeClickCallback((e) => {
2596
+ this.onEdgeClick(e);
2333
2597
  });
2334
2598
  }
2335
2599
  /**
@@ -2338,8 +2602,8 @@ class Ot {
2338
2602
  onEdgeHover(e) {
2339
2603
  if (e) {
2340
2604
  this.edgeManager.highlightEdge(e.edge.source, e.edge.target);
2341
- const s = this.container.getBoundingClientRect(), t = s.left + s.width / 2, i = s.top + s.height / 2;
2342
- this.edgeTooltipManager.show(e.edge, e.sourceNode, e.targetNode, t, i), this.options.onEdgeHover && this.options.onEdgeHover(e.edge, e.sourceNode, e.targetNode), this.emit("edgeHover", e.edge, e.sourceNode, e.targetNode);
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);
2343
2607
  } else
2344
2608
  this.edgeManager.unhighlightCurrentEdge(), this.edgeTooltipManager.hide(), this.options.onEdgeHover && this.options.onEdgeHover(null, null, null), this.emit("edgeHover", null, null, null);
2345
2609
  }
@@ -2347,9 +2611,16 @@ class Ot {
2347
2611
  * Handles node click
2348
2612
  */
2349
2613
  onNodeClick(e) {
2350
- const t = this.edgeManager.getNeighborIds(e.id).map((i) => this.nodeManager.getNode(i)).filter((i) => i !== void 0);
2614
+ this.edgePanelManager.hide();
2615
+ const t = this.edgeManager.getNeighborIds(e.id).map((n) => this.nodeManager.getNode(n)).filter((n) => n !== void 0);
2351
2616
  this.options.showPanel !== !1 && this.panelManager.show(e, t), this.options.onNodeClick && this.options.onNodeClick(e), this.emit("nodeClick", e);
2352
2617
  }
2618
+ /**
2619
+ * Handles edge click
2620
+ */
2621
+ onEdgeClick(e) {
2622
+ this.panelManager.hide(), this.edgeTooltipManager.hide(), this.edgeManager.highlightEdge(e.edge.source, e.edge.target), this.edgePanelManager.show(e.edge, e.sourceNode, e.targetNode), this.focusOnEdge(e.edge.source, e.edge.target), this.emit("edgeClick", e.edge, e.sourceNode, e.targetNode);
2623
+ }
2353
2624
  /**
2354
2625
  * Called every simulation step
2355
2626
  */
@@ -2381,7 +2652,7 @@ class Ot {
2381
2652
  if (e.edges && Array.isArray(e.edges))
2382
2653
  for (const s of e.edges)
2383
2654
  this.addEdge(s);
2384
- this.graphEngine = new Oe(
2655
+ this.graphEngine = new Le(
2385
2656
  this.nodeManager.getAllNodes(),
2386
2657
  this.edgeManager.getAllEdges(),
2387
2658
  {
@@ -2445,20 +2716,20 @@ class Ot {
2445
2716
  * @param fetchFn - Optional fetch function to override the default
2446
2717
  */
2447
2718
  async expandNode(e, s = 1, t) {
2448
- const i = t ?? this.options.onExpand;
2449
- if (!i)
2719
+ const n = t ?? this.options.onExpand;
2720
+ if (!n)
2450
2721
  return console.warn("[ForceGraph3D] No expand callback provided"), !1;
2451
2722
  try {
2452
- const n = await i(e, s);
2453
- if (n.nodes && Array.isArray(n.nodes))
2454
- for (const a of n.nodes)
2723
+ const o = await n(e, s);
2724
+ if (o.nodes && Array.isArray(o.nodes))
2725
+ for (const a of o.nodes)
2455
2726
  this.addNode(a);
2456
- if (n.edges && Array.isArray(n.edges))
2457
- for (const a of n.edges)
2727
+ if (o.edges && Array.isArray(o.edges))
2728
+ for (const a of o.edges)
2458
2729
  this.addEdge(a);
2459
- return this.panelManager.hide(), this.emit("expand", e, n), !0;
2460
- } catch (n) {
2461
- return console.error("[ForceGraph3D] Error expanding node:", n), !1;
2730
+ return this.panelManager.hide(), this.emit("expand", e, o), !0;
2731
+ } catch (o) {
2732
+ return console.error("[ForceGraph3D] Error expanding node:", o), !1;
2462
2733
  }
2463
2734
  }
2464
2735
  /**
@@ -2501,15 +2772,39 @@ class Ot {
2501
2772
  console.warn(`[ForceGraph3D] Node "${e}" not found`);
2502
2773
  return;
2503
2774
  }
2504
- const i = t.position, n = this.sceneManager.camera, a = this.sceneManager.controls, l = n.position.clone().sub(a.target).normalize(), d = {
2505
- x: i.x + l.x * s,
2506
- y: i.y + l.y * s,
2507
- z: i.z + l.z * s
2508
- }, u = { x: n.position.x, y: n.position.y, z: n.position.z }, g = { x: a.target.x, y: a.target.y, z: a.target.z }, b = 800, v = performance.now(), y = () => {
2509
- const f = performance.now() - v, M = Math.min(f / b, 1), C = 1 - Math.pow(1 - M, 3);
2510
- n.position.x = u.x + (d.x - u.x) * C, n.position.y = u.y + (d.y - u.y) * C, n.position.z = u.z + (d.z - u.z) * C, a.target.x = g.x + (i.x - g.x) * C, a.target.y = g.y + (i.y - g.y) * C, a.target.z = g.z + (i.z - g.z) * C, a.update(), M < 1 && requestAnimationFrame(y);
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);
2511
2782
  };
2512
- y();
2783
+ f();
2784
+ }
2785
+ /**
2786
+ * Focuses the camera on an edge (both source and target nodes) with smooth animation
2787
+ * Camera targets the midpoint and zooms out enough to see both nodes
2788
+ */
2789
+ focusOnEdge(e, s, t = 1.5) {
2790
+ const n = this.nodeManager.getNode(e), o = this.nodeManager.getNode(s);
2791
+ if (!n || !o) {
2792
+ console.warn(`[ForceGraph3D] Could not find nodes for edge "${e}" -> "${s}"`);
2793
+ return;
2794
+ }
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);
2806
+ };
2807
+ Y();
2513
2808
  }
2514
2809
  /**
2515
2810
  * Shows the info panel for a specific node
@@ -2530,28 +2825,28 @@ class Ot {
2530
2825
  searchNodes(e) {
2531
2826
  if (!e || e.trim() === "")
2532
2827
  return [];
2533
- const s = e.toLowerCase().trim(), t = this.nodeManager.getAllNodes(), i = [];
2534
- return t.forEach((n) => {
2535
- var u, g, b;
2536
- const a = (u = n.label) == null ? void 0 : u.toLowerCase().includes(s), l = (g = n.id) == null ? void 0 : g.toLowerCase().includes(s), d = (b = n.type) == null ? void 0 : b.toLowerCase().includes(s);
2537
- (a || l || d) && i.push(n);
2538
- }), i;
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;
2539
2834
  }
2540
2835
  /**
2541
2836
  * Searches edges by relationship (case-insensitive)
2542
2837
  * @returns Array of matching edges with source/target node info
2543
2838
  */
2544
2839
  searchEdges(e) {
2545
- var n;
2840
+ var o;
2546
2841
  if (!e || e.trim() === "")
2547
2842
  return [];
2548
- const s = e.toLowerCase().trim(), t = this.edgeManager.getAllEdges(), i = [];
2843
+ const s = e.toLowerCase().trim(), t = this.edgeManager.getAllEdges(), n = [];
2549
2844
  for (const a of t)
2550
- if ((n = a.relationship) == null ? void 0 : n.toLowerCase().includes(s)) {
2551
- const d = this.nodeManager.getNode(a.source), u = this.nodeManager.getNode(a.target);
2552
- d && u && i.push({ edge: a, sourceNode: d, targetNode: u });
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 });
2553
2848
  }
2554
- return i;
2849
+ return n;
2555
2850
  }
2556
2851
  /**
2557
2852
  * Gets all nodes as an array
@@ -2583,7 +2878,7 @@ class Ot {
2583
2878
  */
2584
2879
  emit(e, ...s) {
2585
2880
  const t = this.eventCallbacks.get(e);
2586
- t && t.forEach((i) => i(...s));
2881
+ t && t.forEach((n) => n(...s));
2587
2882
  }
2588
2883
  /**
2589
2884
  * Sets physics parameters
@@ -2660,17 +2955,17 @@ class Ot {
2660
2955
  `, this.container.appendChild(this.devControls);
2661
2956
  const e = this.devControls.querySelector("#dev-repulsion"), s = this.devControls.querySelector("#dev-attraction"), t = this.devControls.querySelector("#dev-damping");
2662
2957
  e == null || e.addEventListener("input", () => {
2663
- const i = parseFloat(e.value);
2664
- this.setPhysicsParams({ repulsionStrength: i }), this.devControls.querySelector("#dev-repulsion-val").textContent = i.toString();
2958
+ const n = parseFloat(e.value);
2959
+ this.setPhysicsParams({ repulsionStrength: n }), this.devControls.querySelector("#dev-repulsion-val").textContent = n.toString();
2665
2960
  }), s == null || s.addEventListener("input", () => {
2666
- const i = parseFloat(s.value) / 1e3;
2667
- this.setPhysicsParams({ attractionStrength: i }), this.devControls.querySelector("#dev-attraction-val").textContent = i.toFixed(3);
2961
+ const n = parseFloat(s.value) / 1e3;
2962
+ this.setPhysicsParams({ attractionStrength: n }), this.devControls.querySelector("#dev-attraction-val").textContent = n.toFixed(3);
2668
2963
  }), t == null || t.addEventListener("input", () => {
2669
- const i = parseFloat(t.value) / 100;
2670
- this.setPhysicsParams({ damping: i }), this.devControls.querySelector("#dev-damping-val").textContent = i.toFixed(2);
2964
+ const n = parseFloat(t.value) / 100;
2965
+ this.setPhysicsParams({ damping: n }), this.devControls.querySelector("#dev-damping-val").textContent = n.toFixed(2);
2671
2966
  }), setInterval(() => {
2672
- const i = this.devControls.querySelector("#dev-node-count"), n = this.devControls.querySelector("#dev-edge-count"), a = this.devControls.querySelector("#dev-fps");
2673
- i && (i.textContent = this.getNodeCount().toString()), n && (n.textContent = this.getEdgeCount().toString()), a && (a.textContent = this.rendererManager.getFPS().toString());
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());
2674
2969
  }, 500);
2675
2970
  }
2676
2971
  /**
@@ -2680,7 +2975,7 @@ class Ot {
2680
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;
2681
2976
  }
2682
2977
  }
2683
- const ke = [
2978
+ const Oe = [
2684
2979
  "Alpha",
2685
2980
  "Beta",
2686
2981
  "Gamma",
@@ -2711,7 +3006,7 @@ const ke = [
2711
3006
  "Link",
2712
3007
  "Point",
2713
3008
  "Vertex"
2714
- ], Q = [
3009
+ ], J = [
2715
3010
  "connects to",
2716
3011
  "links with",
2717
3012
  "relates to",
@@ -2734,14 +3029,14 @@ const ke = [
2734
3029
  16746564
2735
3030
  // Darker tangerine
2736
3031
  ];
2737
- function kt(c = 30) {
3032
+ function It(c = 30) {
2738
3033
  const e = [], s = [];
2739
- for (let i = 0; i < c; i++) {
2740
- const n = i < ke.length ? ke[i] : `Node ${i + 1}`;
3034
+ for (let n = 0; n < c; n++) {
3035
+ const o = n < Oe.length ? Oe[n] : `Node ${n + 1}`;
2741
3036
  e.push({
2742
- id: `node-${i}`,
2743
- label: n,
2744
- color: Ie[i % Ie.length],
3037
+ id: `node-${n}`,
3038
+ label: o,
3039
+ color: Ie[n % Ie.length],
2745
3040
  position: {
2746
3041
  x: (Math.random() - 0.5) * 60,
2747
3042
  y: (Math.random() - 0.5) * 60,
@@ -2749,43 +3044,43 @@ function kt(c = 30) {
2749
3044
  }
2750
3045
  });
2751
3046
  }
2752
- for (let i = 1; i < c; i++) {
2753
- const n = Math.floor(Math.random() * i);
3047
+ for (let n = 1; n < c; n++) {
3048
+ const o = Math.floor(Math.random() * n);
2754
3049
  s.push({
2755
- source: `node-${i}`,
2756
- target: `node-${n}`,
2757
- relationship: Q[Math.floor(Math.random() * Q.length)]
3050
+ source: `node-${n}`,
3051
+ target: `node-${o}`,
3052
+ relationship: J[Math.floor(Math.random() * J.length)]
2758
3053
  });
2759
3054
  }
2760
3055
  const t = Math.floor(c * 0.5);
2761
- for (let i = 0; i < t; i++) {
2762
- const n = Math.floor(Math.random() * c);
3056
+ for (let n = 0; n < t; n++) {
3057
+ const o = Math.floor(Math.random() * c);
2763
3058
  let a = Math.floor(Math.random() * c);
2764
- n === a && (a = (a + 1) % c);
2765
- const l = `node-${n}`, d = `node-${a}`;
3059
+ o === a && (a = (a + 1) % c);
3060
+ const l = `node-${o}`, h = `node-${a}`;
2766
3061
  s.some(
2767
- (g) => g.source === l && g.target === d || g.source === d && g.target === l
3062
+ (u) => u.source === l && u.target === h || u.source === h && u.target === l
2768
3063
  ) || s.push({
2769
3064
  source: l,
2770
- target: d,
2771
- relationship: Q[Math.floor(Math.random() * Q.length)]
3065
+ target: h,
3066
+ relationship: J[Math.floor(Math.random() * J.length)]
2772
3067
  });
2773
3068
  }
2774
3069
  return { nodes: e, edges: s };
2775
3070
  }
2776
- function It(c = 1e3) {
2777
- const e = [], s = [], t = Math.ceil(c / 50), i = [];
2778
- for (let n = 0; n < t; n++)
2779
- i.push({
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({
2780
3075
  x: (Math.random() - 0.5) * 200,
2781
3076
  y: (Math.random() - 0.5) * 200,
2782
3077
  z: (Math.random() - 0.5) * 200
2783
3078
  });
2784
- for (let n = 0; n < c; n++) {
2785
- const a = i[n % t];
3079
+ for (let o = 0; o < c; o++) {
3080
+ const a = n[o % t];
2786
3081
  e.push({
2787
- id: `node-${n}`,
2788
- label: `N${n}`,
3082
+ id: `node-${o}`,
3083
+ label: `N${o}`,
2789
3084
  position: {
2790
3085
  x: a.x + (Math.random() - 0.5) * 40,
2791
3086
  y: a.y + (Math.random() - 0.5) * 40,
@@ -2793,16 +3088,16 @@ function It(c = 1e3) {
2793
3088
  }
2794
3089
  });
2795
3090
  }
2796
- for (let n = 1; n < c; n++) {
2797
- const a = Math.floor(n / 50) * 50, l = a === 0 ? Math.floor(Math.random() * n) : a + Math.floor(Math.random() * Math.min(n - a, 50));
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));
2798
3093
  s.push({
2799
- source: `node-${n}`,
2800
- target: `node-${Math.min(l, n - 1)}`,
3094
+ source: `node-${o}`,
3095
+ target: `node-${Math.min(l, o - 1)}`,
2801
3096
  relationship: "links to"
2802
3097
  });
2803
3098
  }
2804
- for (let n = 1; n < t; n++) {
2805
- const a = n * 50, l = (n - 1) * 50 + Math.floor(Math.random() * 50);
3099
+ for (let o = 1; o < t; o++) {
3100
+ const a = o * 50, l = (o - 1) * 50 + Math.floor(Math.random() * 50);
2806
3101
  s.push({
2807
3102
  source: `node-${a}`,
2808
3103
  target: `node-${l}`,
@@ -2812,12 +3107,12 @@ function It(c = 1e3) {
2812
3107
  return { nodes: e, edges: s };
2813
3108
  }
2814
3109
  export {
2815
- L as DEFAULT_OPTIONS,
3110
+ I as DEFAULT_OPTIONS,
2816
3111
  Ot as ForceGraph3D,
2817
- U as LODLevel,
2818
- R as createEdgeKey,
2819
- It as generateLargeSampleData,
2820
- kt as generateSampleData,
3112
+ X as LODLevel,
3113
+ A as createEdgeKey,
3114
+ Rt as generateLargeSampleData,
3115
+ It as generateSampleData,
2821
3116
  Fe as validateEdgeData,
2822
3117
  Re as validateNodeData
2823
3118
  };