force-3d-graph 1.0.3 → 1.2.0

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