@mindexec/cli 0.2.458 → 0.2.460
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/desktop-workspace-state.cjs +120 -0
- package/electron/main.cjs +17 -6
- package/electron/source-smoke.mjs +21 -0
- package/electron/windows-package-smoke.mjs +8 -2
- package/package.json +6 -5
- 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/scripts/desktop-workspace-state-smoke.mjs +81 -0
- package/server.js +36 -16
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-animated-image-preview.js +270 -0
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-core.js +106 -60
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-interactions.js +30 -26
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-lod-renderer.js +94 -124
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-menu-manager.js +43 -21
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-nodes.js +45 -13
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-render-plan.js +117 -1
- package/wwwroot/_content/MindExecution.Shared/js/mind-map-texture-factory.js +4 -1
- package/wwwroot/_framework/{MindExecution.Core.2ch68iyy8o.dll → MindExecution.Core.oqju650dkd.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Kernel.dh617xfv36.dll → MindExecution.Kernel.7zjugdfmfg.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Admin.0sm50hbae9.dll → MindExecution.Plugins.Admin.qln7lkmsnn.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Business.3wq01orrbu.dll → MindExecution.Plugins.Business.rd6flxuebm.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Concept.z8yl28fa2a.dll → MindExecution.Plugins.Concept.0qrgx3epss.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.Directory.m7murp5oes.dll → MindExecution.Plugins.Directory.4prauy9d1z.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.PlanMaster.yuyrbpf0vh.dll → MindExecution.Plugins.PlanMaster.cobfta1p3l.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Plugins.YouTube.rwxvn00rm2.dll → MindExecution.Plugins.YouTube.99bahbgkkr.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Shared.r9k48iyijb.dll → MindExecution.Shared.sevaa4rgkp.dll} +0 -0
- package/wwwroot/_framework/{MindExecution.Web.742aribkxm.dll → MindExecution.Web.coqh2ccnuk.dll} +0 -0
- package/wwwroot/_framework/blazor.boot.json +21 -21
- package/wwwroot/app-icon-1024.png +0 -0
- package/wwwroot/apple-touch-icon.png +0 -0
- package/wwwroot/appsettings.json +81 -81
- package/wwwroot/favicon-32x32.png +0 -0
- package/wwwroot/favicon.ico +0 -0
- package/wwwroot/icon-192.png +0 -0
- package/wwwroot/icon-512.png +0 -0
- package/wwwroot/index.html +70 -46
- package/wwwroot/manifest.webmanifest +4 -4
- package/wwwroot/mindexec-favicon-v3.png +0 -0
- package/wwwroot/service-worker-assets.js +888 -880
- package/wwwroot/service-worker.js +1 -1
|
@@ -682,13 +682,32 @@ window.MindMapInteractions = (function () {
|
|
|
682
682
|
module._lastNativePasteEventAt = performance.now();
|
|
683
683
|
module._pendingClipboardPasteFallbackToken = null;
|
|
684
684
|
console.log('[MindMap] Ctrl+V fallback read clipboard text. Creating node through PasteTextFromClipboard.');
|
|
685
|
-
await module.dotNetHelper.invokeMethodAsync('PasteTextFromClipboard', text, cursorX, cursorY);
|
|
685
|
+
const createdNode = await module.dotNetHelper.invokeMethodAsync('PasteTextFromClipboard', text, cursorX, cursorY);
|
|
686
|
+
completePastedTextNode(module, createdNode);
|
|
686
687
|
} catch (error) {
|
|
687
688
|
console.warn('[MindMap] Ctrl+V fallback clipboard read failed:', error);
|
|
688
689
|
}
|
|
689
690
|
}, 120);
|
|
690
691
|
}
|
|
691
692
|
|
|
693
|
+
function completePastedTextNode(module, createdNode) {
|
|
694
|
+
const nodeId = String(createdNode?.nodeId ?? createdNode?.NodeId ?? '').trim();
|
|
695
|
+
const nodeEntry = nodeId ? module?.nodeObjectsById?.get?.(nodeId) : null;
|
|
696
|
+
if (!nodeEntry) return false;
|
|
697
|
+
|
|
698
|
+
finalizeSingleSelection(module, nodeId, { notifyBlazor: true, bringToFront: true, showMenu: true });
|
|
699
|
+
module.pendingSelectedActivationNodeIds?.clear?.();
|
|
700
|
+
module.pendingSelectedActivationNodeIds?.add?.(nodeId);
|
|
701
|
+
MindMapNodes.moveCursorAfterNodePlacement?.(
|
|
702
|
+
module,
|
|
703
|
+
nodeEntry.model,
|
|
704
|
+
nodeEntry.model?.width,
|
|
705
|
+
nodeEntry.model?.height,
|
|
706
|
+
{ moveCamera: false }
|
|
707
|
+
);
|
|
708
|
+
return true;
|
|
709
|
+
}
|
|
710
|
+
|
|
692
711
|
function copyTextMetricsFromElement(target, source) {
|
|
693
712
|
if (!target || !source || typeof window === 'undefined' || typeof window.getComputedStyle !== 'function') {
|
|
694
713
|
return;
|
|
@@ -2791,30 +2810,14 @@ window.MindMapInteractions = (function () {
|
|
|
2791
2810
|
if (newNodeIds.length === 1) {
|
|
2792
2811
|
module.selectedNodeIdJs = newNodeIds[0];
|
|
2793
2812
|
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
let nextCursorX, nextCursorY;
|
|
2804
|
-
if (direction === 'vertical') {
|
|
2805
|
-
// Move down (node height + padding)
|
|
2806
|
-
nextCursorX = nodeX;
|
|
2807
|
-
nextCursorY = nodeY - height - PADDING;
|
|
2808
|
-
} else {
|
|
2809
|
-
// Move right (node width + padding)
|
|
2810
|
-
nextCursorX = nodeX + width + PADDING;
|
|
2811
|
-
nextCursorY = nodeY;
|
|
2812
|
-
}
|
|
2813
|
-
|
|
2814
|
-
if (typeof module.updateCursorPosition === 'function') {
|
|
2815
|
-
module.updateCursorPosition(nextCursorX, nextCursorY, false);
|
|
2816
|
-
console.log(`[MindMap] 📍 Cursor moved to (${nextCursorX.toFixed(0)}, ${nextCursorY.toFixed(0)}) after paste`);
|
|
2817
|
-
}
|
|
2813
|
+
const pastedEntry = module.nodeObjectsById?.get?.(newNodeIds[0]);
|
|
2814
|
+
MindMapNodes.moveCursorAfterNodePlacement?.(
|
|
2815
|
+
module,
|
|
2816
|
+
pastedEntry?.model || nodesToPaste[0],
|
|
2817
|
+
pastedEntry?.model?.width || nodesToPaste[0].Width,
|
|
2818
|
+
pastedEntry?.model?.height || nodesToPaste[0].Height,
|
|
2819
|
+
{ moveCamera: false }
|
|
2820
|
+
);
|
|
2818
2821
|
}
|
|
2819
2822
|
if (module.pendingSelectedActivationNodeIds instanceof Set) {
|
|
2820
2823
|
module.pendingSelectedActivationNodeIds.clear();
|
|
@@ -2857,7 +2860,8 @@ window.MindMapInteractions = (function () {
|
|
|
2857
2860
|
if (module.dotNetHelper) {
|
|
2858
2861
|
const cursorX = module.cursorPosition?.x ?? 0;
|
|
2859
2862
|
const cursorY = module.cursorPosition?.y ?? 0;
|
|
2860
|
-
module.dotNetHelper.invokeMethodAsync('PasteTextFromClipboard', finalText, cursorX, cursorY);
|
|
2863
|
+
const createdNode = await module.dotNetHelper.invokeMethodAsync('PasteTextFromClipboard', finalText, cursorX, cursorY);
|
|
2864
|
+
completePastedTextNode(module, createdNode);
|
|
2861
2865
|
}
|
|
2862
2866
|
}
|
|
2863
2867
|
}
|
|
@@ -404,65 +404,24 @@
|
|
|
404
404
|
contentType === 'embed';
|
|
405
405
|
}
|
|
406
406
|
|
|
407
|
-
function
|
|
408
|
-
|
|
409
|
-
if (!normalized) return false;
|
|
410
|
-
return normalized.split(/[?#]/)[0].toLowerCase().endsWith('.gif');
|
|
407
|
+
function isAnimatedGifImageModel(model) {
|
|
408
|
+
return window.MindMapAnimatedImagePreview?.isAnimatedGifImageModel?.(model) === true;
|
|
411
409
|
}
|
|
412
410
|
|
|
413
|
-
function
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
for (const key of keys) {
|
|
417
|
-
const direct = metadata[key];
|
|
418
|
-
if (direct !== undefined && direct !== null && String(direct).trim()) {
|
|
419
|
-
return String(direct).trim();
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
const wantedKeys = new Set(keys.map(key => String(key || '').toLowerCase()));
|
|
424
|
-
for (const key of Object.keys(metadata)) {
|
|
425
|
-
if (wantedKeys.has(String(key || '').toLowerCase())) {
|
|
426
|
-
const value = metadata[key];
|
|
427
|
-
if (value !== undefined && value !== null && String(value).trim()) {
|
|
428
|
-
return String(value).trim();
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
return '';
|
|
411
|
+
function isWebpImageModel(model) {
|
|
412
|
+
return window.MindMapAnimatedImagePreview?.isWebpImageModel?.(model) === true;
|
|
434
413
|
}
|
|
435
414
|
|
|
436
|
-
function
|
|
415
|
+
function isAnimationCapableImageModel(model) {
|
|
437
416
|
if (!model || getNodeContentType(model) !== 'image') {
|
|
438
417
|
return false;
|
|
439
418
|
}
|
|
440
419
|
|
|
441
|
-
if (window.MindMapNodes?.
|
|
442
|
-
return window.MindMapNodes.
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
const metadata = getNodeMetadata(model) || {};
|
|
446
|
-
const mimeType = getMetadataValueCaseInsensitive(
|
|
447
|
-
metadata,
|
|
448
|
-
'fileMime',
|
|
449
|
-
'FileMime',
|
|
450
|
-
'mimeType',
|
|
451
|
-
'MimeType'
|
|
452
|
-
).toLowerCase();
|
|
453
|
-
if (mimeType === 'image/gif') {
|
|
454
|
-
return true;
|
|
420
|
+
if (window.MindMapNodes?.isAnimationCapableImageNodeModel) {
|
|
421
|
+
return window.MindMapNodes.isAnimationCapableImageNodeModel(model) === true;
|
|
455
422
|
}
|
|
456
423
|
|
|
457
|
-
return
|
|
458
|
-
model?.response,
|
|
459
|
-
model?.Response,
|
|
460
|
-
metadata?.OriginalPath,
|
|
461
|
-
metadata?.OriginalUrl,
|
|
462
|
-
metadata?.originalUrl,
|
|
463
|
-
metadata?.ImageUrl,
|
|
464
|
-
metadata?.imageUrl
|
|
465
|
-
].some(isAnimatedGifImageUrl);
|
|
424
|
+
return isAnimatedGifImageModel(model) || isWebpImageModel(model);
|
|
466
425
|
}
|
|
467
426
|
|
|
468
427
|
function isCss3dRendererEnabled(module) {
|
|
@@ -493,40 +452,8 @@
|
|
|
493
452
|
|| normalized.startsWith('file:');
|
|
494
453
|
}
|
|
495
454
|
|
|
496
|
-
function getCanonicalImageAssetKey(url) {
|
|
497
|
-
const normalized = normalizeImageAssetUrl(url);
|
|
498
|
-
if (!normalized) {
|
|
499
|
-
return '';
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
const withoutQuery = normalized.split(/[?#]/)[0];
|
|
503
|
-
const lower = withoutQuery.toLowerCase();
|
|
504
|
-
const thumbsMarker = '/assets/thumbs/';
|
|
505
|
-
const assetsMarker = '/assets/';
|
|
506
|
-
|
|
507
|
-
if (lower.includes(thumbsMarker)) {
|
|
508
|
-
const assetName = withoutQuery.slice(lower.lastIndexOf(thumbsMarker) + thumbsMarker.length).split('/').pop() || '';
|
|
509
|
-
const dotIndex = assetName.lastIndexOf('.');
|
|
510
|
-
return (dotIndex > 0 ? assetName.slice(0, dotIndex) : assetName).toLowerCase();
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
if (lower.includes(assetsMarker)) {
|
|
514
|
-
const assetName = withoutQuery.slice(lower.lastIndexOf(assetsMarker) + assetsMarker.length).split('/').pop() || '';
|
|
515
|
-
const dotIndex = assetName.lastIndexOf('.');
|
|
516
|
-
return (dotIndex > 0 ? assetName.slice(0, dotIndex) : assetName).toLowerCase();
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
return withoutQuery.toLowerCase();
|
|
520
|
-
}
|
|
521
|
-
|
|
522
455
|
function areImageAssetUrlsEquivalent(leftUrl, rightUrl) {
|
|
523
|
-
|
|
524
|
-
const rightKey = getCanonicalImageAssetKey(rightUrl);
|
|
525
|
-
if (leftKey && rightKey) {
|
|
526
|
-
return leftKey === rightKey;
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
return normalizeImageAssetUrl(leftUrl) === normalizeImageAssetUrl(rightUrl);
|
|
456
|
+
return window.MindMapAnimatedImagePreview?.areAssetUrlsEquivalent?.(leftUrl, rightUrl) === true;
|
|
530
457
|
}
|
|
531
458
|
|
|
532
459
|
function isThumbnailImageUrl(url) {
|
|
@@ -557,9 +484,9 @@
|
|
|
557
484
|
const missingAssetUrl = normalizeImageAssetUrl(metadata?.MissingAssetUrl || '');
|
|
558
485
|
const responseFullResUrl = isImageContent && !isThumbnailImageUrl(responseUrl) ? responseUrl : '';
|
|
559
486
|
const missingFullResUrl = !isThumbnailImageUrl(missingAssetUrl) ? missingAssetUrl : '';
|
|
560
|
-
const
|
|
561
|
-
const mediaPreviewUrl =
|
|
562
|
-
const responsePreviewUrl = isImageContent && !
|
|
487
|
+
const animationCapable = isAnimationCapableImageModel(model);
|
|
488
|
+
const mediaPreviewUrl = animationCapable ? '' : (thumbnailUrl || snapshotUrl || previewImageUrl);
|
|
489
|
+
const responsePreviewUrl = isImageContent && !animationCapable ? responseUrl : '';
|
|
563
490
|
const previewUrl = mediaPreviewUrl || responsePreviewUrl || originalPath || originalUrl || missingAssetUrl;
|
|
564
491
|
const fullResUrl = isImageContent
|
|
565
492
|
? (originalUrl || originalPath || responseFullResUrl || missingFullResUrl)
|
|
@@ -575,7 +502,8 @@
|
|
|
575
502
|
missingAssetUrl,
|
|
576
503
|
previewUrl,
|
|
577
504
|
fullResUrl,
|
|
578
|
-
|
|
505
|
+
animationCapable,
|
|
506
|
+
animatedGif: animationCapable
|
|
579
507
|
};
|
|
580
508
|
}
|
|
581
509
|
|
|
@@ -818,6 +746,8 @@
|
|
|
818
746
|
this._imageAtlasLoadingIds = new Set();
|
|
819
747
|
this._imageAtlasActiveLoads = 0;
|
|
820
748
|
this._imageAtlasRetryAfter = new Map();
|
|
749
|
+
this._residentStaticPreviewUrls = new Map();
|
|
750
|
+
this._residentStaticPreviewEpoch = 0;
|
|
821
751
|
this._imageAtlasBatchPendingIds = new Set();
|
|
822
752
|
this._imageAtlasBatchReadyIds = new Set();
|
|
823
753
|
this._imageAtlasBatchActive = false;
|
|
@@ -1115,6 +1045,7 @@
|
|
|
1115
1045
|
if (this._isNodeArrayDirty || this._cachedNodeArray.length !== nodeObjectsById.size) {
|
|
1116
1046
|
this._cachedNodeArray = Array.from(nodeObjectsById.values());
|
|
1117
1047
|
this._isNodeArrayDirty = false;
|
|
1048
|
+
window.MindMapRenderPlan?.prepareImageAtlasForEntries?.(this, this._cachedNodeArray);
|
|
1118
1049
|
}
|
|
1119
1050
|
}
|
|
1120
1051
|
// ▲▲▲ [Optimization] ▲▲▲
|
|
@@ -1379,14 +1310,19 @@
|
|
|
1379
1310
|
return;
|
|
1380
1311
|
}
|
|
1381
1312
|
|
|
1313
|
+
const residentPreviewUrl = this._getResidentStaticPreviewUrl(nodeId, entry.model, assetUrls);
|
|
1314
|
+
|
|
1382
1315
|
const cachedRecord = window.MindMapNodes?.imageCache?.get?.(nodeId) || null;
|
|
1383
|
-
const cachedImage =
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1316
|
+
const cachedImage = residentPreviewUrl
|
|
1317
|
+
? (window.MindMapTextureFactory?.resolveCachedImageEntry?.(cachedRecord, residentPreviewUrl, {
|
|
1318
|
+
preferOriginal: false,
|
|
1319
|
+
allowOriginalReuseForPreview: false,
|
|
1320
|
+
resizeWidth: IMAGE_ATLAS_PREVIEW_REQUEST_WIDTH,
|
|
1321
|
+
originalUrl: assetUrls.fullResUrl || assetUrls.originalUrl || ''
|
|
1322
|
+
}) || null)
|
|
1323
|
+
: null;
|
|
1388
1324
|
const cachedImageUrl = normalizeImageAssetUrl(cachedImage?.url || '');
|
|
1389
|
-
const requestedPreviewUrl = normalizeImageAssetUrl(
|
|
1325
|
+
const requestedPreviewUrl = normalizeImageAssetUrl(residentPreviewUrl);
|
|
1390
1326
|
const cachedRetryAfter = Number(cachedImage?.retryAfter || 0);
|
|
1391
1327
|
const cachedAssetUrl = cachedImageUrl || String(cachedImage?.assetKey || '');
|
|
1392
1328
|
if (
|
|
@@ -1403,11 +1339,28 @@
|
|
|
1403
1339
|
nodeId,
|
|
1404
1340
|
model: entry.model,
|
|
1405
1341
|
previewUrl: assetUrls.previewUrl,
|
|
1406
|
-
|
|
1342
|
+
thumbnailUrl: assetUrls.thumbnailUrl || '',
|
|
1343
|
+
originalUrl: assetUrls.fullResUrl || assetUrls.originalUrl || '',
|
|
1344
|
+
previewEpoch: this._residentStaticPreviewEpoch
|
|
1407
1345
|
});
|
|
1408
1346
|
this._pumpImageAtlasPreviewLoadQueue();
|
|
1409
1347
|
}
|
|
1410
1348
|
|
|
1349
|
+
_getResidentStaticPreviewUrl(nodeId, model, assetUrls = getImageModelAssetUrls(model)) {
|
|
1350
|
+
return window.MindMapAnimatedImagePreview?.getResidentStaticPreviewUrl?.(
|
|
1351
|
+
this, nodeId, model, assetUrls
|
|
1352
|
+
) || '';
|
|
1353
|
+
}
|
|
1354
|
+
|
|
1355
|
+
async _resolveSafeResidentPreviewUrl(item) {
|
|
1356
|
+
const assetUrls = getImageModelAssetUrls(item?.model);
|
|
1357
|
+
const resolver = window.MindMapAnimatedImagePreview?.resolveSafeResidentPreviewUrl;
|
|
1358
|
+
return typeof resolver === 'function'
|
|
1359
|
+
? await resolver(this, item, assetUrls, getImageModelAssetUrls, details =>
|
|
1360
|
+
emitMindCanvasTrace('lod.image.staticPreview.ready', this._module, details))
|
|
1361
|
+
: '';
|
|
1362
|
+
}
|
|
1363
|
+
|
|
1411
1364
|
_pumpImageAtlasPreviewLoadQueue() {
|
|
1412
1365
|
const textureFactory = window.MindMapTextureFactory;
|
|
1413
1366
|
const imageCache = window.MindMapNodes?.imageCache;
|
|
@@ -1440,8 +1393,13 @@
|
|
|
1440
1393
|
this._imageAtlasLoadingIds.add(item.nodeId);
|
|
1441
1394
|
let didLoadImage = false;
|
|
1442
1395
|
|
|
1443
|
-
Promise.resolve(
|
|
1444
|
-
|
|
1396
|
+
Promise.resolve(this._resolveSafeResidentPreviewUrl(item)).then((resolvedPreviewUrl) => {
|
|
1397
|
+
item.resolvedPreviewUrl = resolvedPreviewUrl;
|
|
1398
|
+
if (!resolvedPreviewUrl) {
|
|
1399
|
+
return null;
|
|
1400
|
+
}
|
|
1401
|
+
|
|
1402
|
+
return textureFactory.ensureImageCached(item.nodeId, resolvedPreviewUrl, imageCache, {
|
|
1445
1403
|
authToken: this._module?.authToken || '',
|
|
1446
1404
|
resizeWidth: IMAGE_ATLAS_PREVIEW_REQUEST_WIDTH,
|
|
1447
1405
|
preferOriginal: false,
|
|
@@ -1463,12 +1421,18 @@
|
|
|
1463
1421
|
setImageModelPreviewUrl(item.model, normalized);
|
|
1464
1422
|
}
|
|
1465
1423
|
}
|
|
1466
|
-
})
|
|
1467
|
-
).then((cachedImage) => {
|
|
1424
|
+
});
|
|
1425
|
+
}).then((cachedImage) => {
|
|
1468
1426
|
didLoadImage = !!(cachedImage?.image) && cachedImage?.isError !== true;
|
|
1469
1427
|
item.cachedImage = cachedImage || null;
|
|
1470
|
-
}).catch(() => {
|
|
1428
|
+
}).catch((error) => {
|
|
1471
1429
|
didLoadImage = false;
|
|
1430
|
+
if (isWebpImageModel(item?.model)) {
|
|
1431
|
+
emitMindCanvasTrace('lod.image.staticPreview.failed', this._module, {
|
|
1432
|
+
nodeId: item.nodeId,
|
|
1433
|
+
reason: String(error?.message || error || 'unknown')
|
|
1434
|
+
});
|
|
1435
|
+
}
|
|
1472
1436
|
}).finally(() => {
|
|
1473
1437
|
this._imageAtlasActiveLoads = Math.max(0, this._imageAtlasActiveLoads - 1);
|
|
1474
1438
|
this._imageAtlasQueuedIds.delete(item.nodeId);
|
|
@@ -1511,14 +1475,22 @@
|
|
|
1511
1475
|
_getImageLodSource(entry) {
|
|
1512
1476
|
const nodeId = String(entry?.model?.id || '').trim();
|
|
1513
1477
|
const assetUrls = getImageModelAssetUrls(entry?.model);
|
|
1478
|
+
const webpModel = isWebpImageModel(entry?.model);
|
|
1479
|
+
const residentPreviewUrl = this._getResidentStaticPreviewUrl(nodeId, entry?.model, assetUrls);
|
|
1480
|
+
if (webpModel && !residentPreviewUrl) {
|
|
1481
|
+
this._queueImageAtlasPreviewLoad(entry);
|
|
1482
|
+
return null;
|
|
1483
|
+
}
|
|
1484
|
+
|
|
1514
1485
|
const cachedRecord = nodeId ? window.MindMapNodes?.imageCache?.get?.(nodeId) || null : null;
|
|
1515
1486
|
const cachedImage = nodeId
|
|
1516
1487
|
? (
|
|
1517
|
-
window.MindMapTextureFactory?.resolveCachedImageEntry?.(cachedRecord,
|
|
1488
|
+
window.MindMapTextureFactory?.resolveCachedImageEntry?.(cachedRecord, residentPreviewUrl, {
|
|
1518
1489
|
preferOriginal: false,
|
|
1519
1490
|
allowOriginalReuseForPreview: false,
|
|
1491
|
+
resizeWidth: IMAGE_ATLAS_PREVIEW_REQUEST_WIDTH,
|
|
1520
1492
|
originalUrl: assetUrls.fullResUrl || assetUrls.originalUrl || ''
|
|
1521
|
-
}) ||
|
|
1493
|
+
}) || null
|
|
1522
1494
|
)
|
|
1523
1495
|
: null;
|
|
1524
1496
|
const cachedSource = cachedImage?.image || null;
|
|
@@ -1540,6 +1512,13 @@
|
|
|
1540
1512
|
};
|
|
1541
1513
|
}
|
|
1542
1514
|
|
|
1515
|
+
if (isThumbnailImageUrl(residentPreviewUrl)) {
|
|
1516
|
+
if (!isCachedImageRetryPending) {
|
|
1517
|
+
this._queueImageAtlasPreviewLoad(entry);
|
|
1518
|
+
}
|
|
1519
|
+
return null;
|
|
1520
|
+
}
|
|
1521
|
+
|
|
1543
1522
|
const cssImage = entry?.cssObject?.element?.querySelector?.('img') || null;
|
|
1544
1523
|
const cssImageWidth = Number(cssImage?.naturalWidth || cssImage?.width || 0);
|
|
1545
1524
|
const cssImageHeight = Number(cssImage?.naturalHeight || cssImage?.height || 0);
|
|
@@ -1640,8 +1619,6 @@
|
|
|
1640
1619
|
sy = (source.height - sh) * 0.5;
|
|
1641
1620
|
}
|
|
1642
1621
|
|
|
1643
|
-
// Match NEAR image nodes: CSS/WebGL both use object-fit: cover
|
|
1644
|
-
// against the node rectangle, then map that result over the quad.
|
|
1645
1622
|
scratchCtx.drawImage(source.image, sx, sy, sw, sh, 0, 0, size, size);
|
|
1646
1623
|
scratchCtx.restore();
|
|
1647
1624
|
|
|
@@ -1652,9 +1629,8 @@
|
|
|
1652
1629
|
ctx.fillStyle = '#eef2f7';
|
|
1653
1630
|
ctx.fillRect(x, y, size, size);
|
|
1654
1631
|
ctx.drawImage(scratch, 0, 0, size, size, x, y, size, size);
|
|
1655
|
-
if (this
|
|
1656
|
-
this.
|
|
1657
|
-
}
|
|
1632
|
+
if (!window.MindMapRenderPlan?.uploadImageAtlasTile?.(this, slot, scratch))
|
|
1633
|
+
window.MindMapRenderPlan?.scheduleImageAtlasUpload?.(this, this._module);
|
|
1658
1634
|
return true;
|
|
1659
1635
|
} catch {
|
|
1660
1636
|
try { scratchCtx.restore(); } catch { }
|
|
@@ -3417,7 +3393,7 @@
|
|
|
3417
3393
|
const pendingAnimatedGifCssFallbacks = usesAnimatedGifCssFallbacks && activeImageCssFallbackCount <= 0;
|
|
3418
3394
|
const staleImageCssFallbacks = imageCssFallbackCount > 0 &&
|
|
3419
3395
|
(usesAnyImageCssFallbacks !== true || activeImageCssFallbackCount <= 0);
|
|
3420
|
-
const lineDetailRestorePending =
|
|
3396
|
+
const lineDetailRestorePending = window.MindMapRenderPlan?.hasActionableResidentLineDetails?.(this, module, lodBand) === true;
|
|
3421
3397
|
const dirty = (
|
|
3422
3398
|
this._instancesDirty === true ||
|
|
3423
3399
|
this._imageInstancesDirty === true ||
|
|
@@ -5878,9 +5854,7 @@
|
|
|
5878
5854
|
if (this.isInLODMode === true &&
|
|
5879
5855
|
this._instancesDirty &&
|
|
5880
5856
|
this._shouldDeferResidentInstanceRebuild(module, lodBand)) {
|
|
5881
|
-
|
|
5882
|
-
module._forceUpdateFrames = Math.max(Number(module._forceUpdateFrames || 0), 12);
|
|
5883
|
-
}
|
|
5857
|
+
this._keepResidentLodSettleFrames(module, 2, 'defer-resident-instance-rebuild');
|
|
5884
5858
|
if (LOD_PERF_DEBUG) {
|
|
5885
5859
|
_prof('done');
|
|
5886
5860
|
}
|
|
@@ -5896,9 +5870,7 @@
|
|
|
5896
5870
|
if (this.isInLODMode === true &&
|
|
5897
5871
|
this._lodCleanupPending === true &&
|
|
5898
5872
|
this._isResidentLodInteractionActive(module)) {
|
|
5899
|
-
|
|
5900
|
-
module._forceUpdateFrames = Math.max(Number(module._forceUpdateFrames || 0), 12);
|
|
5901
|
-
}
|
|
5873
|
+
this._keepResidentLodSettleFrames(module, 2, 'defer-lod-cleanup');
|
|
5902
5874
|
if (LOD_PERF_DEBUG) {
|
|
5903
5875
|
_prof('done');
|
|
5904
5876
|
}
|
|
@@ -6174,9 +6146,7 @@
|
|
|
6174
6146
|
// ▼▼▼ [Perf] Only update instance data when dirty or node count changed ▼▼▼
|
|
6175
6147
|
// Check if node count changed (add/remove detection)
|
|
6176
6148
|
if (this._instancesDirty && this._shouldDeferResidentInstanceRebuild(module, lodBand)) {
|
|
6177
|
-
|
|
6178
|
-
module._forceUpdateFrames = Math.max(Number(module._forceUpdateFrames || 0), 12);
|
|
6179
|
-
}
|
|
6149
|
+
this._keepResidentLodSettleFrames(module, 2, 'defer-resident-instance-rebuild');
|
|
6180
6150
|
if (LOD_PERF_DEBUG) {
|
|
6181
6151
|
_prof('done');
|
|
6182
6152
|
}
|
|
@@ -6388,9 +6358,7 @@
|
|
|
6388
6358
|
Number(this._residentRebuildDeferredUntil || 0),
|
|
6389
6359
|
now + LOD_RESIDENT_REBUILD_SETTLE_MS
|
|
6390
6360
|
);
|
|
6391
|
-
|
|
6392
|
-
module._forceUpdateFrames = Math.max(Number(module._forceUpdateFrames || 0), 4);
|
|
6393
|
-
}
|
|
6361
|
+
this._keepResidentLodSettleFrames(module, 2, 'defer-resident-full-rebuild');
|
|
6394
6362
|
}
|
|
6395
6363
|
|
|
6396
6364
|
if (this._instancesDirty && residentFullBuildBlockedThisFrame !== true) {
|
|
@@ -7119,13 +7087,8 @@
|
|
|
7119
7087
|
}, safeDelayMs);
|
|
7120
7088
|
}
|
|
7121
7089
|
|
|
7122
|
-
_keepResidentLodSettleFrames(module = this._module,
|
|
7090
|
+
_keepResidentLodSettleFrames(module = this._module, _frames = 12, reason = 'resident-settle') {
|
|
7123
7091
|
if (module) {
|
|
7124
|
-
if (this._isResidentLodInteractionActive(module)) {
|
|
7125
|
-
module._forceUpdateFrames = Math.max(Number(module._forceUpdateFrames || 0), frames);
|
|
7126
|
-
return;
|
|
7127
|
-
}
|
|
7128
|
-
|
|
7129
7092
|
this._scheduleResidentLodWake(reason, LOD_RESIDENT_REBUILD_SETTLE_MS);
|
|
7130
7093
|
}
|
|
7131
7094
|
}
|
|
@@ -9504,6 +9467,7 @@
|
|
|
9504
9467
|
clearTimeout(this._residentLodWakeTimer);
|
|
9505
9468
|
this._residentLodWakeTimer = 0;
|
|
9506
9469
|
}
|
|
9470
|
+
window.MindMapRenderPlan?.clearScheduledImageAtlasUpload?.(this);
|
|
9507
9471
|
this._residentLodWakeReason = '';
|
|
9508
9472
|
this.isInLODMode = null;
|
|
9509
9473
|
|
|
@@ -9550,6 +9514,8 @@
|
|
|
9550
9514
|
this._imageAtlasLoadingIds.clear();
|
|
9551
9515
|
this._imageAtlasActiveLoads = 0;
|
|
9552
9516
|
this._imageAtlasRetryAfter.clear();
|
|
9517
|
+
this._residentStaticPreviewUrls.clear();
|
|
9518
|
+
this._residentStaticPreviewEpoch++;
|
|
9553
9519
|
this._resetImageAtlasBatchState();
|
|
9554
9520
|
this._imageAtlasRebuildPending = false;
|
|
9555
9521
|
this._imageAtlasRebuildDeferredUntil = 0;
|
|
@@ -9669,6 +9635,7 @@
|
|
|
9669
9635
|
this._nearPriorityRecordById?.delete?.(nodeId);
|
|
9670
9636
|
this._lodConsoleProxyNodeIds?.delete?.(nodeId);
|
|
9671
9637
|
this._lodImageCssFallbackNodeIds.delete(nodeId);
|
|
9638
|
+
this._residentStaticPreviewUrls.delete(nodeId);
|
|
9672
9639
|
this._lodTemplateCssNodeIds?.delete?.(nodeId);
|
|
9673
9640
|
this._fullResCssFringePreparedIds?.delete?.(nodeId);
|
|
9674
9641
|
removedAny = true;
|
|
@@ -10253,6 +10220,8 @@
|
|
|
10253
10220
|
this._imageAtlasLoadingIds.clear();
|
|
10254
10221
|
this._imageAtlasActiveLoads = 0;
|
|
10255
10222
|
this._imageAtlasRetryAfter.clear();
|
|
10223
|
+
this._residentStaticPreviewUrls.clear();
|
|
10224
|
+
this._residentStaticPreviewEpoch++;
|
|
10256
10225
|
this._pendingSelectionRefreshIds.clear();
|
|
10257
10226
|
if (this._idleRebuildTimer) {
|
|
10258
10227
|
clearTimeout(this._idleRebuildTimer);
|
|
@@ -10262,6 +10231,7 @@
|
|
|
10262
10231
|
clearTimeout(this._residentLodWakeTimer);
|
|
10263
10232
|
this._residentLodWakeTimer = 0;
|
|
10264
10233
|
}
|
|
10234
|
+
window.MindMapRenderPlan?.clearScheduledImageAtlasUpload?.(this);
|
|
10265
10235
|
this._resetImageAtlasBatchState();
|
|
10266
10236
|
this.thumbnailMap.clear();
|
|
10267
10237
|
this.pendingNodes.clear();
|
|
@@ -1061,27 +1061,31 @@
|
|
|
1061
1061
|
}
|
|
1062
1062
|
|
|
1063
1063
|
// ▼▼▼ [New] Screen-space position using worldToScreen ▼▼▼
|
|
1064
|
-
function worldToScreen(worldX, worldY, camera, container) {
|
|
1065
|
-
const THREE = globalThis.THREE;
|
|
1066
|
-
const vector = new THREE.Vector3(worldX, worldY, 0);
|
|
1067
|
-
vector.project(camera);
|
|
1068
|
-
|
|
1069
|
-
const
|
|
1070
|
-
const
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1064
|
+
function worldToScreen(worldX, worldY, camera, container) {
|
|
1065
|
+
const THREE = globalThis.THREE;
|
|
1066
|
+
const vector = new THREE.Vector3(worldX, worldY, 0);
|
|
1067
|
+
vector.project(camera);
|
|
1068
|
+
|
|
1069
|
+
const viewportWidth = Number(_module?._lastViewportWidth || _module?._lastContainerWidth || container.clientWidth || 1);
|
|
1070
|
+
const viewportHeight = Number(_module?._lastViewportHeight || _module?._lastContainerHeight || container.clientHeight || 1);
|
|
1071
|
+
const viewportLeft = Number(_module?._lastViewportLeft || 0);
|
|
1072
|
+
const viewportTop = Number(_module?._lastViewportTop || 0);
|
|
1073
|
+
const halfWidth = viewportWidth / 2;
|
|
1074
|
+
const halfHeight = viewportHeight / 2;
|
|
1075
|
+
|
|
1076
|
+
return {
|
|
1077
|
+
x: viewportLeft + (vector.x * halfWidth) + halfWidth,
|
|
1078
|
+
y: viewportTop - (vector.y * halfHeight) + halfHeight
|
|
1079
|
+
};
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
function updateMenuScreenPosition(menuEl, nodeEntry, cameraMotionOnly = false) {
|
|
1079
1083
|
if (!menuEl || !nodeEntry || !_module || !_module.camera || !_module.container) return;
|
|
1080
1084
|
|
|
1081
1085
|
const templateNode = document.getElementById(`node-${nodeEntry.model?.id || currentMenuNodeId}`);
|
|
1082
1086
|
let anchorX = null;
|
|
1083
1087
|
let anchorY = null;
|
|
1084
|
-
const shouldPreferProjectedAnchor =
|
|
1088
|
+
const shouldPreferProjectedAnchor = cameraMotionOnly === true ||
|
|
1085
1089
|
_module.isZooming === true ||
|
|
1086
1090
|
_module.isPanning === true ||
|
|
1087
1091
|
_module.isDraggingNode === true ||
|
|
@@ -1116,8 +1120,15 @@
|
|
|
1116
1120
|
anchorY = screenPos.y;
|
|
1117
1121
|
}
|
|
1118
1122
|
|
|
1119
|
-
|
|
1120
|
-
|
|
1123
|
+
let halfMenuWidth = Number(menuEl._mindMapHalfWidth || 0);
|
|
1124
|
+
let menuHeight = Number(menuEl._mindMapHeight || 0);
|
|
1125
|
+
if (cameraMotionOnly !== true || halfMenuWidth <= 0 || menuHeight <= 0) {
|
|
1126
|
+
const menuRect = menuEl.getBoundingClientRect();
|
|
1127
|
+
halfMenuWidth = menuRect.width > 0 ? menuRect.width / 2 : 0;
|
|
1128
|
+
menuHeight = menuRect.height || 0;
|
|
1129
|
+
menuEl._mindMapHalfWidth = halfMenuWidth;
|
|
1130
|
+
menuEl._mindMapHeight = menuHeight;
|
|
1131
|
+
}
|
|
1121
1132
|
const viewportMargin = 10;
|
|
1122
1133
|
const verticalGap = 14;
|
|
1123
1134
|
|
|
@@ -1126,7 +1137,7 @@
|
|
|
1126
1137
|
Math.max(viewportMargin + halfMenuWidth, anchorX)
|
|
1127
1138
|
);
|
|
1128
1139
|
const anchoredTop = anchorY - verticalGap;
|
|
1129
|
-
const minTop = viewportMargin +
|
|
1140
|
+
const minTop = viewportMargin + menuHeight;
|
|
1130
1141
|
const clampedTop = Math.max(minTop, anchoredTop);
|
|
1131
1142
|
|
|
1132
1143
|
menuEl.style.left = `${clampedLeft}px`;
|
|
@@ -1134,7 +1145,7 @@
|
|
|
1134
1145
|
}
|
|
1135
1146
|
// ▲▲▲ [New] ▲▲▲
|
|
1136
1147
|
|
|
1137
|
-
function update() {
|
|
1148
|
+
function update() {
|
|
1138
1149
|
if (currentMenuElement && currentMenuNodeId && _module) {
|
|
1139
1150
|
const nodeEntry = _module.nodeObjectsById.get(currentMenuNodeId);
|
|
1140
1151
|
if (nodeEntry) {
|
|
@@ -1543,8 +1554,19 @@
|
|
|
1543
1554
|
});
|
|
1544
1555
|
}
|
|
1545
1556
|
}
|
|
1557
|
+
|
|
1558
|
+
function updateForCameraMotion() {
|
|
1559
|
+
if (!currentMenuElement || !currentMenuNodeId || !_module) return false;
|
|
1560
|
+
const nodeEntry = _module.nodeObjectsById.get(currentMenuNodeId);
|
|
1561
|
+
if (!nodeEntry) {
|
|
1562
|
+
hideMenu();
|
|
1563
|
+
return false;
|
|
1564
|
+
}
|
|
1565
|
+
updateMenuScreenPosition(currentMenuElement, nodeEntry, true);
|
|
1566
|
+
return true;
|
|
1567
|
+
}
|
|
1546
1568
|
|
|
1547
|
-
window.MindMapMenuManager = { init, showMenu, hideMenu, update };
|
|
1569
|
+
window.MindMapMenuManager = { init, showMenu, hideMenu, update, updateForCameraMotion };
|
|
1548
1570
|
|
|
1549
1571
|
console.log('✅ mind-map-menu-manager.js loaded');
|
|
1550
1572
|
})();
|