@tscircuit/3d-viewer 0.0.637 → 0.0.639

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -19214,11 +19214,16 @@ function resolveFoldPcbs(circuitJson, foldPcbs) {
19214
19214
  );
19215
19215
  }
19216
19216
 
19217
- // src/utils/pick-cad-component.ts
19218
- var pickCadComponent = (scene, position, circuitJson) => {
19217
+ // src/utils/pick-scene-object.ts
19218
+ var getBoardName = (id, circuitJson) => circuitJson.some((e) => e.type === "pcb_panel" && e.pcb_panel_id === id) ? "Panel" : "Board";
19219
+ var pickSceneObject = (scene, position, circuitJson) => {
19219
19220
  let object = pickVisibleMesh(scene, position) ?? null;
19220
19221
  while (object) {
19221
- const cadComponentId = object.userData.cad_component_id;
19222
+ const {
19223
+ cad_component_id: cadComponentId,
19224
+ pcb_board_id: pcbBoardId,
19225
+ cad_cable_id: cadCableId
19226
+ } = object.userData;
19222
19227
  if (cadComponentId) {
19223
19228
  const cad = circuitJson.find(
19224
19229
  (e) => e.type === "cad_component" && e.cad_component_id === cadComponentId
@@ -19227,8 +19232,8 @@ var pickCadComponent = (scene, position, circuitJson) => {
19227
19232
  const metadata = getGlbComponentMetadata(object);
19228
19233
  if (metadata && metadata.cad_component_id === cadComponentId)
19229
19234
  return {
19230
- cad_component_id: cadComponentId,
19231
- componentName: metadata.componentName ?? cadComponentId
19235
+ objectId: cadComponentId,
19236
+ name: metadata.componentName ?? cadComponentId
19232
19237
  };
19233
19238
  return;
19234
19239
  }
@@ -19236,39 +19241,64 @@ var pickCadComponent = (scene, position, circuitJson) => {
19236
19241
  (e) => e.type === "source_component" && e.source_component_id === cad.source_component_id
19237
19242
  );
19238
19243
  return {
19239
- cad_component_id: cad.cad_component_id,
19240
- componentName: source?.type === "source_component" ? source.name : cad.cad_component_id
19244
+ objectId: cad.cad_component_id,
19245
+ name: source?.type === "source_component" ? source.name : cad.cad_component_id
19241
19246
  };
19242
19247
  }
19248
+ if (pcbBoardId)
19249
+ return {
19250
+ objectId: pcbBoardId,
19251
+ name: getBoardName(pcbBoardId, circuitJson)
19252
+ };
19253
+ if (cadCableId)
19254
+ return { objectId: cadCableId, name: object.userData.name ?? cadCableId };
19243
19255
  object = object.parent;
19244
19256
  }
19245
19257
  };
19246
19258
 
19247
- // src/hooks/useHiddenCadComponents.ts
19259
+ // src/hooks/useObjectVisibility.ts
19248
19260
  import { useState as useState2 } from "react";
19249
- var NO_HIDDEN_COMPONENTS = /* @__PURE__ */ new Set();
19250
- var useHiddenCadComponents = (circuitKey) => {
19261
+
19262
+ // src/utils/object-visibility.ts
19263
+ var ALL_OBJECTS_VISIBLE = { hiddenIds: /* @__PURE__ */ new Set() };
19264
+ var isObjectHidden = (visibility, id) => {
19265
+ if (!visibility) return false;
19266
+ if (id !== void 0 && visibility.hiddenIds.has(id)) return true;
19267
+ return visibility.isolatedId !== void 0 && visibility.isolatedId !== id;
19268
+ };
19269
+ var hasHiddenObjects = (visibility) => visibility.hiddenIds.size > 0 || visibility.isolatedId !== void 0;
19270
+
19271
+ // src/hooks/useObjectVisibility.ts
19272
+ var useObjectVisibility = (circuitKey) => {
19251
19273
  const [state, setState] = useState2({
19252
19274
  circuitKey,
19253
- ids: NO_HIDDEN_COMPONENTS
19275
+ visibility: ALL_OBJECTS_VISIBLE
19254
19276
  });
19255
- const hiddenCadComponentIds = state.circuitKey === circuitKey ? state.ids : NO_HIDDEN_COMPONENTS;
19277
+ const objectVisibility = state.circuitKey === circuitKey ? state.visibility : ALL_OBJECTS_VISIBLE;
19256
19278
  if (state.circuitKey !== circuitKey) {
19257
- setState({ circuitKey, ids: NO_HIDDEN_COMPONENTS });
19279
+ setState({ circuitKey, visibility: ALL_OBJECTS_VISIBLE });
19258
19280
  }
19281
+ const update = (next) => {
19282
+ setState((current) => ({
19283
+ circuitKey,
19284
+ visibility: next(
19285
+ current.circuitKey === circuitKey ? current.visibility : ALL_OBJECTS_VISIBLE
19286
+ )
19287
+ }));
19288
+ };
19259
19289
  return {
19260
- hiddenCadComponentIds,
19261
- hideComponent: (id) => {
19262
- setState((current) => ({
19263
- circuitKey,
19264
- ids: /* @__PURE__ */ new Set([
19265
- ...current.circuitKey === circuitKey ? current.ids : [],
19266
- id
19267
- ])
19290
+ objectVisibility,
19291
+ hideObject: (id) => {
19292
+ update((current) => ({
19293
+ ...current,
19294
+ hiddenIds: /* @__PURE__ */ new Set([...current.hiddenIds, id])
19268
19295
  }));
19269
19296
  },
19270
- unhideAllComponents: () => {
19271
- setState({ circuitKey, ids: NO_HIDDEN_COMPONENTS });
19297
+ isolateObject: (id) => {
19298
+ update((current) => ({ ...current, isolatedId: id }));
19299
+ },
19300
+ unhideAllObjects: () => {
19301
+ update(() => ALL_OBJECTS_VISIBLE);
19272
19302
  }
19273
19303
  };
19274
19304
  };
@@ -19309,8 +19339,8 @@ function configureRuntimeFont() {
19309
19339
  }
19310
19340
 
19311
19341
  // src/CadViewer.tsx
19312
- import { useCallback as useCallback25, useContext as useContext13, useEffect as useEffect56, useRef as useRef30, useState as useState46 } from "react";
19313
- import * as THREE63 from "three";
19342
+ import { useCallback as useCallback25, useContext as useContext13, useEffect as useEffect57, useRef as useRef30, useState as useState46 } from "react";
19343
+ import * as THREE64 from "three";
19314
19344
 
19315
19345
  // src/assembly-explosion/use-assembly-explosion.ts
19316
19346
  import {
@@ -19564,7 +19594,7 @@ function AssemblyExplosionControl({
19564
19594
 
19565
19595
  // src/CadViewerJscad.tsx
19566
19596
  import { su as su12 } from "@tscircuit/circuit-json-util";
19567
- import { forwardRef as forwardRef3, useMemo as useMemo26 } from "react";
19597
+ import { forwardRef as forwardRef3, useMemo as useMemo27 } from "react";
19568
19598
 
19569
19599
  // src/utils/get-cad-pcb-context.ts
19570
19600
  var getCadPcbContext = (cad, circuitJson) => {
@@ -21621,13 +21651,14 @@ var CameraControllerProvider = ({ children, defaultTarget, initialCameraPosition
21621
21651
  }, [initialCameraPosition, defaultTarget]);
21622
21652
  const getPresetConfig = useCallback4(
21623
21653
  (preset) => {
21624
- const targetVector = [
21625
- defaultTarget.x,
21626
- defaultTarget.y,
21627
- defaultTarget.z
21628
- ];
21629
21654
  const camera = mainCameraRef.current;
21630
21655
  const controls = controlsRef.current;
21656
+ const presetTarget = controls?.target ?? defaultTarget;
21657
+ const targetVector = [
21658
+ presetTarget.x,
21659
+ presetTarget.y,
21660
+ presetTarget.z
21661
+ ];
21631
21662
  let distance5 = baseDistance;
21632
21663
  if (camera && controls) {
21633
21664
  distance5 = camera.position.distanceTo(controls.target);
@@ -21637,9 +21668,9 @@ var CameraControllerProvider = ({ children, defaultTarget, initialCameraPosition
21637
21668
  const angledOffset = distance5 / Math.sqrt(2);
21638
21669
  return {
21639
21670
  position: [
21640
- defaultTarget.x,
21641
- defaultTarget.y - angledOffset,
21642
- defaultTarget.z + angledOffset
21671
+ presetTarget.x,
21672
+ presetTarget.y - angledOffset,
21673
+ presetTarget.z + angledOffset
21643
21674
  ],
21644
21675
  target: targetVector,
21645
21676
  up: [0, 0, 1]
@@ -21648,9 +21679,9 @@ var CameraControllerProvider = ({ children, defaultTarget, initialCameraPosition
21648
21679
  case "Top Down":
21649
21680
  return {
21650
21681
  position: [
21651
- defaultTarget.x,
21652
- defaultTarget.y,
21653
- defaultTarget.z + distance5
21682
+ presetTarget.x,
21683
+ presetTarget.y,
21684
+ presetTarget.z + distance5
21654
21685
  ],
21655
21686
  target: targetVector,
21656
21687
  up: [0, 0, 1]
@@ -21658,9 +21689,9 @@ var CameraControllerProvider = ({ children, defaultTarget, initialCameraPosition
21658
21689
  case "Top Left Corner":
21659
21690
  return {
21660
21691
  position: [
21661
- defaultTarget.x - distance5 * 0.6,
21662
- defaultTarget.y - distance5 * 0.6,
21663
- defaultTarget.z + distance5 * 0.6
21692
+ presetTarget.x - distance5 * 0.6,
21693
+ presetTarget.y - distance5 * 0.6,
21694
+ presetTarget.z + distance5 * 0.6
21664
21695
  ],
21665
21696
  target: targetVector,
21666
21697
  up: [0, 0, 1]
@@ -21668,9 +21699,9 @@ var CameraControllerProvider = ({ children, defaultTarget, initialCameraPosition
21668
21699
  case "Top Right Corner":
21669
21700
  return {
21670
21701
  position: [
21671
- defaultTarget.x + distance5 * 0.6,
21672
- defaultTarget.y - distance5 * 0.6,
21673
- defaultTarget.z + distance5 * 0.6
21702
+ presetTarget.x + distance5 * 0.6,
21703
+ presetTarget.y - distance5 * 0.6,
21704
+ presetTarget.z + distance5 * 0.6
21674
21705
  ],
21675
21706
  target: targetVector,
21676
21707
  up: [0, 0, 1]
@@ -21678,9 +21709,9 @@ var CameraControllerProvider = ({ children, defaultTarget, initialCameraPosition
21678
21709
  case "Left Sideview":
21679
21710
  return {
21680
21711
  position: [
21681
- defaultTarget.x - distance5,
21682
- defaultTarget.y,
21683
- defaultTarget.z
21712
+ presetTarget.x - distance5,
21713
+ presetTarget.y,
21714
+ presetTarget.z
21684
21715
  ],
21685
21716
  target: targetVector,
21686
21717
  up: [0, 0, 1]
@@ -21688,9 +21719,9 @@ var CameraControllerProvider = ({ children, defaultTarget, initialCameraPosition
21688
21719
  case "Right Sideview":
21689
21720
  return {
21690
21721
  position: [
21691
- defaultTarget.x + distance5,
21692
- defaultTarget.y,
21693
- defaultTarget.z
21722
+ presetTarget.x + distance5,
21723
+ presetTarget.y,
21724
+ presetTarget.z
21694
21725
  ],
21695
21726
  target: targetVector,
21696
21727
  up: [0, 0, 1]
@@ -21698,9 +21729,9 @@ var CameraControllerProvider = ({ children, defaultTarget, initialCameraPosition
21698
21729
  case "Front":
21699
21730
  return {
21700
21731
  position: [
21701
- defaultTarget.x,
21702
- defaultTarget.y - distance5,
21703
- defaultTarget.z
21732
+ presetTarget.x,
21733
+ presetTarget.y - distance5,
21734
+ presetTarget.z
21704
21735
  ],
21705
21736
  target: targetVector,
21706
21737
  up: [0, 0, 1]
@@ -22302,7 +22333,7 @@ import * as THREE31 from "three";
22302
22333
  // package.json
22303
22334
  var package_default = {
22304
22335
  name: "@tscircuit/3d-viewer",
22305
- version: "0.0.636",
22336
+ version: "0.0.638",
22306
22337
  repository: {
22307
22338
  type: "git",
22308
22339
  url: "https://github.com/tscircuit/3d-viewer"
@@ -25774,9 +25805,36 @@ var ErrorBox = ({ parent }) => {
25774
25805
  return null;
25775
25806
  };
25776
25807
 
25808
+ // src/three-components/BoardGroup.tsx
25809
+ import { useEffect as useEffect30, useMemo as useMemo22 } from "react";
25810
+ import * as THREE35 from "three";
25811
+ import { jsx as jsx20 } from "react/jsx-runtime";
25812
+ var BoardGroup = ({
25813
+ pcbBoardId,
25814
+ hidden = false,
25815
+ children
25816
+ }) => {
25817
+ const scene = useThree();
25818
+ const group = useMemo22(() => new THREE35.Group(), []);
25819
+ group.name = "board";
25820
+ group.userData.pcb_board_id = pcbBoardId;
25821
+ group.visible = !hidden;
25822
+ useEffect30(() => {
25823
+ scene.rootObject.add(group);
25824
+ return () => {
25825
+ scene.rootObject.remove(group);
25826
+ };
25827
+ }, [scene.rootObject, group]);
25828
+ const context = useMemo22(
25829
+ () => ({ ...scene, rootObject: group }),
25830
+ [scene, group]
25831
+ );
25832
+ return /* @__PURE__ */ jsx20(ThreeContext.Provider, { value: context, children });
25833
+ };
25834
+
25777
25835
  // src/three-components/JscadBoardTextures.tsx
25778
25836
  import { su as su9 } from "@tscircuit/circuit-json-util";
25779
- import { useEffect as useEffect30, useMemo as useMemo23 } from "react";
25837
+ import { useEffect as useEffect31, useMemo as useMemo24 } from "react";
25780
25838
 
25781
25839
  // src/textures/open-via-holes-at-pads.ts
25782
25840
  import { CircuitToCanvasDrawer } from "circuit-to-canvas";
@@ -25932,12 +25990,12 @@ function clearViaHolesFromSurface({
25932
25990
 
25933
25991
  // src/textures/create-combined-board-textures.ts
25934
25992
  import { CircuitToCanvasDrawer as CircuitToCanvasDrawer12 } from "circuit-to-canvas";
25935
- import * as THREE47 from "three";
25993
+ import * as THREE48 from "three";
25936
25994
 
25937
25995
  // src/utils/pad-texture.ts
25938
25996
  import { su as su6 } from "@tscircuit/circuit-json-util";
25939
25997
  import { CircuitToCanvasDrawer as CircuitToCanvasDrawer2 } from "circuit-to-canvas";
25940
- import * as THREE35 from "three";
25998
+ import * as THREE36 from "three";
25941
25999
  function createPadTextureForLayer({
25942
26000
  layer,
25943
26001
  circuitJson,
@@ -26017,10 +26075,10 @@ function createPadTextureForLayer({
26017
26075
  drawSoldermaskTop: false,
26018
26076
  drawSoldermaskBottom: false
26019
26077
  });
26020
- const texture = new THREE35.CanvasTexture(canvas);
26078
+ const texture = new THREE36.CanvasTexture(canvas);
26021
26079
  texture.generateMipmaps = true;
26022
- texture.minFilter = THREE35.LinearMipmapLinearFilter;
26023
- texture.magFilter = THREE35.LinearFilter;
26080
+ texture.minFilter = THREE36.LinearMipmapLinearFilter;
26081
+ texture.magFilter = THREE36.LinearFilter;
26024
26082
  texture.anisotropy = 16;
26025
26083
  texture.needsUpdate = true;
26026
26084
  return texture;
@@ -26028,7 +26086,7 @@ function createPadTextureForLayer({
26028
26086
 
26029
26087
  // src/utils/panel-outline-texture.ts
26030
26088
  import { su as su7 } from "@tscircuit/circuit-json-util";
26031
- import * as THREE36 from "three";
26089
+ import * as THREE37 from "three";
26032
26090
  var resolvePanelIdForTexture = (circuitJson) => {
26033
26091
  const panels = circuitJson.filter(
26034
26092
  (e) => e.type === "pcb_panel"
@@ -26096,17 +26154,17 @@ function createPanelOutlineTextureForLayer({
26096
26154
  );
26097
26155
  }
26098
26156
  });
26099
- const texture = new THREE36.CanvasTexture(canvas);
26157
+ const texture = new THREE37.CanvasTexture(canvas);
26100
26158
  texture.generateMipmaps = true;
26101
- texture.minFilter = THREE36.LinearMipmapLinearFilter;
26102
- texture.magFilter = THREE36.LinearFilter;
26159
+ texture.minFilter = THREE37.LinearMipmapLinearFilter;
26160
+ texture.magFilter = THREE37.LinearFilter;
26103
26161
  texture.anisotropy = 16;
26104
26162
  texture.needsUpdate = true;
26105
26163
  return texture;
26106
26164
  }
26107
26165
 
26108
26166
  // src/utils/trace-texture.ts
26109
- import * as THREE37 from "three";
26167
+ import * as THREE38 from "three";
26110
26168
  import { CircuitToCanvasDrawer as CircuitToCanvasDrawer3 } from "circuit-to-canvas";
26111
26169
  import { getElementRenderLayers, su as su8 } from "@tscircuit/circuit-json-util";
26112
26170
  function createTraceTextureForLayer({
@@ -26192,10 +26250,10 @@ function createTraceTextureForLayer({
26192
26250
  drawSoldermaskTop: false,
26193
26251
  drawSoldermaskBottom: false
26194
26252
  });
26195
- const texture = new THREE37.CanvasTexture(canvas);
26253
+ const texture = new THREE38.CanvasTexture(canvas);
26196
26254
  texture.generateMipmaps = true;
26197
- texture.minFilter = THREE37.LinearMipmapLinearFilter;
26198
- texture.magFilter = THREE37.LinearFilter;
26255
+ texture.minFilter = THREE38.LinearMipmapLinearFilter;
26256
+ texture.magFilter = THREE38.LinearFilter;
26199
26257
  texture.anisotropy = 16;
26200
26258
  texture.needsUpdate = true;
26201
26259
  return texture;
@@ -26203,7 +26261,7 @@ function createTraceTextureForLayer({
26203
26261
 
26204
26262
  // src/textures/create-copper-pour-texture-for-layer.ts
26205
26263
  import { CircuitToCanvasDrawer as CircuitToCanvasDrawer4 } from "circuit-to-canvas";
26206
- import * as THREE38 from "three";
26264
+ import * as THREE39 from "three";
26207
26265
  var toRgb = (colorArr) => {
26208
26266
  const [r = 0, g = 0, b = 0] = colorArr;
26209
26267
  return `rgb(${Math.round(r * 255)}, ${Math.round(g * 255)}, ${Math.round(
@@ -26319,17 +26377,17 @@ function createCopperPourTextureForLayer({
26319
26377
  if (!onlyCoveredBySoldermask) {
26320
26378
  setColorAndDraw(uncoveredPours, uncoveredColor);
26321
26379
  }
26322
- const texture = new THREE38.CanvasTexture(canvas);
26380
+ const texture = new THREE39.CanvasTexture(canvas);
26323
26381
  texture.generateMipmaps = true;
26324
- texture.minFilter = THREE38.LinearMipmapLinearFilter;
26325
- texture.magFilter = THREE38.LinearFilter;
26382
+ texture.minFilter = THREE39.LinearMipmapLinearFilter;
26383
+ texture.magFilter = THREE39.LinearFilter;
26326
26384
  texture.anisotropy = 16;
26327
26385
  texture.needsUpdate = true;
26328
26386
  return texture;
26329
26387
  }
26330
26388
 
26331
26389
  // src/textures/create-copper-text-texture-for-layer.ts
26332
- import * as THREE39 from "three";
26390
+ import * as THREE40 from "three";
26333
26391
 
26334
26392
  // src/textures/copper-text/copper-text-drawing.ts
26335
26393
  import { CircuitToCanvasDrawer as CircuitToCanvasDrawer5 } from "circuit-to-canvas";
@@ -26444,17 +26502,17 @@ function createCopperTextTextureForLayer({
26444
26502
  elements,
26445
26503
  copperColor
26446
26504
  });
26447
- const texture = new THREE39.CanvasTexture(canvas);
26505
+ const texture = new THREE40.CanvasTexture(canvas);
26448
26506
  texture.generateMipmaps = true;
26449
- texture.minFilter = THREE39.LinearMipmapLinearFilter;
26450
- texture.magFilter = THREE39.LinearFilter;
26507
+ texture.minFilter = THREE40.LinearMipmapLinearFilter;
26508
+ texture.magFilter = THREE40.LinearFilter;
26451
26509
  texture.anisotropy = 16;
26452
26510
  texture.needsUpdate = true;
26453
26511
  return texture;
26454
26512
  }
26455
26513
 
26456
26514
  // src/textures/create-fabrication-note-texture-for-layer.ts
26457
- import * as THREE40 from "three";
26515
+ import * as THREE41 from "three";
26458
26516
 
26459
26517
  // src/textures/fabrication-note/fabrication-note-drawing.ts
26460
26518
  import { CircuitToCanvasDrawer as CircuitToCanvasDrawer6 } from "circuit-to-canvas";
@@ -26684,17 +26742,17 @@ function createFabricationNoteTextureForLayer({
26684
26742
  bounds,
26685
26743
  elements
26686
26744
  });
26687
- const texture = new THREE40.CanvasTexture(canvas);
26745
+ const texture = new THREE41.CanvasTexture(canvas);
26688
26746
  texture.generateMipmaps = true;
26689
- texture.minFilter = THREE40.LinearMipmapLinearFilter;
26690
- texture.magFilter = THREE40.LinearFilter;
26747
+ texture.minFilter = THREE41.LinearMipmapLinearFilter;
26748
+ texture.magFilter = THREE41.LinearFilter;
26691
26749
  texture.anisotropy = 16;
26692
26750
  texture.needsUpdate = true;
26693
26751
  return texture;
26694
26752
  }
26695
26753
 
26696
26754
  // src/textures/create-keepout-texture-for-layer.ts
26697
- import * as THREE41 from "three";
26755
+ import * as THREE42 from "three";
26698
26756
 
26699
26757
  // src/textures/keepout/keepout-drawing.ts
26700
26758
  import { CircuitToCanvasDrawer as CircuitToCanvasDrawer7 } from "circuit-to-canvas";
@@ -26769,17 +26827,17 @@ function createKeepoutTextureForLayer({
26769
26827
  elements,
26770
26828
  keepoutColor
26771
26829
  });
26772
- const texture = new THREE41.CanvasTexture(canvas);
26830
+ const texture = new THREE42.CanvasTexture(canvas);
26773
26831
  texture.generateMipmaps = true;
26774
- texture.minFilter = THREE41.LinearMipmapLinearFilter;
26775
- texture.magFilter = THREE41.LinearFilter;
26832
+ texture.minFilter = THREE42.LinearMipmapLinearFilter;
26833
+ texture.magFilter = THREE42.LinearFilter;
26776
26834
  texture.anisotropy = 16;
26777
26835
  texture.needsUpdate = true;
26778
26836
  return texture;
26779
26837
  }
26780
26838
 
26781
26839
  // src/textures/create-pcb-note-texture-for-layer.ts
26782
- import * as THREE42 from "three";
26840
+ import * as THREE43 from "three";
26783
26841
 
26784
26842
  // src/textures/pcb-note/pcb-note-drawing.ts
26785
26843
  import { CircuitToCanvasDrawer as CircuitToCanvasDrawer8 } from "circuit-to-canvas";
@@ -26933,17 +26991,17 @@ function createPcbNoteTextureForLayer({
26933
26991
  bounds,
26934
26992
  elements
26935
26993
  });
26936
- const texture = new THREE42.CanvasTexture(canvas);
26994
+ const texture = new THREE43.CanvasTexture(canvas);
26937
26995
  texture.generateMipmaps = true;
26938
- texture.minFilter = THREE42.LinearMipmapLinearFilter;
26939
- texture.magFilter = THREE42.LinearFilter;
26996
+ texture.minFilter = THREE43.LinearMipmapLinearFilter;
26997
+ texture.magFilter = THREE43.LinearFilter;
26940
26998
  texture.anisotropy = 16;
26941
26999
  texture.needsUpdate = true;
26942
27000
  return texture;
26943
27001
  }
26944
27002
 
26945
27003
  // src/textures/create-silkscreen-texture-for-layer.ts
26946
- import * as THREE43 from "three";
27004
+ import * as THREE44 from "three";
26947
27005
 
26948
27006
  // src/textures/silkscreen/silkscreen-drawing.ts
26949
27007
  import { CircuitToCanvasDrawer as CircuitToCanvasDrawer9 } from "circuit-to-canvas";
@@ -27094,21 +27152,21 @@ function createSilkscreenTextureForLayer({
27094
27152
  silkscreenColor,
27095
27153
  soldermaskVisible
27096
27154
  });
27097
- const texture = new THREE43.CanvasTexture(canvas);
27155
+ const texture = new THREE44.CanvasTexture(canvas);
27098
27156
  texture.generateMipmaps = true;
27099
- texture.minFilter = THREE43.LinearMipmapLinearFilter;
27100
- texture.magFilter = THREE43.LinearFilter;
27157
+ texture.minFilter = THREE44.LinearMipmapLinearFilter;
27158
+ texture.magFilter = THREE44.LinearFilter;
27101
27159
  texture.anisotropy = 16;
27102
27160
  texture.needsUpdate = true;
27103
27161
  return texture;
27104
27162
  }
27105
27163
 
27106
27164
  // src/textures/create-soldermask-texture-for-layer.ts
27107
- import * as THREE45 from "three";
27165
+ import * as THREE46 from "three";
27108
27166
 
27109
27167
  // src/textures/soldermask/soldermask-drawing.ts
27110
27168
  import { CircuitToCanvasDrawer as CircuitToCanvasDrawer10 } from "circuit-to-canvas";
27111
- import * as THREE44 from "three";
27169
+ import * as THREE45 from "three";
27112
27170
  var toRgb2 = (colorArr) => {
27113
27171
  const [r = 0, g = 0, b = 0] = colorArr;
27114
27172
  return `rgb(${Math.round(r * 255)}, ${Math.round(g * 255)}, ${Math.round(
@@ -27120,7 +27178,7 @@ var getSoldermaskPalette = (boardData) => {
27120
27178
  soldermaskColors[boardData.material] ?? colors.fr4SolderMaskGreen
27121
27179
  );
27122
27180
  const legacySoldermaskOverCopper = boardData.material === "fr1" ? toRgb2(colors.fr1TracesWithMaskCopper) : toRgb2(colors.fr4TracesWithMaskGreen);
27123
- const requestedSoldermaskColor = resolveSoldermaskColor(boardData.solder_mask_color) ?? (boardData.material === "flex" ? new THREE44.Color(toRgb2(colors.flexAmber)) : null);
27181
+ const requestedSoldermaskColor = resolveSoldermaskColor(boardData.solder_mask_color) ?? (boardData.material === "flex" ? new THREE45.Color(toRgb2(colors.flexAmber)) : null);
27124
27182
  if (!requestedSoldermaskColor) {
27125
27183
  return {
27126
27184
  soldermask: legacySoldermask,
@@ -27129,11 +27187,11 @@ var getSoldermaskPalette = (boardData) => {
27129
27187
  transparent: "rgba(0,0,0,0)"
27130
27188
  };
27131
27189
  }
27132
- const copperColor = new THREE44.Color().setRGB(
27190
+ const copperColor = new THREE45.Color().setRGB(
27133
27191
  colors.copper[0],
27134
27192
  colors.copper[1],
27135
27193
  colors.copper[2],
27136
- THREE44.SRGBColorSpace
27194
+ THREE45.SRGBColorSpace
27137
27195
  );
27138
27196
  return {
27139
27197
  soldermask: soldermaskColorToCss(requestedSoldermaskColor),
@@ -27268,17 +27326,17 @@ function createSoldermaskTextureForLayer({
27268
27326
  elements,
27269
27327
  boardData
27270
27328
  });
27271
- const texture = new THREE45.CanvasTexture(canvas);
27329
+ const texture = new THREE46.CanvasTexture(canvas);
27272
27330
  texture.generateMipmaps = true;
27273
- texture.minFilter = THREE45.LinearMipmapLinearFilter;
27274
- texture.magFilter = THREE45.LinearFilter;
27331
+ texture.minFilter = THREE46.LinearMipmapLinearFilter;
27332
+ texture.magFilter = THREE46.LinearFilter;
27275
27333
  texture.anisotropy = 16;
27276
27334
  texture.needsUpdate = true;
27277
27335
  return texture;
27278
27336
  }
27279
27337
 
27280
27338
  // src/textures/create-through-hole-texture-for-layer.ts
27281
- import * as THREE46 from "three";
27339
+ import * as THREE47 from "three";
27282
27340
 
27283
27341
  // src/textures/through-hole/through-hole-drawing.ts
27284
27342
  import { CircuitToCanvasDrawer as CircuitToCanvasDrawer11 } from "circuit-to-canvas";
@@ -27373,10 +27431,10 @@ function createThroughHoleTextureForLayer({
27373
27431
  elements,
27374
27432
  copperColor
27375
27433
  });
27376
- const texture = new THREE46.CanvasTexture(canvas);
27434
+ const texture = new THREE47.CanvasTexture(canvas);
27377
27435
  texture.generateMipmaps = true;
27378
- texture.minFilter = THREE46.LinearMipmapLinearFilter;
27379
- texture.magFilter = THREE46.LinearFilter;
27436
+ texture.minFilter = THREE47.LinearMipmapLinearFilter;
27437
+ texture.magFilter = THREE47.LinearFilter;
27380
27438
  texture.anisotropy = 16;
27381
27439
  texture.needsUpdate = true;
27382
27440
  return texture;
@@ -27498,10 +27556,10 @@ var createCombinedTexture = ({
27498
27556
  applySoldermaskSurfaceFilter(ctx, canvasWidth, canvasHeight, {
27499
27557
  includeReflection: layer === "top"
27500
27558
  });
27501
- const combinedTexture = new THREE47.CanvasTexture(canvas);
27559
+ const combinedTexture = new THREE48.CanvasTexture(canvas);
27502
27560
  combinedTexture.generateMipmaps = false;
27503
- combinedTexture.minFilter = THREE47.LinearFilter;
27504
- combinedTexture.magFilter = THREE47.LinearFilter;
27561
+ combinedTexture.minFilter = THREE48.LinearFilter;
27562
+ combinedTexture.magFilter = THREE48.LinearFilter;
27505
27563
  combinedTexture.premultiplyAlpha = true;
27506
27564
  combinedTexture.anisotropy = 16;
27507
27565
  combinedTexture.needsUpdate = true;
@@ -27537,11 +27595,11 @@ var createMaskedCopperMask = ({
27537
27595
  height
27538
27596
  );
27539
27597
  ctx.globalCompositeOperation = "source-over";
27540
- const maskTexture = new THREE47.CanvasTexture(canvas);
27541
- maskTexture.colorSpace = THREE47.NoColorSpace;
27598
+ const maskTexture = new THREE48.CanvasTexture(canvas);
27599
+ maskTexture.colorSpace = THREE48.NoColorSpace;
27542
27600
  maskTexture.generateMipmaps = false;
27543
- maskTexture.minFilter = THREE47.LinearFilter;
27544
- maskTexture.magFilter = THREE47.LinearFilter;
27601
+ maskTexture.minFilter = THREE48.LinearFilter;
27602
+ maskTexture.magFilter = THREE48.LinearFilter;
27545
27603
  maskTexture.premultiplyAlpha = false;
27546
27604
  maskTexture.needsUpdate = true;
27547
27605
  return maskTexture;
@@ -27691,7 +27749,7 @@ function createCombinedBoardTextures({
27691
27749
  }
27692
27750
 
27693
27751
  // src/textures/create-three-texture-meshes.ts
27694
- import * as THREE49 from "three";
27752
+ import * as THREE50 from "three";
27695
27753
 
27696
27754
  // src/board-surface-textures.ts
27697
27755
  var REALISTIC_BOARD_SURFACE_MATERIAL = {
@@ -27714,7 +27772,7 @@ var PAD_COPPER_TEXTURE_MATERIAL = {
27714
27772
  };
27715
27773
 
27716
27774
  // src/utils/create-board-relief-textures.ts
27717
- import * as THREE48 from "three";
27775
+ import * as THREE49 from "three";
27718
27776
  var PLAIN_SOLDERMASK_HEIGHT = 0.22;
27719
27777
  var MASKED_COPPER_HEIGHT = 0.7;
27720
27778
  var EXPOSED_COPPER_HEIGHT = 0.86;
@@ -27809,13 +27867,13 @@ var getBoardSurfaceProfile = (r, g, b, hasMaskedCopper) => {
27809
27867
  return PLAIN_SOLDERMASK_PROFILE;
27810
27868
  };
27811
27869
  var createDataTexture = (canvas) => {
27812
- const texture = new THREE48.CanvasTexture(canvas);
27813
- texture.colorSpace = THREE48.NoColorSpace;
27870
+ const texture = new THREE49.CanvasTexture(canvas);
27871
+ texture.colorSpace = THREE49.NoColorSpace;
27814
27872
  texture.generateMipmaps = false;
27815
- texture.minFilter = THREE48.LinearFilter;
27816
- texture.magFilter = THREE48.LinearFilter;
27817
- texture.wrapS = THREE48.ClampToEdgeWrapping;
27818
- texture.wrapT = THREE48.ClampToEdgeWrapping;
27873
+ texture.minFilter = THREE49.LinearFilter;
27874
+ texture.magFilter = THREE49.LinearFilter;
27875
+ texture.wrapS = THREE49.ClampToEdgeWrapping;
27876
+ texture.wrapT = THREE49.ClampToEdgeWrapping;
27819
27877
  texture.needsUpdate = true;
27820
27878
  return texture;
27821
27879
  };
@@ -27939,16 +27997,16 @@ function createTexturePlane(config, boardData) {
27939
27997
  } = config;
27940
27998
  if (!texture) return null;
27941
27999
  const boardOutlineBounds = calculateOutlineBounds(boardData);
27942
- const planeGeom = new THREE49.PlaneGeometry(
28000
+ const planeGeom = new THREE50.PlaneGeometry(
27943
28001
  boardOutlineBounds.width,
27944
28002
  boardOutlineBounds.height
27945
28003
  );
27946
- texture.colorSpace = THREE49.SRGBColorSpace;
28004
+ texture.colorSpace = THREE50.SRGBColorSpace;
27947
28005
  const sharedMaterialOptions = {
27948
28006
  map: texture,
27949
28007
  transparent: true,
27950
28008
  alphaTest: 0.08,
27951
- side: THREE49.FrontSide,
28009
+ side: THREE50.FrontSide,
27952
28010
  depthWrite: true,
27953
28011
  polygonOffset: usePolygonOffset,
27954
28012
  polygonOffsetFactor: usePolygonOffset ? -4 : 0,
@@ -27957,12 +28015,12 @@ function createTexturePlane(config, boardData) {
27957
28015
  opacity: isFaux ? FAUX_BOARD_OPACITY : 1
27958
28016
  };
27959
28017
  const reliefTextures = createBoardReliefTextures(texture, maskedCopperMask);
27960
- const material = new THREE49.MeshPhysicalMaterial({
28018
+ const material = new THREE50.MeshPhysicalMaterial({
27961
28019
  ...sharedMaterialOptions,
27962
28020
  bumpMap: reliefTextures?.bumpMap ?? null,
27963
28021
  bumpScale: REALISTIC_BOARD_SURFACE_MATERIAL.bumpScale,
27964
28022
  normalMap: reliefTextures?.normalMap ?? null,
27965
- normalScale: new THREE49.Vector2(
28023
+ normalScale: new THREE50.Vector2(
27966
28024
  REALISTIC_BOARD_SURFACE_MATERIAL.normalScale,
27967
28025
  REALISTIC_BOARD_SURFACE_MATERIAL.normalScale
27968
28026
  ),
@@ -27976,7 +28034,7 @@ function createTexturePlane(config, boardData) {
27976
28034
  clearcoatRoughness: REALISTIC_BOARD_SURFACE_MATERIAL.clearcoatRoughness,
27977
28035
  envMapIntensity: 0.18
27978
28036
  });
27979
- const mesh = new THREE49.Mesh(planeGeom, material);
28037
+ const mesh = new THREE50.Mesh(planeGeom, material);
27980
28038
  mesh.position.set(
27981
28039
  boardOutlineBounds.centerX,
27982
28040
  boardOutlineBounds.centerY,
@@ -28024,10 +28082,10 @@ function createTextureMeshes(textures, boardData, pcbThickness, isFaux = false)
28024
28082
  }
28025
28083
 
28026
28084
  // src/three-components/JscadBoardTextures.tsx
28027
- import * as THREE50 from "three";
28085
+ import * as THREE51 from "three";
28028
28086
 
28029
28087
  // src/hooks/useBoardTextureVisibility.ts
28030
- import { useMemo as useMemo22 } from "react";
28088
+ import { useMemo as useMemo23 } from "react";
28031
28089
  var useBoardTextureVisibility = (visibility) => {
28032
28090
  const {
28033
28091
  boardBody,
@@ -28040,7 +28098,7 @@ var useBoardTextureVisibility = (visibility) => {
28040
28098
  keepout,
28041
28099
  pcbNotes
28042
28100
  } = visibility;
28043
- return useMemo22(
28101
+ return useMemo23(
28044
28102
  () => ({
28045
28103
  boardBody,
28046
28104
  topCopper,
@@ -28102,7 +28160,7 @@ function JscadBoardTextures({
28102
28160
  const { rootObject } = useThree();
28103
28161
  const { visibility } = useLayerVisibility();
28104
28162
  const textureVisibility = useBoardTextureVisibility(visibility);
28105
- const boardData = useMemo23(() => {
28163
+ const boardData = useMemo24(() => {
28106
28164
  const panels = circuitJson.filter(
28107
28165
  (e) => e.type === "pcb_panel"
28108
28166
  );
@@ -28129,11 +28187,11 @@ function JscadBoardTextures({
28129
28187
  );
28130
28188
  return boardsNotInPanel.length > 0 ? boardsNotInPanel[0] : null;
28131
28189
  }, [circuitJson]);
28132
- const traceTextureResolution = useMemo23(() => {
28190
+ const traceTextureResolution = useMemo24(() => {
28133
28191
  if (!boardData) return TRACE_TEXTURE_RESOLUTION;
28134
28192
  return getLayerTextureResolution(boardData, TRACE_TEXTURE_RESOLUTION);
28135
28193
  }, [boardData]);
28136
- const textures = useMemo23(() => {
28194
+ const textures = useMemo24(() => {
28137
28195
  if (!boardData?.width || !boardData.height) return null;
28138
28196
  return createCombinedBoardTextures({
28139
28197
  circuitJson,
@@ -28142,7 +28200,7 @@ function JscadBoardTextures({
28142
28200
  visibility: textureVisibility
28143
28201
  });
28144
28202
  }, [circuitJson, boardData, traceTextureResolution, textureVisibility]);
28145
- useEffect30(() => {
28203
+ useEffect31(() => {
28146
28204
  if (!rootObject || !boardData || !textures) return;
28147
28205
  const meshes = [];
28148
28206
  const disposeTextureMaterial = (material) => {
@@ -28162,7 +28220,7 @@ function JscadBoardTextures({
28162
28220
  const typedMaterial = material;
28163
28221
  for (const prop of textureProps) {
28164
28222
  const texture = typedMaterial[prop];
28165
- if (texture && texture instanceof THREE50.Texture) {
28223
+ if (texture && texture instanceof THREE51.Texture) {
28166
28224
  texture.dispose();
28167
28225
  typedMaterial[prop] = null;
28168
28226
  }
@@ -28181,16 +28239,16 @@ function JscadBoardTextures({
28181
28239
  }) => {
28182
28240
  if (!texture) return null;
28183
28241
  const boardOutlineBounds = calculateOutlineBounds(boardData);
28184
- const planeGeom = new THREE50.PlaneGeometry(
28242
+ const planeGeom = new THREE51.PlaneGeometry(
28185
28243
  boardOutlineBounds.width,
28186
28244
  boardOutlineBounds.height
28187
28245
  );
28188
- texture.colorSpace = THREE50.SRGBColorSpace;
28246
+ texture.colorSpace = THREE51.SRGBColorSpace;
28189
28247
  const sharedMaterialOptions = {
28190
28248
  map: texture,
28191
28249
  transparent: true,
28192
28250
  alphaTest: 0.08,
28193
- side: THREE50.FrontSide,
28251
+ side: THREE51.FrontSide,
28194
28252
  depthWrite,
28195
28253
  polygonOffset: usePolygonOffset,
28196
28254
  polygonOffsetFactor: usePolygonOffset ? -4 : 0,
@@ -28201,12 +28259,12 @@ function JscadBoardTextures({
28201
28259
  texture,
28202
28260
  maskedCopperMask
28203
28261
  );
28204
- const material = new THREE50.MeshPhysicalMaterial({
28262
+ const material = new THREE51.MeshPhysicalMaterial({
28205
28263
  ...sharedMaterialOptions,
28206
28264
  bumpMap: reliefTextures?.bumpMap ?? null,
28207
28265
  bumpScale: REALISTIC_BOARD_SURFACE_MATERIAL.bumpScale,
28208
28266
  normalMap: reliefTextures?.normalMap ?? null,
28209
- normalScale: new THREE50.Vector2(
28267
+ normalScale: new THREE51.Vector2(
28210
28268
  REALISTIC_BOARD_SURFACE_MATERIAL.normalScale,
28211
28269
  REALISTIC_BOARD_SURFACE_MATERIAL.normalScale
28212
28270
  ),
@@ -28218,7 +28276,7 @@ function JscadBoardTextures({
28218
28276
  clearcoatRoughness: REALISTIC_BOARD_SURFACE_MATERIAL.clearcoatRoughness,
28219
28277
  envMapIntensity: 0.18
28220
28278
  });
28221
- const mesh = new THREE50.Mesh(planeGeom, material);
28279
+ const mesh = new THREE51.Mesh(planeGeom, material);
28222
28280
  mesh.position.set(
28223
28281
  boardOutlineBounds.centerX,
28224
28282
  boardOutlineBounds.centerY,
@@ -28268,7 +28326,7 @@ function JscadBoardTextures({
28268
28326
  for (const material of mesh.material) {
28269
28327
  disposeTextureMaterial(material);
28270
28328
  }
28271
- } else if (mesh.material instanceof THREE50.Material) {
28329
+ } else if (mesh.material instanceof THREE51.Material) {
28272
28330
  disposeTextureMaterial(mesh.material);
28273
28331
  }
28274
28332
  }
@@ -28280,8 +28338,8 @@ function JscadBoardTextures({
28280
28338
  }
28281
28339
 
28282
28340
  // src/three-components/STLModel.tsx
28283
- import { useState as useState19, useEffect as useEffect31, useMemo as useMemo24 } from "react";
28284
- import * as THREE51 from "three";
28341
+ import { useState as useState19, useEffect as useEffect32, useMemo as useMemo25 } from "react";
28342
+ import * as THREE52 from "three";
28285
28343
  import { STLLoader as STLLoader2 } from "three-stdlib";
28286
28344
  function STLModel({
28287
28345
  stlUrl,
@@ -28293,7 +28351,7 @@ function STLModel({
28293
28351
  }) {
28294
28352
  const { rootObject } = useThree();
28295
28353
  const [geom, setGeom] = useState19(null);
28296
- useEffect31(() => {
28354
+ useEffect32(() => {
28297
28355
  const loader = new STLLoader2();
28298
28356
  if (stlData) {
28299
28357
  try {
@@ -28311,18 +28369,18 @@ function STLModel({
28311
28369
  });
28312
28370
  }
28313
28371
  }, [stlUrl, stlData]);
28314
- const mesh = useMemo24(() => {
28372
+ const mesh = useMemo25(() => {
28315
28373
  if (!geom) return null;
28316
28374
  const isBoardLayer = layerType === "board";
28317
- const material = new THREE51.MeshStandardMaterial({
28318
- color: Array.isArray(color) ? new THREE51.Color(color[0], color[1], color[2]) : color,
28375
+ const material = new THREE52.MeshStandardMaterial({
28376
+ color: Array.isArray(color) ? new THREE52.Color(color[0], color[1], color[2]) : color,
28319
28377
  transparent: opacity !== 1,
28320
28378
  opacity,
28321
28379
  polygonOffset: isBoardLayer,
28322
28380
  polygonOffsetFactor: isBoardLayer ? 6 : 0,
28323
28381
  polygonOffsetUnits: isBoardLayer ? 6 : 0
28324
28382
  });
28325
- const createdMesh = new THREE51.Mesh(geom, material);
28383
+ const createdMesh = new THREE52.Mesh(geom, material);
28326
28384
  createdMesh.renderOrder = isBoardLayer ? -1 : 1;
28327
28385
  configureObjectShadows(createdMesh, {
28328
28386
  castShadow: !isBoardLayer && opacity === 1,
@@ -28330,7 +28388,7 @@ function STLModel({
28330
28388
  });
28331
28389
  return createdMesh;
28332
28390
  }, [geom, color, opacity, layerType]);
28333
- useEffect31(() => {
28391
+ useEffect32(() => {
28334
28392
  if (!rootObject || !mesh) return;
28335
28393
  rootObject.add(mesh);
28336
28394
  return () => {
@@ -28347,7 +28405,7 @@ function STLModel({
28347
28405
  }
28348
28406
 
28349
28407
  // src/three-components/VisibleSTLModel.tsx
28350
- import { jsx as jsx20 } from "react/jsx-runtime";
28408
+ import { jsx as jsx21 } from "react/jsx-runtime";
28351
28409
  function VisibleSTLModel({
28352
28410
  stlData,
28353
28411
  color,
@@ -28370,7 +28428,7 @@ function VisibleSTLModel({
28370
28428
  if (!shouldShow) {
28371
28429
  return null;
28372
28430
  }
28373
- return /* @__PURE__ */ jsx20(
28431
+ return /* @__PURE__ */ jsx21(
28374
28432
  STLModel,
28375
28433
  {
28376
28434
  stlData,
@@ -28384,8 +28442,8 @@ function VisibleSTLModel({
28384
28442
  // src/three-components/CadCable.tsx
28385
28443
  import { parseCableString } from "@tscircuit/cableprinter";
28386
28444
  import { createCableMeshes } from "jscad-electronics/cables";
28387
- import { useEffect as useEffect32, useMemo as useMemo25 } from "react";
28388
- import * as THREE52 from "three";
28445
+ import { useEffect as useEffect33, useMemo as useMemo26 } from "react";
28446
+ import * as THREE53 from "three";
28389
28447
  var isCadCableElement = (element) => {
28390
28448
  if (!element || typeof element !== "object") return false;
28391
28449
  const candidate = element;
@@ -28402,14 +28460,14 @@ var getConnectorPin1Side = ({
28402
28460
  const endpoint = end === "start" ? path[0] : path[path.length - 1];
28403
28461
  const adjacent = end === "start" ? path[1] : path[path.length - 2];
28404
28462
  if (!endpoint || !adjacent) return void 0;
28405
- const cableAxis = new THREE52.Vector3(
28463
+ const cableAxis = new THREE53.Vector3(
28406
28464
  adjacent.x - endpoint.x,
28407
28465
  adjacent.y - endpoint.y,
28408
28466
  adjacent.z - endpoint.z
28409
28467
  );
28410
28468
  if (cableAxis.lengthSq() < 1e-12) return void 0;
28411
28469
  cableAxis.normalize();
28412
- const pin1Side = new THREE52.Vector3(
28470
+ const pin1Side = new THREE53.Vector3(
28413
28471
  pin1Position.x - endpoint.x,
28414
28472
  pin1Position.y - endpoint.y,
28415
28473
  pin1Position.z - endpoint.z
@@ -28435,28 +28493,28 @@ var createCadCableObject = (cable) => {
28435
28493
  end: "end"
28436
28494
  })
28437
28495
  });
28438
- const group = new THREE52.Group();
28496
+ const group = new THREE53.Group();
28439
28497
  group.name = `cad-cable-${cable.cad_cable_id}`;
28440
- group.userData = { cadCableId: cable.cad_cable_id, name: cable.name };
28498
+ group.userData = { cad_cable_id: cable.cad_cable_id, name: cable.name };
28441
28499
  for (const cableMesh of cableMeshes) {
28442
- let geometry = new THREE52.BufferGeometry();
28500
+ let geometry = new THREE53.BufferGeometry();
28443
28501
  geometry.setAttribute(
28444
28502
  "position",
28445
- new THREE52.Float32BufferAttribute(cableMesh.positions, 3)
28503
+ new THREE53.Float32BufferAttribute(cableMesh.positions, 3)
28446
28504
  );
28447
28505
  geometry.setIndex(cableMesh.indices);
28448
28506
  if (!cableMesh.smooth) geometry = geometry.toNonIndexed();
28449
28507
  geometry.computeVertexNormals();
28450
28508
  const [red, green, blue, alpha] = cableMesh.color;
28451
- const material = new THREE52.MeshStandardMaterial({
28452
- color: new THREE52.Color(red, green, blue),
28509
+ const material = new THREE53.MeshStandardMaterial({
28510
+ color: new THREE53.Color(red, green, blue),
28453
28511
  metalness: cableMesh.material?.metalness ?? 0,
28454
28512
  roughness: cableMesh.material?.roughness ?? 0.7,
28455
28513
  opacity: alpha,
28456
28514
  transparent: alpha < 1,
28457
- side: THREE52.DoubleSide
28515
+ side: THREE53.DoubleSide
28458
28516
  });
28459
- const mesh = new THREE52.Mesh(geometry, material);
28517
+ const mesh = new THREE53.Mesh(geometry, material);
28460
28518
  mesh.name = `${group.name}:${cableMesh.name}`;
28461
28519
  configureObjectShadows(mesh, { castShadow: true, receiveShadow: true });
28462
28520
  group.add(mesh);
@@ -28465,7 +28523,7 @@ var createCadCableObject = (cable) => {
28465
28523
  };
28466
28524
  var disposeCadCableObject = (group) => {
28467
28525
  group.traverse((object) => {
28468
- if (!(object instanceof THREE52.Mesh)) return;
28526
+ if (!(object instanceof THREE53.Mesh)) return;
28469
28527
  object.geometry.dispose();
28470
28528
  const materials2 = Array.isArray(object.material) ? object.material : [object.material];
28471
28529
  for (const material of materials2) material.dispose();
@@ -28473,7 +28531,7 @@ var disposeCadCableObject = (group) => {
28473
28531
  };
28474
28532
  var CadCable = ({ cable }) => {
28475
28533
  const { rootObject } = useThree();
28476
- const cableObject = useMemo25(() => {
28534
+ const cableObject = useMemo26(() => {
28477
28535
  try {
28478
28536
  return createCadCableObject(cable);
28479
28537
  } catch (error) {
@@ -28481,7 +28539,7 @@ var CadCable = ({ cable }) => {
28481
28539
  return null;
28482
28540
  }
28483
28541
  }, [cable]);
28484
- useEffect32(() => {
28542
+ useEffect33(() => {
28485
28543
  if (!cableObject) return;
28486
28544
  rootObject.add(cableObject);
28487
28545
  return () => {
@@ -28597,7 +28655,7 @@ function addFauxBoardIfNeeded(circuitJson) {
28597
28655
  }
28598
28656
 
28599
28657
  // src/CadViewerJscad.tsx
28600
- import { jsx as jsx21, jsxs as jsxs6 } from "react/jsx-runtime";
28658
+ import { jsx as jsx22, jsxs as jsxs6 } from "react/jsx-runtime";
28601
28659
  var CadViewerJscad = forwardRef3(
28602
28660
  ({
28603
28661
  circuitJson,
@@ -28608,16 +28666,16 @@ var CadViewerJscad = forwardRef3(
28608
28666
  onCameraControllerReady,
28609
28667
  resolveStaticAsset,
28610
28668
  referenceObject,
28611
- hiddenCadComponentIds
28669
+ objectVisibility
28612
28670
  }, ref) => {
28613
28671
  const childrenSoup = useConvertChildrenToCircuitJson(children);
28614
- const internalCircuitJson = useMemo26(() => {
28672
+ const internalCircuitJson = useMemo27(() => {
28615
28673
  return addFauxBoardIfNeeded(
28616
28674
  circuitJson ?? childrenSoup
28617
28675
  );
28618
28676
  }, [circuitJson, childrenSoup]);
28619
28677
  const boardGeom = useBoardGeomBuilder(internalCircuitJson);
28620
- const isFauxBoard = useMemo26(() => {
28678
+ const isFauxBoard = useMemo27(() => {
28621
28679
  if (!internalCircuitJson) return false;
28622
28680
  try {
28623
28681
  const board = su12(internalCircuitJson).pcb_board.list()[0];
@@ -28626,7 +28684,7 @@ var CadViewerJscad = forwardRef3(
28626
28684
  return false;
28627
28685
  }
28628
28686
  }, [internalCircuitJson]);
28629
- const boardDimensions = useMemo26(() => {
28687
+ const boardDimensions = useMemo27(() => {
28630
28688
  if (!internalCircuitJson) return void 0;
28631
28689
  try {
28632
28690
  const board = su12(internalCircuitJson).pcb_board.list()[0];
@@ -28638,7 +28696,7 @@ var CadViewerJscad = forwardRef3(
28638
28696
  return void 0;
28639
28697
  }
28640
28698
  }, [internalCircuitJson]);
28641
- const boardCenter = useMemo26(() => {
28699
+ const boardCenter = useMemo27(() => {
28642
28700
  if (!internalCircuitJson) return void 0;
28643
28701
  try {
28644
28702
  const board = su12(internalCircuitJson).pcb_board.list()[0];
@@ -28650,7 +28708,7 @@ var CadViewerJscad = forwardRef3(
28650
28708
  return void 0;
28651
28709
  }
28652
28710
  }, [internalCircuitJson]);
28653
- const cameraSessionScope = useMemo26(() => {
28711
+ const cameraSessionScope = useMemo27(() => {
28654
28712
  if (!internalCircuitJson) return void 0;
28655
28713
  const board = su12(internalCircuitJson).pcb_board.list()[0];
28656
28714
  if (!board) return void 0;
@@ -28660,13 +28718,20 @@ var CadViewerJscad = forwardRef3(
28660
28718
  dimensions: boardDimensions
28661
28719
  });
28662
28720
  }, [internalCircuitJson, boardCenter, boardDimensions]);
28663
- const initialCameraPosition = useMemo26(() => {
28721
+ const initialCameraPosition = useMemo27(() => {
28664
28722
  return getInitialCameraPosition({ boardDimensions, boardCenter });
28665
28723
  }, [boardDimensions, boardCenter]);
28666
28724
  const pcbThickness = usePcbThickness(internalCircuitJson);
28667
28725
  const { stls: boardStls, loading } = useStlsFromGeom(boardGeom);
28668
- const cad_components = su12(internalCircuitJson).cad_component.list().filter((cad) => !hiddenCadComponentIds?.has(cad.cad_component_id));
28669
- const cadCables = getCadCables(internalCircuitJson);
28726
+ const renderedBoardId = useMemo27(() => {
28727
+ const panel = internalCircuitJson.find((e) => e.type === "pcb_panel");
28728
+ if (panel?.type === "pcb_panel") return panel.pcb_panel_id;
28729
+ return su12(internalCircuitJson).pcb_board.list().find((board) => !board.pcb_panel_id)?.pcb_board_id;
28730
+ }, [internalCircuitJson]);
28731
+ const cad_components = su12(internalCircuitJson).cad_component.list().filter((cad) => !isObjectHidden(objectVisibility, cad.cad_component_id));
28732
+ const cadCables = getCadCables(internalCircuitJson).filter(
28733
+ (cable) => !isObjectHidden(objectVisibility, cable.cad_cable_id)
28734
+ );
28670
28735
  return /* @__PURE__ */ jsxs6(
28671
28736
  CadViewerContainer,
28672
28737
  {
@@ -28681,29 +28746,38 @@ var CadViewerJscad = forwardRef3(
28681
28746
  onUserInteraction,
28682
28747
  onCameraControllerReady,
28683
28748
  children: [
28684
- boardStls.map(({ stlData, color, layerType }, index2) => /* @__PURE__ */ jsx21(
28685
- VisibleSTLModel,
28686
- {
28687
- stlData,
28688
- color,
28689
- opacity: index2 === 0 ? isFauxBoard ? 0.8 : 0.95 : 1,
28690
- layerType
28691
- },
28692
- `board-${index2}`
28693
- )),
28694
- /* @__PURE__ */ jsx21(
28695
- JscadBoardTextures,
28749
+ /* @__PURE__ */ jsxs6(
28750
+ BoardGroup,
28696
28751
  {
28697
- circuitJson: internalCircuitJson,
28698
- pcbThickness,
28699
- isFaux: isFauxBoard
28752
+ pcbBoardId: renderedBoardId,
28753
+ hidden: isObjectHidden(objectVisibility, renderedBoardId),
28754
+ children: [
28755
+ boardStls.map(({ stlData, color, layerType }, index2) => /* @__PURE__ */ jsx22(
28756
+ VisibleSTLModel,
28757
+ {
28758
+ stlData,
28759
+ color,
28760
+ opacity: index2 === 0 ? isFauxBoard ? 0.8 : 0.95 : 1,
28761
+ layerType
28762
+ },
28763
+ `board-${index2}`
28764
+ )),
28765
+ /* @__PURE__ */ jsx22(
28766
+ JscadBoardTextures,
28767
+ {
28768
+ circuitJson: internalCircuitJson,
28769
+ pcbThickness,
28770
+ isFaux: isFauxBoard
28771
+ }
28772
+ )
28773
+ ]
28700
28774
  }
28701
28775
  ),
28702
- cad_components.map((cad_component) => /* @__PURE__ */ jsx21(
28776
+ cad_components.map((cad_component) => /* @__PURE__ */ jsx22(
28703
28777
  ThreeErrorBoundary,
28704
28778
  {
28705
- fallback: ({ error }) => /* @__PURE__ */ jsx21(Error3d, { cad_component, error }),
28706
- children: /* @__PURE__ */ jsx21(
28779
+ fallback: ({ error }) => /* @__PURE__ */ jsx22(Error3d, { cad_component, error }),
28780
+ children: /* @__PURE__ */ jsx22(
28707
28781
  AnyCadComponent,
28708
28782
  {
28709
28783
  cad_component,
@@ -28715,7 +28789,7 @@ var CadViewerJscad = forwardRef3(
28715
28789
  },
28716
28790
  cad_component.cad_component_id
28717
28791
  )),
28718
- cadCables.map((cable) => /* @__PURE__ */ jsx21(CadCable, { cable }, cable.cad_cable_id))
28792
+ cadCables.map((cable) => /* @__PURE__ */ jsx22(CadCable, { cable }, cable.cad_cable_id))
28719
28793
  ]
28720
28794
  }
28721
28795
  );
@@ -29976,13 +30050,13 @@ function createStiffenerMesh({
29976
30050
  }
29977
30051
 
29978
30052
  // src/CadViewerManifold.tsx
29979
- import { useEffect as useEffect34, useMemo as useMemo28, useState as useState21 } from "react";
29980
- import * as THREE60 from "three";
30053
+ import { useEffect as useEffect35, useMemo as useMemo29, useState as useState21 } from "react";
30054
+ import * as THREE61 from "three";
29981
30055
 
29982
30056
  // src/hooks/useManifoldBoardBuilder.ts
29983
30057
  import { su as su16 } from "@tscircuit/circuit-json-util";
29984
- import { useEffect as useEffect33, useMemo as useMemo27, useRef as useRef10, useState as useState20 } from "react";
29985
- import * as THREE56 from "three";
30058
+ import { useEffect as useEffect34, useMemo as useMemo28, useRef as useRef10, useState as useState20 } from "react";
30059
+ import * as THREE57 from "three";
29986
30060
 
29987
30061
  // src/utils/manifold/create-manifold-board.ts
29988
30062
  var arePointsClockwise2 = (points) => {
@@ -30331,17 +30405,17 @@ function processNonPlatedHolesForManifold(Manifold, CrossSection, circuitJson, p
30331
30405
 
30332
30406
  // src/utils/manifold/process-plated-holes.ts
30333
30407
  import { su as su15 } from "@tscircuit/circuit-json-util";
30334
- import * as THREE54 from "three";
30408
+ import * as THREE55 from "three";
30335
30409
 
30336
30410
  // src/utils/manifold-mesh-to-three-geometry.ts
30337
- import * as THREE53 from "three";
30411
+ import * as THREE54 from "three";
30338
30412
  function manifoldMeshToThreeGeometry(manifoldMesh) {
30339
- const geometry = new THREE53.BufferGeometry();
30413
+ const geometry = new THREE54.BufferGeometry();
30340
30414
  geometry.setAttribute(
30341
30415
  "position",
30342
- new THREE53.Float32BufferAttribute(manifoldMesh.vertProperties, 3)
30416
+ new THREE54.Float32BufferAttribute(manifoldMesh.vertProperties, 3)
30343
30417
  );
30344
- geometry.setIndex(new THREE53.Uint32BufferAttribute(manifoldMesh.triVerts, 1));
30418
+ geometry.setIndex(new THREE54.Uint32BufferAttribute(manifoldMesh.triVerts, 1));
30345
30419
  if (manifoldMesh.runIndex && manifoldMesh.runIndex.length > 1 && manifoldMesh.runOriginalID) {
30346
30420
  for (let i = 0; i < manifoldMesh.runIndex.length - 1; i++) {
30347
30421
  const start = manifoldMesh.runIndex[i];
@@ -30375,7 +30449,7 @@ var createEllipsePoints = (width, height, segments) => {
30375
30449
  }
30376
30450
  return points;
30377
30451
  };
30378
- var COPPER_COLOR = new THREE54.Color(...colors.copper);
30452
+ var COPPER_COLOR = new THREE55.Color(...colors.copper);
30379
30453
  var PLATED_HOLE_LIP_HEIGHT = 0.05;
30380
30454
  var PLATED_HOLE_PAD_THICKNESS = 3e-3;
30381
30455
  var PLATED_HOLE_SURFACE_CLEARANCE = 5e-4;
@@ -31015,7 +31089,7 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
31015
31089
  }
31016
31090
 
31017
31091
  // src/utils/manifold/process-vias.ts
31018
- import * as THREE55 from "three";
31092
+ import * as THREE56 from "three";
31019
31093
 
31020
31094
  // src/utils/via-geoms.ts
31021
31095
  function createViaCopper2({
@@ -31053,7 +31127,7 @@ function createViaCopper2({
31053
31127
  }
31054
31128
 
31055
31129
  // src/utils/manifold/process-vias.ts
31056
- var COPPER_COLOR2 = new THREE55.Color(...colors.copper);
31130
+ var COPPER_COLOR2 = new THREE56.Color(...colors.copper);
31057
31131
  function processViasForManifold(Manifold, circuitJson, pcbThickness, manifoldInstancesForCleanup, boardClipVolume, otherHoleDrills = []) {
31058
31132
  const viaBoardDrills = [];
31059
31133
  const pcbVias = getPcbVias(circuitJson);
@@ -31137,7 +31211,7 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson, visibility) => {
31137
31211
  const [error, setError] = useState20(null);
31138
31212
  const [isLoading, setIsLoading] = useState20(true);
31139
31213
  const manifoldInstancesForCleanup = useRef10([]);
31140
- const boardData = useMemo27(() => {
31214
+ const boardData = useMemo28(() => {
31141
31215
  const panels = circuitJson.filter(
31142
31216
  (e) => e.type === "pcb_panel"
31143
31217
  );
@@ -31162,15 +31236,15 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson, visibility) => {
31162
31236
  const boardsNotInPanel = boards.filter((b) => !b.pcb_panel_id);
31163
31237
  return boardsNotInPanel.length > 0 ? boardsNotInPanel[0] : null;
31164
31238
  }, [circuitJson]);
31165
- const isFauxBoard = useMemo27(() => {
31239
+ const isFauxBoard = useMemo28(() => {
31166
31240
  const boards = su16(circuitJson).pcb_board.list();
31167
31241
  return boards.length > 0 && boards[0].pcb_board_id === "faux-board";
31168
31242
  }, [circuitJson]);
31169
- const traceTextureResolution = useMemo27(() => {
31243
+ const traceTextureResolution = useMemo28(() => {
31170
31244
  if (!boardData) return TRACE_TEXTURE_RESOLUTION;
31171
31245
  return getLayerTextureResolution(boardData, TRACE_TEXTURE_RESOLUTION);
31172
31246
  }, [boardData]);
31173
- useEffect33(() => {
31247
+ useEffect34(() => {
31174
31248
  if (!manifoldJSModule || !boardData) {
31175
31249
  setGeoms(null);
31176
31250
  setPcbThickness(null);
@@ -31301,7 +31375,7 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson, visibility) => {
31301
31375
  {
31302
31376
  key: "plated-holes-union",
31303
31377
  geometry: cutPlatedGeom,
31304
- color: new THREE56.Color(
31378
+ color: new THREE57.Color(
31305
31379
  colors.copper[0],
31306
31380
  colors.copper[1],
31307
31381
  colors.copper[2]
@@ -31350,7 +31424,7 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson, visibility) => {
31350
31424
  manifoldInstancesForCleanup.current = [];
31351
31425
  };
31352
31426
  }, [manifoldJSModule, circuitJson, boardData]);
31353
- const textures = useMemo27(() => {
31427
+ const textures = useMemo28(() => {
31354
31428
  if (!boardData || !traceTextureResolution) return null;
31355
31429
  return createCombinedBoardTextures({
31356
31430
  circuitJson,
@@ -31371,7 +31445,7 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson, visibility) => {
31371
31445
  };
31372
31446
 
31373
31447
  // src/utils/flex-meshes.ts
31374
- import * as THREE57 from "three";
31448
+ import * as THREE58 from "three";
31375
31449
  function restoreOutlinePrecision(point, outline, tolerance) {
31376
31450
  let distanceSquared = tolerance * tolerance;
31377
31451
  let closest;
@@ -31406,7 +31480,7 @@ function meshToSurface(mesh, center, outline) {
31406
31480
  const triangles = [];
31407
31481
  for (let i = 0; i < position.count; i += 3) {
31408
31482
  const vertices = [0, 1, 2].map((j) => {
31409
- const v = new THREE57.Vector3().fromBufferAttribute(position, i + j);
31483
+ const v = new THREE58.Vector3().fromBufferAttribute(position, i + j);
31410
31484
  const localMagnitude = Math.max(
31411
31485
  1,
31412
31486
  Math.abs(v.x),
@@ -31429,7 +31503,7 @@ function meshToSurface(mesh, center, outline) {
31429
31503
  return { x: v.x - center.x, y: v.y - center.y, z: v.z };
31430
31504
  });
31431
31505
  const [a, b, c] = vertices;
31432
- const n = new THREE57.Vector3(b.x - a.x, b.y - a.y, b.z - a.z).cross(new THREE57.Vector3(c.x - a.x, c.y - a.y, c.z - a.z)).normalize();
31506
+ const n = new THREE58.Vector3(b.x - a.x, b.y - a.y, b.z - a.z).cross(new THREE58.Vector3(c.x - a.x, c.y - a.y, c.z - a.z)).normalize();
31433
31507
  triangles.push({
31434
31508
  vertices,
31435
31509
  normal: { x: n.x, y: n.y, z: n.z },
@@ -31452,13 +31526,13 @@ function surfaceToGeometry(surface, center) {
31452
31526
  normals.push(triangle.normal.x, triangle.normal.y, triangle.normal.z);
31453
31527
  uvs.push(triangle.uvs?.[i]?.u ?? 0, triangle.uvs?.[i]?.v ?? 0);
31454
31528
  });
31455
- const geometry = new THREE57.BufferGeometry();
31529
+ const geometry = new THREE58.BufferGeometry();
31456
31530
  geometry.setAttribute(
31457
31531
  "position",
31458
- new THREE57.Float32BufferAttribute(positions, 3)
31532
+ new THREE58.Float32BufferAttribute(positions, 3)
31459
31533
  );
31460
- geometry.setAttribute("normal", new THREE57.Float32BufferAttribute(normals, 3));
31461
- geometry.setAttribute("uv", new THREE57.Float32BufferAttribute(uvs, 2));
31534
+ geometry.setAttribute("normal", new THREE58.Float32BufferAttribute(normals, 3));
31535
+ geometry.setAttribute("uv", new THREE58.Float32BufferAttribute(uvs, 2));
31462
31536
  geometry.computeBoundingBox();
31463
31537
  geometry.computeBoundingSphere();
31464
31538
  return geometry;
@@ -31511,7 +31585,7 @@ function createFlexMeshes(geometryMeshes, textureMeshes, json, foldPcbs) {
31511
31585
  z: mesh.position.z
31512
31586
  }));
31513
31587
  const uvs = vertices.map((p) => {
31514
- const local = new THREE57.Vector3(
31588
+ const local = new THREE58.Vector3(
31515
31589
  p.x + board.center.x,
31516
31590
  p.y + board.center.y,
31517
31591
  p.z
@@ -31535,7 +31609,7 @@ function createFlexMeshes(geometryMeshes, textureMeshes, json, foldPcbs) {
31535
31609
  return result;
31536
31610
  }) : textureMeshes;
31537
31611
  for (const stiffener of stiffeners) {
31538
- const mesh = new THREE57.Mesh(
31612
+ const mesh = new THREE58.Mesh(
31539
31613
  surfaceToGeometry(
31540
31614
  createStiffenerMesh({
31541
31615
  stiffener,
@@ -31544,16 +31618,16 @@ function createFlexMeshes(geometryMeshes, textureMeshes, json, foldPcbs) {
31544
31618
  }),
31545
31619
  board.center
31546
31620
  ),
31547
- new THREE57.MeshStandardMaterial({
31621
+ new THREE58.MeshStandardMaterial({
31548
31622
  color: stiffener.material === "fr4" ? "#879568" : stiffener.material === "polyimide" ? "#bd7f27" : "#b8bdc4",
31549
- side: THREE57.DoubleSide
31623
+ side: THREE58.DoubleSide
31550
31624
  })
31551
31625
  );
31552
31626
  mesh.name = "board-stiffener";
31553
31627
  configureObjectShadows(mesh);
31554
31628
  geometry.push(mesh);
31555
31629
  }
31556
- const bounds = new THREE57.Box3();
31630
+ const bounds = new THREE58.Box3();
31557
31631
  for (const mesh of [...geometry, ...textures]) bounds.expandByObject(mesh);
31558
31632
  return {
31559
31633
  geometryMeshes: geometry,
@@ -31570,11 +31644,11 @@ function createFlexMeshes(geometryMeshes, textureMeshes, json, foldPcbs) {
31570
31644
  }
31571
31645
 
31572
31646
  // src/utils/manifold/create-three-geometry-meshes.ts
31573
- import * as THREE59 from "three";
31647
+ import * as THREE60 from "three";
31574
31648
 
31575
31649
  // src/utils/create-board-material.ts
31576
- import * as THREE58 from "three";
31577
- var DEFAULT_SIDE = THREE58.DoubleSide;
31650
+ import * as THREE59 from "three";
31651
+ var DEFAULT_SIDE = THREE59.DoubleSide;
31578
31652
  var createBoardMaterial = ({
31579
31653
  material,
31580
31654
  color,
@@ -31582,7 +31656,7 @@ var createBoardMaterial = ({
31582
31656
  isFaux = false
31583
31657
  }) => {
31584
31658
  if (material === "fr4") {
31585
- return new THREE58.MeshPhysicalMaterial({
31659
+ return new THREE59.MeshPhysicalMaterial({
31586
31660
  color,
31587
31661
  side,
31588
31662
  metalness: 0,
@@ -31600,7 +31674,7 @@ var createBoardMaterial = ({
31600
31674
  polygonOffsetUnits: 1
31601
31675
  });
31602
31676
  }
31603
- return new THREE58.MeshStandardMaterial({
31677
+ return new THREE59.MeshStandardMaterial({
31604
31678
  color,
31605
31679
  side,
31606
31680
  flatShading: true,
@@ -31619,12 +31693,12 @@ function createGeometryMeshes(geoms) {
31619
31693
  const meshes = [];
31620
31694
  if (!geoms) return meshes;
31621
31695
  if (geoms.board?.geometry) {
31622
- const mesh = new THREE59.Mesh(
31696
+ const mesh = new THREE60.Mesh(
31623
31697
  geoms.board.geometry,
31624
31698
  createBoardMaterial({
31625
31699
  material: geoms.board.material,
31626
31700
  color: geoms.board.color,
31627
- side: THREE59.DoubleSide,
31701
+ side: THREE60.DoubleSide,
31628
31702
  isFaux: geoms.board.isFaux
31629
31703
  })
31630
31704
  );
@@ -31635,11 +31709,11 @@ function createGeometryMeshes(geoms) {
31635
31709
  const createMeshesFromArray = (geomArray) => {
31636
31710
  if (geomArray) {
31637
31711
  for (const comp of geomArray) {
31638
- const mesh = new THREE59.Mesh(
31712
+ const mesh = new THREE60.Mesh(
31639
31713
  comp.geometry,
31640
- new THREE59.MeshStandardMaterial({
31714
+ new THREE60.MeshStandardMaterial({
31641
31715
  color: comp.color,
31642
- side: THREE59.DoubleSide,
31716
+ side: THREE60.DoubleSide,
31643
31717
  flatShading: true
31644
31718
  // Consistent with board
31645
31719
  })
@@ -31683,7 +31757,7 @@ function loadManifold() {
31683
31757
  }
31684
31758
 
31685
31759
  // src/CadViewerManifold.tsx
31686
- import { jsx as jsx22, jsxs as jsxs7 } from "react/jsx-runtime";
31760
+ import { jsx as jsx23, jsxs as jsxs7 } from "react/jsx-runtime";
31687
31761
  var BoardMeshes = ({
31688
31762
  geometryMeshes,
31689
31763
  textureMeshes
@@ -31711,14 +31785,14 @@ var BoardMeshes = ({
31711
31785
  const typedMaterial = material;
31712
31786
  for (const prop of textureProps) {
31713
31787
  const texture = typedMaterial[prop];
31714
- if (texture && texture instanceof THREE60.Texture) {
31788
+ if (texture && texture instanceof THREE61.Texture) {
31715
31789
  texture.dispose();
31716
31790
  }
31717
31791
  }
31718
31792
  material.dispose();
31719
31793
  }
31720
31794
  };
31721
- useEffect34(() => {
31795
+ useEffect35(() => {
31722
31796
  if (!rootObject) return;
31723
31797
  for (const mesh of geometryMeshes) {
31724
31798
  let shouldShow = true;
@@ -31740,7 +31814,7 @@ var BoardMeshes = ({
31740
31814
  }
31741
31815
  };
31742
31816
  }, [rootObject, geometryMeshes, visibility]);
31743
- useEffect34(() => {
31817
+ useEffect35(() => {
31744
31818
  if (!rootObject) return;
31745
31819
  for (const mesh of textureMeshes) {
31746
31820
  rootObject.add(mesh);
@@ -31766,17 +31840,17 @@ var CadViewerManifold = ({
31766
31840
  onCameraControllerReady,
31767
31841
  resolveStaticAsset,
31768
31842
  referenceObject,
31769
- hiddenCadComponentIds
31843
+ objectVisibility
31770
31844
  }) => {
31771
31845
  const childrenCircuitJson = useConvertChildrenToCircuitJson(children);
31772
- const circuitJson = useMemo28(() => {
31846
+ const circuitJson = useMemo29(() => {
31773
31847
  const rawCircuitJson = circuitJsonProp ?? childrenCircuitJson;
31774
31848
  return addFauxBoardIfNeeded(rawCircuitJson);
31775
31849
  }, [circuitJsonProp, childrenCircuitJson]);
31776
31850
  const [manifoldJSModule, setManifoldJSModule] = useState21(null);
31777
31851
  const [manifoldLoadingError, setManifoldLoadingError] = useState21(null);
31778
31852
  const { visibility } = useLayerVisibility();
31779
- useEffect34(() => {
31853
+ useEffect35(() => {
31780
31854
  let isActive = true;
31781
31855
  loadManifold().then((module) => {
31782
31856
  if (isActive) setManifoldJSModule(module);
@@ -31800,7 +31874,7 @@ var CadViewerManifold = ({
31800
31874
  boardData,
31801
31875
  isFauxBoard
31802
31876
  } = useManifoldBoardBuilder(manifoldJSModule, circuitJson, visibility);
31803
- const flex = useMemo28(() => {
31877
+ const flex = useMemo29(() => {
31804
31878
  try {
31805
31879
  const resolvedFoldPcbs = resolveFoldPcbs(circuitJson, foldPcbs);
31806
31880
  const posedJson = transformCircuitJsonCadComponents(circuitJson, {
@@ -31831,28 +31905,32 @@ var CadViewerManifold = ({
31831
31905
  circuitJson,
31832
31906
  foldPcbs
31833
31907
  ]);
31834
- const cadComponents = useMemo28(
31835
- () => su17(flex.posedJson).cad_component.list().filter((cad) => !hiddenCadComponentIds?.has(cad.cad_component_id)),
31836
- [flex.posedJson, hiddenCadComponentIds]
31908
+ const cadComponents = useMemo29(
31909
+ () => su17(flex.posedJson).cad_component.list().filter(
31910
+ (cad) => !isObjectHidden(objectVisibility, cad.cad_component_id)
31911
+ ),
31912
+ [flex.posedJson, objectVisibility]
31837
31913
  );
31838
- const cadCables = useMemo28(
31839
- () => getCadCables(flex.posedJson),
31840
- [flex.posedJson]
31914
+ const cadCables = useMemo29(
31915
+ () => getCadCables(flex.posedJson).filter(
31916
+ (cable) => !isObjectHidden(objectVisibility, cable.cad_cable_id)
31917
+ ),
31918
+ [flex.posedJson, objectVisibility]
31841
31919
  );
31842
- const boardDimensions = useMemo28(() => {
31920
+ const boardDimensions = useMemo29(() => {
31843
31921
  if (!boardData) return void 0;
31844
31922
  const bounds = calculateOutlineBounds(boardData);
31845
31923
  return { width: bounds.width, height: bounds.height };
31846
31924
  }, [boardData]);
31847
- const boardCenter = useMemo28(() => {
31925
+ const boardCenter = useMemo29(() => {
31848
31926
  if (!boardData) return void 0;
31849
31927
  const bounds = calculateOutlineBounds(boardData);
31850
31928
  return { x: bounds.centerX, y: bounds.centerY };
31851
31929
  }, [boardData]);
31852
- const initialCameraPosition = useMemo28(() => {
31930
+ const initialCameraPosition = useMemo29(() => {
31853
31931
  return getInitialCameraPosition({ boardDimensions, boardCenter });
31854
31932
  }, [boardDimensions, boardCenter]);
31855
- const cameraSessionScope = useMemo28(() => {
31933
+ const cameraSessionScope = useMemo29(() => {
31856
31934
  if (!boardData) return void 0;
31857
31935
  return JSON.stringify({
31858
31936
  pcbBoardId: boardData.pcb_board_id,
@@ -31878,7 +31956,7 @@ var CadViewerManifold = ({
31878
31956
  );
31879
31957
  }
31880
31958
  if (!manifoldJSModule) {
31881
- return /* @__PURE__ */ jsx22("div", { style: { padding: "1em" }, children: "Loading Manifold module..." });
31959
+ return /* @__PURE__ */ jsx23("div", { style: { padding: "1em" }, children: "Loading Manifold module..." });
31882
31960
  }
31883
31961
  if (builderError || flex.error) {
31884
31962
  return /* @__PURE__ */ jsxs7(
@@ -31899,7 +31977,7 @@ var CadViewerManifold = ({
31899
31977
  );
31900
31978
  }
31901
31979
  if (builderIsLoading) {
31902
- return /* @__PURE__ */ jsx22("div", { style: { padding: "1em" }, children: "Processing board geometry..." });
31980
+ return /* @__PURE__ */ jsx23("div", { style: { padding: "1em" }, children: "Processing board geometry..." });
31903
31981
  }
31904
31982
  return /* @__PURE__ */ jsxs7(
31905
31983
  CadViewerContainer,
@@ -31914,19 +31992,26 @@ var CadViewerManifold = ({
31914
31992
  onUserInteraction,
31915
31993
  onCameraControllerReady,
31916
31994
  children: [
31917
- /* @__PURE__ */ jsx22(
31918
- BoardMeshes,
31995
+ /* @__PURE__ */ jsx23(
31996
+ BoardGroup,
31919
31997
  {
31920
- geometryMeshes: flex.geometryMeshes,
31921
- textureMeshes: flex.textureMeshes
31998
+ pcbBoardId: boardData?.pcb_board_id,
31999
+ hidden: isObjectHidden(objectVisibility, boardData?.pcb_board_id),
32000
+ children: /* @__PURE__ */ jsx23(
32001
+ BoardMeshes,
32002
+ {
32003
+ geometryMeshes: flex.geometryMeshes,
32004
+ textureMeshes: flex.textureMeshes
32005
+ }
32006
+ )
31922
32007
  }
31923
32008
  ),
31924
- flex.bounds && /* @__PURE__ */ jsx22(FitCameraToComparison, { bounds: flex.bounds }),
31925
- cadComponents.map((cad_component) => /* @__PURE__ */ jsx22(
32009
+ flex.bounds && /* @__PURE__ */ jsx23(FitCameraToComparison, { bounds: flex.bounds }),
32010
+ cadComponents.map((cad_component) => /* @__PURE__ */ jsx23(
31926
32011
  ThreeErrorBoundary,
31927
32012
  {
31928
- fallback: ({ error }) => /* @__PURE__ */ jsx22(Error3d, { cad_component, error }),
31929
- children: /* @__PURE__ */ jsx22(
32013
+ fallback: ({ error }) => /* @__PURE__ */ jsx23(Error3d, { cad_component, error }),
32014
+ children: /* @__PURE__ */ jsx23(
31930
32015
  AnyCadComponent,
31931
32016
  {
31932
32017
  cad_component,
@@ -31937,7 +32022,7 @@ var CadViewerManifold = ({
31937
32022
  },
31938
32023
  cad_component.cad_component_id
31939
32024
  )),
31940
- cadCables.map((cable) => /* @__PURE__ */ jsx22(CadCable, { cable }, cable.cad_cable_id))
32025
+ cadCables.map((cable) => /* @__PURE__ */ jsx23(CadCable, { cable }, cable.cad_cable_id))
31941
32026
  ]
31942
32027
  }
31943
32028
  );
@@ -31945,14 +32030,14 @@ var CadViewerManifold = ({
31945
32030
  var CadViewerManifold_default = CadViewerManifold;
31946
32031
 
31947
32032
  // src/CadViewerGlb.tsx
31948
- import { useEffect as useEffect36, useMemo as useMemo30, useState as useState23 } from "react";
32033
+ import { useEffect as useEffect37, useMemo as useMemo31, useState as useState23 } from "react";
31949
32034
 
31950
32035
  // src/hooks/useGlbModel.ts
31951
- import { useEffect as useEffect35, useMemo as useMemo29, useState as useState22 } from "react";
32036
+ import { useEffect as useEffect36, useMemo as useMemo30, useState as useState22 } from "react";
31952
32037
  function useGlbModel(source) {
31953
- const request = useMemo29(() => ({ source }), [source]);
32038
+ const request = useMemo30(() => ({ source }), [source]);
31954
32039
  const [result, setResult] = useState22();
31955
- useEffect35(() => {
32040
+ useEffect36(() => {
31956
32041
  const controller = new AbortController();
31957
32042
  let model;
31958
32043
  loadGlbScene(request.source, controller.signal).then((loaded) => {
@@ -31975,17 +32060,17 @@ function useGlbModel(source) {
31975
32060
  }
31976
32061
 
31977
32062
  // src/CadViewerGlb.tsx
31978
- import * as THREE61 from "three";
31979
- import { Fragment as Fragment5, jsx as jsx23, jsxs as jsxs8 } from "react/jsx-runtime";
32063
+ import * as THREE62 from "three";
32064
+ import { Fragment as Fragment5, jsx as jsx24, jsxs as jsxs8 } from "react/jsx-runtime";
31980
32065
  function GlbScene({
31981
32066
  model,
31982
- hiddenCadComponentIds
32067
+ objectVisibility
31983
32068
  }) {
31984
32069
  const { rootObject } = useThree();
31985
32070
  const { addHoverable, removeHoverable } = useHover();
31986
32071
  const [hover, setHover] = useState23();
31987
- const bounds = useMemo30(() => {
31988
- const box = new THREE61.Box3().setFromObject(model);
32072
+ const bounds = useMemo31(() => {
32073
+ const box = new THREE62.Box3().setFromObject(model);
31989
32074
  if (box.isEmpty()) return;
31990
32075
  return {
31991
32076
  minX: box.min.x,
@@ -31996,24 +32081,29 @@ function GlbScene({
31996
32081
  maxZ: box.max.z
31997
32082
  };
31998
32083
  }, [model]);
31999
- useEffect36(() => {
32084
+ useEffect37(() => {
32000
32085
  rootObject.add(model);
32001
32086
  return () => {
32002
32087
  rootObject.remove(model);
32003
32088
  };
32004
32089
  }, [rootObject, model]);
32005
- useEffect36(() => {
32090
+ useEffect37(() => {
32006
32091
  setHover(void 0);
32007
- model.traverse((object) => {
32092
+ const applyVisibility = (object, inComponent) => {
32008
32093
  const id = object.userData.cad_component_id;
32009
32094
  if (typeof id === "string")
32010
- object.visible = !hiddenCadComponentIds?.has(id);
32011
- });
32012
- }, [model, hiddenCadComponentIds]);
32013
- useEffect36(() => {
32095
+ object.visible = !isObjectHidden(objectVisibility, id);
32096
+ else if (!inComponent && object instanceof THREE62.Mesh)
32097
+ object.visible = !isObjectHidden(objectVisibility, void 0);
32098
+ for (const child of object.children)
32099
+ applyVisibility(child, inComponent || typeof id === "string");
32100
+ };
32101
+ applyVisibility(model, false);
32102
+ }, [model, objectVisibility]);
32103
+ useEffect37(() => {
32014
32104
  const meshes = [];
32015
32105
  model.traverse((mesh) => {
32016
- if (!(mesh instanceof THREE61.Mesh)) return;
32106
+ if (!(mesh instanceof THREE62.Mesh)) return;
32017
32107
  let ancestor = mesh;
32018
32108
  while (ancestor) {
32019
32109
  if (!ancestor.visible) return;
@@ -32041,10 +32131,10 @@ function GlbScene({
32041
32131
  return () => {
32042
32132
  for (const mesh of meshes) removeHoverable(mesh);
32043
32133
  };
32044
- }, [model, hiddenCadComponentIds, addHoverable, removeHoverable]);
32134
+ }, [model, objectVisibility, addHoverable, removeHoverable]);
32045
32135
  return /* @__PURE__ */ jsxs8(Fragment5, { children: [
32046
- bounds && /* @__PURE__ */ jsx23(FitCameraToComparison, { bounds }),
32047
- hover && /* @__PURE__ */ jsx23(
32136
+ bounds && /* @__PURE__ */ jsx24(FitCameraToComparison, { bounds }),
32137
+ hover && /* @__PURE__ */ jsx24(
32048
32138
  Html,
32049
32139
  {
32050
32140
  position: hover.position,
@@ -32063,13 +32153,13 @@ function GlbScene({
32063
32153
  }
32064
32154
  function CadViewerGlb({
32065
32155
  source,
32066
- hiddenCadComponentIds,
32156
+ objectVisibility,
32067
32157
  ...containerProps
32068
32158
  }) {
32069
32159
  const result = useGlbModel(source);
32070
- const framing = useMemo30(() => {
32160
+ const framing = useMemo31(() => {
32071
32161
  if (!result?.model) return void 0;
32072
- const bounds = new THREE61.Box3().setFromObject(result.model);
32162
+ const bounds = new THREE62.Box3().setFromObject(result.model);
32073
32163
  if (bounds.isEmpty()) return void 0;
32074
32164
  return {
32075
32165
  boardDimensions: {
@@ -32082,20 +32172,14 @@ function CadViewerGlb({
32082
32172
  }
32083
32173
  };
32084
32174
  }, [result, source]);
32085
- if (!result) return /* @__PURE__ */ jsx23("div", { role: "status", children: "Loading 3D view..." });
32175
+ if (!result) return /* @__PURE__ */ jsx24("div", { role: "status", children: "Loading 3D view..." });
32086
32176
  if (result.error)
32087
32177
  return /* @__PURE__ */ jsxs8("div", { role: "alert", children: [
32088
32178
  "Unable to load 3D view: ",
32089
32179
  result.error
32090
32180
  ] });
32091
32181
  if (!result.model) return null;
32092
- return /* @__PURE__ */ jsx23(CadViewerContainer, { ...containerProps, ...framing, children: /* @__PURE__ */ jsx23(
32093
- GlbScene,
32094
- {
32095
- model: result.model,
32096
- hiddenCadComponentIds
32097
- }
32098
- ) });
32182
+ return /* @__PURE__ */ jsx24(CadViewerContainer, { ...containerProps, ...framing, children: /* @__PURE__ */ jsx24(GlbScene, { model: result.model, objectVisibility }) });
32099
32183
  }
32100
32184
 
32101
32185
  // node_modules/@radix-ui/react-dropdown-menu/dist/index.mjs
@@ -32197,7 +32281,7 @@ __name2(useComposedRefs, "useComposedRefs");
32197
32281
 
32198
32282
  // node_modules/@radix-ui/react-context/dist/index.mjs
32199
32283
  import * as React12 from "react";
32200
- import { jsx as jsx24 } from "react/jsx-runtime";
32284
+ import { jsx as jsx25 } from "react/jsx-runtime";
32201
32285
  var __defProp4 = Object.defineProperty;
32202
32286
  var __name3 = (target, value) => __defProp4(target, "name", { value, configurable: true });
32203
32287
  // @__NO_SIDE_EFFECTS__
@@ -32207,7 +32291,7 @@ function createContext22(rootComponentName, defaultContext) {
32207
32291
  const Provider = /* @__PURE__ */ __name3((props) => {
32208
32292
  const { children, ...context } = props;
32209
32293
  const value = React12.useMemo(() => context, Object.values(context));
32210
- return /* @__PURE__ */ jsx24(Context.Provider, { value, children });
32294
+ return /* @__PURE__ */ jsx25(Context.Provider, { value, children });
32211
32295
  }, "Provider");
32212
32296
  Provider.displayName = rootComponentName + "Provider";
32213
32297
  function useContext22(consumerName, options = {}) {
@@ -32234,7 +32318,7 @@ function createContextScope(scopeName, createContextScopeDeps = []) {
32234
32318
  const { scope, children, ...context } = props;
32235
32319
  const Context = scope?.[scopeName]?.[index2] || BaseContext;
32236
32320
  const value = React12.useMemo(() => context, Object.values(context));
32237
- return /* @__PURE__ */ jsx24(Context.Provider, { value, children });
32321
+ return /* @__PURE__ */ jsx25(Context.Provider, { value, children });
32238
32322
  }, "Provider");
32239
32323
  Provider.displayName = rootComponentName + "Provider";
32240
32324
  function useContext22(consumerName, scope, options = {}) {
@@ -32619,7 +32703,7 @@ var createSlottableError = /* @__PURE__ */ __name6((ownerName) => {
32619
32703
  var use = React16[" use ".trim().toString()];
32620
32704
 
32621
32705
  // node_modules/@radix-ui/react-primitive/dist/index.mjs
32622
- import { jsx as jsx25 } from "react/jsx-runtime";
32706
+ import { jsx as jsx26 } from "react/jsx-runtime";
32623
32707
  var __defProp8 = Object.defineProperty;
32624
32708
  var __name7 = (target, value) => __defProp8(target, "name", { value, configurable: true });
32625
32709
  var NODES = [
@@ -32649,7 +32733,7 @@ var Primitive = NODES.reduce((primitive, node) => {
32649
32733
  if (typeof window !== "undefined") {
32650
32734
  window[/* @__PURE__ */ Symbol.for("radix-ui")] = true;
32651
32735
  }
32652
- return /* @__PURE__ */ jsx25(Comp, { ...primitiveProps, ref: forwardedRef });
32736
+ return /* @__PURE__ */ jsx26(Comp, { ...primitiveProps, ref: forwardedRef });
32653
32737
  });
32654
32738
  Node2.displayName = `Primitive.${node}`;
32655
32739
  return { ...primitive, [node]: Node2 };
@@ -32664,9 +32748,9 @@ import * as React41 from "react";
32664
32748
 
32665
32749
  // node_modules/@radix-ui/react-collection/dist/index.mjs
32666
32750
  import * as React18 from "react";
32667
- import { jsx as jsx26 } from "react/jsx-runtime";
32668
- import * as React23 from "react";
32669
32751
  import { jsx as jsx27 } from "react/jsx-runtime";
32752
+ import * as React23 from "react";
32753
+ import { jsx as jsx28 } from "react/jsx-runtime";
32670
32754
  var __defProp9 = Object.defineProperty;
32671
32755
  var __name8 = (target, value) => __defProp9(target, "name", { value, configurable: true });
32672
32756
  // @__NO_SIDE_EFFECTS__
@@ -32681,7 +32765,7 @@ function createCollection(name) {
32681
32765
  const { scope, children } = props;
32682
32766
  const ref = React18.useRef(null);
32683
32767
  const itemMap = React18.useRef(/* @__PURE__ */ new Map()).current;
32684
- return /* @__PURE__ */ jsx26(CollectionProviderImpl, { scope, itemMap, collectionRef: ref, children });
32768
+ return /* @__PURE__ */ jsx27(CollectionProviderImpl, { scope, itemMap, collectionRef: ref, children });
32685
32769
  }, "CollectionProvider");
32686
32770
  CollectionProvider.displayName = PROVIDER_NAME;
32687
32771
  const COLLECTION_SLOT_NAME = name + "CollectionSlot";
@@ -32691,7 +32775,7 @@ function createCollection(name) {
32691
32775
  const { scope, children } = props;
32692
32776
  const context = useCollectionContext(COLLECTION_SLOT_NAME, scope);
32693
32777
  const composedRefs = useComposedRefs(forwardedRef, context.collectionRef);
32694
- return /* @__PURE__ */ jsx26(CollectionSlotImpl, { ref: composedRefs, children });
32778
+ return /* @__PURE__ */ jsx27(CollectionSlotImpl, { ref: composedRefs, children });
32695
32779
  }
32696
32780
  );
32697
32781
  CollectionSlot.displayName = COLLECTION_SLOT_NAME;
@@ -32708,7 +32792,7 @@ function createCollection(name) {
32708
32792
  context.itemMap.set(ref, { ref, ...itemData });
32709
32793
  return () => void context.itemMap.delete(ref);
32710
32794
  });
32711
- return /* @__PURE__ */ jsx26(CollectionItemSlotImpl, { ...{ [ITEM_DATA_ATTR]: "" }, ref: composedRefs, children });
32795
+ return /* @__PURE__ */ jsx27(CollectionItemSlotImpl, { ...{ [ITEM_DATA_ATTR]: "" }, ref: composedRefs, children });
32712
32796
  }
32713
32797
  );
32714
32798
  CollectionItemSlot.displayName = ITEM_SLOT_NAME;
@@ -33064,12 +33148,12 @@ function createCollection2(name) {
33064
33148
  const [CollectionStatefulContextProvider, useStatefulCollectionContext] = createCollectionContext(PROVIDER_NAME);
33065
33149
  CollectionStatefulContextProvider.displayName = name + "CollectionStatefulContextProvider";
33066
33150
  const CollectionProvider = /* @__PURE__ */ __name8(({ state, ...props }) => {
33067
- return state ? /* @__PURE__ */ jsx27(CollectionProviderImpl, { ...props, state }) : /* @__PURE__ */ jsx27(CollectionInit, { ...props });
33151
+ return state ? /* @__PURE__ */ jsx28(CollectionProviderImpl, { ...props, state }) : /* @__PURE__ */ jsx28(CollectionInit, { ...props });
33068
33152
  }, "CollectionProvider");
33069
33153
  CollectionProvider.displayName = PROVIDER_NAME;
33070
33154
  const CollectionInit = /* @__PURE__ */ __name8((props) => {
33071
33155
  const state = useInitCollection();
33072
- return /* @__PURE__ */ jsx27(CollectionProviderImpl, { ...props, state });
33156
+ return /* @__PURE__ */ jsx28(CollectionProviderImpl, { ...props, state });
33073
33157
  }, "CollectionInit");
33074
33158
  CollectionInit.displayName = name + "CollectionInit";
33075
33159
  const CollectionProviderImpl = /* @__PURE__ */ __name8((props) => {
@@ -33109,7 +33193,7 @@ function createCollection2(name) {
33109
33193
  observer.disconnect();
33110
33194
  };
33111
33195
  }, [collectionElement, setCollection]);
33112
- return /* @__PURE__ */ jsx27(
33196
+ return /* @__PURE__ */ jsx28(
33113
33197
  CollectionStableContextProvider,
33114
33198
  {
33115
33199
  scope,
@@ -33118,7 +33202,7 @@ function createCollection2(name) {
33118
33202
  getCollection,
33119
33203
  setCollection,
33120
33204
  registryRef,
33121
- children: /* @__PURE__ */ jsx27(
33205
+ children: /* @__PURE__ */ jsx28(
33122
33206
  CollectionStatefulContextProvider,
33123
33207
  {
33124
33208
  scope,
@@ -33138,7 +33222,7 @@ function createCollection2(name) {
33138
33222
  const { scope, children } = props;
33139
33223
  const context = useStableCollectionContext(COLLECTION_SLOT_NAME, scope);
33140
33224
  const composedRefs = useComposedRefs(forwardedRef, context.collectionElementRef);
33141
- return /* @__PURE__ */ jsx27(CollectionSlotImpl, { ref: composedRefs, children });
33225
+ return /* @__PURE__ */ jsx28(CollectionSlotImpl, { ref: composedRefs, children });
33142
33226
  }
33143
33227
  );
33144
33228
  CollectionSlot.displayName = COLLECTION_SLOT_NAME;
@@ -33214,7 +33298,7 @@ function createCollection2(name) {
33214
33298
  });
33215
33299
  };
33216
33300
  }, [setCollection]);
33217
- return /* @__PURE__ */ jsx27(CollectionItemSlotImpl, { ...{ [ITEM_DATA_ATTR]: "" }, ref: composedRefs, children });
33301
+ return /* @__PURE__ */ jsx28(CollectionItemSlotImpl, { ...{ [ITEM_DATA_ATTR]: "" }, ref: composedRefs, children });
33218
33302
  }
33219
33303
  );
33220
33304
  CollectionItemSlot.displayName = ITEM_SLOT_NAME;
@@ -33295,7 +33379,7 @@ __name8(getChildListObserver, "getChildListObserver");
33295
33379
 
33296
33380
  // node_modules/@radix-ui/react-direction/dist/index.mjs
33297
33381
  import * as React19 from "react";
33298
- import { jsx as jsx28 } from "react/jsx-runtime";
33382
+ import { jsx as jsx29 } from "react/jsx-runtime";
33299
33383
  var __defProp10 = Object.defineProperty;
33300
33384
  var __name9 = (target, value) => __defProp10(target, "name", { value, configurable: true });
33301
33385
  var Direction = {
@@ -33333,7 +33417,7 @@ function useCallbackRef(callback) {
33333
33417
  __name10(useCallbackRef, "useCallbackRef");
33334
33418
 
33335
33419
  // node_modules/@radix-ui/react-dismissable-layer/dist/index.mjs
33336
- import { jsx as jsx29 } from "react/jsx-runtime";
33420
+ import { jsx as jsx30 } from "react/jsx-runtime";
33337
33421
  var __defProp12 = Object.defineProperty;
33338
33422
  var __name11 = (target, value) => __defProp12(target, "name", { value, configurable: true });
33339
33423
  var CONTEXT_UPDATE = "dismissableLayer.update";
@@ -33465,7 +33549,7 @@ var DismissableLayer = /* @__PURE__ */ React21.forwardRef(
33465
33549
  document.addEventListener(CONTEXT_UPDATE, handleUpdate);
33466
33550
  return () => document.removeEventListener(CONTEXT_UPDATE, handleUpdate);
33467
33551
  }, []);
33468
- return /* @__PURE__ */ jsx29(
33552
+ return /* @__PURE__ */ jsx30(
33469
33553
  Primitive.div,
33470
33554
  {
33471
33555
  ...layerProps,
@@ -33714,7 +33798,7 @@ __name12(createFocusGuard, "createFocusGuard");
33714
33798
 
33715
33799
  // node_modules/@radix-ui/react-focus-scope/dist/index.mjs
33716
33800
  import * as React25 from "react";
33717
- import { jsx as jsx30 } from "react/jsx-runtime";
33801
+ import { jsx as jsx31 } from "react/jsx-runtime";
33718
33802
  var __defProp14 = Object.defineProperty;
33719
33803
  var __name13 = (target, value) => __defProp14(target, "name", { value, configurable: true });
33720
33804
  var AUTOFOCUS_ON_MOUNT = "focusScope.autoFocusOnMount";
@@ -33853,7 +33937,7 @@ var FocusScope = /* @__PURE__ */ React25.forwardRef(
33853
33937
  },
33854
33938
  [loop, trapped, focusScope.paused]
33855
33939
  );
33856
- return /* @__PURE__ */ jsx30(Primitive.div, { tabIndex: -1, ...scopeProps, ref: composedRefs, onKeyDown: handleKeyDown });
33940
+ return /* @__PURE__ */ jsx31(Primitive.div, { tabIndex: -1, ...scopeProps, ref: composedRefs, onKeyDown: handleKeyDown });
33857
33941
  }, "FocusScope")
33858
33942
  );
33859
33943
  var FocusScopeBranchContext = React25.createContext(null);
@@ -33861,7 +33945,7 @@ function FocusScopeBranchProvider({ registry, children }) {
33861
33945
  if (!registry) {
33862
33946
  return children;
33863
33947
  }
33864
- return /* @__PURE__ */ jsx30(FocusScopeBranchContext.Provider, { value: registry, children });
33948
+ return /* @__PURE__ */ jsx31(FocusScopeBranchContext.Provider, { value: registry, children });
33865
33949
  }
33866
33950
  __name13(FocusScopeBranchProvider, "FocusScopeBranchProvider");
33867
33951
  function useFocusScopeBranchRegistry() {
@@ -35954,7 +36038,7 @@ function useSize(element) {
35954
36038
  __name15(useSize, "useSize");
35955
36039
 
35956
36040
  // node_modules/@radix-ui/react-popper/dist/index.mjs
35957
- import { jsx as jsx31 } from "react/jsx-runtime";
36041
+ import { jsx as jsx32 } from "react/jsx-runtime";
35958
36042
  var __defProp17 = Object.defineProperty;
35959
36043
  var __name16 = (target, value) => __defProp17(target, "name", { value, configurable: true });
35960
36044
  var Sticky = {
@@ -35972,7 +36056,7 @@ var Popper = /* @__PURE__ */ __name16((props) => {
35972
36056
  const { __scopePopper, children } = props;
35973
36057
  const [anchor, setAnchor] = React29.useState(null);
35974
36058
  const [placementState, setPlacementState] = React29.useState(void 0);
35975
- return /* @__PURE__ */ jsx31(
36059
+ return /* @__PURE__ */ jsx32(
35976
36060
  PopperProvider,
35977
36061
  {
35978
36062
  scope: __scopePopper,
@@ -36015,7 +36099,7 @@ var PopperAnchor = /* @__PURE__ */ React29.forwardRef(
36015
36099
  const sideAndAlign = context.placementState && getSideAndAlignFromPlacement(context.placementState);
36016
36100
  const placedSide = sideAndAlign?.[0];
36017
36101
  const placedAlign = sideAndAlign?.[1];
36018
- return virtualRef ? null : /* @__PURE__ */ jsx31(
36102
+ return virtualRef ? null : /* @__PURE__ */ jsx32(
36019
36103
  Primitive.div,
36020
36104
  {
36021
36105
  "data-radix-popper-side": placedSide,
@@ -36139,7 +36223,7 @@ var PopperContent = /* @__PURE__ */ React29.forwardRef(
36139
36223
  useLayoutEffect2(() => {
36140
36224
  if (content) setContentZIndex(window.getComputedStyle(content).zIndex);
36141
36225
  }, [content]);
36142
- return /* @__PURE__ */ jsx31(
36226
+ return /* @__PURE__ */ jsx32(
36143
36227
  "div",
36144
36228
  {
36145
36229
  ref: refs.setFloating,
@@ -36163,7 +36247,7 @@ var PopperContent = /* @__PURE__ */ React29.forwardRef(
36163
36247
  }
36164
36248
  },
36165
36249
  dir: props.dir,
36166
- children: /* @__PURE__ */ jsx31(
36250
+ children: /* @__PURE__ */ jsx32(
36167
36251
  PopperContentProvider,
36168
36252
  {
36169
36253
  scope: __scopePopper,
@@ -36173,7 +36257,7 @@ var PopperContent = /* @__PURE__ */ React29.forwardRef(
36173
36257
  arrowX,
36174
36258
  arrowY,
36175
36259
  shouldHideArrow: cannotCenterArrow,
36176
- children: /* @__PURE__ */ jsx31(
36260
+ children: /* @__PURE__ */ jsx32(
36177
36261
  Primitive.div,
36178
36262
  {
36179
36263
  "data-side": placedSide,
@@ -36239,7 +36323,7 @@ __name16(getSideAndAlignFromPlacement, "getSideAndAlignFromPlacement");
36239
36323
  // node_modules/@radix-ui/react-portal/dist/index.mjs
36240
36324
  import * as React30 from "react";
36241
36325
  import * as ReactDOM4 from "react-dom";
36242
- import { jsx as jsx32 } from "react/jsx-runtime";
36326
+ import { jsx as jsx33 } from "react/jsx-runtime";
36243
36327
  var __defProp18 = Object.defineProperty;
36244
36328
  var __name17 = (target, value) => __defProp18(target, "name", { value, configurable: true });
36245
36329
  var Portal = /* @__PURE__ */ React30.forwardRef(
@@ -36248,7 +36332,7 @@ var Portal = /* @__PURE__ */ React30.forwardRef(
36248
36332
  const [mounted, setMounted] = React30.useState(false);
36249
36333
  useLayoutEffect2(() => setMounted(true), []);
36250
36334
  const container = containerProp || mounted && globalThis?.document?.body;
36251
- return container ? ReactDOM4.createPortal(/* @__PURE__ */ jsx32(Primitive.div, { ...portalProps, ref: forwardedRef }), container) : null;
36335
+ return container ? ReactDOM4.createPortal(/* @__PURE__ */ jsx33(Primitive.div, { ...portalProps, ref: forwardedRef }), container) : null;
36252
36336
  }, "Portal")
36253
36337
  );
36254
36338
 
@@ -36468,7 +36552,7 @@ __name19(useIsHydratedModern, "useIsHydratedModern");
36468
36552
  var useIsHydrated2 = typeof useReactSyncExternalStore === "function" ? useIsHydratedModern : useIsHydrated;
36469
36553
 
36470
36554
  // node_modules/@radix-ui/react-roving-focus/dist/index.mjs
36471
- import { jsx as jsx33 } from "react/jsx-runtime";
36555
+ import { jsx as jsx34 } from "react/jsx-runtime";
36472
36556
  var __defProp21 = Object.defineProperty;
36473
36557
  var __name20 = (target, value) => __defProp21(target, "name", { value, configurable: true });
36474
36558
  var ENTRY_FOCUS = "rovingFocusGroup.onEntryFocus";
@@ -36491,7 +36575,7 @@ var [RovingFocusProvider, useRovingFocusContext] = createRovingFocusGroupContext
36491
36575
  var RovingFocusGroup = /* @__PURE__ */ React33.forwardRef(
36492
36576
  // blank line to reduce diff noise
36493
36577
  /* @__PURE__ */ __name20(function RovingFocusGroup2(props, forwardedRef) {
36494
- return /* @__PURE__ */ jsx33(Collection.Provider, { scope: props.__scopeRovingFocusGroup, children: /* @__PURE__ */ jsx33(Collection.Slot, { scope: props.__scopeRovingFocusGroup, children: /* @__PURE__ */ jsx33(RovingFocusGroupImpl, { ...props, ref: forwardedRef }) }) });
36578
+ return /* @__PURE__ */ jsx34(Collection.Provider, { scope: props.__scopeRovingFocusGroup, children: /* @__PURE__ */ jsx34(Collection.Slot, { scope: props.__scopeRovingFocusGroup, children: /* @__PURE__ */ jsx34(RovingFocusGroupImpl, { ...props, ref: forwardedRef }) }) });
36495
36579
  }, "RovingFocusGroup")
36496
36580
  );
36497
36581
  var RovingFocusGroupImpl = /* @__PURE__ */ React33.forwardRef(/* @__PURE__ */ __name20(function RovingFocusGroupImpl2(props, forwardedRef) {
@@ -36528,7 +36612,7 @@ var RovingFocusGroupImpl = /* @__PURE__ */ React33.forwardRef(/* @__PURE__ */ __
36528
36612
  return () => node.removeEventListener(ENTRY_FOCUS, handleEntryFocus);
36529
36613
  }
36530
36614
  }, [handleEntryFocus]);
36531
- return /* @__PURE__ */ jsx33(
36615
+ return /* @__PURE__ */ jsx34(
36532
36616
  RovingFocusProvider,
36533
36617
  {
36534
36618
  scope: __scopeRovingFocusGroup,
@@ -36549,7 +36633,7 @@ var RovingFocusGroupImpl = /* @__PURE__ */ React33.forwardRef(/* @__PURE__ */ __
36549
36633
  () => setFocusableItemsCount((prevCount) => prevCount - 1),
36550
36634
  []
36551
36635
  ),
36552
- children: /* @__PURE__ */ jsx33(
36636
+ children: /* @__PURE__ */ jsx34(
36553
36637
  Primitive.div,
36554
36638
  {
36555
36639
  tabIndex: isTabbingBackOut || focusableItemsCount === 0 ? -1 : 0,
@@ -36617,14 +36701,14 @@ var RovingFocusGroupItem = /* @__PURE__ */ React33.forwardRef(
36617
36701
  onFocusableItemAdd();
36618
36702
  return () => onFocusableItemRemove();
36619
36703
  }, [isHydrated, focusable, onFocusableItemAdd, onFocusableItemRemove]);
36620
- return /* @__PURE__ */ jsx33(
36704
+ return /* @__PURE__ */ jsx34(
36621
36705
  Collection.ItemSlot,
36622
36706
  {
36623
36707
  scope: __scopeRovingFocusGroup,
36624
36708
  id,
36625
36709
  focusable,
36626
36710
  active,
36627
- children: /* @__PURE__ */ jsx33(
36711
+ children: /* @__PURE__ */ jsx34(
36628
36712
  Primitive.span,
36629
36713
  {
36630
36714
  tabIndex: isCurrentTabStop ? 0 : -1,
@@ -37546,7 +37630,7 @@ ReactRemoveScroll.classNames = RemoveScroll.classNames;
37546
37630
  var Combination_default = ReactRemoveScroll;
37547
37631
 
37548
37632
  // node_modules/@radix-ui/react-menu/dist/index.mjs
37549
- import { jsx as jsx34 } from "react/jsx-runtime";
37633
+ import { jsx as jsx35 } from "react/jsx-runtime";
37550
37634
  var __defProp22 = Object.defineProperty;
37551
37635
  var __name21 = (target, value) => __defProp22(target, "name", { value, configurable: true });
37552
37636
  var Direction3 = {
@@ -37605,7 +37689,7 @@ var Menu = /* @__PURE__ */ __name21((props) => {
37605
37689
  window.addEventListener("blur", handleBlur);
37606
37690
  return () => window.removeEventListener("blur", handleBlur);
37607
37691
  }, [open, handleOpenChange]);
37608
- return /* @__PURE__ */ jsx34(Popper, { ...popperScope, children: /* @__PURE__ */ jsx34(
37692
+ return /* @__PURE__ */ jsx35(Popper, { ...popperScope, children: /* @__PURE__ */ jsx35(
37609
37693
  MenuProvider,
37610
37694
  {
37611
37695
  scope: __scopeMenu,
@@ -37613,7 +37697,7 @@ var Menu = /* @__PURE__ */ __name21((props) => {
37613
37697
  onOpenChange: handleOpenChange,
37614
37698
  content,
37615
37699
  onContentChange: setContent,
37616
- children: /* @__PURE__ */ jsx34(
37700
+ children: /* @__PURE__ */ jsx35(
37617
37701
  MenuRootProvider,
37618
37702
  {
37619
37703
  scope: __scopeMenu,
@@ -37631,7 +37715,7 @@ var MenuAnchor = /* @__PURE__ */ React41.forwardRef(
37631
37715
  /* @__PURE__ */ __name21(function MenuAnchor2(props, forwardedRef) {
37632
37716
  const { __scopeMenu, ...anchorProps } = props;
37633
37717
  const popperScope = usePopperScope(__scopeMenu);
37634
- return /* @__PURE__ */ jsx34(PopperAnchor, { ...popperScope, ...anchorProps, ref: forwardedRef });
37718
+ return /* @__PURE__ */ jsx35(PopperAnchor, { ...popperScope, ...anchorProps, ref: forwardedRef });
37635
37719
  }, "MenuAnchor")
37636
37720
  );
37637
37721
  var PORTAL_NAME = "MenuPortal";
@@ -37641,7 +37725,7 @@ var [PortalProvider, usePortalContext] = createMenuContext(PORTAL_NAME, {
37641
37725
  var MenuPortal = /* @__PURE__ */ __name21((props) => {
37642
37726
  const { __scopeMenu, forceMount, children, container } = props;
37643
37727
  const context = useMenuContext(PORTAL_NAME, __scopeMenu);
37644
- return /* @__PURE__ */ jsx34(PortalProvider, { scope: __scopeMenu, forceMount, children: /* @__PURE__ */ jsx34(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx34(Portal, { asChild: true, container, children }) }) });
37728
+ return /* @__PURE__ */ jsx35(PortalProvider, { scope: __scopeMenu, forceMount, children: /* @__PURE__ */ jsx35(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx35(Portal, { asChild: true, container, children }) }) });
37645
37729
  }, "MenuPortal");
37646
37730
  var CONTENT_NAME2 = "MenuContent";
37647
37731
  var [MenuContentProvider, useMenuContentContext] = createMenuContext(CONTENT_NAME2);
@@ -37651,7 +37735,7 @@ var MenuContent = /* @__PURE__ */ React41.forwardRef(
37651
37735
  const { forceMount = portalContext.forceMount, ...contentProps } = props;
37652
37736
  const context = useMenuContext(CONTENT_NAME2, props.__scopeMenu);
37653
37737
  const rootContext = useMenuRootContext(CONTENT_NAME2, props.__scopeMenu);
37654
- return /* @__PURE__ */ jsx34(Collection2.Provider, { scope: props.__scopeMenu, children: /* @__PURE__ */ jsx34(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx34(Collection2.Slot, { scope: props.__scopeMenu, children: rootContext.modal ? /* @__PURE__ */ jsx34(MenuRootContentModal, { ...contentProps, ref: forwardedRef }) : /* @__PURE__ */ jsx34(MenuRootContentNonModal, { ...contentProps, ref: forwardedRef }) }) }) });
37738
+ return /* @__PURE__ */ jsx35(Collection2.Provider, { scope: props.__scopeMenu, children: /* @__PURE__ */ jsx35(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx35(Collection2.Slot, { scope: props.__scopeMenu, children: rootContext.modal ? /* @__PURE__ */ jsx35(MenuRootContentModal, { ...contentProps, ref: forwardedRef }) : /* @__PURE__ */ jsx35(MenuRootContentNonModal, { ...contentProps, ref: forwardedRef }) }) }) });
37655
37739
  }, "MenuContent")
37656
37740
  );
37657
37741
  var MenuRootContentModal = /* @__PURE__ */ React41.forwardRef(
@@ -37664,7 +37748,7 @@ var MenuRootContentModal = /* @__PURE__ */ React41.forwardRef(
37664
37748
  const content = ref.current;
37665
37749
  if (content) return hideOthers(content);
37666
37750
  }, []);
37667
- return /* @__PURE__ */ jsx34(
37751
+ return /* @__PURE__ */ jsx35(
37668
37752
  MenuContentImpl,
37669
37753
  {
37670
37754
  ...props,
@@ -37684,7 +37768,7 @@ var MenuRootContentModal = /* @__PURE__ */ React41.forwardRef(
37684
37768
  );
37685
37769
  var MenuRootContentNonModal = /* @__PURE__ */ React41.forwardRef(/* @__PURE__ */ __name21(function MenuRootContentNonModal2(props, forwardedRef) {
37686
37770
  const context = useMenuContext(CONTENT_NAME2, props.__scopeMenu);
37687
- return /* @__PURE__ */ jsx34(
37771
+ return /* @__PURE__ */ jsx35(
37688
37772
  MenuContentImpl,
37689
37773
  {
37690
37774
  ...props,
@@ -37776,7 +37860,7 @@ var MenuContentImpl = /* @__PURE__ */ React41.forwardRef(
37776
37860
  const isMovingTowards = pointerDirRef.current === pointerGraceIntentRef.current?.side;
37777
37861
  return isMovingTowards && isPointerInGraceArea(event, pointerGraceIntentRef.current?.area);
37778
37862
  }, []);
37779
- return /* @__PURE__ */ jsx34(
37863
+ return /* @__PURE__ */ jsx35(
37780
37864
  MenuContentProvider,
37781
37865
  {
37782
37866
  scope: __scopeMenu,
@@ -37805,7 +37889,7 @@ var MenuContentImpl = /* @__PURE__ */ React41.forwardRef(
37805
37889
  onPointerGraceIntentChange: React41.useCallback((intent) => {
37806
37890
  pointerGraceIntentRef.current = intent;
37807
37891
  }, []),
37808
- children: /* @__PURE__ */ jsx34(FocusScopeBranchProvider, { registry: isModal ? branchRegistry : null, children: /* @__PURE__ */ jsx34(ScrollLockWrapper, { ...scrollLockWrapperProps, children: /* @__PURE__ */ jsx34(
37892
+ children: /* @__PURE__ */ jsx35(FocusScopeBranchProvider, { registry: isModal ? branchRegistry : null, children: /* @__PURE__ */ jsx35(ScrollLockWrapper, { ...scrollLockWrapperProps, children: /* @__PURE__ */ jsx35(
37809
37893
  FocusScope,
37810
37894
  {
37811
37895
  asChild: true,
@@ -37816,7 +37900,7 @@ var MenuContentImpl = /* @__PURE__ */ React41.forwardRef(
37816
37900
  contentRef.current?.focus({ preventScroll: true });
37817
37901
  }),
37818
37902
  onUnmountAutoFocus: onCloseAutoFocus,
37819
- children: /* @__PURE__ */ jsx34(
37903
+ children: /* @__PURE__ */ jsx35(
37820
37904
  DismissableLayer,
37821
37905
  {
37822
37906
  asChild: true,
@@ -37826,7 +37910,7 @@ var MenuContentImpl = /* @__PURE__ */ React41.forwardRef(
37826
37910
  onFocusOutside,
37827
37911
  onInteractOutside,
37828
37912
  onDismiss,
37829
- children: /* @__PURE__ */ jsx34(
37913
+ children: /* @__PURE__ */ jsx35(
37830
37914
  RovingFocusGroup,
37831
37915
  {
37832
37916
  asChild: true,
@@ -37840,7 +37924,7 @@ var MenuContentImpl = /* @__PURE__ */ React41.forwardRef(
37840
37924
  if (!rootContext.isUsingKeyboardRef.current) event.preventDefault();
37841
37925
  }),
37842
37926
  preventScrollOnEntryFocus: true,
37843
- children: /* @__PURE__ */ jsx34(
37927
+ children: /* @__PURE__ */ jsx35(
37844
37928
  PopperContent,
37845
37929
  {
37846
37930
  role: "menu",
@@ -37924,7 +38008,7 @@ var MenuItem = /* @__PURE__ */ React41.forwardRef(
37924
38008
  }
37925
38009
  }
37926
38010
  }, "handleSelect");
37927
- return /* @__PURE__ */ jsx34(
38011
+ return /* @__PURE__ */ jsx35(
37928
38012
  MenuItemImpl,
37929
38013
  {
37930
38014
  ...itemProps,
@@ -37970,13 +38054,13 @@ var MenuItemImpl = /* @__PURE__ */ React41.forwardRef(
37970
38054
  setTextContent((menuItem.textContent ?? "").trim());
37971
38055
  }
37972
38056
  }, [itemProps.children]);
37973
- return /* @__PURE__ */ jsx34(
38057
+ return /* @__PURE__ */ jsx35(
37974
38058
  Collection2.ItemSlot,
37975
38059
  {
37976
38060
  scope: __scopeMenu,
37977
38061
  disabled,
37978
38062
  textValue: textValue ?? textContent,
37979
- children: /* @__PURE__ */ jsx34(RovingFocusGroupItem, { asChild: true, ...rovingFocusGroupScope, focusable: !disabled, children: /* @__PURE__ */ jsx34(
38063
+ children: /* @__PURE__ */ jsx35(RovingFocusGroupItem, { asChild: true, ...rovingFocusGroupScope, focusable: !disabled, children: /* @__PURE__ */ jsx35(
37980
38064
  Primitive.div,
37981
38065
  {
37982
38066
  role: "menuitem",
@@ -38015,7 +38099,7 @@ var MenuCheckboxItem = /* @__PURE__ */ React41.forwardRef(
38015
38099
  // blank line to reduce diff noise
38016
38100
  /* @__PURE__ */ __name21(function MenuCheckboxItem2(props, forwardedRef) {
38017
38101
  const { checked = false, onCheckedChange, ...checkboxItemProps } = props;
38018
- return /* @__PURE__ */ jsx34(ItemIndicatorProvider, { scope: props.__scopeMenu, checked, children: /* @__PURE__ */ jsx34(
38102
+ return /* @__PURE__ */ jsx35(ItemIndicatorProvider, { scope: props.__scopeMenu, checked, children: /* @__PURE__ */ jsx35(
38019
38103
  MenuItem,
38020
38104
  {
38021
38105
  role: "menuitemcheckbox",
@@ -38046,7 +38130,7 @@ var [ItemIndicatorProvider, useItemIndicatorContext] = createMenuContext(
38046
38130
  var MenuSeparator = /* @__PURE__ */ React41.forwardRef(
38047
38131
  /* @__PURE__ */ __name21(function MenuSeparator2(props, forwardedRef) {
38048
38132
  const { __scopeMenu, ...separatorProps } = props;
38049
- return /* @__PURE__ */ jsx34(
38133
+ return /* @__PURE__ */ jsx35(
38050
38134
  Primitive.div,
38051
38135
  {
38052
38136
  role: "separator",
@@ -38070,7 +38154,7 @@ var MenuSub = /* @__PURE__ */ __name21((props) => {
38070
38154
  if (parentMenuContext.open === false) handleOpenChange(false);
38071
38155
  return () => handleOpenChange(false);
38072
38156
  }, [parentMenuContext.open, handleOpenChange]);
38073
- return /* @__PURE__ */ jsx34(Popper, { ...popperScope, children: /* @__PURE__ */ jsx34(
38157
+ return /* @__PURE__ */ jsx35(Popper, { ...popperScope, children: /* @__PURE__ */ jsx35(
38074
38158
  MenuProvider,
38075
38159
  {
38076
38160
  scope: __scopeMenu,
@@ -38078,7 +38162,7 @@ var MenuSub = /* @__PURE__ */ __name21((props) => {
38078
38162
  onOpenChange: handleOpenChange,
38079
38163
  content,
38080
38164
  onContentChange: setContent,
38081
- children: /* @__PURE__ */ jsx34(
38165
+ children: /* @__PURE__ */ jsx35(
38082
38166
  MenuSubProvider,
38083
38167
  {
38084
38168
  scope: __scopeMenu,
@@ -38115,7 +38199,7 @@ var MenuSubTrigger = /* @__PURE__ */ React41.forwardRef(
38115
38199
  };
38116
38200
  }, [pointerGraceTimerRef, onPointerGraceIntentChange]);
38117
38201
  const composedRefs = useComposedRefs(forwardedRef, subContext.onTriggerChange);
38118
- return /* @__PURE__ */ jsx34(MenuAnchor, { asChild: true, ...scope, children: /* @__PURE__ */ jsx34(
38202
+ return /* @__PURE__ */ jsx35(MenuAnchor, { asChild: true, ...scope, children: /* @__PURE__ */ jsx35(
38119
38203
  MenuItemImpl,
38120
38204
  {
38121
38205
  id: subContext.triggerId,
@@ -38208,7 +38292,7 @@ var MenuSubContent = /* @__PURE__ */ React41.forwardRef(
38208
38292
  const subContext = useMenuSubContext(SUB_CONTENT_NAME, props.__scopeMenu);
38209
38293
  const ref = React41.useRef(null);
38210
38294
  const composedRefs = useComposedRefs(forwardedRef, ref);
38211
- return /* @__PURE__ */ jsx34(Collection2.Provider, { scope: props.__scopeMenu, children: /* @__PURE__ */ jsx34(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx34(Collection2.Slot, { scope: props.__scopeMenu, children: /* @__PURE__ */ jsx34(
38295
+ return /* @__PURE__ */ jsx35(Collection2.Provider, { scope: props.__scopeMenu, children: /* @__PURE__ */ jsx35(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx35(Collection2.Slot, { scope: props.__scopeMenu, children: /* @__PURE__ */ jsx35(
38212
38296
  MenuContentImpl,
38213
38297
  {
38214
38298
  id: subContext.contentId,
@@ -38311,7 +38395,7 @@ function whenMouse(handler) {
38311
38395
  __name21(whenMouse, "whenMouse");
38312
38396
 
38313
38397
  // node_modules/@radix-ui/react-dropdown-menu/dist/index.mjs
38314
- import { jsx as jsx35 } from "react/jsx-runtime";
38398
+ import { jsx as jsx36 } from "react/jsx-runtime";
38315
38399
  var __defProp23 = Object.defineProperty;
38316
38400
  var __name22 = (target, value) => __defProp23(target, "name", { value, configurable: true });
38317
38401
  var DROPDOWN_MENU_NAME = "DropdownMenu";
@@ -38339,7 +38423,7 @@ var DropdownMenu = /* @__PURE__ */ __name22((props) => {
38339
38423
  onChange: onOpenChange,
38340
38424
  caller: DROPDOWN_MENU_NAME
38341
38425
  });
38342
- return /* @__PURE__ */ jsx35(
38426
+ return /* @__PURE__ */ jsx36(
38343
38427
  DropdownMenuProvider,
38344
38428
  {
38345
38429
  scope: __scopeDropdownMenu,
@@ -38350,7 +38434,7 @@ var DropdownMenu = /* @__PURE__ */ __name22((props) => {
38350
38434
  onOpenChange: setOpen,
38351
38435
  onOpenToggle: React42.useCallback(() => setOpen((prevOpen) => !prevOpen), [setOpen]),
38352
38436
  modal,
38353
- children: /* @__PURE__ */ jsx35(Menu, { ...menuScope, open, onOpenChange: setOpen, dir, modal, children })
38437
+ children: /* @__PURE__ */ jsx36(Menu, { ...menuScope, open, onOpenChange: setOpen, dir, modal, children })
38354
38438
  }
38355
38439
  );
38356
38440
  }, "DropdownMenu");
@@ -38362,7 +38446,7 @@ var DropdownMenuTrigger = /* @__PURE__ */ React42.forwardRef(
38362
38446
  const context = useDropdownMenuContext(TRIGGER_NAME, __scopeDropdownMenu);
38363
38447
  const menuScope = useMenuScope(__scopeDropdownMenu);
38364
38448
  const composedRefs = useComposedRefs(forwardedRef, context.triggerRef);
38365
- return /* @__PURE__ */ jsx35(MenuAnchor, { asChild: true, ...menuScope, children: /* @__PURE__ */ jsx35(
38449
+ return /* @__PURE__ */ jsx36(MenuAnchor, { asChild: true, ...menuScope, children: /* @__PURE__ */ jsx36(
38366
38450
  Primitive.button,
38367
38451
  {
38368
38452
  type: "button",
@@ -38394,7 +38478,7 @@ var DropdownMenuTrigger = /* @__PURE__ */ React42.forwardRef(
38394
38478
  var DropdownMenuPortal = /* @__PURE__ */ __name22((props) => {
38395
38479
  const { __scopeDropdownMenu, ...portalProps } = props;
38396
38480
  const menuScope = useMenuScope(__scopeDropdownMenu);
38397
- return /* @__PURE__ */ jsx35(MenuPortal, { ...menuScope, ...portalProps });
38481
+ return /* @__PURE__ */ jsx36(MenuPortal, { ...menuScope, ...portalProps });
38398
38482
  }, "DropdownMenuPortal");
38399
38483
  var CONTENT_NAME3 = "DropdownMenuContent";
38400
38484
  var DropdownMenuContent = /* @__PURE__ */ React42.forwardRef(
@@ -38404,7 +38488,7 @@ var DropdownMenuContent = /* @__PURE__ */ React42.forwardRef(
38404
38488
  const context = useDropdownMenuContext(CONTENT_NAME3, __scopeDropdownMenu);
38405
38489
  const menuScope = useMenuScope(__scopeDropdownMenu);
38406
38490
  const hasInteractedOutsideRef = React42.useRef(false);
38407
- return /* @__PURE__ */ jsx35(
38491
+ return /* @__PURE__ */ jsx36(
38408
38492
  MenuContent,
38409
38493
  {
38410
38494
  id: context.contentId,
@@ -38443,18 +38527,18 @@ var DropdownMenuItem = /* @__PURE__ */ React42.forwardRef(
38443
38527
  /* @__PURE__ */ __name22(function DropdownMenuItem2(props, forwardedRef) {
38444
38528
  const { __scopeDropdownMenu, ...itemProps } = props;
38445
38529
  const menuScope = useMenuScope(__scopeDropdownMenu);
38446
- return /* @__PURE__ */ jsx35(MenuItem, { ...menuScope, ...itemProps, ref: forwardedRef });
38530
+ return /* @__PURE__ */ jsx36(MenuItem, { ...menuScope, ...itemProps, ref: forwardedRef });
38447
38531
  }, "DropdownMenuItem")
38448
38532
  );
38449
38533
  var DropdownMenuCheckboxItem = /* @__PURE__ */ React42.forwardRef(/* @__PURE__ */ __name22(function DropdownMenuCheckboxItem2(props, forwardedRef) {
38450
38534
  const { __scopeDropdownMenu, ...checkboxItemProps } = props;
38451
38535
  const menuScope = useMenuScope(__scopeDropdownMenu);
38452
- return /* @__PURE__ */ jsx35(MenuCheckboxItem, { ...menuScope, ...checkboxItemProps, ref: forwardedRef });
38536
+ return /* @__PURE__ */ jsx36(MenuCheckboxItem, { ...menuScope, ...checkboxItemProps, ref: forwardedRef });
38453
38537
  }, "DropdownMenuCheckboxItem"));
38454
38538
  var DropdownMenuSeparator = /* @__PURE__ */ React42.forwardRef(/* @__PURE__ */ __name22(function DropdownMenuSeparator2(props, forwardedRef) {
38455
38539
  const { __scopeDropdownMenu, ...separatorProps } = props;
38456
38540
  const menuScope = useMenuScope(__scopeDropdownMenu);
38457
- return /* @__PURE__ */ jsx35(MenuSeparator, { ...menuScope, ...separatorProps, ref: forwardedRef });
38541
+ return /* @__PURE__ */ jsx36(MenuSeparator, { ...menuScope, ...separatorProps, ref: forwardedRef });
38458
38542
  }, "DropdownMenuSeparator"));
38459
38543
  var DropdownMenuSub = /* @__PURE__ */ __name22((props) => {
38460
38544
  const { __scopeDropdownMenu, children, open: openProp, onOpenChange, defaultOpen } = props;
@@ -38465,17 +38549,17 @@ var DropdownMenuSub = /* @__PURE__ */ __name22((props) => {
38465
38549
  onChange: onOpenChange,
38466
38550
  caller: "DropdownMenuSub"
38467
38551
  });
38468
- return /* @__PURE__ */ jsx35(MenuSub, { ...menuScope, open, onOpenChange: setOpen, children });
38552
+ return /* @__PURE__ */ jsx36(MenuSub, { ...menuScope, open, onOpenChange: setOpen, children });
38469
38553
  }, "DropdownMenuSub");
38470
38554
  var DropdownMenuSubTrigger = /* @__PURE__ */ React42.forwardRef(/* @__PURE__ */ __name22(function DropdownMenuSubTrigger2(props, forwardedRef) {
38471
38555
  const { __scopeDropdownMenu, ...subTriggerProps } = props;
38472
38556
  const menuScope = useMenuScope(__scopeDropdownMenu);
38473
- return /* @__PURE__ */ jsx35(MenuSubTrigger, { ...menuScope, ...subTriggerProps, ref: forwardedRef });
38557
+ return /* @__PURE__ */ jsx36(MenuSubTrigger, { ...menuScope, ...subTriggerProps, ref: forwardedRef });
38474
38558
  }, "DropdownMenuSubTrigger"));
38475
38559
  var DropdownMenuSubContent = /* @__PURE__ */ React42.forwardRef(/* @__PURE__ */ __name22(function DropdownMenuSubContent2(props, forwardedRef) {
38476
38560
  const { __scopeDropdownMenu, ...subContentProps } = props;
38477
38561
  const menuScope = useMenuScope(__scopeDropdownMenu);
38478
- return /* @__PURE__ */ jsx35(
38562
+ return /* @__PURE__ */ jsx36(
38479
38563
  MenuSubContent,
38480
38564
  {
38481
38565
  ...menuScope,
@@ -38498,7 +38582,7 @@ var DropdownMenuSubContent = /* @__PURE__ */ React42.forwardRef(/* @__PURE__ */
38498
38582
 
38499
38583
  // src/components/ViewportSubContent.tsx
38500
38584
  import { useLayoutEffect as useLayoutEffect5, useState as useState40 } from "react";
38501
- import { jsx as jsx36 } from "react/jsx-runtime";
38585
+ import { jsx as jsx37 } from "react/jsx-runtime";
38502
38586
  var ViewportSubContent = (props) => {
38503
38587
  const [content, setContent] = useState40(null);
38504
38588
  const [overlapWidth, setOverlapWidth] = useState40();
@@ -38529,7 +38613,7 @@ var ViewportSubContent = (props) => {
38529
38613
  window.removeEventListener("resize", update);
38530
38614
  };
38531
38615
  }, [content]);
38532
- return /* @__PURE__ */ jsx36(
38616
+ return /* @__PURE__ */ jsx37(
38533
38617
  DropdownMenuSubContent,
38534
38618
  {
38535
38619
  ...props,
@@ -38562,8 +38646,8 @@ import { useState as useState42 } from "react";
38562
38646
  import { useState as useState41 } from "react";
38563
38647
 
38564
38648
  // src/components/Icons.tsx
38565
- import { jsx as jsx37 } from "react/jsx-runtime";
38566
- var CheckIcon = () => /* @__PURE__ */ jsx37(
38649
+ import { jsx as jsx38 } from "react/jsx-runtime";
38650
+ var CheckIcon = () => /* @__PURE__ */ jsx38(
38567
38651
  "svg",
38568
38652
  {
38569
38653
  xmlns: "http://www.w3.org/2000/svg",
@@ -38575,10 +38659,10 @@ var CheckIcon = () => /* @__PURE__ */ jsx37(
38575
38659
  strokeWidth: "2",
38576
38660
  strokeLinecap: "round",
38577
38661
  strokeLinejoin: "round",
38578
- children: /* @__PURE__ */ jsx37("path", { d: "M20 6 9 17l-5-5" })
38662
+ children: /* @__PURE__ */ jsx38("path", { d: "M20 6 9 17l-5-5" })
38579
38663
  }
38580
38664
  );
38581
- var ChevronRightIcon = ({ isOpen }) => /* @__PURE__ */ jsx37(
38665
+ var ChevronRightIcon = ({ isOpen }) => /* @__PURE__ */ jsx38(
38582
38666
  "svg",
38583
38667
  {
38584
38668
  xmlns: "http://www.w3.org/2000/svg",
@@ -38595,10 +38679,10 @@ var ChevronRightIcon = ({ isOpen }) => /* @__PURE__ */ jsx37(
38595
38679
  transform: isOpen ? "rotate(90deg)" : "rotate(0deg)",
38596
38680
  opacity: 0.6
38597
38681
  },
38598
- children: /* @__PURE__ */ jsx37("path", { d: "m9 18 6-6-6-6" })
38682
+ children: /* @__PURE__ */ jsx38("path", { d: "m9 18 6-6-6-6" })
38599
38683
  }
38600
38684
  );
38601
- var CheckMinusIcon = () => /* @__PURE__ */ jsx37(
38685
+ var CheckMinusIcon = () => /* @__PURE__ */ jsx38(
38602
38686
  "svg",
38603
38687
  {
38604
38688
  xmlns: "http://www.w3.org/2000/svg",
@@ -38610,10 +38694,10 @@ var CheckMinusIcon = () => /* @__PURE__ */ jsx37(
38610
38694
  strokeWidth: "2",
38611
38695
  strokeLinecap: "round",
38612
38696
  strokeLinejoin: "round",
38613
- children: /* @__PURE__ */ jsx37("path", { d: "M5 12h14" })
38697
+ children: /* @__PURE__ */ jsx38("path", { d: "M5 12h14" })
38614
38698
  }
38615
38699
  );
38616
- var DotIcon = () => /* @__PURE__ */ jsx37(
38700
+ var DotIcon = () => /* @__PURE__ */ jsx38(
38617
38701
  "svg",
38618
38702
  {
38619
38703
  xmlns: "http://www.w3.org/2000/svg",
@@ -38626,12 +38710,12 @@ var DotIcon = () => /* @__PURE__ */ jsx37(
38626
38710
  strokeLinecap: "round",
38627
38711
  strokeLinejoin: "round",
38628
38712
  className: "lucide lucide-dot-icon lucide-dot",
38629
- children: /* @__PURE__ */ jsx37("circle", { cx: "12.1", cy: "12.1", r: "4.5", fill: "white" })
38713
+ children: /* @__PURE__ */ jsx38("circle", { cx: "12.1", cy: "12.1", r: "4.5", fill: "white" })
38630
38714
  }
38631
38715
  );
38632
38716
 
38633
38717
  // src/components/AppearanceMenu.tsx
38634
- import { Fragment as Fragment10, jsx as jsx38, jsxs as jsxs9 } from "react/jsx-runtime";
38718
+ import { Fragment as Fragment10, jsx as jsx39, jsxs as jsxs9 } from "react/jsx-runtime";
38635
38719
  var itemStyles = {
38636
38720
  padding: "6px 8px",
38637
38721
  borderRadius: 6,
@@ -38694,7 +38778,7 @@ var AppearanceMenu = ({
38694
38778
  const assemblyStyles = { ...itemStyles };
38695
38779
  if (hoveredItem === "assembly") assemblyStyles.backgroundColor = "#404040";
38696
38780
  return /* @__PURE__ */ jsxs9(Fragment10, { children: [
38697
- /* @__PURE__ */ jsx38(DropdownMenuSeparator, { style: separatorStyles }),
38781
+ /* @__PURE__ */ jsx39(DropdownMenuSeparator, { style: separatorStyles }),
38698
38782
  /* @__PURE__ */ jsxs9(DropdownMenuSub, { onOpenChange: setAppearanceSubOpen, children: [
38699
38783
  /* @__PURE__ */ jsxs9(
38700
38784
  DropdownMenuSubTrigger,
@@ -38708,8 +38792,8 @@ var AppearanceMenu = ({
38708
38792
  onMouseLeave: () => setHoveredItem(null),
38709
38793
  onTouchStart: () => setHoveredItem("appearance"),
38710
38794
  children: [
38711
- /* @__PURE__ */ jsx38("span", { style: { flex: 1, display: "flex", alignItems: "center" }, children: "Appearance" }),
38712
- /* @__PURE__ */ jsx38(
38795
+ /* @__PURE__ */ jsx39("span", { style: { flex: 1, display: "flex", alignItems: "center" }, children: "Appearance" }),
38796
+ /* @__PURE__ */ jsx39(
38713
38797
  "div",
38714
38798
  {
38715
38799
  style: {
@@ -38718,13 +38802,13 @@ var AppearanceMenu = ({
38718
38802
  alignItems: "flex-end",
38719
38803
  marginBottom: "-5px"
38720
38804
  },
38721
- children: /* @__PURE__ */ jsx38(ChevronRightIcon, { isOpen: appearanceSubOpen })
38805
+ children: /* @__PURE__ */ jsx39(ChevronRightIcon, { isOpen: appearanceSubOpen })
38722
38806
  }
38723
38807
  )
38724
38808
  ]
38725
38809
  }
38726
38810
  ),
38727
- /* @__PURE__ */ jsx38(DropdownMenuPortal, { children: /* @__PURE__ */ jsxs9(
38811
+ /* @__PURE__ */ jsx39(DropdownMenuPortal, { children: /* @__PURE__ */ jsxs9(
38728
38812
  ViewportSubContent,
38729
38813
  {
38730
38814
  style: { ...contentStyles, marginLeft: -2 },
@@ -38747,8 +38831,8 @@ var AppearanceMenu = ({
38747
38831
  onMouseLeave: () => setHoveredItem(null),
38748
38832
  onTouchStart: () => setHoveredItem("darkBackground"),
38749
38833
  children: [
38750
- /* @__PURE__ */ jsx38("span", { style: iconContainerStyles, children: darkBackgroundEnabled && /* @__PURE__ */ jsx38(CheckIcon, {}) }),
38751
- /* @__PURE__ */ jsx38("span", { style: { display: "flex", alignItems: "center" }, children: "Dark Background" })
38834
+ /* @__PURE__ */ jsx39("span", { style: iconContainerStyles, children: darkBackgroundEnabled && /* @__PURE__ */ jsx39(CheckIcon, {}) }),
38835
+ /* @__PURE__ */ jsx39("span", { style: { display: "flex", alignItems: "center" }, children: "Dark Background" })
38752
38836
  ]
38753
38837
  }
38754
38838
  ),
@@ -38768,13 +38852,13 @@ var AppearanceMenu = ({
38768
38852
  onMouseLeave: () => setHoveredItem(null),
38769
38853
  onTouchStart: () => setHoveredItem("lighting"),
38770
38854
  children: [
38771
- /* @__PURE__ */ jsx38("span", { style: iconContainerStyles, children: lightingEnabled && /* @__PURE__ */ jsx38(CheckIcon, {}) }),
38772
- /* @__PURE__ */ jsx38("span", { style: { display: "flex", alignItems: "center" }, children: "Lighting" })
38855
+ /* @__PURE__ */ jsx39("span", { style: iconContainerStyles, children: lightingEnabled && /* @__PURE__ */ jsx39(CheckIcon, {}) }),
38856
+ /* @__PURE__ */ jsx39("span", { style: { display: "flex", alignItems: "center" }, children: "Lighting" })
38773
38857
  ]
38774
38858
  }
38775
38859
  ),
38776
38860
  showLayerControls && /* @__PURE__ */ jsxs9(Fragment10, { children: [
38777
- /* @__PURE__ */ jsx38(DropdownMenuSeparator, { style: separatorStyles }),
38861
+ /* @__PURE__ */ jsx39(DropdownMenuSeparator, { style: separatorStyles }),
38778
38862
  /* @__PURE__ */ jsxs9(
38779
38863
  DropdownMenuItem,
38780
38864
  {
@@ -38791,8 +38875,8 @@ var AppearanceMenu = ({
38791
38875
  onMouseLeave: () => setHoveredItem(null),
38792
38876
  onTouchStart: () => setHoveredItem("boardBody"),
38793
38877
  children: [
38794
- /* @__PURE__ */ jsx38("span", { style: iconContainerStyles, children: visibility.boardBody && /* @__PURE__ */ jsx38(CheckIcon, {}) }),
38795
- /* @__PURE__ */ jsx38("span", { style: { display: "flex", alignItems: "center" }, children: "Board Body" })
38878
+ /* @__PURE__ */ jsx39("span", { style: iconContainerStyles, children: visibility.boardBody && /* @__PURE__ */ jsx39(CheckIcon, {}) }),
38879
+ /* @__PURE__ */ jsx39("span", { style: { display: "flex", alignItems: "center" }, children: "Board Body" })
38796
38880
  ]
38797
38881
  }
38798
38882
  ),
@@ -38812,8 +38896,8 @@ var AppearanceMenu = ({
38812
38896
  onMouseLeave: () => setHoveredItem(null),
38813
38897
  onTouchStart: () => setHoveredItem("topCopper"),
38814
38898
  children: [
38815
- /* @__PURE__ */ jsx38("span", { style: iconContainerStyles, children: visibility.topCopper && /* @__PURE__ */ jsx38(CheckIcon, {}) }),
38816
- /* @__PURE__ */ jsx38("span", { style: { display: "flex", alignItems: "center" }, children: "Top Copper" })
38899
+ /* @__PURE__ */ jsx39("span", { style: iconContainerStyles, children: visibility.topCopper && /* @__PURE__ */ jsx39(CheckIcon, {}) }),
38900
+ /* @__PURE__ */ jsx39("span", { style: { display: "flex", alignItems: "center" }, children: "Top Copper" })
38817
38901
  ]
38818
38902
  }
38819
38903
  ),
@@ -38833,8 +38917,8 @@ var AppearanceMenu = ({
38833
38917
  onMouseLeave: () => setHoveredItem(null),
38834
38918
  onTouchStart: () => setHoveredItem("bottomCopper"),
38835
38919
  children: [
38836
- /* @__PURE__ */ jsx38("span", { style: iconContainerStyles, children: visibility.bottomCopper && /* @__PURE__ */ jsx38(CheckIcon, {}) }),
38837
- /* @__PURE__ */ jsx38("span", { style: { display: "flex", alignItems: "center" }, children: "Bottom Copper" })
38920
+ /* @__PURE__ */ jsx39("span", { style: iconContainerStyles, children: visibility.bottomCopper && /* @__PURE__ */ jsx39(CheckIcon, {}) }),
38921
+ /* @__PURE__ */ jsx39("span", { style: { display: "flex", alignItems: "center" }, children: "Bottom Copper" })
38838
38922
  ]
38839
38923
  }
38840
38924
  ),
@@ -38854,8 +38938,8 @@ var AppearanceMenu = ({
38854
38938
  onMouseLeave: () => setHoveredItem(null),
38855
38939
  onTouchStart: () => setHoveredItem("keepout"),
38856
38940
  children: [
38857
- /* @__PURE__ */ jsx38("span", { style: iconContainerStyles, children: visibility.keepout && /* @__PURE__ */ jsx38(CheckIcon, {}) }),
38858
- /* @__PURE__ */ jsx38("span", { style: { display: "flex", alignItems: "center" }, children: "Keepout" })
38941
+ /* @__PURE__ */ jsx39("span", { style: iconContainerStyles, children: visibility.keepout && /* @__PURE__ */ jsx39(CheckIcon, {}) }),
38942
+ /* @__PURE__ */ jsx39("span", { style: { display: "flex", alignItems: "center" }, children: "Keepout" })
38859
38943
  ]
38860
38944
  }
38861
38945
  ),
@@ -38878,8 +38962,8 @@ var AppearanceMenu = ({
38878
38962
  onMouseLeave: () => setHoveredItem(null),
38879
38963
  onTouchStart: () => setHoveredItem("topSilkscreen"),
38880
38964
  children: [
38881
- /* @__PURE__ */ jsx38("span", { style: iconContainerStyles, children: visibility.topSilkscreen && /* @__PURE__ */ jsx38(CheckIcon, {}) }),
38882
- /* @__PURE__ */ jsx38("span", { style: { display: "flex", alignItems: "center" }, children: "Top Silkscreen" })
38965
+ /* @__PURE__ */ jsx39("span", { style: iconContainerStyles, children: visibility.topSilkscreen && /* @__PURE__ */ jsx39(CheckIcon, {}) }),
38966
+ /* @__PURE__ */ jsx39("span", { style: { display: "flex", alignItems: "center" }, children: "Top Silkscreen" })
38883
38967
  ]
38884
38968
  }
38885
38969
  ),
@@ -38902,8 +38986,8 @@ var AppearanceMenu = ({
38902
38986
  onMouseLeave: () => setHoveredItem(null),
38903
38987
  onTouchStart: () => setHoveredItem("bottomSilkscreen"),
38904
38988
  children: [
38905
- /* @__PURE__ */ jsx38("span", { style: iconContainerStyles, children: visibility.bottomSilkscreen && /* @__PURE__ */ jsx38(CheckIcon, {}) }),
38906
- /* @__PURE__ */ jsx38("span", { style: { display: "flex", alignItems: "center" }, children: "Bottom Silkscreen" })
38989
+ /* @__PURE__ */ jsx39("span", { style: iconContainerStyles, children: visibility.bottomSilkscreen && /* @__PURE__ */ jsx39(CheckIcon, {}) }),
38990
+ /* @__PURE__ */ jsx39("span", { style: { display: "flex", alignItems: "center" }, children: "Bottom Silkscreen" })
38907
38991
  ]
38908
38992
  }
38909
38993
  ),
@@ -38923,8 +39007,8 @@ var AppearanceMenu = ({
38923
39007
  onMouseLeave: () => setHoveredItem(null),
38924
39008
  onTouchStart: () => setHoveredItem("topMask"),
38925
39009
  children: [
38926
- /* @__PURE__ */ jsx38("span", { style: iconContainerStyles, children: visibility.topMask && /* @__PURE__ */ jsx38(CheckIcon, {}) }),
38927
- /* @__PURE__ */ jsx38("span", { style: { display: "flex", alignItems: "center" }, children: "Top Soldermask" })
39010
+ /* @__PURE__ */ jsx39("span", { style: iconContainerStyles, children: visibility.topMask && /* @__PURE__ */ jsx39(CheckIcon, {}) }),
39011
+ /* @__PURE__ */ jsx39("span", { style: { display: "flex", alignItems: "center" }, children: "Top Soldermask" })
38928
39012
  ]
38929
39013
  }
38930
39014
  ),
@@ -38944,8 +39028,8 @@ var AppearanceMenu = ({
38944
39028
  onMouseLeave: () => setHoveredItem(null),
38945
39029
  onTouchStart: () => setHoveredItem("bottomMask"),
38946
39030
  children: [
38947
- /* @__PURE__ */ jsx38("span", { style: iconContainerStyles, children: visibility.bottomMask && /* @__PURE__ */ jsx38(CheckIcon, {}) }),
38948
- /* @__PURE__ */ jsx38("span", { style: { display: "flex", alignItems: "center" }, children: "Bottom Soldermask" })
39031
+ /* @__PURE__ */ jsx39("span", { style: iconContainerStyles, children: visibility.bottomMask && /* @__PURE__ */ jsx39(CheckIcon, {}) }),
39032
+ /* @__PURE__ */ jsx39("span", { style: { display: "flex", alignItems: "center" }, children: "Bottom Soldermask" })
38949
39033
  ]
38950
39034
  }
38951
39035
  ),
@@ -38965,8 +39049,8 @@ var AppearanceMenu = ({
38965
39049
  onMouseLeave: () => setHoveredItem(null),
38966
39050
  onTouchStart: () => setHoveredItem("pcbNotes"),
38967
39051
  children: [
38968
- /* @__PURE__ */ jsx38("span", { style: iconContainerStyles, children: visibility.pcbNotes && /* @__PURE__ */ jsx38(CheckIcon, {}) }),
38969
- /* @__PURE__ */ jsx38("span", { style: { display: "flex", alignItems: "center" }, children: "PCB Notes" })
39052
+ /* @__PURE__ */ jsx39("span", { style: iconContainerStyles, children: visibility.pcbNotes && /* @__PURE__ */ jsx39(CheckIcon, {}) }),
39053
+ /* @__PURE__ */ jsx39("span", { style: { display: "flex", alignItems: "center" }, children: "PCB Notes" })
38970
39054
  ]
38971
39055
  }
38972
39056
  ),
@@ -38986,8 +39070,8 @@ var AppearanceMenu = ({
38986
39070
  onMouseLeave: () => setHoveredItem(null),
38987
39071
  onTouchStart: () => setHoveredItem("smtModels"),
38988
39072
  children: [
38989
- /* @__PURE__ */ jsx38("span", { style: iconContainerStyles, children: visibility.smtModels && /* @__PURE__ */ jsx38(CheckIcon, {}) }),
38990
- /* @__PURE__ */ jsx38("span", { style: { display: "flex", alignItems: "center" }, children: "Surface Mount Components" })
39073
+ /* @__PURE__ */ jsx39("span", { style: iconContainerStyles, children: visibility.smtModels && /* @__PURE__ */ jsx39(CheckIcon, {}) }),
39074
+ /* @__PURE__ */ jsx39("span", { style: { display: "flex", alignItems: "center" }, children: "Surface Mount Components" })
38991
39075
  ]
38992
39076
  }
38993
39077
  ),
@@ -39010,12 +39094,12 @@ var AppearanceMenu = ({
39010
39094
  onMouseLeave: () => setHoveredItem(null),
39011
39095
  onTouchStart: () => setHoveredItem("throughHoleModels"),
39012
39096
  children: [
39013
- /* @__PURE__ */ jsx38("span", { style: iconContainerStyles, children: visibility.throughHoleModels && /* @__PURE__ */ jsx38(CheckIcon, {}) }),
39014
- /* @__PURE__ */ jsx38("span", { style: { display: "flex", alignItems: "center" }, children: "Through-Hole Components" })
39097
+ /* @__PURE__ */ jsx39("span", { style: iconContainerStyles, children: visibility.throughHoleModels && /* @__PURE__ */ jsx39(CheckIcon, {}) }),
39098
+ /* @__PURE__ */ jsx39("span", { style: { display: "flex", alignItems: "center" }, children: "Through-Hole Components" })
39015
39099
  ]
39016
39100
  }
39017
39101
  ),
39018
- /* @__PURE__ */ jsx38(DropdownMenuSeparator, { style: separatorStyles }),
39102
+ /* @__PURE__ */ jsx39(DropdownMenuSeparator, { style: separatorStyles }),
39019
39103
  /* @__PURE__ */ jsxs9(
39020
39104
  DropdownMenuItem,
39021
39105
  {
@@ -39037,10 +39121,10 @@ var AppearanceMenu = ({
39037
39121
  title: `Enclosure: ${visibility.enclosure}`,
39038
39122
  children: [
39039
39123
  /* @__PURE__ */ jsxs9("span", { style: iconContainerStyles, children: [
39040
- visibility.enclosure === "opaque" && /* @__PURE__ */ jsx38(CheckIcon, {}),
39041
- visibility.enclosure === "translucent" && /* @__PURE__ */ jsx38(CheckMinusIcon, {})
39124
+ visibility.enclosure === "opaque" && /* @__PURE__ */ jsx39(CheckIcon, {}),
39125
+ visibility.enclosure === "translucent" && /* @__PURE__ */ jsx39(CheckMinusIcon, {})
39042
39126
  ] }),
39043
- /* @__PURE__ */ jsx38("span", { style: { display: "flex", alignItems: "center" }, children: "Enclosure" })
39127
+ /* @__PURE__ */ jsx39("span", { style: { display: "flex", alignItems: "center" }, children: "Enclosure" })
39044
39128
  ]
39045
39129
  }
39046
39130
  ),
@@ -39057,8 +39141,8 @@ var AppearanceMenu = ({
39057
39141
  onMouseLeave: () => setHoveredItem(null),
39058
39142
  onTouchStart: () => setHoveredItem("assembly"),
39059
39143
  children: [
39060
- /* @__PURE__ */ jsx38("span", { style: iconContainerStyles, children: visibility.assembly && /* @__PURE__ */ jsx38(CheckIcon, {}) }),
39061
- /* @__PURE__ */ jsx38("span", { style: { display: "flex", alignItems: "center" }, children: "Assembly" })
39144
+ /* @__PURE__ */ jsx39("span", { style: iconContainerStyles, children: visibility.assembly && /* @__PURE__ */ jsx39(CheckIcon, {}) }),
39145
+ /* @__PURE__ */ jsx39("span", { style: { display: "flex", alignItems: "center" }, children: "Assembly" })
39062
39146
  ]
39063
39147
  }
39064
39148
  )
@@ -39071,7 +39155,7 @@ var AppearanceMenu = ({
39071
39155
  };
39072
39156
 
39073
39157
  // src/components/ContextMenu.tsx
39074
- import { Fragment as Fragment11, jsx as jsx39, jsxs as jsxs10 } from "react/jsx-runtime";
39158
+ import { Fragment as Fragment11, jsx as jsx40, jsxs as jsxs10 } from "react/jsx-runtime";
39075
39159
  var cameraOptions = [
39076
39160
  "Custom",
39077
39161
  "Top Center Angled",
@@ -39158,9 +39242,10 @@ var ContextMenu = ({
39158
39242
  onReferenceObjectSelect = () => {
39159
39243
  },
39160
39244
  onViewSchematicComponent,
39161
- componentName,
39162
- onHideComponent,
39163
- onUnhideAllComponents,
39245
+ objectName,
39246
+ onHideObject,
39247
+ onIsolateObject,
39248
+ onUnhideAll,
39164
39249
  onSectionView,
39165
39250
  onExplosionView,
39166
39251
  explosionAvailable = false,
@@ -39173,7 +39258,7 @@ var ContextMenu = ({
39173
39258
  const [advancedSubOpen, setAdvancedSubOpen] = useState42(false);
39174
39259
  const [referenceObjectSubOpen, setReferenceObjectSubOpen] = useState42(false);
39175
39260
  const [hoveredItem, setHoveredItem] = useState42(null);
39176
- return /* @__PURE__ */ jsx39(
39261
+ return /* @__PURE__ */ jsx40(
39177
39262
  "div",
39178
39263
  {
39179
39264
  ref: menuRef,
@@ -39185,8 +39270,8 @@ var ContextMenu = ({
39185
39270
  height: 0
39186
39271
  },
39187
39272
  children: /* @__PURE__ */ jsxs10(DropdownMenu, { open: true, modal: false, children: [
39188
- /* @__PURE__ */ jsx39(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx39("div", { style: { position: "absolute", width: 1, height: 1 } }) }),
39189
- /* @__PURE__ */ jsx39(DropdownMenuPortal, { children: /* @__PURE__ */ jsxs10(
39273
+ /* @__PURE__ */ jsx40(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx40("div", { style: { position: "absolute", width: 1, height: 1 } }) }),
39274
+ /* @__PURE__ */ jsx40(DropdownMenuPortal, { children: /* @__PURE__ */ jsxs10(
39190
39275
  DropdownMenuContent,
39191
39276
  {
39192
39277
  style: contentStyles2,
@@ -39195,7 +39280,7 @@ var ContextMenu = ({
39195
39280
  sideOffset: 0,
39196
39281
  align: "start",
39197
39282
  children: [
39198
- onHideComponent && /* @__PURE__ */ jsx39(
39283
+ onHideObject && /* @__PURE__ */ jsx40(
39199
39284
  DropdownMenuItem,
39200
39285
  {
39201
39286
  style: {
@@ -39203,13 +39288,27 @@ var ContextMenu = ({
39203
39288
  ...itemPaddingStyles2,
39204
39289
  backgroundColor: hoveredItem === "hide" ? "#404040" : "transparent"
39205
39290
  },
39206
- onSelect: onHideComponent,
39291
+ onSelect: onHideObject,
39207
39292
  onMouseEnter: () => setHoveredItem("hide"),
39208
39293
  onMouseLeave: () => setHoveredItem(null),
39209
- children: `Hide "${componentName}"`
39294
+ children: `Hide "${objectName}"`
39210
39295
  }
39211
39296
  ),
39212
- onViewSchematicComponent && /* @__PURE__ */ jsx39(Fragment11, { children: /* @__PURE__ */ jsx39(
39297
+ onIsolateObject && /* @__PURE__ */ jsx40(
39298
+ DropdownMenuItem,
39299
+ {
39300
+ style: {
39301
+ ...itemStyles2,
39302
+ ...itemPaddingStyles2,
39303
+ backgroundColor: hoveredItem === "isolate" ? "#404040" : "transparent"
39304
+ },
39305
+ onSelect: onIsolateObject,
39306
+ onMouseEnter: () => setHoveredItem("isolate"),
39307
+ onMouseLeave: () => setHoveredItem(null),
39308
+ children: `Isolate "${objectName}"`
39309
+ }
39310
+ ),
39311
+ onViewSchematicComponent && /* @__PURE__ */ jsx40(Fragment11, { children: /* @__PURE__ */ jsx40(
39213
39312
  DropdownMenuItem,
39214
39313
  {
39215
39314
  style: {
@@ -39223,7 +39322,7 @@ var ContextMenu = ({
39223
39322
  children: "Show on schematic"
39224
39323
  }
39225
39324
  ) }),
39226
- onUnhideAllComponents && /* @__PURE__ */ jsx39(
39325
+ onUnhideAll && /* @__PURE__ */ jsx40(
39227
39326
  DropdownMenuItem,
39228
39327
  {
39229
39328
  style: {
@@ -39231,13 +39330,13 @@ var ContextMenu = ({
39231
39330
  ...itemPaddingStyles2,
39232
39331
  backgroundColor: hoveredItem === "unhide" ? "#404040" : "transparent"
39233
39332
  },
39234
- onSelect: onUnhideAllComponents,
39333
+ onSelect: onUnhideAll,
39235
39334
  onMouseEnter: () => setHoveredItem("unhide"),
39236
39335
  onMouseLeave: () => setHoveredItem(null),
39237
- children: "Unhide All Components"
39336
+ children: "Unhide All"
39238
39337
  }
39239
39338
  ),
39240
- (onViewSchematicComponent || onHideComponent || onUnhideAllComponents) && /* @__PURE__ */ jsx39(DropdownMenuSeparator, { style: separatorStyles2 }),
39339
+ (onViewSchematicComponent || onHideObject || onIsolateObject || onUnhideAll) && /* @__PURE__ */ jsx40(DropdownMenuSeparator, { style: separatorStyles2 }),
39241
39340
  /* @__PURE__ */ jsxs10(DropdownMenuSub, { onOpenChange: setCameraSubOpen, children: [
39242
39341
  /* @__PURE__ */ jsxs10(
39243
39342
  DropdownMenuSubTrigger,
@@ -39251,7 +39350,7 @@ var ContextMenu = ({
39251
39350
  onMouseLeave: () => setHoveredItem(null),
39252
39351
  onTouchStart: () => setHoveredItem("camera"),
39253
39352
  children: [
39254
- /* @__PURE__ */ jsx39(
39353
+ /* @__PURE__ */ jsx40(
39255
39354
  "span",
39256
39355
  {
39257
39356
  style: { flex: 1, display: "flex", alignItems: "center" },
@@ -39268,15 +39367,15 @@ var ContextMenu = ({
39268
39367
  marginLeft: "auto"
39269
39368
  },
39270
39369
  children: [
39271
- /* @__PURE__ */ jsx39("span", { style: { opacity: 0.55, fontSize: 13 }, children: cameraPreset }),
39272
- /* @__PURE__ */ jsx39(ChevronRightIcon, { isOpen: cameraSubOpen })
39370
+ /* @__PURE__ */ jsx40("span", { style: { opacity: 0.55, fontSize: 13 }, children: cameraPreset }),
39371
+ /* @__PURE__ */ jsx40(ChevronRightIcon, { isOpen: cameraSubOpen })
39273
39372
  ]
39274
39373
  }
39275
39374
  )
39276
39375
  ]
39277
39376
  }
39278
39377
  ),
39279
- /* @__PURE__ */ jsx39(DropdownMenuPortal, { children: /* @__PURE__ */ jsxs10(
39378
+ /* @__PURE__ */ jsx40(DropdownMenuPortal, { children: /* @__PURE__ */ jsxs10(
39280
39379
  ViewportSubContent,
39281
39380
  {
39282
39381
  style: { ...contentStyles2, marginLeft: -2 },
@@ -39295,13 +39394,13 @@ var ContextMenu = ({
39295
39394
  onMouseLeave: () => setHoveredItem(null),
39296
39395
  onTouchStart: () => setHoveredItem(option),
39297
39396
  children: [
39298
- /* @__PURE__ */ jsx39("span", { style: iconContainerStyles2, children: cameraPreset === option && /* @__PURE__ */ jsx39(DotIcon, {}) }),
39299
- /* @__PURE__ */ jsx39("span", { style: { display: "flex", alignItems: "center" }, children: option })
39397
+ /* @__PURE__ */ jsx40("span", { style: iconContainerStyles2, children: cameraPreset === option && /* @__PURE__ */ jsx40(DotIcon, {}) }),
39398
+ /* @__PURE__ */ jsx40("span", { style: { display: "flex", alignItems: "center" }, children: option })
39300
39399
  ]
39301
39400
  },
39302
39401
  option
39303
39402
  )),
39304
- /* @__PURE__ */ jsx39(DropdownMenuSeparator, { style: separatorStyles2 }),
39403
+ /* @__PURE__ */ jsx40(DropdownMenuSeparator, { style: separatorStyles2 }),
39305
39404
  /* @__PURE__ */ jsxs10(
39306
39405
  DropdownMenuItem,
39307
39406
  {
@@ -39314,8 +39413,8 @@ var ContextMenu = ({
39314
39413
  onMouseLeave: () => setHoveredItem(null),
39315
39414
  onTouchStart: () => setHoveredItem("autorotate"),
39316
39415
  children: [
39317
- /* @__PURE__ */ jsx39("span", { style: iconContainerStyles2, children: autoRotate && /* @__PURE__ */ jsx39(CheckIcon, {}) }),
39318
- /* @__PURE__ */ jsx39("span", { style: { display: "flex", alignItems: "center" }, children: "Auto rotate" })
39416
+ /* @__PURE__ */ jsx40("span", { style: iconContainerStyles2, children: autoRotate && /* @__PURE__ */ jsx40(CheckIcon, {}) }),
39417
+ /* @__PURE__ */ jsx40("span", { style: { display: "flex", alignItems: "center" }, children: "Auto rotate" })
39319
39418
  ]
39320
39419
  }
39321
39420
  ),
@@ -39336,8 +39435,8 @@ var ContextMenu = ({
39336
39435
  onMouseLeave: () => setHoveredItem(null),
39337
39436
  onTouchStart: () => setHoveredItem("cameratype"),
39338
39437
  children: [
39339
- /* @__PURE__ */ jsx39("span", { style: iconContainerStyles2, children: cameraType === "orthographic" && /* @__PURE__ */ jsx39(CheckIcon, {}) }),
39340
- /* @__PURE__ */ jsx39("span", { style: { display: "flex", alignItems: "center" }, children: "Orthographic Camera" })
39438
+ /* @__PURE__ */ jsx40("span", { style: iconContainerStyles2, children: cameraType === "orthographic" && /* @__PURE__ */ jsx40(CheckIcon, {}) }),
39439
+ /* @__PURE__ */ jsx40("span", { style: { display: "flex", alignItems: "center" }, children: "Orthographic Camera" })
39341
39440
  ]
39342
39441
  }
39343
39442
  )
@@ -39358,14 +39457,14 @@ var ContextMenu = ({
39358
39457
  onMouseLeave: () => setHoveredItem(null),
39359
39458
  onTouchStart: () => setHoveredItem("reference-object"),
39360
39459
  children: [
39361
- /* @__PURE__ */ jsx39(
39460
+ /* @__PURE__ */ jsx40(
39362
39461
  "span",
39363
39462
  {
39364
39463
  style: { flex: 1, display: "flex", alignItems: "center" },
39365
39464
  children: "Show Reference Object"
39366
39465
  }
39367
39466
  ),
39368
- /* @__PURE__ */ jsx39(
39467
+ /* @__PURE__ */ jsx40(
39369
39468
  "div",
39370
39469
  {
39371
39470
  style: {
@@ -39374,13 +39473,13 @@ var ContextMenu = ({
39374
39473
  gap: 6,
39375
39474
  marginLeft: "auto"
39376
39475
  },
39377
- children: /* @__PURE__ */ jsx39(ChevronRightIcon, { isOpen: referenceObjectSubOpen })
39476
+ children: /* @__PURE__ */ jsx40(ChevronRightIcon, { isOpen: referenceObjectSubOpen })
39378
39477
  }
39379
39478
  )
39380
39479
  ]
39381
39480
  }
39382
39481
  ),
39383
- /* @__PURE__ */ jsx39(DropdownMenuPortal, { children: /* @__PURE__ */ jsx39(
39482
+ /* @__PURE__ */ jsx40(DropdownMenuPortal, { children: /* @__PURE__ */ jsx40(
39384
39483
  ViewportSubContent,
39385
39484
  {
39386
39485
  style: { ...contentStyles2, marginLeft: -2 },
@@ -39404,8 +39503,8 @@ var ContextMenu = ({
39404
39503
  onMouseLeave: () => setHoveredItem(null),
39405
39504
  onTouchStart: () => setHoveredItem(optionKey),
39406
39505
  children: [
39407
- /* @__PURE__ */ jsx39("span", { style: iconContainerStyles2, children: referenceObject === option.type && /* @__PURE__ */ jsx39(DotIcon, {}) }),
39408
- /* @__PURE__ */ jsx39("span", { style: { display: "flex", alignItems: "center" }, children: option.label })
39506
+ /* @__PURE__ */ jsx40("span", { style: iconContainerStyles2, children: referenceObject === option.type && /* @__PURE__ */ jsx40(DotIcon, {}) }),
39507
+ /* @__PURE__ */ jsx40("span", { style: { display: "flex", alignItems: "center" }, children: option.label })
39409
39508
  ]
39410
39509
  },
39411
39510
  optionKey
@@ -39426,8 +39525,8 @@ var ContextMenu = ({
39426
39525
  onMouseEnter: () => setHoveredItem("fold"),
39427
39526
  onMouseLeave: () => setHoveredItem(null),
39428
39527
  children: [
39429
- /* @__PURE__ */ jsx39("span", { style: iconContainerStyles2, children: foldPcbs && /* @__PURE__ */ jsx39(CheckIcon, {}) }),
39430
- /* @__PURE__ */ jsx39("span", { children: "Fold PCBs" })
39528
+ /* @__PURE__ */ jsx40("span", { style: iconContainerStyles2, children: foldPcbs && /* @__PURE__ */ jsx40(CheckIcon, {}) }),
39529
+ /* @__PURE__ */ jsx40("span", { children: "Fold PCBs" })
39431
39530
  ]
39432
39531
  }
39433
39532
  ),
@@ -39447,20 +39546,20 @@ var ContextMenu = ({
39447
39546
  onMouseLeave: () => setHoveredItem(null),
39448
39547
  onTouchStart: () => setHoveredItem("grid"),
39449
39548
  children: [
39450
- /* @__PURE__ */ jsx39("span", { style: iconContainerStyles2, children: gridEnabled && /* @__PURE__ */ jsx39(CheckIcon, {}) }),
39451
- /* @__PURE__ */ jsx39("span", { style: { display: "flex", alignItems: "center" }, children: "Show Grid" })
39549
+ /* @__PURE__ */ jsx40("span", { style: iconContainerStyles2, children: gridEnabled && /* @__PURE__ */ jsx40(CheckIcon, {}) }),
39550
+ /* @__PURE__ */ jsx40("span", { style: { display: "flex", alignItems: "center" }, children: "Show Grid" })
39452
39551
  ]
39453
39552
  }
39454
39553
  ),
39455
- /* @__PURE__ */ jsx39(
39554
+ /* @__PURE__ */ jsx40(
39456
39555
  AppearanceMenu,
39457
39556
  {
39458
39557
  hasAssembly,
39459
39558
  showLayerControls: !preRendered
39460
39559
  }
39461
39560
  ),
39462
- /* @__PURE__ */ jsx39(DropdownMenuSeparator, { style: separatorStyles2 }),
39463
- /* @__PURE__ */ jsx39(
39561
+ /* @__PURE__ */ jsx40(DropdownMenuSeparator, { style: separatorStyles2 }),
39562
+ /* @__PURE__ */ jsx40(
39464
39563
  DropdownMenuItem,
39465
39564
  {
39466
39565
  style: {
@@ -39472,10 +39571,10 @@ var ContextMenu = ({
39472
39571
  onMouseEnter: () => setHoveredItem("download"),
39473
39572
  onMouseLeave: () => setHoveredItem(null),
39474
39573
  onTouchStart: () => setHoveredItem("download"),
39475
- children: /* @__PURE__ */ jsx39("span", { style: { display: "flex", alignItems: "center" }, children: "Download GLTF" })
39574
+ children: /* @__PURE__ */ jsx40("span", { style: { display: "flex", alignItems: "center" }, children: "Download GLTF" })
39476
39575
  }
39477
39576
  ),
39478
- /* @__PURE__ */ jsx39(DropdownMenuSeparator, { style: separatorStyles2 }),
39577
+ /* @__PURE__ */ jsx40(DropdownMenuSeparator, { style: separatorStyles2 }),
39479
39578
  (onSectionView || onExplosionView || !flexScene && !preRendered) && /* @__PURE__ */ jsxs10(Fragment11, { children: [
39480
39579
  /* @__PURE__ */ jsxs10(DropdownMenuSub, { onOpenChange: setAdvancedSubOpen, children: [
39481
39580
  /* @__PURE__ */ jsxs10(
@@ -39490,12 +39589,12 @@ var ContextMenu = ({
39490
39589
  onMouseLeave: () => setHoveredItem(null),
39491
39590
  onTouchStart: () => setHoveredItem("advanced"),
39492
39591
  children: [
39493
- /* @__PURE__ */ jsx39("span", { style: { flex: 1 }, children: "Advanced" }),
39494
- /* @__PURE__ */ jsx39(ChevronRightIcon, { isOpen: advancedSubOpen })
39592
+ /* @__PURE__ */ jsx40("span", { style: { flex: 1 }, children: "Advanced" }),
39593
+ /* @__PURE__ */ jsx40(ChevronRightIcon, { isOpen: advancedSubOpen })
39495
39594
  ]
39496
39595
  }
39497
39596
  ),
39498
- /* @__PURE__ */ jsx39(DropdownMenuPortal, { children: /* @__PURE__ */ jsxs10(
39597
+ /* @__PURE__ */ jsx40(DropdownMenuPortal, { children: /* @__PURE__ */ jsxs10(
39499
39598
  ViewportSubContent,
39500
39599
  {
39501
39600
  style: { ...contentStyles2, marginLeft: -2 },
@@ -39523,7 +39622,7 @@ var ContextMenu = ({
39523
39622
  ]
39524
39623
  }
39525
39624
  ),
39526
- onExplosionView && /* @__PURE__ */ jsx39(
39625
+ onExplosionView && /* @__PURE__ */ jsx40(
39527
39626
  DropdownMenuItem,
39528
39627
  {
39529
39628
  disabled: !explosionAvailable,
@@ -39539,7 +39638,7 @@ var ContextMenu = ({
39539
39638
  children: "Exploded view\u2026"
39540
39639
  }
39541
39640
  ),
39542
- onSectionView && /* @__PURE__ */ jsx39(
39641
+ onSectionView && /* @__PURE__ */ jsx40(
39543
39642
  DropdownMenuItem,
39544
39643
  {
39545
39644
  style: {
@@ -39557,7 +39656,7 @@ var ContextMenu = ({
39557
39656
  }
39558
39657
  ) })
39559
39658
  ] }),
39560
- /* @__PURE__ */ jsx39(DropdownMenuSeparator, { style: separatorStyles2 })
39659
+ /* @__PURE__ */ jsx40(DropdownMenuSeparator, { style: separatorStyles2 })
39561
39660
  ] }),
39562
39661
  /* @__PURE__ */ jsxs10(
39563
39662
  DropdownMenuItem,
@@ -39572,8 +39671,8 @@ var ContextMenu = ({
39572
39671
  onMouseLeave: () => setHoveredItem(null),
39573
39672
  onTouchStart: () => setHoveredItem("shortcuts"),
39574
39673
  children: [
39575
- /* @__PURE__ */ jsx39("span", { style: { flex: 1, display: "flex", alignItems: "center" }, children: "Keyboard Shortcuts" }),
39576
- /* @__PURE__ */ jsx39(
39674
+ /* @__PURE__ */ jsx40("span", { style: { flex: 1, display: "flex", alignItems: "center" }, children: "Keyboard Shortcuts" }),
39675
+ /* @__PURE__ */ jsx40(
39577
39676
  "div",
39578
39677
  {
39579
39678
  style: {
@@ -39587,8 +39686,8 @@ var ContextMenu = ({
39587
39686
  ]
39588
39687
  }
39589
39688
  ),
39590
- /* @__PURE__ */ jsx39(DropdownMenuSeparator, { style: separatorStyles2 }),
39591
- /* @__PURE__ */ jsx39(
39689
+ /* @__PURE__ */ jsx40(DropdownMenuSeparator, { style: separatorStyles2 }),
39690
+ /* @__PURE__ */ jsx40(
39592
39691
  "div",
39593
39692
  {
39594
39693
  style: {
@@ -39626,10 +39725,10 @@ var ContextMenu = ({
39626
39725
  };
39627
39726
 
39628
39727
  // src/components/KeyboardShortcutsDialog.tsx
39629
- import { useEffect as useEffect54, useMemo as useMemo40, useRef as useRef28, useState as useState44 } from "react";
39728
+ import { useEffect as useEffect55, useMemo as useMemo41, useRef as useRef28, useState as useState44 } from "react";
39630
39729
 
39631
39730
  // src/hooks/useRegisteredHotkey.ts
39632
- import { useEffect as useEffect53, useMemo as useMemo39, useRef as useRef27, useState as useState43 } from "react";
39731
+ import { useEffect as useEffect54, useMemo as useMemo40, useRef as useRef27, useState as useState43 } from "react";
39633
39732
  var hotkeyRegistry = /* @__PURE__ */ new Map();
39634
39733
  var subscribers = /* @__PURE__ */ new Set();
39635
39734
  var isListenerAttached = false;
@@ -39753,14 +39852,14 @@ var subscribeToRegistry = (subscriber) => {
39753
39852
  var useRegisteredHotkey = (id, handler, metadata) => {
39754
39853
  const handlerRef = useRef27(handler);
39755
39854
  handlerRef.current = handler;
39756
- const normalizedMetadata = useMemo39(
39855
+ const normalizedMetadata = useMemo40(
39757
39856
  () => ({
39758
39857
  shortcut: metadata.shortcut,
39759
39858
  description: metadata.description
39760
39859
  }),
39761
39860
  [metadata.shortcut, metadata.description]
39762
39861
  );
39763
- useEffect53(() => {
39862
+ useEffect54(() => {
39764
39863
  const registration = {
39765
39864
  id,
39766
39865
  ...normalizedMetadata,
@@ -39776,7 +39875,7 @@ var useHotkeyRegistry = () => {
39776
39875
  const [entries, setEntries] = useState43(
39777
39876
  () => Array.from(hotkeyRegistry.values())
39778
39877
  );
39779
- useEffect53(() => subscribeToRegistry(setEntries), []);
39878
+ useEffect54(() => subscribeToRegistry(setEntries), []);
39780
39879
  return entries;
39781
39880
  };
39782
39881
  var registerHotkeyViewer = (element) => {
@@ -39785,7 +39884,7 @@ var registerHotkeyViewer = (element) => {
39785
39884
  };
39786
39885
 
39787
39886
  // src/components/KeyboardShortcutsDialog.tsx
39788
- import { jsx as jsx40, jsxs as jsxs11 } from "react/jsx-runtime";
39887
+ import { jsx as jsx41, jsxs as jsxs11 } from "react/jsx-runtime";
39789
39888
  var KeyboardShortcutsDialog = ({
39790
39889
  open,
39791
39890
  onClose
@@ -39793,7 +39892,7 @@ var KeyboardShortcutsDialog = ({
39793
39892
  const [query, setQuery] = useState44("");
39794
39893
  const inputRef = useRef28(null);
39795
39894
  const hotkeys = useHotkeyRegistry();
39796
- useEffect54(() => {
39895
+ useEffect55(() => {
39797
39896
  if (!open) return void 0;
39798
39897
  const handleKeyDown = (event) => {
39799
39898
  if (event.key === "Escape") {
@@ -39804,14 +39903,14 @@ var KeyboardShortcutsDialog = ({
39804
39903
  window.addEventListener("keydown", handleKeyDown);
39805
39904
  return () => window.removeEventListener("keydown", handleKeyDown);
39806
39905
  }, [open, onClose]);
39807
- useEffect54(() => {
39906
+ useEffect55(() => {
39808
39907
  if (open) {
39809
39908
  setTimeout(() => {
39810
39909
  inputRef.current?.focus();
39811
39910
  }, 0);
39812
39911
  }
39813
39912
  }, [open]);
39814
- const filteredHotkeys = useMemo40(() => {
39913
+ const filteredHotkeys = useMemo41(() => {
39815
39914
  const normalizedQuery = query.trim().toLowerCase();
39816
39915
  if (!normalizedQuery) {
39817
39916
  return hotkeys;
@@ -39824,7 +39923,7 @@ var KeyboardShortcutsDialog = ({
39824
39923
  if (!open) {
39825
39924
  return null;
39826
39925
  }
39827
- return /* @__PURE__ */ jsx40(
39926
+ return /* @__PURE__ */ jsx41(
39828
39927
  "div",
39829
39928
  {
39830
39929
  role: "dialog",
@@ -39864,7 +39963,7 @@ var KeyboardShortcutsDialog = ({
39864
39963
  },
39865
39964
  children: [
39866
39965
  /* @__PURE__ */ jsxs11("div", { style: { display: "flex", justifyContent: "space-between" }, children: [
39867
- /* @__PURE__ */ jsx40(
39966
+ /* @__PURE__ */ jsx41(
39868
39967
  "h2",
39869
39968
  {
39870
39969
  style: {
@@ -39876,7 +39975,7 @@ var KeyboardShortcutsDialog = ({
39876
39975
  children: "Keyboard Shortcuts"
39877
39976
  }
39878
39977
  ),
39879
- /* @__PURE__ */ jsx40(
39978
+ /* @__PURE__ */ jsx41(
39880
39979
  "button",
39881
39980
  {
39882
39981
  type: "button",
@@ -39892,7 +39991,7 @@ var KeyboardShortcutsDialog = ({
39892
39991
  }
39893
39992
  )
39894
39993
  ] }),
39895
- /* @__PURE__ */ jsx40(
39994
+ /* @__PURE__ */ jsx41(
39896
39995
  "input",
39897
39996
  {
39898
39997
  ref: inputRef,
@@ -39915,7 +40014,7 @@ var KeyboardShortcutsDialog = ({
39915
40014
  ]
39916
40015
  }
39917
40016
  ),
39918
- /* @__PURE__ */ jsx40("div", { style: { overflowY: "auto" }, children: /* @__PURE__ */ jsxs11(
40017
+ /* @__PURE__ */ jsx41("div", { style: { overflowY: "auto" }, children: /* @__PURE__ */ jsxs11(
39919
40018
  "table",
39920
40019
  {
39921
40020
  style: {
@@ -39924,11 +40023,11 @@ var KeyboardShortcutsDialog = ({
39924
40023
  fontSize: "0.95rem"
39925
40024
  },
39926
40025
  children: [
39927
- /* @__PURE__ */ jsx40("thead", { children: /* @__PURE__ */ jsxs11("tr", { style: { textAlign: "left", color: "#a1a1b5" }, children: [
39928
- /* @__PURE__ */ jsx40("th", { style: { padding: "12px 24px", width: "25%" }, children: "Key" }),
39929
- /* @__PURE__ */ jsx40("th", { style: { padding: "12px 24px" }, children: "Description" })
40026
+ /* @__PURE__ */ jsx41("thead", { children: /* @__PURE__ */ jsxs11("tr", { style: { textAlign: "left", color: "#a1a1b5" }, children: [
40027
+ /* @__PURE__ */ jsx41("th", { style: { padding: "12px 24px", width: "25%" }, children: "Key" }),
40028
+ /* @__PURE__ */ jsx41("th", { style: { padding: "12px 24px" }, children: "Description" })
39930
40029
  ] }) }),
39931
- /* @__PURE__ */ jsx40("tbody", { children: filteredHotkeys.length === 0 ? /* @__PURE__ */ jsx40("tr", { children: /* @__PURE__ */ jsx40(
40030
+ /* @__PURE__ */ jsx41("tbody", { children: filteredHotkeys.length === 0 ? /* @__PURE__ */ jsx41("tr", { children: /* @__PURE__ */ jsx41(
39932
40031
  "td",
39933
40032
  {
39934
40033
  colSpan: 2,
@@ -39940,7 +40039,7 @@ var KeyboardShortcutsDialog = ({
39940
40039
  {
39941
40040
  style: { borderTop: "1px solid rgba(255, 255, 255, 0.05)" },
39942
40041
  children: [
39943
- /* @__PURE__ */ jsx40("td", { style: { padding: "12px 24px" }, children: /* @__PURE__ */ jsx40(
40042
+ /* @__PURE__ */ jsx41("td", { style: { padding: "12px 24px" }, children: /* @__PURE__ */ jsx41(
39944
40043
  "span",
39945
40044
  {
39946
40045
  style: {
@@ -39958,7 +40057,7 @@ var KeyboardShortcutsDialog = ({
39958
40057
  children: hotkey.shortcut
39959
40058
  }
39960
40059
  ) }),
39961
- /* @__PURE__ */ jsx40("td", { style: { padding: "12px 24px" }, children: hotkey.description })
40060
+ /* @__PURE__ */ jsx41("td", { style: { padding: "12px 24px" }, children: hotkey.description })
39962
40061
  ]
39963
40062
  },
39964
40063
  hotkey.id
@@ -39975,7 +40074,7 @@ var KeyboardShortcutsDialog = ({
39975
40074
 
39976
40075
  // src/contexts/ToastContext.tsx
39977
40076
  import { Toaster, toast as hotToast } from "react-hot-toast";
39978
- import { Fragment as Fragment12, jsx as jsx41, jsxs as jsxs12 } from "react/jsx-runtime";
40077
+ import { Fragment as Fragment12, jsx as jsx42, jsxs as jsxs12 } from "react/jsx-runtime";
39979
40078
  var useToast = () => {
39980
40079
  return {
39981
40080
  showToast: (message, duration = 2e3) => {
@@ -39988,7 +40087,7 @@ var ToastProvider = ({
39988
40087
  }) => {
39989
40088
  return /* @__PURE__ */ jsxs12(Fragment12, { children: [
39990
40089
  children,
39991
- /* @__PURE__ */ jsx41(Toaster, { position: "bottom-right" })
40090
+ /* @__PURE__ */ jsx42(Toaster, { position: "bottom-right" })
39992
40091
  ] });
39993
40092
  };
39994
40093
 
@@ -40033,7 +40132,7 @@ function useCameraPreset({
40033
40132
  }
40034
40133
 
40035
40134
  // src/hooks/useContextMenu.ts
40036
- import { useState as useState45, useCallback as useCallback23, useRef as useRef29, useEffect as useEffect55 } from "react";
40135
+ import { useState as useState45, useCallback as useCallback23, useRef as useRef29, useEffect as useEffect56 } from "react";
40037
40136
  var useContextMenu = ({ containerRef, onOpen }) => {
40038
40137
  const [menuVisible, setMenuVisible] = useState45(false);
40039
40138
  const [menuPos, setMenuPos] = useState45({
@@ -40150,7 +40249,7 @@ var useContextMenu = ({ containerRef, onOpen }) => {
40150
40249
  }
40151
40250
  setMenuVisible(false);
40152
40251
  }, []);
40153
- useEffect55(() => {
40252
+ useEffect56(() => {
40154
40253
  if (menuVisible) {
40155
40254
  document.addEventListener("mousedown", handleClickAway);
40156
40255
  document.addEventListener("touchstart", handleClickAway);
@@ -40184,33 +40283,33 @@ var useContextMenu = ({ containerRef, onOpen }) => {
40184
40283
  };
40185
40284
 
40186
40285
  // src/sections/section-export.ts
40187
- import * as THREE62 from "three";
40286
+ import * as THREE63 from "three";
40188
40287
  function createSectionExport(root, spec) {
40189
40288
  root.updateWorldMatrix(true, true);
40190
40289
  const output = root.clone(true);
40191
40290
  output.updateWorldMatrix(true, true);
40192
40291
  const plane = sectionPlane(spec);
40193
40292
  const hatch = createSectionHatch();
40194
- const capMaterial = new THREE62.MeshBasicMaterial({
40293
+ const capMaterial = new THREE63.MeshBasicMaterial({
40195
40294
  map: hatch,
40196
- side: THREE62.DoubleSide
40295
+ side: THREE63.DoubleSide
40197
40296
  });
40198
40297
  const ownedGeometries = [];
40199
40298
  const ownedMaterials = [capMaterial];
40200
40299
  output.traverse((object) => {
40201
- if (!(object instanceof THREE62.Mesh)) return;
40300
+ if (!(object instanceof THREE63.Mesh)) return;
40202
40301
  const indexed = Boolean(object.geometry.index);
40203
40302
  const source = object.geometry.index ? object.geometry.toNonIndexed() : object.geometry;
40204
40303
  const p = source.getAttribute("position");
40205
40304
  if (!p) return;
40206
40305
  const worldPositions = new Float32Array(p.count * 3);
40207
- const world = new THREE62.Vector3();
40306
+ const world = new THREE63.Vector3();
40208
40307
  for (let i = 0; i < p.count; i++)
40209
40308
  world.fromBufferAttribute(p, i).applyMatrix4(object.matrixWorld).toArray(worldPositions, i * 3);
40210
40309
  const attributes = Object.entries(source.attributes);
40211
40310
  const values = new Map(attributes.map(([name]) => [name, []]));
40212
- const geometry = new THREE62.BufferGeometry();
40213
- const point = (i) => new THREE62.Vector3().fromArray(worldPositions, i * 3);
40311
+ const geometry = new THREE63.BufferGeometry();
40312
+ const point = (i) => new THREE63.Vector3().fromArray(worldPositions, i * 3);
40214
40313
  for (let i = 0; i < p.count; i += 3) {
40215
40314
  let polygon2 = [
40216
40315
  [1, 0, 0],
@@ -40259,7 +40358,7 @@ function createSectionExport(root, spec) {
40259
40358
  for (const [name, attribute] of attributes)
40260
40359
  geometry.setAttribute(
40261
40360
  name,
40262
- new THREE62.Float32BufferAttribute(values.get(name), attribute.itemSize)
40361
+ new THREE63.Float32BufferAttribute(values.get(name), attribute.itemSize)
40263
40362
  );
40264
40363
  if (geometry.getAttribute("normal")) geometry.normalizeNormals();
40265
40364
  ownedGeometries.push(geometry);
@@ -40273,18 +40372,18 @@ function createSectionExport(root, spec) {
40273
40372
  object.material = Array.isArray(object.material) ? object.material.map(cloneMaterial) : cloneMaterial(object.material);
40274
40373
  const { loops } = findSectionLoops({ positions: worldPositions, ...spec });
40275
40374
  const cap = buildSectionCap(loops, spec);
40276
- cap.applyMatrix4(new THREE62.Matrix4().copy(object.matrixWorld).invert());
40375
+ cap.applyMatrix4(new THREE63.Matrix4().copy(object.matrixWorld).invert());
40277
40376
  ownedGeometries.push(cap);
40278
40377
  object.userData.sectionExportCap = cap;
40279
40378
  if (indexed) source.dispose();
40280
40379
  });
40281
40380
  const pending = [];
40282
40381
  output.traverse((object) => {
40283
- if (object instanceof THREE62.Mesh && object.userData.sectionExportCap)
40382
+ if (object instanceof THREE63.Mesh && object.userData.sectionExportCap)
40284
40383
  pending.push(object);
40285
40384
  });
40286
40385
  for (const mesh of pending) {
40287
- mesh.add(new THREE62.Mesh(mesh.userData.sectionExportCap, capMaterial));
40386
+ mesh.add(new THREE63.Mesh(mesh.userData.sectionExportCap, capMaterial));
40288
40387
  delete mesh.userData.sectionExportCap;
40289
40388
  }
40290
40389
  delete output.userData.sectionView;
@@ -40332,8 +40431,8 @@ var useGlobalDownloadGltf = () => {
40332
40431
  };
40333
40432
 
40334
40433
  // src/CadViewer.tsx
40335
- import { jsx as jsx42, jsxs as jsxs13 } from "react/jsx-runtime";
40336
- var DEFAULT_TARGET = new THREE63.Vector3(0, 0, 0);
40434
+ import { jsx as jsx43, jsxs as jsxs13 } from "react/jsx-runtime";
40435
+ var DEFAULT_TARGET = new THREE64.Vector3(0, 0, 0);
40337
40436
  var INITIAL_CAMERA_POSITION = [5, -5, 5];
40338
40437
  var readStoredCameraType = () => {
40339
40438
  if (typeof window === "undefined") return void 0;
@@ -40363,12 +40462,12 @@ var CadViewerInner = (props) => {
40363
40462
  const resolvedFoldPcbs = resolveFoldPcbs(circuitJson, foldPcbs);
40364
40463
  const circuitJsonKey = glbSource === void 0 ? JSON.stringify(circuitJson) : void 0;
40365
40464
  const circuitKey = glbSource ?? circuitJsonKey;
40366
- const { hiddenCadComponentIds, hideComponent, unhideAllComponents } = useHiddenCadComponents(circuitKey);
40465
+ const { objectVisibility, hideObject, isolateObject, unhideAllObjects } = useObjectVisibility(circuitKey);
40367
40466
  const resolvedProps = {
40368
40467
  ...props,
40369
40468
  circuitJson,
40370
40469
  children: void 0,
40371
- hiddenCadComponentIds
40470
+ objectVisibility
40372
40471
  };
40373
40472
  const [engine, setEngine] = useState46(() => {
40374
40473
  const stored = window.localStorage.getItem("cadViewerEngine");
@@ -40393,11 +40492,11 @@ var CadViewerInner = (props) => {
40393
40492
  const externalCameraControllerReady = props.onCameraControllerReady;
40394
40493
  const sceneRef = useContext13(SchematicNavigationContext);
40395
40494
  const [selectedComponent, setSelectedComponent] = useState46();
40396
- const [selectedCadComponent, setSelectedCadComponent] = useState46();
40495
+ const [selectedObject, setSelectedObject] = useState46();
40397
40496
  const handleMenuOpen = useCallback25(
40398
40497
  (position) => {
40399
- setSelectedCadComponent(
40400
- pickCadComponent(sceneRef.current, position, circuitJson)
40498
+ setSelectedObject(
40499
+ pickSceneObject(sceneRef.current, position, circuitJson)
40401
40500
  );
40402
40501
  setSelectedComponent(
40403
40502
  props.onViewSchematicComponent ? pickSchematicComponent(sceneRef.current, position, circuitJson) : void 0
@@ -40510,28 +40609,28 @@ var CadViewerInner = (props) => {
40510
40609
  description: "Toggle translucent components"
40511
40610
  }
40512
40611
  );
40513
- useEffect56(() => {
40612
+ useEffect57(() => {
40514
40613
  if (containerRef.current) {
40515
40614
  registerHotkeyViewer(containerRef.current);
40516
40615
  }
40517
40616
  }, []);
40518
- useEffect56(() => {
40617
+ useEffect57(() => {
40519
40618
  window.localStorage.setItem("cadViewerEngine", engine);
40520
40619
  }, [engine]);
40521
- useEffect56(() => {
40620
+ useEffect57(() => {
40522
40621
  window.localStorage.setItem("cadViewerAutoRotate", String(autoRotate));
40523
40622
  }, [autoRotate]);
40524
- useEffect56(() => {
40623
+ useEffect57(() => {
40525
40624
  window.localStorage.setItem(
40526
40625
  "cadViewerAutoRotateUserToggled",
40527
40626
  String(autoRotateUserToggled)
40528
40627
  );
40529
40628
  }, [autoRotateUserToggled]);
40530
- useEffect56(() => {
40629
+ useEffect57(() => {
40531
40630
  window.localStorage.setItem("cadViewerCameraType", cameraType);
40532
40631
  }, [cameraType]);
40533
40632
  const viewerKey = props.circuitJson ? circuitJsonKey : void 0;
40534
- return /* @__PURE__ */ jsx42(AssemblyExplosionContext.Provider, { value: explosion, children: /* @__PURE__ */ jsxs13(
40633
+ return /* @__PURE__ */ jsx43(AssemblyExplosionContext.Provider, { value: explosion, children: /* @__PURE__ */ jsxs13(
40535
40634
  "div",
40536
40635
  {
40537
40636
  ref: containerRef,
@@ -40547,7 +40646,7 @@ var CadViewerInner = (props) => {
40547
40646
  },
40548
40647
  ...contextMenuEventHandlers,
40549
40648
  children: [
40550
- explosionPanelOpen && /* @__PURE__ */ jsx42(
40649
+ explosionPanelOpen && /* @__PURE__ */ jsx43(
40551
40650
  AssemblyExplosionControl,
40552
40651
  {
40553
40652
  stages: explosion.stages,
@@ -40560,18 +40659,18 @@ var CadViewerInner = (props) => {
40560
40659
  }
40561
40660
  }
40562
40661
  ),
40563
- glbSource !== void 0 ? /* @__PURE__ */ jsx42(
40662
+ glbSource !== void 0 ? /* @__PURE__ */ jsx43(
40564
40663
  CadViewerGlb,
40565
40664
  {
40566
40665
  source: glbSource,
40567
- hiddenCadComponentIds,
40666
+ objectVisibility,
40568
40667
  autoRotateDisabled: props.autoRotateDisabled || !autoRotate,
40569
40668
  clickToInteractEnabled: props.clickToInteractEnabled,
40570
40669
  onUserInteraction: handleUserInteraction,
40571
40670
  onCameraControllerReady: handleCameraControllerReady,
40572
40671
  referenceObject
40573
40672
  }
40574
- ) : hasFlexGeometry ? /* @__PURE__ */ jsx42(
40673
+ ) : hasFlexGeometry ? /* @__PURE__ */ jsx43(
40575
40674
  CadViewerManifold_default,
40576
40675
  {
40577
40676
  ...resolvedProps,
@@ -40581,7 +40680,7 @@ var CadViewerInner = (props) => {
40581
40680
  onCameraControllerReady: handleCameraControllerReady,
40582
40681
  referenceObject
40583
40682
  }
40584
- ) : engine === "jscad" ? /* @__PURE__ */ jsx42(
40683
+ ) : engine === "jscad" ? /* @__PURE__ */ jsx43(
40585
40684
  CadViewerJscad,
40586
40685
  {
40587
40686
  ...resolvedProps,
@@ -40591,7 +40690,7 @@ var CadViewerInner = (props) => {
40591
40690
  onCameraControllerReady: handleCameraControllerReady,
40592
40691
  referenceObject
40593
40692
  }
40594
- ) : /* @__PURE__ */ jsx42(
40693
+ ) : /* @__PURE__ */ jsx43(
40595
40694
  CadViewerManifold_default,
40596
40695
  {
40597
40696
  ...resolvedProps,
@@ -40602,18 +40701,22 @@ var CadViewerInner = (props) => {
40602
40701
  referenceObject
40603
40702
  }
40604
40703
  ),
40605
- /* @__PURE__ */ jsx42(SectionPanel, {}),
40606
- menuVisible && /* @__PURE__ */ jsx42(
40704
+ /* @__PURE__ */ jsx43(SectionPanel, {}),
40705
+ menuVisible && /* @__PURE__ */ jsx43(
40607
40706
  ContextMenu,
40608
40707
  {
40609
40708
  hasAssembly,
40610
- componentName: selectedCadComponent?.componentName,
40611
- onHideComponent: selectedCadComponent ? () => {
40612
- hideComponent(selectedCadComponent.cad_component_id);
40709
+ objectName: selectedObject?.name,
40710
+ onHideObject: selectedObject ? () => {
40711
+ hideObject(selectedObject.objectId);
40613
40712
  closeMenu();
40614
40713
  } : void 0,
40615
- onUnhideAllComponents: hiddenCadComponentIds.size > 0 ? () => {
40616
- unhideAllComponents();
40714
+ onIsolateObject: selectedObject && objectVisibility.isolatedId !== selectedObject.objectId ? () => {
40715
+ isolateObject(selectedObject.objectId);
40716
+ closeMenu();
40717
+ } : void 0,
40718
+ onUnhideAll: hasHiddenObjects(objectVisibility) ? () => {
40719
+ unhideAllObjects();
40617
40720
  closeMenu();
40618
40721
  } : void 0,
40619
40722
  onViewSchematicComponent: selectedComponent && props.onViewSchematicComponent ? () => {
@@ -40682,7 +40785,7 @@ var CadViewerInner = (props) => {
40682
40785
  }
40683
40786
  }
40684
40787
  ),
40685
- /* @__PURE__ */ jsx42(
40788
+ /* @__PURE__ */ jsx43(
40686
40789
  KeyboardShortcutsDialog,
40687
40790
  {
40688
40791
  open: isKeyboardShortcutsDialogOpen,
@@ -40697,13 +40800,13 @@ var CadViewerInner = (props) => {
40697
40800
  var CadViewer = (props) => {
40698
40801
  configureRuntimeFont();
40699
40802
  const sceneRef = useRef30(null);
40700
- return /* @__PURE__ */ jsx42(SchematicNavigationContext.Provider, { value: sceneRef, children: /* @__PURE__ */ jsx42(
40803
+ return /* @__PURE__ */ jsx43(SchematicNavigationContext.Provider, { value: sceneRef, children: /* @__PURE__ */ jsx43(
40701
40804
  CameraControllerProvider,
40702
40805
  {
40703
40806
  defaultTarget: DEFAULT_TARGET,
40704
40807
  initialCameraPosition: INITIAL_CAMERA_POSITION,
40705
40808
  initialCameraType: readStoredCameraType(),
40706
- children: /* @__PURE__ */ jsx42(LayerVisibilityProvider, { children: /* @__PURE__ */ jsx42(AppearanceProvider, { children: /* @__PURE__ */ jsx42(ToastProvider, { children: /* @__PURE__ */ jsx42(SectionProvider, { children: /* @__PURE__ */ jsx42(CadViewerInner, { ...props }) }) }) }) })
40809
+ children: /* @__PURE__ */ jsx43(LayerVisibilityProvider, { children: /* @__PURE__ */ jsx43(AppearanceProvider, { children: /* @__PURE__ */ jsx43(ToastProvider, { children: /* @__PURE__ */ jsx43(SectionProvider, { children: /* @__PURE__ */ jsx43(CadViewerInner, { ...props }) }) }) }) })
40707
40810
  }
40708
40811
  ) });
40709
40812
  };
@@ -40711,11 +40814,11 @@ var CadViewer = (props) => {
40711
40814
  // src/convert-circuit-json-to-3d-svg.ts
40712
40815
  var import_debug = __toESM(require_browser(), 1);
40713
40816
  import { su as su18 } from "@tscircuit/circuit-json-util";
40714
- import * as THREE67 from "three";
40817
+ import * as THREE68 from "three";
40715
40818
  import { SVGRenderer } from "three/examples/jsm/renderers/SVGRenderer.js";
40716
40819
 
40717
40820
  // src/utils/create-geometry-from-polygons.ts
40718
- import * as THREE64 from "three";
40821
+ import * as THREE65 from "three";
40719
40822
  import { BufferGeometry as BufferGeometry9, Float32BufferAttribute as Float32BufferAttribute8 } from "three";
40720
40823
  function createGeometryFromPolygons(polygons) {
40721
40824
  const geometry = new BufferGeometry9();
@@ -40729,12 +40832,12 @@ function createGeometryFromPolygons(polygons) {
40729
40832
  ...polygon2.vertices[i + 1]
40730
40833
  // Third vertex
40731
40834
  );
40732
- const v1 = new THREE64.Vector3(...polygon2.vertices[0]);
40733
- const v2 = new THREE64.Vector3(...polygon2.vertices[i]);
40734
- const v3 = new THREE64.Vector3(...polygon2.vertices[i + 1]);
40735
- const normal = new THREE64.Vector3().crossVectors(
40736
- new THREE64.Vector3().subVectors(v2, v1),
40737
- new THREE64.Vector3().subVectors(v3, v1)
40835
+ const v1 = new THREE65.Vector3(...polygon2.vertices[0]);
40836
+ const v2 = new THREE65.Vector3(...polygon2.vertices[i]);
40837
+ const v3 = new THREE65.Vector3(...polygon2.vertices[i + 1]);
40838
+ const normal = new THREE65.Vector3().crossVectors(
40839
+ new THREE65.Vector3().subVectors(v2, v1),
40840
+ new THREE65.Vector3().subVectors(v3, v1)
40738
40841
  ).normalize();
40739
40842
  normals.push(
40740
40843
  normal.x,
@@ -40762,10 +40865,10 @@ import {
40762
40865
  convertCSGToThreeGeom as convertCSGToThreeGeom3,
40763
40866
  getJscadModelForFootprint as getJscadModelForFootprint2
40764
40867
  } from "jscad-electronics/vanilla";
40765
- import * as THREE66 from "three";
40868
+ import * as THREE67 from "three";
40766
40869
 
40767
40870
  // src/utils/load-model.ts
40768
- import * as THREE65 from "three";
40871
+ import * as THREE66 from "three";
40769
40872
  import { GLTFLoader as GLTFLoader3 } from "three/examples/jsm/loaders/GLTFLoader.js";
40770
40873
  import { OBJLoader as OBJLoader2 } from "three/examples/jsm/loaders/OBJLoader.js";
40771
40874
  import { STLLoader as STLLoader3 } from "three/examples/jsm/loaders/STLLoader.js";
@@ -40773,12 +40876,12 @@ async function load3DModel(url) {
40773
40876
  if (url.endsWith(".stl")) {
40774
40877
  const loader = new STLLoader3();
40775
40878
  const geometry = await loader.loadAsync(url);
40776
- const material = new THREE65.MeshStandardMaterial({
40879
+ const material = new THREE66.MeshStandardMaterial({
40777
40880
  color: 8947848,
40778
40881
  metalness: 0.5,
40779
40882
  roughness: 0.5
40780
40883
  });
40781
- return new THREE65.Mesh(geometry, material);
40884
+ return new THREE66.Mesh(geometry, material);
40782
40885
  }
40783
40886
  if (url.endsWith(".obj")) {
40784
40887
  const loader = new OBJLoader2();
@@ -40811,9 +40914,9 @@ async function renderComponent(component, scene) {
40811
40914
  }
40812
40915
  if (component.rotation) {
40813
40916
  model.rotation.set(
40814
- THREE66.MathUtils.degToRad(component.rotation.x ?? 0),
40815
- THREE66.MathUtils.degToRad(component.rotation.y ?? 0),
40816
- THREE66.MathUtils.degToRad(component.rotation.z ?? 0)
40917
+ THREE67.MathUtils.degToRad(component.rotation.x ?? 0),
40918
+ THREE67.MathUtils.degToRad(component.rotation.y ?? 0),
40919
+ THREE67.MathUtils.degToRad(component.rotation.z ?? 0)
40817
40920
  );
40818
40921
  }
40819
40922
  scene.add(model);
@@ -40827,13 +40930,13 @@ async function renderComponent(component, scene) {
40827
40930
  );
40828
40931
  if (jscadObject && (jscadObject.polygons || jscadObject.sides)) {
40829
40932
  const threeGeom = convertCSGToThreeGeom3(jscadObject);
40830
- const material2 = new THREE66.MeshStandardMaterial({
40933
+ const material2 = new THREE67.MeshStandardMaterial({
40831
40934
  color: 8947848,
40832
40935
  metalness: 0.5,
40833
40936
  roughness: 0.5,
40834
- side: THREE66.DoubleSide
40937
+ side: THREE67.DoubleSide
40835
40938
  });
40836
- const mesh2 = new THREE66.Mesh(threeGeom, material2);
40939
+ const mesh2 = new THREE67.Mesh(threeGeom, material2);
40837
40940
  if (component.position) {
40838
40941
  mesh2.position.set(
40839
40942
  component.position.x ?? 0,
@@ -40843,9 +40946,9 @@ async function renderComponent(component, scene) {
40843
40946
  }
40844
40947
  if (component.rotation) {
40845
40948
  mesh2.rotation.set(
40846
- THREE66.MathUtils.degToRad(component.rotation.x ?? 0),
40847
- THREE66.MathUtils.degToRad(component.rotation.y ?? 0),
40848
- THREE66.MathUtils.degToRad(component.rotation.z ?? 0)
40949
+ THREE67.MathUtils.degToRad(component.rotation.x ?? 0),
40950
+ THREE67.MathUtils.degToRad(component.rotation.y ?? 0),
40951
+ THREE67.MathUtils.degToRad(component.rotation.z ?? 0)
40849
40952
  );
40850
40953
  }
40851
40954
  scene.add(mesh2);
@@ -40862,17 +40965,17 @@ async function renderComponent(component, scene) {
40862
40965
  if (!geom || !geom.polygons && !geom.sides) {
40863
40966
  continue;
40864
40967
  }
40865
- const color = new THREE66.Color(geomInfo.color);
40968
+ const color = new THREE67.Color(geomInfo.color);
40866
40969
  color.convertLinearToSRGB();
40867
40970
  const geomWithColor = { ...geom, color: [color.r, color.g, color.b] };
40868
40971
  const threeGeom = convertCSGToThreeGeom3(geomWithColor);
40869
- const material2 = new THREE66.MeshStandardMaterial({
40972
+ const material2 = new THREE67.MeshStandardMaterial({
40870
40973
  vertexColors: true,
40871
40974
  metalness: 0.2,
40872
40975
  roughness: 0.8,
40873
- side: THREE66.DoubleSide
40976
+ side: THREE67.DoubleSide
40874
40977
  });
40875
- const mesh2 = new THREE66.Mesh(threeGeom, material2);
40978
+ const mesh2 = new THREE67.Mesh(threeGeom, material2);
40876
40979
  if (component.position) {
40877
40980
  mesh2.position.set(
40878
40981
  component.position.x ?? 0,
@@ -40882,22 +40985,22 @@ async function renderComponent(component, scene) {
40882
40985
  }
40883
40986
  if (component.rotation) {
40884
40987
  mesh2.rotation.set(
40885
- THREE66.MathUtils.degToRad(component.rotation.x ?? 0),
40886
- THREE66.MathUtils.degToRad(component.rotation.y ?? 0),
40887
- THREE66.MathUtils.degToRad(component.rotation.z ?? 0)
40988
+ THREE67.MathUtils.degToRad(component.rotation.x ?? 0),
40989
+ THREE67.MathUtils.degToRad(component.rotation.y ?? 0),
40990
+ THREE67.MathUtils.degToRad(component.rotation.z ?? 0)
40888
40991
  );
40889
40992
  }
40890
40993
  scene.add(mesh2);
40891
40994
  }
40892
40995
  return;
40893
40996
  }
40894
- const geometry = new THREE66.BoxGeometry(0.5, 0.5, 0.5);
40895
- const material = new THREE66.MeshStandardMaterial({
40997
+ const geometry = new THREE67.BoxGeometry(0.5, 0.5, 0.5);
40998
+ const material = new THREE67.MeshStandardMaterial({
40896
40999
  color: 16711680,
40897
41000
  transparent: true,
40898
41001
  opacity: 0.25
40899
41002
  });
40900
- const mesh = new THREE66.Mesh(geometry, material);
41003
+ const mesh = new THREE67.Mesh(geometry, material);
40901
41004
  if (component.position) {
40902
41005
  mesh.position.set(
40903
41006
  component.position.x ?? 0,
@@ -40918,11 +41021,11 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
40918
41021
  padding = 20,
40919
41022
  zoom = 1.5
40920
41023
  } = options;
40921
- const scene = new THREE67.Scene();
41024
+ const scene = new THREE68.Scene();
40922
41025
  const renderer = new SVGRenderer();
40923
41026
  renderer.setSize(width, height);
40924
- renderer.setClearColor(new THREE67.Color(backgroundColor), 1);
40925
- const camera = new THREE67.OrthographicCamera();
41027
+ renderer.setClearColor(new THREE68.Color(backgroundColor), 1);
41028
+ const camera = new THREE68.OrthographicCamera();
40926
41029
  const aspect = width / height;
40927
41030
  const frustumSize = 100;
40928
41031
  const halfFrustumSize = frustumSize / 2 / zoom;
@@ -40936,11 +41039,11 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
40936
41039
  camera.position.set(position.x, position.y, position.z);
40937
41040
  camera.up.set(0, 1, 0);
40938
41041
  const lookAt2 = options.camera?.lookAt ?? { x: 0, y: 0, z: 0 };
40939
- camera.lookAt(new THREE67.Vector3(lookAt2.x, lookAt2.y, lookAt2.z));
41042
+ camera.lookAt(new THREE68.Vector3(lookAt2.x, lookAt2.y, lookAt2.z));
40940
41043
  camera.updateProjectionMatrix();
40941
- const ambientLight = new THREE67.AmbientLight(16777215, Math.PI / 2);
41044
+ const ambientLight = new THREE68.AmbientLight(16777215, Math.PI / 2);
40942
41045
  scene.add(ambientLight);
40943
- const pointLight = new THREE67.PointLight(16777215, Math.PI / 4);
41046
+ const pointLight = new THREE68.PointLight(16777215, Math.PI / 4);
40944
41047
  pointLight.position.set(-10, -10, 10);
40945
41048
  scene.add(pointLight);
40946
41049
  const components = su18(circuitJson).cad_component.list();
@@ -40972,28 +41075,28 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
40972
41075
  const material = createBoardMaterial({
40973
41076
  material: boardData?.material,
40974
41077
  color: edgeColor,
40975
- side: THREE67.DoubleSide
41078
+ side: THREE68.DoubleSide
40976
41079
  });
40977
- const mesh = new THREE67.Mesh(geometry, material);
41080
+ const mesh = new THREE68.Mesh(geometry, material);
40978
41081
  scene.add(mesh);
40979
41082
  }
40980
41083
  }
40981
- const gridColor = new THREE67.Color(8947848);
40982
- const gridHelper = new THREE67.GridHelper(100, 100, gridColor, gridColor);
41084
+ const gridColor = new THREE68.Color(8947848);
41085
+ const gridHelper = new THREE68.GridHelper(100, 100, gridColor, gridColor);
40983
41086
  gridHelper.rotation.x = Math.PI / 2;
40984
41087
  const materials2 = Array.isArray(gridHelper.material) ? gridHelper.material : [gridHelper.material];
40985
41088
  for (const mat of materials2) {
40986
41089
  mat.transparent = true;
40987
41090
  mat.opacity = 0.3;
40988
- if (mat instanceof THREE67.LineBasicMaterial) {
41091
+ if (mat instanceof THREE68.LineBasicMaterial) {
40989
41092
  mat.color = gridColor;
40990
41093
  mat.vertexColors = false;
40991
41094
  }
40992
41095
  }
40993
41096
  scene.add(gridHelper);
40994
- const box = new THREE67.Box3().setFromObject(scene);
40995
- const center = box.getCenter(new THREE67.Vector3());
40996
- const size4 = box.getSize(new THREE67.Vector3());
41097
+ const box = new THREE68.Box3().setFromObject(scene);
41098
+ const center = box.getCenter(new THREE68.Vector3());
41099
+ const size4 = box.getSize(new THREE68.Vector3());
40997
41100
  scene.position.sub(center);
40998
41101
  const maxDim = Math.max(size4.x, size4.y, size4.z);
40999
41102
  if (maxDim > 0) {
@@ -41013,10 +41116,10 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
41013
41116
  import {
41014
41117
  GLTFExporter as GLTFExporter3
41015
41118
  } from "three/examples/jsm/exporters/GLTFExporter.js";
41016
- import { useEffect as useEffect57, useState as useState47, useMemo as useMemo41, useCallback as useCallback26 } from "react";
41119
+ import { useEffect as useEffect58, useState as useState47, useMemo as useMemo42, useCallback as useCallback26 } from "react";
41017
41120
  function useSaveGltfAs(options = {}) {
41018
41121
  const parse2 = useParser(options);
41019
- const link = useMemo41(() => document.createElement("a"), []);
41122
+ const link = useMemo42(() => document.createElement("a"), []);
41020
41123
  const saveAs = async (filename) => {
41021
41124
  const name = filename ?? options.filename ?? "";
41022
41125
  if (options.binary == null) options.binary = name.endsWith(".glb");
@@ -41026,7 +41129,7 @@ function useSaveGltfAs(options = {}) {
41026
41129
  link.dispatchEvent(new MouseEvent("click"));
41027
41130
  URL.revokeObjectURL(url);
41028
41131
  };
41029
- useEffect57(
41132
+ useEffect58(
41030
41133
  () => () => {
41031
41134
  link.remove();
41032
41135
  instance = null;
@@ -41047,11 +41150,11 @@ function useExportGltfUrl(options = {}) {
41047
41150
  (instance) => parse2(instance).then(setUrl).catch(setError),
41048
41151
  []
41049
41152
  );
41050
- useEffect57(() => () => URL.revokeObjectURL(url), [url]);
41153
+ useEffect58(() => () => URL.revokeObjectURL(url), [url]);
41051
41154
  return [ref, url, error];
41052
41155
  }
41053
41156
  function useParser(options = {}) {
41054
- const exporter = useMemo41(() => new GLTFExporter3(), []);
41157
+ const exporter = useMemo42(() => new GLTFExporter3(), []);
41055
41158
  return (instance) => {
41056
41159
  const { promise, resolve, reject } = Promise.withResolvers();
41057
41160
  exporter.parse(