@mindexec/cli 0.2.433 → 0.2.435

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mindexec/cli",
3
- "version": "0.2.433",
3
+ "version": "0.2.435",
4
4
  "description": "MindExec local runtime and bridge CLI",
5
5
  "main": "server.js",
6
6
  "type": "module",
@@ -127,7 +127,14 @@
127
127
  const LOD_PAN_VISIBILITY_REFRESH_INTERVAL_MS = 120;
128
128
  const CAMERA_LERP_BASE_FRAME_MS = 1000 / 60;
129
129
  const CAMERA_KEYBOARD_PAN_LERP_60HZ = 0.38;
130
- const CAMERA_MOUSE_PAN_LERP_60HZ = 0.46;
130
+ const CAMERA_MOUSE_PAN_LERP_60HZ = 0.30;
131
+ const CAMERA_MOUSE_PAN_SNAP_SCREEN_PX = 0.1;
132
+ const RECENT_PAN_INPUT_WINDOW_MS = 220;
133
+ const CAMERA_PAN_INPUT_WAKE_REASONS = new Set([
134
+ 'pan-input',
135
+ 'trackpad-pan-input',
136
+ 'ctrl-wheel-pan-input'
137
+ ]);
131
138
  const NODE_ADD_FRAME_BUDGET_MS = 6;
132
139
  const NODE_ADD_LOADING_FRAME_BUDGET_MS = 8;
133
140
  const NODE_ADD_MIN_SLICE = 8;
@@ -388,6 +395,22 @@
388
395
  return 1 - Math.pow(1 - safeBase, frameScale);
389
396
  }
390
397
 
398
+ function getCameraPanSnapWorldThreshold(module) {
399
+ const camera = module?.camera;
400
+ if (!camera?.isPerspectiveCamera) {
401
+ return 0.001;
402
+ }
403
+
404
+ const cameraZ = Math.max(1, Math.abs(Number(camera.position?.z || 1)));
405
+ const viewportHeight = Math.max(
406
+ 1,
407
+ Number(module?._lastViewportHeight || module?._lastContainerHeight || 1080)
408
+ );
409
+ const fovDegrees = Math.max(1, Math.min(179, Number(camera.fov || 45)));
410
+ const viewHeight = 2 * Math.tan((fovDegrees * Math.PI) / 360) * cameraZ;
411
+ return Math.max(0.001, (viewHeight / viewportHeight) * CAMERA_MOUSE_PAN_SNAP_SCREEN_PX);
412
+ }
413
+
391
414
  const _mindCanvasPerfClassState = {
392
415
  moving: false,
393
416
  dense: false,
@@ -970,9 +993,10 @@
970
993
  const cameraZ = Number(camera.position?.z || 0);
971
994
  const cameraX = Number(camera.position?.x || 0);
972
995
  const cameraY = Number(camera.position?.y || 0);
996
+ const isPanMotionActive = module.isPanning === true || module._panSmoothingActive === true;
973
997
  const marginPolicy = getVisibilityMarginPolicy(
974
998
  cameraZ,
975
- module.isPanning === true,
999
+ isPanMotionActive,
976
1000
  isCtrlWheelVerticalScrolling
977
1001
  );
978
1002
  const cullingMarginPx = marginPolicy.cullingMarginPx;
@@ -989,7 +1013,7 @@
989
1013
  let leadTopCells = 0;
990
1014
  let leadBottomCells = 0;
991
1015
 
992
- if (module.isPanning === true && cameraZ < 12000) {
1016
+ if (isPanMotionActive && cameraZ < 12000) {
993
1017
  const panLeadWorld = Math.min(
994
1018
  rawMarginWorld * (cameraZ < 4500 ? 1.35 : 1.1),
995
1019
  cellSize * Math.max(1, maxMarginCells)
@@ -3044,6 +3068,8 @@ ${summaryLines.map(line => `<div>${escapeNodeFrameDebugHtml(line)}</div>`).join(
3044
3068
  this.nodeObjectsById = new Map();
3045
3069
  this.lodUpdateQueue = []; // Initialize lodUpdateQueue
3046
3070
  this.isPanning = false;
3071
+ this._panSmoothingActive = false;
3072
+ this._resetPanLerpDeltaOnNextFrame = false;
3047
3073
  this._currentDpr = null;
3048
3074
  this._lastViewportWidth = 0;
3049
3075
  this._lastViewportHeight = 0;
@@ -4105,12 +4131,24 @@ ${summaryLines.map(line => `<div>${escapeNodeFrameDebugHtml(line)}</div>`).join(
4105
4131
  }
4106
4132
 
4107
4133
  requestAnimationWake(reason = 'runtime-wake') {
4134
+ const wakeReason = String(reason || 'runtime-wake');
4135
+ const isPanInputWake = CAMERA_PAN_INPUT_WAKE_REASONS.has(wakeReason);
4136
+ if (isPanInputWake) {
4137
+ this._lastPanInputAt = typeof performance !== 'undefined' && typeof performance.now === 'function'
4138
+ ? performance.now()
4139
+ : Date.now();
4140
+ this._panSmoothingActive = true;
4141
+ }
4142
+
4108
4143
  if (this._animationLoopRunning !== true || this._animationLoopExecuting === true) {
4109
4144
  return;
4110
4145
  }
4111
4146
 
4112
- const wakeReason = String(reason || 'runtime-wake');
4113
4147
  this._lastAnimationWakeReason = wakeReason;
4148
+ const resumedFromIdleCadence = !!this._animationIdleTimerId;
4149
+ if (resumedFromIdleCadence && isPanInputWake) {
4150
+ this._resetPanLerpDeltaOnNextFrame = true;
4151
+ }
4114
4152
  if (this._animationIdleTimerId) {
4115
4153
  clearTimeout(this._animationIdleTimerId);
4116
4154
  this._animationIdleTimerId = null;
@@ -4880,7 +4918,7 @@ ${summaryLines.map(line => `<div>${escapeNodeFrameDebugHtml(line)}</div>`).join(
4880
4918
 
4881
4919
  this._deferredDprTimer = setTimeout(() => {
4882
4920
  this._deferredDprTimer = null;
4883
- if (this.isZooming || this.isPanning || this.isDraggingNode || this.isDraggingMultipleNodes || this.isResizing || this.isWindowResizing) {
4921
+ if (this.isZooming || this.isPanning || this._panSmoothingActive || this.isDraggingNode || this.isDraggingMultipleNodes || this.isResizing || this.isWindowResizing) {
4884
4922
  this._scheduleDeferredRendererPixelRatioApply(delayMs);
4885
4923
  return;
4886
4924
  }
@@ -5274,6 +5312,7 @@ ${summaryLines.map(line => `<div>${escapeNodeFrameDebugHtml(line)}</div>`).join(
5274
5312
  (typeof performance !== 'undefined' && typeof performance.now === 'function')
5275
5313
  ? performance.now()
5276
5314
  : Date.now();
5315
+ const isPanMotionActive = this.isPanning === true || this._panSmoothingActive === true;
5277
5316
 
5278
5317
  let cullingMarginPx = 3000;
5279
5318
  let maxMarginCells = 6;
@@ -5297,7 +5336,7 @@ ${summaryLines.map(line => `<div>${escapeNodeFrameDebugHtml(line)}</div>`).join(
5297
5336
  const cameraZ = Number(camera.position?.z || 0);
5298
5337
  const marginPolicy = getVisibilityMarginPolicy(
5299
5338
  cameraZ,
5300
- this.isPanning === true,
5339
+ isPanMotionActive,
5301
5340
  isCtrlWheelVerticalScrolling
5302
5341
  );
5303
5342
  cullingMarginPx = marginPolicy.cullingMarginPx;
@@ -5340,7 +5379,7 @@ ${summaryLines.map(line => `<div>${escapeNodeFrameDebugHtml(line)}</div>`).join(
5340
5379
  }
5341
5380
  }
5342
5381
 
5343
- if (this.isPanning === true && cameraZ < 12000) {
5382
+ if (isPanMotionActive && cameraZ < 12000) {
5344
5383
  const panLeadWorld = Math.min(
5345
5384
  rawMarginWorld * (cameraZ < 4500 ? 1.35 : 1.1),
5346
5385
  cellSize * Math.max(1, maxMarginCells)
@@ -5398,7 +5437,7 @@ ${summaryLines.map(line => `<div>${escapeNodeFrameDebugHtml(line)}</div>`).join(
5398
5437
  const previousVisibilityNodeCount = Number(this._lastVisibilityNodeCount || 0);
5399
5438
  const canAttemptIncrementalFullResPan =
5400
5439
  isFullResMode &&
5401
- this.isPanning === true &&
5440
+ isPanMotionActive &&
5402
5441
  this.isZooming !== true &&
5403
5442
  this._fullResMotionFrozen !== true &&
5404
5443
  this.isWindowResizing !== true &&
@@ -5780,7 +5819,8 @@ ${summaryLines.map(line => `<div>${escapeNodeFrameDebugHtml(line)}</div>`).join(
5780
5819
  const frameDelta = frameStart - (this._lastFrameTime || frameStart);
5781
5820
  this._lastFrameTime = frameStart;
5782
5821
  this._lastFrameDeltaMs = Number.isFinite(frameDelta) ? frameDelta : 0;
5783
- if (frameDelta > 0 && Number.isFinite(frameDelta)) {
5822
+ const shouldIgnoreIdleWakeFrameDelta = this._resetPanLerpDeltaOnNextFrame === true;
5823
+ if (frameDelta > 0 && Number.isFinite(frameDelta) && !shouldIgnoreIdleWakeFrameDelta) {
5784
5824
  const previousAvgFrameTime = Number(this._avgFrameTime || frameDelta);
5785
5825
  const nextAvgFrameTime = previousAvgFrameTime + ((frameDelta - previousAvgFrameTime) * 0.15);
5786
5826
  this._avgFrameTime = nextAvgFrameTime;
@@ -5857,20 +5897,54 @@ ${summaryLines.map(line => `<div>${escapeNodeFrameDebugHtml(line)}</div>`).join(
5857
5897
  // ?�▼??[Changed] Time-normalized camera smoothing ?�▼?? // Mouse move events can arrive at an uneven cadence even when rAF is 60fps.
5858
5898
  // Keep zoom instant, but smooth mouse pan enough to hide input sampling jitter.
5859
5899
  const sZoom = 1.0;
5860
- const panLerp60hz = this.isPanning
5900
+ const isRecentPanInput =
5901
+ (frameStart - Number(this._lastPanInputAt || 0)) <= RECENT_PAN_INPUT_WINDOW_MS;
5902
+ const panSnapWorldThreshold = getCameraPanSnapWorldThreshold(this);
5903
+ const cameraTargetX = Number(this.targetX ?? this.camera.position.x);
5904
+ const cameraTargetY = Number(this.targetY ?? this.camera.position.y);
5905
+ const pendingPanDistanceBeforeLerp = Math.hypot(
5906
+ cameraTargetX - Number(this.camera.position.x || 0),
5907
+ cameraTargetY - Number(this.camera.position.y || 0)
5908
+ );
5909
+ let isPanSmoothingActive = this.isZooming !== true && (
5910
+ this.isPanning === true ||
5911
+ ((isRecentPanInput || this._panSmoothingActive === true) &&
5912
+ pendingPanDistanceBeforeLerp > panSnapWorldThreshold)
5913
+ );
5914
+ const panLerp60hz = isPanSmoothingActive
5861
5915
  ? CAMERA_MOUSE_PAN_LERP_60HZ
5862
5916
  : CAMERA_KEYBOARD_PAN_LERP_60HZ;
5863
- const sPan = this.isZooming ? 1.0 : normalizeFrameLerp(panLerp60hz, frameDelta);
5917
+ const panFrameDelta = this._resetPanLerpDeltaOnNextFrame === true
5918
+ ? CAMERA_LERP_BASE_FRAME_MS
5919
+ : frameDelta;
5920
+ this._resetPanLerpDeltaOnNextFrame = false;
5921
+ const sPan = this.isZooming ? 1.0 : normalizeFrameLerp(panLerp60hz, panFrameDelta);
5864
5922
  // ?�▲??[Changed] ?�▲??
5865
5923
  this._tmpOldCamPos.copy(this.camera.position);
5866
- this.camera.position.x += (this.targetX - this.camera.position.x) * sPan;
5867
- this.camera.position.y += (this.targetY - this.camera.position.y) * sPan;
5924
+ this.camera.position.x += (cameraTargetX - this.camera.position.x) * sPan;
5925
+ this.camera.position.y += (cameraTargetY - this.camera.position.y) * sPan;
5868
5926
  this.camera.position.z += (this.targetZ - this.camera.position.z) * sZoom;
5869
5927
 
5928
+ let remainingPanDistance = Math.hypot(
5929
+ cameraTargetX - Number(this.camera.position.x || 0),
5930
+ cameraTargetY - Number(this.camera.position.y || 0)
5931
+ );
5932
+ if (this.isZooming !== true &&
5933
+ this.isPanning !== true &&
5934
+ remainingPanDistance <= panSnapWorldThreshold) {
5935
+ this.camera.position.x = cameraTargetX;
5936
+ this.camera.position.y = cameraTargetY;
5937
+ remainingPanDistance = 0;
5938
+ isPanSmoothingActive = false;
5939
+ }
5940
+ this._panSmoothingActive = isPanSmoothingActive;
5941
+
5870
5942
  // Check delta
5871
5943
  const deltaMove = this.camera.position.distanceToSquared(this._tmpOldCamPos);
5872
5944
  const didCameraPositionChange = deltaMove > 0.0001;
5873
- const isCameraMoving = didCameraPositionChange || hasFreshImmediateCameraFeedbackAtFrameStart;
5945
+ const isCameraMoving = didCameraPositionChange ||
5946
+ hasFreshImmediateCameraFeedbackAtFrameStart ||
5947
+ (isPanSmoothingActive && remainingPanDistance > panSnapWorldThreshold);
5874
5948
  if (isCameraMoving) {
5875
5949
  this._viewStatePersistAfterMotion = true;
5876
5950
  }
@@ -5941,13 +6015,10 @@ ${summaryLines.map(line => `<div>${escapeNodeFrameDebugHtml(line)}</div>`).join(
5941
6015
  const wasViewStateMotionFrozenLastFrame = this._wasViewStateMotionFrozenLastFrame === true;
5942
6016
  const CTRL_WHEEL_SCROLL_ACTIVE_WINDOW_MS = 140;
5943
6017
  const CAMERA_NAVIGATION_OVERLAY_ACTIVE_WINDOW_MS = 220;
5944
- const RECENT_PAN_INPUT_WINDOW_MS = 220;
5945
6018
  const isCtrlWheelVerticalScrolling =
5946
6019
  (frameStart - Number(this._ctrlWheelScrollInputTime || 0)) <= CTRL_WHEEL_SCROLL_ACTIVE_WINDOW_MS;
5947
6020
  const isCameraNavigationOverlayPriority =
5948
6021
  (frameStart - Number(this._cameraNavigationOverlayInputTime || 0)) <= CAMERA_NAVIGATION_OVERLAY_ACTIVE_WINDOW_MS;
5949
- const isRecentPanInput =
5950
- (frameStart - Number(this._lastPanInputAt || 0)) <= RECENT_PAN_INPUT_WINDOW_MS;
5951
6022
  const isCameraManipulatingForOverlay =
5952
6023
  this.isZooming === true ||
5953
6024
  this.isPanning === true ||
@@ -5972,7 +6043,12 @@ ${summaryLines.map(line => `<div>${escapeNodeFrameDebugHtml(line)}</div>`).join(
5972
6043
  this._wasPanningLastFrame = this.isPanning === true;
5973
6044
  this._wasCameraMovingLastFrame = isCameraMoving === true;
5974
6045
  this._wasResizingLastFrame = this.isResizing === true;
5975
- if (zoomEndedThisFrame || panEndedThisFrame || cameraEndedThisFrame || resizeEndedThisFrame) {
6046
+ const shouldFinalizeMotionThisFrame =
6047
+ zoomEndedThisFrame ||
6048
+ cameraEndedThisFrame ||
6049
+ resizeEndedThisFrame ||
6050
+ (panEndedThisFrame && isPanSmoothingActive !== true);
6051
+ if (shouldFinalizeMotionThisFrame) {
5976
6052
  this._lastMotionEndAt = frameStart;
5977
6053
  if (this._cursorDomDeferredForMotion === true) {
5978
6054
  updateCursorDomElement(this);
@@ -6130,7 +6206,7 @@ ${summaryLines.map(line => `<div>${escapeNodeFrameDebugHtml(line)}</div>`).join(
6130
6206
  const idleUpdateDue = false;
6131
6207
  const isLodPanVisibilityRefreshDue =
6132
6208
  !isResidentMidFarLodFrame &&
6133
- this.isPanning === true &&
6209
+ isPanSmoothingActive &&
6134
6210
  this.isZooming !== true &&
6135
6211
  this.useLODRendering === true &&
6136
6212
  this.lodRenderer?.isInLODMode === true &&
@@ -6260,7 +6336,7 @@ ${summaryLines.map(line => `<div>${escapeNodeFrameDebugHtml(line)}</div>`).join(
6260
6336
  Number(this._avgFrameTime || 0) >= FULL_RES_MOTION_FREEZE_FRAME_MS
6261
6337
  );
6262
6338
  const shouldAdaptiveFreezeMotionSafeguard =
6263
- (this.isZooming === true || this.isPanning === true) &&
6339
+ (this.isZooming === true || isPanSmoothingActive) &&
6264
6340
  this.lodRenderer?.isInLODMode === true &&
6265
6341
  isMotionHeavyScene &&
6266
6342
  isMotionFreezeEligible;
@@ -6287,7 +6363,7 @@ ${summaryLines.map(line => `<div>${escapeNodeFrameDebugHtml(line)}</div>`).join(
6287
6363
  this._wasViewStateMotionFrozenLastFrame = shouldFreezeFullResDuringMotion === true;
6288
6364
  const shouldThrottleVisibilityCullingDuringPan =
6289
6365
  isVisibilityCullingEnabled &&
6290
- this.isPanning === true &&
6366
+ isPanSmoothingActive &&
6291
6367
  this.isZooming !== true &&
6292
6368
  !shouldFreezeVisibilityDuringMotion &&
6293
6369
  !isNodeInteracting &&
@@ -6324,7 +6400,7 @@ ${summaryLines.map(line => `<div>${escapeNodeFrameDebugHtml(line)}</div>`).join(
6324
6400
  const shouldThrottleFullResVisibilityCullingDuringPan =
6325
6401
  isFullResMode === true &&
6326
6402
  isVisibilityCullingEnabled &&
6327
- this.isPanning === true &&
6403
+ isPanSmoothingActive &&
6328
6404
  this.isZooming !== true &&
6329
6405
  !shouldFreezeVisibilityDuringMotion &&
6330
6406
  !shouldFreezeFullResDuringMotion &&
@@ -6551,7 +6627,7 @@ ${summaryLines.map(line => `<div>${escapeNodeFrameDebugHtml(line)}</div>`).join(
6551
6627
  const isIncrementalPanVisibilityFrame =
6552
6628
  visibilityChangedThisFrame === true &&
6553
6629
  lastVisibilityProfile?.incrementalPanMode === true &&
6554
- this.isPanning === true &&
6630
+ isPanSmoothingActive &&
6555
6631
  this.isZooming !== true &&
6556
6632
  !isNodeInteracting &&
6557
6633
  !hasNonCameraNavigationForcedUpdate &&
@@ -2238,6 +2238,8 @@
2238
2238
  const hasContextSourcePins =
2239
2239
  wrapper.classList?.contains?.('has-context-source-pins') === true
2240
2240
  || wrapper.querySelector?.('.map-node-automation-context-source, .map-node-automation-worker-source') !== null;
2241
+ if (window.MindMapRenderPlan?.reuseCssMediaFrameDom?.(
2242
+ cssObject, worldWidth, worldHeight, hasContextSourcePins) === true) return;
2241
2243
 
2242
2244
  wrapper.style.width = `${scaledWidth}px`;
2243
2245
  wrapper.style.height = `${scaledHeight}px`;
@@ -2596,9 +2598,14 @@
2596
2598
  const wrapperFrame = toFrame(wrapperWidth / resolutionScale, wrapperHeight / resolutionScale);
2597
2599
  const innerFrame = toFrame(innerWidth, innerHeight);
2598
2600
  const liveFrame = wrapperFrame || innerFrame || userFrame;
2599
- const wrapperRect = typeof wrapper?.getBoundingClientRect === 'function' ? wrapper.getBoundingClientRect() : null;
2600
- const innerRect = typeof inner?.getBoundingClientRect === 'function' ? inner.getBoundingClientRect() : null;
2601
- const hasMeasuredLayout =
2601
+ if (options.preferModelDimensions === true) {
2602
+ return modelFrame || liveFrame || { width: 1, height: 1 };
2603
+ }
2604
+
2605
+ const canMeasureLayout = entry?.currentType === 'CSS' || cssObject?.visible === true;
2606
+ const wrapperRect = canMeasureLayout && typeof wrapper?.getBoundingClientRect === 'function' ? wrapper.getBoundingClientRect() : null;
2607
+ const innerRect = canMeasureLayout && typeof inner?.getBoundingClientRect === 'function' ? inner.getBoundingClientRect() : null;
2608
+ const hasMeasuredLayout = canMeasureLayout && (
2602
2609
  Number(wrapperRect?.width || 0) > 0
2603
2610
  || Number(wrapperRect?.height || 0) > 0
2604
2611
  || Number(innerRect?.width || 0) > 0
@@ -2606,17 +2613,13 @@
2606
2613
  || Number(wrapper?.offsetWidth || 0) > 0
2607
2614
  || Number(wrapper?.offsetHeight || 0) > 0
2608
2615
  || Number(inner?.offsetWidth || 0) > 0
2609
- || Number(inner?.offsetHeight || 0) > 0;
2616
+ || Number(inner?.offsetHeight || 0) > 0);
2610
2617
  const cssCurrentlyVisible =
2611
2618
  (entry?.currentType === 'CSS' || cssObject?.visible === true)
2612
2619
  && cssObject?.visible !== false
2613
2620
  && hasMeasuredLayout;
2614
2621
  const intrinsicAspectRatio = getCssMediaIntrinsicAspectRatio(nodeModel, cssObject);
2615
2622
 
2616
- if (options.preferModelDimensions === true) {
2617
- return modelFrame || liveFrame || { width: 1, height: 1 };
2618
- }
2619
-
2620
2623
  if (intrinsicAspectRatio > 0 && modelFrame && liveFrame) {
2621
2624
  const modelAspectError = getCssMediaFrameAspectError(modelFrame, intrinsicAspectRatio);
2622
2625
  const liveAspectError = getCssMediaFrameAspectError(liveFrame, intrinsicAspectRatio);
@@ -2666,7 +2669,10 @@
2666
2669
  if (!videoContent?.style) {
2667
2670
  return;
2668
2671
  }
2669
-
2672
+ if (_module?.renderDebugFlags?.tintVideoLayoutInNear !== true) {
2673
+ if (videoContent.dataset?.debugVideoLayout) clearCss3dVideoDebugLayout(cssObject);
2674
+ return;
2675
+ }
2670
2676
  const hostWidth = Math.max(1, Number(frameWidth || 0));
2671
2677
  const hostHeight = Math.max(1, Number(frameHeight || 0));
2672
2678
  const intrinsicSize = getCss3dVideoIntrinsicSize(nodeModel, cssObject?.element?.querySelector?.('video') || null);
@@ -2972,20 +2978,20 @@
2972
2978
  const hostWidth = Math.max(
2973
2979
  1,
2974
2980
  Math.round(Number(
2975
- state.videoContent.clientWidth
2976
- || cssObject?.userData?.worldWidth
2981
+ cssObject?.userData?.worldWidth
2977
2982
  || nodeModel?.width
2978
2983
  || nodeModel?.Width
2984
+ || state.videoContent.clientWidth
2979
2985
  || 0
2980
2986
  ))
2981
2987
  );
2982
2988
  const hostHeight = Math.max(
2983
2989
  1,
2984
2990
  Math.round(Number(
2985
- state.videoContent.clientHeight
2986
- || cssObject?.userData?.worldHeight
2991
+ cssObject?.userData?.worldHeight
2987
2992
  || nodeModel?.height
2988
2993
  || nodeModel?.Height
2994
+ || state.videoContent.clientHeight
2989
2995
  || 0
2990
2996
  ))
2991
2997
  );
@@ -24026,8 +24032,6 @@
24026
24032
  }
24027
24033
  }
24028
24034
 
24029
- // ▼▼▼ [Critical fix] Race condition: disable removal of the original Blazor template DOM ▼▼▼
24030
- // The original template is needed for markdown height measurement, so keep it in the DOM.
24031
24035
  // (It lives in a hidden div, so it is not visible.)
24032
24036
  /*
24033
24037
  const razorMapNode = document.querySelector(`#${templateId}`);
@@ -24070,8 +24074,6 @@
24070
24074
  });
24071
24075
  clonedElement.style.borderRadius = '0px';
24072
24076
 
24073
- // ▼▼▼ [Changed] Remove offset to match WebGL positioning (top-left origin) ▼▼▼
24074
- // CSS3DObject places the wrapper at the coordinate. If we add an extra 50% offset
24075
24077
  // to the inner element, the node shifts down-right.
24076
24078
  // Remove it so the element sits at the wrapper origin (0,0).
24077
24079
  clonedElement.style.position = 'absolute';
@@ -24102,8 +24104,6 @@
24102
24104
  wrapper.style.transition = CSS3D_WRAPPER_TRANSITION;
24103
24105
  wrapper.style.webkitTransition = CSS3D_WRAPPER_WEBKIT_TRANSITION;
24104
24106
 
24105
- // ▼▼▼ [Critical fix] Change wrapper origin from center (default) to top-left (0 0) ▼▼▼
24106
- // WebGL meshes use the top-left as (0,0,0), so align CSS3D elements accordingly.
24107
24107
  wrapper.style.transformOrigin = '0 0';
24108
24108
  // ▲▲▲ [Critical fix] ▲▲▲
24109
24109
 
@@ -4152,6 +4152,8 @@
4152
4152
  (now - Number(module?._lastMotionEndAt || 0)) < 120;
4153
4153
  return this.isInLODMode !== true && (
4154
4154
  module?.isPanning === true ||
4155
+ module?._cameraMovingThisFrame === true ||
4156
+ module?._panSmoothingActive === true ||
4155
4157
  module?.isZooming === true ||
4156
4158
  module?.isDraggingNode === true ||
4157
4159
  module?.isDraggingMultipleNodes === true ||
@@ -4803,6 +4805,11 @@
4803
4805
  return;
4804
4806
  }
4805
4807
  const cssParentScene = module?.cssScene || module?.scene;
4808
+ const shouldUseHighCss3dDetail = this._shouldUseHighCss3dDetail(entry, module);
4809
+ if (window.MindMapRenderPlan?.reuseStableVisibleCss?.(this, entry, module, nodeId, {
4810
+ isHighDetail: shouldUseHighCss3dDetail,
4811
+ allowResident: isLivePortalCssLodModel(model)
4812
+ }) === true) return;
4806
4813
 
4807
4814
  // Create if not exists
4808
4815
  if (!entry.cssObject) {
@@ -4843,7 +4850,6 @@
4843
4850
  }
4844
4851
  // ▲▲▲ [FIX] ▲▲▲
4845
4852
 
4846
- const shouldUseHighCss3dDetail = this._shouldUseHighCss3dDetail(entry, module);
4847
4853
  this._setCss3dLodClass(entry, shouldUseHighCss3dDetail);
4848
4854
 
4849
4855
  // ▼▼▼ [CRITICAL] Sync content BEFORE making CSS visible ▼▼▼
@@ -4894,15 +4900,6 @@
4894
4900
  }
4895
4901
  // ▲▲▲ [FIX] ▲▲▲
4896
4902
 
4897
- // CSS3D media nodes need one more sync after the DOM is actually visible.
4898
- // The video canvas proxy refuses to start on hidden CSS objects, so the
4899
- // pre-visibility sync above can otherwise leave the native <video> surface
4900
- // active in near mode and trigger browser compositor artifacts.
4901
- if (isMediaNode && window.MindMapCss3DManager?.syncCss3dMediaNodeFrame) {
4902
- window.MindMapCss3DManager.syncCss3dMediaNodeFrame(model, entry.cssObject, {
4903
- updateSpatialGrid: false
4904
- });
4905
- }
4906
4903
  if (getNodeContentType(model) === 'video' &&
4907
4904
  window.MindMapCss3DManager?.syncVideoNodeVisibilityPlayback) {
4908
4905
  window.MindMapCss3DManager.syncVideoNodeVisibilityPlayback(model, entry.cssObject, true);
@@ -4978,6 +4975,9 @@
4978
4975
  const shouldForceMediaGlFallback =
4979
4976
  (contentType === 'video' || contentType === 'embed') &&
4980
4977
  (options?.forceMediaGlFallback === true || !isCss3dRendererEnabled(this._module));
4978
+ const cssElement = entry?.cssObject?.element || null;
4979
+ let cssVisualChanged = entry?.currentType === 'CSS' || entry?.cssObject?.visible === true ||
4980
+ (!!entry?.cssObject?.parent && cssElement?.style?.display !== 'none');
4981
4981
  if (contentType === 'image' && entry?.model) {
4982
4982
  entry.model._showImageBodyInCssMode = false;
4983
4983
  this._resetFullResImageBridgeState(entry);
@@ -5020,11 +5020,11 @@
5020
5020
  }
5021
5021
  this._setGlowVisibility(entry, false);
5022
5022
  if (nodeId) {
5023
- this._nearCssVisibleIds.delete(nodeId);
5024
- this._lodImageCssFallbackNodeIds.delete(nodeId);
5025
- this._lodTemplateCssNodeIds.delete(nodeId);
5023
+ cssVisualChanged = this._nearCssVisibleIds.delete(nodeId) || cssVisualChanged;
5024
+ cssVisualChanged = this._lodImageCssFallbackNodeIds.delete(nodeId) || cssVisualChanged;
5025
+ cssVisualChanged = this._lodTemplateCssNodeIds.delete(nodeId) || cssVisualChanged;
5026
5026
  }
5027
- if (this._module) {
5027
+ if (this._module && cssVisualChanged) {
5028
5028
  this._module._css3dVisualChangedThisFrame = true;
5029
5029
  this._module._css3dVisualChangedSinceLastRender = true;
5030
5030
  }
@@ -5336,7 +5336,6 @@
5336
5336
 
5337
5337
  if (uniform.value.getHex && uniform.value.getHex() === hex) return;
5338
5338
  uniform.value.setHex(hex);
5339
- mat.needsUpdate = true;
5340
5339
  }
5341
5340
 
5342
5341
  _setInstancedDefaultBorderColor(hex) {
@@ -5350,11 +5349,9 @@
5350
5349
 
5351
5350
  if (uniform && uniform.value) {
5352
5351
  uniform.value.setHex(hex);
5353
- mat.needsUpdate = true;
5354
5352
  }
5355
5353
  if (lineMaterial?.color) {
5356
5354
  lineMaterial.color.setHex(hex);
5357
- lineMaterial.needsUpdate = true;
5358
5355
  }
5359
5356
  }
5360
5357
 
@@ -5366,7 +5363,6 @@
5366
5363
  const nextValue = visible ? 1.0 : 0.0;
5367
5364
  if (uniform.value === nextValue) return;
5368
5365
  uniform.value = nextValue;
5369
- mat.needsUpdate = true;
5370
5366
  }
5371
5367
 
5372
5368
  _setInstancedFarInsetBorderVisibility(visible) {
@@ -5380,21 +5376,14 @@
5380
5376
  const nextValue = visible ? 1.0 : 0.0;
5381
5377
  const nextOpacity = visible ? LOD_NODE_BORDER_OPACITY_FAR : LOD_NODE_BORDER_OPACITY_MID;
5382
5378
  const nextLineOpacity = visible ? LOD_TEXT_LINE_OPACITY_FAR : LOD_TEXT_LINE_OPACITY_MID;
5383
- let changed = false;
5384
5379
  if (uniform && uniform.value !== nextValue) {
5385
5380
  uniform.value = nextValue;
5386
- changed = true;
5387
5381
  }
5388
5382
  if (opacityUniform && opacityUniform.value !== nextOpacity) {
5389
5383
  opacityUniform.value = nextOpacity;
5390
- changed = true;
5391
- }
5392
- if (changed) {
5393
- mat.needsUpdate = true;
5394
5384
  }
5395
5385
  if (lineOpacityUniform && lineOpacityUniform.value !== nextLineOpacity) {
5396
5386
  lineOpacityUniform.value = nextLineOpacity;
5397
- lineMaterial.needsUpdate = true;
5398
5387
  }
5399
5388
  }
5400
5389
 
@@ -7036,6 +7025,8 @@
7036
7025
 
7037
7026
  _isResidentLodInteractionActive(module = this._module) {
7038
7027
  return module?.isPanning === true ||
7028
+ module?._cameraMovingThisFrame === true ||
7029
+ module?._panSmoothingActive === true ||
7039
7030
  module?.isZooming === true ||
7040
7031
  module?.isDraggingNode === true ||
7041
7032
  module?.isDraggingMultipleNodes === true ||
@@ -726,7 +726,7 @@
726
726
  viewportH: viewportHeight
727
727
  },
728
728
  state: {
729
- isPanning: activeModule.isPanning === true,
729
+ isPanning: activeModule.isPanning === true || activeModule._panSmoothingActive === true,
730
730
  isZooming: activeModule.isZooming === true,
731
731
  isWindowResizing: activeModule.isWindowResizing === true,
732
732
  isResizing: activeModule.isResizing === true,
@@ -1,7 +1,7 @@
1
1
  (function () {
2
2
  'use strict';
3
3
 
4
- const BUILD_ID = '20260712-boundary-transition-cache-v37';
4
+ const BUILD_ID = '20260712-boundary-transition-cache-v38';
5
5
  const FRAME_SAMPLE_LIMIT = 240;
6
6
  const INITIAL_LINE_TEXTURE_ROWS = 1024;
7
7
  const GPU_WARM_RETRY_DELAY_MS = 120;
@@ -9,6 +9,9 @@
9
9
  const frameSampleStates = new WeakMap();
10
10
  const residentLinePrewarmStates = new WeakMap();
11
11
  const residentTransitionStates = new WeakMap();
12
+ const cssMediaFrameDomStates = new WeakMap();
13
+ let cssMediaFrameDomReuseCount = 0;
14
+ let cssMediaFrameDomApplyCount = 0;
12
15
  const RESIDENT_CSS_CACHE_TEXT_TYPES = new Set(['text', 'note', 'memo', 'markdown', 'code', 'csv-table']);
13
16
  const VIEW_SYNC_SECTION_KEYS = [
14
17
  'fullResSetup', 'fullResImages', 'fullResCssQueue', 'fullResHandoff', 'fullResOther',
@@ -284,6 +287,95 @@
284
287
  return batch;
285
288
  }
286
289
 
290
+ function reuseCssMediaFrameDom(cssObject, width, height, hasContextSourcePins = false) {
291
+ const wrapper = cssObject?.element || null;
292
+ const isMedia = wrapper?.classList?.contains?.('node-type-image') === true ||
293
+ wrapper?.classList?.contains?.('node-type-video') === true ||
294
+ wrapper?.classList?.contains?.('node-type-embed') === true;
295
+ if (!isMedia || !wrapper?.style) return false;
296
+
297
+ const inner = wrapper.firstElementChild || null;
298
+ const content = inner?.querySelector?.('.node-content-wrapper') || null;
299
+ const response = inner?.querySelector?.('.node-response') || null;
300
+ const surface = inner?.querySelector?.('img,video,canvas.mind-map-video-proxy,iframe,.embed-card,.embed-iframe-shell') || null;
301
+ const resolutionScale = Math.max(1, Number(cssObject?.userData?.resolutionScale || 1));
302
+ const worldWidth = Math.max(1, Math.round(Number(width || 1)));
303
+ const worldHeight = Math.max(1, Math.round(Number(height || 1)));
304
+ const scaledWidth = worldWidth * resolutionScale;
305
+ const scaledHeight = worldHeight * resolutionScale;
306
+ const state = cssMediaFrameDomStates.get(cssObject) || null;
307
+ const structureMatches = !!state && state.wrapper === wrapper && state.inner === inner &&
308
+ state.content === content && state.response === response && state.surface === surface &&
309
+ state.innerChildren === Number(inner?.childElementCount ?? inner?.children?.length ?? 0) &&
310
+ state.contentChildren === Number(content?.childElementCount ?? content?.children?.length ?? 0);
311
+ const frameMatches = structureMatches && state.width === worldWidth && state.height === worldHeight &&
312
+ state.resolutionScale === resolutionScale && state.hasContextSourcePins === (hasContextSourcePins === true);
313
+ const frameStylesReady = wrapper.style.width === `${scaledWidth}px` && wrapper.style.height === `${scaledHeight}px` &&
314
+ (!inner?.style || (inner.style.width === `${worldWidth}px` && inner.style.height === `${worldHeight}px`));
315
+
316
+ if (frameMatches && frameStylesReady) {
317
+ cssMediaFrameDomReuseCount++;
318
+ return true;
319
+ }
320
+
321
+ cssMediaFrameDomStates.set(cssObject, {
322
+ wrapper,
323
+ inner,
324
+ content,
325
+ response,
326
+ surface,
327
+ innerChildren: Number(inner?.childElementCount ?? inner?.children?.length ?? 0),
328
+ contentChildren: Number(content?.childElementCount ?? content?.children?.length ?? 0),
329
+ width: worldWidth,
330
+ height: worldHeight,
331
+ resolutionScale,
332
+ hasContextSourcePins: hasContextSourcePins === true
333
+ });
334
+ cssMediaFrameDomApplyCount++;
335
+ return false;
336
+ }
337
+
338
+ function reuseStableVisibleCss(renderer, entry, module, nodeIdValue, options = {}) {
339
+ const cssObject = entry?.cssObject || null;
340
+ const element = cssObject?.element || null;
341
+ const nodeId = String(nodeIdValue || entry?.model?.id || entry?.model?.Id || entry?.glObject?.userData?.nodeId || '').trim();
342
+ const cssScene = module?.cssScene || module?.scene || null;
343
+ const allowResident = options.allowResident === true;
344
+ if (!nodeId || !element || entry?.isCssDirty === true || entry?.currentType !== 'CSS' ||
345
+ cssObject.visible !== true || cssObject.userData?._residentTransitionPrepared === true ||
346
+ (!allowResident && renderer?.isInLODMode === true) || (cssScene && cssObject.parent !== cssScene) ||
347
+ element.style?.display === 'none' || element.style?.visibility === 'hidden' || element.style?.opacity === '0' ||
348
+ module?._cssParentRepairNeeded === true || module?._cssTransformDirtyIds?.has?.(nodeId) === true) return false;
349
+
350
+ const selectedNodeId = String(module?.selectedNodeIdJs || module?.selectedNodeId || '').trim();
351
+ const editingNodeId = String(module?._textOverlayV2State?.editing?.nodeId || module?._editingOverlayState?.nodeId || '').trim();
352
+ if (selectedNodeId === nodeId || module?.multiSelectedNodeIds?.has?.(nodeId) === true ||
353
+ module?.draggedNodeId === nodeId || editingNodeId === nodeId ||
354
+ renderer?._getCurrentHoveredNodeId?.(module) === nodeId) return false;
355
+
356
+ const inner = element.querySelector?.('.node-container') || null;
357
+ const targets = inner && inner !== element ? [element, inner] : [element];
358
+ const isHigh = options.isHighDetail === true;
359
+ for (const target of targets) {
360
+ if (!target?.classList || target.classList.contains(isHigh ? 'lod-high' : 'lod-low') !== true ||
361
+ target.classList.contains(isHigh ? 'lod-low' : 'lod-high') === true) return false;
362
+ }
363
+ if (isHigh && (element.matches?.('[data-text-overlay-source-suspended],.mind-map-text-overlay-source-suspended,.mind-map-v2-source-suspended') === true ||
364
+ element.querySelector?.('[data-text-overlay-source-suspended],.mind-map-text-overlay-source-suspended,.mind-map-v2-source-suspended'))) return false;
365
+
366
+ const contentType = String(entry?.model?.contentType ?? entry?.model?.ContentType ?? '').trim().toLowerCase();
367
+ if (contentType === 'image' || contentType === 'video') {
368
+ const media = element.querySelector?.('img,video') || null;
369
+ const source = media?.getAttribute?.('src') || media?.currentSrc || media?.src || '';
370
+ if (!media || !source) return false;
371
+ } else if (contentType === 'embed' &&
372
+ !element.querySelector?.('.embed-card,.embed-frame,.embed-iframe-shell')) return false;
373
+
374
+ renderer?._nearCssVisibleIds?.add?.(nodeId);
375
+ if (renderer) renderer._fullResCssStableReuseCount = Number(renderer._fullResCssStableReuseCount || 0) + 1;
376
+ return true;
377
+ }
378
+
287
379
  function reuseActiveCssMediaFallback(renderer, entry, module) {
288
380
  const cssObject = entry?.cssObject || null;
289
381
  const element = cssObject?.element || null;
@@ -1323,6 +1415,9 @@
1323
1415
  visibilityP95Ms: percentile(state, 'visibilityMs', 0.95),
1324
1416
  viewSyncP95Ms: percentile(state, 'viewSyncMs', 0.95),
1325
1417
  css3dRenderP95Ms: percentile(state, 'css3dRenderMs', 0.95),
1418
+ fullResCssStableReuseCount: Number(renderer?._fullResCssStableReuseCount || 0),
1419
+ cssMediaFrameDomReuseCount,
1420
+ cssMediaFrameDomApplyCount,
1326
1421
  residentLinePrewarmCount: Number(renderer?._residentLinePrewarmCount || 0),
1327
1422
  residentLineBufferPrewarmCount: Number(renderer?._residentLineBufferPrewarmCount || 0),
1328
1423
  residentIdleBuildCount: Number(renderer?._residentIdleBuildCount || 0),
@@ -1368,6 +1463,9 @@
1368
1463
  frameSampleStates.delete(renderer);
1369
1464
  renderer._fullResStablePlanSkipCount = 0;
1370
1465
  renderer._lastFullResStablePlanSkipped = false;
1466
+ renderer._fullResCssStableReuseCount = 0;
1467
+ cssMediaFrameDomReuseCount = 0;
1468
+ cssMediaFrameDomApplyCount = 0;
1371
1469
  }
1372
1470
 
1373
1471
  window.MindMapRenderPlan = Object.freeze({
@@ -1387,6 +1485,8 @@
1387
1485
  renderResidentWarmScene,
1388
1486
  prepareImageAtlasCapacity,
1389
1487
  fallbackBatch,
1488
+ reuseCssMediaFrameDom,
1489
+ reuseStableVisibleCss,
1390
1490
  reuseActiveCssMediaFallback,
1391
1491
  hasAnimatedGifCssFallbackCandidates,
1392
1492
  hasResidentDirtyWork,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "mainAssemblyName": "MindExecution.Web",
3
3
  "resources": {
4
- "hash": "sha256-vI5xHgVEIfozQqYzVjlqe6BhywMU49Aum6z6LqwLXdw=",
4
+ "hash": "sha256-A1OJeSdC0err06G8T2jbUHqkQDe7emn8bFuOwoj3t08=",
5
5
  "fingerprinting": {
6
6
  "Google.Protobuf.9h59ukbel7.dll": "Google.Protobuf.dll",
7
7
  "Markdig.d1j7v41cl1.dll": "Markdig.dll",
@@ -126,12 +126,12 @@
126
126
  "MindExecution.Kernel.75hxk08tt0.dll": "MindExecution.Kernel.dll",
127
127
  "MindExecution.Plugins.Admin.0zkmk8wahq.dll": "MindExecution.Plugins.Admin.dll",
128
128
  "MindExecution.Plugins.Business.vyw3769hrw.dll": "MindExecution.Plugins.Business.dll",
129
- "MindExecution.Plugins.Concept.gmo0tv41kt.dll": "MindExecution.Plugins.Concept.dll",
129
+ "MindExecution.Plugins.Concept.7uhld08zkc.dll": "MindExecution.Plugins.Concept.dll",
130
130
  "MindExecution.Plugins.Directory.jtw9q1dm9n.dll": "MindExecution.Plugins.Directory.dll",
131
- "MindExecution.Plugins.PlanMaster.ts9iffoyt9.dll": "MindExecution.Plugins.PlanMaster.dll",
132
- "MindExecution.Plugins.YouTube.m4ag6l6urx.dll": "MindExecution.Plugins.YouTube.dll",
133
- "MindExecution.Shared.u07hdbavl1.dll": "MindExecution.Shared.dll",
134
- "MindExecution.Web.m9h5r0uvry.dll": "MindExecution.Web.dll",
131
+ "MindExecution.Plugins.PlanMaster.y1sj1ifw0z.dll": "MindExecution.Plugins.PlanMaster.dll",
132
+ "MindExecution.Plugins.YouTube.ij0uk05x1o.dll": "MindExecution.Plugins.YouTube.dll",
133
+ "MindExecution.Shared.1h72etbxec.dll": "MindExecution.Shared.dll",
134
+ "MindExecution.Web.18xe2efznc.dll": "MindExecution.Web.dll",
135
135
  "dotnet.native.566r55w3xu.js": "dotnet.native.js",
136
136
  "dotnet.native.x6q5aixc38.wasm": "dotnet.native.wasm",
137
137
  "dotnet.js": "dotnet.js",
@@ -279,15 +279,15 @@
279
279
  "MindExecution.Core.808jj176e1.dll": "sha256-uMmP6rEgsbuwnsZ6Cnxrpmzio4usBtoJERfkOvz25iY=",
280
280
  "MindExecution.Kernel.75hxk08tt0.dll": "sha256-9db04cSFp4z4iblswVb0UWgpjeluVqZUa7g27Oj3p40=",
281
281
  "MindExecution.Plugins.Business.vyw3769hrw.dll": "sha256-WSc1w7WNOhnmzD3DcIgg4PCYzHeeU5rc7KK7eLgsu+M=",
282
- "MindExecution.Plugins.Concept.gmo0tv41kt.dll": "sha256-qBXUF9WweoI0L8luwIA4Y9tkNvvyfftGeZiaXQOaBK4=",
283
- "MindExecution.Plugins.PlanMaster.ts9iffoyt9.dll": "sha256-4/JDS1wN3+2JYM4cX21FZkbfzyuTB7WsnR+gy0E2/aw=",
284
- "MindExecution.Shared.u07hdbavl1.dll": "sha256-ztbH6CE39o0VvcB+c+X98XXU9FHq82JJDeRrHzvTghs=",
285
- "MindExecution.Web.m9h5r0uvry.dll": "sha256-Vn53TxOtXF7QbcK6wIkTAZqZj5YxnIrQsC73i7TJkyQ="
282
+ "MindExecution.Plugins.Concept.7uhld08zkc.dll": "sha256-cUU0G3dB5DWTJNWZOm9H11vbZAYmN/V+IrFMt9vlBIk=",
283
+ "MindExecution.Plugins.PlanMaster.y1sj1ifw0z.dll": "sha256-xi09lt0NHokoI+n3J5fhJbUl67m/1L130G1zeUGBXEk=",
284
+ "MindExecution.Shared.1h72etbxec.dll": "sha256-VeRGhlstb2Mj+LaayW5MnfvrVz9wwtNbPnyUr60G+UM=",
285
+ "MindExecution.Web.18xe2efznc.dll": "sha256-T3bBjSn7Uc2X45eMbh/5L7RKDkSKcKbxB6gAzKbVXJE="
286
286
  },
287
287
  "lazyAssembly": {
288
288
  "MindExecution.Plugins.Admin.0zkmk8wahq.dll": "sha256-VLiwzLIr+tjKr6+yQfhMVQHq2Yx26QenAkC092+fEdw=",
289
289
  "MindExecution.Plugins.Directory.jtw9q1dm9n.dll": "sha256-Z1x+H7sTj3w9XjWxfqGsd3Jv+qlzwQxAur6pJIP4l20=",
290
- "MindExecution.Plugins.YouTube.m4ag6l6urx.dll": "sha256-uk7G3IbzHVe7WPbDEUTEA5jyyE+/cWWrMYZ2IBRPQB4="
290
+ "MindExecution.Plugins.YouTube.ij0uk05x1o.dll": "sha256-PoKIu/xjyXhnHtDJoQjpwhYVQygI4ViEkCbfM6hy/Nk="
291
291
  }
292
292
  },
293
293
  "cacheBootResources": true,
@@ -579,7 +579,7 @@
579
579
  }
580
580
 
581
581
  const base = '_content/MindExecution.Shared/js/';
582
- const scriptVersion = '20260712-boundary-transition-cache-v923';
582
+ const scriptVersion = '20260712-pan-smoothing-v926';
583
583
  const scriptUrl = (script) => `${base}${script}?v=${scriptVersion}`;
584
584
  console.log(`[Script Loader] Shared JS version: ${scriptVersion}`);
585
585
  const criticalScripts = [
@@ -1,5 +1,5 @@
1
1
  self.assetsManifest = {
2
- "version": "MRR9dM9W",
2
+ "version": "6c1WQjRz",
3
3
  "assets": [
4
4
  {
5
5
  "hash": "sha256-+CSYMcqLNTsq3VnH11jgYyOCCdxvHzL74CBmo4sCmMU=",
@@ -78,7 +78,7 @@
78
78
  "url": "_content/MindExecution.Shared/js/marked.min.js"
79
79
  },
80
80
  {
81
- "hash": "sha256-VtCWP9VR+lpe3PbV1E2voY0wiwg+YYP3M77qU8JJwTM=",
81
+ "hash": "sha256-DBjG7fXZAAblaqAtuyJcqQeX7OBMP6n+9KWSmTXr8tA=",
82
82
  "url": "_content/MindExecution.Shared/js/mind-map-core.js"
83
83
  },
84
84
  {
@@ -86,7 +86,7 @@
86
86
  "url": "_content/MindExecution.Shared/js/mind-map-core.js.backup"
87
87
  },
88
88
  {
89
- "hash": "sha256-LfMMR/7oC/A5wNUsJSdpAAHUBPSOBbI+bEVriVfbWGQ=",
89
+ "hash": "sha256-lQz/ypxVlzVl+8tIKCNG6goy086bDvnI+R/VV4OEfdE=",
90
90
  "url": "_content/MindExecution.Shared/js/mind-map-css3d-manager.js"
91
91
  },
92
92
  {
@@ -114,11 +114,11 @@
114
114
  "url": "_content/MindExecution.Shared/js/mind-map-lod-plan-worker.js"
115
115
  },
116
116
  {
117
- "hash": "sha256-IwXEhkurFaTiITycukVzAgPcA8Vk5G5dpTr+jIQKi2E=",
117
+ "hash": "sha256-lGkrhT2O7MSfdBU0XZGkVtvvOhcr27zlOhTkhUZ3oPo=",
118
118
  "url": "_content/MindExecution.Shared/js/mind-map-lod-renderer.js"
119
119
  },
120
120
  {
121
- "hash": "sha256-cOAX+ZZ70JU+eU1RVGVgVFBCJq40NZ/qZ0zbQl9wTzM=",
121
+ "hash": "sha256-KfVS6Milo4kpU7VFahI25MaUZ3sxGBj+0OdaKruxTWY=",
122
122
  "url": "_content/MindExecution.Shared/js/mind-map-logic-workers.js"
123
123
  },
124
124
  {
@@ -150,7 +150,7 @@
150
150
  "url": "_content/MindExecution.Shared/js/mind-map-pipeline.js"
151
151
  },
152
152
  {
153
- "hash": "sha256-RjC8fUKPNF/NdW6W8x9/8yqUaEOfJbMYtr2ciSl4XHQ=",
153
+ "hash": "sha256-apvwkVi4x7Zhjy7Nu4LrpqZ5ThSXyk2ZQCDz8TJyUnY=",
154
154
  "url": "_content/MindExecution.Shared/js/mind-map-render-plan.js"
155
155
  },
156
156
  {
@@ -426,28 +426,28 @@
426
426
  "url": "_framework/MindExecution.Plugins.Business.vyw3769hrw.dll"
427
427
  },
428
428
  {
429
- "hash": "sha256-qBXUF9WweoI0L8luwIA4Y9tkNvvyfftGeZiaXQOaBK4=",
430
- "url": "_framework/MindExecution.Plugins.Concept.gmo0tv41kt.dll"
429
+ "hash": "sha256-cUU0G3dB5DWTJNWZOm9H11vbZAYmN/V+IrFMt9vlBIk=",
430
+ "url": "_framework/MindExecution.Plugins.Concept.7uhld08zkc.dll"
431
431
  },
432
432
  {
433
433
  "hash": "sha256-Z1x+H7sTj3w9XjWxfqGsd3Jv+qlzwQxAur6pJIP4l20=",
434
434
  "url": "_framework/MindExecution.Plugins.Directory.jtw9q1dm9n.dll"
435
435
  },
436
436
  {
437
- "hash": "sha256-4/JDS1wN3+2JYM4cX21FZkbfzyuTB7WsnR+gy0E2/aw=",
438
- "url": "_framework/MindExecution.Plugins.PlanMaster.ts9iffoyt9.dll"
437
+ "hash": "sha256-xi09lt0NHokoI+n3J5fhJbUl67m/1L130G1zeUGBXEk=",
438
+ "url": "_framework/MindExecution.Plugins.PlanMaster.y1sj1ifw0z.dll"
439
439
  },
440
440
  {
441
- "hash": "sha256-uk7G3IbzHVe7WPbDEUTEA5jyyE+/cWWrMYZ2IBRPQB4=",
442
- "url": "_framework/MindExecution.Plugins.YouTube.m4ag6l6urx.dll"
441
+ "hash": "sha256-PoKIu/xjyXhnHtDJoQjpwhYVQygI4ViEkCbfM6hy/Nk=",
442
+ "url": "_framework/MindExecution.Plugins.YouTube.ij0uk05x1o.dll"
443
443
  },
444
444
  {
445
- "hash": "sha256-ztbH6CE39o0VvcB+c+X98XXU9FHq82JJDeRrHzvTghs=",
446
- "url": "_framework/MindExecution.Shared.u07hdbavl1.dll"
445
+ "hash": "sha256-VeRGhlstb2Mj+LaayW5MnfvrVz9wwtNbPnyUr60G+UM=",
446
+ "url": "_framework/MindExecution.Shared.1h72etbxec.dll"
447
447
  },
448
448
  {
449
- "hash": "sha256-Vn53TxOtXF7QbcK6wIkTAZqZj5YxnIrQsC73i7TJkyQ=",
450
- "url": "_framework/MindExecution.Web.m9h5r0uvry.dll"
449
+ "hash": "sha256-T3bBjSn7Uc2X45eMbh/5L7RKDkSKcKbxB6gAzKbVXJE=",
450
+ "url": "_framework/MindExecution.Web.18xe2efznc.dll"
451
451
  },
452
452
  {
453
453
  "hash": "sha256-IsZJ91/OW+fHzNqIgEc7Y072ns8z9dGritiSyvR9Wgc=",
@@ -766,7 +766,7 @@
766
766
  "url": "_framework/Websocket.Client.vapounvmnl.dll"
767
767
  },
768
768
  {
769
- "hash": "sha256-MD0kvjpf75Vf42k550ThUA2aJndMKVFGP2iftaPrl2E=",
769
+ "hash": "sha256-BQeM7uox0PW+Qf3cMKSzu+YUaxrxFojAXZ8+e+ZLR6k=",
770
770
  "url": "_framework/blazor.boot.json"
771
771
  },
772
772
  {
@@ -826,7 +826,7 @@
826
826
  "url": "icon-512.png"
827
827
  },
828
828
  {
829
- "hash": "sha256-r3GcUrMmL938c4fztCOgu1rT3vgXovbh/fBJZBvrsms=",
829
+ "hash": "sha256-DHFD2bw+0sIZ77FHp9yqyo5GQ1MJwl+JGgmP0XXZIv0=",
830
830
  "url": "index.html"
831
831
  },
832
832
  {
@@ -1,4 +1,4 @@
1
- /* Manifest version: MRR9dM9W */
1
+ /* Manifest version: 6c1WQjRz */
2
2
  // Hosted deployments should prefer the network over stale offline caches.
3
3
  // This service worker immediately clears old Blazor offline caches and unregisters itself.
4
4