@omiron33/omi-neuron-web 0.2.21 → 0.2.22
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.
- package/README.md +157 -1
- package/dist/{NeuronWebExplorer-lBM0Jcf9.d.ts → NeuronWebExplorer-CB7Vkkce.d.cts} +5 -1
- package/dist/{NeuronWebExplorer-7sRtXdqa.d.cts → NeuronWebExplorer-DFyhvtXO.d.ts} +5 -1
- package/dist/api/index.d.cts +3 -3
- package/dist/api/index.d.ts +3 -3
- package/dist/{chunk-XSDOIONK.js → chunk-E4TZDZ5U.js} +353 -7
- package/dist/chunk-E4TZDZ5U.js.map +1 -0
- package/dist/{chunk-5SZ37JXQ.cjs → chunk-HOW2F2KP.cjs} +353 -6
- package/dist/chunk-HOW2F2KP.cjs.map +1 -0
- package/dist/{edge-U2Qgwg-K.d.cts → cluster-CU_pBUcK.d.cts} +123 -1
- package/dist/{edge-U2Qgwg-K.d.ts → cluster-CU_pBUcK.d.ts} +123 -1
- package/dist/index.cjs +655 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +66 -7
- package/dist/index.d.ts +66 -7
- package/dist/index.js +641 -4
- package/dist/index.js.map +1 -1
- package/dist/{query-helpers-DMnkjfO0.d.cts → query-helpers-CA23s1ct.d.cts} +2 -102
- package/dist/{query-helpers-BpVwXZJk.d.ts → query-helpers-CdDGFiK3.d.ts} +2 -102
- package/dist/visualization/index.cjs +18 -14
- package/dist/visualization/index.d.cts +9 -5
- package/dist/visualization/index.d.ts +9 -5
- package/dist/visualization/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-5SZ37JXQ.cjs.map +0 -1
- package/dist/chunk-XSDOIONK.js.map +0 -1
|
@@ -32,11 +32,26 @@ function _interopNamespace(e) {
|
|
|
32
32
|
var THREE3__namespace = /*#__PURE__*/_interopNamespace(THREE3);
|
|
33
33
|
|
|
34
34
|
// src/visualization/constants.ts
|
|
35
|
+
var DEFAULT_STATUS_COLORS = {
|
|
36
|
+
default: "#c0c5ff",
|
|
37
|
+
// Same as defaultDomainColor (lavender)
|
|
38
|
+
draft: "#9ca3af",
|
|
39
|
+
// Gray
|
|
40
|
+
active: "#4ade80",
|
|
41
|
+
// Green
|
|
42
|
+
complete: "#60a5fa",
|
|
43
|
+
// Blue
|
|
44
|
+
blocked: "#f87171",
|
|
45
|
+
// Red
|
|
46
|
+
archived: "#6b7280"
|
|
47
|
+
// Dark gray
|
|
48
|
+
};
|
|
35
49
|
var DEFAULT_THEME = {
|
|
36
50
|
colors: {
|
|
37
51
|
background: "#020314",
|
|
38
52
|
domainColors: {},
|
|
39
53
|
defaultDomainColor: "#c0c5ff",
|
|
54
|
+
statusColors: DEFAULT_STATUS_COLORS,
|
|
40
55
|
edgeDefault: "#4d4d55",
|
|
41
56
|
edgeActive: "#c6d4ff",
|
|
42
57
|
edgeSelected: "#ffffff",
|
|
@@ -505,9 +520,14 @@ var NodeRenderer = class {
|
|
|
505
520
|
const shouldRenderLabels = labelVisibility !== "none" && (labelVisibility === "interaction" || this.config.maxVisibleLabels > 0 && this.config.labelDistance > 0);
|
|
506
521
|
const resolveNode = (node) => {
|
|
507
522
|
const tier = node.tier ?? "tertiary";
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
523
|
+
let baseColor;
|
|
524
|
+
if (node.status && this.config.statusColors?.[node.status]) {
|
|
525
|
+
baseColor = new THREE3__namespace.Color(this.config.statusColors[node.status]);
|
|
526
|
+
} else {
|
|
527
|
+
baseColor = new THREE3__namespace.Color(
|
|
528
|
+
this.config.domainColors[node.domain] ?? this.config.defaultColor
|
|
529
|
+
);
|
|
530
|
+
}
|
|
511
531
|
const position = new THREE3__namespace.Vector3();
|
|
512
532
|
if (node.position) {
|
|
513
533
|
position.set(...node.position);
|
|
@@ -1952,6 +1972,299 @@ var EdgeRenderer = class {
|
|
|
1952
1972
|
arrow.quaternion.setFromUnitVectors(new THREE3__namespace.Vector3(0, 1, 0), direction);
|
|
1953
1973
|
}
|
|
1954
1974
|
};
|
|
1975
|
+
function computeConvexHull2D(points) {
|
|
1976
|
+
if (points.length < 3) {
|
|
1977
|
+
return points.map((p) => new THREE3__namespace.Vector2(p.x, p.y));
|
|
1978
|
+
}
|
|
1979
|
+
const points2D = points.map((p) => new THREE3__namespace.Vector2(p.x, p.y));
|
|
1980
|
+
let minIdx = 0;
|
|
1981
|
+
for (let i = 1; i < points2D.length; i++) {
|
|
1982
|
+
if (points2D[i].y < points2D[minIdx].y || points2D[i].y === points2D[minIdx].y && points2D[i].x < points2D[minIdx].x) {
|
|
1983
|
+
minIdx = i;
|
|
1984
|
+
}
|
|
1985
|
+
}
|
|
1986
|
+
[points2D[0], points2D[minIdx]] = [points2D[minIdx], points2D[0]];
|
|
1987
|
+
const pivot = points2D[0];
|
|
1988
|
+
const rest = points2D.slice(1).sort((a, b) => {
|
|
1989
|
+
const angleA = Math.atan2(a.y - pivot.y, a.x - pivot.x);
|
|
1990
|
+
const angleB = Math.atan2(b.y - pivot.y, b.x - pivot.x);
|
|
1991
|
+
if (angleA !== angleB) return angleA - angleB;
|
|
1992
|
+
return a.distanceTo(pivot) - b.distanceTo(pivot);
|
|
1993
|
+
});
|
|
1994
|
+
const hull = [pivot];
|
|
1995
|
+
for (const point of rest) {
|
|
1996
|
+
while (hull.length > 1) {
|
|
1997
|
+
const top = hull[hull.length - 1];
|
|
1998
|
+
const nextToTop = hull[hull.length - 2];
|
|
1999
|
+
const cross = (top.x - nextToTop.x) * (point.y - nextToTop.y) - (top.y - nextToTop.y) * (point.x - nextToTop.x);
|
|
2000
|
+
if (cross <= 0) {
|
|
2001
|
+
hull.pop();
|
|
2002
|
+
} else {
|
|
2003
|
+
break;
|
|
2004
|
+
}
|
|
2005
|
+
}
|
|
2006
|
+
hull.push(point);
|
|
2007
|
+
}
|
|
2008
|
+
return hull;
|
|
2009
|
+
}
|
|
2010
|
+
function expandHull(hull, padding) {
|
|
2011
|
+
if (hull.length < 3 || padding <= 0) return hull;
|
|
2012
|
+
const centroid = new THREE3__namespace.Vector2(0, 0);
|
|
2013
|
+
for (const p of hull) {
|
|
2014
|
+
centroid.add(p);
|
|
2015
|
+
}
|
|
2016
|
+
centroid.divideScalar(hull.length);
|
|
2017
|
+
return hull.map((p) => {
|
|
2018
|
+
const dir = new THREE3__namespace.Vector2().subVectors(p, centroid).normalize();
|
|
2019
|
+
return new THREE3__namespace.Vector2(p.x + dir.x * padding, p.y + dir.y * padding);
|
|
2020
|
+
});
|
|
2021
|
+
}
|
|
2022
|
+
var ClusterRenderer = class {
|
|
2023
|
+
constructor(scene, config = {}) {
|
|
2024
|
+
this.scene = scene;
|
|
2025
|
+
this.config = {
|
|
2026
|
+
defaultColor: config.defaultColor ?? "#4a5568",
|
|
2027
|
+
fillOpacity: config.fillOpacity ?? 0.08,
|
|
2028
|
+
strokeOpacity: config.strokeOpacity ?? 0.25,
|
|
2029
|
+
strokeWidth: config.strokeWidth ?? 1.5,
|
|
2030
|
+
labelFontFamily: config.labelFontFamily ?? "system-ui, sans-serif",
|
|
2031
|
+
labelFontSize: config.labelFontSize ?? 11,
|
|
2032
|
+
labelTextColor: config.labelTextColor ?? "#ffffff",
|
|
2033
|
+
labelBackground: config.labelBackground ?? "rgba(0, 0, 0, 0.6)",
|
|
2034
|
+
transitionsEnabled: config.transitionsEnabled ?? true,
|
|
2035
|
+
transitionDurationMs: config.transitionDurationMs ?? 300,
|
|
2036
|
+
zOffset: config.zOffset ?? -0.5,
|
|
2037
|
+
hullPadding: config.hullPadding ?? 1.2
|
|
2038
|
+
};
|
|
2039
|
+
this.scene.add(this.group);
|
|
2040
|
+
}
|
|
2041
|
+
group = new THREE3__namespace.Group();
|
|
2042
|
+
clusterStates = /* @__PURE__ */ new Map();
|
|
2043
|
+
config;
|
|
2044
|
+
/**
|
|
2045
|
+
* Render clusters with convex hull boundaries
|
|
2046
|
+
*/
|
|
2047
|
+
renderClusters(clusters, nodePositions) {
|
|
2048
|
+
const currentIds = new Set(clusters.map((c) => c.id));
|
|
2049
|
+
for (const [id, state] of this.clusterStates) {
|
|
2050
|
+
if (!currentIds.has(id)) {
|
|
2051
|
+
this.removeClusterState(state);
|
|
2052
|
+
this.clusterStates.delete(id);
|
|
2053
|
+
}
|
|
2054
|
+
}
|
|
2055
|
+
for (const cluster of clusters) {
|
|
2056
|
+
const memberPositions = this.getMemberPositions(cluster.nodeIds, nodePositions);
|
|
2057
|
+
if (memberPositions.length < 1) {
|
|
2058
|
+
continue;
|
|
2059
|
+
}
|
|
2060
|
+
let state = this.clusterStates.get(cluster.id);
|
|
2061
|
+
if (!state) {
|
|
2062
|
+
state = this.createClusterState(cluster);
|
|
2063
|
+
this.clusterStates.set(cluster.id, state);
|
|
2064
|
+
}
|
|
2065
|
+
this.updateClusterGeometry(state, cluster, memberPositions);
|
|
2066
|
+
}
|
|
2067
|
+
}
|
|
2068
|
+
/**
|
|
2069
|
+
* Update cluster positions when nodes move (e.g., ambient motion)
|
|
2070
|
+
*/
|
|
2071
|
+
updatePositions(nodePositions) {
|
|
2072
|
+
for (const [clusterId, state] of this.clusterStates) {
|
|
2073
|
+
let hasChanged = false;
|
|
2074
|
+
for (const [nodeId, lastPos] of state.lastNodePositions) {
|
|
2075
|
+
const currentPos = nodePositions.get(nodeId);
|
|
2076
|
+
if (currentPos && !currentPos.equals(lastPos)) {
|
|
2077
|
+
hasChanged = true;
|
|
2078
|
+
break;
|
|
2079
|
+
}
|
|
2080
|
+
}
|
|
2081
|
+
if (hasChanged) {
|
|
2082
|
+
const nodeIds = Array.from(state.lastNodePositions.keys());
|
|
2083
|
+
const memberPositions = this.getMemberPositions(nodeIds, nodePositions);
|
|
2084
|
+
if (memberPositions.length > 0) {
|
|
2085
|
+
this.updateClusterGeometry(state, { id: clusterId, label: "", nodeIds }, memberPositions);
|
|
2086
|
+
}
|
|
2087
|
+
}
|
|
2088
|
+
}
|
|
2089
|
+
}
|
|
2090
|
+
/**
|
|
2091
|
+
* Update method called each frame
|
|
2092
|
+
*/
|
|
2093
|
+
update(_delta, _elapsed) {
|
|
2094
|
+
}
|
|
2095
|
+
/**
|
|
2096
|
+
* Clear all clusters
|
|
2097
|
+
*/
|
|
2098
|
+
clear() {
|
|
2099
|
+
for (const state of this.clusterStates.values()) {
|
|
2100
|
+
this.removeClusterState(state);
|
|
2101
|
+
}
|
|
2102
|
+
this.clusterStates.clear();
|
|
2103
|
+
}
|
|
2104
|
+
/**
|
|
2105
|
+
* Dispose of all resources
|
|
2106
|
+
*/
|
|
2107
|
+
dispose() {
|
|
2108
|
+
this.clear();
|
|
2109
|
+
this.scene.remove(this.group);
|
|
2110
|
+
}
|
|
2111
|
+
getMemberPositions(nodeIds, nodePositions) {
|
|
2112
|
+
const positions = [];
|
|
2113
|
+
for (const nodeId of nodeIds) {
|
|
2114
|
+
const pos = nodePositions.get(nodeId);
|
|
2115
|
+
if (pos) {
|
|
2116
|
+
positions.push(pos.clone());
|
|
2117
|
+
}
|
|
2118
|
+
}
|
|
2119
|
+
return positions;
|
|
2120
|
+
}
|
|
2121
|
+
createClusterState(cluster) {
|
|
2122
|
+
const color = new THREE3__namespace.Color(cluster.color ?? this.config.defaultColor);
|
|
2123
|
+
const labelElement = document.createElement("div");
|
|
2124
|
+
labelElement.className = "neuron-cluster-label";
|
|
2125
|
+
labelElement.style.cssText = `
|
|
2126
|
+
font-family: ${this.config.labelFontFamily};
|
|
2127
|
+
font-size: ${this.config.labelFontSize}px;
|
|
2128
|
+
font-weight: 500;
|
|
2129
|
+
color: ${this.config.labelTextColor};
|
|
2130
|
+
background: ${this.config.labelBackground};
|
|
2131
|
+
padding: 4px 10px;
|
|
2132
|
+
border-radius: 12px;
|
|
2133
|
+
white-space: nowrap;
|
|
2134
|
+
pointer-events: none;
|
|
2135
|
+
user-select: none;
|
|
2136
|
+
opacity: 0.85;
|
|
2137
|
+
text-transform: uppercase;
|
|
2138
|
+
letter-spacing: 0.5px;
|
|
2139
|
+
`;
|
|
2140
|
+
labelElement.textContent = cluster.label;
|
|
2141
|
+
const label = new CSS2DRenderer_js.CSS2DObject(labelElement);
|
|
2142
|
+
label.position.set(0, 0, 0);
|
|
2143
|
+
this.group.add(label);
|
|
2144
|
+
return {
|
|
2145
|
+
id: cluster.id,
|
|
2146
|
+
mesh: null,
|
|
2147
|
+
outline: null,
|
|
2148
|
+
label,
|
|
2149
|
+
labelElement,
|
|
2150
|
+
color,
|
|
2151
|
+
centroid: new THREE3__namespace.Vector3(),
|
|
2152
|
+
lastNodePositions: /* @__PURE__ */ new Map()
|
|
2153
|
+
};
|
|
2154
|
+
}
|
|
2155
|
+
updateClusterGeometry(state, cluster, memberPositions) {
|
|
2156
|
+
if (cluster.color) {
|
|
2157
|
+
state.color.set(cluster.color);
|
|
2158
|
+
}
|
|
2159
|
+
if (state.labelElement && cluster.label) {
|
|
2160
|
+
state.labelElement.textContent = cluster.label;
|
|
2161
|
+
}
|
|
2162
|
+
state.lastNodePositions.clear();
|
|
2163
|
+
for (let i = 0; i < cluster.nodeIds.length; i++) {
|
|
2164
|
+
if (memberPositions[i]) {
|
|
2165
|
+
state.lastNodePositions.set(cluster.nodeIds[i], memberPositions[i].clone());
|
|
2166
|
+
}
|
|
2167
|
+
}
|
|
2168
|
+
state.centroid.set(0, 0, 0);
|
|
2169
|
+
for (const pos of memberPositions) {
|
|
2170
|
+
state.centroid.add(pos);
|
|
2171
|
+
}
|
|
2172
|
+
state.centroid.divideScalar(memberPositions.length);
|
|
2173
|
+
if (cluster.position) {
|
|
2174
|
+
state.centroid.set(cluster.position.x, cluster.position.y, cluster.position.z);
|
|
2175
|
+
}
|
|
2176
|
+
if (state.label) {
|
|
2177
|
+
state.label.position.copy(state.centroid);
|
|
2178
|
+
state.label.position.y += 1.5;
|
|
2179
|
+
}
|
|
2180
|
+
if (memberPositions.length < 3) {
|
|
2181
|
+
this.removeClusterMesh(state);
|
|
2182
|
+
return;
|
|
2183
|
+
}
|
|
2184
|
+
const hull2D = computeConvexHull2D(memberPositions);
|
|
2185
|
+
const expandedHull = expandHull(hull2D, this.config.hullPadding ?? 1.2);
|
|
2186
|
+
if (expandedHull.length < 3) {
|
|
2187
|
+
this.removeClusterMesh(state);
|
|
2188
|
+
return;
|
|
2189
|
+
}
|
|
2190
|
+
const shape = new THREE3__namespace.Shape(expandedHull);
|
|
2191
|
+
const geometry = new THREE3__namespace.ShapeGeometry(shape);
|
|
2192
|
+
const avgZ = memberPositions.reduce((sum, p) => sum + p.z, 0) / memberPositions.length + (this.config.zOffset ?? -0.5);
|
|
2193
|
+
if (state.mesh) {
|
|
2194
|
+
state.mesh.geometry.dispose();
|
|
2195
|
+
state.mesh.geometry = geometry;
|
|
2196
|
+
state.mesh.position.z = avgZ;
|
|
2197
|
+
state.mesh.material.color.copy(state.color);
|
|
2198
|
+
} else {
|
|
2199
|
+
const material = new THREE3__namespace.MeshBasicMaterial({
|
|
2200
|
+
color: state.color,
|
|
2201
|
+
transparent: true,
|
|
2202
|
+
opacity: this.config.fillOpacity,
|
|
2203
|
+
side: THREE3__namespace.DoubleSide,
|
|
2204
|
+
depthWrite: false
|
|
2205
|
+
});
|
|
2206
|
+
state.mesh = new THREE3__namespace.Mesh(geometry, material);
|
|
2207
|
+
state.mesh.position.z = avgZ;
|
|
2208
|
+
state.mesh.renderOrder = -1;
|
|
2209
|
+
this.group.add(state.mesh);
|
|
2210
|
+
}
|
|
2211
|
+
const outlinePoints = [...expandedHull, expandedHull[0]].map(
|
|
2212
|
+
(p) => new THREE3__namespace.Vector3(p.x, p.y, avgZ + 0.01)
|
|
2213
|
+
);
|
|
2214
|
+
if (state.outline) {
|
|
2215
|
+
state.outline.geometry.dispose();
|
|
2216
|
+
state.outline.geometry = new THREE3__namespace.BufferGeometry().setFromPoints(outlinePoints);
|
|
2217
|
+
state.outline.material.color.copy(state.color);
|
|
2218
|
+
} else {
|
|
2219
|
+
const outlineGeometry = new THREE3__namespace.BufferGeometry().setFromPoints(outlinePoints);
|
|
2220
|
+
const outlineMaterial = new THREE3__namespace.LineBasicMaterial({
|
|
2221
|
+
color: state.color,
|
|
2222
|
+
transparent: true,
|
|
2223
|
+
opacity: this.config.strokeOpacity,
|
|
2224
|
+
linewidth: this.config.strokeWidth
|
|
2225
|
+
});
|
|
2226
|
+
state.outline = new THREE3__namespace.Line(outlineGeometry, outlineMaterial);
|
|
2227
|
+
state.outline.renderOrder = -1;
|
|
2228
|
+
this.group.add(state.outline);
|
|
2229
|
+
}
|
|
2230
|
+
}
|
|
2231
|
+
removeClusterMesh(state) {
|
|
2232
|
+
if (state.mesh) {
|
|
2233
|
+
state.mesh.geometry.dispose();
|
|
2234
|
+
state.mesh.material.dispose();
|
|
2235
|
+
this.group.remove(state.mesh);
|
|
2236
|
+
state.mesh = null;
|
|
2237
|
+
}
|
|
2238
|
+
if (state.outline) {
|
|
2239
|
+
state.outline.geometry.dispose();
|
|
2240
|
+
state.outline.material.dispose();
|
|
2241
|
+
this.group.remove(state.outline);
|
|
2242
|
+
state.outline = null;
|
|
2243
|
+
}
|
|
2244
|
+
}
|
|
2245
|
+
removeClusterState(state) {
|
|
2246
|
+
this.removeClusterMesh(state);
|
|
2247
|
+
if (state.label) {
|
|
2248
|
+
if (state.labelElement?.parentNode) {
|
|
2249
|
+
state.labelElement.parentNode.removeChild(state.labelElement);
|
|
2250
|
+
}
|
|
2251
|
+
this.group.remove(state.label);
|
|
2252
|
+
}
|
|
2253
|
+
}
|
|
2254
|
+
/**
|
|
2255
|
+
* Get cluster visibility state for external use
|
|
2256
|
+
*/
|
|
2257
|
+
getClusterIds() {
|
|
2258
|
+
return Array.from(this.clusterStates.keys());
|
|
2259
|
+
}
|
|
2260
|
+
/**
|
|
2261
|
+
* Get centroid position for a cluster
|
|
2262
|
+
*/
|
|
2263
|
+
getClusterCentroid(clusterId) {
|
|
2264
|
+
const state = this.clusterStates.get(clusterId);
|
|
2265
|
+
return state ? state.centroid.clone() : null;
|
|
2266
|
+
}
|
|
2267
|
+
};
|
|
1955
2268
|
|
|
1956
2269
|
// src/visualization/layouts/fuzzy-layout.ts
|
|
1957
2270
|
var GOLDEN_ANGLE = Math.PI * (3 - Math.sqrt(5));
|
|
@@ -2674,6 +2987,7 @@ function NeuronWeb({
|
|
|
2674
2987
|
const transitionsEnabled = resolvedPerformanceMode === "normal" && !prefersReducedMotion && profileAllowsContinuous && resolvedAnimationConfig.transitionDurationMs > 0;
|
|
2675
2988
|
return new NodeRenderer(sceneManager.scene, {
|
|
2676
2989
|
domainColors: resolvedTheme.colors.domainColors,
|
|
2990
|
+
statusColors: resolvedTheme.colors.statusColors,
|
|
2677
2991
|
defaultColor: resolvedTheme.colors.defaultDomainColor,
|
|
2678
2992
|
baseScale: 1.15,
|
|
2679
2993
|
tierScales: {
|
|
@@ -2778,6 +3092,27 @@ function NeuronWeb({
|
|
|
2778
3092
|
edgeRenderer?.dispose();
|
|
2779
3093
|
};
|
|
2780
3094
|
}, [edgeRenderer]);
|
|
3095
|
+
const clusterRenderer = react.useMemo(() => {
|
|
3096
|
+
if (!sceneManager) return null;
|
|
3097
|
+
if (!graphData.clusters?.length) return null;
|
|
3098
|
+
return new ClusterRenderer(sceneManager.scene, {
|
|
3099
|
+
defaultColor: resolvedTheme.colors.defaultDomainColor,
|
|
3100
|
+
fillOpacity: 0.08,
|
|
3101
|
+
strokeOpacity: 0.25,
|
|
3102
|
+
strokeWidth: 1.5,
|
|
3103
|
+
labelFontFamily: resolvedTheme.typography.labelFontFamily,
|
|
3104
|
+
labelFontSize: resolvedTheme.typography.labelFontSize - 1,
|
|
3105
|
+
labelTextColor: resolvedTheme.colors.labelText,
|
|
3106
|
+
labelBackground: resolvedTheme.colors.labelBackground,
|
|
3107
|
+
zOffset: -0.5,
|
|
3108
|
+
hullPadding: 1.2
|
|
3109
|
+
});
|
|
3110
|
+
}, [sceneManager, graphData.clusters?.length, resolvedTheme]);
|
|
3111
|
+
react.useEffect(() => {
|
|
3112
|
+
return () => {
|
|
3113
|
+
clusterRenderer?.dispose();
|
|
3114
|
+
};
|
|
3115
|
+
}, [clusterRenderer]);
|
|
2781
3116
|
const doubleClickEnabled = false;
|
|
2782
3117
|
const interactionManager = react.useMemo(() => {
|
|
2783
3118
|
if (!sceneManager) return null;
|
|
@@ -3203,7 +3538,18 @@ function NeuronWeb({
|
|
|
3203
3538
|
nodeRenderer.renderNodes(displayNodes);
|
|
3204
3539
|
const positions = nodeRenderer.getNodePositionsBySlug(/* @__PURE__ */ new Map());
|
|
3205
3540
|
edgeRenderer.renderEdges(workingGraph.edges, positions);
|
|
3206
|
-
|
|
3541
|
+
if (clusterRenderer && graphData.clusters?.length) {
|
|
3542
|
+
const nodePositionsById = /* @__PURE__ */ new Map();
|
|
3543
|
+
for (const node of displayNodes) {
|
|
3544
|
+
const pos = nodeRenderer.getNodePosition(node.id);
|
|
3545
|
+
if (pos) {
|
|
3546
|
+
nodePositionsById.set(node.id, pos);
|
|
3547
|
+
nodePositionsById.set(node.slug, pos);
|
|
3548
|
+
}
|
|
3549
|
+
}
|
|
3550
|
+
clusterRenderer.renderClusters(graphData.clusters, nodePositionsById);
|
|
3551
|
+
}
|
|
3552
|
+
}, [displayNodes, workingGraph.edges, graphData.clusters, sceneManager, nodeRenderer, edgeRenderer, clusterRenderer]);
|
|
3207
3553
|
react.useEffect(() => {
|
|
3208
3554
|
if (!sceneManager) return;
|
|
3209
3555
|
sceneManager.updateBackground(resolvedTheme.colors.background);
|
|
@@ -4126,6 +4472,7 @@ function dedupePreserveOrder(values) {
|
|
|
4126
4472
|
}
|
|
4127
4473
|
|
|
4128
4474
|
exports.DEFAULT_RENDERING_OPTIONS = DEFAULT_RENDERING_OPTIONS;
|
|
4475
|
+
exports.DEFAULT_STATUS_COLORS = DEFAULT_STATUS_COLORS;
|
|
4129
4476
|
exports.DEFAULT_THEME = DEFAULT_THEME;
|
|
4130
4477
|
exports.NeuronContext = NeuronContext;
|
|
4131
4478
|
exports.NeuronWeb = NeuronWeb;
|
|
@@ -4141,5 +4488,5 @@ exports.normalizeStoryBeat = normalizeStoryBeat;
|
|
|
4141
4488
|
exports.useNeuronContext = useNeuronContext;
|
|
4142
4489
|
exports.useNeuronGraph = useNeuronGraph;
|
|
4143
4490
|
exports.validateStoryBeat = validateStoryBeat;
|
|
4144
|
-
//# sourceMappingURL=chunk-
|
|
4145
|
-
//# sourceMappingURL=chunk-
|
|
4491
|
+
//# sourceMappingURL=chunk-HOW2F2KP.cjs.map
|
|
4492
|
+
//# sourceMappingURL=chunk-HOW2F2KP.cjs.map
|