@vectojs/core 0.2.2 → 0.2.4

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
@@ -3,16 +3,16 @@
3
3
 
4
4
 
5
5
 
6
- var _chunk72WVPMSJjs = require('./chunk-72WVPMSJ.js');
6
+ var _chunkIKLYTHALjs = require('./chunk-IKLYTHAL.js');
7
7
 
8
8
 
9
9
 
10
10
 
11
11
 
12
12
 
13
- var _chunkLIX7DJTIjs = require('./chunk-LIX7DJTI.js');
14
13
 
15
14
 
15
+ var _chunkTPNADFNNjs = require('./chunk-TPNADFNN.js');
16
16
 
17
17
 
18
18
 
@@ -22,12 +22,14 @@ var _chunkLIX7DJTIjs = require('./chunk-LIX7DJTI.js');
22
22
 
23
23
 
24
24
 
25
- var _chunkLA3FJLP2js = require('./chunk-LA3FJLP2.js');
26
25
 
27
26
 
27
+ var _chunkTQ4H357Qjs = require('./chunk-TQ4H357Q.js');
28
28
 
29
29
 
30
- var _chunkRW6NC4RBjs = require('./chunk-RW6NC4RB.js');
30
+
31
+
32
+ var _chunk76NMTLYLjs = require('./chunk-76NMTLYL.js');
31
33
 
32
34
  // src/tree/ComputeParticleEntity.ts
33
35
  var PARTICLE_STRIDE_FLOATS = 8;
@@ -39,7 +41,7 @@ var PARTICLE_OFFSET_ORIGIN_X = 4;
39
41
  var PARTICLE_OFFSET_ORIGIN_Y = 5;
40
42
  var PARTICLE_OFFSET_SIZE = 6;
41
43
  var PARTICLE_OFFSET_LIFE = 7;
42
- var ComputeParticleEntity = (_class = class extends _chunkLA3FJLP2js.Entity {
44
+ var ComputeParticleEntity = (_class = class extends _chunkTQ4H357Qjs.Entity {
43
45
 
44
46
 
45
47
 
@@ -408,7 +410,7 @@ var Scene = (_class2 = class _Scene {
408
410
  this.particleBackend = _nullishCoalesce(options.particleBackend, () => ( "auto"));
409
411
  this.a11ySyncInterval = _nullishCoalesce(options.a11ySyncInterval, () => ( 0));
410
412
  this.reducedMotionQuery = typeof window !== "undefined" && typeof window.matchMedia === "function" ? window.matchMedia("(prefers-reduced-motion: reduce)") : null;
411
- this.root = new class RootEntity extends _chunkLA3FJLP2js.Entity {
413
+ this.root = new class RootEntity extends _chunkTQ4H357Qjs.Entity {
412
414
  isPointInside() {
413
415
  return false;
414
416
  }
@@ -417,7 +419,7 @@ var Scene = (_class2 = class _Scene {
417
419
  }
418
420
  }("root");
419
421
  this.root._scene = this;
420
- this.overlayRoot = new class OverlayRoot extends _chunkLA3FJLP2js.Entity {
422
+ this.overlayRoot = new class OverlayRoot extends _chunkTQ4H357Qjs.Entity {
421
423
  isPointInside() {
422
424
  return false;
423
425
  }
@@ -428,7 +430,7 @@ var Scene = (_class2 = class _Scene {
428
430
  if (options.renderer) {
429
431
  this.renderer = options.renderer;
430
432
  } else {
431
- this.renderer = new (0, _chunkLIX7DJTIjs.CanvasRenderer)(canvas);
433
+ this.renderer = new (0, _chunkTPNADFNNjs.CanvasRenderer)(canvas);
432
434
  }
433
435
  if (typeof document !== "undefined") {
434
436
  this.a11yRoot = document.createElement("div");
@@ -489,6 +491,17 @@ var Scene = (_class2 = class _Scene {
489
491
  getRenderer() {
490
492
  return this.renderer;
491
493
  }
494
+ /** Convert browser viewport coordinates into this Scene's logical coordinates. */
495
+ clientToScene(clientX, clientY) {
496
+ const rect = _optionalChain([this, 'access', _19 => _19.canvas, 'access', _20 => _20.getBoundingClientRect, 'optionalCall', _21 => _21()]);
497
+ if (!rect) return { x: clientX, y: clientY };
498
+ const cssWidth = rect.width || this.canvas.clientWidth || this.width;
499
+ const cssHeight = rect.height || this.canvas.clientHeight || this.height;
500
+ return {
501
+ x: (clientX - rect.left) * (cssWidth > 0 ? this.width / cssWidth : 1),
502
+ y: (clientY - rect.top) * (cssHeight > 0 ? this.height / cssHeight : 1)
503
+ };
504
+ }
492
505
  /**
493
506
  * Add a top-level entity to the scene graph.
494
507
  *
@@ -563,12 +576,21 @@ var Scene = (_class2 = class _Scene {
563
576
  this.removeA11yRecursively(overlay);
564
577
  this.markDirty();
565
578
  }
579
+ destroyEntitySubtree(entity) {
580
+ while (entity.children.length > 0) this.destroyEntitySubtree(entity.children.at(-1));
581
+ entity.destroy();
582
+ }
566
583
  /**
567
584
  * Tear down the Scene, halt the loop, and clean up event listeners and DOM elements.
568
585
  */
569
586
  destroy() {
587
+ if (this.destroyed) return;
570
588
  this.destroyed = true;
571
589
  this.stop();
590
+ while (this.root.children.length > 0) this.destroyEntitySubtree(this.root.children.at(-1));
591
+ while (this.overlayRoot.children.length > 0) {
592
+ this.destroyEntitySubtree(this.overlayRoot.children.at(-1));
593
+ }
572
594
  if (typeof window !== "undefined" && !this.disableWindowResize) {
573
595
  window.removeEventListener("resize", this.resizeHandler);
574
596
  }
@@ -580,12 +602,13 @@ var Scene = (_class2 = class _Scene {
580
602
  this.canvas.removeEventListener("pointerleave", this.pointerLeaveListener);
581
603
  }
582
604
  }
583
- _optionalChain([this, 'access', _19 => _19.a11yRoot, 'optionalAccess', _20 => _20.remove, 'call', _21 => _21()]);
584
- _optionalChain([this, 'access', _22 => _22.portalRoot, 'optionalAccess', _23 => _23.remove, 'call', _24 => _24()]);
605
+ _optionalChain([this, 'access', _22 => _22.a11yRoot, 'optionalAccess', _23 => _23.remove, 'call', _24 => _24()]);
606
+ _optionalChain([this, 'access', _25 => _25.portalRoot, 'optionalAccess', _26 => _26.remove, 'call', _27 => _27()]);
585
607
  this.a11yElements.clear();
586
- _optionalChain([this, 'access', _25 => _25.pointRenderer, 'optionalAccess', _26 => _26.destroy, 'call', _27 => _27()]);
587
- _optionalChain([this, 'access', _28 => _28.glCanvas, 'optionalAccess', _29 => _29.remove, 'call', _30 => _30()]);
588
- _optionalChain([this, 'access', _31 => _31.gpuCanvas, 'optionalAccess', _32 => _32.remove, 'call', _33 => _33()]);
608
+ _optionalChain([this, 'access', _28 => _28.pointRenderer, 'optionalAccess', _29 => _29.destroy, 'call', _30 => _30()]);
609
+ _optionalChain([this, 'access', _31 => _31.renderer, 'access', _32 => _32.dispose, 'optionalCall', _33 => _33()]);
610
+ _optionalChain([this, 'access', _34 => _34.glCanvas, 'optionalAccess', _35 => _35.remove, 'call', _36 => _36()]);
611
+ _optionalChain([this, 'access', _37 => _37.gpuCanvas, 'optionalAccess', _38 => _38.remove, 'call', _39 => _39()]);
589
612
  this.gpuCanvas = null;
590
613
  this.gpuContext = null;
591
614
  if (this.recoveryTimerId) {
@@ -603,9 +626,9 @@ var Scene = (_class2 = class _Scene {
603
626
  }
604
627
  if (typeof window !== "undefined" && this.canvas && typeof this.canvas.addEventListener === "function") {
605
628
  this.pointerMoveListener = (e) => {
606
- const rect = this.canvas.getBoundingClientRect();
607
- this.mouseX = e.clientX - rect.left;
608
- this.mouseY = e.clientY - rect.top;
629
+ const point = this.clientToScene(e.clientX, e.clientY);
630
+ this.mouseX = point.x;
631
+ this.mouseY = point.y;
609
632
  };
610
633
  this.pointerLeaveListener = () => {
611
634
  this.mouseX = -9999;
@@ -721,6 +744,7 @@ var Scene = (_class2 = class _Scene {
721
744
  el.id = node.id;
722
745
  el.setAttribute("data-vecto-id", node.id);
723
746
  el.style.position = "absolute";
747
+ el.style.transformOrigin = "0 0";
724
748
  el.style.pointerEvents = "auto";
725
749
  el.style.touchAction = "pinch-zoom";
726
750
  el.style.margin = "0";
@@ -736,42 +760,42 @@ var Scene = (_class2 = class _Scene {
736
760
  el.style.background = "transparent";
737
761
  }
738
762
  el.addEventListener("click", (e) => {
739
- node.dispatchEvent(new (0, _chunkLA3FJLP2js.VectoJSEvent)("click", node, e));
763
+ node.dispatchEvent(new (0, _chunkTQ4H357Qjs.VectoJSEvent)("click", node, e));
740
764
  });
741
765
  el.addEventListener("mouseenter", (e) => {
742
766
  if (this.debugA11y) el.style.backgroundColor = "rgba(56, 189, 248, 0.2)";
743
- node.dispatchEvent(new (0, _chunkLA3FJLP2js.VectoJSEvent)("hover", node, e, false));
767
+ node.dispatchEvent(new (0, _chunkTQ4H357Qjs.VectoJSEvent)("hover", node, e, false));
744
768
  });
745
769
  el.addEventListener("mouseleave", (e) => {
746
770
  if (this.debugA11y) el.style.backgroundColor = "rgba(56, 189, 248, 0.05)";
747
- node.dispatchEvent(new (0, _chunkLA3FJLP2js.VectoJSEvent)("pointerleave", node, e, false));
771
+ node.dispatchEvent(new (0, _chunkTQ4H357Qjs.VectoJSEvent)("pointerleave", node, e, false));
748
772
  });
749
773
  const capEl = el;
750
774
  el.addEventListener("pointerdown", (e) => {
751
775
  if (typeof capEl.setPointerCapture === "function") capEl.setPointerCapture(e.pointerId);
752
- node.dispatchEvent(new (0, _chunkLA3FJLP2js.VectoJSEvent)("pointerdown", node, e));
776
+ node.dispatchEvent(new (0, _chunkTQ4H357Qjs.VectoJSEvent)("pointerdown", node, e));
753
777
  });
754
778
  el.addEventListener("pointerup", (e) => {
755
779
  if (typeof capEl.releasePointerCapture === "function")
756
780
  capEl.releasePointerCapture(e.pointerId);
757
- node.dispatchEvent(new (0, _chunkLA3FJLP2js.VectoJSEvent)("pointerup", node, e));
781
+ node.dispatchEvent(new (0, _chunkTQ4H357Qjs.VectoJSEvent)("pointerup", node, e));
758
782
  });
759
783
  el.addEventListener(
760
784
  "pointermove",
761
- (e) => node.dispatchEvent(new (0, _chunkLA3FJLP2js.VectoJSEvent)("pointermove", node, e))
785
+ (e) => node.dispatchEvent(new (0, _chunkTQ4H357Qjs.VectoJSEvent)("pointermove", node, e))
762
786
  );
763
787
  el.addEventListener(
764
788
  "wheel",
765
789
  (e) => {
766
- node.dispatchEvent(new (0, _chunkLA3FJLP2js.VectoJSEvent)("wheel", node, e));
790
+ node.dispatchEvent(new (0, _chunkTQ4H357Qjs.VectoJSEvent)("wheel", node, e));
767
791
  },
768
792
  { passive: false }
769
793
  );
770
794
  el.addEventListener("keydown", (e) => {
771
- node.dispatchEvent(new (0, _chunkLA3FJLP2js.VectoJSEvent)("keydown", node, e));
795
+ node.dispatchEvent(new (0, _chunkTQ4H357Qjs.VectoJSEvent)("keydown", node, e));
772
796
  });
773
797
  el.addEventListener("keyup", (e) => {
774
- node.dispatchEvent(new (0, _chunkLA3FJLP2js.VectoJSEvent)("keyup", node, e));
798
+ node.dispatchEvent(new (0, _chunkTQ4H357Qjs.VectoJSEvent)("keyup", node, e));
775
799
  });
776
800
  if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement) {
777
801
  const input = el;
@@ -785,6 +809,7 @@ var Scene = (_class2 = class _Scene {
785
809
  selectionEnd: _nullishCoalesce(input.selectionEnd, () => ( input.value.length)),
786
810
  composition
787
811
  });
812
+ this.markDirty();
788
813
  };
789
814
  el.addEventListener("input", forward);
790
815
  el.addEventListener("change", forward);
@@ -797,7 +822,7 @@ var Scene = (_class2 = class _Scene {
797
822
  });
798
823
  el.addEventListener("compositionupdate", (e) => {
799
824
  const data = _nullishCoalesce(e.data, () => ( ""));
800
- composition = { start: _nullishCoalesce(_optionalChain([composition, 'optionalAccess', _34 => _34.start]), () => ( 0)), length: data.length };
825
+ composition = { start: _nullishCoalesce(_optionalChain([composition, 'optionalAccess', _40 => _40.start]), () => ( 0)), length: data.length };
801
826
  forward();
802
827
  });
803
828
  el.addEventListener("compositionend", () => {
@@ -843,7 +868,7 @@ var Scene = (_class2 = class _Scene {
843
868
  el.addEventListener("keydown", (e) => {
844
869
  if (e.key === "Enter" || e.key === " ") {
845
870
  e.preventDefault();
846
- node.dispatchEvent(new (0, _chunkLA3FJLP2js.VectoJSEvent)("click", node, e));
871
+ node.dispatchEvent(new (0, _chunkTQ4H357Qjs.VectoJSEvent)("click", node, e));
847
872
  }
848
873
  });
849
874
  }
@@ -868,7 +893,8 @@ var Scene = (_class2 = class _Scene {
868
893
  if (el.placeholder !== attrs.placeholder) el.placeholder = attrs.placeholder;
869
894
  }
870
895
  if (attrs.href !== void 0 && el instanceof HTMLAnchorElement) {
871
- if (el.getAttribute("href") !== attrs.href) el.setAttribute("href", attrs.href);
896
+ const safeHref = _chunkTPNADFNNjs.sanitizeUrl.call(void 0, attrs.href);
897
+ if (el.getAttribute("href") !== safeHref) el.setAttribute("href", safeHref);
872
898
  }
873
899
  if (el instanceof HTMLImageElement) {
874
900
  if (attrs.src !== void 0 && el.src !== attrs.src) el.src = attrs.src;
@@ -929,12 +955,12 @@ var Scene = (_class2 = class _Scene {
929
955
  el.style.height = `${this.height}px`;
930
956
  el.style.transform = "";
931
957
  } else {
932
- const pos = node.getGlobalPosition();
933
- el.style.left = `${pos.x + node.a11yOffsetX}px`;
934
- el.style.top = `${pos.y + node.a11yOffsetY}px`;
935
- el.style.width = `${node.width * node.scaleX}px`;
936
- el.style.height = `${node.height * node.scaleY}px`;
937
- el.style.transform = `rotate(${node.rotation}rad)`;
958
+ const { a, b, c, d, e, f } = node.getWorldTransform();
959
+ el.style.left = `${e + node.a11yOffsetX}px`;
960
+ el.style.top = `${f + node.a11yOffsetY}px`;
961
+ el.style.width = `${node.width}px`;
962
+ el.style.height = `${node.height}px`;
963
+ el.style.transform = `matrix(${a}, ${b}, ${c}, ${d}, 0, 0)`;
938
964
  }
939
965
  }
940
966
  for (const child of node.children) this.syncA11y(child);
@@ -996,6 +1022,35 @@ var Scene = (_class2 = class _Scene {
996
1022
  }
997
1023
  this.a11yNeedsReorder = false;
998
1024
  }
1025
+ /** Keep DOM/WebGL overlay layers aligned with the canvas's CSS box. */
1026
+ syncOverlayGeometry() {
1027
+ const parent = this.canvas.parentElement;
1028
+ if (!parent) return;
1029
+ const canvasRect = _optionalChain([this, 'access', _41 => _41.canvas, 'access', _42 => _42.getBoundingClientRect, 'optionalCall', _43 => _43()]);
1030
+ const parentRect = _optionalChain([parent, 'access', _44 => _44.getBoundingClientRect, 'optionalCall', _45 => _45()]);
1031
+ const cssWidth = _optionalChain([canvasRect, 'optionalAccess', _46 => _46.width]) || this.canvas.clientWidth || this.width;
1032
+ const cssHeight = _optionalChain([canvasRect, 'optionalAccess', _47 => _47.height]) || this.canvas.clientHeight || this.height;
1033
+ const left = (_nullishCoalesce(_optionalChain([canvasRect, 'optionalAccess', _48 => _48.left]), () => ( 0))) - (_nullishCoalesce(_optionalChain([parentRect, 'optionalAccess', _49 => _49.left]), () => ( 0))) - (parent.clientLeft || 0) + parent.scrollLeft;
1034
+ const top = (_nullishCoalesce(_optionalChain([canvasRect, 'optionalAccess', _50 => _50.top]), () => ( 0))) - (_nullishCoalesce(_optionalChain([parentRect, 'optionalAccess', _51 => _51.top]), () => ( 0))) - (parent.clientTop || 0) + parent.scrollTop;
1035
+ const scaleX = this.width > 0 ? cssWidth / this.width : 1;
1036
+ const scaleY = this.height > 0 ? cssHeight / this.height : 1;
1037
+ for (const root of [this.a11yRoot, this.portalRoot]) {
1038
+ if (!root) continue;
1039
+ root.style.left = `${left}px`;
1040
+ root.style.top = `${top}px`;
1041
+ root.style.width = `${this.width}px`;
1042
+ root.style.height = `${this.height}px`;
1043
+ root.style.transformOrigin = "0 0";
1044
+ root.style.transform = `scale(${scaleX}, ${scaleY})`;
1045
+ }
1046
+ for (const canvas of [this.glCanvas, this.gpuCanvas]) {
1047
+ if (!canvas) continue;
1048
+ canvas.style.left = `${left}px`;
1049
+ canvas.style.top = `${top}px`;
1050
+ canvas.style.width = `${cssWidth}px`;
1051
+ canvas.style.height = `${cssHeight}px`;
1052
+ }
1053
+ }
999
1054
  getA11yTree() {
1000
1055
  const map = /* @__PURE__ */ new Map();
1001
1056
  const roots = [];
@@ -1039,7 +1094,7 @@ var Scene = (_class2 = class _Scene {
1039
1094
  traverse(this.root, null);
1040
1095
  return roots;
1041
1096
  }
1042
- renderPortalDOM(portal, te, tf, a, b, c, d) {
1097
+ renderPortalDOM(portal, te, tf, a, b, c, d, opacity) {
1043
1098
  if (!this.portalRoot) return;
1044
1099
  this.activePortalsThisFrame.add(portal.id);
1045
1100
  this.portalEntities.set(portal.id, portal);
@@ -1073,6 +1128,11 @@ var Scene = (_class2 = class _Scene {
1073
1128
  portal.domElement.style.zIndex = zIndexStr;
1074
1129
  portal.lastZIndex = zIndexStr;
1075
1130
  }
1131
+ const opacityStr = String(opacity);
1132
+ if (portal.lastOpacity !== opacityStr) {
1133
+ portal.domElement.style.opacity = opacityStr;
1134
+ portal.lastOpacity = opacityStr;
1135
+ }
1076
1136
  }
1077
1137
  reconcilePortals() {
1078
1138
  if (!this.portalRoot) return;
@@ -1096,7 +1156,7 @@ var Scene = (_class2 = class _Scene {
1096
1156
  * (and {@link respectReducedMotion} is on). `0` means uncapped.
1097
1157
  */
1098
1158
  effectiveMaxFPS() {
1099
- const reduced = this.respectReducedMotion && !!_optionalChain([this, 'access', _35 => _35.reducedMotionQuery, 'optionalAccess', _36 => _36.matches]);
1159
+ const reduced = this.respectReducedMotion && !!_optionalChain([this, 'access', _52 => _52.reducedMotionQuery, 'optionalAccess', _53 => _53.matches]);
1100
1160
  if (reduced)
1101
1161
  return this.maxFPS > 0 ? Math.min(this.maxFPS, REDUCED_MOTION_FPS) : REDUCED_MOTION_FPS;
1102
1162
  return this.maxFPS;
@@ -1143,14 +1203,18 @@ var Scene = (_class2 = class _Scene {
1143
1203
  * @param time - Current absolute time in milliseconds (default 0).
1144
1204
  */
1145
1205
  render(renderer, dt = 0, time = 0) {
1146
- if (this.a11yRoot && this.canvas.parentElement) {
1206
+ const isMainRenderer = renderer === this.renderer;
1207
+ if (isMainRenderer && this.a11yRoot && this.canvas.parentElement) {
1147
1208
  const parentStyle = this.canvas.parentElement.style;
1148
1209
  if (!parentStyle.position || parentStyle.position === "static") {
1149
1210
  parentStyle.position = "relative";
1150
1211
  }
1212
+ this.syncOverlayGeometry();
1213
+ }
1214
+ if (isMainRenderer) {
1215
+ this.renderOrderCounter = 0;
1216
+ this.activePortalsThisFrame.clear();
1151
1217
  }
1152
- this.renderOrderCounter = 0;
1153
- this.activePortalsThisFrame.clear();
1154
1218
  const computeEntities = [];
1155
1219
  const collectComputeEntities = (node) => {
1156
1220
  if (node instanceof ComputeParticleEntity) {
@@ -1165,7 +1229,8 @@ var Scene = (_class2 = class _Scene {
1165
1229
  collectComputeEntities(overlay);
1166
1230
  }
1167
1231
  if (computeEntities.length > 0) {
1168
- if (!this.device && !this.webgpuDisabled && !this.initializingWebGPU && !this.deviceLost) {
1232
+ const isMainRenderPath = renderer === this.renderer;
1233
+ if (isMainRenderPath && !this.device && !this.webgpuDisabled && !this.initializingWebGPU && !this.deviceLost) {
1169
1234
  this.initializingWebGPU = true;
1170
1235
  this.initWebGPUContext(computeEntities).then((newDevice) => {
1171
1236
  this.device = newDevice;
@@ -1188,12 +1253,16 @@ var Scene = (_class2 = class _Scene {
1188
1253
  }
1189
1254
  }
1190
1255
  }).catch((err) => {
1191
- console.error("Failed to initialize WebGPU:", err);
1256
+ if (this.particleBackend === "webgpu") {
1257
+ console.error("Failed to initialize WebGPU:", err);
1258
+ } else {
1259
+ console.warn("WebGPU unavailable; using CPU particle fallback.", err);
1260
+ }
1192
1261
  this.webgpuDisabled = true;
1193
1262
  this.initializingWebGPU = false;
1194
1263
  });
1195
1264
  }
1196
- if (this.device && this.manager && !this.deviceLost && !this.webgpuDisabled) {
1265
+ if (isMainRenderPath && this.device && this.manager && !this.deviceLost && !this.webgpuDisabled) {
1197
1266
  try {
1198
1267
  const commandEncoder = this.device.createCommandEncoder();
1199
1268
  const computePass = commandEncoder.beginComputePass();
@@ -1241,21 +1310,20 @@ var Scene = (_class2 = class _Scene {
1241
1310
  this.device = null;
1242
1311
  this.recreateWebGPUDeviceWithRetry(computeEntities);
1243
1312
  }
1244
- } else {
1313
+ } else if (isMainRenderPath) {
1245
1314
  for (const entity of computeEntities) {
1246
1315
  entity.updateCPU(dt / 1e3, this.mouseX, this.mouseY, this.width, this.height);
1247
1316
  }
1248
1317
  }
1249
1318
  }
1250
1319
  renderer.clear();
1251
- const isMainRenderer = renderer === this.renderer;
1252
1320
  if (isMainRenderer) {
1253
- _optionalChain([this, 'access', _37 => _37.pointRenderer, 'optionalAccess', _38 => _38.begin, 'call', _39 => _39()]);
1321
+ _optionalChain([this, 'access', _54 => _54.pointRenderer, 'optionalAccess', _55 => _55.begin, 'call', _56 => _56()]);
1254
1322
  }
1255
1323
  const vw = this.width;
1256
1324
  const vh = this.height;
1257
- const renderNode = (node, pa, pb, pc, pd, pe, pf) => {
1258
- node.update(dt, time);
1325
+ const renderNode = (node, pa, pb, pc, pd, pe, pf, parentOpacity) => {
1326
+ if (isMainRenderer) node.update(dt, time);
1259
1327
  const cos = Math.cos(node.rotation);
1260
1328
  const sin = Math.sin(node.rotation);
1261
1329
  const te = pa * node.x + pc * node.y + pe;
@@ -1264,16 +1332,24 @@ var Scene = (_class2 = class _Scene {
1264
1332
  const sxSin = node.scaleX * sin;
1265
1333
  const syCos = node.scaleY * cos;
1266
1334
  const sySin = node.scaleY * sin;
1267
- const a = pa * sxCos + pc * sxSin;
1268
- const b = pb * sxCos + pd * sxSin;
1269
- const c = pa * -sySin + pc * syCos;
1270
- const d = pb * -sySin + pd * syCos;
1271
- const a11yEl = this.a11yElements.get(node.id);
1335
+ const a = pa * sxCos + pc * sySin;
1336
+ const b = pb * sxCos + pd * sySin;
1337
+ const c = pa * -sxSin + pc * syCos;
1338
+ const d = pb * -sxSin + pd * syCos;
1339
+ const worldScaleX = Math.hypot(a, b);
1340
+ const worldScaleY = Math.hypot(c, d);
1341
+ const worldOpacity = parentOpacity * node.opacity;
1342
+ const scaleTolerance = Math.max(1, worldScaleX, worldScaleY) * 1e-6;
1343
+ const orthogonalTolerance = Math.max(1, worldScaleX * worldScaleY) * 1e-6;
1344
+ const isSimilarityTransform = Number.isFinite(worldScaleX) && Number.isFinite(worldScaleY) && Math.abs(worldScaleX - worldScaleY) <= scaleTolerance && Math.abs(a * c + b * d) <= orthogonalTolerance;
1345
+ const a11yEl = isMainRenderer ? this.a11yElements.get(node.id) : void 0;
1272
1346
  if (a11yEl) {
1273
1347
  a11yEl.style.zIndex = String(this.renderOrderCounter++);
1274
1348
  }
1275
1349
  if (node.isDOMPortal) {
1276
- this.renderPortalDOM(node, te, tf, a, b, c, d);
1350
+ if (isMainRenderer) {
1351
+ this.renderPortalDOM(node, te, tf, a, b, c, d, worldOpacity);
1352
+ }
1277
1353
  return;
1278
1354
  }
1279
1355
  let visible = true;
@@ -1299,33 +1375,27 @@ var Scene = (_class2 = class _Scene {
1299
1375
  if (node.children.length === 0 && node.scaleX === node.scaleY) {
1300
1376
  const bc = node.getBatchCircle();
1301
1377
  if (bc) {
1302
- if (visible) {
1303
- if (isMainRenderer && this.pointRenderer) {
1304
- this.pointRenderer.addCircle(
1305
- te,
1306
- tf,
1307
- bc.radius * Math.hypot(a, b),
1308
- bc.color,
1309
- node.opacity
1310
- );
1311
- } else {
1312
- renderer.fillCircle(node.x, node.y, bc.radius * node.scaleX, bc.color, node.opacity);
1378
+ if (!visible) return;
1379
+ if (isMainRenderer && this.pointRenderer) {
1380
+ if (isSimilarityTransform) {
1381
+ this.pointRenderer.addCircle(te, tf, bc.radius * worldScaleX, bc.color, worldOpacity);
1382
+ return;
1313
1383
  }
1384
+ } else {
1385
+ renderer.fillCircle(node.x, node.y, bc.radius * node.scaleX, bc.color, worldOpacity);
1386
+ return;
1314
1387
  }
1315
- return;
1316
- }
1317
- if (isMainRenderer && this.pointRenderer) {
1388
+ } else if (isMainRenderer && this.pointRenderer) {
1318
1389
  const br = node.getBatchRect();
1319
- if (br) {
1390
+ if (br && isSimilarityTransform && a * d - b * c >= 0) {
1320
1391
  if (visible) {
1321
- const ws = Math.hypot(a, b);
1322
1392
  this.pointRenderer.addRect(
1323
1393
  te,
1324
1394
  tf,
1325
- br.width * ws,
1326
- br.height * ws,
1395
+ br.width * worldScaleX,
1396
+ br.height * worldScaleX,
1327
1397
  br.color,
1328
- node.opacity,
1398
+ worldOpacity,
1329
1399
  Math.atan2(b, a)
1330
1400
  );
1331
1401
  }
@@ -1338,11 +1408,11 @@ var Scene = (_class2 = class _Scene {
1338
1408
  renderer.translate(node.x, node.y);
1339
1409
  renderer.scale(node.scaleX, node.scaleY);
1340
1410
  renderer.rotate(node.rotation);
1341
- renderer.setGlobalAlpha(node.opacity);
1411
+ renderer.setGlobalAlpha(worldOpacity);
1342
1412
  if (visible) {
1343
1413
  if (node instanceof ComputeParticleEntity) {
1344
1414
  if (this.deviceLost || this.webgpuDisabled || !this.device || !this.manager) {
1345
- this.renderCPUParticles(renderer, node);
1415
+ this.renderCPUParticles(renderer, node, worldOpacity);
1346
1416
  }
1347
1417
  } else {
1348
1418
  node.render(renderer);
@@ -1352,26 +1422,26 @@ var Scene = (_class2 = class _Scene {
1352
1422
  renderer.clip(0, 0, node.width, node.height);
1353
1423
  }
1354
1424
  for (const child of node.children) {
1355
- renderNode(child, a, b, c, d, te, tf);
1425
+ renderNode(child, a, b, c, d, te, tf, worldOpacity);
1356
1426
  }
1357
1427
  renderer.flush();
1358
1428
  renderer.restore();
1359
1429
  };
1360
- renderNode(this.root, 1, 0, 0, 1, 0, 0);
1430
+ renderNode(this.root, 1, 0, 0, 1, 0, 0, 1);
1361
1431
  for (const overlay of this.overlayRoot.children) {
1362
- renderNode(overlay, 1, 0, 0, 1, 0, 0);
1432
+ renderNode(overlay, 1, 0, 0, 1, 0, 0, 1);
1363
1433
  }
1364
- this.reconcilePortals();
1434
+ if (isMainRenderer) this.reconcilePortals();
1365
1435
  renderer.flush();
1366
1436
  if (isMainRenderer) {
1367
- _optionalChain([this, 'access', _40 => _40.pointRenderer, 'optionalAccess', _41 => _41.flush, 'call', _42 => _42()]);
1437
+ _optionalChain([this, 'access', _57 => _57.pointRenderer, 'optionalAccess', _58 => _58.flush, 'call', _59 => _59()]);
1368
1438
  }
1369
1439
  }
1370
1440
  /**
1371
1441
  * Export the current scene state to a lightweight, flat SVG XML string.
1372
1442
  */
1373
1443
  toSVG() {
1374
- const renderer = new (0, _chunkLIX7DJTIjs.SVGRenderer)(this.width, this.height);
1444
+ const renderer = new (0, _chunkTPNADFNNjs.SVGRenderer)(this.width, this.height);
1375
1445
  this.render(renderer, 0, 0);
1376
1446
  return renderer.toXMLString();
1377
1447
  }
@@ -1384,7 +1454,7 @@ var Scene = (_class2 = class _Scene {
1384
1454
  if (typeof this.renderer.resize === "function") {
1385
1455
  this.renderer.resize(width, height);
1386
1456
  }
1387
- _optionalChain([this, 'access', _43 => _43.pointRenderer, 'optionalAccess', _44 => _44.resize, 'call', _45 => _45(width, height)]);
1457
+ _optionalChain([this, 'access', _60 => _60.pointRenderer, 'optionalAccess', _61 => _61.resize, 'call', _62 => _62(width, height)]);
1388
1458
  this.markDirty();
1389
1459
  }
1390
1460
  /**
@@ -1491,13 +1561,15 @@ var Scene = (_class2 = class _Scene {
1491
1561
  this.manager.initPipelines(format);
1492
1562
  for (const entity of entities) {
1493
1563
  this.manager.setupEntityResources(entity);
1494
- newDevice.queue.writeBuffer(entity.gpuStorageBuffer, 0, entity.particleData);
1564
+ if (entity.gpuStorageBuffer) {
1565
+ newDevice.queue.writeBuffer(entity.gpuStorageBuffer, 0, entity.particleData);
1566
+ }
1495
1567
  }
1496
1568
  }
1497
1569
  }).catch(() => this.recreateWebGPUDeviceWithRetry(entities, attempt + 1));
1498
1570
  }, backoff);
1499
1571
  }
1500
- renderCPUParticles(renderer, entity) {
1572
+ renderCPUParticles(renderer, entity, worldOpacity) {
1501
1573
  const data = entity.particleData;
1502
1574
  const size = entity.maxParticles;
1503
1575
  const isMain = renderer === this.renderer;
@@ -1508,7 +1580,7 @@ var Scene = (_class2 = class _Scene {
1508
1580
  const pSize = data[idx + 6];
1509
1581
  const life = data[idx + 7];
1510
1582
  if (life === 0) continue;
1511
- const opacity = life < 0 ? entity.opacity : entity.opacity * Math.min(1, life);
1583
+ const opacity = life < 0 ? worldOpacity : worldOpacity * Math.min(1, life);
1512
1584
  const scale = life >= 0 ? Math.min(1, life) : 1;
1513
1585
  if (isMain && this.pointRenderer) {
1514
1586
  this.pointRenderer.addCircle(x, y, pSize * scale, entity.baseColor, opacity);
@@ -1532,10 +1604,10 @@ var Scene = (_class2 = class _Scene {
1532
1604
  // src/components/TextEntity.ts
1533
1605
  var sharedMeasurer;
1534
1606
  function defaultMeasurer() {
1535
- if (sharedMeasurer === void 0) sharedMeasurer = _chunk72WVPMSJjs.createCanvasMeasurer.call(void 0, "sans-serif");
1607
+ if (sharedMeasurer === void 0) sharedMeasurer = _chunkIKLYTHALjs.createCanvasMeasurer.call(void 0, "sans-serif");
1536
1608
  return sharedMeasurer;
1537
1609
  }
1538
- var TextEntity = (_class3 = class extends _chunkLA3FJLP2js.Entity {
1610
+ var TextEntity = (_class3 = class extends _chunkTQ4H357Qjs.Entity {
1539
1611
 
1540
1612
 
1541
1613
 
@@ -1552,7 +1624,7 @@ var TextEntity = (_class3 = class extends _chunkLA3FJLP2js.Entity {
1552
1624
  this.text = text;
1553
1625
  this.atlas = atlas;
1554
1626
  this.fontSize = fontSize;
1555
- this.layout = new (0, _chunk72WVPMSJjs.LayoutEngine)(maxWidth, 1e4, defaultMeasurer());
1627
+ this.layout = new (0, _chunkIKLYTHALjs.LayoutEngine)(maxWidth, 1e4, defaultMeasurer());
1556
1628
  this.prepared = this.layout.prepare(this.text, this.atlas, this.fontSize);
1557
1629
  this.applyLayout();
1558
1630
  this.interactive = true;
@@ -1592,10 +1664,9 @@ var TextEntity = (_class3 = class extends _chunkLA3FJLP2js.Entity {
1592
1664
  this.a11yOffsetY = 0;
1593
1665
  }
1594
1666
  isPointInside(globalX, globalY) {
1595
- const pos = this.getGlobalPosition();
1596
- const lx = globalX - pos.x;
1597
- const ly = globalY - pos.y;
1598
- return lx >= 0 && lx <= this.width && ly >= 0 && ly <= this.height;
1667
+ const local = this.worldToLocal(globalX, globalY);
1668
+ if (!local) return false;
1669
+ return local.x >= 0 && local.x <= this.width && local.y >= 0 && local.y <= this.height;
1599
1670
  }
1600
1671
  render(renderer) {
1601
1672
  const currentFill = this.isHovered ? this.hoveredFillStyle : this.fillStyle;
@@ -1634,7 +1705,7 @@ var TextEntity = (_class3 = class extends _chunkLA3FJLP2js.Entity {
1634
1705
  }, _class3);
1635
1706
 
1636
1707
  // src/components/GridTextEntity.ts
1637
- var GridTextEntity = (_class4 = class extends _chunkLA3FJLP2js.Entity {
1708
+ var GridTextEntity = (_class4 = class extends _chunkTQ4H357Qjs.Entity {
1638
1709
 
1639
1710
  __init54() {this.fillStyle = "#ffffff"}
1640
1711
  __init55() {this.grid = []}
@@ -1653,7 +1724,7 @@ var GridTextEntity = (_class4 = class extends _chunkLA3FJLP2js.Entity {
1653
1724
  updateGrid(ascii) {
1654
1725
  this.grid = ascii;
1655
1726
  this.rows = ascii.length;
1656
- this.cols = _optionalChain([ascii, 'access', _46 => _46[0], 'optionalAccess', _47 => _47.length]) || 0;
1727
+ this.cols = _optionalChain([ascii, 'access', _63 => _63[0], 'optionalAccess', _64 => _64.length]) || 0;
1657
1728
  }
1658
1729
  isPointInside(_globalX, _globalY) {
1659
1730
  return false;
@@ -1728,7 +1799,7 @@ function distSqToSegment(px, py, x1, y1, x2, y2) {
1728
1799
  const ey = py - cy;
1729
1800
  return ex * ex + ey * ey;
1730
1801
  }
1731
- var SplineEntity = (_class5 = class extends _chunkLA3FJLP2js.Entity {
1802
+ var SplineEntity = (_class5 = class extends _chunkTQ4H357Qjs.Entity {
1732
1803
 
1733
1804
 
1734
1805
 
@@ -1810,10 +1881,9 @@ var SplineEntity = (_class5 = class extends _chunkLA3FJLP2js.Entity {
1810
1881
  * this method already calls it as a refinement when it is overridden.
1811
1882
  */
1812
1883
  isPointInside(globalX, globalY) {
1813
- const pos = this.getGlobalPosition();
1814
- const scale = this.getWorldScale();
1815
- const lx = (globalX - pos.x) / (scale.x || 1);
1816
- const ly = (globalY - pos.y) / (scale.y || 1);
1884
+ const local = this.worldToLocal(globalX, globalY);
1885
+ if (!local) return false;
1886
+ const { x: lx, y: ly } = local;
1817
1887
  const inAabb = lx >= this.bounds.x && lx <= this.bounds.x + this.bounds.width && ly >= this.bounds.y && ly <= this.bounds.y + this.bounds.height;
1818
1888
  if (!inAabb) return false;
1819
1889
  const refined = this.hitTestCurve(lx, ly);
@@ -2050,7 +2120,7 @@ var SpatialHashGrid = (_class6 = class {
2050
2120
  const keys = this.entityCells.get(id);
2051
2121
  if (!keys) return;
2052
2122
  for (const key of keys) {
2053
- _optionalChain([this, 'access', _48 => _48.grid, 'access', _49 => _49.get, 'call', _50 => _50(key), 'optionalAccess', _51 => _51.delete, 'call', _52 => _52(id)]);
2123
+ _optionalChain([this, 'access', _65 => _65.grid, 'access', _66 => _66.get, 'call', _67 => _67(key), 'optionalAccess', _68 => _68.delete, 'call', _69 => _69(id)]);
2054
2124
  }
2055
2125
  this.entityCells.delete(id);
2056
2126
  }
@@ -2086,7 +2156,7 @@ var SpatialHashGrid = (_class6 = class {
2086
2156
  }, _class6);
2087
2157
 
2088
2158
  // src/tree/DOMPortalEntity.ts
2089
- var DOMPortalEntity = (_class7 = class extends _chunkLA3FJLP2js.Entity {
2159
+ var DOMPortalEntity = (_class7 = class extends _chunkTQ4H357Qjs.Entity {
2090
2160
 
2091
2161
  __init64() {this.isDOMPortal = true}
2092
2162
  __init65() {this.domListeners = []}
@@ -2097,8 +2167,9 @@ var DOMPortalEntity = (_class7 = class extends _chunkLA3FJLP2js.Entity {
2097
2167
  __init70() {this.lastHeight = ""}
2098
2168
  __init71() {this.lastTransform = ""}
2099
2169
  __init72() {this.lastZIndex = ""}
2170
+ __init73() {this.lastOpacity = ""}
2100
2171
  constructor(domElement, width, height, id) {
2101
- super(id);_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);;
2172
+ super(id);_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);;
2102
2173
  this.domElement = domElement;
2103
2174
  this.width = _nullishCoalesce(width, () => ( 0));
2104
2175
  this.height = _nullishCoalesce(height, () => ( 0));
@@ -2120,7 +2191,7 @@ var DOMPortalEntity = (_class7 = class extends _chunkLA3FJLP2js.Entity {
2120
2191
  const events = ["click", "pointerdown", "pointerup", "pointermove", "wheel"];
2121
2192
  for (const type of events) {
2122
2193
  const handler = (e) => {
2123
- this.dispatchEvent(new (0, _chunkLA3FJLP2js.VectoJSEvent)(type, this, e));
2194
+ this.dispatchEvent(new (0, _chunkTQ4H357Qjs.VectoJSEvent)(type, this, e));
2124
2195
  };
2125
2196
  this.domElement.addEventListener(type, handler);
2126
2197
  this.domListeners.push({ type, handler, capture: false });
@@ -2131,7 +2202,7 @@ var DOMPortalEntity = (_class7 = class extends _chunkLA3FJLP2js.Entity {
2131
2202
  ];
2132
2203
  for (const { native, vecto } of hoverEvents) {
2133
2204
  const handler = (e) => {
2134
- this.dispatchEvent(new (0, _chunkLA3FJLP2js.VectoJSEvent)(vecto, this, e, false));
2205
+ this.dispatchEvent(new (0, _chunkTQ4H357Qjs.VectoJSEvent)(vecto, this, e, false));
2135
2206
  };
2136
2207
  this.domElement.addEventListener(native, handler);
2137
2208
  this.domListeners.push({ type: native, handler, capture: false });
@@ -2139,7 +2210,7 @@ var DOMPortalEntity = (_class7 = class extends _chunkLA3FJLP2js.Entity {
2139
2210
  const focusEvents = ["focus", "blur"];
2140
2211
  for (const type of focusEvents) {
2141
2212
  const handler = (e) => {
2142
- this.dispatchEvent(new (0, _chunkLA3FJLP2js.VectoJSEvent)(type, this, e, true));
2213
+ this.dispatchEvent(new (0, _chunkTQ4H357Qjs.VectoJSEvent)(type, this, e, true));
2143
2214
  };
2144
2215
  this.domElement.addEventListener(type, handler, true);
2145
2216
  this.domListeners.push({ type, handler, capture: true });
@@ -2147,22 +2218,15 @@ var DOMPortalEntity = (_class7 = class extends _chunkLA3FJLP2js.Entity {
2147
2218
  }
2148
2219
  }
2149
2220
  isPointInside(globalX, globalY) {
2150
- const pos = this.getGlobalPosition();
2151
- const scale = this.getWorldScale();
2152
- const rot = this.getWorldRotation();
2153
- const dx = globalX - pos.x;
2154
- const dy = globalY - pos.y;
2155
- const cos = Math.cos(-rot);
2156
- const sin = Math.sin(-rot);
2157
- const lx = (dx * cos - dy * sin) / scale.x;
2158
- const ly = (dx * sin + dy * cos) / scale.y;
2159
2221
  const w = this.width > 0 ? this.width : this.cachedWidth;
2160
2222
  const h = this.height > 0 ? this.height : this.cachedHeight;
2161
- return lx >= 0 && lx <= w && ly >= 0 && ly <= h;
2223
+ const local = this.worldToLocal(globalX, globalY);
2224
+ if (!local) return false;
2225
+ return local.x >= 0 && local.x <= w && local.y >= 0 && local.y <= h;
2162
2226
  }
2163
- add(child) {
2227
+ add(_child) {
2164
2228
  console.warn(`DOMPortalEntity (${this.id}) is a leaf node. Child entities are not supported.`);
2165
- return super.add(child);
2229
+ return this;
2166
2230
  }
2167
2231
  render() {
2168
2232
  }
@@ -2185,8 +2249,10 @@ var DOMPortalEntity = (_class7 = class extends _chunkLA3FJLP2js.Entity {
2185
2249
  }, _class7);
2186
2250
 
2187
2251
  // src/index.ts
2188
- Scene.registerWebGLPointRendererCreator(_chunkLIX7DJTIjs.createWebGLPointRenderer);
2189
- Scene.registerWebGPUParticleSystemManager(_chunkLIX7DJTIjs.WebGPUParticleSystemManager);
2252
+ Scene.registerWebGLPointRendererCreator(_chunkTPNADFNNjs.createWebGLPointRenderer);
2253
+ Scene.registerWebGPUParticleSystemManager(_chunkTPNADFNNjs.WebGPUParticleSystemManager);
2254
+
2255
+
2190
2256
 
2191
2257
 
2192
2258
 
@@ -2229,4 +2295,4 @@ Scene.registerWebGPUParticleSystemManager(_chunkLIX7DJTIjs.WebGPUParticleSystemM
2229
2295
 
2230
2296
 
2231
2297
 
2232
- exports.ArabicShaper = _chunkRW6NC4RBjs.ArabicShaper; exports.BidiResolver = _chunkRW6NC4RBjs.BidiResolver; exports.CanvasRenderer = _chunkLIX7DJTIjs.CanvasRenderer; exports.ComputeParticleEntity = ComputeParticleEntity; exports.DOMPortalEntity = DOMPortalEntity; exports.Easing = _chunkLA3FJLP2js.Easing; exports.Entity = _chunkLA3FJLP2js.Entity; exports.GridTextEntity = GridTextEntity; exports.LayoutEngine = _chunk72WVPMSJjs.LayoutEngine; exports.LayoutResultBuffer = _chunk72WVPMSJjs.LayoutResultBuffer; exports.LayoutWorkerManager = _chunkRW6NC4RBjs.LayoutWorkerManager; exports.MSDFFont = _chunkLA3FJLP2js.MSDFFont; exports.MSDFTextEntity = _chunkLA3FJLP2js.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.SVGEntity = _chunkLA3FJLP2js.SVGEntity; exports.SVGRenderer = _chunkLIX7DJTIjs.SVGRenderer; exports.Scene = Scene; exports.SpatialHashGrid = SpatialHashGrid; exports.SplineEntity = SplineEntity; exports.SpringDriver = _chunkLA3FJLP2js.SpringDriver; exports.SpringPhysics = _chunkLA3FJLP2js.SpringPhysics; exports.TextEntity = TextEntity; exports.TweenDriver = _chunkLA3FJLP2js.TweenDriver; exports.VectoJSEvent = _chunkLA3FJLP2js.VectoJSEvent; exports.WebGPUParticleSystemManager = _chunkLIX7DJTIjs.WebGPUParticleSystemManager; exports.computeLineSegments = _chunk72WVPMSJjs.computeLineSegments; exports.createCanvasMeasurer = _chunk72WVPMSJjs.createCanvasMeasurer; exports.createWebGLPointRenderer = _chunkLIX7DJTIjs.createWebGLPointRenderer; exports.isTweenConfig = _chunkLA3FJLP2js.isTweenConfig; exports.loadSpline = loadSpline; exports.parseColorToRGBA = _chunkLIX7DJTIjs.parseColorToRGBA; exports.polySegmentToBezier = polySegmentToBezier;
2298
+ exports.ArabicShaper = _chunk76NMTLYLjs.ArabicShaper; exports.BidiResolver = _chunk76NMTLYLjs.BidiResolver; exports.CanvasRenderer = _chunkTPNADFNNjs.CanvasRenderer; exports.ComputeParticleEntity = ComputeParticleEntity; exports.DOMPortalEntity = DOMPortalEntity; exports.Easing = _chunkTQ4H357Qjs.Easing; exports.Entity = _chunkTQ4H357Qjs.Entity; exports.GridTextEntity = GridTextEntity; exports.LayoutEngine = _chunkIKLYTHALjs.LayoutEngine; exports.LayoutResultBuffer = _chunkIKLYTHALjs.LayoutResultBuffer; exports.LayoutWorkerManager = _chunk76NMTLYLjs.LayoutWorkerManager; exports.MSDFFont = _chunkTQ4H357Qjs.MSDFFont; exports.MSDFTextEntity = _chunkTQ4H357Qjs.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.SVGEntity = _chunkTQ4H357Qjs.SVGEntity; exports.SVGRenderer = _chunkTPNADFNNjs.SVGRenderer; exports.Scene = Scene; exports.SpatialHashGrid = SpatialHashGrid; exports.SplineEntity = SplineEntity; exports.SpringDriver = _chunkTQ4H357Qjs.SpringDriver; exports.SpringPhysics = _chunkTQ4H357Qjs.SpringPhysics; exports.TextEntity = TextEntity; exports.TweenDriver = _chunkTQ4H357Qjs.TweenDriver; exports.VectoJSEvent = _chunkTQ4H357Qjs.VectoJSEvent; exports.WebGPUParticleSystemManager = _chunkTPNADFNNjs.WebGPUParticleSystemManager; exports.computeLineSegments = _chunkIKLYTHALjs.computeLineSegments; exports.createCanvasMeasurer = _chunkIKLYTHALjs.createCanvasMeasurer; exports.createWebGLPointRenderer = _chunkTPNADFNNjs.createWebGLPointRenderer; exports.isSafeUrl = _chunkTPNADFNNjs.isSafeUrl; exports.isTweenConfig = _chunkTQ4H357Qjs.isTweenConfig; exports.loadSpline = loadSpline; exports.parseColorToRGBA = _chunkTPNADFNNjs.parseColorToRGBA; exports.polySegmentToBezier = polySegmentToBezier; exports.sanitizeUrl = _chunkTPNADFNNjs.sanitizeUrl;