@mulmoclaude/shapescript-plugin 2.5.0 → 2.6.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.
@@ -8893,7 +8893,7 @@ var Qc = class {
8893
8893
  }
8894
8894
  expectEndOfStatement() {
8895
8895
  let e = this.current(), t = this.tokens[this.pos - 1];
8896
- if (!(!t || e.type === a.NEWLINE || e.type === a.RBRACE || e.type === a.EOF || e.line !== t.line)) throw new o(`Unexpected \`${String(e.value)}\` after a statement — ShapeScript takes one statement per line; start a new line here`, e.line, e.column);
8896
+ if (t && e.type !== a.NEWLINE && e.type !== a.RBRACE && e.type !== a.EOF && e.line === t.line) throw new o(`Unexpected \`${String(e.value)}\` after a statement — ShapeScript takes one statement per line; start a new line here`, e.line, e.column);
8897
8897
  }
8898
8898
  skipNewlines() {
8899
8899
  for (; this.current().type === a.NEWLINE;) this.advance();
@@ -10454,8 +10454,7 @@ function _u(e, t, n, r, i = null, a = 0, o = 0) {
10454
10454
  let e = w(p);
10455
10455
  C = r(e, T(p) - e, !0, o + 1, a + p / 8, _);
10456
10456
  } else C = S && _u(p, t, n, r, i, a, o + 1);
10457
- if (C) return !0;
10458
- return !1;
10457
+ return !!C;
10459
10458
  function w(e) {
10460
10459
  let { uint16Array: t, uint32Array: n } = $, r = e * 2;
10461
10460
  for (; !zl(r, t);) e = Hl(e), r = e * 2;
@@ -13499,26 +13498,46 @@ function hh(e) {
13499
13498
  }
13500
13499
  return n;
13501
13500
  }
13502
- var gh = 3e4, _h = 8, vh = 12, yh = 4, bh = 1e-9, xh = class extends Error {
13501
+ var gh = "pathValue";
13502
+ function _h(e) {
13503
+ return e.userData[gh] = !0, e;
13504
+ }
13505
+ function vh(e) {
13506
+ return e.userData[gh] === !0;
13507
+ }
13508
+ var yh = /* @__PURE__ */ new Set([
13509
+ "circle",
13510
+ "square",
13511
+ "roundrect",
13512
+ "polygon"
13513
+ ]);
13514
+ function bh(e) {
13515
+ if (!vh(e)) throw Error("`loft` expects `path` cross-sections, not meshes — pass the path itself rather than a `fill` of it");
13516
+ if (e.isMesh) return tl(e);
13517
+ let t = hh(e);
13518
+ if (t.length < 3) throw Error("A `loft` cross-section needs at least three points");
13519
+ return t;
13520
+ }
13521
+ var xh = 3e4, Sh = 8, Ch = 12, wh = 4, Th = 1e-9, Eh = class extends Error {
13503
13522
  constructor(e) {
13504
13523
  super(e), this.name = "ShapeScriptLimitError";
13505
13524
  }
13506
13525
  };
13507
- function Sh(e) {
13526
+ function Dh(e) {
13508
13527
  return {
13509
13528
  ...e,
13510
13529
  color: e.color?.clone(),
13511
13530
  glow: e.glow?.clone()
13512
13531
  };
13513
13532
  }
13514
- var Ch = 200, wh = 200;
13515
- function Th(e) {
13533
+ var Oh = 200, kh = 200;
13534
+ function Ah(e) {
13516
13535
  let t = e.getAttribute("position"), n = e.getIndex(), r = n?.count ?? t.count, i = new J(), a = new J(), o = new J(), s = 0;
13517
13536
  for (let e = 0; e < r; e += 3) i.fromBufferAttribute(t, n ? n.getX(e) : e), a.fromBufferAttribute(t, n ? n.getX(e + 1) : e + 1), o.fromBufferAttribute(t, n ? n.getX(e + 2) : e + 2), s += i.dot(a.cross(o));
13518
13537
  return s / 6;
13519
13538
  }
13520
- function Eh(e) {
13521
- if (Th(e) >= 0) return e;
13539
+ function jh(e) {
13540
+ if (Ah(e) >= 0) return e;
13522
13541
  let t = e.getIndex();
13523
13542
  if (t) {
13524
13543
  for (let e = 0; e < t.count; e += 3) {
@@ -13534,10 +13553,10 @@ function Eh(e) {
13534
13553
  }
13535
13554
  return e;
13536
13555
  }
13537
- function Dh(e) {
13556
+ function Mh(e) {
13538
13557
  return Math.max(0, Math.round(Math.log2(Math.max(4, e))) - 2);
13539
13558
  }
13540
- var Oh = class {
13559
+ var Nh = class {
13541
13560
  options;
13542
13561
  evaluator;
13543
13562
  symbols;
@@ -13553,6 +13572,7 @@ var Oh = class {
13553
13572
  logs = [];
13554
13573
  background;
13555
13574
  sceneDepth = 0;
13575
+ customShapeDepth = 0;
13556
13576
  valueSink = null;
13557
13577
  retained = [];
13558
13578
  constructor(e = {}) {
@@ -13594,15 +13614,14 @@ var Oh = class {
13594
13614
  this.chargeEstimate(r * n);
13595
13615
  }
13596
13616
  chargeEstimate(e) {
13597
- if (this.vertexCount + e > this.maxVertices) throw new xh(`ShapeScript exceeds ${this.maxVertices} vertices — lower \`detail\` or simplify the path`);
13617
+ if (this.vertexCount + e > this.maxVertices) throw new Eh(`ShapeScript exceeds ${this.maxVertices} vertices — lower \`detail\` or simplify the path`);
13598
13618
  }
13599
13619
  makeMesh(e, t) {
13600
- if (this.vertexCount += e.getAttribute("position")?.count ?? 0, this.vertexCount > this.maxVertices) throw e.dispose(), t.dispose(), new xh(`ShapeScript exceeds ${this.maxVertices} vertices — lower \`detail\` or use fewer shapes`);
13620
+ if (this.vertexCount += e.getAttribute("position")?.count ?? 0, this.vertexCount > this.maxVertices) throw e.dispose(), t.dispose(), new Eh(`ShapeScript exceeds ${this.maxVertices} vertices — lower \`detail\` or use fewer shapes`);
13601
13621
  return new ti(e, t);
13602
13622
  }
13603
13623
  convertNode(e) {
13604
- if (this.nodeCount += 1, this.nodeCount > this.maxNodes) throw new xh(`ShapeScript produced more than ${this.maxNodes} objectsreduce the loop counts or the nesting`);
13605
- if (Date.now() - this.startedAt > this.maxDurationMs) throw new xh(`ShapeScript took longer than ${this.maxDurationMs}ms to build — simplify the model or use fewer boolean operations`);
13624
+ if (Ph.has(e.type) && this.chargeNode(), Date.now() - this.startedAt > this.maxDurationMs) throw new Eh(`ShapeScript took longer than ${this.maxDurationMs}ms to build simplify the model or use fewer boolean operations`);
13606
13625
  switch (e.type) {
13607
13626
  case "shape": return this.convertShape(e);
13608
13627
  case "csg": return this.convertCSG(e);
@@ -13625,7 +13644,7 @@ var Oh = class {
13625
13644
  case "material": return this.handleMaterialCommand(e), null;
13626
13645
  case "smoothing": return this.currentTransform().material.smoothing = this.evaluateNumber(e.value), null;
13627
13646
  case "background": return this.handleBackground(e.value), null;
13628
- case "print": return this.logs.length < Ch && this.logs.push(Fh(this.evaluator.evaluate(e.value))), null;
13647
+ case "print": return this.logs.length < Oh && this.logs.push(Uh(this.evaluator.evaluate(e.value))), null;
13629
13648
  case "assert":
13630
13649
  if (!this.evaluator.evaluateToBoolean(e.value)) throw Error("Assertion failed");
13631
13650
  return null;
@@ -13644,10 +13663,10 @@ var Oh = class {
13644
13663
  convertPathProfile(e) {
13645
13664
  return this.withPathDetail(() => {
13646
13665
  let t = this.collectPathPoints(e), n = this.shapeFromPathPoints(t);
13647
- if (!mh(t)) return this.lineFromPath(e, n);
13648
- this.chargePathEstimate(n, vh), this.requireEnclosedArea(n, "path");
13666
+ if (!mh(t)) return _h(this.lineFromPath(e, n));
13667
+ this.chargePathEstimate(n, Ch), this.requireEnclosedArea(n, "path");
13649
13668
  let r = this.makeMesh(this.placePath(new Qa(n), e), this.createMaterial({ properties: {} }));
13650
- return this.applyCurrentTransform(r), r;
13669
+ return this.applyCurrentTransform(r), _h(r);
13651
13670
  });
13652
13671
  }
13653
13672
  withPathDetail(e) {
@@ -13668,7 +13687,7 @@ var Oh = class {
13668
13687
  return this.applyCurrentTransform(o), o;
13669
13688
  }
13670
13689
  warn(e) {
13671
- this.warningSet.has(e) || this.warnings.length >= wh || (this.warningSet.add(e), this.warnings.push(e));
13690
+ this.warningSet.has(e) || this.warnings.length >= kh || (this.warningSet.add(e), this.warnings.push(e));
13672
13691
  }
13673
13692
  handleBackground(e) {
13674
13693
  if (this.sceneDepth > 0) throw Error("`background` can only be used at the root of the script");
@@ -13697,6 +13716,9 @@ var Oh = class {
13697
13716
  this.sceneDepth--, this.popTransform(), this.symbols.popScope();
13698
13717
  }
13699
13718
  }
13719
+ chargeNode() {
13720
+ if (this.nodeCount += 1, this.nodeCount > this.maxNodes) throw new Eh(`ShapeScript produced more than ${this.maxNodes} objects — reduce the loop counts or the nesting`);
13721
+ }
13700
13722
  addChildren(e, t) {
13701
13723
  for (let n of t) {
13702
13724
  let t = this.convertNode(n);
@@ -13737,7 +13759,10 @@ var Oh = class {
13737
13759
  }
13738
13760
  }
13739
13761
  convertShape(e) {
13740
- return e.points === void 0 ? this.withShapeOptions(e.properties, () => this.finishMesh(this.createGeometry(e), e, !1)) : this.placeValue(this.polygonValue(e));
13762
+ return e.points === void 0 ? this.withShapeOptions(e.properties, () => {
13763
+ let t = this.finishMesh(this.createGeometry(e), e, !1);
13764
+ return yh.has(e.primitive) ? _h(t) : t;
13765
+ }) : this.placeValue(this.polygonValue(e), { charged: !0 });
13741
13766
  }
13742
13767
  captureValues(e, t) {
13743
13768
  let n = this.valueSink;
@@ -13748,25 +13773,26 @@ var Oh = class {
13748
13773
  this.valueSink = n;
13749
13774
  }
13750
13775
  }
13751
- placeValue(e) {
13776
+ placeValue(e, { charged: t = !1 } = {}) {
13752
13777
  if (this.valueSink) return this.valueSink.push(this.transformedForCapture(e)), null;
13753
- if (_c(e) && e.kind === "mesh") return this.placeMesh(e);
13778
+ if (!t && Rh(e) && this.chargeNode(), _c(e) && e.kind === "mesh") return this.placeMesh(e);
13754
13779
  if (_c(e) && e.kind === "polygon") return this.placePolygons([e]);
13755
13780
  if (Array.isArray(e) && e.length > 0 && e.every((e) => _c(e) && (e.kind === "mesh" || e.kind === "polygon"))) {
13756
- let t = e.filter((e) => _c(e) && e.kind === "mesh"), n = e.filter((e) => _c(e) && e.kind === "polygon"), r = n.length ? Ms(n, n.some((e) => e.colors)) : void 0, i = Ph([...t.map((e) => e.geometry), ...r ? [r] : []]);
13781
+ let t = e.filter((e) => _c(e) && e.kind === "mesh"), n = e.filter((e) => _c(e) && e.kind === "polygon"), r = n.length ? Ms(n, n.some((e) => e.colors)) : void 0, i = Hh([...t.map((e) => e.geometry), ...r ? [r] : []]);
13757
13782
  r?.dispose();
13758
- let a = this.placeMesh({
13783
+ let a = n.length === 0 && t.every((e) => e.path), o = this.placeMesh({
13759
13784
  kind: "mesh",
13760
- geometry: i
13785
+ geometry: i,
13786
+ ...a ? { path: a } : {}
13761
13787
  });
13762
- return i.dispose(), a;
13788
+ return i.dispose(), o;
13763
13789
  }
13764
13790
  throw Error("Unused value — a statement that is not a shape does nothing here; use `define` or `print`");
13765
13791
  }
13766
13792
  transformedForCapture(e) {
13767
13793
  let t = this.currentTransform().matrix, n = t.equals(new Y());
13768
13794
  if (Array.isArray(e)) return n ? e : e.map((e) => this.transformedForCapture(e));
13769
- if (!jh(e) || n) return e;
13795
+ if (!zh(e) || n) return e;
13770
13796
  if (e.kind === "polygon") return {
13771
13797
  ...e,
13772
13798
  points: e.points.map((e) => new J(...e).applyMatrix4(t).toArray())
@@ -13788,7 +13814,7 @@ var Oh = class {
13788
13814
  }
13789
13815
  placeMesh(e) {
13790
13816
  let t = e.geometry.clone(), n = this.makeMesh(t, this.createMaterial({ properties: {} }, void 0, t.hasAttribute("color")));
13791
- return e.name !== void 0 && (n.name = e.name), this.applyCurrentTransform(n), n;
13817
+ return e.name !== void 0 && (n.name = e.name), e.path && _h(n), this.applyCurrentTransform(n), n;
13792
13818
  }
13793
13819
  placePolygons(e) {
13794
13820
  let t = e.some((e) => e.colors !== void 0), n = Ms(e, t);
@@ -13806,31 +13832,32 @@ var Oh = class {
13806
13832
  this.captureValues(r, () => this.inScope(n, () => {
13807
13833
  this.currentTransform().matrix.identity(), this.addChildren(n, e), t?.(r);
13808
13834
  }));
13809
- let i = this.meshesIn(n), a = i.map((e) => Mh(e).applyMatrix4(e.matrixWorld)), o = i.length === 1 ? i[0] : void 0, s = o?.geometry.userData.polygons, c = o && s ? s.map((e) => ({
13835
+ let i = this.meshesIn(n), a = i.map((e) => Bh(e).applyMatrix4(e.matrixWorld)), o = i.length === 1 ? i[0] : void 0, s = o?.geometry.userData.polygons, c = o && s ? s.map((e) => ({
13810
13836
  ...e,
13811
13837
  points: e.points.map((e) => new J(...e).applyMatrix4(o.matrixWorld).toArray())
13812
- })) : void 0;
13838
+ })) : void 0, l = i.length > 0 && i.every(vh);
13813
13839
  return {
13814
13840
  captured: r,
13815
13841
  geometries: a,
13816
13842
  name: o?.name || void 0,
13817
- polygons: c
13843
+ polygons: c,
13844
+ path: l
13818
13845
  };
13819
13846
  } finally {
13820
13847
  oh(n), this.vertexCount = i, this.vertexCount += this.retained.slice(a).reduce((e, t) => e + t.getAttribute("position").count, 0);
13821
13848
  }
13822
13849
  }
13823
13850
  convertMesh(e) {
13824
- let { captured: t, geometries: n } = this.buildScratch(e.children), r = Ah(t).filter((e) => e.kind === "polygon"), i = Ah(t).filter((e) => e.kind === "mesh"), a = r.some((e) => e.colors !== void 0), o = [...r.length ? [Ms(r, a)] : [], ...n], s = [...o, ...i.map((e) => e.geometry)];
13851
+ let { captured: t, geometries: n } = this.buildScratch(e.children), r = Lh(t).filter((e) => e.kind === "polygon"), i = Lh(t).filter((e) => e.kind === "mesh"), a = r.some((e) => e.colors !== void 0), o = [...r.length ? [Ms(r, a)] : [], ...n], s = [...o, ...i.map((e) => e.geometry)];
13825
13852
  if (s.length === 0) throw Error("`mesh` needs at least one polygon");
13826
- let c = Ph(s);
13853
+ let c = Hh(s);
13827
13854
  o.forEach((e) => e.dispose()), i.length === 0 && n.length === 0 && (c.userData = { polygons: r });
13828
13855
  let l = this.makeMesh(c, this.createMaterial({ properties: {} }, void 0, c.hasAttribute("color")));
13829
13856
  return this.applyCurrentTransform(l), l;
13830
13857
  }
13831
13858
  polygonValue(e) {
13832
13859
  let t = [], n = [], r = e.properties.color === void 0 ? void 0 : this.evaluateRGBA(e.properties.color), i = r !== void 0, a = (e) => {
13833
- if (++this.pathCommandCount > this.maxLoopIterations) throw new xh(`ShapeScript polygon exceeds ${this.maxLoopIterations} commands`);
13860
+ if (++this.pathCommandCount > this.maxLoopIterations) throw new Eh(`ShapeScript polygon exceeds ${this.maxLoopIterations} commands`);
13834
13861
  switch (e.type) {
13835
13862
  case "define":
13836
13863
  this.handleDefine(e);
@@ -13898,29 +13925,31 @@ var Oh = class {
13898
13925
  }), t;
13899
13926
  }
13900
13927
  shapeValue(e) {
13901
- let { captured: t, geometries: n, name: r, polygons: i } = this.buildScratch([e]);
13928
+ let { captured: t, geometries: n, name: r, polygons: i, path: a } = this.buildScratch([e]);
13902
13929
  if (n.length === 0) {
13903
13930
  if (t.length === 1) return t[0];
13904
13931
  if (t.length > 1) return t;
13905
13932
  throw Error("The shape used as a value produced nothing");
13906
13933
  }
13907
- let a = Ph(n);
13908
- return n.forEach((e) => e.dispose()), this.chargeRetained(a), {
13934
+ let o = Hh(n);
13935
+ return n.forEach((e) => e.dispose()), this.chargeRetained(o), {
13909
13936
  kind: "mesh",
13910
- geometry: a,
13937
+ geometry: o,
13911
13938
  ...r === void 0 ? {} : { name: r },
13912
- ...i === void 0 ? {} : { polygons: i }
13939
+ ...i === void 0 ? {} : { polygons: i },
13940
+ ...a ? { path: a } : {}
13913
13941
  };
13914
13942
  }
13915
13943
  callShapeFunction(e, t) {
13916
13944
  let { params: n = [], body: r = [], value: i, name: a } = e.definition;
13917
13945
  return this.evaluator.withArguments(n, t, () => {
13918
- let { captured: e, geometries: t } = this.buildScratch(r, (e) => {
13946
+ let { captured: e, geometries: t, path: n } = this.buildScratch(r, (e) => {
13919
13947
  i !== void 0 && e.push(this.transformedForCapture(this.evaluator.evaluate(i)));
13920
13948
  });
13921
- for (let n of t) this.chargeRetained(n), e.push({
13949
+ for (let r of t) this.chargeRetained(r), e.push({
13922
13950
  kind: "mesh",
13923
- geometry: n
13951
+ geometry: r,
13952
+ ...n ? { path: n } : {}
13924
13953
  });
13925
13954
  if (e.length === 0) throw Error(`Function \`${a}\` produced no value`);
13926
13955
  return e.length === 1 ? e[0] : e;
@@ -13934,7 +13963,7 @@ var Oh = class {
13934
13963
  switch (e.primitive) {
13935
13964
  case "cube": return this.requireExtent("cube", t), new Ai(t[0], t[1], t[2]);
13936
13965
  case "sphere": return this.requireExtent("sphere", t), new eo(.5, this.detailLevel, this.detailLevel).scale(...t);
13937
- case "icosphere": return this.requireExtent("icosphere", t), js(.5, Dh(this.detailLevel)).geometry.scale(...t);
13966
+ case "icosphere": return this.requireExtent("icosphere", t), js(.5, Mh(this.detailLevel)).geometry.scale(...t);
13938
13967
  case "cylinder": {
13939
13968
  let n = e.properties.radiusTop ? this.evaluateNumber(e.properties.radiusTop) : t[0] / 2, r = e.properties.radiusBottom ? this.evaluateNumber(e.properties.radiusBottom) : t[0] / 2, i = e.properties.height ? this.evaluateNumber(e.properties.height) : t[1];
13940
13969
  return this.requireExtent("cylinder", [n || r, i]), new Mi(n, r, i, this.detailLevel);
@@ -13970,7 +13999,7 @@ var Oh = class {
13970
13999
  return this.requireExtent("torus", [i, a]), new to(i, a, Math.max(3, Math.floor(this.detailLevel / 2)), this.detailLevel);
13971
14000
  }
13972
14001
  materialFor(e, t) {
13973
- let n = Sh(t);
14002
+ let n = Dh(t);
13974
14003
  return e.material !== void 0 && this.applyMaterialValue(n, this.evaluator.evaluate(e.material)), e.color !== void 0 && this.applyColor(n, this.evaluateRGBA(e.color)), e.opacity !== void 0 && (n.opacity *= this.evaluateNumber(e.opacity)), e.metallicity !== void 0 && (n.metallicity = this.evaluateNumber(e.metallicity)), e.roughness !== void 0 && (n.roughness = this.evaluateNumber(e.roughness)), e.glow !== void 0 && (n.glow = this.glowColor(this.evaluator.evaluate(e.glow))), e.texture !== void 0 && this.warnTexture(this.evaluator.evaluate(e.texture)), n;
13975
14004
  }
13976
14005
  applyColor(e, [t, n, r, i]) {
@@ -14092,7 +14121,7 @@ var Oh = class {
14092
14121
  });
14093
14122
  }
14094
14123
  iterations(e) {
14095
- return Fc(this.evaluator.evaluate(e), this.maxLoopIterations, () => new xh(`ShapeScript loop exceeds ${this.maxLoopIterations} iterations — narrow the range or increase the step`));
14124
+ return Fc(this.evaluator.evaluate(e), this.maxLoopIterations, () => new Eh(`ShapeScript loop exceeds ${this.maxLoopIterations} iterations — narrow the range or increase the step`));
14096
14125
  }
14097
14126
  convertIf(e) {
14098
14127
  let t = new An(), n = this.evaluator.evaluateToBoolean(e.condition);
@@ -14110,7 +14139,7 @@ var Oh = class {
14110
14139
  }
14111
14140
  convertCustomShape(e) {
14112
14141
  let t = this.symbols.get(e.name);
14113
- if (t !== void 0 && jh(t)) {
14142
+ if (t !== void 0 && zh(t)) {
14114
14143
  let n = new An();
14115
14144
  return this.inScope(n, () => {
14116
14145
  this.applyPlacement(this.currentTransform().matrix, e.properties);
@@ -14122,18 +14151,27 @@ var Oh = class {
14122
14151
  if (typeof t != "object" || Array.isArray(t) || !("type" in t)) return this.placeValue(t);
14123
14152
  let n = t;
14124
14153
  if (!n.body) throw Error(`Custom shape '${e.name}' has no body`);
14125
- let r = new An(), i = n.body, { position: a, orientation: o, rotation: s, size: c, name: l, ...u } = e.properties;
14126
- return this.inScope(r, () => {
14127
- this.applyPlacement(this.currentTransform().matrix, {
14128
- position: a,
14129
- orientation: o,
14130
- rotation: s,
14131
- size: c
14132
- }), this.currentTransform().material = this.materialFor(u, this.currentTransform().material);
14133
- for (let e of n.options ?? []) this.symbols.set(e.name, this.evaluator.evaluate(e.defaultValue));
14134
- for (let [e, t] of Object.entries(u)) e in kh || this.symbols.set(e, this.evaluator.evaluate(t));
14135
- l !== void 0 && (r.name = String(this.evaluator.evaluate(l))), this.withShapeOptions(u, () => this.addChildren(r, i));
14136
- });
14154
+ if (this.customShapeDepth >= Fh) throw Error(`Custom shape \`${e.name}\` recursed more than ${Fh} levels deep`);
14155
+ let r = new An(), i = n.body, { position: a, orientation: o, rotation: s, size: c, name: l, ...u } = e.properties, d = this.evaluateOptionOverrides(u);
14156
+ this.customShapeDepth++;
14157
+ try {
14158
+ return this.inScope(r, () => {
14159
+ this.applyPlacement(this.currentTransform().matrix, {
14160
+ position: a,
14161
+ orientation: o,
14162
+ rotation: s,
14163
+ size: c
14164
+ }), this.currentTransform().material = this.materialFor(u, this.currentTransform().material);
14165
+ for (let e of n.options ?? []) this.symbols.set(e.name, this.evaluator.evaluate(e.defaultValue));
14166
+ for (let [e, t] of d) this.symbols.set(e, t);
14167
+ l !== void 0 && (r.name = String(this.evaluator.evaluate(l))), this.withShapeOptions(u, () => this.addChildren(r, i));
14168
+ });
14169
+ } finally {
14170
+ this.customShapeDepth--;
14171
+ }
14172
+ }
14173
+ evaluateOptionOverrides(e) {
14174
+ return Object.entries(e).filter(([e]) => !(e in Ih)).map(([e, t]) => [e, this.evaluator.evaluate(t)]);
14137
14175
  }
14138
14176
  applyPlacement(e, t) {
14139
14177
  let n = t.position ? new J(...this.evaluateVector3(t.position)) : new J(), r = t.orientation ?? t.rotation, i = r ? this.rotationOf(r) : new Mt(), a = t.size ? new J(...this.evaluateSize(t.size)) : new J(1, 1, 1);
@@ -14143,7 +14181,7 @@ var Oh = class {
14143
14181
  let e = this.currentTransform();
14144
14182
  this.transformStack.push({
14145
14183
  matrix: e.matrix.clone(),
14146
- material: Sh(e.material)
14184
+ material: Dh(e.material)
14147
14185
  });
14148
14186
  }
14149
14187
  popTransform() {
@@ -14241,9 +14279,9 @@ var Oh = class {
14241
14279
  n.matrix.multiply(r);
14242
14280
  }
14243
14281
  requireEnclosedArea(e, t) {
14244
- let n = e.getPoints(vh), r = Wa.area(n);
14282
+ let n = e.getPoints(Ch), r = Wa.area(n);
14245
14283
  if (!Number.isFinite(r)) throw Error(`\`${t}\` needs finite path coordinates — these overflow`);
14246
- if (n.length < 3 || Math.abs(r) < bh) throw Error(`\`${t}\` needs a path that encloses an area — this one has fewer than three distinct points, or they are collinear`);
14284
+ if (n.length < 3 || Math.abs(r) < Th) throw Error(`\`${t}\` needs a path that encloses an area — this one has fewer than three distinct points, or they are collinear`);
14247
14285
  return e;
14248
14286
  }
14249
14287
  extrudeProperties(e) {
@@ -14270,7 +14308,7 @@ var Oh = class {
14270
14308
  let { depth: t, properties: n } = this.extrudeProperties(e);
14271
14309
  return e.path ? this.withPathDetail(() => {
14272
14310
  let r = e.path, i = this.collectPathPoints(r), a = this.shapeFromPathPoints(i), o = Math.max(1, Math.floor(this.detailLevel / 4));
14273
- this.chargePathEstimate(a, o, yh);
14311
+ this.chargePathEstimate(a, o, wh);
14274
14312
  let s = mh(i) ? new qa(this.requireEnclosedArea(a, "extrude"), {
14275
14313
  depth: t,
14276
14314
  bevelEnabled: !1,
@@ -14290,7 +14328,7 @@ var Oh = class {
14290
14328
  curveSegments: 1
14291
14329
  }).translate(0, 0, -t / 2)] : [], a = n.map((e) => ul(hh(e), t)), o = [...i, ...a];
14292
14330
  for (let e of o) this.chargeEstimate(e.getAttribute("position").count);
14293
- let s = o.length === 1 ? o[0] : Ph(o);
14331
+ let s = o.length === 1 ? o[0] : Hh(o);
14294
14332
  return o.length > 1 && o.forEach((e) => e.dispose()), s;
14295
14333
  });
14296
14334
  });
@@ -14309,7 +14347,7 @@ var Oh = class {
14309
14347
  if (!n.length) throw Error("`extrude … along` needs a planar section to sweep");
14310
14348
  let { points: r, closed: i } = this.sweepPathOf(t);
14311
14349
  this.chargeEstimate(n.reduce((e, t) => e + t.length * r.length, 0));
14312
- let a = n.map((e) => al(ol(e, r, i), i)), o = a.length === 1 ? a[0] : Ph(a);
14350
+ let a = n.map((e) => al(ol(e, r, i), i)), o = a.length === 1 ? a[0] : Hh(a);
14313
14351
  return a.length > 1 && a.forEach((e) => e.dispose()), o;
14314
14352
  });
14315
14353
  }
@@ -14349,7 +14387,7 @@ var Oh = class {
14349
14387
  }, a = (e) => {
14350
14388
  if (t.multiply(e), !t.elements.every(Number.isFinite)) throw Error("Path transform overflowed to a non-finite value — `translate`, `rotate` and `scale` accumulate inside a path");
14351
14389
  }, o = (e) => {
14352
- if (++this.pathCommandCount > this.maxLoopIterations) throw new xh(`ShapeScript path exceeds ${this.maxLoopIterations} commands`);
14390
+ if (++this.pathCommandCount > this.maxLoopIterations) throw new Eh(`ShapeScript path exceeds ${this.maxLoopIterations} commands`);
14353
14391
  switch (e.type) {
14354
14392
  case "define":
14355
14393
  this.handleDefine(e);
@@ -14449,7 +14487,7 @@ var Oh = class {
14449
14487
  requireLatheProfile(e) {
14450
14488
  if (!e.every((e) => Number.isFinite(e.x) && Number.isFinite(e.y))) throw Error("`lathe` profile has non-finite coordinates — a curve control point or a path command overflowed");
14451
14489
  let t = Math.max(...e.map((e) => Math.abs(e.x))), n = Math.max(...e.map((e) => e.y)) - Math.min(...e.map((e) => e.y));
14452
- if (t < bh || n < bh) throw Error("`lathe` needs a profile with both radius and height — one on the axis of rotation sweeps nothing");
14490
+ if (t < Th || n < Th) throw Error("`lathe` needs a profile with both radius and height — one on the axis of rotation sweeps nothing");
14453
14491
  }
14454
14492
  buildLathe(e) {
14455
14493
  let t = null;
@@ -14469,7 +14507,7 @@ var Oh = class {
14469
14507
  if (r.length < 2) throw Error("Lathe path must have at least 2 points");
14470
14508
  if (this.requireLatheProfile(r), r.every((e) => e.x <= uh)) for (let e of r) e.x = -e.x;
14471
14509
  this.chargeEstimate(r.length * (this.detailLevel + 1));
14472
- let i = Eh(new Xa(r, this.detailLevel));
14510
+ let i = jh(new Xa(r, this.detailLevel));
14473
14511
  return this.finishMesh(i, e, !0, this.currentTransform().material);
14474
14512
  });
14475
14513
  }
@@ -14478,18 +14516,22 @@ var Oh = class {
14478
14516
  this.operandDepth++;
14479
14517
  try {
14480
14518
  this.captureValues(null, () => this.inScope(e, () => {
14481
- this.currentTransform().matrix.identity(), this.addChildren(e, t), n = Sh(this.currentTransform().material);
14519
+ this.currentTransform().matrix.identity(), this.addChildren(e, t), n = Dh(this.currentTransform().material);
14482
14520
  }));
14483
14521
  } finally {
14484
14522
  this.operandDepth--;
14485
14523
  }
14486
14524
  e.updateMatrixWorld(!0);
14487
- let r = [], i = [];
14525
+ let r = [], i = [], a = [];
14488
14526
  return e.traverse((e) => {
14489
- e.isMesh ? r.push(e) : e.isLine && i.push(e);
14527
+ if (e.isMesh) r.push(e);
14528
+ else if (e.isLine) i.push(e);
14529
+ else return;
14530
+ a.push(e);
14490
14531
  }), {
14491
14532
  meshes: r,
14492
14533
  lines: i,
14534
+ operands: a,
14493
14535
  material: n
14494
14536
  };
14495
14537
  }
@@ -14497,7 +14539,7 @@ var Oh = class {
14497
14539
  let n = new An(), r = this.vertexCount, i, a;
14498
14540
  try {
14499
14541
  let r = this.buildOperands(n, e.children);
14500
- a = r.material, i = t(r.meshes, r.lines);
14542
+ a = r.material, i = t(r.meshes, r.lines, r.operands);
14501
14543
  } finally {
14502
14544
  oh(n), this.vertexCount = r;
14503
14545
  }
@@ -14507,9 +14549,9 @@ var Oh = class {
14507
14549
  return this.withShapeOptions(e.properties, () => this.buildLoft(e));
14508
14550
  }
14509
14551
  buildLoft(e) {
14510
- return this.buildFromChildren(e, (e) => {
14511
- let t = e.map(tl), n = t.length * Math.max(0, ...t.map((e) => e.length));
14512
- return this.chargeEstimate(n), al(t);
14552
+ return this.buildFromChildren(e, (e, t, n) => {
14553
+ let r = n.map(bh), i = r.length * Math.max(0, ...r.map((e) => e.length));
14554
+ return this.chargeEstimate(i), al(r);
14513
14555
  });
14514
14556
  }
14515
14557
  planarShapes(e) {
@@ -14523,11 +14565,11 @@ var Oh = class {
14523
14565
  let t = El(this.textOf(e), {
14524
14566
  ...e.wrapWidth === void 0 ? {} : { wrapWidth: this.textWrapWidth(e.wrapWidth) },
14525
14567
  lineSpacing: e.lineSpacing === void 0 ? 0 : this.evaluateNumber(e.lineSpacing),
14526
- curveSegments: Math.max(1, Math.floor(this.detailLevel / _h))
14568
+ curveSegments: Math.max(1, Math.floor(this.detailLevel / Sh))
14527
14569
  });
14528
14570
  t.missing.length && this.warn(`The built-in font has no glyph for ${[...new Set(t.missing)].map((e) => `"${e}"`).join(" ")} — drawn as "?"`);
14529
14571
  let n = t.rings.reduce((e, t) => e + t.length, 0);
14530
- return t.shapes.length === 0 ? null : this.operandDepth > 0 || this.valueSink !== null ? (this.chargeEstimate(n), this.finishMesh(new Qa(t.shapes, 1), e, !0)) : this.textOutline(e, t, n);
14572
+ return t.shapes.length === 0 ? null : this.operandDepth > 0 || this.valueSink !== null ? (this.chargeEstimate(n), _h(this.finishMesh(new Qa(t.shapes, 1), e, !0))) : this.textOutline(e, t, n);
14531
14573
  });
14532
14574
  }
14533
14575
  textWrapWidth(e) {
@@ -14538,7 +14580,7 @@ var Oh = class {
14538
14580
  textOf(e) {
14539
14581
  let t = e.lines.map((e) => {
14540
14582
  let t = this.evaluator.evaluate(e);
14541
- return Dl(Array.isArray(t) ? t : [t], (e) => Fh(e));
14583
+ return Dl(Array.isArray(t) ? t : [t], (e) => Uh(e));
14542
14584
  }).join("\n");
14543
14585
  if (t.length > 2e3) throw Error(`\`text\` is limited to ${hl} characters`);
14544
14586
  return t;
@@ -14575,7 +14617,7 @@ var Oh = class {
14575
14617
  return new Qa(t, 1);
14576
14618
  });
14577
14619
  let n = this.buildPath(t);
14578
- this.chargePathEstimate(n, vh), this.requireEnclosedArea(n, "fill");
14620
+ this.chargePathEstimate(n, Ch), this.requireEnclosedArea(n, "fill");
14579
14621
  let r = this.placePath(new Qa(n), t);
14580
14622
  return this.finishMesh(r, e);
14581
14623
  });
@@ -14600,7 +14642,7 @@ var Oh = class {
14600
14642
  throw r.dispose(), e;
14601
14643
  }
14602
14644
  this.chargeEstimate(r.getAttribute("position").count);
14603
- let a = Nh(t);
14645
+ let a = Vh(t);
14604
14646
  return a && r.setAttribute("color", new X(new Float32Array(r.getAttribute("position").count * 3).map((e, t) => a[t % 3]), 3)), r;
14605
14647
  });
14606
14648
  }
@@ -14675,7 +14717,19 @@ var Oh = class {
14675
14717
  if (!e.every(Number.isFinite)) throw Error("Expected finite color channels");
14676
14718
  return e;
14677
14719
  }
14678
- }, kh = {
14720
+ }, Ph = /* @__PURE__ */ new Set([
14721
+ "shape",
14722
+ "csg",
14723
+ "extrude",
14724
+ "loft",
14725
+ "lathe",
14726
+ "fill",
14727
+ "hull",
14728
+ "minkowski",
14729
+ "text",
14730
+ "mesh",
14731
+ "path"
14732
+ ]), Fh = 256, Ih = {
14679
14733
  position: !0,
14680
14734
  orientation: !0,
14681
14735
  rotation: !0,
@@ -14690,23 +14744,26 @@ var Oh = class {
14690
14744
  detail: !0,
14691
14745
  smoothing: !0
14692
14746
  };
14693
- function Ah(e) {
14747
+ function Lh(e) {
14694
14748
  let t = [];
14695
- for (let n of e) Array.isArray(n) ? t.push(...Ah(n)) : jh(n) && t.push(n);
14749
+ for (let n of e) Array.isArray(n) ? t.push(...Lh(n)) : zh(n) && t.push(n);
14696
14750
  return t;
14697
14751
  }
14698
- function jh(e) {
14752
+ function Rh(e) {
14753
+ return zh(e) || Array.isArray(e) && e.length > 0 && e.every(zh);
14754
+ }
14755
+ function zh(e) {
14699
14756
  return _c(e) && (e.kind === "mesh" || e.kind === "polygon");
14700
14757
  }
14701
- function Mh(e) {
14702
- let t = e.geometry.clone(), n = Nh(e);
14758
+ function Bh(e) {
14759
+ let t = e.geometry.clone(), n = Vh(e);
14703
14760
  if (n && !t.hasAttribute("color")) {
14704
14761
  let e = t.getAttribute("position").count;
14705
14762
  t.setAttribute("color", new X(new Float32Array(e * 3).map((e, t) => n[t % 3]), 3));
14706
14763
  }
14707
14764
  return t;
14708
14765
  }
14709
- function Nh(e) {
14766
+ function Vh(e) {
14710
14767
  let t = Array.isArray(e.material) ? e.material[0] : e.material, n = e.geometry.getAttribute("color");
14711
14768
  if (n && n.count > 0) {
14712
14769
  let e = [
@@ -14723,7 +14780,7 @@ function Nh(e) {
14723
14780
  t.color.b
14724
14781
  ];
14725
14782
  }
14726
- function Ph(e) {
14783
+ function Hh(e) {
14727
14784
  let t = e.some((e) => e.hasAttribute("color")), n = e.map((e) => {
14728
14785
  let n = e.index ? e.toNonIndexed() : e.clone();
14729
14786
  n.hasAttribute("normal") || n.computeVertexNormals();
@@ -14740,11 +14797,11 @@ function Ph(e) {
14740
14797
  if (!r) throw Error("Could not combine the shapes into one mesh");
14741
14798
  return n.length > 1 && n.forEach((e) => e.dispose()), r;
14742
14799
  }
14743
- function Fh(e) {
14744
- return Array.isArray(e) ? e.map((e) => Array.isArray(e) ? `(${Fh(e)})` : Fh(e)).join(" ") : typeof e == "object" ? e.kind === "range" ? `${e.from} to ${e.to} step ${e.step}` : `<${e.kind}>` : String(e);
14800
+ function Uh(e) {
14801
+ return Array.isArray(e) ? e.map((e) => Array.isArray(e) ? `(${Uh(e)})` : Uh(e)).join(" ") : typeof e == "object" ? e.kind === "range" ? `${e.from} to ${e.to} step ${e.step}` : `<${e.kind}>` : String(e);
14745
14802
  }
14746
- function Ih(e, t = {}) {
14747
- return new Oh(t).convert(e);
14803
+ function Wh(e, t = {}) {
14804
+ return new Nh(t).convert(e);
14748
14805
  }
14749
14806
  //#endregion
14750
- export { d as $, le as $t, ki as A, Ze as An, Ee as At, h as B, e as Bn, ae as Bt, en as C, J as Cn, pe as Ct, Di as D, Mn as Dn, _e as Dt, P as E, $t as En, ge as Et, bs as F, ro as Fn, V as Ft, s as G, L as Gt, g as H, r as Hn, ne as Ht, An as I, rt as In, H as It, Y as J, Hr as Jt, jt as K, R as Kt, T as L, W as Ln, M as Lt, w as M, Cs as Mn, ie as Mt, fi as N, oo as Nn, re as Nt, Go as O, no as On, ve as Ot, qe as P, et as Pn, B as Pt, ho as Q, it as Qt, S as R, nt as Rn, De as Rt, tn as S, q as Sn, fe as St, ee as T, Je as Tn, he as Tt, He as U, i as Un, U as Ut, _ as V, t as Vn, oe as Vt, Ue as W, z as Wt, Ur as X, I as Xt, ti as Y, F as Yt, mo as Z, l as Zt, Bt as _, k as _n, be as _t, oh as a, zn as an, ci as at, Oi as b, D as bn, we as bt, j as c, ls as cn, Mt as ct, Ai as d, yr as dn, je as dt, Me as en, f as et, vr as f, br as fn, ke as ft, Ln as g, O as gn, Ce as gt, u as h, A as hn, te as ht, lh as i, We as in, Ho as it, X as j, G as jn, se as jt, at as k, Qe as kn, ye as kt, Ko as l, c as ln, ce as lt, y as m, v as mn, N as mt, xh as n, de as nn, p as nt, ch as o, uo as on, Za as ot, Mr as p, so as pn, ue as pt, Ft as q, fo as qt, Ih as r, Ve as rn, Uo as rt, $c as s, b as sn, cs as st, gh as t, Ae as tn, m as tt, Xo as u, Xt as un, lt as ut, Ss as v, C as vn, xe as vt, ii as w, Zt as wn, me as wt, Ei as x, x as xn, Te as xt, Yo as y, E as yn, Se as yt, pn as z, o as zn, Oe as zt };
14807
+ export { d as $, le as $t, ki as A, Ze as An, Ee as At, h as B, e as Bn, ae as Bt, en as C, J as Cn, pe as Ct, Di as D, Mn as Dn, _e as Dt, P as E, $t as En, ge as Et, bs as F, ro as Fn, V as Ft, s as G, L as Gt, g as H, r as Hn, ne as Ht, An as I, rt as In, H as It, Y as J, Hr as Jt, jt as K, R as Kt, T as L, W as Ln, M as Lt, w as M, Cs as Mn, ie as Mt, fi as N, oo as Nn, re as Nt, Go as O, no as On, ve as Ot, qe as P, et as Pn, B as Pt, ho as Q, it as Qt, S as R, nt as Rn, De as Rt, tn as S, q as Sn, fe as St, ee as T, Je as Tn, he as Tt, He as U, i as Un, U as Ut, _ as V, t as Vn, oe as Vt, Ue as W, z as Wt, Ur as X, I as Xt, ti as Y, F as Yt, mo as Z, l as Zt, Bt as _, k as _n, be as _t, oh as a, zn as an, ci as at, Oi as b, D as bn, we as bt, j as c, ls as cn, Mt as ct, Ai as d, yr as dn, je as dt, Me as en, f as et, vr as f, br as fn, ke as ft, Ln as g, O as gn, Ce as gt, u as h, A as hn, te as ht, lh as i, We as in, Ho as it, X as j, G as jn, se as jt, at as k, Qe as kn, ye as kt, Ko as l, c as ln, ce as lt, y as m, v as mn, N as mt, Eh as n, de as nn, p as nt, ch as o, uo as on, Za as ot, Mr as p, so as pn, ue as pt, Ft as q, fo as qt, Wh as r, Ve as rn, Uo as rt, $c as s, b as sn, cs as st, xh as t, Ae as tn, m as tt, Xo as u, Xt as un, lt as ut, Ss as v, C as vn, xe as vt, ii as w, Zt as wn, me as wt, Ei as x, x as xn, Te as xt, Yo as y, E as yn, Se as yt, pn as z, o as zn, Oe as zt };