@tscircuit/3d-viewer 0.0.628 → 0.0.629

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
@@ -18896,19 +18896,109 @@ var pickVisibleMesh = (scene, position) => {
18896
18896
  }
18897
18897
  };
18898
18898
 
18899
+ // src/utils/prerendered-glb.ts
18900
+ import * as THREE4 from "three";
18901
+ import { GLTFLoader } from "three-stdlib";
18902
+
18903
+ // src/utils/configure-object-shadows.ts
18904
+ import * as THREE3 from "three";
18905
+ var configureObjectShadows = (object, { castShadow = true, receiveShadow = true } = {}) => {
18906
+ object.traverse((child) => {
18907
+ if (!(child instanceof THREE3.Mesh)) return;
18908
+ child.castShadow = castShadow;
18909
+ child.receiveShadow = receiveShadow;
18910
+ });
18911
+ };
18912
+
18913
+ // src/utils/prerendered-glb.ts
18914
+ function getGlbComponentMetadata(object) {
18915
+ const metadata = object.userData.tscircuit;
18916
+ if (!metadata || typeof metadata !== "object") return;
18917
+ const result = {};
18918
+ for (const key of [
18919
+ "cad_component_id",
18920
+ "source_component_id",
18921
+ "pcb_component_id",
18922
+ "componentName"
18923
+ ]) {
18924
+ if (typeof metadata[key] === "string") result[key] = metadata[key];
18925
+ }
18926
+ return result;
18927
+ }
18928
+ function prepareGlbScene(scene) {
18929
+ const root = new THREE4.Group();
18930
+ root.name = "prerendered-glb";
18931
+ root.applyMatrix4(
18932
+ new THREE4.Matrix4().set(-1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1)
18933
+ );
18934
+ root.add(scene);
18935
+ scene.traverse((object) => {
18936
+ const metadata = getGlbComponentMetadata(object);
18937
+ if (metadata) Object.assign(object.userData, metadata);
18938
+ });
18939
+ configureObjectShadows(root);
18940
+ return root;
18941
+ }
18942
+ function disposeGlbScene(scene) {
18943
+ const geometries = /* @__PURE__ */ new Set();
18944
+ const materials = /* @__PURE__ */ new Set();
18945
+ const textures = /* @__PURE__ */ new Set();
18946
+ scene.traverse((object) => {
18947
+ if (!(object instanceof THREE4.Mesh)) return;
18948
+ geometries.add(object.geometry);
18949
+ for (const material of Array.isArray(object.material) ? object.material : [object.material]) {
18950
+ materials.add(material);
18951
+ for (const value of Object.values(material)) {
18952
+ if (value instanceof THREE4.Texture) textures.add(value);
18953
+ }
18954
+ }
18955
+ });
18956
+ for (const texture of textures) {
18957
+ texture.dispose();
18958
+ if (typeof ImageBitmap !== "undefined" && texture.image instanceof ImageBitmap)
18959
+ texture.image.close();
18960
+ }
18961
+ for (const material of materials) material.dispose();
18962
+ for (const geometry of geometries) geometry.dispose();
18963
+ }
18964
+ async function loadGlbScene(source, signal) {
18965
+ const loadSignal = AbortSignal.any([signal, AbortSignal.timeout(3e4)]);
18966
+ let bytes;
18967
+ if (typeof source === "string") {
18968
+ const response = await fetch(source, { signal: loadSignal });
18969
+ if (!response.ok) throw new Error(`Unable to load GLB (${response.status})`);
18970
+ bytes = await response.arrayBuffer();
18971
+ } else bytes = source;
18972
+ loadSignal.throwIfAborted();
18973
+ const gltf = await new GLTFLoader().parseAsync(bytes, "");
18974
+ if (loadSignal.aborted) {
18975
+ disposeGlbScene(gltf.scene);
18976
+ loadSignal.throwIfAborted();
18977
+ }
18978
+ return prepareGlbScene(gltf.scene);
18979
+ }
18980
+
18899
18981
  // src/utils/pick-schematic-component.ts
18900
18982
  var pickSchematicComponent = (scene, position, circuitJson) => {
18901
18983
  let object = pickVisibleMesh(scene, position) ?? null;
18902
18984
  let pcbComponentId;
18985
+ let glbIdentity;
18903
18986
  while (object) {
18904
18987
  pcbComponentId ??= object.userData.pcb_component_id;
18988
+ const metadata = getGlbComponentMetadata(object);
18989
+ if (metadata?.source_component_id && metadata.pcb_component_id && metadata.componentName)
18990
+ glbIdentity ??= {
18991
+ source_component_id: metadata.source_component_id,
18992
+ pcb_component_id: metadata.pcb_component_id,
18993
+ refdes: metadata.componentName
18994
+ };
18905
18995
  object = object.parent;
18906
18996
  }
18907
18997
  if (!pcbComponentId) return;
18908
18998
  const pcb = circuitJson.find(
18909
18999
  (e) => e.type === "pcb_component" && e.pcb_component_id === pcbComponentId
18910
19000
  );
18911
- if (pcb?.type !== "pcb_component") return;
19001
+ if (pcb?.type !== "pcb_component") return glbIdentity;
18912
19002
  const source = circuitJson.find(
18913
19003
  (e) => e.type === "source_component" && e.source_component_id === pcb.source_component_id
18914
19004
  );
@@ -18936,7 +19026,15 @@ var pickCadComponent = (scene, position, circuitJson) => {
18936
19026
  const cad = circuitJson.find(
18937
19027
  (e) => e.type === "cad_component" && e.cad_component_id === cadComponentId
18938
19028
  );
18939
- if (cad?.type !== "cad_component") return;
19029
+ if (cad?.type !== "cad_component") {
19030
+ const metadata = getGlbComponentMetadata(object);
19031
+ if (metadata && metadata.cad_component_id === cadComponentId)
19032
+ return {
19033
+ cad_component_id: cadComponentId,
19034
+ componentName: metadata.componentName ?? cadComponentId
19035
+ };
19036
+ return;
19037
+ }
18940
19038
  const source = circuitJson.find(
18941
19039
  (e) => e.type === "source_component" && e.source_component_id === cad.source_component_id
18942
19040
  );
@@ -19014,8 +19112,8 @@ function configureRuntimeFont() {
19014
19112
  }
19015
19113
 
19016
19114
  // src/CadViewer.tsx
19017
- import { useCallback as useCallback25, useContext as useContext11, useEffect as useEffect51, useRef as useRef29, useState as useState42 } from "react";
19018
- import * as THREE57 from "three";
19115
+ import { useCallback as useCallback25, useContext as useContext11, useEffect as useEffect53, useRef as useRef29, useState as useState44 } from "react";
19116
+ import * as THREE59 from "three";
19019
19117
 
19020
19118
  // src/hooks/use-convert-children-to-soup.ts
19021
19119
  import { Circuit } from "@tscircuit/core";
@@ -19146,7 +19244,7 @@ function usePcbThickness(circuitJson) {
19146
19244
  // src/react-three/Html.tsx
19147
19245
  import { useRef, useEffect as useEffect3, useState as useState3 } from "react";
19148
19246
  import ReactDOM from "react-dom";
19149
- import * as THREE3 from "three";
19247
+ import * as THREE5 from "three";
19150
19248
 
19151
19249
  // lib/utils/z-index-map.ts
19152
19250
  var zIndexMap = {
@@ -19178,7 +19276,7 @@ var Html = ({ children, position, style }) => {
19178
19276
  }, [renderer, children]);
19179
19277
  useFrame(() => {
19180
19278
  if (!camera || !el.current || !renderer) return;
19181
- const vector = new THREE3.Vector3(...position);
19279
+ const vector = new THREE5.Vector3(...position);
19182
19280
  vector.project(camera);
19183
19281
  const rect = renderer.domElement.getBoundingClientRect();
19184
19282
  const x = Math.round((vector.x + 1) / 2 * rect.width);
@@ -19202,7 +19300,7 @@ import {
19202
19300
  getJscadModelForFootprint
19203
19301
  } from "jscad-electronics/vanilla";
19204
19302
  import { useMemo as useMemo6, useEffect as useEffect6 } from "react";
19205
- import * as THREE6 from "three";
19303
+ import * as THREE7 from "three";
19206
19304
 
19207
19305
  // src/ContainerWithTooltip.tsx
19208
19306
  import { useEffect as useEffect5 } from "react";
@@ -19217,7 +19315,7 @@ import {
19217
19315
  useEffect as useEffect4,
19218
19316
  useRef as useRef2
19219
19317
  } from "react";
19220
- import * as THREE4 from "three";
19318
+ import * as THREE6 from "three";
19221
19319
  import { jsx as jsx3 } from "react/jsx-runtime";
19222
19320
  var HoverContext = createContext4(null);
19223
19321
  var useHover = () => {
@@ -19230,8 +19328,8 @@ var useHover = () => {
19230
19328
  var HoverProvider = ({ children }) => {
19231
19329
  const { camera, renderer } = useThree();
19232
19330
  const [hoverables, setHoverables] = useState4([]);
19233
- const raycaster = useMemo5(() => new THREE4.Raycaster(), []);
19234
- const mouse = useMemo5(() => new THREE4.Vector2(), []);
19331
+ const raycaster = useMemo5(() => new THREE6.Raycaster(), []);
19332
+ const mouse = useMemo5(() => new THREE6.Vector2(), []);
19235
19333
  const hoverablesRef = useRef2(hoverables);
19236
19334
  hoverablesRef.current = hoverables;
19237
19335
  const hoveredObjectRef = useRef2(null);
@@ -19360,16 +19458,6 @@ var ContainerWithTooltip = ({
19360
19458
  };
19361
19459
  var ContainerWithTooltip_default = ContainerWithTooltip;
19362
19460
 
19363
- // src/utils/configure-object-shadows.ts
19364
- import * as THREE5 from "three";
19365
- var configureObjectShadows = (object, { castShadow = true, receiveShadow = true } = {}) => {
19366
- object.traverse((child) => {
19367
- if (!(child instanceof THREE5.Mesh)) return;
19368
- child.castShadow = castShadow;
19369
- child.receiveShadow = receiveShadow;
19370
- });
19371
- };
19372
-
19373
19461
  // src/three-components/FootprinterModel.tsx
19374
19462
  import { jsx as jsx5 } from "react/jsx-runtime";
19375
19463
  var FootprinterModel = ({
@@ -19386,24 +19474,24 @@ var FootprinterModel = ({
19386
19474
  const group = useMemo6(() => {
19387
19475
  if (!footprint) return null;
19388
19476
  const { geometries } = getJscadModelForFootprint(footprint, jscadModeling);
19389
- const group2 = new THREE6.Group();
19477
+ const group2 = new THREE7.Group();
19390
19478
  for (const geomInfo of geometries.flat(Infinity)) {
19391
19479
  const geom = geomInfo.geom;
19392
19480
  if (!geom || !geom.polygons && !geom.sides) {
19393
19481
  continue;
19394
19482
  }
19395
- const color = new THREE6.Color(geomInfo.color);
19483
+ const color = new THREE7.Color(geomInfo.color);
19396
19484
  color.convertLinearToSRGB();
19397
19485
  const geomWithColor = { ...geom, color: [color.r, color.g, color.b] };
19398
19486
  const threeGeom = convertCSGToThreeGeom(geomWithColor);
19399
- const material = new THREE6.MeshStandardMaterial({
19487
+ const material = new THREE7.MeshStandardMaterial({
19400
19488
  vertexColors: true,
19401
- side: THREE6.DoubleSide,
19489
+ side: THREE7.DoubleSide,
19402
19490
  transparent: isTranslucent,
19403
19491
  opacity: isTranslucent ? 0.5 : 1,
19404
19492
  depthWrite: !isTranslucent
19405
19493
  });
19406
- const mesh = new THREE6.Mesh(threeGeom, material);
19494
+ const mesh = new THREE7.Mesh(threeGeom, material);
19407
19495
  mesh.renderOrder = isTranslucent ? 2 : 1;
19408
19496
  configureObjectShadows(mesh, {
19409
19497
  castShadow: !isTranslucent,
@@ -19438,7 +19526,7 @@ var FootprinterModel = ({
19438
19526
  useEffect6(() => {
19439
19527
  if (!group) return;
19440
19528
  group.traverse((child) => {
19441
- if (child instanceof THREE6.Mesh && child.material instanceof THREE6.MeshStandardMaterial) {
19529
+ if (child instanceof THREE7.Mesh && child.material instanceof THREE7.MeshStandardMaterial) {
19442
19530
  if (isHovered) {
19443
19531
  child.material.emissive.setHex(255);
19444
19532
  child.material.emissiveIntensity = 0.2;
@@ -19462,17 +19550,17 @@ var FootprinterModel = ({
19462
19550
 
19463
19551
  // src/three-components/GltfModel.tsx
19464
19552
  import { useState as useState5, useEffect as useEffect8 } from "react";
19465
- import * as THREE10 from "three";
19466
- import { GLTFLoader } from "three-stdlib";
19553
+ import * as THREE11 from "three";
19554
+ import { GLTFLoader as GLTFLoader2 } from "three-stdlib";
19467
19555
 
19468
19556
  // src/react-three/getDefaultEnvironmentMap.ts
19469
- import * as THREE7 from "three";
19557
+ import * as THREE8 from "three";
19470
19558
  import { RoomEnvironment } from "three-stdlib";
19471
19559
  var environmentCache = /* @__PURE__ */ new WeakMap();
19472
19560
  var createFallbackEnvironmentMap = () => {
19473
- const texture = new THREE7.Texture();
19561
+ const texture = new THREE8.Texture();
19474
19562
  texture.name = "fallback-environment-map";
19475
- texture.mapping = THREE7.EquirectangularReflectionMapping;
19563
+ texture.mapping = THREE8.EquirectangularReflectionMapping;
19476
19564
  return texture;
19477
19565
  };
19478
19566
  var getDefaultEnvironmentMap = (renderer) => {
@@ -19481,8 +19569,8 @@ var getDefaultEnvironmentMap = (renderer) => {
19481
19569
  const cached = environmentCache.get(cacheKey);
19482
19570
  if (cached) return cached;
19483
19571
  let texture;
19484
- if (renderer instanceof THREE7.WebGLRenderer) {
19485
- const pmremGenerator = new THREE7.PMREMGenerator(renderer);
19572
+ if (renderer instanceof THREE8.WebGLRenderer) {
19573
+ const pmremGenerator = new THREE8.PMREMGenerator(renderer);
19486
19574
  texture = pmremGenerator.fromScene(RoomEnvironment(), 0.04).texture;
19487
19575
  pmremGenerator.dispose();
19488
19576
  } else {
@@ -19494,18 +19582,18 @@ var getDefaultEnvironmentMap = (renderer) => {
19494
19582
 
19495
19583
  // src/three-components/useCadModelTransformGraph.ts
19496
19584
  import { useEffect as useEffect7, useMemo as useMemo7 } from "react";
19497
- import * as THREE9 from "three";
19585
+ import * as THREE10 from "three";
19498
19586
 
19499
19587
  // src/utils/cad-model-fit.ts
19500
- import * as THREE8 from "three";
19588
+ import * as THREE9 from "three";
19501
19589
  function getObjectBoundsRelativeToParent(object) {
19502
- const bounds = new THREE8.Box3();
19590
+ const bounds = new THREE9.Box3();
19503
19591
  let hasBounds = false;
19504
19592
  object.updateWorldMatrix(true, false);
19505
- const parentInverseMatrix = object.parent ? object.parent.matrixWorld.clone().invert() : new THREE8.Matrix4();
19593
+ const parentInverseMatrix = object.parent ? object.parent.matrixWorld.clone().invert() : new THREE9.Matrix4();
19506
19594
  object.traverse((node) => {
19507
19595
  node.updateWorldMatrix(true, false);
19508
- if (node instanceof THREE8.Mesh && node.geometry) {
19596
+ if (node instanceof THREE9.Mesh && node.geometry) {
19509
19597
  if (!node.geometry.boundingBox) {
19510
19598
  node.geometry.computeBoundingBox();
19511
19599
  }
@@ -19527,9 +19615,9 @@ function getObjectBoundsRelativeToParent(object) {
19527
19615
  function getLocalBoundsSize(object) {
19528
19616
  const bounds = getObjectBoundsRelativeToParent(object);
19529
19617
  if (!bounds) {
19530
- return new THREE8.Vector3();
19618
+ return new THREE9.Vector3();
19531
19619
  }
19532
- return bounds.getSize(new THREE8.Vector3());
19620
+ return bounds.getSize(new THREE9.Vector3());
19533
19621
  }
19534
19622
  function getCadModelFitScale(object, targetSize, fitMode = "contain_within_bounds") {
19535
19623
  if (!targetSize) {
@@ -19561,10 +19649,10 @@ var useCadModelTransformGraph = ({
19561
19649
  scale: scale11
19562
19650
  }) => {
19563
19651
  const { rootObject } = useThree();
19564
- const boardTransformGroup = useMemo7(() => new THREE9.Group(), []);
19565
- const fitTransformGroup = useMemo7(() => new THREE9.Group(), []);
19566
- const modelTransformGroup = useMemo7(() => new THREE9.Group(), []);
19567
- const loaderTransformGroup = useMemo7(() => new THREE9.Group(), []);
19652
+ const boardTransformGroup = useMemo7(() => new THREE10.Group(), []);
19653
+ const fitTransformGroup = useMemo7(() => new THREE10.Group(), []);
19654
+ const modelTransformGroup = useMemo7(() => new THREE10.Group(), []);
19655
+ const loaderTransformGroup = useMemo7(() => new THREE10.Group(), []);
19568
19656
  useEffect7(() => {
19569
19657
  boardTransformGroup.add(fitTransformGroup);
19570
19658
  return () => {
@@ -19690,7 +19778,7 @@ function GltfModel({
19690
19778
  });
19691
19779
  useEffect8(() => {
19692
19780
  if (!gltfUrl) return;
19693
- const loader = new GLTFLoader();
19781
+ const loader = new GLTFLoader2();
19694
19782
  let isMounted = true;
19695
19783
  loader.load(
19696
19784
  gltfUrl,
@@ -19698,7 +19786,7 @@ function GltfModel({
19698
19786
  if (!isMounted) return;
19699
19787
  const scene = gltf.scene;
19700
19788
  scene.traverse((child) => {
19701
- if (child instanceof THREE10.Mesh && child.material) {
19789
+ if (child instanceof THREE11.Mesh && child.material) {
19702
19790
  const setMaterialTransparency = (mat) => {
19703
19791
  mat.transparent = isTranslucent;
19704
19792
  mat.opacity = isTranslucent ? 0.5 : 1;
@@ -19737,7 +19825,7 @@ function GltfModel({
19737
19825
  if (!environmentMap) return;
19738
19826
  const previousMaterialState = [];
19739
19827
  const applyEnvironmentToMaterial = (material) => {
19740
- if (!(material instanceof THREE10.MeshStandardMaterial)) return;
19828
+ if (!(material instanceof THREE11.MeshStandardMaterial)) return;
19741
19829
  previousMaterialState.push({
19742
19830
  material,
19743
19831
  envMap: material.envMap ?? null,
@@ -19750,7 +19838,7 @@ function GltfModel({
19750
19838
  material.needsUpdate = true;
19751
19839
  };
19752
19840
  model.traverse((child) => {
19753
- if (!(child instanceof THREE10.Mesh)) return;
19841
+ if (!(child instanceof THREE11.Mesh)) return;
19754
19842
  const material = child.material;
19755
19843
  if (Array.isArray(material)) {
19756
19844
  material.forEach(applyEnvironmentToMaterial);
@@ -19769,10 +19857,10 @@ function GltfModel({
19769
19857
  useEffect8(() => {
19770
19858
  if (!model) return;
19771
19859
  model.traverse((child) => {
19772
- if (!(child instanceof THREE10.Mesh)) return;
19860
+ if (!(child instanceof THREE11.Mesh)) return;
19773
19861
  const materials = Array.isArray(child.material) ? child.material : [child.material];
19774
19862
  for (const material of materials) {
19775
- if (!(material instanceof THREE10.MeshStandardMaterial)) continue;
19863
+ if (!(material instanceof THREE11.MeshStandardMaterial)) continue;
19776
19864
  if (isHovered) {
19777
19865
  material.emissive.setHex(255);
19778
19866
  material.emissiveIntensity = 0.2;
@@ -19801,7 +19889,7 @@ function GltfModel({
19801
19889
  var import_jscad_planner = __toESM(require_dist(), 1);
19802
19890
  var import_modeling = __toESM(require_src(), 1);
19803
19891
  import { convertCSGToThreeGeom as convertCSGToThreeGeom2 } from "jscad-electronics/vanilla";
19804
- import * as THREE11 from "three";
19892
+ import * as THREE12 from "three";
19805
19893
  import { useState as useState6, useEffect as useEffect9 } from "react";
19806
19894
  import { jsx as jsx7 } from "react/jsx-runtime";
19807
19895
  var JscadModel = ({
@@ -19827,11 +19915,11 @@ var JscadModel = ({
19827
19915
  return;
19828
19916
  }
19829
19917
  const geometry = convertCSGToThreeGeom2(jscadObject);
19830
- const material2 = new THREE11.MeshStandardMaterial({
19918
+ const material2 = new THREE12.MeshStandardMaterial({
19831
19919
  vertexColors: true,
19832
- side: THREE11.DoubleSide
19920
+ side: THREE12.DoubleSide
19833
19921
  });
19834
- const model = new THREE11.Mesh(geometry, material2);
19922
+ const model = new THREE12.Mesh(geometry, material2);
19835
19923
  setMesh(model);
19836
19924
  return () => {
19837
19925
  geometry.dispose();
@@ -19866,7 +19954,7 @@ var JscadModel = ({
19866
19954
  useEffect9(() => {
19867
19955
  if (!material) return;
19868
19956
  if (isHovered) {
19869
- const color = new THREE11.Color(material.color.getHex());
19957
+ const color = new THREE12.Color(material.color.getHex());
19870
19958
  material.emissive.copy(color);
19871
19959
  material.emissive.setRGB(0, 0, 1);
19872
19960
  material.emissiveIntensity = 0.2;
@@ -19986,7 +20074,7 @@ function useGlobalObjLoader(url) {
19986
20074
 
19987
20075
  // src/three-components/MixedStlModel.tsx
19988
20076
  import { useMemo as useMemo8 } from "react";
19989
- import * as THREE12 from "three";
20077
+ import * as THREE13 from "three";
19990
20078
  import { jsx as jsx8 } from "react/jsx-runtime";
19991
20079
  function MixedStlModel({
19992
20080
  url,
@@ -20007,7 +20095,7 @@ function MixedStlModel({
20007
20095
  const model = useMemo8(() => {
20008
20096
  if (obj && !(obj instanceof Error)) {
20009
20097
  obj.traverse((child) => {
20010
- if (child instanceof THREE12.Mesh && child.material) {
20098
+ if (child instanceof THREE13.Mesh && child.material) {
20011
20099
  const setMaterialTransparency = (mat) => {
20012
20100
  mat.transparent = isTranslucent;
20013
20101
  mat.opacity = isTranslucent ? 0.5 : 1;
@@ -20028,9 +20116,9 @@ function MixedStlModel({
20028
20116
  });
20029
20117
  return obj;
20030
20118
  }
20031
- const fallbackMesh = new THREE12.Mesh(
20032
- new THREE12.BoxGeometry(0.5, 0.5, 0.5),
20033
- new THREE12.MeshStandardMaterial({
20119
+ const fallbackMesh = new THREE13.Mesh(
20120
+ new THREE13.BoxGeometry(0.5, 0.5, 0.5),
20121
+ new THREE13.MeshStandardMaterial({
20034
20122
  transparent: true,
20035
20123
  color: "red",
20036
20124
  opacity: 0.25
@@ -20076,8 +20164,8 @@ import {
20076
20164
  BufferGeometry,
20077
20165
  Color as Color3,
20078
20166
  Float32BufferAttribute,
20079
- Group as Group4,
20080
- Mesh as Mesh8,
20167
+ Group as Group5,
20168
+ Mesh as Mesh9,
20081
20169
  MeshStandardMaterial as MeshStandardMaterial5
20082
20170
  } from "three";
20083
20171
  var DEFAULT_COLOR = new Color3(0.82, 0.82, 0.82);
@@ -20133,7 +20221,7 @@ function applyFaceColorGroups(geometry, mesh) {
20133
20221
  return materials;
20134
20222
  }
20135
20223
  function occtMeshesToGroup(meshes) {
20136
- const group = new Group4();
20224
+ const group = new Group5();
20137
20225
  for (const mesh of meshes) {
20138
20226
  const positions = mesh.attributes.position?.array ?? [];
20139
20227
  const indices = mesh.index?.array ?? [];
@@ -20151,7 +20239,7 @@ function occtMeshesToGroup(meshes) {
20151
20239
  geometry.setIndex(indices);
20152
20240
  geometry.clearGroups();
20153
20241
  const materials = applyFaceColorGroups(geometry, mesh);
20154
- const threeMesh = new Mesh8(
20242
+ const threeMesh = new Mesh9(
20155
20243
  geometry,
20156
20244
  materials.length > 1 ? materials : materials[0]
20157
20245
  );
@@ -20388,7 +20476,7 @@ var StepModel = ({
20388
20476
  };
20389
20477
 
20390
20478
  // src/utils/cad-model-loader-transform.ts
20391
- import * as THREE13 from "three";
20479
+ import * as THREE14 from "three";
20392
20480
  function applyCoordinateTransform(point, config) {
20393
20481
  let { x, y, z } = point;
20394
20482
  if (config.axisMapping) {
@@ -20547,15 +20635,15 @@ function getCadLoaderTransformMatrix(config) {
20547
20635
  const basisX = applyCoordinateTransform({ x: 1, y: 0, z: 0 }, config);
20548
20636
  const basisY = applyCoordinateTransform({ x: 0, y: 1, z: 0 }, config);
20549
20637
  const basisZ = applyCoordinateTransform({ x: 0, y: 0, z: 1 }, config);
20550
- return new THREE13.Matrix4().makeBasis(
20551
- new THREE13.Vector3(basisX.x, basisX.y, basisX.z),
20552
- new THREE13.Vector3(basisY.x, basisY.y, basisY.z),
20553
- new THREE13.Vector3(basisZ.x, basisZ.y, basisZ.z)
20638
+ return new THREE14.Matrix4().makeBasis(
20639
+ new THREE14.Vector3(basisX.x, basisX.y, basisX.z),
20640
+ new THREE14.Vector3(basisY.x, basisY.y, basisY.z),
20641
+ new THREE14.Vector3(basisZ.x, basisZ.y, basisZ.z)
20554
20642
  );
20555
20643
  }
20556
20644
 
20557
20645
  // src/utils/cad-model-transform.ts
20558
- import * as THREE14 from "three";
20646
+ import * as THREE15 from "three";
20559
20647
  function toRadians(value) {
20560
20648
  return value * Math.PI / 180;
20561
20649
  }
@@ -20599,8 +20687,8 @@ function getBaseCadRotation(cadComponent, layer) {
20599
20687
  ];
20600
20688
  }
20601
20689
  function rotateOriginPosition(origin, boardNormalRotation) {
20602
- const vector = new THREE14.Vector3(origin.x, origin.y, origin.z);
20603
- const euler = new THREE14.Euler(
20690
+ const vector = new THREE15.Vector3(origin.x, origin.y, origin.z);
20691
+ const euler = new THREE15.Euler(
20604
20692
  boardNormalRotation[0],
20605
20693
  boardNormalRotation[1],
20606
20694
  boardNormalRotation[2],
@@ -20986,12 +21074,12 @@ var AnyCadComponent = ({
20986
21074
 
20987
21075
  // src/CadViewerContainer.tsx
20988
21076
  import { forwardRef as forwardRef2, useEffect as useEffect22, useMemo as useMemo17, useState as useState13 } from "react";
20989
- import * as THREE27 from "three";
21077
+ import * as THREE28 from "three";
20990
21078
 
20991
21079
  // package.json
20992
21080
  var package_default = {
20993
21081
  name: "@tscircuit/3d-viewer",
20994
- version: "0.0.627",
21082
+ version: "0.0.628",
20995
21083
  repository: {
20996
21084
  type: "git",
20997
21085
  url: "https://github.com/tscircuit/3d-viewer"
@@ -21145,10 +21233,10 @@ import {
21145
21233
  useRef as useRef3,
21146
21234
  useState as useState11
21147
21235
  } from "react";
21148
- import * as THREE16 from "three";
21236
+ import * as THREE17 from "three";
21149
21237
 
21150
21238
  // src/utils/camera-session-storage.ts
21151
- import * as THREE15 from "three";
21239
+ import * as THREE16 from "three";
21152
21240
  var CAMERA_SESSION_STORAGE_KEY = "cadViewerCameraStateSession";
21153
21241
  function getCameraSessionStorageKey(cameraSessionScope) {
21154
21242
  if (!cameraSessionScope) return CAMERA_SESSION_STORAGE_KEY;
@@ -21164,7 +21252,7 @@ function saveCameraSession({
21164
21252
  position: camera.position.toArray(),
21165
21253
  quaternion: camera.quaternion.toArray(),
21166
21254
  up: camera.up.toArray(),
21167
- fov: camera instanceof THREE15.PerspectiveCamera ? camera.fov : 50,
21255
+ fov: camera instanceof THREE16.PerspectiveCamera ? camera.fov : 50,
21168
21256
  target: controls.target.toArray()
21169
21257
  };
21170
21258
  sessionStorage.setItem(
@@ -21191,7 +21279,7 @@ function loadCameraSession({
21191
21279
  camera.position.fromArray(storedCameraSession.position);
21192
21280
  camera.quaternion.fromArray(storedCameraSession.quaternion);
21193
21281
  camera.up.fromArray(storedCameraSession.up);
21194
- if (camera instanceof THREE15.PerspectiveCamera) {
21282
+ if (camera instanceof THREE16.PerspectiveCamera) {
21195
21283
  camera.fov = storedCameraSession.fov;
21196
21284
  camera.updateProjectionMatrix();
21197
21285
  }
@@ -21229,7 +21317,7 @@ var CameraControllerProvider = ({ children, defaultTarget, initialCameraPosition
21229
21317
  );
21230
21318
  const [cameraPosition, setCameraPosition] = useState11(initialCameraPosition ?? null);
21231
21319
  const [cameraRotation, setCameraRotation] = useState11(
21232
- new THREE16.Euler(0, 0, 0)
21320
+ new THREE17.Euler(0, 0, 0)
21233
21321
  );
21234
21322
  const baseDistance = useMemo11(() => {
21235
21323
  const [x, y, z] = initialCameraPosition ?? [5, -5, 5];
@@ -21383,7 +21471,7 @@ var useCameraController = () => {
21383
21471
 
21384
21472
  // src/hooks/cameraAnimation.ts
21385
21473
  import { useCallback as useCallback5, useEffect as useEffect14, useRef as useRef4 } from "react";
21386
- import * as THREE17 from "three";
21474
+ import * as THREE18 from "three";
21387
21475
  var easeInOutCubic = (t) => t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2;
21388
21476
  var CameraAnimatorWithContext = () => {
21389
21477
  const {
@@ -21394,24 +21482,24 @@ var CameraAnimatorWithContext = () => {
21394
21482
  getPresetConfig
21395
21483
  } = useCameraController();
21396
21484
  const animationRef = useRef4(null);
21397
- const tempQuaternion = useRef4(new THREE17.Quaternion());
21398
- const tempTarget = useRef4(new THREE17.Vector3());
21399
- const tempUp = useRef4(new THREE17.Vector3());
21400
- const tempRoll = useRef4(new THREE17.Quaternion());
21401
- const tempRollTarget = useRef4(new THREE17.Quaternion());
21402
- const baseOrientationHelper = useRef4(new THREE17.Object3D());
21403
- const orientationHelper = useRef4(new THREE17.Object3D());
21485
+ const tempQuaternion = useRef4(new THREE18.Quaternion());
21486
+ const tempTarget = useRef4(new THREE18.Vector3());
21487
+ const tempUp = useRef4(new THREE18.Vector3());
21488
+ const tempRoll = useRef4(new THREE18.Quaternion());
21489
+ const tempRollTarget = useRef4(new THREE18.Quaternion());
21490
+ const baseOrientationHelper = useRef4(new THREE18.Object3D());
21491
+ const orientationHelper = useRef4(new THREE18.Object3D());
21404
21492
  const animateTo = useCallback5(
21405
21493
  ({ position, target, up, durationMs = 600 }) => {
21406
21494
  if (!mainCameraRef.current) return;
21407
21495
  const currentTarget = controlsRef.current?.target ?? defaultTarget;
21408
- const toPosition = new THREE17.Vector3(
21496
+ const toPosition = new THREE18.Vector3(
21409
21497
  position[0],
21410
21498
  position[1],
21411
21499
  position[2]
21412
21500
  );
21413
- const resolvedTarget = target ? new THREE17.Vector3(target[0], target[1], target[2]) : defaultTarget.clone();
21414
- const resolvedUp = new THREE17.Vector3(...up ?? [0, 0, 1]).normalize();
21501
+ const resolvedTarget = target ? new THREE18.Vector3(target[0], target[1], target[2]) : defaultTarget.clone();
21502
+ const resolvedUp = new THREE18.Vector3(...up ?? [0, 0, 1]).normalize();
21415
21503
  const toOrientationHelper = orientationHelper.current;
21416
21504
  toOrientationHelper.position.copy(toPosition);
21417
21505
  toOrientationHelper.up.copy(resolvedUp);
@@ -21596,7 +21684,7 @@ import {
21596
21684
  useImperativeHandle,
21597
21685
  useMemo as useMemo12
21598
21686
  } from "react";
21599
- import * as THREE19 from "three";
21687
+ import * as THREE20 from "three";
21600
21688
 
21601
21689
  // src/react-three/remove-existing-canvases.ts
21602
21690
  function removeExistingCanvases(container) {
@@ -21604,13 +21692,13 @@ function removeExistingCanvases(container) {
21604
21692
  }
21605
21693
 
21606
21694
  // src/react-three/configure-renderer.ts
21607
- import * as THREE18 from "three";
21695
+ import * as THREE19 from "three";
21608
21696
  var configureRenderer = (renderer) => {
21609
- renderer.outputColorSpace = THREE18.SRGBColorSpace;
21610
- renderer.toneMapping = THREE18.ACESFilmicToneMapping;
21697
+ renderer.outputColorSpace = THREE19.SRGBColorSpace;
21698
+ renderer.toneMapping = THREE19.ACESFilmicToneMapping;
21611
21699
  renderer.toneMappingExposure = 1;
21612
21700
  renderer.shadowMap.enabled = true;
21613
- renderer.shadowMap.type = THREE18.PCFSoftShadowMap;
21701
+ renderer.shadowMap.type = THREE19.PCFSoftShadowMap;
21614
21702
  };
21615
21703
 
21616
21704
  // src/react-three/Canvas.tsx
@@ -21642,16 +21730,16 @@ var Canvas = forwardRef(
21642
21730
  },
21643
21731
  []
21644
21732
  );
21645
- const scene = useMemo12(() => new THREE19.Scene(), []);
21733
+ const scene = useMemo12(() => new THREE20.Scene(), []);
21646
21734
  if (sceneProps?.up) {
21647
21735
  scene.up.set(sceneProps.up.x, sceneProps.up.y, sceneProps.up.z);
21648
21736
  }
21649
- const rootObject = useRef6(new THREE19.Object3D());
21737
+ const rootObject = useRef6(new THREE20.Object3D());
21650
21738
  useImperativeHandle(ref, () => rootObject.current);
21651
21739
  useEffect16(() => {
21652
21740
  if (!mountRef.current) return;
21653
21741
  removeExistingCanvases(mountRef.current);
21654
- const renderer = new THREE19.WebGLRenderer({ antialias: true, alpha: true });
21742
+ const renderer = new THREE20.WebGLRenderer({ antialias: true, alpha: true });
21655
21743
  configureRenderer(renderer);
21656
21744
  renderer.setSize(
21657
21745
  mountRef.current.clientWidth,
@@ -21660,7 +21748,7 @@ var Canvas = forwardRef(
21660
21748
  renderer.setPixelRatio(window.devicePixelRatio);
21661
21749
  mountRef.current.appendChild(renderer.domElement);
21662
21750
  const aspect = mountRef.current.clientWidth / mountRef.current.clientHeight;
21663
- const camera = cameraType === "perspective" ? new THREE19.PerspectiveCamera(75, aspect, 0.1, 1e3) : new THREE19.OrthographicCamera(
21751
+ const camera = cameraType === "perspective" ? new THREE20.PerspectiveCamera(75, aspect, 0.1, 1e3) : new THREE20.OrthographicCamera(
21664
21752
  -10 * aspect,
21665
21753
  10 * aspect,
21666
21754
  10,
@@ -21697,7 +21785,7 @@ var Canvas = forwardRef(
21697
21785
  });
21698
21786
  onCreatedRef.current?.({ camera, renderer });
21699
21787
  let animationFrameId;
21700
- const clock = new THREE19.Clock();
21788
+ const clock = new THREE20.Clock();
21701
21789
  let isVisible = true;
21702
21790
  const visibilityObserver = new IntersectionObserver(([entry]) => {
21703
21791
  isVisible = entry?.isIntersecting ?? false;
@@ -21716,9 +21804,9 @@ var Canvas = forwardRef(
21716
21804
  const handleResize = () => {
21717
21805
  if (mountRef.current?.clientWidth && mountRef.current.clientHeight) {
21718
21806
  const newAspect = mountRef.current.clientWidth / mountRef.current.clientHeight;
21719
- if (camera instanceof THREE19.PerspectiveCamera) {
21807
+ if (camera instanceof THREE20.PerspectiveCamera) {
21720
21808
  camera.aspect = newAspect;
21721
- } else if (camera instanceof THREE19.OrthographicCamera) {
21809
+ } else if (camera instanceof THREE20.OrthographicCamera) {
21722
21810
  camera.left = -10 * newAspect;
21723
21811
  camera.right = 10 * newAspect;
21724
21812
  camera.top = 10;
@@ -21757,7 +21845,7 @@ var Canvas = forwardRef(
21757
21845
 
21758
21846
  // src/react-three/Grid.tsx
21759
21847
  import { useEffect as useEffect17, useMemo as useMemo13 } from "react";
21760
- import * as THREE20 from "three";
21848
+ import * as THREE21 from "three";
21761
21849
  var vertexShader = `
21762
21850
  varying vec3 worldPosition;
21763
21851
  void main() {
@@ -21803,24 +21891,24 @@ var Grid = ({
21803
21891
  const { scene, camera } = useThree();
21804
21892
  const size4 = 1e3;
21805
21893
  const gridMesh = useMemo13(() => {
21806
- const geometry = new THREE20.PlaneGeometry(size4, size4);
21894
+ const geometry = new THREE21.PlaneGeometry(size4, size4);
21807
21895
  geometry.rotateX(-Math.PI / 2);
21808
- const material = new THREE20.ShaderMaterial({
21896
+ const material = new THREE21.ShaderMaterial({
21809
21897
  vertexShader,
21810
21898
  fragmentShader,
21811
21899
  uniforms: {
21812
21900
  cellSize: { value: cellSize },
21813
21901
  sectionSize: { value: sectionSize },
21814
- gridColor: { value: new THREE20.Color(15658734) },
21815
- sectionColor: { value: new THREE20.Color(13421823) },
21902
+ gridColor: { value: new THREE21.Color(15658734) },
21903
+ sectionColor: { value: new THREE21.Color(13421823) },
21816
21904
  fadeDistance: { value: 100 },
21817
21905
  // Fade out based on sectionSize
21818
21906
  fadeStrength: { value: 1.5 }
21819
21907
  },
21820
21908
  transparent: true,
21821
- side: THREE20.DoubleSide
21909
+ side: THREE21.DoubleSide
21822
21910
  });
21823
- const mesh = new THREE20.Mesh(geometry, material);
21911
+ const mesh = new THREE21.Mesh(geometry, material);
21824
21912
  if (rotation) {
21825
21913
  mesh.rotation.fromArray(rotation);
21826
21914
  }
@@ -21849,7 +21937,7 @@ var Grid = ({
21849
21937
 
21850
21938
  // src/react-three/Lights.tsx
21851
21939
  import { useEffect as useEffect18, useMemo as useMemo14 } from "react";
21852
- import * as THREE21 from "three";
21940
+ import * as THREE22 from "three";
21853
21941
  var UNDERSIDE_LIGHT_FACTOR = 0.75;
21854
21942
  var Lights = ({
21855
21943
  boardDimensions,
@@ -21859,7 +21947,7 @@ var Lights = ({
21859
21947
  }) => {
21860
21948
  const { scene } = useThree();
21861
21949
  const lightRig = useMemo14(() => {
21862
- const rig = new THREE21.Group();
21950
+ const rig = new THREE22.Group();
21863
21951
  rig.name = "cad-viewer-light-rig";
21864
21952
  const centerX = boardCenter?.x ?? 0;
21865
21953
  const centerY = boardCenter?.y ?? 0;
@@ -21871,14 +21959,14 @@ var Lights = ({
21871
21959
  const shadowHalfSize = largestBoardDimension * 0.8;
21872
21960
  const lightDistance = largestBoardDimension;
21873
21961
  const keyLightDistance = largestBoardDimension * 1.7;
21874
- const ambientLight = new THREE21.AmbientLight(16186360, 0.22);
21962
+ const ambientLight = new THREE22.AmbientLight(16186360, 0.22);
21875
21963
  ambientLight.name = "cad-viewer-soft-ambient";
21876
21964
  rig.add(ambientLight);
21877
- const hemisphereLight = new THREE21.HemisphereLight(15004141, 1581597, 0.2);
21965
+ const hemisphereLight = new THREE22.HemisphereLight(15004141, 1581597, 0.2);
21878
21966
  hemisphereLight.name = "cad-viewer-hemisphere";
21879
21967
  rig.add(hemisphereLight);
21880
21968
  const addDirectionalLight = (name, color, intensity, position, castShadow = false) => {
21881
- const light = new THREE21.DirectionalLight(color, intensity);
21969
+ const light = new THREE22.DirectionalLight(color, intensity);
21882
21970
  light.name = name;
21883
21971
  light.position.set(
21884
21972
  centerX + position[0],
@@ -21955,7 +22043,7 @@ var Lights = ({
21955
22043
  useEffect18(() => {
21956
22044
  const previousBackground = scene.background;
21957
22045
  const previousEnvironment = scene.environment;
21958
- scene.background = darkBackgroundEnabled ? new THREE21.Color(1053456) : null;
22046
+ scene.background = darkBackgroundEnabled ? new THREE22.Color(1053456) : null;
21959
22047
  scene.environment = null;
21960
22048
  return () => {
21961
22049
  scene.background = previousBackground;
@@ -21974,11 +22062,11 @@ var Lights = ({
21974
22062
 
21975
22063
  // src/react-three/OrbitControls.tsx
21976
22064
  import { useEffect as useEffect19, useMemo as useMemo15 } from "react";
21977
- import * as THREE23 from "three";
22065
+ import * as THREE24 from "three";
21978
22066
  import { OrbitControls as ThreeOrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
21979
22067
 
21980
22068
  // src/react-three/infinite-dolly.ts
21981
- import * as THREE22 from "three";
22069
+ import * as THREE23 from "three";
21982
22070
  var MINIMUM_DOLLY_DISTANCE_RATIO = 0.05;
21983
22071
  var getMinimumDollyDistance = ({
21984
22072
  camera,
@@ -21992,12 +22080,12 @@ var applyInfiniteDolly = ({
21992
22080
  controls,
21993
22081
  minimumDollyDistance
21994
22082
  }) => {
21995
- if (!(camera instanceof THREE22.PerspectiveCamera)) return false;
22083
+ if (!(camera instanceof THREE23.PerspectiveCamera)) return false;
21996
22084
  const orbitDistance = controls.getDistance();
21997
22085
  if (Number.isFinite(orbitDistance) && orbitDistance >= minimumDollyDistance) {
21998
22086
  return false;
21999
22087
  }
22000
- const viewDirection = new THREE22.Vector3();
22088
+ const viewDirection = new THREE23.Vector3();
22001
22089
  camera.getWorldDirection(viewDirection);
22002
22090
  controls.target.copy(camera.position).addScaledVector(viewDirection, minimumDollyDistance);
22003
22091
  return true;
@@ -22022,7 +22110,7 @@ var OrbitControls = ({
22022
22110
  return new ThreeOrbitControls(camera, renderer.domElement);
22023
22111
  }, [camera, renderer]);
22024
22112
  const minimumDollyDistance = useMemo15(() => {
22025
- if (!controls || !(camera instanceof THREE23.PerspectiveCamera)) {
22113
+ if (!controls || !(camera instanceof THREE24.PerspectiveCamera)) {
22026
22114
  return Number.EPSILON;
22027
22115
  }
22028
22116
  const initialOrbitDistance = target ? Math.hypot(
@@ -22057,9 +22145,9 @@ var OrbitControls = ({
22057
22145
  if (dampingFactor !== void 0) controls.dampingFactor = dampingFactor;
22058
22146
  controls.zoomToCursor = true;
22059
22147
  controls.mouseButtons = {
22060
- LEFT: THREE23.MOUSE.ROTATE,
22148
+ LEFT: THREE24.MOUSE.ROTATE,
22061
22149
  // Left click to rotate
22062
- MIDDLE: THREE23.MOUSE.PAN,
22150
+ MIDDLE: THREE24.MOUSE.PAN,
22063
22151
  // Middle click to pan
22064
22152
  RIGHT: null
22065
22153
  // Right-click always disabled - only context menu
@@ -22183,14 +22271,14 @@ var getComparisonBounds = (type, boardDimensions, boardCenter) => {
22183
22271
 
22184
22272
  // src/three-components/OrientationCubeCanvas.tsx
22185
22273
  import { useEffect as useEffect20, useRef as useRef7 } from "react";
22186
- import * as THREE24 from "three";
22274
+ import * as THREE25 from "three";
22187
22275
  import { Text as TroikaText } from "troika-three-text";
22188
22276
  import { jsx as jsx14 } from "react/jsx-runtime";
22189
22277
  function computePointInFront(rotationVector, distance5) {
22190
- const quaternion = new THREE24.Quaternion().setFromEuler(
22191
- new THREE24.Euler(rotationVector.x, rotationVector.y, rotationVector.z)
22278
+ const quaternion = new THREE25.Quaternion().setFromEuler(
22279
+ new THREE25.Euler(rotationVector.x, rotationVector.y, rotationVector.z)
22192
22280
  );
22193
- const forwardVector = new THREE24.Vector3(0, 0, 1);
22281
+ const forwardVector = new THREE25.Vector3(0, 0, 1);
22194
22282
  forwardVector.applyQuaternion(quaternion);
22195
22283
  const result = forwardVector.multiplyScalar(distance5);
22196
22284
  return result;
@@ -22203,31 +22291,31 @@ var OrientationCubeCanvas = () => {
22203
22291
  const container = containerRef.current;
22204
22292
  const canvas = document.createElement("canvas");
22205
22293
  container.appendChild(canvas);
22206
- const renderer = new THREE24.WebGLRenderer({
22294
+ const renderer = new THREE25.WebGLRenderer({
22207
22295
  canvas,
22208
22296
  antialias: true,
22209
22297
  alpha: true
22210
22298
  });
22211
22299
  renderer.setSize(120, 120);
22212
22300
  renderer.setPixelRatio(window.devicePixelRatio);
22213
- const scene = new THREE24.Scene();
22214
- const camera = new THREE24.PerspectiveCamera(75, 1, 0.1, 1e3);
22301
+ const scene = new THREE25.Scene();
22302
+ const camera = new THREE25.PerspectiveCamera(75, 1, 0.1, 1e3);
22215
22303
  camera.up.set(0, 0, 1);
22216
- const ambientLight = new THREE24.AmbientLight(16777215, Math.PI / 2);
22304
+ const ambientLight = new THREE25.AmbientLight(16777215, Math.PI / 2);
22217
22305
  scene.add(ambientLight);
22218
- const group = new THREE24.Group();
22306
+ const group = new THREE25.Group();
22219
22307
  group.rotation.fromArray([Math.PI / 2, 0, 0]);
22220
22308
  const cubeSize = 1;
22221
- const box = new THREE24.Mesh(
22222
- new THREE24.BoxGeometry(cubeSize, cubeSize, cubeSize),
22223
- new THREE24.MeshStandardMaterial({ color: "white" })
22309
+ const box = new THREE25.Mesh(
22310
+ new THREE25.BoxGeometry(cubeSize, cubeSize, cubeSize),
22311
+ new THREE25.MeshStandardMaterial({ color: "white" })
22224
22312
  );
22225
22313
  group.add(box);
22226
- const edges = new THREE24.LineSegments(
22227
- new THREE24.EdgesGeometry(
22228
- new THREE24.BoxGeometry(cubeSize, cubeSize, cubeSize)
22314
+ const edges = new THREE25.LineSegments(
22315
+ new THREE25.EdgesGeometry(
22316
+ new THREE25.BoxGeometry(cubeSize, cubeSize, cubeSize)
22229
22317
  ),
22230
- new THREE24.LineBasicMaterial({ color: 0, linewidth: 2 })
22318
+ new THREE25.LineBasicMaterial({ color: 0, linewidth: 2 })
22231
22319
  );
22232
22320
  group.add(edges);
22233
22321
  scene.add(group);
@@ -22289,7 +22377,7 @@ var OrientationCubeCanvas = () => {
22289
22377
  if (!isVisible) return;
22290
22378
  if (mainCameraRef.current) {
22291
22379
  const cameraPosition = computePointInFront(
22292
- mainCameraRef.current.rotation ?? new THREE24.Euler(0, 0, 0),
22380
+ mainCameraRef.current.rotation ?? new THREE25.Euler(0, 0, 0),
22293
22381
  2
22294
22382
  );
22295
22383
  if (!cameraPosition.equals(camera.position)) {
@@ -22341,12 +22429,12 @@ var OrientationCubeCanvas = () => {
22341
22429
  import { useEffect as useEffect21, useMemo as useMemo16 } from "react";
22342
22430
 
22343
22431
  // src/reference-objects/create-reference-object.ts
22344
- import * as THREE25 from "three";
22432
+ import * as THREE26 from "three";
22345
22433
  var createRoundedRectangleShape = (width, height, radius) => {
22346
22434
  const halfWidth = width / 2;
22347
22435
  const halfHeight = height / 2;
22348
22436
  const safeRadius = Math.min(radius, halfWidth, halfHeight);
22349
- const shape = new THREE25.Shape();
22437
+ const shape = new THREE26.Shape();
22350
22438
  shape.moveTo(-halfWidth + safeRadius, -halfHeight);
22351
22439
  shape.lineTo(halfWidth - safeRadius, -halfHeight);
22352
22440
  shape.quadraticCurveTo(
@@ -22385,7 +22473,7 @@ var createRoundedPrismGeometry = (width, height, depth, radius) => {
22385
22473
  );
22386
22474
  };
22387
22475
  var createPrismGeometryFromShape = (shape, depth) => {
22388
- const geometry = new THREE25.ExtrudeGeometry(shape, {
22476
+ const geometry = new THREE26.ExtrudeGeometry(shape, {
22389
22477
  depth,
22390
22478
  bevelEnabled: false,
22391
22479
  curveSegments: 24
@@ -22397,16 +22485,16 @@ var createPrismGeometryFromShape = (shape, depth) => {
22397
22485
  var normalizeObjectToSpec = (object, type) => {
22398
22486
  const spec = REFERENCE_OBJECT_SPECS[type];
22399
22487
  object.updateMatrixWorld(true);
22400
- const initialBounds = new THREE25.Box3().setFromObject(object);
22401
- const initialSize = initialBounds.getSize(new THREE25.Vector3());
22488
+ const initialBounds = new THREE26.Box3().setFromObject(object);
22489
+ const initialSize = initialBounds.getSize(new THREE26.Vector3());
22402
22490
  object.scale.set(
22403
22491
  spec.width / initialSize.x,
22404
22492
  spec.height / initialSize.y,
22405
22493
  spec.depth / initialSize.z
22406
22494
  );
22407
22495
  object.updateMatrixWorld(true);
22408
- const scaledBounds = new THREE25.Box3().setFromObject(object);
22409
- const scaledCenter = scaledBounds.getCenter(new THREE25.Vector3());
22496
+ const scaledBounds = new THREE26.Box3().setFromObject(object);
22497
+ const scaledCenter = scaledBounds.getCenter(new THREE26.Vector3());
22410
22498
  object.position.set(
22411
22499
  -scaledCenter.x,
22412
22500
  -scaledCenter.y,
@@ -22415,15 +22503,15 @@ var normalizeObjectToSpec = (object, type) => {
22415
22503
  object.updateMatrixWorld(true);
22416
22504
  };
22417
22505
  var createBananaGeometry = () => {
22418
- const curve = new THREE25.CatmullRomCurve3([
22419
- new THREE25.Vector3(-82, 18, 16),
22420
- new THREE25.Vector3(-67, 7, 15),
22421
- new THREE25.Vector3(-43, -9, 14),
22422
- new THREE25.Vector3(-15, -18, 14),
22423
- new THREE25.Vector3(16, -18, 14),
22424
- new THREE25.Vector3(47, -8, 14.5),
22425
- new THREE25.Vector3(72, 8, 16),
22426
- new THREE25.Vector3(84, 19, 17)
22506
+ const curve = new THREE26.CatmullRomCurve3([
22507
+ new THREE26.Vector3(-82, 18, 16),
22508
+ new THREE26.Vector3(-67, 7, 15),
22509
+ new THREE26.Vector3(-43, -9, 14),
22510
+ new THREE26.Vector3(-15, -18, 14),
22511
+ new THREE26.Vector3(16, -18, 14),
22512
+ new THREE26.Vector3(47, -8, 14.5),
22513
+ new THREE26.Vector3(72, 8, 16),
22514
+ new THREE26.Vector3(84, 19, 17)
22427
22515
  ]);
22428
22516
  const tubularSegments = 84;
22429
22517
  const radialSegments = 30;
@@ -22433,8 +22521,8 @@ var createBananaGeometry = () => {
22433
22521
  const colors2 = [];
22434
22522
  const uvs = [];
22435
22523
  const indices = [];
22436
- const ripeYellow = new THREE25.Color(16766023);
22437
- const stemGreen = new THREE25.Color(12038965);
22524
+ const ripeYellow = new THREE26.Color(16766023);
22525
+ const stemGreen = new THREE26.Color(12038965);
22438
22526
  for (let segment = 0; segment <= tubularSegments; segment++) {
22439
22527
  const t = segment / tubularSegments;
22440
22528
  const point = curve.getPointAt(t);
@@ -22449,7 +22537,7 @@ var createBananaGeometry = () => {
22449
22537
  const sin = Math.sin(angle3);
22450
22538
  const cos = Math.cos(angle3);
22451
22539
  const ridgeScale = 1 + Math.cos(angle3 * 5 + 0.35) * 0.035;
22452
- const radialNormal = new THREE25.Vector3().addScaledVector(normal, cos).addScaledVector(binormal, sin * 0.9).normalize();
22540
+ const radialNormal = new THREE26.Vector3().addScaledVector(normal, cos).addScaledVector(binormal, sin * 0.9).normalize();
22453
22541
  const vertex = point.clone().addScaledVector(normal, cos * radius * ridgeScale).addScaledVector(binormal, sin * radius * 0.9 * ridgeScale);
22454
22542
  positions.push(vertex.x, vertex.y, vertex.z);
22455
22543
  normals.push(radialNormal.x, radialNormal.y, radialNormal.z);
@@ -22467,26 +22555,26 @@ var createBananaGeometry = () => {
22467
22555
  indices.push(a, d, b, b, d, c);
22468
22556
  }
22469
22557
  }
22470
- const geometry = new THREE25.BufferGeometry();
22558
+ const geometry = new THREE26.BufferGeometry();
22471
22559
  geometry.setIndex(indices);
22472
22560
  geometry.setAttribute(
22473
22561
  "position",
22474
- new THREE25.Float32BufferAttribute(positions, 3)
22562
+ new THREE26.Float32BufferAttribute(positions, 3)
22475
22563
  );
22476
- geometry.setAttribute("normal", new THREE25.Float32BufferAttribute(normals, 3));
22477
- geometry.setAttribute("color", new THREE25.Float32BufferAttribute(colors2, 3));
22478
- geometry.setAttribute("uv", new THREE25.Float32BufferAttribute(uvs, 2));
22564
+ geometry.setAttribute("normal", new THREE26.Float32BufferAttribute(normals, 3));
22565
+ geometry.setAttribute("color", new THREE26.Float32BufferAttribute(colors2, 3));
22566
+ geometry.setAttribute("uv", new THREE26.Float32BufferAttribute(uvs, 2));
22479
22567
  geometry.computeBoundingBox();
22480
22568
  geometry.computeBoundingSphere();
22481
22569
  return { geometry, curve };
22482
22570
  };
22483
22571
  var createBanana = () => {
22484
- const group = new THREE25.Group();
22485
- const banana = new THREE25.Group();
22572
+ const group = new THREE26.Group();
22573
+ const banana = new THREE26.Group();
22486
22574
  const { geometry, curve } = createBananaGeometry();
22487
- const peel = new THREE25.Mesh(
22575
+ const peel = new THREE26.Mesh(
22488
22576
  geometry,
22489
- new THREE25.MeshStandardMaterial({
22577
+ new THREE26.MeshStandardMaterial({
22490
22578
  color: 16777215,
22491
22579
  roughness: 0.72,
22492
22580
  metalness: 0,
@@ -22495,9 +22583,9 @@ var createBanana = () => {
22495
22583
  );
22496
22584
  peel.name = "banana-peel";
22497
22585
  banana.add(peel);
22498
- const blossomTip = new THREE25.Mesh(
22499
- new THREE25.SphereGeometry(3.4, 20, 12),
22500
- new THREE25.MeshStandardMaterial({
22586
+ const blossomTip = new THREE26.Mesh(
22587
+ new THREE26.SphereGeometry(3.4, 20, 12),
22588
+ new THREE26.MeshStandardMaterial({
22501
22589
  color: 6242844,
22502
22590
  roughness: 0.92
22503
22591
  })
@@ -22508,20 +22596,20 @@ var createBanana = () => {
22508
22596
  banana.add(blossomTip);
22509
22597
  const stemLength = 11;
22510
22598
  const stemTangent = curve.getTangentAt(1).normalize();
22511
- const stem = new THREE25.Mesh(
22512
- new THREE25.CylinderGeometry(2.5, 4.1, stemLength, 18),
22513
- new THREE25.MeshStandardMaterial({
22599
+ const stem = new THREE26.Mesh(
22600
+ new THREE26.CylinderGeometry(2.5, 4.1, stemLength, 18),
22601
+ new THREE26.MeshStandardMaterial({
22514
22602
  color: 8483625,
22515
22603
  roughness: 0.82
22516
22604
  })
22517
22605
  );
22518
- stem.quaternion.setFromUnitVectors(new THREE25.Vector3(0, 1, 0), stemTangent);
22606
+ stem.quaternion.setFromUnitVectors(new THREE26.Vector3(0, 1, 0), stemTangent);
22519
22607
  stem.position.copy(curve.getPointAt(1)).addScaledVector(stemTangent, stemLength / 2);
22520
22608
  stem.name = "banana-stem";
22521
22609
  banana.add(stem);
22522
- const stemTip = new THREE25.Mesh(
22523
- new THREE25.SphereGeometry(2.55, 18, 10),
22524
- new THREE25.MeshStandardMaterial({
22610
+ const stemTip = new THREE26.Mesh(
22611
+ new THREE26.SphereGeometry(2.55, 18, 10),
22612
+ new THREE26.MeshStandardMaterial({
22525
22613
  color: 5981470,
22526
22614
  roughness: 0.9
22527
22615
  })
@@ -22535,7 +22623,7 @@ var createBanana = () => {
22535
22623
  };
22536
22624
  var createMacbookLidGeometry = (width, height, depth, radius, indentRadius) => {
22537
22625
  const lidShape = createRoundedRectangleShape(width, height, radius);
22538
- const indent = new THREE25.Path();
22626
+ const indent = new THREE26.Path();
22539
22627
  indent.absarc(0, 0, indentRadius, 0, Math.PI * 2, true);
22540
22628
  lidShape.holes.push(indent);
22541
22629
  return createPrismGeometryFromShape(lidShape, depth);
@@ -22543,9 +22631,9 @@ var createMacbookLidGeometry = (width, height, depth, radius, indentRadius) => {
22543
22631
  var createMacbookIndent = (topZ, radius) => {
22544
22632
  const indentDepth = 0.35;
22545
22633
  const diskDepth = 0.25;
22546
- const disk = new THREE25.Mesh(
22547
- new THREE25.CylinderGeometry(radius - 0.15, radius - 0.15, diskDepth, 48),
22548
- new THREE25.MeshStandardMaterial({
22634
+ const disk = new THREE26.Mesh(
22635
+ new THREE26.CylinderGeometry(radius - 0.15, radius - 0.15, diskDepth, 48),
22636
+ new THREE26.MeshStandardMaterial({
22549
22637
  color: 10199202,
22550
22638
  roughness: 0.48,
22551
22639
  metalness: 0.28
@@ -22558,10 +22646,10 @@ var createMacbookIndent = (topZ, radius) => {
22558
22646
  };
22559
22647
  var createCreditCard = () => {
22560
22648
  const spec = REFERENCE_OBJECT_SPECS["credit-card"];
22561
- const group = new THREE25.Group();
22562
- const body = new THREE25.Mesh(
22649
+ const group = new THREE26.Group();
22650
+ const body = new THREE26.Mesh(
22563
22651
  createRoundedPrismGeometry(spec.width, spec.height, spec.depth, 3.18),
22564
- new THREE25.MeshStandardMaterial({
22652
+ new THREE26.MeshStandardMaterial({
22565
22653
  color: 2383272,
22566
22654
  roughness: 0.38,
22567
22655
  metalness: 0.08
@@ -22570,9 +22658,9 @@ var createCreditCard = () => {
22570
22658
  body.name = "credit-card-body";
22571
22659
  group.add(body);
22572
22660
  const surfaceZ = spec.depth / 2 + 0.08;
22573
- const chip = new THREE25.Mesh(
22661
+ const chip = new THREE26.Mesh(
22574
22662
  createRoundedPrismGeometry(12, 9, 0.14, 1.2),
22575
- new THREE25.MeshStandardMaterial({
22663
+ new THREE26.MeshStandardMaterial({
22576
22664
  color: 14003525,
22577
22665
  roughness: 0.3,
22578
22666
  metalness: 0.62
@@ -22581,14 +22669,14 @@ var createCreditCard = () => {
22581
22669
  chip.position.set(-21, 3, surfaceZ);
22582
22670
  chip.name = "credit-card-chip";
22583
22671
  group.add(chip);
22584
- const stripeMaterial = new THREE25.MeshStandardMaterial({
22672
+ const stripeMaterial = new THREE26.MeshStandardMaterial({
22585
22673
  color: 15331061,
22586
22674
  roughness: 0.45,
22587
22675
  metalness: 0.05
22588
22676
  });
22589
22677
  for (let index2 = 0; index2 < 4; index2++) {
22590
- const stripe = new THREE25.Mesh(
22591
- new THREE25.BoxGeometry(index2 === 3 ? 8 : 12, 0.8, 0.1),
22678
+ const stripe = new THREE26.Mesh(
22679
+ new THREE26.BoxGeometry(index2 === 3 ? 8 : 12, 0.8, 0.1),
22592
22680
  stripeMaterial
22593
22681
  );
22594
22682
  stripe.position.set(-20 + index2 * 14, -14, surfaceZ + 0.08);
@@ -22599,13 +22687,13 @@ var createCreditCard = () => {
22599
22687
  };
22600
22688
  var createMacbook = () => {
22601
22689
  const spec = REFERENCE_OBJECT_SPECS["14in-macbook"];
22602
- const group = new THREE25.Group();
22603
- const aluminumMaterial = new THREE25.MeshStandardMaterial({
22690
+ const group = new THREE26.Group();
22691
+ const aluminumMaterial = new THREE26.MeshStandardMaterial({
22604
22692
  color: 12896201,
22605
22693
  roughness: 0.3,
22606
22694
  metalness: 0.38
22607
22695
  });
22608
- const body = new THREE25.Mesh(
22696
+ const body = new THREE26.Mesh(
22609
22697
  createRoundedPrismGeometry(spec.width, spec.height, 13.5, 9),
22610
22698
  aluminumMaterial
22611
22699
  );
@@ -22616,7 +22704,7 @@ var createMacbook = () => {
22616
22704
  const lidCenterZ = 6.75;
22617
22705
  const lidTopZ = lidCenterZ + lidDepth / 2;
22618
22706
  const indentRadius = 12;
22619
- const lid = new THREE25.Mesh(
22707
+ const lid = new THREE26.Mesh(
22620
22708
  createMacbookLidGeometry(
22621
22709
  spec.width - 1.8,
22622
22710
  spec.height - 1.8,
@@ -22629,9 +22717,9 @@ var createMacbook = () => {
22629
22717
  lid.position.z = lidCenterZ;
22630
22718
  lid.name = "macbook-lid";
22631
22719
  group.add(lid);
22632
- const hinge = new THREE25.Mesh(
22633
- new THREE25.BoxGeometry(spec.width - 42, 3.2, 1.2),
22634
- new THREE25.MeshStandardMaterial({
22720
+ const hinge = new THREE26.Mesh(
22721
+ new THREE26.BoxGeometry(spec.width - 42, 3.2, 1.2),
22722
+ new THREE26.MeshStandardMaterial({
22635
22723
  color: 3158838,
22636
22724
  roughness: 0.55,
22637
22725
  metalness: 0.45
@@ -22641,9 +22729,9 @@ var createMacbook = () => {
22641
22729
  hinge.name = "macbook-hinge";
22642
22730
  group.add(hinge);
22643
22731
  group.add(createMacbookIndent(lidTopZ, indentRadius));
22644
- const frontNotch = new THREE25.Mesh(
22645
- new THREE25.BoxGeometry(54, 1.2, 0.8),
22646
- new THREE25.MeshStandardMaterial({
22732
+ const frontNotch = new THREE26.Mesh(
22733
+ new THREE26.BoxGeometry(54, 1.2, 0.8),
22734
+ new THREE26.MeshStandardMaterial({
22647
22735
  color: 6712174,
22648
22736
  roughness: 0.45,
22649
22737
  metalness: 0.5
@@ -22666,7 +22754,7 @@ var disposeReferenceObject = (object) => {
22666
22754
  const geometries = /* @__PURE__ */ new Set();
22667
22755
  const materials = /* @__PURE__ */ new Set();
22668
22756
  object.traverse((child) => {
22669
- if (!(child instanceof THREE25.Mesh)) return;
22757
+ if (!(child instanceof THREE26.Mesh)) return;
22670
22758
  geometries.add(child.geometry);
22671
22759
  const childMaterials = Array.isArray(child.material) ? child.material : [child.material];
22672
22760
  for (const material of childMaterials) materials.add(material);
@@ -22676,28 +22764,28 @@ var disposeReferenceObject = (object) => {
22676
22764
  };
22677
22765
 
22678
22766
  // src/reference-objects/fit-camera-to-bounds.ts
22679
- import * as THREE26 from "three";
22767
+ import * as THREE27 from "three";
22680
22768
  var fitCameraToBounds = (camera, controls, bounds, padding = 1.18) => {
22681
22769
  const width = Math.max(bounds.maxX - bounds.minX, 0);
22682
22770
  const height = Math.max(bounds.maxY - bounds.minY, 0);
22683
22771
  const depth = Math.max(bounds.maxZ - bounds.minZ, 0);
22684
- const center = new THREE26.Vector3(
22772
+ const center = new THREE27.Vector3(
22685
22773
  (bounds.minX + bounds.maxX) / 2,
22686
22774
  (bounds.minY + bounds.maxY) / 2,
22687
22775
  (bounds.minZ + bounds.maxZ) / 2
22688
22776
  );
22689
22777
  const radius = Math.max(Math.hypot(width, height, depth) / 2, 1);
22690
- const previousTarget = controls?.target ?? new THREE26.Vector3();
22691
- const direction = new THREE26.Vector3(0, -0.75, 0.9).normalize();
22778
+ const previousTarget = controls?.target ?? new THREE27.Vector3();
22779
+ const direction = new THREE27.Vector3(0, -0.75, 0.9).normalize();
22692
22780
  let distance5 = Math.max(camera.position.distanceTo(previousTarget), 5);
22693
- if (camera instanceof THREE26.PerspectiveCamera) {
22694
- const verticalFov = THREE26.MathUtils.degToRad(camera.fov);
22781
+ if (camera instanceof THREE27.PerspectiveCamera) {
22782
+ const verticalFov = THREE27.MathUtils.degToRad(camera.fov);
22695
22783
  const horizontalFov = 2 * Math.atan(Math.tan(verticalFov / 2) * camera.aspect);
22696
22784
  const limitingFov = Math.min(verticalFov, horizontalFov);
22697
22785
  distance5 = radius * padding / Math.sin(limitingFov / 2);
22698
22786
  camera.far = Math.max(camera.far, distance5 + radius * padding * 3);
22699
22787
  camera.updateProjectionMatrix();
22700
- } else if (camera instanceof THREE26.OrthographicCamera) {
22788
+ } else if (camera instanceof THREE27.OrthographicCamera) {
22701
22789
  const halfViewWidth = Math.abs(camera.right - camera.left) / 2;
22702
22790
  const halfViewHeight = Math.abs(camera.top - camera.bottom) / 2;
22703
22791
  camera.zoom = Math.min(
@@ -22818,7 +22906,7 @@ var CadViewerContainer = forwardRef2(
22818
22906
  Canvas,
22819
22907
  {
22820
22908
  ref,
22821
- scene: { up: new THREE27.Vector3(0, 0, 1) },
22909
+ scene: { up: new THREE28.Vector3(0, 0, 1) },
22822
22910
  camera: { up: [0, 0, 1], position: initialCameraPosition },
22823
22911
  onCreated: ({ camera }) => {
22824
22912
  mainCameraRef.current = camera;
@@ -23010,7 +23098,7 @@ var createBoardGeomWithOutline = (board, depth = 1.2, options = {}) => {
23010
23098
  };
23011
23099
 
23012
23100
  // src/utils/get-board-edge-color.ts
23013
- import * as THREE29 from "three";
23101
+ import * as THREE30 from "three";
23014
23102
 
23015
23103
  // src/geoms/constants.ts
23016
23104
  var M = 0.01;
@@ -23043,7 +23131,7 @@ var soldermaskColors = {
23043
23131
  };
23044
23132
 
23045
23133
  // src/utils/soldermask-color.ts
23046
- import * as THREE28 from "three";
23134
+ import * as THREE29 from "three";
23047
23135
  var SOLDERMASK_PRESET_HEX = {
23048
23136
  red: "#650202",
23049
23137
  blue: "#003f7d",
@@ -23074,9 +23162,9 @@ var resolveSoldermaskColor = (requestedColor) => {
23074
23162
  }
23075
23163
  const presetName = lowercaseColor;
23076
23164
  const presetColor = SOLDERMASK_PRESET_HEX[presetName];
23077
- if (presetColor) return new THREE28.Color(presetColor);
23078
- const isCssColor = Object.hasOwn(THREE28.Color.NAMES, lowercaseColor) || CSS_HEX_COLOR_PATTERN.test(normalizedColor) || CSS_RGB_INTEGER_PATTERN.test(normalizedColor) || CSS_RGB_PERCENT_PATTERN.test(normalizedColor) || CSS_HSL_PATTERN.test(normalizedColor);
23079
- return isCssColor ? new THREE28.Color(lowercaseColor) : null;
23165
+ if (presetColor) return new THREE29.Color(presetColor);
23166
+ const isCssColor = Object.hasOwn(THREE29.Color.NAMES, lowercaseColor) || CSS_HEX_COLOR_PATTERN.test(normalizedColor) || CSS_RGB_INTEGER_PATTERN.test(normalizedColor) || CSS_RGB_PERCENT_PATTERN.test(normalizedColor) || CSS_HSL_PATTERN.test(normalizedColor);
23167
+ return isCssColor ? new THREE29.Color(lowercaseColor) : null;
23080
23168
  };
23081
23169
  var resolveSoldermaskOpacity = (requestedColor) => {
23082
23170
  const presetName = requestedColor?.trim().toLowerCase();
@@ -23103,7 +23191,7 @@ var soldermaskColorToCss = (color) => {
23103
23191
  };
23104
23192
 
23105
23193
  // src/utils/get-board-edge-color.ts
23106
- var LEGACY_FR4_EDGE_COLOR = new THREE29.Color(1063462);
23194
+ var LEGACY_FR4_EDGE_COLOR = new THREE30.Color(1063462);
23107
23195
  var getBoardEdgeColor = ({
23108
23196
  material,
23109
23197
  solder_mask_color
@@ -23112,7 +23200,7 @@ var getBoardEdgeColor = ({
23112
23200
  if (soldermaskColor) return soldermaskColor;
23113
23201
  if (material === "fr4") return LEGACY_FR4_EDGE_COLOR.clone();
23114
23202
  const materialColor = boardMaterialColors[material] ?? colors.fr4Tan;
23115
- return new THREE29.Color(materialColor[0], materialColor[1], materialColor[2]);
23203
+ return new THREE30.Color(materialColor[0], materialColor[1], materialColor[2]);
23116
23204
  };
23117
23205
 
23118
23206
  // src/soup-to-3d/index.ts
@@ -24562,7 +24650,7 @@ var Text = ({
24562
24650
  };
24563
24651
 
24564
24652
  // src/three-components/Error3d.tsx
24565
- import * as THREE30 from "three";
24653
+ import * as THREE31 from "three";
24566
24654
  import { Fragment as Fragment3, jsx as jsx16, jsxs as jsxs3 } from "react/jsx-runtime";
24567
24655
  var Error3d = ({
24568
24656
  error,
@@ -24596,7 +24684,7 @@ var Error3d = ({
24596
24684
  return [0, 0, 0];
24597
24685
  }, [cad_component]);
24598
24686
  const group = useMemo19(() => {
24599
- const g = new THREE30.Group();
24687
+ const g = new THREE31.Group();
24600
24688
  g.position.fromArray(position);
24601
24689
  return g;
24602
24690
  }, [position]);
@@ -24658,9 +24746,9 @@ var Error3d = ({
24658
24746
  };
24659
24747
  var ErrorBox = ({ parent }) => {
24660
24748
  const mesh = useMemo19(() => {
24661
- const m = new THREE30.Mesh(
24662
- new THREE30.BoxGeometry(0.5, 0.5, 0.5),
24663
- new THREE30.MeshStandardMaterial({
24749
+ const m = new THREE31.Mesh(
24750
+ new THREE31.BoxGeometry(0.5, 0.5, 0.5),
24751
+ new THREE31.MeshStandardMaterial({
24664
24752
  depthTest: false,
24665
24753
  transparent: true,
24666
24754
  color: "red",
@@ -24837,12 +24925,12 @@ function clearViaHolesFromSurface({
24837
24925
  }
24838
24926
 
24839
24927
  // src/textures/create-combined-board-textures.ts
24840
- import * as THREE43 from "three";
24928
+ import * as THREE44 from "three";
24841
24929
 
24842
24930
  // src/utils/pad-texture.ts
24843
24931
  import { su as su6 } from "@tscircuit/circuit-json-util";
24844
24932
  import { CircuitToCanvasDrawer as CircuitToCanvasDrawer2 } from "circuit-to-canvas";
24845
- import * as THREE31 from "three";
24933
+ import * as THREE32 from "three";
24846
24934
  function createPadTextureForLayer({
24847
24935
  layer,
24848
24936
  circuitJson,
@@ -24922,10 +25010,10 @@ function createPadTextureForLayer({
24922
25010
  drawSoldermaskTop: false,
24923
25011
  drawSoldermaskBottom: false
24924
25012
  });
24925
- const texture = new THREE31.CanvasTexture(canvas);
25013
+ const texture = new THREE32.CanvasTexture(canvas);
24926
25014
  texture.generateMipmaps = true;
24927
- texture.minFilter = THREE31.LinearMipmapLinearFilter;
24928
- texture.magFilter = THREE31.LinearFilter;
25015
+ texture.minFilter = THREE32.LinearMipmapLinearFilter;
25016
+ texture.magFilter = THREE32.LinearFilter;
24929
25017
  texture.anisotropy = 16;
24930
25018
  texture.needsUpdate = true;
24931
25019
  return texture;
@@ -24933,7 +25021,7 @@ function createPadTextureForLayer({
24933
25021
 
24934
25022
  // src/utils/panel-outline-texture.ts
24935
25023
  import { su as su7 } from "@tscircuit/circuit-json-util";
24936
- import * as THREE32 from "three";
25024
+ import * as THREE33 from "three";
24937
25025
  var resolvePanelIdForTexture = (circuitJson) => {
24938
25026
  const panels = circuitJson.filter(
24939
25027
  (e) => e.type === "pcb_panel"
@@ -25001,17 +25089,17 @@ function createPanelOutlineTextureForLayer({
25001
25089
  );
25002
25090
  }
25003
25091
  });
25004
- const texture = new THREE32.CanvasTexture(canvas);
25092
+ const texture = new THREE33.CanvasTexture(canvas);
25005
25093
  texture.generateMipmaps = true;
25006
- texture.minFilter = THREE32.LinearMipmapLinearFilter;
25007
- texture.magFilter = THREE32.LinearFilter;
25094
+ texture.minFilter = THREE33.LinearMipmapLinearFilter;
25095
+ texture.magFilter = THREE33.LinearFilter;
25008
25096
  texture.anisotropy = 16;
25009
25097
  texture.needsUpdate = true;
25010
25098
  return texture;
25011
25099
  }
25012
25100
 
25013
25101
  // src/utils/trace-texture.ts
25014
- import * as THREE33 from "three";
25102
+ import * as THREE34 from "three";
25015
25103
  import { CircuitToCanvasDrawer as CircuitToCanvasDrawer3 } from "circuit-to-canvas";
25016
25104
  import { getElementRenderLayers, su as su8 } from "@tscircuit/circuit-json-util";
25017
25105
  function createTraceTextureForLayer({
@@ -25097,10 +25185,10 @@ function createTraceTextureForLayer({
25097
25185
  drawSoldermaskTop: false,
25098
25186
  drawSoldermaskBottom: false
25099
25187
  });
25100
- const texture = new THREE33.CanvasTexture(canvas);
25188
+ const texture = new THREE34.CanvasTexture(canvas);
25101
25189
  texture.generateMipmaps = true;
25102
- texture.minFilter = THREE33.LinearMipmapLinearFilter;
25103
- texture.magFilter = THREE33.LinearFilter;
25190
+ texture.minFilter = THREE34.LinearMipmapLinearFilter;
25191
+ texture.magFilter = THREE34.LinearFilter;
25104
25192
  texture.anisotropy = 16;
25105
25193
  texture.needsUpdate = true;
25106
25194
  return texture;
@@ -25108,7 +25196,7 @@ function createTraceTextureForLayer({
25108
25196
 
25109
25197
  // src/textures/create-copper-pour-texture-for-layer.ts
25110
25198
  import { CircuitToCanvasDrawer as CircuitToCanvasDrawer4 } from "circuit-to-canvas";
25111
- import * as THREE34 from "three";
25199
+ import * as THREE35 from "three";
25112
25200
  var toRgb = (colorArr) => {
25113
25201
  const [r = 0, g = 0, b = 0] = colorArr;
25114
25202
  return `rgb(${Math.round(r * 255)}, ${Math.round(g * 255)}, ${Math.round(
@@ -25232,17 +25320,17 @@ function createCopperPourTextureForLayer({
25232
25320
  if (!onlyCoveredBySoldermask) {
25233
25321
  setColorAndDraw(uncoveredPours, uncoveredColor);
25234
25322
  }
25235
- const texture = new THREE34.CanvasTexture(canvas);
25323
+ const texture = new THREE35.CanvasTexture(canvas);
25236
25324
  texture.generateMipmaps = true;
25237
- texture.minFilter = THREE34.LinearMipmapLinearFilter;
25238
- texture.magFilter = THREE34.LinearFilter;
25325
+ texture.minFilter = THREE35.LinearMipmapLinearFilter;
25326
+ texture.magFilter = THREE35.LinearFilter;
25239
25327
  texture.anisotropy = 16;
25240
25328
  texture.needsUpdate = true;
25241
25329
  return texture;
25242
25330
  }
25243
25331
 
25244
25332
  // src/textures/create-copper-text-texture-for-layer.ts
25245
- import * as THREE35 from "three";
25333
+ import * as THREE36 from "three";
25246
25334
 
25247
25335
  // src/textures/copper-text/copper-text-drawing.ts
25248
25336
  import { CircuitToCanvasDrawer as CircuitToCanvasDrawer5 } from "circuit-to-canvas";
@@ -25357,17 +25445,17 @@ function createCopperTextTextureForLayer({
25357
25445
  elements,
25358
25446
  copperColor
25359
25447
  });
25360
- const texture = new THREE35.CanvasTexture(canvas);
25448
+ const texture = new THREE36.CanvasTexture(canvas);
25361
25449
  texture.generateMipmaps = true;
25362
- texture.minFilter = THREE35.LinearMipmapLinearFilter;
25363
- texture.magFilter = THREE35.LinearFilter;
25450
+ texture.minFilter = THREE36.LinearMipmapLinearFilter;
25451
+ texture.magFilter = THREE36.LinearFilter;
25364
25452
  texture.anisotropy = 16;
25365
25453
  texture.needsUpdate = true;
25366
25454
  return texture;
25367
25455
  }
25368
25456
 
25369
25457
  // src/textures/create-fabrication-note-texture-for-layer.ts
25370
- import * as THREE36 from "three";
25458
+ import * as THREE37 from "three";
25371
25459
 
25372
25460
  // src/textures/fabrication-note/fabrication-note-drawing.ts
25373
25461
  import { CircuitToCanvasDrawer as CircuitToCanvasDrawer6 } from "circuit-to-canvas";
@@ -25597,17 +25685,17 @@ function createFabricationNoteTextureForLayer({
25597
25685
  bounds,
25598
25686
  elements
25599
25687
  });
25600
- const texture = new THREE36.CanvasTexture(canvas);
25688
+ const texture = new THREE37.CanvasTexture(canvas);
25601
25689
  texture.generateMipmaps = true;
25602
- texture.minFilter = THREE36.LinearMipmapLinearFilter;
25603
- texture.magFilter = THREE36.LinearFilter;
25690
+ texture.minFilter = THREE37.LinearMipmapLinearFilter;
25691
+ texture.magFilter = THREE37.LinearFilter;
25604
25692
  texture.anisotropy = 16;
25605
25693
  texture.needsUpdate = true;
25606
25694
  return texture;
25607
25695
  }
25608
25696
 
25609
25697
  // src/textures/create-keepout-texture-for-layer.ts
25610
- import * as THREE37 from "three";
25698
+ import * as THREE38 from "three";
25611
25699
 
25612
25700
  // src/textures/keepout/keepout-drawing.ts
25613
25701
  import { CircuitToCanvasDrawer as CircuitToCanvasDrawer7 } from "circuit-to-canvas";
@@ -25682,17 +25770,17 @@ function createKeepoutTextureForLayer({
25682
25770
  elements,
25683
25771
  keepoutColor
25684
25772
  });
25685
- const texture = new THREE37.CanvasTexture(canvas);
25773
+ const texture = new THREE38.CanvasTexture(canvas);
25686
25774
  texture.generateMipmaps = true;
25687
- texture.minFilter = THREE37.LinearMipmapLinearFilter;
25688
- texture.magFilter = THREE37.LinearFilter;
25775
+ texture.minFilter = THREE38.LinearMipmapLinearFilter;
25776
+ texture.magFilter = THREE38.LinearFilter;
25689
25777
  texture.anisotropy = 16;
25690
25778
  texture.needsUpdate = true;
25691
25779
  return texture;
25692
25780
  }
25693
25781
 
25694
25782
  // src/textures/create-pcb-note-texture-for-layer.ts
25695
- import * as THREE38 from "three";
25783
+ import * as THREE39 from "three";
25696
25784
 
25697
25785
  // src/textures/pcb-note/pcb-note-drawing.ts
25698
25786
  import { CircuitToCanvasDrawer as CircuitToCanvasDrawer8 } from "circuit-to-canvas";
@@ -25846,17 +25934,17 @@ function createPcbNoteTextureForLayer({
25846
25934
  bounds,
25847
25935
  elements
25848
25936
  });
25849
- const texture = new THREE38.CanvasTexture(canvas);
25937
+ const texture = new THREE39.CanvasTexture(canvas);
25850
25938
  texture.generateMipmaps = true;
25851
- texture.minFilter = THREE38.LinearMipmapLinearFilter;
25852
- texture.magFilter = THREE38.LinearFilter;
25939
+ texture.minFilter = THREE39.LinearMipmapLinearFilter;
25940
+ texture.magFilter = THREE39.LinearFilter;
25853
25941
  texture.anisotropy = 16;
25854
25942
  texture.needsUpdate = true;
25855
25943
  return texture;
25856
25944
  }
25857
25945
 
25858
25946
  // src/textures/create-silkscreen-texture-for-layer.ts
25859
- import * as THREE39 from "three";
25947
+ import * as THREE40 from "three";
25860
25948
 
25861
25949
  // src/textures/silkscreen/silkscreen-drawing.ts
25862
25950
  import { CircuitToCanvasDrawer as CircuitToCanvasDrawer9 } from "circuit-to-canvas";
@@ -26007,21 +26095,21 @@ function createSilkscreenTextureForLayer({
26007
26095
  silkscreenColor,
26008
26096
  soldermaskVisible
26009
26097
  });
26010
- const texture = new THREE39.CanvasTexture(canvas);
26098
+ const texture = new THREE40.CanvasTexture(canvas);
26011
26099
  texture.generateMipmaps = true;
26012
- texture.minFilter = THREE39.LinearMipmapLinearFilter;
26013
- texture.magFilter = THREE39.LinearFilter;
26100
+ texture.minFilter = THREE40.LinearMipmapLinearFilter;
26101
+ texture.magFilter = THREE40.LinearFilter;
26014
26102
  texture.anisotropy = 16;
26015
26103
  texture.needsUpdate = true;
26016
26104
  return texture;
26017
26105
  }
26018
26106
 
26019
26107
  // src/textures/create-soldermask-texture-for-layer.ts
26020
- import * as THREE41 from "three";
26108
+ import * as THREE42 from "three";
26021
26109
 
26022
26110
  // src/textures/soldermask/soldermask-drawing.ts
26023
26111
  import { CircuitToCanvasDrawer as CircuitToCanvasDrawer10 } from "circuit-to-canvas";
26024
- import * as THREE40 from "three";
26112
+ import * as THREE41 from "three";
26025
26113
  var toRgb2 = (colorArr) => {
26026
26114
  const [r = 0, g = 0, b = 0] = colorArr;
26027
26115
  return `rgb(${Math.round(r * 255)}, ${Math.round(g * 255)}, ${Math.round(
@@ -26044,11 +26132,11 @@ var getSoldermaskPalette = (boardData) => {
26044
26132
  transparent: "rgba(0,0,0,0)"
26045
26133
  };
26046
26134
  }
26047
- const copperColor = new THREE40.Color().setRGB(
26135
+ const copperColor = new THREE41.Color().setRGB(
26048
26136
  colors.copper[0],
26049
26137
  colors.copper[1],
26050
26138
  colors.copper[2],
26051
- THREE40.SRGBColorSpace
26139
+ THREE41.SRGBColorSpace
26052
26140
  );
26053
26141
  return {
26054
26142
  soldermask: soldermaskColorToCss(requestedSoldermaskColor),
@@ -26183,17 +26271,17 @@ function createSoldermaskTextureForLayer({
26183
26271
  elements,
26184
26272
  boardData
26185
26273
  });
26186
- const texture = new THREE41.CanvasTexture(canvas);
26274
+ const texture = new THREE42.CanvasTexture(canvas);
26187
26275
  texture.generateMipmaps = true;
26188
- texture.minFilter = THREE41.LinearMipmapLinearFilter;
26189
- texture.magFilter = THREE41.LinearFilter;
26276
+ texture.minFilter = THREE42.LinearMipmapLinearFilter;
26277
+ texture.magFilter = THREE42.LinearFilter;
26190
26278
  texture.anisotropy = 16;
26191
26279
  texture.needsUpdate = true;
26192
26280
  return texture;
26193
26281
  }
26194
26282
 
26195
26283
  // src/textures/create-through-hole-texture-for-layer.ts
26196
- import * as THREE42 from "three";
26284
+ import * as THREE43 from "three";
26197
26285
 
26198
26286
  // src/textures/through-hole/through-hole-drawing.ts
26199
26287
  import { CircuitToCanvasDrawer as CircuitToCanvasDrawer11 } from "circuit-to-canvas";
@@ -26288,10 +26376,10 @@ function createThroughHoleTextureForLayer({
26288
26376
  elements,
26289
26377
  copperColor
26290
26378
  });
26291
- const texture = new THREE42.CanvasTexture(canvas);
26379
+ const texture = new THREE43.CanvasTexture(canvas);
26292
26380
  texture.generateMipmaps = true;
26293
- texture.minFilter = THREE42.LinearMipmapLinearFilter;
26294
- texture.magFilter = THREE42.LinearFilter;
26381
+ texture.minFilter = THREE43.LinearMipmapLinearFilter;
26382
+ texture.magFilter = THREE43.LinearFilter;
26295
26383
  texture.anisotropy = 16;
26296
26384
  texture.needsUpdate = true;
26297
26385
  return texture;
@@ -26388,10 +26476,10 @@ var createCombinedTexture = ({
26388
26476
  applySoldermaskSurfaceFilter(ctx, canvasWidth, canvasHeight, {
26389
26477
  includeReflection: layer === "top"
26390
26478
  });
26391
- const combinedTexture = new THREE43.CanvasTexture(canvas);
26479
+ const combinedTexture = new THREE44.CanvasTexture(canvas);
26392
26480
  combinedTexture.generateMipmaps = false;
26393
- combinedTexture.minFilter = THREE43.LinearFilter;
26394
- combinedTexture.magFilter = THREE43.LinearFilter;
26481
+ combinedTexture.minFilter = THREE44.LinearFilter;
26482
+ combinedTexture.magFilter = THREE44.LinearFilter;
26395
26483
  combinedTexture.premultiplyAlpha = true;
26396
26484
  combinedTexture.anisotropy = 16;
26397
26485
  combinedTexture.needsUpdate = true;
@@ -26427,11 +26515,11 @@ var createMaskedCopperMask = ({
26427
26515
  height
26428
26516
  );
26429
26517
  ctx.globalCompositeOperation = "source-over";
26430
- const maskTexture = new THREE43.CanvasTexture(canvas);
26431
- maskTexture.colorSpace = THREE43.NoColorSpace;
26518
+ const maskTexture = new THREE44.CanvasTexture(canvas);
26519
+ maskTexture.colorSpace = THREE44.NoColorSpace;
26432
26520
  maskTexture.generateMipmaps = false;
26433
- maskTexture.minFilter = THREE43.LinearFilter;
26434
- maskTexture.magFilter = THREE43.LinearFilter;
26521
+ maskTexture.minFilter = THREE44.LinearFilter;
26522
+ maskTexture.magFilter = THREE44.LinearFilter;
26435
26523
  maskTexture.premultiplyAlpha = false;
26436
26524
  maskTexture.needsUpdate = true;
26437
26525
  return maskTexture;
@@ -26577,7 +26665,7 @@ function createCombinedBoardTextures({
26577
26665
  }
26578
26666
 
26579
26667
  // src/textures/create-three-texture-meshes.ts
26580
- import * as THREE45 from "three";
26668
+ import * as THREE46 from "three";
26581
26669
 
26582
26670
  // src/board-surface-textures.ts
26583
26671
  var REALISTIC_BOARD_SURFACE_MATERIAL = {
@@ -26600,7 +26688,7 @@ var PAD_COPPER_TEXTURE_MATERIAL = {
26600
26688
  };
26601
26689
 
26602
26690
  // src/utils/create-board-relief-textures.ts
26603
- import * as THREE44 from "three";
26691
+ import * as THREE45 from "three";
26604
26692
  var PLAIN_SOLDERMASK_HEIGHT = 0.22;
26605
26693
  var MASKED_COPPER_HEIGHT = 0.7;
26606
26694
  var EXPOSED_COPPER_HEIGHT = 0.86;
@@ -26695,13 +26783,13 @@ var getBoardSurfaceProfile = (r, g, b, hasMaskedCopper) => {
26695
26783
  return PLAIN_SOLDERMASK_PROFILE;
26696
26784
  };
26697
26785
  var createDataTexture = (canvas) => {
26698
- const texture = new THREE44.CanvasTexture(canvas);
26699
- texture.colorSpace = THREE44.NoColorSpace;
26786
+ const texture = new THREE45.CanvasTexture(canvas);
26787
+ texture.colorSpace = THREE45.NoColorSpace;
26700
26788
  texture.generateMipmaps = false;
26701
- texture.minFilter = THREE44.LinearFilter;
26702
- texture.magFilter = THREE44.LinearFilter;
26703
- texture.wrapS = THREE44.ClampToEdgeWrapping;
26704
- texture.wrapT = THREE44.ClampToEdgeWrapping;
26789
+ texture.minFilter = THREE45.LinearFilter;
26790
+ texture.magFilter = THREE45.LinearFilter;
26791
+ texture.wrapS = THREE45.ClampToEdgeWrapping;
26792
+ texture.wrapT = THREE45.ClampToEdgeWrapping;
26705
26793
  texture.needsUpdate = true;
26706
26794
  return texture;
26707
26795
  };
@@ -26825,16 +26913,16 @@ function createTexturePlane(config, boardData) {
26825
26913
  } = config;
26826
26914
  if (!texture) return null;
26827
26915
  const boardOutlineBounds = calculateOutlineBounds(boardData);
26828
- const planeGeom = new THREE45.PlaneGeometry(
26916
+ const planeGeom = new THREE46.PlaneGeometry(
26829
26917
  boardOutlineBounds.width,
26830
26918
  boardOutlineBounds.height
26831
26919
  );
26832
- texture.colorSpace = THREE45.SRGBColorSpace;
26920
+ texture.colorSpace = THREE46.SRGBColorSpace;
26833
26921
  const sharedMaterialOptions = {
26834
26922
  map: texture,
26835
26923
  transparent: true,
26836
26924
  alphaTest: 0.08,
26837
- side: THREE45.FrontSide,
26925
+ side: THREE46.FrontSide,
26838
26926
  depthWrite: true,
26839
26927
  polygonOffset: usePolygonOffset,
26840
26928
  polygonOffsetFactor: usePolygonOffset ? -4 : 0,
@@ -26843,12 +26931,12 @@ function createTexturePlane(config, boardData) {
26843
26931
  opacity: isFaux ? FAUX_BOARD_OPACITY : 1
26844
26932
  };
26845
26933
  const reliefTextures = createBoardReliefTextures(texture, maskedCopperMask);
26846
- const material = new THREE45.MeshPhysicalMaterial({
26934
+ const material = new THREE46.MeshPhysicalMaterial({
26847
26935
  ...sharedMaterialOptions,
26848
26936
  bumpMap: reliefTextures?.bumpMap ?? null,
26849
26937
  bumpScale: REALISTIC_BOARD_SURFACE_MATERIAL.bumpScale,
26850
26938
  normalMap: reliefTextures?.normalMap ?? null,
26851
- normalScale: new THREE45.Vector2(
26939
+ normalScale: new THREE46.Vector2(
26852
26940
  REALISTIC_BOARD_SURFACE_MATERIAL.normalScale,
26853
26941
  REALISTIC_BOARD_SURFACE_MATERIAL.normalScale
26854
26942
  ),
@@ -26862,7 +26950,7 @@ function createTexturePlane(config, boardData) {
26862
26950
  clearcoatRoughness: REALISTIC_BOARD_SURFACE_MATERIAL.clearcoatRoughness,
26863
26951
  envMapIntensity: 0.18
26864
26952
  });
26865
- const mesh = new THREE45.Mesh(planeGeom, material);
26953
+ const mesh = new THREE46.Mesh(planeGeom, material);
26866
26954
  mesh.position.set(
26867
26955
  boardOutlineBounds.centerX,
26868
26956
  boardOutlineBounds.centerY,
@@ -26910,7 +26998,7 @@ function createTextureMeshes(textures, boardData, pcbThickness, isFaux = false)
26910
26998
  }
26911
26999
 
26912
27000
  // src/three-components/JscadBoardTextures.tsx
26913
- import * as THREE46 from "three";
27001
+ import * as THREE47 from "three";
26914
27002
 
26915
27003
  // src/hooks/useBoardTextureVisibility.ts
26916
27004
  import { useMemo as useMemo20 } from "react";
@@ -27048,7 +27136,7 @@ function JscadBoardTextures({
27048
27136
  const typedMaterial = material;
27049
27137
  for (const prop of textureProps) {
27050
27138
  const texture = typedMaterial[prop];
27051
- if (texture && texture instanceof THREE46.Texture) {
27139
+ if (texture && texture instanceof THREE47.Texture) {
27052
27140
  texture.dispose();
27053
27141
  typedMaterial[prop] = null;
27054
27142
  }
@@ -27067,16 +27155,16 @@ function JscadBoardTextures({
27067
27155
  }) => {
27068
27156
  if (!texture) return null;
27069
27157
  const boardOutlineBounds = calculateOutlineBounds(boardData);
27070
- const planeGeom = new THREE46.PlaneGeometry(
27158
+ const planeGeom = new THREE47.PlaneGeometry(
27071
27159
  boardOutlineBounds.width,
27072
27160
  boardOutlineBounds.height
27073
27161
  );
27074
- texture.colorSpace = THREE46.SRGBColorSpace;
27162
+ texture.colorSpace = THREE47.SRGBColorSpace;
27075
27163
  const sharedMaterialOptions = {
27076
27164
  map: texture,
27077
27165
  transparent: true,
27078
27166
  alphaTest: 0.08,
27079
- side: THREE46.FrontSide,
27167
+ side: THREE47.FrontSide,
27080
27168
  depthWrite,
27081
27169
  polygonOffset: usePolygonOffset,
27082
27170
  polygonOffsetFactor: usePolygonOffset ? -4 : 0,
@@ -27087,12 +27175,12 @@ function JscadBoardTextures({
27087
27175
  texture,
27088
27176
  maskedCopperMask
27089
27177
  );
27090
- const material = new THREE46.MeshPhysicalMaterial({
27178
+ const material = new THREE47.MeshPhysicalMaterial({
27091
27179
  ...sharedMaterialOptions,
27092
27180
  bumpMap: reliefTextures?.bumpMap ?? null,
27093
27181
  bumpScale: REALISTIC_BOARD_SURFACE_MATERIAL.bumpScale,
27094
27182
  normalMap: reliefTextures?.normalMap ?? null,
27095
- normalScale: new THREE46.Vector2(
27183
+ normalScale: new THREE47.Vector2(
27096
27184
  REALISTIC_BOARD_SURFACE_MATERIAL.normalScale,
27097
27185
  REALISTIC_BOARD_SURFACE_MATERIAL.normalScale
27098
27186
  ),
@@ -27104,7 +27192,7 @@ function JscadBoardTextures({
27104
27192
  clearcoatRoughness: REALISTIC_BOARD_SURFACE_MATERIAL.clearcoatRoughness,
27105
27193
  envMapIntensity: 0.18
27106
27194
  });
27107
- const mesh = new THREE46.Mesh(planeGeom, material);
27195
+ const mesh = new THREE47.Mesh(planeGeom, material);
27108
27196
  mesh.position.set(
27109
27197
  boardOutlineBounds.centerX,
27110
27198
  boardOutlineBounds.centerY,
@@ -27154,7 +27242,7 @@ function JscadBoardTextures({
27154
27242
  for (const material of mesh.material) {
27155
27243
  disposeTextureMaterial(material);
27156
27244
  }
27157
- } else if (mesh.material instanceof THREE46.Material) {
27245
+ } else if (mesh.material instanceof THREE47.Material) {
27158
27246
  disposeTextureMaterial(mesh.material);
27159
27247
  }
27160
27248
  }
@@ -27167,7 +27255,7 @@ function JscadBoardTextures({
27167
27255
 
27168
27256
  // src/three-components/STLModel.tsx
27169
27257
  import { useState as useState17, useEffect as useEffect28, useMemo as useMemo22 } from "react";
27170
- import * as THREE47 from "three";
27258
+ import * as THREE48 from "three";
27171
27259
  import { STLLoader } from "three-stdlib";
27172
27260
  function STLModel({
27173
27261
  stlUrl,
@@ -27200,15 +27288,15 @@ function STLModel({
27200
27288
  const mesh = useMemo22(() => {
27201
27289
  if (!geom) return null;
27202
27290
  const isBoardLayer = layerType === "board";
27203
- const material = new THREE47.MeshStandardMaterial({
27204
- color: Array.isArray(color) ? new THREE47.Color(color[0], color[1], color[2]) : color,
27291
+ const material = new THREE48.MeshStandardMaterial({
27292
+ color: Array.isArray(color) ? new THREE48.Color(color[0], color[1], color[2]) : color,
27205
27293
  transparent: opacity !== 1,
27206
27294
  opacity,
27207
27295
  polygonOffset: isBoardLayer,
27208
27296
  polygonOffsetFactor: isBoardLayer ? 6 : 0,
27209
27297
  polygonOffsetUnits: isBoardLayer ? 6 : 0
27210
27298
  });
27211
- const createdMesh = new THREE47.Mesh(geom, material);
27299
+ const createdMesh = new THREE48.Mesh(geom, material);
27212
27300
  createdMesh.renderOrder = isBoardLayer ? -1 : 1;
27213
27301
  configureObjectShadows(createdMesh, {
27214
27302
  castShadow: !isBoardLayer && opacity === 1,
@@ -27271,7 +27359,7 @@ function VisibleSTLModel({
27271
27359
  import { parseCableString } from "@tscircuit/cableprinter";
27272
27360
  import { createCableMeshes } from "jscad-electronics/cables";
27273
27361
  import { useEffect as useEffect29, useMemo as useMemo23 } from "react";
27274
- import * as THREE48 from "three";
27362
+ import * as THREE49 from "three";
27275
27363
  var isCadCableElement = (element) => {
27276
27364
  if (!element || typeof element !== "object") return false;
27277
27365
  const candidate = element;
@@ -27288,14 +27376,14 @@ var getConnectorPin1Side = ({
27288
27376
  const endpoint = end === "start" ? path[0] : path[path.length - 1];
27289
27377
  const adjacent = end === "start" ? path[1] : path[path.length - 2];
27290
27378
  if (!endpoint || !adjacent) return void 0;
27291
- const cableAxis = new THREE48.Vector3(
27379
+ const cableAxis = new THREE49.Vector3(
27292
27380
  adjacent.x - endpoint.x,
27293
27381
  adjacent.y - endpoint.y,
27294
27382
  adjacent.z - endpoint.z
27295
27383
  );
27296
27384
  if (cableAxis.lengthSq() < 1e-12) return void 0;
27297
27385
  cableAxis.normalize();
27298
- const pin1Side = new THREE48.Vector3(
27386
+ const pin1Side = new THREE49.Vector3(
27299
27387
  pin1Position.x - endpoint.x,
27300
27388
  pin1Position.y - endpoint.y,
27301
27389
  pin1Position.z - endpoint.z
@@ -27321,28 +27409,28 @@ var createCadCableObject = (cable) => {
27321
27409
  end: "end"
27322
27410
  })
27323
27411
  });
27324
- const group = new THREE48.Group();
27412
+ const group = new THREE49.Group();
27325
27413
  group.name = `cad-cable-${cable.cad_cable_id}`;
27326
27414
  group.userData = { cadCableId: cable.cad_cable_id, name: cable.name };
27327
27415
  for (const cableMesh of cableMeshes) {
27328
- let geometry = new THREE48.BufferGeometry();
27416
+ let geometry = new THREE49.BufferGeometry();
27329
27417
  geometry.setAttribute(
27330
27418
  "position",
27331
- new THREE48.Float32BufferAttribute(cableMesh.positions, 3)
27419
+ new THREE49.Float32BufferAttribute(cableMesh.positions, 3)
27332
27420
  );
27333
27421
  geometry.setIndex(cableMesh.indices);
27334
27422
  if (!cableMesh.smooth) geometry = geometry.toNonIndexed();
27335
27423
  geometry.computeVertexNormals();
27336
27424
  const [red, green, blue, alpha] = cableMesh.color;
27337
- const material = new THREE48.MeshStandardMaterial({
27338
- color: new THREE48.Color(red, green, blue),
27425
+ const material = new THREE49.MeshStandardMaterial({
27426
+ color: new THREE49.Color(red, green, blue),
27339
27427
  metalness: cableMesh.material?.metalness ?? 0,
27340
27428
  roughness: cableMesh.material?.roughness ?? 0.7,
27341
27429
  opacity: alpha,
27342
27430
  transparent: alpha < 1,
27343
- side: THREE48.DoubleSide
27431
+ side: THREE49.DoubleSide
27344
27432
  });
27345
- const mesh = new THREE48.Mesh(geometry, material);
27433
+ const mesh = new THREE49.Mesh(geometry, material);
27346
27434
  mesh.name = `${group.name}:${cableMesh.name}`;
27347
27435
  configureObjectShadows(mesh, { castShadow: true, receiveShadow: true });
27348
27436
  group.add(mesh);
@@ -27351,7 +27439,7 @@ var createCadCableObject = (cable) => {
27351
27439
  };
27352
27440
  var disposeCadCableObject = (group) => {
27353
27441
  group.traverse((object) => {
27354
- if (!(object instanceof THREE48.Mesh)) return;
27442
+ if (!(object instanceof THREE49.Mesh)) return;
27355
27443
  object.geometry.dispose();
27356
27444
  const materials = Array.isArray(object.material) ? object.material : [object.material];
27357
27445
  for (const material of materials) material.dispose();
@@ -28863,12 +28951,12 @@ function createStiffenerMesh({
28863
28951
 
28864
28952
  // src/CadViewerManifold.tsx
28865
28953
  import { useEffect as useEffect31, useMemo as useMemo26, useState as useState19 } from "react";
28866
- import * as THREE56 from "three";
28954
+ import * as THREE57 from "three";
28867
28955
 
28868
28956
  // src/hooks/useManifoldBoardBuilder.ts
28869
28957
  import { su as su16 } from "@tscircuit/circuit-json-util";
28870
28958
  import { useEffect as useEffect30, useMemo as useMemo25, useRef as useRef9, useState as useState18 } from "react";
28871
- import * as THREE52 from "three";
28959
+ import * as THREE53 from "three";
28872
28960
 
28873
28961
  // src/utils/manifold/create-manifold-board.ts
28874
28962
  var arePointsClockwise2 = (points) => {
@@ -29217,17 +29305,17 @@ function processNonPlatedHolesForManifold(Manifold, CrossSection, circuitJson, p
29217
29305
 
29218
29306
  // src/utils/manifold/process-plated-holes.ts
29219
29307
  import { su as su15 } from "@tscircuit/circuit-json-util";
29220
- import * as THREE50 from "three";
29308
+ import * as THREE51 from "three";
29221
29309
 
29222
29310
  // src/utils/manifold-mesh-to-three-geometry.ts
29223
- import * as THREE49 from "three";
29311
+ import * as THREE50 from "three";
29224
29312
  function manifoldMeshToThreeGeometry(manifoldMesh) {
29225
- const geometry = new THREE49.BufferGeometry();
29313
+ const geometry = new THREE50.BufferGeometry();
29226
29314
  geometry.setAttribute(
29227
29315
  "position",
29228
- new THREE49.Float32BufferAttribute(manifoldMesh.vertProperties, 3)
29316
+ new THREE50.Float32BufferAttribute(manifoldMesh.vertProperties, 3)
29229
29317
  );
29230
- geometry.setIndex(new THREE49.Uint32BufferAttribute(manifoldMesh.triVerts, 1));
29318
+ geometry.setIndex(new THREE50.Uint32BufferAttribute(manifoldMesh.triVerts, 1));
29231
29319
  if (manifoldMesh.runIndex && manifoldMesh.runIndex.length > 1 && manifoldMesh.runOriginalID) {
29232
29320
  for (let i = 0; i < manifoldMesh.runIndex.length - 1; i++) {
29233
29321
  const start = manifoldMesh.runIndex[i];
@@ -29261,7 +29349,7 @@ var createEllipsePoints = (width, height, segments) => {
29261
29349
  }
29262
29350
  return points;
29263
29351
  };
29264
- var COPPER_COLOR = new THREE50.Color(...colors.copper);
29352
+ var COPPER_COLOR = new THREE51.Color(...colors.copper);
29265
29353
  var PLATED_HOLE_LIP_HEIGHT = 0.05;
29266
29354
  var PLATED_HOLE_PAD_THICKNESS = 3e-3;
29267
29355
  var PLATED_HOLE_SURFACE_CLEARANCE = 5e-4;
@@ -29891,7 +29979,7 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
29891
29979
  }
29892
29980
 
29893
29981
  // src/utils/manifold/process-vias.ts
29894
- import * as THREE51 from "three";
29982
+ import * as THREE52 from "three";
29895
29983
 
29896
29984
  // src/utils/via-geoms.ts
29897
29985
  function createViaCopper2({
@@ -29929,7 +30017,7 @@ function createViaCopper2({
29929
30017
  }
29930
30018
 
29931
30019
  // src/utils/manifold/process-vias.ts
29932
- var COPPER_COLOR2 = new THREE51.Color(...colors.copper);
30020
+ var COPPER_COLOR2 = new THREE52.Color(...colors.copper);
29933
30021
  function processViasForManifold(Manifold, circuitJson, pcbThickness, manifoldInstancesForCleanup, boardClipVolume, otherHoleDrills = []) {
29934
30022
  const viaBoardDrills = [];
29935
30023
  const pcbVias = getPcbVias(circuitJson);
@@ -30177,7 +30265,7 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson, visibility) => {
30177
30265
  {
30178
30266
  key: "plated-holes-union",
30179
30267
  geometry: cutPlatedGeom,
30180
- color: new THREE52.Color(
30268
+ color: new THREE53.Color(
30181
30269
  colors.copper[0],
30182
30270
  colors.copper[1],
30183
30271
  colors.copper[2]
@@ -30247,7 +30335,7 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson, visibility) => {
30247
30335
  };
30248
30336
 
30249
30337
  // src/utils/flex-meshes.ts
30250
- import * as THREE53 from "three";
30338
+ import * as THREE54 from "three";
30251
30339
  function restoreOutlinePrecision(point, outline, tolerance) {
30252
30340
  let distanceSquared = tolerance * tolerance;
30253
30341
  let closest;
@@ -30282,7 +30370,7 @@ function meshToSurface(mesh, center, outline) {
30282
30370
  const triangles = [];
30283
30371
  for (let i = 0; i < position.count; i += 3) {
30284
30372
  const vertices = [0, 1, 2].map((j) => {
30285
- const v = new THREE53.Vector3().fromBufferAttribute(position, i + j);
30373
+ const v = new THREE54.Vector3().fromBufferAttribute(position, i + j);
30286
30374
  const localMagnitude = Math.max(
30287
30375
  1,
30288
30376
  Math.abs(v.x),
@@ -30305,7 +30393,7 @@ function meshToSurface(mesh, center, outline) {
30305
30393
  return { x: v.x - center.x, y: v.y - center.y, z: v.z };
30306
30394
  });
30307
30395
  const [a, b, c] = vertices;
30308
- const n = new THREE53.Vector3(b.x - a.x, b.y - a.y, b.z - a.z).cross(new THREE53.Vector3(c.x - a.x, c.y - a.y, c.z - a.z)).normalize();
30396
+ const n = new THREE54.Vector3(b.x - a.x, b.y - a.y, b.z - a.z).cross(new THREE54.Vector3(c.x - a.x, c.y - a.y, c.z - a.z)).normalize();
30309
30397
  triangles.push({
30310
30398
  vertices,
30311
30399
  normal: { x: n.x, y: n.y, z: n.z },
@@ -30328,13 +30416,13 @@ function surfaceToGeometry(surface, center) {
30328
30416
  normals.push(triangle.normal.x, triangle.normal.y, triangle.normal.z);
30329
30417
  uvs.push(triangle.uvs?.[i]?.u ?? 0, triangle.uvs?.[i]?.v ?? 0);
30330
30418
  });
30331
- const geometry = new THREE53.BufferGeometry();
30419
+ const geometry = new THREE54.BufferGeometry();
30332
30420
  geometry.setAttribute(
30333
30421
  "position",
30334
- new THREE53.Float32BufferAttribute(positions, 3)
30422
+ new THREE54.Float32BufferAttribute(positions, 3)
30335
30423
  );
30336
- geometry.setAttribute("normal", new THREE53.Float32BufferAttribute(normals, 3));
30337
- geometry.setAttribute("uv", new THREE53.Float32BufferAttribute(uvs, 2));
30424
+ geometry.setAttribute("normal", new THREE54.Float32BufferAttribute(normals, 3));
30425
+ geometry.setAttribute("uv", new THREE54.Float32BufferAttribute(uvs, 2));
30338
30426
  geometry.computeBoundingBox();
30339
30427
  geometry.computeBoundingSphere();
30340
30428
  return geometry;
@@ -30387,7 +30475,7 @@ function createFlexMeshes(geometryMeshes, textureMeshes, json, foldPcbs) {
30387
30475
  z: mesh.position.z
30388
30476
  }));
30389
30477
  const uvs = vertices.map((p) => {
30390
- const local = new THREE53.Vector3(
30478
+ const local = new THREE54.Vector3(
30391
30479
  p.x + board.center.x,
30392
30480
  p.y + board.center.y,
30393
30481
  p.z
@@ -30411,7 +30499,7 @@ function createFlexMeshes(geometryMeshes, textureMeshes, json, foldPcbs) {
30411
30499
  return result;
30412
30500
  }) : textureMeshes;
30413
30501
  for (const stiffener of stiffeners) {
30414
- const mesh = new THREE53.Mesh(
30502
+ const mesh = new THREE54.Mesh(
30415
30503
  surfaceToGeometry(
30416
30504
  createStiffenerMesh({
30417
30505
  stiffener,
@@ -30420,16 +30508,16 @@ function createFlexMeshes(geometryMeshes, textureMeshes, json, foldPcbs) {
30420
30508
  }),
30421
30509
  board.center
30422
30510
  ),
30423
- new THREE53.MeshStandardMaterial({
30511
+ new THREE54.MeshStandardMaterial({
30424
30512
  color: stiffener.material === "fr4" ? "#879568" : stiffener.material === "polyimide" ? "#bd7f27" : "#b8bdc4",
30425
- side: THREE53.DoubleSide
30513
+ side: THREE54.DoubleSide
30426
30514
  })
30427
30515
  );
30428
30516
  mesh.name = "board-stiffener";
30429
30517
  configureObjectShadows(mesh);
30430
30518
  geometry.push(mesh);
30431
30519
  }
30432
- const bounds = new THREE53.Box3();
30520
+ const bounds = new THREE54.Box3();
30433
30521
  for (const mesh of [...geometry, ...textures]) bounds.expandByObject(mesh);
30434
30522
  return {
30435
30523
  geometryMeshes: geometry,
@@ -30446,11 +30534,11 @@ function createFlexMeshes(geometryMeshes, textureMeshes, json, foldPcbs) {
30446
30534
  }
30447
30535
 
30448
30536
  // src/utils/manifold/create-three-geometry-meshes.ts
30449
- import * as THREE55 from "three";
30537
+ import * as THREE56 from "three";
30450
30538
 
30451
30539
  // src/utils/create-board-material.ts
30452
- import * as THREE54 from "three";
30453
- var DEFAULT_SIDE = THREE54.DoubleSide;
30540
+ import * as THREE55 from "three";
30541
+ var DEFAULT_SIDE = THREE55.DoubleSide;
30454
30542
  var createBoardMaterial = ({
30455
30543
  material,
30456
30544
  color,
@@ -30458,7 +30546,7 @@ var createBoardMaterial = ({
30458
30546
  isFaux = false
30459
30547
  }) => {
30460
30548
  if (material === "fr4") {
30461
- return new THREE54.MeshPhysicalMaterial({
30549
+ return new THREE55.MeshPhysicalMaterial({
30462
30550
  color,
30463
30551
  side,
30464
30552
  metalness: 0,
@@ -30476,7 +30564,7 @@ var createBoardMaterial = ({
30476
30564
  polygonOffsetUnits: 1
30477
30565
  });
30478
30566
  }
30479
- return new THREE54.MeshStandardMaterial({
30567
+ return new THREE55.MeshStandardMaterial({
30480
30568
  color,
30481
30569
  side,
30482
30570
  flatShading: true,
@@ -30495,12 +30583,12 @@ function createGeometryMeshes(geoms) {
30495
30583
  const meshes = [];
30496
30584
  if (!geoms) return meshes;
30497
30585
  if (geoms.board?.geometry) {
30498
- const mesh = new THREE55.Mesh(
30586
+ const mesh = new THREE56.Mesh(
30499
30587
  geoms.board.geometry,
30500
30588
  createBoardMaterial({
30501
30589
  material: geoms.board.material,
30502
30590
  color: geoms.board.color,
30503
- side: THREE55.DoubleSide,
30591
+ side: THREE56.DoubleSide,
30504
30592
  isFaux: geoms.board.isFaux
30505
30593
  })
30506
30594
  );
@@ -30511,11 +30599,11 @@ function createGeometryMeshes(geoms) {
30511
30599
  const createMeshesFromArray = (geomArray) => {
30512
30600
  if (geomArray) {
30513
30601
  for (const comp of geomArray) {
30514
- const mesh = new THREE55.Mesh(
30602
+ const mesh = new THREE56.Mesh(
30515
30603
  comp.geometry,
30516
- new THREE55.MeshStandardMaterial({
30604
+ new THREE56.MeshStandardMaterial({
30517
30605
  color: comp.color,
30518
- side: THREE55.DoubleSide,
30606
+ side: THREE56.DoubleSide,
30519
30607
  flatShading: true
30520
30608
  // Consistent with board
30521
30609
  })
@@ -30587,7 +30675,7 @@ var BoardMeshes = ({
30587
30675
  const typedMaterial = material;
30588
30676
  for (const prop of textureProps) {
30589
30677
  const texture = typedMaterial[prop];
30590
- if (texture && texture instanceof THREE56.Texture) {
30678
+ if (texture && texture instanceof THREE57.Texture) {
30591
30679
  texture.dispose();
30592
30680
  }
30593
30681
  }
@@ -30820,47 +30908,201 @@ var CadViewerManifold = ({
30820
30908
  };
30821
30909
  var CadViewerManifold_default = CadViewerManifold;
30822
30910
 
30823
- // node_modules/@radix-ui/react-dropdown-menu/dist/index.mjs
30824
- import * as React42 from "react";
30825
-
30826
- // node_modules/@radix-ui/primitive/dist/index.mjs
30827
- var __defProp2 = Object.defineProperty;
30828
- var __name = (target, value) => __defProp2(target, "name", { value, configurable: true });
30829
- var canUseDOM = !!(typeof window !== "undefined" && window.document && window.document.createElement);
30830
- function composeEventHandlers(originalEventHandler, ourEventHandler, { checkForDefaultPrevented = true } = {}) {
30831
- return /* @__PURE__ */ __name(function handleEvent(event) {
30832
- originalEventHandler?.(event);
30833
- if (checkForDefaultPrevented === false || !event || !event.defaultPrevented) {
30834
- return ourEventHandler?.(event);
30835
- }
30836
- }, "handleEvent");
30837
- }
30838
- __name(composeEventHandlers, "composeEventHandlers");
30839
- function getOwnerWindow(element) {
30840
- if (!canUseDOM) {
30841
- throw new Error("Cannot access window outside of the DOM");
30842
- }
30843
- return element?.ownerDocument?.defaultView ?? window;
30844
- }
30845
- __name(getOwnerWindow, "getOwnerWindow");
30846
- function getOwnerDocument(element) {
30847
- if (!canUseDOM) {
30848
- throw new Error("Cannot access document outside of the DOM");
30849
- }
30850
- return element?.ownerDocument ?? document;
30911
+ // src/CadViewerGlb.tsx
30912
+ import { useEffect as useEffect33, useMemo as useMemo28, useState as useState21 } from "react";
30913
+
30914
+ // src/hooks/useGlbModel.ts
30915
+ import { useEffect as useEffect32, useMemo as useMemo27, useState as useState20 } from "react";
30916
+ function useGlbModel(source) {
30917
+ const request = useMemo27(() => ({ source }), [source]);
30918
+ const [result, setResult] = useState20();
30919
+ useEffect32(() => {
30920
+ const controller = new AbortController();
30921
+ let model;
30922
+ loadGlbScene(request.source, controller.signal).then((loaded) => {
30923
+ model = loaded;
30924
+ if (controller.signal.aborted) disposeGlbScene(loaded);
30925
+ else setResult({ request, model: loaded });
30926
+ }).catch((error) => {
30927
+ if (!controller.signal.aborted)
30928
+ setResult({
30929
+ request,
30930
+ error: error instanceof Error ? error.message : String(error)
30931
+ });
30932
+ });
30933
+ return () => {
30934
+ controller.abort();
30935
+ if (model) disposeGlbScene(model);
30936
+ };
30937
+ }, [request]);
30938
+ return result?.request === request ? result : void 0;
30851
30939
  }
30852
- __name(getOwnerDocument, "getOwnerDocument");
30853
- function getActiveElement(node, activeDescendant = false) {
30854
- const { activeElement } = getOwnerDocument(node);
30855
- if (!activeElement?.nodeName) {
30856
- return null;
30857
- }
30858
- if (isFrame(activeElement) && activeElement.contentDocument) {
30859
- return getActiveElement(activeElement.contentDocument.body, activeDescendant);
30860
- }
30861
- if (activeDescendant) {
30862
- const id = activeElement.getAttribute("aria-activedescendant");
30863
- if (id) {
30940
+
30941
+ // src/CadViewerGlb.tsx
30942
+ import * as THREE58 from "three";
30943
+ import { Fragment as Fragment4, jsx as jsx20, jsxs as jsxs6 } from "react/jsx-runtime";
30944
+ function GlbScene({
30945
+ model,
30946
+ hiddenCadComponentIds
30947
+ }) {
30948
+ const { rootObject } = useThree();
30949
+ const { addHoverable, removeHoverable } = useHover();
30950
+ const [hover, setHover] = useState21();
30951
+ const bounds = useMemo28(() => {
30952
+ const box = new THREE58.Box3().setFromObject(model);
30953
+ if (box.isEmpty()) return;
30954
+ return {
30955
+ minX: box.min.x,
30956
+ maxX: box.max.x,
30957
+ minY: box.min.y,
30958
+ maxY: box.max.y,
30959
+ minZ: box.min.z,
30960
+ maxZ: box.max.z
30961
+ };
30962
+ }, [model]);
30963
+ useEffect33(() => {
30964
+ rootObject.add(model);
30965
+ return () => {
30966
+ rootObject.remove(model);
30967
+ };
30968
+ }, [rootObject, model]);
30969
+ useEffect33(() => {
30970
+ setHover(void 0);
30971
+ model.traverse((object) => {
30972
+ const id = object.userData.cad_component_id;
30973
+ if (typeof id === "string")
30974
+ object.visible = !hiddenCadComponentIds?.has(id);
30975
+ });
30976
+ }, [model, hiddenCadComponentIds]);
30977
+ useEffect33(() => {
30978
+ const meshes = [];
30979
+ model.traverse((mesh) => {
30980
+ if (!(mesh instanceof THREE58.Mesh)) return;
30981
+ let ancestor = mesh;
30982
+ while (ancestor) {
30983
+ if (!ancestor.visible) return;
30984
+ ancestor = ancestor.parent;
30985
+ }
30986
+ meshes.push(mesh);
30987
+ addHoverable({
30988
+ object: mesh,
30989
+ onHover: ({ mousePosition }) => {
30990
+ let object = mesh;
30991
+ let name;
30992
+ let visible = true;
30993
+ while (object) {
30994
+ name ??= getGlbComponentMetadata(object)?.componentName;
30995
+ visible &&= object.visible;
30996
+ object = object.parent;
30997
+ }
30998
+ setHover(
30999
+ name && visible ? { name, position: mousePosition } : void 0
31000
+ );
31001
+ },
31002
+ onUnhover: () => setHover(void 0)
31003
+ });
31004
+ });
31005
+ return () => {
31006
+ for (const mesh of meshes) removeHoverable(mesh);
31007
+ };
31008
+ }, [model, hiddenCadComponentIds, addHoverable, removeHoverable]);
31009
+ return /* @__PURE__ */ jsxs6(Fragment4, { children: [
31010
+ bounds && /* @__PURE__ */ jsx20(FitCameraToComparison, { bounds }),
31011
+ hover && /* @__PURE__ */ jsx20(
31012
+ Html,
31013
+ {
31014
+ position: hover.position,
31015
+ style: {
31016
+ background: "white",
31017
+ color: "black",
31018
+ padding: "5px",
31019
+ borderRadius: "3px",
31020
+ fontFamily: "sans-serif",
31021
+ transform: "translate(1rem, 1rem)"
31022
+ },
31023
+ children: hover.name
31024
+ }
31025
+ )
31026
+ ] });
31027
+ }
31028
+ function CadViewerGlb({
31029
+ source,
31030
+ hiddenCadComponentIds,
31031
+ ...containerProps
31032
+ }) {
31033
+ const result = useGlbModel(source);
31034
+ const framing = useMemo28(() => {
31035
+ if (!result?.model) return void 0;
31036
+ const bounds = new THREE58.Box3().setFromObject(result.model);
31037
+ if (bounds.isEmpty()) return void 0;
31038
+ return {
31039
+ boardDimensions: {
31040
+ width: bounds.max.x - bounds.min.x,
31041
+ height: bounds.max.y - bounds.min.y
31042
+ },
31043
+ boardCenter: {
31044
+ x: (bounds.min.x + bounds.max.x) / 2,
31045
+ y: (bounds.min.y + bounds.max.y) / 2
31046
+ }
31047
+ };
31048
+ }, [result, source]);
31049
+ if (!result) return /* @__PURE__ */ jsx20("div", { role: "status", children: "Loading 3D view..." });
31050
+ if (result.error)
31051
+ return /* @__PURE__ */ jsxs6("div", { role: "alert", children: [
31052
+ "Unable to load 3D view: ",
31053
+ result.error
31054
+ ] });
31055
+ if (!result.model) return null;
31056
+ return /* @__PURE__ */ jsx20(CadViewerContainer, { ...containerProps, ...framing, children: /* @__PURE__ */ jsx20(
31057
+ GlbScene,
31058
+ {
31059
+ model: result.model,
31060
+ hiddenCadComponentIds
31061
+ }
31062
+ ) });
31063
+ }
31064
+
31065
+ // node_modules/@radix-ui/react-dropdown-menu/dist/index.mjs
31066
+ import * as React42 from "react";
31067
+
31068
+ // node_modules/@radix-ui/primitive/dist/index.mjs
31069
+ var __defProp2 = Object.defineProperty;
31070
+ var __name = (target, value) => __defProp2(target, "name", { value, configurable: true });
31071
+ var canUseDOM = !!(typeof window !== "undefined" && window.document && window.document.createElement);
31072
+ function composeEventHandlers(originalEventHandler, ourEventHandler, { checkForDefaultPrevented = true } = {}) {
31073
+ return /* @__PURE__ */ __name(function handleEvent(event) {
31074
+ originalEventHandler?.(event);
31075
+ if (checkForDefaultPrevented === false || !event || !event.defaultPrevented) {
31076
+ return ourEventHandler?.(event);
31077
+ }
31078
+ }, "handleEvent");
31079
+ }
31080
+ __name(composeEventHandlers, "composeEventHandlers");
31081
+ function getOwnerWindow(element) {
31082
+ if (!canUseDOM) {
31083
+ throw new Error("Cannot access window outside of the DOM");
31084
+ }
31085
+ return element?.ownerDocument?.defaultView ?? window;
31086
+ }
31087
+ __name(getOwnerWindow, "getOwnerWindow");
31088
+ function getOwnerDocument(element) {
31089
+ if (!canUseDOM) {
31090
+ throw new Error("Cannot access document outside of the DOM");
31091
+ }
31092
+ return element?.ownerDocument ?? document;
31093
+ }
31094
+ __name(getOwnerDocument, "getOwnerDocument");
31095
+ function getActiveElement(node, activeDescendant = false) {
31096
+ const { activeElement } = getOwnerDocument(node);
31097
+ if (!activeElement?.nodeName) {
31098
+ return null;
31099
+ }
31100
+ if (isFrame(activeElement) && activeElement.contentDocument) {
31101
+ return getActiveElement(activeElement.contentDocument.body, activeDescendant);
31102
+ }
31103
+ if (activeDescendant) {
31104
+ const id = activeElement.getAttribute("aria-activedescendant");
31105
+ if (id) {
30864
31106
  const element = getOwnerDocument(activeElement).getElementById(id);
30865
31107
  if (element) {
30866
31108
  return element;
@@ -30919,7 +31161,7 @@ __name2(useComposedRefs, "useComposedRefs");
30919
31161
 
30920
31162
  // node_modules/@radix-ui/react-context/dist/index.mjs
30921
31163
  import * as React12 from "react";
30922
- import { jsx as jsx20 } from "react/jsx-runtime";
31164
+ import { jsx as jsx21 } from "react/jsx-runtime";
30923
31165
  var __defProp4 = Object.defineProperty;
30924
31166
  var __name3 = (target, value) => __defProp4(target, "name", { value, configurable: true });
30925
31167
  // @__NO_SIDE_EFFECTS__
@@ -30929,7 +31171,7 @@ function createContext22(rootComponentName, defaultContext) {
30929
31171
  const Provider = /* @__PURE__ */ __name3((props) => {
30930
31172
  const { children, ...context } = props;
30931
31173
  const value = React12.useMemo(() => context, Object.values(context));
30932
- return /* @__PURE__ */ jsx20(Context.Provider, { value, children });
31174
+ return /* @__PURE__ */ jsx21(Context.Provider, { value, children });
30933
31175
  }, "Provider");
30934
31176
  Provider.displayName = rootComponentName + "Provider";
30935
31177
  function useContext22(consumerName, options = {}) {
@@ -30956,7 +31198,7 @@ function createContextScope(scopeName, createContextScopeDeps = []) {
30956
31198
  const { scope, children, ...context } = props;
30957
31199
  const Context = scope?.[scopeName]?.[index2] || BaseContext;
30958
31200
  const value = React12.useMemo(() => context, Object.values(context));
30959
- return /* @__PURE__ */ jsx20(Context.Provider, { value, children });
31201
+ return /* @__PURE__ */ jsx21(Context.Provider, { value, children });
30960
31202
  }, "Provider");
30961
31203
  Provider.displayName = rootComponentName + "Provider";
30962
31204
  function useContext22(consumerName, scope, options = {}) {
@@ -31341,7 +31583,7 @@ var createSlottableError = /* @__PURE__ */ __name6((ownerName) => {
31341
31583
  var use = React16[" use ".trim().toString()];
31342
31584
 
31343
31585
  // node_modules/@radix-ui/react-primitive/dist/index.mjs
31344
- import { jsx as jsx21 } from "react/jsx-runtime";
31586
+ import { jsx as jsx22 } from "react/jsx-runtime";
31345
31587
  var __defProp8 = Object.defineProperty;
31346
31588
  var __name7 = (target, value) => __defProp8(target, "name", { value, configurable: true });
31347
31589
  var NODES = [
@@ -31371,7 +31613,7 @@ var Primitive = NODES.reduce((primitive, node) => {
31371
31613
  if (typeof window !== "undefined") {
31372
31614
  window[/* @__PURE__ */ Symbol.for("radix-ui")] = true;
31373
31615
  }
31374
- return /* @__PURE__ */ jsx21(Comp, { ...primitiveProps, ref: forwardedRef });
31616
+ return /* @__PURE__ */ jsx22(Comp, { ...primitiveProps, ref: forwardedRef });
31375
31617
  });
31376
31618
  Node2.displayName = `Primitive.${node}`;
31377
31619
  return { ...primitive, [node]: Node2 };
@@ -31386,9 +31628,9 @@ import * as React41 from "react";
31386
31628
 
31387
31629
  // node_modules/@radix-ui/react-collection/dist/index.mjs
31388
31630
  import * as React18 from "react";
31389
- import { jsx as jsx22 } from "react/jsx-runtime";
31390
- import * as React23 from "react";
31391
31631
  import { jsx as jsx23 } from "react/jsx-runtime";
31632
+ import * as React23 from "react";
31633
+ import { jsx as jsx24 } from "react/jsx-runtime";
31392
31634
  var __defProp9 = Object.defineProperty;
31393
31635
  var __name8 = (target, value) => __defProp9(target, "name", { value, configurable: true });
31394
31636
  // @__NO_SIDE_EFFECTS__
@@ -31403,7 +31645,7 @@ function createCollection(name) {
31403
31645
  const { scope, children } = props;
31404
31646
  const ref = React18.useRef(null);
31405
31647
  const itemMap = React18.useRef(/* @__PURE__ */ new Map()).current;
31406
- return /* @__PURE__ */ jsx22(CollectionProviderImpl, { scope, itemMap, collectionRef: ref, children });
31648
+ return /* @__PURE__ */ jsx23(CollectionProviderImpl, { scope, itemMap, collectionRef: ref, children });
31407
31649
  }, "CollectionProvider");
31408
31650
  CollectionProvider.displayName = PROVIDER_NAME;
31409
31651
  const COLLECTION_SLOT_NAME = name + "CollectionSlot";
@@ -31413,7 +31655,7 @@ function createCollection(name) {
31413
31655
  const { scope, children } = props;
31414
31656
  const context = useCollectionContext(COLLECTION_SLOT_NAME, scope);
31415
31657
  const composedRefs = useComposedRefs(forwardedRef, context.collectionRef);
31416
- return /* @__PURE__ */ jsx22(CollectionSlotImpl, { ref: composedRefs, children });
31658
+ return /* @__PURE__ */ jsx23(CollectionSlotImpl, { ref: composedRefs, children });
31417
31659
  }
31418
31660
  );
31419
31661
  CollectionSlot.displayName = COLLECTION_SLOT_NAME;
@@ -31430,7 +31672,7 @@ function createCollection(name) {
31430
31672
  context.itemMap.set(ref, { ref, ...itemData });
31431
31673
  return () => void context.itemMap.delete(ref);
31432
31674
  });
31433
- return /* @__PURE__ */ jsx22(CollectionItemSlotImpl, { ...{ [ITEM_DATA_ATTR]: "" }, ref: composedRefs, children });
31675
+ return /* @__PURE__ */ jsx23(CollectionItemSlotImpl, { ...{ [ITEM_DATA_ATTR]: "" }, ref: composedRefs, children });
31434
31676
  }
31435
31677
  );
31436
31678
  CollectionItemSlot.displayName = ITEM_SLOT_NAME;
@@ -31786,12 +32028,12 @@ function createCollection2(name) {
31786
32028
  const [CollectionStatefulContextProvider, useStatefulCollectionContext] = createCollectionContext(PROVIDER_NAME);
31787
32029
  CollectionStatefulContextProvider.displayName = name + "CollectionStatefulContextProvider";
31788
32030
  const CollectionProvider = /* @__PURE__ */ __name8(({ state, ...props }) => {
31789
- return state ? /* @__PURE__ */ jsx23(CollectionProviderImpl, { ...props, state }) : /* @__PURE__ */ jsx23(CollectionInit, { ...props });
32031
+ return state ? /* @__PURE__ */ jsx24(CollectionProviderImpl, { ...props, state }) : /* @__PURE__ */ jsx24(CollectionInit, { ...props });
31790
32032
  }, "CollectionProvider");
31791
32033
  CollectionProvider.displayName = PROVIDER_NAME;
31792
32034
  const CollectionInit = /* @__PURE__ */ __name8((props) => {
31793
32035
  const state = useInitCollection();
31794
- return /* @__PURE__ */ jsx23(CollectionProviderImpl, { ...props, state });
32036
+ return /* @__PURE__ */ jsx24(CollectionProviderImpl, { ...props, state });
31795
32037
  }, "CollectionInit");
31796
32038
  CollectionInit.displayName = name + "CollectionInit";
31797
32039
  const CollectionProviderImpl = /* @__PURE__ */ __name8((props) => {
@@ -31831,7 +32073,7 @@ function createCollection2(name) {
31831
32073
  observer.disconnect();
31832
32074
  };
31833
32075
  }, [collectionElement, setCollection]);
31834
- return /* @__PURE__ */ jsx23(
32076
+ return /* @__PURE__ */ jsx24(
31835
32077
  CollectionStableContextProvider,
31836
32078
  {
31837
32079
  scope,
@@ -31840,7 +32082,7 @@ function createCollection2(name) {
31840
32082
  getCollection,
31841
32083
  setCollection,
31842
32084
  registryRef,
31843
- children: /* @__PURE__ */ jsx23(
32085
+ children: /* @__PURE__ */ jsx24(
31844
32086
  CollectionStatefulContextProvider,
31845
32087
  {
31846
32088
  scope,
@@ -31860,7 +32102,7 @@ function createCollection2(name) {
31860
32102
  const { scope, children } = props;
31861
32103
  const context = useStableCollectionContext(COLLECTION_SLOT_NAME, scope);
31862
32104
  const composedRefs = useComposedRefs(forwardedRef, context.collectionElementRef);
31863
- return /* @__PURE__ */ jsx23(CollectionSlotImpl, { ref: composedRefs, children });
32105
+ return /* @__PURE__ */ jsx24(CollectionSlotImpl, { ref: composedRefs, children });
31864
32106
  }
31865
32107
  );
31866
32108
  CollectionSlot.displayName = COLLECTION_SLOT_NAME;
@@ -31936,7 +32178,7 @@ function createCollection2(name) {
31936
32178
  });
31937
32179
  };
31938
32180
  }, [setCollection]);
31939
- return /* @__PURE__ */ jsx23(CollectionItemSlotImpl, { ...{ [ITEM_DATA_ATTR]: "" }, ref: composedRefs, children });
32181
+ return /* @__PURE__ */ jsx24(CollectionItemSlotImpl, { ...{ [ITEM_DATA_ATTR]: "" }, ref: composedRefs, children });
31940
32182
  }
31941
32183
  );
31942
32184
  CollectionItemSlot.displayName = ITEM_SLOT_NAME;
@@ -32017,7 +32259,7 @@ __name8(getChildListObserver, "getChildListObserver");
32017
32259
 
32018
32260
  // node_modules/@radix-ui/react-direction/dist/index.mjs
32019
32261
  import * as React19 from "react";
32020
- import { jsx as jsx24 } from "react/jsx-runtime";
32262
+ import { jsx as jsx25 } from "react/jsx-runtime";
32021
32263
  var __defProp10 = Object.defineProperty;
32022
32264
  var __name9 = (target, value) => __defProp10(target, "name", { value, configurable: true });
32023
32265
  var Direction = {
@@ -32055,7 +32297,7 @@ function useCallbackRef(callback) {
32055
32297
  __name10(useCallbackRef, "useCallbackRef");
32056
32298
 
32057
32299
  // node_modules/@radix-ui/react-dismissable-layer/dist/index.mjs
32058
- import { jsx as jsx25 } from "react/jsx-runtime";
32300
+ import { jsx as jsx26 } from "react/jsx-runtime";
32059
32301
  var __defProp12 = Object.defineProperty;
32060
32302
  var __name11 = (target, value) => __defProp12(target, "name", { value, configurable: true });
32061
32303
  var CONTEXT_UPDATE = "dismissableLayer.update";
@@ -32187,7 +32429,7 @@ var DismissableLayer = /* @__PURE__ */ React21.forwardRef(
32187
32429
  document.addEventListener(CONTEXT_UPDATE, handleUpdate);
32188
32430
  return () => document.removeEventListener(CONTEXT_UPDATE, handleUpdate);
32189
32431
  }, []);
32190
- return /* @__PURE__ */ jsx25(
32432
+ return /* @__PURE__ */ jsx26(
32191
32433
  Primitive.div,
32192
32434
  {
32193
32435
  ...layerProps,
@@ -32436,7 +32678,7 @@ __name12(createFocusGuard, "createFocusGuard");
32436
32678
 
32437
32679
  // node_modules/@radix-ui/react-focus-scope/dist/index.mjs
32438
32680
  import * as React25 from "react";
32439
- import { jsx as jsx26 } from "react/jsx-runtime";
32681
+ import { jsx as jsx27 } from "react/jsx-runtime";
32440
32682
  var __defProp14 = Object.defineProperty;
32441
32683
  var __name13 = (target, value) => __defProp14(target, "name", { value, configurable: true });
32442
32684
  var AUTOFOCUS_ON_MOUNT = "focusScope.autoFocusOnMount";
@@ -32575,7 +32817,7 @@ var FocusScope = /* @__PURE__ */ React25.forwardRef(
32575
32817
  },
32576
32818
  [loop, trapped, focusScope.paused]
32577
32819
  );
32578
- return /* @__PURE__ */ jsx26(Primitive.div, { tabIndex: -1, ...scopeProps, ref: composedRefs, onKeyDown: handleKeyDown });
32820
+ return /* @__PURE__ */ jsx27(Primitive.div, { tabIndex: -1, ...scopeProps, ref: composedRefs, onKeyDown: handleKeyDown });
32579
32821
  }, "FocusScope")
32580
32822
  );
32581
32823
  var FocusScopeBranchContext = React25.createContext(null);
@@ -32583,7 +32825,7 @@ function FocusScopeBranchProvider({ registry, children }) {
32583
32825
  if (!registry) {
32584
32826
  return children;
32585
32827
  }
32586
- return /* @__PURE__ */ jsx26(FocusScopeBranchContext.Provider, { value: registry, children });
32828
+ return /* @__PURE__ */ jsx27(FocusScopeBranchContext.Provider, { value: registry, children });
32587
32829
  }
32588
32830
  __name13(FocusScopeBranchProvider, "FocusScopeBranchProvider");
32589
32831
  function useFocusScopeBranchRegistry() {
@@ -34676,7 +34918,7 @@ function useSize(element) {
34676
34918
  __name15(useSize, "useSize");
34677
34919
 
34678
34920
  // node_modules/@radix-ui/react-popper/dist/index.mjs
34679
- import { jsx as jsx27 } from "react/jsx-runtime";
34921
+ import { jsx as jsx28 } from "react/jsx-runtime";
34680
34922
  var __defProp17 = Object.defineProperty;
34681
34923
  var __name16 = (target, value) => __defProp17(target, "name", { value, configurable: true });
34682
34924
  var Sticky = {
@@ -34694,7 +34936,7 @@ var Popper = /* @__PURE__ */ __name16((props) => {
34694
34936
  const { __scopePopper, children } = props;
34695
34937
  const [anchor, setAnchor] = React29.useState(null);
34696
34938
  const [placementState, setPlacementState] = React29.useState(void 0);
34697
- return /* @__PURE__ */ jsx27(
34939
+ return /* @__PURE__ */ jsx28(
34698
34940
  PopperProvider,
34699
34941
  {
34700
34942
  scope: __scopePopper,
@@ -34737,7 +34979,7 @@ var PopperAnchor = /* @__PURE__ */ React29.forwardRef(
34737
34979
  const sideAndAlign = context.placementState && getSideAndAlignFromPlacement(context.placementState);
34738
34980
  const placedSide = sideAndAlign?.[0];
34739
34981
  const placedAlign = sideAndAlign?.[1];
34740
- return virtualRef ? null : /* @__PURE__ */ jsx27(
34982
+ return virtualRef ? null : /* @__PURE__ */ jsx28(
34741
34983
  Primitive.div,
34742
34984
  {
34743
34985
  "data-radix-popper-side": placedSide,
@@ -34861,7 +35103,7 @@ var PopperContent = /* @__PURE__ */ React29.forwardRef(
34861
35103
  useLayoutEffect2(() => {
34862
35104
  if (content) setContentZIndex(window.getComputedStyle(content).zIndex);
34863
35105
  }, [content]);
34864
- return /* @__PURE__ */ jsx27(
35106
+ return /* @__PURE__ */ jsx28(
34865
35107
  "div",
34866
35108
  {
34867
35109
  ref: refs.setFloating,
@@ -34885,7 +35127,7 @@ var PopperContent = /* @__PURE__ */ React29.forwardRef(
34885
35127
  }
34886
35128
  },
34887
35129
  dir: props.dir,
34888
- children: /* @__PURE__ */ jsx27(
35130
+ children: /* @__PURE__ */ jsx28(
34889
35131
  PopperContentProvider,
34890
35132
  {
34891
35133
  scope: __scopePopper,
@@ -34895,7 +35137,7 @@ var PopperContent = /* @__PURE__ */ React29.forwardRef(
34895
35137
  arrowX,
34896
35138
  arrowY,
34897
35139
  shouldHideArrow: cannotCenterArrow,
34898
- children: /* @__PURE__ */ jsx27(
35140
+ children: /* @__PURE__ */ jsx28(
34899
35141
  Primitive.div,
34900
35142
  {
34901
35143
  "data-side": placedSide,
@@ -34961,7 +35203,7 @@ __name16(getSideAndAlignFromPlacement, "getSideAndAlignFromPlacement");
34961
35203
  // node_modules/@radix-ui/react-portal/dist/index.mjs
34962
35204
  import * as React30 from "react";
34963
35205
  import * as ReactDOM4 from "react-dom";
34964
- import { jsx as jsx28 } from "react/jsx-runtime";
35206
+ import { jsx as jsx29 } from "react/jsx-runtime";
34965
35207
  var __defProp18 = Object.defineProperty;
34966
35208
  var __name17 = (target, value) => __defProp18(target, "name", { value, configurable: true });
34967
35209
  var Portal = /* @__PURE__ */ React30.forwardRef(
@@ -34970,7 +35212,7 @@ var Portal = /* @__PURE__ */ React30.forwardRef(
34970
35212
  const [mounted, setMounted] = React30.useState(false);
34971
35213
  useLayoutEffect2(() => setMounted(true), []);
34972
35214
  const container = containerProp || mounted && globalThis?.document?.body;
34973
- return container ? ReactDOM4.createPortal(/* @__PURE__ */ jsx28(Primitive.div, { ...portalProps, ref: forwardedRef }), container) : null;
35215
+ return container ? ReactDOM4.createPortal(/* @__PURE__ */ jsx29(Primitive.div, { ...portalProps, ref: forwardedRef }), container) : null;
34974
35216
  }, "Portal")
34975
35217
  );
34976
35218
 
@@ -35190,7 +35432,7 @@ __name19(useIsHydratedModern, "useIsHydratedModern");
35190
35432
  var useIsHydrated2 = typeof useReactSyncExternalStore === "function" ? useIsHydratedModern : useIsHydrated;
35191
35433
 
35192
35434
  // node_modules/@radix-ui/react-roving-focus/dist/index.mjs
35193
- import { jsx as jsx29 } from "react/jsx-runtime";
35435
+ import { jsx as jsx30 } from "react/jsx-runtime";
35194
35436
  var __defProp21 = Object.defineProperty;
35195
35437
  var __name20 = (target, value) => __defProp21(target, "name", { value, configurable: true });
35196
35438
  var ENTRY_FOCUS = "rovingFocusGroup.onEntryFocus";
@@ -35213,7 +35455,7 @@ var [RovingFocusProvider, useRovingFocusContext] = createRovingFocusGroupContext
35213
35455
  var RovingFocusGroup = /* @__PURE__ */ React33.forwardRef(
35214
35456
  // blank line to reduce diff noise
35215
35457
  /* @__PURE__ */ __name20(function RovingFocusGroup2(props, forwardedRef) {
35216
- return /* @__PURE__ */ jsx29(Collection.Provider, { scope: props.__scopeRovingFocusGroup, children: /* @__PURE__ */ jsx29(Collection.Slot, { scope: props.__scopeRovingFocusGroup, children: /* @__PURE__ */ jsx29(RovingFocusGroupImpl, { ...props, ref: forwardedRef }) }) });
35458
+ return /* @__PURE__ */ jsx30(Collection.Provider, { scope: props.__scopeRovingFocusGroup, children: /* @__PURE__ */ jsx30(Collection.Slot, { scope: props.__scopeRovingFocusGroup, children: /* @__PURE__ */ jsx30(RovingFocusGroupImpl, { ...props, ref: forwardedRef }) }) });
35217
35459
  }, "RovingFocusGroup")
35218
35460
  );
35219
35461
  var RovingFocusGroupImpl = /* @__PURE__ */ React33.forwardRef(/* @__PURE__ */ __name20(function RovingFocusGroupImpl2(props, forwardedRef) {
@@ -35250,7 +35492,7 @@ var RovingFocusGroupImpl = /* @__PURE__ */ React33.forwardRef(/* @__PURE__ */ __
35250
35492
  return () => node.removeEventListener(ENTRY_FOCUS, handleEntryFocus);
35251
35493
  }
35252
35494
  }, [handleEntryFocus]);
35253
- return /* @__PURE__ */ jsx29(
35495
+ return /* @__PURE__ */ jsx30(
35254
35496
  RovingFocusProvider,
35255
35497
  {
35256
35498
  scope: __scopeRovingFocusGroup,
@@ -35271,7 +35513,7 @@ var RovingFocusGroupImpl = /* @__PURE__ */ React33.forwardRef(/* @__PURE__ */ __
35271
35513
  () => setFocusableItemsCount((prevCount) => prevCount - 1),
35272
35514
  []
35273
35515
  ),
35274
- children: /* @__PURE__ */ jsx29(
35516
+ children: /* @__PURE__ */ jsx30(
35275
35517
  Primitive.div,
35276
35518
  {
35277
35519
  tabIndex: isTabbingBackOut || focusableItemsCount === 0 ? -1 : 0,
@@ -35339,14 +35581,14 @@ var RovingFocusGroupItem = /* @__PURE__ */ React33.forwardRef(
35339
35581
  onFocusableItemAdd();
35340
35582
  return () => onFocusableItemRemove();
35341
35583
  }, [isHydrated, focusable, onFocusableItemAdd, onFocusableItemRemove]);
35342
- return /* @__PURE__ */ jsx29(
35584
+ return /* @__PURE__ */ jsx30(
35343
35585
  Collection.ItemSlot,
35344
35586
  {
35345
35587
  scope: __scopeRovingFocusGroup,
35346
35588
  id,
35347
35589
  focusable,
35348
35590
  active,
35349
- children: /* @__PURE__ */ jsx29(
35591
+ children: /* @__PURE__ */ jsx30(
35350
35592
  Primitive.span,
35351
35593
  {
35352
35594
  tabIndex: isCurrentTabStop ? 0 : -1,
@@ -35602,9 +35844,9 @@ function assignRef(ref, value) {
35602
35844
  }
35603
35845
 
35604
35846
  // node_modules/use-callback-ref/dist/es2015/useRef.js
35605
- import { useState as useState32 } from "react";
35847
+ import { useState as useState34 } from "react";
35606
35848
  function useCallbackRef2(initialValue, callback) {
35607
- var ref = useState32(function() {
35849
+ var ref = useState34(function() {
35608
35850
  return {
35609
35851
  // value
35610
35852
  value: initialValue,
@@ -36268,7 +36510,7 @@ ReactRemoveScroll.classNames = RemoveScroll.classNames;
36268
36510
  var Combination_default = ReactRemoveScroll;
36269
36511
 
36270
36512
  // node_modules/@radix-ui/react-menu/dist/index.mjs
36271
- import { jsx as jsx30 } from "react/jsx-runtime";
36513
+ import { jsx as jsx31 } from "react/jsx-runtime";
36272
36514
  var __defProp22 = Object.defineProperty;
36273
36515
  var __name21 = (target, value) => __defProp22(target, "name", { value, configurable: true });
36274
36516
  var Direction3 = {
@@ -36327,7 +36569,7 @@ var Menu = /* @__PURE__ */ __name21((props) => {
36327
36569
  window.addEventListener("blur", handleBlur);
36328
36570
  return () => window.removeEventListener("blur", handleBlur);
36329
36571
  }, [open, handleOpenChange]);
36330
- return /* @__PURE__ */ jsx30(Popper, { ...popperScope, children: /* @__PURE__ */ jsx30(
36572
+ return /* @__PURE__ */ jsx31(Popper, { ...popperScope, children: /* @__PURE__ */ jsx31(
36331
36573
  MenuProvider,
36332
36574
  {
36333
36575
  scope: __scopeMenu,
@@ -36335,7 +36577,7 @@ var Menu = /* @__PURE__ */ __name21((props) => {
36335
36577
  onOpenChange: handleOpenChange,
36336
36578
  content,
36337
36579
  onContentChange: setContent,
36338
- children: /* @__PURE__ */ jsx30(
36580
+ children: /* @__PURE__ */ jsx31(
36339
36581
  MenuRootProvider,
36340
36582
  {
36341
36583
  scope: __scopeMenu,
@@ -36353,7 +36595,7 @@ var MenuAnchor = /* @__PURE__ */ React41.forwardRef(
36353
36595
  /* @__PURE__ */ __name21(function MenuAnchor2(props, forwardedRef) {
36354
36596
  const { __scopeMenu, ...anchorProps } = props;
36355
36597
  const popperScope = usePopperScope(__scopeMenu);
36356
- return /* @__PURE__ */ jsx30(PopperAnchor, { ...popperScope, ...anchorProps, ref: forwardedRef });
36598
+ return /* @__PURE__ */ jsx31(PopperAnchor, { ...popperScope, ...anchorProps, ref: forwardedRef });
36357
36599
  }, "MenuAnchor")
36358
36600
  );
36359
36601
  var PORTAL_NAME = "MenuPortal";
@@ -36363,7 +36605,7 @@ var [PortalProvider, usePortalContext] = createMenuContext(PORTAL_NAME, {
36363
36605
  var MenuPortal = /* @__PURE__ */ __name21((props) => {
36364
36606
  const { __scopeMenu, forceMount, children, container } = props;
36365
36607
  const context = useMenuContext(PORTAL_NAME, __scopeMenu);
36366
- return /* @__PURE__ */ jsx30(PortalProvider, { scope: __scopeMenu, forceMount, children: /* @__PURE__ */ jsx30(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx30(Portal, { asChild: true, container, children }) }) });
36608
+ return /* @__PURE__ */ jsx31(PortalProvider, { scope: __scopeMenu, forceMount, children: /* @__PURE__ */ jsx31(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx31(Portal, { asChild: true, container, children }) }) });
36367
36609
  }, "MenuPortal");
36368
36610
  var CONTENT_NAME2 = "MenuContent";
36369
36611
  var [MenuContentProvider, useMenuContentContext] = createMenuContext(CONTENT_NAME2);
@@ -36373,7 +36615,7 @@ var MenuContent = /* @__PURE__ */ React41.forwardRef(
36373
36615
  const { forceMount = portalContext.forceMount, ...contentProps } = props;
36374
36616
  const context = useMenuContext(CONTENT_NAME2, props.__scopeMenu);
36375
36617
  const rootContext = useMenuRootContext(CONTENT_NAME2, props.__scopeMenu);
36376
- return /* @__PURE__ */ jsx30(Collection2.Provider, { scope: props.__scopeMenu, children: /* @__PURE__ */ jsx30(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx30(Collection2.Slot, { scope: props.__scopeMenu, children: rootContext.modal ? /* @__PURE__ */ jsx30(MenuRootContentModal, { ...contentProps, ref: forwardedRef }) : /* @__PURE__ */ jsx30(MenuRootContentNonModal, { ...contentProps, ref: forwardedRef }) }) }) });
36618
+ return /* @__PURE__ */ jsx31(Collection2.Provider, { scope: props.__scopeMenu, children: /* @__PURE__ */ jsx31(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx31(Collection2.Slot, { scope: props.__scopeMenu, children: rootContext.modal ? /* @__PURE__ */ jsx31(MenuRootContentModal, { ...contentProps, ref: forwardedRef }) : /* @__PURE__ */ jsx31(MenuRootContentNonModal, { ...contentProps, ref: forwardedRef }) }) }) });
36377
36619
  }, "MenuContent")
36378
36620
  );
36379
36621
  var MenuRootContentModal = /* @__PURE__ */ React41.forwardRef(
@@ -36386,7 +36628,7 @@ var MenuRootContentModal = /* @__PURE__ */ React41.forwardRef(
36386
36628
  const content = ref.current;
36387
36629
  if (content) return hideOthers(content);
36388
36630
  }, []);
36389
- return /* @__PURE__ */ jsx30(
36631
+ return /* @__PURE__ */ jsx31(
36390
36632
  MenuContentImpl,
36391
36633
  {
36392
36634
  ...props,
@@ -36406,7 +36648,7 @@ var MenuRootContentModal = /* @__PURE__ */ React41.forwardRef(
36406
36648
  );
36407
36649
  var MenuRootContentNonModal = /* @__PURE__ */ React41.forwardRef(/* @__PURE__ */ __name21(function MenuRootContentNonModal2(props, forwardedRef) {
36408
36650
  const context = useMenuContext(CONTENT_NAME2, props.__scopeMenu);
36409
- return /* @__PURE__ */ jsx30(
36651
+ return /* @__PURE__ */ jsx31(
36410
36652
  MenuContentImpl,
36411
36653
  {
36412
36654
  ...props,
@@ -36498,7 +36740,7 @@ var MenuContentImpl = /* @__PURE__ */ React41.forwardRef(
36498
36740
  const isMovingTowards = pointerDirRef.current === pointerGraceIntentRef.current?.side;
36499
36741
  return isMovingTowards && isPointerInGraceArea(event, pointerGraceIntentRef.current?.area);
36500
36742
  }, []);
36501
- return /* @__PURE__ */ jsx30(
36743
+ return /* @__PURE__ */ jsx31(
36502
36744
  MenuContentProvider,
36503
36745
  {
36504
36746
  scope: __scopeMenu,
@@ -36527,7 +36769,7 @@ var MenuContentImpl = /* @__PURE__ */ React41.forwardRef(
36527
36769
  onPointerGraceIntentChange: React41.useCallback((intent) => {
36528
36770
  pointerGraceIntentRef.current = intent;
36529
36771
  }, []),
36530
- children: /* @__PURE__ */ jsx30(FocusScopeBranchProvider, { registry: isModal ? branchRegistry : null, children: /* @__PURE__ */ jsx30(ScrollLockWrapper, { ...scrollLockWrapperProps, children: /* @__PURE__ */ jsx30(
36772
+ children: /* @__PURE__ */ jsx31(FocusScopeBranchProvider, { registry: isModal ? branchRegistry : null, children: /* @__PURE__ */ jsx31(ScrollLockWrapper, { ...scrollLockWrapperProps, children: /* @__PURE__ */ jsx31(
36531
36773
  FocusScope,
36532
36774
  {
36533
36775
  asChild: true,
@@ -36538,7 +36780,7 @@ var MenuContentImpl = /* @__PURE__ */ React41.forwardRef(
36538
36780
  contentRef.current?.focus({ preventScroll: true });
36539
36781
  }),
36540
36782
  onUnmountAutoFocus: onCloseAutoFocus,
36541
- children: /* @__PURE__ */ jsx30(
36783
+ children: /* @__PURE__ */ jsx31(
36542
36784
  DismissableLayer,
36543
36785
  {
36544
36786
  asChild: true,
@@ -36548,7 +36790,7 @@ var MenuContentImpl = /* @__PURE__ */ React41.forwardRef(
36548
36790
  onFocusOutside,
36549
36791
  onInteractOutside,
36550
36792
  onDismiss,
36551
- children: /* @__PURE__ */ jsx30(
36793
+ children: /* @__PURE__ */ jsx31(
36552
36794
  RovingFocusGroup,
36553
36795
  {
36554
36796
  asChild: true,
@@ -36562,7 +36804,7 @@ var MenuContentImpl = /* @__PURE__ */ React41.forwardRef(
36562
36804
  if (!rootContext.isUsingKeyboardRef.current) event.preventDefault();
36563
36805
  }),
36564
36806
  preventScrollOnEntryFocus: true,
36565
- children: /* @__PURE__ */ jsx30(
36807
+ children: /* @__PURE__ */ jsx31(
36566
36808
  PopperContent,
36567
36809
  {
36568
36810
  role: "menu",
@@ -36646,7 +36888,7 @@ var MenuItem = /* @__PURE__ */ React41.forwardRef(
36646
36888
  }
36647
36889
  }
36648
36890
  }, "handleSelect");
36649
- return /* @__PURE__ */ jsx30(
36891
+ return /* @__PURE__ */ jsx31(
36650
36892
  MenuItemImpl,
36651
36893
  {
36652
36894
  ...itemProps,
@@ -36692,13 +36934,13 @@ var MenuItemImpl = /* @__PURE__ */ React41.forwardRef(
36692
36934
  setTextContent((menuItem.textContent ?? "").trim());
36693
36935
  }
36694
36936
  }, [itemProps.children]);
36695
- return /* @__PURE__ */ jsx30(
36937
+ return /* @__PURE__ */ jsx31(
36696
36938
  Collection2.ItemSlot,
36697
36939
  {
36698
36940
  scope: __scopeMenu,
36699
36941
  disabled,
36700
36942
  textValue: textValue ?? textContent,
36701
- children: /* @__PURE__ */ jsx30(RovingFocusGroupItem, { asChild: true, ...rovingFocusGroupScope, focusable: !disabled, children: /* @__PURE__ */ jsx30(
36943
+ children: /* @__PURE__ */ jsx31(RovingFocusGroupItem, { asChild: true, ...rovingFocusGroupScope, focusable: !disabled, children: /* @__PURE__ */ jsx31(
36702
36944
  Primitive.div,
36703
36945
  {
36704
36946
  role: "menuitem",
@@ -36737,7 +36979,7 @@ var MenuCheckboxItem = /* @__PURE__ */ React41.forwardRef(
36737
36979
  // blank line to reduce diff noise
36738
36980
  /* @__PURE__ */ __name21(function MenuCheckboxItem2(props, forwardedRef) {
36739
36981
  const { checked = false, onCheckedChange, ...checkboxItemProps } = props;
36740
- return /* @__PURE__ */ jsx30(ItemIndicatorProvider, { scope: props.__scopeMenu, checked, children: /* @__PURE__ */ jsx30(
36982
+ return /* @__PURE__ */ jsx31(ItemIndicatorProvider, { scope: props.__scopeMenu, checked, children: /* @__PURE__ */ jsx31(
36741
36983
  MenuItem,
36742
36984
  {
36743
36985
  role: "menuitemcheckbox",
@@ -36768,7 +37010,7 @@ var [ItemIndicatorProvider, useItemIndicatorContext] = createMenuContext(
36768
37010
  var MenuSeparator = /* @__PURE__ */ React41.forwardRef(
36769
37011
  /* @__PURE__ */ __name21(function MenuSeparator2(props, forwardedRef) {
36770
37012
  const { __scopeMenu, ...separatorProps } = props;
36771
- return /* @__PURE__ */ jsx30(
37013
+ return /* @__PURE__ */ jsx31(
36772
37014
  Primitive.div,
36773
37015
  {
36774
37016
  role: "separator",
@@ -36792,7 +37034,7 @@ var MenuSub = /* @__PURE__ */ __name21((props) => {
36792
37034
  if (parentMenuContext.open === false) handleOpenChange(false);
36793
37035
  return () => handleOpenChange(false);
36794
37036
  }, [parentMenuContext.open, handleOpenChange]);
36795
- return /* @__PURE__ */ jsx30(Popper, { ...popperScope, children: /* @__PURE__ */ jsx30(
37037
+ return /* @__PURE__ */ jsx31(Popper, { ...popperScope, children: /* @__PURE__ */ jsx31(
36796
37038
  MenuProvider,
36797
37039
  {
36798
37040
  scope: __scopeMenu,
@@ -36800,7 +37042,7 @@ var MenuSub = /* @__PURE__ */ __name21((props) => {
36800
37042
  onOpenChange: handleOpenChange,
36801
37043
  content,
36802
37044
  onContentChange: setContent,
36803
- children: /* @__PURE__ */ jsx30(
37045
+ children: /* @__PURE__ */ jsx31(
36804
37046
  MenuSubProvider,
36805
37047
  {
36806
37048
  scope: __scopeMenu,
@@ -36837,7 +37079,7 @@ var MenuSubTrigger = /* @__PURE__ */ React41.forwardRef(
36837
37079
  };
36838
37080
  }, [pointerGraceTimerRef, onPointerGraceIntentChange]);
36839
37081
  const composedRefs = useComposedRefs(forwardedRef, subContext.onTriggerChange);
36840
- return /* @__PURE__ */ jsx30(MenuAnchor, { asChild: true, ...scope, children: /* @__PURE__ */ jsx30(
37082
+ return /* @__PURE__ */ jsx31(MenuAnchor, { asChild: true, ...scope, children: /* @__PURE__ */ jsx31(
36841
37083
  MenuItemImpl,
36842
37084
  {
36843
37085
  id: subContext.triggerId,
@@ -36930,7 +37172,7 @@ var MenuSubContent = /* @__PURE__ */ React41.forwardRef(
36930
37172
  const subContext = useMenuSubContext(SUB_CONTENT_NAME, props.__scopeMenu);
36931
37173
  const ref = React41.useRef(null);
36932
37174
  const composedRefs = useComposedRefs(forwardedRef, ref);
36933
- return /* @__PURE__ */ jsx30(Collection2.Provider, { scope: props.__scopeMenu, children: /* @__PURE__ */ jsx30(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx30(Collection2.Slot, { scope: props.__scopeMenu, children: /* @__PURE__ */ jsx30(
37175
+ return /* @__PURE__ */ jsx31(Collection2.Provider, { scope: props.__scopeMenu, children: /* @__PURE__ */ jsx31(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx31(Collection2.Slot, { scope: props.__scopeMenu, children: /* @__PURE__ */ jsx31(
36934
37176
  MenuContentImpl,
36935
37177
  {
36936
37178
  id: subContext.contentId,
@@ -37033,7 +37275,7 @@ function whenMouse(handler) {
37033
37275
  __name21(whenMouse, "whenMouse");
37034
37276
 
37035
37277
  // node_modules/@radix-ui/react-dropdown-menu/dist/index.mjs
37036
- import { jsx as jsx31 } from "react/jsx-runtime";
37278
+ import { jsx as jsx32 } from "react/jsx-runtime";
37037
37279
  var __defProp23 = Object.defineProperty;
37038
37280
  var __name22 = (target, value) => __defProp23(target, "name", { value, configurable: true });
37039
37281
  var DROPDOWN_MENU_NAME = "DropdownMenu";
@@ -37061,7 +37303,7 @@ var DropdownMenu = /* @__PURE__ */ __name22((props) => {
37061
37303
  onChange: onOpenChange,
37062
37304
  caller: DROPDOWN_MENU_NAME
37063
37305
  });
37064
- return /* @__PURE__ */ jsx31(
37306
+ return /* @__PURE__ */ jsx32(
37065
37307
  DropdownMenuProvider,
37066
37308
  {
37067
37309
  scope: __scopeDropdownMenu,
@@ -37072,7 +37314,7 @@ var DropdownMenu = /* @__PURE__ */ __name22((props) => {
37072
37314
  onOpenChange: setOpen,
37073
37315
  onOpenToggle: React42.useCallback(() => setOpen((prevOpen) => !prevOpen), [setOpen]),
37074
37316
  modal,
37075
- children: /* @__PURE__ */ jsx31(Menu, { ...menuScope, open, onOpenChange: setOpen, dir, modal, children })
37317
+ children: /* @__PURE__ */ jsx32(Menu, { ...menuScope, open, onOpenChange: setOpen, dir, modal, children })
37076
37318
  }
37077
37319
  );
37078
37320
  }, "DropdownMenu");
@@ -37084,7 +37326,7 @@ var DropdownMenuTrigger = /* @__PURE__ */ React42.forwardRef(
37084
37326
  const context = useDropdownMenuContext(TRIGGER_NAME, __scopeDropdownMenu);
37085
37327
  const menuScope = useMenuScope(__scopeDropdownMenu);
37086
37328
  const composedRefs = useComposedRefs(forwardedRef, context.triggerRef);
37087
- return /* @__PURE__ */ jsx31(MenuAnchor, { asChild: true, ...menuScope, children: /* @__PURE__ */ jsx31(
37329
+ return /* @__PURE__ */ jsx32(MenuAnchor, { asChild: true, ...menuScope, children: /* @__PURE__ */ jsx32(
37088
37330
  Primitive.button,
37089
37331
  {
37090
37332
  type: "button",
@@ -37116,7 +37358,7 @@ var DropdownMenuTrigger = /* @__PURE__ */ React42.forwardRef(
37116
37358
  var DropdownMenuPortal = /* @__PURE__ */ __name22((props) => {
37117
37359
  const { __scopeDropdownMenu, ...portalProps } = props;
37118
37360
  const menuScope = useMenuScope(__scopeDropdownMenu);
37119
- return /* @__PURE__ */ jsx31(MenuPortal, { ...menuScope, ...portalProps });
37361
+ return /* @__PURE__ */ jsx32(MenuPortal, { ...menuScope, ...portalProps });
37120
37362
  }, "DropdownMenuPortal");
37121
37363
  var CONTENT_NAME3 = "DropdownMenuContent";
37122
37364
  var DropdownMenuContent = /* @__PURE__ */ React42.forwardRef(
@@ -37126,7 +37368,7 @@ var DropdownMenuContent = /* @__PURE__ */ React42.forwardRef(
37126
37368
  const context = useDropdownMenuContext(CONTENT_NAME3, __scopeDropdownMenu);
37127
37369
  const menuScope = useMenuScope(__scopeDropdownMenu);
37128
37370
  const hasInteractedOutsideRef = React42.useRef(false);
37129
- return /* @__PURE__ */ jsx31(
37371
+ return /* @__PURE__ */ jsx32(
37130
37372
  MenuContent,
37131
37373
  {
37132
37374
  id: context.contentId,
@@ -37165,18 +37407,18 @@ var DropdownMenuItem = /* @__PURE__ */ React42.forwardRef(
37165
37407
  /* @__PURE__ */ __name22(function DropdownMenuItem2(props, forwardedRef) {
37166
37408
  const { __scopeDropdownMenu, ...itemProps } = props;
37167
37409
  const menuScope = useMenuScope(__scopeDropdownMenu);
37168
- return /* @__PURE__ */ jsx31(MenuItem, { ...menuScope, ...itemProps, ref: forwardedRef });
37410
+ return /* @__PURE__ */ jsx32(MenuItem, { ...menuScope, ...itemProps, ref: forwardedRef });
37169
37411
  }, "DropdownMenuItem")
37170
37412
  );
37171
37413
  var DropdownMenuCheckboxItem = /* @__PURE__ */ React42.forwardRef(/* @__PURE__ */ __name22(function DropdownMenuCheckboxItem2(props, forwardedRef) {
37172
37414
  const { __scopeDropdownMenu, ...checkboxItemProps } = props;
37173
37415
  const menuScope = useMenuScope(__scopeDropdownMenu);
37174
- return /* @__PURE__ */ jsx31(MenuCheckboxItem, { ...menuScope, ...checkboxItemProps, ref: forwardedRef });
37416
+ return /* @__PURE__ */ jsx32(MenuCheckboxItem, { ...menuScope, ...checkboxItemProps, ref: forwardedRef });
37175
37417
  }, "DropdownMenuCheckboxItem"));
37176
37418
  var DropdownMenuSeparator = /* @__PURE__ */ React42.forwardRef(/* @__PURE__ */ __name22(function DropdownMenuSeparator2(props, forwardedRef) {
37177
37419
  const { __scopeDropdownMenu, ...separatorProps } = props;
37178
37420
  const menuScope = useMenuScope(__scopeDropdownMenu);
37179
- return /* @__PURE__ */ jsx31(MenuSeparator, { ...menuScope, ...separatorProps, ref: forwardedRef });
37421
+ return /* @__PURE__ */ jsx32(MenuSeparator, { ...menuScope, ...separatorProps, ref: forwardedRef });
37180
37422
  }, "DropdownMenuSeparator"));
37181
37423
  var DropdownMenuSub = /* @__PURE__ */ __name22((props) => {
37182
37424
  const { __scopeDropdownMenu, children, open: openProp, onOpenChange, defaultOpen } = props;
@@ -37187,17 +37429,17 @@ var DropdownMenuSub = /* @__PURE__ */ __name22((props) => {
37187
37429
  onChange: onOpenChange,
37188
37430
  caller: "DropdownMenuSub"
37189
37431
  });
37190
- return /* @__PURE__ */ jsx31(MenuSub, { ...menuScope, open, onOpenChange: setOpen, children });
37432
+ return /* @__PURE__ */ jsx32(MenuSub, { ...menuScope, open, onOpenChange: setOpen, children });
37191
37433
  }, "DropdownMenuSub");
37192
37434
  var DropdownMenuSubTrigger = /* @__PURE__ */ React42.forwardRef(/* @__PURE__ */ __name22(function DropdownMenuSubTrigger2(props, forwardedRef) {
37193
37435
  const { __scopeDropdownMenu, ...subTriggerProps } = props;
37194
37436
  const menuScope = useMenuScope(__scopeDropdownMenu);
37195
- return /* @__PURE__ */ jsx31(MenuSubTrigger, { ...menuScope, ...subTriggerProps, ref: forwardedRef });
37437
+ return /* @__PURE__ */ jsx32(MenuSubTrigger, { ...menuScope, ...subTriggerProps, ref: forwardedRef });
37196
37438
  }, "DropdownMenuSubTrigger"));
37197
37439
  var DropdownMenuSubContent = /* @__PURE__ */ React42.forwardRef(/* @__PURE__ */ __name22(function DropdownMenuSubContent2(props, forwardedRef) {
37198
37440
  const { __scopeDropdownMenu, ...subContentProps } = props;
37199
37441
  const menuScope = useMenuScope(__scopeDropdownMenu);
37200
- return /* @__PURE__ */ jsx31(
37442
+ return /* @__PURE__ */ jsx32(
37201
37443
  MenuSubContent,
37202
37444
  {
37203
37445
  ...menuScope,
@@ -37219,11 +37461,11 @@ var DropdownMenuSubContent = /* @__PURE__ */ React42.forwardRef(/* @__PURE__ */
37219
37461
  }, "DropdownMenuSubContent"));
37220
37462
 
37221
37463
  // src/components/ViewportSubContent.tsx
37222
- import { useLayoutEffect as useLayoutEffect5, useState as useState36 } from "react";
37223
- import { jsx as jsx32 } from "react/jsx-runtime";
37464
+ import { useLayoutEffect as useLayoutEffect5, useState as useState38 } from "react";
37465
+ import { jsx as jsx33 } from "react/jsx-runtime";
37224
37466
  var ViewportSubContent = (props) => {
37225
- const [content, setContent] = useState36(null);
37226
- const [overlapWidth, setOverlapWidth] = useState36();
37467
+ const [content, setContent] = useState38(null);
37468
+ const [overlapWidth, setOverlapWidth] = useState38();
37227
37469
  useLayoutEffect5(() => {
37228
37470
  if (!content) return;
37229
37471
  const trigger = document.getElementById(
@@ -37251,7 +37493,7 @@ var ViewportSubContent = (props) => {
37251
37493
  window.removeEventListener("resize", update);
37252
37494
  };
37253
37495
  }, [content]);
37254
- return /* @__PURE__ */ jsx32(
37496
+ return /* @__PURE__ */ jsx33(
37255
37497
  DropdownMenuSubContent,
37256
37498
  {
37257
37499
  ...props,
@@ -37278,14 +37520,14 @@ var menuViewportStyles = {
37278
37520
  };
37279
37521
 
37280
37522
  // src/components/ContextMenu.tsx
37281
- import { useState as useState38 } from "react";
37523
+ import { useState as useState40 } from "react";
37282
37524
 
37283
37525
  // src/components/AppearanceMenu.tsx
37284
- import { useState as useState37 } from "react";
37526
+ import { useState as useState39 } from "react";
37285
37527
 
37286
37528
  // src/components/Icons.tsx
37287
- import { jsx as jsx33 } from "react/jsx-runtime";
37288
- var CheckIcon = () => /* @__PURE__ */ jsx33(
37529
+ import { jsx as jsx34 } from "react/jsx-runtime";
37530
+ var CheckIcon = () => /* @__PURE__ */ jsx34(
37289
37531
  "svg",
37290
37532
  {
37291
37533
  xmlns: "http://www.w3.org/2000/svg",
@@ -37297,10 +37539,10 @@ var CheckIcon = () => /* @__PURE__ */ jsx33(
37297
37539
  strokeWidth: "2",
37298
37540
  strokeLinecap: "round",
37299
37541
  strokeLinejoin: "round",
37300
- children: /* @__PURE__ */ jsx33("path", { d: "M20 6 9 17l-5-5" })
37542
+ children: /* @__PURE__ */ jsx34("path", { d: "M20 6 9 17l-5-5" })
37301
37543
  }
37302
37544
  );
37303
- var ChevronRightIcon = ({ isOpen }) => /* @__PURE__ */ jsx33(
37545
+ var ChevronRightIcon = ({ isOpen }) => /* @__PURE__ */ jsx34(
37304
37546
  "svg",
37305
37547
  {
37306
37548
  xmlns: "http://www.w3.org/2000/svg",
@@ -37317,10 +37559,10 @@ var ChevronRightIcon = ({ isOpen }) => /* @__PURE__ */ jsx33(
37317
37559
  transform: isOpen ? "rotate(90deg)" : "rotate(0deg)",
37318
37560
  opacity: 0.6
37319
37561
  },
37320
- children: /* @__PURE__ */ jsx33("path", { d: "m9 18 6-6-6-6" })
37562
+ children: /* @__PURE__ */ jsx34("path", { d: "m9 18 6-6-6-6" })
37321
37563
  }
37322
37564
  );
37323
- var CheckMinusIcon = () => /* @__PURE__ */ jsx33(
37565
+ var CheckMinusIcon = () => /* @__PURE__ */ jsx34(
37324
37566
  "svg",
37325
37567
  {
37326
37568
  xmlns: "http://www.w3.org/2000/svg",
@@ -37332,10 +37574,10 @@ var CheckMinusIcon = () => /* @__PURE__ */ jsx33(
37332
37574
  strokeWidth: "2",
37333
37575
  strokeLinecap: "round",
37334
37576
  strokeLinejoin: "round",
37335
- children: /* @__PURE__ */ jsx33("path", { d: "M5 12h14" })
37577
+ children: /* @__PURE__ */ jsx34("path", { d: "M5 12h14" })
37336
37578
  }
37337
37579
  );
37338
- var DotIcon = () => /* @__PURE__ */ jsx33(
37580
+ var DotIcon = () => /* @__PURE__ */ jsx34(
37339
37581
  "svg",
37340
37582
  {
37341
37583
  xmlns: "http://www.w3.org/2000/svg",
@@ -37348,12 +37590,12 @@ var DotIcon = () => /* @__PURE__ */ jsx33(
37348
37590
  strokeLinecap: "round",
37349
37591
  strokeLinejoin: "round",
37350
37592
  className: "lucide lucide-dot-icon lucide-dot",
37351
- children: /* @__PURE__ */ jsx33("circle", { cx: "12.1", cy: "12.1", r: "4.5", fill: "white" })
37593
+ children: /* @__PURE__ */ jsx34("circle", { cx: "12.1", cy: "12.1", r: "4.5", fill: "white" })
37352
37594
  }
37353
37595
  );
37354
37596
 
37355
37597
  // src/components/AppearanceMenu.tsx
37356
- import { Fragment as Fragment8, jsx as jsx34, jsxs as jsxs6 } from "react/jsx-runtime";
37598
+ import { Fragment as Fragment9, jsx as jsx35, jsxs as jsxs7 } from "react/jsx-runtime";
37357
37599
  var itemStyles = {
37358
37600
  padding: "6px 8px",
37359
37601
  borderRadius: 6,
@@ -37400,7 +37642,9 @@ var iconContainerStyles = {
37400
37642
  justifyContent: "center",
37401
37643
  flexShrink: 0
37402
37644
  };
37403
- var AppearanceMenu = () => {
37645
+ var AppearanceMenu = ({
37646
+ showLayerControls = true
37647
+ }) => {
37404
37648
  const { visibility, setLayerVisibility } = useLayerVisibility();
37405
37649
  const {
37406
37650
  darkBackgroundEnabled,
@@ -37408,12 +37652,12 @@ var AppearanceMenu = () => {
37408
37652
  lightingEnabled,
37409
37653
  setLightingEnabled
37410
37654
  } = useAppearance();
37411
- const [appearanceSubOpen, setAppearanceSubOpen] = useState37(false);
37412
- const [hoveredItem, setHoveredItem] = useState37(null);
37413
- return /* @__PURE__ */ jsxs6(Fragment8, { children: [
37414
- /* @__PURE__ */ jsx34(DropdownMenuSeparator, { style: separatorStyles }),
37415
- /* @__PURE__ */ jsxs6(DropdownMenuSub, { onOpenChange: setAppearanceSubOpen, children: [
37416
- /* @__PURE__ */ jsxs6(
37655
+ const [appearanceSubOpen, setAppearanceSubOpen] = useState39(false);
37656
+ const [hoveredItem, setHoveredItem] = useState39(null);
37657
+ return /* @__PURE__ */ jsxs7(Fragment9, { children: [
37658
+ /* @__PURE__ */ jsx35(DropdownMenuSeparator, { style: separatorStyles }),
37659
+ /* @__PURE__ */ jsxs7(DropdownMenuSub, { onOpenChange: setAppearanceSubOpen, children: [
37660
+ /* @__PURE__ */ jsxs7(
37417
37661
  DropdownMenuSubTrigger,
37418
37662
  {
37419
37663
  style: {
@@ -37425,8 +37669,8 @@ var AppearanceMenu = () => {
37425
37669
  onMouseLeave: () => setHoveredItem(null),
37426
37670
  onTouchStart: () => setHoveredItem("appearance"),
37427
37671
  children: [
37428
- /* @__PURE__ */ jsx34("span", { style: { flex: 1, display: "flex", alignItems: "center" }, children: "Appearance" }),
37429
- /* @__PURE__ */ jsx34(
37672
+ /* @__PURE__ */ jsx35("span", { style: { flex: 1, display: "flex", alignItems: "center" }, children: "Appearance" }),
37673
+ /* @__PURE__ */ jsx35(
37430
37674
  "div",
37431
37675
  {
37432
37676
  style: {
@@ -37435,20 +37679,20 @@ var AppearanceMenu = () => {
37435
37679
  alignItems: "flex-end",
37436
37680
  marginBottom: "-5px"
37437
37681
  },
37438
- children: /* @__PURE__ */ jsx34(ChevronRightIcon, { isOpen: appearanceSubOpen })
37682
+ children: /* @__PURE__ */ jsx35(ChevronRightIcon, { isOpen: appearanceSubOpen })
37439
37683
  }
37440
37684
  )
37441
37685
  ]
37442
37686
  }
37443
37687
  ),
37444
- /* @__PURE__ */ jsx34(DropdownMenuPortal, { children: /* @__PURE__ */ jsxs6(
37688
+ /* @__PURE__ */ jsx35(DropdownMenuPortal, { children: /* @__PURE__ */ jsxs7(
37445
37689
  ViewportSubContent,
37446
37690
  {
37447
37691
  style: { ...contentStyles, marginLeft: -2 },
37448
37692
  collisionPadding: 10,
37449
37693
  avoidCollisions: true,
37450
37694
  children: [
37451
- /* @__PURE__ */ jsxs6(
37695
+ /* @__PURE__ */ jsxs7(
37452
37696
  DropdownMenuItem,
37453
37697
  {
37454
37698
  style: {
@@ -37464,12 +37708,12 @@ var AppearanceMenu = () => {
37464
37708
  onMouseLeave: () => setHoveredItem(null),
37465
37709
  onTouchStart: () => setHoveredItem("darkBackground"),
37466
37710
  children: [
37467
- /* @__PURE__ */ jsx34("span", { style: iconContainerStyles, children: darkBackgroundEnabled && /* @__PURE__ */ jsx34(CheckIcon, {}) }),
37468
- /* @__PURE__ */ jsx34("span", { style: { display: "flex", alignItems: "center" }, children: "Dark Background" })
37711
+ /* @__PURE__ */ jsx35("span", { style: iconContainerStyles, children: darkBackgroundEnabled && /* @__PURE__ */ jsx35(CheckIcon, {}) }),
37712
+ /* @__PURE__ */ jsx35("span", { style: { display: "flex", alignItems: "center" }, children: "Dark Background" })
37469
37713
  ]
37470
37714
  }
37471
37715
  ),
37472
- /* @__PURE__ */ jsxs6(
37716
+ /* @__PURE__ */ jsxs7(
37473
37717
  DropdownMenuItem,
37474
37718
  {
37475
37719
  style: {
@@ -37485,278 +37729,283 @@ var AppearanceMenu = () => {
37485
37729
  onMouseLeave: () => setHoveredItem(null),
37486
37730
  onTouchStart: () => setHoveredItem("lighting"),
37487
37731
  children: [
37488
- /* @__PURE__ */ jsx34("span", { style: iconContainerStyles, children: lightingEnabled && /* @__PURE__ */ jsx34(CheckIcon, {}) }),
37489
- /* @__PURE__ */ jsx34("span", { style: { display: "flex", alignItems: "center" }, children: "Lighting" })
37490
- ]
37491
- }
37492
- ),
37493
- /* @__PURE__ */ jsx34(DropdownMenuSeparator, { style: separatorStyles }),
37494
- /* @__PURE__ */ jsxs6(
37495
- DropdownMenuItem,
37496
- {
37497
- style: {
37498
- ...itemStyles,
37499
- backgroundColor: hoveredItem === "boardBody" ? "#404040" : "transparent"
37500
- },
37501
- onSelect: (e) => e.preventDefault(),
37502
- onPointerDown: (e) => {
37503
- e.preventDefault();
37504
- setLayerVisibility("boardBody", !visibility.boardBody);
37505
- },
37506
- onMouseEnter: () => setHoveredItem("boardBody"),
37507
- onMouseLeave: () => setHoveredItem(null),
37508
- onTouchStart: () => setHoveredItem("boardBody"),
37509
- children: [
37510
- /* @__PURE__ */ jsx34("span", { style: iconContainerStyles, children: visibility.boardBody && /* @__PURE__ */ jsx34(CheckIcon, {}) }),
37511
- /* @__PURE__ */ jsx34("span", { style: { display: "flex", alignItems: "center" }, children: "Board Body" })
37512
- ]
37513
- }
37514
- ),
37515
- /* @__PURE__ */ jsxs6(
37516
- DropdownMenuItem,
37517
- {
37518
- style: {
37519
- ...itemStyles,
37520
- backgroundColor: hoveredItem === "topCopper" ? "#404040" : "transparent"
37521
- },
37522
- onSelect: (e) => e.preventDefault(),
37523
- onPointerDown: (e) => {
37524
- e.preventDefault();
37525
- setLayerVisibility("topCopper", !visibility.topCopper);
37526
- },
37527
- onMouseEnter: () => setHoveredItem("topCopper"),
37528
- onMouseLeave: () => setHoveredItem(null),
37529
- onTouchStart: () => setHoveredItem("topCopper"),
37530
- children: [
37531
- /* @__PURE__ */ jsx34("span", { style: iconContainerStyles, children: visibility.topCopper && /* @__PURE__ */ jsx34(CheckIcon, {}) }),
37532
- /* @__PURE__ */ jsx34("span", { style: { display: "flex", alignItems: "center" }, children: "Top Copper" })
37533
- ]
37534
- }
37535
- ),
37536
- /* @__PURE__ */ jsxs6(
37537
- DropdownMenuItem,
37538
- {
37539
- style: {
37540
- ...itemStyles,
37541
- backgroundColor: hoveredItem === "bottomCopper" ? "#404040" : "transparent"
37542
- },
37543
- onSelect: (e) => e.preventDefault(),
37544
- onPointerDown: (e) => {
37545
- e.preventDefault();
37546
- setLayerVisibility("bottomCopper", !visibility.bottomCopper);
37547
- },
37548
- onMouseEnter: () => setHoveredItem("bottomCopper"),
37549
- onMouseLeave: () => setHoveredItem(null),
37550
- onTouchStart: () => setHoveredItem("bottomCopper"),
37551
- children: [
37552
- /* @__PURE__ */ jsx34("span", { style: iconContainerStyles, children: visibility.bottomCopper && /* @__PURE__ */ jsx34(CheckIcon, {}) }),
37553
- /* @__PURE__ */ jsx34("span", { style: { display: "flex", alignItems: "center" }, children: "Bottom Copper" })
37554
- ]
37555
- }
37556
- ),
37557
- /* @__PURE__ */ jsxs6(
37558
- DropdownMenuItem,
37559
- {
37560
- style: {
37561
- ...itemStyles,
37562
- backgroundColor: hoveredItem === "keepout" ? "#404040" : "transparent"
37563
- },
37564
- onSelect: (e) => e.preventDefault(),
37565
- onPointerDown: (e) => {
37566
- e.preventDefault();
37567
- setLayerVisibility("keepout", !visibility.keepout);
37568
- },
37569
- onMouseEnter: () => setHoveredItem("keepout"),
37570
- onMouseLeave: () => setHoveredItem(null),
37571
- onTouchStart: () => setHoveredItem("keepout"),
37572
- children: [
37573
- /* @__PURE__ */ jsx34("span", { style: iconContainerStyles, children: visibility.keepout && /* @__PURE__ */ jsx34(CheckIcon, {}) }),
37574
- /* @__PURE__ */ jsx34("span", { style: { display: "flex", alignItems: "center" }, children: "Keepout" })
37575
- ]
37576
- }
37577
- ),
37578
- /* @__PURE__ */ jsxs6(
37579
- DropdownMenuItem,
37580
- {
37581
- style: {
37582
- ...itemStyles,
37583
- backgroundColor: hoveredItem === "topSilkscreen" ? "#404040" : "transparent"
37584
- },
37585
- onSelect: (e) => e.preventDefault(),
37586
- onPointerDown: (e) => {
37587
- e.preventDefault();
37588
- setLayerVisibility("topSilkscreen", !visibility.topSilkscreen);
37589
- },
37590
- onMouseEnter: () => setHoveredItem("topSilkscreen"),
37591
- onMouseLeave: () => setHoveredItem(null),
37592
- onTouchStart: () => setHoveredItem("topSilkscreen"),
37593
- children: [
37594
- /* @__PURE__ */ jsx34("span", { style: iconContainerStyles, children: visibility.topSilkscreen && /* @__PURE__ */ jsx34(CheckIcon, {}) }),
37595
- /* @__PURE__ */ jsx34("span", { style: { display: "flex", alignItems: "center" }, children: "Top Silkscreen" })
37596
- ]
37597
- }
37598
- ),
37599
- /* @__PURE__ */ jsxs6(
37600
- DropdownMenuItem,
37601
- {
37602
- style: {
37603
- ...itemStyles,
37604
- backgroundColor: hoveredItem === "bottomSilkscreen" ? "#404040" : "transparent"
37605
- },
37606
- onSelect: (e) => e.preventDefault(),
37607
- onPointerDown: (e) => {
37608
- e.preventDefault();
37609
- setLayerVisibility(
37610
- "bottomSilkscreen",
37611
- !visibility.bottomSilkscreen
37612
- );
37613
- },
37614
- onMouseEnter: () => setHoveredItem("bottomSilkscreen"),
37615
- onMouseLeave: () => setHoveredItem(null),
37616
- onTouchStart: () => setHoveredItem("bottomSilkscreen"),
37617
- children: [
37618
- /* @__PURE__ */ jsx34("span", { style: iconContainerStyles, children: visibility.bottomSilkscreen && /* @__PURE__ */ jsx34(CheckIcon, {}) }),
37619
- /* @__PURE__ */ jsx34("span", { style: { display: "flex", alignItems: "center" }, children: "Bottom Silkscreen" })
37620
- ]
37621
- }
37622
- ),
37623
- /* @__PURE__ */ jsxs6(
37624
- DropdownMenuItem,
37625
- {
37626
- style: {
37627
- ...itemStyles,
37628
- backgroundColor: hoveredItem === "topMask" ? "#404040" : "transparent"
37629
- },
37630
- onSelect: (e) => e.preventDefault(),
37631
- onPointerDown: (e) => {
37632
- e.preventDefault();
37633
- setLayerVisibility("topMask", !visibility.topMask);
37634
- },
37635
- onMouseEnter: () => setHoveredItem("topMask"),
37636
- onMouseLeave: () => setHoveredItem(null),
37637
- onTouchStart: () => setHoveredItem("topMask"),
37638
- children: [
37639
- /* @__PURE__ */ jsx34("span", { style: iconContainerStyles, children: visibility.topMask && /* @__PURE__ */ jsx34(CheckIcon, {}) }),
37640
- /* @__PURE__ */ jsx34("span", { style: { display: "flex", alignItems: "center" }, children: "Top Soldermask" })
37641
- ]
37642
- }
37643
- ),
37644
- /* @__PURE__ */ jsxs6(
37645
- DropdownMenuItem,
37646
- {
37647
- style: {
37648
- ...itemStyles,
37649
- backgroundColor: hoveredItem === "bottomMask" ? "#404040" : "transparent"
37650
- },
37651
- onSelect: (e) => e.preventDefault(),
37652
- onPointerDown: (e) => {
37653
- e.preventDefault();
37654
- setLayerVisibility("bottomMask", !visibility.bottomMask);
37655
- },
37656
- onMouseEnter: () => setHoveredItem("bottomMask"),
37657
- onMouseLeave: () => setHoveredItem(null),
37658
- onTouchStart: () => setHoveredItem("bottomMask"),
37659
- children: [
37660
- /* @__PURE__ */ jsx34("span", { style: iconContainerStyles, children: visibility.bottomMask && /* @__PURE__ */ jsx34(CheckIcon, {}) }),
37661
- /* @__PURE__ */ jsx34("span", { style: { display: "flex", alignItems: "center" }, children: "Bottom Soldermask" })
37662
- ]
37663
- }
37664
- ),
37665
- /* @__PURE__ */ jsxs6(
37666
- DropdownMenuItem,
37667
- {
37668
- style: {
37669
- ...itemStyles,
37670
- backgroundColor: hoveredItem === "pcbNotes" ? "#404040" : "transparent"
37671
- },
37672
- onSelect: (e) => e.preventDefault(),
37673
- onPointerDown: (e) => {
37674
- e.preventDefault();
37675
- setLayerVisibility("pcbNotes", !visibility.pcbNotes);
37676
- },
37677
- onMouseEnter: () => setHoveredItem("pcbNotes"),
37678
- onMouseLeave: () => setHoveredItem(null),
37679
- onTouchStart: () => setHoveredItem("pcbNotes"),
37680
- children: [
37681
- /* @__PURE__ */ jsx34("span", { style: iconContainerStyles, children: visibility.pcbNotes && /* @__PURE__ */ jsx34(CheckIcon, {}) }),
37682
- /* @__PURE__ */ jsx34("span", { style: { display: "flex", alignItems: "center" }, children: "PCB Notes" })
37683
- ]
37684
- }
37685
- ),
37686
- /* @__PURE__ */ jsxs6(
37687
- DropdownMenuItem,
37688
- {
37689
- style: {
37690
- ...itemStyles,
37691
- backgroundColor: hoveredItem === "smtModels" ? "#404040" : "transparent"
37692
- },
37693
- onSelect: (e) => e.preventDefault(),
37694
- onPointerDown: (e) => {
37695
- e.preventDefault();
37696
- setLayerVisibility("smtModels", !visibility.smtModels);
37697
- },
37698
- onMouseEnter: () => setHoveredItem("smtModels"),
37699
- onMouseLeave: () => setHoveredItem(null),
37700
- onTouchStart: () => setHoveredItem("smtModels"),
37701
- children: [
37702
- /* @__PURE__ */ jsx34("span", { style: iconContainerStyles, children: visibility.smtModels && /* @__PURE__ */ jsx34(CheckIcon, {}) }),
37703
- /* @__PURE__ */ jsx34("span", { style: { display: "flex", alignItems: "center" }, children: "Surface Mount Components" })
37732
+ /* @__PURE__ */ jsx35("span", { style: iconContainerStyles, children: lightingEnabled && /* @__PURE__ */ jsx35(CheckIcon, {}) }),
37733
+ /* @__PURE__ */ jsx35("span", { style: { display: "flex", alignItems: "center" }, children: "Lighting" })
37704
37734
  ]
37705
37735
  }
37706
37736
  ),
37707
- /* @__PURE__ */ jsxs6(
37708
- DropdownMenuItem,
37709
- {
37710
- style: {
37711
- ...itemStyles,
37712
- backgroundColor: hoveredItem === "throughHoleModels" ? "#404040" : "transparent"
37713
- },
37714
- onSelect: (e) => e.preventDefault(),
37715
- onPointerDown: (e) => {
37716
- e.preventDefault();
37717
- setLayerVisibility(
37718
- "throughHoleModels",
37719
- !visibility.throughHoleModels
37720
- );
37721
- },
37722
- onMouseEnter: () => setHoveredItem("throughHoleModels"),
37723
- onMouseLeave: () => setHoveredItem(null),
37724
- onTouchStart: () => setHoveredItem("throughHoleModels"),
37725
- children: [
37726
- /* @__PURE__ */ jsx34("span", { style: iconContainerStyles, children: visibility.throughHoleModels && /* @__PURE__ */ jsx34(CheckIcon, {}) }),
37727
- /* @__PURE__ */ jsx34("span", { style: { display: "flex", alignItems: "center" }, children: "Through-Hole Components" })
37728
- ]
37729
- }
37730
- ),
37731
- /* @__PURE__ */ jsx34(DropdownMenuSeparator, { style: separatorStyles }),
37732
- /* @__PURE__ */ jsxs6(
37733
- DropdownMenuItem,
37734
- {
37735
- style: {
37736
- ...itemStyles,
37737
- backgroundColor: hoveredItem === "enclosure" ? "#404040" : "transparent"
37738
- },
37739
- onSelect: (e) => e.preventDefault(),
37740
- onPointerDown: (e) => {
37741
- e.preventDefault();
37742
- setLayerVisibility(
37743
- "enclosure",
37744
- nextEnclosureVisibility(visibility.enclosure)
37745
- );
37746
- },
37747
- onMouseEnter: () => setHoveredItem("enclosure"),
37748
- onMouseLeave: () => setHoveredItem(null),
37749
- onTouchStart: () => setHoveredItem("enclosure"),
37750
- title: `Enclosure: ${visibility.enclosure}`,
37751
- children: [
37752
- /* @__PURE__ */ jsxs6("span", { style: iconContainerStyles, children: [
37753
- visibility.enclosure === "opaque" && /* @__PURE__ */ jsx34(CheckIcon, {}),
37754
- visibility.enclosure === "translucent" && /* @__PURE__ */ jsx34(CheckMinusIcon, {})
37755
- ] }),
37756
- /* @__PURE__ */ jsx34("span", { style: { display: "flex", alignItems: "center" }, children: "Enclosure" })
37757
- ]
37758
- }
37759
- )
37737
+ showLayerControls && /* @__PURE__ */ jsxs7(Fragment9, { children: [
37738
+ /* @__PURE__ */ jsx35(DropdownMenuSeparator, { style: separatorStyles }),
37739
+ /* @__PURE__ */ jsxs7(
37740
+ DropdownMenuItem,
37741
+ {
37742
+ style: {
37743
+ ...itemStyles,
37744
+ backgroundColor: hoveredItem === "boardBody" ? "#404040" : "transparent"
37745
+ },
37746
+ onSelect: (e) => e.preventDefault(),
37747
+ onPointerDown: (e) => {
37748
+ e.preventDefault();
37749
+ setLayerVisibility("boardBody", !visibility.boardBody);
37750
+ },
37751
+ onMouseEnter: () => setHoveredItem("boardBody"),
37752
+ onMouseLeave: () => setHoveredItem(null),
37753
+ onTouchStart: () => setHoveredItem("boardBody"),
37754
+ children: [
37755
+ /* @__PURE__ */ jsx35("span", { style: iconContainerStyles, children: visibility.boardBody && /* @__PURE__ */ jsx35(CheckIcon, {}) }),
37756
+ /* @__PURE__ */ jsx35("span", { style: { display: "flex", alignItems: "center" }, children: "Board Body" })
37757
+ ]
37758
+ }
37759
+ ),
37760
+ /* @__PURE__ */ jsxs7(
37761
+ DropdownMenuItem,
37762
+ {
37763
+ style: {
37764
+ ...itemStyles,
37765
+ backgroundColor: hoveredItem === "topCopper" ? "#404040" : "transparent"
37766
+ },
37767
+ onSelect: (e) => e.preventDefault(),
37768
+ onPointerDown: (e) => {
37769
+ e.preventDefault();
37770
+ setLayerVisibility("topCopper", !visibility.topCopper);
37771
+ },
37772
+ onMouseEnter: () => setHoveredItem("topCopper"),
37773
+ onMouseLeave: () => setHoveredItem(null),
37774
+ onTouchStart: () => setHoveredItem("topCopper"),
37775
+ children: [
37776
+ /* @__PURE__ */ jsx35("span", { style: iconContainerStyles, children: visibility.topCopper && /* @__PURE__ */ jsx35(CheckIcon, {}) }),
37777
+ /* @__PURE__ */ jsx35("span", { style: { display: "flex", alignItems: "center" }, children: "Top Copper" })
37778
+ ]
37779
+ }
37780
+ ),
37781
+ /* @__PURE__ */ jsxs7(
37782
+ DropdownMenuItem,
37783
+ {
37784
+ style: {
37785
+ ...itemStyles,
37786
+ backgroundColor: hoveredItem === "bottomCopper" ? "#404040" : "transparent"
37787
+ },
37788
+ onSelect: (e) => e.preventDefault(),
37789
+ onPointerDown: (e) => {
37790
+ e.preventDefault();
37791
+ setLayerVisibility("bottomCopper", !visibility.bottomCopper);
37792
+ },
37793
+ onMouseEnter: () => setHoveredItem("bottomCopper"),
37794
+ onMouseLeave: () => setHoveredItem(null),
37795
+ onTouchStart: () => setHoveredItem("bottomCopper"),
37796
+ children: [
37797
+ /* @__PURE__ */ jsx35("span", { style: iconContainerStyles, children: visibility.bottomCopper && /* @__PURE__ */ jsx35(CheckIcon, {}) }),
37798
+ /* @__PURE__ */ jsx35("span", { style: { display: "flex", alignItems: "center" }, children: "Bottom Copper" })
37799
+ ]
37800
+ }
37801
+ ),
37802
+ /* @__PURE__ */ jsxs7(
37803
+ DropdownMenuItem,
37804
+ {
37805
+ style: {
37806
+ ...itemStyles,
37807
+ backgroundColor: hoveredItem === "keepout" ? "#404040" : "transparent"
37808
+ },
37809
+ onSelect: (e) => e.preventDefault(),
37810
+ onPointerDown: (e) => {
37811
+ e.preventDefault();
37812
+ setLayerVisibility("keepout", !visibility.keepout);
37813
+ },
37814
+ onMouseEnter: () => setHoveredItem("keepout"),
37815
+ onMouseLeave: () => setHoveredItem(null),
37816
+ onTouchStart: () => setHoveredItem("keepout"),
37817
+ children: [
37818
+ /* @__PURE__ */ jsx35("span", { style: iconContainerStyles, children: visibility.keepout && /* @__PURE__ */ jsx35(CheckIcon, {}) }),
37819
+ /* @__PURE__ */ jsx35("span", { style: { display: "flex", alignItems: "center" }, children: "Keepout" })
37820
+ ]
37821
+ }
37822
+ ),
37823
+ /* @__PURE__ */ jsxs7(
37824
+ DropdownMenuItem,
37825
+ {
37826
+ style: {
37827
+ ...itemStyles,
37828
+ backgroundColor: hoveredItem === "topSilkscreen" ? "#404040" : "transparent"
37829
+ },
37830
+ onSelect: (e) => e.preventDefault(),
37831
+ onPointerDown: (e) => {
37832
+ e.preventDefault();
37833
+ setLayerVisibility(
37834
+ "topSilkscreen",
37835
+ !visibility.topSilkscreen
37836
+ );
37837
+ },
37838
+ onMouseEnter: () => setHoveredItem("topSilkscreen"),
37839
+ onMouseLeave: () => setHoveredItem(null),
37840
+ onTouchStart: () => setHoveredItem("topSilkscreen"),
37841
+ children: [
37842
+ /* @__PURE__ */ jsx35("span", { style: iconContainerStyles, children: visibility.topSilkscreen && /* @__PURE__ */ jsx35(CheckIcon, {}) }),
37843
+ /* @__PURE__ */ jsx35("span", { style: { display: "flex", alignItems: "center" }, children: "Top Silkscreen" })
37844
+ ]
37845
+ }
37846
+ ),
37847
+ /* @__PURE__ */ jsxs7(
37848
+ DropdownMenuItem,
37849
+ {
37850
+ style: {
37851
+ ...itemStyles,
37852
+ backgroundColor: hoveredItem === "bottomSilkscreen" ? "#404040" : "transparent"
37853
+ },
37854
+ onSelect: (e) => e.preventDefault(),
37855
+ onPointerDown: (e) => {
37856
+ e.preventDefault();
37857
+ setLayerVisibility(
37858
+ "bottomSilkscreen",
37859
+ !visibility.bottomSilkscreen
37860
+ );
37861
+ },
37862
+ onMouseEnter: () => setHoveredItem("bottomSilkscreen"),
37863
+ onMouseLeave: () => setHoveredItem(null),
37864
+ onTouchStart: () => setHoveredItem("bottomSilkscreen"),
37865
+ children: [
37866
+ /* @__PURE__ */ jsx35("span", { style: iconContainerStyles, children: visibility.bottomSilkscreen && /* @__PURE__ */ jsx35(CheckIcon, {}) }),
37867
+ /* @__PURE__ */ jsx35("span", { style: { display: "flex", alignItems: "center" }, children: "Bottom Silkscreen" })
37868
+ ]
37869
+ }
37870
+ ),
37871
+ /* @__PURE__ */ jsxs7(
37872
+ DropdownMenuItem,
37873
+ {
37874
+ style: {
37875
+ ...itemStyles,
37876
+ backgroundColor: hoveredItem === "topMask" ? "#404040" : "transparent"
37877
+ },
37878
+ onSelect: (e) => e.preventDefault(),
37879
+ onPointerDown: (e) => {
37880
+ e.preventDefault();
37881
+ setLayerVisibility("topMask", !visibility.topMask);
37882
+ },
37883
+ onMouseEnter: () => setHoveredItem("topMask"),
37884
+ onMouseLeave: () => setHoveredItem(null),
37885
+ onTouchStart: () => setHoveredItem("topMask"),
37886
+ children: [
37887
+ /* @__PURE__ */ jsx35("span", { style: iconContainerStyles, children: visibility.topMask && /* @__PURE__ */ jsx35(CheckIcon, {}) }),
37888
+ /* @__PURE__ */ jsx35("span", { style: { display: "flex", alignItems: "center" }, children: "Top Soldermask" })
37889
+ ]
37890
+ }
37891
+ ),
37892
+ /* @__PURE__ */ jsxs7(
37893
+ DropdownMenuItem,
37894
+ {
37895
+ style: {
37896
+ ...itemStyles,
37897
+ backgroundColor: hoveredItem === "bottomMask" ? "#404040" : "transparent"
37898
+ },
37899
+ onSelect: (e) => e.preventDefault(),
37900
+ onPointerDown: (e) => {
37901
+ e.preventDefault();
37902
+ setLayerVisibility("bottomMask", !visibility.bottomMask);
37903
+ },
37904
+ onMouseEnter: () => setHoveredItem("bottomMask"),
37905
+ onMouseLeave: () => setHoveredItem(null),
37906
+ onTouchStart: () => setHoveredItem("bottomMask"),
37907
+ children: [
37908
+ /* @__PURE__ */ jsx35("span", { style: iconContainerStyles, children: visibility.bottomMask && /* @__PURE__ */ jsx35(CheckIcon, {}) }),
37909
+ /* @__PURE__ */ jsx35("span", { style: { display: "flex", alignItems: "center" }, children: "Bottom Soldermask" })
37910
+ ]
37911
+ }
37912
+ ),
37913
+ /* @__PURE__ */ jsxs7(
37914
+ DropdownMenuItem,
37915
+ {
37916
+ style: {
37917
+ ...itemStyles,
37918
+ backgroundColor: hoveredItem === "pcbNotes" ? "#404040" : "transparent"
37919
+ },
37920
+ onSelect: (e) => e.preventDefault(),
37921
+ onPointerDown: (e) => {
37922
+ e.preventDefault();
37923
+ setLayerVisibility("pcbNotes", !visibility.pcbNotes);
37924
+ },
37925
+ onMouseEnter: () => setHoveredItem("pcbNotes"),
37926
+ onMouseLeave: () => setHoveredItem(null),
37927
+ onTouchStart: () => setHoveredItem("pcbNotes"),
37928
+ children: [
37929
+ /* @__PURE__ */ jsx35("span", { style: iconContainerStyles, children: visibility.pcbNotes && /* @__PURE__ */ jsx35(CheckIcon, {}) }),
37930
+ /* @__PURE__ */ jsx35("span", { style: { display: "flex", alignItems: "center" }, children: "PCB Notes" })
37931
+ ]
37932
+ }
37933
+ ),
37934
+ /* @__PURE__ */ jsxs7(
37935
+ DropdownMenuItem,
37936
+ {
37937
+ style: {
37938
+ ...itemStyles,
37939
+ backgroundColor: hoveredItem === "smtModels" ? "#404040" : "transparent"
37940
+ },
37941
+ onSelect: (e) => e.preventDefault(),
37942
+ onPointerDown: (e) => {
37943
+ e.preventDefault();
37944
+ setLayerVisibility("smtModels", !visibility.smtModels);
37945
+ },
37946
+ onMouseEnter: () => setHoveredItem("smtModels"),
37947
+ onMouseLeave: () => setHoveredItem(null),
37948
+ onTouchStart: () => setHoveredItem("smtModels"),
37949
+ children: [
37950
+ /* @__PURE__ */ jsx35("span", { style: iconContainerStyles, children: visibility.smtModels && /* @__PURE__ */ jsx35(CheckIcon, {}) }),
37951
+ /* @__PURE__ */ jsx35("span", { style: { display: "flex", alignItems: "center" }, children: "Surface Mount Components" })
37952
+ ]
37953
+ }
37954
+ ),
37955
+ /* @__PURE__ */ jsxs7(
37956
+ DropdownMenuItem,
37957
+ {
37958
+ style: {
37959
+ ...itemStyles,
37960
+ backgroundColor: hoveredItem === "throughHoleModels" ? "#404040" : "transparent"
37961
+ },
37962
+ onSelect: (e) => e.preventDefault(),
37963
+ onPointerDown: (e) => {
37964
+ e.preventDefault();
37965
+ setLayerVisibility(
37966
+ "throughHoleModels",
37967
+ !visibility.throughHoleModels
37968
+ );
37969
+ },
37970
+ onMouseEnter: () => setHoveredItem("throughHoleModels"),
37971
+ onMouseLeave: () => setHoveredItem(null),
37972
+ onTouchStart: () => setHoveredItem("throughHoleModels"),
37973
+ children: [
37974
+ /* @__PURE__ */ jsx35("span", { style: iconContainerStyles, children: visibility.throughHoleModels && /* @__PURE__ */ jsx35(CheckIcon, {}) }),
37975
+ /* @__PURE__ */ jsx35("span", { style: { display: "flex", alignItems: "center" }, children: "Through-Hole Components" })
37976
+ ]
37977
+ }
37978
+ ),
37979
+ /* @__PURE__ */ jsx35(DropdownMenuSeparator, { style: separatorStyles }),
37980
+ /* @__PURE__ */ jsxs7(
37981
+ DropdownMenuItem,
37982
+ {
37983
+ style: {
37984
+ ...itemStyles,
37985
+ backgroundColor: hoveredItem === "enclosure" ? "#404040" : "transparent"
37986
+ },
37987
+ onSelect: (e) => e.preventDefault(),
37988
+ onPointerDown: (e) => {
37989
+ e.preventDefault();
37990
+ setLayerVisibility(
37991
+ "enclosure",
37992
+ nextEnclosureVisibility(visibility.enclosure)
37993
+ );
37994
+ },
37995
+ onMouseEnter: () => setHoveredItem("enclosure"),
37996
+ onMouseLeave: () => setHoveredItem(null),
37997
+ onTouchStart: () => setHoveredItem("enclosure"),
37998
+ title: `Enclosure: ${visibility.enclosure}`,
37999
+ children: [
38000
+ /* @__PURE__ */ jsxs7("span", { style: iconContainerStyles, children: [
38001
+ visibility.enclosure === "opaque" && /* @__PURE__ */ jsx35(CheckIcon, {}),
38002
+ visibility.enclosure === "translucent" && /* @__PURE__ */ jsx35(CheckMinusIcon, {})
38003
+ ] }),
38004
+ /* @__PURE__ */ jsx35("span", { style: { display: "flex", alignItems: "center" }, children: "Enclosure" })
38005
+ ]
38006
+ }
38007
+ )
38008
+ ] })
37760
38009
  ]
37761
38010
  }
37762
38011
  ) })
@@ -37765,7 +38014,7 @@ var AppearanceMenu = () => {
37765
38014
  };
37766
38015
 
37767
38016
  // src/components/ContextMenu.tsx
37768
- import { Fragment as Fragment9, jsx as jsx35, jsxs as jsxs7 } from "react/jsx-runtime";
38017
+ import { Fragment as Fragment10, jsx as jsx36, jsxs as jsxs8 } from "react/jsx-runtime";
37769
38018
  var cameraOptions = [
37770
38019
  "Custom",
37771
38020
  "Top Center Angled",
@@ -37843,6 +38092,7 @@ var ContextMenu = ({
37843
38092
  foldPcbs = false,
37844
38093
  onFoldPcbsToggle,
37845
38094
  flexScene = false,
38095
+ preRendered = false,
37846
38096
  referenceObject = null,
37847
38097
  onEngineSwitch,
37848
38098
  onCameraPresetSelect,
@@ -37858,10 +38108,10 @@ var ContextMenu = ({
37858
38108
  }) => {
37859
38109
  const { cameraType, setCameraType } = useCameraController();
37860
38110
  const { gridEnabled, setGridEnabled } = useAppearance();
37861
- const [cameraSubOpen, setCameraSubOpen] = useState38(false);
37862
- const [referenceObjectSubOpen, setReferenceObjectSubOpen] = useState38(false);
37863
- const [hoveredItem, setHoveredItem] = useState38(null);
37864
- return /* @__PURE__ */ jsx35(
38111
+ const [cameraSubOpen, setCameraSubOpen] = useState40(false);
38112
+ const [referenceObjectSubOpen, setReferenceObjectSubOpen] = useState40(false);
38113
+ const [hoveredItem, setHoveredItem] = useState40(null);
38114
+ return /* @__PURE__ */ jsx36(
37865
38115
  "div",
37866
38116
  {
37867
38117
  ref: menuRef,
@@ -37872,9 +38122,9 @@ var ContextMenu = ({
37872
38122
  width: 0,
37873
38123
  height: 0
37874
38124
  },
37875
- children: /* @__PURE__ */ jsxs7(DropdownMenu, { open: true, modal: false, children: [
37876
- /* @__PURE__ */ jsx35(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx35("div", { style: { position: "absolute", width: 1, height: 1 } }) }),
37877
- /* @__PURE__ */ jsx35(DropdownMenuPortal, { children: /* @__PURE__ */ jsxs7(
38125
+ children: /* @__PURE__ */ jsxs8(DropdownMenu, { open: true, modal: false, children: [
38126
+ /* @__PURE__ */ jsx36(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx36("div", { style: { position: "absolute", width: 1, height: 1 } }) }),
38127
+ /* @__PURE__ */ jsx36(DropdownMenuPortal, { children: /* @__PURE__ */ jsxs8(
37878
38128
  DropdownMenuContent,
37879
38129
  {
37880
38130
  style: contentStyles2,
@@ -37883,7 +38133,7 @@ var ContextMenu = ({
37883
38133
  sideOffset: 0,
37884
38134
  align: "start",
37885
38135
  children: [
37886
- onHideComponent && /* @__PURE__ */ jsx35(
38136
+ onHideComponent && /* @__PURE__ */ jsx36(
37887
38137
  DropdownMenuItem,
37888
38138
  {
37889
38139
  style: {
@@ -37897,7 +38147,7 @@ var ContextMenu = ({
37897
38147
  children: `Hide "${componentName}"`
37898
38148
  }
37899
38149
  ),
37900
- onViewSchematicComponent && /* @__PURE__ */ jsx35(Fragment9, { children: /* @__PURE__ */ jsx35(
38150
+ onViewSchematicComponent && /* @__PURE__ */ jsx36(Fragment10, { children: /* @__PURE__ */ jsx36(
37901
38151
  DropdownMenuItem,
37902
38152
  {
37903
38153
  style: {
@@ -37911,7 +38161,7 @@ var ContextMenu = ({
37911
38161
  children: "Show on schematic"
37912
38162
  }
37913
38163
  ) }),
37914
- onUnhideAllComponents && /* @__PURE__ */ jsx35(
38164
+ onUnhideAllComponents && /* @__PURE__ */ jsx36(
37915
38165
  DropdownMenuItem,
37916
38166
  {
37917
38167
  style: {
@@ -37925,9 +38175,9 @@ var ContextMenu = ({
37925
38175
  children: "Unhide All Components"
37926
38176
  }
37927
38177
  ),
37928
- (onViewSchematicComponent || onHideComponent || onUnhideAllComponents) && /* @__PURE__ */ jsx35(DropdownMenuSeparator, { style: separatorStyles2 }),
37929
- /* @__PURE__ */ jsxs7(DropdownMenuSub, { onOpenChange: setCameraSubOpen, children: [
37930
- /* @__PURE__ */ jsxs7(
38178
+ (onViewSchematicComponent || onHideComponent || onUnhideAllComponents) && /* @__PURE__ */ jsx36(DropdownMenuSeparator, { style: separatorStyles2 }),
38179
+ /* @__PURE__ */ jsxs8(DropdownMenuSub, { onOpenChange: setCameraSubOpen, children: [
38180
+ /* @__PURE__ */ jsxs8(
37931
38181
  DropdownMenuSubTrigger,
37932
38182
  {
37933
38183
  style: {
@@ -37939,14 +38189,14 @@ var ContextMenu = ({
37939
38189
  onMouseLeave: () => setHoveredItem(null),
37940
38190
  onTouchStart: () => setHoveredItem("camera"),
37941
38191
  children: [
37942
- /* @__PURE__ */ jsx35(
38192
+ /* @__PURE__ */ jsx36(
37943
38193
  "span",
37944
38194
  {
37945
38195
  style: { flex: 1, display: "flex", alignItems: "center" },
37946
38196
  children: "Camera"
37947
38197
  }
37948
38198
  ),
37949
- /* @__PURE__ */ jsxs7(
38199
+ /* @__PURE__ */ jsxs8(
37950
38200
  "div",
37951
38201
  {
37952
38202
  style: {
@@ -37956,22 +38206,22 @@ var ContextMenu = ({
37956
38206
  marginLeft: "auto"
37957
38207
  },
37958
38208
  children: [
37959
- /* @__PURE__ */ jsx35("span", { style: { opacity: 0.55, fontSize: 13 }, children: cameraPreset }),
37960
- /* @__PURE__ */ jsx35(ChevronRightIcon, { isOpen: cameraSubOpen })
38209
+ /* @__PURE__ */ jsx36("span", { style: { opacity: 0.55, fontSize: 13 }, children: cameraPreset }),
38210
+ /* @__PURE__ */ jsx36(ChevronRightIcon, { isOpen: cameraSubOpen })
37961
38211
  ]
37962
38212
  }
37963
38213
  )
37964
38214
  ]
37965
38215
  }
37966
38216
  ),
37967
- /* @__PURE__ */ jsx35(DropdownMenuPortal, { children: /* @__PURE__ */ jsxs7(
38217
+ /* @__PURE__ */ jsx36(DropdownMenuPortal, { children: /* @__PURE__ */ jsxs8(
37968
38218
  ViewportSubContent,
37969
38219
  {
37970
38220
  style: { ...contentStyles2, marginLeft: -2 },
37971
38221
  collisionPadding: 10,
37972
38222
  avoidCollisions: true,
37973
38223
  children: [
37974
- cameraOptions.map((option) => /* @__PURE__ */ jsxs7(
38224
+ cameraOptions.map((option) => /* @__PURE__ */ jsxs8(
37975
38225
  DropdownMenuItem,
37976
38226
  {
37977
38227
  style: {
@@ -37983,14 +38233,14 @@ var ContextMenu = ({
37983
38233
  onMouseLeave: () => setHoveredItem(null),
37984
38234
  onTouchStart: () => setHoveredItem(option),
37985
38235
  children: [
37986
- /* @__PURE__ */ jsx35("span", { style: iconContainerStyles2, children: cameraPreset === option && /* @__PURE__ */ jsx35(DotIcon, {}) }),
37987
- /* @__PURE__ */ jsx35("span", { style: { display: "flex", alignItems: "center" }, children: option })
38236
+ /* @__PURE__ */ jsx36("span", { style: iconContainerStyles2, children: cameraPreset === option && /* @__PURE__ */ jsx36(DotIcon, {}) }),
38237
+ /* @__PURE__ */ jsx36("span", { style: { display: "flex", alignItems: "center" }, children: option })
37988
38238
  ]
37989
38239
  },
37990
38240
  option
37991
38241
  )),
37992
- /* @__PURE__ */ jsx35(DropdownMenuSeparator, { style: separatorStyles2 }),
37993
- /* @__PURE__ */ jsxs7(
38242
+ /* @__PURE__ */ jsx36(DropdownMenuSeparator, { style: separatorStyles2 }),
38243
+ /* @__PURE__ */ jsxs8(
37994
38244
  DropdownMenuItem,
37995
38245
  {
37996
38246
  style: {
@@ -38002,12 +38252,12 @@ var ContextMenu = ({
38002
38252
  onMouseLeave: () => setHoveredItem(null),
38003
38253
  onTouchStart: () => setHoveredItem("autorotate"),
38004
38254
  children: [
38005
- /* @__PURE__ */ jsx35("span", { style: iconContainerStyles2, children: autoRotate && /* @__PURE__ */ jsx35(CheckIcon, {}) }),
38006
- /* @__PURE__ */ jsx35("span", { style: { display: "flex", alignItems: "center" }, children: "Auto rotate" })
38255
+ /* @__PURE__ */ jsx36("span", { style: iconContainerStyles2, children: autoRotate && /* @__PURE__ */ jsx36(CheckIcon, {}) }),
38256
+ /* @__PURE__ */ jsx36("span", { style: { display: "flex", alignItems: "center" }, children: "Auto rotate" })
38007
38257
  ]
38008
38258
  }
38009
38259
  ),
38010
- /* @__PURE__ */ jsxs7(
38260
+ /* @__PURE__ */ jsxs8(
38011
38261
  DropdownMenuItem,
38012
38262
  {
38013
38263
  style: {
@@ -38024,8 +38274,8 @@ var ContextMenu = ({
38024
38274
  onMouseLeave: () => setHoveredItem(null),
38025
38275
  onTouchStart: () => setHoveredItem("cameratype"),
38026
38276
  children: [
38027
- /* @__PURE__ */ jsx35("span", { style: iconContainerStyles2, children: cameraType === "orthographic" && /* @__PURE__ */ jsx35(CheckIcon, {}) }),
38028
- /* @__PURE__ */ jsx35("span", { style: { display: "flex", alignItems: "center" }, children: "Orthographic Camera" })
38277
+ /* @__PURE__ */ jsx36("span", { style: iconContainerStyles2, children: cameraType === "orthographic" && /* @__PURE__ */ jsx36(CheckIcon, {}) }),
38278
+ /* @__PURE__ */ jsx36("span", { style: { display: "flex", alignItems: "center" }, children: "Orthographic Camera" })
38029
38279
  ]
38030
38280
  }
38031
38281
  )
@@ -38033,8 +38283,8 @@ var ContextMenu = ({
38033
38283
  }
38034
38284
  ) })
38035
38285
  ] }),
38036
- /* @__PURE__ */ jsxs7(DropdownMenuSub, { onOpenChange: setReferenceObjectSubOpen, children: [
38037
- /* @__PURE__ */ jsxs7(
38286
+ /* @__PURE__ */ jsxs8(DropdownMenuSub, { onOpenChange: setReferenceObjectSubOpen, children: [
38287
+ /* @__PURE__ */ jsxs8(
38038
38288
  DropdownMenuSubTrigger,
38039
38289
  {
38040
38290
  style: {
@@ -38046,14 +38296,14 @@ var ContextMenu = ({
38046
38296
  onMouseLeave: () => setHoveredItem(null),
38047
38297
  onTouchStart: () => setHoveredItem("reference-object"),
38048
38298
  children: [
38049
- /* @__PURE__ */ jsx35(
38299
+ /* @__PURE__ */ jsx36(
38050
38300
  "span",
38051
38301
  {
38052
38302
  style: { flex: 1, display: "flex", alignItems: "center" },
38053
38303
  children: "Show Reference Object"
38054
38304
  }
38055
38305
  ),
38056
- /* @__PURE__ */ jsx35(
38306
+ /* @__PURE__ */ jsx36(
38057
38307
  "div",
38058
38308
  {
38059
38309
  style: {
@@ -38062,13 +38312,13 @@ var ContextMenu = ({
38062
38312
  gap: 6,
38063
38313
  marginLeft: "auto"
38064
38314
  },
38065
- children: /* @__PURE__ */ jsx35(ChevronRightIcon, { isOpen: referenceObjectSubOpen })
38315
+ children: /* @__PURE__ */ jsx36(ChevronRightIcon, { isOpen: referenceObjectSubOpen })
38066
38316
  }
38067
38317
  )
38068
38318
  ]
38069
38319
  }
38070
38320
  ),
38071
- /* @__PURE__ */ jsx35(DropdownMenuPortal, { children: /* @__PURE__ */ jsx35(
38321
+ /* @__PURE__ */ jsx36(DropdownMenuPortal, { children: /* @__PURE__ */ jsx36(
38072
38322
  ViewportSubContent,
38073
38323
  {
38074
38324
  style: { ...contentStyles2, marginLeft: -2 },
@@ -38076,7 +38326,7 @@ var ContextMenu = ({
38076
38326
  avoidCollisions: true,
38077
38327
  children: REFERENCE_OBJECT_MENU_OPTIONS.map((option) => {
38078
38328
  const optionKey = option.type ?? "none";
38079
- return /* @__PURE__ */ jsxs7(
38329
+ return /* @__PURE__ */ jsxs8(
38080
38330
  DropdownMenuItem,
38081
38331
  {
38082
38332
  style: {
@@ -38092,8 +38342,8 @@ var ContextMenu = ({
38092
38342
  onMouseLeave: () => setHoveredItem(null),
38093
38343
  onTouchStart: () => setHoveredItem(optionKey),
38094
38344
  children: [
38095
- /* @__PURE__ */ jsx35("span", { style: iconContainerStyles2, children: referenceObject === option.type && /* @__PURE__ */ jsx35(DotIcon, {}) }),
38096
- /* @__PURE__ */ jsx35("span", { style: { display: "flex", alignItems: "center" }, children: option.label })
38345
+ /* @__PURE__ */ jsx36("span", { style: iconContainerStyles2, children: referenceObject === option.type && /* @__PURE__ */ jsx36(DotIcon, {}) }),
38346
+ /* @__PURE__ */ jsx36("span", { style: { display: "flex", alignItems: "center" }, children: option.label })
38097
38347
  ]
38098
38348
  },
38099
38349
  optionKey
@@ -38102,7 +38352,7 @@ var ContextMenu = ({
38102
38352
  }
38103
38353
  ) })
38104
38354
  ] }),
38105
- onFoldPcbsToggle && /* @__PURE__ */ jsxs7(
38355
+ onFoldPcbsToggle && /* @__PURE__ */ jsxs8(
38106
38356
  DropdownMenuCheckboxItem,
38107
38357
  {
38108
38358
  checked: foldPcbs,
@@ -38114,12 +38364,12 @@ var ContextMenu = ({
38114
38364
  onMouseEnter: () => setHoveredItem("fold"),
38115
38365
  onMouseLeave: () => setHoveredItem(null),
38116
38366
  children: [
38117
- /* @__PURE__ */ jsx35("span", { style: iconContainerStyles2, children: foldPcbs && /* @__PURE__ */ jsx35(CheckIcon, {}) }),
38118
- /* @__PURE__ */ jsx35("span", { children: "Fold PCBs" })
38367
+ /* @__PURE__ */ jsx36("span", { style: iconContainerStyles2, children: foldPcbs && /* @__PURE__ */ jsx36(CheckIcon, {}) }),
38368
+ /* @__PURE__ */ jsx36("span", { children: "Fold PCBs" })
38119
38369
  ]
38120
38370
  }
38121
38371
  ),
38122
- /* @__PURE__ */ jsxs7(
38372
+ /* @__PURE__ */ jsxs8(
38123
38373
  DropdownMenuItem,
38124
38374
  {
38125
38375
  style: {
@@ -38135,14 +38385,14 @@ var ContextMenu = ({
38135
38385
  onMouseLeave: () => setHoveredItem(null),
38136
38386
  onTouchStart: () => setHoveredItem("grid"),
38137
38387
  children: [
38138
- /* @__PURE__ */ jsx35("span", { style: iconContainerStyles2, children: gridEnabled && /* @__PURE__ */ jsx35(CheckIcon, {}) }),
38139
- /* @__PURE__ */ jsx35("span", { style: { display: "flex", alignItems: "center" }, children: "Show Grid" })
38388
+ /* @__PURE__ */ jsx36("span", { style: iconContainerStyles2, children: gridEnabled && /* @__PURE__ */ jsx36(CheckIcon, {}) }),
38389
+ /* @__PURE__ */ jsx36("span", { style: { display: "flex", alignItems: "center" }, children: "Show Grid" })
38140
38390
  ]
38141
38391
  }
38142
38392
  ),
38143
- /* @__PURE__ */ jsx35(AppearanceMenu, {}),
38144
- /* @__PURE__ */ jsx35(DropdownMenuSeparator, { style: separatorStyles2 }),
38145
- /* @__PURE__ */ jsx35(
38393
+ /* @__PURE__ */ jsx36(AppearanceMenu, { showLayerControls: !preRendered }),
38394
+ /* @__PURE__ */ jsx36(DropdownMenuSeparator, { style: separatorStyles2 }),
38395
+ /* @__PURE__ */ jsx36(
38146
38396
  DropdownMenuItem,
38147
38397
  {
38148
38398
  style: {
@@ -38154,11 +38404,11 @@ var ContextMenu = ({
38154
38404
  onMouseEnter: () => setHoveredItem("download"),
38155
38405
  onMouseLeave: () => setHoveredItem(null),
38156
38406
  onTouchStart: () => setHoveredItem("download"),
38157
- children: /* @__PURE__ */ jsx35("span", { style: { display: "flex", alignItems: "center" }, children: "Download GLTF" })
38407
+ children: /* @__PURE__ */ jsx36("span", { style: { display: "flex", alignItems: "center" }, children: "Download GLTF" })
38158
38408
  }
38159
38409
  ),
38160
- /* @__PURE__ */ jsx35(DropdownMenuSeparator, { style: separatorStyles2 }),
38161
- !flexScene && /* @__PURE__ */ jsxs7(
38410
+ /* @__PURE__ */ jsx36(DropdownMenuSeparator, { style: separatorStyles2 }),
38411
+ !flexScene && !preRendered && /* @__PURE__ */ jsxs8(
38162
38412
  DropdownMenuItem,
38163
38413
  {
38164
38414
  style: {
@@ -38175,7 +38425,7 @@ var ContextMenu = ({
38175
38425
  onMouseLeave: () => setHoveredItem(null),
38176
38426
  onTouchStart: () => setHoveredItem("engine"),
38177
38427
  children: [
38178
- /* @__PURE__ */ jsxs7(
38428
+ /* @__PURE__ */ jsxs8(
38179
38429
  "span",
38180
38430
  {
38181
38431
  style: { flex: 1, display: "flex", alignItems: "center" },
@@ -38186,7 +38436,7 @@ var ContextMenu = ({
38186
38436
  ]
38187
38437
  }
38188
38438
  ),
38189
- /* @__PURE__ */ jsx35(
38439
+ /* @__PURE__ */ jsx36(
38190
38440
  "div",
38191
38441
  {
38192
38442
  style: {
@@ -38200,8 +38450,8 @@ var ContextMenu = ({
38200
38450
  ]
38201
38451
  }
38202
38452
  ),
38203
- /* @__PURE__ */ jsx35(DropdownMenuSeparator, { style: separatorStyles2 }),
38204
- /* @__PURE__ */ jsxs7(
38453
+ /* @__PURE__ */ jsx36(DropdownMenuSeparator, { style: separatorStyles2 }),
38454
+ /* @__PURE__ */ jsxs8(
38205
38455
  DropdownMenuItem,
38206
38456
  {
38207
38457
  style: {
@@ -38214,8 +38464,8 @@ var ContextMenu = ({
38214
38464
  onMouseLeave: () => setHoveredItem(null),
38215
38465
  onTouchStart: () => setHoveredItem("shortcuts"),
38216
38466
  children: [
38217
- /* @__PURE__ */ jsx35("span", { style: { flex: 1, display: "flex", alignItems: "center" }, children: "Keyboard Shortcuts" }),
38218
- /* @__PURE__ */ jsx35(
38467
+ /* @__PURE__ */ jsx36("span", { style: { flex: 1, display: "flex", alignItems: "center" }, children: "Keyboard Shortcuts" }),
38468
+ /* @__PURE__ */ jsx36(
38219
38469
  "div",
38220
38470
  {
38221
38471
  style: {
@@ -38229,8 +38479,8 @@ var ContextMenu = ({
38229
38479
  ]
38230
38480
  }
38231
38481
  ),
38232
- /* @__PURE__ */ jsx35(DropdownMenuSeparator, { style: separatorStyles2 }),
38233
- /* @__PURE__ */ jsx35(
38482
+ /* @__PURE__ */ jsx36(DropdownMenuSeparator, { style: separatorStyles2 }),
38483
+ /* @__PURE__ */ jsx36(
38234
38484
  "div",
38235
38485
  {
38236
38486
  style: {
@@ -38241,7 +38491,7 @@ var ContextMenu = ({
38241
38491
  paddingTop: 4,
38242
38492
  paddingBottom: 4
38243
38493
  },
38244
- children: /* @__PURE__ */ jsxs7(
38494
+ children: /* @__PURE__ */ jsxs8(
38245
38495
  "span",
38246
38496
  {
38247
38497
  style: {
@@ -38268,10 +38518,10 @@ var ContextMenu = ({
38268
38518
  };
38269
38519
 
38270
38520
  // src/components/KeyboardShortcutsDialog.tsx
38271
- import { useEffect as useEffect49, useMemo as useMemo36, useRef as useRef27, useState as useState40 } from "react";
38521
+ import { useEffect as useEffect51, useMemo as useMemo38, useRef as useRef27, useState as useState42 } from "react";
38272
38522
 
38273
38523
  // src/hooks/useRegisteredHotkey.ts
38274
- import { useEffect as useEffect48, useMemo as useMemo35, useRef as useRef26, useState as useState39 } from "react";
38524
+ import { useEffect as useEffect50, useMemo as useMemo37, useRef as useRef26, useState as useState41 } from "react";
38275
38525
  var hotkeyRegistry = /* @__PURE__ */ new Map();
38276
38526
  var subscribers = /* @__PURE__ */ new Set();
38277
38527
  var isListenerAttached = false;
@@ -38395,14 +38645,14 @@ var subscribeToRegistry = (subscriber) => {
38395
38645
  var useRegisteredHotkey = (id, handler, metadata) => {
38396
38646
  const handlerRef = useRef26(handler);
38397
38647
  handlerRef.current = handler;
38398
- const normalizedMetadata = useMemo35(
38648
+ const normalizedMetadata = useMemo37(
38399
38649
  () => ({
38400
38650
  shortcut: metadata.shortcut,
38401
38651
  description: metadata.description
38402
38652
  }),
38403
38653
  [metadata.shortcut, metadata.description]
38404
38654
  );
38405
- useEffect48(() => {
38655
+ useEffect50(() => {
38406
38656
  const registration = {
38407
38657
  id,
38408
38658
  ...normalizedMetadata,
@@ -38415,10 +38665,10 @@ var useRegisteredHotkey = (id, handler, metadata) => {
38415
38665
  }, [id, normalizedMetadata]);
38416
38666
  };
38417
38667
  var useHotkeyRegistry = () => {
38418
- const [entries, setEntries] = useState39(
38668
+ const [entries, setEntries] = useState41(
38419
38669
  () => Array.from(hotkeyRegistry.values())
38420
38670
  );
38421
- useEffect48(() => subscribeToRegistry(setEntries), []);
38671
+ useEffect50(() => subscribeToRegistry(setEntries), []);
38422
38672
  return entries;
38423
38673
  };
38424
38674
  var registerHotkeyViewer = (element) => {
@@ -38427,15 +38677,15 @@ var registerHotkeyViewer = (element) => {
38427
38677
  };
38428
38678
 
38429
38679
  // src/components/KeyboardShortcutsDialog.tsx
38430
- import { jsx as jsx36, jsxs as jsxs8 } from "react/jsx-runtime";
38680
+ import { jsx as jsx37, jsxs as jsxs9 } from "react/jsx-runtime";
38431
38681
  var KeyboardShortcutsDialog = ({
38432
38682
  open,
38433
38683
  onClose
38434
38684
  }) => {
38435
- const [query, setQuery] = useState40("");
38685
+ const [query, setQuery] = useState42("");
38436
38686
  const inputRef = useRef27(null);
38437
38687
  const hotkeys = useHotkeyRegistry();
38438
- useEffect49(() => {
38688
+ useEffect51(() => {
38439
38689
  if (!open) return void 0;
38440
38690
  const handleKeyDown = (event) => {
38441
38691
  if (event.key === "Escape") {
@@ -38446,14 +38696,14 @@ var KeyboardShortcutsDialog = ({
38446
38696
  window.addEventListener("keydown", handleKeyDown);
38447
38697
  return () => window.removeEventListener("keydown", handleKeyDown);
38448
38698
  }, [open, onClose]);
38449
- useEffect49(() => {
38699
+ useEffect51(() => {
38450
38700
  if (open) {
38451
38701
  setTimeout(() => {
38452
38702
  inputRef.current?.focus();
38453
38703
  }, 0);
38454
38704
  }
38455
38705
  }, [open]);
38456
- const filteredHotkeys = useMemo36(() => {
38706
+ const filteredHotkeys = useMemo38(() => {
38457
38707
  const normalizedQuery = query.trim().toLowerCase();
38458
38708
  if (!normalizedQuery) {
38459
38709
  return hotkeys;
@@ -38466,7 +38716,7 @@ var KeyboardShortcutsDialog = ({
38466
38716
  if (!open) {
38467
38717
  return null;
38468
38718
  }
38469
- return /* @__PURE__ */ jsx36(
38719
+ return /* @__PURE__ */ jsx37(
38470
38720
  "div",
38471
38721
  {
38472
38722
  role: "dialog",
@@ -38481,7 +38731,7 @@ var KeyboardShortcutsDialog = ({
38481
38731
  zIndex: 9999
38482
38732
  },
38483
38733
  onClick: onClose,
38484
- children: /* @__PURE__ */ jsxs8(
38734
+ children: /* @__PURE__ */ jsxs9(
38485
38735
  "div",
38486
38736
  {
38487
38737
  style: {
@@ -38497,7 +38747,7 @@ var KeyboardShortcutsDialog = ({
38497
38747
  },
38498
38748
  onClick: (event) => event.stopPropagation(),
38499
38749
  children: [
38500
- /* @__PURE__ */ jsxs8(
38750
+ /* @__PURE__ */ jsxs9(
38501
38751
  "header",
38502
38752
  {
38503
38753
  style: {
@@ -38505,8 +38755,8 @@ var KeyboardShortcutsDialog = ({
38505
38755
  borderBottom: "1px solid rgba(255, 255, 255, 0.08)"
38506
38756
  },
38507
38757
  children: [
38508
- /* @__PURE__ */ jsxs8("div", { style: { display: "flex", justifyContent: "space-between" }, children: [
38509
- /* @__PURE__ */ jsx36(
38758
+ /* @__PURE__ */ jsxs9("div", { style: { display: "flex", justifyContent: "space-between" }, children: [
38759
+ /* @__PURE__ */ jsx37(
38510
38760
  "h2",
38511
38761
  {
38512
38762
  style: {
@@ -38518,7 +38768,7 @@ var KeyboardShortcutsDialog = ({
38518
38768
  children: "Keyboard Shortcuts"
38519
38769
  }
38520
38770
  ),
38521
- /* @__PURE__ */ jsx36(
38771
+ /* @__PURE__ */ jsx37(
38522
38772
  "button",
38523
38773
  {
38524
38774
  type: "button",
@@ -38534,7 +38784,7 @@ var KeyboardShortcutsDialog = ({
38534
38784
  }
38535
38785
  )
38536
38786
  ] }),
38537
- /* @__PURE__ */ jsx36(
38787
+ /* @__PURE__ */ jsx37(
38538
38788
  "input",
38539
38789
  {
38540
38790
  ref: inputRef,
@@ -38557,7 +38807,7 @@ var KeyboardShortcutsDialog = ({
38557
38807
  ]
38558
38808
  }
38559
38809
  ),
38560
- /* @__PURE__ */ jsx36("div", { style: { overflowY: "auto" }, children: /* @__PURE__ */ jsxs8(
38810
+ /* @__PURE__ */ jsx37("div", { style: { overflowY: "auto" }, children: /* @__PURE__ */ jsxs9(
38561
38811
  "table",
38562
38812
  {
38563
38813
  style: {
@@ -38566,23 +38816,23 @@ var KeyboardShortcutsDialog = ({
38566
38816
  fontSize: "0.95rem"
38567
38817
  },
38568
38818
  children: [
38569
- /* @__PURE__ */ jsx36("thead", { children: /* @__PURE__ */ jsxs8("tr", { style: { textAlign: "left", color: "#a1a1b5" }, children: [
38570
- /* @__PURE__ */ jsx36("th", { style: { padding: "12px 24px", width: "25%" }, children: "Key" }),
38571
- /* @__PURE__ */ jsx36("th", { style: { padding: "12px 24px" }, children: "Description" })
38819
+ /* @__PURE__ */ jsx37("thead", { children: /* @__PURE__ */ jsxs9("tr", { style: { textAlign: "left", color: "#a1a1b5" }, children: [
38820
+ /* @__PURE__ */ jsx37("th", { style: { padding: "12px 24px", width: "25%" }, children: "Key" }),
38821
+ /* @__PURE__ */ jsx37("th", { style: { padding: "12px 24px" }, children: "Description" })
38572
38822
  ] }) }),
38573
- /* @__PURE__ */ jsx36("tbody", { children: filteredHotkeys.length === 0 ? /* @__PURE__ */ jsx36("tr", { children: /* @__PURE__ */ jsx36(
38823
+ /* @__PURE__ */ jsx37("tbody", { children: filteredHotkeys.length === 0 ? /* @__PURE__ */ jsx37("tr", { children: /* @__PURE__ */ jsx37(
38574
38824
  "td",
38575
38825
  {
38576
38826
  colSpan: 2,
38577
38827
  style: { padding: "24px", textAlign: "center" },
38578
38828
  children: "No shortcuts found"
38579
38829
  }
38580
- ) }) : filteredHotkeys.map((hotkey) => /* @__PURE__ */ jsxs8(
38830
+ ) }) : filteredHotkeys.map((hotkey) => /* @__PURE__ */ jsxs9(
38581
38831
  "tr",
38582
38832
  {
38583
38833
  style: { borderTop: "1px solid rgba(255, 255, 255, 0.05)" },
38584
38834
  children: [
38585
- /* @__PURE__ */ jsx36("td", { style: { padding: "12px 24px" }, children: /* @__PURE__ */ jsx36(
38835
+ /* @__PURE__ */ jsx37("td", { style: { padding: "12px 24px" }, children: /* @__PURE__ */ jsx37(
38586
38836
  "span",
38587
38837
  {
38588
38838
  style: {
@@ -38600,7 +38850,7 @@ var KeyboardShortcutsDialog = ({
38600
38850
  children: hotkey.shortcut
38601
38851
  }
38602
38852
  ) }),
38603
- /* @__PURE__ */ jsx36("td", { style: { padding: "12px 24px" }, children: hotkey.description })
38853
+ /* @__PURE__ */ jsx37("td", { style: { padding: "12px 24px" }, children: hotkey.description })
38604
38854
  ]
38605
38855
  },
38606
38856
  hotkey.id
@@ -38617,7 +38867,7 @@ var KeyboardShortcutsDialog = ({
38617
38867
 
38618
38868
  // src/contexts/ToastContext.tsx
38619
38869
  import { Toaster, toast as hotToast } from "react-hot-toast";
38620
- import { Fragment as Fragment10, jsx as jsx37, jsxs as jsxs9 } from "react/jsx-runtime";
38870
+ import { Fragment as Fragment11, jsx as jsx38, jsxs as jsxs10 } from "react/jsx-runtime";
38621
38871
  var useToast = () => {
38622
38872
  return {
38623
38873
  showToast: (message, duration = 2e3) => {
@@ -38628,9 +38878,9 @@ var useToast = () => {
38628
38878
  var ToastProvider = ({
38629
38879
  children
38630
38880
  }) => {
38631
- return /* @__PURE__ */ jsxs9(Fragment10, { children: [
38881
+ return /* @__PURE__ */ jsxs10(Fragment11, { children: [
38632
38882
  children,
38633
- /* @__PURE__ */ jsx37(Toaster, { position: "bottom-right" })
38883
+ /* @__PURE__ */ jsx38(Toaster, { position: "bottom-right" })
38634
38884
  ] });
38635
38885
  };
38636
38886
 
@@ -38675,10 +38925,10 @@ function useCameraPreset({
38675
38925
  }
38676
38926
 
38677
38927
  // src/hooks/useContextMenu.ts
38678
- import { useState as useState41, useCallback as useCallback23, useRef as useRef28, useEffect as useEffect50 } from "react";
38928
+ import { useState as useState43, useCallback as useCallback23, useRef as useRef28, useEffect as useEffect52 } from "react";
38679
38929
  var useContextMenu = ({ containerRef, onOpen }) => {
38680
- const [menuVisible, setMenuVisible] = useState41(false);
38681
- const [menuPos, setMenuPos] = useState41({
38930
+ const [menuVisible, setMenuVisible] = useState43(false);
38931
+ const [menuPos, setMenuPos] = useState43({
38682
38932
  x: 0,
38683
38933
  y: 0
38684
38934
  });
@@ -38792,7 +39042,7 @@ var useContextMenu = ({ containerRef, onOpen }) => {
38792
39042
  }
38793
39043
  setMenuVisible(false);
38794
39044
  }, []);
38795
- useEffect50(() => {
39045
+ useEffect52(() => {
38796
39046
  if (menuVisible) {
38797
39047
  document.addEventListener("mousedown", handleClickAway);
38798
39048
  document.addEventListener("touchstart", handleClickAway);
@@ -38855,8 +39105,8 @@ var useGlobalDownloadGltf = () => {
38855
39105
  };
38856
39106
 
38857
39107
  // src/CadViewer.tsx
38858
- import { jsx as jsx38, jsxs as jsxs10 } from "react/jsx-runtime";
38859
- var DEFAULT_TARGET = new THREE57.Vector3(0, 0, 0);
39108
+ import { jsx as jsx39, jsxs as jsxs11 } from "react/jsx-runtime";
39109
+ var DEFAULT_TARGET = new THREE59.Vector3(0, 0, 0);
38860
39110
  var INITIAL_CAMERA_POSITION = [5, -5, 5];
38861
39111
  var readStoredCameraType = () => {
38862
39112
  if (typeof window === "undefined") return void 0;
@@ -38864,18 +39114,20 @@ var readStoredCameraType = () => {
38864
39114
  return stored === "orthographic" || stored === "perspective" ? stored : void 0;
38865
39115
  };
38866
39116
  var CadViewerInner = (props) => {
39117
+ const glbSource = props.glbUrl ?? props.glbData;
38867
39118
  const childrenCircuitJson = useConvertChildrenToCircuitJson(
38868
- props.circuitJson ? void 0 : props.children
39119
+ props.circuitJson || glbSource !== void 0 ? void 0 : props.children
38869
39120
  );
38870
39121
  const circuitJson = props.circuitJson ?? childrenCircuitJson;
38871
39122
  const hasBends = circuitJson.some((element) => element.type === "pcb_bend");
38872
39123
  const hasFlexGeometry = hasBends || circuitJson.some((element) => element.type === "pcb_stiffener");
38873
- const [foldPcbsOverride, setFoldPcbs] = useState42(
39124
+ const [foldPcbsOverride, setFoldPcbs] = useState44(
38874
39125
  void 0
38875
39126
  );
38876
39127
  const foldPcbs = foldPcbsOverride ?? props.foldPcbs;
38877
39128
  const resolvedFoldPcbs = resolveFoldPcbs(circuitJson, foldPcbs);
38878
- const circuitKey = JSON.stringify(circuitJson);
39129
+ const circuitJsonKey = glbSource === void 0 ? JSON.stringify(circuitJson) : void 0;
39130
+ const circuitKey = glbSource ?? circuitJsonKey;
38879
39131
  const { hiddenCadComponentIds, hideComponent, unhideAllComponents } = useHiddenCadComponents(circuitKey);
38880
39132
  const resolvedProps = {
38881
39133
  ...props,
@@ -38883,30 +39135,30 @@ var CadViewerInner = (props) => {
38883
39135
  children: void 0,
38884
39136
  hiddenCadComponentIds
38885
39137
  };
38886
- const [engine, setEngine] = useState42(() => {
39138
+ const [engine, setEngine] = useState44(() => {
38887
39139
  const stored = window.localStorage.getItem("cadViewerEngine");
38888
39140
  return stored === "jscad" || stored === "manifold" ? stored : "manifold";
38889
39141
  });
38890
39142
  const containerRef = useRef29(null);
38891
- const [isKeyboardShortcutsDialogOpen, setIsKeyboardShortcutsDialogOpen] = useState42(false);
38892
- const [autoRotate, setAutoRotate] = useState42(() => {
39143
+ const [isKeyboardShortcutsDialogOpen, setIsKeyboardShortcutsDialogOpen] = useState44(false);
39144
+ const [autoRotate, setAutoRotate] = useState44(() => {
38893
39145
  const stored = window.localStorage.getItem("cadViewerAutoRotate");
38894
39146
  return stored !== "false";
38895
39147
  });
38896
- const [autoRotateUserToggled, setAutoRotateUserToggled] = useState42(() => {
39148
+ const [autoRotateUserToggled, setAutoRotateUserToggled] = useState44(() => {
38897
39149
  const stored = window.localStorage.getItem("cadViewerAutoRotateUserToggled");
38898
39150
  return stored === "true";
38899
39151
  });
38900
- const [cameraPreset, setCameraPreset] = useState42("Custom");
38901
- const [referenceObject, setReferenceObject] = useState42(null);
39152
+ const [cameraPreset, setCameraPreset] = useState44("Custom");
39153
+ const [referenceObject, setReferenceObject] = useState44(null);
38902
39154
  const { cameraType } = useCameraController();
38903
39155
  const { visibility, setLayerVisibility } = useLayerVisibility();
38904
39156
  const { showToast } = useToast();
38905
39157
  const cameraControllerRef = useRef29(null);
38906
39158
  const externalCameraControllerReady = props.onCameraControllerReady;
38907
39159
  const sceneRef = useContext11(SchematicNavigationContext);
38908
- const [selectedComponent, setSelectedComponent] = useState42();
38909
- const [selectedCadComponent, setSelectedCadComponent] = useState42();
39160
+ const [selectedComponent, setSelectedComponent] = useState44();
39161
+ const [selectedCadComponent, setSelectedCadComponent] = useState44();
38910
39162
  const handleMenuOpen = useCallback25(
38911
39163
  (position) => {
38912
39164
  setSelectedCadComponent(
@@ -39023,28 +39275,28 @@ var CadViewerInner = (props) => {
39023
39275
  description: "Toggle translucent components"
39024
39276
  }
39025
39277
  );
39026
- useEffect51(() => {
39278
+ useEffect53(() => {
39027
39279
  if (containerRef.current) {
39028
39280
  registerHotkeyViewer(containerRef.current);
39029
39281
  }
39030
39282
  }, []);
39031
- useEffect51(() => {
39283
+ useEffect53(() => {
39032
39284
  window.localStorage.setItem("cadViewerEngine", engine);
39033
39285
  }, [engine]);
39034
- useEffect51(() => {
39286
+ useEffect53(() => {
39035
39287
  window.localStorage.setItem("cadViewerAutoRotate", String(autoRotate));
39036
39288
  }, [autoRotate]);
39037
- useEffect51(() => {
39289
+ useEffect53(() => {
39038
39290
  window.localStorage.setItem(
39039
39291
  "cadViewerAutoRotateUserToggled",
39040
39292
  String(autoRotateUserToggled)
39041
39293
  );
39042
39294
  }, [autoRotateUserToggled]);
39043
- useEffect51(() => {
39295
+ useEffect53(() => {
39044
39296
  window.localStorage.setItem("cadViewerCameraType", cameraType);
39045
39297
  }, [cameraType]);
39046
- const viewerKey = props.circuitJson ? circuitKey : void 0;
39047
- return /* @__PURE__ */ jsxs10(
39298
+ const viewerKey = props.circuitJson ? circuitJsonKey : void 0;
39299
+ return /* @__PURE__ */ jsxs11(
39048
39300
  "div",
39049
39301
  {
39050
39302
  ref: containerRef,
@@ -39060,7 +39312,18 @@ var CadViewerInner = (props) => {
39060
39312
  },
39061
39313
  ...contextMenuEventHandlers,
39062
39314
  children: [
39063
- hasFlexGeometry ? /* @__PURE__ */ jsx38(
39315
+ glbSource !== void 0 ? /* @__PURE__ */ jsx39(
39316
+ CadViewerGlb,
39317
+ {
39318
+ source: glbSource,
39319
+ hiddenCadComponentIds,
39320
+ autoRotateDisabled: props.autoRotateDisabled || !autoRotate,
39321
+ clickToInteractEnabled: props.clickToInteractEnabled,
39322
+ onUserInteraction: handleUserInteraction,
39323
+ onCameraControllerReady: handleCameraControllerReady,
39324
+ referenceObject
39325
+ }
39326
+ ) : hasFlexGeometry ? /* @__PURE__ */ jsx39(
39064
39327
  CadViewerManifold_default,
39065
39328
  {
39066
39329
  ...resolvedProps,
@@ -39070,7 +39333,7 @@ var CadViewerInner = (props) => {
39070
39333
  onCameraControllerReady: handleCameraControllerReady,
39071
39334
  referenceObject
39072
39335
  }
39073
- ) : engine === "jscad" ? /* @__PURE__ */ jsx38(
39336
+ ) : engine === "jscad" ? /* @__PURE__ */ jsx39(
39074
39337
  CadViewerJscad,
39075
39338
  {
39076
39339
  ...resolvedProps,
@@ -39080,7 +39343,7 @@ var CadViewerInner = (props) => {
39080
39343
  onCameraControllerReady: handleCameraControllerReady,
39081
39344
  referenceObject
39082
39345
  }
39083
- ) : /* @__PURE__ */ jsx38(
39346
+ ) : /* @__PURE__ */ jsx39(
39084
39347
  CadViewerManifold_default,
39085
39348
  {
39086
39349
  ...resolvedProps,
@@ -39091,7 +39354,7 @@ var CadViewerInner = (props) => {
39091
39354
  referenceObject
39092
39355
  }
39093
39356
  ),
39094
- menuVisible && /* @__PURE__ */ jsx38(
39357
+ menuVisible && /* @__PURE__ */ jsx39(
39095
39358
  ContextMenu,
39096
39359
  {
39097
39360
  componentName: selectedCadComponent?.componentName,
@@ -39110,9 +39373,10 @@ var CadViewerInner = (props) => {
39110
39373
  menuRef,
39111
39374
  menuPos,
39112
39375
  engine,
39376
+ preRendered: glbSource !== void 0,
39113
39377
  flexScene: hasFlexGeometry,
39114
39378
  foldPcbs: resolvedFoldPcbs,
39115
- onFoldPcbsToggle: hasBends ? () => {
39379
+ onFoldPcbsToggle: hasBends && glbSource === void 0 ? () => {
39116
39380
  setFoldPcbs(!resolvedFoldPcbs);
39117
39381
  setCameraPreset("Custom");
39118
39382
  closeMenu();
@@ -39151,7 +39415,7 @@ var CadViewerInner = (props) => {
39151
39415
  }
39152
39416
  }
39153
39417
  ),
39154
- /* @__PURE__ */ jsx38(
39418
+ /* @__PURE__ */ jsx39(
39155
39419
  KeyboardShortcutsDialog,
39156
39420
  {
39157
39421
  open: isKeyboardShortcutsDialogOpen,
@@ -39166,13 +39430,13 @@ var CadViewerInner = (props) => {
39166
39430
  var CadViewer = (props) => {
39167
39431
  configureRuntimeFont();
39168
39432
  const sceneRef = useRef29(null);
39169
- return /* @__PURE__ */ jsx38(SchematicNavigationContext.Provider, { value: sceneRef, children: /* @__PURE__ */ jsx38(
39433
+ return /* @__PURE__ */ jsx39(SchematicNavigationContext.Provider, { value: sceneRef, children: /* @__PURE__ */ jsx39(
39170
39434
  CameraControllerProvider,
39171
39435
  {
39172
39436
  defaultTarget: DEFAULT_TARGET,
39173
39437
  initialCameraPosition: INITIAL_CAMERA_POSITION,
39174
39438
  initialCameraType: readStoredCameraType(),
39175
- children: /* @__PURE__ */ jsx38(LayerVisibilityProvider, { children: /* @__PURE__ */ jsx38(AppearanceProvider, { children: /* @__PURE__ */ jsx38(ToastProvider, { children: /* @__PURE__ */ jsx38(CadViewerInner, { ...props }) }) }) })
39439
+ children: /* @__PURE__ */ jsx39(LayerVisibilityProvider, { children: /* @__PURE__ */ jsx39(AppearanceProvider, { children: /* @__PURE__ */ jsx39(ToastProvider, { children: /* @__PURE__ */ jsx39(CadViewerInner, { ...props }) }) }) })
39176
39440
  }
39177
39441
  ) });
39178
39442
  };
@@ -39180,11 +39444,11 @@ var CadViewer = (props) => {
39180
39444
  // src/convert-circuit-json-to-3d-svg.ts
39181
39445
  var import_debug = __toESM(require_browser(), 1);
39182
39446
  import { su as su18 } from "@tscircuit/circuit-json-util";
39183
- import * as THREE61 from "three";
39447
+ import * as THREE63 from "three";
39184
39448
  import { SVGRenderer } from "three/examples/jsm/renderers/SVGRenderer.js";
39185
39449
 
39186
39450
  // src/utils/create-geometry-from-polygons.ts
39187
- import * as THREE58 from "three";
39451
+ import * as THREE60 from "three";
39188
39452
  import { BufferGeometry as BufferGeometry6, Float32BufferAttribute as Float32BufferAttribute6 } from "three";
39189
39453
  function createGeometryFromPolygons(polygons) {
39190
39454
  const geometry = new BufferGeometry6();
@@ -39198,12 +39462,12 @@ function createGeometryFromPolygons(polygons) {
39198
39462
  ...polygon2.vertices[i + 1]
39199
39463
  // Third vertex
39200
39464
  );
39201
- const v1 = new THREE58.Vector3(...polygon2.vertices[0]);
39202
- const v2 = new THREE58.Vector3(...polygon2.vertices[i]);
39203
- const v3 = new THREE58.Vector3(...polygon2.vertices[i + 1]);
39204
- const normal = new THREE58.Vector3().crossVectors(
39205
- new THREE58.Vector3().subVectors(v2, v1),
39206
- new THREE58.Vector3().subVectors(v3, v1)
39465
+ const v1 = new THREE60.Vector3(...polygon2.vertices[0]);
39466
+ const v2 = new THREE60.Vector3(...polygon2.vertices[i]);
39467
+ const v3 = new THREE60.Vector3(...polygon2.vertices[i + 1]);
39468
+ const normal = new THREE60.Vector3().crossVectors(
39469
+ new THREE60.Vector3().subVectors(v2, v1),
39470
+ new THREE60.Vector3().subVectors(v3, v1)
39207
39471
  ).normalize();
39208
39472
  normals.push(
39209
39473
  normal.x,
@@ -39231,23 +39495,23 @@ import {
39231
39495
  convertCSGToThreeGeom as convertCSGToThreeGeom3,
39232
39496
  getJscadModelForFootprint as getJscadModelForFootprint2
39233
39497
  } from "jscad-electronics/vanilla";
39234
- import * as THREE60 from "three";
39498
+ import * as THREE62 from "three";
39235
39499
 
39236
39500
  // src/utils/load-model.ts
39237
- import * as THREE59 from "three";
39238
- import { GLTFLoader as GLTFLoader2 } from "three/examples/jsm/loaders/GLTFLoader.js";
39501
+ import * as THREE61 from "three";
39502
+ import { GLTFLoader as GLTFLoader3 } from "three/examples/jsm/loaders/GLTFLoader.js";
39239
39503
  import { OBJLoader as OBJLoader2 } from "three/examples/jsm/loaders/OBJLoader.js";
39240
39504
  import { STLLoader as STLLoader2 } from "three/examples/jsm/loaders/STLLoader.js";
39241
39505
  async function load3DModel(url) {
39242
39506
  if (url.endsWith(".stl")) {
39243
39507
  const loader = new STLLoader2();
39244
39508
  const geometry = await loader.loadAsync(url);
39245
- const material = new THREE59.MeshStandardMaterial({
39509
+ const material = new THREE61.MeshStandardMaterial({
39246
39510
  color: 8947848,
39247
39511
  metalness: 0.5,
39248
39512
  roughness: 0.5
39249
39513
  });
39250
- return new THREE59.Mesh(geometry, material);
39514
+ return new THREE61.Mesh(geometry, material);
39251
39515
  }
39252
39516
  if (url.endsWith(".obj")) {
39253
39517
  const loader = new OBJLoader2();
@@ -39257,7 +39521,7 @@ async function load3DModel(url) {
39257
39521
  return await loadVrml(url);
39258
39522
  }
39259
39523
  if (url.endsWith(".gltf") || url.endsWith(".glb")) {
39260
- const loader = new GLTFLoader2();
39524
+ const loader = new GLTFLoader3();
39261
39525
  const gltf = await loader.loadAsync(url);
39262
39526
  return gltf.scene;
39263
39527
  }
@@ -39280,9 +39544,9 @@ async function renderComponent(component, scene) {
39280
39544
  }
39281
39545
  if (component.rotation) {
39282
39546
  model.rotation.set(
39283
- THREE60.MathUtils.degToRad(component.rotation.x ?? 0),
39284
- THREE60.MathUtils.degToRad(component.rotation.y ?? 0),
39285
- THREE60.MathUtils.degToRad(component.rotation.z ?? 0)
39547
+ THREE62.MathUtils.degToRad(component.rotation.x ?? 0),
39548
+ THREE62.MathUtils.degToRad(component.rotation.y ?? 0),
39549
+ THREE62.MathUtils.degToRad(component.rotation.z ?? 0)
39286
39550
  );
39287
39551
  }
39288
39552
  scene.add(model);
@@ -39296,13 +39560,13 @@ async function renderComponent(component, scene) {
39296
39560
  );
39297
39561
  if (jscadObject && (jscadObject.polygons || jscadObject.sides)) {
39298
39562
  const threeGeom = convertCSGToThreeGeom3(jscadObject);
39299
- const material2 = new THREE60.MeshStandardMaterial({
39563
+ const material2 = new THREE62.MeshStandardMaterial({
39300
39564
  color: 8947848,
39301
39565
  metalness: 0.5,
39302
39566
  roughness: 0.5,
39303
- side: THREE60.DoubleSide
39567
+ side: THREE62.DoubleSide
39304
39568
  });
39305
- const mesh2 = new THREE60.Mesh(threeGeom, material2);
39569
+ const mesh2 = new THREE62.Mesh(threeGeom, material2);
39306
39570
  if (component.position) {
39307
39571
  mesh2.position.set(
39308
39572
  component.position.x ?? 0,
@@ -39312,9 +39576,9 @@ async function renderComponent(component, scene) {
39312
39576
  }
39313
39577
  if (component.rotation) {
39314
39578
  mesh2.rotation.set(
39315
- THREE60.MathUtils.degToRad(component.rotation.x ?? 0),
39316
- THREE60.MathUtils.degToRad(component.rotation.y ?? 0),
39317
- THREE60.MathUtils.degToRad(component.rotation.z ?? 0)
39579
+ THREE62.MathUtils.degToRad(component.rotation.x ?? 0),
39580
+ THREE62.MathUtils.degToRad(component.rotation.y ?? 0),
39581
+ THREE62.MathUtils.degToRad(component.rotation.z ?? 0)
39318
39582
  );
39319
39583
  }
39320
39584
  scene.add(mesh2);
@@ -39331,17 +39595,17 @@ async function renderComponent(component, scene) {
39331
39595
  if (!geom || !geom.polygons && !geom.sides) {
39332
39596
  continue;
39333
39597
  }
39334
- const color = new THREE60.Color(geomInfo.color);
39598
+ const color = new THREE62.Color(geomInfo.color);
39335
39599
  color.convertLinearToSRGB();
39336
39600
  const geomWithColor = { ...geom, color: [color.r, color.g, color.b] };
39337
39601
  const threeGeom = convertCSGToThreeGeom3(geomWithColor);
39338
- const material2 = new THREE60.MeshStandardMaterial({
39602
+ const material2 = new THREE62.MeshStandardMaterial({
39339
39603
  vertexColors: true,
39340
39604
  metalness: 0.2,
39341
39605
  roughness: 0.8,
39342
- side: THREE60.DoubleSide
39606
+ side: THREE62.DoubleSide
39343
39607
  });
39344
- const mesh2 = new THREE60.Mesh(threeGeom, material2);
39608
+ const mesh2 = new THREE62.Mesh(threeGeom, material2);
39345
39609
  if (component.position) {
39346
39610
  mesh2.position.set(
39347
39611
  component.position.x ?? 0,
@@ -39351,22 +39615,22 @@ async function renderComponent(component, scene) {
39351
39615
  }
39352
39616
  if (component.rotation) {
39353
39617
  mesh2.rotation.set(
39354
- THREE60.MathUtils.degToRad(component.rotation.x ?? 0),
39355
- THREE60.MathUtils.degToRad(component.rotation.y ?? 0),
39356
- THREE60.MathUtils.degToRad(component.rotation.z ?? 0)
39618
+ THREE62.MathUtils.degToRad(component.rotation.x ?? 0),
39619
+ THREE62.MathUtils.degToRad(component.rotation.y ?? 0),
39620
+ THREE62.MathUtils.degToRad(component.rotation.z ?? 0)
39357
39621
  );
39358
39622
  }
39359
39623
  scene.add(mesh2);
39360
39624
  }
39361
39625
  return;
39362
39626
  }
39363
- const geometry = new THREE60.BoxGeometry(0.5, 0.5, 0.5);
39364
- const material = new THREE60.MeshStandardMaterial({
39627
+ const geometry = new THREE62.BoxGeometry(0.5, 0.5, 0.5);
39628
+ const material = new THREE62.MeshStandardMaterial({
39365
39629
  color: 16711680,
39366
39630
  transparent: true,
39367
39631
  opacity: 0.25
39368
39632
  });
39369
- const mesh = new THREE60.Mesh(geometry, material);
39633
+ const mesh = new THREE62.Mesh(geometry, material);
39370
39634
  if (component.position) {
39371
39635
  mesh.position.set(
39372
39636
  component.position.x ?? 0,
@@ -39387,11 +39651,11 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
39387
39651
  padding = 20,
39388
39652
  zoom = 1.5
39389
39653
  } = options;
39390
- const scene = new THREE61.Scene();
39654
+ const scene = new THREE63.Scene();
39391
39655
  const renderer = new SVGRenderer();
39392
39656
  renderer.setSize(width, height);
39393
- renderer.setClearColor(new THREE61.Color(backgroundColor), 1);
39394
- const camera = new THREE61.OrthographicCamera();
39657
+ renderer.setClearColor(new THREE63.Color(backgroundColor), 1);
39658
+ const camera = new THREE63.OrthographicCamera();
39395
39659
  const aspect = width / height;
39396
39660
  const frustumSize = 100;
39397
39661
  const halfFrustumSize = frustumSize / 2 / zoom;
@@ -39405,11 +39669,11 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
39405
39669
  camera.position.set(position.x, position.y, position.z);
39406
39670
  camera.up.set(0, 1, 0);
39407
39671
  const lookAt2 = options.camera?.lookAt ?? { x: 0, y: 0, z: 0 };
39408
- camera.lookAt(new THREE61.Vector3(lookAt2.x, lookAt2.y, lookAt2.z));
39672
+ camera.lookAt(new THREE63.Vector3(lookAt2.x, lookAt2.y, lookAt2.z));
39409
39673
  camera.updateProjectionMatrix();
39410
- const ambientLight = new THREE61.AmbientLight(16777215, Math.PI / 2);
39674
+ const ambientLight = new THREE63.AmbientLight(16777215, Math.PI / 2);
39411
39675
  scene.add(ambientLight);
39412
- const pointLight = new THREE61.PointLight(16777215, Math.PI / 4);
39676
+ const pointLight = new THREE63.PointLight(16777215, Math.PI / 4);
39413
39677
  pointLight.position.set(-10, -10, 10);
39414
39678
  scene.add(pointLight);
39415
39679
  const components = su18(circuitJson).cad_component.list();
@@ -39441,28 +39705,28 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
39441
39705
  const material = createBoardMaterial({
39442
39706
  material: boardData?.material,
39443
39707
  color: edgeColor,
39444
- side: THREE61.DoubleSide
39708
+ side: THREE63.DoubleSide
39445
39709
  });
39446
- const mesh = new THREE61.Mesh(geometry, material);
39710
+ const mesh = new THREE63.Mesh(geometry, material);
39447
39711
  scene.add(mesh);
39448
39712
  }
39449
39713
  }
39450
- const gridColor = new THREE61.Color(8947848);
39451
- const gridHelper = new THREE61.GridHelper(100, 100, gridColor, gridColor);
39714
+ const gridColor = new THREE63.Color(8947848);
39715
+ const gridHelper = new THREE63.GridHelper(100, 100, gridColor, gridColor);
39452
39716
  gridHelper.rotation.x = Math.PI / 2;
39453
39717
  const materials = Array.isArray(gridHelper.material) ? gridHelper.material : [gridHelper.material];
39454
39718
  for (const mat of materials) {
39455
39719
  mat.transparent = true;
39456
39720
  mat.opacity = 0.3;
39457
- if (mat instanceof THREE61.LineBasicMaterial) {
39721
+ if (mat instanceof THREE63.LineBasicMaterial) {
39458
39722
  mat.color = gridColor;
39459
39723
  mat.vertexColors = false;
39460
39724
  }
39461
39725
  }
39462
39726
  scene.add(gridHelper);
39463
- const box = new THREE61.Box3().setFromObject(scene);
39464
- const center = box.getCenter(new THREE61.Vector3());
39465
- const size4 = box.getSize(new THREE61.Vector3());
39727
+ const box = new THREE63.Box3().setFromObject(scene);
39728
+ const center = box.getCenter(new THREE63.Vector3());
39729
+ const size4 = box.getSize(new THREE63.Vector3());
39466
39730
  scene.position.sub(center);
39467
39731
  const maxDim = Math.max(size4.x, size4.y, size4.z);
39468
39732
  if (maxDim > 0) {
@@ -39480,10 +39744,10 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
39480
39744
 
39481
39745
  // src/hooks/exporter/gltf.ts
39482
39746
  import { GLTFExporter as GLTFExporter3 } from "three-stdlib";
39483
- import { useEffect as useEffect52, useState as useState43, useMemo as useMemo37, useCallback as useCallback26 } from "react";
39747
+ import { useEffect as useEffect54, useState as useState45, useMemo as useMemo39, useCallback as useCallback26 } from "react";
39484
39748
  function useSaveGltfAs(options = {}) {
39485
39749
  const parse2 = useParser(options);
39486
- const link = useMemo37(() => document.createElement("a"), []);
39750
+ const link = useMemo39(() => document.createElement("a"), []);
39487
39751
  const saveAs = async (filename) => {
39488
39752
  const name = filename ?? options.filename ?? "";
39489
39753
  if (options.binary == null) options.binary = name.endsWith(".glb");
@@ -39493,7 +39757,7 @@ function useSaveGltfAs(options = {}) {
39493
39757
  link.dispatchEvent(new MouseEvent("click"));
39494
39758
  URL.revokeObjectURL(url);
39495
39759
  };
39496
- useEffect52(
39760
+ useEffect54(
39497
39761
  () => () => {
39498
39762
  link.remove();
39499
39763
  instance = null;
@@ -39508,17 +39772,17 @@ function useSaveGltfAs(options = {}) {
39508
39772
  }
39509
39773
  function useExportGltfUrl(options = {}) {
39510
39774
  const parse2 = useParser(options);
39511
- const [url, setUrl] = useState43();
39512
- const [error, setError] = useState43();
39775
+ const [url, setUrl] = useState45();
39776
+ const [error, setError] = useState45();
39513
39777
  const ref = useCallback26(
39514
39778
  (instance) => parse2(instance).then(setUrl).catch(setError),
39515
39779
  []
39516
39780
  );
39517
- useEffect52(() => () => URL.revokeObjectURL(url), [url]);
39781
+ useEffect54(() => () => URL.revokeObjectURL(url), [url]);
39518
39782
  return [ref, url, error];
39519
39783
  }
39520
39784
  function useParser(options = {}) {
39521
- const exporter = useMemo37(() => new GLTFExporter3(), []);
39785
+ const exporter = useMemo39(() => new GLTFExporter3(), []);
39522
39786
  return (instance) => {
39523
39787
  const { promise, resolve, reject } = Promise.withResolvers();
39524
39788
  exporter.parse(