@tscircuit/3d-viewer 0.0.525 → 0.0.527

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -61,6 +61,7 @@ interface LayerVisibilityState {
61
61
  modelsMarkedDNP: boolean;
62
62
  modelBoundingBoxes: boolean;
63
63
  threedAxis: boolean;
64
+ pcbNotes: boolean;
64
65
  backgroundStart: boolean;
65
66
  backgroundEnd: boolean;
66
67
  }
package/dist/index.js CHANGED
@@ -14469,6 +14469,7 @@ var defaultVisibility = {
14469
14469
  modelsMarkedDNP: false,
14470
14470
  modelBoundingBoxes: false,
14471
14471
  threedAxis: false,
14472
+ pcbNotes: false,
14472
14473
  backgroundStart: true,
14473
14474
  backgroundEnd: true
14474
14475
  };
@@ -28768,7 +28769,7 @@ import * as THREE16 from "three";
28768
28769
  // package.json
28769
28770
  var package_default = {
28770
28771
  name: "@tscircuit/3d-viewer",
28771
- version: "0.0.524",
28772
+ version: "0.0.526",
28772
28773
  main: "./dist/index.js",
28773
28774
  module: "./dist/index.js",
28774
28775
  type: "module",
@@ -28798,7 +28799,7 @@ var package_default = {
28798
28799
  "@jscad/regl-renderer": "^2.6.12",
28799
28800
  "@jscad/stl-serializer": "^2.1.20",
28800
28801
  "circuit-json": "^0.0.372",
28801
- "circuit-to-canvas": "^0.0.81",
28802
+ "circuit-to-canvas": "^0.0.87",
28802
28803
  "react-hot-toast": "^2.6.0",
28803
28804
  three: "^0.165.0",
28804
28805
  "three-stdlib": "^2.36.0",
@@ -31737,7 +31738,7 @@ import { su as su8 } from "@tscircuit/circuit-json-util";
31737
31738
  import { useEffect as useEffect23, useMemo as useMemo19 } from "react";
31738
31739
 
31739
31740
  // src/textures/create-combined-board-textures.ts
31740
- import * as THREE28 from "three";
31741
+ import * as THREE27 from "three";
31741
31742
 
31742
31743
  // node_modules/@tscircuit/math-utils/dist/chunk-5N7UJNVK.js
31743
31744
  var getBoundsFromPoints = (points) => {
@@ -32233,227 +32234,11 @@ function createCopperTextTextureForLayer({
32233
32234
  return texture;
32234
32235
  }
32235
32236
 
32236
- // src/textures/create-copper-pour-texture-for-layer.ts
32237
- import * as THREE23 from "three";
32238
- import { CircuitToCanvasDrawer as CircuitToCanvasDrawer2 } from "circuit-to-canvas";
32239
-
32240
- // src/geoms/brep-converter.ts
32241
- var import_primitives7 = __toESM(require_primitives(), 1);
32242
- var import_booleans5 = __toESM(require_booleans(), 1);
32243
- function segmentToPoints(p1, p2, bulge, arcSegments) {
32244
- if (!bulge || Math.abs(bulge) < 1e-9) {
32245
- return [];
32246
- }
32247
- const theta = 4 * Math.atan(bulge);
32248
- const dx = p2[0] - p1[0];
32249
- const dy = p2[1] - p1[1];
32250
- const dist = Math.sqrt(dx * dx + dy * dy);
32251
- if (dist < 1e-9) return [];
32252
- const radius = Math.abs(dist / (2 * Math.sin(theta / 2)));
32253
- const m = Math.sqrt(Math.max(0, radius * radius - dist / 2 * (dist / 2)));
32254
- const midPoint = [(p1[0] + p2[0]) / 2, (p1[1] + p2[1]) / 2];
32255
- const ux = dx / dist;
32256
- const uy = dy / dist;
32257
- const nx = -uy;
32258
- const ny = ux;
32259
- const centerX = midPoint[0] + nx * m * Math.sign(bulge);
32260
- const centerY = midPoint[1] + ny * m * Math.sign(bulge);
32261
- const startAngle = Math.atan2(p1[1] - centerY, p1[0] - centerX);
32262
- const points = [];
32263
- const numSteps = Math.max(
32264
- 2,
32265
- Math.ceil(arcSegments * Math.abs(theta) / (Math.PI * 2) * 4)
32266
- );
32267
- const angleStep = theta / numSteps;
32268
- for (let i = 1; i < numSteps; i++) {
32269
- const angle = startAngle + angleStep * i;
32270
- points.push([
32271
- centerX + radius * Math.cos(angle),
32272
- centerY + radius * Math.sin(angle)
32273
- ]);
32274
- }
32275
- return points;
32276
- }
32277
- function ringToPoints(ring, arcSegments) {
32278
- const allPoints = [];
32279
- const vertices = ring.vertices;
32280
- for (let i = 0; i < vertices.length; i++) {
32281
- const p1 = vertices[i];
32282
- const p2 = vertices[(i + 1) % vertices.length];
32283
- allPoints.push([p1.x, p1.y]);
32284
- if (p1.bulge) {
32285
- const arcPoints = segmentToPoints(
32286
- [p1.x, p1.y],
32287
- [p2.x, p2.y],
32288
- p1.bulge,
32289
- arcSegments
32290
- );
32291
- allPoints.push(...arcPoints);
32292
- }
32293
- }
32294
- return allPoints;
32295
- }
32296
-
32297
- // src/textures/create-copper-pour-texture-for-layer.ts
32298
- function drawPolygon({
32299
- ctx,
32300
- points,
32301
- canvasXFromPcb,
32302
- canvasYFromPcb
32303
- }) {
32304
- if (points.length < 3) return;
32305
- ctx.beginPath();
32306
- points.forEach((point, index2) => {
32307
- const canvasX = canvasXFromPcb(point[0]);
32308
- const canvasY = canvasYFromPcb(point[1]);
32309
- if (index2 === 0) {
32310
- ctx.moveTo(canvasX, canvasY);
32311
- } else {
32312
- ctx.lineTo(canvasX, canvasY);
32313
- }
32314
- });
32315
- ctx.closePath();
32316
- ctx.fill();
32317
- }
32318
- function drawBrepShape({
32319
- ctx,
32320
- pour,
32321
- canvasXFromPcb,
32322
- canvasYFromPcb
32323
- }) {
32324
- const brepShape = pour.brep_shape;
32325
- if (!brepShape || !brepShape.outer_ring) return;
32326
- const outerRingPoints = ringToPoints(brepShape.outer_ring, 32);
32327
- if (outerRingPoints.length >= 3) {
32328
- drawPolygon({
32329
- ctx,
32330
- points: outerRingPoints,
32331
- canvasXFromPcb,
32332
- canvasYFromPcb
32333
- });
32334
- }
32335
- if (brepShape.inner_rings && brepShape.inner_rings.length > 0) {
32336
- ctx.globalCompositeOperation = "destination-out";
32337
- for (const innerRing of brepShape.inner_rings) {
32338
- const innerRingPoints = ringToPoints(innerRing, 32);
32339
- if (innerRingPoints.length >= 3) {
32340
- drawPolygon({
32341
- ctx,
32342
- points: innerRingPoints,
32343
- canvasXFromPcb,
32344
- canvasYFromPcb
32345
- });
32346
- }
32347
- }
32348
- ctx.globalCompositeOperation = "source-over";
32349
- }
32350
- }
32351
- function createCopperPourTextureForLayer({
32352
- layer,
32353
- circuitJson,
32354
- boardData,
32355
- traceTextureResolution = TRACE_TEXTURE_RESOLUTION
32356
- }) {
32357
- const copperPours = circuitJson.filter(
32358
- (e) => e.type === "pcb_copper_pour"
32359
- );
32360
- const pcbRenderLayer = layer === "top" ? "top_copper" : "bottom_copper";
32361
- const poursOnLayer = copperPours.filter((p) => p.layer === layer);
32362
- if (poursOnLayer.length === 0) return null;
32363
- const boardOutlineBounds = calculateOutlineBounds(boardData);
32364
- const canvas = document.createElement("canvas");
32365
- const canvasWidth = Math.floor(
32366
- boardOutlineBounds.width * traceTextureResolution
32367
- );
32368
- const canvasHeight = Math.floor(
32369
- boardOutlineBounds.height * traceTextureResolution
32370
- );
32371
- canvas.width = canvasWidth;
32372
- canvas.height = canvasHeight;
32373
- const ctx = canvas.getContext("2d");
32374
- if (!ctx) return null;
32375
- if (layer === "bottom") {
32376
- ctx.translate(0, canvasHeight);
32377
- ctx.scale(1, -1);
32378
- }
32379
- const canvasXFromPcb = (pcbX) => (pcbX - boardOutlineBounds.minX) * traceTextureResolution;
32380
- const canvasYFromPcb = (pcbY) => (boardOutlineBounds.maxY - pcbY) * traceTextureResolution;
32381
- const rectAndPolygonPours = poursOnLayer.filter(
32382
- (pour) => pour.shape === "rect" || pour.shape === "polygon"
32383
- );
32384
- const brepPours = poursOnLayer.filter((pour) => pour.shape === "brep");
32385
- if (rectAndPolygonPours.length > 0) {
32386
- const drawer = new CircuitToCanvasDrawer2(ctx);
32387
- drawer.setCameraBounds({
32388
- minX: boardOutlineBounds.minX,
32389
- maxX: boardOutlineBounds.maxX,
32390
- minY: boardOutlineBounds.minY,
32391
- maxY: boardOutlineBounds.maxY
32392
- });
32393
- const coveredPours = rectAndPolygonPours.filter(
32394
- (p) => p.covered_with_solder_mask !== false
32395
- );
32396
- const uncoveredPours = rectAndPolygonPours.filter(
32397
- (p) => p.covered_with_solder_mask === false
32398
- );
32399
- const coveredColor = `rgb(${colors.fr4TracesWithMaskGreen.map((c) => c * 255).join(",")})`;
32400
- const uncoveredColor = `rgb(${colors.copper.map((c) => c * 255).join(",")})`;
32401
- if (coveredPours.length > 0) {
32402
- drawer.configure({
32403
- colorOverrides: {
32404
- copper: {
32405
- top: coveredColor,
32406
- bottom: coveredColor,
32407
- inner1: coveredColor,
32408
- inner2: coveredColor,
32409
- inner3: coveredColor,
32410
- inner4: coveredColor,
32411
- inner5: coveredColor,
32412
- inner6: coveredColor
32413
- }
32414
- }
32415
- });
32416
- drawer.drawElements(coveredPours, { layers: [pcbRenderLayer] });
32417
- }
32418
- if (uncoveredPours.length > 0) {
32419
- drawer.configure({
32420
- colorOverrides: {
32421
- copper: {
32422
- top: uncoveredColor,
32423
- bottom: uncoveredColor,
32424
- inner1: uncoveredColor,
32425
- inner2: uncoveredColor,
32426
- inner3: uncoveredColor,
32427
- inner4: uncoveredColor,
32428
- inner5: uncoveredColor,
32429
- inner6: uncoveredColor
32430
- }
32431
- }
32432
- });
32433
- drawer.drawElements(uncoveredPours, { layers: [pcbRenderLayer] });
32434
- }
32435
- }
32436
- for (const pour of brepPours) {
32437
- const covered = pour.covered_with_solder_mask !== false;
32438
- const colorArr = covered ? colors.fr4TracesWithMaskGreen : colors.copper;
32439
- const copperColor = `rgb(${colorArr[0] * 255}, ${colorArr[1] * 255}, ${colorArr[2] * 255})`;
32440
- ctx.fillStyle = copperColor;
32441
- drawBrepShape({ ctx, pour, canvasXFromPcb, canvasYFromPcb });
32442
- }
32443
- const texture = new THREE23.CanvasTexture(canvas);
32444
- texture.generateMipmaps = true;
32445
- texture.minFilter = THREE23.LinearMipmapLinearFilter;
32446
- texture.magFilter = THREE23.LinearFilter;
32447
- texture.anisotropy = 16;
32448
- texture.needsUpdate = true;
32449
- return texture;
32450
- }
32451
-
32452
32237
  // src/textures/create-fabrication-note-texture-for-layer.ts
32453
- import * as THREE24 from "three";
32238
+ import * as THREE23 from "three";
32454
32239
 
32455
32240
  // src/textures/fabrication-note/fabrication-note-drawing.ts
32456
- import { CircuitToCanvasDrawer as CircuitToCanvasDrawer3 } from "circuit-to-canvas";
32241
+ import { CircuitToCanvasDrawer as CircuitToCanvasDrawer2 } from "circuit-to-canvas";
32457
32242
 
32458
32243
  // src/utils/units.ts
32459
32244
  var MM_PER_INCH = 25.4;
@@ -32551,7 +32336,7 @@ var drawFabricationNoteLayer = ({
32551
32336
  }) => {
32552
32337
  const renderLayer = `${layer}_fabrication_note`;
32553
32338
  const normalizedElements = elements.map(normalizeFabricationElement);
32554
- const drawer = new CircuitToCanvasDrawer3(ctx);
32339
+ const drawer = new CircuitToCanvasDrawer2(ctx);
32555
32340
  drawer.configure({
32556
32341
  colorOverrides: {
32557
32342
  copper: {
@@ -32677,20 +32462,20 @@ function createFabricationNoteTextureForLayer({
32677
32462
  bounds,
32678
32463
  elements
32679
32464
  });
32680
- const texture = new THREE24.CanvasTexture(canvas);
32465
+ const texture = new THREE23.CanvasTexture(canvas);
32681
32466
  texture.generateMipmaps = true;
32682
- texture.minFilter = THREE24.LinearMipmapLinearFilter;
32683
- texture.magFilter = THREE24.LinearFilter;
32467
+ texture.minFilter = THREE23.LinearMipmapLinearFilter;
32468
+ texture.magFilter = THREE23.LinearFilter;
32684
32469
  texture.anisotropy = 16;
32685
32470
  texture.needsUpdate = true;
32686
32471
  return texture;
32687
32472
  }
32688
32473
 
32689
32474
  // src/textures/create-pcb-note-texture-for-layer.ts
32690
- import * as THREE25 from "three";
32475
+ import * as THREE24 from "three";
32691
32476
 
32692
32477
  // src/textures/pcb-note/pcb-note-drawing.ts
32693
- import { CircuitToCanvasDrawer as CircuitToCanvasDrawer4 } from "circuit-to-canvas";
32478
+ import { CircuitToCanvasDrawer as CircuitToCanvasDrawer3 } from "circuit-to-canvas";
32694
32479
  var TRANSPARENT2 = "rgba(0,0,0,0)";
32695
32480
  var setDrawerBounds3 = (drawer, bounds) => {
32696
32481
  drawer.setCameraBounds({
@@ -32769,7 +32554,7 @@ var drawPcbNoteLayer = ({
32769
32554
  elements
32770
32555
  }) => {
32771
32556
  const normalizedElements = elements.map(normalizePcbNoteElement);
32772
- const drawer = new CircuitToCanvasDrawer4(ctx);
32557
+ const drawer = new CircuitToCanvasDrawer3(ctx);
32773
32558
  drawer.configure({
32774
32559
  colorOverrides: {
32775
32560
  copper: {
@@ -32838,20 +32623,20 @@ function createPcbNoteTextureForLayer({
32838
32623
  bounds,
32839
32624
  elements
32840
32625
  });
32841
- const texture = new THREE25.CanvasTexture(canvas);
32626
+ const texture = new THREE24.CanvasTexture(canvas);
32842
32627
  texture.generateMipmaps = true;
32843
- texture.minFilter = THREE25.LinearMipmapLinearFilter;
32844
- texture.magFilter = THREE25.LinearFilter;
32628
+ texture.minFilter = THREE24.LinearMipmapLinearFilter;
32629
+ texture.magFilter = THREE24.LinearFilter;
32845
32630
  texture.anisotropy = 16;
32846
32631
  texture.needsUpdate = true;
32847
32632
  return texture;
32848
32633
  }
32849
32634
 
32850
32635
  // src/textures/create-silkscreen-texture-for-layer.ts
32851
- import * as THREE26 from "three";
32636
+ import * as THREE25 from "three";
32852
32637
 
32853
32638
  // src/textures/silkscreen/silkscreen-drawing.ts
32854
- import { CircuitToCanvasDrawer as CircuitToCanvasDrawer5 } from "circuit-to-canvas";
32639
+ import { CircuitToCanvasDrawer as CircuitToCanvasDrawer4 } from "circuit-to-canvas";
32855
32640
  var FABRICATION_NOTE_COLOR2 = "rgb(255,243,204)";
32856
32641
  var TRANSPARENT3 = "rgba(0,0,0,0)";
32857
32642
  var setDrawerBounds4 = (drawer, bounds) => {
@@ -32870,7 +32655,7 @@ var drawSilkscreenLayer = ({
32870
32655
  silkscreenColor
32871
32656
  }) => {
32872
32657
  const renderLayer = layer === "top" ? "top_silkscreen" : "bottom_silkscreen";
32873
- const drawer = new CircuitToCanvasDrawer5(ctx);
32658
+ const drawer = new CircuitToCanvasDrawer4(ctx);
32874
32659
  drawer.configure({
32875
32660
  colorOverrides: {
32876
32661
  copper: {
@@ -32957,20 +32742,20 @@ function createSilkscreenTextureForLayer({
32957
32742
  elements,
32958
32743
  silkscreenColor
32959
32744
  });
32960
- const texture = new THREE26.CanvasTexture(canvas);
32745
+ const texture = new THREE25.CanvasTexture(canvas);
32961
32746
  texture.generateMipmaps = true;
32962
- texture.minFilter = THREE26.LinearMipmapLinearFilter;
32963
- texture.magFilter = THREE26.LinearFilter;
32747
+ texture.minFilter = THREE25.LinearMipmapLinearFilter;
32748
+ texture.magFilter = THREE25.LinearFilter;
32964
32749
  texture.anisotropy = 16;
32965
32750
  texture.needsUpdate = true;
32966
32751
  return texture;
32967
32752
  }
32968
32753
 
32969
32754
  // src/textures/create-soldermask-texture-for-layer.ts
32970
- import * as THREE27 from "three";
32755
+ import * as THREE26 from "three";
32971
32756
 
32972
32757
  // src/textures/soldermask/soldermask-drawing.ts
32973
- import { CircuitToCanvasDrawer as CircuitToCanvasDrawer6 } from "circuit-to-canvas";
32758
+ import { CircuitToCanvasDrawer as CircuitToCanvasDrawer5 } from "circuit-to-canvas";
32974
32759
  var toRgb = (colorArr) => {
32975
32760
  const [r = 0, g = 0, b = 0] = colorArr;
32976
32761
  return `rgb(${Math.round(r * 255)}, ${Math.round(g * 255)}, ${Math.round(
@@ -33006,7 +32791,7 @@ var drawSoldermaskLayer = ({
33006
32791
  }) => {
33007
32792
  const palette = getSoldermaskPalette(boardMaterial);
33008
32793
  const copperRenderLayer = layer === "top" ? "top_copper" : "bottom_copper";
33009
- const drawer = new CircuitToCanvasDrawer6(ctx);
32794
+ const drawer = new CircuitToCanvasDrawer5(ctx);
33010
32795
  drawer.configure({
33011
32796
  colorOverrides: {
33012
32797
  copper: {
@@ -33050,7 +32835,7 @@ var drawSoldermaskLayer = ({
33050
32835
  if (uncoveredPours.length > 0) {
33051
32836
  ctx.save();
33052
32837
  ctx.globalCompositeOperation = "destination-out";
33053
- const cutoutDrawer = new CircuitToCanvasDrawer6(ctx);
32838
+ const cutoutDrawer = new CircuitToCanvasDrawer5(ctx);
33054
32839
  cutoutDrawer.configure({
33055
32840
  colorOverrides: {
33056
32841
  copper: {
@@ -33099,10 +32884,10 @@ function createSoldermaskTextureForLayer({
33099
32884
  elements,
33100
32885
  boardMaterial: boardData.material
33101
32886
  });
33102
- const texture = new THREE27.CanvasTexture(canvas);
32887
+ const texture = new THREE26.CanvasTexture(canvas);
33103
32888
  texture.generateMipmaps = true;
33104
- texture.minFilter = THREE27.LinearMipmapLinearFilter;
33105
- texture.magFilter = THREE27.LinearFilter;
32889
+ texture.minFilter = THREE26.LinearMipmapLinearFilter;
32890
+ texture.magFilter = THREE26.LinearFilter;
33106
32891
  texture.anisotropy = 16;
33107
32892
  texture.needsUpdate = true;
33108
32893
  return texture;
@@ -33140,10 +32925,10 @@ var createCombinedTexture = ({
33140
32925
  const image = texture.image;
33141
32926
  ctx.drawImage(image, 0, 0, canvasWidth, canvasHeight);
33142
32927
  });
33143
- const combinedTexture = new THREE28.CanvasTexture(canvas);
32928
+ const combinedTexture = new THREE27.CanvasTexture(canvas);
33144
32929
  combinedTexture.generateMipmaps = false;
33145
- combinedTexture.minFilter = THREE28.LinearFilter;
33146
- combinedTexture.magFilter = THREE28.LinearFilter;
32930
+ combinedTexture.minFilter = THREE27.LinearFilter;
32931
+ combinedTexture.magFilter = THREE27.LinearFilter;
33147
32932
  combinedTexture.premultiplyAlpha = true;
33148
32933
  combinedTexture.anisotropy = 16;
33149
32934
  combinedTexture.needsUpdate = true;
@@ -33184,12 +32969,6 @@ function createCombinedBoardTextures({
33184
32969
  copperColor,
33185
32970
  traceTextureResolution
33186
32971
  }) : null;
33187
- const copperPourTexture = showCopper ? createCopperPourTextureForLayer({
33188
- layer,
33189
- circuitJson,
33190
- boardData,
33191
- traceTextureResolution
33192
- }) : null;
33193
32972
  const padTexture = showCopper ? createPadTextureForLayer({
33194
32973
  layer,
33195
32974
  circuitJson,
@@ -33210,7 +32989,8 @@ function createCombinedBoardTextures({
33210
32989
  boardData,
33211
32990
  traceTextureResolution
33212
32991
  }) : null;
33213
- const pcbNoteTexture = showSilkscreen ? createPcbNoteTextureForLayer({
32992
+ const showPcbNotes = visibility?.pcbNotes ?? false;
32993
+ const pcbNoteTexture = showPcbNotes ? createPcbNoteTextureForLayer({
33214
32994
  layer,
33215
32995
  circuitJson,
33216
32996
  boardData,
@@ -33224,7 +33004,6 @@ function createCombinedBoardTextures({
33224
33004
  }) : null;
33225
33005
  return createCombinedTexture({
33226
33006
  textures: [
33227
- copperPourTexture,
33228
33007
  traceTexture,
33229
33008
  padTexture,
33230
33009
  soldermaskTexture,
@@ -33245,6 +33024,14 @@ function createCombinedBoardTextures({
33245
33024
  };
33246
33025
  }
33247
33026
 
33027
+ // src/textures/create-copper-pour-texture-for-layer.ts
33028
+ import * as THREE28 from "three";
33029
+ import { CircuitToCanvasDrawer as CircuitToCanvasDrawer6 } from "circuit-to-canvas";
33030
+
33031
+ // src/geoms/brep-converter.ts
33032
+ var import_primitives7 = __toESM(require_primitives(), 1);
33033
+ var import_booleans5 = __toESM(require_booleans(), 1);
33034
+
33248
33035
  // src/textures/create-three-texture-meshes.ts
33249
33036
  import * as THREE29 from "three";
33250
33037
  function createTexturePlane(config, boardData) {
@@ -36846,10 +36633,6 @@ var oppositeSideMap = {
36846
36633
  bottom: "top",
36847
36634
  top: "bottom"
36848
36635
  };
36849
- var oppositeAlignmentMap = {
36850
- start: "end",
36851
- end: "start"
36852
- };
36853
36636
  function clamp2(start, value, end) {
36854
36637
  return max(start, min(value, end));
36855
36638
  }
@@ -36868,9 +36651,9 @@ function getOppositeAxis(axis) {
36868
36651
  function getAxisLength(axis) {
36869
36652
  return axis === "y" ? "height" : "width";
36870
36653
  }
36871
- var yAxisSides = /* @__PURE__ */ new Set(["top", "bottom"]);
36872
36654
  function getSideAxis(placement) {
36873
- return yAxisSides.has(getSide(placement)) ? "y" : "x";
36655
+ const firstChar = placement[0];
36656
+ return firstChar === "t" || firstChar === "b" ? "y" : "x";
36874
36657
  }
36875
36658
  function getAlignmentAxis(placement) {
36876
36659
  return getOppositeAxis(getSideAxis(placement));
@@ -36893,7 +36676,7 @@ function getExpandedPlacements(placement) {
36893
36676
  return [getOppositeAlignmentPlacement(placement), oppositePlacement, getOppositeAlignmentPlacement(oppositePlacement)];
36894
36677
  }
36895
36678
  function getOppositeAlignmentPlacement(placement) {
36896
- return placement.replace(/start|end/g, (alignment) => oppositeAlignmentMap[alignment]);
36679
+ return placement.includes("start") ? placement.replace("start", "end") : placement.replace("end", "start");
36897
36680
  }
36898
36681
  var lrPlacement = ["left", "right"];
36899
36682
  var rlPlacement = ["right", "left"];
@@ -36924,7 +36707,8 @@ function getOppositeAxisPlacements(placement, flipAlignment, direction, rtl) {
36924
36707
  return list;
36925
36708
  }
36926
36709
  function getOppositePlacement(placement) {
36927
- return placement.replace(/left|right|bottom|top/g, (side) => oppositeSideMap[side]);
36710
+ const side = getSide(placement);
36711
+ return oppositeSideMap[side] + placement.slice(side.length);
36928
36712
  }
36929
36713
  function expandPaddingObject(padding) {
36930
36714
  return {
@@ -37074,6 +36858,7 @@ async function detectOverflow(state, options) {
37074
36858
  right: (elementClientRect.right - clippingClientRect.right + paddingObject.right) / offsetScale.x
37075
36859
  };
37076
36860
  }
36861
+ var MAX_RESET_COUNT = 50;
37077
36862
  var computePosition = async (reference, floating, config) => {
37078
36863
  const {
37079
36864
  placement = "bottom",
@@ -37081,7 +36866,10 @@ var computePosition = async (reference, floating, config) => {
37081
36866
  middleware = [],
37082
36867
  platform: platform2
37083
36868
  } = config;
37084
- const validMiddleware = middleware.filter(Boolean);
36869
+ const platformWithDetectOverflow = platform2.detectOverflow ? platform2 : {
36870
+ ...platform2,
36871
+ detectOverflow
36872
+ };
37085
36873
  const rtl = await (platform2.isRTL == null ? void 0 : platform2.isRTL(floating));
37086
36874
  let rects = await platform2.getElementRects({
37087
36875
  reference,
@@ -37093,14 +36881,17 @@ var computePosition = async (reference, floating, config) => {
37093
36881
  y
37094
36882
  } = computeCoordsFromPlacement(rects, placement, rtl);
37095
36883
  let statefulPlacement = placement;
37096
- let middlewareData = {};
37097
36884
  let resetCount = 0;
37098
- for (let i = 0; i < validMiddleware.length; i++) {
37099
- var _platform$detectOverf;
36885
+ const middlewareData = {};
36886
+ for (let i = 0; i < middleware.length; i++) {
36887
+ const currentMiddleware = middleware[i];
36888
+ if (!currentMiddleware) {
36889
+ continue;
36890
+ }
37100
36891
  const {
37101
36892
  name,
37102
36893
  fn
37103
- } = validMiddleware[i];
36894
+ } = currentMiddleware;
37104
36895
  const {
37105
36896
  x: nextX,
37106
36897
  y: nextY,
@@ -37114,10 +36905,7 @@ var computePosition = async (reference, floating, config) => {
37114
36905
  strategy,
37115
36906
  middlewareData,
37116
36907
  rects,
37117
- platform: {
37118
- ...platform2,
37119
- detectOverflow: (_platform$detectOverf = platform2.detectOverflow) != null ? _platform$detectOverf : detectOverflow
37120
- },
36908
+ platform: platformWithDetectOverflow,
37121
36909
  elements: {
37122
36910
  reference,
37123
36911
  floating
@@ -37125,14 +36913,11 @@ var computePosition = async (reference, floating, config) => {
37125
36913
  });
37126
36914
  x = nextX != null ? nextX : x;
37127
36915
  y = nextY != null ? nextY : y;
37128
- middlewareData = {
37129
- ...middlewareData,
37130
- [name]: {
37131
- ...middlewareData[name],
37132
- ...data
37133
- }
36916
+ middlewareData[name] = {
36917
+ ...middlewareData[name],
36918
+ ...data
37134
36919
  };
37135
- if (reset && resetCount <= 50) {
36920
+ if (reset && resetCount < MAX_RESET_COUNT) {
37136
36921
  resetCount++;
37137
36922
  if (typeof reset === "object") {
37138
36923
  if (reset.placement) {
@@ -37720,7 +37505,6 @@ function isShadowRoot(value) {
37720
37505
  }
37721
37506
  return value instanceof ShadowRoot || value instanceof getWindow(value).ShadowRoot;
37722
37507
  }
37723
- var invalidOverflowDisplayValues = /* @__PURE__ */ new Set(["inline", "contents"]);
37724
37508
  function isOverflowElement(element) {
37725
37509
  const {
37726
37510
  overflow,
@@ -37728,29 +37512,31 @@ function isOverflowElement(element) {
37728
37512
  overflowY,
37729
37513
  display
37730
37514
  } = getComputedStyle2(element);
37731
- return /auto|scroll|overlay|hidden|clip/.test(overflow + overflowY + overflowX) && !invalidOverflowDisplayValues.has(display);
37515
+ return /auto|scroll|overlay|hidden|clip/.test(overflow + overflowY + overflowX) && display !== "inline" && display !== "contents";
37732
37516
  }
37733
- var tableElements = /* @__PURE__ */ new Set(["table", "td", "th"]);
37734
37517
  function isTableElement(element) {
37735
- return tableElements.has(getNodeName(element));
37518
+ return /^(table|td|th)$/.test(getNodeName(element));
37736
37519
  }
37737
- var topLayerSelectors = [":popover-open", ":modal"];
37738
37520
  function isTopLayer(element) {
37739
- return topLayerSelectors.some((selector) => {
37740
- try {
37741
- return element.matches(selector);
37742
- } catch (_e) {
37743
- return false;
37521
+ try {
37522
+ if (element.matches(":popover-open")) {
37523
+ return true;
37744
37524
  }
37745
- });
37525
+ } catch (_e) {
37526
+ }
37527
+ try {
37528
+ return element.matches(":modal");
37529
+ } catch (_e) {
37530
+ return false;
37531
+ }
37746
37532
  }
37747
- var transformProperties = ["transform", "translate", "scale", "rotate", "perspective"];
37748
- var willChangeValues = ["transform", "translate", "scale", "rotate", "perspective", "filter"];
37749
- var containValues = ["paint", "layout", "strict", "content"];
37533
+ var willChangeRe = /transform|translate|scale|rotate|perspective|filter/;
37534
+ var containRe = /paint|layout|strict|content/;
37535
+ var isNotNone = (value) => !!value && value !== "none";
37536
+ var isWebKitValue;
37750
37537
  function isContainingBlock(elementOrCss) {
37751
- const webkit = isWebKit();
37752
37538
  const css = isElement(elementOrCss) ? getComputedStyle2(elementOrCss) : elementOrCss;
37753
- return transformProperties.some((value) => css[value] ? css[value] !== "none" : false) || (css.containerType ? css.containerType !== "normal" : false) || !webkit && (css.backdropFilter ? css.backdropFilter !== "none" : false) || !webkit && (css.filter ? css.filter !== "none" : false) || willChangeValues.some((value) => (css.willChange || "").includes(value)) || containValues.some((value) => (css.contain || "").includes(value));
37539
+ return isNotNone(css.transform) || isNotNone(css.translate) || isNotNone(css.scale) || isNotNone(css.rotate) || isNotNone(css.perspective) || !isWebKit() && (isNotNone(css.backdropFilter) || isNotNone(css.filter)) || willChangeRe.test(css.willChange || "") || containRe.test(css.contain || "");
37754
37540
  }
37755
37541
  function getContainingBlock(element) {
37756
37542
  let currentNode = getParentNode(element);
@@ -37765,12 +37551,13 @@ function getContainingBlock(element) {
37765
37551
  return null;
37766
37552
  }
37767
37553
  function isWebKit() {
37768
- if (typeof CSS === "undefined" || !CSS.supports) return false;
37769
- return CSS.supports("-webkit-backdrop-filter", "none");
37554
+ if (isWebKitValue == null) {
37555
+ isWebKitValue = typeof CSS !== "undefined" && CSS.supports && CSS.supports("-webkit-backdrop-filter", "none");
37556
+ }
37557
+ return isWebKitValue;
37770
37558
  }
37771
- var lastTraversableNodeNames = /* @__PURE__ */ new Set(["html", "body", "#document"]);
37772
37559
  function isLastTraversableNode(node) {
37773
- return lastTraversableNodeNames.has(getNodeName(node));
37560
+ return /^(html|body|#document)$/.test(getNodeName(node));
37774
37561
  }
37775
37562
  function getComputedStyle2(element) {
37776
37563
  return getWindow(element).getComputedStyle(element);
@@ -37824,8 +37611,9 @@ function getOverflowAncestors(node, list, traverseIframes) {
37824
37611
  if (isBody) {
37825
37612
  const frameElement = getFrameElement(win);
37826
37613
  return list.concat(win, win.visualViewport || [], isOverflowElement(scrollableAncestor) ? scrollableAncestor : [], frameElement && traverseIframes ? getOverflowAncestors(frameElement) : []);
37614
+ } else {
37615
+ return list.concat(scrollableAncestor, getOverflowAncestors(scrollableAncestor, [], traverseIframes));
37827
37616
  }
37828
- return list.concat(scrollableAncestor, getOverflowAncestors(scrollableAncestor, [], traverseIframes));
37829
37617
  }
37830
37618
  function getFrameElement(win) {
37831
37619
  return win.parent && Object.getPrototypeOf(win.parent) ? win.frameElement : null;
@@ -37989,7 +37777,7 @@ function convertOffsetParentRelativeRectToViewportRelativeRect(_ref) {
37989
37777
  if (getNodeName(offsetParent) !== "body" || isOverflowElement(documentElement)) {
37990
37778
  scroll = getNodeScroll(offsetParent);
37991
37779
  }
37992
- if (isHTMLElement(offsetParent)) {
37780
+ if (isOffsetParentAnElement) {
37993
37781
  const offsetRect = getBoundingClientRect(offsetParent);
37994
37782
  scale2 = getScale(offsetParent);
37995
37783
  offsets.x = offsetRect.x + offsetParent.clientLeft;
@@ -38063,7 +37851,6 @@ function getViewportRect(element, strategy) {
38063
37851
  y
38064
37852
  };
38065
37853
  }
38066
- var absoluteOrFixed = /* @__PURE__ */ new Set(["absolute", "fixed"]);
38067
37854
  function getInnerBoundingClientRect(element, strategy) {
38068
37855
  const clientRect = getBoundingClientRect(element, true, strategy === "fixed");
38069
37856
  const top = clientRect.top + element.clientTop;
@@ -38121,7 +37908,7 @@ function getClippingElementAncestors(element, cache) {
38121
37908
  if (!currentNodeIsContaining && computedStyle.position === "fixed") {
38122
37909
  currentContainingBlockComputedStyle = null;
38123
37910
  }
38124
- const shouldDropCurrentNode = elementIsFixed ? !currentNodeIsContaining && !currentContainingBlockComputedStyle : !currentNodeIsContaining && computedStyle.position === "static" && !!currentContainingBlockComputedStyle && absoluteOrFixed.has(currentContainingBlockComputedStyle.position) || isOverflowElement(currentNode) && !currentNodeIsContaining && hasFixedPositionAncestor(element, currentNode);
37911
+ const shouldDropCurrentNode = elementIsFixed ? !currentNodeIsContaining && !currentContainingBlockComputedStyle : !currentNodeIsContaining && computedStyle.position === "static" && !!currentContainingBlockComputedStyle && (currentContainingBlockComputedStyle.position === "absolute" || currentContainingBlockComputedStyle.position === "fixed") || isOverflowElement(currentNode) && !currentNodeIsContaining && hasFixedPositionAncestor(element, currentNode);
38125
37912
  if (shouldDropCurrentNode) {
38126
37913
  result = result.filter((ancestor) => ancestor !== currentNode);
38127
37914
  } else {
@@ -38141,20 +37928,23 @@ function getClippingRect(_ref) {
38141
37928
  } = _ref;
38142
37929
  const elementClippingAncestors = boundary === "clippingAncestors" ? isTopLayer(element) ? [] : getClippingElementAncestors(element, this._c) : [].concat(boundary);
38143
37930
  const clippingAncestors = [...elementClippingAncestors, rootBoundary];
38144
- const firstClippingAncestor = clippingAncestors[0];
38145
- const clippingRect = clippingAncestors.reduce((accRect, clippingAncestor) => {
38146
- const rect = getClientRectFromClippingAncestor(element, clippingAncestor, strategy);
38147
- accRect.top = max(rect.top, accRect.top);
38148
- accRect.right = min(rect.right, accRect.right);
38149
- accRect.bottom = min(rect.bottom, accRect.bottom);
38150
- accRect.left = max(rect.left, accRect.left);
38151
- return accRect;
38152
- }, getClientRectFromClippingAncestor(element, firstClippingAncestor, strategy));
37931
+ const firstRect = getClientRectFromClippingAncestor(element, clippingAncestors[0], strategy);
37932
+ let top = firstRect.top;
37933
+ let right = firstRect.right;
37934
+ let bottom = firstRect.bottom;
37935
+ let left = firstRect.left;
37936
+ for (let i = 1; i < clippingAncestors.length; i++) {
37937
+ const rect = getClientRectFromClippingAncestor(element, clippingAncestors[i], strategy);
37938
+ top = max(rect.top, top);
37939
+ right = min(rect.right, right);
37940
+ bottom = min(rect.bottom, bottom);
37941
+ left = max(rect.left, left);
37942
+ }
38153
37943
  return {
38154
- width: clippingRect.right - clippingRect.left,
38155
- height: clippingRect.bottom - clippingRect.top,
38156
- x: clippingRect.left,
38157
- y: clippingRect.top
37944
+ width: right - left,
37945
+ height: bottom - top,
37946
+ x: left,
37947
+ y: top
38158
37948
  };
38159
37949
  }
38160
37950
  function getDimensions(element) {
@@ -38363,7 +38153,7 @@ function autoUpdate(reference, floating, update, options) {
38363
38153
  animationFrame = false
38364
38154
  } = options;
38365
38155
  const referenceEl = unwrapElement(reference);
38366
- const ancestors = ancestorScroll || ancestorResize ? [...referenceEl ? getOverflowAncestors(referenceEl) : [], ...getOverflowAncestors(floating)] : [];
38156
+ const ancestors = ancestorScroll || ancestorResize ? [...referenceEl ? getOverflowAncestors(referenceEl) : [], ...floating ? getOverflowAncestors(floating) : []] : [];
38367
38157
  ancestors.forEach((ancestor) => {
38368
38158
  ancestorScroll && ancestor.addEventListener("scroll", update, {
38369
38159
  passive: true
@@ -38376,7 +38166,7 @@ function autoUpdate(reference, floating, update, options) {
38376
38166
  if (elementResize) {
38377
38167
  resizeObserver = new ResizeObserver((_ref) => {
38378
38168
  let [firstEntry] = _ref;
38379
- if (firstEntry && firstEntry.target === referenceEl && resizeObserver) {
38169
+ if (firstEntry && firstEntry.target === referenceEl && resizeObserver && floating) {
38380
38170
  resizeObserver.unobserve(floating);
38381
38171
  cancelAnimationFrame(reobserveFrame);
38382
38172
  reobserveFrame = requestAnimationFrame(() => {
@@ -38389,7 +38179,9 @@ function autoUpdate(reference, floating, update, options) {
38389
38179
  if (referenceEl && !animationFrame) {
38390
38180
  resizeObserver.observe(referenceEl);
38391
38181
  }
38392
- resizeObserver.observe(floating);
38182
+ if (floating) {
38183
+ resizeObserver.observe(floating);
38184
+ }
38393
38185
  }
38394
38186
  let frameId;
38395
38187
  let prevRefRect = animationFrame ? getBoundingClientRect(reference) : null;
@@ -38697,34 +38489,61 @@ var arrow$1 = (options) => {
38697
38489
  }
38698
38490
  };
38699
38491
  };
38700
- var offset3 = (options, deps) => ({
38701
- ...offset2(options),
38702
- options: [options, deps]
38703
- });
38704
- var shift3 = (options, deps) => ({
38705
- ...shift2(options),
38706
- options: [options, deps]
38707
- });
38708
- var limitShift3 = (options, deps) => ({
38709
- ...limitShift2(options),
38710
- options: [options, deps]
38711
- });
38712
- var flip3 = (options, deps) => ({
38713
- ...flip2(options),
38714
- options: [options, deps]
38715
- });
38716
- var size3 = (options, deps) => ({
38717
- ...size2(options),
38718
- options: [options, deps]
38719
- });
38720
- var hide3 = (options, deps) => ({
38721
- ...hide2(options),
38722
- options: [options, deps]
38723
- });
38724
- var arrow3 = (options, deps) => ({
38725
- ...arrow$1(options),
38726
- options: [options, deps]
38727
- });
38492
+ var offset3 = (options, deps) => {
38493
+ const result = offset2(options);
38494
+ return {
38495
+ name: result.name,
38496
+ fn: result.fn,
38497
+ options: [options, deps]
38498
+ };
38499
+ };
38500
+ var shift3 = (options, deps) => {
38501
+ const result = shift2(options);
38502
+ return {
38503
+ name: result.name,
38504
+ fn: result.fn,
38505
+ options: [options, deps]
38506
+ };
38507
+ };
38508
+ var limitShift3 = (options, deps) => {
38509
+ const result = limitShift2(options);
38510
+ return {
38511
+ fn: result.fn,
38512
+ options: [options, deps]
38513
+ };
38514
+ };
38515
+ var flip3 = (options, deps) => {
38516
+ const result = flip2(options);
38517
+ return {
38518
+ name: result.name,
38519
+ fn: result.fn,
38520
+ options: [options, deps]
38521
+ };
38522
+ };
38523
+ var size3 = (options, deps) => {
38524
+ const result = size2(options);
38525
+ return {
38526
+ name: result.name,
38527
+ fn: result.fn,
38528
+ options: [options, deps]
38529
+ };
38530
+ };
38531
+ var hide3 = (options, deps) => {
38532
+ const result = hide2(options);
38533
+ return {
38534
+ name: result.name,
38535
+ fn: result.fn,
38536
+ options: [options, deps]
38537
+ };
38538
+ };
38539
+ var arrow3 = (options, deps) => {
38540
+ const result = arrow$1(options);
38541
+ return {
38542
+ name: result.name,
38543
+ fn: result.fn,
38544
+ options: [options, deps]
38545
+ };
38546
+ };
38728
38547
 
38729
38548
  // node_modules/@radix-ui/react-arrow/dist/index.mjs
38730
38549
  import * as React29 from "react";
@@ -41614,6 +41433,27 @@ var AppearanceMenu = () => {
41614
41433
  ]
41615
41434
  }
41616
41435
  ),
41436
+ /* @__PURE__ */ jsxs8(
41437
+ Item22,
41438
+ {
41439
+ style: {
41440
+ ...itemStyles,
41441
+ backgroundColor: hoveredItem === "pcbNotes" ? "#404040" : "transparent"
41442
+ },
41443
+ onSelect: (e) => e.preventDefault(),
41444
+ onPointerDown: (e) => {
41445
+ e.preventDefault();
41446
+ setLayerVisibility("pcbNotes", !visibility.pcbNotes);
41447
+ },
41448
+ onMouseEnter: () => setHoveredItem("pcbNotes"),
41449
+ onMouseLeave: () => setHoveredItem(null),
41450
+ onTouchStart: () => setHoveredItem("pcbNotes"),
41451
+ children: [
41452
+ /* @__PURE__ */ jsx35("span", { style: iconContainerStyles, children: visibility.pcbNotes && /* @__PURE__ */ jsx35(CheckIcon, {}) }),
41453
+ /* @__PURE__ */ jsx35("span", { style: { display: "flex", alignItems: "center" }, children: "PCB Notes" })
41454
+ ]
41455
+ }
41456
+ ),
41617
41457
  /* @__PURE__ */ jsxs8(
41618
41458
  Item22,
41619
41459
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tscircuit/3d-viewer",
3
- "version": "0.0.525",
3
+ "version": "0.0.527",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.js",
6
6
  "type": "module",
@@ -30,7 +30,7 @@
30
30
  "@jscad/regl-renderer": "^2.6.12",
31
31
  "@jscad/stl-serializer": "^2.1.20",
32
32
  "circuit-json": "^0.0.372",
33
- "circuit-to-canvas": "^0.0.81",
33
+ "circuit-to-canvas": "^0.0.87",
34
34
  "react-hot-toast": "^2.6.0",
35
35
  "three": "^0.165.0",
36
36
  "three-stdlib": "^2.36.0",