@vectojs/core 1.30.0 → 1.31.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
@@ -19,7 +19,7 @@ var _chunkM73XB4ZKjs = require('./chunk-M73XB4ZK.js');
19
19
 
20
20
 
21
21
 
22
- var _chunk7PI7LVWWjs = require('./chunk-7PI7LVWW.js');
22
+ var _chunkTRT2TRCWjs = require('./chunk-TRT2TRCW.js');
23
23
 
24
24
  // src/tree/Scene.ts
25
25
  var _animation = require('@vectojs/animation'); _createStarExport(_animation);
@@ -34,7 +34,7 @@ var PARTICLE_OFFSET_ORIGIN_X = 4;
34
34
  var PARTICLE_OFFSET_ORIGIN_Y = 5;
35
35
  var PARTICLE_OFFSET_SIZE = 6;
36
36
  var PARTICLE_OFFSET_LIFE = 7;
37
- var ComputeParticleEntity = (_class = class extends _chunk7PI7LVWWjs.Entity {
37
+ var ComputeParticleEntity = (_class = class extends _chunkTRT2TRCWjs.Entity {
38
38
 
39
39
 
40
40
 
@@ -1380,6 +1380,7 @@ var SCENE_OPTION_KEYS = [
1380
1380
  "autoThrottle",
1381
1381
  "contentProjection",
1382
1382
  "contentProjectionMargin",
1383
+ "contentSemanticMargin",
1383
1384
  "debugA11y",
1384
1385
  "disableWindowResize",
1385
1386
  "maxDPR",
@@ -1957,10 +1958,19 @@ var Scene = (_class7 = class _Scene {
1957
1958
  __init54() {this.a11yElements = /* @__PURE__ */ new Map()}
1958
1959
  /** DOM nodes mirroring static text content, keyed by entity id. */
1959
1960
  __init55() {this.contentElements = /* @__PURE__ */ new Map()}
1961
+ /**
1962
+ * What the last completed content-projection sync was built from, per entity.
1963
+ *
1964
+ * Compared at the top of {@link syncContentProjection} to skip a block whose
1965
+ * content AND geometry are both unchanged, before the O(glyphs) projection
1966
+ * build. Only populated for entities that opt in via
1967
+ * {@link Entity.getContentEpoch}. (carryctx CTX-0199)
1968
+ */
1969
+ __init56() {this.contentSyncState = /* @__PURE__ */ new Map()}
1960
1970
  /** Pending cold font-calibration frame per projected grid entity. */
1961
- __init56() {this.contentGridCalibrationFrames = /* @__PURE__ */ new Map()}
1971
+ __init57() {this.contentGridCalibrationFrames = /* @__PURE__ */ new Map()}
1962
1972
  /** Detached, untransformed font probes used by the cold calibration pass. */
1963
- __init57() {this.contentGridCalibrationProbes = /* @__PURE__ */ new Map()}
1973
+ __init58() {this.contentGridCalibrationProbes = /* @__PURE__ */ new Map()}
1964
1974
  /**
1965
1975
  * Monotonic stamp identifying the conditions grid cells were calibrated under.
1966
1976
  *
@@ -1981,54 +1991,59 @@ var Scene = (_class7 = class _Scene {
1981
1991
  * A plain incrementing integer rather than the descriptive calibration key,
1982
1992
  * because it goes into an attribute selector and must not need escaping.
1983
1993
  */
1984
- __init58() {this.contentGridCalibrationGeneration = 0}
1994
+ __init59() {this.contentGridCalibrationGeneration = 0}
1985
1995
  /** The `(fontEpoch, pageScale)` pair the current generation corresponds to. */
1986
- __init59() {this.contentGridCalibrationStamp = ""}
1996
+ __init60() {this.contentGridCalibrationStamp = ""}
1987
1997
  /** Invalidates grid font calibration after browser font availability changes. */
1988
- __init60() {this.contentFontEpoch = 0}
1998
+ __init61() {this.contentFontEpoch = 0}
1989
1999
  /** Cached Canvas-to-client scale for the current font/viewport epoch. */
1990
- __init61() {this.contentMetricScaleEpoch = -1}
1991
- __init62() {this.contentMetricScaleX = 1}
1992
- __init63() {this.contentProjectionEnabled = true}
1993
- // Virtualization margin (px) for content projection; `undefined` → one
1994
- // viewport height, resolved at sync time. `Infinity` = materialize everything.
1995
- __init64() {this.contentProjectionMargin = void 0}
2000
+ __init62() {this.contentMetricScaleEpoch = -1}
2001
+ __init63() {this.contentMetricScaleX = 1}
2002
+ __init64() {this.contentProjectionEnabled = true}
2003
+ // Virtualization margin (px) for the content-projection CARRIER band;
2004
+ // `undefined` → one viewport height, resolved at sync time. `Infinity` is
2005
+ // unsupported here: it unwindows every carrier, which is O(total glyphs).
2006
+ __init65() {this.contentProjectionMargin = void 0}
2007
+ // Virtualization margin (px) for the SEMANTIC tier — whether a block has
2008
+ // any projected DOM. `undefined` → falls back to contentProjectionMargin, so
2009
+ // the default keeps one gate. `Infinity` = every block keeps resident text.
2010
+ __init66() {this.contentSemanticMargin = void 0}
1996
2011
  /**
1997
2012
  * True while a text-selection drag that started on a projection's blank
1998
2013
  * region (no text node under the press) is being driven manually — the
1999
2014
  * browser has no native anchor for it, so mousemove extends the Selection
2000
2015
  * from the position we resolved ourselves.
2001
2016
  */
2002
- __init65() {this.blankRegionSelectionDrag = false}
2003
- __init66() {this.contentSelectionAnchor = null}
2004
- __init67() {this.contentSelectionEndListener = null}
2017
+ __init67() {this.blankRegionSelectionDrag = false}
2018
+ __init68() {this.contentSelectionAnchor = null}
2019
+ __init69() {this.contentSelectionEndListener = null}
2005
2020
  // Animation/interactive flags collected during the render walk (tree-walk
2006
2021
  // fusion): the loop reads last frame's answers instead of re-walking the
2007
2022
  // tree up to 4× per tick. Start true so the first tick stays conservative.
2008
- __init68() {this.frameHadAnimation = true}
2009
- __init69() {this.frameHadInteractive = true}
2023
+ __init70() {this.frameHadAnimation = true}
2024
+ __init71() {this.frameHadInteractive = true}
2010
2025
 
2011
2026
  /** Active `(resolution: Ndppx)` media query watching for a runtime DPR change
2012
2027
  * (window moved between monitors, browser zoom) so the canvas backing store
2013
2028
  * can be re-scaled — otherwise it stays rasterized at the old DPR and blurs.
2014
2029
  * A resolution media query only fires when leaving its exact value, so the
2015
2030
  * handler re-arms a fresh query for the new DPR each time. */
2016
- __init70() {this.dprMediaQuery = null}
2031
+ __init72() {this.dprMediaQuery = null}
2017
2032
  /** For embedded (`disableWindowResize`) scenes: observes the canvas element so
2018
2033
  * a CSS/layout-driven size change re-runs `resize()`. A window `resize`
2019
2034
  * listener never fires for these (the window isn't what changed), so without
2020
2035
  * this an embedded canvas stayed at its initial size forever. */
2021
- __init71() {this.canvasResizeObserver = null}
2022
- __init72() {this.dprChangeHandler = null}
2023
- __init73() {this.focusedA11yElement = null}
2036
+ __init73() {this.canvasResizeObserver = null}
2037
+ __init74() {this.dprChangeHandler = null}
2038
+ __init75() {this.focusedA11yElement = null}
2024
2039
  /** Last geometry `syncOverlayGeometry` wrote, so an unchanged frame can skip the
2025
2040
  * style writes entirely. Reset to `null` to force the next sync (a new overlay
2026
2041
  * layer was created and has never been positioned). */
2027
- __init74() {this._overlayGeometry = null}
2042
+ __init76() {this._overlayGeometry = null}
2028
2043
  /** Shadow elements the pointer is currently inside. Lets a removal that happens
2029
2044
  * mid-hover synthesize the `pointerleave` the browser never sends for a
2030
2045
  * detached element, so the entity doesn't keep its hover state. */
2031
- __init75() {this.hoveredA11yElements = /* @__PURE__ */ new WeakSet()}
2046
+ __init77() {this.hoveredA11yElements = /* @__PURE__ */ new WeakSet()}
2032
2047
  /**
2033
2048
  * Entity ids the application has pinned via {@link requestA11yProjection}.
2034
2049
  *
@@ -2036,22 +2051,22 @@ var Scene = (_class7 = class _Scene {
2036
2051
  * a stale id simply never matches. Cleared per-entity by
2037
2052
  * {@link releaseA11yProjection}.
2038
2053
  */
2039
- __init76() {this.a11yProjectionRequests = /* @__PURE__ */ new Set()}
2054
+ __init78() {this.a11yProjectionRequests = /* @__PURE__ */ new Set()}
2040
2055
  /** Persistent tabindex=-1 element in a11yRoot. When the focused a11y mirror is
2041
2056
  * pruned (virtualization/streaming/removal) while it holds focus, we move
2042
2057
  * focus here instead of letting the browser drop it to <body> — keeping the
2043
2058
  * screen-reader virtual cursor inside the scene's a11y region. */
2044
- __init77() {this.focusSentinel = null}
2045
- __init78() {this.caretBlinkTimer = null}
2046
- __init79() {this.a11yNeedsReorder = true}
2047
- __init80() {this.portalRoot = null}
2048
- __init81() {this.fullViewportElements = []}
2049
- __init82() {this.normalElements = []}
2050
- __init83() {this.activeIds = /* @__PURE__ */ new Set()}
2059
+ __init79() {this.focusSentinel = null}
2060
+ __init80() {this.caretBlinkTimer = null}
2061
+ __init81() {this.a11yNeedsReorder = true}
2062
+ __init82() {this.portalRoot = null}
2063
+ __init83() {this.fullViewportElements = []}
2064
+ __init84() {this.normalElements = []}
2065
+ __init85() {this.activeIds = /* @__PURE__ */ new Set()}
2051
2066
  /** Per-parent insertion cursor, reused by `enforceA11yDomOrder`. */
2052
- __init84() {this.a11yOrderCursors = /* @__PURE__ */ new Map()}
2067
+ __init86() {this.a11yOrderCursors = /* @__PURE__ */ new Map()}
2053
2068
  /** Membership set for the elements being ordered, reused per reorder pass. */
2054
- __init85() {this.a11yOrderMembers = /* @__PURE__ */ new Set()}
2069
+ __init87() {this.a11yOrderMembers = /* @__PURE__ */ new Set()}
2055
2070
  /**
2056
2071
  * Elements that are an *ancestor* of another ordered element, reused per pass.
2057
2072
  *
@@ -2059,11 +2074,11 @@ var Scene = (_class7 = class _Scene {
2059
2074
  * items) spans every descendant row, so it must not extend a visual row band —
2060
2075
  * see {@link sortNormalElementsVisually}.
2061
2076
  */
2062
- __init86() {this.a11yOrderContainers = /* @__PURE__ */ new Set()}
2063
- __init87() {this.activePortalsThisFrame = /* @__PURE__ */ new Set()}
2064
- __init88() {this.activePortalsPrevFrame = /* @__PURE__ */ new Set()}
2065
- __init89() {this.portalEntities = /* @__PURE__ */ new Map()}
2066
- __init90() {this.renderOrderCounter = 0}
2077
+ __init88() {this.a11yOrderContainers = /* @__PURE__ */ new Set()}
2078
+ __init89() {this.activePortalsThisFrame = /* @__PURE__ */ new Set()}
2079
+ __init90() {this.activePortalsPrevFrame = /* @__PURE__ */ new Set()}
2080
+ __init91() {this.portalEntities = /* @__PURE__ */ new Map()}
2081
+ __init92() {this.renderOrderCounter = 0}
2067
2082
  /**
2068
2083
  * Monotonic render-frame counter, bumped once per authoritative `render()`
2069
2084
  * pass. Entities stamp their per-frame world-matrix cache with this value and
@@ -2072,7 +2087,7 @@ var Scene = (_class7 = class _Scene {
2072
2087
  * back to the ancestor walk. Public for the same reason `Entity._getTrig`/
2073
2088
  * `_setWorldCache` are: it is a cross-class render-internal contract.
2074
2089
  */
2075
- __init91() {this.currentFrame = 0}
2090
+ __init93() {this.currentFrame = 0}
2076
2091
  // ── WASM transform backend (invisible accelerator) ──────────────────────────
2077
2092
  // When `_transformBackend === 'wasm'`, the main render walk sources each
2078
2093
  // entity's world matrix from an SoA store composed by `_wasm` (see
@@ -2080,24 +2095,24 @@ var Scene = (_class7 = class _Scene {
2080
2095
  // fallback and the default: a null backend, a non-main renderer, or any entity
2081
2096
  // absent from the store all fall back to the JS composition, so WASM can only
2082
2097
  // ever change *how fast* a world matrix is produced, never *what* it is.
2083
- __init92() {this._wasm = null}
2084
- __init93() {this._transformBackend = "js"}
2098
+ __init94() {this._wasm = null}
2099
+ __init95() {this._transformBackend = "js"}
2085
2100
  // Resident store state (Stage 3). The store layout — slot assignment + sibling
2086
2101
  // runs — depends only on tree TOPOLOGY, so it is rebuilt only when the
2087
2102
  // structure changes (add/remove/reparent bump `_structureVersion`). Between
2088
2103
  // rebuilds the per-frame cost is: gather each entity's transform into the
2089
2104
  // resident wasm input view + run the kernel — no reallocation, no readback.
2090
- __init94() {this._treeStore = null}
2091
- __init95() {this._slotEntity = []}
2105
+ __init96() {this._treeStore = null}
2106
+ __init97() {this._slotEntity = []}
2092
2107
  // store slot -> entity (also validates slots)
2093
- __init96() {this._wasmInputs = null}
2094
- __init97() {this._wasmWorld = null}
2095
- __init98() {this._structureVersion = 0}
2096
- __init99() {this._storeStructureVersion = -1}
2108
+ __init98() {this._wasmInputs = null}
2109
+ __init99() {this._wasmWorld = null}
2110
+ __init100() {this._structureVersion = 0}
2111
+ __init101() {this._storeStructureVersion = -1}
2097
2112
  // Cached list of ComputeParticleEntity instances in the tree, keyed by the
2098
2113
  // structure version it was gathered at. Rebuilt only on a topology change.
2099
- __init100() {this._computeEntities = []}
2100
- __init101() {this._computeEntitiesVersion = -1}
2114
+ __init102() {this._computeEntities = []}
2115
+ __init103() {this._computeEntitiesVersion = -1}
2101
2116
  /** Invalidate the resident WASM store layout; the next wasm-mode frame rebuilds
2102
2117
  * it. Called by `Entity.add`/`remove` (topology changes only). */
2103
2118
  markStructureChanged() {
@@ -2182,7 +2197,7 @@ var Scene = (_class7 = class _Scene {
2182
2197
  * cached globally; the instance is per-Scene, which is the isolation that
2183
2198
  * actually matters.
2184
2199
  */
2185
- __init102() {this._wasmRuntime = null}
2200
+ __init104() {this._wasmRuntime = null}
2186
2201
  /**
2187
2202
  * Load (or reuse) this Scene's shared WASM runtime.
2188
2203
  *
@@ -2210,30 +2225,30 @@ var Scene = (_class7 = class _Scene {
2210
2225
  get wasmRuntime() {
2211
2226
  return this._wasmRuntime;
2212
2227
  }
2213
- __init103() {this._hitWasm = null}
2228
+ __init105() {this._hitWasm = null}
2214
2229
  // Cache key: which frame + structure version the grid was last (successfully,
2215
2230
  // non-overflowing) built for. findEntityAt is called ad-hoc (pointer
2216
2231
  // hover/click), not every frame, so the grid is refreshed lazily on demand
2217
2232
  // rather than proactively every render() — unlike the transform store, which
2218
2233
  // every frame's draw depends on.
2219
- __init104() {this._hitGridFrame = -1}
2220
- __init105() {this._hitGridOk = false}
2221
- __init106() {this._hitSlotEntity = []}
2222
- __init107() {this._hitBoundless = []}
2234
+ __init106() {this._hitGridFrame = -1}
2235
+ __init107() {this._hitGridOk = false}
2236
+ __init108() {this._hitSlotEntity = []}
2237
+ __init109() {this._hitBoundless = []}
2223
2238
  /** Reused buffer for the fused gather, so a pointer query allocates nothing. */
2224
- __init108() {this._hitGatherBuffer = null}
2239
+ __init110() {this._hitGatherBuffer = null}
2225
2240
  /**
2226
2241
  * Whether the last grid build sourced its AABBs from the WASM transform store
2227
2242
  * rather than recomputing them in JS. Diagnostic only — both paths must
2228
2243
  * produce the same entity for a given point.
2229
2244
  */
2230
- __init109() {this._hitFusedGather = false}
2245
+ __init111() {this._hitFusedGather = false}
2231
2246
  /**
2232
2247
  * Whether `compute_aabbs` has run against the current frame's world matrices.
2233
2248
  * The AABB pass is only meaningful after a `compose_*`, so the fused gather
2234
2249
  * must not read the views before then.
2235
2250
  */
2236
- __init110() {this._wasmAabbsFresh = false}
2251
+ __init112() {this._wasmAabbsFresh = false}
2237
2252
  /** Did the last hit-grid build use the fused (WASM-store) gather? */
2238
2253
  get hitGatherPath() {
2239
2254
  return this._hitFusedGather ? "fused" : "js";
@@ -2242,9 +2257,9 @@ var Scene = (_class7 = class _Scene {
2242
2257
  * Why the transform accelerator did or did not run on the most recent frame.
2243
2258
  * Written by the render walk and `_syncWasmStore`.
2244
2259
  */
2245
- __init111() {this._transformReason = "not-installed"}
2260
+ __init113() {this._transformReason = "not-installed"}
2246
2261
  /** Why the batched-driver accelerator did or did not run. */
2247
- __init112() {this._animReason = "not-installed"}
2262
+ __init114() {this._animReason = "not-installed"}
2248
2263
  /**
2249
2264
  * Why the hit-test accelerator did or did not serve the last pointer query.
2250
2265
  * The grid is built lazily on demand, not every frame, so this describes the
@@ -2252,11 +2267,11 @@ var Scene = (_class7 = class _Scene {
2252
2267
  * before a backend exists; `_ensureHitGrid` moves it to `'not-applicable'`
2253
2268
  * once one is installed but nothing has queried yet.
2254
2269
  */
2255
- __init113() {this._hitReason = "not-installed"}
2270
+ __init115() {this._hitReason = "not-installed"}
2256
2271
  /** Why the particle accelerator did or did not run. */
2257
- __init114() {this._particleReason = "not-applicable"}
2272
+ __init116() {this._particleReason = "not-applicable"}
2258
2273
  /** Which particle implementation actually simulated the most recent frame. */
2259
- __init115() {this._particlePath = "none"}
2274
+ __init117() {this._particlePath = "none"}
2260
2275
  /**
2261
2276
  * Per-frame status of every invisible accelerator: whether each is installed,
2262
2277
  * whether it actually ran on the most recent frame, and why.
@@ -2416,25 +2431,25 @@ var Scene = (_class7 = class _Scene {
2416
2431
  // EasingFn (which cannot cross into WASM) all fall through to it — WASM can
2417
2432
  // only ever change *how* a driver is advanced, never *what* value it lands
2418
2433
  // on.
2419
- __init116() {this._animWasm = null}
2434
+ __init118() {this._animWasm = null}
2420
2435
  // Entities with at least one active driver, added by Entity._spawnDriver.
2421
2436
  // Self-pruning: _tickBatchedDrivers drops an entry the first time it visits
2422
2437
  // an entity whose drivers have since all completed or been removed. This is
2423
2438
  // what lets the batch pass find its candidates in O(active drivers), not
2424
2439
  // O(tree size) — the exact mistake G3's first integrated benchmark made.
2425
- __init117() {this._activeDriverEntities = /* @__PURE__ */ new Set()}
2440
+ __init119() {this._activeDriverEntities = /* @__PURE__ */ new Set()}
2426
2441
  // Reused across frames instead of allocating a fresh array + N {entity,prop,
2427
2442
  // driver} objects every call — the integrated benchmark
2428
2443
  // (benchmarks/anim-wasm-scene) found that allocation churn was the
2429
2444
  // dominant integrated cost, not the wasm kernel itself. Parallel arrays,
2430
2445
  // truncated to the live count after each use so a stale tail slot never
2431
2446
  // pins a no-longer-active entity/driver in memory.
2432
- __init118() {this._springEntities = []}
2433
- __init119() {this._springProps = []}
2434
- __init120() {this._springDrivers = []}
2435
- __init121() {this._tweenEntities = []}
2436
- __init122() {this._tweenProps = []}
2437
- __init123() {this._tweenDrivers = []}
2447
+ __init120() {this._springEntities = []}
2448
+ __init121() {this._springProps = []}
2449
+ __init122() {this._springDrivers = []}
2450
+ __init123() {this._tweenEntities = []}
2451
+ __init124() {this._tweenProps = []}
2452
+ __init125() {this._tweenDrivers = []}
2438
2453
  /**
2439
2454
  * Minimum number of batchable (spring, or named-easing tween) active drivers
2440
2455
  * before a frame engages the WASM batch path at all; below it, every driver
@@ -2506,7 +2521,7 @@ var Scene = (_class7 = class _Scene {
2506
2521
  * Setting {@link animDriverGateCount} overwrites all three, so existing code
2507
2522
  * that tuned the single knob keeps working unchanged.
2508
2523
  */
2509
- __init124() {this._animBatchedLastFrame = false}
2524
+ __init126() {this._animBatchedLastFrame = false}
2510
2525
  /**
2511
2526
  * Whether the WASM batch path actually ran on the most recent frame.
2512
2527
  *
@@ -2518,7 +2533,7 @@ var Scene = (_class7 = class _Scene {
2518
2533
  get animBatchedLastFrame() {
2519
2534
  return this._animBatchedLastFrame;
2520
2535
  }
2521
- __init125() {this.animGate = {
2536
+ __init127() {this.animGate = {
2522
2537
  spring: 128,
2523
2538
  tween: 256,
2524
2539
  mixed: 128
@@ -2556,7 +2571,7 @@ var Scene = (_class7 = class _Scene {
2556
2571
  // (benchmarks/particle-wasm). f32 (matches the WGSL shader), bit-identical to
2557
2572
  // a JS f32 reference oracle; updateCPU (f64) stays the permanent fallback when
2558
2573
  // no backend is installed or a scene runs on WebGPU.
2559
- __init126() {this._particleWasm = null}
2574
+ __init128() {this._particleWasm = null}
2560
2575
  /** Which backend runs the CPU particle simulation. Reflects only whether a
2561
2576
  * backend is installed (the WebGPU compute path, when active, is used first
2562
2577
  * regardless). */
@@ -2833,24 +2848,24 @@ var Scene = (_class7 = class _Scene {
2833
2848
  * sync, so retaining the order prevents a newly opened overlay from spending
2834
2849
  * its first frame below previously projected controls.
2835
2850
  */
2836
- __init127() {this.a11yRenderOrders = /* @__PURE__ */ new Map()}
2851
+ __init129() {this.a11yRenderOrders = /* @__PURE__ */ new Map()}
2837
2852
  // Optional WebGL point-cloud layer (see SceneOptions.pointBackend).
2838
- __init128() {this.pointRenderer = null}
2839
- __init129() {this.glCanvas = null}
2840
- __init130() {this.glContextLostHandler = null}
2841
- __init131() {this.glContextRestoredHandler = null}
2853
+ __init130() {this.pointRenderer = null}
2854
+ __init131() {this.glCanvas = null}
2855
+ __init132() {this.glContextLostHandler = null}
2856
+ __init133() {this.glContextRestoredHandler = null}
2842
2857
 
2843
2858
 
2844
2859
 
2845
- __init132() {this.disableWindowResize = false}
2860
+ __init134() {this.disableWindowResize = false}
2846
2861
  /** See {@link SceneOptions.maxDPR}. `undefined` = uncapped (real DPR). */
2847
2862
 
2848
2863
  // WebGPU properties
2849
- __init133() {this.destroyed = false}
2850
- __init134() {this.device = null}
2851
- __init135() {this.deviceLost = false}
2852
- __init136() {this.particleBackend = "auto"}
2853
- __init137() {this._webgpuDisabled = false}
2864
+ __init135() {this.destroyed = false}
2865
+ __init136() {this.device = null}
2866
+ __init137() {this.deviceLost = false}
2867
+ __init138() {this.particleBackend = "auto"}
2868
+ __init139() {this._webgpuDisabled = false}
2854
2869
  get webgpuDisabled() {
2855
2870
  return this._webgpuDisabled || this.particleBackend === "cpu";
2856
2871
  }
@@ -2878,22 +2893,22 @@ var Scene = (_class7 = class _Scene {
2878
2893
  set webgpuDisabled(value) {
2879
2894
  this._webgpuDisabled = value;
2880
2895
  }
2881
- __init138() {this.recoveryTimerId = null}
2882
- __init139() {this.manager = null}
2883
- __init140() {this.initializingWebGPU = false}
2884
- __init141() {this.gpuCanvas = null}
2885
- __init142() {this.gpuContext = null}
2896
+ __init140() {this.recoveryTimerId = null}
2897
+ __init141() {this.manager = null}
2898
+ __init142() {this.initializingWebGPU = false}
2899
+ __init143() {this.gpuCanvas = null}
2900
+ __init144() {this.gpuContext = null}
2886
2901
  /** True while the GPU canvas holds a presented particle frame (needs clearing when they leave). */
2887
- __init143() {this.gpuHasContent = false}
2888
- __init144() {this.mouseX = -9999}
2889
- __init145() {this.mouseY = -9999}
2890
- __init146() {this.pointerMoveListener = null}
2891
- __init147() {this.pointerLeaveListener = null}
2902
+ __init145() {this.gpuHasContent = false}
2903
+ __init146() {this.mouseX = -9999}
2904
+ __init147() {this.mouseY = -9999}
2905
+ __init148() {this.pointerMoveListener = null}
2906
+ __init149() {this.pointerLeaveListener = null}
2892
2907
  /** Element the pointer listeners are bound to (parent container if present,
2893
2908
  * else the canvas). Stored so `destroy()` detaches from the same element. */
2894
- __init148() {this.pointerEventTarget = null}
2895
- __init149() {this.hasWarnedZeroSize = false}
2896
- __init150() {this.fontLoadHandler = null}
2909
+ __init150() {this.pointerEventTarget = null}
2910
+ __init151() {this.hasWarnedZeroSize = false}
2911
+ __init152() {this.fontLoadHandler = null}
2897
2912
  // ── Dev-mode warning infrastructure ──────────────────────────────
2898
2913
  //
2899
2914
  // Enable with `Scene.devMode = true` or by setting `globalThis.__DEV__`.
@@ -2927,7 +2942,7 @@ var Scene = (_class7 = class _Scene {
2927
2942
  return false;
2928
2943
  }
2929
2944
 
2930
- __init151() {this._devFrameCount = 0}
2945
+ __init153() {this._devFrameCount = 0}
2931
2946
  _devWarn(message) {
2932
2947
  if (!this._devActive) return;
2933
2948
  console.warn(`[vectojs/dev] ${message}`);
@@ -3004,7 +3019,7 @@ var Scene = (_class7 = class _Scene {
3004
3019
  };
3005
3020
  walkProjections(this.root);
3006
3021
  }
3007
- constructor(canvas, options = {}) {;_class7.prototype.__init27.call(this);_class7.prototype.__init28.call(this);_class7.prototype.__init29.call(this);_class7.prototype.__init30.call(this);_class7.prototype.__init31.call(this);_class7.prototype.__init32.call(this);_class7.prototype.__init33.call(this);_class7.prototype.__init34.call(this);_class7.prototype.__init35.call(this);_class7.prototype.__init36.call(this);_class7.prototype.__init37.call(this);_class7.prototype.__init38.call(this);_class7.prototype.__init39.call(this);_class7.prototype.__init40.call(this);_class7.prototype.__init41.call(this);_class7.prototype.__init42.call(this);_class7.prototype.__init43.call(this);_class7.prototype.__init44.call(this);_class7.prototype.__init45.call(this);_class7.prototype.__init46.call(this);_class7.prototype.__init47.call(this);_class7.prototype.__init48.call(this);_class7.prototype.__init49.call(this);_class7.prototype.__init50.call(this);_class7.prototype.__init51.call(this);_class7.prototype.__init52.call(this);_class7.prototype.__init53.call(this);_class7.prototype.__init54.call(this);_class7.prototype.__init55.call(this);_class7.prototype.__init56.call(this);_class7.prototype.__init57.call(this);_class7.prototype.__init58.call(this);_class7.prototype.__init59.call(this);_class7.prototype.__init60.call(this);_class7.prototype.__init61.call(this);_class7.prototype.__init62.call(this);_class7.prototype.__init63.call(this);_class7.prototype.__init64.call(this);_class7.prototype.__init65.call(this);_class7.prototype.__init66.call(this);_class7.prototype.__init67.call(this);_class7.prototype.__init68.call(this);_class7.prototype.__init69.call(this);_class7.prototype.__init70.call(this);_class7.prototype.__init71.call(this);_class7.prototype.__init72.call(this);_class7.prototype.__init73.call(this);_class7.prototype.__init74.call(this);_class7.prototype.__init75.call(this);_class7.prototype.__init76.call(this);_class7.prototype.__init77.call(this);_class7.prototype.__init78.call(this);_class7.prototype.__init79.call(this);_class7.prototype.__init80.call(this);_class7.prototype.__init81.call(this);_class7.prototype.__init82.call(this);_class7.prototype.__init83.call(this);_class7.prototype.__init84.call(this);_class7.prototype.__init85.call(this);_class7.prototype.__init86.call(this);_class7.prototype.__init87.call(this);_class7.prototype.__init88.call(this);_class7.prototype.__init89.call(this);_class7.prototype.__init90.call(this);_class7.prototype.__init91.call(this);_class7.prototype.__init92.call(this);_class7.prototype.__init93.call(this);_class7.prototype.__init94.call(this);_class7.prototype.__init95.call(this);_class7.prototype.__init96.call(this);_class7.prototype.__init97.call(this);_class7.prototype.__init98.call(this);_class7.prototype.__init99.call(this);_class7.prototype.__init100.call(this);_class7.prototype.__init101.call(this);_class7.prototype.__init102.call(this);_class7.prototype.__init103.call(this);_class7.prototype.__init104.call(this);_class7.prototype.__init105.call(this);_class7.prototype.__init106.call(this);_class7.prototype.__init107.call(this);_class7.prototype.__init108.call(this);_class7.prototype.__init109.call(this);_class7.prototype.__init110.call(this);_class7.prototype.__init111.call(this);_class7.prototype.__init112.call(this);_class7.prototype.__init113.call(this);_class7.prototype.__init114.call(this);_class7.prototype.__init115.call(this);_class7.prototype.__init116.call(this);_class7.prototype.__init117.call(this);_class7.prototype.__init118.call(this);_class7.prototype.__init119.call(this);_class7.prototype.__init120.call(this);_class7.prototype.__init121.call(this);_class7.prototype.__init122.call(this);_class7.prototype.__init123.call(this);_class7.prototype.__init124.call(this);_class7.prototype.__init125.call(this);_class7.prototype.__init126.call(this);_class7.prototype.__init127.call(this);_class7.prototype.__init128.call(this);_class7.prototype.__init129.call(this);_class7.prototype.__init130.call(this);_class7.prototype.__init131.call(this);_class7.prototype.__init132.call(this);_class7.prototype.__init133.call(this);_class7.prototype.__init134.call(this);_class7.prototype.__init135.call(this);_class7.prototype.__init136.call(this);_class7.prototype.__init137.call(this);_class7.prototype.__init138.call(this);_class7.prototype.__init139.call(this);_class7.prototype.__init140.call(this);_class7.prototype.__init141.call(this);_class7.prototype.__init142.call(this);_class7.prototype.__init143.call(this);_class7.prototype.__init144.call(this);_class7.prototype.__init145.call(this);_class7.prototype.__init146.call(this);_class7.prototype.__init147.call(this);_class7.prototype.__init148.call(this);_class7.prototype.__init149.call(this);_class7.prototype.__init150.call(this);_class7.prototype.__init151.call(this);
3022
+ constructor(canvas, options = {}) {;_class7.prototype.__init27.call(this);_class7.prototype.__init28.call(this);_class7.prototype.__init29.call(this);_class7.prototype.__init30.call(this);_class7.prototype.__init31.call(this);_class7.prototype.__init32.call(this);_class7.prototype.__init33.call(this);_class7.prototype.__init34.call(this);_class7.prototype.__init35.call(this);_class7.prototype.__init36.call(this);_class7.prototype.__init37.call(this);_class7.prototype.__init38.call(this);_class7.prototype.__init39.call(this);_class7.prototype.__init40.call(this);_class7.prototype.__init41.call(this);_class7.prototype.__init42.call(this);_class7.prototype.__init43.call(this);_class7.prototype.__init44.call(this);_class7.prototype.__init45.call(this);_class7.prototype.__init46.call(this);_class7.prototype.__init47.call(this);_class7.prototype.__init48.call(this);_class7.prototype.__init49.call(this);_class7.prototype.__init50.call(this);_class7.prototype.__init51.call(this);_class7.prototype.__init52.call(this);_class7.prototype.__init53.call(this);_class7.prototype.__init54.call(this);_class7.prototype.__init55.call(this);_class7.prototype.__init56.call(this);_class7.prototype.__init57.call(this);_class7.prototype.__init58.call(this);_class7.prototype.__init59.call(this);_class7.prototype.__init60.call(this);_class7.prototype.__init61.call(this);_class7.prototype.__init62.call(this);_class7.prototype.__init63.call(this);_class7.prototype.__init64.call(this);_class7.prototype.__init65.call(this);_class7.prototype.__init66.call(this);_class7.prototype.__init67.call(this);_class7.prototype.__init68.call(this);_class7.prototype.__init69.call(this);_class7.prototype.__init70.call(this);_class7.prototype.__init71.call(this);_class7.prototype.__init72.call(this);_class7.prototype.__init73.call(this);_class7.prototype.__init74.call(this);_class7.prototype.__init75.call(this);_class7.prototype.__init76.call(this);_class7.prototype.__init77.call(this);_class7.prototype.__init78.call(this);_class7.prototype.__init79.call(this);_class7.prototype.__init80.call(this);_class7.prototype.__init81.call(this);_class7.prototype.__init82.call(this);_class7.prototype.__init83.call(this);_class7.prototype.__init84.call(this);_class7.prototype.__init85.call(this);_class7.prototype.__init86.call(this);_class7.prototype.__init87.call(this);_class7.prototype.__init88.call(this);_class7.prototype.__init89.call(this);_class7.prototype.__init90.call(this);_class7.prototype.__init91.call(this);_class7.prototype.__init92.call(this);_class7.prototype.__init93.call(this);_class7.prototype.__init94.call(this);_class7.prototype.__init95.call(this);_class7.prototype.__init96.call(this);_class7.prototype.__init97.call(this);_class7.prototype.__init98.call(this);_class7.prototype.__init99.call(this);_class7.prototype.__init100.call(this);_class7.prototype.__init101.call(this);_class7.prototype.__init102.call(this);_class7.prototype.__init103.call(this);_class7.prototype.__init104.call(this);_class7.prototype.__init105.call(this);_class7.prototype.__init106.call(this);_class7.prototype.__init107.call(this);_class7.prototype.__init108.call(this);_class7.prototype.__init109.call(this);_class7.prototype.__init110.call(this);_class7.prototype.__init111.call(this);_class7.prototype.__init112.call(this);_class7.prototype.__init113.call(this);_class7.prototype.__init114.call(this);_class7.prototype.__init115.call(this);_class7.prototype.__init116.call(this);_class7.prototype.__init117.call(this);_class7.prototype.__init118.call(this);_class7.prototype.__init119.call(this);_class7.prototype.__init120.call(this);_class7.prototype.__init121.call(this);_class7.prototype.__init122.call(this);_class7.prototype.__init123.call(this);_class7.prototype.__init124.call(this);_class7.prototype.__init125.call(this);_class7.prototype.__init126.call(this);_class7.prototype.__init127.call(this);_class7.prototype.__init128.call(this);_class7.prototype.__init129.call(this);_class7.prototype.__init130.call(this);_class7.prototype.__init131.call(this);_class7.prototype.__init132.call(this);_class7.prototype.__init133.call(this);_class7.prototype.__init134.call(this);_class7.prototype.__init135.call(this);_class7.prototype.__init136.call(this);_class7.prototype.__init137.call(this);_class7.prototype.__init138.call(this);_class7.prototype.__init139.call(this);_class7.prototype.__init140.call(this);_class7.prototype.__init141.call(this);_class7.prototype.__init142.call(this);_class7.prototype.__init143.call(this);_class7.prototype.__init144.call(this);_class7.prototype.__init145.call(this);_class7.prototype.__init146.call(this);_class7.prototype.__init147.call(this);_class7.prototype.__init148.call(this);_class7.prototype.__init149.call(this);_class7.prototype.__init150.call(this);_class7.prototype.__init151.call(this);_class7.prototype.__init152.call(this);_class7.prototype.__init153.call(this);
3008
3023
  this.canvas = canvas;
3009
3024
  this.debugA11y = _nullishCoalesce(options.debugA11y, () => ( false));
3010
3025
  this.disableWindowResize = _nullishCoalesce(options.disableWindowResize, () => ( false));
@@ -3028,6 +3043,7 @@ var Scene = (_class7 = class _Scene {
3028
3043
  this.a11ySyncInterval = _nullishCoalesce(options.a11ySyncInterval, () => ( 0));
3029
3044
  this.contentProjectionEnabled = _nullishCoalesce(options.contentProjection, () => ( true));
3030
3045
  this.contentProjectionMargin = options.contentProjectionMargin;
3046
+ this.contentSemanticMargin = options.contentSemanticMargin;
3031
3047
  this.readingDirection = _nullishCoalesce(options.readingDirection, () => ( "ltr"));
3032
3048
  this.renderMode = _nullishCoalesce(options.renderMode, () => ( "always"));
3033
3049
  this._devActive = _Scene._devModeDetected();
@@ -3039,7 +3055,7 @@ var Scene = (_class7 = class _Scene {
3039
3055
  this.forcedColorsChangeHandler = () => this.markDirty();
3040
3056
  _optionalChain([this, 'access', _62 => _62.forcedColorsQuery, 'access', _63 => _63.addEventListener, 'optionalCall', _64 => _64("change", this.forcedColorsChangeHandler)]);
3041
3057
  }
3042
- this.root = new class RootEntity extends _chunk7PI7LVWWjs.Entity {
3058
+ this.root = new class RootEntity extends _chunkTRT2TRCWjs.Entity {
3043
3059
  isPointInside() {
3044
3060
  return false;
3045
3061
  }
@@ -3048,7 +3064,7 @@ var Scene = (_class7 = class _Scene {
3048
3064
  }
3049
3065
  }("root");
3050
3066
  this.root._scene = this;
3051
- this.overlayRoot = new class OverlayRoot extends _chunk7PI7LVWWjs.Entity {
3067
+ this.overlayRoot = new class OverlayRoot extends _chunkTRT2TRCWjs.Entity {
3052
3068
  isPointInside() {
3053
3069
  return false;
3054
3070
  }
@@ -3450,6 +3466,7 @@ var Scene = (_class7 = class _Scene {
3450
3466
  this.clearContentGridState(node.id, contentEl);
3451
3467
  contentEl.remove();
3452
3468
  this.contentElements.delete(node.id);
3469
+ this.contentSyncState.delete(node.id);
3453
3470
  this.a11yNeedsReorder = true;
3454
3471
  }
3455
3472
  const el = this.a11yElements.get(node.id);
@@ -3463,7 +3480,7 @@ var Scene = (_class7 = class _Scene {
3463
3480
  }
3464
3481
  if (this.hoveredA11yElements.has(el)) {
3465
3482
  this.hoveredA11yElements.delete(el);
3466
- node.dispatchEvent(new (0, _chunk7PI7LVWWjs.VectoJSEvent)("pointerleave", node, void 0, false));
3483
+ node.dispatchEvent(new (0, _chunkTRT2TRCWjs.VectoJSEvent)("pointerleave", node, void 0, false));
3467
3484
  }
3468
3485
  this.preserveFocusOnRemoval(el);
3469
3486
  el.remove();
@@ -3594,6 +3611,7 @@ var Scene = (_class7 = class _Scene {
3594
3611
  this.a11yElements.clear();
3595
3612
  for (const el of this.contentElements.values()) el.remove();
3596
3613
  this.contentElements.clear();
3614
+ this.contentSyncState.clear();
3597
3615
  if (typeof cancelAnimationFrame === "function") {
3598
3616
  for (const frame of this.contentGridCalibrationFrames.values()) {
3599
3617
  cancelAnimationFrame(frame);
@@ -4076,20 +4094,20 @@ var Scene = (_class7 = class _Scene {
4076
4094
  el.style.background = "transparent";
4077
4095
  }
4078
4096
  el.addEventListener("click", (e) => {
4079
- node.dispatchEvent(new (0, _chunk7PI7LVWWjs.VectoJSEvent)("click", node, e));
4097
+ node.dispatchEvent(new (0, _chunkTRT2TRCWjs.VectoJSEvent)("click", node, e));
4080
4098
  });
4081
4099
  el.addEventListener("dblclick", (e) => {
4082
- node.dispatchEvent(new (0, _chunk7PI7LVWWjs.VectoJSEvent)("dblclick", node, e));
4100
+ node.dispatchEvent(new (0, _chunkTRT2TRCWjs.VectoJSEvent)("dblclick", node, e));
4083
4101
  });
4084
4102
  el.addEventListener("mouseenter", (e) => {
4085
4103
  if (this.debugA11y) el.style.backgroundColor = "rgba(56, 189, 248, 0.2)";
4086
4104
  this.hoveredA11yElements.add(el);
4087
- node.dispatchEvent(new (0, _chunk7PI7LVWWjs.VectoJSEvent)("hover", node, e, false));
4105
+ node.dispatchEvent(new (0, _chunkTRT2TRCWjs.VectoJSEvent)("hover", node, e, false));
4088
4106
  });
4089
4107
  el.addEventListener("mouseleave", (e) => {
4090
4108
  if (this.debugA11y) el.style.backgroundColor = "rgba(56, 189, 248, 0.05)";
4091
4109
  this.hoveredA11yElements.delete(el);
4092
- node.dispatchEvent(new (0, _chunk7PI7LVWWjs.VectoJSEvent)("pointerleave", node, e, false));
4110
+ node.dispatchEvent(new (0, _chunkTRT2TRCWjs.VectoJSEvent)("pointerleave", node, e, false));
4093
4111
  });
4094
4112
  const capEl = el;
4095
4113
  const releasePointer = (event) => {
@@ -4105,24 +4123,24 @@ var Scene = (_class7 = class _Scene {
4105
4123
  };
4106
4124
  el.addEventListener("pointerdown", (e) => {
4107
4125
  if (typeof capEl.setPointerCapture === "function") capEl.setPointerCapture(e.pointerId);
4108
- node.dispatchEvent(new (0, _chunk7PI7LVWWjs.VectoJSEvent)("pointerdown", node, e));
4126
+ node.dispatchEvent(new (0, _chunkTRT2TRCWjs.VectoJSEvent)("pointerdown", node, e));
4109
4127
  });
4110
4128
  el.addEventListener("pointerup", (e) => {
4111
4129
  releasePointer(e);
4112
- node.dispatchEvent(new (0, _chunk7PI7LVWWjs.VectoJSEvent)("pointerup", node, e));
4130
+ node.dispatchEvent(new (0, _chunkTRT2TRCWjs.VectoJSEvent)("pointerup", node, e));
4113
4131
  });
4114
4132
  el.addEventListener("pointercancel", (e) => {
4115
4133
  releasePointer(e);
4116
- node.dispatchEvent(new (0, _chunk7PI7LVWWjs.VectoJSEvent)("pointercancel", node, e));
4134
+ node.dispatchEvent(new (0, _chunkTRT2TRCWjs.VectoJSEvent)("pointercancel", node, e));
4117
4135
  });
4118
4136
  el.addEventListener(
4119
4137
  "pointermove",
4120
- (e) => node.dispatchEvent(new (0, _chunk7PI7LVWWjs.VectoJSEvent)("pointermove", node, e))
4138
+ (e) => node.dispatchEvent(new (0, _chunkTRT2TRCWjs.VectoJSEvent)("pointermove", node, e))
4121
4139
  );
4122
4140
  el.addEventListener(
4123
4141
  "wheel",
4124
4142
  (e) => {
4125
- node.dispatchEvent(new (0, _chunk7PI7LVWWjs.VectoJSEvent)("wheel", node, e));
4143
+ node.dispatchEvent(new (0, _chunkTRT2TRCWjs.VectoJSEvent)("wheel", node, e));
4126
4144
  },
4127
4145
  { passive: false }
4128
4146
  );
@@ -4147,10 +4165,10 @@ var Scene = (_class7 = class _Scene {
4147
4165
  );
4148
4166
  emitInitialScroll = emitScroll;
4149
4167
  el.addEventListener("keydown", (e) => {
4150
- node.dispatchEvent(new (0, _chunk7PI7LVWWjs.VectoJSEvent)("keydown", node, e));
4168
+ node.dispatchEvent(new (0, _chunkTRT2TRCWjs.VectoJSEvent)("keydown", node, e));
4151
4169
  });
4152
4170
  el.addEventListener("keyup", (e) => {
4153
- node.dispatchEvent(new (0, _chunk7PI7LVWWjs.VectoJSEvent)("keyup", node, e));
4171
+ node.dispatchEvent(new (0, _chunkTRT2TRCWjs.VectoJSEvent)("keyup", node, e));
4154
4172
  });
4155
4173
  if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement) {
4156
4174
  const input = el;
@@ -4216,7 +4234,7 @@ var Scene = (_class7 = class _Scene {
4216
4234
  el.addEventListener("keydown", (e) => {
4217
4235
  if (e.key === "Enter" || e.key === " ") {
4218
4236
  e.preventDefault();
4219
- node.dispatchEvent(new (0, _chunk7PI7LVWWjs.VectoJSEvent)("click", node, e));
4237
+ node.dispatchEvent(new (0, _chunkTRT2TRCWjs.VectoJSEvent)("click", node, e));
4220
4238
  }
4221
4239
  });
4222
4240
  }
@@ -4556,14 +4574,27 @@ var Scene = (_class7 = class _Scene {
4556
4574
  this.contentElements.delete(node.id);
4557
4575
  this.a11yNeedsReorder = true;
4558
4576
  }
4577
+ this.contentSyncState.delete(node.id);
4559
4578
  };
4560
4579
  const worldTf = node.getWorldTransform();
4561
- const margin = _nullishCoalesce(this.contentProjectionMargin, () => ( this.height));
4562
- if (Number.isFinite(margin) && !this.projectionBoxVisible(node, worldTf, margin)) {
4580
+ const interactionMargin = _nullishCoalesce(this.contentProjectionMargin, () => ( this.height));
4581
+ const semanticMargin = _nullishCoalesce(this.contentSemanticMargin, () => ( interactionMargin));
4582
+ if (Number.isFinite(semanticMargin) && !this.projectionBoxVisible(node, worldTf, semanticMargin)) {
4563
4583
  releaseProjectionEl();
4564
4584
  return;
4565
4585
  }
4566
- const lineBand = Number.isFinite(margin) ? this.projectionVisibleLocalYBand(node, worldTf, margin) : null;
4586
+ const inInteractionBand = !Number.isFinite(interactionMargin) || this.projectionBoxVisible(node, worldTf, interactionMargin);
4587
+ const tier = inInteractionBand ? "fine" : "coarse";
4588
+ const lineBand = tier === "coarse" ? null : Number.isFinite(interactionMargin) ? this.projectionVisibleLocalYBand(node, worldTf, interactionMargin) : null;
4589
+ const visible = this.projectionBoxVisible(node, worldTf, 0);
4590
+ const epoch = node.getContentEpoch();
4591
+ const prior = this.contentSyncState.get(node.id);
4592
+ if (epoch !== null && el && prior !== void 0) {
4593
+ const { a: a2, b: b2, c: c2, d: d2, e: e2, f: f2 } = worldTf;
4594
+ if (prior.epoch === epoch && prior.fontEpoch === this.contentFontEpoch && prior.a === a2 && prior.b === b2 && prior.c === c2 && prior.d === d2 && prior.e === e2 && prior.f === f2 && prior.tier === tier && prior.hasBand === (lineBand !== null) && (lineBand === null || prior.bandMin === lineBand.minY && prior.bandMax === lineBand.maxY) && prior.visible === visible && prior.width === node.width && prior.height === node.height && prior.interactive === node.interactive) {
4595
+ return;
4596
+ }
4597
+ }
4567
4598
  const projection = node.getContentProjection(
4568
4599
  lineBand ? { minY: lineBand.minY, maxY: lineBand.maxY } : void 0
4569
4600
  );
@@ -4587,7 +4618,7 @@ var Scene = (_class7 = class _Scene {
4587
4618
  el.addEventListener(
4588
4619
  "wheel",
4589
4620
  (e2) => {
4590
- node.dispatchEvent(new (0, _chunk7PI7LVWWjs.VectoJSEvent)("wheel", node, e2));
4621
+ node.dispatchEvent(new (0, _chunkTRT2TRCWjs.VectoJSEvent)("wheel", node, e2));
4591
4622
  },
4592
4623
  { passive: false }
4593
4624
  );
@@ -4596,14 +4627,15 @@ var Scene = (_class7 = class _Scene {
4596
4627
  this.a11yNeedsReorder = true;
4597
4628
  }
4598
4629
  const lines = projection.lines;
4599
- if (!projection.grid && el.dataset.vectoContentGrid !== void 0) {
4630
+ const useCarriers = tier === "fine";
4631
+ if ((!projection.grid || !useCarriers) && el.dataset.vectoContentGrid !== void 0) {
4600
4632
  this.clearContentGridState(node.id, el);
4601
4633
  }
4602
- if (projection.grid) {
4634
+ if (projection.grid && useCarriers) {
4603
4635
  const gridSyncStart = this._phaseTiming ? performance.now() : 0;
4604
4636
  this.syncContentGridProjection(node, el, projection, projection.grid, lineBand);
4605
4637
  if (this._phaseTiming) this._recordPhase("gridSync", performance.now() - gridSyncStart);
4606
- } else if (lines && lines.length > 0) {
4638
+ } else if (useCarriers && lines && lines.length > 0) {
4607
4639
  const lineWindow = projectionLineWindow(lines, lineBand, _nullishCoalesce(projection.lineHeight, () => ( 16)));
4608
4640
  const signature = JSON.stringify({
4609
4641
  lines,
@@ -4666,11 +4698,13 @@ var Scene = (_class7 = class _Scene {
4666
4698
  }
4667
4699
  }
4668
4700
  } else {
4669
- if (el.textContent !== projection.text) {
4701
+ const demoted = tier === "coarse" && el.children.length > 0;
4702
+ if (el.textContent !== projection.text || demoted) {
4670
4703
  this.releaseContentSelectionForRebuild(el);
4671
4704
  el.textContent = projection.text;
4672
4705
  }
4673
4706
  delete el.dataset.vectoProjectionLines;
4707
+ if (tier === "coarse") delete el.dataset.vectoProjectionWindow;
4674
4708
  }
4675
4709
  const font = _nullishCoalesce(projection.font, () => ( ""));
4676
4710
  if (el.style.font !== font) el.style.font = font;
@@ -4703,9 +4737,29 @@ var Scene = (_class7 = class _Scene {
4703
4737
  if (node.width > 0) el.style.width = `${node.width}px`;
4704
4738
  if (node.height > 0) el.style.height = `${node.height}px`;
4705
4739
  el.style.transform = `matrix(${a}, ${b}, ${c}, ${d}, 0, 0)`;
4706
- const visible = this.projectionBoxVisible(node, worldTf, 0);
4707
4740
  const display = visible ? "" : "none";
4708
4741
  if (el.style.display !== display) el.style.display = display;
4742
+ if (epoch !== null) {
4743
+ const { a: a2, b: b2, c: c2, d: d2, e: e2, f: f2 } = worldTf;
4744
+ const next = _nullishCoalesce(prior, () => ( {}));
4745
+ next.epoch = epoch;
4746
+ next.fontEpoch = this.contentFontEpoch;
4747
+ next.a = a2;
4748
+ next.b = b2;
4749
+ next.c = c2;
4750
+ next.d = d2;
4751
+ next.e = e2;
4752
+ next.f = f2;
4753
+ next.tier = tier;
4754
+ next.hasBand = lineBand !== null;
4755
+ next.bandMin = _nullishCoalesce(_optionalChain([lineBand, 'optionalAccess', _132 => _132.minY]), () => ( 0));
4756
+ next.bandMax = _nullishCoalesce(_optionalChain([lineBand, 'optionalAccess', _133 => _133.maxY]), () => ( 0));
4757
+ next.visible = visible;
4758
+ next.width = node.width;
4759
+ next.height = node.height;
4760
+ next.interactive = node.interactive;
4761
+ if (prior === void 0) this.contentSyncState.set(node.id, next);
4762
+ }
4709
4763
  }
4710
4764
  /**
4711
4765
  * Materialize a prepared grid in logical source order while positioning each
@@ -4729,9 +4783,9 @@ var Scene = (_class7 = class _Scene {
4729
4783
  const domIndex = lineIndex - gridWindow.start;
4730
4784
  const gridLine = grid.lines[lineIndex];
4731
4785
  const projectedLine = projectionLines[lineIndex];
4732
- const lineHeight = _nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess', _132 => _132.lineHeight]), () => ( grid.lineHeight));
4733
- const baseline = _nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess', _133 => _133.baseline]), () => ( grid.baseline));
4734
- const lineFont = _nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess', _134 => _134.font]), () => ( grid.font));
4786
+ const lineHeight = _nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess', _134 => _134.lineHeight]), () => ( grid.lineHeight));
4787
+ const baseline = _nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess', _135 => _135.baseline]), () => ( grid.baseline));
4788
+ const lineFont = _nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess', _136 => _136.font]), () => ( grid.font));
4735
4789
  const lineSignature = contentGridLineSignature(
4736
4790
  grid,
4737
4791
  gridLine,
@@ -4751,8 +4805,8 @@ var Scene = (_class7 = class _Scene {
4751
4805
  lineElement.dir = "ltr";
4752
4806
  lineElement.dataset.vectoGridLine = `${lineIndex}`;
4753
4807
  lineElement.style.position = "absolute";
4754
- lineElement.style.left = `${_nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess', _135 => _135.x]), () => ( 0))}px`;
4755
- lineElement.style.top = `${(_nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess', _136 => _136.y]), () => ( lineIndex * grid.lineHeight))) + baseline - _text.cssLineBoxBaseline.call(void 0, lineFont, lineHeight)}px`;
4808
+ lineElement.style.left = `${_nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess', _137 => _137.x]), () => ( 0))}px`;
4809
+ lineElement.style.top = `${(_nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess', _138 => _138.y]), () => ( lineIndex * grid.lineHeight))) + baseline - _text.cssLineBoxBaseline.call(void 0, lineFont, lineHeight)}px`;
4756
4810
  lineElement.style.width = `${gridLine.width}px`;
4757
4811
  lineElement.style.height = `${lineHeight}px`;
4758
4812
  lineElement.style.whiteSpace = "pre";
@@ -4823,7 +4877,7 @@ var Scene = (_class7 = class _Scene {
4823
4877
  if (selectionLine !== null && selectionLine >= gridWindow.end) {
4824
4878
  rebuiltSelectionLine = true;
4825
4879
  }
4826
- _optionalChain([el, 'access', _137 => _137.lastElementChild, 'optionalAccess', _138 => _138.remove, 'call', _139 => _139()]);
4880
+ _optionalChain([el, 'access', _139 => _139.lastElementChild, 'optionalAccess', _140 => _140.remove, 'call', _141 => _141()]);
4827
4881
  }
4828
4882
  if (rebuiltSelectionLine) this.releaseContentSelectionForRebuild(el);
4829
4883
  el.dataset.vectoProjectionLines = signature;
@@ -4892,7 +4946,7 @@ var Scene = (_class7 = class _Scene {
4892
4946
  if (previous !== void 0 && typeof cancelAnimationFrame === "function") {
4893
4947
  cancelAnimationFrame(previous);
4894
4948
  }
4895
- _optionalChain([this, 'access', _140 => _140.contentGridCalibrationProbes, 'access', _141 => _141.get, 'call', _142 => _142(entityId), 'optionalAccess', _143 => _143.remove, 'call', _144 => _144()]);
4949
+ _optionalChain([this, 'access', _142 => _142.contentGridCalibrationProbes, 'access', _143 => _143.get, 'call', _144 => _144(entityId), 'optionalAccess', _145 => _145.remove, 'call', _146 => _146()]);
4896
4950
  this.contentGridCalibrationProbes.delete(entityId);
4897
4951
  const calibrationStart = typeof performance !== "undefined" ? performance.now() : 0;
4898
4952
  const probe = document.createElement("div");
@@ -4926,7 +4980,7 @@ var Scene = (_class7 = class _Scene {
4926
4980
  target.dataset.vectoGridCalib = generation;
4927
4981
  continue;
4928
4982
  }
4929
- const sourceText = _nullishCoalesce(_optionalChain([target, 'access', _145 => _145.textContent, 'optionalAccess', _146 => _146.slice, 'call', _147 => _147(0, sourceLength)]), () => ( ""));
4983
+ const sourceText = _nullishCoalesce(_optionalChain([target, 'access', _147 => _147.textContent, 'optionalAccess', _148 => _148.slice, 'call', _149 => _149(0, sourceLength)]), () => ( ""));
4930
4984
  if (!sourceText) {
4931
4985
  target.dataset.vectoGridCalib = generation;
4932
4986
  continue;
@@ -5173,12 +5227,12 @@ var Scene = (_class7 = class _Scene {
5173
5227
  syncOverlayGeometry() {
5174
5228
  const parent = this.canvas.parentElement;
5175
5229
  if (!parent) return;
5176
- const canvasRect = _optionalChain([this, 'access', _148 => _148.canvas, 'access', _149 => _149.getBoundingClientRect, 'optionalCall', _150 => _150()]);
5177
- const parentRect = _optionalChain([parent, 'access', _151 => _151.getBoundingClientRect, 'optionalCall', _152 => _152()]);
5178
- const cssWidth = _optionalChain([canvasRect, 'optionalAccess', _153 => _153.width]) || this.canvas.clientWidth || this.width;
5179
- const cssHeight = _optionalChain([canvasRect, 'optionalAccess', _154 => _154.height]) || this.canvas.clientHeight || this.height;
5180
- const left = (_nullishCoalesce(_optionalChain([canvasRect, 'optionalAccess', _155 => _155.left]), () => ( 0))) - (_nullishCoalesce(_optionalChain([parentRect, 'optionalAccess', _156 => _156.left]), () => ( 0))) - (parent.clientLeft || 0) + parent.scrollLeft;
5181
- const top = (_nullishCoalesce(_optionalChain([canvasRect, 'optionalAccess', _157 => _157.top]), () => ( 0))) - (_nullishCoalesce(_optionalChain([parentRect, 'optionalAccess', _158 => _158.top]), () => ( 0))) - (parent.clientTop || 0) + parent.scrollTop;
5230
+ const canvasRect = _optionalChain([this, 'access', _150 => _150.canvas, 'access', _151 => _151.getBoundingClientRect, 'optionalCall', _152 => _152()]);
5231
+ const parentRect = _optionalChain([parent, 'access', _153 => _153.getBoundingClientRect, 'optionalCall', _154 => _154()]);
5232
+ const cssWidth = _optionalChain([canvasRect, 'optionalAccess', _155 => _155.width]) || this.canvas.clientWidth || this.width;
5233
+ const cssHeight = _optionalChain([canvasRect, 'optionalAccess', _156 => _156.height]) || this.canvas.clientHeight || this.height;
5234
+ const left = (_nullishCoalesce(_optionalChain([canvasRect, 'optionalAccess', _157 => _157.left]), () => ( 0))) - (_nullishCoalesce(_optionalChain([parentRect, 'optionalAccess', _158 => _158.left]), () => ( 0))) - (parent.clientLeft || 0) + parent.scrollLeft;
5235
+ const top = (_nullishCoalesce(_optionalChain([canvasRect, 'optionalAccess', _159 => _159.top]), () => ( 0))) - (_nullishCoalesce(_optionalChain([parentRect, 'optionalAccess', _160 => _160.top]), () => ( 0))) - (parent.clientTop || 0) + parent.scrollTop;
5182
5236
  const scaleX = this.width > 0 ? cssWidth / this.width : 1;
5183
5237
  const scaleY = this.height > 0 ? cssHeight / this.height : 1;
5184
5238
  const prev = this._overlayGeometry;
@@ -5317,7 +5371,7 @@ var Scene = (_class7 = class _Scene {
5317
5371
  * (and {@link respectReducedMotion} is on). `0` means uncapped.
5318
5372
  */
5319
5373
  effectiveMaxFPS() {
5320
- const reduced = this.respectReducedMotion && !!_optionalChain([this, 'access', _159 => _159.reducedMotionQuery, 'optionalAccess', _160 => _160.matches]);
5374
+ const reduced = this.respectReducedMotion && !!_optionalChain([this, 'access', _161 => _161.reducedMotionQuery, 'optionalAccess', _162 => _162.matches]);
5321
5375
  if (reduced)
5322
5376
  return this.maxFPS > 0 ? Math.min(this.maxFPS, REDUCED_MOTION_FPS) : REDUCED_MOTION_FPS;
5323
5377
  return this.maxFPS;
@@ -5412,7 +5466,7 @@ var Scene = (_class7 = class _Scene {
5412
5466
  * @param time - Current absolute time in milliseconds (default 0).
5413
5467
  */
5414
5468
  render(renderer, dt = 0, time = 0) {
5415
- if (_optionalChain([renderer, 'access', _161 => _161.isContextLost, 'optionalCall', _162 => _162()])) return;
5469
+ if (_optionalChain([renderer, 'access', _163 => _163.isContextLost, 'optionalCall', _164 => _164()])) return;
5416
5470
  const isMainRenderer = renderer === this.renderer;
5417
5471
  if (isMainRenderer && this.a11yRoot && this.canvas.parentElement) {
5418
5472
  const parentStyle = this.canvas.parentElement.style;
@@ -5556,14 +5610,14 @@ var Scene = (_class7 = class _Scene {
5556
5610
  }
5557
5611
  renderer.clear();
5558
5612
  if (isMainRenderer) {
5559
- _optionalChain([this, 'access', _163 => _163.pointRenderer, 'optionalAccess', _164 => _164.begin, 'call', _165 => _165()]);
5613
+ _optionalChain([this, 'access', _165 => _165.pointRenderer, 'optionalAccess', _166 => _166.begin, 'call', _167 => _167()]);
5560
5614
  }
5561
5615
  const vw = this.width;
5562
5616
  const vh = this.height;
5563
5617
  let walkHadAnimation = false;
5564
5618
  let walkHadInteractive = false;
5565
5619
  const runUpdate = (node) => {
5566
- const overridesUpdate = node.update !== _chunk7PI7LVWWjs.Entity.prototype.update;
5620
+ const overridesUpdate = node.update !== _chunkTRT2TRCWjs.Entity.prototype.update;
5567
5621
  let pending = node.hasPendingAnimations();
5568
5622
  if (pending || overridesUpdate) {
5569
5623
  node.update(dt, time);
@@ -5572,7 +5626,7 @@ var Scene = (_class7 = class _Scene {
5572
5626
  if (pending) walkHadAnimation = true;
5573
5627
  if (!walkHadInteractive && node.interactive) walkHadInteractive = true;
5574
5628
  if (this._devActive && this._devFrameCount % 120 === 0) {
5575
- if (overridesUpdate && node.hasPendingAnimations === _chunk7PI7LVWWjs.Entity.prototype.hasPendingAnimations) {
5629
+ if (overridesUpdate && node.hasPendingAnimations === _chunkTRT2TRCWjs.Entity.prototype.hasPendingAnimations) {
5576
5630
  this._devWarn(
5577
5631
  `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.`
5578
5632
  );
@@ -5770,9 +5824,9 @@ var Scene = (_class7 = class _Scene {
5770
5824
  const flushT0 = this._phaseTiming ? performance.now() : 0;
5771
5825
  renderer.flush();
5772
5826
  if (isMainRenderer) {
5773
- _optionalChain([this, 'access', _166 => _166.pointRenderer, 'optionalAccess', _167 => _167.flush, 'call', _168 => _168()]);
5827
+ _optionalChain([this, 'access', _168 => _168.pointRenderer, 'optionalAccess', _169 => _169.flush, 'call', _170 => _170()]);
5774
5828
  }
5775
- _optionalChain([renderer, 'access', _169 => _169.present, 'optionalCall', _170 => _170()]);
5829
+ _optionalChain([renderer, 'access', _171 => _171.present, 'optionalCall', _172 => _172()]);
5776
5830
  if (this._phaseTiming) this._recordPhase("flush", performance.now() - flushT0);
5777
5831
  if (flushTiming) endVectoUserTiming(flushTiming);
5778
5832
  if (this._devActive) {
@@ -6053,8 +6107,8 @@ function pointInBounds(b, x, y) {
6053
6107
  function contentGridLineSignature(grid, line, projected, lineHeight, baseline, font, isFirstLine) {
6054
6108
  const parts = [
6055
6109
  // Line box: position, size, and the font that resolves its baseline.
6056
- `${_nullishCoalesce(_optionalChain([projected, 'optionalAccess', _171 => _171.x]), () => ( 0))}`,
6057
- `${_nullishCoalesce(_optionalChain([projected, 'optionalAccess', _172 => _172.y]), () => ( ""))}`,
6110
+ `${_nullishCoalesce(_optionalChain([projected, 'optionalAccess', _173 => _173.x]), () => ( 0))}`,
6111
+ `${_nullishCoalesce(_optionalChain([projected, 'optionalAccess', _174 => _174.y]), () => ( ""))}`,
6058
6112
  `${lineHeight}`,
6059
6113
  `${baseline}`,
6060
6114
  font,
@@ -6096,20 +6150,22 @@ function defaultMeasurer() {
6096
6150
  sharedMeasurer ??= _layout.resolveGlyphMeasurer.call(void 0, "sans-serif");
6097
6151
  return sharedMeasurer;
6098
6152
  }
6099
- var TextEntity = (_class8 = class extends _chunk7PI7LVWWjs.Entity {
6153
+ var TextEntity = (_class8 = class extends _chunkTRT2TRCWjs.Entity {
6100
6154
 
6101
6155
 
6102
6156
 
6103
6157
 
6104
- __init152() {this.nodes = []}
6158
+ __init154() {this.nodes = []}
6105
6159
 
6106
- __init153() {this.fillStyle = "#94a3b8"}
6107
- __init154() {this.strokeStyle = null}
6108
- __init155() {this.hoveredFillStyle = "#ffffff"}
6109
- __init156() {this.lineWidth = 1}
6110
- __init157() {this.isHovered = false}
6160
+ __init155() {this.fillStyle = "#94a3b8"}
6161
+ __init156() {this.strokeStyle = null}
6162
+ __init157() {this.hoveredFillStyle = "#ffffff"}
6163
+ __init158() {this.lineWidth = 1}
6164
+ __init159() {this.isHovered = false}
6165
+ /** Bumped by {@link applyLayout}; read by `Scene` to skip an unchanged sync. */
6166
+ __init160() {this.contentEpoch = 0}
6111
6167
  constructor(text, atlas, maxWidth, fontSize = 24) {
6112
- super();_class8.prototype.__init152.call(this);_class8.prototype.__init153.call(this);_class8.prototype.__init154.call(this);_class8.prototype.__init155.call(this);_class8.prototype.__init156.call(this);_class8.prototype.__init157.call(this);;
6168
+ super();_class8.prototype.__init154.call(this);_class8.prototype.__init155.call(this);_class8.prototype.__init156.call(this);_class8.prototype.__init157.call(this);_class8.prototype.__init158.call(this);_class8.prototype.__init159.call(this);_class8.prototype.__init160.call(this);;
6113
6169
  this.text = text;
6114
6170
  this.atlas = atlas;
6115
6171
  this.fontSize = fontSize;
@@ -6128,6 +6184,9 @@ var TextEntity = (_class8 = class extends _chunk7PI7LVWWjs.Entity {
6128
6184
  if (!this.text) return null;
6129
6185
  return { text: this.text, font: `${this.fontSize}px sans-serif` };
6130
6186
  }
6187
+ getContentEpoch() {
6188
+ return this.contentEpoch;
6189
+ }
6131
6190
  /**
6132
6191
  * Replace the text content. Runs the **cold** measurement pass (re-segment +
6133
6192
  * re-measure) since the glyphs changed, then re-lays out.
@@ -6174,6 +6233,7 @@ var TextEntity = (_class8 = class extends _chunk7PI7LVWWjs.Entity {
6174
6233
  }
6175
6234
  /** Hot pass: place the cached {@link PreparedText} and refresh the a11y box. */
6176
6235
  applyLayout() {
6236
+ this.contentEpoch++;
6177
6237
  const result = this.layout.layoutPrepared(this.prepared);
6178
6238
  this.nodes = result.nodes;
6179
6239
  this.width = result.totalWidth;
@@ -6222,17 +6282,17 @@ var TextEntity = (_class8 = class extends _chunk7PI7LVWWjs.Entity {
6222
6282
  }, _class8);
6223
6283
 
6224
6284
  // src/components/GridTextEntity.ts
6225
- var GridTextEntity = (_class9 = class extends _chunk7PI7LVWWjs.Entity {
6285
+ var GridTextEntity = (_class9 = class extends _chunkTRT2TRCWjs.Entity {
6226
6286
 
6227
- __init158() {this.fillStyle = "#ffffff"}
6228
- __init159() {this.grid = []}
6287
+ __init161() {this.fillStyle = "#ffffff"}
6288
+ __init162() {this.grid = []}
6229
6289
  // Array of rows
6230
- __init160() {this.cols = 0}
6231
- __init161() {this.rows = 0}
6290
+ __init163() {this.cols = 0}
6291
+ __init164() {this.rows = 0}
6232
6292
 
6233
6293
 
6234
6294
  constructor(_atlas, fontSize = 10) {
6235
- super();_class9.prototype.__init158.call(this);_class9.prototype.__init159.call(this);_class9.prototype.__init160.call(this);_class9.prototype.__init161.call(this);;
6295
+ super();_class9.prototype.__init161.call(this);_class9.prototype.__init162.call(this);_class9.prototype.__init163.call(this);_class9.prototype.__init164.call(this);;
6236
6296
  this.fontSize = fontSize;
6237
6297
  this.charWidth = fontSize * 1;
6238
6298
  this.charHeight = fontSize * 1.1;
@@ -6241,7 +6301,7 @@ var GridTextEntity = (_class9 = class extends _chunk7PI7LVWWjs.Entity {
6241
6301
  updateGrid(ascii) {
6242
6302
  this.grid = ascii;
6243
6303
  this.rows = ascii.length;
6244
- this.cols = _optionalChain([ascii, 'access', _173 => _173[0], 'optionalAccess', _174 => _174.length]) || 0;
6304
+ this.cols = _optionalChain([ascii, 'access', _175 => _175[0], 'optionalAccess', _176 => _176.length]) || 0;
6245
6305
  }
6246
6306
  isPointInside(_globalX, _globalY) {
6247
6307
  return false;
@@ -6316,7 +6376,7 @@ function distSqToSegment(px, py, x1, y1, x2, y2) {
6316
6376
  const ey = py - cy;
6317
6377
  return ex * ex + ey * ey;
6318
6378
  }
6319
- var SplineEntity = (_class10 = class extends _chunk7PI7LVWWjs.Entity {
6379
+ var SplineEntity = (_class10 = class extends _chunkTRT2TRCWjs.Entity {
6320
6380
 
6321
6381
 
6322
6382
 
@@ -6324,23 +6384,23 @@ var SplineEntity = (_class10 = class extends _chunk7PI7LVWWjs.Entity {
6324
6384
 
6325
6385
 
6326
6386
 
6327
- __init162() {this.offscreen = null}
6328
- __init163() {this.baked = false}
6387
+ __init165() {this.offscreen = null}
6388
+ __init166() {this.baked = false}
6329
6389
  /** Logical (CSS-pixel) size of the baked bitmap — the blit destination size. */
6330
- __init164() {this.bakedWidth = 0}
6331
- __init165() {this.bakedHeight = 0}
6390
+ __init167() {this.bakedWidth = 0}
6391
+ __init168() {this.bakedHeight = 0}
6332
6392
  /** Gradient strokes can't be baked to a solid-color bitmap; they render per-frame. */
6333
6393
 
6334
6394
  /** Lazily-flattened polylines (one Float32Array of [x,y,...] per segment) for hit-testing. */
6335
- __init166() {this.polylines = null}
6395
+ __init169() {this.polylines = null}
6336
6396
  /**
6337
6397
  * When `true`, the renderer draws a rounded-rect outline of the entity's
6338
6398
  * local bounds after painting the curves. Useful for drag feedback and
6339
6399
  * debugging hit areas. Defaults to `false`.
6340
6400
  */
6341
- __init167() {this.showBounds = false}
6401
+ __init170() {this.showBounds = false}
6342
6402
  constructor(doc, opts = {}) {
6343
- super();_class10.prototype.__init162.call(this);_class10.prototype.__init163.call(this);_class10.prototype.__init164.call(this);_class10.prototype.__init165.call(this);_class10.prototype.__init166.call(this);_class10.prototype.__init167.call(this);;
6403
+ super();_class10.prototype.__init165.call(this);_class10.prototype.__init166.call(this);_class10.prototype.__init167.call(this);_class10.prototype.__init168.call(this);_class10.prototype.__init169.call(this);_class10.prototype.__init170.call(this);;
6344
6404
  this.doc = doc;
6345
6405
  this.lineWidth = _nullishCoalesce(opts.lineWidth, () => ( 2));
6346
6406
  this.cache = _nullishCoalesce(opts.cache, () => ( true));
@@ -6351,7 +6411,7 @@ var SplineEntity = (_class10 = class extends _chunk7PI7LVWWjs.Entity {
6351
6411
  this.width = this.bounds.width;
6352
6412
  this.height = this.bounds.height;
6353
6413
  const isGradient = (c) => c !== null && !Array.isArray(c);
6354
- this.containsGradient = (_nullishCoalesce(_optionalChain([this, 'access', _175 => _175.doc, 'access', _176 => _176.equations, 'optionalAccess', _177 => _177.some, 'call', _178 => _178((eq) => isGradient(eq.color_rgb))]), () => ( false))) || (_nullishCoalesce(_optionalChain([this, 'access', _179 => _179.doc, 'access', _180 => _180.paths, 'optionalAccess', _181 => _181.some, 'call', _182 => _182((p) => isGradient(p.color_rgb))]), () => ( false)));
6414
+ this.containsGradient = (_nullishCoalesce(_optionalChain([this, 'access', _177 => _177.doc, 'access', _178 => _178.equations, 'optionalAccess', _179 => _179.some, 'call', _180 => _180((eq) => isGradient(eq.color_rgb))]), () => ( false))) || (_nullishCoalesce(_optionalChain([this, 'access', _181 => _181.doc, 'access', _182 => _182.paths, 'optionalAccess', _183 => _183.some, 'call', _184 => _184((p) => isGradient(p.color_rgb))]), () => ( false)));
6355
6415
  this.interactive = true;
6356
6416
  }
6357
6417
  computeBounds() {
@@ -6591,7 +6651,7 @@ async function loadSpline(url) {
6591
6651
  }
6592
6652
 
6593
6653
  // src/components/Rect.ts
6594
- var Rect = class extends _chunk7PI7LVWWjs.Entity {
6654
+ var Rect = class extends _chunkTRT2TRCWjs.Entity {
6595
6655
 
6596
6656
 
6597
6657
 
@@ -6640,7 +6700,7 @@ var Rect = class extends _chunk7PI7LVWWjs.Entity {
6640
6700
  };
6641
6701
 
6642
6702
  // src/components/Circle.ts
6643
- var Circle = class extends _chunk7PI7LVWWjs.Entity {
6703
+ var Circle = class extends _chunkTRT2TRCWjs.Entity {
6644
6704
 
6645
6705
 
6646
6706
 
@@ -6700,7 +6760,7 @@ var Circle = class extends _chunk7PI7LVWWjs.Entity {
6700
6760
  };
6701
6761
 
6702
6762
  // src/components/Group.ts
6703
- var Group = class extends _chunk7PI7LVWWjs.Entity {
6763
+ var Group = class extends _chunkTRT2TRCWjs.Entity {
6704
6764
  constructor(...children) {
6705
6765
  super();
6706
6766
  if (children.length > 0) this.add(...children);
@@ -6719,21 +6779,21 @@ var _math = require('@vectojs/math'); _createStarExport(_math);
6719
6779
 
6720
6780
 
6721
6781
  // src/tree/DOMPortalEntity.ts
6722
- var DOMPortalEntity = (_class11 = class extends _chunk7PI7LVWWjs.Entity {
6782
+ var DOMPortalEntity = (_class11 = class extends _chunkTRT2TRCWjs.Entity {
6723
6783
 
6724
- __init168() {this.isDOMPortal = true}
6725
- __init169() {this.domListeners = []}
6726
- __init170() {this.resizeObserver = null}
6727
- __init171() {this.domBound = false}
6728
- __init172() {this.cachedWidth = 100}
6729
- __init173() {this.cachedHeight = 100}
6730
- __init174() {this.lastWidth = ""}
6731
- __init175() {this.lastHeight = ""}
6732
- __init176() {this.lastTransform = ""}
6733
- __init177() {this.lastZIndex = ""}
6734
- __init178() {this.lastOpacity = ""}
6784
+ __init171() {this.isDOMPortal = true}
6785
+ __init172() {this.domListeners = []}
6786
+ __init173() {this.resizeObserver = null}
6787
+ __init174() {this.domBound = false}
6788
+ __init175() {this.cachedWidth = 100}
6789
+ __init176() {this.cachedHeight = 100}
6790
+ __init177() {this.lastWidth = ""}
6791
+ __init178() {this.lastHeight = ""}
6792
+ __init179() {this.lastTransform = ""}
6793
+ __init180() {this.lastZIndex = ""}
6794
+ __init181() {this.lastOpacity = ""}
6735
6795
  constructor(domElement, width, height, id) {
6736
- super(id);_class11.prototype.__init168.call(this);_class11.prototype.__init169.call(this);_class11.prototype.__init170.call(this);_class11.prototype.__init171.call(this);_class11.prototype.__init172.call(this);_class11.prototype.__init173.call(this);_class11.prototype.__init174.call(this);_class11.prototype.__init175.call(this);_class11.prototype.__init176.call(this);_class11.prototype.__init177.call(this);_class11.prototype.__init178.call(this);;
6796
+ super(id);_class11.prototype.__init171.call(this);_class11.prototype.__init172.call(this);_class11.prototype.__init173.call(this);_class11.prototype.__init174.call(this);_class11.prototype.__init175.call(this);_class11.prototype.__init176.call(this);_class11.prototype.__init177.call(this);_class11.prototype.__init178.call(this);_class11.prototype.__init179.call(this);_class11.prototype.__init180.call(this);_class11.prototype.__init181.call(this);;
6737
6797
  this.domElement = domElement;
6738
6798
  this.width = _nullishCoalesce(width, () => ( 0));
6739
6799
  this.height = _nullishCoalesce(height, () => ( 0));
@@ -6775,7 +6835,7 @@ var DOMPortalEntity = (_class11 = class extends _chunk7PI7LVWWjs.Entity {
6775
6835
  ];
6776
6836
  for (const type of events) {
6777
6837
  const handler = (e) => {
6778
- this.dispatchEvent(new (0, _chunk7PI7LVWWjs.VectoJSEvent)(type, this, e));
6838
+ this.dispatchEvent(new (0, _chunkTRT2TRCWjs.VectoJSEvent)(type, this, e));
6779
6839
  };
6780
6840
  this.domElement.addEventListener(type, handler);
6781
6841
  this.domListeners.push({ type, handler, capture: false });
@@ -6786,7 +6846,7 @@ var DOMPortalEntity = (_class11 = class extends _chunk7PI7LVWWjs.Entity {
6786
6846
  ];
6787
6847
  for (const { native, vecto } of hoverEvents) {
6788
6848
  const handler = (e) => {
6789
- this.dispatchEvent(new (0, _chunk7PI7LVWWjs.VectoJSEvent)(vecto, this, e, false));
6849
+ this.dispatchEvent(new (0, _chunkTRT2TRCWjs.VectoJSEvent)(vecto, this, e, false));
6790
6850
  };
6791
6851
  this.domElement.addEventListener(native, handler);
6792
6852
  this.domListeners.push({ type: native, handler, capture: false });
@@ -6794,7 +6854,7 @@ var DOMPortalEntity = (_class11 = class extends _chunk7PI7LVWWjs.Entity {
6794
6854
  const focusEvents = ["focus", "blur"];
6795
6855
  for (const type of focusEvents) {
6796
6856
  const handler = (e) => {
6797
- this.dispatchEvent(new (0, _chunk7PI7LVWWjs.VectoJSEvent)(type, this, e, true));
6857
+ this.dispatchEvent(new (0, _chunkTRT2TRCWjs.VectoJSEvent)(type, this, e, true));
6798
6858
  };
6799
6859
  this.domElement.addEventListener(type, handler, true);
6800
6860
  this.domListeners.push({ type, handler, capture: true });
@@ -6891,4 +6951,4 @@ Scene.registerWebGPUParticleSystemManager(_chunkM73XB4ZKjs.WebGPUParticleSystemM
6891
6951
 
6892
6952
 
6893
6953
 
6894
- exports.CanvasRenderer = _chunkM73XB4ZKjs.CanvasRenderer; exports.Circle = Circle; exports.ComputeParticleEntity = ComputeParticleEntity; exports.DOMPortalEntity = DOMPortalEntity; exports.Entity = _chunk7PI7LVWWjs.Entity; exports.GlyphRasterAtlas = _chunkM73XB4ZKjs.GlyphRasterAtlas; exports.GridTextEntity = GridTextEntity; exports.Group = Group; exports.MSDFTextEntity = _chunk7PI7LVWWjs.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 = _chunk7PI7LVWWjs.SVGEntity; exports.SVGRenderer = _chunkM73XB4ZKjs.SVGRenderer; exports.Scene = Scene; exports.SplineEntity = SplineEntity; exports.TextEntity = TextEntity; exports.TextRasterCache = _chunkM73XB4ZKjs.TextRasterCache; exports.VECTO_USER_TIMING = VECTO_USER_TIMING; exports.VectoJSEvent = _chunk7PI7LVWWjs.VectoJSEvent; exports.WebGPUParticleSystemManager = _chunkM73XB4ZKjs.WebGPUParticleSystemManager; exports.beginVectoUserTiming = beginVectoUserTiming; exports.contentLineInHint = _chunk7PI7LVWWjs.contentLineInHint; exports.createWebGLPointRenderer = _chunkM73XB4ZKjs.createWebGLPointRenderer; exports.endVectoUserTiming = endVectoUserTiming; exports.installRendererDevTraps = _chunkM73XB4ZKjs.installRendererDevTraps; exports.isRendererDevMode = _chunkM73XB4ZKjs.isRendererDevMode; exports.isSafeUrl = _chunkM73XB4ZKjs.isSafeUrl; exports.loadSpline = loadSpline; exports.measureVectoUserTiming = measureVectoUserTiming; exports.parseColorToRGBA = _chunkM73XB4ZKjs.parseColorToRGBA; exports.polySegmentToBezier = polySegmentToBezier; exports.sanitizeUrl = _chunkM73XB4ZKjs.sanitizeUrl; exports.setRendererDevMode = _chunkM73XB4ZKjs.setRendererDevMode;
6954
+ exports.CanvasRenderer = _chunkM73XB4ZKjs.CanvasRenderer; exports.Circle = Circle; exports.ComputeParticleEntity = ComputeParticleEntity; exports.DOMPortalEntity = DOMPortalEntity; exports.Entity = _chunkTRT2TRCWjs.Entity; exports.GlyphRasterAtlas = _chunkM73XB4ZKjs.GlyphRasterAtlas; exports.GridTextEntity = GridTextEntity; exports.Group = Group; exports.MSDFTextEntity = _chunkTRT2TRCWjs.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 = _chunkTRT2TRCWjs.SVGEntity; exports.SVGRenderer = _chunkM73XB4ZKjs.SVGRenderer; exports.Scene = Scene; exports.SplineEntity = SplineEntity; exports.TextEntity = TextEntity; exports.TextRasterCache = _chunkM73XB4ZKjs.TextRasterCache; exports.VECTO_USER_TIMING = VECTO_USER_TIMING; exports.VectoJSEvent = _chunkTRT2TRCWjs.VectoJSEvent; exports.WebGPUParticleSystemManager = _chunkM73XB4ZKjs.WebGPUParticleSystemManager; exports.beginVectoUserTiming = beginVectoUserTiming; exports.contentLineInHint = _chunkTRT2TRCWjs.contentLineInHint; exports.createWebGLPointRenderer = _chunkM73XB4ZKjs.createWebGLPointRenderer; exports.endVectoUserTiming = endVectoUserTiming; exports.installRendererDevTraps = _chunkM73XB4ZKjs.installRendererDevTraps; exports.isRendererDevMode = _chunkM73XB4ZKjs.isRendererDevMode; exports.isSafeUrl = _chunkM73XB4ZKjs.isSafeUrl; exports.loadSpline = loadSpline; exports.measureVectoUserTiming = measureVectoUserTiming; exports.parseColorToRGBA = _chunkM73XB4ZKjs.parseColorToRGBA; exports.polySegmentToBezier = polySegmentToBezier; exports.sanitizeUrl = _chunkM73XB4ZKjs.sanitizeUrl; exports.setRendererDevMode = _chunkM73XB4ZKjs.setRendererDevMode;