@tscircuit/cli 0.1.125 → 0.1.127

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.
Files changed (3) hide show
  1. package/README.md +2 -1
  2. package/dist/main.js +948 -428
  3. package/package.json +6 -3
package/dist/main.js CHANGED
@@ -305499,9 +305499,9 @@ var require_color_string = __commonJS((exports2, module2) => {
305499
305499
  return null;
305500
305500
  }
305501
305501
  for (i = 0;i < 3; i++) {
305502
- rgb2[i] = clamp7(rgb2[i], 0, 255);
305502
+ rgb2[i] = clamp5(rgb2[i], 0, 255);
305503
305503
  }
305504
- rgb2[3] = clamp7(rgb2[3], 0, 1);
305504
+ rgb2[3] = clamp5(rgb2[3], 0, 1);
305505
305505
  return rgb2;
305506
305506
  };
305507
305507
  cs.get.hsl = function(string) {
@@ -305513,9 +305513,9 @@ var require_color_string = __commonJS((exports2, module2) => {
305513
305513
  if (match) {
305514
305514
  var alpha = parseFloat(match[4]);
305515
305515
  var h = (parseFloat(match[1]) % 360 + 360) % 360;
305516
- var s = clamp7(parseFloat(match[2]), 0, 100);
305517
- var l = clamp7(parseFloat(match[3]), 0, 100);
305518
- var a = clamp7(isNaN(alpha) ? 1 : alpha, 0, 1);
305516
+ var s = clamp5(parseFloat(match[2]), 0, 100);
305517
+ var l = clamp5(parseFloat(match[3]), 0, 100);
305518
+ var a = clamp5(isNaN(alpha) ? 1 : alpha, 0, 1);
305519
305519
  return [h, s, l, a];
305520
305520
  }
305521
305521
  return null;
@@ -305529,9 +305529,9 @@ var require_color_string = __commonJS((exports2, module2) => {
305529
305529
  if (match) {
305530
305530
  var alpha = parseFloat(match[4]);
305531
305531
  var h = (parseFloat(match[1]) % 360 + 360) % 360;
305532
- var w = clamp7(parseFloat(match[2]), 0, 100);
305533
- var b = clamp7(parseFloat(match[3]), 0, 100);
305534
- var a = clamp7(isNaN(alpha) ? 1 : alpha, 0, 1);
305532
+ var w = clamp5(parseFloat(match[2]), 0, 100);
305533
+ var b = clamp5(parseFloat(match[3]), 0, 100);
305534
+ var a = clamp5(isNaN(alpha) ? 1 : alpha, 0, 1);
305535
305535
  return [h, w, b, a];
305536
305536
  }
305537
305537
  return null;
@@ -305566,7 +305566,7 @@ var require_color_string = __commonJS((exports2, module2) => {
305566
305566
  cs.to.keyword = function(rgb2) {
305567
305567
  return reverseNames[rgb2.slice(0, 3)];
305568
305568
  };
305569
- function clamp7(num, min, max) {
305569
+ function clamp5(num, min, max) {
305570
305570
  return Math.min(Math.max(min, num), max);
305571
305571
  }
305572
305572
  function hexDouble(num) {
@@ -305720,9 +305720,9 @@ var require_conversions = __commonJS((exports2, module2) => {
305720
305720
  let currentClosestKeyword;
305721
305721
  for (const keyword of Object.keys(cssKeywords)) {
305722
305722
  const value2 = cssKeywords[keyword];
305723
- const distance8 = comparativeDistance(rgb2, value2);
305724
- if (distance8 < currentClosestDistance) {
305725
- currentClosestDistance = distance8;
305723
+ const distance6 = comparativeDistance(rgb2, value2);
305724
+ if (distance6 < currentClosestDistance) {
305725
+ currentClosestDistance = distance6;
305726
305726
  currentClosestKeyword = keyword;
305727
305727
  }
305728
305728
  }
@@ -441906,7 +441906,7 @@ var getGlobalDepsInstallCommand = (packageManager, deps) => {
441906
441906
  import { execSync as execSync2 } from "node:child_process";
441907
441907
  var import_semver2 = __toESM2(require_semver2(), 1);
441908
441908
  // package.json
441909
- var version = "0.1.124";
441909
+ var version = "0.1.126";
441910
441910
  var package_default = {
441911
441911
  name: "@tscircuit/cli",
441912
441912
  version,
@@ -441917,6 +441917,7 @@ var package_default = {
441917
441917
  "@tscircuit/fake-snippets": "^0.0.75",
441918
441918
  "@tscircuit/file-server": "^0.0.24",
441919
441919
  "@tscircuit/runframe": "^0.0.566",
441920
+ "@tscircuit/math-utils": "^0.0.18",
441920
441921
  "@types/bun": "^1.2.2",
441921
441922
  "@types/configstore": "^6.0.2",
441922
441923
  "@types/debug": "^4.1.12",
@@ -441948,9 +441949,11 @@ var package_default = {
441948
441949
  redaxios: "^0.5.1",
441949
441950
  semver: "^7.6.3",
441950
441951
  tempy: "^3.1.0",
441951
- tscircuit: "^0.0.485",
441952
+ tscircuit: "^0.0.491",
441952
441953
  "@tscircuit/circuit-json-util": "^0.0.47",
441953
- "typed-ky": "^0.0.4"
441954
+ "typed-ky": "^0.0.4",
441955
+ "circuit-json-to-simple-3d": "^0.0.3",
441956
+ "@tscircuit/simple-3d-svg": "^0.0.10"
441954
441957
  },
441955
441958
  peerDependencies: {
441956
441959
  typescript: "^5.0.0"
@@ -464847,21 +464850,221 @@ init_dist2();
464847
464850
  // node_modules/@tscircuit/math-utils/dist/index.js
464848
464851
  var exports_dist3 = {};
464849
464852
  __export2(exports_dist3, {
464853
+ segmentToSegmentMinDistance: () => segmentToSegmentMinDistance,
464854
+ segmentToCircleMinDistance: () => segmentToCircleMinDistance,
464855
+ segmentToBoxMinDistance: () => segmentToBoxMinDistance,
464856
+ segmentToBoundsMinDistance: () => segmentToBoundsMinDistance,
464850
464857
  pointToSegmentDistance: () => pointToSegmentDistance2,
464858
+ pointToSegmentClosestPoint: () => pointToSegmentClosestPoint,
464859
+ pointToBoxDistance: () => pointToBoxDistance,
464860
+ pointToBoundsDistance: () => pointToBoundsDistance,
464851
464861
  orientation: () => orientation2,
464852
464862
  onSegment: () => onSegment2,
464863
+ midpoint: () => midpoint,
464853
464864
  grid: () => grid,
464854
464865
  getUnitVectorFromPointAToB: () => getUnitVectorFromPointAToB,
464855
464866
  getUnitVectorFromDirection: () => getUnitVectorFromDirection,
464867
+ getSegmentIntersection: () => getSegmentIntersection,
464856
464868
  getBoundingBox: () => getBoundingBox2,
464857
464869
  findNearestPointsBetweenBoxSets: () => findNearestPointsBetweenBoxSets2,
464858
464870
  doesLineIntersectLine: () => doesLineIntersectLine2,
464859
464871
  doSegmentsIntersect: () => doSegmentsIntersect2,
464860
464872
  distance: () => distance4,
464873
+ distSq: () => distSq,
464861
464874
  computeDistanceBetweenBoxes: () => computeDistanceBetweenBoxes2,
464862
464875
  clamp: () => clamp2
464863
464876
  });
464864
464877
 
464878
+ // node_modules/@tscircuit/math-utils/dist/chunk-3453HRP7.js
464879
+ function doesLineIntersectLine2([a1, a2], [b1, b2], {
464880
+ lineThickness = 0
464881
+ } = {}) {
464882
+ if (lineThickness === 0) {
464883
+ return doSegmentsIntersect2(a1, a2, b1, b2);
464884
+ }
464885
+ const minDist = segmentsDistance2(a1, a2, b1, b2);
464886
+ return minDist <= lineThickness;
464887
+ }
464888
+ function doSegmentsIntersect2(p1, q1, p2, q2) {
464889
+ const o1 = orientation2(p1, q1, p2);
464890
+ const o2 = orientation2(p1, q1, q2);
464891
+ const o3 = orientation2(p2, q2, p1);
464892
+ const o4 = orientation2(p2, q2, q1);
464893
+ if (o1 !== o2 && o3 !== o4) {
464894
+ return true;
464895
+ }
464896
+ if (o1 === 0 && onSegment2(p1, p2, q1))
464897
+ return true;
464898
+ if (o2 === 0 && onSegment2(p1, q2, q1))
464899
+ return true;
464900
+ if (o3 === 0 && onSegment2(p2, p1, q2))
464901
+ return true;
464902
+ if (o4 === 0 && onSegment2(p2, q1, q2))
464903
+ return true;
464904
+ return false;
464905
+ }
464906
+ function orientation2(p, q, r) {
464907
+ const val54 = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
464908
+ if (val54 === 0)
464909
+ return 0;
464910
+ return val54 > 0 ? 1 : 2;
464911
+ }
464912
+ function onSegment2(p, q, r) {
464913
+ return q.x <= Math.max(p.x, r.x) && q.x >= Math.min(p.x, r.x) && q.y <= Math.max(p.y, r.y) && q.y >= Math.min(p.y, r.y);
464914
+ }
464915
+ function segmentsDistance2(a1, a2, b1, b2) {
464916
+ if (a1.x === a2.x && a1.y === a2.y) {
464917
+ return pointToSegmentDistance2(a1, b1, b2);
464918
+ }
464919
+ if (b1.x === b2.x && b1.y === b2.y) {
464920
+ return pointToSegmentDistance2(b1, a1, a2);
464921
+ }
464922
+ if (doSegmentsIntersect2(a1, a2, b1, b2)) {
464923
+ return 0;
464924
+ }
464925
+ const distances = [
464926
+ pointToSegmentDistance2(a1, b1, b2),
464927
+ pointToSegmentDistance2(a2, b1, b2),
464928
+ pointToSegmentDistance2(b1, a1, a2),
464929
+ pointToSegmentDistance2(b2, a1, a2)
464930
+ ];
464931
+ return Math.min(...distances);
464932
+ }
464933
+ function pointToSegmentDistance2(p, v, w) {
464934
+ const l2 = (w.x - v.x) ** 2 + (w.y - v.y) ** 2;
464935
+ if (l2 === 0)
464936
+ return distance4(p, v);
464937
+ let t2 = ((p.x - v.x) * (w.x - v.x) + (p.y - v.y) * (w.y - v.y)) / l2;
464938
+ t2 = Math.max(0, Math.min(1, t2));
464939
+ const projection = {
464940
+ x: v.x + t2 * (w.x - v.x),
464941
+ y: v.y + t2 * (w.y - v.y)
464942
+ };
464943
+ return distance4(p, projection);
464944
+ }
464945
+ function distance4(p1, p2) {
464946
+ const dx = p1.x - p2.x;
464947
+ const dy = p1.y - p2.y;
464948
+ return Math.sqrt(dx * dx + dy * dy);
464949
+ }
464950
+ function getSegmentIntersection(a, b, u, v) {
464951
+ const dx1 = b.x - a.x;
464952
+ const dy1 = b.y - a.y;
464953
+ const dx2 = v.x - u.x;
464954
+ const dy2 = v.y - u.y;
464955
+ const dx3 = a.x - u.x;
464956
+ const dy3 = a.y - u.y;
464957
+ const denominator = dx1 * dy2 - dy1 * dx2;
464958
+ if (Math.abs(denominator) < 0.0000000001) {
464959
+ return null;
464960
+ }
464961
+ const t2 = (dy3 * dx2 - dx3 * dy2) / denominator;
464962
+ const s = (dx1 * dy3 - dy1 * dx3) / denominator;
464963
+ const epsilon = 0.000000001;
464964
+ if (t2 >= -epsilon && t2 <= 1 + epsilon && s >= -epsilon && s <= 1 + epsilon) {
464965
+ const intersectionX = a.x + t2 * dx1;
464966
+ const intersectionY = a.y + t2 * dy1;
464967
+ return { x: intersectionX, y: intersectionY };
464968
+ }
464969
+ return null;
464970
+ }
464971
+
464972
+ // node_modules/@tscircuit/math-utils/dist/chunk-FWQGMQBW.js
464973
+ function segmentToSegmentMinDistance(a, b, u, v) {
464974
+ if (a.x === b.x && a.y === b.y) {
464975
+ return pointToSegmentDistance2(a, u, v);
464976
+ }
464977
+ if (u.x === v.x && u.y === v.y) {
464978
+ return pointToSegmentDistance2(u, a, b);
464979
+ }
464980
+ if (doSegmentsIntersect2(a, b, u, v)) {
464981
+ return 0;
464982
+ }
464983
+ const distances = [
464984
+ pointToSegmentDistance2(a, u, v),
464985
+ pointToSegmentDistance2(b, u, v),
464986
+ pointToSegmentDistance2(u, a, b),
464987
+ pointToSegmentDistance2(v, a, b)
464988
+ ];
464989
+ return Math.min(...distances);
464990
+ }
464991
+ function segmentToBoundsMinDistance(a, b, bounds6) {
464992
+ const topLeft = { x: bounds6.minX, y: bounds6.minY };
464993
+ const topRight = { x: bounds6.maxX, y: bounds6.minY };
464994
+ const bottomLeft = { x: bounds6.minX, y: bounds6.maxY };
464995
+ const bottomRight = { x: bounds6.maxX, y: bounds6.maxY };
464996
+ if (doSegmentsIntersect2(a, b, topLeft, topRight) || doSegmentsIntersect2(a, b, topRight, bottomRight) || doSegmentsIntersect2(a, b, bottomRight, bottomLeft) || doSegmentsIntersect2(a, b, bottomLeft, topLeft)) {
464997
+ return 0;
464998
+ }
464999
+ if (a.x >= bounds6.minX && a.x <= bounds6.maxX && a.y >= bounds6.minY && a.y <= bounds6.maxY && b.x >= bounds6.minX && b.x <= bounds6.maxX && b.y >= bounds6.minY && b.y <= bounds6.maxY) {
465000
+ return 0;
465001
+ }
465002
+ const distances = [
465003
+ pointToSegmentDistance2(topLeft, a, b),
465004
+ pointToSegmentDistance2(topRight, a, b),
465005
+ pointToSegmentDistance2(bottomLeft, a, b),
465006
+ pointToSegmentDistance2(bottomRight, a, b)
465007
+ ];
465008
+ if (a.x >= bounds6.minX && a.x <= bounds6.maxX && a.y >= bounds6.minY && a.y <= bounds6.maxY) {
465009
+ return 0;
465010
+ }
465011
+ if (b.x >= bounds6.minX && b.x <= bounds6.maxX && b.y >= bounds6.minY && b.y <= bounds6.maxY) {
465012
+ return 0;
465013
+ }
465014
+ if (a.x < bounds6.minX || a.x > bounds6.maxX || a.y < bounds6.minY || a.y > bounds6.maxY) {
465015
+ const closestX = clamp2(a.x, bounds6.minX, bounds6.maxX);
465016
+ const closestY = clamp2(a.y, bounds6.minY, bounds6.maxY);
465017
+ distances.push(distance4(a, { x: closestX, y: closestY }));
465018
+ }
465019
+ if (b.x < bounds6.minX || b.x > bounds6.maxX || b.y < bounds6.minY || b.y > bounds6.maxY) {
465020
+ const closestX = clamp2(b.x, bounds6.minX, bounds6.maxX);
465021
+ const closestY = clamp2(b.y, bounds6.minY, bounds6.maxY);
465022
+ distances.push(distance4(b, { x: closestX, y: closestY }));
465023
+ }
465024
+ return Math.min(...distances);
465025
+ }
465026
+ function segmentToBoxMinDistance(a, b, box) {
465027
+ const halfWidth = box.width / 2;
465028
+ const halfHeight = box.height / 2;
465029
+ const bounds6 = {
465030
+ minX: box.center.x - halfWidth,
465031
+ maxX: box.center.x + halfWidth,
465032
+ minY: box.center.y - halfHeight,
465033
+ maxY: box.center.y + halfHeight
465034
+ };
465035
+ return segmentToBoundsMinDistance(a, b, bounds6);
465036
+ }
465037
+ function segmentToCircleMinDistance(a, b, circle) {
465038
+ const circleCenter = { x: circle.x, y: circle.y };
465039
+ if (a.x === b.x && a.y === b.y) {
465040
+ return Math.max(0, distance4(a, circleCenter) - circle.radius);
465041
+ }
465042
+ const ab = { x: b.x - a.x, y: b.y - a.y };
465043
+ const ac = { x: circleCenter.x - a.x, y: circleCenter.y - a.y };
465044
+ const abLengthSq = ab.x * ab.x + ab.y * ab.y;
465045
+ const t2 = Math.max(0, Math.min(1, (ab.x * ac.x + ab.y * ac.y) / abLengthSq));
465046
+ const closestPoint = {
465047
+ x: a.x + t2 * ab.x,
465048
+ y: a.y + t2 * ab.y
465049
+ };
465050
+ const distToCenter = distance4(closestPoint, circleCenter);
465051
+ return Math.max(0, distToCenter - circle.radius);
465052
+ }
465053
+ function pointToSegmentClosestPoint(p, a, b) {
465054
+ const dx_ab = b.x - a.x;
465055
+ const dy_ab = b.y - a.y;
465056
+ const l2 = dx_ab * dx_ab + dy_ab * dy_ab;
465057
+ if (l2 === 0)
465058
+ return { x: a.x, y: a.y };
465059
+ let t2 = ((p.x - a.x) * dx_ab + (p.y - a.y) * dy_ab) / l2;
465060
+ t2 = Math.max(0, Math.min(1, t2));
465061
+ const closestPoint = {
465062
+ x: a.x + t2 * dx_ab,
465063
+ y: a.y + t2 * dy_ab
465064
+ };
465065
+ return closestPoint;
465066
+ }
465067
+
464865
465068
  // node_modules/@tscircuit/math-utils/dist/chunk-GIGMPRPV.js
464866
465069
  var getUnitVectorFromPointAToB = (a, b) => {
464867
465070
  const delta = {
@@ -464934,77 +465137,39 @@ function grid({
464934
465137
  return cells;
464935
465138
  }
464936
465139
 
464937
- // node_modules/@tscircuit/math-utils/dist/chunk-CHQOCSFB.js
464938
- function doesLineIntersectLine2([a1, a2], [b1, b2], {
464939
- lineThickness = 0
464940
- } = {}) {
464941
- if (lineThickness === 0) {
464942
- return doSegmentsIntersect2(a1, a2, b1, b2);
464943
- }
464944
- const minDist = segmentsDistance2(a1, a2, b1, b2);
464945
- return minDist <= lineThickness;
464946
- }
464947
- function doSegmentsIntersect2(p1, q1, p2, q2) {
464948
- const o1 = orientation2(p1, q1, p2);
464949
- const o2 = orientation2(p1, q1, q2);
464950
- const o3 = orientation2(p2, q2, p1);
464951
- const o4 = orientation2(p2, q2, q1);
464952
- if (o1 !== o2 && o3 !== o4) {
464953
- return true;
464954
- }
464955
- if (o1 === 0 && onSegment2(p1, p2, q1))
464956
- return true;
464957
- if (o2 === 0 && onSegment2(p1, q2, q1))
464958
- return true;
464959
- if (o3 === 0 && onSegment2(p2, p1, q2))
464960
- return true;
464961
- if (o4 === 0 && onSegment2(p2, q1, q2))
464962
- return true;
464963
- return false;
464964
- }
464965
- function orientation2(p, q, r) {
464966
- const val54 = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
464967
- if (val54 === 0)
465140
+ // node_modules/@tscircuit/math-utils/dist/chunk-SLG2OU3P.js
465141
+ function pointToBoxDistance(p, box) {
465142
+ const halfWidth = box.width / 2;
465143
+ const halfHeight = box.height / 2;
465144
+ const minX = box.center.x - halfWidth;
465145
+ const maxX = box.center.x + halfWidth;
465146
+ const minY = box.center.y - halfHeight;
465147
+ const maxY = box.center.y + halfHeight;
465148
+ if (p.x >= minX && p.x <= maxX && p.y >= minY && p.y <= maxY) {
464968
465149
  return 0;
464969
- return val54 > 0 ? 1 : 2;
464970
- }
464971
- function onSegment2(p, q, r) {
464972
- return q.x <= Math.max(p.x, r.x) && q.x >= Math.min(p.x, r.x) && q.y <= Math.max(p.y, r.y) && q.y >= Math.min(p.y, r.y);
464973
- }
464974
- function segmentsDistance2(a1, a2, b1, b2) {
464975
- if (a1.x === a2.x && a1.y === a2.y) {
464976
- return pointToSegmentDistance2(a1, b1, b2);
464977
465150
  }
464978
- if (b1.x === b2.x && b1.y === b2.y) {
464979
- return pointToSegmentDistance2(b1, a1, a2);
464980
- }
464981
- if (doSegmentsIntersect2(a1, a2, b1, b2)) {
465151
+ const closestX = clamp2(p.x, minX, maxX);
465152
+ const closestY = clamp2(p.y, minY, maxY);
465153
+ return distance4(p, { x: closestX, y: closestY });
465154
+ }
465155
+ function pointToBoundsDistance(p, bounds6) {
465156
+ if (p.x >= bounds6.minX && p.x <= bounds6.maxX && p.y >= bounds6.minY && p.y <= bounds6.maxY) {
464982
465157
  return 0;
464983
465158
  }
464984
- const distances = [
464985
- pointToSegmentDistance2(a1, b1, b2),
464986
- pointToSegmentDistance2(a2, b1, b2),
464987
- pointToSegmentDistance2(b1, a1, a2),
464988
- pointToSegmentDistance2(b2, a1, a2)
464989
- ];
464990
- return Math.min(...distances);
465159
+ const closestX = clamp2(p.x, bounds6.minX, bounds6.maxX);
465160
+ const closestY = clamp2(p.y, bounds6.minY, bounds6.maxY);
465161
+ return distance4(p, { x: closestX, y: closestY });
464991
465162
  }
464992
- function pointToSegmentDistance2(p, v, w) {
464993
- const l2 = (w.x - v.x) ** 2 + (w.y - v.y) ** 2;
464994
- if (l2 === 0)
464995
- return distance4(p, v);
464996
- let t2 = ((p.x - v.x) * (w.x - v.x) + (p.y - v.y) * (w.y - v.y)) / l2;
464997
- t2 = Math.max(0, Math.min(1, t2));
464998
- const projection = {
464999
- x: v.x + t2 * (w.x - v.x),
465000
- y: v.y + t2 * (w.y - v.y)
465163
+ function midpoint(p1, p2) {
465164
+ return {
465165
+ x: (p1.x + p2.x) / 2,
465166
+ y: (p1.y + p2.y) / 2
465001
465167
  };
465002
- return distance4(p, projection);
465003
465168
  }
465004
- function distance4(p1, p2) {
465169
+ function distSq(p1, p2) {
465005
465170
  const dx = p1.x - p2.x;
465006
465171
  const dy = p1.y - p2.y;
465007
- return Math.sqrt(dx * dx + dy * dy);
465172
+ return dx * dx + dy * dy;
465008
465173
  }
465009
465174
 
465010
465175
  // node_modules/@tscircuit/core/dist/index.js
@@ -468117,7 +468282,7 @@ function distance5(p1, p2) {
468117
468282
  const dy = p1.y - p2.y;
468118
468283
  return Math.sqrt(dx * dx + dy * dy);
468119
468284
  }
468120
- function getSegmentIntersection(a, b, u, v) {
468285
+ function getSegmentIntersection2(a, b, u, v) {
468121
468286
  const dx1 = b.x - a.x;
468122
468287
  const dy1 = b.y - a.y;
468123
468288
  const dx2 = v.x - u.x;
@@ -468168,7 +468333,7 @@ function computeDistanceBetweenBoxes3(boxA, boxB) {
468168
468333
  function clamp3(value2, min, max) {
468169
468334
  return Math.max(min, Math.min(max, value2));
468170
468335
  }
468171
- function segmentToSegmentMinDistance(a, b, u, v) {
468336
+ function segmentToSegmentMinDistance2(a, b, u, v) {
468172
468337
  if (a.x === b.x && a.y === b.y) {
468173
468338
  return pointToSegmentDistance3(a, u, v);
468174
468339
  }
@@ -468186,7 +468351,7 @@ function segmentToSegmentMinDistance(a, b, u, v) {
468186
468351
  ];
468187
468352
  return Math.min(...distances);
468188
468353
  }
468189
- function segmentToBoundsMinDistance(a, b, bounds6) {
468354
+ function segmentToBoundsMinDistance2(a, b, bounds6) {
468190
468355
  const topLeft = { x: bounds6.minX, y: bounds6.minY };
468191
468356
  const topRight = { x: bounds6.maxX, y: bounds6.minY };
468192
468357
  const bottomLeft = { x: bounds6.minX, y: bounds6.maxY };
@@ -468221,7 +468386,7 @@ function segmentToBoundsMinDistance(a, b, bounds6) {
468221
468386
  }
468222
468387
  return Math.min(...distances);
468223
468388
  }
468224
- function segmentToBoxMinDistance(a, b, box) {
468389
+ function segmentToBoxMinDistance2(a, b, box) {
468225
468390
  const halfWidth = box.width / 2;
468226
468391
  const halfHeight = box.height / 2;
468227
468392
  const bounds6 = {
@@ -468230,9 +468395,9 @@ function segmentToBoxMinDistance(a, b, box) {
468230
468395
  minY: box.center.y - halfHeight,
468231
468396
  maxY: box.center.y + halfHeight
468232
468397
  };
468233
- return segmentToBoundsMinDistance(a, b, bounds6);
468398
+ return segmentToBoundsMinDistance2(a, b, bounds6);
468234
468399
  }
468235
- function pointToSegmentClosestPoint(p, a, b) {
468400
+ function pointToSegmentClosestPoint2(p, a, b) {
468236
468401
  const dx_ab = b.x - a.x;
468237
468402
  const dy_ab = b.y - a.y;
468238
468403
  const l2 = dx_ab * dx_ab + dy_ab * dy_ab;
@@ -468246,7 +468411,7 @@ function pointToSegmentClosestPoint(p, a, b) {
468246
468411
  };
468247
468412
  return closestPoint;
468248
468413
  }
468249
- function midpoint(p1, p2) {
468414
+ function midpoint2(p1, p2) {
468250
468415
  return {
468251
468416
  x: (p1.x + p2.x) / 2,
468252
468417
  y: (p1.y + p2.y) / 2
@@ -469298,7 +469463,7 @@ function computeDumbbellPaths({
469298
469463
  margin,
469299
469464
  subdivisions = 0
469300
469465
  }) {
469301
- const midpoint2 = (p1, p2) => ({
469466
+ const midpoint22 = (p1, p2) => ({
469302
469467
  x: (p1.x + p2.x) / 2,
469303
469468
  y: (p1.y + p2.y) / 2
469304
469469
  });
@@ -469505,8 +469670,8 @@ function computeDumbbellPaths({
469505
469670
  innerPoints.B_Left,
469506
469671
  innerPoints.B_Opp,
469507
469672
  innerPoints.B_Right,
469508
- midpoint2(innerPoints.midpoint, midpoint2(innerPoints.B_Right, innerPoints.A_Right)),
469509
- midpoint2(innerPoints.midpoint, midpoint2(innerPoints.A_Left, innerPoints.B_Left)),
469673
+ midpoint22(innerPoints.midpoint, midpoint22(innerPoints.B_Right, innerPoints.A_Right)),
469674
+ midpoint22(innerPoints.midpoint, midpoint22(innerPoints.A_Left, innerPoints.B_Left)),
469510
469675
  innerPoints.A_Left,
469511
469676
  innerPoints.A_Opp,
469512
469677
  innerPoints.A_Right,
@@ -469517,8 +469682,8 @@ function computeDumbbellPaths({
469517
469682
  innerPoints.B_Right,
469518
469683
  innerPoints.B_Opp,
469519
469684
  innerPoints.B_Left,
469520
- midpoint2(innerPoints.midpoint, midpoint2(innerPoints.A_Left, innerPoints.B_Left)),
469521
- midpoint2(innerPoints.midpoint, midpoint2(innerPoints.A_Right, innerPoints.B_Right)),
469685
+ midpoint22(innerPoints.midpoint, midpoint22(innerPoints.A_Left, innerPoints.B_Left)),
469686
+ midpoint22(innerPoints.midpoint, midpoint22(innerPoints.A_Right, innerPoints.B_Right)),
469522
469687
  innerPoints.A_Right,
469523
469688
  innerPoints.A_Opp,
469524
469689
  innerPoints.A_Left,
@@ -469529,8 +469694,8 @@ function computeDumbbellPaths({
469529
469694
  innerPoints.B_Left,
469530
469695
  innerPoints.B_Opp,
469531
469696
  innerPoints.B_Right,
469532
- midpoint2(innerPoints.midpoint, midpoint2(innerPoints.A_Right, innerPoints.B_Right)),
469533
- midpoint2(innerPoints.midpoint, midpoint2(innerPoints.A_Left, innerPoints.B_Left)),
469697
+ midpoint22(innerPoints.midpoint, midpoint22(innerPoints.A_Right, innerPoints.B_Right)),
469698
+ midpoint22(innerPoints.midpoint, midpoint22(innerPoints.A_Left, innerPoints.B_Left)),
469534
469699
  innerPoints.A_Left,
469535
469700
  innerPoints.A_Opp,
469536
469701
  innerPoints.A_Right,
@@ -469541,8 +469706,8 @@ function computeDumbbellPaths({
469541
469706
  innerPoints.B_Right,
469542
469707
  innerPoints.B_Opp,
469543
469708
  innerPoints.B_Left,
469544
- midpoint2(innerPoints.midpoint, midpoint2(innerPoints.A_Left, innerPoints.B_Left)),
469545
- midpoint2(innerPoints.midpoint, midpoint2(innerPoints.A_Right, innerPoints.B_Right)),
469709
+ midpoint22(innerPoints.midpoint, midpoint22(innerPoints.A_Left, innerPoints.B_Left)),
469710
+ midpoint22(innerPoints.midpoint, midpoint22(innerPoints.A_Right, innerPoints.B_Right)),
469546
469711
  innerPoints.A_Right,
469547
469712
  innerPoints.A_Opp,
469548
469713
  innerPoints.A_Left,
@@ -469550,8 +469715,8 @@ function computeDumbbellPaths({
469550
469715
  ]
469551
469716
  ];
469552
469717
  const getJLines = () => {
469553
- const mid_AR_BR = midpoint2(innerPoints.A_Right, innerPoints.B_Right);
469554
- const mid_AL_BL = midpoint2(innerPoints.B_Left, innerPoints.A_Left);
469718
+ const mid_AR_BR = midpoint22(innerPoints.A_Right, innerPoints.B_Right);
469719
+ const mid_AL_BL = midpoint22(innerPoints.B_Left, innerPoints.A_Left);
469555
469720
  return [
469556
469721
  { startsAt: "E", goesTo: "B", points: [E, B] },
469557
469722
  { startsAt: "E", goesTo: "A", points: [E, A] },
@@ -471246,7 +471411,7 @@ var ViaPossibilitiesSolver2 = class extends BaseSolver {
471246
471411
  if (segment[0].z !== this.currentHead.z) {
471247
471412
  continue;
471248
471413
  }
471249
- const intersection = getSegmentIntersection(proposedSegment[0], proposedSegment[1], segment[0], segment[1]);
471414
+ const intersection = getSegmentIntersection2(proposedSegment[0], proposedSegment[1], segment[0], segment[1]);
471250
471415
  if (intersection) {
471251
471416
  const distToIntersection = distance5(this.currentHead, intersection);
471252
471417
  if (distToIntersection < 0.000001)
@@ -471269,7 +471434,7 @@ var ViaPossibilitiesSolver2 = class extends BaseSolver {
471269
471434
  let viaXY;
471270
471435
  const distToIntersection = closestIntersection.dist;
471271
471436
  if (distToIntersection < this.VIA_INTERSECTION_BUFFER_DISTANCE) {
471272
- viaXY = midpoint(this.currentHead, closestIntersection.point);
471437
+ viaXY = midpoint2(this.currentHead, closestIntersection.point);
471273
471438
  } else {
471274
471439
  const intersectionPoint = closestIntersection.point;
471275
471440
  const vectorX = intersectionPoint.x - this.currentHead.x;
@@ -471294,7 +471459,7 @@ var ViaPossibilitiesSolver2 = class extends BaseSolver {
471294
471459
  let viaXY;
471295
471460
  const distToTarget = distance5(this.currentHead, targetEnd);
471296
471461
  if (distToTarget < this.VIA_INTERSECTION_BUFFER_DISTANCE) {
471297
- viaXY = midpoint(this.currentHead, targetEnd);
471462
+ viaXY = midpoint2(this.currentHead, targetEnd);
471298
471463
  } else {
471299
471464
  const vectorX = targetEnd.x - this.currentHead.x;
471300
471465
  const vectorY = targetEnd.y - this.currentHead.y;
@@ -472304,7 +472469,7 @@ var MultiHeadPolyLineIntraNodeSolver = class extends BaseSolver {
472304
472469
  const path2Segments = path2SegmentsByLayer.get(zLayer) ?? [];
472305
472470
  for (const segment1 of path1Segments) {
472306
472471
  for (const segment2 of path2Segments) {
472307
- minGap = Math.min(minGap, segmentToSegmentMinDistance(segment1[0], segment1[1], segment2[0], segment2[1]) - this.traceWidth);
472472
+ minGap = Math.min(minGap, segmentToSegmentMinDistance2(segment1[0], segment1[1], segment2[0], segment2[1]) - this.traceWidth);
472308
472473
  }
472309
472474
  }
472310
472475
  for (const via of path1Vias) {
@@ -472513,7 +472678,7 @@ var MultiHeadPolyLineIntraNodeSolver = class extends BaseSolver {
472513
472678
  for (const seg1 of segments1) {
472514
472679
  for (const seg2 of segments2) {
472515
472680
  if (seg1.layer === seg2.layer) {
472516
- const minDist = segmentToSegmentMinDistance(seg1.p1, seg1.p2, seg2.p1, seg2.p2);
472681
+ const minDist = segmentToSegmentMinDistance2(seg1.p1, seg1.p2, seg2.p1, seg2.p2);
472517
472682
  if (minDist < EPSILON4)
472518
472683
  continue;
472519
472684
  const center1 = {
@@ -472535,7 +472700,7 @@ var MultiHeadPolyLineIntraNodeSolver = class extends BaseSolver {
472535
472700
  const sourceIdSeg2 = `seg:${j}:${seg2.p1Idx}:${seg2.p2Idx}`;
472536
472701
  const sourceIdSeg1 = `seg:${i}:${seg1.p1Idx}:${seg1.p2Idx}`;
472537
472702
  const endpointForce = (ep, epIdx, otherSeg, targetLine, oppLine, srcIdOpp, srcIdThis) => {
472538
- const cp = pointToSegmentClosestPoint(ep, otherSeg.p1, otherSeg.p2);
472703
+ const cp = pointToSegmentClosestPoint2(ep, otherSeg.p1, otherSeg.p2);
472539
472704
  const dx2 = ep.x - cp.x;
472540
472705
  const dy2 = ep.y - cp.y;
472541
472706
  const dSq2 = dx2 * dx2 + dy2 * dy2;
@@ -472560,7 +472725,7 @@ var MultiHeadPolyLineIntraNodeSolver = class extends BaseSolver {
472560
472725
  for (const via1 of vias1) {
472561
472726
  for (const seg2 of segments2) {
472562
472727
  if (via1.layers.includes(seg2.layer)) {
472563
- const closestPointOnSeg = pointToSegmentClosestPoint(via1.point, seg2.p1, seg2.p2);
472728
+ const closestPointOnSeg = pointToSegmentClosestPoint2(via1.point, seg2.p1, seg2.p2);
472564
472729
  const dx = via1.point.x - closestPointOnSeg.x;
472565
472730
  const dy = via1.point.y - closestPointOnSeg.y;
472566
472731
  const dSq = dx * dx + dy * dy;
@@ -472589,7 +472754,7 @@ var MultiHeadPolyLineIntraNodeSolver = class extends BaseSolver {
472589
472754
  for (const via2 of vias2) {
472590
472755
  for (const seg1 of segments1) {
472591
472756
  if (via2.layers.includes(seg1.layer)) {
472592
- const closestPointOnSeg = pointToSegmentClosestPoint(via2.point, seg1.p1, seg1.p2);
472757
+ const closestPointOnSeg = pointToSegmentClosestPoint2(via2.point, seg1.p1, seg1.p2);
472593
472758
  const dx = via2.point.x - closestPointOnSeg.x;
472594
472759
  const dy = via2.point.y - closestPointOnSeg.y;
472595
472760
  const dSq = dx * dx + dy * dy;
@@ -473054,7 +473219,7 @@ var MultiHeadPolyLineIntraNodeSolver2 = class extends MultiHeadPolyLineIntraNode
473054
473219
  }
473055
473220
  };
473056
473221
  const endpointForce = (ep, epIdx, otherSeg, targetLine, oppLine) => {
473057
- const cp = pointToSegmentClosestPoint(ep, otherSeg.p1, otherSeg.p2);
473222
+ const cp = pointToSegmentClosestPoint2(ep, otherSeg.p1, otherSeg.p2);
473058
473223
  const dx = ep.x - cp.x;
473059
473224
  const dy = ep.y - cp.y;
473060
473225
  const dSq = dx * dx + dy * dy;
@@ -473107,7 +473272,7 @@ var MultiHeadPolyLineIntraNodeSolver2 = class extends MultiHeadPolyLineIntraNode
473107
473272
  for (const seg1 of segments1) {
473108
473273
  for (const seg2 of segments2) {
473109
473274
  if (seg1.layer === seg2.layer) {
473110
- const minDist = segmentToSegmentMinDistance(seg1.p1, seg1.p2, seg2.p1, seg2.p2);
473275
+ const minDist = segmentToSegmentMinDistance2(seg1.p1, seg1.p2, seg2.p1, seg2.p2);
473111
473276
  endpointForce(seg1.p1, seg1.p1Idx, seg2, i, j);
473112
473277
  endpointForce(seg1.p2, seg1.p2Idx, seg2, i, j);
473113
473278
  endpointForce(seg2.p1, seg2.p1Idx, seg1, j, i);
@@ -473118,7 +473283,7 @@ var MultiHeadPolyLineIntraNodeSolver2 = class extends MultiHeadPolyLineIntraNode
473118
473283
  for (const via1 of vias1) {
473119
473284
  for (const seg2 of segments2) {
473120
473285
  if (via1.layers.includes(seg2.layer)) {
473121
- const closestPointOnSeg = pointToSegmentClosestPoint(via1.point, seg2.p1, seg2.p2);
473286
+ const closestPointOnSeg = pointToSegmentClosestPoint2(via1.point, seg2.p1, seg2.p2);
473122
473287
  const dx = via1.point.x - closestPointOnSeg.x;
473123
473288
  const dy = via1.point.y - closestPointOnSeg.y;
473124
473289
  const dSq = dx * dx + dy * dy;
@@ -473145,7 +473310,7 @@ var MultiHeadPolyLineIntraNodeSolver2 = class extends MultiHeadPolyLineIntraNode
473145
473310
  for (const via2 of vias2) {
473146
473311
  for (const seg1 of segments1) {
473147
473312
  if (via2.layers.includes(seg1.layer)) {
473148
- const closestPointOnSeg = pointToSegmentClosestPoint(via2.point, seg1.p1, seg1.p2);
473313
+ const closestPointOnSeg = pointToSegmentClosestPoint2(via2.point, seg1.p1, seg1.p2);
473149
473314
  const dx = via2.point.x - closestPointOnSeg.x;
473150
473315
  const dy = via2.point.y - closestPointOnSeg.y;
473151
473316
  const dSq = dx * dx + dy * dy;
@@ -479036,7 +479201,7 @@ var SingleSimplifiedPathSolver5 = class extends SingleSimplifiedPathSolver {
479036
479201
  if (!obstacle.zLayers?.includes(start.z)) {
479037
479202
  continue;
479038
479203
  }
479039
- const distToObstacle = segmentToBoxMinDistance(start, end, obstacle);
479204
+ const distToObstacle = segmentToBoxMinDistance2(start, end, obstacle);
479040
479205
  if (distToObstacle < this.OBSTACLE_MARGIN + this.TRACE_THICKNESS / 2) {
479041
479206
  return false;
479042
479207
  }
@@ -479954,7 +480119,7 @@ var SingleRouteUselessViaRemovalSolver = class extends BaseSolver {
479954
480119
  };
479955
480120
  const obstacles = this.obstacleSHI.searchArea(segmentBox.centerX, segmentBox.centerY, segmentBox.width + (this.TRACE_THICKNESS + this.OBSTACLE_MARGIN) * 2, segmentBox.height + (this.TRACE_THICKNESS + this.OBSTACLE_MARGIN) * 2);
479956
480121
  for (const obstacle of obstacles) {
479957
- const distToObstacle = segmentToBoxMinDistance(A, B, obstacle);
480122
+ const distToObstacle = segmentToBoxMinDistance2(A, B, obstacle);
479958
480123
  if (distToObstacle < this.TRACE_THICKNESS + this.OBSTACLE_MARGIN) {
479959
480124
  return false;
479960
480125
  }
@@ -480502,303 +480667,13 @@ init_dist2();
480502
480667
  // node_modules/@tscircuit/checks/dist/index.js
480503
480668
  init_dist4();
480504
480669
  init_dist4();
480505
-
480506
- // node_modules/@tscircuit/checks/node_modules/circuit-json-to-connectivity-map/dist/index.js
480507
- function findConnectedNetworks2(connections) {
480508
- const networks = /* @__PURE__ */ new Map;
480509
- let netCounter = 0;
480510
- function getOrCreateNetwork(nodeId) {
480511
- for (const [, network] of networks) {
480512
- if (network.has(nodeId)) {
480513
- return network;
480514
- }
480515
- }
480516
- const newNetwork = /* @__PURE__ */ new Set;
480517
- networks.set(`connectivity_net${netCounter++}`, newNetwork);
480518
- return newNetwork;
480519
- }
480520
- for (const connection of connections) {
480521
- let network = null;
480522
- for (const nodeId of connection) {
480523
- if (!network) {
480524
- network = getOrCreateNetwork(nodeId);
480525
- } else if (!network.has(nodeId)) {
480526
- const existingNetwork = getOrCreateNetwork(nodeId);
480527
- if (existingNetwork !== network) {
480528
- for (const node of existingNetwork) {
480529
- network.add(node);
480530
- }
480531
- networks.delete(Array.from(networks.entries()).find(([, net2]) => net2 === existingNetwork)[0]);
480532
- }
480533
- }
480534
- network.add(nodeId);
480535
- }
480536
- }
480537
- return Object.fromEntries(Array.from(networks.entries()).map(([netId, connectedNodes]) => [
480538
- netId,
480539
- Array.from(connectedNodes)
480540
- ]));
480541
- }
480542
- var ConnectivityMap3 = class {
480543
- netMap;
480544
- idToNetMap;
480545
- constructor(netMap) {
480546
- this.netMap = netMap;
480547
- this.idToNetMap = {};
480548
- for (const [netId, ids] of Object.entries(netMap)) {
480549
- for (const id of ids) {
480550
- this.idToNetMap[id] = netId;
480551
- }
480552
- }
480553
- }
480554
- addConnections(connections) {
480555
- for (const connection of connections) {
480556
- const existingNets = /* @__PURE__ */ new Set;
480557
- for (const id of connection) {
480558
- const existingNetId = this.idToNetMap[id];
480559
- if (existingNetId) {
480560
- existingNets.add(existingNetId);
480561
- }
480562
- }
480563
- let targetNetId;
480564
- if (existingNets.size === 0) {
480565
- targetNetId = `connectivity_net${Object.keys(this.netMap).length}`;
480566
- this.netMap[targetNetId] = [];
480567
- } else if (existingNets.size === 1) {
480568
- targetNetId = existingNets.values().next().value ?? `connectivity_net${Object.keys(this.netMap).length}`;
480569
- } else {
480570
- targetNetId = existingNets.values().next().value ?? `connectivity_net${Object.keys(this.netMap).length}`;
480571
- for (const netId of existingNets) {
480572
- if (netId !== targetNetId) {
480573
- this.netMap[targetNetId].push(...this.netMap[netId]);
480574
- this.netMap[netId] = this.netMap[targetNetId];
480575
- for (const id of this.netMap[targetNetId]) {
480576
- this.idToNetMap[id] = targetNetId;
480577
- }
480578
- }
480579
- }
480580
- }
480581
- for (const id of connection) {
480582
- if (!this.netMap[targetNetId].includes(id)) {
480583
- this.netMap[targetNetId].push(id);
480584
- }
480585
- this.idToNetMap[id] = targetNetId;
480586
- }
480587
- }
480588
- }
480589
- getIdsConnectedToNet(netId) {
480590
- return this.netMap[netId] || [];
480591
- }
480592
- getNetConnectedToId(id) {
480593
- return this.idToNetMap[id];
480594
- }
480595
- areIdsConnected(id1, id2) {
480596
- if (id1 === id2)
480597
- return true;
480598
- const netId1 = this.getNetConnectedToId(id1);
480599
- if (!netId1)
480600
- return false;
480601
- const netId2 = this.getNetConnectedToId(id2);
480602
- if (!netId2)
480603
- return false;
480604
- return netId1 === netId2 || netId2 === id1 || netId2 === id1;
480605
- }
480606
- areAllIdsConnected(ids) {
480607
- const netId = this.getNetConnectedToId(ids[0]);
480608
- for (const id of ids) {
480609
- const nextNetId = this.getNetConnectedToId(id);
480610
- if (nextNetId === undefined) {
480611
- return false;
480612
- }
480613
- if (nextNetId !== netId) {
480614
- return false;
480615
- }
480616
- }
480617
- return true;
480618
- }
480619
- };
480620
- var getFullConnectivityMapFromCircuitJson2 = (circuitJson) => {
480621
- const connections = [];
480622
- for (const element of circuitJson) {
480623
- if (element.type === "source_trace") {
480624
- connections.push([
480625
- element.source_trace_id,
480626
- ...element.connected_source_port_ids ?? [],
480627
- ...element.connected_source_net_ids ?? []
480628
- ].filter(Boolean));
480629
- } else if (element.type === "pcb_port") {
480630
- const { pcb_port_id, source_port_id } = element;
480631
- if (source_port_id && pcb_port_id) {
480632
- connections.push([source_port_id, pcb_port_id]);
480633
- }
480634
- } else if (element.type === "pcb_smtpad") {
480635
- const { pcb_smtpad_id, pcb_port_id } = element;
480636
- if (pcb_port_id && pcb_smtpad_id) {
480637
- connections.push([pcb_smtpad_id, pcb_port_id]);
480638
- }
480639
- } else if (element.type === "pcb_plated_hole") {
480640
- const { pcb_plated_hole_id, pcb_port_id } = element;
480641
- if (pcb_port_id && pcb_plated_hole_id) {
480642
- connections.push([pcb_plated_hole_id, pcb_port_id]);
480643
- }
480644
- } else if (element.type === "pcb_trace") {
480645
- const { pcb_trace_id, source_trace_id } = element;
480646
- const route = Array.isArray(element.route) ? element.route.filter((rp) => rp && rp.route_type === "wire") : [];
480647
- if (source_trace_id && pcb_trace_id) {
480648
- connections.push([pcb_trace_id, source_trace_id]);
480649
- }
480650
- if (Array.isArray(route)) {
480651
- const startId = route.find((rp) => rp && rp.start_pcb_port_id)?.start_pcb_port_id;
480652
- const endId = route.find((rp) => rp && rp.end_pcb_port_id)?.end_pcb_port_id;
480653
- if (startId && pcb_trace_id && endId) {
480654
- connections.push([startId, pcb_trace_id, endId]);
480655
- }
480656
- }
480657
- } else if (element.type === "pcb_via") {
480658
- const { pcb_via_id, pcb_trace_id } = element;
480659
- if (pcb_trace_id && pcb_via_id) {
480660
- connections.push([pcb_via_id, pcb_trace_id]);
480661
- }
480662
- } else if (element.type === "source_component") {
480663
- if (element.internally_connected_source_port_ids) {
480664
- for (const portGroup of element.internally_connected_source_port_ids) {
480665
- connections.push(portGroup);
480666
- }
480667
- }
480668
- }
480669
- }
480670
- const netMap = findConnectedNetworks2(connections);
480671
- return new ConnectivityMap3(netMap);
480672
- };
480673
-
480674
- // node_modules/@tscircuit/checks/dist/index.js
480670
+ init_dist2();
480675
480671
  init_dist4();
480676
-
480677
- // node_modules/@tscircuit/checks/node_modules/@tscircuit/math-utils/dist/chunk-3453HRP7.js
480678
- function doSegmentsIntersect5(p1, q1, p2, q2) {
480679
- const o1 = orientation5(p1, q1, p2);
480680
- const o2 = orientation5(p1, q1, q2);
480681
- const o3 = orientation5(p2, q2, p1);
480682
- const o4 = orientation5(p2, q2, q1);
480683
- if (o1 !== o2 && o3 !== o4) {
480684
- return true;
480685
- }
480686
- if (o1 === 0 && onSegment5(p1, p2, q1))
480687
- return true;
480688
- if (o2 === 0 && onSegment5(p1, q2, q1))
480689
- return true;
480690
- if (o3 === 0 && onSegment5(p2, p1, q2))
480691
- return true;
480692
- if (o4 === 0 && onSegment5(p2, q1, q2))
480693
- return true;
480694
- return false;
480695
- }
480696
- function orientation5(p, q, r) {
480697
- const val54 = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
480698
- if (val54 === 0)
480699
- return 0;
480700
- return val54 > 0 ? 1 : 2;
480701
- }
480702
- function onSegment5(p, q, r) {
480703
- return q.x <= Math.max(p.x, r.x) && q.x >= Math.min(p.x, r.x) && q.y <= Math.max(p.y, r.y) && q.y >= Math.min(p.y, r.y);
480704
- }
480705
- function pointToSegmentDistance5(p, v, w) {
480706
- const l2 = (w.x - v.x) ** 2 + (w.y - v.y) ** 2;
480707
- if (l2 === 0)
480708
- return distance7(p, v);
480709
- let t2 = ((p.x - v.x) * (w.x - v.x) + (p.y - v.y) * (w.y - v.y)) / l2;
480710
- t2 = Math.max(0, Math.min(1, t2));
480711
- const projection = {
480712
- x: v.x + t2 * (w.x - v.x),
480713
- y: v.y + t2 * (w.y - v.y)
480714
- };
480715
- return distance7(p, projection);
480716
- }
480717
- function distance7(p1, p2) {
480718
- const dx = p1.x - p2.x;
480719
- const dy = p1.y - p2.y;
480720
- return Math.sqrt(dx * dx + dy * dy);
480721
- }
480722
-
480723
- // node_modules/@tscircuit/checks/node_modules/@tscircuit/math-utils/dist/chunk-MHHTZHOJ.js
480724
- function clamp5(value2, min, max) {
480725
- return Math.max(min, Math.min(max, value2));
480726
- }
480727
-
480728
- // node_modules/@tscircuit/checks/node_modules/@tscircuit/math-utils/dist/chunk-FWQGMQBW.js
480729
- function segmentToSegmentMinDistance2(a, b, u, v) {
480730
- if (a.x === b.x && a.y === b.y) {
480731
- return pointToSegmentDistance5(a, u, v);
480732
- }
480733
- if (u.x === v.x && u.y === v.y) {
480734
- return pointToSegmentDistance5(u, a, b);
480735
- }
480736
- if (doSegmentsIntersect5(a, b, u, v)) {
480737
- return 0;
480738
- }
480739
- const distances = [
480740
- pointToSegmentDistance5(a, u, v),
480741
- pointToSegmentDistance5(b, u, v),
480742
- pointToSegmentDistance5(u, a, b),
480743
- pointToSegmentDistance5(v, a, b)
480744
- ];
480745
- return Math.min(...distances);
480746
- }
480747
- function segmentToBoundsMinDistance2(a, b, bounds6) {
480748
- const topLeft = { x: bounds6.minX, y: bounds6.minY };
480749
- const topRight = { x: bounds6.maxX, y: bounds6.minY };
480750
- const bottomLeft = { x: bounds6.minX, y: bounds6.maxY };
480751
- const bottomRight = { x: bounds6.maxX, y: bounds6.maxY };
480752
- if (doSegmentsIntersect5(a, b, topLeft, topRight) || doSegmentsIntersect5(a, b, topRight, bottomRight) || doSegmentsIntersect5(a, b, bottomRight, bottomLeft) || doSegmentsIntersect5(a, b, bottomLeft, topLeft)) {
480753
- return 0;
480754
- }
480755
- if (a.x >= bounds6.minX && a.x <= bounds6.maxX && a.y >= bounds6.minY && a.y <= bounds6.maxY && b.x >= bounds6.minX && b.x <= bounds6.maxX && b.y >= bounds6.minY && b.y <= bounds6.maxY) {
480756
- return 0;
480757
- }
480758
- const distances = [
480759
- pointToSegmentDistance5(topLeft, a, b),
480760
- pointToSegmentDistance5(topRight, a, b),
480761
- pointToSegmentDistance5(bottomLeft, a, b),
480762
- pointToSegmentDistance5(bottomRight, a, b)
480763
- ];
480764
- if (a.x >= bounds6.minX && a.x <= bounds6.maxX && a.y >= bounds6.minY && a.y <= bounds6.maxY) {
480765
- return 0;
480766
- }
480767
- if (b.x >= bounds6.minX && b.x <= bounds6.maxX && b.y >= bounds6.minY && b.y <= bounds6.maxY) {
480768
- return 0;
480769
- }
480770
- if (a.x < bounds6.minX || a.x > bounds6.maxX || a.y < bounds6.minY || a.y > bounds6.maxY) {
480771
- const closestX = clamp5(a.x, bounds6.minX, bounds6.maxX);
480772
- const closestY = clamp5(a.y, bounds6.minY, bounds6.maxY);
480773
- distances.push(distance7(a, { x: closestX, y: closestY }));
480774
- }
480775
- if (b.x < bounds6.minX || b.x > bounds6.maxX || b.y < bounds6.minY || b.y > bounds6.maxY) {
480776
- const closestX = clamp5(b.x, bounds6.minX, bounds6.maxX);
480777
- const closestY = clamp5(b.y, bounds6.minY, bounds6.maxY);
480778
- distances.push(distance7(b, { x: closestX, y: closestY }));
480779
- }
480780
- return Math.min(...distances);
480781
- }
480782
- function segmentToCircleMinDistance(a, b, circle) {
480783
- const circleCenter = { x: circle.x, y: circle.y };
480784
- if (a.x === b.x && a.y === b.y) {
480785
- return Math.max(0, distance7(a, circleCenter) - circle.radius);
480786
- }
480787
- const ab = { x: b.x - a.x, y: b.y - a.y };
480788
- const ac = { x: circleCenter.x - a.x, y: circleCenter.y - a.y };
480789
- const abLengthSq = ab.x * ab.x + ab.y * ab.y;
480790
- const t2 = Math.max(0, Math.min(1, (ab.x * ac.x + ab.y * ac.y) / abLengthSq));
480791
- const closestPoint = {
480792
- x: a.x + t2 * ab.x,
480793
- y: a.y + t2 * ab.y
480794
- };
480795
- const distToCenter = distance7(closestPoint, circleCenter);
480796
- return Math.max(0, distToCenter - circle.radius);
480797
- }
480798
-
480799
- // node_modules/@tscircuit/checks/dist/index.js
480800
480672
  init_dist4();
480801
480673
  init_dist3();
480674
+ init_dist4();
480675
+ init_dist4();
480676
+ init_dist2();
480802
480677
  var SpatialObjectIndex = class {
480803
480678
  buckets;
480804
480679
  objectsById;
@@ -480950,7 +480825,7 @@ var getClosestPointBetweenSegments = (segmentA, segmentB) => {
480950
480825
  };
480951
480826
  }
480952
480827
  if (lenSqrA === 0) {
480953
- const t22 = clamp6(((a1.x - b1.x) * vb.x + (a1.y - b1.y) * vb.y) / lenSqrB, 0, 1);
480828
+ const t22 = clamp4(((a1.x - b1.x) * vb.x + (a1.y - b1.y) * vb.y) / lenSqrB, 0, 1);
480954
480829
  const closestOnB2 = {
480955
480830
  x: b1.x + t22 * vb.x,
480956
480831
  y: b1.y + t22 * vb.y
@@ -480960,7 +480835,7 @@ var getClosestPointBetweenSegments = (segmentA, segmentB) => {
480960
480835
  y: (a1.y + closestOnB2.y) / 2
480961
480836
  };
480962
480837
  }
480963
- const t2 = clamp6(((b1.x - a1.x) * va.x + (b1.y - a1.y) * va.y) / lenSqrA, 0, 1);
480838
+ const t2 = clamp4(((b1.x - a1.x) * va.x + (b1.y - a1.y) * va.y) / lenSqrA, 0, 1);
480964
480839
  const closestOnA2 = {
480965
480840
  x: a1.x + t2 * va.x,
480966
480841
  y: a1.y + t2 * va.y
@@ -480982,12 +480857,12 @@ var getClosestPointBetweenSegments = (segmentA, segmentB) => {
480982
480857
  }
480983
480858
  let tA = (dotAB * dotBW - dotBB * dotAW) / denominator;
480984
480859
  let tB = (dotAA * dotBW - dotAB * dotAW) / denominator;
480985
- tA = clamp6(tA, 0, 1);
480986
- tB = clamp6(tB, 0, 1);
480860
+ tA = clamp4(tA, 0, 1);
480861
+ tB = clamp4(tB, 0, 1);
480987
480862
  tB = (tA * dotAB + dotBW) / dotBB;
480988
- tB = clamp6(tB, 0, 1);
480863
+ tB = clamp4(tB, 0, 1);
480989
480864
  tA = (tB * dotAB - dotAW) / dotAA;
480990
- tA = clamp6(tA, 0, 1);
480865
+ tA = clamp4(tA, 0, 1);
480991
480866
  const closestOnA = {
480992
480867
  x: a1.x + tA * va.x,
480993
480868
  y: a1.y + tA * va.y
@@ -480998,7 +480873,7 @@ var getClosestPointBetweenSegments = (segmentA, segmentB) => {
480998
480873
  };
480999
480874
  const dx = closestOnA.x - closestOnB.x;
481000
480875
  const dy = closestOnA.y - closestOnB.y;
481001
- const distance23 = Math.sqrt(dx * dx + dy * dy);
480876
+ const distance32 = Math.sqrt(dx * dx + dy * dy);
481002
480877
  const averagePoint = {
481003
480878
  x: (closestOnA.x + closestOnB.x) / 2,
481004
480879
  y: (closestOnA.y + closestOnB.y) / 2
@@ -481007,16 +480882,16 @@ var getClosestPointBetweenSegments = (segmentA, segmentB) => {
481007
480882
  };
481008
480883
  var closestPointsParallelSegments = (a1, a2, b1, b2, va, vb, lenSqrA, lenSqrB) => {
481009
480884
  let tA = ((b1.x - a1.x) * va.x + (b1.y - a1.y) * va.y) / lenSqrA;
481010
- tA = clamp6(tA, 0, 1);
480885
+ tA = clamp4(tA, 0, 1);
481011
480886
  const pointOnA1 = { x: a1.x + tA * va.x, y: a1.y + tA * va.y };
481012
480887
  let tA2 = ((b2.x - a1.x) * va.x + (b2.y - a1.y) * va.y) / lenSqrA;
481013
- tA2 = clamp6(tA2, 0, 1);
480888
+ tA2 = clamp4(tA2, 0, 1);
481014
480889
  const pointOnA2 = { x: a1.x + tA2 * va.x, y: a1.y + tA2 * va.y };
481015
480890
  let tB = ((a1.x - b1.x) * vb.x + (a1.y - b1.y) * vb.y) / lenSqrB;
481016
- tB = clamp6(tB, 0, 1);
480891
+ tB = clamp4(tB, 0, 1);
481017
480892
  const pointOnB1 = { x: b1.x + tB * vb.x, y: b1.y + tB * vb.y };
481018
480893
  let tB2 = ((a2.x - b1.x) * vb.x + (a2.y - b1.y) * vb.y) / lenSqrB;
481019
- tB2 = clamp6(tB2, 0, 1);
480894
+ tB2 = clamp4(tB2, 0, 1);
481020
480895
  const pointOnB2 = { x: b1.x + tB2 * vb.x, y: b1.y + tB2 * vb.y };
481021
480896
  const distances = [
481022
480897
  {
@@ -481046,7 +480921,7 @@ var closestPointsParallelSegments = (a1, a2, b1, b2, va, vb, lenSqrA, lenSqrB) =
481046
480921
  y: (closestPair.pointA.y + closestPair.pointB.y) / 2
481047
480922
  };
481048
480923
  };
481049
- var clamp6 = (value2, min, max) => {
480924
+ var clamp4 = (value2, min, max) => {
481050
480925
  return Math.max(min, Math.min(max, value2));
481051
480926
  };
481052
480927
  var getRadiusOfCircuitJsonElement = (obj) => {
@@ -481177,7 +481052,7 @@ function checkEachPcbTraceNonOverlapping(circuitJson, {
481177
481052
  connMap
481178
481053
  } = {}) {
481179
481054
  const errors = [];
481180
- connMap ??= getFullConnectivityMapFromCircuitJson2(circuitJson);
481055
+ connMap ??= getFullConnectivityMapFromCircuitJson(circuitJson);
481181
481056
  const pcbTraces = cju_default(circuitJson).pcb_trace.list();
481182
481057
  const pcbTraceSegments = pcbTraces.flatMap((pcbTrace) => {
481183
481058
  const segments = [];
@@ -481239,7 +481114,7 @@ function checkEachPcbTraceNonOverlapping(circuitJson, {
481239
481114
  continue;
481240
481115
  if (connMap.areIdsConnected(segmentA.pcb_trace_id, segmentB.pcb_trace_id))
481241
481116
  continue;
481242
- const gap2 = segmentToSegmentMinDistance2({ x: segmentA.x1, y: segmentA.y1 }, { x: segmentA.x2, y: segmentA.y2 }, { x: segmentB.x1, y: segmentB.y1 }, { x: segmentB.x2, y: segmentB.y2 }) - segmentA.thickness / 2 - segmentB.thickness / 2;
481117
+ const gap2 = segmentToSegmentMinDistance({ x: segmentA.x1, y: segmentA.y1 }, { x: segmentA.x2, y: segmentA.y2 }, { x: segmentB.x1, y: segmentB.y1 }, { x: segmentB.x2, y: segmentB.y2 }) - segmentA.thickness / 2 - segmentB.thickness / 2;
481243
481118
  if (gap2 > DEFAULT_TRACE_MARGIN - EPSILON4)
481244
481119
  continue;
481245
481120
  const pcb_trace_error_id = `overlap_${segmentA.pcb_trace_id}_${segmentB.pcb_trace_id}`;
@@ -481271,8 +481146,8 @@ function checkEachPcbTraceNonOverlapping(circuitJson, {
481271
481146
  const isCircular = obj.type === "pcb_via" || obj.type === "pcb_plated_hole" && obj.shape === "circle" || obj.type === "pcb_hole" || obj.type === "pcb_smtpad" && obj.shape === "circle";
481272
481147
  if (isCircular) {
481273
481148
  const radius = getRadiusOfCircuitJsonElement(obj);
481274
- const distance23 = segmentToCircleMinDistance({ x: segmentA.x1, y: segmentA.y1 }, { x: segmentA.x2, y: segmentA.y2 }, { x: obj.x, y: obj.y, radius });
481275
- const gap2 = distance23 - segmentA.thickness / 2;
481149
+ const distance32 = segmentToCircleMinDistance({ x: segmentA.x1, y: segmentA.y1 }, { x: segmentA.x2, y: segmentA.y2 }, { x: obj.x, y: obj.y, radius });
481150
+ const gap2 = distance32 - segmentA.thickness / 2;
481276
481151
  if (gap2 > DEFAULT_TRACE_MARGIN - EPSILON4)
481277
481152
  continue;
481278
481153
  const pcb_trace_error_id = `overlap_${segmentA.pcb_trace_id}_${primaryObjId}`;
@@ -481296,7 +481171,7 @@ function checkEachPcbTraceNonOverlapping(circuitJson, {
481296
481171
  ].filter(Boolean)
481297
481172
  });
481298
481173
  }
481299
- const gap = segmentToBoundsMinDistance2({ x: segmentA.x1, y: segmentA.y1 }, { x: segmentA.x2, y: segmentA.y2 }, getCollidableBounds(obj)) - segmentA.thickness / 2;
481174
+ const gap = segmentToBoundsMinDistance({ x: segmentA.x1, y: segmentA.y1 }, { x: segmentA.x2, y: segmentA.y2 }, getCollidableBounds(obj)) - segmentA.thickness / 2;
481300
481175
  if (gap + EPSILON4 < requiredMargin) {
481301
481176
  const pcb_trace_error_id = `overlap_${segmentA.pcb_trace_id}_${primaryObjId}`;
481302
481177
  if (errorIds.has(pcb_trace_error_id))
@@ -482231,8 +482106,8 @@ var PinBuilder = class {
482231
482106
  };
482232
482107
  pathfinder.addObstacle(obstacle);
482233
482108
  }
482234
- const distance8 = Math.abs(targetX - this.x) + Math.abs(targetY - this.y);
482235
- if (distance8 < 10) {
482109
+ const distance6 = Math.abs(targetX - this.x) + Math.abs(targetY - this.y);
482110
+ if (distance6 < 10) {
482236
482111
  const path21 = pathfinder.findPath(currentPos, targetPos);
482237
482112
  if (path21.length > 0) {
482238
482113
  for (let i = 1;i < path21.length; i++) {
@@ -484304,9 +484179,9 @@ function findBestPinToRemove(params2) {
484304
484179
  pinNumber: pin.pinNumber
484305
484180
  };
484306
484181
  applyEditOperation(testTemplate, testOp);
484307
- const distance8 = computeSimilarityDistanceAfterRemoval(testTemplate, target);
484308
- if (distance8 < bestDistance) {
484309
- bestDistance = distance8;
484182
+ const distance6 = computeSimilarityDistanceAfterRemoval(testTemplate, target);
484183
+ if (distance6 < bestDistance) {
484184
+ bestDistance = distance6;
484310
484185
  bestPinNumber = pin.pinNumber;
484311
484186
  }
484312
484187
  } catch (error) {
@@ -495909,9 +495784,648 @@ var registerBuild = (program3) => {
495909
495784
  import fs24 from "node:fs";
495910
495785
  import path24 from "node:path";
495911
495786
  init_dist6();
495787
+
495788
+ // node_modules/circuit-json-to-simple-3d/dist/index.js
495789
+ init_dist4();
495790
+
495791
+ // node_modules/@tscircuit/simple-3d-svg/dist/index.js
495792
+ var stlCache = /* @__PURE__ */ new Map;
495793
+ async function loadSTL(url) {
495794
+ if (stlCache.has(url)) {
495795
+ return stlCache.get(url);
495796
+ }
495797
+ const response = await fetch(url);
495798
+ const buffer = await response.arrayBuffer();
495799
+ const mesh = parseSTL(buffer);
495800
+ stlCache.set(url, mesh);
495801
+ return mesh;
495802
+ }
495803
+ function parseSTL(buffer) {
495804
+ const view = new DataView(buffer);
495805
+ const header = new TextDecoder().decode(buffer.slice(0, 5));
495806
+ if (header.toLowerCase() === "solid") {
495807
+ return parseASCIISTL(buffer);
495808
+ } else {
495809
+ return parseBinarySTL(view);
495810
+ }
495811
+ }
495812
+ function parseASCIISTL(buffer) {
495813
+ const text = new TextDecoder().decode(buffer);
495814
+ const lines = text.split(`
495815
+ `).map((line) => line.trim());
495816
+ const triangles = [];
495817
+ let i = 0;
495818
+ while (i < lines.length) {
495819
+ const line = lines[i];
495820
+ if (line && line.startsWith("facet normal")) {
495821
+ const normalMatch = line.match(/facet normal\s+([-+]?\d*\.?\d+(?:[eE][-+]?\d+)?)\s+([-+]?\d*\.?\d+(?:[eE][-+]?\d+)?)\s+([-+]?\d*\.?\d+(?:[eE][-+]?\d+)?)/);
495822
+ const normal = normalMatch ? {
495823
+ x: parseFloat(normalMatch[1]),
495824
+ y: parseFloat(normalMatch[2]),
495825
+ z: parseFloat(normalMatch[3])
495826
+ } : { x: 0, y: 0, z: 1 };
495827
+ i++;
495828
+ const vertices = [];
495829
+ while (i < lines.length && lines[i] && !lines[i].startsWith("endfacet")) {
495830
+ const vertexLine = lines[i];
495831
+ if (vertexLine.startsWith("vertex")) {
495832
+ const vertexMatch = vertexLine.match(/vertex\s+([-+]?\d*\.?\d+(?:[eE][-+]?\d+)?)\s+([-+]?\d*\.?\d+(?:[eE][-+]?\d+)?)\s+([-+]?\d*\.?\d+(?:[eE][-+]?\d+)?)/);
495833
+ if (vertexMatch) {
495834
+ vertices.push({
495835
+ x: parseFloat(vertexMatch[1]),
495836
+ y: parseFloat(vertexMatch[2]),
495837
+ z: parseFloat(vertexMatch[3])
495838
+ });
495839
+ }
495840
+ }
495841
+ i++;
495842
+ }
495843
+ if (vertices.length === 3) {
495844
+ triangles.push({
495845
+ vertices: [vertices[0], vertices[1], vertices[2]],
495846
+ normal
495847
+ });
495848
+ }
495849
+ }
495850
+ i++;
495851
+ }
495852
+ return {
495853
+ triangles,
495854
+ boundingBox: calculateBoundingBox(triangles)
495855
+ };
495856
+ }
495857
+ function parseBinarySTL(view) {
495858
+ let offset = 80;
495859
+ const numTriangles = view.getUint32(offset, true);
495860
+ offset += 4;
495861
+ const triangles = [];
495862
+ for (let i = 0;i < numTriangles; i++) {
495863
+ const normal = {
495864
+ x: view.getFloat32(offset, true),
495865
+ y: view.getFloat32(offset + 4, true),
495866
+ z: view.getFloat32(offset + 8, true)
495867
+ };
495868
+ offset += 12;
495869
+ const vertices = [
495870
+ {
495871
+ x: view.getFloat32(offset, true),
495872
+ y: view.getFloat32(offset + 4, true),
495873
+ z: view.getFloat32(offset + 8, true)
495874
+ },
495875
+ {
495876
+ x: view.getFloat32(offset + 12, true),
495877
+ y: view.getFloat32(offset + 16, true),
495878
+ z: view.getFloat32(offset + 20, true)
495879
+ },
495880
+ {
495881
+ x: view.getFloat32(offset + 24, true),
495882
+ y: view.getFloat32(offset + 28, true),
495883
+ z: view.getFloat32(offset + 32, true)
495884
+ }
495885
+ ];
495886
+ offset += 36;
495887
+ offset += 2;
495888
+ triangles.push({ vertices, normal });
495889
+ }
495890
+ return {
495891
+ triangles,
495892
+ boundingBox: calculateBoundingBox(triangles)
495893
+ };
495894
+ }
495895
+ function calculateBoundingBox(triangles) {
495896
+ if (triangles.length === 0) {
495897
+ return {
495898
+ min: { x: 0, y: 0, z: 0 },
495899
+ max: { x: 0, y: 0, z: 0 }
495900
+ };
495901
+ }
495902
+ let minX = Infinity, minY = Infinity, minZ = Infinity;
495903
+ let maxX = -Infinity, maxY = -Infinity, maxZ = -Infinity;
495904
+ for (const triangle of triangles) {
495905
+ for (const vertex of triangle.vertices) {
495906
+ minX = Math.min(minX, vertex.x);
495907
+ minY = Math.min(minY, vertex.y);
495908
+ minZ = Math.min(minZ, vertex.z);
495909
+ maxX = Math.max(maxX, vertex.x);
495910
+ maxY = Math.max(maxY, vertex.y);
495911
+ maxZ = Math.max(maxZ, vertex.z);
495912
+ }
495913
+ }
495914
+ return {
495915
+ min: { x: minX, y: minY, z: minZ },
495916
+ max: { x: maxX, y: maxY, z: maxZ }
495917
+ };
495918
+ }
495919
+ function colorToCss(c) {
495920
+ return typeof c === "string" ? c : `rgba(${c[0]},${c[1]},${c[2]},${c[3]})`;
495921
+ }
495922
+ function add(a, b) {
495923
+ return { x: a.x + b.x, y: a.y + b.y, z: a.z + b.z };
495924
+ }
495925
+ function sub(a, b) {
495926
+ return { x: a.x - b.x, y: a.y - b.y, z: a.z - b.z };
495927
+ }
495928
+ function dot(a, b) {
495929
+ return a.x * b.x + a.y * b.y + a.z * b.z;
495930
+ }
495931
+ function cross3(a, b) {
495932
+ return {
495933
+ x: a.y * b.z - a.z * b.y,
495934
+ y: a.z * b.x - a.x * b.z,
495935
+ z: a.x * b.y - a.y * b.x
495936
+ };
495937
+ }
495938
+ function scale9(v, k) {
495939
+ return { x: v.x * k, y: v.y * k, z: v.z * k };
495940
+ }
495941
+ function len(v) {
495942
+ return Math.sqrt(dot(v, v));
495943
+ }
495944
+ function norm(v) {
495945
+ const l = len(v) || 1;
495946
+ return scale9(v, 1 / l);
495947
+ }
495948
+ function rotLocal(p, r = { x: 0, y: 0, z: 0 }) {
495949
+ let { x, y, z: z3 } = p;
495950
+ if (r.x) {
495951
+ const c = Math.cos(r.x);
495952
+ const s = Math.sin(r.x);
495953
+ const y2 = y * c - z3 * s;
495954
+ z3 = y * s + z3 * c;
495955
+ y = y2;
495956
+ }
495957
+ if (r.y) {
495958
+ const c = Math.cos(r.y);
495959
+ const s = Math.sin(r.y);
495960
+ const x2 = x * c + z3 * s;
495961
+ z3 = -x * s + z3 * c;
495962
+ x = x2;
495963
+ }
495964
+ if (r.z) {
495965
+ const c = Math.cos(r.z);
495966
+ const s = Math.sin(r.z);
495967
+ const x2 = x * c - y * s;
495968
+ y = x * s + y * c;
495969
+ x = x2;
495970
+ }
495971
+ return { x, y, z: z3 };
495972
+ }
495973
+ var W_DEF = 400;
495974
+ var H_DEF = 400;
495975
+ var FOCAL = 2;
495976
+ function axes(cam) {
495977
+ const f = norm(sub(cam.lookAt, cam.position));
495978
+ const wUp = { x: 0, y: 1, z: 0 };
495979
+ let r = norm(cross3(f, wUp));
495980
+ if (!len(r))
495981
+ r = { x: 1, y: 0, z: 0 };
495982
+ const u = cross3(r, f);
495983
+ return { r, u, f };
495984
+ }
495985
+ function toCam(p, cam) {
495986
+ const { r, u, f } = axes(cam);
495987
+ const d = sub(p, cam.position);
495988
+ return { x: dot(d, r), y: dot(d, u), z: dot(d, f) };
495989
+ }
495990
+ function proj(p, w, h, focal) {
495991
+ if (p.z <= 0)
495992
+ return null;
495993
+ const s = focal / p.z;
495994
+ return { x: p.x * s * w / 2, y: -p.y * s * h / 2, z: p.z };
495995
+ }
495996
+ var FACES = [
495997
+ [0, 1, 2, 3],
495998
+ [4, 5, 6, 7],
495999
+ [0, 1, 5, 4],
496000
+ [3, 2, 6, 7],
496001
+ [1, 2, 6, 5],
496002
+ [0, 3, 7, 4]
496003
+ ];
496004
+ var TOP = [3, 2, 6, 7];
496005
+ function verts(b) {
496006
+ const {
496007
+ size: { x: sx, y: sy, z: sz },
496008
+ center,
496009
+ rotation: rotation4
496010
+ } = b;
496011
+ const offs = [
496012
+ { x: -sx / 2, y: -sy / 2, z: -sz / 2 },
496013
+ { x: sx / 2, y: -sy / 2, z: -sz / 2 },
496014
+ { x: sx / 2, y: sy / 2, z: -sz / 2 },
496015
+ { x: -sx / 2, y: sy / 2, z: -sz / 2 },
496016
+ { x: -sx / 2, y: -sy / 2, z: sz / 2 },
496017
+ { x: sx / 2, y: -sy / 2, z: sz / 2 },
496018
+ { x: sx / 2, y: sy / 2, z: sz / 2 },
496019
+ { x: -sx / 2, y: sy / 2, z: sz / 2 }
496020
+ ];
496021
+ return offs.map((o) => add(center, rotLocal(o, rotation4)));
496022
+ }
496023
+ function inv3(m2) {
496024
+ const a = m2[0][0], d = m2[0][1], g = m2[0][2];
496025
+ const b = m2[1][0], e = m2[1][1], h = m2[1][2];
496026
+ const c = m2[2][0], f = m2[2][1], i = m2[2][2];
496027
+ const A = e * i - f * h;
496028
+ const B = -(d * i - f * g);
496029
+ const C = d * h - e * g;
496030
+ const D = -(b * i - c * h);
496031
+ const E = a * i - c * g;
496032
+ const F = -(a * h - b * g);
496033
+ const G = b * f - c * e;
496034
+ const H = -(a * f - c * d);
496035
+ const I = a * e - b * d;
496036
+ const det = a * A + d * D + g * G;
496037
+ const invDet = det ? 1 / det : 0;
496038
+ return [
496039
+ [A * invDet, B * invDet, C * invDet],
496040
+ [D * invDet, E * invDet, F * invDet],
496041
+ [G * invDet, H * invDet, I * invDet]
496042
+ ];
496043
+ }
496044
+ function mul3(a, b) {
496045
+ const r = [
496046
+ [0, 0, 0],
496047
+ [0, 0, 0],
496048
+ [0, 0, 0]
496049
+ ];
496050
+ for (let i = 0;i < 3; i++) {
496051
+ for (let j = 0;j < 3; j++) {
496052
+ r[i][j] = a[i][0] * b[0][j] + a[i][1] * b[1][j] + a[i][2] * b[2][j];
496053
+ }
496054
+ }
496055
+ return r;
496056
+ }
496057
+ function affineMatrix(src, dst) {
496058
+ const S = [
496059
+ [src[0].x, src[1].x, src[2].x],
496060
+ [src[0].y, src[1].y, src[2].y],
496061
+ [1, 1, 1]
496062
+ ];
496063
+ const D = [
496064
+ [dst[0].x, dst[1].x, dst[2].x],
496065
+ [dst[0].y, dst[1].y, dst[2].y],
496066
+ [1, 1, 1]
496067
+ ];
496068
+ const M = mul3(D, inv3(S));
496069
+ return `matrix(${M[0][0]} ${M[1][0]} ${M[0][1]} ${M[1][1]} ${M[0][2]} ${M[1][2]})`;
496070
+ }
496071
+ function scaleAndPositionMesh(mesh, box) {
496072
+ const { boundingBox } = mesh;
496073
+ const meshSize = sub(boundingBox.max, boundingBox.min);
496074
+ const boxSize = box.size;
496075
+ const scaleX = boxSize.x / meshSize.x;
496076
+ const scaleY = boxSize.y / meshSize.y;
496077
+ const scaleZ = boxSize.z / meshSize.z;
496078
+ const uniformScale = Math.min(scaleX, scaleY, scaleZ);
496079
+ const meshCenter = scale9(add(boundingBox.min, boundingBox.max), 0.5);
496080
+ const transformedVertices = [];
496081
+ for (const triangle of mesh.triangles) {
496082
+ for (const vertex of triangle.vertices) {
496083
+ let transformed = sub(vertex, meshCenter);
496084
+ transformed = scale9(transformed, uniformScale);
496085
+ if (box.stlRotation) {
496086
+ transformed = rotLocal(transformed, box.stlRotation);
496087
+ }
496088
+ if (box.stlPosition) {
496089
+ transformed = add(transformed, box.stlPosition);
496090
+ }
496091
+ if (box.rotation) {
496092
+ transformed = rotLocal(transformed, box.rotation);
496093
+ }
496094
+ transformed = add(transformed, box.center);
496095
+ transformedVertices.push(transformed);
496096
+ }
496097
+ }
496098
+ return transformedVertices;
496099
+ }
496100
+ async function renderScene(scene, opt = {}) {
496101
+ const W = opt.width ?? W_DEF;
496102
+ const H = opt.height ?? H_DEF;
496103
+ const focal = scene.camera.focalLength ?? FOCAL;
496104
+ const faces = [];
496105
+ const images = [];
496106
+ const labels = [];
496107
+ let clipSeq = 0;
496108
+ const texId = /* @__PURE__ */ new Map;
496109
+ const stlMeshes = /* @__PURE__ */ new Map;
496110
+ for (const box of scene.boxes) {
496111
+ if (box.stlUrl && !stlMeshes.has(box.stlUrl)) {
496112
+ try {
496113
+ const mesh = await loadSTL(box.stlUrl);
496114
+ stlMeshes.set(box.stlUrl, mesh);
496115
+ } catch (error) {
496116
+ console.warn(`Failed to load STL from ${box.stlUrl}:`, error);
496117
+ }
496118
+ }
496119
+ }
496120
+ for (const box of scene.boxes) {
496121
+ if (box.stlUrl && stlMeshes.has(box.stlUrl)) {
496122
+ const mesh = stlMeshes.get(box.stlUrl);
496123
+ const transformedVertices = scaleAndPositionMesh(mesh, box);
496124
+ for (let i = 0;i < mesh.triangles.length; i++) {
496125
+ const triangle = mesh.triangles[i];
496126
+ const vertexStart = i * 3;
496127
+ const v0w = transformedVertices[vertexStart];
496128
+ const v1w = transformedVertices[vertexStart + 1];
496129
+ const v2w = transformedVertices[vertexStart + 2];
496130
+ const v0c = toCam(v0w, scene.camera);
496131
+ const v1c = toCam(v1w, scene.camera);
496132
+ const v2c = toCam(v2w, scene.camera);
496133
+ const v0p = proj(v0c, W, H, focal);
496134
+ const v1p = proj(v1c, W, H, focal);
496135
+ const v2p = proj(v2c, W, H, focal);
496136
+ if (v0p && v1p && v2p) {
496137
+ const edge1 = sub(v1c, v0c);
496138
+ const edge2 = sub(v2c, v0c);
496139
+ const faceNormal = cross3(edge1, edge2);
496140
+ if (faceNormal.z < 0) {
496141
+ const depth = Math.max(v0c.z, v1c.z, v2c.z);
496142
+ faces.push({
496143
+ pts: [v0p, v1p, v2p],
496144
+ depth,
496145
+ fill: colorToCss(box.color)
496146
+ });
496147
+ }
496148
+ }
496149
+ }
496150
+ } else {
496151
+ const vw = verts(box);
496152
+ const vc = vw.map((v) => toCam(v, scene.camera));
496153
+ const vp = vc.map((v) => proj(v, W, H, focal));
496154
+ for (const idx of FACES) {
496155
+ const p4 = [];
496156
+ let zMax = -Infinity;
496157
+ let behind = false;
496158
+ for (const i of idx) {
496159
+ const p = vp[i];
496160
+ if (!p) {
496161
+ behind = true;
496162
+ break;
496163
+ }
496164
+ p4.push(p);
496165
+ zMax = Math.max(zMax, vc[i].z);
496166
+ }
496167
+ if (behind)
496168
+ continue;
496169
+ const [a, b, c] = idx;
496170
+ const n2 = cross3(sub(vc[b], vc[a]), sub(vc[c], vc[a]));
496171
+ if (n2.z >= 0)
496172
+ continue;
496173
+ faces.push({
496174
+ pts: p4,
496175
+ depth: zMax,
496176
+ fill: colorToCss(box.color)
496177
+ });
496178
+ }
496179
+ if (box.faceImages?.top) {
496180
+ const pts = TOP.map((i) => vp[i]);
496181
+ if (pts.every(Boolean)) {
496182
+ const dst = pts;
496183
+ const cz = Math.max(...TOP.map((i) => vc[i].z));
496184
+ const href = box.faceImages.top;
496185
+ if (!texId.has(href)) {
496186
+ texId.set(href, `tex${texId.size}`);
496187
+ }
496188
+ const sym = texId.get(href);
496189
+ const subdivisions = box.projectionSubdivision ?? 2;
496190
+ const quadsPerSide = subdivisions;
496191
+ for (let row = 0;row < quadsPerSide; row++) {
496192
+ for (let col = 0;col < quadsPerSide; col++) {
496193
+ const u0 = col / quadsPerSide;
496194
+ const u1 = (col + 1) / quadsPerSide;
496195
+ const v0 = row / quadsPerSide;
496196
+ const v1 = (row + 1) / quadsPerSide;
496197
+ const lerp = (a, b, t2) => ({
496198
+ x: a.x * (1 - t2) + b.x * t2,
496199
+ y: a.y * (1 - t2) + b.y * t2,
496200
+ z: a.z * (1 - t2) + b.z * t2
496201
+ });
496202
+ const p00 = lerp(lerp(dst[0], dst[1], u0), lerp(dst[3], dst[2], u0), v0);
496203
+ const p10 = lerp(lerp(dst[0], dst[1], u1), lerp(dst[3], dst[2], u1), v0);
496204
+ const p01 = lerp(lerp(dst[0], dst[1], u0), lerp(dst[3], dst[2], u0), v1);
496205
+ const p11 = lerp(lerp(dst[0], dst[1], u1), lerp(dst[3], dst[2], u1), v1);
496206
+ const tri0Mat = affineMatrix([
496207
+ { x: u0, y: v0 },
496208
+ { x: u1, y: v0 },
496209
+ { x: u1, y: v1 }
496210
+ ], [p00, p10, p11]);
496211
+ const id0 = `clip${clipSeq++}`;
496212
+ images.push({
496213
+ matrix: tri0Mat,
496214
+ depth: cz,
496215
+ href,
496216
+ clip: id0,
496217
+ points: `${u0},${v0} ${u1},${v0} ${u1},${v1}`,
496218
+ sym
496219
+ });
496220
+ const tri1Mat = affineMatrix([
496221
+ { x: u0, y: v0 },
496222
+ { x: u1, y: v1 },
496223
+ { x: u0, y: v1 }
496224
+ ], [p00, p11, p01]);
496225
+ const id1 = `clip${clipSeq++}`;
496226
+ images.push({
496227
+ matrix: tri1Mat,
496228
+ depth: cz,
496229
+ href,
496230
+ clip: id1,
496231
+ points: `${u0},${v0} ${u1},${v1} ${u0},${v1}`,
496232
+ sym
496233
+ });
496234
+ }
496235
+ }
496236
+ }
496237
+ }
496238
+ if (box.topLabel) {
496239
+ const pts = TOP.map((i) => vp[i]);
496240
+ if (pts.every(Boolean)) {
496241
+ const p0 = pts[0];
496242
+ const p1 = pts[1];
496243
+ const p3 = pts[3];
496244
+ const u = sub(p1, p0);
496245
+ const v = sub(p3, p0);
496246
+ const lu = len(u);
496247
+ const lv = len(v);
496248
+ if (lu && lv) {
496249
+ const uN = scale9(u, 1 / lu);
496250
+ const vN = scale9(v, 1 / lv);
496251
+ const cx = pts.reduce((s, p) => s + p.x, 0) / 4;
496252
+ const cy = pts.reduce((s, p) => s + p.y, 0) / 4;
496253
+ const cz = Math.max(...TOP.map((i) => vc[i].z));
496254
+ const m2 = `matrix(${uN.x} ${uN.y} ${vN.x} ${vN.y} ${cx} ${cy})`;
496255
+ const fillCol = box.topLabelColor ?? [0, 0, 0, 1];
496256
+ labels.push({
496257
+ matrix: m2,
496258
+ depth: cz,
496259
+ text: box.topLabel,
496260
+ fill: colorToCss(fillCol)
496261
+ });
496262
+ }
496263
+ }
496264
+ }
496265
+ }
496266
+ }
496267
+ const allElements = [
496268
+ ...faces.map((f) => ({ type: "face", data: f })),
496269
+ ...images.map((i) => ({ type: "image", data: i })),
496270
+ ...labels.map((l) => ({ type: "label", data: l }))
496271
+ ];
496272
+ allElements.sort((a, b) => b.data.depth - a.data.depth);
496273
+ const out = [];
496274
+ out.push(`<svg xmlns="http://www.w3.org/2000/svg" width="${W}" height="${H}" viewBox="${-W / 2} ${-H / 2} ${W} ${H}">`);
496275
+ if (opt.backgroundColor) {
496276
+ out.push(` <rect x="${-W / 2}" y="${-H / 2}" width="${W}" height="${H}" fill="${colorToCss(opt.backgroundColor)}" />
496277
+ `);
496278
+ }
496279
+ if (images.length) {
496280
+ out.push(` <defs>
496281
+ `);
496282
+ for (const [href, id] of texId) {
496283
+ out.push(` <image id="${id}" href="${href}" width="1" height="1" preserveAspectRatio="none" style="image-rendering:pixelated"/>
496284
+ `);
496285
+ }
496286
+ for (const img of images) {
496287
+ out.push(` <clipPath id="${img.clip}" clipPathUnits="objectBoundingBox"><polygon points="${img.points}" /></clipPath>
496288
+ `);
496289
+ }
496290
+ out.push(` </defs>
496291
+ `);
496292
+ }
496293
+ let inStrokeGroup = false;
496294
+ for (const element of allElements) {
496295
+ if (element.type === "face" || element.type === "image") {
496296
+ if (!inStrokeGroup) {
496297
+ out.push(` <g stroke="#000" stroke-width="1" stroke-linecap="round" stroke-linejoin="round">
496298
+ `);
496299
+ inStrokeGroup = true;
496300
+ }
496301
+ if (element.type === "face") {
496302
+ const f = element.data;
496303
+ out.push(` <polygon fill="${f.fill}" points="${f.pts.map((p) => `${p.x},${p.y}`).join(" ")}" />
496304
+ `);
496305
+ } else {
496306
+ const img = element.data;
496307
+ out.push(` <g transform="${img.matrix}" clip-path="url(#${img.clip})"><use href="#${img.sym}"/></g>
496308
+ `);
496309
+ }
496310
+ } else if (element.type === "label") {
496311
+ if (inStrokeGroup) {
496312
+ out.push(` </g>
496313
+ `);
496314
+ inStrokeGroup = false;
496315
+ }
496316
+ const l = element.data;
496317
+ out.push(` <g font-family="sans-serif" font-size="14" text-anchor="middle" dominant-baseline="central" transform="${l.matrix}"><text x="0" y="0" fill="${l.fill}">${l.text}</text></g>
496318
+ `);
496319
+ }
496320
+ }
496321
+ if (inStrokeGroup) {
496322
+ out.push(` </g>
496323
+ `);
496324
+ }
496325
+ out.push("</svg>");
496326
+ return out.join("");
496327
+ }
496328
+
496329
+ // node_modules/circuit-json-to-simple-3d/dist/index.js
496330
+ init_dist6();
496331
+ function getDefaultCameraForPcbBoard(pcbBoard, anglePreset = "angle1") {
496332
+ const w = pcbBoard.width;
496333
+ const h = pcbBoard.height;
496334
+ const cx = pcbBoard.center?.x;
496335
+ const cz = pcbBoard.center?.y;
496336
+ const dist = Math.max(w, h) * 1.5;
496337
+ let position4;
496338
+ if (anglePreset === "angle1") {
496339
+ position4 = { x: cx - dist, y: dist, z: cz - dist };
496340
+ } else if (anglePreset === "angle2") {
496341
+ position4 = { x: cx + dist, y: dist, z: cz - dist };
496342
+ } else if (anglePreset === "left") {
496343
+ position4 = { x: cx - dist, y: 0, z: 0 };
496344
+ } else if (anglePreset === "right") {
496345
+ position4 = { x: cx + dist, y: 0, z: 0 };
496346
+ } else if (anglePreset === "left-raised") {
496347
+ position4 = { x: cx - dist, y: dist, z: 0 };
496348
+ } else if (anglePreset === "right-raised") {
496349
+ position4 = { x: cx + dist, y: dist, z: 0 };
496350
+ } else {
496351
+ throw new Error(`Unknown angle preset: ${anglePreset}`);
496352
+ }
496353
+ return {
496354
+ position: position4,
496355
+ lookAt: { x: cx, y: 0, z: cz },
496356
+ focalLength: 2
496357
+ };
496358
+ }
496359
+ async function convertCircuitJsonToSimple3dSvg(circuitJson, opts = {}) {
496360
+ const db = cju_default(circuitJson);
496361
+ const boxes = [];
496362
+ const pcbTopSvg = convertCircuitJsonToPcbSvg(circuitJson, {
496363
+ layer: "top",
496364
+ matchBoardAspectRatio: true,
496365
+ backgroundColor: "transparent",
496366
+ drawPaddingOutsideBoard: false,
496367
+ colorOverrides: {
496368
+ copper: {
496369
+ top: "#ffe066",
496370
+ bottom: "#ffe066"
496371
+ },
496372
+ drill: "rgba(0,0,0,0.5)"
496373
+ }
496374
+ }).replace("<svg", "<svg transform='scale(1, -1)'");
496375
+ const pcbBoard = db.pcb_board.list()[0];
496376
+ if (!pcbBoard)
496377
+ throw new Error("No pcb_board, can't render to 3d");
496378
+ const camera = opts.camera ?? getDefaultCameraForPcbBoard(pcbBoard, opts.anglePreset ?? "angle1");
496379
+ if (!camera.focalLength) {
496380
+ camera.focalLength = 1;
496381
+ }
496382
+ boxes.push({
496383
+ center: {
496384
+ x: pcbBoard.center.x,
496385
+ y: 0,
496386
+ z: pcbBoard.center.y
496387
+ },
496388
+ size: {
496389
+ x: pcbBoard.width,
496390
+ y: pcbBoard.thickness,
496391
+ z: pcbBoard.height
496392
+ },
496393
+ faceImages: {
496394
+ top: `data:image/svg+xml;base64,${btoa(pcbTopSvg)}`
496395
+ },
496396
+ projectionSubdivision: 10,
496397
+ color: "rgba(0,140,0,0.8)"
496398
+ });
496399
+ const DEFAULT_COMP_HEIGHT = 2;
496400
+ for (const comp of db.pcb_component.list()) {
496401
+ const sourceComponent = db.source_component.get(comp.source_component_id);
496402
+ const compHeight = Math.min(Math.min(comp.width, comp.height), DEFAULT_COMP_HEIGHT);
496403
+ boxes.push({
496404
+ center: {
496405
+ x: comp.center.x,
496406
+ y: pcbBoard.thickness / 2 + compHeight / 2,
496407
+ z: comp.center.y
496408
+ },
496409
+ size: {
496410
+ x: comp.width,
496411
+ y: compHeight,
496412
+ z: comp.height
496413
+ },
496414
+ color: "rgba(128,128,128,0.5)",
496415
+ topLabel: sourceComponent?.name ?? "?",
496416
+ topLabelColor: "white"
496417
+ });
496418
+ }
496419
+ return await renderScene({ boxes, camera }, {
496420
+ backgroundColor: "lightgray"
496421
+ });
496422
+ }
496423
+
496424
+ // lib/shared/snapshot-project.ts
495912
496425
  var snapshotProject = async ({
495913
496426
  update = false,
495914
496427
  ignored = [],
496428
+ threeD = false,
495915
496429
  onExit = (code) => process.exit(code),
495916
496430
  onError = (msg) => console.error(msg),
495917
496431
  onSuccess = (msg) => console.log(msg)
@@ -495938,13 +496452,18 @@ var snapshotProject = async ({
495938
496452
  const { circuitJson } = await generateCircuitJson({ filePath: file });
495939
496453
  const pcbSvg = convertCircuitJsonToPcbSvg(circuitJson);
495940
496454
  const schSvg = convertCircuitJsonToSchematicSvg(circuitJson);
496455
+ const svg3d = threeD ? await convertCircuitJsonToSimple3dSvg(circuitJson) : null;
495941
496456
  const snapDir = path24.join(path24.dirname(file), "__snapshots__");
495942
496457
  fs24.mkdirSync(snapDir, { recursive: true });
495943
496458
  const base = path24.basename(file).replace(/\.tsx$/, "");
495944
- for (const [type, svg] of [
496459
+ const snapshotPairs = [
495945
496460
  ["pcb", pcbSvg],
495946
496461
  ["schematic", schSvg]
495947
- ]) {
496462
+ ];
496463
+ if (threeD && svg3d) {
496464
+ snapshotPairs.push(["3d", svg3d]);
496465
+ }
496466
+ for (const [type, svg] of snapshotPairs) {
495948
496467
  const snapPath = path24.join(snapDir, `${base}-${type}.snap.svg`);
495949
496468
  if (update || !fs24.existsSync(snapPath)) {
495950
496469
  fs24.writeFileSync(snapPath, svg);
@@ -495971,9 +496490,10 @@ ${mismatches.join(`
495971
496490
 
495972
496491
  // cli/snapshot/register.ts
495973
496492
  var registerSnapshot = (program3) => {
495974
- program3.command("snapshot").description("Generate schematic and PCB snapshots").option("-u, --update", "Update snapshots on disk").action(async (options) => {
496493
+ program3.command("snapshot").description("Generate schematic and PCB snapshots (add --3d for 3d preview)").option("-u, --update", "Update snapshots on disk").option("--3d", "Generate 3d preview snapshots").action(async (options) => {
495975
496494
  await snapshotProject({
495976
496495
  update: options.update ?? false,
496496
+ threeD: options["3d"] ?? false,
495977
496497
  onExit: (code) => process.exit(code),
495978
496498
  onError: (msg) => console.error(msg),
495979
496499
  onSuccess: (msg) => console.log(msg)