@tscircuit/3d-viewer 0.0.628 → 0.0.630

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.629",
20995
21083
  repository: {
20996
21084
  type: "git",
20997
21085
  url: "https://github.com/tscircuit/3d-viewer"
@@ -21058,8 +21146,8 @@ var package_default = {
21058
21146
  "@tscircuit/alphabet": "^0.0.25",
21059
21147
  "@tscircuit/circuit-json-util": "^0.0.119",
21060
21148
  "@tscircuit/copper-pour-solver": "^0.0.29",
21061
- "@tscircuit/core": "^0.0.2152",
21062
- "@tscircuit/props": "^0.0.701",
21149
+ "@tscircuit/core": "^0.0.2188",
21150
+ "@tscircuit/props": "^0.0.705",
21063
21151
  "@tscircuit/solver-utils": "^0.0.4",
21064
21152
  "@types/debug": "^4.1.13",
21065
21153
  "@types/jsdom": "^21.1.7",
@@ -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;
@@ -23022,7 +23110,7 @@ var colors = {
23022
23110
  fr4SolderMaskGreen: [0.06, 0.31, 0.19],
23023
23111
  fr4TracesWithMaskGreen: [0.09, 0.38, 0.23],
23024
23112
  fr4TracesWithoutMaskTan: [0.6, 0.43, 0.28],
23025
- flexAmber: [0.8, 0.61, 0.2],
23113
+ flexAmber: [204 / 255, 155 / 255, 50 / 255],
23026
23114
  fr1Tan: [0.8, 0.4, 0.2],
23027
23115
  fr1TracesWithMaskCopper: [0.9, 0.6, 0.2],
23028
23116
  fr1SolderMaskGreen: [0.02, 0.1, 0.04]
@@ -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(
@@ -26033,9 +26121,7 @@ var getSoldermaskPalette = (boardData) => {
26033
26121
  soldermaskColors[boardData.material] ?? colors.fr4SolderMaskGreen
26034
26122
  );
26035
26123
  const legacySoldermaskOverCopper = boardData.material === "fr1" ? toRgb2(colors.fr1TracesWithMaskCopper) : toRgb2(colors.fr4TracesWithMaskGreen);
26036
- const requestedSoldermaskColor = resolveSoldermaskColor(
26037
- boardData.solder_mask_color
26038
- );
26124
+ const requestedSoldermaskColor = resolveSoldermaskColor(boardData.solder_mask_color) ?? (boardData.material === "flex" ? new THREE41.Color(toRgb2(colors.flexAmber)) : null);
26039
26125
  if (!requestedSoldermaskColor) {
26040
26126
  return {
26041
26127
  soldermask: legacySoldermask,
@@ -26044,11 +26130,11 @@ var getSoldermaskPalette = (boardData) => {
26044
26130
  transparent: "rgba(0,0,0,0)"
26045
26131
  };
26046
26132
  }
26047
- const copperColor = new THREE40.Color().setRGB(
26133
+ const copperColor = new THREE41.Color().setRGB(
26048
26134
  colors.copper[0],
26049
26135
  colors.copper[1],
26050
26136
  colors.copper[2],
26051
- THREE40.SRGBColorSpace
26137
+ THREE41.SRGBColorSpace
26052
26138
  );
26053
26139
  return {
26054
26140
  soldermask: soldermaskColorToCss(requestedSoldermaskColor),
@@ -26183,17 +26269,17 @@ function createSoldermaskTextureForLayer({
26183
26269
  elements,
26184
26270
  boardData
26185
26271
  });
26186
- const texture = new THREE41.CanvasTexture(canvas);
26272
+ const texture = new THREE42.CanvasTexture(canvas);
26187
26273
  texture.generateMipmaps = true;
26188
- texture.minFilter = THREE41.LinearMipmapLinearFilter;
26189
- texture.magFilter = THREE41.LinearFilter;
26274
+ texture.minFilter = THREE42.LinearMipmapLinearFilter;
26275
+ texture.magFilter = THREE42.LinearFilter;
26190
26276
  texture.anisotropy = 16;
26191
26277
  texture.needsUpdate = true;
26192
26278
  return texture;
26193
26279
  }
26194
26280
 
26195
26281
  // src/textures/create-through-hole-texture-for-layer.ts
26196
- import * as THREE42 from "three";
26282
+ import * as THREE43 from "three";
26197
26283
 
26198
26284
  // src/textures/through-hole/through-hole-drawing.ts
26199
26285
  import { CircuitToCanvasDrawer as CircuitToCanvasDrawer11 } from "circuit-to-canvas";
@@ -26288,10 +26374,10 @@ function createThroughHoleTextureForLayer({
26288
26374
  elements,
26289
26375
  copperColor
26290
26376
  });
26291
- const texture = new THREE42.CanvasTexture(canvas);
26377
+ const texture = new THREE43.CanvasTexture(canvas);
26292
26378
  texture.generateMipmaps = true;
26293
- texture.minFilter = THREE42.LinearMipmapLinearFilter;
26294
- texture.magFilter = THREE42.LinearFilter;
26379
+ texture.minFilter = THREE43.LinearMipmapLinearFilter;
26380
+ texture.magFilter = THREE43.LinearFilter;
26295
26381
  texture.anisotropy = 16;
26296
26382
  texture.needsUpdate = true;
26297
26383
  return texture;
@@ -26388,10 +26474,10 @@ var createCombinedTexture = ({
26388
26474
  applySoldermaskSurfaceFilter(ctx, canvasWidth, canvasHeight, {
26389
26475
  includeReflection: layer === "top"
26390
26476
  });
26391
- const combinedTexture = new THREE43.CanvasTexture(canvas);
26477
+ const combinedTexture = new THREE44.CanvasTexture(canvas);
26392
26478
  combinedTexture.generateMipmaps = false;
26393
- combinedTexture.minFilter = THREE43.LinearFilter;
26394
- combinedTexture.magFilter = THREE43.LinearFilter;
26479
+ combinedTexture.minFilter = THREE44.LinearFilter;
26480
+ combinedTexture.magFilter = THREE44.LinearFilter;
26395
26481
  combinedTexture.premultiplyAlpha = true;
26396
26482
  combinedTexture.anisotropy = 16;
26397
26483
  combinedTexture.needsUpdate = true;
@@ -26427,11 +26513,11 @@ var createMaskedCopperMask = ({
26427
26513
  height
26428
26514
  );
26429
26515
  ctx.globalCompositeOperation = "source-over";
26430
- const maskTexture = new THREE43.CanvasTexture(canvas);
26431
- maskTexture.colorSpace = THREE43.NoColorSpace;
26516
+ const maskTexture = new THREE44.CanvasTexture(canvas);
26517
+ maskTexture.colorSpace = THREE44.NoColorSpace;
26432
26518
  maskTexture.generateMipmaps = false;
26433
- maskTexture.minFilter = THREE43.LinearFilter;
26434
- maskTexture.magFilter = THREE43.LinearFilter;
26519
+ maskTexture.minFilter = THREE44.LinearFilter;
26520
+ maskTexture.magFilter = THREE44.LinearFilter;
26435
26521
  maskTexture.premultiplyAlpha = false;
26436
26522
  maskTexture.needsUpdate = true;
26437
26523
  return maskTexture;
@@ -26577,7 +26663,7 @@ function createCombinedBoardTextures({
26577
26663
  }
26578
26664
 
26579
26665
  // src/textures/create-three-texture-meshes.ts
26580
- import * as THREE45 from "three";
26666
+ import * as THREE46 from "three";
26581
26667
 
26582
26668
  // src/board-surface-textures.ts
26583
26669
  var REALISTIC_BOARD_SURFACE_MATERIAL = {
@@ -26600,7 +26686,7 @@ var PAD_COPPER_TEXTURE_MATERIAL = {
26600
26686
  };
26601
26687
 
26602
26688
  // src/utils/create-board-relief-textures.ts
26603
- import * as THREE44 from "three";
26689
+ import * as THREE45 from "three";
26604
26690
  var PLAIN_SOLDERMASK_HEIGHT = 0.22;
26605
26691
  var MASKED_COPPER_HEIGHT = 0.7;
26606
26692
  var EXPOSED_COPPER_HEIGHT = 0.86;
@@ -26695,13 +26781,13 @@ var getBoardSurfaceProfile = (r, g, b, hasMaskedCopper) => {
26695
26781
  return PLAIN_SOLDERMASK_PROFILE;
26696
26782
  };
26697
26783
  var createDataTexture = (canvas) => {
26698
- const texture = new THREE44.CanvasTexture(canvas);
26699
- texture.colorSpace = THREE44.NoColorSpace;
26784
+ const texture = new THREE45.CanvasTexture(canvas);
26785
+ texture.colorSpace = THREE45.NoColorSpace;
26700
26786
  texture.generateMipmaps = false;
26701
- texture.minFilter = THREE44.LinearFilter;
26702
- texture.magFilter = THREE44.LinearFilter;
26703
- texture.wrapS = THREE44.ClampToEdgeWrapping;
26704
- texture.wrapT = THREE44.ClampToEdgeWrapping;
26787
+ texture.minFilter = THREE45.LinearFilter;
26788
+ texture.magFilter = THREE45.LinearFilter;
26789
+ texture.wrapS = THREE45.ClampToEdgeWrapping;
26790
+ texture.wrapT = THREE45.ClampToEdgeWrapping;
26705
26791
  texture.needsUpdate = true;
26706
26792
  return texture;
26707
26793
  };
@@ -26825,16 +26911,16 @@ function createTexturePlane(config, boardData) {
26825
26911
  } = config;
26826
26912
  if (!texture) return null;
26827
26913
  const boardOutlineBounds = calculateOutlineBounds(boardData);
26828
- const planeGeom = new THREE45.PlaneGeometry(
26914
+ const planeGeom = new THREE46.PlaneGeometry(
26829
26915
  boardOutlineBounds.width,
26830
26916
  boardOutlineBounds.height
26831
26917
  );
26832
- texture.colorSpace = THREE45.SRGBColorSpace;
26918
+ texture.colorSpace = THREE46.SRGBColorSpace;
26833
26919
  const sharedMaterialOptions = {
26834
26920
  map: texture,
26835
26921
  transparent: true,
26836
26922
  alphaTest: 0.08,
26837
- side: THREE45.FrontSide,
26923
+ side: THREE46.FrontSide,
26838
26924
  depthWrite: true,
26839
26925
  polygonOffset: usePolygonOffset,
26840
26926
  polygonOffsetFactor: usePolygonOffset ? -4 : 0,
@@ -26843,12 +26929,12 @@ function createTexturePlane(config, boardData) {
26843
26929
  opacity: isFaux ? FAUX_BOARD_OPACITY : 1
26844
26930
  };
26845
26931
  const reliefTextures = createBoardReliefTextures(texture, maskedCopperMask);
26846
- const material = new THREE45.MeshPhysicalMaterial({
26932
+ const material = new THREE46.MeshPhysicalMaterial({
26847
26933
  ...sharedMaterialOptions,
26848
26934
  bumpMap: reliefTextures?.bumpMap ?? null,
26849
26935
  bumpScale: REALISTIC_BOARD_SURFACE_MATERIAL.bumpScale,
26850
26936
  normalMap: reliefTextures?.normalMap ?? null,
26851
- normalScale: new THREE45.Vector2(
26937
+ normalScale: new THREE46.Vector2(
26852
26938
  REALISTIC_BOARD_SURFACE_MATERIAL.normalScale,
26853
26939
  REALISTIC_BOARD_SURFACE_MATERIAL.normalScale
26854
26940
  ),
@@ -26862,7 +26948,7 @@ function createTexturePlane(config, boardData) {
26862
26948
  clearcoatRoughness: REALISTIC_BOARD_SURFACE_MATERIAL.clearcoatRoughness,
26863
26949
  envMapIntensity: 0.18
26864
26950
  });
26865
- const mesh = new THREE45.Mesh(planeGeom, material);
26951
+ const mesh = new THREE46.Mesh(planeGeom, material);
26866
26952
  mesh.position.set(
26867
26953
  boardOutlineBounds.centerX,
26868
26954
  boardOutlineBounds.centerY,
@@ -26910,7 +26996,7 @@ function createTextureMeshes(textures, boardData, pcbThickness, isFaux = false)
26910
26996
  }
26911
26997
 
26912
26998
  // src/three-components/JscadBoardTextures.tsx
26913
- import * as THREE46 from "three";
26999
+ import * as THREE47 from "three";
26914
27000
 
26915
27001
  // src/hooks/useBoardTextureVisibility.ts
26916
27002
  import { useMemo as useMemo20 } from "react";
@@ -27048,7 +27134,7 @@ function JscadBoardTextures({
27048
27134
  const typedMaterial = material;
27049
27135
  for (const prop of textureProps) {
27050
27136
  const texture = typedMaterial[prop];
27051
- if (texture && texture instanceof THREE46.Texture) {
27137
+ if (texture && texture instanceof THREE47.Texture) {
27052
27138
  texture.dispose();
27053
27139
  typedMaterial[prop] = null;
27054
27140
  }
@@ -27067,16 +27153,16 @@ function JscadBoardTextures({
27067
27153
  }) => {
27068
27154
  if (!texture) return null;
27069
27155
  const boardOutlineBounds = calculateOutlineBounds(boardData);
27070
- const planeGeom = new THREE46.PlaneGeometry(
27156
+ const planeGeom = new THREE47.PlaneGeometry(
27071
27157
  boardOutlineBounds.width,
27072
27158
  boardOutlineBounds.height
27073
27159
  );
27074
- texture.colorSpace = THREE46.SRGBColorSpace;
27160
+ texture.colorSpace = THREE47.SRGBColorSpace;
27075
27161
  const sharedMaterialOptions = {
27076
27162
  map: texture,
27077
27163
  transparent: true,
27078
27164
  alphaTest: 0.08,
27079
- side: THREE46.FrontSide,
27165
+ side: THREE47.FrontSide,
27080
27166
  depthWrite,
27081
27167
  polygonOffset: usePolygonOffset,
27082
27168
  polygonOffsetFactor: usePolygonOffset ? -4 : 0,
@@ -27087,12 +27173,12 @@ function JscadBoardTextures({
27087
27173
  texture,
27088
27174
  maskedCopperMask
27089
27175
  );
27090
- const material = new THREE46.MeshPhysicalMaterial({
27176
+ const material = new THREE47.MeshPhysicalMaterial({
27091
27177
  ...sharedMaterialOptions,
27092
27178
  bumpMap: reliefTextures?.bumpMap ?? null,
27093
27179
  bumpScale: REALISTIC_BOARD_SURFACE_MATERIAL.bumpScale,
27094
27180
  normalMap: reliefTextures?.normalMap ?? null,
27095
- normalScale: new THREE46.Vector2(
27181
+ normalScale: new THREE47.Vector2(
27096
27182
  REALISTIC_BOARD_SURFACE_MATERIAL.normalScale,
27097
27183
  REALISTIC_BOARD_SURFACE_MATERIAL.normalScale
27098
27184
  ),
@@ -27104,7 +27190,7 @@ function JscadBoardTextures({
27104
27190
  clearcoatRoughness: REALISTIC_BOARD_SURFACE_MATERIAL.clearcoatRoughness,
27105
27191
  envMapIntensity: 0.18
27106
27192
  });
27107
- const mesh = new THREE46.Mesh(planeGeom, material);
27193
+ const mesh = new THREE47.Mesh(planeGeom, material);
27108
27194
  mesh.position.set(
27109
27195
  boardOutlineBounds.centerX,
27110
27196
  boardOutlineBounds.centerY,
@@ -27154,7 +27240,7 @@ function JscadBoardTextures({
27154
27240
  for (const material of mesh.material) {
27155
27241
  disposeTextureMaterial(material);
27156
27242
  }
27157
- } else if (mesh.material instanceof THREE46.Material) {
27243
+ } else if (mesh.material instanceof THREE47.Material) {
27158
27244
  disposeTextureMaterial(mesh.material);
27159
27245
  }
27160
27246
  }
@@ -27167,7 +27253,7 @@ function JscadBoardTextures({
27167
27253
 
27168
27254
  // src/three-components/STLModel.tsx
27169
27255
  import { useState as useState17, useEffect as useEffect28, useMemo as useMemo22 } from "react";
27170
- import * as THREE47 from "three";
27256
+ import * as THREE48 from "three";
27171
27257
  import { STLLoader } from "three-stdlib";
27172
27258
  function STLModel({
27173
27259
  stlUrl,
@@ -27200,15 +27286,15 @@ function STLModel({
27200
27286
  const mesh = useMemo22(() => {
27201
27287
  if (!geom) return null;
27202
27288
  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,
27289
+ const material = new THREE48.MeshStandardMaterial({
27290
+ color: Array.isArray(color) ? new THREE48.Color(color[0], color[1], color[2]) : color,
27205
27291
  transparent: opacity !== 1,
27206
27292
  opacity,
27207
27293
  polygonOffset: isBoardLayer,
27208
27294
  polygonOffsetFactor: isBoardLayer ? 6 : 0,
27209
27295
  polygonOffsetUnits: isBoardLayer ? 6 : 0
27210
27296
  });
27211
- const createdMesh = new THREE47.Mesh(geom, material);
27297
+ const createdMesh = new THREE48.Mesh(geom, material);
27212
27298
  createdMesh.renderOrder = isBoardLayer ? -1 : 1;
27213
27299
  configureObjectShadows(createdMesh, {
27214
27300
  castShadow: !isBoardLayer && opacity === 1,
@@ -27271,7 +27357,7 @@ function VisibleSTLModel({
27271
27357
  import { parseCableString } from "@tscircuit/cableprinter";
27272
27358
  import { createCableMeshes } from "jscad-electronics/cables";
27273
27359
  import { useEffect as useEffect29, useMemo as useMemo23 } from "react";
27274
- import * as THREE48 from "three";
27360
+ import * as THREE49 from "three";
27275
27361
  var isCadCableElement = (element) => {
27276
27362
  if (!element || typeof element !== "object") return false;
27277
27363
  const candidate = element;
@@ -27288,14 +27374,14 @@ var getConnectorPin1Side = ({
27288
27374
  const endpoint = end === "start" ? path[0] : path[path.length - 1];
27289
27375
  const adjacent = end === "start" ? path[1] : path[path.length - 2];
27290
27376
  if (!endpoint || !adjacent) return void 0;
27291
- const cableAxis = new THREE48.Vector3(
27377
+ const cableAxis = new THREE49.Vector3(
27292
27378
  adjacent.x - endpoint.x,
27293
27379
  adjacent.y - endpoint.y,
27294
27380
  adjacent.z - endpoint.z
27295
27381
  );
27296
27382
  if (cableAxis.lengthSq() < 1e-12) return void 0;
27297
27383
  cableAxis.normalize();
27298
- const pin1Side = new THREE48.Vector3(
27384
+ const pin1Side = new THREE49.Vector3(
27299
27385
  pin1Position.x - endpoint.x,
27300
27386
  pin1Position.y - endpoint.y,
27301
27387
  pin1Position.z - endpoint.z
@@ -27321,28 +27407,28 @@ var createCadCableObject = (cable) => {
27321
27407
  end: "end"
27322
27408
  })
27323
27409
  });
27324
- const group = new THREE48.Group();
27410
+ const group = new THREE49.Group();
27325
27411
  group.name = `cad-cable-${cable.cad_cable_id}`;
27326
27412
  group.userData = { cadCableId: cable.cad_cable_id, name: cable.name };
27327
27413
  for (const cableMesh of cableMeshes) {
27328
- let geometry = new THREE48.BufferGeometry();
27414
+ let geometry = new THREE49.BufferGeometry();
27329
27415
  geometry.setAttribute(
27330
27416
  "position",
27331
- new THREE48.Float32BufferAttribute(cableMesh.positions, 3)
27417
+ new THREE49.Float32BufferAttribute(cableMesh.positions, 3)
27332
27418
  );
27333
27419
  geometry.setIndex(cableMesh.indices);
27334
27420
  if (!cableMesh.smooth) geometry = geometry.toNonIndexed();
27335
27421
  geometry.computeVertexNormals();
27336
27422
  const [red, green, blue, alpha] = cableMesh.color;
27337
- const material = new THREE48.MeshStandardMaterial({
27338
- color: new THREE48.Color(red, green, blue),
27423
+ const material = new THREE49.MeshStandardMaterial({
27424
+ color: new THREE49.Color(red, green, blue),
27339
27425
  metalness: cableMesh.material?.metalness ?? 0,
27340
27426
  roughness: cableMesh.material?.roughness ?? 0.7,
27341
27427
  opacity: alpha,
27342
27428
  transparent: alpha < 1,
27343
- side: THREE48.DoubleSide
27429
+ side: THREE49.DoubleSide
27344
27430
  });
27345
- const mesh = new THREE48.Mesh(geometry, material);
27431
+ const mesh = new THREE49.Mesh(geometry, material);
27346
27432
  mesh.name = `${group.name}:${cableMesh.name}`;
27347
27433
  configureObjectShadows(mesh, { castShadow: true, receiveShadow: true });
27348
27434
  group.add(mesh);
@@ -27351,7 +27437,7 @@ var createCadCableObject = (cable) => {
27351
27437
  };
27352
27438
  var disposeCadCableObject = (group) => {
27353
27439
  group.traverse((object) => {
27354
- if (!(object instanceof THREE48.Mesh)) return;
27440
+ if (!(object instanceof THREE49.Mesh)) return;
27355
27441
  object.geometry.dispose();
27356
27442
  const materials = Array.isArray(object.material) ? object.material : [object.material];
27357
27443
  for (const material of materials) material.dispose();
@@ -28863,12 +28949,12 @@ function createStiffenerMesh({
28863
28949
 
28864
28950
  // src/CadViewerManifold.tsx
28865
28951
  import { useEffect as useEffect31, useMemo as useMemo26, useState as useState19 } from "react";
28866
- import * as THREE56 from "three";
28952
+ import * as THREE57 from "three";
28867
28953
 
28868
28954
  // src/hooks/useManifoldBoardBuilder.ts
28869
28955
  import { su as su16 } from "@tscircuit/circuit-json-util";
28870
28956
  import { useEffect as useEffect30, useMemo as useMemo25, useRef as useRef9, useState as useState18 } from "react";
28871
- import * as THREE52 from "three";
28957
+ import * as THREE53 from "three";
28872
28958
 
28873
28959
  // src/utils/manifold/create-manifold-board.ts
28874
28960
  var arePointsClockwise2 = (points) => {
@@ -29217,17 +29303,17 @@ function processNonPlatedHolesForManifold(Manifold, CrossSection, circuitJson, p
29217
29303
 
29218
29304
  // src/utils/manifold/process-plated-holes.ts
29219
29305
  import { su as su15 } from "@tscircuit/circuit-json-util";
29220
- import * as THREE50 from "three";
29306
+ import * as THREE51 from "three";
29221
29307
 
29222
29308
  // src/utils/manifold-mesh-to-three-geometry.ts
29223
- import * as THREE49 from "three";
29309
+ import * as THREE50 from "three";
29224
29310
  function manifoldMeshToThreeGeometry(manifoldMesh) {
29225
- const geometry = new THREE49.BufferGeometry();
29311
+ const geometry = new THREE50.BufferGeometry();
29226
29312
  geometry.setAttribute(
29227
29313
  "position",
29228
- new THREE49.Float32BufferAttribute(manifoldMesh.vertProperties, 3)
29314
+ new THREE50.Float32BufferAttribute(manifoldMesh.vertProperties, 3)
29229
29315
  );
29230
- geometry.setIndex(new THREE49.Uint32BufferAttribute(manifoldMesh.triVerts, 1));
29316
+ geometry.setIndex(new THREE50.Uint32BufferAttribute(manifoldMesh.triVerts, 1));
29231
29317
  if (manifoldMesh.runIndex && manifoldMesh.runIndex.length > 1 && manifoldMesh.runOriginalID) {
29232
29318
  for (let i = 0; i < manifoldMesh.runIndex.length - 1; i++) {
29233
29319
  const start = manifoldMesh.runIndex[i];
@@ -29261,7 +29347,7 @@ var createEllipsePoints = (width, height, segments) => {
29261
29347
  }
29262
29348
  return points;
29263
29349
  };
29264
- var COPPER_COLOR = new THREE50.Color(...colors.copper);
29350
+ var COPPER_COLOR = new THREE51.Color(...colors.copper);
29265
29351
  var PLATED_HOLE_LIP_HEIGHT = 0.05;
29266
29352
  var PLATED_HOLE_PAD_THICKNESS = 3e-3;
29267
29353
  var PLATED_HOLE_SURFACE_CLEARANCE = 5e-4;
@@ -29891,7 +29977,7 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
29891
29977
  }
29892
29978
 
29893
29979
  // src/utils/manifold/process-vias.ts
29894
- import * as THREE51 from "three";
29980
+ import * as THREE52 from "three";
29895
29981
 
29896
29982
  // src/utils/via-geoms.ts
29897
29983
  function createViaCopper2({
@@ -29929,7 +30015,7 @@ function createViaCopper2({
29929
30015
  }
29930
30016
 
29931
30017
  // src/utils/manifold/process-vias.ts
29932
- var COPPER_COLOR2 = new THREE51.Color(...colors.copper);
30018
+ var COPPER_COLOR2 = new THREE52.Color(...colors.copper);
29933
30019
  function processViasForManifold(Manifold, circuitJson, pcbThickness, manifoldInstancesForCleanup, boardClipVolume, otherHoleDrills = []) {
29934
30020
  const viaBoardDrills = [];
29935
30021
  const pcbVias = getPcbVias(circuitJson);
@@ -30177,7 +30263,7 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson, visibility) => {
30177
30263
  {
30178
30264
  key: "plated-holes-union",
30179
30265
  geometry: cutPlatedGeom,
30180
- color: new THREE52.Color(
30266
+ color: new THREE53.Color(
30181
30267
  colors.copper[0],
30182
30268
  colors.copper[1],
30183
30269
  colors.copper[2]
@@ -30247,7 +30333,7 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson, visibility) => {
30247
30333
  };
30248
30334
 
30249
30335
  // src/utils/flex-meshes.ts
30250
- import * as THREE53 from "three";
30336
+ import * as THREE54 from "three";
30251
30337
  function restoreOutlinePrecision(point, outline, tolerance) {
30252
30338
  let distanceSquared = tolerance * tolerance;
30253
30339
  let closest;
@@ -30282,7 +30368,7 @@ function meshToSurface(mesh, center, outline) {
30282
30368
  const triangles = [];
30283
30369
  for (let i = 0; i < position.count; i += 3) {
30284
30370
  const vertices = [0, 1, 2].map((j) => {
30285
- const v = new THREE53.Vector3().fromBufferAttribute(position, i + j);
30371
+ const v = new THREE54.Vector3().fromBufferAttribute(position, i + j);
30286
30372
  const localMagnitude = Math.max(
30287
30373
  1,
30288
30374
  Math.abs(v.x),
@@ -30305,7 +30391,7 @@ function meshToSurface(mesh, center, outline) {
30305
30391
  return { x: v.x - center.x, y: v.y - center.y, z: v.z };
30306
30392
  });
30307
30393
  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();
30394
+ 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
30395
  triangles.push({
30310
30396
  vertices,
30311
30397
  normal: { x: n.x, y: n.y, z: n.z },
@@ -30328,13 +30414,13 @@ function surfaceToGeometry(surface, center) {
30328
30414
  normals.push(triangle.normal.x, triangle.normal.y, triangle.normal.z);
30329
30415
  uvs.push(triangle.uvs?.[i]?.u ?? 0, triangle.uvs?.[i]?.v ?? 0);
30330
30416
  });
30331
- const geometry = new THREE53.BufferGeometry();
30417
+ const geometry = new THREE54.BufferGeometry();
30332
30418
  geometry.setAttribute(
30333
30419
  "position",
30334
- new THREE53.Float32BufferAttribute(positions, 3)
30420
+ new THREE54.Float32BufferAttribute(positions, 3)
30335
30421
  );
30336
- geometry.setAttribute("normal", new THREE53.Float32BufferAttribute(normals, 3));
30337
- geometry.setAttribute("uv", new THREE53.Float32BufferAttribute(uvs, 2));
30422
+ geometry.setAttribute("normal", new THREE54.Float32BufferAttribute(normals, 3));
30423
+ geometry.setAttribute("uv", new THREE54.Float32BufferAttribute(uvs, 2));
30338
30424
  geometry.computeBoundingBox();
30339
30425
  geometry.computeBoundingSphere();
30340
30426
  return geometry;
@@ -30387,7 +30473,7 @@ function createFlexMeshes(geometryMeshes, textureMeshes, json, foldPcbs) {
30387
30473
  z: mesh.position.z
30388
30474
  }));
30389
30475
  const uvs = vertices.map((p) => {
30390
- const local = new THREE53.Vector3(
30476
+ const local = new THREE54.Vector3(
30391
30477
  p.x + board.center.x,
30392
30478
  p.y + board.center.y,
30393
30479
  p.z
@@ -30411,7 +30497,7 @@ function createFlexMeshes(geometryMeshes, textureMeshes, json, foldPcbs) {
30411
30497
  return result;
30412
30498
  }) : textureMeshes;
30413
30499
  for (const stiffener of stiffeners) {
30414
- const mesh = new THREE53.Mesh(
30500
+ const mesh = new THREE54.Mesh(
30415
30501
  surfaceToGeometry(
30416
30502
  createStiffenerMesh({
30417
30503
  stiffener,
@@ -30420,16 +30506,16 @@ function createFlexMeshes(geometryMeshes, textureMeshes, json, foldPcbs) {
30420
30506
  }),
30421
30507
  board.center
30422
30508
  ),
30423
- new THREE53.MeshStandardMaterial({
30509
+ new THREE54.MeshStandardMaterial({
30424
30510
  color: stiffener.material === "fr4" ? "#879568" : stiffener.material === "polyimide" ? "#bd7f27" : "#b8bdc4",
30425
- side: THREE53.DoubleSide
30511
+ side: THREE54.DoubleSide
30426
30512
  })
30427
30513
  );
30428
30514
  mesh.name = "board-stiffener";
30429
30515
  configureObjectShadows(mesh);
30430
30516
  geometry.push(mesh);
30431
30517
  }
30432
- const bounds = new THREE53.Box3();
30518
+ const bounds = new THREE54.Box3();
30433
30519
  for (const mesh of [...geometry, ...textures]) bounds.expandByObject(mesh);
30434
30520
  return {
30435
30521
  geometryMeshes: geometry,
@@ -30446,11 +30532,11 @@ function createFlexMeshes(geometryMeshes, textureMeshes, json, foldPcbs) {
30446
30532
  }
30447
30533
 
30448
30534
  // src/utils/manifold/create-three-geometry-meshes.ts
30449
- import * as THREE55 from "three";
30535
+ import * as THREE56 from "three";
30450
30536
 
30451
30537
  // src/utils/create-board-material.ts
30452
- import * as THREE54 from "three";
30453
- var DEFAULT_SIDE = THREE54.DoubleSide;
30538
+ import * as THREE55 from "three";
30539
+ var DEFAULT_SIDE = THREE55.DoubleSide;
30454
30540
  var createBoardMaterial = ({
30455
30541
  material,
30456
30542
  color,
@@ -30458,7 +30544,7 @@ var createBoardMaterial = ({
30458
30544
  isFaux = false
30459
30545
  }) => {
30460
30546
  if (material === "fr4") {
30461
- return new THREE54.MeshPhysicalMaterial({
30547
+ return new THREE55.MeshPhysicalMaterial({
30462
30548
  color,
30463
30549
  side,
30464
30550
  metalness: 0,
@@ -30476,7 +30562,7 @@ var createBoardMaterial = ({
30476
30562
  polygonOffsetUnits: 1
30477
30563
  });
30478
30564
  }
30479
- return new THREE54.MeshStandardMaterial({
30565
+ return new THREE55.MeshStandardMaterial({
30480
30566
  color,
30481
30567
  side,
30482
30568
  flatShading: true,
@@ -30495,12 +30581,12 @@ function createGeometryMeshes(geoms) {
30495
30581
  const meshes = [];
30496
30582
  if (!geoms) return meshes;
30497
30583
  if (geoms.board?.geometry) {
30498
- const mesh = new THREE55.Mesh(
30584
+ const mesh = new THREE56.Mesh(
30499
30585
  geoms.board.geometry,
30500
30586
  createBoardMaterial({
30501
30587
  material: geoms.board.material,
30502
30588
  color: geoms.board.color,
30503
- side: THREE55.DoubleSide,
30589
+ side: THREE56.DoubleSide,
30504
30590
  isFaux: geoms.board.isFaux
30505
30591
  })
30506
30592
  );
@@ -30511,11 +30597,11 @@ function createGeometryMeshes(geoms) {
30511
30597
  const createMeshesFromArray = (geomArray) => {
30512
30598
  if (geomArray) {
30513
30599
  for (const comp of geomArray) {
30514
- const mesh = new THREE55.Mesh(
30600
+ const mesh = new THREE56.Mesh(
30515
30601
  comp.geometry,
30516
- new THREE55.MeshStandardMaterial({
30602
+ new THREE56.MeshStandardMaterial({
30517
30603
  color: comp.color,
30518
- side: THREE55.DoubleSide,
30604
+ side: THREE56.DoubleSide,
30519
30605
  flatShading: true
30520
30606
  // Consistent with board
30521
30607
  })
@@ -30587,7 +30673,7 @@ var BoardMeshes = ({
30587
30673
  const typedMaterial = material;
30588
30674
  for (const prop of textureProps) {
30589
30675
  const texture = typedMaterial[prop];
30590
- if (texture && texture instanceof THREE56.Texture) {
30676
+ if (texture && texture instanceof THREE57.Texture) {
30591
30677
  texture.dispose();
30592
30678
  }
30593
30679
  }
@@ -30820,46 +30906,200 @@ var CadViewerManifold = ({
30820
30906
  };
30821
30907
  var CadViewerManifold_default = CadViewerManifold;
30822
30908
 
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;
30909
+ // src/CadViewerGlb.tsx
30910
+ import { useEffect as useEffect33, useMemo as useMemo28, useState as useState21 } from "react";
30911
+
30912
+ // src/hooks/useGlbModel.ts
30913
+ import { useEffect as useEffect32, useMemo as useMemo27, useState as useState20 } from "react";
30914
+ function useGlbModel(source) {
30915
+ const request = useMemo27(() => ({ source }), [source]);
30916
+ const [result, setResult] = useState20();
30917
+ useEffect32(() => {
30918
+ const controller = new AbortController();
30919
+ let model;
30920
+ loadGlbScene(request.source, controller.signal).then((loaded) => {
30921
+ model = loaded;
30922
+ if (controller.signal.aborted) disposeGlbScene(loaded);
30923
+ else setResult({ request, model: loaded });
30924
+ }).catch((error) => {
30925
+ if (!controller.signal.aborted)
30926
+ setResult({
30927
+ request,
30928
+ error: error instanceof Error ? error.message : String(error)
30929
+ });
30930
+ });
30931
+ return () => {
30932
+ controller.abort();
30933
+ if (model) disposeGlbScene(model);
30934
+ };
30935
+ }, [request]);
30936
+ return result?.request === request ? result : void 0;
30851
30937
  }
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");
30938
+
30939
+ // src/CadViewerGlb.tsx
30940
+ import * as THREE58 from "three";
30941
+ import { Fragment as Fragment4, jsx as jsx20, jsxs as jsxs6 } from "react/jsx-runtime";
30942
+ function GlbScene({
30943
+ model,
30944
+ hiddenCadComponentIds
30945
+ }) {
30946
+ const { rootObject } = useThree();
30947
+ const { addHoverable, removeHoverable } = useHover();
30948
+ const [hover, setHover] = useState21();
30949
+ const bounds = useMemo28(() => {
30950
+ const box = new THREE58.Box3().setFromObject(model);
30951
+ if (box.isEmpty()) return;
30952
+ return {
30953
+ minX: box.min.x,
30954
+ maxX: box.max.x,
30955
+ minY: box.min.y,
30956
+ maxY: box.max.y,
30957
+ minZ: box.min.z,
30958
+ maxZ: box.max.z
30959
+ };
30960
+ }, [model]);
30961
+ useEffect33(() => {
30962
+ rootObject.add(model);
30963
+ return () => {
30964
+ rootObject.remove(model);
30965
+ };
30966
+ }, [rootObject, model]);
30967
+ useEffect33(() => {
30968
+ setHover(void 0);
30969
+ model.traverse((object) => {
30970
+ const id = object.userData.cad_component_id;
30971
+ if (typeof id === "string")
30972
+ object.visible = !hiddenCadComponentIds?.has(id);
30973
+ });
30974
+ }, [model, hiddenCadComponentIds]);
30975
+ useEffect33(() => {
30976
+ const meshes = [];
30977
+ model.traverse((mesh) => {
30978
+ if (!(mesh instanceof THREE58.Mesh)) return;
30979
+ let ancestor = mesh;
30980
+ while (ancestor) {
30981
+ if (!ancestor.visible) return;
30982
+ ancestor = ancestor.parent;
30983
+ }
30984
+ meshes.push(mesh);
30985
+ addHoverable({
30986
+ object: mesh,
30987
+ onHover: ({ mousePosition }) => {
30988
+ let object = mesh;
30989
+ let name;
30990
+ let visible = true;
30991
+ while (object) {
30992
+ name ??= getGlbComponentMetadata(object)?.componentName;
30993
+ visible &&= object.visible;
30994
+ object = object.parent;
30995
+ }
30996
+ setHover(
30997
+ name && visible ? { name, position: mousePosition } : void 0
30998
+ );
30999
+ },
31000
+ onUnhover: () => setHover(void 0)
31001
+ });
31002
+ });
31003
+ return () => {
31004
+ for (const mesh of meshes) removeHoverable(mesh);
31005
+ };
31006
+ }, [model, hiddenCadComponentIds, addHoverable, removeHoverable]);
31007
+ return /* @__PURE__ */ jsxs6(Fragment4, { children: [
31008
+ bounds && /* @__PURE__ */ jsx20(FitCameraToComparison, { bounds }),
31009
+ hover && /* @__PURE__ */ jsx20(
31010
+ Html,
31011
+ {
31012
+ position: hover.position,
31013
+ style: {
31014
+ background: "white",
31015
+ color: "black",
31016
+ padding: "5px",
31017
+ borderRadius: "3px",
31018
+ fontFamily: "sans-serif",
31019
+ transform: "translate(1rem, 1rem)"
31020
+ },
31021
+ children: hover.name
31022
+ }
31023
+ )
31024
+ ] });
31025
+ }
31026
+ function CadViewerGlb({
31027
+ source,
31028
+ hiddenCadComponentIds,
31029
+ ...containerProps
31030
+ }) {
31031
+ const result = useGlbModel(source);
31032
+ const framing = useMemo28(() => {
31033
+ if (!result?.model) return void 0;
31034
+ const bounds = new THREE58.Box3().setFromObject(result.model);
31035
+ if (bounds.isEmpty()) return void 0;
31036
+ return {
31037
+ boardDimensions: {
31038
+ width: bounds.max.x - bounds.min.x,
31039
+ height: bounds.max.y - bounds.min.y
31040
+ },
31041
+ boardCenter: {
31042
+ x: (bounds.min.x + bounds.max.x) / 2,
31043
+ y: (bounds.min.y + bounds.max.y) / 2
31044
+ }
31045
+ };
31046
+ }, [result, source]);
31047
+ if (!result) return /* @__PURE__ */ jsx20("div", { role: "status", children: "Loading 3D view..." });
31048
+ if (result.error)
31049
+ return /* @__PURE__ */ jsxs6("div", { role: "alert", children: [
31050
+ "Unable to load 3D view: ",
31051
+ result.error
31052
+ ] });
31053
+ if (!result.model) return null;
31054
+ return /* @__PURE__ */ jsx20(CadViewerContainer, { ...containerProps, ...framing, children: /* @__PURE__ */ jsx20(
31055
+ GlbScene,
31056
+ {
31057
+ model: result.model,
31058
+ hiddenCadComponentIds
31059
+ }
31060
+ ) });
31061
+ }
31062
+
31063
+ // node_modules/@radix-ui/react-dropdown-menu/dist/index.mjs
31064
+ import * as React42 from "react";
31065
+
31066
+ // node_modules/@radix-ui/primitive/dist/index.mjs
31067
+ var __defProp2 = Object.defineProperty;
31068
+ var __name = (target, value) => __defProp2(target, "name", { value, configurable: true });
31069
+ var canUseDOM = !!(typeof window !== "undefined" && window.document && window.document.createElement);
31070
+ function composeEventHandlers(originalEventHandler, ourEventHandler, { checkForDefaultPrevented = true } = {}) {
31071
+ return /* @__PURE__ */ __name(function handleEvent(event) {
31072
+ originalEventHandler?.(event);
31073
+ if (checkForDefaultPrevented === false || !event || !event.defaultPrevented) {
31074
+ return ourEventHandler?.(event);
31075
+ }
31076
+ }, "handleEvent");
31077
+ }
31078
+ __name(composeEventHandlers, "composeEventHandlers");
31079
+ function getOwnerWindow(element) {
31080
+ if (!canUseDOM) {
31081
+ throw new Error("Cannot access window outside of the DOM");
31082
+ }
31083
+ return element?.ownerDocument?.defaultView ?? window;
31084
+ }
31085
+ __name(getOwnerWindow, "getOwnerWindow");
31086
+ function getOwnerDocument(element) {
31087
+ if (!canUseDOM) {
31088
+ throw new Error("Cannot access document outside of the DOM");
31089
+ }
31090
+ return element?.ownerDocument ?? document;
31091
+ }
31092
+ __name(getOwnerDocument, "getOwnerDocument");
31093
+ function getActiveElement(node, activeDescendant = false) {
31094
+ const { activeElement } = getOwnerDocument(node);
31095
+ if (!activeElement?.nodeName) {
31096
+ return null;
31097
+ }
31098
+ if (isFrame(activeElement) && activeElement.contentDocument) {
31099
+ return getActiveElement(activeElement.contentDocument.body, activeDescendant);
31100
+ }
31101
+ if (activeDescendant) {
31102
+ const id = activeElement.getAttribute("aria-activedescendant");
30863
31103
  if (id) {
30864
31104
  const element = getOwnerDocument(activeElement).getElementById(id);
30865
31105
  if (element) {
@@ -30919,7 +31159,7 @@ __name2(useComposedRefs, "useComposedRefs");
30919
31159
 
30920
31160
  // node_modules/@radix-ui/react-context/dist/index.mjs
30921
31161
  import * as React12 from "react";
30922
- import { jsx as jsx20 } from "react/jsx-runtime";
31162
+ import { jsx as jsx21 } from "react/jsx-runtime";
30923
31163
  var __defProp4 = Object.defineProperty;
30924
31164
  var __name3 = (target, value) => __defProp4(target, "name", { value, configurable: true });
30925
31165
  // @__NO_SIDE_EFFECTS__
@@ -30929,7 +31169,7 @@ function createContext22(rootComponentName, defaultContext) {
30929
31169
  const Provider = /* @__PURE__ */ __name3((props) => {
30930
31170
  const { children, ...context } = props;
30931
31171
  const value = React12.useMemo(() => context, Object.values(context));
30932
- return /* @__PURE__ */ jsx20(Context.Provider, { value, children });
31172
+ return /* @__PURE__ */ jsx21(Context.Provider, { value, children });
30933
31173
  }, "Provider");
30934
31174
  Provider.displayName = rootComponentName + "Provider";
30935
31175
  function useContext22(consumerName, options = {}) {
@@ -30956,7 +31196,7 @@ function createContextScope(scopeName, createContextScopeDeps = []) {
30956
31196
  const { scope, children, ...context } = props;
30957
31197
  const Context = scope?.[scopeName]?.[index2] || BaseContext;
30958
31198
  const value = React12.useMemo(() => context, Object.values(context));
30959
- return /* @__PURE__ */ jsx20(Context.Provider, { value, children });
31199
+ return /* @__PURE__ */ jsx21(Context.Provider, { value, children });
30960
31200
  }, "Provider");
30961
31201
  Provider.displayName = rootComponentName + "Provider";
30962
31202
  function useContext22(consumerName, scope, options = {}) {
@@ -31341,7 +31581,7 @@ var createSlottableError = /* @__PURE__ */ __name6((ownerName) => {
31341
31581
  var use = React16[" use ".trim().toString()];
31342
31582
 
31343
31583
  // node_modules/@radix-ui/react-primitive/dist/index.mjs
31344
- import { jsx as jsx21 } from "react/jsx-runtime";
31584
+ import { jsx as jsx22 } from "react/jsx-runtime";
31345
31585
  var __defProp8 = Object.defineProperty;
31346
31586
  var __name7 = (target, value) => __defProp8(target, "name", { value, configurable: true });
31347
31587
  var NODES = [
@@ -31371,7 +31611,7 @@ var Primitive = NODES.reduce((primitive, node) => {
31371
31611
  if (typeof window !== "undefined") {
31372
31612
  window[/* @__PURE__ */ Symbol.for("radix-ui")] = true;
31373
31613
  }
31374
- return /* @__PURE__ */ jsx21(Comp, { ...primitiveProps, ref: forwardedRef });
31614
+ return /* @__PURE__ */ jsx22(Comp, { ...primitiveProps, ref: forwardedRef });
31375
31615
  });
31376
31616
  Node2.displayName = `Primitive.${node}`;
31377
31617
  return { ...primitive, [node]: Node2 };
@@ -31386,9 +31626,9 @@ import * as React41 from "react";
31386
31626
 
31387
31627
  // node_modules/@radix-ui/react-collection/dist/index.mjs
31388
31628
  import * as React18 from "react";
31389
- import { jsx as jsx22 } from "react/jsx-runtime";
31390
- import * as React23 from "react";
31391
31629
  import { jsx as jsx23 } from "react/jsx-runtime";
31630
+ import * as React23 from "react";
31631
+ import { jsx as jsx24 } from "react/jsx-runtime";
31392
31632
  var __defProp9 = Object.defineProperty;
31393
31633
  var __name8 = (target, value) => __defProp9(target, "name", { value, configurable: true });
31394
31634
  // @__NO_SIDE_EFFECTS__
@@ -31403,7 +31643,7 @@ function createCollection(name) {
31403
31643
  const { scope, children } = props;
31404
31644
  const ref = React18.useRef(null);
31405
31645
  const itemMap = React18.useRef(/* @__PURE__ */ new Map()).current;
31406
- return /* @__PURE__ */ jsx22(CollectionProviderImpl, { scope, itemMap, collectionRef: ref, children });
31646
+ return /* @__PURE__ */ jsx23(CollectionProviderImpl, { scope, itemMap, collectionRef: ref, children });
31407
31647
  }, "CollectionProvider");
31408
31648
  CollectionProvider.displayName = PROVIDER_NAME;
31409
31649
  const COLLECTION_SLOT_NAME = name + "CollectionSlot";
@@ -31413,7 +31653,7 @@ function createCollection(name) {
31413
31653
  const { scope, children } = props;
31414
31654
  const context = useCollectionContext(COLLECTION_SLOT_NAME, scope);
31415
31655
  const composedRefs = useComposedRefs(forwardedRef, context.collectionRef);
31416
- return /* @__PURE__ */ jsx22(CollectionSlotImpl, { ref: composedRefs, children });
31656
+ return /* @__PURE__ */ jsx23(CollectionSlotImpl, { ref: composedRefs, children });
31417
31657
  }
31418
31658
  );
31419
31659
  CollectionSlot.displayName = COLLECTION_SLOT_NAME;
@@ -31430,7 +31670,7 @@ function createCollection(name) {
31430
31670
  context.itemMap.set(ref, { ref, ...itemData });
31431
31671
  return () => void context.itemMap.delete(ref);
31432
31672
  });
31433
- return /* @__PURE__ */ jsx22(CollectionItemSlotImpl, { ...{ [ITEM_DATA_ATTR]: "" }, ref: composedRefs, children });
31673
+ return /* @__PURE__ */ jsx23(CollectionItemSlotImpl, { ...{ [ITEM_DATA_ATTR]: "" }, ref: composedRefs, children });
31434
31674
  }
31435
31675
  );
31436
31676
  CollectionItemSlot.displayName = ITEM_SLOT_NAME;
@@ -31786,12 +32026,12 @@ function createCollection2(name) {
31786
32026
  const [CollectionStatefulContextProvider, useStatefulCollectionContext] = createCollectionContext(PROVIDER_NAME);
31787
32027
  CollectionStatefulContextProvider.displayName = name + "CollectionStatefulContextProvider";
31788
32028
  const CollectionProvider = /* @__PURE__ */ __name8(({ state, ...props }) => {
31789
- return state ? /* @__PURE__ */ jsx23(CollectionProviderImpl, { ...props, state }) : /* @__PURE__ */ jsx23(CollectionInit, { ...props });
32029
+ return state ? /* @__PURE__ */ jsx24(CollectionProviderImpl, { ...props, state }) : /* @__PURE__ */ jsx24(CollectionInit, { ...props });
31790
32030
  }, "CollectionProvider");
31791
32031
  CollectionProvider.displayName = PROVIDER_NAME;
31792
32032
  const CollectionInit = /* @__PURE__ */ __name8((props) => {
31793
32033
  const state = useInitCollection();
31794
- return /* @__PURE__ */ jsx23(CollectionProviderImpl, { ...props, state });
32034
+ return /* @__PURE__ */ jsx24(CollectionProviderImpl, { ...props, state });
31795
32035
  }, "CollectionInit");
31796
32036
  CollectionInit.displayName = name + "CollectionInit";
31797
32037
  const CollectionProviderImpl = /* @__PURE__ */ __name8((props) => {
@@ -31831,7 +32071,7 @@ function createCollection2(name) {
31831
32071
  observer.disconnect();
31832
32072
  };
31833
32073
  }, [collectionElement, setCollection]);
31834
- return /* @__PURE__ */ jsx23(
32074
+ return /* @__PURE__ */ jsx24(
31835
32075
  CollectionStableContextProvider,
31836
32076
  {
31837
32077
  scope,
@@ -31840,7 +32080,7 @@ function createCollection2(name) {
31840
32080
  getCollection,
31841
32081
  setCollection,
31842
32082
  registryRef,
31843
- children: /* @__PURE__ */ jsx23(
32083
+ children: /* @__PURE__ */ jsx24(
31844
32084
  CollectionStatefulContextProvider,
31845
32085
  {
31846
32086
  scope,
@@ -31860,7 +32100,7 @@ function createCollection2(name) {
31860
32100
  const { scope, children } = props;
31861
32101
  const context = useStableCollectionContext(COLLECTION_SLOT_NAME, scope);
31862
32102
  const composedRefs = useComposedRefs(forwardedRef, context.collectionElementRef);
31863
- return /* @__PURE__ */ jsx23(CollectionSlotImpl, { ref: composedRefs, children });
32103
+ return /* @__PURE__ */ jsx24(CollectionSlotImpl, { ref: composedRefs, children });
31864
32104
  }
31865
32105
  );
31866
32106
  CollectionSlot.displayName = COLLECTION_SLOT_NAME;
@@ -31936,7 +32176,7 @@ function createCollection2(name) {
31936
32176
  });
31937
32177
  };
31938
32178
  }, [setCollection]);
31939
- return /* @__PURE__ */ jsx23(CollectionItemSlotImpl, { ...{ [ITEM_DATA_ATTR]: "" }, ref: composedRefs, children });
32179
+ return /* @__PURE__ */ jsx24(CollectionItemSlotImpl, { ...{ [ITEM_DATA_ATTR]: "" }, ref: composedRefs, children });
31940
32180
  }
31941
32181
  );
31942
32182
  CollectionItemSlot.displayName = ITEM_SLOT_NAME;
@@ -32017,7 +32257,7 @@ __name8(getChildListObserver, "getChildListObserver");
32017
32257
 
32018
32258
  // node_modules/@radix-ui/react-direction/dist/index.mjs
32019
32259
  import * as React19 from "react";
32020
- import { jsx as jsx24 } from "react/jsx-runtime";
32260
+ import { jsx as jsx25 } from "react/jsx-runtime";
32021
32261
  var __defProp10 = Object.defineProperty;
32022
32262
  var __name9 = (target, value) => __defProp10(target, "name", { value, configurable: true });
32023
32263
  var Direction = {
@@ -32055,7 +32295,7 @@ function useCallbackRef(callback) {
32055
32295
  __name10(useCallbackRef, "useCallbackRef");
32056
32296
 
32057
32297
  // node_modules/@radix-ui/react-dismissable-layer/dist/index.mjs
32058
- import { jsx as jsx25 } from "react/jsx-runtime";
32298
+ import { jsx as jsx26 } from "react/jsx-runtime";
32059
32299
  var __defProp12 = Object.defineProperty;
32060
32300
  var __name11 = (target, value) => __defProp12(target, "name", { value, configurable: true });
32061
32301
  var CONTEXT_UPDATE = "dismissableLayer.update";
@@ -32187,7 +32427,7 @@ var DismissableLayer = /* @__PURE__ */ React21.forwardRef(
32187
32427
  document.addEventListener(CONTEXT_UPDATE, handleUpdate);
32188
32428
  return () => document.removeEventListener(CONTEXT_UPDATE, handleUpdate);
32189
32429
  }, []);
32190
- return /* @__PURE__ */ jsx25(
32430
+ return /* @__PURE__ */ jsx26(
32191
32431
  Primitive.div,
32192
32432
  {
32193
32433
  ...layerProps,
@@ -32436,7 +32676,7 @@ __name12(createFocusGuard, "createFocusGuard");
32436
32676
 
32437
32677
  // node_modules/@radix-ui/react-focus-scope/dist/index.mjs
32438
32678
  import * as React25 from "react";
32439
- import { jsx as jsx26 } from "react/jsx-runtime";
32679
+ import { jsx as jsx27 } from "react/jsx-runtime";
32440
32680
  var __defProp14 = Object.defineProperty;
32441
32681
  var __name13 = (target, value) => __defProp14(target, "name", { value, configurable: true });
32442
32682
  var AUTOFOCUS_ON_MOUNT = "focusScope.autoFocusOnMount";
@@ -32575,7 +32815,7 @@ var FocusScope = /* @__PURE__ */ React25.forwardRef(
32575
32815
  },
32576
32816
  [loop, trapped, focusScope.paused]
32577
32817
  );
32578
- return /* @__PURE__ */ jsx26(Primitive.div, { tabIndex: -1, ...scopeProps, ref: composedRefs, onKeyDown: handleKeyDown });
32818
+ return /* @__PURE__ */ jsx27(Primitive.div, { tabIndex: -1, ...scopeProps, ref: composedRefs, onKeyDown: handleKeyDown });
32579
32819
  }, "FocusScope")
32580
32820
  );
32581
32821
  var FocusScopeBranchContext = React25.createContext(null);
@@ -32583,7 +32823,7 @@ function FocusScopeBranchProvider({ registry, children }) {
32583
32823
  if (!registry) {
32584
32824
  return children;
32585
32825
  }
32586
- return /* @__PURE__ */ jsx26(FocusScopeBranchContext.Provider, { value: registry, children });
32826
+ return /* @__PURE__ */ jsx27(FocusScopeBranchContext.Provider, { value: registry, children });
32587
32827
  }
32588
32828
  __name13(FocusScopeBranchProvider, "FocusScopeBranchProvider");
32589
32829
  function useFocusScopeBranchRegistry() {
@@ -34676,7 +34916,7 @@ function useSize(element) {
34676
34916
  __name15(useSize, "useSize");
34677
34917
 
34678
34918
  // node_modules/@radix-ui/react-popper/dist/index.mjs
34679
- import { jsx as jsx27 } from "react/jsx-runtime";
34919
+ import { jsx as jsx28 } from "react/jsx-runtime";
34680
34920
  var __defProp17 = Object.defineProperty;
34681
34921
  var __name16 = (target, value) => __defProp17(target, "name", { value, configurable: true });
34682
34922
  var Sticky = {
@@ -34694,7 +34934,7 @@ var Popper = /* @__PURE__ */ __name16((props) => {
34694
34934
  const { __scopePopper, children } = props;
34695
34935
  const [anchor, setAnchor] = React29.useState(null);
34696
34936
  const [placementState, setPlacementState] = React29.useState(void 0);
34697
- return /* @__PURE__ */ jsx27(
34937
+ return /* @__PURE__ */ jsx28(
34698
34938
  PopperProvider,
34699
34939
  {
34700
34940
  scope: __scopePopper,
@@ -34737,7 +34977,7 @@ var PopperAnchor = /* @__PURE__ */ React29.forwardRef(
34737
34977
  const sideAndAlign = context.placementState && getSideAndAlignFromPlacement(context.placementState);
34738
34978
  const placedSide = sideAndAlign?.[0];
34739
34979
  const placedAlign = sideAndAlign?.[1];
34740
- return virtualRef ? null : /* @__PURE__ */ jsx27(
34980
+ return virtualRef ? null : /* @__PURE__ */ jsx28(
34741
34981
  Primitive.div,
34742
34982
  {
34743
34983
  "data-radix-popper-side": placedSide,
@@ -34861,7 +35101,7 @@ var PopperContent = /* @__PURE__ */ React29.forwardRef(
34861
35101
  useLayoutEffect2(() => {
34862
35102
  if (content) setContentZIndex(window.getComputedStyle(content).zIndex);
34863
35103
  }, [content]);
34864
- return /* @__PURE__ */ jsx27(
35104
+ return /* @__PURE__ */ jsx28(
34865
35105
  "div",
34866
35106
  {
34867
35107
  ref: refs.setFloating,
@@ -34885,7 +35125,7 @@ var PopperContent = /* @__PURE__ */ React29.forwardRef(
34885
35125
  }
34886
35126
  },
34887
35127
  dir: props.dir,
34888
- children: /* @__PURE__ */ jsx27(
35128
+ children: /* @__PURE__ */ jsx28(
34889
35129
  PopperContentProvider,
34890
35130
  {
34891
35131
  scope: __scopePopper,
@@ -34895,7 +35135,7 @@ var PopperContent = /* @__PURE__ */ React29.forwardRef(
34895
35135
  arrowX,
34896
35136
  arrowY,
34897
35137
  shouldHideArrow: cannotCenterArrow,
34898
- children: /* @__PURE__ */ jsx27(
35138
+ children: /* @__PURE__ */ jsx28(
34899
35139
  Primitive.div,
34900
35140
  {
34901
35141
  "data-side": placedSide,
@@ -34961,7 +35201,7 @@ __name16(getSideAndAlignFromPlacement, "getSideAndAlignFromPlacement");
34961
35201
  // node_modules/@radix-ui/react-portal/dist/index.mjs
34962
35202
  import * as React30 from "react";
34963
35203
  import * as ReactDOM4 from "react-dom";
34964
- import { jsx as jsx28 } from "react/jsx-runtime";
35204
+ import { jsx as jsx29 } from "react/jsx-runtime";
34965
35205
  var __defProp18 = Object.defineProperty;
34966
35206
  var __name17 = (target, value) => __defProp18(target, "name", { value, configurable: true });
34967
35207
  var Portal = /* @__PURE__ */ React30.forwardRef(
@@ -34970,7 +35210,7 @@ var Portal = /* @__PURE__ */ React30.forwardRef(
34970
35210
  const [mounted, setMounted] = React30.useState(false);
34971
35211
  useLayoutEffect2(() => setMounted(true), []);
34972
35212
  const container = containerProp || mounted && globalThis?.document?.body;
34973
- return container ? ReactDOM4.createPortal(/* @__PURE__ */ jsx28(Primitive.div, { ...portalProps, ref: forwardedRef }), container) : null;
35213
+ return container ? ReactDOM4.createPortal(/* @__PURE__ */ jsx29(Primitive.div, { ...portalProps, ref: forwardedRef }), container) : null;
34974
35214
  }, "Portal")
34975
35215
  );
34976
35216
 
@@ -35190,7 +35430,7 @@ __name19(useIsHydratedModern, "useIsHydratedModern");
35190
35430
  var useIsHydrated2 = typeof useReactSyncExternalStore === "function" ? useIsHydratedModern : useIsHydrated;
35191
35431
 
35192
35432
  // node_modules/@radix-ui/react-roving-focus/dist/index.mjs
35193
- import { jsx as jsx29 } from "react/jsx-runtime";
35433
+ import { jsx as jsx30 } from "react/jsx-runtime";
35194
35434
  var __defProp21 = Object.defineProperty;
35195
35435
  var __name20 = (target, value) => __defProp21(target, "name", { value, configurable: true });
35196
35436
  var ENTRY_FOCUS = "rovingFocusGroup.onEntryFocus";
@@ -35213,7 +35453,7 @@ var [RovingFocusProvider, useRovingFocusContext] = createRovingFocusGroupContext
35213
35453
  var RovingFocusGroup = /* @__PURE__ */ React33.forwardRef(
35214
35454
  // blank line to reduce diff noise
35215
35455
  /* @__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 }) }) });
35456
+ return /* @__PURE__ */ jsx30(Collection.Provider, { scope: props.__scopeRovingFocusGroup, children: /* @__PURE__ */ jsx30(Collection.Slot, { scope: props.__scopeRovingFocusGroup, children: /* @__PURE__ */ jsx30(RovingFocusGroupImpl, { ...props, ref: forwardedRef }) }) });
35217
35457
  }, "RovingFocusGroup")
35218
35458
  );
35219
35459
  var RovingFocusGroupImpl = /* @__PURE__ */ React33.forwardRef(/* @__PURE__ */ __name20(function RovingFocusGroupImpl2(props, forwardedRef) {
@@ -35250,7 +35490,7 @@ var RovingFocusGroupImpl = /* @__PURE__ */ React33.forwardRef(/* @__PURE__ */ __
35250
35490
  return () => node.removeEventListener(ENTRY_FOCUS, handleEntryFocus);
35251
35491
  }
35252
35492
  }, [handleEntryFocus]);
35253
- return /* @__PURE__ */ jsx29(
35493
+ return /* @__PURE__ */ jsx30(
35254
35494
  RovingFocusProvider,
35255
35495
  {
35256
35496
  scope: __scopeRovingFocusGroup,
@@ -35271,7 +35511,7 @@ var RovingFocusGroupImpl = /* @__PURE__ */ React33.forwardRef(/* @__PURE__ */ __
35271
35511
  () => setFocusableItemsCount((prevCount) => prevCount - 1),
35272
35512
  []
35273
35513
  ),
35274
- children: /* @__PURE__ */ jsx29(
35514
+ children: /* @__PURE__ */ jsx30(
35275
35515
  Primitive.div,
35276
35516
  {
35277
35517
  tabIndex: isTabbingBackOut || focusableItemsCount === 0 ? -1 : 0,
@@ -35339,14 +35579,14 @@ var RovingFocusGroupItem = /* @__PURE__ */ React33.forwardRef(
35339
35579
  onFocusableItemAdd();
35340
35580
  return () => onFocusableItemRemove();
35341
35581
  }, [isHydrated, focusable, onFocusableItemAdd, onFocusableItemRemove]);
35342
- return /* @__PURE__ */ jsx29(
35582
+ return /* @__PURE__ */ jsx30(
35343
35583
  Collection.ItemSlot,
35344
35584
  {
35345
35585
  scope: __scopeRovingFocusGroup,
35346
35586
  id,
35347
35587
  focusable,
35348
35588
  active,
35349
- children: /* @__PURE__ */ jsx29(
35589
+ children: /* @__PURE__ */ jsx30(
35350
35590
  Primitive.span,
35351
35591
  {
35352
35592
  tabIndex: isCurrentTabStop ? 0 : -1,
@@ -35602,9 +35842,9 @@ function assignRef(ref, value) {
35602
35842
  }
35603
35843
 
35604
35844
  // node_modules/use-callback-ref/dist/es2015/useRef.js
35605
- import { useState as useState32 } from "react";
35845
+ import { useState as useState34 } from "react";
35606
35846
  function useCallbackRef2(initialValue, callback) {
35607
- var ref = useState32(function() {
35847
+ var ref = useState34(function() {
35608
35848
  return {
35609
35849
  // value
35610
35850
  value: initialValue,
@@ -36268,7 +36508,7 @@ ReactRemoveScroll.classNames = RemoveScroll.classNames;
36268
36508
  var Combination_default = ReactRemoveScroll;
36269
36509
 
36270
36510
  // node_modules/@radix-ui/react-menu/dist/index.mjs
36271
- import { jsx as jsx30 } from "react/jsx-runtime";
36511
+ import { jsx as jsx31 } from "react/jsx-runtime";
36272
36512
  var __defProp22 = Object.defineProperty;
36273
36513
  var __name21 = (target, value) => __defProp22(target, "name", { value, configurable: true });
36274
36514
  var Direction3 = {
@@ -36327,7 +36567,7 @@ var Menu = /* @__PURE__ */ __name21((props) => {
36327
36567
  window.addEventListener("blur", handleBlur);
36328
36568
  return () => window.removeEventListener("blur", handleBlur);
36329
36569
  }, [open, handleOpenChange]);
36330
- return /* @__PURE__ */ jsx30(Popper, { ...popperScope, children: /* @__PURE__ */ jsx30(
36570
+ return /* @__PURE__ */ jsx31(Popper, { ...popperScope, children: /* @__PURE__ */ jsx31(
36331
36571
  MenuProvider,
36332
36572
  {
36333
36573
  scope: __scopeMenu,
@@ -36335,7 +36575,7 @@ var Menu = /* @__PURE__ */ __name21((props) => {
36335
36575
  onOpenChange: handleOpenChange,
36336
36576
  content,
36337
36577
  onContentChange: setContent,
36338
- children: /* @__PURE__ */ jsx30(
36578
+ children: /* @__PURE__ */ jsx31(
36339
36579
  MenuRootProvider,
36340
36580
  {
36341
36581
  scope: __scopeMenu,
@@ -36353,7 +36593,7 @@ var MenuAnchor = /* @__PURE__ */ React41.forwardRef(
36353
36593
  /* @__PURE__ */ __name21(function MenuAnchor2(props, forwardedRef) {
36354
36594
  const { __scopeMenu, ...anchorProps } = props;
36355
36595
  const popperScope = usePopperScope(__scopeMenu);
36356
- return /* @__PURE__ */ jsx30(PopperAnchor, { ...popperScope, ...anchorProps, ref: forwardedRef });
36596
+ return /* @__PURE__ */ jsx31(PopperAnchor, { ...popperScope, ...anchorProps, ref: forwardedRef });
36357
36597
  }, "MenuAnchor")
36358
36598
  );
36359
36599
  var PORTAL_NAME = "MenuPortal";
@@ -36363,7 +36603,7 @@ var [PortalProvider, usePortalContext] = createMenuContext(PORTAL_NAME, {
36363
36603
  var MenuPortal = /* @__PURE__ */ __name21((props) => {
36364
36604
  const { __scopeMenu, forceMount, children, container } = props;
36365
36605
  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 }) }) });
36606
+ return /* @__PURE__ */ jsx31(PortalProvider, { scope: __scopeMenu, forceMount, children: /* @__PURE__ */ jsx31(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx31(Portal, { asChild: true, container, children }) }) });
36367
36607
  }, "MenuPortal");
36368
36608
  var CONTENT_NAME2 = "MenuContent";
36369
36609
  var [MenuContentProvider, useMenuContentContext] = createMenuContext(CONTENT_NAME2);
@@ -36373,7 +36613,7 @@ var MenuContent = /* @__PURE__ */ React41.forwardRef(
36373
36613
  const { forceMount = portalContext.forceMount, ...contentProps } = props;
36374
36614
  const context = useMenuContext(CONTENT_NAME2, props.__scopeMenu);
36375
36615
  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 }) }) }) });
36616
+ 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
36617
  }, "MenuContent")
36378
36618
  );
36379
36619
  var MenuRootContentModal = /* @__PURE__ */ React41.forwardRef(
@@ -36386,7 +36626,7 @@ var MenuRootContentModal = /* @__PURE__ */ React41.forwardRef(
36386
36626
  const content = ref.current;
36387
36627
  if (content) return hideOthers(content);
36388
36628
  }, []);
36389
- return /* @__PURE__ */ jsx30(
36629
+ return /* @__PURE__ */ jsx31(
36390
36630
  MenuContentImpl,
36391
36631
  {
36392
36632
  ...props,
@@ -36406,7 +36646,7 @@ var MenuRootContentModal = /* @__PURE__ */ React41.forwardRef(
36406
36646
  );
36407
36647
  var MenuRootContentNonModal = /* @__PURE__ */ React41.forwardRef(/* @__PURE__ */ __name21(function MenuRootContentNonModal2(props, forwardedRef) {
36408
36648
  const context = useMenuContext(CONTENT_NAME2, props.__scopeMenu);
36409
- return /* @__PURE__ */ jsx30(
36649
+ return /* @__PURE__ */ jsx31(
36410
36650
  MenuContentImpl,
36411
36651
  {
36412
36652
  ...props,
@@ -36498,7 +36738,7 @@ var MenuContentImpl = /* @__PURE__ */ React41.forwardRef(
36498
36738
  const isMovingTowards = pointerDirRef.current === pointerGraceIntentRef.current?.side;
36499
36739
  return isMovingTowards && isPointerInGraceArea(event, pointerGraceIntentRef.current?.area);
36500
36740
  }, []);
36501
- return /* @__PURE__ */ jsx30(
36741
+ return /* @__PURE__ */ jsx31(
36502
36742
  MenuContentProvider,
36503
36743
  {
36504
36744
  scope: __scopeMenu,
@@ -36527,7 +36767,7 @@ var MenuContentImpl = /* @__PURE__ */ React41.forwardRef(
36527
36767
  onPointerGraceIntentChange: React41.useCallback((intent) => {
36528
36768
  pointerGraceIntentRef.current = intent;
36529
36769
  }, []),
36530
- children: /* @__PURE__ */ jsx30(FocusScopeBranchProvider, { registry: isModal ? branchRegistry : null, children: /* @__PURE__ */ jsx30(ScrollLockWrapper, { ...scrollLockWrapperProps, children: /* @__PURE__ */ jsx30(
36770
+ children: /* @__PURE__ */ jsx31(FocusScopeBranchProvider, { registry: isModal ? branchRegistry : null, children: /* @__PURE__ */ jsx31(ScrollLockWrapper, { ...scrollLockWrapperProps, children: /* @__PURE__ */ jsx31(
36531
36771
  FocusScope,
36532
36772
  {
36533
36773
  asChild: true,
@@ -36538,7 +36778,7 @@ var MenuContentImpl = /* @__PURE__ */ React41.forwardRef(
36538
36778
  contentRef.current?.focus({ preventScroll: true });
36539
36779
  }),
36540
36780
  onUnmountAutoFocus: onCloseAutoFocus,
36541
- children: /* @__PURE__ */ jsx30(
36781
+ children: /* @__PURE__ */ jsx31(
36542
36782
  DismissableLayer,
36543
36783
  {
36544
36784
  asChild: true,
@@ -36548,7 +36788,7 @@ var MenuContentImpl = /* @__PURE__ */ React41.forwardRef(
36548
36788
  onFocusOutside,
36549
36789
  onInteractOutside,
36550
36790
  onDismiss,
36551
- children: /* @__PURE__ */ jsx30(
36791
+ children: /* @__PURE__ */ jsx31(
36552
36792
  RovingFocusGroup,
36553
36793
  {
36554
36794
  asChild: true,
@@ -36562,7 +36802,7 @@ var MenuContentImpl = /* @__PURE__ */ React41.forwardRef(
36562
36802
  if (!rootContext.isUsingKeyboardRef.current) event.preventDefault();
36563
36803
  }),
36564
36804
  preventScrollOnEntryFocus: true,
36565
- children: /* @__PURE__ */ jsx30(
36805
+ children: /* @__PURE__ */ jsx31(
36566
36806
  PopperContent,
36567
36807
  {
36568
36808
  role: "menu",
@@ -36646,7 +36886,7 @@ var MenuItem = /* @__PURE__ */ React41.forwardRef(
36646
36886
  }
36647
36887
  }
36648
36888
  }, "handleSelect");
36649
- return /* @__PURE__ */ jsx30(
36889
+ return /* @__PURE__ */ jsx31(
36650
36890
  MenuItemImpl,
36651
36891
  {
36652
36892
  ...itemProps,
@@ -36692,13 +36932,13 @@ var MenuItemImpl = /* @__PURE__ */ React41.forwardRef(
36692
36932
  setTextContent((menuItem.textContent ?? "").trim());
36693
36933
  }
36694
36934
  }, [itemProps.children]);
36695
- return /* @__PURE__ */ jsx30(
36935
+ return /* @__PURE__ */ jsx31(
36696
36936
  Collection2.ItemSlot,
36697
36937
  {
36698
36938
  scope: __scopeMenu,
36699
36939
  disabled,
36700
36940
  textValue: textValue ?? textContent,
36701
- children: /* @__PURE__ */ jsx30(RovingFocusGroupItem, { asChild: true, ...rovingFocusGroupScope, focusable: !disabled, children: /* @__PURE__ */ jsx30(
36941
+ children: /* @__PURE__ */ jsx31(RovingFocusGroupItem, { asChild: true, ...rovingFocusGroupScope, focusable: !disabled, children: /* @__PURE__ */ jsx31(
36702
36942
  Primitive.div,
36703
36943
  {
36704
36944
  role: "menuitem",
@@ -36737,7 +36977,7 @@ var MenuCheckboxItem = /* @__PURE__ */ React41.forwardRef(
36737
36977
  // blank line to reduce diff noise
36738
36978
  /* @__PURE__ */ __name21(function MenuCheckboxItem2(props, forwardedRef) {
36739
36979
  const { checked = false, onCheckedChange, ...checkboxItemProps } = props;
36740
- return /* @__PURE__ */ jsx30(ItemIndicatorProvider, { scope: props.__scopeMenu, checked, children: /* @__PURE__ */ jsx30(
36980
+ return /* @__PURE__ */ jsx31(ItemIndicatorProvider, { scope: props.__scopeMenu, checked, children: /* @__PURE__ */ jsx31(
36741
36981
  MenuItem,
36742
36982
  {
36743
36983
  role: "menuitemcheckbox",
@@ -36768,7 +37008,7 @@ var [ItemIndicatorProvider, useItemIndicatorContext] = createMenuContext(
36768
37008
  var MenuSeparator = /* @__PURE__ */ React41.forwardRef(
36769
37009
  /* @__PURE__ */ __name21(function MenuSeparator2(props, forwardedRef) {
36770
37010
  const { __scopeMenu, ...separatorProps } = props;
36771
- return /* @__PURE__ */ jsx30(
37011
+ return /* @__PURE__ */ jsx31(
36772
37012
  Primitive.div,
36773
37013
  {
36774
37014
  role: "separator",
@@ -36792,7 +37032,7 @@ var MenuSub = /* @__PURE__ */ __name21((props) => {
36792
37032
  if (parentMenuContext.open === false) handleOpenChange(false);
36793
37033
  return () => handleOpenChange(false);
36794
37034
  }, [parentMenuContext.open, handleOpenChange]);
36795
- return /* @__PURE__ */ jsx30(Popper, { ...popperScope, children: /* @__PURE__ */ jsx30(
37035
+ return /* @__PURE__ */ jsx31(Popper, { ...popperScope, children: /* @__PURE__ */ jsx31(
36796
37036
  MenuProvider,
36797
37037
  {
36798
37038
  scope: __scopeMenu,
@@ -36800,7 +37040,7 @@ var MenuSub = /* @__PURE__ */ __name21((props) => {
36800
37040
  onOpenChange: handleOpenChange,
36801
37041
  content,
36802
37042
  onContentChange: setContent,
36803
- children: /* @__PURE__ */ jsx30(
37043
+ children: /* @__PURE__ */ jsx31(
36804
37044
  MenuSubProvider,
36805
37045
  {
36806
37046
  scope: __scopeMenu,
@@ -36837,7 +37077,7 @@ var MenuSubTrigger = /* @__PURE__ */ React41.forwardRef(
36837
37077
  };
36838
37078
  }, [pointerGraceTimerRef, onPointerGraceIntentChange]);
36839
37079
  const composedRefs = useComposedRefs(forwardedRef, subContext.onTriggerChange);
36840
- return /* @__PURE__ */ jsx30(MenuAnchor, { asChild: true, ...scope, children: /* @__PURE__ */ jsx30(
37080
+ return /* @__PURE__ */ jsx31(MenuAnchor, { asChild: true, ...scope, children: /* @__PURE__ */ jsx31(
36841
37081
  MenuItemImpl,
36842
37082
  {
36843
37083
  id: subContext.triggerId,
@@ -36930,7 +37170,7 @@ var MenuSubContent = /* @__PURE__ */ React41.forwardRef(
36930
37170
  const subContext = useMenuSubContext(SUB_CONTENT_NAME, props.__scopeMenu);
36931
37171
  const ref = React41.useRef(null);
36932
37172
  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(
37173
+ 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
37174
  MenuContentImpl,
36935
37175
  {
36936
37176
  id: subContext.contentId,
@@ -37033,7 +37273,7 @@ function whenMouse(handler) {
37033
37273
  __name21(whenMouse, "whenMouse");
37034
37274
 
37035
37275
  // node_modules/@radix-ui/react-dropdown-menu/dist/index.mjs
37036
- import { jsx as jsx31 } from "react/jsx-runtime";
37276
+ import { jsx as jsx32 } from "react/jsx-runtime";
37037
37277
  var __defProp23 = Object.defineProperty;
37038
37278
  var __name22 = (target, value) => __defProp23(target, "name", { value, configurable: true });
37039
37279
  var DROPDOWN_MENU_NAME = "DropdownMenu";
@@ -37061,7 +37301,7 @@ var DropdownMenu = /* @__PURE__ */ __name22((props) => {
37061
37301
  onChange: onOpenChange,
37062
37302
  caller: DROPDOWN_MENU_NAME
37063
37303
  });
37064
- return /* @__PURE__ */ jsx31(
37304
+ return /* @__PURE__ */ jsx32(
37065
37305
  DropdownMenuProvider,
37066
37306
  {
37067
37307
  scope: __scopeDropdownMenu,
@@ -37072,7 +37312,7 @@ var DropdownMenu = /* @__PURE__ */ __name22((props) => {
37072
37312
  onOpenChange: setOpen,
37073
37313
  onOpenToggle: React42.useCallback(() => setOpen((prevOpen) => !prevOpen), [setOpen]),
37074
37314
  modal,
37075
- children: /* @__PURE__ */ jsx31(Menu, { ...menuScope, open, onOpenChange: setOpen, dir, modal, children })
37315
+ children: /* @__PURE__ */ jsx32(Menu, { ...menuScope, open, onOpenChange: setOpen, dir, modal, children })
37076
37316
  }
37077
37317
  );
37078
37318
  }, "DropdownMenu");
@@ -37084,7 +37324,7 @@ var DropdownMenuTrigger = /* @__PURE__ */ React42.forwardRef(
37084
37324
  const context = useDropdownMenuContext(TRIGGER_NAME, __scopeDropdownMenu);
37085
37325
  const menuScope = useMenuScope(__scopeDropdownMenu);
37086
37326
  const composedRefs = useComposedRefs(forwardedRef, context.triggerRef);
37087
- return /* @__PURE__ */ jsx31(MenuAnchor, { asChild: true, ...menuScope, children: /* @__PURE__ */ jsx31(
37327
+ return /* @__PURE__ */ jsx32(MenuAnchor, { asChild: true, ...menuScope, children: /* @__PURE__ */ jsx32(
37088
37328
  Primitive.button,
37089
37329
  {
37090
37330
  type: "button",
@@ -37116,7 +37356,7 @@ var DropdownMenuTrigger = /* @__PURE__ */ React42.forwardRef(
37116
37356
  var DropdownMenuPortal = /* @__PURE__ */ __name22((props) => {
37117
37357
  const { __scopeDropdownMenu, ...portalProps } = props;
37118
37358
  const menuScope = useMenuScope(__scopeDropdownMenu);
37119
- return /* @__PURE__ */ jsx31(MenuPortal, { ...menuScope, ...portalProps });
37359
+ return /* @__PURE__ */ jsx32(MenuPortal, { ...menuScope, ...portalProps });
37120
37360
  }, "DropdownMenuPortal");
37121
37361
  var CONTENT_NAME3 = "DropdownMenuContent";
37122
37362
  var DropdownMenuContent = /* @__PURE__ */ React42.forwardRef(
@@ -37126,7 +37366,7 @@ var DropdownMenuContent = /* @__PURE__ */ React42.forwardRef(
37126
37366
  const context = useDropdownMenuContext(CONTENT_NAME3, __scopeDropdownMenu);
37127
37367
  const menuScope = useMenuScope(__scopeDropdownMenu);
37128
37368
  const hasInteractedOutsideRef = React42.useRef(false);
37129
- return /* @__PURE__ */ jsx31(
37369
+ return /* @__PURE__ */ jsx32(
37130
37370
  MenuContent,
37131
37371
  {
37132
37372
  id: context.contentId,
@@ -37165,18 +37405,18 @@ var DropdownMenuItem = /* @__PURE__ */ React42.forwardRef(
37165
37405
  /* @__PURE__ */ __name22(function DropdownMenuItem2(props, forwardedRef) {
37166
37406
  const { __scopeDropdownMenu, ...itemProps } = props;
37167
37407
  const menuScope = useMenuScope(__scopeDropdownMenu);
37168
- return /* @__PURE__ */ jsx31(MenuItem, { ...menuScope, ...itemProps, ref: forwardedRef });
37408
+ return /* @__PURE__ */ jsx32(MenuItem, { ...menuScope, ...itemProps, ref: forwardedRef });
37169
37409
  }, "DropdownMenuItem")
37170
37410
  );
37171
37411
  var DropdownMenuCheckboxItem = /* @__PURE__ */ React42.forwardRef(/* @__PURE__ */ __name22(function DropdownMenuCheckboxItem2(props, forwardedRef) {
37172
37412
  const { __scopeDropdownMenu, ...checkboxItemProps } = props;
37173
37413
  const menuScope = useMenuScope(__scopeDropdownMenu);
37174
- return /* @__PURE__ */ jsx31(MenuCheckboxItem, { ...menuScope, ...checkboxItemProps, ref: forwardedRef });
37414
+ return /* @__PURE__ */ jsx32(MenuCheckboxItem, { ...menuScope, ...checkboxItemProps, ref: forwardedRef });
37175
37415
  }, "DropdownMenuCheckboxItem"));
37176
37416
  var DropdownMenuSeparator = /* @__PURE__ */ React42.forwardRef(/* @__PURE__ */ __name22(function DropdownMenuSeparator2(props, forwardedRef) {
37177
37417
  const { __scopeDropdownMenu, ...separatorProps } = props;
37178
37418
  const menuScope = useMenuScope(__scopeDropdownMenu);
37179
- return /* @__PURE__ */ jsx31(MenuSeparator, { ...menuScope, ...separatorProps, ref: forwardedRef });
37419
+ return /* @__PURE__ */ jsx32(MenuSeparator, { ...menuScope, ...separatorProps, ref: forwardedRef });
37180
37420
  }, "DropdownMenuSeparator"));
37181
37421
  var DropdownMenuSub = /* @__PURE__ */ __name22((props) => {
37182
37422
  const { __scopeDropdownMenu, children, open: openProp, onOpenChange, defaultOpen } = props;
@@ -37187,17 +37427,17 @@ var DropdownMenuSub = /* @__PURE__ */ __name22((props) => {
37187
37427
  onChange: onOpenChange,
37188
37428
  caller: "DropdownMenuSub"
37189
37429
  });
37190
- return /* @__PURE__ */ jsx31(MenuSub, { ...menuScope, open, onOpenChange: setOpen, children });
37430
+ return /* @__PURE__ */ jsx32(MenuSub, { ...menuScope, open, onOpenChange: setOpen, children });
37191
37431
  }, "DropdownMenuSub");
37192
37432
  var DropdownMenuSubTrigger = /* @__PURE__ */ React42.forwardRef(/* @__PURE__ */ __name22(function DropdownMenuSubTrigger2(props, forwardedRef) {
37193
37433
  const { __scopeDropdownMenu, ...subTriggerProps } = props;
37194
37434
  const menuScope = useMenuScope(__scopeDropdownMenu);
37195
- return /* @__PURE__ */ jsx31(MenuSubTrigger, { ...menuScope, ...subTriggerProps, ref: forwardedRef });
37435
+ return /* @__PURE__ */ jsx32(MenuSubTrigger, { ...menuScope, ...subTriggerProps, ref: forwardedRef });
37196
37436
  }, "DropdownMenuSubTrigger"));
37197
37437
  var DropdownMenuSubContent = /* @__PURE__ */ React42.forwardRef(/* @__PURE__ */ __name22(function DropdownMenuSubContent2(props, forwardedRef) {
37198
37438
  const { __scopeDropdownMenu, ...subContentProps } = props;
37199
37439
  const menuScope = useMenuScope(__scopeDropdownMenu);
37200
- return /* @__PURE__ */ jsx31(
37440
+ return /* @__PURE__ */ jsx32(
37201
37441
  MenuSubContent,
37202
37442
  {
37203
37443
  ...menuScope,
@@ -37219,11 +37459,11 @@ var DropdownMenuSubContent = /* @__PURE__ */ React42.forwardRef(/* @__PURE__ */
37219
37459
  }, "DropdownMenuSubContent"));
37220
37460
 
37221
37461
  // src/components/ViewportSubContent.tsx
37222
- import { useLayoutEffect as useLayoutEffect5, useState as useState36 } from "react";
37223
- import { jsx as jsx32 } from "react/jsx-runtime";
37462
+ import { useLayoutEffect as useLayoutEffect5, useState as useState38 } from "react";
37463
+ import { jsx as jsx33 } from "react/jsx-runtime";
37224
37464
  var ViewportSubContent = (props) => {
37225
- const [content, setContent] = useState36(null);
37226
- const [overlapWidth, setOverlapWidth] = useState36();
37465
+ const [content, setContent] = useState38(null);
37466
+ const [overlapWidth, setOverlapWidth] = useState38();
37227
37467
  useLayoutEffect5(() => {
37228
37468
  if (!content) return;
37229
37469
  const trigger = document.getElementById(
@@ -37251,7 +37491,7 @@ var ViewportSubContent = (props) => {
37251
37491
  window.removeEventListener("resize", update);
37252
37492
  };
37253
37493
  }, [content]);
37254
- return /* @__PURE__ */ jsx32(
37494
+ return /* @__PURE__ */ jsx33(
37255
37495
  DropdownMenuSubContent,
37256
37496
  {
37257
37497
  ...props,
@@ -37278,14 +37518,14 @@ var menuViewportStyles = {
37278
37518
  };
37279
37519
 
37280
37520
  // src/components/ContextMenu.tsx
37281
- import { useState as useState38 } from "react";
37521
+ import { useState as useState40 } from "react";
37282
37522
 
37283
37523
  // src/components/AppearanceMenu.tsx
37284
- import { useState as useState37 } from "react";
37524
+ import { useState as useState39 } from "react";
37285
37525
 
37286
37526
  // src/components/Icons.tsx
37287
- import { jsx as jsx33 } from "react/jsx-runtime";
37288
- var CheckIcon = () => /* @__PURE__ */ jsx33(
37527
+ import { jsx as jsx34 } from "react/jsx-runtime";
37528
+ var CheckIcon = () => /* @__PURE__ */ jsx34(
37289
37529
  "svg",
37290
37530
  {
37291
37531
  xmlns: "http://www.w3.org/2000/svg",
@@ -37297,10 +37537,10 @@ var CheckIcon = () => /* @__PURE__ */ jsx33(
37297
37537
  strokeWidth: "2",
37298
37538
  strokeLinecap: "round",
37299
37539
  strokeLinejoin: "round",
37300
- children: /* @__PURE__ */ jsx33("path", { d: "M20 6 9 17l-5-5" })
37540
+ children: /* @__PURE__ */ jsx34("path", { d: "M20 6 9 17l-5-5" })
37301
37541
  }
37302
37542
  );
37303
- var ChevronRightIcon = ({ isOpen }) => /* @__PURE__ */ jsx33(
37543
+ var ChevronRightIcon = ({ isOpen }) => /* @__PURE__ */ jsx34(
37304
37544
  "svg",
37305
37545
  {
37306
37546
  xmlns: "http://www.w3.org/2000/svg",
@@ -37317,10 +37557,10 @@ var ChevronRightIcon = ({ isOpen }) => /* @__PURE__ */ jsx33(
37317
37557
  transform: isOpen ? "rotate(90deg)" : "rotate(0deg)",
37318
37558
  opacity: 0.6
37319
37559
  },
37320
- children: /* @__PURE__ */ jsx33("path", { d: "m9 18 6-6-6-6" })
37560
+ children: /* @__PURE__ */ jsx34("path", { d: "m9 18 6-6-6-6" })
37321
37561
  }
37322
37562
  );
37323
- var CheckMinusIcon = () => /* @__PURE__ */ jsx33(
37563
+ var CheckMinusIcon = () => /* @__PURE__ */ jsx34(
37324
37564
  "svg",
37325
37565
  {
37326
37566
  xmlns: "http://www.w3.org/2000/svg",
@@ -37332,10 +37572,10 @@ var CheckMinusIcon = () => /* @__PURE__ */ jsx33(
37332
37572
  strokeWidth: "2",
37333
37573
  strokeLinecap: "round",
37334
37574
  strokeLinejoin: "round",
37335
- children: /* @__PURE__ */ jsx33("path", { d: "M5 12h14" })
37575
+ children: /* @__PURE__ */ jsx34("path", { d: "M5 12h14" })
37336
37576
  }
37337
37577
  );
37338
- var DotIcon = () => /* @__PURE__ */ jsx33(
37578
+ var DotIcon = () => /* @__PURE__ */ jsx34(
37339
37579
  "svg",
37340
37580
  {
37341
37581
  xmlns: "http://www.w3.org/2000/svg",
@@ -37348,12 +37588,12 @@ var DotIcon = () => /* @__PURE__ */ jsx33(
37348
37588
  strokeLinecap: "round",
37349
37589
  strokeLinejoin: "round",
37350
37590
  className: "lucide lucide-dot-icon lucide-dot",
37351
- children: /* @__PURE__ */ jsx33("circle", { cx: "12.1", cy: "12.1", r: "4.5", fill: "white" })
37591
+ children: /* @__PURE__ */ jsx34("circle", { cx: "12.1", cy: "12.1", r: "4.5", fill: "white" })
37352
37592
  }
37353
37593
  );
37354
37594
 
37355
37595
  // src/components/AppearanceMenu.tsx
37356
- import { Fragment as Fragment8, jsx as jsx34, jsxs as jsxs6 } from "react/jsx-runtime";
37596
+ import { Fragment as Fragment9, jsx as jsx35, jsxs as jsxs7 } from "react/jsx-runtime";
37357
37597
  var itemStyles = {
37358
37598
  padding: "6px 8px",
37359
37599
  borderRadius: 6,
@@ -37400,7 +37640,9 @@ var iconContainerStyles = {
37400
37640
  justifyContent: "center",
37401
37641
  flexShrink: 0
37402
37642
  };
37403
- var AppearanceMenu = () => {
37643
+ var AppearanceMenu = ({
37644
+ showLayerControls = true
37645
+ }) => {
37404
37646
  const { visibility, setLayerVisibility } = useLayerVisibility();
37405
37647
  const {
37406
37648
  darkBackgroundEnabled,
@@ -37408,12 +37650,12 @@ var AppearanceMenu = () => {
37408
37650
  lightingEnabled,
37409
37651
  setLightingEnabled
37410
37652
  } = 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(
37653
+ const [appearanceSubOpen, setAppearanceSubOpen] = useState39(false);
37654
+ const [hoveredItem, setHoveredItem] = useState39(null);
37655
+ return /* @__PURE__ */ jsxs7(Fragment9, { children: [
37656
+ /* @__PURE__ */ jsx35(DropdownMenuSeparator, { style: separatorStyles }),
37657
+ /* @__PURE__ */ jsxs7(DropdownMenuSub, { onOpenChange: setAppearanceSubOpen, children: [
37658
+ /* @__PURE__ */ jsxs7(
37417
37659
  DropdownMenuSubTrigger,
37418
37660
  {
37419
37661
  style: {
@@ -37425,8 +37667,8 @@ var AppearanceMenu = () => {
37425
37667
  onMouseLeave: () => setHoveredItem(null),
37426
37668
  onTouchStart: () => setHoveredItem("appearance"),
37427
37669
  children: [
37428
- /* @__PURE__ */ jsx34("span", { style: { flex: 1, display: "flex", alignItems: "center" }, children: "Appearance" }),
37429
- /* @__PURE__ */ jsx34(
37670
+ /* @__PURE__ */ jsx35("span", { style: { flex: 1, display: "flex", alignItems: "center" }, children: "Appearance" }),
37671
+ /* @__PURE__ */ jsx35(
37430
37672
  "div",
37431
37673
  {
37432
37674
  style: {
@@ -37435,20 +37677,20 @@ var AppearanceMenu = () => {
37435
37677
  alignItems: "flex-end",
37436
37678
  marginBottom: "-5px"
37437
37679
  },
37438
- children: /* @__PURE__ */ jsx34(ChevronRightIcon, { isOpen: appearanceSubOpen })
37680
+ children: /* @__PURE__ */ jsx35(ChevronRightIcon, { isOpen: appearanceSubOpen })
37439
37681
  }
37440
37682
  )
37441
37683
  ]
37442
37684
  }
37443
37685
  ),
37444
- /* @__PURE__ */ jsx34(DropdownMenuPortal, { children: /* @__PURE__ */ jsxs6(
37686
+ /* @__PURE__ */ jsx35(DropdownMenuPortal, { children: /* @__PURE__ */ jsxs7(
37445
37687
  ViewportSubContent,
37446
37688
  {
37447
37689
  style: { ...contentStyles, marginLeft: -2 },
37448
37690
  collisionPadding: 10,
37449
37691
  avoidCollisions: true,
37450
37692
  children: [
37451
- /* @__PURE__ */ jsxs6(
37693
+ /* @__PURE__ */ jsxs7(
37452
37694
  DropdownMenuItem,
37453
37695
  {
37454
37696
  style: {
@@ -37464,12 +37706,12 @@ var AppearanceMenu = () => {
37464
37706
  onMouseLeave: () => setHoveredItem(null),
37465
37707
  onTouchStart: () => setHoveredItem("darkBackground"),
37466
37708
  children: [
37467
- /* @__PURE__ */ jsx34("span", { style: iconContainerStyles, children: darkBackgroundEnabled && /* @__PURE__ */ jsx34(CheckIcon, {}) }),
37468
- /* @__PURE__ */ jsx34("span", { style: { display: "flex", alignItems: "center" }, children: "Dark Background" })
37709
+ /* @__PURE__ */ jsx35("span", { style: iconContainerStyles, children: darkBackgroundEnabled && /* @__PURE__ */ jsx35(CheckIcon, {}) }),
37710
+ /* @__PURE__ */ jsx35("span", { style: { display: "flex", alignItems: "center" }, children: "Dark Background" })
37469
37711
  ]
37470
37712
  }
37471
37713
  ),
37472
- /* @__PURE__ */ jsxs6(
37714
+ /* @__PURE__ */ jsxs7(
37473
37715
  DropdownMenuItem,
37474
37716
  {
37475
37717
  style: {
@@ -37485,278 +37727,283 @@ var AppearanceMenu = () => {
37485
37727
  onMouseLeave: () => setHoveredItem(null),
37486
37728
  onTouchStart: () => setHoveredItem("lighting"),
37487
37729
  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" })
37730
+ /* @__PURE__ */ jsx35("span", { style: iconContainerStyles, children: lightingEnabled && /* @__PURE__ */ jsx35(CheckIcon, {}) }),
37731
+ /* @__PURE__ */ jsx35("span", { style: { display: "flex", alignItems: "center" }, children: "Lighting" })
37596
37732
  ]
37597
37733
  }
37598
37734
  ),
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" })
37704
- ]
37705
- }
37706
- ),
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
- )
37735
+ showLayerControls && /* @__PURE__ */ jsxs7(Fragment9, { children: [
37736
+ /* @__PURE__ */ jsx35(DropdownMenuSeparator, { style: separatorStyles }),
37737
+ /* @__PURE__ */ jsxs7(
37738
+ DropdownMenuItem,
37739
+ {
37740
+ style: {
37741
+ ...itemStyles,
37742
+ backgroundColor: hoveredItem === "boardBody" ? "#404040" : "transparent"
37743
+ },
37744
+ onSelect: (e) => e.preventDefault(),
37745
+ onPointerDown: (e) => {
37746
+ e.preventDefault();
37747
+ setLayerVisibility("boardBody", !visibility.boardBody);
37748
+ },
37749
+ onMouseEnter: () => setHoveredItem("boardBody"),
37750
+ onMouseLeave: () => setHoveredItem(null),
37751
+ onTouchStart: () => setHoveredItem("boardBody"),
37752
+ children: [
37753
+ /* @__PURE__ */ jsx35("span", { style: iconContainerStyles, children: visibility.boardBody && /* @__PURE__ */ jsx35(CheckIcon, {}) }),
37754
+ /* @__PURE__ */ jsx35("span", { style: { display: "flex", alignItems: "center" }, children: "Board Body" })
37755
+ ]
37756
+ }
37757
+ ),
37758
+ /* @__PURE__ */ jsxs7(
37759
+ DropdownMenuItem,
37760
+ {
37761
+ style: {
37762
+ ...itemStyles,
37763
+ backgroundColor: hoveredItem === "topCopper" ? "#404040" : "transparent"
37764
+ },
37765
+ onSelect: (e) => e.preventDefault(),
37766
+ onPointerDown: (e) => {
37767
+ e.preventDefault();
37768
+ setLayerVisibility("topCopper", !visibility.topCopper);
37769
+ },
37770
+ onMouseEnter: () => setHoveredItem("topCopper"),
37771
+ onMouseLeave: () => setHoveredItem(null),
37772
+ onTouchStart: () => setHoveredItem("topCopper"),
37773
+ children: [
37774
+ /* @__PURE__ */ jsx35("span", { style: iconContainerStyles, children: visibility.topCopper && /* @__PURE__ */ jsx35(CheckIcon, {}) }),
37775
+ /* @__PURE__ */ jsx35("span", { style: { display: "flex", alignItems: "center" }, children: "Top Copper" })
37776
+ ]
37777
+ }
37778
+ ),
37779
+ /* @__PURE__ */ jsxs7(
37780
+ DropdownMenuItem,
37781
+ {
37782
+ style: {
37783
+ ...itemStyles,
37784
+ backgroundColor: hoveredItem === "bottomCopper" ? "#404040" : "transparent"
37785
+ },
37786
+ onSelect: (e) => e.preventDefault(),
37787
+ onPointerDown: (e) => {
37788
+ e.preventDefault();
37789
+ setLayerVisibility("bottomCopper", !visibility.bottomCopper);
37790
+ },
37791
+ onMouseEnter: () => setHoveredItem("bottomCopper"),
37792
+ onMouseLeave: () => setHoveredItem(null),
37793
+ onTouchStart: () => setHoveredItem("bottomCopper"),
37794
+ children: [
37795
+ /* @__PURE__ */ jsx35("span", { style: iconContainerStyles, children: visibility.bottomCopper && /* @__PURE__ */ jsx35(CheckIcon, {}) }),
37796
+ /* @__PURE__ */ jsx35("span", { style: { display: "flex", alignItems: "center" }, children: "Bottom Copper" })
37797
+ ]
37798
+ }
37799
+ ),
37800
+ /* @__PURE__ */ jsxs7(
37801
+ DropdownMenuItem,
37802
+ {
37803
+ style: {
37804
+ ...itemStyles,
37805
+ backgroundColor: hoveredItem === "keepout" ? "#404040" : "transparent"
37806
+ },
37807
+ onSelect: (e) => e.preventDefault(),
37808
+ onPointerDown: (e) => {
37809
+ e.preventDefault();
37810
+ setLayerVisibility("keepout", !visibility.keepout);
37811
+ },
37812
+ onMouseEnter: () => setHoveredItem("keepout"),
37813
+ onMouseLeave: () => setHoveredItem(null),
37814
+ onTouchStart: () => setHoveredItem("keepout"),
37815
+ children: [
37816
+ /* @__PURE__ */ jsx35("span", { style: iconContainerStyles, children: visibility.keepout && /* @__PURE__ */ jsx35(CheckIcon, {}) }),
37817
+ /* @__PURE__ */ jsx35("span", { style: { display: "flex", alignItems: "center" }, children: "Keepout" })
37818
+ ]
37819
+ }
37820
+ ),
37821
+ /* @__PURE__ */ jsxs7(
37822
+ DropdownMenuItem,
37823
+ {
37824
+ style: {
37825
+ ...itemStyles,
37826
+ backgroundColor: hoveredItem === "topSilkscreen" ? "#404040" : "transparent"
37827
+ },
37828
+ onSelect: (e) => e.preventDefault(),
37829
+ onPointerDown: (e) => {
37830
+ e.preventDefault();
37831
+ setLayerVisibility(
37832
+ "topSilkscreen",
37833
+ !visibility.topSilkscreen
37834
+ );
37835
+ },
37836
+ onMouseEnter: () => setHoveredItem("topSilkscreen"),
37837
+ onMouseLeave: () => setHoveredItem(null),
37838
+ onTouchStart: () => setHoveredItem("topSilkscreen"),
37839
+ children: [
37840
+ /* @__PURE__ */ jsx35("span", { style: iconContainerStyles, children: visibility.topSilkscreen && /* @__PURE__ */ jsx35(CheckIcon, {}) }),
37841
+ /* @__PURE__ */ jsx35("span", { style: { display: "flex", alignItems: "center" }, children: "Top Silkscreen" })
37842
+ ]
37843
+ }
37844
+ ),
37845
+ /* @__PURE__ */ jsxs7(
37846
+ DropdownMenuItem,
37847
+ {
37848
+ style: {
37849
+ ...itemStyles,
37850
+ backgroundColor: hoveredItem === "bottomSilkscreen" ? "#404040" : "transparent"
37851
+ },
37852
+ onSelect: (e) => e.preventDefault(),
37853
+ onPointerDown: (e) => {
37854
+ e.preventDefault();
37855
+ setLayerVisibility(
37856
+ "bottomSilkscreen",
37857
+ !visibility.bottomSilkscreen
37858
+ );
37859
+ },
37860
+ onMouseEnter: () => setHoveredItem("bottomSilkscreen"),
37861
+ onMouseLeave: () => setHoveredItem(null),
37862
+ onTouchStart: () => setHoveredItem("bottomSilkscreen"),
37863
+ children: [
37864
+ /* @__PURE__ */ jsx35("span", { style: iconContainerStyles, children: visibility.bottomSilkscreen && /* @__PURE__ */ jsx35(CheckIcon, {}) }),
37865
+ /* @__PURE__ */ jsx35("span", { style: { display: "flex", alignItems: "center" }, children: "Bottom Silkscreen" })
37866
+ ]
37867
+ }
37868
+ ),
37869
+ /* @__PURE__ */ jsxs7(
37870
+ DropdownMenuItem,
37871
+ {
37872
+ style: {
37873
+ ...itemStyles,
37874
+ backgroundColor: hoveredItem === "topMask" ? "#404040" : "transparent"
37875
+ },
37876
+ onSelect: (e) => e.preventDefault(),
37877
+ onPointerDown: (e) => {
37878
+ e.preventDefault();
37879
+ setLayerVisibility("topMask", !visibility.topMask);
37880
+ },
37881
+ onMouseEnter: () => setHoveredItem("topMask"),
37882
+ onMouseLeave: () => setHoveredItem(null),
37883
+ onTouchStart: () => setHoveredItem("topMask"),
37884
+ children: [
37885
+ /* @__PURE__ */ jsx35("span", { style: iconContainerStyles, children: visibility.topMask && /* @__PURE__ */ jsx35(CheckIcon, {}) }),
37886
+ /* @__PURE__ */ jsx35("span", { style: { display: "flex", alignItems: "center" }, children: "Top Soldermask" })
37887
+ ]
37888
+ }
37889
+ ),
37890
+ /* @__PURE__ */ jsxs7(
37891
+ DropdownMenuItem,
37892
+ {
37893
+ style: {
37894
+ ...itemStyles,
37895
+ backgroundColor: hoveredItem === "bottomMask" ? "#404040" : "transparent"
37896
+ },
37897
+ onSelect: (e) => e.preventDefault(),
37898
+ onPointerDown: (e) => {
37899
+ e.preventDefault();
37900
+ setLayerVisibility("bottomMask", !visibility.bottomMask);
37901
+ },
37902
+ onMouseEnter: () => setHoveredItem("bottomMask"),
37903
+ onMouseLeave: () => setHoveredItem(null),
37904
+ onTouchStart: () => setHoveredItem("bottomMask"),
37905
+ children: [
37906
+ /* @__PURE__ */ jsx35("span", { style: iconContainerStyles, children: visibility.bottomMask && /* @__PURE__ */ jsx35(CheckIcon, {}) }),
37907
+ /* @__PURE__ */ jsx35("span", { style: { display: "flex", alignItems: "center" }, children: "Bottom Soldermask" })
37908
+ ]
37909
+ }
37910
+ ),
37911
+ /* @__PURE__ */ jsxs7(
37912
+ DropdownMenuItem,
37913
+ {
37914
+ style: {
37915
+ ...itemStyles,
37916
+ backgroundColor: hoveredItem === "pcbNotes" ? "#404040" : "transparent"
37917
+ },
37918
+ onSelect: (e) => e.preventDefault(),
37919
+ onPointerDown: (e) => {
37920
+ e.preventDefault();
37921
+ setLayerVisibility("pcbNotes", !visibility.pcbNotes);
37922
+ },
37923
+ onMouseEnter: () => setHoveredItem("pcbNotes"),
37924
+ onMouseLeave: () => setHoveredItem(null),
37925
+ onTouchStart: () => setHoveredItem("pcbNotes"),
37926
+ children: [
37927
+ /* @__PURE__ */ jsx35("span", { style: iconContainerStyles, children: visibility.pcbNotes && /* @__PURE__ */ jsx35(CheckIcon, {}) }),
37928
+ /* @__PURE__ */ jsx35("span", { style: { display: "flex", alignItems: "center" }, children: "PCB Notes" })
37929
+ ]
37930
+ }
37931
+ ),
37932
+ /* @__PURE__ */ jsxs7(
37933
+ DropdownMenuItem,
37934
+ {
37935
+ style: {
37936
+ ...itemStyles,
37937
+ backgroundColor: hoveredItem === "smtModels" ? "#404040" : "transparent"
37938
+ },
37939
+ onSelect: (e) => e.preventDefault(),
37940
+ onPointerDown: (e) => {
37941
+ e.preventDefault();
37942
+ setLayerVisibility("smtModels", !visibility.smtModels);
37943
+ },
37944
+ onMouseEnter: () => setHoveredItem("smtModels"),
37945
+ onMouseLeave: () => setHoveredItem(null),
37946
+ onTouchStart: () => setHoveredItem("smtModels"),
37947
+ children: [
37948
+ /* @__PURE__ */ jsx35("span", { style: iconContainerStyles, children: visibility.smtModels && /* @__PURE__ */ jsx35(CheckIcon, {}) }),
37949
+ /* @__PURE__ */ jsx35("span", { style: { display: "flex", alignItems: "center" }, children: "Surface Mount Components" })
37950
+ ]
37951
+ }
37952
+ ),
37953
+ /* @__PURE__ */ jsxs7(
37954
+ DropdownMenuItem,
37955
+ {
37956
+ style: {
37957
+ ...itemStyles,
37958
+ backgroundColor: hoveredItem === "throughHoleModels" ? "#404040" : "transparent"
37959
+ },
37960
+ onSelect: (e) => e.preventDefault(),
37961
+ onPointerDown: (e) => {
37962
+ e.preventDefault();
37963
+ setLayerVisibility(
37964
+ "throughHoleModels",
37965
+ !visibility.throughHoleModels
37966
+ );
37967
+ },
37968
+ onMouseEnter: () => setHoveredItem("throughHoleModels"),
37969
+ onMouseLeave: () => setHoveredItem(null),
37970
+ onTouchStart: () => setHoveredItem("throughHoleModels"),
37971
+ children: [
37972
+ /* @__PURE__ */ jsx35("span", { style: iconContainerStyles, children: visibility.throughHoleModels && /* @__PURE__ */ jsx35(CheckIcon, {}) }),
37973
+ /* @__PURE__ */ jsx35("span", { style: { display: "flex", alignItems: "center" }, children: "Through-Hole Components" })
37974
+ ]
37975
+ }
37976
+ ),
37977
+ /* @__PURE__ */ jsx35(DropdownMenuSeparator, { style: separatorStyles }),
37978
+ /* @__PURE__ */ jsxs7(
37979
+ DropdownMenuItem,
37980
+ {
37981
+ style: {
37982
+ ...itemStyles,
37983
+ backgroundColor: hoveredItem === "enclosure" ? "#404040" : "transparent"
37984
+ },
37985
+ onSelect: (e) => e.preventDefault(),
37986
+ onPointerDown: (e) => {
37987
+ e.preventDefault();
37988
+ setLayerVisibility(
37989
+ "enclosure",
37990
+ nextEnclosureVisibility(visibility.enclosure)
37991
+ );
37992
+ },
37993
+ onMouseEnter: () => setHoveredItem("enclosure"),
37994
+ onMouseLeave: () => setHoveredItem(null),
37995
+ onTouchStart: () => setHoveredItem("enclosure"),
37996
+ title: `Enclosure: ${visibility.enclosure}`,
37997
+ children: [
37998
+ /* @__PURE__ */ jsxs7("span", { style: iconContainerStyles, children: [
37999
+ visibility.enclosure === "opaque" && /* @__PURE__ */ jsx35(CheckIcon, {}),
38000
+ visibility.enclosure === "translucent" && /* @__PURE__ */ jsx35(CheckMinusIcon, {})
38001
+ ] }),
38002
+ /* @__PURE__ */ jsx35("span", { style: { display: "flex", alignItems: "center" }, children: "Enclosure" })
38003
+ ]
38004
+ }
38005
+ )
38006
+ ] })
37760
38007
  ]
37761
38008
  }
37762
38009
  ) })
@@ -37765,7 +38012,7 @@ var AppearanceMenu = () => {
37765
38012
  };
37766
38013
 
37767
38014
  // src/components/ContextMenu.tsx
37768
- import { Fragment as Fragment9, jsx as jsx35, jsxs as jsxs7 } from "react/jsx-runtime";
38015
+ import { Fragment as Fragment10, jsx as jsx36, jsxs as jsxs8 } from "react/jsx-runtime";
37769
38016
  var cameraOptions = [
37770
38017
  "Custom",
37771
38018
  "Top Center Angled",
@@ -37843,6 +38090,7 @@ var ContextMenu = ({
37843
38090
  foldPcbs = false,
37844
38091
  onFoldPcbsToggle,
37845
38092
  flexScene = false,
38093
+ preRendered = false,
37846
38094
  referenceObject = null,
37847
38095
  onEngineSwitch,
37848
38096
  onCameraPresetSelect,
@@ -37858,10 +38106,10 @@ var ContextMenu = ({
37858
38106
  }) => {
37859
38107
  const { cameraType, setCameraType } = useCameraController();
37860
38108
  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(
38109
+ const [cameraSubOpen, setCameraSubOpen] = useState40(false);
38110
+ const [referenceObjectSubOpen, setReferenceObjectSubOpen] = useState40(false);
38111
+ const [hoveredItem, setHoveredItem] = useState40(null);
38112
+ return /* @__PURE__ */ jsx36(
37865
38113
  "div",
37866
38114
  {
37867
38115
  ref: menuRef,
@@ -37872,9 +38120,9 @@ var ContextMenu = ({
37872
38120
  width: 0,
37873
38121
  height: 0
37874
38122
  },
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(
38123
+ children: /* @__PURE__ */ jsxs8(DropdownMenu, { open: true, modal: false, children: [
38124
+ /* @__PURE__ */ jsx36(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx36("div", { style: { position: "absolute", width: 1, height: 1 } }) }),
38125
+ /* @__PURE__ */ jsx36(DropdownMenuPortal, { children: /* @__PURE__ */ jsxs8(
37878
38126
  DropdownMenuContent,
37879
38127
  {
37880
38128
  style: contentStyles2,
@@ -37883,7 +38131,7 @@ var ContextMenu = ({
37883
38131
  sideOffset: 0,
37884
38132
  align: "start",
37885
38133
  children: [
37886
- onHideComponent && /* @__PURE__ */ jsx35(
38134
+ onHideComponent && /* @__PURE__ */ jsx36(
37887
38135
  DropdownMenuItem,
37888
38136
  {
37889
38137
  style: {
@@ -37897,7 +38145,7 @@ var ContextMenu = ({
37897
38145
  children: `Hide "${componentName}"`
37898
38146
  }
37899
38147
  ),
37900
- onViewSchematicComponent && /* @__PURE__ */ jsx35(Fragment9, { children: /* @__PURE__ */ jsx35(
38148
+ onViewSchematicComponent && /* @__PURE__ */ jsx36(Fragment10, { children: /* @__PURE__ */ jsx36(
37901
38149
  DropdownMenuItem,
37902
38150
  {
37903
38151
  style: {
@@ -37911,7 +38159,7 @@ var ContextMenu = ({
37911
38159
  children: "Show on schematic"
37912
38160
  }
37913
38161
  ) }),
37914
- onUnhideAllComponents && /* @__PURE__ */ jsx35(
38162
+ onUnhideAllComponents && /* @__PURE__ */ jsx36(
37915
38163
  DropdownMenuItem,
37916
38164
  {
37917
38165
  style: {
@@ -37925,9 +38173,9 @@ var ContextMenu = ({
37925
38173
  children: "Unhide All Components"
37926
38174
  }
37927
38175
  ),
37928
- (onViewSchematicComponent || onHideComponent || onUnhideAllComponents) && /* @__PURE__ */ jsx35(DropdownMenuSeparator, { style: separatorStyles2 }),
37929
- /* @__PURE__ */ jsxs7(DropdownMenuSub, { onOpenChange: setCameraSubOpen, children: [
37930
- /* @__PURE__ */ jsxs7(
38176
+ (onViewSchematicComponent || onHideComponent || onUnhideAllComponents) && /* @__PURE__ */ jsx36(DropdownMenuSeparator, { style: separatorStyles2 }),
38177
+ /* @__PURE__ */ jsxs8(DropdownMenuSub, { onOpenChange: setCameraSubOpen, children: [
38178
+ /* @__PURE__ */ jsxs8(
37931
38179
  DropdownMenuSubTrigger,
37932
38180
  {
37933
38181
  style: {
@@ -37939,14 +38187,14 @@ var ContextMenu = ({
37939
38187
  onMouseLeave: () => setHoveredItem(null),
37940
38188
  onTouchStart: () => setHoveredItem("camera"),
37941
38189
  children: [
37942
- /* @__PURE__ */ jsx35(
38190
+ /* @__PURE__ */ jsx36(
37943
38191
  "span",
37944
38192
  {
37945
38193
  style: { flex: 1, display: "flex", alignItems: "center" },
37946
38194
  children: "Camera"
37947
38195
  }
37948
38196
  ),
37949
- /* @__PURE__ */ jsxs7(
38197
+ /* @__PURE__ */ jsxs8(
37950
38198
  "div",
37951
38199
  {
37952
38200
  style: {
@@ -37956,22 +38204,22 @@ var ContextMenu = ({
37956
38204
  marginLeft: "auto"
37957
38205
  },
37958
38206
  children: [
37959
- /* @__PURE__ */ jsx35("span", { style: { opacity: 0.55, fontSize: 13 }, children: cameraPreset }),
37960
- /* @__PURE__ */ jsx35(ChevronRightIcon, { isOpen: cameraSubOpen })
38207
+ /* @__PURE__ */ jsx36("span", { style: { opacity: 0.55, fontSize: 13 }, children: cameraPreset }),
38208
+ /* @__PURE__ */ jsx36(ChevronRightIcon, { isOpen: cameraSubOpen })
37961
38209
  ]
37962
38210
  }
37963
38211
  )
37964
38212
  ]
37965
38213
  }
37966
38214
  ),
37967
- /* @__PURE__ */ jsx35(DropdownMenuPortal, { children: /* @__PURE__ */ jsxs7(
38215
+ /* @__PURE__ */ jsx36(DropdownMenuPortal, { children: /* @__PURE__ */ jsxs8(
37968
38216
  ViewportSubContent,
37969
38217
  {
37970
38218
  style: { ...contentStyles2, marginLeft: -2 },
37971
38219
  collisionPadding: 10,
37972
38220
  avoidCollisions: true,
37973
38221
  children: [
37974
- cameraOptions.map((option) => /* @__PURE__ */ jsxs7(
38222
+ cameraOptions.map((option) => /* @__PURE__ */ jsxs8(
37975
38223
  DropdownMenuItem,
37976
38224
  {
37977
38225
  style: {
@@ -37983,14 +38231,14 @@ var ContextMenu = ({
37983
38231
  onMouseLeave: () => setHoveredItem(null),
37984
38232
  onTouchStart: () => setHoveredItem(option),
37985
38233
  children: [
37986
- /* @__PURE__ */ jsx35("span", { style: iconContainerStyles2, children: cameraPreset === option && /* @__PURE__ */ jsx35(DotIcon, {}) }),
37987
- /* @__PURE__ */ jsx35("span", { style: { display: "flex", alignItems: "center" }, children: option })
38234
+ /* @__PURE__ */ jsx36("span", { style: iconContainerStyles2, children: cameraPreset === option && /* @__PURE__ */ jsx36(DotIcon, {}) }),
38235
+ /* @__PURE__ */ jsx36("span", { style: { display: "flex", alignItems: "center" }, children: option })
37988
38236
  ]
37989
38237
  },
37990
38238
  option
37991
38239
  )),
37992
- /* @__PURE__ */ jsx35(DropdownMenuSeparator, { style: separatorStyles2 }),
37993
- /* @__PURE__ */ jsxs7(
38240
+ /* @__PURE__ */ jsx36(DropdownMenuSeparator, { style: separatorStyles2 }),
38241
+ /* @__PURE__ */ jsxs8(
37994
38242
  DropdownMenuItem,
37995
38243
  {
37996
38244
  style: {
@@ -38002,12 +38250,12 @@ var ContextMenu = ({
38002
38250
  onMouseLeave: () => setHoveredItem(null),
38003
38251
  onTouchStart: () => setHoveredItem("autorotate"),
38004
38252
  children: [
38005
- /* @__PURE__ */ jsx35("span", { style: iconContainerStyles2, children: autoRotate && /* @__PURE__ */ jsx35(CheckIcon, {}) }),
38006
- /* @__PURE__ */ jsx35("span", { style: { display: "flex", alignItems: "center" }, children: "Auto rotate" })
38253
+ /* @__PURE__ */ jsx36("span", { style: iconContainerStyles2, children: autoRotate && /* @__PURE__ */ jsx36(CheckIcon, {}) }),
38254
+ /* @__PURE__ */ jsx36("span", { style: { display: "flex", alignItems: "center" }, children: "Auto rotate" })
38007
38255
  ]
38008
38256
  }
38009
38257
  ),
38010
- /* @__PURE__ */ jsxs7(
38258
+ /* @__PURE__ */ jsxs8(
38011
38259
  DropdownMenuItem,
38012
38260
  {
38013
38261
  style: {
@@ -38024,8 +38272,8 @@ var ContextMenu = ({
38024
38272
  onMouseLeave: () => setHoveredItem(null),
38025
38273
  onTouchStart: () => setHoveredItem("cameratype"),
38026
38274
  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" })
38275
+ /* @__PURE__ */ jsx36("span", { style: iconContainerStyles2, children: cameraType === "orthographic" && /* @__PURE__ */ jsx36(CheckIcon, {}) }),
38276
+ /* @__PURE__ */ jsx36("span", { style: { display: "flex", alignItems: "center" }, children: "Orthographic Camera" })
38029
38277
  ]
38030
38278
  }
38031
38279
  )
@@ -38033,8 +38281,8 @@ var ContextMenu = ({
38033
38281
  }
38034
38282
  ) })
38035
38283
  ] }),
38036
- /* @__PURE__ */ jsxs7(DropdownMenuSub, { onOpenChange: setReferenceObjectSubOpen, children: [
38037
- /* @__PURE__ */ jsxs7(
38284
+ /* @__PURE__ */ jsxs8(DropdownMenuSub, { onOpenChange: setReferenceObjectSubOpen, children: [
38285
+ /* @__PURE__ */ jsxs8(
38038
38286
  DropdownMenuSubTrigger,
38039
38287
  {
38040
38288
  style: {
@@ -38046,14 +38294,14 @@ var ContextMenu = ({
38046
38294
  onMouseLeave: () => setHoveredItem(null),
38047
38295
  onTouchStart: () => setHoveredItem("reference-object"),
38048
38296
  children: [
38049
- /* @__PURE__ */ jsx35(
38297
+ /* @__PURE__ */ jsx36(
38050
38298
  "span",
38051
38299
  {
38052
38300
  style: { flex: 1, display: "flex", alignItems: "center" },
38053
38301
  children: "Show Reference Object"
38054
38302
  }
38055
38303
  ),
38056
- /* @__PURE__ */ jsx35(
38304
+ /* @__PURE__ */ jsx36(
38057
38305
  "div",
38058
38306
  {
38059
38307
  style: {
@@ -38062,13 +38310,13 @@ var ContextMenu = ({
38062
38310
  gap: 6,
38063
38311
  marginLeft: "auto"
38064
38312
  },
38065
- children: /* @__PURE__ */ jsx35(ChevronRightIcon, { isOpen: referenceObjectSubOpen })
38313
+ children: /* @__PURE__ */ jsx36(ChevronRightIcon, { isOpen: referenceObjectSubOpen })
38066
38314
  }
38067
38315
  )
38068
38316
  ]
38069
38317
  }
38070
38318
  ),
38071
- /* @__PURE__ */ jsx35(DropdownMenuPortal, { children: /* @__PURE__ */ jsx35(
38319
+ /* @__PURE__ */ jsx36(DropdownMenuPortal, { children: /* @__PURE__ */ jsx36(
38072
38320
  ViewportSubContent,
38073
38321
  {
38074
38322
  style: { ...contentStyles2, marginLeft: -2 },
@@ -38076,7 +38324,7 @@ var ContextMenu = ({
38076
38324
  avoidCollisions: true,
38077
38325
  children: REFERENCE_OBJECT_MENU_OPTIONS.map((option) => {
38078
38326
  const optionKey = option.type ?? "none";
38079
- return /* @__PURE__ */ jsxs7(
38327
+ return /* @__PURE__ */ jsxs8(
38080
38328
  DropdownMenuItem,
38081
38329
  {
38082
38330
  style: {
@@ -38092,8 +38340,8 @@ var ContextMenu = ({
38092
38340
  onMouseLeave: () => setHoveredItem(null),
38093
38341
  onTouchStart: () => setHoveredItem(optionKey),
38094
38342
  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 })
38343
+ /* @__PURE__ */ jsx36("span", { style: iconContainerStyles2, children: referenceObject === option.type && /* @__PURE__ */ jsx36(DotIcon, {}) }),
38344
+ /* @__PURE__ */ jsx36("span", { style: { display: "flex", alignItems: "center" }, children: option.label })
38097
38345
  ]
38098
38346
  },
38099
38347
  optionKey
@@ -38102,7 +38350,7 @@ var ContextMenu = ({
38102
38350
  }
38103
38351
  ) })
38104
38352
  ] }),
38105
- onFoldPcbsToggle && /* @__PURE__ */ jsxs7(
38353
+ onFoldPcbsToggle && /* @__PURE__ */ jsxs8(
38106
38354
  DropdownMenuCheckboxItem,
38107
38355
  {
38108
38356
  checked: foldPcbs,
@@ -38114,12 +38362,12 @@ var ContextMenu = ({
38114
38362
  onMouseEnter: () => setHoveredItem("fold"),
38115
38363
  onMouseLeave: () => setHoveredItem(null),
38116
38364
  children: [
38117
- /* @__PURE__ */ jsx35("span", { style: iconContainerStyles2, children: foldPcbs && /* @__PURE__ */ jsx35(CheckIcon, {}) }),
38118
- /* @__PURE__ */ jsx35("span", { children: "Fold PCBs" })
38365
+ /* @__PURE__ */ jsx36("span", { style: iconContainerStyles2, children: foldPcbs && /* @__PURE__ */ jsx36(CheckIcon, {}) }),
38366
+ /* @__PURE__ */ jsx36("span", { children: "Fold PCBs" })
38119
38367
  ]
38120
38368
  }
38121
38369
  ),
38122
- /* @__PURE__ */ jsxs7(
38370
+ /* @__PURE__ */ jsxs8(
38123
38371
  DropdownMenuItem,
38124
38372
  {
38125
38373
  style: {
@@ -38135,14 +38383,14 @@ var ContextMenu = ({
38135
38383
  onMouseLeave: () => setHoveredItem(null),
38136
38384
  onTouchStart: () => setHoveredItem("grid"),
38137
38385
  children: [
38138
- /* @__PURE__ */ jsx35("span", { style: iconContainerStyles2, children: gridEnabled && /* @__PURE__ */ jsx35(CheckIcon, {}) }),
38139
- /* @__PURE__ */ jsx35("span", { style: { display: "flex", alignItems: "center" }, children: "Show Grid" })
38386
+ /* @__PURE__ */ jsx36("span", { style: iconContainerStyles2, children: gridEnabled && /* @__PURE__ */ jsx36(CheckIcon, {}) }),
38387
+ /* @__PURE__ */ jsx36("span", { style: { display: "flex", alignItems: "center" }, children: "Show Grid" })
38140
38388
  ]
38141
38389
  }
38142
38390
  ),
38143
- /* @__PURE__ */ jsx35(AppearanceMenu, {}),
38144
- /* @__PURE__ */ jsx35(DropdownMenuSeparator, { style: separatorStyles2 }),
38145
- /* @__PURE__ */ jsx35(
38391
+ /* @__PURE__ */ jsx36(AppearanceMenu, { showLayerControls: !preRendered }),
38392
+ /* @__PURE__ */ jsx36(DropdownMenuSeparator, { style: separatorStyles2 }),
38393
+ /* @__PURE__ */ jsx36(
38146
38394
  DropdownMenuItem,
38147
38395
  {
38148
38396
  style: {
@@ -38154,11 +38402,11 @@ var ContextMenu = ({
38154
38402
  onMouseEnter: () => setHoveredItem("download"),
38155
38403
  onMouseLeave: () => setHoveredItem(null),
38156
38404
  onTouchStart: () => setHoveredItem("download"),
38157
- children: /* @__PURE__ */ jsx35("span", { style: { display: "flex", alignItems: "center" }, children: "Download GLTF" })
38405
+ children: /* @__PURE__ */ jsx36("span", { style: { display: "flex", alignItems: "center" }, children: "Download GLTF" })
38158
38406
  }
38159
38407
  ),
38160
- /* @__PURE__ */ jsx35(DropdownMenuSeparator, { style: separatorStyles2 }),
38161
- !flexScene && /* @__PURE__ */ jsxs7(
38408
+ /* @__PURE__ */ jsx36(DropdownMenuSeparator, { style: separatorStyles2 }),
38409
+ !flexScene && !preRendered && /* @__PURE__ */ jsxs8(
38162
38410
  DropdownMenuItem,
38163
38411
  {
38164
38412
  style: {
@@ -38175,7 +38423,7 @@ var ContextMenu = ({
38175
38423
  onMouseLeave: () => setHoveredItem(null),
38176
38424
  onTouchStart: () => setHoveredItem("engine"),
38177
38425
  children: [
38178
- /* @__PURE__ */ jsxs7(
38426
+ /* @__PURE__ */ jsxs8(
38179
38427
  "span",
38180
38428
  {
38181
38429
  style: { flex: 1, display: "flex", alignItems: "center" },
@@ -38186,7 +38434,7 @@ var ContextMenu = ({
38186
38434
  ]
38187
38435
  }
38188
38436
  ),
38189
- /* @__PURE__ */ jsx35(
38437
+ /* @__PURE__ */ jsx36(
38190
38438
  "div",
38191
38439
  {
38192
38440
  style: {
@@ -38200,8 +38448,8 @@ var ContextMenu = ({
38200
38448
  ]
38201
38449
  }
38202
38450
  ),
38203
- /* @__PURE__ */ jsx35(DropdownMenuSeparator, { style: separatorStyles2 }),
38204
- /* @__PURE__ */ jsxs7(
38451
+ /* @__PURE__ */ jsx36(DropdownMenuSeparator, { style: separatorStyles2 }),
38452
+ /* @__PURE__ */ jsxs8(
38205
38453
  DropdownMenuItem,
38206
38454
  {
38207
38455
  style: {
@@ -38214,8 +38462,8 @@ var ContextMenu = ({
38214
38462
  onMouseLeave: () => setHoveredItem(null),
38215
38463
  onTouchStart: () => setHoveredItem("shortcuts"),
38216
38464
  children: [
38217
- /* @__PURE__ */ jsx35("span", { style: { flex: 1, display: "flex", alignItems: "center" }, children: "Keyboard Shortcuts" }),
38218
- /* @__PURE__ */ jsx35(
38465
+ /* @__PURE__ */ jsx36("span", { style: { flex: 1, display: "flex", alignItems: "center" }, children: "Keyboard Shortcuts" }),
38466
+ /* @__PURE__ */ jsx36(
38219
38467
  "div",
38220
38468
  {
38221
38469
  style: {
@@ -38229,8 +38477,8 @@ var ContextMenu = ({
38229
38477
  ]
38230
38478
  }
38231
38479
  ),
38232
- /* @__PURE__ */ jsx35(DropdownMenuSeparator, { style: separatorStyles2 }),
38233
- /* @__PURE__ */ jsx35(
38480
+ /* @__PURE__ */ jsx36(DropdownMenuSeparator, { style: separatorStyles2 }),
38481
+ /* @__PURE__ */ jsx36(
38234
38482
  "div",
38235
38483
  {
38236
38484
  style: {
@@ -38241,7 +38489,7 @@ var ContextMenu = ({
38241
38489
  paddingTop: 4,
38242
38490
  paddingBottom: 4
38243
38491
  },
38244
- children: /* @__PURE__ */ jsxs7(
38492
+ children: /* @__PURE__ */ jsxs8(
38245
38493
  "span",
38246
38494
  {
38247
38495
  style: {
@@ -38268,10 +38516,10 @@ var ContextMenu = ({
38268
38516
  };
38269
38517
 
38270
38518
  // src/components/KeyboardShortcutsDialog.tsx
38271
- import { useEffect as useEffect49, useMemo as useMemo36, useRef as useRef27, useState as useState40 } from "react";
38519
+ import { useEffect as useEffect51, useMemo as useMemo38, useRef as useRef27, useState as useState42 } from "react";
38272
38520
 
38273
38521
  // src/hooks/useRegisteredHotkey.ts
38274
- import { useEffect as useEffect48, useMemo as useMemo35, useRef as useRef26, useState as useState39 } from "react";
38522
+ import { useEffect as useEffect50, useMemo as useMemo37, useRef as useRef26, useState as useState41 } from "react";
38275
38523
  var hotkeyRegistry = /* @__PURE__ */ new Map();
38276
38524
  var subscribers = /* @__PURE__ */ new Set();
38277
38525
  var isListenerAttached = false;
@@ -38395,14 +38643,14 @@ var subscribeToRegistry = (subscriber) => {
38395
38643
  var useRegisteredHotkey = (id, handler, metadata) => {
38396
38644
  const handlerRef = useRef26(handler);
38397
38645
  handlerRef.current = handler;
38398
- const normalizedMetadata = useMemo35(
38646
+ const normalizedMetadata = useMemo37(
38399
38647
  () => ({
38400
38648
  shortcut: metadata.shortcut,
38401
38649
  description: metadata.description
38402
38650
  }),
38403
38651
  [metadata.shortcut, metadata.description]
38404
38652
  );
38405
- useEffect48(() => {
38653
+ useEffect50(() => {
38406
38654
  const registration = {
38407
38655
  id,
38408
38656
  ...normalizedMetadata,
@@ -38415,10 +38663,10 @@ var useRegisteredHotkey = (id, handler, metadata) => {
38415
38663
  }, [id, normalizedMetadata]);
38416
38664
  };
38417
38665
  var useHotkeyRegistry = () => {
38418
- const [entries, setEntries] = useState39(
38666
+ const [entries, setEntries] = useState41(
38419
38667
  () => Array.from(hotkeyRegistry.values())
38420
38668
  );
38421
- useEffect48(() => subscribeToRegistry(setEntries), []);
38669
+ useEffect50(() => subscribeToRegistry(setEntries), []);
38422
38670
  return entries;
38423
38671
  };
38424
38672
  var registerHotkeyViewer = (element) => {
@@ -38427,15 +38675,15 @@ var registerHotkeyViewer = (element) => {
38427
38675
  };
38428
38676
 
38429
38677
  // src/components/KeyboardShortcutsDialog.tsx
38430
- import { jsx as jsx36, jsxs as jsxs8 } from "react/jsx-runtime";
38678
+ import { jsx as jsx37, jsxs as jsxs9 } from "react/jsx-runtime";
38431
38679
  var KeyboardShortcutsDialog = ({
38432
38680
  open,
38433
38681
  onClose
38434
38682
  }) => {
38435
- const [query, setQuery] = useState40("");
38683
+ const [query, setQuery] = useState42("");
38436
38684
  const inputRef = useRef27(null);
38437
38685
  const hotkeys = useHotkeyRegistry();
38438
- useEffect49(() => {
38686
+ useEffect51(() => {
38439
38687
  if (!open) return void 0;
38440
38688
  const handleKeyDown = (event) => {
38441
38689
  if (event.key === "Escape") {
@@ -38446,14 +38694,14 @@ var KeyboardShortcutsDialog = ({
38446
38694
  window.addEventListener("keydown", handleKeyDown);
38447
38695
  return () => window.removeEventListener("keydown", handleKeyDown);
38448
38696
  }, [open, onClose]);
38449
- useEffect49(() => {
38697
+ useEffect51(() => {
38450
38698
  if (open) {
38451
38699
  setTimeout(() => {
38452
38700
  inputRef.current?.focus();
38453
38701
  }, 0);
38454
38702
  }
38455
38703
  }, [open]);
38456
- const filteredHotkeys = useMemo36(() => {
38704
+ const filteredHotkeys = useMemo38(() => {
38457
38705
  const normalizedQuery = query.trim().toLowerCase();
38458
38706
  if (!normalizedQuery) {
38459
38707
  return hotkeys;
@@ -38466,7 +38714,7 @@ var KeyboardShortcutsDialog = ({
38466
38714
  if (!open) {
38467
38715
  return null;
38468
38716
  }
38469
- return /* @__PURE__ */ jsx36(
38717
+ return /* @__PURE__ */ jsx37(
38470
38718
  "div",
38471
38719
  {
38472
38720
  role: "dialog",
@@ -38481,7 +38729,7 @@ var KeyboardShortcutsDialog = ({
38481
38729
  zIndex: 9999
38482
38730
  },
38483
38731
  onClick: onClose,
38484
- children: /* @__PURE__ */ jsxs8(
38732
+ children: /* @__PURE__ */ jsxs9(
38485
38733
  "div",
38486
38734
  {
38487
38735
  style: {
@@ -38497,7 +38745,7 @@ var KeyboardShortcutsDialog = ({
38497
38745
  },
38498
38746
  onClick: (event) => event.stopPropagation(),
38499
38747
  children: [
38500
- /* @__PURE__ */ jsxs8(
38748
+ /* @__PURE__ */ jsxs9(
38501
38749
  "header",
38502
38750
  {
38503
38751
  style: {
@@ -38505,8 +38753,8 @@ var KeyboardShortcutsDialog = ({
38505
38753
  borderBottom: "1px solid rgba(255, 255, 255, 0.08)"
38506
38754
  },
38507
38755
  children: [
38508
- /* @__PURE__ */ jsxs8("div", { style: { display: "flex", justifyContent: "space-between" }, children: [
38509
- /* @__PURE__ */ jsx36(
38756
+ /* @__PURE__ */ jsxs9("div", { style: { display: "flex", justifyContent: "space-between" }, children: [
38757
+ /* @__PURE__ */ jsx37(
38510
38758
  "h2",
38511
38759
  {
38512
38760
  style: {
@@ -38518,7 +38766,7 @@ var KeyboardShortcutsDialog = ({
38518
38766
  children: "Keyboard Shortcuts"
38519
38767
  }
38520
38768
  ),
38521
- /* @__PURE__ */ jsx36(
38769
+ /* @__PURE__ */ jsx37(
38522
38770
  "button",
38523
38771
  {
38524
38772
  type: "button",
@@ -38534,7 +38782,7 @@ var KeyboardShortcutsDialog = ({
38534
38782
  }
38535
38783
  )
38536
38784
  ] }),
38537
- /* @__PURE__ */ jsx36(
38785
+ /* @__PURE__ */ jsx37(
38538
38786
  "input",
38539
38787
  {
38540
38788
  ref: inputRef,
@@ -38557,7 +38805,7 @@ var KeyboardShortcutsDialog = ({
38557
38805
  ]
38558
38806
  }
38559
38807
  ),
38560
- /* @__PURE__ */ jsx36("div", { style: { overflowY: "auto" }, children: /* @__PURE__ */ jsxs8(
38808
+ /* @__PURE__ */ jsx37("div", { style: { overflowY: "auto" }, children: /* @__PURE__ */ jsxs9(
38561
38809
  "table",
38562
38810
  {
38563
38811
  style: {
@@ -38566,23 +38814,23 @@ var KeyboardShortcutsDialog = ({
38566
38814
  fontSize: "0.95rem"
38567
38815
  },
38568
38816
  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" })
38817
+ /* @__PURE__ */ jsx37("thead", { children: /* @__PURE__ */ jsxs9("tr", { style: { textAlign: "left", color: "#a1a1b5" }, children: [
38818
+ /* @__PURE__ */ jsx37("th", { style: { padding: "12px 24px", width: "25%" }, children: "Key" }),
38819
+ /* @__PURE__ */ jsx37("th", { style: { padding: "12px 24px" }, children: "Description" })
38572
38820
  ] }) }),
38573
- /* @__PURE__ */ jsx36("tbody", { children: filteredHotkeys.length === 0 ? /* @__PURE__ */ jsx36("tr", { children: /* @__PURE__ */ jsx36(
38821
+ /* @__PURE__ */ jsx37("tbody", { children: filteredHotkeys.length === 0 ? /* @__PURE__ */ jsx37("tr", { children: /* @__PURE__ */ jsx37(
38574
38822
  "td",
38575
38823
  {
38576
38824
  colSpan: 2,
38577
38825
  style: { padding: "24px", textAlign: "center" },
38578
38826
  children: "No shortcuts found"
38579
38827
  }
38580
- ) }) : filteredHotkeys.map((hotkey) => /* @__PURE__ */ jsxs8(
38828
+ ) }) : filteredHotkeys.map((hotkey) => /* @__PURE__ */ jsxs9(
38581
38829
  "tr",
38582
38830
  {
38583
38831
  style: { borderTop: "1px solid rgba(255, 255, 255, 0.05)" },
38584
38832
  children: [
38585
- /* @__PURE__ */ jsx36("td", { style: { padding: "12px 24px" }, children: /* @__PURE__ */ jsx36(
38833
+ /* @__PURE__ */ jsx37("td", { style: { padding: "12px 24px" }, children: /* @__PURE__ */ jsx37(
38586
38834
  "span",
38587
38835
  {
38588
38836
  style: {
@@ -38600,7 +38848,7 @@ var KeyboardShortcutsDialog = ({
38600
38848
  children: hotkey.shortcut
38601
38849
  }
38602
38850
  ) }),
38603
- /* @__PURE__ */ jsx36("td", { style: { padding: "12px 24px" }, children: hotkey.description })
38851
+ /* @__PURE__ */ jsx37("td", { style: { padding: "12px 24px" }, children: hotkey.description })
38604
38852
  ]
38605
38853
  },
38606
38854
  hotkey.id
@@ -38617,7 +38865,7 @@ var KeyboardShortcutsDialog = ({
38617
38865
 
38618
38866
  // src/contexts/ToastContext.tsx
38619
38867
  import { Toaster, toast as hotToast } from "react-hot-toast";
38620
- import { Fragment as Fragment10, jsx as jsx37, jsxs as jsxs9 } from "react/jsx-runtime";
38868
+ import { Fragment as Fragment11, jsx as jsx38, jsxs as jsxs10 } from "react/jsx-runtime";
38621
38869
  var useToast = () => {
38622
38870
  return {
38623
38871
  showToast: (message, duration = 2e3) => {
@@ -38628,9 +38876,9 @@ var useToast = () => {
38628
38876
  var ToastProvider = ({
38629
38877
  children
38630
38878
  }) => {
38631
- return /* @__PURE__ */ jsxs9(Fragment10, { children: [
38879
+ return /* @__PURE__ */ jsxs10(Fragment11, { children: [
38632
38880
  children,
38633
- /* @__PURE__ */ jsx37(Toaster, { position: "bottom-right" })
38881
+ /* @__PURE__ */ jsx38(Toaster, { position: "bottom-right" })
38634
38882
  ] });
38635
38883
  };
38636
38884
 
@@ -38675,10 +38923,10 @@ function useCameraPreset({
38675
38923
  }
38676
38924
 
38677
38925
  // src/hooks/useContextMenu.ts
38678
- import { useState as useState41, useCallback as useCallback23, useRef as useRef28, useEffect as useEffect50 } from "react";
38926
+ import { useState as useState43, useCallback as useCallback23, useRef as useRef28, useEffect as useEffect52 } from "react";
38679
38927
  var useContextMenu = ({ containerRef, onOpen }) => {
38680
- const [menuVisible, setMenuVisible] = useState41(false);
38681
- const [menuPos, setMenuPos] = useState41({
38928
+ const [menuVisible, setMenuVisible] = useState43(false);
38929
+ const [menuPos, setMenuPos] = useState43({
38682
38930
  x: 0,
38683
38931
  y: 0
38684
38932
  });
@@ -38792,7 +39040,7 @@ var useContextMenu = ({ containerRef, onOpen }) => {
38792
39040
  }
38793
39041
  setMenuVisible(false);
38794
39042
  }, []);
38795
- useEffect50(() => {
39043
+ useEffect52(() => {
38796
39044
  if (menuVisible) {
38797
39045
  document.addEventListener("mousedown", handleClickAway);
38798
39046
  document.addEventListener("touchstart", handleClickAway);
@@ -38855,8 +39103,8 @@ var useGlobalDownloadGltf = () => {
38855
39103
  };
38856
39104
 
38857
39105
  // 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);
39106
+ import { jsx as jsx39, jsxs as jsxs11 } from "react/jsx-runtime";
39107
+ var DEFAULT_TARGET = new THREE59.Vector3(0, 0, 0);
38860
39108
  var INITIAL_CAMERA_POSITION = [5, -5, 5];
38861
39109
  var readStoredCameraType = () => {
38862
39110
  if (typeof window === "undefined") return void 0;
@@ -38864,18 +39112,20 @@ var readStoredCameraType = () => {
38864
39112
  return stored === "orthographic" || stored === "perspective" ? stored : void 0;
38865
39113
  };
38866
39114
  var CadViewerInner = (props) => {
39115
+ const glbSource = props.glbUrl ?? props.glbData;
38867
39116
  const childrenCircuitJson = useConvertChildrenToCircuitJson(
38868
- props.circuitJson ? void 0 : props.children
39117
+ props.circuitJson || glbSource !== void 0 ? void 0 : props.children
38869
39118
  );
38870
39119
  const circuitJson = props.circuitJson ?? childrenCircuitJson;
38871
39120
  const hasBends = circuitJson.some((element) => element.type === "pcb_bend");
38872
39121
  const hasFlexGeometry = hasBends || circuitJson.some((element) => element.type === "pcb_stiffener");
38873
- const [foldPcbsOverride, setFoldPcbs] = useState42(
39122
+ const [foldPcbsOverride, setFoldPcbs] = useState44(
38874
39123
  void 0
38875
39124
  );
38876
39125
  const foldPcbs = foldPcbsOverride ?? props.foldPcbs;
38877
39126
  const resolvedFoldPcbs = resolveFoldPcbs(circuitJson, foldPcbs);
38878
- const circuitKey = JSON.stringify(circuitJson);
39127
+ const circuitJsonKey = glbSource === void 0 ? JSON.stringify(circuitJson) : void 0;
39128
+ const circuitKey = glbSource ?? circuitJsonKey;
38879
39129
  const { hiddenCadComponentIds, hideComponent, unhideAllComponents } = useHiddenCadComponents(circuitKey);
38880
39130
  const resolvedProps = {
38881
39131
  ...props,
@@ -38883,30 +39133,30 @@ var CadViewerInner = (props) => {
38883
39133
  children: void 0,
38884
39134
  hiddenCadComponentIds
38885
39135
  };
38886
- const [engine, setEngine] = useState42(() => {
39136
+ const [engine, setEngine] = useState44(() => {
38887
39137
  const stored = window.localStorage.getItem("cadViewerEngine");
38888
39138
  return stored === "jscad" || stored === "manifold" ? stored : "manifold";
38889
39139
  });
38890
39140
  const containerRef = useRef29(null);
38891
- const [isKeyboardShortcutsDialogOpen, setIsKeyboardShortcutsDialogOpen] = useState42(false);
38892
- const [autoRotate, setAutoRotate] = useState42(() => {
39141
+ const [isKeyboardShortcutsDialogOpen, setIsKeyboardShortcutsDialogOpen] = useState44(false);
39142
+ const [autoRotate, setAutoRotate] = useState44(() => {
38893
39143
  const stored = window.localStorage.getItem("cadViewerAutoRotate");
38894
39144
  return stored !== "false";
38895
39145
  });
38896
- const [autoRotateUserToggled, setAutoRotateUserToggled] = useState42(() => {
39146
+ const [autoRotateUserToggled, setAutoRotateUserToggled] = useState44(() => {
38897
39147
  const stored = window.localStorage.getItem("cadViewerAutoRotateUserToggled");
38898
39148
  return stored === "true";
38899
39149
  });
38900
- const [cameraPreset, setCameraPreset] = useState42("Custom");
38901
- const [referenceObject, setReferenceObject] = useState42(null);
39150
+ const [cameraPreset, setCameraPreset] = useState44("Custom");
39151
+ const [referenceObject, setReferenceObject] = useState44(null);
38902
39152
  const { cameraType } = useCameraController();
38903
39153
  const { visibility, setLayerVisibility } = useLayerVisibility();
38904
39154
  const { showToast } = useToast();
38905
39155
  const cameraControllerRef = useRef29(null);
38906
39156
  const externalCameraControllerReady = props.onCameraControllerReady;
38907
39157
  const sceneRef = useContext11(SchematicNavigationContext);
38908
- const [selectedComponent, setSelectedComponent] = useState42();
38909
- const [selectedCadComponent, setSelectedCadComponent] = useState42();
39158
+ const [selectedComponent, setSelectedComponent] = useState44();
39159
+ const [selectedCadComponent, setSelectedCadComponent] = useState44();
38910
39160
  const handleMenuOpen = useCallback25(
38911
39161
  (position) => {
38912
39162
  setSelectedCadComponent(
@@ -39023,28 +39273,28 @@ var CadViewerInner = (props) => {
39023
39273
  description: "Toggle translucent components"
39024
39274
  }
39025
39275
  );
39026
- useEffect51(() => {
39276
+ useEffect53(() => {
39027
39277
  if (containerRef.current) {
39028
39278
  registerHotkeyViewer(containerRef.current);
39029
39279
  }
39030
39280
  }, []);
39031
- useEffect51(() => {
39281
+ useEffect53(() => {
39032
39282
  window.localStorage.setItem("cadViewerEngine", engine);
39033
39283
  }, [engine]);
39034
- useEffect51(() => {
39284
+ useEffect53(() => {
39035
39285
  window.localStorage.setItem("cadViewerAutoRotate", String(autoRotate));
39036
39286
  }, [autoRotate]);
39037
- useEffect51(() => {
39287
+ useEffect53(() => {
39038
39288
  window.localStorage.setItem(
39039
39289
  "cadViewerAutoRotateUserToggled",
39040
39290
  String(autoRotateUserToggled)
39041
39291
  );
39042
39292
  }, [autoRotateUserToggled]);
39043
- useEffect51(() => {
39293
+ useEffect53(() => {
39044
39294
  window.localStorage.setItem("cadViewerCameraType", cameraType);
39045
39295
  }, [cameraType]);
39046
- const viewerKey = props.circuitJson ? circuitKey : void 0;
39047
- return /* @__PURE__ */ jsxs10(
39296
+ const viewerKey = props.circuitJson ? circuitJsonKey : void 0;
39297
+ return /* @__PURE__ */ jsxs11(
39048
39298
  "div",
39049
39299
  {
39050
39300
  ref: containerRef,
@@ -39060,7 +39310,18 @@ var CadViewerInner = (props) => {
39060
39310
  },
39061
39311
  ...contextMenuEventHandlers,
39062
39312
  children: [
39063
- hasFlexGeometry ? /* @__PURE__ */ jsx38(
39313
+ glbSource !== void 0 ? /* @__PURE__ */ jsx39(
39314
+ CadViewerGlb,
39315
+ {
39316
+ source: glbSource,
39317
+ hiddenCadComponentIds,
39318
+ autoRotateDisabled: props.autoRotateDisabled || !autoRotate,
39319
+ clickToInteractEnabled: props.clickToInteractEnabled,
39320
+ onUserInteraction: handleUserInteraction,
39321
+ onCameraControllerReady: handleCameraControllerReady,
39322
+ referenceObject
39323
+ }
39324
+ ) : hasFlexGeometry ? /* @__PURE__ */ jsx39(
39064
39325
  CadViewerManifold_default,
39065
39326
  {
39066
39327
  ...resolvedProps,
@@ -39070,7 +39331,7 @@ var CadViewerInner = (props) => {
39070
39331
  onCameraControllerReady: handleCameraControllerReady,
39071
39332
  referenceObject
39072
39333
  }
39073
- ) : engine === "jscad" ? /* @__PURE__ */ jsx38(
39334
+ ) : engine === "jscad" ? /* @__PURE__ */ jsx39(
39074
39335
  CadViewerJscad,
39075
39336
  {
39076
39337
  ...resolvedProps,
@@ -39080,7 +39341,7 @@ var CadViewerInner = (props) => {
39080
39341
  onCameraControllerReady: handleCameraControllerReady,
39081
39342
  referenceObject
39082
39343
  }
39083
- ) : /* @__PURE__ */ jsx38(
39344
+ ) : /* @__PURE__ */ jsx39(
39084
39345
  CadViewerManifold_default,
39085
39346
  {
39086
39347
  ...resolvedProps,
@@ -39091,7 +39352,7 @@ var CadViewerInner = (props) => {
39091
39352
  referenceObject
39092
39353
  }
39093
39354
  ),
39094
- menuVisible && /* @__PURE__ */ jsx38(
39355
+ menuVisible && /* @__PURE__ */ jsx39(
39095
39356
  ContextMenu,
39096
39357
  {
39097
39358
  componentName: selectedCadComponent?.componentName,
@@ -39110,9 +39371,10 @@ var CadViewerInner = (props) => {
39110
39371
  menuRef,
39111
39372
  menuPos,
39112
39373
  engine,
39374
+ preRendered: glbSource !== void 0,
39113
39375
  flexScene: hasFlexGeometry,
39114
39376
  foldPcbs: resolvedFoldPcbs,
39115
- onFoldPcbsToggle: hasBends ? () => {
39377
+ onFoldPcbsToggle: hasBends && glbSource === void 0 ? () => {
39116
39378
  setFoldPcbs(!resolvedFoldPcbs);
39117
39379
  setCameraPreset("Custom");
39118
39380
  closeMenu();
@@ -39151,7 +39413,7 @@ var CadViewerInner = (props) => {
39151
39413
  }
39152
39414
  }
39153
39415
  ),
39154
- /* @__PURE__ */ jsx38(
39416
+ /* @__PURE__ */ jsx39(
39155
39417
  KeyboardShortcutsDialog,
39156
39418
  {
39157
39419
  open: isKeyboardShortcutsDialogOpen,
@@ -39166,13 +39428,13 @@ var CadViewerInner = (props) => {
39166
39428
  var CadViewer = (props) => {
39167
39429
  configureRuntimeFont();
39168
39430
  const sceneRef = useRef29(null);
39169
- return /* @__PURE__ */ jsx38(SchematicNavigationContext.Provider, { value: sceneRef, children: /* @__PURE__ */ jsx38(
39431
+ return /* @__PURE__ */ jsx39(SchematicNavigationContext.Provider, { value: sceneRef, children: /* @__PURE__ */ jsx39(
39170
39432
  CameraControllerProvider,
39171
39433
  {
39172
39434
  defaultTarget: DEFAULT_TARGET,
39173
39435
  initialCameraPosition: INITIAL_CAMERA_POSITION,
39174
39436
  initialCameraType: readStoredCameraType(),
39175
- children: /* @__PURE__ */ jsx38(LayerVisibilityProvider, { children: /* @__PURE__ */ jsx38(AppearanceProvider, { children: /* @__PURE__ */ jsx38(ToastProvider, { children: /* @__PURE__ */ jsx38(CadViewerInner, { ...props }) }) }) })
39437
+ children: /* @__PURE__ */ jsx39(LayerVisibilityProvider, { children: /* @__PURE__ */ jsx39(AppearanceProvider, { children: /* @__PURE__ */ jsx39(ToastProvider, { children: /* @__PURE__ */ jsx39(CadViewerInner, { ...props }) }) }) })
39176
39438
  }
39177
39439
  ) });
39178
39440
  };
@@ -39180,11 +39442,11 @@ var CadViewer = (props) => {
39180
39442
  // src/convert-circuit-json-to-3d-svg.ts
39181
39443
  var import_debug = __toESM(require_browser(), 1);
39182
39444
  import { su as su18 } from "@tscircuit/circuit-json-util";
39183
- import * as THREE61 from "three";
39445
+ import * as THREE63 from "three";
39184
39446
  import { SVGRenderer } from "three/examples/jsm/renderers/SVGRenderer.js";
39185
39447
 
39186
39448
  // src/utils/create-geometry-from-polygons.ts
39187
- import * as THREE58 from "three";
39449
+ import * as THREE60 from "three";
39188
39450
  import { BufferGeometry as BufferGeometry6, Float32BufferAttribute as Float32BufferAttribute6 } from "three";
39189
39451
  function createGeometryFromPolygons(polygons) {
39190
39452
  const geometry = new BufferGeometry6();
@@ -39198,12 +39460,12 @@ function createGeometryFromPolygons(polygons) {
39198
39460
  ...polygon2.vertices[i + 1]
39199
39461
  // Third vertex
39200
39462
  );
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)
39463
+ const v1 = new THREE60.Vector3(...polygon2.vertices[0]);
39464
+ const v2 = new THREE60.Vector3(...polygon2.vertices[i]);
39465
+ const v3 = new THREE60.Vector3(...polygon2.vertices[i + 1]);
39466
+ const normal = new THREE60.Vector3().crossVectors(
39467
+ new THREE60.Vector3().subVectors(v2, v1),
39468
+ new THREE60.Vector3().subVectors(v3, v1)
39207
39469
  ).normalize();
39208
39470
  normals.push(
39209
39471
  normal.x,
@@ -39231,23 +39493,23 @@ import {
39231
39493
  convertCSGToThreeGeom as convertCSGToThreeGeom3,
39232
39494
  getJscadModelForFootprint as getJscadModelForFootprint2
39233
39495
  } from "jscad-electronics/vanilla";
39234
- import * as THREE60 from "three";
39496
+ import * as THREE62 from "three";
39235
39497
 
39236
39498
  // src/utils/load-model.ts
39237
- import * as THREE59 from "three";
39238
- import { GLTFLoader as GLTFLoader2 } from "three/examples/jsm/loaders/GLTFLoader.js";
39499
+ import * as THREE61 from "three";
39500
+ import { GLTFLoader as GLTFLoader3 } from "three/examples/jsm/loaders/GLTFLoader.js";
39239
39501
  import { OBJLoader as OBJLoader2 } from "three/examples/jsm/loaders/OBJLoader.js";
39240
39502
  import { STLLoader as STLLoader2 } from "three/examples/jsm/loaders/STLLoader.js";
39241
39503
  async function load3DModel(url) {
39242
39504
  if (url.endsWith(".stl")) {
39243
39505
  const loader = new STLLoader2();
39244
39506
  const geometry = await loader.loadAsync(url);
39245
- const material = new THREE59.MeshStandardMaterial({
39507
+ const material = new THREE61.MeshStandardMaterial({
39246
39508
  color: 8947848,
39247
39509
  metalness: 0.5,
39248
39510
  roughness: 0.5
39249
39511
  });
39250
- return new THREE59.Mesh(geometry, material);
39512
+ return new THREE61.Mesh(geometry, material);
39251
39513
  }
39252
39514
  if (url.endsWith(".obj")) {
39253
39515
  const loader = new OBJLoader2();
@@ -39257,7 +39519,7 @@ async function load3DModel(url) {
39257
39519
  return await loadVrml(url);
39258
39520
  }
39259
39521
  if (url.endsWith(".gltf") || url.endsWith(".glb")) {
39260
- const loader = new GLTFLoader2();
39522
+ const loader = new GLTFLoader3();
39261
39523
  const gltf = await loader.loadAsync(url);
39262
39524
  return gltf.scene;
39263
39525
  }
@@ -39280,9 +39542,9 @@ async function renderComponent(component, scene) {
39280
39542
  }
39281
39543
  if (component.rotation) {
39282
39544
  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)
39545
+ THREE62.MathUtils.degToRad(component.rotation.x ?? 0),
39546
+ THREE62.MathUtils.degToRad(component.rotation.y ?? 0),
39547
+ THREE62.MathUtils.degToRad(component.rotation.z ?? 0)
39286
39548
  );
39287
39549
  }
39288
39550
  scene.add(model);
@@ -39296,13 +39558,13 @@ async function renderComponent(component, scene) {
39296
39558
  );
39297
39559
  if (jscadObject && (jscadObject.polygons || jscadObject.sides)) {
39298
39560
  const threeGeom = convertCSGToThreeGeom3(jscadObject);
39299
- const material2 = new THREE60.MeshStandardMaterial({
39561
+ const material2 = new THREE62.MeshStandardMaterial({
39300
39562
  color: 8947848,
39301
39563
  metalness: 0.5,
39302
39564
  roughness: 0.5,
39303
- side: THREE60.DoubleSide
39565
+ side: THREE62.DoubleSide
39304
39566
  });
39305
- const mesh2 = new THREE60.Mesh(threeGeom, material2);
39567
+ const mesh2 = new THREE62.Mesh(threeGeom, material2);
39306
39568
  if (component.position) {
39307
39569
  mesh2.position.set(
39308
39570
  component.position.x ?? 0,
@@ -39312,9 +39574,9 @@ async function renderComponent(component, scene) {
39312
39574
  }
39313
39575
  if (component.rotation) {
39314
39576
  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)
39577
+ THREE62.MathUtils.degToRad(component.rotation.x ?? 0),
39578
+ THREE62.MathUtils.degToRad(component.rotation.y ?? 0),
39579
+ THREE62.MathUtils.degToRad(component.rotation.z ?? 0)
39318
39580
  );
39319
39581
  }
39320
39582
  scene.add(mesh2);
@@ -39331,17 +39593,17 @@ async function renderComponent(component, scene) {
39331
39593
  if (!geom || !geom.polygons && !geom.sides) {
39332
39594
  continue;
39333
39595
  }
39334
- const color = new THREE60.Color(geomInfo.color);
39596
+ const color = new THREE62.Color(geomInfo.color);
39335
39597
  color.convertLinearToSRGB();
39336
39598
  const geomWithColor = { ...geom, color: [color.r, color.g, color.b] };
39337
39599
  const threeGeom = convertCSGToThreeGeom3(geomWithColor);
39338
- const material2 = new THREE60.MeshStandardMaterial({
39600
+ const material2 = new THREE62.MeshStandardMaterial({
39339
39601
  vertexColors: true,
39340
39602
  metalness: 0.2,
39341
39603
  roughness: 0.8,
39342
- side: THREE60.DoubleSide
39604
+ side: THREE62.DoubleSide
39343
39605
  });
39344
- const mesh2 = new THREE60.Mesh(threeGeom, material2);
39606
+ const mesh2 = new THREE62.Mesh(threeGeom, material2);
39345
39607
  if (component.position) {
39346
39608
  mesh2.position.set(
39347
39609
  component.position.x ?? 0,
@@ -39351,22 +39613,22 @@ async function renderComponent(component, scene) {
39351
39613
  }
39352
39614
  if (component.rotation) {
39353
39615
  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)
39616
+ THREE62.MathUtils.degToRad(component.rotation.x ?? 0),
39617
+ THREE62.MathUtils.degToRad(component.rotation.y ?? 0),
39618
+ THREE62.MathUtils.degToRad(component.rotation.z ?? 0)
39357
39619
  );
39358
39620
  }
39359
39621
  scene.add(mesh2);
39360
39622
  }
39361
39623
  return;
39362
39624
  }
39363
- const geometry = new THREE60.BoxGeometry(0.5, 0.5, 0.5);
39364
- const material = new THREE60.MeshStandardMaterial({
39625
+ const geometry = new THREE62.BoxGeometry(0.5, 0.5, 0.5);
39626
+ const material = new THREE62.MeshStandardMaterial({
39365
39627
  color: 16711680,
39366
39628
  transparent: true,
39367
39629
  opacity: 0.25
39368
39630
  });
39369
- const mesh = new THREE60.Mesh(geometry, material);
39631
+ const mesh = new THREE62.Mesh(geometry, material);
39370
39632
  if (component.position) {
39371
39633
  mesh.position.set(
39372
39634
  component.position.x ?? 0,
@@ -39387,11 +39649,11 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
39387
39649
  padding = 20,
39388
39650
  zoom = 1.5
39389
39651
  } = options;
39390
- const scene = new THREE61.Scene();
39652
+ const scene = new THREE63.Scene();
39391
39653
  const renderer = new SVGRenderer();
39392
39654
  renderer.setSize(width, height);
39393
- renderer.setClearColor(new THREE61.Color(backgroundColor), 1);
39394
- const camera = new THREE61.OrthographicCamera();
39655
+ renderer.setClearColor(new THREE63.Color(backgroundColor), 1);
39656
+ const camera = new THREE63.OrthographicCamera();
39395
39657
  const aspect = width / height;
39396
39658
  const frustumSize = 100;
39397
39659
  const halfFrustumSize = frustumSize / 2 / zoom;
@@ -39405,11 +39667,11 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
39405
39667
  camera.position.set(position.x, position.y, position.z);
39406
39668
  camera.up.set(0, 1, 0);
39407
39669
  const lookAt2 = options.camera?.lookAt ?? { x: 0, y: 0, z: 0 };
39408
- camera.lookAt(new THREE61.Vector3(lookAt2.x, lookAt2.y, lookAt2.z));
39670
+ camera.lookAt(new THREE63.Vector3(lookAt2.x, lookAt2.y, lookAt2.z));
39409
39671
  camera.updateProjectionMatrix();
39410
- const ambientLight = new THREE61.AmbientLight(16777215, Math.PI / 2);
39672
+ const ambientLight = new THREE63.AmbientLight(16777215, Math.PI / 2);
39411
39673
  scene.add(ambientLight);
39412
- const pointLight = new THREE61.PointLight(16777215, Math.PI / 4);
39674
+ const pointLight = new THREE63.PointLight(16777215, Math.PI / 4);
39413
39675
  pointLight.position.set(-10, -10, 10);
39414
39676
  scene.add(pointLight);
39415
39677
  const components = su18(circuitJson).cad_component.list();
@@ -39441,28 +39703,28 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
39441
39703
  const material = createBoardMaterial({
39442
39704
  material: boardData?.material,
39443
39705
  color: edgeColor,
39444
- side: THREE61.DoubleSide
39706
+ side: THREE63.DoubleSide
39445
39707
  });
39446
- const mesh = new THREE61.Mesh(geometry, material);
39708
+ const mesh = new THREE63.Mesh(geometry, material);
39447
39709
  scene.add(mesh);
39448
39710
  }
39449
39711
  }
39450
- const gridColor = new THREE61.Color(8947848);
39451
- const gridHelper = new THREE61.GridHelper(100, 100, gridColor, gridColor);
39712
+ const gridColor = new THREE63.Color(8947848);
39713
+ const gridHelper = new THREE63.GridHelper(100, 100, gridColor, gridColor);
39452
39714
  gridHelper.rotation.x = Math.PI / 2;
39453
39715
  const materials = Array.isArray(gridHelper.material) ? gridHelper.material : [gridHelper.material];
39454
39716
  for (const mat of materials) {
39455
39717
  mat.transparent = true;
39456
39718
  mat.opacity = 0.3;
39457
- if (mat instanceof THREE61.LineBasicMaterial) {
39719
+ if (mat instanceof THREE63.LineBasicMaterial) {
39458
39720
  mat.color = gridColor;
39459
39721
  mat.vertexColors = false;
39460
39722
  }
39461
39723
  }
39462
39724
  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());
39725
+ const box = new THREE63.Box3().setFromObject(scene);
39726
+ const center = box.getCenter(new THREE63.Vector3());
39727
+ const size4 = box.getSize(new THREE63.Vector3());
39466
39728
  scene.position.sub(center);
39467
39729
  const maxDim = Math.max(size4.x, size4.y, size4.z);
39468
39730
  if (maxDim > 0) {
@@ -39480,10 +39742,10 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
39480
39742
 
39481
39743
  // src/hooks/exporter/gltf.ts
39482
39744
  import { GLTFExporter as GLTFExporter3 } from "three-stdlib";
39483
- import { useEffect as useEffect52, useState as useState43, useMemo as useMemo37, useCallback as useCallback26 } from "react";
39745
+ import { useEffect as useEffect54, useState as useState45, useMemo as useMemo39, useCallback as useCallback26 } from "react";
39484
39746
  function useSaveGltfAs(options = {}) {
39485
39747
  const parse2 = useParser(options);
39486
- const link = useMemo37(() => document.createElement("a"), []);
39748
+ const link = useMemo39(() => document.createElement("a"), []);
39487
39749
  const saveAs = async (filename) => {
39488
39750
  const name = filename ?? options.filename ?? "";
39489
39751
  if (options.binary == null) options.binary = name.endsWith(".glb");
@@ -39493,7 +39755,7 @@ function useSaveGltfAs(options = {}) {
39493
39755
  link.dispatchEvent(new MouseEvent("click"));
39494
39756
  URL.revokeObjectURL(url);
39495
39757
  };
39496
- useEffect52(
39758
+ useEffect54(
39497
39759
  () => () => {
39498
39760
  link.remove();
39499
39761
  instance = null;
@@ -39508,17 +39770,17 @@ function useSaveGltfAs(options = {}) {
39508
39770
  }
39509
39771
  function useExportGltfUrl(options = {}) {
39510
39772
  const parse2 = useParser(options);
39511
- const [url, setUrl] = useState43();
39512
- const [error, setError] = useState43();
39773
+ const [url, setUrl] = useState45();
39774
+ const [error, setError] = useState45();
39513
39775
  const ref = useCallback26(
39514
39776
  (instance) => parse2(instance).then(setUrl).catch(setError),
39515
39777
  []
39516
39778
  );
39517
- useEffect52(() => () => URL.revokeObjectURL(url), [url]);
39779
+ useEffect54(() => () => URL.revokeObjectURL(url), [url]);
39518
39780
  return [ref, url, error];
39519
39781
  }
39520
39782
  function useParser(options = {}) {
39521
- const exporter = useMemo37(() => new GLTFExporter3(), []);
39783
+ const exporter = useMemo39(() => new GLTFExporter3(), []);
39522
39784
  return (instance) => {
39523
39785
  const { promise, resolve, reject } = Promise.withResolvers();
39524
39786
  exporter.parse(