force-3d-graph 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,9 @@
1
- var ot = Object.defineProperty;
2
- var nt = (c, e, o) => e in c ? ot(c, e, { enumerable: !0, configurable: !0, writable: !0, value: o }) : c[e] = o;
3
- var r = (c, e, o) => nt(c, typeof e != "symbol" ? e + "" : e, o);
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);
4
4
  import * as p from "three";
5
- import { EventDispatcher as it, Vector3 as N, MOUSE as H, TOUCH as K, Spherical as Ne, Quaternion as ze, Vector2 as S, Ray as st, Plane as at, MathUtils as rt } from "three";
6
- const O = {
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 = {
7
7
  backgroundColor: 657930,
8
8
  cameraPosition: { x: 0, y: 0, z: 80 },
9
9
  cameraFov: 75,
@@ -23,10 +23,12 @@ const O = {
23
23
  edgeOpacity: 0.4,
24
24
  enableEdgeCulling: !0,
25
25
  showPanel: !0,
26
+ showSearch: !0,
27
+ searchPlaceholder: "Search nodes or relationships...",
26
28
  targetFPS: 60,
27
29
  maxVisibleNodes: 1e4
28
30
  };
29
- var _ = /* @__PURE__ */ ((c) => (c[c.HIGH = 0] = "HIGH", c[c.MEDIUM = 1] = "MEDIUM", c[c.LOW = 2] = "LOW", c))(_ || {});
31
+ var U = /* @__PURE__ */ ((c) => (c[c.HIGH = 0] = "HIGH", c[c.MEDIUM = 1] = "MEDIUM", c[c.LOW = 2] = "LOW", c))(U || {});
30
32
  function lt() {
31
33
  const c = document.createElement("div");
32
34
  return c.id = "force-graph-3d-container", c.style.cssText = `
@@ -41,20 +43,20 @@ function lt() {
41
43
  function ct(c) {
42
44
  return c && c instanceof HTMLElement ? c : (console.warn("[ForceGraph3D] No container provided, creating one automatically"), lt());
43
45
  }
44
- function Se(c) {
46
+ function ze(c) {
45
47
  const e = c.getBoundingClientRect();
46
48
  return {
47
49
  width: e.width || window.innerWidth,
48
50
  height: e.height || window.innerHeight
49
51
  };
50
52
  }
51
- function Ie(c) {
53
+ function Re(c) {
52
54
  if (!c || typeof c != "object")
53
55
  return console.warn("[ForceGraph3D] Invalid node: must be an object"), !1;
54
56
  const e = c;
55
57
  return typeof e.id != "string" || e.id.trim() === "" ? (console.warn("[ForceGraph3D] Invalid node: id must be a non-empty string"), !1) : typeof e.label != "string" ? (console.warn("[ForceGraph3D] Invalid node: label must be a string"), !1) : e.color !== void 0 && typeof e.color != "number" ? (console.warn("[ForceGraph3D] Invalid node: color must be a number (hex)"), !1) : e.position !== void 0 && !dt(e.position) ? (console.warn("[ForceGraph3D] Invalid node: position must have x, y, z numbers"), !1) : !0;
56
58
  }
57
- function Re(c) {
59
+ function Fe(c) {
58
60
  if (!c || typeof c != "object")
59
61
  return console.warn("[ForceGraph3D] Invalid edge: must be an object"), !1;
60
62
  const e = c;
@@ -68,56 +70,56 @@ function dt(c) {
68
70
  const e = c;
69
71
  return typeof e.x == "number" && typeof e.y == "number" && typeof e.z == "number";
70
72
  }
71
- function I(c, e) {
73
+ function R(c, e) {
72
74
  return c === e ? `${c}-${e}` : c < e ? `${c}-${e}` : `${e}-${c}`;
73
75
  }
74
- const Pe = { type: "change" }, ae = { type: "start" }, Te = { type: "end" }, Z = new st(), Oe = new at(), pt = Math.cos(70 * rt.DEG2RAD);
75
- class gt extends it {
76
- constructor(e, o) {
77
- super(), this.object = e, this.domElement = o, 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: H.ROTATE, MIDDLE: H.DOLLY, RIGHT: H.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() {
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 {
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() {
78
80
  return l.phi;
79
81
  }, this.getAzimuthalAngle = function() {
80
82
  return l.theta;
81
83
  }, this.getDistance = function() {
82
84
  return this.object.position.distanceTo(this.target);
83
- }, this.listenToKeyEvents = function(s) {
84
- s.addEventListener("keydown", ie), this._domElementKeyEvents = s;
85
+ }, this.listenToKeyEvents = function(o) {
86
+ o.addEventListener("keydown", ne), this._domElementKeyEvents = o;
85
87
  }, this.stopListenToKeyEvents = function() {
86
- this._domElementKeyEvents.removeEventListener("keydown", ie), this._domElementKeyEvents = null;
88
+ this._domElementKeyEvents.removeEventListener("keydown", ne), this._domElementKeyEvents = null;
87
89
  }, this.saveState = function() {
88
90
  t.target0.copy(t.target), t.position0.copy(t.object.position), t.zoom0 = t.object.zoom;
89
91
  }, this.reset = function() {
90
- t.target.copy(t.target0), t.object.position.copy(t.position0), t.object.zoom = t.zoom0, t.object.updateProjectionMatrix(), t.dispatchEvent(Pe), t.update(), i = n.NONE;
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;
91
93
  }, this.update = function() {
92
- const s = new N(), h = new ze().setFromUnitVectors(e.up, new N(0, 1, 0)), m = h.clone().invert(), b = new N(), E = new ze(), F = new N(), z = 2 * Math.PI;
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;
93
95
  return function(tt = null) {
94
96
  const Ce = t.object.position;
95
- s.copy(Ce).sub(t.target), s.applyQuaternion(h), l.setFromVector3(s), t.autoRotate && i === n.NONE && G(Ae(tt)), t.enableDamping ? (l.theta += d.theta * t.dampingFactor, l.phi += d.phi * t.dampingFactor) : (l.theta += d.theta, l.phi += d.phi);
96
- let P = t.minAzimuthAngle, T = t.maxAzimuthAngle;
97
- isFinite(P) && isFinite(T) && (P < -Math.PI ? P += z : P > Math.PI && (P -= z), T < -Math.PI ? T += z : T > Math.PI && (T -= z), P <= T ? l.theta = Math.max(P, Math.min(T, l.theta)) : l.theta = l.theta > (P + T) / 2 ? Math.max(P, l.theta) : Math.min(T, 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 && U || t.object.isOrthographicCamera ? l.radius = oe(l.radius) : l.radius = oe(l.radius * g), s.setFromSpherical(l), s.applyQuaternion(m), Ce.copy(t.target).add(s), t.object.lookAt(t.target), t.enableDamping === !0 ? (d.theta *= 1 - t.dampingFactor, d.phi *= 1 - t.dampingFactor, u.multiplyScalar(1 - t.dampingFactor)) : (d.set(0, 0, 0), u.set(0, 0, 0));
98
- let se = !1;
99
- if (t.zoomToCursor && U) {
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 && _) {
100
102
  let Y = null;
101
103
  if (t.object.isPerspectiveCamera) {
102
- const B = s.length();
103
- Y = oe(B * g);
104
+ const B = o.length();
105
+ Y = se(B * u);
104
106
  const q = B - Y;
105
107
  t.object.position.addScaledVector(re, q), t.object.updateMatrixWorld();
106
108
  } else if (t.object.isOrthographicCamera) {
107
- const B = new N(L.x, L.y, 0);
108
- B.unproject(t.object), t.object.zoom = Math.max(t.minZoom, Math.min(t.maxZoom, t.object.zoom / g)), t.object.updateProjectionMatrix(), se = !0;
109
- const q = new N(L.x, L.y, 0);
110
- q.unproject(t.object), t.object.position.sub(q).add(B), t.object.updateMatrixWorld(), Y = s.length();
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();
111
113
  } else
112
114
  console.warn("WARNING: OrbitControls.js encountered an unknown camera type - zoom to cursor disabled."), t.zoomToCursor = !1;
113
- 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) : (Oe.setFromNormalAndCoplanarPoint(t.object.up, t.target), Z.intersectPlane(Oe, t.target))));
114
- } else t.object.isOrthographicCamera && (t.object.zoom = Math.max(t.minZoom, Math.min(t.maxZoom, t.object.zoom / g)), t.object.updateProjectionMatrix(), se = !0);
115
- return g = 1, U = !1, se || b.distanceToSquared(t.object.position) > a || 8 * (1 - E.dot(t.object.quaternion)) > a || F.distanceToSquared(t.target) > 0 ? (t.dispatchEvent(Pe), b.copy(t.object.position), E.copy(t.object.quaternion), F.copy(t.target), !0) : !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;
116
118
  };
117
119
  }(), this.dispose = function() {
118
- t.domElement.removeEventListener("contextmenu", Ee), t.domElement.removeEventListener("pointerdown", be), t.domElement.removeEventListener("pointercancel", $), t.domElement.removeEventListener("wheel", ve), t.domElement.removeEventListener("pointermove", ne), t.domElement.removeEventListener("pointerup", $), t._domElementKeyEvents !== null && (t._domElementKeyEvents.removeEventListener("keydown", ie), t._domElementKeyEvents = null);
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);
119
121
  };
120
- const t = this, n = {
122
+ const t = this, i = {
121
123
  NONE: -1,
122
124
  ROTATE: 0,
123
125
  DOLLY: 1,
@@ -127,175 +129,175 @@ class gt extends it {
127
129
  TOUCH_DOLLY_PAN: 5,
128
130
  TOUCH_DOLLY_ROTATE: 6
129
131
  };
130
- let i = n.NONE;
132
+ let n = i.NONE;
131
133
  const a = 1e-6, l = new Ne(), d = new Ne();
132
- let g = 1;
133
- const u = new N(), x = new S(), v = new S(), y = new S(), f = new S(), M = new S(), C = new S(), R = new S(), A = new S(), k = new S(), re = new N(), L = new S();
134
- let U = !1;
135
- const w = [], V = {};
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 = {};
136
138
  let J = !1;
137
- function Ae(s) {
138
- return s !== null ? 2 * Math.PI / 60 * t.autoRotateSpeed * s : 2 * Math.PI / 60 / 60 * t.autoRotateSpeed;
139
+ function He(o) {
140
+ return o !== null ? 2 * Math.PI / 60 * t.autoRotateSpeed * o : 2 * Math.PI / 60 / 60 * t.autoRotateSpeed;
139
141
  }
140
- function X(s) {
141
- const h = Math.abs(s * 0.01);
142
+ function X(o) {
143
+ const h = Math.abs(o * 0.01);
142
144
  return Math.pow(0.95, t.zoomSpeed * h);
143
145
  }
144
- function G(s) {
145
- d.theta -= s;
146
+ function K(o) {
147
+ d.theta -= o;
146
148
  }
147
- function W(s) {
148
- d.phi -= s;
149
+ function W(o) {
150
+ d.phi -= o;
149
151
  }
150
152
  const le = function() {
151
- const s = new N();
152
- return function(m, b) {
153
- s.setFromMatrixColumn(b, 0), s.multiplyScalar(-m), u.add(s);
153
+ const o = new N();
154
+ return function(m, x) {
155
+ o.setFromMatrixColumn(x, 0), o.multiplyScalar(-m), g.add(o);
154
156
  };
155
157
  }(), ce = function() {
156
- const s = new N();
157
- return function(m, b) {
158
- t.screenSpacePanning === !0 ? s.setFromMatrixColumn(b, 1) : (s.setFromMatrixColumn(b, 0), s.crossVectors(t.object.up, s)), s.multiplyScalar(m), u.add(s);
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);
159
161
  };
160
- }(), j = function() {
161
- const s = new N();
162
- return function(m, b) {
163
- const E = t.domElement;
162
+ }(), A = function() {
163
+ const o = new N();
164
+ return function(m, x) {
165
+ const w = t.domElement;
164
166
  if (t.object.isPerspectiveCamera) {
165
- const F = t.object.position;
166
- s.copy(F).sub(t.target);
167
- let z = s.length();
168
- z *= Math.tan(t.object.fov / 2 * Math.PI / 180), le(2 * m * z / E.clientHeight, t.object.matrix), ce(2 * b * z / E.clientHeight, t.object.matrix);
169
- } else t.object.isOrthographicCamera ? (le(m * (t.object.right - t.object.left) / t.object.zoom / E.clientWidth, t.object.matrix), ce(b * (t.object.top - t.object.bottom) / t.object.zoom / E.clientHeight, t.object.matrix)) : (console.warn("WARNING: OrbitControls.js encountered an unknown camera type - pan disabled."), t.enablePan = !1);
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);
170
172
  };
171
173
  }();
172
- function ee(s) {
173
- t.object.isPerspectiveCamera || t.object.isOrthographicCamera ? g /= s : (console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."), t.enableZoom = !1);
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
176
  }
175
- function he(s) {
176
- t.object.isPerspectiveCamera || t.object.isOrthographicCamera ? g *= s : (console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."), t.enableZoom = !1);
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
179
  }
178
- function te(s, h) {
180
+ function te(o, h) {
179
181
  if (!t.zoomToCursor)
180
182
  return;
181
- U = !0;
182
- const m = t.domElement.getBoundingClientRect(), b = s - m.left, E = h - m.top, F = m.width, z = m.height;
183
- L.x = b / F * 2 - 1, L.y = -(E / z) * 2 + 1, re.set(L.x, L.y, 1).unproject(t.object).sub(t.object.position).normalize();
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();
184
186
  }
185
- function oe(s) {
186
- return Math.max(t.minDistance, Math.min(t.maxDistance, s));
187
+ function se(o) {
188
+ return Math.max(t.minDistance, Math.min(t.maxDistance, o));
187
189
  }
188
- function de(s) {
189
- x.set(s.clientX, s.clientY);
190
+ function de(o) {
191
+ b.set(o.clientX, o.clientY);
190
192
  }
191
- function je(s) {
192
- te(s.clientX, s.clientX), R.set(s.clientX, s.clientY);
193
+ function Ae(o) {
194
+ te(o.clientX, o.clientX), F.set(o.clientX, o.clientY);
193
195
  }
194
- function pe(s) {
195
- f.set(s.clientX, s.clientY);
196
+ function pe(o) {
197
+ f.set(o.clientX, o.clientY);
196
198
  }
197
- function De(s) {
198
- v.set(s.clientX, s.clientY), y.subVectors(v, x).multiplyScalar(t.rotateSpeed);
199
+ function je(o) {
200
+ v.set(o.clientX, o.clientY), y.subVectors(v, b).multiplyScalar(t.rotateSpeed);
199
201
  const h = t.domElement;
200
- G(2 * Math.PI * y.x / h.clientHeight), W(2 * Math.PI * y.y / h.clientHeight), x.copy(v), t.update();
202
+ K(2 * Math.PI * y.x / h.clientHeight), W(2 * Math.PI * y.y / h.clientHeight), b.copy(v), t.update();
201
203
  }
202
- function He(s) {
203
- A.set(s.clientX, s.clientY), k.subVectors(A, R), k.y > 0 ? ee(X(k.y)) : k.y < 0 && he(X(k.y)), R.copy(A), t.update();
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
206
  }
205
- function Ke(s) {
206
- M.set(s.clientX, s.clientY), C.subVectors(M, f).multiplyScalar(t.panSpeed), j(C.x, C.y), f.copy(M), t.update();
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
209
  }
208
- function Ge(s) {
209
- te(s.clientX, s.clientY), s.deltaY < 0 ? he(X(s.deltaY)) : s.deltaY > 0 && ee(X(s.deltaY)), t.update();
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
212
  }
211
- function $e(s) {
213
+ function Ge(o) {
212
214
  let h = !1;
213
- switch (s.code) {
215
+ switch (o.code) {
214
216
  case t.keys.UP:
215
- s.ctrlKey || s.metaKey || s.shiftKey ? W(2 * Math.PI * t.rotateSpeed / t.domElement.clientHeight) : j(0, t.keyPanSpeed), h = !0;
217
+ o.ctrlKey || o.metaKey || o.shiftKey ? W(2 * Math.PI * t.rotateSpeed / t.domElement.clientHeight) : A(0, t.keyPanSpeed), h = !0;
216
218
  break;
217
219
  case t.keys.BOTTOM:
218
- s.ctrlKey || s.metaKey || s.shiftKey ? W(-2 * Math.PI * t.rotateSpeed / t.domElement.clientHeight) : j(0, -t.keyPanSpeed), h = !0;
220
+ o.ctrlKey || o.metaKey || o.shiftKey ? W(-2 * Math.PI * t.rotateSpeed / t.domElement.clientHeight) : A(0, -t.keyPanSpeed), h = !0;
219
221
  break;
220
222
  case t.keys.LEFT:
221
- s.ctrlKey || s.metaKey || s.shiftKey ? G(2 * Math.PI * t.rotateSpeed / t.domElement.clientHeight) : j(t.keyPanSpeed, 0), h = !0;
223
+ o.ctrlKey || o.metaKey || o.shiftKey ? K(2 * Math.PI * t.rotateSpeed / t.domElement.clientHeight) : A(t.keyPanSpeed, 0), h = !0;
222
224
  break;
223
225
  case t.keys.RIGHT:
224
- s.ctrlKey || s.metaKey || s.shiftKey ? G(-2 * Math.PI * t.rotateSpeed / t.domElement.clientHeight) : j(-t.keyPanSpeed, 0), h = !0;
226
+ o.ctrlKey || o.metaKey || o.shiftKey ? K(-2 * Math.PI * t.rotateSpeed / t.domElement.clientHeight) : A(-t.keyPanSpeed, 0), h = !0;
225
227
  break;
226
228
  }
227
- h && (s.preventDefault(), t.update());
229
+ h && (o.preventDefault(), t.update());
228
230
  }
229
- function ge(s) {
230
- if (w.length === 1)
231
- x.set(s.pageX, s.pageY);
231
+ function ue(o) {
232
+ if (E.length === 1)
233
+ b.set(o.pageX, o.pageY);
232
234
  else {
233
- const h = D(s), m = 0.5 * (s.pageX + h.x), b = 0.5 * (s.pageY + h.y);
234
- x.set(m, b);
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
237
  }
236
238
  }
237
- function ue(s) {
238
- if (w.length === 1)
239
- f.set(s.pageX, s.pageY);
239
+ function ge(o) {
240
+ if (E.length === 1)
241
+ f.set(o.pageX, o.pageY);
240
242
  else {
241
- const h = D(s), m = 0.5 * (s.pageX + h.x), b = 0.5 * (s.pageY + h.y);
242
- f.set(m, b);
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
245
  }
244
246
  }
245
- function me(s) {
246
- const h = D(s), m = s.pageX - h.x, b = s.pageY - h.y, E = Math.sqrt(m * m + b * b);
247
- R.set(0, E);
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);
248
250
  }
249
- function Ye(s) {
250
- t.enableZoom && me(s), t.enablePan && ue(s);
251
+ function Ye(o) {
252
+ t.enableZoom && me(o), t.enablePan && ge(o);
251
253
  }
252
- function Be(s) {
253
- t.enableZoom && me(s), t.enableRotate && ge(s);
254
+ function Be(o) {
255
+ t.enableZoom && me(o), t.enableRotate && ue(o);
254
256
  }
255
- function fe(s) {
256
- if (w.length == 1)
257
- v.set(s.pageX, s.pageY);
257
+ function fe(o) {
258
+ if (E.length == 1)
259
+ v.set(o.pageX, o.pageY);
258
260
  else {
259
- const m = D(s), b = 0.5 * (s.pageX + m.x), E = 0.5 * (s.pageY + m.y);
260
- v.set(b, E);
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
263
  }
262
- y.subVectors(v, x).multiplyScalar(t.rotateSpeed);
264
+ y.subVectors(v, b).multiplyScalar(t.rotateSpeed);
263
265
  const h = t.domElement;
264
- G(2 * Math.PI * y.x / h.clientHeight), W(2 * Math.PI * y.y / h.clientHeight), x.copy(v);
266
+ K(2 * Math.PI * y.x / h.clientHeight), W(2 * Math.PI * y.y / h.clientHeight), b.copy(v);
265
267
  }
266
- function ye(s) {
267
- if (w.length === 1)
268
- M.set(s.pageX, s.pageY);
268
+ function ye(o) {
269
+ if (E.length === 1)
270
+ M.set(o.pageX, o.pageY);
269
271
  else {
270
- const h = D(s), m = 0.5 * (s.pageX + h.x), b = 0.5 * (s.pageY + h.y);
271
- M.set(m, b);
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
274
  }
273
- C.subVectors(M, f).multiplyScalar(t.panSpeed), j(C.x, C.y), f.copy(M);
275
+ C.subVectors(M, f).multiplyScalar(t.panSpeed), A(C.x, C.y), f.copy(M);
274
276
  }
275
- function xe(s) {
276
- const h = D(s), m = s.pageX - h.x, b = s.pageY - h.y, E = Math.sqrt(m * m + b * b);
277
- A.set(0, E), k.set(0, Math.pow(A.y / R.y, t.zoomSpeed)), ee(k.y), R.copy(A);
278
- const F = (s.pageX + h.x) * 0.5, z = (s.pageY + h.y) * 0.5;
279
- te(F, z);
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);
280
282
  }
281
- function _e(s) {
282
- t.enableZoom && xe(s), t.enablePan && ye(s);
283
+ function Ue(o) {
284
+ t.enableZoom && be(o), t.enablePan && ye(o);
283
285
  }
284
- function Ue(s) {
285
- t.enableZoom && xe(s), t.enableRotate && fe(s);
286
+ function _e(o) {
287
+ t.enableZoom && be(o), t.enableRotate && fe(o);
286
288
  }
287
- function be(s) {
288
- t.enabled !== !1 && (w.length === 0 && (t.domElement.setPointerCapture(s.pointerId), t.domElement.addEventListener("pointermove", ne), t.domElement.addEventListener("pointerup", $)), Je(s), s.pointerType === "touch" ? Ze(s) : Ve(s));
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
291
  }
290
- function ne(s) {
291
- t.enabled !== !1 && (s.pointerType === "touch" ? Qe(s) : Xe(s));
292
+ function ie(o) {
293
+ t.enabled !== !1 && (o.pointerType === "touch" ? Qe(o) : Xe(o));
292
294
  }
293
- function $(s) {
294
- et(s), w.length === 0 && (t.domElement.releasePointerCapture(s.pointerId), t.domElement.removeEventListener("pointermove", ne), t.domElement.removeEventListener("pointerup", $)), t.dispatchEvent(Te), i = n.NONE;
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
297
  }
296
- function Ve(s) {
298
+ function Ve(o) {
297
299
  let h;
298
- switch (s.button) {
300
+ switch (o.button) {
299
301
  case 0:
300
302
  h = t.mouseButtons.LEFT;
301
303
  break;
@@ -309,57 +311,57 @@ class gt extends it {
309
311
  h = -1;
310
312
  }
311
313
  switch (h) {
312
- case H.DOLLY:
314
+ case D.DOLLY:
313
315
  if (t.enableZoom === !1) return;
314
- je(s), i = n.DOLLY;
316
+ Ae(o), n = i.DOLLY;
315
317
  break;
316
- case H.ROTATE:
317
- if (s.ctrlKey || s.metaKey || s.shiftKey) {
318
+ case D.ROTATE:
319
+ if (o.ctrlKey || o.metaKey || o.shiftKey) {
318
320
  if (t.enablePan === !1) return;
319
- pe(s), i = n.PAN;
321
+ pe(o), n = i.PAN;
320
322
  } else {
321
323
  if (t.enableRotate === !1) return;
322
- de(s), i = n.ROTATE;
324
+ de(o), n = i.ROTATE;
323
325
  }
324
326
  break;
325
- case H.PAN:
326
- if (s.ctrlKey || s.metaKey || s.shiftKey) {
327
+ case D.PAN:
328
+ if (o.ctrlKey || o.metaKey || o.shiftKey) {
327
329
  if (t.enableRotate === !1) return;
328
- de(s), i = n.ROTATE;
330
+ de(o), n = i.ROTATE;
329
331
  } else {
330
332
  if (t.enablePan === !1) return;
331
- pe(s), i = n.PAN;
333
+ pe(o), n = i.PAN;
332
334
  }
333
335
  break;
334
336
  default:
335
- i = n.NONE;
337
+ n = i.NONE;
336
338
  }
337
- i !== n.NONE && t.dispatchEvent(ae);
339
+ n !== i.NONE && t.dispatchEvent(ae);
338
340
  }
339
- function Xe(s) {
340
- switch (i) {
341
- case n.ROTATE:
341
+ function Xe(o) {
342
+ switch (n) {
343
+ case i.ROTATE:
342
344
  if (t.enableRotate === !1) return;
343
- De(s);
345
+ je(o);
344
346
  break;
345
- case n.DOLLY:
347
+ case i.DOLLY:
346
348
  if (t.enableZoom === !1) return;
347
- He(s);
349
+ De(o);
348
350
  break;
349
- case n.PAN:
351
+ case i.PAN:
350
352
  if (t.enablePan === !1) return;
351
- Ke(s);
353
+ $e(o);
352
354
  break;
353
355
  }
354
356
  }
355
- function ve(s) {
356
- t.enabled === !1 || t.enableZoom === !1 || i !== n.NONE || (s.preventDefault(), t.dispatchEvent(ae), Ge(We(s)), t.dispatchEvent(Te));
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
359
  }
358
- function We(s) {
359
- const h = s.deltaMode, m = {
360
- clientX: s.clientX,
361
- clientY: s.clientY,
362
- deltaY: s.deltaY
360
+ function We(o) {
361
+ const h = o.deltaMode, m = {
362
+ clientX: o.clientX,
363
+ clientY: o.clientY,
364
+ deltaY: o.deltaY
363
365
  };
364
366
  switch (h) {
365
367
  case 1:
@@ -369,101 +371,101 @@ class gt extends it {
369
371
  m.deltaY *= 100;
370
372
  break;
371
373
  }
372
- return s.ctrlKey && !J && (m.deltaY *= 10), m;
374
+ return o.ctrlKey && !J && (m.deltaY *= 10), m;
373
375
  }
374
- function qe(s) {
375
- s.key === "Control" && (J = !0, document.addEventListener("keyup", Me, { passive: !0, capture: !0 }));
376
+ function qe(o) {
377
+ o.key === "Control" && (J = !0, document.addEventListener("keyup", Me, { passive: !0, capture: !0 }));
376
378
  }
377
- function Me(s) {
378
- s.key === "Control" && (J = !1, document.removeEventListener("keyup", Me, { passive: !0, capture: !0 }));
379
+ function Me(o) {
380
+ o.key === "Control" && (J = !1, document.removeEventListener("keyup", Me, { passive: !0, capture: !0 }));
379
381
  }
380
- function ie(s) {
381
- t.enabled === !1 || t.enablePan === !1 || $e(s);
382
+ function ne(o) {
383
+ t.enabled === !1 || t.enablePan === !1 || Ge(o);
382
384
  }
383
- function Ze(s) {
384
- switch (we(s), w.length) {
385
+ function Ze(o) {
386
+ switch (Ee(o), E.length) {
385
387
  case 1:
386
388
  switch (t.touches.ONE) {
387
- case K.ROTATE:
389
+ case $.ROTATE:
388
390
  if (t.enableRotate === !1) return;
389
- ge(s), i = n.TOUCH_ROTATE;
391
+ ue(o), n = i.TOUCH_ROTATE;
390
392
  break;
391
- case K.PAN:
393
+ case $.PAN:
392
394
  if (t.enablePan === !1) return;
393
- ue(s), i = n.TOUCH_PAN;
395
+ ge(o), n = i.TOUCH_PAN;
394
396
  break;
395
397
  default:
396
- i = n.NONE;
398
+ n = i.NONE;
397
399
  }
398
400
  break;
399
401
  case 2:
400
402
  switch (t.touches.TWO) {
401
- case K.DOLLY_PAN:
403
+ case $.DOLLY_PAN:
402
404
  if (t.enableZoom === !1 && t.enablePan === !1) return;
403
- Ye(s), i = n.TOUCH_DOLLY_PAN;
405
+ Ye(o), n = i.TOUCH_DOLLY_PAN;
404
406
  break;
405
- case K.DOLLY_ROTATE:
407
+ case $.DOLLY_ROTATE:
406
408
  if (t.enableZoom === !1 && t.enableRotate === !1) return;
407
- Be(s), i = n.TOUCH_DOLLY_ROTATE;
409
+ Be(o), n = i.TOUCH_DOLLY_ROTATE;
408
410
  break;
409
411
  default:
410
- i = n.NONE;
412
+ n = i.NONE;
411
413
  }
412
414
  break;
413
415
  default:
414
- i = n.NONE;
416
+ n = i.NONE;
415
417
  }
416
- i !== n.NONE && t.dispatchEvent(ae);
418
+ n !== i.NONE && t.dispatchEvent(ae);
417
419
  }
418
- function Qe(s) {
419
- switch (we(s), i) {
420
- case n.TOUCH_ROTATE:
420
+ function Qe(o) {
421
+ switch (Ee(o), n) {
422
+ case i.TOUCH_ROTATE:
421
423
  if (t.enableRotate === !1) return;
422
- fe(s), t.update();
424
+ fe(o), t.update();
423
425
  break;
424
- case n.TOUCH_PAN:
426
+ case i.TOUCH_PAN:
425
427
  if (t.enablePan === !1) return;
426
- ye(s), t.update();
428
+ ye(o), t.update();
427
429
  break;
428
- case n.TOUCH_DOLLY_PAN:
430
+ case i.TOUCH_DOLLY_PAN:
429
431
  if (t.enableZoom === !1 && t.enablePan === !1) return;
430
- _e(s), t.update();
432
+ Ue(o), t.update();
431
433
  break;
432
- case n.TOUCH_DOLLY_ROTATE:
434
+ case i.TOUCH_DOLLY_ROTATE:
433
435
  if (t.enableZoom === !1 && t.enableRotate === !1) return;
434
- Ue(s), t.update();
436
+ _e(o), t.update();
435
437
  break;
436
438
  default:
437
- i = n.NONE;
439
+ n = i.NONE;
438
440
  }
439
441
  }
440
- function Ee(s) {
441
- t.enabled !== !1 && s.preventDefault();
442
+ function we(o) {
443
+ t.enabled !== !1 && o.preventDefault();
442
444
  }
443
- function Je(s) {
444
- w.push(s.pointerId);
445
+ function Je(o) {
446
+ E.push(o.pointerId);
445
447
  }
446
- function et(s) {
447
- delete V[s.pointerId];
448
- for (let h = 0; h < w.length; h++)
449
- if (w[h] == s.pointerId) {
450
- w.splice(h, 1);
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);
451
453
  return;
452
454
  }
453
455
  }
454
- function we(s) {
455
- let h = V[s.pointerId];
456
- h === void 0 && (h = new S(), V[s.pointerId] = h), h.set(s.pageX, s.pageY);
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);
457
459
  }
458
- function D(s) {
459
- const h = s.pointerId === w[0] ? w[1] : w[0];
460
+ function j(o) {
461
+ const h = o.pointerId === E[0] ? E[1] : E[0];
460
462
  return V[h];
461
463
  }
462
- t.domElement.addEventListener("contextmenu", Ee), t.domElement.addEventListener("pointerdown", be), t.domElement.addEventListener("pointercancel", $), 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", G), t.domElement.addEventListener("wheel", ve, { passive: !1 }), document.addEventListener("keydown", qe, { passive: !0, capture: !0 }), this.update();
463
465
  }
464
466
  }
465
- class ut {
466
- constructor(e, o) {
467
+ class gt {
468
+ constructor(e, s) {
467
469
  r(this, "scene");
468
470
  r(this, "camera");
469
471
  r(this, "renderer");
@@ -471,16 +473,16 @@ class ut {
471
473
  r(this, "container");
472
474
  r(this, "resizeHandler");
473
475
  this.container = e, this.scene = new p.Scene(), this.scene.background = new p.Color(
474
- o.backgroundColor ?? 657930
476
+ s.backgroundColor ?? 657930
475
477
  );
476
- const { width: t, height: n } = Se(e), i = o.cameraFov ?? 75;
477
- this.camera = new p.PerspectiveCamera(i, t / n, 0.1, 2e3);
478
- const a = o.cameraPosition ?? { x: 0, y: 0, z: 80 };
478
+ const { width: t, height: i } = ze(e), n = s.cameraFov ?? 75;
479
+ this.camera = new p.PerspectiveCamera(n, t / i, 0.1, 2e3);
480
+ const a = s.cameraPosition ?? { x: 0, y: 0, z: 80 };
479
481
  this.camera.position.set(a.x, a.y, a.z), this.renderer = new p.WebGLRenderer({
480
482
  antialias: !0,
481
483
  alpha: !0,
482
484
  powerPreference: "high-performance"
483
- }), 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);
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);
484
486
  }
485
487
  /**
486
488
  * Sets up scene lighting for gradient glass on dark background
@@ -488,14 +490,14 @@ class ut {
488
490
  setupLighting() {
489
491
  const e = new p.AmbientLight(16777215, 0.4);
490
492
  this.scene.add(e);
491
- const o = new p.DirectionalLight(16777215, 0.9);
492
- o.position.set(50, 60, 40), o.castShadow = !0, o.shadow.mapSize.width = 1024, o.shadow.mapSize.height = 1024, this.scene.add(o);
493
+ const s = new p.DirectionalLight(16777215, 0.9);
494
+ s.position.set(50, 60, 40), s.castShadow = !0, s.shadow.mapSize.width = 1024, s.shadow.mapSize.height = 1024, this.scene.add(s);
493
495
  const t = new p.DirectionalLight(16773344, 0.4);
494
496
  t.position.set(-50, 30, -40), this.scene.add(t);
495
- const n = new p.DirectionalLight(16777215, 0.3);
496
- n.position.set(0, -30, -50), this.scene.add(n);
497
- const i = new p.PointLight(16750950, 0.5, 150);
498
- i.position.set(40, 20, 40), this.scene.add(i);
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);
499
501
  const a = new p.PointLight(16764057, 0.4, 150);
500
502
  a.position.set(-40, -20, 40), this.scene.add(a);
501
503
  const l = new p.PointLight(6724095, 0.2, 100);
@@ -505,8 +507,8 @@ class ut {
505
507
  * Handle window resize
506
508
  */
507
509
  onWindowResize() {
508
- const { width: e, height: o } = Se(this.container);
509
- this.camera.aspect = e / o, this.camera.updateProjectionMatrix(), this.renderer.setSize(e, o);
510
+ const { width: e, height: s } = ze(this.container);
511
+ this.camera.aspect = e / s, this.camera.updateProjectionMatrix(), this.renderer.setSize(e, s);
510
512
  }
511
513
  /**
512
514
  * Adds an object to the scene
@@ -554,12 +556,12 @@ class ut {
554
556
  }
555
557
  }
556
558
  class mt {
557
- constructor(e, o) {
559
+ constructor(e, s) {
558
560
  r(this, "sceneManager");
559
561
  r(this, "nodeFactory");
560
562
  r(this, "nodes", /* @__PURE__ */ new Map());
561
563
  r(this, "nodeObjects", /* @__PURE__ */ new Map());
562
- this.sceneManager = e, this.nodeFactory = o;
564
+ this.sceneManager = e, this.nodeFactory = s;
563
565
  }
564
566
  /**
565
567
  * Checks if a node exists
@@ -571,8 +573,8 @@ class mt {
571
573
  * Adds a node to the graph
572
574
  * @returns true if added, false if node already exists or invalid
573
575
  */
574
- addNode(e, o = 0) {
575
- if (!Ie(e))
576
+ addNode(e, s = 0) {
577
+ if (!Re(e))
576
578
  return !1;
577
579
  if (this.nodes.has(e.id))
578
580
  return console.warn(`[ForceGraph3D] Node with id "${e.id}" already exists`), !1;
@@ -580,47 +582,47 @@ class mt {
580
582
  x: (Math.random() - 0.5) * 50,
581
583
  y: (Math.random() - 0.5) * 50,
582
584
  z: (Math.random() - 0.5) * 50
583
- }, n = {
585
+ }, i = {
584
586
  ...e,
585
587
  position: t,
586
588
  velocity: { x: 0, y: 0, z: 0 },
587
589
  mass: 1
588
- }, i = this.nodeFactory.createNode(
590
+ }, n = this.nodeFactory.createNode(
589
591
  { ...e, position: t },
590
- o
592
+ s
591
593
  );
592
- return this.sceneManager.add(i.group), this.nodes.set(e.id, n), this.nodeObjects.set(e.id, i), !0;
594
+ return this.sceneManager.add(n.group), this.nodes.set(e.id, i), this.nodeObjects.set(e.id, n), !0;
593
595
  }
594
596
  /**
595
597
  * Removes a node from the graph
596
598
  * @returns true if removed, false if not found
597
599
  */
598
600
  removeNode(e) {
599
- const o = this.nodes.get(e), t = this.nodeObjects.get(e);
600
- return !o || !t ? !1 : (this.sceneManager.remove(t.group), this.nodeFactory.disposeNode(t), this.nodes.delete(e), this.nodeObjects.delete(e), !0);
601
+ const s = this.nodes.get(e), t = this.nodeObjects.get(e);
602
+ return !s || !t ? !1 : (this.sceneManager.remove(t.group), this.nodeFactory.disposeNode(t), this.nodes.delete(e), this.nodeObjects.delete(e), !0);
601
603
  }
602
604
  /**
603
605
  * Updates a node's properties
604
606
  */
605
- updateNode(e, o) {
606
- const t = this.nodes.get(e), n = this.nodeObjects.get(e);
607
- return !t || !n ? (console.warn(`[ForceGraph3D] Node "${e}" not found`), !1) : (o.label !== void 0 && (t.label = o.label, this.nodeFactory.updateNodeLabel(n, o.label)), o.color !== void 0 && (t.color = o.color, this.nodeFactory.updateNodeColor(n, o.color)), Object.keys(o).forEach((i) => {
608
- i !== "id" && i !== "label" && i !== "color" && i !== "position" && (t[i] = o[i]);
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]);
609
611
  }), !0);
610
612
  }
611
613
  /**
612
614
  * Updates a node's position (called by physics engine)
613
615
  */
614
- updateNodePosition(e, o) {
615
- const t = this.nodes.get(e), n = this.nodeObjects.get(e);
616
- t && n && (t.position = o, n.group.position.set(o.x, o.y, o.z));
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
619
  }
618
620
  /**
619
621
  * Updates a node's LOD level
620
622
  */
621
- updateNodeLOD(e, o) {
623
+ updateNodeLOD(e, s) {
622
624
  const t = this.nodeObjects.get(e);
623
- t && this.nodeFactory.updateNodeLOD(t, o);
625
+ t && this.nodeFactory.updateNodeLOD(t, s);
624
626
  }
625
627
  /**
626
628
  * Gets a node by ID
@@ -645,8 +647,8 @@ class mt {
645
647
  */
646
648
  getAllNodeObjects() {
647
649
  const e = [];
648
- return this.nodeObjects.forEach((o) => {
649
- e.push(o.group);
650
+ return this.nodeObjects.forEach((s) => {
651
+ e.push(s.group);
650
652
  }), e;
651
653
  }
652
654
  /**
@@ -654,8 +656,8 @@ class mt {
654
656
  */
655
657
  getAllSpheres() {
656
658
  const e = [];
657
- return this.nodeObjects.forEach((o) => {
658
- e.push(o.sphere);
659
+ return this.nodeObjects.forEach((s) => {
660
+ e.push(s.sphere);
659
661
  }), e;
660
662
  }
661
663
  /**
@@ -668,8 +670,8 @@ class mt {
668
670
  * Clears all nodes
669
671
  */
670
672
  clear() {
671
- this.nodes.forEach((e, o) => {
672
- this.removeNode(o);
673
+ this.nodes.forEach((e, s) => {
674
+ this.removeNode(s);
673
675
  });
674
676
  }
675
677
  /**
@@ -680,7 +682,7 @@ class mt {
680
682
  }
681
683
  }
682
684
  class ft {
683
- constructor(e, o, t) {
685
+ constructor(e, s, t) {
684
686
  r(this, "sceneManager");
685
687
  r(this, "nodeManager");
686
688
  r(this, "edgeFactory");
@@ -688,13 +690,13 @@ class ft {
688
690
  r(this, "edgeObjects", []);
689
691
  r(this, "edgeKeySet", /* @__PURE__ */ new Set());
690
692
  r(this, "highlightedEdgeKey", null);
691
- this.sceneManager = e, this.nodeManager = o, this.edgeFactory = t;
693
+ this.sceneManager = e, this.nodeManager = s, this.edgeFactory = t;
692
694
  }
693
695
  /**
694
696
  * Checks if an edge exists
695
697
  */
696
- hasEdge(e, o) {
697
- const t = I(e, o);
698
+ hasEdge(e, s) {
699
+ const t = R(e, s);
698
700
  return this.edgeKeySet.has(t);
699
701
  }
700
702
  /**
@@ -702,50 +704,50 @@ class ft {
702
704
  * @returns true if added, false if edge already exists or nodes don't exist
703
705
  */
704
706
  addEdge(e) {
705
- if (!Re(e))
707
+ if (!Fe(e))
706
708
  return !1;
707
709
  if (!this.nodeManager.hasNode(e.source))
708
710
  return console.warn(`[ForceGraph3D] Source node "${e.source}" does not exist`), !1;
709
711
  if (!this.nodeManager.hasNode(e.target))
710
712
  return console.warn(`[ForceGraph3D] Target node "${e.target}" does not exist`), !1;
711
- const o = I(e.source, e.target);
712
- if (this.edgeKeySet.has(o))
713
+ const s = R(e.source, e.target);
714
+ if (this.edgeKeySet.has(s))
713
715
  return console.warn(`[ForceGraph3D] Edge "${e.source}" -> "${e.target}" already exists`), !1;
714
- const t = this.nodeManager.getNode(e.source), n = this.nodeManager.getNode(e.target), i = this.edgeFactory.createEdge(
716
+ const t = this.nodeManager.getNode(e.source), i = this.nodeManager.getNode(e.target), n = this.edgeFactory.createEdge(
715
717
  e,
716
718
  t,
717
- n,
719
+ i,
718
720
  t.position,
719
- n.position
721
+ i.position
720
722
  );
721
- return this.sceneManager.add(i.line), this.edges.push(e), this.edgeObjects.push(i), this.edgeKeySet.add(o), !0;
723
+ return this.sceneManager.add(n.line), this.edges.push(e), this.edgeObjects.push(n), this.edgeKeySet.add(s), !0;
722
724
  }
723
725
  /**
724
726
  * Removes an edge from the graph
725
727
  * @returns true if removed, false if not found
726
728
  */
727
- removeEdge(e, o) {
728
- const t = I(e, o);
729
+ removeEdge(e, s) {
730
+ const t = R(e, s);
729
731
  if (!this.edgeKeySet.has(t))
730
732
  return !1;
731
- const n = this.edges.findIndex(
732
- (a) => I(a.source, a.target) === t
733
+ const i = this.edges.findIndex(
734
+ (a) => R(a.source, a.target) === t
733
735
  );
734
- if (n === -1)
736
+ if (i === -1)
735
737
  return !1;
736
- const i = this.edgeObjects[n];
737
- return this.sceneManager.remove(i.line), this.edgeFactory.disposeEdge(i), this.edges.splice(n, 1), this.edgeObjects.splice(n, 1), this.edgeKeySet.delete(t), this.highlightedEdgeKey === t && (this.highlightedEdgeKey = null), !0;
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
740
  }
739
741
  /**
740
742
  * Highlights an edge
741
743
  */
742
- highlightEdge(e, o) {
743
- const t = I(e, o);
744
+ highlightEdge(e, s) {
745
+ const t = R(e, s);
744
746
  this.highlightedEdgeKey && this.highlightedEdgeKey !== t && this.unhighlightCurrentEdge();
745
- const n = this.edges.findIndex(
746
- (i) => I(i.source, i.target) === t
747
+ const i = this.edges.findIndex(
748
+ (n) => R(n.source, n.target) === t
747
749
  );
748
- n !== -1 && (this.edgeFactory.highlightEdge(this.edgeObjects[n]), this.highlightedEdgeKey = t);
750
+ i !== -1 && (this.edgeFactory.highlightEdge(this.edgeObjects[i]), this.highlightedEdgeKey = t);
749
751
  }
750
752
  /**
751
753
  * Unhighlights the currently highlighted edge
@@ -753,7 +755,7 @@ class ft {
753
755
  unhighlightCurrentEdge() {
754
756
  if (!this.highlightedEdgeKey) return;
755
757
  const e = this.edges.findIndex(
756
- (o) => I(o.source, o.target) === this.highlightedEdgeKey
758
+ (s) => R(s.source, s.target) === this.highlightedEdgeKey
757
759
  );
758
760
  e !== -1 && this.edgeFactory.unhighlightEdge(this.edgeObjects[e]), this.highlightedEdgeKey = null;
759
761
  }
@@ -761,10 +763,10 @@ class ft {
761
763
  * Removes all edges connected to a node
762
764
  */
763
765
  removeEdgesForNode(e) {
764
- const o = [];
766
+ const s = [];
765
767
  this.edges.forEach((t) => {
766
- (t.source === e || t.target === e) && o.push({ source: t.source, target: t.target });
767
- }), o.forEach((t) => {
768
+ (t.source === e || t.target === e) && s.push({ source: t.source, target: t.target });
769
+ }), s.forEach((t) => {
768
770
  this.removeEdge(t.source, t.target);
769
771
  });
770
772
  }
@@ -772,27 +774,27 @@ class ft {
772
774
  * Gets all edges for a node
773
775
  */
774
776
  getEdgesForNode(e) {
775
- return this.edges.filter((o) => o.source === e || o.target === e);
777
+ return this.edges.filter((s) => s.source === e || s.target === e);
776
778
  }
777
779
  /**
778
780
  * Gets neighbor node IDs for a node
779
781
  */
780
782
  getNeighborIds(e) {
781
- const o = [];
783
+ const s = [];
782
784
  return this.edges.forEach((t) => {
783
- t.source === e ? o.push(t.target) : t.target === e && o.push(t.source);
784
- }), [...new Set(o)];
785
+ t.source === e ? s.push(t.target) : t.target === e && s.push(t.source);
786
+ }), [...new Set(s)];
785
787
  }
786
788
  /**
787
789
  * Updates all edge positions based on current node positions
788
790
  */
789
791
  updateEdgePositions() {
790
- this.edgeObjects.forEach((e, o) => {
791
- const t = this.edges[o], n = this.nodeManager.getNode(t.source), i = this.nodeManager.getNode(t.target);
792
- n && i && this.edgeFactory.updateEdgePositions(
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
795
  e,
794
- n.position,
795
- i.position
796
+ i.position,
797
+ n.position
796
798
  );
797
799
  });
798
800
  }
@@ -829,8 +831,8 @@ class ft {
829
831
  this.clear();
830
832
  }
831
833
  }
832
- class Le {
833
- constructor(e, o, t = {}) {
834
+ class Oe {
835
+ constructor(e, s, t = {}) {
834
836
  r(this, "nodes");
835
837
  r(this, "edges");
836
838
  // Physics parameters
@@ -844,7 +846,7 @@ class Le {
844
846
  r(this, "alphaDecay", 0.0228);
845
847
  r(this, "alphaMin", 1e-3);
846
848
  r(this, "alphaTarget", 0);
847
- this.nodes = e, this.edges = o, this.repulsionStrength = t.repulsionStrength ?? 100, this.attractionStrength = t.attractionStrength ?? 0.01, this.damping = t.damping ?? 0.9, this.useBarnesHut = t.useBarnesHut ?? !1, this.barnesHutTheta = t.barnesHutTheta ?? 0.5;
849
+ this.nodes = e, this.edges = s, this.repulsionStrength = t.repulsionStrength ?? 100, this.attractionStrength = t.attractionStrength ?? 0.01, this.damping = t.damping ?? 0.9, this.useBarnesHut = t.useBarnesHut ?? !1, this.barnesHutTheta = t.barnesHutTheta ?? 0.5;
848
850
  }
849
851
  /**
850
852
  * Runs one simulation step
@@ -858,15 +860,15 @@ class Le {
858
860
  * Brute force repulsion - O(n²)
859
861
  */
860
862
  calculateRepulsionBruteForce() {
861
- const e = Array.from(this.nodes.values()), o = e.length;
862
- for (let t = 0; t < o; t++) {
863
- const n = e[t];
864
- for (let i = t + 1; i < o; i++) {
865
- const a = e[i], l = a.position.x - n.position.x, d = a.position.y - n.position.y, g = a.position.z - n.position.z;
866
- let u = l * l + d * d + g * g;
867
- u < 0.01 && (u = 0.01);
868
- const x = Math.sqrt(u), v = this.repulsionStrength * this.alpha / u, y = l / x * v, f = d / x * v, M = g / x * v;
869
- n.velocity.x -= y / n.mass, n.velocity.y -= f / n.mass, n.velocity.z -= M / n.mass, a.velocity.x += y / a.mass, a.velocity.y += f / a.mass, a.velocity.z += M / a.mass;
863
+ const e = Array.from(this.nodes.values()), s = e.length;
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;
870
872
  }
871
873
  }
872
874
  }
@@ -874,48 +876,48 @@ class Le {
874
876
  * Barnes-Hut approximation - O(n log n)
875
877
  */
876
878
  calculateRepulsionBarnesHut() {
877
- const e = Array.from(this.nodes.values()), o = new yt(e);
879
+ const e = Array.from(this.nodes.values()), s = new yt(e);
878
880
  for (const t of e)
879
- this.calculateForceFromOctree(t, o.root);
881
+ this.calculateForceFromOctree(t, s.root);
880
882
  }
881
883
  /**
882
884
  * Recursive force calculation using octree
883
885
  */
884
- calculateForceFromOctree(e, o) {
885
- if (o.isLeaf) {
886
- o.node && o.node.id !== e.id && this.applyRepulsionBetween(e, o.node);
886
+ calculateForceFromOctree(e, s) {
887
+ if (s.isLeaf) {
888
+ s.node && s.node.id !== e.id && this.applyRepulsionBetween(e, s.node);
887
889
  return;
888
890
  }
889
- if (o.mass === 0) return;
890
- const t = o.centerOfMass.x - e.position.x, n = o.centerOfMass.y - e.position.y, i = o.centerOfMass.z - e.position.z, a = Math.sqrt(t * t + n * n + i * i);
891
- if (o.size / a < this.barnesHutTheta) {
892
- const l = Math.max(a * a, 0.01), d = this.repulsionStrength * this.alpha * o.mass / l;
893
- e.velocity.x -= t / a * d / e.mass, e.velocity.y -= n / a * d / e.mass, e.velocity.z -= i / a * d / e.mass;
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);
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
896
  } else
895
- for (const l of o.children)
897
+ for (const l of s.children)
896
898
  l && this.calculateForceFromOctree(e, l);
897
899
  }
898
900
  /**
899
901
  * Apply repulsion between two nodes
900
902
  */
901
- applyRepulsionBetween(e, o) {
902
- const t = o.position.x - e.position.x, n = o.position.y - e.position.y, i = o.position.z - e.position.z;
903
- let a = t * t + n * n + i * i;
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
906
  a < 0.01 && (a = 0.01);
905
907
  const l = Math.sqrt(a), d = this.repulsionStrength * this.alpha / a;
906
- e.velocity.x -= t / l * d / e.mass, e.velocity.y -= n / l * d / e.mass, e.velocity.z -= i / l * d / e.mass;
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
909
  }
908
910
  /**
909
911
  * Calculate attraction forces along edges
910
912
  */
911
913
  calculateAttraction() {
912
914
  for (const e of this.edges) {
913
- const o = this.nodes.get(e.source), t = this.nodes.get(e.target);
914
- if (!o || !t) continue;
915
- const n = t.position.x - o.position.x, i = t.position.y - o.position.y, a = t.position.z - o.position.z, l = Math.sqrt(n * n + i * i + a * a);
915
+ const s = this.nodes.get(e.source), t = this.nodes.get(e.target);
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);
916
918
  if (l < 0.01) continue;
917
- const g = (l - 15) * this.attractionStrength * this.alpha, u = n / l * g, x = i / l * g, v = a / l * g;
918
- o.velocity.x += u / o.mass, o.velocity.y += x / o.mass, o.velocity.z += v / o.mass, t.velocity.x -= u / t.mass, t.velocity.y -= x / t.mass, t.velocity.z -= v / t.mass;
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
921
  }
920
922
  }
921
923
  /**
@@ -953,8 +955,8 @@ class Le {
953
955
  class yt {
954
956
  constructor(e) {
955
957
  r(this, "root");
956
- const o = this.calculateBounds(e);
957
- this.root = this.buildTree(e, o);
958
+ const s = this.calculateBounds(e);
959
+ this.root = this.buildTree(e, s);
958
960
  }
959
961
  calculateBounds(e) {
960
962
  if (e.length === 0)
@@ -962,22 +964,22 @@ class yt {
962
964
  min: { x: -100, y: -100, z: -100 },
963
965
  max: { x: 100, y: 100, z: 100 }
964
966
  };
965
- const o = { x: 1 / 0, y: 1 / 0, z: 1 / 0 }, t = { x: -1 / 0, y: -1 / 0, z: -1 / 0 };
966
- for (const i of e)
967
- o.x = Math.min(o.x, i.position.x), o.y = Math.min(o.y, i.position.y), o.z = Math.min(o.z, i.position.z), t.x = Math.max(t.x, i.position.x), t.y = Math.max(t.y, i.position.y), t.z = Math.max(t.z, i.position.z);
968
- const n = 10;
969
- return o.x -= n, o.y -= n, o.z -= n, t.x += n, t.y += n, t.z += n, { min: o, max: t };
970
- }
971
- buildTree(e, o, t = 0) {
972
- const n = Math.max(
973
- o.max.x - o.min.x,
974
- o.max.y - o.min.y,
975
- o.max.z - o.min.z
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 };
972
+ }
973
+ buildTree(e, s, t = 0) {
974
+ const i = Math.max(
975
+ s.max.x - s.min.x,
976
+ s.max.y - s.min.y,
977
+ s.max.z - s.min.z
976
978
  );
977
979
  if (e.length === 0)
978
980
  return {
979
- bounds: o,
980
- size: n,
981
+ bounds: s,
982
+ size: i,
981
983
  centerOfMass: { x: 0, y: 0, z: 0 },
982
984
  mass: 0,
983
985
  isLeaf: !0,
@@ -990,8 +992,8 @@ class yt {
990
992
  for (const M of e)
991
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;
992
994
  return y > 0 && (f.x /= y, f.y /= y, f.z /= y), {
993
- bounds: o,
994
- size: n,
995
+ bounds: s,
996
+ size: i,
995
997
  centerOfMass: f,
996
998
  mass: y,
997
999
  isLeaf: !0,
@@ -999,42 +1001,42 @@ class yt {
999
1001
  children: []
1000
1002
  };
1001
1003
  }
1002
- const i = (o.min.x + o.max.x) / 2, a = (o.min.y + o.max.y) / 2, l = (o.min.z + o.max.z) / 2, d = [[], [], [], [], [], [], [], []];
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 = [[], [], [], [], [], [], [], []];
1003
1005
  for (const y of e) {
1004
- const f = (y.position.x >= i ? 1 : 0) + (y.position.y >= a ? 2 : 0) + (y.position.z >= l ? 4 : 0);
1006
+ const f = (y.position.x >= n ? 1 : 0) + (y.position.y >= a ? 2 : 0) + (y.position.z >= l ? 4 : 0);
1005
1007
  d[f].push(y);
1006
1008
  }
1007
- const g = [
1008
- { min: { x: o.min.x, y: o.min.y, z: o.min.z }, max: { x: i, y: a, z: l } },
1009
- { min: { x: i, y: o.min.y, z: o.min.z }, max: { x: o.max.x, y: a, z: l } },
1010
- { min: { x: o.min.x, y: a, z: o.min.z }, max: { x: i, y: o.max.y, z: l } },
1011
- { min: { x: i, y: a, z: o.min.z }, max: { x: o.max.x, y: o.max.y, z: l } },
1012
- { min: { x: o.min.x, y: o.min.y, z: l }, max: { x: i, y: a, z: o.max.z } },
1013
- { min: { x: i, y: o.min.y, z: l }, max: { x: o.max.x, y: a, z: o.max.z } },
1014
- { min: { x: o.min.x, y: a, z: l }, max: { x: i, y: o.max.y, z: o.max.z } },
1015
- { min: { x: i, y: a, z: l }, max: { x: o.max.x, y: o.max.y, z: o.max.z } }
1016
- ], u = [];
1017
- let x = 0;
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 = [];
1019
+ let b = 0;
1018
1020
  const v = { x: 0, y: 0, z: 0 };
1019
1021
  for (let y = 0; y < 8; y++)
1020
1022
  if (d[y].length > 0) {
1021
- const f = this.buildTree(d[y], g[y], t + 1);
1022
- u.push(f), x += f.mass, v.x += f.centerOfMass.x * f.mass, v.y += f.centerOfMass.y * f.mass, v.z += f.centerOfMass.z * f.mass;
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;
1023
1025
  } else
1024
- u.push(null);
1025
- return x > 0 && (v.x /= x, v.y /= x, v.z /= x), {
1026
- bounds: o,
1027
- size: n,
1026
+ g.push(null);
1027
+ return b > 0 && (v.x /= b, v.y /= b, v.z /= b), {
1028
+ bounds: s,
1029
+ size: i,
1028
1030
  centerOfMass: v,
1029
- mass: x,
1031
+ mass: b,
1030
1032
  isLeaf: !1,
1031
1033
  node: null,
1032
- children: u
1034
+ children: g
1033
1035
  };
1034
1036
  }
1035
1037
  }
1036
- class xt {
1037
- constructor(e, o, t, n = 60) {
1038
+ class bt {
1039
+ constructor(e, s, t, i = 60) {
1038
1040
  r(this, "sceneManager");
1039
1041
  r(this, "animationId", null);
1040
1042
  r(this, "isRunning", !1);
@@ -1052,14 +1054,14 @@ class xt {
1052
1054
  r(this, "animate", () => {
1053
1055
  if (!this.isRunning) return;
1054
1056
  this.animationId = requestAnimationFrame(this.animate);
1055
- const e = performance.now(), o = e - this.lastFrameTime;
1056
- if (o < this.frameInterval)
1057
+ const e = performance.now(), s = e - this.lastFrameTime;
1058
+ if (s < this.frameInterval)
1057
1059
  return;
1058
- this.lastFrameTime = e - o % this.frameInterval, this.frameCount++;
1060
+ this.lastFrameTime = e - s % this.frameInterval, this.frameCount++;
1059
1061
  const t = e - this.fpsStartTime;
1060
1062
  t >= 1e3 && (this.currentFPS = this.frameCount / (t / 1e3), this.frameCount = 0, this.fpsStartTime = e), this.onSimulate(), this.onRender(), this.sceneManager.render();
1061
1063
  });
1062
- this.sceneManager = e, this.onSimulate = o, this.onRender = t, this.frameInterval = 1e3 / n;
1064
+ this.sceneManager = e, this.onSimulate = s, this.onRender = t, this.frameInterval = 1e3 / i;
1063
1065
  }
1064
1066
  /**
1065
1067
  * Starts the animation loop
@@ -1098,7 +1100,7 @@ class xt {
1098
1100
  this.stop();
1099
1101
  }
1100
1102
  }
1101
- class bt {
1103
+ class xt {
1102
1104
  constructor() {
1103
1105
  r(this, "envMap", null);
1104
1106
  r(this, "materialCache", /* @__PURE__ */ new Map());
@@ -1121,7 +1123,7 @@ class bt {
1121
1123
  * Creates environment map for glass reflections on dark background
1122
1124
  */
1123
1125
  createEnvironmentMap() {
1124
- const o = [], t = [
1126
+ const s = [], t = [
1125
1127
  // Subtle colored gradients for interesting reflections
1126
1128
  { colors: ["#1a1a2e", "#16213e", "#0f3460"] },
1127
1129
  // +x
@@ -1136,10 +1138,10 @@ class bt {
1136
1138
  { colors: ["#2d1a1a", "#1a0a0a", "#0f0505"] }
1137
1139
  // -z
1138
1140
  ];
1139
- for (const n of t) {
1140
- const i = document.createElement("canvas");
1141
- i.width = 256, i.height = 256;
1142
- const a = i.getContext("2d"), l = a.createRadialGradient(
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(
1143
1145
  256 / 2,
1144
1146
  256 / 2,
1145
1147
  0,
@@ -1147,17 +1149,17 @@ class bt {
1147
1149
  256 / 2,
1148
1150
  256 * 0.8
1149
1151
  );
1150
- 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);
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);
1151
1153
  const d = a.getImageData(0, 0, 256, 256);
1152
- for (let g = 0; g < d.data.length; g += 4) {
1153
- const u = (Math.random() - 0.5) * 5;
1154
- d.data[g] = Math.min(255, Math.max(0, d.data[g] + u)), d.data[g + 1] = Math.min(255, Math.max(0, d.data[g + 1] + u)), d.data[g + 2] = Math.min(255, Math.max(0, d.data[g + 2] + u));
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));
1155
1157
  }
1156
- a.putImageData(d, 0, 0), o.push(i);
1158
+ a.putImageData(d, 0, 0), s.push(n);
1157
1159
  }
1158
- this.envMap = new p.CubeTexture(o.map((n) => {
1159
- const i = new Image();
1160
- return i.src = n.toDataURL(), i;
1160
+ this.envMap = new p.CubeTexture(s.map((i) => {
1161
+ const n = new Image();
1162
+ return n.src = i.toDataURL(), n;
1161
1163
  })), this.envMap.needsUpdate = !0;
1162
1164
  }
1163
1165
  /**
@@ -1174,9 +1176,9 @@ class bt {
1174
1176
  const t = "glass-single";
1175
1177
  if (this.materialCache.has(t))
1176
1178
  return this.materialCache.get(t).clone();
1177
- const n = new p.Color(16750950), i = new p.ShaderMaterial({
1179
+ const i = new p.Color(16750950), n = new p.ShaderMaterial({
1178
1180
  uniforms: {
1179
- uColor: { value: n },
1181
+ uColor: { value: i },
1180
1182
  uEnvMap: { value: this.envMap },
1181
1183
  uGlowColor: { value: new p.Color(16777215) },
1182
1184
  uGlowIntensity: { value: 0.8 },
@@ -1248,16 +1250,16 @@ class bt {
1248
1250
  depthWrite: !0,
1249
1251
  blending: p.NormalBlending
1250
1252
  });
1251
- return this.materialCache.set(t, i), i.clone();
1253
+ return this.materialCache.set(t, n), n.clone();
1252
1254
  }
1253
1255
  /**
1254
1256
  * Creates material for edges (light color for dark background)
1255
1257
  */
1256
- createEdgeMaterial(e = 6710886, o = 0.4) {
1258
+ createEdgeMaterial(e = 6710886, s = 0.4) {
1257
1259
  return new p.LineBasicMaterial({
1258
1260
  color: e,
1259
1261
  transparent: !0,
1260
- opacity: o,
1262
+ opacity: s,
1261
1263
  linewidth: 1
1262
1264
  });
1263
1265
  }
@@ -1276,11 +1278,11 @@ class bt {
1276
1278
  /**
1277
1279
  * Creates a sprite material for labels (light text for dark background)
1278
1280
  */
1279
- createLabelMaterial(e, o = 24) {
1280
- const t = document.createElement("canvas"), n = t.getContext("2d");
1281
- n.font = `600 ${o}px Inter, -apple-system, sans-serif`;
1282
- const a = n.measureText(e).width;
1283
- t.width = Math.max(128, a + 24), t.height = o + 20, n.clearRect(0, 0, t.width, t.height), n.font = `600 ${o}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);
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);
1284
1286
  const l = new p.CanvasTexture(t);
1285
1287
  return l.needsUpdate = !0, new p.SpriteMaterial({
1286
1288
  map: l,
@@ -1303,19 +1305,19 @@ class bt {
1303
1305
  }
1304
1306
  }
1305
1307
  class vt {
1306
- constructor(e, o = 2, t = [32, 16, 8]) {
1308
+ constructor(e, s = 2, t = [32, 16, 8]) {
1307
1309
  r(this, "materialFactory");
1308
1310
  r(this, "geometryCache", /* @__PURE__ */ new Map());
1309
1311
  r(this, "nodeRadius");
1310
1312
  r(this, "lodSegments");
1311
- this.materialFactory = e, this.nodeRadius = o, this.lodSegments = t, this.initGeometryCache();
1313
+ this.materialFactory = e, this.nodeRadius = s, this.lodSegments = t, this.initGeometryCache();
1312
1314
  }
1313
1315
  /**
1314
1316
  * Pre-create geometries for each LOD level
1315
1317
  */
1316
1318
  initGeometryCache() {
1317
- this.lodSegments.forEach((e, o) => {
1318
- const t = `lod-${o}`;
1319
+ this.lodSegments.forEach((e, s) => {
1320
+ const t = `lod-${s}`;
1319
1321
  this.geometryCache.set(
1320
1322
  t,
1321
1323
  new p.SphereGeometry(this.nodeRadius, e, e)
@@ -1326,18 +1328,18 @@ class vt {
1326
1328
  * Gets geometry for the specified LOD level
1327
1329
  */
1328
1330
  getGeometry(e) {
1329
- const o = `lod-${e}`;
1330
- return this.geometryCache.has(o) ? this.geometryCache.get(o) : this.geometryCache.get("lod-0");
1331
+ const s = `lod-${e}`;
1332
+ return this.geometryCache.has(s) ? this.geometryCache.get(s) : this.geometryCache.get("lod-0");
1331
1333
  }
1332
1334
  /**
1333
1335
  * Creates a node visual (glass ball + label)
1334
1336
  */
1335
- createNode(e, o = 0) {
1337
+ createNode(e, s = 0) {
1336
1338
  const t = new p.Group();
1337
1339
  t.name = `node-${e.id}`, t.userData = { nodeId: e.id, nodeData: e };
1338
- const n = this.getGeometry(o), i = this.materialFactory.createGlassMaterial(
1340
+ const i = this.getGeometry(s), n = this.materialFactory.createGlassMaterial(
1339
1341
  e.color ?? 4886754
1340
- ), a = new p.Mesh(n, i);
1342
+ ), a = new p.Mesh(i, n);
1341
1343
  a.castShadow = !0, a.receiveShadow = !0, t.add(a);
1342
1344
  const l = this.materialFactory.createLabelMaterial(e.label), d = new p.Sprite(l);
1343
1345
  return d.position.y = this.nodeRadius + 1.5, d.scale.set(4, 1, 1), t.add(d), e.position && t.position.set(
@@ -1348,28 +1350,28 @@ class vt {
1348
1350
  group: t,
1349
1351
  sphere: a,
1350
1352
  label: d,
1351
- lodLevel: o
1353
+ lodLevel: s
1352
1354
  };
1353
1355
  }
1354
1356
  /**
1355
1357
  * Updates the LOD level of a node
1356
1358
  */
1357
- updateNodeLOD(e, o) {
1358
- if (e.lodLevel === o) return;
1359
- const t = this.getGeometry(o);
1360
- e.sphere.geometry = t, e.lodLevel = o;
1359
+ updateNodeLOD(e, s) {
1360
+ if (e.lodLevel === s) return;
1361
+ const t = this.getGeometry(s);
1362
+ e.sphere.geometry = t, e.lodLevel = s;
1361
1363
  }
1362
1364
  /**
1363
1365
  * Updates the color of a node
1364
1366
  */
1365
- updateNodeColor(e, o) {
1366
- e.sphere.material instanceof p.Material && e.sphere.material.dispose(), e.sphere.material = this.materialFactory.createGlassMaterial(o);
1367
+ updateNodeColor(e, s) {
1368
+ e.sphere.material instanceof p.Material && e.sphere.material.dispose(), e.sphere.material = this.materialFactory.createGlassMaterial(s);
1367
1369
  }
1368
1370
  /**
1369
1371
  * Updates the label of a node
1370
1372
  */
1371
- updateNodeLabel(e, o) {
1372
- e.label.material instanceof p.SpriteMaterial && (e.label.material.map && e.label.material.map.dispose(), e.label.material.dispose()), e.label.material = this.materialFactory.createLabelMaterial(o);
1373
+ updateNodeLabel(e, s) {
1374
+ e.label.material instanceof p.SpriteMaterial && (e.label.material.map && e.label.material.map.dispose(), e.label.material.dispose()), e.label.material = this.materialFactory.createLabelMaterial(s);
1373
1375
  }
1374
1376
  /**
1375
1377
  * Disposes a node's resources
@@ -1385,13 +1387,13 @@ class vt {
1385
1387
  }
1386
1388
  }
1387
1389
  class Mt {
1388
- constructor(e, o = 10066329, t = 0.5) {
1390
+ constructor(e, s = 10066329, t = 0.5) {
1389
1391
  r(this, "materialFactory");
1390
1392
  r(this, "edgeColor");
1391
1393
  r(this, "edgeOpacity");
1392
1394
  r(this, "defaultMaterial", null);
1393
1395
  r(this, "highlightMaterial", null);
1394
- this.materialFactory = e, this.edgeColor = o, this.edgeOpacity = t;
1396
+ this.materialFactory = e, this.edgeColor = s, this.edgeOpacity = t;
1395
1397
  }
1396
1398
  /**
1397
1399
  * Gets or creates the default edge material
@@ -1411,25 +1413,25 @@ class Mt {
1411
1413
  /**
1412
1414
  * Creates an edge line between two positions
1413
1415
  */
1414
- createEdge(e, o, t, n, i) {
1416
+ createEdge(e, s, t, i, n) {
1415
1417
  const a = new p.BufferGeometry(), l = new Float32Array([
1416
- n.x,
1417
- n.y,
1418
- n.z,
1419
1418
  i.x,
1420
1419
  i.y,
1421
- i.z
1420
+ i.z,
1421
+ n.x,
1422
+ n.y,
1423
+ n.z
1422
1424
  ]);
1423
1425
  a.setAttribute("position", new p.BufferAttribute(l, 3));
1424
- const d = this.getDefaultMaterial().clone(), g = new p.Line(a, d);
1425
- return g.name = `edge-${e.source}-${e.target}`, g.userData = {
1426
+ const d = this.getDefaultMaterial().clone(), u = new p.Line(a, d);
1427
+ return u.name = `edge-${e.source}-${e.target}`, u.userData = {
1426
1428
  source: e.source,
1427
1429
  target: e.target,
1428
1430
  edge: e,
1429
- sourceNode: o,
1431
+ sourceNode: s,
1430
1432
  targetNode: t
1431
- }, g.frustumCulled = !0, {
1432
- line: g,
1433
+ }, u.frustumCulled = !0, {
1434
+ line: u,
1433
1435
  source: e.source,
1434
1436
  target: e.target
1435
1437
  };
@@ -1449,9 +1451,9 @@ class Mt {
1449
1451
  /**
1450
1452
  * Updates an edge's positions
1451
1453
  */
1452
- updateEdgePositions(e, o, t) {
1453
- const n = e.line.geometry.attributes.position, i = n.array;
1454
- i[0] = o.x, i[1] = o.y, i[2] = o.z, i[3] = t.x, i[4] = t.y, i[5] = t.z, n.needsUpdate = !0, e.line.geometry.computeBoundingSphere();
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
1457
  }
1456
1458
  /**
1457
1459
  * Disposes an edge's resources
@@ -1466,28 +1468,28 @@ class Mt {
1466
1468
  this.defaultMaterial && this.defaultMaterial.dispose(), this.highlightMaterial && this.highlightMaterial.dispose();
1467
1469
  }
1468
1470
  }
1469
- class Et {
1470
- constructor(e, o = [50, 100, 200], t = !0) {
1471
+ class wt {
1472
+ constructor(e, s = [50, 100, 200], t = !0) {
1471
1473
  r(this, "camera");
1472
1474
  r(this, "lodDistances");
1473
1475
  r(this, "enabled");
1474
- this.camera = e, this.lodDistances = o, this.enabled = t;
1476
+ this.camera = e, this.lodDistances = s, this.enabled = t;
1475
1477
  }
1476
1478
  /**
1477
1479
  * Gets the LOD level for a position based on distance from camera
1478
1480
  */
1479
1481
  getLODLevel(e) {
1480
1482
  if (!this.enabled)
1481
- return _.HIGH;
1482
- const o = e.x - this.camera.position.x, t = e.y - this.camera.position.y, n = e.z - this.camera.position.z, i = Math.sqrt(o * o + t * t + n * n);
1483
- return i < this.lodDistances[0] ? _.HIGH : i < this.lodDistances[1] ? _.MEDIUM : _.LOW;
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;
1484
1486
  }
1485
1487
  /**
1486
1488
  * Checks if a node should be visible based on distance
1487
1489
  */
1488
- shouldRenderNode(e, o = 500) {
1489
- const t = e.x - this.camera.position.x, n = e.y - this.camera.position.y, i = e.z - this.camera.position.z;
1490
- return Math.sqrt(t * t + n * n + i * i) < o;
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
1493
  }
1492
1494
  /**
1493
1495
  * Sets the LOD distances
@@ -1502,13 +1504,13 @@ class Et {
1502
1504
  this.enabled = e;
1503
1505
  }
1504
1506
  }
1505
- class wt {
1506
- constructor(e, o = !0) {
1507
+ class Et {
1508
+ constructor(e, s = !0) {
1507
1509
  r(this, "camera");
1508
1510
  r(this, "frustum");
1509
1511
  r(this, "projScreenMatrix");
1510
1512
  r(this, "enabled");
1511
- this.camera = e, this.frustum = new p.Frustum(), this.projScreenMatrix = new p.Matrix4(), this.enabled = o;
1513
+ this.camera = e, this.frustum = new p.Frustum(), this.projScreenMatrix = new p.Matrix4(), this.enabled = s;
1512
1514
  }
1513
1515
  /**
1514
1516
  * Updates the frustum from the camera
@@ -1524,33 +1526,33 @@ class wt {
1524
1526
  */
1525
1527
  isPointVisible(e) {
1526
1528
  if (!this.enabled) return !0;
1527
- const o = new p.Vector3(e.x, e.y, e.z);
1528
- return this.frustum.containsPoint(o);
1529
+ const s = new p.Vector3(e.x, e.y, e.z);
1530
+ return this.frustum.containsPoint(s);
1529
1531
  }
1530
1532
  /**
1531
1533
  * Checks if a sphere is inside or intersects the frustum
1532
1534
  */
1533
- isSphereVisible(e, o) {
1535
+ isSphereVisible(e, s) {
1534
1536
  if (!this.enabled) return !0;
1535
1537
  const t = new p.Sphere(
1536
1538
  new p.Vector3(e.x, e.y, e.z),
1537
- o
1539
+ s
1538
1540
  );
1539
1541
  return this.frustum.intersectsSphere(t);
1540
1542
  }
1541
1543
  /**
1542
1544
  * Checks if a line segment is potentially visible
1543
1545
  */
1544
- isLineVisible(e, o) {
1546
+ isLineVisible(e, s) {
1545
1547
  if (!this.enabled) return !0;
1546
- const t = new p.Vector3(e.x, e.y, e.z), n = new p.Vector3(o.x, o.y, o.z);
1547
- if (this.frustum.containsPoint(t) || this.frustum.containsPoint(n))
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
1550
  return !0;
1549
- const i = new p.Vector3(
1550
- (e.x + o.x) / 2,
1551
- (e.y + o.y) / 2,
1552
- (e.z + o.z) / 2
1553
- ), a = i.distanceTo(t), l = new p.Sphere(i, a);
1551
+ const n = new p.Vector3(
1552
+ (e.x + s.x) / 2,
1553
+ (e.y + s.y) / 2,
1554
+ (e.z + s.z) / 2
1555
+ ), a = n.distanceTo(t), l = new p.Sphere(n, a);
1554
1556
  return this.frustum.intersectsSphere(l);
1555
1557
  }
1556
1558
  /**
@@ -1561,7 +1563,7 @@ class wt {
1561
1563
  }
1562
1564
  }
1563
1565
  class Ct {
1564
- constructor(e, o) {
1566
+ constructor(e, s) {
1565
1567
  r(this, "sceneManager");
1566
1568
  r(this, "raycaster");
1567
1569
  r(this, "mouse");
@@ -1573,7 +1575,7 @@ class Ct {
1573
1575
  r(this, "hoveredEdgeKey", null);
1574
1576
  r(this, "nodeObjects", []);
1575
1577
  r(this, "edgeObjects", []);
1576
- this.sceneManager = e, this.container = o, this.raycaster = new p.Raycaster(), this.raycaster.params.Line = { threshold: 0.5 }, this.mouse = new p.Vector2(), this.handleClick = this.handleClick.bind(this), this.handleMouseMove = this.handleMouseMove.bind(this), o.addEventListener("click", this.handleClick), o.addEventListener("mousemove", this.handleMouseMove);
1578
+ this.sceneManager = e, this.container = s, this.raycaster = new p.Raycaster(), this.raycaster.params.Line = { threshold: 0.5 }, this.mouse = new p.Vector2(), this.handleClick = this.handleClick.bind(this), this.handleMouseMove = this.handleMouseMove.bind(this), s.addEventListener("click", this.handleClick), s.addEventListener("mousemove", this.handleMouseMove);
1577
1579
  }
1578
1580
  /**
1579
1581
  * Updates the list of node objects to raycast against
@@ -1609,35 +1611,35 @@ class Ct {
1609
1611
  * Handles click events
1610
1612
  */
1611
1613
  handleClick(e) {
1612
- const o = this.getIntersectedNode(e);
1613
- o && this.onNodeClick && this.onNodeClick(o);
1614
+ const s = this.getIntersectedNode(e);
1615
+ s && this.onNodeClick && this.onNodeClick(s);
1614
1616
  }
1615
1617
  /**
1616
1618
  * Handles mouse move events for hover detection
1617
1619
  */
1618
1620
  handleMouseMove(e) {
1619
- const o = this.getIntersectedNode(e), t = (o == null ? void 0 : o.id) ?? null;
1620
- if (t !== this.hoveredNodeId && (this.hoveredNodeId = t, this.onNodeHover && this.onNodeHover(o)), o) {
1621
+ const s = this.getIntersectedNode(e), t = (s == null ? void 0 : s.id) ?? null;
1622
+ if (t !== this.hoveredNodeId && (this.hoveredNodeId = t, this.onNodeHover && this.onNodeHover(s)), s) {
1621
1623
  this.hoveredEdgeKey !== null && this.onEdgeHover && (this.hoveredEdgeKey = null, this.onEdgeHover(null)), this.container.style.cursor = "pointer";
1622
1624
  return;
1623
1625
  }
1624
- const n = this.getIntersectedEdge(e), i = n ? `${n.edge.source}-${n.edge.target}` : null;
1625
- i !== this.hoveredEdgeKey && (this.hoveredEdgeKey = i, this.onEdgeHover && this.onEdgeHover(n)), this.container.style.cursor = n ? "pointer" : "default";
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";
1626
1628
  }
1627
1629
  /**
1628
1630
  * Gets the intersected node from a mouse event
1629
1631
  */
1630
1632
  getIntersectedNode(e) {
1631
- var n;
1632
- const o = this.container.getBoundingClientRect();
1633
- this.mouse.x = (e.clientX - o.left) / o.width * 2 - 1, this.mouse.y = -((e.clientY - o.top) / o.height) * 2 + 1, this.raycaster.setFromCamera(this.mouse, this.sceneManager.camera);
1633
+ var i;
1634
+ const s = this.container.getBoundingClientRect();
1635
+ 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);
1634
1636
  const t = this.raycaster.intersectObjects(this.nodeObjects, !0);
1635
1637
  if (t.length > 0) {
1636
- let i = t[0].object;
1637
- for (; i; ) {
1638
- if ((n = i.userData) != null && n.nodeData)
1639
- return i.userData.nodeData;
1640
- i = i.parent;
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;
1641
1643
  }
1642
1644
  }
1643
1645
  return null;
@@ -1646,17 +1648,17 @@ class Ct {
1646
1648
  * Gets the intersected edge from a mouse event
1647
1649
  */
1648
1650
  getIntersectedEdge(e) {
1649
- const o = this.container.getBoundingClientRect();
1650
- this.mouse.x = (e.clientX - o.left) / o.width * 2 - 1, this.mouse.y = -((e.clientY - o.top) / o.height) * 2 + 1, this.raycaster.setFromCamera(this.mouse, this.sceneManager.camera);
1651
+ const s = this.container.getBoundingClientRect();
1652
+ 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);
1651
1653
  const t = this.raycaster.intersectObjects(this.edgeObjects, !1);
1652
1654
  if (t.length > 0) {
1653
- const n = t[0].object, i = n.userData;
1654
- if (i != null && i.edge && (i != null && i.sourceNode) && (i != null && i.targetNode))
1655
+ const i = t[0].object, n = i.userData;
1656
+ if (n != null && n.edge && (n != null && n.sourceNode) && (n != null && n.targetNode))
1655
1657
  return {
1656
- edge: i.edge,
1657
- sourceNode: i.sourceNode,
1658
- targetNode: i.targetNode,
1659
- edgeLine: n
1658
+ edge: n.edge,
1659
+ sourceNode: n.sourceNode,
1660
+ targetNode: n.targetNode,
1661
+ edgeLine: i
1660
1662
  };
1661
1663
  }
1662
1664
  return null;
@@ -1664,15 +1666,15 @@ class Ct {
1664
1666
  /**
1665
1667
  * Performs a raycast and returns the intersected node ID
1666
1668
  */
1667
- getIntersectedNodeId(e, o) {
1668
- var i;
1669
+ getIntersectedNodeId(e, s) {
1670
+ var n;
1669
1671
  const t = this.container.getBoundingClientRect();
1670
- this.mouse.x = (e - t.left) / t.width * 2 - 1, this.mouse.y = -((o - t.top) / t.height) * 2 + 1, this.raycaster.setFromCamera(this.mouse, this.sceneManager.camera);
1671
- const n = this.raycaster.intersectObjects(this.nodeObjects, !0);
1672
- if (n.length > 0) {
1673
- let a = n[0].object;
1672
+ 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;
1674
1676
  for (; a; ) {
1675
- if ((i = a.userData) != null && i.nodeId)
1677
+ if ((n = a.userData) != null && n.nodeId)
1676
1678
  return a.userData.nodeId;
1677
1679
  a = a.parent;
1678
1680
  }
@@ -1724,8 +1726,8 @@ class Nt {
1724
1726
  opacity: 0;
1725
1727
  pointer-events: none;
1726
1728
  transition: opacity 0.3s ease, transform 0.3s ease;
1727
- `, Object.entries(this.panelStyles).forEach(([e, o]) => {
1728
- this.panel.style.setProperty(e, o);
1729
+ `, Object.entries(this.panelStyles).forEach(([e, s]) => {
1730
+ this.panel.style.setProperty(e, s);
1729
1731
  }), this.container.appendChild(this.panel);
1730
1732
  }
1731
1733
  /**
@@ -1738,8 +1740,8 @@ class Nt {
1738
1740
  * Sets custom panel styles
1739
1741
  */
1740
1742
  setPanelStyles(e) {
1741
- this.panelStyles = e, this.panel && Object.entries(e).forEach(([o, t]) => {
1742
- this.panel.style.setProperty(o, t);
1743
+ this.panelStyles = e, this.panel && Object.entries(e).forEach(([s, t]) => {
1744
+ this.panel.style.setProperty(s, t);
1743
1745
  });
1744
1746
  }
1745
1747
  /**
@@ -1751,15 +1753,15 @@ class Nt {
1751
1753
  /**
1752
1754
  * Shows the panel with node information
1753
1755
  */
1754
- show(e, o) {
1756
+ show(e, s) {
1755
1757
  if (!this.panel) return;
1756
1758
  this.currentNodeId = e.id;
1757
1759
  let t;
1758
- this.panelTemplate ? t = this.panelTemplate(e, o) : t = this.generateDefaultContent(e, o), this.panel.innerHTML = t;
1759
- const n = this.panel.querySelector('[data-action="expand"]'), i = this.panel.querySelector("[data-depth-select]");
1760
- n && this.onExpand && n.addEventListener("click", () => {
1760
+ 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", () => {
1761
1763
  if (this.currentNodeId) {
1762
- const l = i ? parseInt(i.value, 10) : 1;
1764
+ const l = n ? parseInt(n.value, 10) : 1;
1763
1765
  this.onExpand(this.currentNodeId, l);
1764
1766
  }
1765
1767
  });
@@ -1771,7 +1773,7 @@ class Nt {
1771
1773
  /**
1772
1774
  * Generates default panel content
1773
1775
  */
1774
- generateDefaultContent(e, o) {
1776
+ generateDefaultContent(e, s) {
1775
1777
  const t = e.color ? `#${e.color.toString(16).padStart(6, "0")}` : "#4A90E2";
1776
1778
  return `
1777
1779
  <style>
@@ -1899,16 +1901,16 @@ class Nt {
1899
1901
 
1900
1902
  <div class="info-row">
1901
1903
  <span class="info-label">Connections</span>
1902
- <span class="info-value">${o.length}</span>
1904
+ <span class="info-value">${s.length}</span>
1903
1905
  </div>
1904
1906
 
1905
- ${o.length > 0 ? `
1907
+ ${s.length > 0 ? `
1906
1908
  <div class="neighbors-section">
1907
1909
  <div class="neighbors-title">Connected To</div>
1908
- ${o.slice(0, 5).map(
1909
- (n) => `<span class="neighbor-chip">${this.escapeHtml(n.label)}</span>`
1910
+ ${s.slice(0, 5).map(
1911
+ (i) => `<span class="neighbor-chip">${this.escapeHtml(i.label)}</span>`
1910
1912
  ).join("")}
1911
- ${o.length > 5 ? `<span class="neighbor-chip">+${o.length - 5} more</span>` : ""}
1913
+ ${s.length > 5 ? `<span class="neighbor-chip">+${s.length - 5} more</span>` : ""}
1912
1914
  </div>
1913
1915
  ` : ""}
1914
1916
 
@@ -1932,8 +1934,8 @@ class Nt {
1932
1934
  * Escapes HTML to prevent XSS
1933
1935
  */
1934
1936
  escapeHtml(e) {
1935
- const o = document.createElement("div");
1936
- return o.textContent = e, o.innerHTML;
1937
+ const s = document.createElement("div");
1938
+ return s.textContent = e, s.innerHTML;
1937
1939
  }
1938
1940
  /**
1939
1941
  * Hides the panel
@@ -1960,7 +1962,7 @@ class Nt {
1960
1962
  this.panel && this.panel.parentNode && this.panel.parentNode.removeChild(this.panel), this.panel = null;
1961
1963
  }
1962
1964
  }
1963
- class zt {
1965
+ class St {
1964
1966
  constructor() {
1965
1967
  r(this, "tooltip", null);
1966
1968
  r(this, "visible", !1);
@@ -2004,22 +2006,22 @@ class zt {
2004
2006
  /**
2005
2007
  * Positions the tooltip near the mouse
2006
2008
  */
2007
- positionTooltip(e, o) {
2009
+ positionTooltip(e, s) {
2008
2010
  if (!this.tooltip) return;
2009
- const t = this.tooltip.getBoundingClientRect(), n = window.innerWidth, i = window.innerHeight;
2010
- let a = e + 15, l = o + 15;
2011
- a + t.width > n - 10 && (a = e - t.width - 15), l + t.height > i - 10 && (l = o - t.height - 15), a < 10 && (a = 10), l < 10 && (l = 10), this.tooltip.style.left = `${a}px`, this.tooltip.style.top = `${l}px`;
2011
+ const t = this.tooltip.getBoundingClientRect(), i = window.innerWidth, n = window.innerHeight;
2012
+ let a = e + 15, l = s + 15;
2013
+ 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`;
2012
2014
  }
2013
2015
  /**
2014
2016
  * Shows the tooltip with edge info
2015
2017
  */
2016
- show(e, o, t, n, i) {
2018
+ show(e, s, t, i, n) {
2017
2019
  if (!this.tooltip) return;
2018
2020
  const a = e.relationship || "connected to";
2019
2021
  this.tooltip.innerHTML = `
2020
2022
  <div style="display: flex; flex-direction: column; gap: 4px;">
2021
2023
  <div style="display: flex; align-items: center; gap: 6px; flex-wrap: wrap;">
2022
- <span style="font-weight: 600; color: #ff9966;">${this.escapeHtml(o.label)}</span>
2024
+ <span style="font-weight: 600; color: #ff9966;">${this.escapeHtml(s.label)}</span>
2023
2025
  </div>
2024
2026
  <div style="color: rgba(255, 255, 255, 0.6); font-style: italic; font-size: 12px; padding-left: 8px;">
2025
2027
  ↳ ${this.escapeHtml(a)}
@@ -2028,13 +2030,13 @@ class zt {
2028
2030
  <span style="font-weight: 600; color: #ff9966;">${this.escapeHtml(t.label)}</span>
2029
2031
  </div>
2030
2032
  </div>
2031
- `, this.positionTooltip(n, i), this.tooltip.style.opacity = "1", this.tooltip.style.transform = "translateY(0)", this.visible = !0;
2033
+ `, this.positionTooltip(i, n), this.tooltip.style.opacity = "1", this.tooltip.style.transform = "translateY(0)", this.visible = !0;
2032
2034
  }
2033
2035
  /**
2034
2036
  * Updates tooltip position (called externally on mouse move)
2035
2037
  */
2036
- updatePosition(e, o) {
2037
- this.visible && this.positionTooltip(e, o);
2038
+ updatePosition(e, s) {
2039
+ this.visible && this.positionTooltip(e, s);
2038
2040
  }
2039
2041
  /**
2040
2042
  * Hides the tooltip
@@ -2052,8 +2054,8 @@ class zt {
2052
2054
  * Escapes HTML to prevent XSS
2053
2055
  */
2054
2056
  escapeHtml(e) {
2055
- const o = document.createElement("div");
2056
- return o.textContent = e, o.innerHTML;
2057
+ const s = document.createElement("div");
2058
+ return s.textContent = e, s.innerHTML;
2057
2059
  }
2058
2060
  /**
2059
2061
  * Dispose the tooltip
@@ -2062,8 +2064,181 @@ class zt {
2062
2064
  this.tooltip && this.tooltip.parentNode && this.tooltip.parentNode.removeChild(this.tooltip), this.tooltip = null;
2063
2065
  }
2064
2066
  }
2067
+ class zt {
2068
+ constructor(e, s) {
2069
+ r(this, "container");
2070
+ r(this, "searchContainer", null);
2071
+ r(this, "searchInput", null);
2072
+ r(this, "searchResults", null);
2073
+ r(this, "searchTimeout", null);
2074
+ r(this, "placeholder");
2075
+ r(this, "onSearch");
2076
+ r(this, "onResultClick");
2077
+ this.container = e, this.placeholder = s.placeholder || "Search nodes or relationships...", this.onSearch = s.onSearch, this.onResultClick = s.onResultClick, this.init();
2078
+ }
2079
+ init() {
2080
+ this.createSearchUI(), this.addEventListeners();
2081
+ }
2082
+ createSearchUI() {
2083
+ this.searchContainer = document.createElement("div"), this.searchContainer.className = "f3d-search-container", Object.assign(this.searchContainer.style, {
2084
+ position: "absolute",
2085
+ top: "20px",
2086
+ left: "20px",
2087
+ zIndex: "100",
2088
+ width: "320px"
2089
+ });
2090
+ const e = document.createElement("div");
2091
+ e.className = "f3d-search-input-wrapper", Object.assign(e.style, {
2092
+ position: "relative",
2093
+ display: "flex",
2094
+ alignItems: "center"
2095
+ }), e.innerHTML = `
2096
+ <svg class="f3d-search-icon" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor"
2097
+ stroke-width="2" style="position: absolute; left: 14px; z-index: 10; color: rgba(255, 255, 255, 0.5); pointer-events: none;">
2098
+ <circle cx="11" cy="11" r="8"></circle>
2099
+ <path d="m21 21-4.35-4.35"></path>
2100
+ </svg>
2101
+ `, this.searchInput = document.createElement("input"), this.searchInput.type = "text", this.searchInput.className = "f3d-search-input", this.searchInput.placeholder = this.placeholder, this.searchInput.autocomplete = "off", Object.assign(this.searchInput.style, {
2102
+ width: "100%",
2103
+ padding: "12px 16px 12px 42px",
2104
+ background: "rgba(255, 255, 255, 0.08)",
2105
+ backdropFilter: "blur(20px)",
2106
+ webkitBackdropFilter: "blur(20px)",
2107
+ border: "1px solid rgba(255, 255, 255, 0.12)",
2108
+ borderRadius: "12px",
2109
+ color: "white",
2110
+ fontSize: "14px",
2111
+ fontFamily: "inherit",
2112
+ outline: "none",
2113
+ transition: "all 0.2s ease"
2114
+ }), this.searchInput.addEventListener("focus", () => {
2115
+ this.searchInput && (this.searchInput.style.background = "rgba(255, 255, 255, 0.12)", this.searchInput.style.borderColor = "rgba(255, 153, 102, 0.5)", this.searchInput.style.boxShadow = "0 0 20px rgba(255, 153, 102, 0.15)");
2116
+ }), this.searchInput.addEventListener("blur", () => {
2117
+ this.searchInput && (this.searchInput.style.background = "rgba(255, 255, 255, 0.08)", this.searchInput.style.borderColor = "rgba(255, 255, 255, 0.12)", this.searchInput.style.boxShadow = "none");
2118
+ }), this.searchResults = document.createElement("div"), this.searchResults.className = "f3d-search-results", Object.assign(this.searchResults.style, {
2119
+ position: "absolute",
2120
+ top: "100%",
2121
+ left: "0",
2122
+ right: "0",
2123
+ marginTop: "8px",
2124
+ background: "rgba(20, 20, 25, 0.95)",
2125
+ backdropFilter: "blur(20px)",
2126
+ webkitBackdropFilter: "blur(20px)",
2127
+ border: "1px solid rgba(255, 255, 255, 0.1)",
2128
+ borderRadius: "12px",
2129
+ maxHeight: "300px",
2130
+ overflowY: "auto",
2131
+ display: "none",
2132
+ boxShadow: "0 10px 40px rgba(0, 0, 0, 0.4)"
2133
+ }), e.appendChild(this.searchInput), this.searchContainer.appendChild(e), this.searchContainer.appendChild(this.searchResults), this.container.appendChild(this.searchContainer);
2134
+ const s = document.createElement("style");
2135
+ s.textContent = `
2136
+ .f3d-search-result-item {
2137
+ padding: 10px 14px;
2138
+ cursor: pointer;
2139
+ border-bottom: 1px solid rgba(255, 255, 255, 0.05);
2140
+ transition: background 0.15s ease;
2141
+ }
2142
+ .f3d-search-result-item:hover {
2143
+ background: rgba(255, 153, 102, 0.15);
2144
+ }
2145
+ .f3d-search-result-item:last-child {
2146
+ border-bottom: none;
2147
+ }
2148
+ .f3d-result-label {
2149
+ color: white;
2150
+ font-size: 13px;
2151
+ font-weight: 500;
2152
+ margin-bottom: 2px;
2153
+ }
2154
+ .f3d-result-type {
2155
+ color: rgba(255, 153, 102, 0.8);
2156
+ font-size: 11px;
2157
+ text-transform: uppercase;
2158
+ letter-spacing: 0.5px;
2159
+ }
2160
+ .f3d-result-relationship {
2161
+ color: rgba(255, 255, 255, 0.5);
2162
+ font-size: 11px;
2163
+ font-style: italic;
2164
+ }
2165
+ .f3d-no-results {
2166
+ padding: 14px;
2167
+ color: rgba(255, 255, 255, 0.4);
2168
+ font-size: 13px;
2169
+ text-align: center;
2170
+ }
2171
+ .f3d-search-section-header {
2172
+ padding: 8px 14px 6px;
2173
+ color: rgba(255, 255, 255, 0.3);
2174
+ font-size: 10px;
2175
+ text-transform: uppercase;
2176
+ letter-spacing: 1px;
2177
+ font-weight: 600;
2178
+ background: rgba(0, 0, 0, 0.2);
2179
+ }
2180
+ .f3d-search-results::-webkit-scrollbar { width: 6px; }
2181
+ .f3d-search-results::-webkit-scrollbar-track { background: transparent; }
2182
+ .f3d-search-results::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.15); border-radius: 3px; }
2183
+ .f3d-search-results::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, 0.25); }
2184
+ `, document.head.appendChild(s);
2185
+ }
2186
+ addEventListeners() {
2187
+ !this.searchInput || !this.searchResults || (this.searchInput.addEventListener("input", (e) => {
2188
+ const s = e.target.value;
2189
+ this.searchTimeout && window.clearTimeout(this.searchTimeout), this.searchTimeout = window.setTimeout(() => {
2190
+ this.performSearch(s);
2191
+ }, 150);
2192
+ }), this.searchInput.addEventListener("focus", () => {
2193
+ this.searchInput && this.searchInput.value.length > 0 && (this.searchResults.style.display = "block");
2194
+ }), document.addEventListener("click", (e) => {
2195
+ this.searchContainer && !this.searchContainer.contains(e.target) && this.searchResults && (this.searchResults.style.display = "none");
2196
+ }));
2197
+ }
2198
+ performSearch(e) {
2199
+ if (!this.searchResults) return;
2200
+ if (e.trim().length === 0) {
2201
+ this.searchResults.style.display = "none";
2202
+ return;
2203
+ }
2204
+ const { nodeResults: s, edgeResults: t } = this.onSearch(e);
2205
+ if (s.length === 0 && t.length === 0) {
2206
+ this.searchResults.innerHTML = '<div class="f3d-no-results">No results found</div>', this.searchResults.style.display = "block";
2207
+ return;
2208
+ }
2209
+ let i = "";
2210
+ s.length > 0 && (i += '<div class="f3d-search-section-header">Nodes</div>', s.slice(0, 10).forEach((n) => {
2211
+ const a = n.type || "Node";
2212
+ i += `
2213
+ <div class="f3d-search-result-item" data-node-id="${this.escapeHtml(n.id)}">
2214
+ <div class="f3d-result-label">${this.escapeHtml(n.label)}</div>
2215
+ <div class="f3d-result-type">${this.escapeHtml(a)}</div>
2216
+ </div>
2217
+ `;
2218
+ }), 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 }) => {
2219
+ i += `
2220
+ <div class="f3d-search-result-item" data-node-id="${this.escapeHtml(n.source)}">
2221
+ <div class="f3d-result-label">${this.escapeHtml(a.label)} → ${this.escapeHtml(l.label)}</div>
2222
+ <div class="f3d-result-relationship">${this.escapeHtml(n.relationship || "connected")}</div>
2223
+ </div>
2224
+ `;
2225
+ }), 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) => {
2226
+ n.addEventListener("click", () => {
2227
+ const a = n.dataset.nodeId;
2228
+ a && (this.onResultClick(a), this.searchResults && (this.searchResults.style.display = "none"), this.searchInput && this.searchInput.blur());
2229
+ });
2230
+ });
2231
+ }
2232
+ escapeHtml(e) {
2233
+ const s = document.createElement("div");
2234
+ return s.textContent = e, s.innerHTML;
2235
+ }
2236
+ dispose() {
2237
+ this.searchContainer && this.searchContainer.parentNode && this.searchContainer.parentNode.removeChild(this.searchContainer);
2238
+ }
2239
+ }
2065
2240
  class Ot {
2066
- constructor(e, o = {}) {
2241
+ constructor(e, s = {}) {
2067
2242
  // Options
2068
2243
  r(this, "options");
2069
2244
  r(this, "container");
@@ -2084,27 +2259,28 @@ class Ot {
2084
2259
  r(this, "raycasterManager");
2085
2260
  r(this, "panelManager");
2086
2261
  r(this, "edgeTooltipManager");
2262
+ r(this, "searchManager", null);
2087
2263
  // Event system
2088
2264
  r(this, "eventCallbacks", /* @__PURE__ */ new Map());
2089
2265
  // State
2090
2266
  r(this, "initialized", !1);
2091
2267
  r(this, "devControls", null);
2092
- this.options = { ...O, ...o }, this.container = ct(e), this.materialFactory = new bt(), this.nodeFactory = new vt(
2268
+ this.options = { ...L, ...s }, this.container = ct(e), this.materialFactory = new xt(), this.nodeFactory = new vt(
2093
2269
  this.materialFactory,
2094
- this.options.nodeRadius ?? O.nodeRadius,
2095
- this.options.lodSegments ?? O.lodSegments
2270
+ this.options.nodeRadius ?? L.nodeRadius,
2271
+ this.options.lodSegments ?? L.lodSegments
2096
2272
  ), this.edgeFactory = new Mt(
2097
2273
  this.materialFactory,
2098
- this.options.edgeColor ?? O.edgeColor,
2099
- this.options.edgeOpacity ?? O.edgeOpacity
2100
- ), this.sceneManager = new ut(this.container, this.options), this.lodManager = new Et(
2274
+ this.options.edgeColor ?? L.edgeColor,
2275
+ this.options.edgeOpacity ?? L.edgeOpacity
2276
+ ), this.sceneManager = new gt(this.container, this.options), this.lodManager = new wt(
2101
2277
  this.sceneManager.camera,
2102
- this.options.lodDistances ?? O.lodDistances,
2103
- this.options.enableLOD ?? O.enableLOD
2104
- ), this.frustumCuller = new wt(
2278
+ this.options.lodDistances ?? L.lodDistances,
2279
+ this.options.enableLOD ?? L.enableLOD
2280
+ ), this.frustumCuller = new Et(
2105
2281
  this.sceneManager.camera,
2106
- this.options.enableEdgeCulling ?? O.enableEdgeCulling
2107
- ), this.nodeManager = new mt(this.sceneManager, this.nodeFactory), this.edgeManager = new ft(this.sceneManager, this.nodeManager, this.edgeFactory), this.graphEngine = new Le(
2282
+ this.options.enableEdgeCulling ?? L.enableEdgeCulling
2283
+ ), this.nodeManager = new mt(this.sceneManager, this.nodeFactory), this.edgeManager = new ft(this.sceneManager, this.nodeManager, this.edgeFactory), this.graphEngine = new Oe(
2108
2284
  this.nodeManager.getAllNodes(),
2109
2285
  this.edgeManager.getAllEdges(),
2110
2286
  {
@@ -2114,12 +2290,23 @@ class Ot {
2114
2290
  useBarnesHut: this.options.useBarnesHut,
2115
2291
  barnesHutTheta: this.options.barnesHutTheta
2116
2292
  }
2117
- ), this.rendererManager = new xt(
2293
+ ), this.rendererManager = new bt(
2118
2294
  this.sceneManager,
2119
2295
  () => this.onSimulate(),
2120
2296
  () => this.onRender(),
2121
- this.options.targetFPS ?? O.targetFPS
2122
- ), this.raycasterManager = new Ct(this.sceneManager, this.container), this.panelManager = new Nt(this.container), this.edgeTooltipManager = new zt(), this.setupCallbacks(), this.rendererManager.start(), this.initialized = !0, this.emit("ready");
2297
+ this.options.targetFPS ?? L.targetFPS
2298
+ ), 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, {
2299
+ placeholder: this.options.searchPlaceholder,
2300
+ onSearch: (t) => ({
2301
+ nodeResults: this.searchNodes(t),
2302
+ edgeResults: this.searchEdges(t)
2303
+ }),
2304
+ onResultClick: (t) => {
2305
+ this.focusOnNode(t), setTimeout(() => {
2306
+ this.showNodePanel(t);
2307
+ }, 400);
2308
+ }
2309
+ })), this.setupCallbacks(), this.rendererManager.start(), this.initialized = !0, this.emit("ready");
2123
2310
  }
2124
2311
  /**
2125
2312
  * Sets up internal callbacks
@@ -2127,8 +2314,8 @@ class Ot {
2127
2314
  setupCallbacks() {
2128
2315
  this.raycasterManager.setClickCallback((e) => {
2129
2316
  this.onNodeClick(e);
2130
- }), this.options.onNodeHover && this.raycasterManager.setHoverCallback(this.options.onNodeHover), this.panelManager.setExpandCallback((e, o) => {
2131
- this.expandNode(e, o);
2317
+ }), this.options.onNodeHover && this.raycasterManager.setHoverCallback(this.options.onNodeHover), this.panelManager.setExpandCallback((e, s) => {
2318
+ this.expandNode(e, s);
2132
2319
  }), this.options.panelTemplate && this.panelManager.setPanelTemplate(this.options.panelTemplate), this.options.panelStyles && this.panelManager.setPanelStyles(this.options.panelStyles), this.raycasterManager.setEdgeHoverCallback((e) => {
2133
2320
  this.onEdgeHover(e);
2134
2321
  });
@@ -2139,8 +2326,8 @@ class Ot {
2139
2326
  onEdgeHover(e) {
2140
2327
  if (e) {
2141
2328
  this.edgeManager.highlightEdge(e.edge.source, e.edge.target);
2142
- const o = this.container.getBoundingClientRect(), t = o.left + o.width / 2, n = o.top + o.height / 2;
2143
- 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);
2329
+ const s = this.container.getBoundingClientRect(), t = s.left + s.width / 2, i = s.top + s.height / 2;
2330
+ 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);
2144
2331
  } else
2145
2332
  this.edgeManager.unhighlightCurrentEdge(), this.edgeTooltipManager.hide(), this.options.onEdgeHover && this.options.onEdgeHover(null, null, null), this.emit("edgeHover", null, null, null);
2146
2333
  }
@@ -2148,7 +2335,7 @@ class Ot {
2148
2335
  * Handles node click
2149
2336
  */
2150
2337
  onNodeClick(e) {
2151
- const t = this.edgeManager.getNeighborIds(e.id).map((n) => this.nodeManager.getNode(n)).filter((n) => n !== void 0);
2338
+ const t = this.edgeManager.getNeighborIds(e.id).map((i) => this.nodeManager.getNode(i)).filter((i) => i !== void 0);
2152
2339
  this.options.showPanel !== !1 && this.panelManager.show(e, t), this.options.onNodeClick && this.options.onNodeClick(e), this.emit("nodeClick", e);
2153
2340
  }
2154
2341
  /**
@@ -2156,9 +2343,9 @@ class Ot {
2156
2343
  */
2157
2344
  onSimulate() {
2158
2345
  this.graphEngine.simulate();
2159
- for (const [e, o] of this.nodeManager.getAllNodes())
2160
- if (this.nodeManager.updateNodePosition(e, o.position), this.options.enableLOD) {
2161
- const t = this.lodManager.getLODLevel(o.position);
2346
+ for (const [e, s] of this.nodeManager.getAllNodes())
2347
+ if (this.nodeManager.updateNodePosition(e, s.position), this.options.enableLOD) {
2348
+ const t = this.lodManager.getLODLevel(s.position);
2162
2349
  this.nodeManager.updateNodeLOD(e, t);
2163
2350
  }
2164
2351
  this.edgeManager.updateEdgePositions();
@@ -2177,12 +2364,12 @@ class Ot {
2177
2364
  */
2178
2365
  setData(e) {
2179
2366
  if (this.edgeManager.clear(), this.nodeManager.clear(), e.nodes && Array.isArray(e.nodes))
2180
- for (const o of e.nodes)
2181
- this.addNode(o);
2367
+ for (const s of e.nodes)
2368
+ this.addNode(s);
2182
2369
  if (e.edges && Array.isArray(e.edges))
2183
- for (const o of e.edges)
2184
- this.addEdge(o);
2185
- this.graphEngine = new Le(
2370
+ for (const s of e.edges)
2371
+ this.addEdge(s);
2372
+ this.graphEngine = new Oe(
2186
2373
  this.nodeManager.getAllNodes(),
2187
2374
  this.edgeManager.getAllEdges(),
2188
2375
  {
@@ -2199,10 +2386,10 @@ class Ot {
2199
2386
  * @returns true if added, false if node already exists or invalid
2200
2387
  */
2201
2388
  addNode(e) {
2202
- if (!Ie(e))
2389
+ if (!Re(e))
2203
2390
  return !1;
2204
- const o = this.nodeManager.addNode(e);
2205
- return o && (this.graphEngine.restart(), this.options.onNodeAdd && this.options.onNodeAdd(e), this.emit("nodeAdd", e)), o;
2391
+ const s = this.nodeManager.addNode(e);
2392
+ return s && (this.graphEngine.restart(), this.options.onNodeAdd && this.options.onNodeAdd(e), this.emit("nodeAdd", e)), s;
2206
2393
  }
2207
2394
  /**
2208
2395
  * Removes a node from the graph
@@ -2212,32 +2399,32 @@ class Ot {
2212
2399
  if (!ht(e))
2213
2400
  return !1;
2214
2401
  this.edgeManager.removeEdgesForNode(e);
2215
- const o = this.nodeManager.removeNode(e);
2216
- return o && (this.graphEngine.restart(), this.options.onNodeRemove && this.options.onNodeRemove(e), this.emit("nodeRemove", e), this.panelManager.getCurrentNodeId() === e && this.panelManager.hide()), o;
2402
+ const s = this.nodeManager.removeNode(e);
2403
+ return s && (this.graphEngine.restart(), this.options.onNodeRemove && this.options.onNodeRemove(e), this.emit("nodeRemove", e), this.panelManager.getCurrentNodeId() === e && this.panelManager.hide()), s;
2217
2404
  }
2218
2405
  /**
2219
2406
  * Updates a node's properties
2220
2407
  */
2221
- updateNode(e, o) {
2222
- return this.nodeManager.updateNode(e, o);
2408
+ updateNode(e, s) {
2409
+ return this.nodeManager.updateNode(e, s);
2223
2410
  }
2224
2411
  /**
2225
2412
  * Adds an edge to the graph
2226
2413
  * @returns true if added, false if edge already exists or nodes don't exist
2227
2414
  */
2228
2415
  addEdge(e) {
2229
- if (!Re(e))
2416
+ if (!Fe(e))
2230
2417
  return !1;
2231
- const o = this.edgeManager.addEdge(e);
2232
- return o && (this.graphEngine.setEdges(this.edgeManager.getAllEdges()), this.graphEngine.restart(), this.options.onEdgeAdd && this.options.onEdgeAdd(e), this.emit("edgeAdd", e)), o;
2418
+ const s = this.edgeManager.addEdge(e);
2419
+ return s && (this.graphEngine.setEdges(this.edgeManager.getAllEdges()), this.graphEngine.restart(), this.options.onEdgeAdd && this.options.onEdgeAdd(e), this.emit("edgeAdd", e)), s;
2233
2420
  }
2234
2421
  /**
2235
2422
  * Removes an edge from the graph
2236
2423
  * @returns true if removed, false if not found
2237
2424
  */
2238
- removeEdge(e, o) {
2239
- const t = this.edgeManager.removeEdge(e, o);
2240
- return t && (this.graphEngine.setEdges(this.edgeManager.getAllEdges()), this.options.onEdgeRemove && this.options.onEdgeRemove({ source: e, target: o }), this.emit("edgeRemove", { source: e, target: o })), t;
2425
+ removeEdge(e, s) {
2426
+ const t = this.edgeManager.removeEdge(e, s);
2427
+ return t && (this.graphEngine.setEdges(this.edgeManager.getAllEdges()), this.options.onEdgeRemove && this.options.onEdgeRemove({ source: e, target: s }), this.emit("edgeRemove", { source: e, target: s })), t;
2241
2428
  }
2242
2429
  /**
2243
2430
  * Expands a node by fetching more data
@@ -2245,21 +2432,21 @@ class Ot {
2245
2432
  * @param depth - The depth of expansion (1-3 levels, default 1)
2246
2433
  * @param fetchFn - Optional fetch function to override the default
2247
2434
  */
2248
- async expandNode(e, o = 1, t) {
2249
- const n = t ?? this.options.onExpand;
2250
- if (!n)
2435
+ async expandNode(e, s = 1, t) {
2436
+ const i = t ?? this.options.onExpand;
2437
+ if (!i)
2251
2438
  return console.warn("[ForceGraph3D] No expand callback provided"), !1;
2252
2439
  try {
2253
- const i = await n(e, o);
2254
- if (i.nodes && Array.isArray(i.nodes))
2255
- for (const a of i.nodes)
2440
+ const n = await i(e, s);
2441
+ if (n.nodes && Array.isArray(n.nodes))
2442
+ for (const a of n.nodes)
2256
2443
  this.addNode(a);
2257
- if (i.edges && Array.isArray(i.edges))
2258
- for (const a of i.edges)
2444
+ if (n.edges && Array.isArray(n.edges))
2445
+ for (const a of n.edges)
2259
2446
  this.addEdge(a);
2260
- return this.panelManager.hide(), this.emit("expand", e, i), !0;
2261
- } catch (i) {
2262
- return console.error("[ForceGraph3D] Error expanding node:", i), !1;
2447
+ return this.panelManager.hide(), this.emit("expand", e, n), !0;
2448
+ } catch (n) {
2449
+ return console.error("[ForceGraph3D] Error expanding node:", n), !1;
2263
2450
  }
2264
2451
  }
2265
2452
  /**
@@ -2296,19 +2483,19 @@ class Ot {
2296
2483
  /**
2297
2484
  * Focuses the camera on a specific node with smooth animation
2298
2485
  */
2299
- focusOnNode(e, o = 30) {
2486
+ focusOnNode(e, s = 30) {
2300
2487
  const t = this.nodeManager.getNode(e);
2301
2488
  if (!t) {
2302
2489
  console.warn(`[ForceGraph3D] Node "${e}" not found`);
2303
2490
  return;
2304
2491
  }
2305
- const n = t.position, i = this.sceneManager.camera, a = this.sceneManager.controls, l = i.position.clone().sub(a.target).normalize(), d = {
2306
- x: n.x + l.x * o,
2307
- y: n.y + l.y * o,
2308
- z: n.z + l.z * o
2309
- }, g = { x: i.position.x, y: i.position.y, z: i.position.z }, u = { x: a.target.x, y: a.target.y, z: a.target.z }, x = 800, v = performance.now(), y = () => {
2310
- const f = performance.now() - v, M = Math.min(f / x, 1), C = 1 - Math.pow(1 - M, 3);
2311
- i.position.x = g.x + (d.x - g.x) * C, i.position.y = g.y + (d.y - g.y) * C, i.position.z = g.z + (d.z - g.z) * C, a.target.x = u.x + (n.x - u.x) * C, a.target.y = u.y + (n.y - u.y) * C, a.target.z = u.z + (n.z - u.z) * C, a.update(), M < 1 && requestAnimationFrame(y);
2492
+ const i = t.position, n = this.sceneManager.camera, a = this.sceneManager.controls, l = n.position.clone().sub(a.target).normalize(), d = {
2493
+ x: i.x + l.x * s,
2494
+ y: i.y + l.y * s,
2495
+ z: i.z + l.z * s
2496
+ }, 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 = () => {
2497
+ const f = performance.now() - v, M = Math.min(f / b, 1), C = 1 - Math.pow(1 - M, 3);
2498
+ 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);
2312
2499
  };
2313
2500
  y();
2314
2501
  }
@@ -2316,13 +2503,13 @@ class Ot {
2316
2503
  * Shows the info panel for a specific node
2317
2504
  */
2318
2505
  showNodePanel(e) {
2319
- const o = this.nodeManager.getNode(e);
2320
- if (!o) {
2506
+ const s = this.nodeManager.getNode(e);
2507
+ if (!s) {
2321
2508
  console.warn(`[ForceGraph3D] Node "${e}" not found`);
2322
2509
  return;
2323
2510
  }
2324
2511
  const t = this.getNeighbors(e);
2325
- this.panelManager.show(o, t);
2512
+ this.panelManager.show(s, t);
2326
2513
  }
2327
2514
  /**
2328
2515
  * Searches nodes by label or ID (case-insensitive)
@@ -2331,28 +2518,28 @@ class Ot {
2331
2518
  searchNodes(e) {
2332
2519
  if (!e || e.trim() === "")
2333
2520
  return [];
2334
- const o = e.toLowerCase().trim(), t = this.nodeManager.getAllNodes(), n = [];
2335
- return t.forEach((i) => {
2336
- var g, u, x;
2337
- const a = (g = i.label) == null ? void 0 : g.toLowerCase().includes(o), l = (u = i.id) == null ? void 0 : u.toLowerCase().includes(o), d = (x = i.type) == null ? void 0 : x.toLowerCase().includes(o);
2338
- (a || l || d) && n.push(i);
2339
- }), n;
2521
+ const s = e.toLowerCase().trim(), t = this.nodeManager.getAllNodes(), i = [];
2522
+ return t.forEach((n) => {
2523
+ var u, g, b;
2524
+ 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);
2525
+ (a || l || d) && i.push(n);
2526
+ }), i;
2340
2527
  }
2341
2528
  /**
2342
2529
  * Searches edges by relationship (case-insensitive)
2343
2530
  * @returns Array of matching edges with source/target node info
2344
2531
  */
2345
2532
  searchEdges(e) {
2346
- var i;
2533
+ var n;
2347
2534
  if (!e || e.trim() === "")
2348
2535
  return [];
2349
- const o = e.toLowerCase().trim(), t = this.edgeManager.getAllEdges(), n = [];
2536
+ const s = e.toLowerCase().trim(), t = this.edgeManager.getAllEdges(), i = [];
2350
2537
  for (const a of t)
2351
- if ((i = a.relationship) == null ? void 0 : i.toLowerCase().includes(o)) {
2352
- const d = this.nodeManager.getNode(a.source), g = this.nodeManager.getNode(a.target);
2353
- d && g && n.push({ edge: a, sourceNode: d, targetNode: g });
2538
+ if ((n = a.relationship) == null ? void 0 : n.toLowerCase().includes(s)) {
2539
+ const d = this.nodeManager.getNode(a.source), u = this.nodeManager.getNode(a.target);
2540
+ d && u && i.push({ edge: a, sourceNode: d, targetNode: u });
2354
2541
  }
2355
- return n;
2542
+ return i;
2356
2543
  }
2357
2544
  /**
2358
2545
  * Gets all nodes as an array
@@ -2376,15 +2563,15 @@ class Ot {
2376
2563
  /**
2377
2564
  * Registers an event listener
2378
2565
  */
2379
- on(e, o) {
2380
- this.eventCallbacks.has(e) || this.eventCallbacks.set(e, []), this.eventCallbacks.get(e).push(o);
2566
+ on(e, s) {
2567
+ this.eventCallbacks.has(e) || this.eventCallbacks.set(e, []), this.eventCallbacks.get(e).push(s);
2381
2568
  }
2382
2569
  /**
2383
2570
  * Emits an event
2384
2571
  */
2385
- emit(e, ...o) {
2572
+ emit(e, ...s) {
2386
2573
  const t = this.eventCallbacks.get(e);
2387
- t && t.forEach((n) => n(...o));
2574
+ t && t.forEach((i) => i(...s));
2388
2575
  }
2389
2576
  /**
2390
2577
  * Sets physics parameters
@@ -2459,29 +2646,29 @@ class Ot {
2459
2646
  <div>FPS: <span class="value" id="dev-fps">60</span></div>
2460
2647
  </div>
2461
2648
  `, this.container.appendChild(this.devControls);
2462
- const e = this.devControls.querySelector("#dev-repulsion"), o = this.devControls.querySelector("#dev-attraction"), t = this.devControls.querySelector("#dev-damping");
2649
+ const e = this.devControls.querySelector("#dev-repulsion"), s = this.devControls.querySelector("#dev-attraction"), t = this.devControls.querySelector("#dev-damping");
2463
2650
  e == null || e.addEventListener("input", () => {
2464
- const n = parseFloat(e.value);
2465
- this.setPhysicsParams({ repulsionStrength: n }), this.devControls.querySelector("#dev-repulsion-val").textContent = n.toString();
2466
- }), o == null || o.addEventListener("input", () => {
2467
- const n = parseFloat(o.value) / 1e3;
2468
- this.setPhysicsParams({ attractionStrength: n }), this.devControls.querySelector("#dev-attraction-val").textContent = n.toFixed(3);
2651
+ const i = parseFloat(e.value);
2652
+ this.setPhysicsParams({ repulsionStrength: i }), this.devControls.querySelector("#dev-repulsion-val").textContent = i.toString();
2653
+ }), s == null || s.addEventListener("input", () => {
2654
+ const i = parseFloat(s.value) / 1e3;
2655
+ this.setPhysicsParams({ attractionStrength: i }), this.devControls.querySelector("#dev-attraction-val").textContent = i.toFixed(3);
2469
2656
  }), t == null || t.addEventListener("input", () => {
2470
- const n = parseFloat(t.value) / 100;
2471
- this.setPhysicsParams({ damping: n }), this.devControls.querySelector("#dev-damping-val").textContent = n.toFixed(2);
2657
+ const i = parseFloat(t.value) / 100;
2658
+ this.setPhysicsParams({ damping: i }), this.devControls.querySelector("#dev-damping-val").textContent = i.toFixed(2);
2472
2659
  }), setInterval(() => {
2473
- const n = this.devControls.querySelector("#dev-node-count"), i = this.devControls.querySelector("#dev-edge-count"), a = this.devControls.querySelector("#dev-fps");
2474
- n && (n.textContent = this.getNodeCount().toString()), i && (i.textContent = this.getEdgeCount().toString()), a && (a.textContent = this.rendererManager.getFPS().toString());
2660
+ const i = this.devControls.querySelector("#dev-node-count"), n = this.devControls.querySelector("#dev-edge-count"), a = this.devControls.querySelector("#dev-fps");
2661
+ i && (i.textContent = this.getNodeCount().toString()), n && (n.textContent = this.getEdgeCount().toString()), a && (a.textContent = this.rendererManager.getFPS().toString());
2475
2662
  }, 500);
2476
2663
  }
2477
2664
  /**
2478
2665
  * Destroys the graph and releases all resources
2479
2666
  */
2480
2667
  destroy() {
2481
- this.rendererManager.dispose(), this.panelManager.dispose(), this.raycasterManager.dispose(), this.edgeTooltipManager.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;
2668
+ 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;
2482
2669
  }
2483
2670
  }
2484
- const Fe = [
2671
+ const ke = [
2485
2672
  "Alpha",
2486
2673
  "Beta",
2487
2674
  "Gamma",
@@ -2523,7 +2710,7 @@ const Fe = [
2523
2710
  "partners with",
2524
2711
  "collaborates with",
2525
2712
  "supports"
2526
- ], ke = [
2713
+ ], Ie = [
2527
2714
  16777215,
2528
2715
  // White
2529
2716
  16750950,
@@ -2535,14 +2722,14 @@ const Fe = [
2535
2722
  16746564
2536
2723
  // Darker tangerine
2537
2724
  ];
2538
- function Lt(c = 30) {
2539
- const e = [], o = [];
2540
- for (let n = 0; n < c; n++) {
2541
- const i = n < Fe.length ? Fe[n] : `Node ${n + 1}`;
2725
+ function kt(c = 30) {
2726
+ const e = [], s = [];
2727
+ for (let i = 0; i < c; i++) {
2728
+ const n = i < ke.length ? ke[i] : `Node ${i + 1}`;
2542
2729
  e.push({
2543
- id: `node-${n}`,
2544
- label: i,
2545
- color: ke[n % ke.length],
2730
+ id: `node-${i}`,
2731
+ label: n,
2732
+ color: Ie[i % Ie.length],
2546
2733
  position: {
2547
2734
  x: (Math.random() - 0.5) * 60,
2548
2735
  y: (Math.random() - 0.5) * 60,
@@ -2550,43 +2737,43 @@ function Lt(c = 30) {
2550
2737
  }
2551
2738
  });
2552
2739
  }
2553
- for (let n = 1; n < c; n++) {
2554
- const i = Math.floor(Math.random() * n);
2555
- o.push({
2556
- source: `node-${n}`,
2557
- target: `node-${i}`,
2740
+ for (let i = 1; i < c; i++) {
2741
+ const n = Math.floor(Math.random() * i);
2742
+ s.push({
2743
+ source: `node-${i}`,
2744
+ target: `node-${n}`,
2558
2745
  relationship: Q[Math.floor(Math.random() * Q.length)]
2559
2746
  });
2560
2747
  }
2561
2748
  const t = Math.floor(c * 0.5);
2562
- for (let n = 0; n < t; n++) {
2563
- const i = Math.floor(Math.random() * c);
2749
+ for (let i = 0; i < t; i++) {
2750
+ const n = Math.floor(Math.random() * c);
2564
2751
  let a = Math.floor(Math.random() * c);
2565
- i === a && (a = (a + 1) % c);
2566
- const l = `node-${i}`, d = `node-${a}`;
2567
- o.some(
2568
- (u) => u.source === l && u.target === d || u.source === d && u.target === l
2569
- ) || o.push({
2752
+ n === a && (a = (a + 1) % c);
2753
+ const l = `node-${n}`, d = `node-${a}`;
2754
+ s.some(
2755
+ (g) => g.source === l && g.target === d || g.source === d && g.target === l
2756
+ ) || s.push({
2570
2757
  source: l,
2571
2758
  target: d,
2572
2759
  relationship: Q[Math.floor(Math.random() * Q.length)]
2573
2760
  });
2574
2761
  }
2575
- return { nodes: e, edges: o };
2762
+ return { nodes: e, edges: s };
2576
2763
  }
2577
- function Ft(c = 1e3) {
2578
- const e = [], o = [], t = Math.ceil(c / 50), n = [];
2579
- for (let i = 0; i < t; i++)
2580
- n.push({
2764
+ function It(c = 1e3) {
2765
+ const e = [], s = [], t = Math.ceil(c / 50), i = [];
2766
+ for (let n = 0; n < t; n++)
2767
+ i.push({
2581
2768
  x: (Math.random() - 0.5) * 200,
2582
2769
  y: (Math.random() - 0.5) * 200,
2583
2770
  z: (Math.random() - 0.5) * 200
2584
2771
  });
2585
- for (let i = 0; i < c; i++) {
2586
- const a = n[i % t];
2772
+ for (let n = 0; n < c; n++) {
2773
+ const a = i[n % t];
2587
2774
  e.push({
2588
- id: `node-${i}`,
2589
- label: `N${i}`,
2775
+ id: `node-${n}`,
2776
+ label: `N${n}`,
2590
2777
  position: {
2591
2778
  x: a.x + (Math.random() - 0.5) * 40,
2592
2779
  y: a.y + (Math.random() - 0.5) * 40,
@@ -2594,32 +2781,32 @@ function Ft(c = 1e3) {
2594
2781
  }
2595
2782
  });
2596
2783
  }
2597
- for (let i = 1; i < c; i++) {
2598
- const a = Math.floor(i / 50) * 50, l = a === 0 ? Math.floor(Math.random() * i) : a + Math.floor(Math.random() * Math.min(i - a, 50));
2599
- o.push({
2600
- source: `node-${i}`,
2601
- target: `node-${Math.min(l, i - 1)}`,
2784
+ for (let n = 1; n < c; n++) {
2785
+ 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));
2786
+ s.push({
2787
+ source: `node-${n}`,
2788
+ target: `node-${Math.min(l, n - 1)}`,
2602
2789
  relationship: "links to"
2603
2790
  });
2604
2791
  }
2605
- for (let i = 1; i < t; i++) {
2606
- const a = i * 50, l = (i - 1) * 50 + Math.floor(Math.random() * 50);
2607
- o.push({
2792
+ for (let n = 1; n < t; n++) {
2793
+ const a = n * 50, l = (n - 1) * 50 + Math.floor(Math.random() * 50);
2794
+ s.push({
2608
2795
  source: `node-${a}`,
2609
2796
  target: `node-${l}`,
2610
2797
  relationship: "bridges to"
2611
2798
  });
2612
2799
  }
2613
- return { nodes: e, edges: o };
2800
+ return { nodes: e, edges: s };
2614
2801
  }
2615
2802
  export {
2616
- O as DEFAULT_OPTIONS,
2803
+ L as DEFAULT_OPTIONS,
2617
2804
  Ot as ForceGraph3D,
2618
- _ as LODLevel,
2619
- I as createEdgeKey,
2620
- Ft as generateLargeSampleData,
2621
- Lt as generateSampleData,
2622
- Re as validateEdgeData,
2623
- Ie as validateNodeData
2805
+ U as LODLevel,
2806
+ R as createEdgeKey,
2807
+ It as generateLargeSampleData,
2808
+ kt as generateSampleData,
2809
+ Fe as validateEdgeData,
2810
+ Re as validateNodeData
2624
2811
  };
2625
2812
  //# sourceMappingURL=force-3d-graph.js.map