@canvas-harness/core 0.1.4 → 0.1.5
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/dist/index.cjs +172 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +172 -31
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -4886,7 +4886,7 @@ var drawWithNodeTransform = (ctx, node, fn) => {
|
|
|
4886
4886
|
};
|
|
4887
4887
|
|
|
4888
4888
|
// src/render/renderer.ts
|
|
4889
|
-
var
|
|
4889
|
+
var SCENE_CACHE_MARGIN_PX = 256;
|
|
4890
4890
|
var MIN_ON_SCREEN_SIZE_PX = 1.5;
|
|
4891
4891
|
var MIN_READABLE_FONT_PX = 3;
|
|
4892
4892
|
var createRenderer = (opts) => {
|
|
@@ -4903,6 +4903,30 @@ var createRenderer = (opts) => {
|
|
|
4903
4903
|
let interactiveDirty = false;
|
|
4904
4904
|
let overlaySet = /* @__PURE__ */ new Set();
|
|
4905
4905
|
let lastDrawn = 0;
|
|
4906
|
+
let cacheSurface = null;
|
|
4907
|
+
let cacheCamX = 0;
|
|
4908
|
+
let cacheCamY = 0;
|
|
4909
|
+
let cacheCamZ = 1;
|
|
4910
|
+
let cacheStale = true;
|
|
4911
|
+
const ensureCacheSurface = () => {
|
|
4912
|
+
const dpr = staticSurface.dpr;
|
|
4913
|
+
const cssW = staticSurface.cssWidth + 2 * SCENE_CACHE_MARGIN_PX;
|
|
4914
|
+
const cssH = staticSurface.cssHeight + 2 * SCENE_CACHE_MARGIN_PX;
|
|
4915
|
+
if (!cacheSurface) {
|
|
4916
|
+
const canvas = document.createElement("canvas");
|
|
4917
|
+
const ctx = canvas.getContext("2d");
|
|
4918
|
+
if (!ctx) throw new Error("Canvas 2d context unavailable");
|
|
4919
|
+
cacheSurface = { canvas, ctx, cssWidth: 0, cssHeight: 0, dpr: 1 };
|
|
4920
|
+
}
|
|
4921
|
+
if (cacheSurface.cssWidth !== cssW || cacheSurface.cssHeight !== cssH || cacheSurface.dpr !== dpr) {
|
|
4922
|
+
cacheSurface.cssWidth = cssW;
|
|
4923
|
+
cacheSurface.cssHeight = cssH;
|
|
4924
|
+
cacheSurface.dpr = dpr;
|
|
4925
|
+
cacheSurface.canvas.width = Math.max(1, Math.round(cssW * dpr));
|
|
4926
|
+
cacheSurface.canvas.height = Math.max(1, Math.round(cssH * dpr));
|
|
4927
|
+
}
|
|
4928
|
+
return cacheSurface;
|
|
4929
|
+
};
|
|
4906
4930
|
let sortedNodeIdsCache = null;
|
|
4907
4931
|
let sortedEdgeIdsCache = null;
|
|
4908
4932
|
const invalidateSortedCaches = () => {
|
|
@@ -4911,6 +4935,7 @@ var createRenderer = (opts) => {
|
|
|
4911
4935
|
};
|
|
4912
4936
|
const requestRepaint = () => {
|
|
4913
4937
|
staticDirty = true;
|
|
4938
|
+
cacheStale = true;
|
|
4914
4939
|
loop.requestFrame();
|
|
4915
4940
|
};
|
|
4916
4941
|
const assetCache = createAssetCache({ onReady: requestRepaint });
|
|
@@ -4925,16 +4950,12 @@ var createRenderer = (opts) => {
|
|
|
4925
4950
|
interactiveDirty = false;
|
|
4926
4951
|
}
|
|
4927
4952
|
};
|
|
4928
|
-
const
|
|
4929
|
-
const
|
|
4930
|
-
clearSurface(staticSurface);
|
|
4931
|
-
applyCameraTransform(staticSurface, camera);
|
|
4932
|
-
const scale = camera.z * staticSurface.dpr;
|
|
4953
|
+
const paintSceneBody = (surface, camera, viewport, fullRender = true) => {
|
|
4954
|
+
const scale = camera.z * surface.dpr;
|
|
4933
4955
|
const interaction = store.getInteractionState();
|
|
4934
4956
|
const excludedNodes = interaction.mode === "dragging" || interaction.mode === "resizing" ? new Set(interaction.draggedIds) : null;
|
|
4935
4957
|
const excludedEdges = excludedNodes ? incidentEdgeIds(excludedNodes) : null;
|
|
4936
|
-
|
|
4937
|
-
paintBackground(staticSurface.ctx, { viewport, zoom: camera.z, background });
|
|
4958
|
+
paintBackground(surface.ctx, { viewport, zoom: camera.z, background });
|
|
4938
4959
|
const visible = visibleNodes(camera, viewport);
|
|
4939
4960
|
const isMoving2 = interaction.mode === "panning" || interaction.mode === "zooming" || interaction.mode === "dragging" || interaction.mode === "resizing" || interaction.mode === "rotating";
|
|
4940
4961
|
const minOnScreen = MIN_ON_SCREEN_SIZE_PX;
|
|
@@ -4956,8 +4977,8 @@ var createRenderer = (opts) => {
|
|
|
4956
4977
|
for (const node of visible) {
|
|
4957
4978
|
if (node.type !== "frame") continue;
|
|
4958
4979
|
if (excludedNodes?.has(node.id)) continue;
|
|
4959
|
-
drawWithNodeTransform(
|
|
4960
|
-
paintFrameNode(
|
|
4980
|
+
drawWithNodeTransform(surface.ctx, node, () => {
|
|
4981
|
+
paintFrameNode(surface.ctx, node, scale, theme);
|
|
4961
4982
|
});
|
|
4962
4983
|
drawn++;
|
|
4963
4984
|
}
|
|
@@ -4970,52 +4991,53 @@ var createRenderer = (opts) => {
|
|
|
4970
4991
|
const useRough = roughEnabled && (node.style?.roughness ?? 0) > 0;
|
|
4971
4992
|
const roughReady = useRough ? getRoughCanvasCtor() !== null : false;
|
|
4972
4993
|
const composite = isCompositePrimitive(node.type);
|
|
4973
|
-
drawWithNodeTransform(
|
|
4994
|
+
drawWithNodeTransform(surface.ctx, node, () => {
|
|
4974
4995
|
if (useRough && roughReady) {
|
|
4975
4996
|
if (composite) {
|
|
4976
|
-
drawCompositeRough(
|
|
4997
|
+
drawCompositeRough(surface.ctx, node, camera.z, theme);
|
|
4977
4998
|
} else {
|
|
4978
|
-
|
|
4979
|
-
drawShape(
|
|
4980
|
-
|
|
4981
|
-
drawRoughShape(
|
|
4999
|
+
surface.ctx.translate(ROUGH_FILL_MISREGISTER_X, ROUGH_FILL_MISREGISTER_Y);
|
|
5000
|
+
drawShape(surface.ctx, node, scale, theme, { skipStroke: true });
|
|
5001
|
+
surface.ctx.translate(-ROUGH_FILL_MISREGISTER_X, -ROUGH_FILL_MISREGISTER_Y);
|
|
5002
|
+
drawRoughShape(surface.ctx, node, camera.z, theme);
|
|
4982
5003
|
}
|
|
4983
5004
|
} else {
|
|
4984
|
-
drawShape(
|
|
5005
|
+
drawShape(surface.ctx, node, scale, theme);
|
|
4985
5006
|
if (useRough && !roughReady) {
|
|
4986
5007
|
onRoughReady(() => {
|
|
4987
5008
|
staticDirty = true;
|
|
5009
|
+
cacheStale = true;
|
|
4988
5010
|
loop.requestFrame();
|
|
4989
5011
|
});
|
|
4990
5012
|
}
|
|
4991
5013
|
}
|
|
4992
|
-
if (!isEditingThis) paintNodeContent(
|
|
5014
|
+
if (!isEditingThis) paintNodeContent(surface.ctx, node, renderEnv);
|
|
4993
5015
|
});
|
|
4994
5016
|
drawn++;
|
|
4995
5017
|
continue;
|
|
4996
5018
|
}
|
|
4997
5019
|
if (node.type === "image") {
|
|
4998
|
-
drawWithNodeTransform(
|
|
4999
|
-
paintImageNode(
|
|
5020
|
+
drawWithNodeTransform(surface.ctx, node, () => {
|
|
5021
|
+
paintImageNode(surface.ctx, node, assetCache, theme);
|
|
5000
5022
|
});
|
|
5001
5023
|
drawn++;
|
|
5002
5024
|
continue;
|
|
5003
5025
|
}
|
|
5004
5026
|
if (node.type === "icon") {
|
|
5005
|
-
drawWithNodeTransform(
|
|
5006
|
-
paintIconNode(
|
|
5027
|
+
drawWithNodeTransform(surface.ctx, node, () => {
|
|
5028
|
+
paintIconNode(surface.ctx, node, assetCache, scale, theme);
|
|
5007
5029
|
});
|
|
5008
5030
|
drawn++;
|
|
5009
5031
|
continue;
|
|
5010
5032
|
}
|
|
5011
5033
|
if (node.type === "text") {
|
|
5012
|
-
drawWithNodeTransform(
|
|
5034
|
+
drawWithNodeTransform(surface.ctx, node, () => {
|
|
5013
5035
|
if (isEditingThis) return;
|
|
5014
5036
|
const hasContent = node.content && node.content.trim().length > 0;
|
|
5015
5037
|
if (hasContent) {
|
|
5016
|
-
paintNodeContent(
|
|
5038
|
+
paintNodeContent(surface.ctx, node, renderEnv);
|
|
5017
5039
|
} else {
|
|
5018
|
-
paintEmptyTextPlaceholder(
|
|
5040
|
+
paintEmptyTextPlaceholder(surface.ctx, node, camera.z);
|
|
5019
5041
|
}
|
|
5020
5042
|
});
|
|
5021
5043
|
drawn++;
|
|
@@ -5027,7 +5049,7 @@ var createRenderer = (opts) => {
|
|
|
5027
5049
|
if (camera.z < def.lod.minZoomForPlaceholder) continue;
|
|
5028
5050
|
const preferCanvas = camera.z < def.lod.minZoomForReact || isMoving2;
|
|
5029
5051
|
if (preferCanvas) {
|
|
5030
|
-
if (paintCustomCanvasFallback(
|
|
5052
|
+
if (paintCustomCanvasFallback(surface.ctx, node, def, scale, renderEnv)) {
|
|
5031
5053
|
drawn++;
|
|
5032
5054
|
}
|
|
5033
5055
|
continue;
|
|
@@ -5037,10 +5059,10 @@ var createRenderer = (opts) => {
|
|
|
5037
5059
|
continue;
|
|
5038
5060
|
}
|
|
5039
5061
|
if (def.renderCanvas) {
|
|
5040
|
-
drawWithNodeTransform(
|
|
5041
|
-
|
|
5042
|
-
def.renderCanvas(
|
|
5043
|
-
|
|
5062
|
+
drawWithNodeTransform(surface.ctx, node, () => {
|
|
5063
|
+
surface.ctx.save();
|
|
5064
|
+
def.renderCanvas(surface.ctx, node, renderEnv);
|
|
5065
|
+
surface.ctx.restore();
|
|
5044
5066
|
});
|
|
5045
5067
|
drawn++;
|
|
5046
5068
|
}
|
|
@@ -5049,15 +5071,120 @@ var createRenderer = (opts) => {
|
|
|
5049
5071
|
const edgeRoughEnabled = !cameraIsMoving && movingNodeCount <= ROUGH_MAX_MOVING_NODES && camera.z >= ROUGH_MIN_ZOOM && visEdges.length <= ROUGH_MAX_NODES;
|
|
5050
5072
|
for (const edge of visEdges) {
|
|
5051
5073
|
if (excludedEdges?.has(edge.id)) continue;
|
|
5052
|
-
paintOneEdge(
|
|
5074
|
+
paintOneEdge(surface.ctx, edge, scale, edgeRoughEnabled, camera.z, isMoving2);
|
|
5053
5075
|
drawn++;
|
|
5054
5076
|
}
|
|
5077
|
+
if (!fullRender) return;
|
|
5055
5078
|
lastDrawn = drawn;
|
|
5056
5079
|
if (!setsEqual(nextOverlaySet, overlaySet)) {
|
|
5057
5080
|
overlaySet = nextOverlaySet;
|
|
5058
5081
|
onOverlayChange?.([...overlaySet]);
|
|
5059
5082
|
}
|
|
5060
5083
|
};
|
|
5084
|
+
const applyCacheTransform = (cache5, centerX, centerY, z) => {
|
|
5085
|
+
const s = z * cache5.dpr;
|
|
5086
|
+
const m = SCENE_CACHE_MARGIN_PX * cache5.dpr;
|
|
5087
|
+
cache5.ctx.setTransform(s, 0, 0, s, -centerX * s + m, -centerY * s + m);
|
|
5088
|
+
};
|
|
5089
|
+
const renderFullCache = (camera) => {
|
|
5090
|
+
const cache5 = ensureCacheSurface();
|
|
5091
|
+
clearSurface(cache5);
|
|
5092
|
+
applyCacheTransform(cache5, camera.x, camera.y, camera.z);
|
|
5093
|
+
const marginWorld = SCENE_CACHE_MARGIN_PX / camera.z;
|
|
5094
|
+
const viewport = inflateRect(worldViewport(staticSurface, camera), marginWorld);
|
|
5095
|
+
paintSceneBody(cache5, camera, viewport);
|
|
5096
|
+
cacheCamX = camera.x;
|
|
5097
|
+
cacheCamY = camera.y;
|
|
5098
|
+
cacheCamZ = camera.z;
|
|
5099
|
+
cacheStale = false;
|
|
5100
|
+
};
|
|
5101
|
+
const canExtend = (camera) => {
|
|
5102
|
+
if (!cacheSurface) return false;
|
|
5103
|
+
const s = camera.z * staticSurface.dpr;
|
|
5104
|
+
const dx = Math.abs((cacheCamX - camera.x) * s);
|
|
5105
|
+
const dy = Math.abs((cacheCamY - camera.y) * s);
|
|
5106
|
+
return dx < cacheSurface.canvas.width && dy < cacheSurface.canvas.height;
|
|
5107
|
+
};
|
|
5108
|
+
const renderCacheStrip = (cache5, centerX, centerY, z, px, py, pw, ph) => {
|
|
5109
|
+
const ctx = cache5.ctx;
|
|
5110
|
+
const s = z * cache5.dpr;
|
|
5111
|
+
const m = SCENE_CACHE_MARGIN_PX * cache5.dpr;
|
|
5112
|
+
ctx.save();
|
|
5113
|
+
ctx.setTransform(1, 0, 0, 1, 0, 0);
|
|
5114
|
+
ctx.beginPath();
|
|
5115
|
+
ctx.rect(px, py, pw, ph);
|
|
5116
|
+
ctx.clip();
|
|
5117
|
+
ctx.clearRect(px, py, pw, ph);
|
|
5118
|
+
applyCacheTransform(cache5, centerX, centerY, z);
|
|
5119
|
+
const viewport = {
|
|
5120
|
+
x: (px - m) / s + centerX,
|
|
5121
|
+
y: (py - m) / s + centerY,
|
|
5122
|
+
w: pw / s,
|
|
5123
|
+
h: ph / s
|
|
5124
|
+
};
|
|
5125
|
+
paintSceneBody(cache5, { z }, viewport, false);
|
|
5126
|
+
ctx.restore();
|
|
5127
|
+
};
|
|
5128
|
+
const extendCache = (camera) => {
|
|
5129
|
+
const cache5 = ensureCacheSurface();
|
|
5130
|
+
const s = camera.z * cache5.dpr;
|
|
5131
|
+
const cacheW = cache5.canvas.width;
|
|
5132
|
+
const cacheH = cache5.canvas.height;
|
|
5133
|
+
const dx = Math.round((cacheCamX - camera.x) * s);
|
|
5134
|
+
const dy = Math.round((cacheCamY - camera.y) * s);
|
|
5135
|
+
const newCamX = cacheCamX - dx / s;
|
|
5136
|
+
const newCamY = cacheCamY - dy / s;
|
|
5137
|
+
cache5.ctx.setTransform(1, 0, 0, 1, 0, 0);
|
|
5138
|
+
cache5.ctx.drawImage(cache5.canvas, 0, 0, cacheW, cacheH, dx, dy, cacheW, cacheH);
|
|
5139
|
+
cacheCamX = newCamX;
|
|
5140
|
+
cacheCamY = newCamY;
|
|
5141
|
+
cacheCamZ = camera.z;
|
|
5142
|
+
const hw = Math.abs(dx);
|
|
5143
|
+
const vh = Math.abs(dy);
|
|
5144
|
+
const hx = dx > 0 ? 0 : cacheW - hw;
|
|
5145
|
+
const vy = dy > 0 ? 0 : cacheH - vh;
|
|
5146
|
+
const vx = dx > 0 ? hw : 0;
|
|
5147
|
+
const vw = cacheW - hw;
|
|
5148
|
+
if (hw > 0) renderCacheStrip(cache5, newCamX, newCamY, camera.z, hx, 0, hw, cacheH);
|
|
5149
|
+
if (vh > 0 && vw > 0) renderCacheStrip(cache5, newCamX, newCamY, camera.z, vx, vy, vw, vh);
|
|
5150
|
+
};
|
|
5151
|
+
const cacheSourceOffset = (camera) => {
|
|
5152
|
+
const dpr = staticSurface.dpr;
|
|
5153
|
+
return {
|
|
5154
|
+
x: Math.round(((camera.x - cacheCamX) * cacheCamZ + SCENE_CACHE_MARGIN_PX) * dpr),
|
|
5155
|
+
y: Math.round(((camera.y - cacheCamY) * cacheCamZ + SCENE_CACHE_MARGIN_PX) * dpr)
|
|
5156
|
+
};
|
|
5157
|
+
};
|
|
5158
|
+
const viewportFitsInCache = (camera) => {
|
|
5159
|
+
if (!cacheSurface) return false;
|
|
5160
|
+
const { x, y } = cacheSourceOffset(camera);
|
|
5161
|
+
return x >= 0 && y >= 0 && x + staticSurface.canvas.width <= cacheSurface.canvas.width && y + staticSurface.canvas.height <= cacheSurface.canvas.height;
|
|
5162
|
+
};
|
|
5163
|
+
const presentStatic = (camera) => {
|
|
5164
|
+
const cache5 = ensureCacheSurface();
|
|
5165
|
+
const w = staticSurface.canvas.width;
|
|
5166
|
+
const h = staticSurface.canvas.height;
|
|
5167
|
+
const { x: srcX, y: srcY } = cacheSourceOffset(camera);
|
|
5168
|
+
staticSurface.ctx.setTransform(1, 0, 0, 1, 0, 0);
|
|
5169
|
+
staticSurface.ctx.clearRect(0, 0, w, h);
|
|
5170
|
+
staticSurface.ctx.drawImage(cache5.canvas, srcX, srcY, w, h, 0, 0, w, h);
|
|
5171
|
+
};
|
|
5172
|
+
const paintStatic = () => {
|
|
5173
|
+
const camera = store.getCamera();
|
|
5174
|
+
if (!cacheStale && camera.z === cacheCamZ) {
|
|
5175
|
+
if (viewportFitsInCache(camera)) {
|
|
5176
|
+
presentStatic(camera);
|
|
5177
|
+
return;
|
|
5178
|
+
}
|
|
5179
|
+
if (canExtend(camera)) {
|
|
5180
|
+
extendCache(camera);
|
|
5181
|
+
presentStatic(camera);
|
|
5182
|
+
return;
|
|
5183
|
+
}
|
|
5184
|
+
}
|
|
5185
|
+
renderFullCache(camera);
|
|
5186
|
+
presentStatic(camera);
|
|
5187
|
+
};
|
|
5061
5188
|
const paintCustomCanvasFallback = (ctx, node, def, drawScale, env) => {
|
|
5062
5189
|
if (def.getSnapshot) {
|
|
5063
5190
|
const snap = def.getSnapshot(node, {
|
|
@@ -5342,6 +5469,7 @@ var createRenderer = (opts) => {
|
|
|
5342
5469
|
const onStoreChange = () => {
|
|
5343
5470
|
invalidateSortedCaches();
|
|
5344
5471
|
staticDirty = true;
|
|
5472
|
+
cacheStale = true;
|
|
5345
5473
|
interactiveDirty = true;
|
|
5346
5474
|
loop.requestFrame();
|
|
5347
5475
|
};
|
|
@@ -5358,6 +5486,7 @@ var createRenderer = (opts) => {
|
|
|
5358
5486
|
interactiveDirty = true;
|
|
5359
5487
|
if (state.mode === "dragging" || state.mode === "resizing" || state.mode === "rotating" || state.mode === "panning" || state.mode === "zooming" || state.mode === "idle") {
|
|
5360
5488
|
staticDirty = true;
|
|
5489
|
+
cacheStale = true;
|
|
5361
5490
|
}
|
|
5362
5491
|
loop.requestFrame();
|
|
5363
5492
|
};
|
|
@@ -5367,16 +5496,19 @@ var createRenderer = (opts) => {
|
|
|
5367
5496
|
const unsubInteraction = store.subscribe("interaction", onInteractionChange);
|
|
5368
5497
|
const unsubFontEpoch = subscribeFontEpoch(() => {
|
|
5369
5498
|
staticDirty = true;
|
|
5499
|
+
cacheStale = true;
|
|
5370
5500
|
loop.requestFrame();
|
|
5371
5501
|
});
|
|
5372
5502
|
const unsubMathEpoch = subscribeMathEpoch(() => {
|
|
5373
5503
|
staticDirty = true;
|
|
5504
|
+
cacheStale = true;
|
|
5374
5505
|
loop.requestFrame();
|
|
5375
5506
|
});
|
|
5376
5507
|
return {
|
|
5377
5508
|
start() {
|
|
5378
5509
|
loop.start();
|
|
5379
5510
|
staticDirty = true;
|
|
5511
|
+
cacheStale = true;
|
|
5380
5512
|
interactiveDirty = isInteractive(store.getInteractionState());
|
|
5381
5513
|
loop.requestFrame();
|
|
5382
5514
|
},
|
|
@@ -5385,6 +5517,7 @@ var createRenderer = (opts) => {
|
|
|
5385
5517
|
},
|
|
5386
5518
|
invalidate() {
|
|
5387
5519
|
staticDirty = true;
|
|
5520
|
+
cacheStale = true;
|
|
5388
5521
|
interactiveDirty = true;
|
|
5389
5522
|
loop.requestFrame();
|
|
5390
5523
|
},
|
|
@@ -5393,6 +5526,7 @@ var createRenderer = (opts) => {
|
|
|
5393
5526
|
const b = sizeSurface(interactiveSurface, cssW, cssH, maxDpr);
|
|
5394
5527
|
if (a || b) {
|
|
5395
5528
|
staticDirty = true;
|
|
5529
|
+
cacheStale = true;
|
|
5396
5530
|
interactiveDirty = true;
|
|
5397
5531
|
loop.requestFrame();
|
|
5398
5532
|
}
|
|
@@ -5400,6 +5534,7 @@ var createRenderer = (opts) => {
|
|
|
5400
5534
|
setBackground(bg) {
|
|
5401
5535
|
background = bg;
|
|
5402
5536
|
staticDirty = true;
|
|
5537
|
+
cacheStale = true;
|
|
5403
5538
|
loop.requestFrame();
|
|
5404
5539
|
},
|
|
5405
5540
|
setSelectionColor(color) {
|
|
@@ -5410,6 +5545,7 @@ var createRenderer = (opts) => {
|
|
|
5410
5545
|
setHideFrames(hidden) {
|
|
5411
5546
|
hideFrames = hidden;
|
|
5412
5547
|
staticDirty = true;
|
|
5548
|
+
cacheStale = true;
|
|
5413
5549
|
loop.requestFrame();
|
|
5414
5550
|
},
|
|
5415
5551
|
stats: () => loop.stats(),
|
|
@@ -5424,6 +5560,11 @@ var createRenderer = (opts) => {
|
|
|
5424
5560
|
unsubFontEpoch();
|
|
5425
5561
|
unsubMathEpoch();
|
|
5426
5562
|
assetCache.dispose();
|
|
5563
|
+
if (cacheSurface) {
|
|
5564
|
+
cacheSurface.canvas.width = 0;
|
|
5565
|
+
cacheSurface.canvas.height = 0;
|
|
5566
|
+
cacheSurface = null;
|
|
5567
|
+
}
|
|
5427
5568
|
}
|
|
5428
5569
|
};
|
|
5429
5570
|
};
|