@mindexec/cli 0.2.446 → 0.2.447
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 +2 -2
- package/package.json +2 -2
- package/remote-fast/osx-arm64/mindexec-remote-fast.dll +0 -0
- package/remote-fast/osx-x64/mindexec-remote-fast.dll +0 -0
- package/remote-fast/win-x64/mindexec-remote-fast.dll +0 -0
- package/remote-hub.js +1 -1
- package/scripts/remote-fleet-render-smoke.mjs +74 -36
- package/scripts/remote-hub-smoke.mjs +7 -0
- package/wwwroot/_content/MindExecution.Shared/js/background-themes.js +1 -3
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-core.js +199 -100
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-css3d-hotpath.js +902 -0
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-css3d-manager.js +56 -385
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-interactions.js +90 -134
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-lod-renderer.js +167 -24
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-nodes.js +92 -50
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-pipeline.js +35 -12
- package/wwwroot/_content/MindExecution.Shared/js/renderers/CSS3DRenderer.js +35 -2
- package/wwwroot/_framework/{MindExecution.Core.djyzj5mxyk.dll → MindExecution.Core.mswl4wlkm9.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Kernel.6e5cj9aijz.dll → MindExecution.Kernel.zupeldfptg.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Admin.siulh9tfrf.dll → MindExecution.Plugins.Admin.hq0vyqnqtn.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Business.8cjtrc7qd3.dll → MindExecution.Plugins.Business.pucw3o7rno.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Concept.rpp78mc75u.dll → MindExecution.Plugins.Concept.557tzzkrrx.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Directory.wfv0ff9v4u.dll → MindExecution.Plugins.Directory.zh1ddg1fn6.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.PlanMaster.jdppnbd6g4.dll → MindExecution.Plugins.PlanMaster.0z9pzynpu9.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.YouTube.a43f2q3pkw.dll → MindExecution.Plugins.YouTube.y8g77r54fa.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Shared.gwtyj0e9lw.dll → MindExecution.Shared.1ymsdbwid2.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Web.j3zaapcxtt.dll → MindExecution.Web.bb1txupuv0.dll} +0 -0
- package/wwwroot/_framework/blazor.boot.json +21 -21
- package/wwwroot/index.html +2 -1
- package/wwwroot/service-worker-assets.js +35 -31
- package/wwwroot/service-worker.js +1 -1
|
@@ -1649,65 +1649,18 @@ window.MindMapInteractions = (function () {
|
|
|
1649
1649
|
return null;
|
|
1650
1650
|
}
|
|
1651
1651
|
|
|
1652
|
-
function getNodeProjectedClientFrame(module, entry) {
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
}
|
|
1661
|
-
|
|
1662
|
-
const sourceObject = entry.glObject || entry.cssObject;
|
|
1663
|
-
const position = sourceObject?.position;
|
|
1664
|
-
if (!position) {
|
|
1665
|
-
return null;
|
|
1666
|
-
}
|
|
1667
|
-
|
|
1668
|
-
const width = Number(
|
|
1669
|
-
entry.glObject?.userData?.worldWidth ||
|
|
1670
|
-
entry.cssObject?.userData?.worldWidth ||
|
|
1671
|
-
entry.model?.width ||
|
|
1672
|
-
entry.model?.Width ||
|
|
1673
|
-
0
|
|
1674
|
-
);
|
|
1675
|
-
const height = Number(
|
|
1676
|
-
entry.glObject?.userData?.worldHeight ||
|
|
1677
|
-
entry.cssObject?.userData?.worldHeight ||
|
|
1678
|
-
entry.model?.height ||
|
|
1679
|
-
entry.model?.Height ||
|
|
1680
|
-
0
|
|
1681
|
-
);
|
|
1682
|
-
if (!(width > 0 && height > 0)) {
|
|
1683
|
-
return null;
|
|
1684
|
-
}
|
|
1685
|
-
|
|
1686
|
-
const corners = [
|
|
1687
|
-
new THREE.Vector3(position.x, position.y, position.z || 0),
|
|
1688
|
-
new THREE.Vector3(position.x + width, position.y, position.z || 0),
|
|
1689
|
-
new THREE.Vector3(position.x, position.y - height, position.z || 0),
|
|
1690
|
-
new THREE.Vector3(position.x + width, position.y - height, position.z || 0)
|
|
1691
|
-
];
|
|
1692
|
-
|
|
1693
|
-
const xs = [];
|
|
1694
|
-
const ys = [];
|
|
1695
|
-
for (const corner of corners) {
|
|
1696
|
-
corner.project(module.camera);
|
|
1697
|
-
xs.push(rect.left + ((corner.x + 1) * rect.width / 2));
|
|
1698
|
-
ys.push(rect.top + ((-corner.y + 1) * rect.height / 2));
|
|
1699
|
-
}
|
|
1700
|
-
|
|
1701
|
-
return {
|
|
1702
|
-
left: Math.min(...xs),
|
|
1703
|
-
right: Math.max(...xs),
|
|
1704
|
-
top: Math.min(...ys),
|
|
1705
|
-
bottom: Math.max(...ys)
|
|
1706
|
-
};
|
|
1652
|
+
function getNodeProjectedClientFrame(module, entry, context = null, nodeId = null) {
|
|
1653
|
+
return window.MindMapCss3dHotPath?.getProjectedClientFrame?.(
|
|
1654
|
+
module,
|
|
1655
|
+
entry,
|
|
1656
|
+
context,
|
|
1657
|
+
getCachedViewportMetrics(module),
|
|
1658
|
+
nodeId
|
|
1659
|
+
) || null;
|
|
1707
1660
|
}
|
|
1708
1661
|
|
|
1709
|
-
function isClientPointInsideNodeFrame(module, entry, clientX, clientY, padding = 2) {
|
|
1710
|
-
const frame = getNodeProjectedClientFrame(module, entry);
|
|
1662
|
+
function isClientPointInsideNodeFrame(module, entry, clientX, clientY, padding = 2, context = null, nodeId = null) {
|
|
1663
|
+
const frame = getNodeProjectedClientFrame(module, entry, context, nodeId);
|
|
1711
1664
|
if (!frame) {
|
|
1712
1665
|
return true;
|
|
1713
1666
|
}
|
|
@@ -1718,13 +1671,13 @@ window.MindMapInteractions = (function () {
|
|
|
1718
1671
|
clientY <= frame.bottom + padding;
|
|
1719
1672
|
}
|
|
1720
1673
|
|
|
1721
|
-
function isOutOfFrameNodeDomHit(module, nodeId, clientX, clientY) {
|
|
1674
|
+
function isOutOfFrameNodeDomHit(module, nodeId, clientX, clientY, context = null) {
|
|
1722
1675
|
const entry = nodeId ? module?.nodeObjectsById?.get?.(nodeId) : null;
|
|
1723
1676
|
if (!entry?.cssObject?.element) {
|
|
1724
1677
|
return false;
|
|
1725
1678
|
}
|
|
1726
1679
|
|
|
1727
|
-
return !isClientPointInsideNodeFrame(module, entry, clientX, clientY, 3);
|
|
1680
|
+
return !isClientPointInsideNodeFrame(module, entry, clientX, clientY, 3, context, nodeId);
|
|
1728
1681
|
}
|
|
1729
1682
|
|
|
1730
1683
|
function resolveNodeIdFromHitObject(object) {
|
|
@@ -1871,13 +1824,15 @@ window.MindMapInteractions = (function () {
|
|
|
1871
1824
|
return bestHit;
|
|
1872
1825
|
}
|
|
1873
1826
|
|
|
1874
|
-
function findCssNodeHitAtClientPoint(module, clientX, clientY) {
|
|
1827
|
+
function findCssNodeHitAtClientPoint(module, clientX, clientY, context = null) {
|
|
1875
1828
|
if (!module?.nodeObjectsById) {
|
|
1876
1829
|
return null;
|
|
1877
1830
|
}
|
|
1878
1831
|
|
|
1879
1832
|
if (typeof document !== 'undefined' && typeof document.elementsFromPoint === 'function') {
|
|
1880
|
-
const domStack =
|
|
1833
|
+
const domStack = context
|
|
1834
|
+
? window.MindMapCss3dHotPath.getDomStack(module, context)
|
|
1835
|
+
: document.elementsFromPoint(clientX, clientY);
|
|
1881
1836
|
let bestHit = null;
|
|
1882
1837
|
let bestPriority = -Infinity;
|
|
1883
1838
|
|
|
@@ -1903,7 +1858,7 @@ window.MindMapInteractions = (function () {
|
|
|
1903
1858
|
continue;
|
|
1904
1859
|
}
|
|
1905
1860
|
|
|
1906
|
-
if (!isClientPointInsideNodeFrame(module, entry, clientX, clientY, 2)) {
|
|
1861
|
+
if (!isClientPointInsideNodeFrame(module, entry, clientX, clientY, 2, context, nodeId)) {
|
|
1907
1862
|
continue;
|
|
1908
1863
|
}
|
|
1909
1864
|
|
|
@@ -1927,8 +1882,13 @@ window.MindMapInteractions = (function () {
|
|
|
1927
1882
|
|
|
1928
1883
|
let bestHit = null;
|
|
1929
1884
|
let bestPriority = -Infinity;
|
|
1930
|
-
const worldPoint =
|
|
1931
|
-
|
|
1885
|
+
const worldPoint = window.MindMapCss3dHotPath
|
|
1886
|
+
? window.MindMapCss3dHotPath.getContextWorldPoint(
|
|
1887
|
+
context,
|
|
1888
|
+
() => getWorldPoint(module, clientX, clientY)
|
|
1889
|
+
)
|
|
1890
|
+
: getWorldPoint(module, clientX, clientY);
|
|
1891
|
+
const candidateIds = getCssFallbackCandidateIds(module, worldPoint, context);
|
|
1932
1892
|
for (let i = 0; i < candidateIds.length; i++) {
|
|
1933
1893
|
const nodeId = candidateIds[i];
|
|
1934
1894
|
const entry = module.nodeObjectsById.get(nodeId);
|
|
@@ -1945,7 +1905,7 @@ window.MindMapInteractions = (function () {
|
|
|
1945
1905
|
continue;
|
|
1946
1906
|
}
|
|
1947
1907
|
|
|
1948
|
-
if (!isClientPointInsideNodeFrame(module, entry, clientX, clientY, 2)) {
|
|
1908
|
+
if (!isClientPointInsideNodeFrame(module, entry, clientX, clientY, 2, context, nodeId)) {
|
|
1949
1909
|
continue;
|
|
1950
1910
|
}
|
|
1951
1911
|
|
|
@@ -2142,11 +2102,20 @@ window.MindMapInteractions = (function () {
|
|
|
2142
2102
|
cellRadius: normalizedCellRadius
|
|
2143
2103
|
});
|
|
2144
2104
|
if (Array.isArray(cachedCandidateIds)) {
|
|
2105
|
+
module._lastHitTestCandidateSource = 'worker';
|
|
2106
|
+
window.MindMapCss3dHotPath?.recordHitCandidates?.(module, 'worker', cachedCandidateIds.length);
|
|
2145
2107
|
return cachedCandidateIds;
|
|
2146
2108
|
}
|
|
2147
2109
|
|
|
2148
|
-
if (!module.spatialGrid)
|
|
2149
|
-
|
|
2110
|
+
if (!module.spatialGrid || module._spatialIndexRepairState) {
|
|
2111
|
+
module._lastHitTestCandidateSource = 'unavailable';
|
|
2112
|
+
window.MindMapCss3dHotPath?.noteUnavailableIndex?.(module, 'pointer-index-unavailable');
|
|
2113
|
+
return null;
|
|
2114
|
+
}
|
|
2115
|
+
const localIds = collectLocalHitTestCandidateNodeIds(module, point, normalizedCellRadius);
|
|
2116
|
+
module._lastHitTestCandidateSource = 'spatial-grid';
|
|
2117
|
+
window.MindMapCss3dHotPath?.recordHitCandidates?.(module, 'spatial-grid', localIds.length);
|
|
2118
|
+
return localIds;
|
|
2150
2119
|
}
|
|
2151
2120
|
|
|
2152
2121
|
function appendMeshesForHitTestCandidateIds(module, candidateIds, meshes, options = {}) {
|
|
@@ -2207,49 +2176,19 @@ window.MindMapInteractions = (function () {
|
|
|
2207
2176
|
};
|
|
2208
2177
|
}
|
|
2209
2178
|
|
|
2210
|
-
function collectLocalSelectionCandidateNodeIds(module, selectionRect) {
|
|
2211
|
-
if (!module?.spatialGrid || !selectionRect) {
|
|
2212
|
-
return [];
|
|
2213
|
-
}
|
|
2214
|
-
|
|
2215
|
-
const cellSize = Math.max(1, Number(module.GRID_CELL_SIZE || 500));
|
|
2216
|
-
const startCellX = Math.floor(Number(selectionRect.left || 0) / cellSize);
|
|
2217
|
-
const endCellX = Math.floor(Number(selectionRect.right || 0) / cellSize);
|
|
2218
|
-
const startCellY = Math.floor(Number(selectionRect.bottom || 0) / cellSize);
|
|
2219
|
-
const endCellY = Math.floor(Number(selectionRect.top || 0) / cellSize);
|
|
2220
|
-
const candidateIds = [];
|
|
2221
|
-
const seenIds = new Set();
|
|
2222
|
-
|
|
2223
|
-
for (let cellX = startCellX; cellX <= endCellX; cellX++) {
|
|
2224
|
-
for (let cellY = startCellY; cellY <= endCellY; cellY++) {
|
|
2225
|
-
const nodeIds = module.spatialGrid.get(`${cellX}:${cellY}`);
|
|
2226
|
-
if (!nodeIds) {
|
|
2227
|
-
continue;
|
|
2228
|
-
}
|
|
2229
|
-
|
|
2230
|
-
nodeIds.forEach((nodeId) => {
|
|
2231
|
-
const normalizedNodeId = String(nodeId || '').trim();
|
|
2232
|
-
if (!normalizedNodeId || seenIds.has(normalizedNodeId)) {
|
|
2233
|
-
return;
|
|
2234
|
-
}
|
|
2235
|
-
|
|
2236
|
-
seenIds.add(normalizedNodeId);
|
|
2237
|
-
candidateIds.push(normalizedNodeId);
|
|
2238
|
-
});
|
|
2239
|
-
}
|
|
2240
|
-
}
|
|
2241
|
-
|
|
2242
|
-
return candidateIds;
|
|
2243
|
-
}
|
|
2244
|
-
|
|
2245
2179
|
function collectSelectionBoxNodeIdsLocal(module, selectionRect) {
|
|
2246
2180
|
const selectedIds = new Set();
|
|
2247
2181
|
if (!module?.nodeObjectsById || !selectionRect) {
|
|
2248
2182
|
return selectedIds;
|
|
2249
2183
|
}
|
|
2250
2184
|
|
|
2251
|
-
|
|
2185
|
+
let candidateIds = window.MindMapCss3dHotPath?.collectSpatialRectCandidateIds?.(module, selectionRect) ?? null;
|
|
2186
|
+
if (candidateIds === null) {
|
|
2187
|
+
window.MindMapCss3dHotPath?.noteUnavailableIndex?.(module, 'selection-box-index-unavailable');
|
|
2188
|
+
candidateIds = window.MindMapCss3dHotPath?.getBoundedFallbackIds?.(module) || [];
|
|
2189
|
+
}
|
|
2252
2190
|
const processCandidateNode = (nodeId) => {
|
|
2191
|
+
window.MindMapCss3dHotPath?.increment?.(module, 'selection', 'nodesVisited');
|
|
2253
2192
|
const nodeEntry = module.nodeObjectsById.get(nodeId);
|
|
2254
2193
|
if (!nodeEntry?.glObject?.userData) {
|
|
2255
2194
|
return;
|
|
@@ -2271,12 +2210,8 @@ window.MindMapInteractions = (function () {
|
|
|
2271
2210
|
}
|
|
2272
2211
|
};
|
|
2273
2212
|
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
processCandidateNode(candidateIds[i]);
|
|
2277
|
-
}
|
|
2278
|
-
} else {
|
|
2279
|
-
module.nodeObjectsById.forEach((_, nodeId) => processCandidateNode(nodeId));
|
|
2213
|
+
for (let i = 0; i < candidateIds.length; i++) {
|
|
2214
|
+
processCandidateNode(candidateIds[i]);
|
|
2280
2215
|
}
|
|
2281
2216
|
|
|
2282
2217
|
return selectedIds;
|
|
@@ -2331,27 +2266,28 @@ window.MindMapInteractions = (function () {
|
|
|
2331
2266
|
});
|
|
2332
2267
|
}
|
|
2333
2268
|
|
|
2334
|
-
function getCssFallbackCandidateIds(module, worldPoint) {
|
|
2269
|
+
function getCssFallbackCandidateIds(module, worldPoint, context = null) {
|
|
2335
2270
|
if (!module?.nodeObjectsById) {
|
|
2336
2271
|
return [];
|
|
2337
2272
|
}
|
|
2338
2273
|
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
: [];
|
|
2274
|
+
if (context?.candidateIds !== undefined) return context.candidateIds;
|
|
2275
|
+
const candidateIds = worldPoint ? getHitTestCandidateNodeIds(module, worldPoint, { visibleOnly: false }) : [];
|
|
2342
2276
|
if (Array.isArray(candidateIds)) {
|
|
2277
|
+
if (context) {
|
|
2278
|
+
context.candidateIds = candidateIds;
|
|
2279
|
+
context.candidateSource = module._lastHitTestCandidateSource || 'spatial-grid';
|
|
2280
|
+
}
|
|
2343
2281
|
return candidateIds;
|
|
2344
2282
|
}
|
|
2345
2283
|
|
|
2346
|
-
const fallbackIds =
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
module.container?.querySelectorAll?.('[data-node-id]')?.forEach?.(element => addId(element.dataset?.nodeId));
|
|
2354
|
-
return Array.from(fallbackIds);
|
|
2284
|
+
const fallbackIds = window.MindMapCss3dHotPath?.getBoundedFallbackIds?.(module) || [];
|
|
2285
|
+
window.MindMapCss3dHotPath?.recordHitCandidates?.(module, 'bounded-fallback', fallbackIds.length);
|
|
2286
|
+
if (context) {
|
|
2287
|
+
context.candidateIds = fallbackIds;
|
|
2288
|
+
context.candidateSource = 'bounded-fallback';
|
|
2289
|
+
}
|
|
2290
|
+
return fallbackIds;
|
|
2355
2291
|
}
|
|
2356
2292
|
// ▲▲▲ [New] ▲▲▲
|
|
2357
2293
|
|
|
@@ -2964,7 +2900,8 @@ window.MindMapInteractions = (function () {
|
|
|
2964
2900
|
}
|
|
2965
2901
|
|
|
2966
2902
|
const nodeId = getTargetNodeId(target);
|
|
2967
|
-
if (nodeId && event && isOutOfFrameNodeDomHit(
|
|
2903
|
+
if (nodeId && event && isOutOfFrameNodeDomHit(
|
|
2904
|
+
module, nodeId, event.clientX, event.clientY, getPointerHitContext(module, event))) {
|
|
2968
2905
|
return false;
|
|
2969
2906
|
}
|
|
2970
2907
|
|
|
@@ -2977,23 +2914,40 @@ window.MindMapInteractions = (function () {
|
|
|
2977
2914
|
const topCssHit = event ? getPointerCssHit(module, event) : null;
|
|
2978
2915
|
return topCssHit?.nodeId || nodeId;
|
|
2979
2916
|
}
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2917
|
+
const context = getPointerHitContext(module, event);
|
|
2918
|
+
if (nodeId && !isOutOfFrameNodeDomHit(module, nodeId, event.clientX, event.clientY, context)) {
|
|
2919
|
+
const entry = module.nodeObjectsById?.get?.(nodeId) || null;
|
|
2920
|
+
if (entry) {
|
|
2921
|
+
context.cssHit = {
|
|
2922
|
+
nodeId,
|
|
2923
|
+
entry,
|
|
2924
|
+
priority: getEntryInteractionPriority(module, entry, nodeId)
|
|
2925
|
+
};
|
|
2926
|
+
}
|
|
2927
|
+
return nodeId;
|
|
2984
2928
|
}
|
|
2985
|
-
|
|
2986
|
-
return
|
|
2987
|
-
? null
|
|
2988
|
-
: nodeId;
|
|
2929
|
+
const topCssHit = getPointerCssHit(module, event);
|
|
2930
|
+
return topCssHit?.nodeId || null;
|
|
2989
2931
|
}
|
|
2990
|
-
function
|
|
2932
|
+
function getPointerHitContext(module, event) {
|
|
2991
2933
|
if (!event || !module) return null;
|
|
2992
2934
|
let context = pointerHitContexts.get(event);
|
|
2993
2935
|
if (!context || context.module !== module) {
|
|
2994
|
-
context =
|
|
2936
|
+
context = window.MindMapCss3dHotPath.createPointerHitContext(
|
|
2937
|
+
module,
|
|
2938
|
+
event,
|
|
2939
|
+
getCachedViewportMetrics(module)
|
|
2940
|
+
);
|
|
2995
2941
|
pointerHitContexts.set(event, context);
|
|
2996
2942
|
}
|
|
2943
|
+
return context;
|
|
2944
|
+
}
|
|
2945
|
+
function getPointerCssHit(module, event) {
|
|
2946
|
+
const context = getPointerHitContext(module, event);
|
|
2947
|
+
if (!context) return null;
|
|
2948
|
+
if (context.cssHit === undefined) {
|
|
2949
|
+
context.cssHit = findCssNodeHitAtClientPoint(module, event.clientX, event.clientY, context);
|
|
2950
|
+
}
|
|
2997
2951
|
return context.cssHit;
|
|
2998
2952
|
}
|
|
2999
2953
|
function getMountedEmbedCanvasDragTarget(module, target, event) {
|
|
@@ -3025,7 +2979,8 @@ window.MindMapInteractions = (function () {
|
|
|
3025
2979
|
return null;
|
|
3026
2980
|
}
|
|
3027
2981
|
|
|
3028
|
-
if (event && !isClientPointInsideNodeFrame(
|
|
2982
|
+
if (event && !isClientPointInsideNodeFrame(
|
|
2983
|
+
module, nodeEntry, event.clientX, event.clientY, 3, getPointerHitContext(module, event), nodeId)) {
|
|
3029
2984
|
return null;
|
|
3030
2985
|
}
|
|
3031
2986
|
|
|
@@ -3387,6 +3342,7 @@ window.MindMapInteractions = (function () {
|
|
|
3387
3342
|
if (previousIds.size === selectedIds.size && [...selectedIds].every(id => previousIds.has(id))) return;
|
|
3388
3343
|
|
|
3389
3344
|
const changedIds = new Set([...previousIds, ...selectedIds]);
|
|
3345
|
+
window.MindMapCss3dHotPath?.increment?.(module, 'selection', 'nodesVisited', changedIds.size);
|
|
3390
3346
|
changedIds.forEach(nodeId => {
|
|
3391
3347
|
const entry = module.nodeObjectsById.get(nodeId);
|
|
3392
3348
|
if (String(entry?.model?.contentType ?? entry?.model?.ContentType ?? '').toLowerCase() !== 'embed' || !entry?.cssObject?.element) return;
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
// ▲▲▲ [Usage] ▲▲▲
|
|
52
52
|
|
|
53
53
|
// Procedural line rendering settings
|
|
54
|
-
const LOD_RENDERER_BUILD_ID = '
|
|
54
|
+
const LOD_RENDERER_BUILD_ID = '20260725-cold-mid-line-restore-v846';
|
|
55
55
|
const DirtyKind = Object.freeze({
|
|
56
56
|
ResidentFullRebuild: 'resident-full-rebuild',
|
|
57
57
|
ResidentPatch: 'resident-patch',
|
|
@@ -585,7 +585,14 @@
|
|
|
585
585
|
return !isAnimatedGifImageModel(model);
|
|
586
586
|
}
|
|
587
587
|
|
|
588
|
-
|
|
588
|
+
// Every video needs a resident MID/FAR visual. Videos without an
|
|
589
|
+
// explicit preview use a lightweight atlas placeholder so the live
|
|
590
|
+
// <video> element can stay suspended without making the node vanish.
|
|
591
|
+
if (contentType === 'video') {
|
|
592
|
+
return true;
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
if (contentType !== 'embed') {
|
|
589
596
|
return false;
|
|
590
597
|
}
|
|
591
598
|
|
|
@@ -1255,6 +1262,33 @@
|
|
|
1255
1262
|
return [invAtlas, invAtlas, invAtlas, invAtlas];
|
|
1256
1263
|
}
|
|
1257
1264
|
|
|
1265
|
+
_getOrCreateImageAtlasSlot(nodeId) {
|
|
1266
|
+
const normalizedId = String(nodeId || '').trim();
|
|
1267
|
+
if (!normalizedId) {
|
|
1268
|
+
return null;
|
|
1269
|
+
}
|
|
1270
|
+
|
|
1271
|
+
let slot = this.imageAtlasSlots.get(normalizedId) || null;
|
|
1272
|
+
if (slot) {
|
|
1273
|
+
return slot;
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
const slotIndex = this._allocateImageAtlasSlot();
|
|
1277
|
+
if (slotIndex < 0) {
|
|
1278
|
+
return null;
|
|
1279
|
+
}
|
|
1280
|
+
|
|
1281
|
+
slot = {
|
|
1282
|
+
slotIndex,
|
|
1283
|
+
key: '',
|
|
1284
|
+
uvRect: this._getImageAtlasUvRect(slotIndex),
|
|
1285
|
+
ready: false,
|
|
1286
|
+
unsupported: false
|
|
1287
|
+
};
|
|
1288
|
+
this.imageAtlasSlots.set(normalizedId, slot);
|
|
1289
|
+
return slot;
|
|
1290
|
+
}
|
|
1291
|
+
|
|
1258
1292
|
_compactImageAtlasLoadQueue(force = false) {
|
|
1259
1293
|
const cursor = this._imageAtlasLoadCursor || 0;
|
|
1260
1294
|
if (cursor <= 0) return;
|
|
@@ -1653,35 +1687,114 @@
|
|
|
1653
1687
|
}
|
|
1654
1688
|
}
|
|
1655
1689
|
|
|
1690
|
+
_drawVideoLodPlaceholder(slot, nodeWidth, nodeHeight) {
|
|
1691
|
+
if (!slot || !this.imageAtlasCanvas || typeof document === 'undefined') {
|
|
1692
|
+
return false;
|
|
1693
|
+
}
|
|
1694
|
+
|
|
1695
|
+
const ctx = this.imageAtlasCanvas.getContext('2d', { alpha: false });
|
|
1696
|
+
if (!ctx) {
|
|
1697
|
+
return false;
|
|
1698
|
+
}
|
|
1699
|
+
|
|
1700
|
+
const columns = this.imageAtlasColumns || IMAGE_LOD_ATLAS_COLUMNS;
|
|
1701
|
+
const col = slot.slotIndex % columns;
|
|
1702
|
+
const row = Math.floor(slot.slotIndex / columns);
|
|
1703
|
+
const x = col * IMAGE_LOD_THUMBNAIL_SIZE;
|
|
1704
|
+
const y = row * IMAGE_LOD_THUMBNAIL_SIZE;
|
|
1705
|
+
const size = IMAGE_LOD_THUMBNAIL_SIZE;
|
|
1706
|
+
const safeWidth = Math.max(1, Number(nodeWidth || 300));
|
|
1707
|
+
const safeHeight = Math.max(1, Number(nodeHeight || 300));
|
|
1708
|
+
const targetAspect = safeWidth / safeHeight;
|
|
1709
|
+
|
|
1710
|
+
try {
|
|
1711
|
+
ctx.save();
|
|
1712
|
+
|
|
1713
|
+
const background = ctx.createLinearGradient(x, y, x, y + size);
|
|
1714
|
+
background.addColorStop(0, '#26364d');
|
|
1715
|
+
background.addColorStop(1, '#0f172a');
|
|
1716
|
+
ctx.fillStyle = background;
|
|
1717
|
+
ctx.fillRect(x, y, size, size);
|
|
1718
|
+
|
|
1719
|
+
const inset = 4;
|
|
1720
|
+
ctx.strokeStyle = 'rgba(148, 163, 184, 0.58)';
|
|
1721
|
+
ctx.lineWidth = 2;
|
|
1722
|
+
ctx.strokeRect(x + inset, y + inset, size - inset * 2, size - inset * 2);
|
|
1723
|
+
|
|
1724
|
+
// Pre-compensate the icon for the square atlas tile being
|
|
1725
|
+
// stretched to the video's world-space aspect ratio.
|
|
1726
|
+
const radiusX = size * 0.19;
|
|
1727
|
+
const radiusY = Math.min(size * 0.34, radiusX * Math.max(0.55, targetAspect));
|
|
1728
|
+
const centerX = x + size * 0.5;
|
|
1729
|
+
const centerY = y + size * 0.48;
|
|
1730
|
+
ctx.beginPath();
|
|
1731
|
+
ctx.ellipse(centerX, centerY, radiusX, radiusY, 0, 0, Math.PI * 2);
|
|
1732
|
+
ctx.fillStyle = 'rgba(255, 255, 255, 0.18)';
|
|
1733
|
+
ctx.fill();
|
|
1734
|
+
ctx.strokeStyle = 'rgba(255, 255, 255, 0.62)';
|
|
1735
|
+
ctx.lineWidth = 2;
|
|
1736
|
+
ctx.stroke();
|
|
1737
|
+
|
|
1738
|
+
const triangleWidth = size * 0.13;
|
|
1739
|
+
const triangleHeight = Math.min(size * 0.24, triangleWidth * Math.max(0.85, targetAspect));
|
|
1740
|
+
ctx.beginPath();
|
|
1741
|
+
ctx.moveTo(centerX - triangleWidth * 0.35, centerY - triangleHeight * 0.5);
|
|
1742
|
+
ctx.lineTo(centerX + triangleWidth * 0.7, centerY);
|
|
1743
|
+
ctx.lineTo(centerX - triangleWidth * 0.35, centerY + triangleHeight * 0.5);
|
|
1744
|
+
ctx.closePath();
|
|
1745
|
+
ctx.fillStyle = '#f8fafc';
|
|
1746
|
+
ctx.fill();
|
|
1747
|
+
|
|
1748
|
+
ctx.fillStyle = 'rgba(226, 232, 240, 0.35)';
|
|
1749
|
+
ctx.fillRect(x + size * 0.18, y + size * 0.82, size * 0.64, 2);
|
|
1750
|
+
ctx.fillStyle = 'rgba(248, 250, 252, 0.78)';
|
|
1751
|
+
ctx.fillRect(x + size * 0.18, y + size * 0.82, size * 0.2, 2);
|
|
1752
|
+
ctx.restore();
|
|
1753
|
+
|
|
1754
|
+
if (this.imageAtlasTexture) {
|
|
1755
|
+
this.imageAtlasTexture.needsUpdate = true;
|
|
1756
|
+
}
|
|
1757
|
+
return true;
|
|
1758
|
+
} catch {
|
|
1759
|
+
try { ctx.restore(); } catch { }
|
|
1760
|
+
return false;
|
|
1761
|
+
}
|
|
1762
|
+
}
|
|
1763
|
+
|
|
1656
1764
|
_ensureImageLodThumbnail(entry) {
|
|
1657
1765
|
const nodeId = entry?.model?.id;
|
|
1658
1766
|
if (!nodeId) {
|
|
1659
1767
|
return null;
|
|
1660
1768
|
}
|
|
1661
1769
|
|
|
1770
|
+
const contentType = getNodeContentType(entry?.model);
|
|
1771
|
+
const nodeWidth = Math.max(1, Number(entry?.model?.width || entry?.model?.Width || 300));
|
|
1772
|
+
const nodeHeight = Math.max(1, Number(entry?.model?.height || entry?.model?.Height || 300));
|
|
1662
1773
|
const source = this._getImageLodSource(entry);
|
|
1663
1774
|
if (!source) {
|
|
1775
|
+
if (contentType === 'video') {
|
|
1776
|
+
const placeholderKey = `video-placeholder|node:${Math.round(nodeWidth)}x${Math.round(nodeHeight)}`;
|
|
1777
|
+
const placeholderSlot = this._getOrCreateImageAtlasSlot(nodeId);
|
|
1778
|
+
if (!placeholderSlot) {
|
|
1779
|
+
return null;
|
|
1780
|
+
}
|
|
1781
|
+
if (placeholderSlot.ready && placeholderSlot.key === placeholderKey) {
|
|
1782
|
+
return placeholderSlot;
|
|
1783
|
+
}
|
|
1784
|
+
if (this._drawVideoLodPlaceholder(placeholderSlot, nodeWidth, nodeHeight)) {
|
|
1785
|
+
placeholderSlot.key = placeholderKey;
|
|
1786
|
+
placeholderSlot.ready = true;
|
|
1787
|
+
placeholderSlot.unsupported = false;
|
|
1788
|
+
return placeholderSlot;
|
|
1789
|
+
}
|
|
1790
|
+
}
|
|
1664
1791
|
return null;
|
|
1665
1792
|
}
|
|
1666
1793
|
|
|
1667
|
-
const nodeWidth = Math.max(1, Number(entry?.model?.width || entry?.model?.Width || 300));
|
|
1668
|
-
const nodeHeight = Math.max(1, Number(entry?.model?.height || entry?.model?.Height || 300));
|
|
1669
1794
|
const sourceKey = `${source.key}|node:${Math.round(nodeWidth)}x${Math.round(nodeHeight)}`;
|
|
1670
|
-
|
|
1671
|
-
let slot = this.imageAtlasSlots.get(nodeId) || null;
|
|
1795
|
+
const slot = this._getOrCreateImageAtlasSlot(nodeId);
|
|
1672
1796
|
if (!slot) {
|
|
1673
|
-
|
|
1674
|
-
if (slotIndex < 0) {
|
|
1675
|
-
return null;
|
|
1676
|
-
}
|
|
1677
|
-
slot = {
|
|
1678
|
-
slotIndex,
|
|
1679
|
-
key: '',
|
|
1680
|
-
uvRect: this._getImageAtlasUvRect(slotIndex),
|
|
1681
|
-
ready: false,
|
|
1682
|
-
unsupported: false
|
|
1683
|
-
};
|
|
1684
|
-
this.imageAtlasSlots.set(nodeId, slot);
|
|
1797
|
+
return null;
|
|
1685
1798
|
}
|
|
1686
1799
|
|
|
1687
1800
|
if (slot.ready && slot.key === sourceKey) {
|
|
@@ -1699,6 +1812,14 @@
|
|
|
1699
1812
|
return slot;
|
|
1700
1813
|
}
|
|
1701
1814
|
|
|
1815
|
+
if (contentType === 'video' &&
|
|
1816
|
+
this._drawVideoLodPlaceholder(slot, nodeWidth, nodeHeight)) {
|
|
1817
|
+
slot.key = `video-placeholder|source:${sourceKey}`;
|
|
1818
|
+
slot.ready = true;
|
|
1819
|
+
slot.unsupported = false;
|
|
1820
|
+
return slot;
|
|
1821
|
+
}
|
|
1822
|
+
|
|
1702
1823
|
if (source.fetchFallbackOnDrawFailure === true) {
|
|
1703
1824
|
slot.key = '';
|
|
1704
1825
|
slot.ready = false;
|
|
@@ -3340,6 +3461,8 @@
|
|
|
3340
3461
|
_hasPendingLineDetailRestore(lodBand = this._currentLodBand) {
|
|
3341
3462
|
return ENABLE_INSTANCED_TEXT_LINES === true &&
|
|
3342
3463
|
this._lineDetailsPatchPending === true &&
|
|
3464
|
+
this._deferLineRestorePending !== true &&
|
|
3465
|
+
this._disableLineRender !== true &&
|
|
3343
3466
|
this.isInLODMode === true &&
|
|
3344
3467
|
lodBand === 'MID' &&
|
|
3345
3468
|
this.isLoading !== true;
|
|
@@ -6642,15 +6765,29 @@
|
|
|
6642
6765
|
|
|
6643
6766
|
if (disableLines) {
|
|
6644
6767
|
const cachedLineData = this.lineDataCache.get(nodeId) || null;
|
|
6645
|
-
|
|
6646
|
-
|
|
6647
|
-
|
|
6768
|
+
const deferredLineData = cachedLineData || (
|
|
6769
|
+
this._deferLineRestorePending === true
|
|
6770
|
+
? window.MindMapRenderPlan?.resolveResidentLineData?.(
|
|
6771
|
+
this,
|
|
6772
|
+
entry,
|
|
6773
|
+
w,
|
|
6774
|
+
h,
|
|
6775
|
+
false,
|
|
6776
|
+
MAX_LINE_SAMPLES,
|
|
6777
|
+
LINE_HEIGHT_PX,
|
|
6778
|
+
LINE_PADDING_PX
|
|
6779
|
+
) || null
|
|
6780
|
+
: null
|
|
6781
|
+
);
|
|
6782
|
+
if (deferredLineData) {
|
|
6783
|
+
lineCounts.push(deferredLineData.lineCount || 0);
|
|
6784
|
+
lineHeights.push(deferredLineData.lineHeightPx || LINE_HEIGHT_PX);
|
|
6648
6785
|
linePaddings.push(
|
|
6649
|
-
|
|
6650
|
-
|
|
6786
|
+
deferredLineData.paddingX || LINE_PADDING_PX,
|
|
6787
|
+
deferredLineData.paddingY || LINE_PADDING_PX
|
|
6651
6788
|
);
|
|
6652
6789
|
for (let i = 0; i < MAX_LINE_SAMPLES; i++) {
|
|
6653
|
-
lineLengths.push(
|
|
6790
|
+
lineLengths.push(deferredLineData.lineLengths?.[i] || 0);
|
|
6654
6791
|
}
|
|
6655
6792
|
} else {
|
|
6656
6793
|
lineCounts.push(0);
|
|
@@ -7910,6 +8047,12 @@
|
|
|
7910
8047
|
if (!hasResidentInstances) {
|
|
7911
8048
|
this._setInstancesDirty('initial-board-build');
|
|
7912
8049
|
}
|
|
8050
|
+
if (shouldDeferLineRestore) {
|
|
8051
|
+
this._scheduleResidentLodWake(
|
|
8052
|
+
'post-load-line-restore',
|
|
8053
|
+
POST_LOAD_LINE_RESTORE_DELAY_MS + 16
|
|
8054
|
+
);
|
|
8055
|
+
}
|
|
7913
8056
|
// ▼▼▼ [UX] Show nodes immediately after loading ends ▼▼▼
|
|
7914
8057
|
if (this.instancedHaloMesh) this.instancedHaloMesh.visible = this.isInLODMode === true && shouldShowInstancedHaloInLodBand(this._currentLodBand);
|
|
7915
8058
|
if (this.instancedMesh) this.instancedMesh.visible = this.isInLODMode === true;
|