@vectojs/core 1.24.0 → 1.26.0

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.js CHANGED
@@ -9,13 +9,13 @@
9
9
 
10
10
 
11
11
 
12
- var _chunkKEBYJVD6js = require('./chunk-KEBYJVD6.js');
12
+ var _chunkKHGHP2J3js = require('./chunk-KHGHP2J3.js');
13
13
 
14
14
 
15
15
 
16
16
 
17
17
 
18
- var _chunkAGP4VLF4js = require('./chunk-AGP4VLF4.js');
18
+ var _chunkZ3HFY75Rjs = require('./chunk-Z3HFY75R.js');
19
19
 
20
20
  // src/tree/Scene.ts
21
21
  var _animation = require('@vectojs/animation'); _createStarExport(_animation);
@@ -30,7 +30,7 @@ var PARTICLE_OFFSET_ORIGIN_X = 4;
30
30
  var PARTICLE_OFFSET_ORIGIN_Y = 5;
31
31
  var PARTICLE_OFFSET_SIZE = 6;
32
32
  var PARTICLE_OFFSET_LIFE = 7;
33
- var ComputeParticleEntity = (_class = class extends _chunkAGP4VLF4js.Entity {
33
+ var ComputeParticleEntity = (_class = class extends _chunkZ3HFY75Rjs.Entity {
34
34
 
35
35
 
36
36
 
@@ -94,7 +94,7 @@ var ComputeParticleEntity = (_class = class extends _chunkAGP4VLF4js.Entity {
94
94
  this.particleData[idx + PARTICLE_OFFSET_LIFE] = -1;
95
95
  }
96
96
  this.needsInit = true;
97
- _optionalChain([this, 'access', _ => _.scene, 'optionalAccess', _2 => _2.markDirty, 'call', _3 => _3()]);
97
+ _optionalChain([this, 'access', _2 => _2.scene, 'optionalAccess', _3 => _3.markDirty, 'call', _4 => _4()]);
98
98
  }
99
99
  /**
100
100
  * Sets the origins (ox, oy) for a subset or all particles.
@@ -120,7 +120,7 @@ var ComputeParticleEntity = (_class = class extends _chunkAGP4VLF4js.Entity {
120
120
  }
121
121
  }
122
122
  this.needsInit = true;
123
- _optionalChain([this, 'access', _4 => _4.scene, 'optionalAccess', _5 => _5.markDirty, 'call', _6 => _6()]);
123
+ _optionalChain([this, 'access', _5 => _5.scene, 'optionalAccess', _6 => _6.markDirty, 'call', _7 => _7()]);
124
124
  }
125
125
  /**
126
126
  * Sets the current positions (x, y) for a subset or all particles.
@@ -136,7 +136,7 @@ var ComputeParticleEntity = (_class = class extends _chunkAGP4VLF4js.Entity {
136
136
  this.particleData[idx + PARTICLE_OFFSET_POSITION_Y] = positions[ptIdx + 1];
137
137
  }
138
138
  this.needsInit = true;
139
- _optionalChain([this, 'access', _7 => _7.scene, 'optionalAccess', _8 => _8.markDirty, 'call', _9 => _9()]);
139
+ _optionalChain([this, 'access', _8 => _8.scene, 'optionalAccess', _9 => _9.markDirty, 'call', _10 => _10()]);
140
140
  }
141
141
  /**
142
142
  * Sets the current velocities (vx, vy) for a subset or all particles.
@@ -152,7 +152,7 @@ var ComputeParticleEntity = (_class = class extends _chunkAGP4VLF4js.Entity {
152
152
  this.particleData[idx + PARTICLE_OFFSET_VELOCITY_Y] = velocities[ptIdx + 1];
153
153
  }
154
154
  this.needsInit = true;
155
- _optionalChain([this, 'access', _10 => _10.scene, 'optionalAccess', _11 => _11.markDirty, 'call', _12 => _12()]);
155
+ _optionalChain([this, 'access', _11 => _11.scene, 'optionalAccess', _12 => _12.markDirty, 'call', _13 => _13()]);
156
156
  }
157
157
  /**
158
158
  * Triggers an explosion force center.
@@ -1259,7 +1259,7 @@ var VECTO_USER_TIMING = {
1259
1259
  var nextSpanId = 0;
1260
1260
  function beginVectoUserTiming(name) {
1261
1261
  const candidate = globalThis.performance;
1262
- if (typeof _optionalChain([candidate, 'optionalAccess', _13 => _13.mark]) !== "function" || typeof candidate.measure !== "function") {
1262
+ if (typeof _optionalChain([candidate, 'optionalAccess', _14 => _14.mark]) !== "function" || typeof candidate.measure !== "function") {
1263
1263
  return null;
1264
1264
  }
1265
1265
  const id = nextSpanId++;
@@ -1286,15 +1286,15 @@ function endVectoUserTiming(span) {
1286
1286
  } catch (e8) {
1287
1287
  } finally {
1288
1288
  try {
1289
- _optionalChain([timing, 'access', _14 => _14.clearMarks, 'optionalCall', _15 => _15(span.startMark)]);
1290
- _optionalChain([timing, 'access', _16 => _16.clearMarks, 'optionalCall', _17 => _17(span.endMark)]);
1289
+ _optionalChain([timing, 'access', _15 => _15.clearMarks, 'optionalCall', _16 => _16(span.startMark)]);
1290
+ _optionalChain([timing, 'access', _17 => _17.clearMarks, 'optionalCall', _18 => _18(span.endMark)]);
1291
1291
  } catch (e9) {
1292
1292
  }
1293
1293
  }
1294
1294
  }
1295
1295
  function measureVectoUserTiming(name, durationMs) {
1296
1296
  const candidate = globalThis.performance;
1297
- if (typeof _optionalChain([candidate, 'optionalAccess', _18 => _18.now]) !== "function" || typeof candidate.mark !== "function" || typeof candidate.measure !== "function") {
1297
+ if (typeof _optionalChain([candidate, 'optionalAccess', _19 => _19.now]) !== "function" || typeof candidate.mark !== "function" || typeof candidate.measure !== "function") {
1298
1298
  return;
1299
1299
  }
1300
1300
  const id = nextSpanId++;
@@ -1309,8 +1309,8 @@ function measureVectoUserTiming(name, durationMs) {
1309
1309
  } catch (e10) {
1310
1310
  } finally {
1311
1311
  try {
1312
- _optionalChain([candidate, 'access', _19 => _19.clearMarks, 'optionalCall', _20 => _20(startMark)]);
1313
- _optionalChain([candidate, 'access', _21 => _21.clearMarks, 'optionalCall', _22 => _22(endMark)]);
1312
+ _optionalChain([candidate, 'access', _20 => _20.clearMarks, 'optionalCall', _21 => _21(startMark)]);
1313
+ _optionalChain([candidate, 'access', _22 => _22.clearMarks, 'optionalCall', _23 => _23(endMark)]);
1314
1314
  } catch (e11) {
1315
1315
  }
1316
1316
  }
@@ -1371,6 +1371,57 @@ function rebaseChildBox(parent, parentOriginX, parentOriginY, child, childOrigin
1371
1371
  REBASED_BOX.matrix = `matrix(${a}, ${b}, ${c}, ${d}, 0, 0)`;
1372
1372
  return REBASED_BOX;
1373
1373
  }
1374
+ var SCENE_OPTION_KEYS = [
1375
+ "a11ySyncInterval",
1376
+ "autoThrottle",
1377
+ "contentProjection",
1378
+ "contentProjectionMargin",
1379
+ "debugA11y",
1380
+ "disableWindowResize",
1381
+ "maxDPR",
1382
+ "maxFPS",
1383
+ "particleBackend",
1384
+ "pointBackend",
1385
+ "readingDirection",
1386
+ "renderer",
1387
+ "renderMode",
1388
+ "respectReducedMotion",
1389
+ "userTiming"
1390
+ ];
1391
+ var SCENE_FIELD_NOT_OPTION = {
1392
+ devMode: "set the static `Scene.devMode = true` before constructing"
1393
+ };
1394
+ function editDistance(a, b) {
1395
+ const m = a.length;
1396
+ const n = b.length;
1397
+ if (m === 0 || n === 0) return Math.max(m, n);
1398
+ let prev = Array.from({ length: n + 1 }, (_, i) => i);
1399
+ const curr = Array.from({ length: n + 1 });
1400
+ for (let i = 1; i <= m; i++) {
1401
+ curr[0] = i;
1402
+ for (let j = 1; j <= n; j++) {
1403
+ const cost = a.charCodeAt(i - 1) === b.charCodeAt(j - 1) ? 0 : 1;
1404
+ curr[j] = Math.min(curr[j - 1] + 1, prev[j] + 1, prev[j - 1] + cost);
1405
+ }
1406
+ prev = curr.slice();
1407
+ }
1408
+ return prev[n];
1409
+ }
1410
+ function closestOptionKey(key) {
1411
+ const lower = key.toLowerCase();
1412
+ let best;
1413
+ let bestScore = Infinity;
1414
+ for (const candidate of SCENE_OPTION_KEYS) {
1415
+ if (candidate.toLowerCase() === lower) return candidate;
1416
+ const d = editDistance(lower, candidate.toLowerCase());
1417
+ if (d < bestScore) {
1418
+ bestScore = d;
1419
+ best = candidate;
1420
+ }
1421
+ }
1422
+ const limit = Math.max(2, Math.floor(key.length / 3));
1423
+ return bestScore <= limit ? best : void 0;
1424
+ }
1374
1425
  var REDUCED_MOTION_FPS = 30;
1375
1426
  function parseInlinePx(value) {
1376
1427
  if (!value || !value.endsWith("px")) return null;
@@ -1456,9 +1507,9 @@ function parseCssMatrix(transform) {
1456
1507
  }
1457
1508
  function clientToGridLocal(contentEl, canvas, clientX, clientY) {
1458
1509
  const line = contentEl.querySelector("[data-vecto-grid-line]");
1459
- const originMarker = _optionalChain([line, 'optionalAccess', _23 => _23.querySelector, 'call', _24 => _24('[data-vecto-grid-basis="origin"]')]);
1460
- const xMarker = _optionalChain([line, 'optionalAccess', _25 => _25.querySelector, 'call', _26 => _26('[data-vecto-grid-basis="x"]')]);
1461
- const yMarker = _optionalChain([line, 'optionalAccess', _27 => _27.querySelector, 'call', _28 => _28('[data-vecto-grid-basis="y"]')]);
1510
+ const originMarker = _optionalChain([line, 'optionalAccess', _24 => _24.querySelector, 'call', _25 => _25('[data-vecto-grid-basis="origin"]')]);
1511
+ const xMarker = _optionalChain([line, 'optionalAccess', _26 => _26.querySelector, 'call', _27 => _27('[data-vecto-grid-basis="x"]')]);
1512
+ const yMarker = _optionalChain([line, 'optionalAccess', _28 => _28.querySelector, 'call', _29 => _29('[data-vecto-grid-basis="y"]')]);
1462
1513
  if (line && originMarker && xMarker && yMarker) {
1463
1514
  const origin = originMarker.getBoundingClientRect();
1464
1515
  const xPoint = xMarker.getBoundingClientRect();
@@ -1542,7 +1593,7 @@ function nearestTextPositionInLine(line, x, y) {
1542
1593
  nearest = { position: { node, offset }, distance: candidate.distance };
1543
1594
  }
1544
1595
  }
1545
- return _nullishCoalesce(_optionalChain([nearest, 'optionalAccess', _29 => _29.position]), () => ( null));
1596
+ return _nullishCoalesce(_optionalChain([nearest, 'optionalAccess', _30 => _30.position]), () => ( null));
1546
1597
  }
1547
1598
  function nearestTextPositionInProjection(contentEl, canvas, x, y, eventTarget) {
1548
1599
  if (contentEl.dataset.vectoContentGrid !== void 0) {
@@ -1556,7 +1607,7 @@ function nearestTextPositionInProjection(contentEl, canvas, x, y, eventTarget) {
1556
1607
  }
1557
1608
  targetLine = targetLine.parentElement;
1558
1609
  }
1559
- if (_optionalChain([targetLine, 'optionalAccess', _30 => _30.parentElement]) === contentEl) {
1610
+ if (_optionalChain([targetLine, 'optionalAccess', _31 => _31.parentElement]) === contentEl) {
1560
1611
  return nearestTextPositionInLine(targetLine, x, y);
1561
1612
  }
1562
1613
  let bestLine = null;
@@ -1834,7 +1885,7 @@ var Scene = (_class7 = class _Scene {
1834
1885
  __init50() {this.forcedColorsChangeHandler = null}
1835
1886
  /** True when the OS asks for reduced motion and we respect it. Read by the animation drivers. */
1836
1887
  get prefersReducedMotion() {
1837
- return this.respectReducedMotion && !!_optionalChain([this, 'access', _31 => _31.reducedMotionQuery, 'optionalAccess', _32 => _32.matches]);
1888
+ return this.respectReducedMotion && !!_optionalChain([this, 'access', _32 => _32.reducedMotionQuery, 'optionalAccess', _33 => _33.matches]);
1838
1889
  }
1839
1890
  /**
1840
1891
  * True when the OS is in a forced-colors mode (Windows High Contrast, and the
@@ -1845,7 +1896,7 @@ var Scene = (_class7 = class _Scene {
1845
1896
  * when the setting toggles.
1846
1897
  */
1847
1898
  get forcedColors() {
1848
- return !!_optionalChain([this, 'access', _33 => _33.forcedColorsQuery, 'optionalAccess', _34 => _34.matches]);
1899
+ return !!_optionalChain([this, 'access', _34 => _34.forcedColorsQuery, 'optionalAccess', _35 => _35.matches]);
1849
1900
  }
1850
1901
  /**
1851
1902
  * Throttle interval (ms) for the a11y/automation shadow sync. `0` = every
@@ -2281,7 +2332,7 @@ var Scene = (_class7 = class _Scene {
2281
2332
  const idx = cell[k];
2282
2333
  if (x < minx[idx] || x > maxx[idx] || y < miny[idx] || y > maxy[idx]) continue;
2283
2334
  const entity = this._hitSlotEntity[idx];
2284
- if (_optionalChain([entity, 'optionalAccess', _35 => _35.isPointInside, 'call', _36 => _36(x, y)]) && this.isHitEligible(entity, x, y)) {
2335
+ if (_optionalChain([entity, 'optionalAccess', _36 => _36.isPointInside, 'call', _37 => _37(x, y)]) && this.isHitEligible(entity, x, y)) {
2285
2336
  bestIndex = idx;
2286
2337
  bestEntity = entity;
2287
2338
  break;
@@ -2752,7 +2803,7 @@ var Scene = (_class7 = class _Scene {
2752
2803
  * active.
2753
2804
  */
2754
2805
  get webglDrawStats() {
2755
- return _nullishCoalesce(_optionalChain([this, 'access', _37 => _37.pointRenderer, 'optionalAccess', _38 => _38.stats, 'optionalCall', _39 => _39()]), () => ( null));
2806
+ return _nullishCoalesce(_optionalChain([this, 'access', _38 => _38.pointRenderer, 'optionalAccess', _39 => _39.stats, 'optionalCall', _40 => _40()]), () => ( null));
2756
2807
  }
2757
2808
  /**
2758
2809
  * Whether a WebGPU device is currently live for particle compute.
@@ -2794,8 +2845,8 @@ var Scene = (_class7 = class _Scene {
2794
2845
  static _devModeDetected() {
2795
2846
  if (_Scene.devMode) return true;
2796
2847
  const gp = typeof globalThis !== "undefined" ? globalThis : void 0;
2797
- if (_optionalChain([gp, 'optionalAccess', _40 => _40.__DEV__])) return true;
2798
- if (_optionalChain([gp, 'optionalAccess', _41 => _41.process, 'optionalAccess', _42 => _42.env, 'optionalAccess', _43 => _43.NODE_ENV]) === "development") return true;
2848
+ if (_optionalChain([gp, 'optionalAccess', _41 => _41.__DEV__])) return true;
2849
+ if (_optionalChain([gp, 'optionalAccess', _42 => _42.process, 'optionalAccess', _43 => _43.env, 'optionalAccess', _44 => _44.NODE_ENV]) === "development") return true;
2799
2850
  return false;
2800
2851
  }
2801
2852
 
@@ -2804,6 +2855,37 @@ var Scene = (_class7 = class _Scene {
2804
2855
  if (!this._devActive) return;
2805
2856
  console.warn(`[vectojs/dev] ${message}`);
2806
2857
  }
2858
+ /**
2859
+ * Warn (dev mode only) about `SceneOptions` keys this version does not read.
2860
+ *
2861
+ * A structural type makes an unrecognized key a silent no-op, and TypeScript
2862
+ * only rejects one when the object literal sits inline at the call site — not
2863
+ * when options are built dynamically, and never in plain JS. Since the
2864
+ * failure mode is "the option appears to work", a runtime check is the only
2865
+ * thing that surfaces it.
2866
+ *
2867
+ * Dev-mode only on purpose: the loop is O(keys × known keys) with an edit
2868
+ * distance per pair, which is nothing at construction but is still pure
2869
+ * overhead in production, where the value has already been shipped.
2870
+ */
2871
+ _warnUnknownOptions(options) {
2872
+ if (!this._devActive) return;
2873
+ const known = new Set(SCENE_OPTION_KEYS);
2874
+ for (const key of Object.keys(options)) {
2875
+ if (known.has(key)) continue;
2876
+ const fieldHint = SCENE_FIELD_NOT_OPTION[key];
2877
+ if (fieldHint) {
2878
+ this._devWarn(
2879
+ `SceneOptions: \`${key}\` is not a constructor option \u2014 ${fieldHint}. Passing it here has no effect.`
2880
+ );
2881
+ continue;
2882
+ }
2883
+ const suggestion = closestOptionKey(key);
2884
+ this._devWarn(
2885
+ `SceneOptions: unknown option \`${key}\` is ignored.` + (suggestion ? ` Did you mean \`${suggestion}\`?` : "")
2886
+ );
2887
+ }
2888
+ }
2807
2889
  /** @internal Periodic dev checks — called once per frame in dev mode. */
2808
2890
  _devRunChecks() {
2809
2891
  this._devFrameCount++;
@@ -2826,9 +2908,9 @@ var Scene = (_class7 = class _Scene {
2826
2908
  let checked = 0;
2827
2909
  const walkProjections = (node) => {
2828
2910
  if (checked > 10) return;
2829
- const proj = _optionalChain([node, 'access', _44 => _44.getContentProjection, 'optionalCall', _45 => _45()]);
2830
- if (_optionalChain([proj, 'optionalAccess', _46 => _46.text]) && proj.selectable !== false) {
2831
- const el = _optionalChain([this, 'access', _47 => _47.contentElements, 'optionalAccess', _48 => _48.get, 'call', _49 => _49(node.id)]);
2911
+ const proj = _optionalChain([node, 'access', _45 => _45.getContentProjection, 'optionalCall', _46 => _46()]);
2912
+ if (_optionalChain([proj, 'optionalAccess', _47 => _47.text]) && proj.selectable !== false) {
2913
+ const el = _optionalChain([this, 'access', _48 => _48.contentElements, 'optionalAccess', _49 => _49.get, 'call', _50 => _50(node.id)]);
2832
2914
  if (el) {
2833
2915
  const projectedText = el.textContent || "";
2834
2916
  if (projectedText !== "" && projectedText !== proj.text) {
@@ -2849,8 +2931,8 @@ var Scene = (_class7 = class _Scene {
2849
2931
  this.disableWindowResize = _nullishCoalesce(options.disableWindowResize, () => ( false));
2850
2932
  this.maxDPR = options.maxDPR;
2851
2933
  if (this.disableWindowResize) {
2852
- const styleWidth = parseInlinePx(_optionalChain([canvas, 'access', _50 => _50.style, 'optionalAccess', _51 => _51.width]));
2853
- const styleHeight = parseInlinePx(_optionalChain([canvas, 'access', _52 => _52.style, 'optionalAccess', _53 => _53.height]));
2934
+ const styleWidth = parseInlinePx(_optionalChain([canvas, 'access', _51 => _51.style, 'optionalAccess', _52 => _52.width]));
2935
+ const styleHeight = parseInlinePx(_optionalChain([canvas, 'access', _53 => _53.style, 'optionalAccess', _54 => _54.height]));
2854
2936
  this.width = _nullishCoalesce(styleWidth, () => ( (canvas.width || canvas.clientWidth || 0)));
2855
2937
  this.height = _nullishCoalesce(styleHeight, () => ( (canvas.height || canvas.clientHeight || 0)));
2856
2938
  } else {
@@ -2858,7 +2940,7 @@ var Scene = (_class7 = class _Scene {
2858
2940
  this.height = typeof window !== "undefined" ? window.innerHeight : canvas.clientHeight || canvas.height || 600;
2859
2941
  }
2860
2942
  const globalProcess = typeof globalThis !== "undefined" ? globalThis.process : void 0;
2861
- const isTest = globalProcess && (_optionalChain([globalProcess, 'access', _54 => _54.env, 'optionalAccess', _55 => _55.NODE_ENV]) === "test" || _optionalChain([globalProcess, 'access', _56 => _56.env, 'optionalAccess', _57 => _57.VITEST]) === "true");
2943
+ const isTest = globalProcess && (_optionalChain([globalProcess, 'access', _55 => _55.env, 'optionalAccess', _56 => _56.NODE_ENV]) === "test" || _optionalChain([globalProcess, 'access', _57 => _57.env, 'optionalAccess', _58 => _58.VITEST]) === "true");
2862
2944
  this.maxFPS = _nullishCoalesce(options.maxFPS, () => ( (isTest ? 0 : 60)));
2863
2945
  this.respectReducedMotion = _nullishCoalesce(options.respectReducedMotion, () => ( true));
2864
2946
  this.autoThrottle = _nullishCoalesce(options.autoThrottle, () => ( true));
@@ -2868,14 +2950,16 @@ var Scene = (_class7 = class _Scene {
2868
2950
  this.contentProjectionEnabled = _nullishCoalesce(options.contentProjection, () => ( true));
2869
2951
  this.contentProjectionMargin = options.contentProjectionMargin;
2870
2952
  this.readingDirection = _nullishCoalesce(options.readingDirection, () => ( "ltr"));
2953
+ this.renderMode = _nullishCoalesce(options.renderMode, () => ( "always"));
2871
2954
  this._devActive = _Scene._devModeDetected();
2955
+ this._warnUnknownOptions(options);
2872
2956
  this.reducedMotionQuery = typeof window !== "undefined" && typeof window.matchMedia === "function" ? window.matchMedia("(prefers-reduced-motion: reduce)") : null;
2873
2957
  if (typeof window !== "undefined" && typeof window.matchMedia === "function") {
2874
2958
  this.forcedColorsQuery = window.matchMedia("(forced-colors: active)");
2875
2959
  this.forcedColorsChangeHandler = () => this.markDirty();
2876
- _optionalChain([this, 'access', _58 => _58.forcedColorsQuery, 'access', _59 => _59.addEventListener, 'optionalCall', _60 => _60("change", this.forcedColorsChangeHandler)]);
2960
+ _optionalChain([this, 'access', _59 => _59.forcedColorsQuery, 'access', _60 => _60.addEventListener, 'optionalCall', _61 => _61("change", this.forcedColorsChangeHandler)]);
2877
2961
  }
2878
- this.root = new class RootEntity extends _chunkAGP4VLF4js.Entity {
2962
+ this.root = new class RootEntity extends _chunkZ3HFY75Rjs.Entity {
2879
2963
  isPointInside() {
2880
2964
  return false;
2881
2965
  }
@@ -2884,7 +2968,7 @@ var Scene = (_class7 = class _Scene {
2884
2968
  }
2885
2969
  }("root");
2886
2970
  this.root._scene = this;
2887
- this.overlayRoot = new class OverlayRoot extends _chunkAGP4VLF4js.Entity {
2971
+ this.overlayRoot = new class OverlayRoot extends _chunkZ3HFY75Rjs.Entity {
2888
2972
  isPointInside() {
2889
2973
  return false;
2890
2974
  }
@@ -2895,15 +2979,15 @@ var Scene = (_class7 = class _Scene {
2895
2979
  if (options.renderer) {
2896
2980
  this.renderer = options.renderer;
2897
2981
  } else {
2898
- this.renderer = new (0, _chunkKEBYJVD6js.CanvasRenderer)(
2982
+ this.renderer = new (0, _chunkKHGHP2J3js.CanvasRenderer)(
2899
2983
  canvas,
2900
2984
  this.disableWindowResize ? { width: this.width, height: this.height } : void 0,
2901
2985
  this.maxDPR
2902
2986
  );
2903
2987
  }
2904
- _optionalChain([this, 'access', _61 => _61.renderer, 'access', _62 => _62.onContextRestored, 'optionalCall', _63 => _63(() => {
2988
+ _optionalChain([this, 'access', _62 => _62.renderer, 'access', _63 => _63.onContextRestored, 'optionalCall', _64 => _64(() => {
2905
2989
  this.markDirty();
2906
- if (_optionalChain([this, 'access', _64 => _64.renderer, 'access', _65 => _65.isContextLost, 'optionalCall', _66 => _66()]) !== true) this.render(this.renderer);
2990
+ if (_optionalChain([this, 'access', _65 => _65.renderer, 'access', _66 => _66.isContextLost, 'optionalCall', _67 => _67()]) !== true) this.render(this.renderer);
2907
2991
  })]);
2908
2992
  if (typeof document !== "undefined") {
2909
2993
  this.a11yRoot = document.createElement("div");
@@ -3073,7 +3157,7 @@ var Scene = (_class7 = class _Scene {
3073
3157
  watchDevicePixelRatio() {
3074
3158
  if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
3075
3159
  if (this.dprMediaQuery && this.dprChangeHandler) {
3076
- _optionalChain([this, 'access', _67 => _67.dprMediaQuery, 'access', _68 => _68.removeEventListener, 'optionalCall', _69 => _69("change", this.dprChangeHandler)]);
3160
+ _optionalChain([this, 'access', _68 => _68.dprMediaQuery, 'access', _69 => _69.removeEventListener, 'optionalCall', _70 => _70("change", this.dprChangeHandler)]);
3077
3161
  }
3078
3162
  const dpr = window.devicePixelRatio || 1;
3079
3163
  const query = window.matchMedia(`(resolution: ${dpr}dppx)`);
@@ -3081,7 +3165,7 @@ var Scene = (_class7 = class _Scene {
3081
3165
  this.resize(this.width, this.height);
3082
3166
  this.watchDevicePixelRatio();
3083
3167
  };
3084
- _optionalChain([query, 'access', _70 => _70.addEventListener, 'optionalCall', _71 => _71("change", handler)]);
3168
+ _optionalChain([query, 'access', _71 => _71.addEventListener, 'optionalCall', _72 => _72("change", handler)]);
3085
3169
  this.dprMediaQuery = query;
3086
3170
  this.dprChangeHandler = handler;
3087
3171
  }
@@ -3101,7 +3185,7 @@ var Scene = (_class7 = class _Scene {
3101
3185
  if (typeof gl.addEventListener !== "function") return;
3102
3186
  this.glContextLostHandler = (e) => {
3103
3187
  e.preventDefault();
3104
- _optionalChain([this, 'access', _72 => _72.pointRenderer, 'optionalAccess', _73 => _73.destroy, 'call', _74 => _74()]);
3188
+ _optionalChain([this, 'access', _73 => _73.pointRenderer, 'optionalAccess', _74 => _74.destroy, 'call', _75 => _75()]);
3105
3189
  this.pointRenderer = null;
3106
3190
  };
3107
3191
  this.glContextRestoredHandler = () => {
@@ -3131,26 +3215,26 @@ var Scene = (_class7 = class _Scene {
3131
3215
  * to the live DOM selection.
3132
3216
  */
3133
3217
  contentGridSelectionLine(el) {
3134
- const candidates = [_optionalChain([this, 'access', _75 => _75.contentSelectionAnchor, 'optionalAccess', _76 => _76.node])];
3218
+ const candidates = [_optionalChain([this, 'access', _76 => _76.contentSelectionAnchor, 'optionalAccess', _77 => _77.node])];
3135
3219
  if (typeof window !== "undefined" && typeof window.getSelection === "function") {
3136
3220
  const selection = window.getSelection();
3137
- candidates.push(_optionalChain([selection, 'optionalAccess', _77 => _77.anchorNode]), _optionalChain([selection, 'optionalAccess', _78 => _78.focusNode]));
3221
+ candidates.push(_optionalChain([selection, 'optionalAccess', _78 => _78.anchorNode]), _optionalChain([selection, 'optionalAccess', _79 => _79.focusNode]));
3138
3222
  }
3139
3223
  for (const candidate of candidates) {
3140
3224
  if (!candidate || !el.contains(candidate)) continue;
3141
3225
  let cursor = candidate;
3142
3226
  while (cursor && cursor.parentNode !== el) cursor = cursor.parentNode;
3143
- const lineIndex = _optionalChain([cursor, 'optionalAccess', _79 => _79.dataset, 'optionalAccess', _80 => _80.vectoGridLine]);
3227
+ const lineIndex = _optionalChain([cursor, 'optionalAccess', _80 => _80.dataset, 'optionalAccess', _81 => _81.vectoGridLine]);
3144
3228
  if (lineIndex !== void 0) return Number(lineIndex);
3145
3229
  }
3146
3230
  return null;
3147
3231
  }
3148
3232
  releaseContentSelectionForRebuild(el) {
3149
3233
  const selection = typeof window !== "undefined" && typeof window.getSelection === "function" ? window.getSelection() : null;
3150
- const ownsSelection = this.contentSelectionAnchor && el.contains(this.contentSelectionAnchor.node) || (_optionalChain([selection, 'optionalAccess', _81 => _81.anchorNode]) ? el.contains(selection.anchorNode) : false) || (_optionalChain([selection, 'optionalAccess', _82 => _82.focusNode]) ? el.contains(selection.focusNode) : false);
3234
+ const ownsSelection = this.contentSelectionAnchor && el.contains(this.contentSelectionAnchor.node) || (_optionalChain([selection, 'optionalAccess', _82 => _82.anchorNode]) ? el.contains(selection.anchorNode) : false) || (_optionalChain([selection, 'optionalAccess', _83 => _83.focusNode]) ? el.contains(selection.focusNode) : false);
3151
3235
  if (!ownsSelection) return;
3152
3236
  this.endContentSelectionDrag();
3153
- _optionalChain([selection, 'optionalAccess', _83 => _83.removeAllRanges, 'call', _84 => _84()]);
3237
+ _optionalChain([selection, 'optionalAccess', _84 => _84.removeAllRanges, 'call', _85 => _85()]);
3154
3238
  }
3155
3239
  /**
3156
3240
  * Rebuild a content-projection element's DOM (`rebuild`) while preserving a
@@ -3209,7 +3293,7 @@ var Scene = (_class7 = class _Scene {
3209
3293
  }
3210
3294
  /** Convert browser viewport coordinates into this Scene's logical coordinates. */
3211
3295
  clientToScene(clientX, clientY) {
3212
- const rect = _optionalChain([this, 'access', _85 => _85.canvas, 'access', _86 => _86.getBoundingClientRect, 'optionalCall', _87 => _87()]);
3296
+ const rect = _optionalChain([this, 'access', _86 => _86.canvas, 'access', _87 => _87.getBoundingClientRect, 'optionalCall', _88 => _88()]);
3213
3297
  if (!rect) return { x: clientX, y: clientY };
3214
3298
  const cssWidth = rect.width || this.canvas.clientWidth || this.width;
3215
3299
  const cssHeight = rect.height || this.canvas.clientHeight || this.height;
@@ -3247,7 +3331,7 @@ var Scene = (_class7 = class _Scene {
3247
3331
  cancelAnimationFrame(calibrationFrame);
3248
3332
  }
3249
3333
  this.contentGridCalibrationFrames.delete(entityId);
3250
- _optionalChain([this, 'access', _88 => _88.contentGridCalibrationProbes, 'access', _89 => _89.get, 'call', _90 => _90(entityId), 'optionalAccess', _91 => _91.remove, 'call', _92 => _92()]);
3334
+ _optionalChain([this, 'access', _89 => _89.contentGridCalibrationProbes, 'access', _90 => _90.get, 'call', _91 => _91(entityId), 'optionalAccess', _92 => _92.remove, 'call', _93 => _93()]);
3251
3335
  this.contentGridCalibrationProbes.delete(entityId);
3252
3336
  delete el.dataset.vectoGridCalibrationPending;
3253
3337
  delete el.dataset.vectoGridCalibration;
@@ -3299,7 +3383,7 @@ var Scene = (_class7 = class _Scene {
3299
3383
  }
3300
3384
  if (this.hoveredA11yElements.has(el)) {
3301
3385
  this.hoveredA11yElements.delete(el);
3302
- node.dispatchEvent(new (0, _chunkAGP4VLF4js.VectoJSEvent)("pointerleave", node, void 0, false));
3386
+ node.dispatchEvent(new (0, _chunkZ3HFY75Rjs.VectoJSEvent)("pointerleave", node, void 0, false));
3303
3387
  }
3304
3388
  this.preserveFocusOnRemoval(el);
3305
3389
  el.remove();
@@ -3401,12 +3485,12 @@ var Scene = (_class7 = class _Scene {
3401
3485
  this.canvasResizeObserver = null;
3402
3486
  }
3403
3487
  if (this.dprMediaQuery && this.dprChangeHandler) {
3404
- _optionalChain([this, 'access', _93 => _93.dprMediaQuery, 'access', _94 => _94.removeEventListener, 'optionalCall', _95 => _95("change", this.dprChangeHandler)]);
3488
+ _optionalChain([this, 'access', _94 => _94.dprMediaQuery, 'access', _95 => _95.removeEventListener, 'optionalCall', _96 => _96("change", this.dprChangeHandler)]);
3405
3489
  this.dprMediaQuery = null;
3406
3490
  this.dprChangeHandler = null;
3407
3491
  }
3408
3492
  if (this.forcedColorsQuery && this.forcedColorsChangeHandler) {
3409
- _optionalChain([this, 'access', _96 => _96.forcedColorsQuery, 'access', _97 => _97.removeEventListener, 'optionalCall', _98 => _98("change", this.forcedColorsChangeHandler)]);
3493
+ _optionalChain([this, 'access', _97 => _97.forcedColorsQuery, 'access', _98 => _98.removeEventListener, 'optionalCall', _99 => _99("change", this.forcedColorsChangeHandler)]);
3410
3494
  this.forcedColorsQuery = null;
3411
3495
  this.forcedColorsChangeHandler = null;
3412
3496
  }
@@ -3424,9 +3508,9 @@ var Scene = (_class7 = class _Scene {
3424
3508
  }
3425
3509
  this.pointerEventTarget = null;
3426
3510
  }
3427
- _optionalChain([this, 'access', _99 => _99.a11yRoot, 'optionalAccess', _100 => _100.remove, 'call', _101 => _101()]);
3511
+ _optionalChain([this, 'access', _100 => _100.a11yRoot, 'optionalAccess', _101 => _101.remove, 'call', _102 => _102()]);
3428
3512
  this.focusSentinel = null;
3429
- _optionalChain([this, 'access', _102 => _102.portalRoot, 'optionalAccess', _103 => _103.remove, 'call', _104 => _104()]);
3513
+ _optionalChain([this, 'access', _103 => _103.portalRoot, 'optionalAccess', _104 => _104.remove, 'call', _105 => _105()]);
3430
3514
  this.a11yElements.clear();
3431
3515
  for (const el of this.contentElements.values()) el.remove();
3432
3516
  this.contentElements.clear();
@@ -3449,10 +3533,10 @@ var Scene = (_class7 = class _Scene {
3449
3533
  }
3450
3534
  this.glContextLostHandler = null;
3451
3535
  this.glContextRestoredHandler = null;
3452
- _optionalChain([this, 'access', _105 => _105.pointRenderer, 'optionalAccess', _106 => _106.destroy, 'call', _107 => _107()]);
3453
- _optionalChain([this, 'access', _108 => _108.renderer, 'access', _109 => _109.dispose, 'optionalCall', _110 => _110()]);
3454
- _optionalChain([this, 'access', _111 => _111.glCanvas, 'optionalAccess', _112 => _112.remove, 'call', _113 => _113()]);
3455
- _optionalChain([this, 'access', _114 => _114.gpuCanvas, 'optionalAccess', _115 => _115.remove, 'call', _116 => _116()]);
3536
+ _optionalChain([this, 'access', _106 => _106.pointRenderer, 'optionalAccess', _107 => _107.destroy, 'call', _108 => _108()]);
3537
+ _optionalChain([this, 'access', _109 => _109.renderer, 'access', _110 => _110.dispose, 'optionalCall', _111 => _111()]);
3538
+ _optionalChain([this, 'access', _112 => _112.glCanvas, 'optionalAccess', _113 => _113.remove, 'call', _114 => _114()]);
3539
+ _optionalChain([this, 'access', _115 => _115.gpuCanvas, 'optionalAccess', _116 => _116.remove, 'call', _117 => _117()]);
3456
3540
  this.gpuCanvas = null;
3457
3541
  this.gpuContext = null;
3458
3542
  if (this.recoveryTimerId) {
@@ -3464,7 +3548,7 @@ var Scene = (_class7 = class _Scene {
3464
3548
  this.manager = null;
3465
3549
  }
3466
3550
  if (this.device) {
3467
- _optionalChain([this, 'access', _117 => _117.device, 'access', _118 => _118.destroy, 'optionalCall', _119 => _119()]);
3551
+ _optionalChain([this, 'access', _118 => _118.device, 'access', _119 => _119.destroy, 'optionalCall', _120 => _120()]);
3468
3552
  this.device = null;
3469
3553
  }
3470
3554
  }
@@ -3812,20 +3896,20 @@ var Scene = (_class7 = class _Scene {
3812
3896
  el.style.background = "transparent";
3813
3897
  }
3814
3898
  el.addEventListener("click", (e) => {
3815
- node.dispatchEvent(new (0, _chunkAGP4VLF4js.VectoJSEvent)("click", node, e));
3899
+ node.dispatchEvent(new (0, _chunkZ3HFY75Rjs.VectoJSEvent)("click", node, e));
3816
3900
  });
3817
3901
  el.addEventListener("dblclick", (e) => {
3818
- node.dispatchEvent(new (0, _chunkAGP4VLF4js.VectoJSEvent)("dblclick", node, e));
3902
+ node.dispatchEvent(new (0, _chunkZ3HFY75Rjs.VectoJSEvent)("dblclick", node, e));
3819
3903
  });
3820
3904
  el.addEventListener("mouseenter", (e) => {
3821
3905
  if (this.debugA11y) el.style.backgroundColor = "rgba(56, 189, 248, 0.2)";
3822
3906
  this.hoveredA11yElements.add(el);
3823
- node.dispatchEvent(new (0, _chunkAGP4VLF4js.VectoJSEvent)("hover", node, e, false));
3907
+ node.dispatchEvent(new (0, _chunkZ3HFY75Rjs.VectoJSEvent)("hover", node, e, false));
3824
3908
  });
3825
3909
  el.addEventListener("mouseleave", (e) => {
3826
3910
  if (this.debugA11y) el.style.backgroundColor = "rgba(56, 189, 248, 0.05)";
3827
3911
  this.hoveredA11yElements.delete(el);
3828
- node.dispatchEvent(new (0, _chunkAGP4VLF4js.VectoJSEvent)("pointerleave", node, e, false));
3912
+ node.dispatchEvent(new (0, _chunkZ3HFY75Rjs.VectoJSEvent)("pointerleave", node, e, false));
3829
3913
  });
3830
3914
  const capEl = el;
3831
3915
  const releasePointer = (event) => {
@@ -3841,32 +3925,32 @@ var Scene = (_class7 = class _Scene {
3841
3925
  };
3842
3926
  el.addEventListener("pointerdown", (e) => {
3843
3927
  if (typeof capEl.setPointerCapture === "function") capEl.setPointerCapture(e.pointerId);
3844
- node.dispatchEvent(new (0, _chunkAGP4VLF4js.VectoJSEvent)("pointerdown", node, e));
3928
+ node.dispatchEvent(new (0, _chunkZ3HFY75Rjs.VectoJSEvent)("pointerdown", node, e));
3845
3929
  });
3846
3930
  el.addEventListener("pointerup", (e) => {
3847
3931
  releasePointer(e);
3848
- node.dispatchEvent(new (0, _chunkAGP4VLF4js.VectoJSEvent)("pointerup", node, e));
3932
+ node.dispatchEvent(new (0, _chunkZ3HFY75Rjs.VectoJSEvent)("pointerup", node, e));
3849
3933
  });
3850
3934
  el.addEventListener("pointercancel", (e) => {
3851
3935
  releasePointer(e);
3852
- node.dispatchEvent(new (0, _chunkAGP4VLF4js.VectoJSEvent)("pointercancel", node, e));
3936
+ node.dispatchEvent(new (0, _chunkZ3HFY75Rjs.VectoJSEvent)("pointercancel", node, e));
3853
3937
  });
3854
3938
  el.addEventListener(
3855
3939
  "pointermove",
3856
- (e) => node.dispatchEvent(new (0, _chunkAGP4VLF4js.VectoJSEvent)("pointermove", node, e))
3940
+ (e) => node.dispatchEvent(new (0, _chunkZ3HFY75Rjs.VectoJSEvent)("pointermove", node, e))
3857
3941
  );
3858
3942
  el.addEventListener(
3859
3943
  "wheel",
3860
3944
  (e) => {
3861
- node.dispatchEvent(new (0, _chunkAGP4VLF4js.VectoJSEvent)("wheel", node, e));
3945
+ node.dispatchEvent(new (0, _chunkZ3HFY75Rjs.VectoJSEvent)("wheel", node, e));
3862
3946
  },
3863
3947
  { passive: false }
3864
3948
  );
3865
3949
  el.addEventListener("keydown", (e) => {
3866
- node.dispatchEvent(new (0, _chunkAGP4VLF4js.VectoJSEvent)("keydown", node, e));
3950
+ node.dispatchEvent(new (0, _chunkZ3HFY75Rjs.VectoJSEvent)("keydown", node, e));
3867
3951
  });
3868
3952
  el.addEventListener("keyup", (e) => {
3869
- node.dispatchEvent(new (0, _chunkAGP4VLF4js.VectoJSEvent)("keyup", node, e));
3953
+ node.dispatchEvent(new (0, _chunkZ3HFY75Rjs.VectoJSEvent)("keyup", node, e));
3870
3954
  });
3871
3955
  if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement) {
3872
3956
  const input = el;
@@ -3897,7 +3981,7 @@ var Scene = (_class7 = class _Scene {
3897
3981
  el.addEventListener("compositionupdate", (e) => {
3898
3982
  const data = _nullishCoalesce(e.data, () => ( ""));
3899
3983
  composition = {
3900
- start: _nullishCoalesce(_optionalChain([composition, 'optionalAccess', _120 => _120.start]), () => ( 0)),
3984
+ start: _nullishCoalesce(_optionalChain([composition, 'optionalAccess', _121 => _121.start]), () => ( 0)),
3901
3985
  length: data.length
3902
3986
  };
3903
3987
  forward();
@@ -3932,7 +4016,7 @@ var Scene = (_class7 = class _Scene {
3932
4016
  el.addEventListener("keydown", (e) => {
3933
4017
  if (e.key === "Enter" || e.key === " ") {
3934
4018
  e.preventDefault();
3935
- node.dispatchEvent(new (0, _chunkAGP4VLF4js.VectoJSEvent)("click", node, e));
4019
+ node.dispatchEvent(new (0, _chunkZ3HFY75Rjs.VectoJSEvent)("click", node, e));
3936
4020
  }
3937
4021
  });
3938
4022
  }
@@ -3970,7 +4054,7 @@ var Scene = (_class7 = class _Scene {
3970
4054
  this.syncOptionalAttribute(
3971
4055
  el,
3972
4056
  "href",
3973
- attrs.href === void 0 ? void 0 : _chunkKEBYJVD6js.sanitizeUrl.call(void 0, attrs.href)
4057
+ attrs.href === void 0 ? void 0 : _chunkKHGHP2J3js.sanitizeUrl.call(void 0, attrs.href)
3974
4058
  );
3975
4059
  this.syncOptionalAttribute(el, "target", attrs.target);
3976
4060
  }
@@ -4247,7 +4331,7 @@ var Scene = (_class7 = class _Scene {
4247
4331
  el.addEventListener(
4248
4332
  "wheel",
4249
4333
  (e2) => {
4250
- node.dispatchEvent(new (0, _chunkAGP4VLF4js.VectoJSEvent)("wheel", node, e2));
4334
+ node.dispatchEvent(new (0, _chunkZ3HFY75Rjs.VectoJSEvent)("wheel", node, e2));
4251
4335
  },
4252
4336
  { passive: false }
4253
4337
  );
@@ -4376,9 +4460,9 @@ var Scene = (_class7 = class _Scene {
4376
4460
  for (let lineIndex = 0; lineIndex < grid.lines.length; lineIndex++) {
4377
4461
  const gridLine = grid.lines[lineIndex];
4378
4462
  const projectedLine = projectionLines[lineIndex];
4379
- const lineHeight = _nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess', _121 => _121.lineHeight]), () => ( grid.lineHeight));
4380
- const baseline = _nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess', _122 => _122.baseline]), () => ( grid.baseline));
4381
- const lineFont = _nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess', _123 => _123.font]), () => ( grid.font));
4463
+ const lineHeight = _nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess', _122 => _122.lineHeight]), () => ( grid.lineHeight));
4464
+ const baseline = _nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess', _123 => _123.baseline]), () => ( grid.baseline));
4465
+ const lineFont = _nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess', _124 => _124.font]), () => ( grid.font));
4382
4466
  const lineSignature = contentGridLineSignature(
4383
4467
  grid,
4384
4468
  gridLine,
@@ -4398,8 +4482,8 @@ var Scene = (_class7 = class _Scene {
4398
4482
  lineElement.dir = "ltr";
4399
4483
  lineElement.dataset.vectoGridLine = `${lineIndex}`;
4400
4484
  lineElement.style.position = "absolute";
4401
- lineElement.style.left = `${_nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess', _124 => _124.x]), () => ( 0))}px`;
4402
- lineElement.style.top = `${(_nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess', _125 => _125.y]), () => ( lineIndex * grid.lineHeight))) + baseline - _text.cssLineBoxBaseline.call(void 0, lineFont, lineHeight)}px`;
4485
+ lineElement.style.left = `${_nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess', _125 => _125.x]), () => ( 0))}px`;
4486
+ lineElement.style.top = `${(_nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess', _126 => _126.y]), () => ( lineIndex * grid.lineHeight))) + baseline - _text.cssLineBoxBaseline.call(void 0, lineFont, lineHeight)}px`;
4403
4487
  lineElement.style.width = `${gridLine.width}px`;
4404
4488
  lineElement.style.height = `${lineHeight}px`;
4405
4489
  lineElement.style.whiteSpace = "pre";
@@ -4469,7 +4553,7 @@ var Scene = (_class7 = class _Scene {
4469
4553
  if (selectionLine !== null && selectionLine >= grid.lines.length) {
4470
4554
  rebuiltSelectionLine = true;
4471
4555
  }
4472
- _optionalChain([el, 'access', _126 => _126.lastElementChild, 'optionalAccess', _127 => _127.remove, 'call', _128 => _128()]);
4556
+ _optionalChain([el, 'access', _127 => _127.lastElementChild, 'optionalAccess', _128 => _128.remove, 'call', _129 => _129()]);
4473
4557
  }
4474
4558
  if (rebuiltSelectionLine) this.releaseContentSelectionForRebuild(el);
4475
4559
  el.dataset.vectoProjectionLines = signature;
@@ -4533,7 +4617,7 @@ var Scene = (_class7 = class _Scene {
4533
4617
  if (previous !== void 0 && typeof cancelAnimationFrame === "function") {
4534
4618
  cancelAnimationFrame(previous);
4535
4619
  }
4536
- _optionalChain([this, 'access', _129 => _129.contentGridCalibrationProbes, 'access', _130 => _130.get, 'call', _131 => _131(entityId), 'optionalAccess', _132 => _132.remove, 'call', _133 => _133()]);
4620
+ _optionalChain([this, 'access', _130 => _130.contentGridCalibrationProbes, 'access', _131 => _131.get, 'call', _132 => _132(entityId), 'optionalAccess', _133 => _133.remove, 'call', _134 => _134()]);
4537
4621
  this.contentGridCalibrationProbes.delete(entityId);
4538
4622
  const calibrationStart = typeof performance !== "undefined" ? performance.now() : 0;
4539
4623
  const probe = document.createElement("div");
@@ -4567,7 +4651,7 @@ var Scene = (_class7 = class _Scene {
4567
4651
  target.dataset.vectoGridCalib = generation;
4568
4652
  continue;
4569
4653
  }
4570
- const sourceText = _nullishCoalesce(_optionalChain([target, 'access', _134 => _134.textContent, 'optionalAccess', _135 => _135.slice, 'call', _136 => _136(0, sourceLength)]), () => ( ""));
4654
+ const sourceText = _nullishCoalesce(_optionalChain([target, 'access', _135 => _135.textContent, 'optionalAccess', _136 => _136.slice, 'call', _137 => _137(0, sourceLength)]), () => ( ""));
4571
4655
  if (!sourceText) {
4572
4656
  target.dataset.vectoGridCalib = generation;
4573
4657
  continue;
@@ -4794,12 +4878,12 @@ var Scene = (_class7 = class _Scene {
4794
4878
  syncOverlayGeometry() {
4795
4879
  const parent = this.canvas.parentElement;
4796
4880
  if (!parent) return;
4797
- const canvasRect = _optionalChain([this, 'access', _137 => _137.canvas, 'access', _138 => _138.getBoundingClientRect, 'optionalCall', _139 => _139()]);
4798
- const parentRect = _optionalChain([parent, 'access', _140 => _140.getBoundingClientRect, 'optionalCall', _141 => _141()]);
4799
- const cssWidth = _optionalChain([canvasRect, 'optionalAccess', _142 => _142.width]) || this.canvas.clientWidth || this.width;
4800
- const cssHeight = _optionalChain([canvasRect, 'optionalAccess', _143 => _143.height]) || this.canvas.clientHeight || this.height;
4801
- const left = (_nullishCoalesce(_optionalChain([canvasRect, 'optionalAccess', _144 => _144.left]), () => ( 0))) - (_nullishCoalesce(_optionalChain([parentRect, 'optionalAccess', _145 => _145.left]), () => ( 0))) - (parent.clientLeft || 0) + parent.scrollLeft;
4802
- const top = (_nullishCoalesce(_optionalChain([canvasRect, 'optionalAccess', _146 => _146.top]), () => ( 0))) - (_nullishCoalesce(_optionalChain([parentRect, 'optionalAccess', _147 => _147.top]), () => ( 0))) - (parent.clientTop || 0) + parent.scrollTop;
4881
+ const canvasRect = _optionalChain([this, 'access', _138 => _138.canvas, 'access', _139 => _139.getBoundingClientRect, 'optionalCall', _140 => _140()]);
4882
+ const parentRect = _optionalChain([parent, 'access', _141 => _141.getBoundingClientRect, 'optionalCall', _142 => _142()]);
4883
+ const cssWidth = _optionalChain([canvasRect, 'optionalAccess', _143 => _143.width]) || this.canvas.clientWidth || this.width;
4884
+ const cssHeight = _optionalChain([canvasRect, 'optionalAccess', _144 => _144.height]) || this.canvas.clientHeight || this.height;
4885
+ const left = (_nullishCoalesce(_optionalChain([canvasRect, 'optionalAccess', _145 => _145.left]), () => ( 0))) - (_nullishCoalesce(_optionalChain([parentRect, 'optionalAccess', _146 => _146.left]), () => ( 0))) - (parent.clientLeft || 0) + parent.scrollLeft;
4886
+ const top = (_nullishCoalesce(_optionalChain([canvasRect, 'optionalAccess', _147 => _147.top]), () => ( 0))) - (_nullishCoalesce(_optionalChain([parentRect, 'optionalAccess', _148 => _148.top]), () => ( 0))) - (parent.clientTop || 0) + parent.scrollTop;
4803
4887
  const scaleX = this.width > 0 ? cssWidth / this.width : 1;
4804
4888
  const scaleY = this.height > 0 ? cssHeight / this.height : 1;
4805
4889
  const prev = this._overlayGeometry;
@@ -4938,7 +5022,7 @@ var Scene = (_class7 = class _Scene {
4938
5022
  * (and {@link respectReducedMotion} is on). `0` means uncapped.
4939
5023
  */
4940
5024
  effectiveMaxFPS() {
4941
- const reduced = this.respectReducedMotion && !!_optionalChain([this, 'access', _148 => _148.reducedMotionQuery, 'optionalAccess', _149 => _149.matches]);
5025
+ const reduced = this.respectReducedMotion && !!_optionalChain([this, 'access', _149 => _149.reducedMotionQuery, 'optionalAccess', _150 => _150.matches]);
4942
5026
  if (reduced)
4943
5027
  return this.maxFPS > 0 ? Math.min(this.maxFPS, REDUCED_MOTION_FPS) : REDUCED_MOTION_FPS;
4944
5028
  return this.maxFPS;
@@ -5033,7 +5117,7 @@ var Scene = (_class7 = class _Scene {
5033
5117
  * @param time - Current absolute time in milliseconds (default 0).
5034
5118
  */
5035
5119
  render(renderer, dt = 0, time = 0) {
5036
- if (_optionalChain([renderer, 'access', _150 => _150.isContextLost, 'optionalCall', _151 => _151()])) return;
5120
+ if (_optionalChain([renderer, 'access', _151 => _151.isContextLost, 'optionalCall', _152 => _152()])) return;
5037
5121
  const isMainRenderer = renderer === this.renderer;
5038
5122
  if (isMainRenderer && this.a11yRoot && this.canvas.parentElement) {
5039
5123
  const parentStyle = this.canvas.parentElement.style;
@@ -5177,14 +5261,14 @@ var Scene = (_class7 = class _Scene {
5177
5261
  }
5178
5262
  renderer.clear();
5179
5263
  if (isMainRenderer) {
5180
- _optionalChain([this, 'access', _152 => _152.pointRenderer, 'optionalAccess', _153 => _153.begin, 'call', _154 => _154()]);
5264
+ _optionalChain([this, 'access', _153 => _153.pointRenderer, 'optionalAccess', _154 => _154.begin, 'call', _155 => _155()]);
5181
5265
  }
5182
5266
  const vw = this.width;
5183
5267
  const vh = this.height;
5184
5268
  let walkHadAnimation = false;
5185
5269
  let walkHadInteractive = false;
5186
5270
  const runUpdate = (node) => {
5187
- const overridesUpdate = node.update !== _chunkAGP4VLF4js.Entity.prototype.update;
5271
+ const overridesUpdate = node.update !== _chunkZ3HFY75Rjs.Entity.prototype.update;
5188
5272
  let pending = node.hasPendingAnimations();
5189
5273
  if (pending || overridesUpdate) {
5190
5274
  node.update(dt, time);
@@ -5193,7 +5277,7 @@ var Scene = (_class7 = class _Scene {
5193
5277
  if (pending) walkHadAnimation = true;
5194
5278
  if (!walkHadInteractive && node.interactive) walkHadInteractive = true;
5195
5279
  if (this._devActive && this._devFrameCount % 120 === 0) {
5196
- if (overridesUpdate && node.hasPendingAnimations === _chunkAGP4VLF4js.Entity.prototype.hasPendingAnimations) {
5280
+ if (overridesUpdate && node.hasPendingAnimations === _chunkZ3HFY75Rjs.Entity.prototype.hasPendingAnimations) {
5197
5281
  this._devWarn(
5198
5282
  `Entity "${node.id}" overrides update() but not hasPendingAnimations(). Custom motion in update() without overriding hasPendingAnimations() causes the idle throttle to drop the animation to ~2fps. Override hasPendingAnimations() to return true while motion is in flight.`
5199
5283
  );
@@ -5391,9 +5475,9 @@ var Scene = (_class7 = class _Scene {
5391
5475
  const flushT0 = this._phaseTiming ? performance.now() : 0;
5392
5476
  renderer.flush();
5393
5477
  if (isMainRenderer) {
5394
- _optionalChain([this, 'access', _155 => _155.pointRenderer, 'optionalAccess', _156 => _156.flush, 'call', _157 => _157()]);
5478
+ _optionalChain([this, 'access', _156 => _156.pointRenderer, 'optionalAccess', _157 => _157.flush, 'call', _158 => _158()]);
5395
5479
  }
5396
- _optionalChain([renderer, 'access', _158 => _158.present, 'optionalCall', _159 => _159()]);
5480
+ _optionalChain([renderer, 'access', _159 => _159.present, 'optionalCall', _160 => _160()]);
5397
5481
  if (this._phaseTiming) this._recordPhase("flush", performance.now() - flushT0);
5398
5482
  if (flushTiming) endVectoUserTiming(flushTiming);
5399
5483
  if (this._devActive) {
@@ -5405,7 +5489,7 @@ var Scene = (_class7 = class _Scene {
5405
5489
  * Export the current scene state to a lightweight, flat SVG XML string.
5406
5490
  */
5407
5491
  toSVG() {
5408
- const renderer = new (0, _chunkKEBYJVD6js.SVGRenderer)(this.width, this.height);
5492
+ const renderer = new (0, _chunkKHGHP2J3js.SVGRenderer)(this.width, this.height);
5409
5493
  this.render(renderer, 0, 0);
5410
5494
  return renderer.toXMLString();
5411
5495
  }
@@ -5674,8 +5758,8 @@ function pointInBounds(b, x, y) {
5674
5758
  function contentGridLineSignature(grid, line, projected, lineHeight, baseline, font, isFirstLine) {
5675
5759
  const parts = [
5676
5760
  // Line box: position, size, and the font that resolves its baseline.
5677
- `${_nullishCoalesce(_optionalChain([projected, 'optionalAccess', _160 => _160.x]), () => ( 0))}`,
5678
- `${_nullishCoalesce(_optionalChain([projected, 'optionalAccess', _161 => _161.y]), () => ( ""))}`,
5761
+ `${_nullishCoalesce(_optionalChain([projected, 'optionalAccess', _161 => _161.x]), () => ( 0))}`,
5762
+ `${_nullishCoalesce(_optionalChain([projected, 'optionalAccess', _162 => _162.y]), () => ( ""))}`,
5679
5763
  `${lineHeight}`,
5680
5764
  `${baseline}`,
5681
5765
  font,
@@ -5712,12 +5796,12 @@ function contentGridLineSignature(grid, line, projected, lineHeight, baseline, f
5712
5796
 
5713
5797
 
5714
5798
  var _layout = require('@vectojs/layout'); _createStarExport(_layout);
5715
- var sharedMeasurer;
5799
+ var sharedMeasurer = null;
5716
5800
  function defaultMeasurer() {
5717
- if (sharedMeasurer === void 0) sharedMeasurer = _layout.createCanvasMeasurer.call(void 0, "sans-serif");
5801
+ sharedMeasurer ??= _layout.resolveGlyphMeasurer.call(void 0, "sans-serif");
5718
5802
  return sharedMeasurer;
5719
5803
  }
5720
- var TextEntity = (_class8 = class extends _chunkAGP4VLF4js.Entity {
5804
+ var TextEntity = (_class8 = class extends _chunkZ3HFY75Rjs.Entity {
5721
5805
 
5722
5806
 
5723
5807
 
@@ -5843,7 +5927,7 @@ var TextEntity = (_class8 = class extends _chunkAGP4VLF4js.Entity {
5843
5927
  }, _class8);
5844
5928
 
5845
5929
  // src/components/GridTextEntity.ts
5846
- var GridTextEntity = (_class9 = class extends _chunkAGP4VLF4js.Entity {
5930
+ var GridTextEntity = (_class9 = class extends _chunkZ3HFY75Rjs.Entity {
5847
5931
 
5848
5932
  __init155() {this.fillStyle = "#ffffff"}
5849
5933
  __init156() {this.grid = []}
@@ -5862,7 +5946,7 @@ var GridTextEntity = (_class9 = class extends _chunkAGP4VLF4js.Entity {
5862
5946
  updateGrid(ascii) {
5863
5947
  this.grid = ascii;
5864
5948
  this.rows = ascii.length;
5865
- this.cols = _optionalChain([ascii, 'access', _162 => _162[0], 'optionalAccess', _163 => _163.length]) || 0;
5949
+ this.cols = _optionalChain([ascii, 'access', _163 => _163[0], 'optionalAccess', _164 => _164.length]) || 0;
5866
5950
  }
5867
5951
  isPointInside(_globalX, _globalY) {
5868
5952
  return false;
@@ -5937,7 +6021,7 @@ function distSqToSegment(px, py, x1, y1, x2, y2) {
5937
6021
  const ey = py - cy;
5938
6022
  return ex * ex + ey * ey;
5939
6023
  }
5940
- var SplineEntity = (_class10 = class extends _chunkAGP4VLF4js.Entity {
6024
+ var SplineEntity = (_class10 = class extends _chunkZ3HFY75Rjs.Entity {
5941
6025
 
5942
6026
 
5943
6027
 
@@ -5972,7 +6056,7 @@ var SplineEntity = (_class10 = class extends _chunkAGP4VLF4js.Entity {
5972
6056
  this.width = this.bounds.width;
5973
6057
  this.height = this.bounds.height;
5974
6058
  const isGradient = (c) => c !== null && !Array.isArray(c);
5975
- this.containsGradient = (_nullishCoalesce(_optionalChain([this, 'access', _164 => _164.doc, 'access', _165 => _165.equations, 'optionalAccess', _166 => _166.some, 'call', _167 => _167((eq) => isGradient(eq.color_rgb))]), () => ( false))) || (_nullishCoalesce(_optionalChain([this, 'access', _168 => _168.doc, 'access', _169 => _169.paths, 'optionalAccess', _170 => _170.some, 'call', _171 => _171((p) => isGradient(p.color_rgb))]), () => ( false)));
6059
+ this.containsGradient = (_nullishCoalesce(_optionalChain([this, 'access', _165 => _165.doc, 'access', _166 => _166.equations, 'optionalAccess', _167 => _167.some, 'call', _168 => _168((eq) => isGradient(eq.color_rgb))]), () => ( false))) || (_nullishCoalesce(_optionalChain([this, 'access', _169 => _169.doc, 'access', _170 => _170.paths, 'optionalAccess', _171 => _171.some, 'call', _172 => _172((p) => isGradient(p.color_rgb))]), () => ( false)));
5976
6060
  this.interactive = true;
5977
6061
  }
5978
6062
  computeBounds() {
@@ -6212,7 +6296,7 @@ async function loadSpline(url) {
6212
6296
  }
6213
6297
 
6214
6298
  // src/components/Rect.ts
6215
- var Rect = class extends _chunkAGP4VLF4js.Entity {
6299
+ var Rect = class extends _chunkZ3HFY75Rjs.Entity {
6216
6300
 
6217
6301
 
6218
6302
 
@@ -6261,7 +6345,7 @@ var Rect = class extends _chunkAGP4VLF4js.Entity {
6261
6345
  };
6262
6346
 
6263
6347
  // src/components/Circle.ts
6264
- var Circle = class extends _chunkAGP4VLF4js.Entity {
6348
+ var Circle = class extends _chunkZ3HFY75Rjs.Entity {
6265
6349
 
6266
6350
 
6267
6351
 
@@ -6321,7 +6405,7 @@ var Circle = class extends _chunkAGP4VLF4js.Entity {
6321
6405
  };
6322
6406
 
6323
6407
  // src/components/Group.ts
6324
- var Group = class extends _chunkAGP4VLF4js.Entity {
6408
+ var Group = class extends _chunkZ3HFY75Rjs.Entity {
6325
6409
  constructor(...children) {
6326
6410
  super();
6327
6411
  if (children.length > 0) this.add(...children);
@@ -6340,7 +6424,7 @@ var _math = require('@vectojs/math'); _createStarExport(_math);
6340
6424
 
6341
6425
 
6342
6426
  // src/tree/DOMPortalEntity.ts
6343
- var DOMPortalEntity = (_class11 = class extends _chunkAGP4VLF4js.Entity {
6427
+ var DOMPortalEntity = (_class11 = class extends _chunkZ3HFY75Rjs.Entity {
6344
6428
 
6345
6429
  __init165() {this.isDOMPortal = true}
6346
6430
  __init166() {this.domListeners = []}
@@ -6396,7 +6480,7 @@ var DOMPortalEntity = (_class11 = class extends _chunkAGP4VLF4js.Entity {
6396
6480
  ];
6397
6481
  for (const type of events) {
6398
6482
  const handler = (e) => {
6399
- this.dispatchEvent(new (0, _chunkAGP4VLF4js.VectoJSEvent)(type, this, e));
6483
+ this.dispatchEvent(new (0, _chunkZ3HFY75Rjs.VectoJSEvent)(type, this, e));
6400
6484
  };
6401
6485
  this.domElement.addEventListener(type, handler);
6402
6486
  this.domListeners.push({ type, handler, capture: false });
@@ -6407,7 +6491,7 @@ var DOMPortalEntity = (_class11 = class extends _chunkAGP4VLF4js.Entity {
6407
6491
  ];
6408
6492
  for (const { native, vecto } of hoverEvents) {
6409
6493
  const handler = (e) => {
6410
- this.dispatchEvent(new (0, _chunkAGP4VLF4js.VectoJSEvent)(vecto, this, e, false));
6494
+ this.dispatchEvent(new (0, _chunkZ3HFY75Rjs.VectoJSEvent)(vecto, this, e, false));
6411
6495
  };
6412
6496
  this.domElement.addEventListener(native, handler);
6413
6497
  this.domListeners.push({ type: native, handler, capture: false });
@@ -6415,7 +6499,7 @@ var DOMPortalEntity = (_class11 = class extends _chunkAGP4VLF4js.Entity {
6415
6499
  const focusEvents = ["focus", "blur"];
6416
6500
  for (const type of focusEvents) {
6417
6501
  const handler = (e) => {
6418
- this.dispatchEvent(new (0, _chunkAGP4VLF4js.VectoJSEvent)(type, this, e, true));
6502
+ this.dispatchEvent(new (0, _chunkZ3HFY75Rjs.VectoJSEvent)(type, this, e, true));
6419
6503
  };
6420
6504
  this.domElement.addEventListener(type, handler, true);
6421
6505
  this.domListeners.push({ type, handler, capture: true });
@@ -6466,8 +6550,9 @@ var DOMPortalEntity = (_class11 = class extends _chunkAGP4VLF4js.Entity {
6466
6550
  }, _class11);
6467
6551
 
6468
6552
  // src/index.ts
6469
- Scene.registerWebGLPointRendererCreator(_chunkKEBYJVD6js.createWebGLPointRenderer);
6470
- Scene.registerWebGPUParticleSystemManager(_chunkKEBYJVD6js.WebGPUParticleSystemManager);
6553
+ Scene.registerWebGLPointRendererCreator(_chunkKHGHP2J3js.createWebGLPointRenderer);
6554
+ Scene.registerWebGPUParticleSystemManager(_chunkKHGHP2J3js.WebGPUParticleSystemManager);
6555
+
6471
6556
 
6472
6557
 
6473
6558
 
@@ -6507,4 +6592,4 @@ Scene.registerWebGPUParticleSystemManager(_chunkKEBYJVD6js.WebGPUParticleSystemM
6507
6592
 
6508
6593
 
6509
6594
 
6510
- exports.CanvasRenderer = _chunkKEBYJVD6js.CanvasRenderer; exports.Circle = Circle; exports.ComputeParticleEntity = ComputeParticleEntity; exports.DOMPortalEntity = DOMPortalEntity; exports.Entity = _chunkAGP4VLF4js.Entity; exports.GlyphRasterAtlas = _chunkKEBYJVD6js.GlyphRasterAtlas; exports.GridTextEntity = GridTextEntity; exports.Group = Group; exports.MSDFTextEntity = _chunkAGP4VLF4js.MSDFTextEntity; exports.PARTICLE_OFFSET_LIFE = PARTICLE_OFFSET_LIFE; exports.PARTICLE_OFFSET_ORIGIN_X = PARTICLE_OFFSET_ORIGIN_X; exports.PARTICLE_OFFSET_ORIGIN_Y = PARTICLE_OFFSET_ORIGIN_Y; exports.PARTICLE_OFFSET_POSITION_X = PARTICLE_OFFSET_POSITION_X; exports.PARTICLE_OFFSET_POSITION_Y = PARTICLE_OFFSET_POSITION_Y; exports.PARTICLE_OFFSET_SIZE = PARTICLE_OFFSET_SIZE; exports.PARTICLE_OFFSET_VELOCITY_X = PARTICLE_OFFSET_VELOCITY_X; exports.PARTICLE_OFFSET_VELOCITY_Y = PARTICLE_OFFSET_VELOCITY_Y; exports.PARTICLE_STRIDE_FLOATS = PARTICLE_STRIDE_FLOATS; exports.REDUCED_MOTION_FPS = REDUCED_MOTION_FPS; exports.Rect = Rect; exports.SVGEntity = _chunkAGP4VLF4js.SVGEntity; exports.SVGRenderer = _chunkKEBYJVD6js.SVGRenderer; exports.Scene = Scene; exports.SplineEntity = SplineEntity; exports.TextEntity = TextEntity; exports.TextRasterCache = _chunkKEBYJVD6js.TextRasterCache; exports.VECTO_USER_TIMING = VECTO_USER_TIMING; exports.VectoJSEvent = _chunkAGP4VLF4js.VectoJSEvent; exports.WebGPUParticleSystemManager = _chunkKEBYJVD6js.WebGPUParticleSystemManager; exports.beginVectoUserTiming = beginVectoUserTiming; exports.createWebGLPointRenderer = _chunkKEBYJVD6js.createWebGLPointRenderer; exports.endVectoUserTiming = endVectoUserTiming; exports.isSafeUrl = _chunkKEBYJVD6js.isSafeUrl; exports.loadSpline = loadSpline; exports.measureVectoUserTiming = measureVectoUserTiming; exports.parseColorToRGBA = _chunkKEBYJVD6js.parseColorToRGBA; exports.polySegmentToBezier = polySegmentToBezier; exports.sanitizeUrl = _chunkKEBYJVD6js.sanitizeUrl;
6595
+ exports.CanvasRenderer = _chunkKHGHP2J3js.CanvasRenderer; exports.Circle = Circle; exports.ComputeParticleEntity = ComputeParticleEntity; exports.DOMPortalEntity = DOMPortalEntity; exports.Entity = _chunkZ3HFY75Rjs.Entity; exports.GlyphRasterAtlas = _chunkKHGHP2J3js.GlyphRasterAtlas; exports.GridTextEntity = GridTextEntity; exports.Group = Group; exports.MSDFTextEntity = _chunkZ3HFY75Rjs.MSDFTextEntity; exports.PARTICLE_OFFSET_LIFE = PARTICLE_OFFSET_LIFE; exports.PARTICLE_OFFSET_ORIGIN_X = PARTICLE_OFFSET_ORIGIN_X; exports.PARTICLE_OFFSET_ORIGIN_Y = PARTICLE_OFFSET_ORIGIN_Y; exports.PARTICLE_OFFSET_POSITION_X = PARTICLE_OFFSET_POSITION_X; exports.PARTICLE_OFFSET_POSITION_Y = PARTICLE_OFFSET_POSITION_Y; exports.PARTICLE_OFFSET_SIZE = PARTICLE_OFFSET_SIZE; exports.PARTICLE_OFFSET_VELOCITY_X = PARTICLE_OFFSET_VELOCITY_X; exports.PARTICLE_OFFSET_VELOCITY_Y = PARTICLE_OFFSET_VELOCITY_Y; exports.PARTICLE_STRIDE_FLOATS = PARTICLE_STRIDE_FLOATS; exports.REDUCED_MOTION_FPS = REDUCED_MOTION_FPS; exports.Rect = Rect; exports.SCENE_OPTION_KEYS = SCENE_OPTION_KEYS; exports.SVGEntity = _chunkZ3HFY75Rjs.SVGEntity; exports.SVGRenderer = _chunkKHGHP2J3js.SVGRenderer; exports.Scene = Scene; exports.SplineEntity = SplineEntity; exports.TextEntity = TextEntity; exports.TextRasterCache = _chunkKHGHP2J3js.TextRasterCache; exports.VECTO_USER_TIMING = VECTO_USER_TIMING; exports.VectoJSEvent = _chunkZ3HFY75Rjs.VectoJSEvent; exports.WebGPUParticleSystemManager = _chunkKHGHP2J3js.WebGPUParticleSystemManager; exports.beginVectoUserTiming = beginVectoUserTiming; exports.createWebGLPointRenderer = _chunkKHGHP2J3js.createWebGLPointRenderer; exports.endVectoUserTiming = endVectoUserTiming; exports.isSafeUrl = _chunkKHGHP2J3js.isSafeUrl; exports.loadSpline = loadSpline; exports.measureVectoUserTiming = measureVectoUserTiming; exports.parseColorToRGBA = _chunkKHGHP2J3js.parseColorToRGBA; exports.polySegmentToBezier = polySegmentToBezier; exports.sanitizeUrl = _chunkKHGHP2J3js.sanitizeUrl;