@tscircuit/pcb-viewer 1.11.282 → 1.11.283

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
@@ -10468,7 +10468,6 @@ var createBoxFromPoints = (points) => {
10468
10468
  }
10469
10469
  return { minX, maxX, minY, maxY };
10470
10470
  };
10471
- var getBoundsFromPoints = createBoxFromPoints;
10472
10471
  var mergeBoundingBoxesInternal = (a, b) => ({
10473
10472
  minX: Math.min(a.minX, b.minX),
10474
10473
  maxX: Math.max(a.maxX, b.maxX),
@@ -10605,7 +10604,7 @@ function calculateDiagonalLabel(params) {
10605
10604
  } = params;
10606
10605
  const deltaX = dimensionEnd.x - dimensionStart.x;
10607
10606
  const deltaY = dimensionEnd.y - dimensionStart.y;
10608
- const distance5 = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
10607
+ const distance4 = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
10609
10608
  const screenDeltaX = screenDimensionEnd.x - screenDimensionStart.x;
10610
10609
  const screenDeltaY = screenDimensionEnd.y - screenDimensionStart.y;
10611
10610
  const screenDistance = Math.sqrt(
@@ -10647,11 +10646,11 @@ function calculateDiagonalLabel(params) {
10647
10646
  const x = midX + offsetX;
10648
10647
  const y = midY + offsetY;
10649
10648
  return {
10650
- distance: distance5,
10649
+ distance: distance4,
10651
10650
  screenDistance,
10652
10651
  x,
10653
10652
  y,
10654
- show: distance5 > 0.01 && screenDistance > 30 && isDiagonal
10653
+ show: distance4 > 0.01 && screenDistance > 30 && isDiagonal
10655
10654
  };
10656
10655
  }
10657
10656
 
@@ -10945,11 +10944,11 @@ var DimensionOverlay = ({
10945
10944
  for (const snap of snappingPointsWithScreen) {
10946
10945
  const dx = snap.screenPoint.x - screenPoint.x;
10947
10946
  const dy = snap.screenPoint.y - screenPoint.y;
10948
- const distance5 = Math.hypot(dx, dy);
10949
- if (distance5 > SNAP_THRESHOLD_PX) continue;
10950
- if (!bestMatch || distance5 < bestMatch.distance) {
10947
+ const distance4 = Math.hypot(dx, dy);
10948
+ if (distance4 > SNAP_THRESHOLD_PX) continue;
10949
+ if (!bestMatch || distance4 < bestMatch.distance) {
10951
10950
  bestMatch = {
10952
- distance: distance5,
10951
+ distance: distance4,
10953
10952
  id: snap.id,
10954
10953
  point: snap.point
10955
10954
  };
@@ -11548,10 +11547,10 @@ var isInsideOfSmtpad = (elm, point, padding = 0) => {
11548
11547
  };
11549
11548
  var isInsideOfPlatedHole = (hole, point, padding = 0) => {
11550
11549
  if (hole.shape === "circle") {
11551
- const distance5 = Math.sqrt(
11550
+ const distance4 = Math.sqrt(
11552
11551
  (point.x - hole.x) ** 2 + (point.y - hole.y) ** 2
11553
11552
  );
11554
- return distance5 <= hole.outer_diameter / 2 + padding;
11553
+ return distance4 <= hole.outer_diameter / 2 + padding;
11555
11554
  } else if (hole.shape === "circular_hole_with_rect_pad") {
11556
11555
  const dx = Math.abs(point.x - hole.x);
11557
11556
  const dy = Math.abs(point.y - hole.y);
@@ -12379,7 +12378,7 @@ var ErrorOverlay = ({
12379
12378
 
12380
12379
  // src/components/MouseElementTracker.tsx
12381
12380
  import { pointToSegmentDistance } from "@tscircuit/math-utils";
12382
- import { distance as distance4 } from "circuit-json";
12381
+ import { distance as distance3 } from "circuit-json";
12383
12382
 
12384
12383
  // src/lib/util/if-sets-match-exactly.ts
12385
12384
  function ifSetsMatchExactly(set1, set2) {
@@ -12709,6 +12708,7 @@ var BoardAnchorOffsetOverlay = ({
12709
12708
  const components = elements.filter(
12710
12709
  (el) => isPcbComponent(el)
12711
12710
  );
12711
+ const groups = elements.filter((el) => isPcbGroup(el));
12712
12712
  const hoveredComponentIds = highlightedPrimitives.map((primitive) => {
12713
12713
  if (isPcbComponent(primitive._parent_pcb_component)) {
12714
12714
  return primitive._parent_pcb_component.pcb_component_id;
@@ -12718,20 +12718,36 @@ var BoardAnchorOffsetOverlay = ({
12718
12718
  }
12719
12719
  return null;
12720
12720
  }).filter((id) => Boolean(id));
12721
+ const hoveredGroupIds = /* @__PURE__ */ new Set();
12722
+ hoveredComponentIds.forEach((componentId) => {
12723
+ const component = components.find((c) => c.pcb_component_id === componentId);
12724
+ if (component?.pcb_group_id) {
12725
+ hoveredGroupIds.add(component.pcb_group_id);
12726
+ }
12727
+ });
12721
12728
  const isShowingAnchorOffsets = useGlobalStore(
12722
12729
  (state) => state.is_showing_group_anchor_offsets
12723
12730
  );
12724
12731
  if (!isShowingAnchorOffsets && hoveredComponentIds.length === 0) {
12725
12732
  return null;
12726
12733
  }
12727
- const targets = components.map((component) => {
12734
+ const componentTargets = components.map((component) => {
12728
12735
  const boardId = component.positioned_relative_to_pcb_board_id;
12729
12736
  if (!boardId) return null;
12730
12737
  const board = boards.find((b) => b.pcb_board_id === boardId);
12731
- return board ? { component, board } : null;
12738
+ return board ? { component, board, type: "component" } : null;
12732
12739
  }).filter(
12733
12740
  (target) => Boolean(target)
12734
12741
  );
12742
+ const groupTargets = groups.map((group) => {
12743
+ const boardId = group.positioned_relative_to_pcb_board_id;
12744
+ if (!boardId || !group.center) return null;
12745
+ const board = boards.find((b) => b.pcb_board_id === boardId);
12746
+ return board ? { group, board, type: "group" } : null;
12747
+ }).filter(
12748
+ (target) => Boolean(target)
12749
+ );
12750
+ const targets = [...componentTargets, ...groupTargets];
12735
12751
  if (targets.length === 0) return null;
12736
12752
  const shouldShowAllTargets = hoveredComponentIds.length === 0;
12737
12753
  const labelStyle = {
@@ -12742,9 +12758,13 @@ var BoardAnchorOffsetOverlay = ({
12742
12758
  fontFamily: "monospace",
12743
12759
  fontWeight: "bold"
12744
12760
  };
12745
- const targetEntries = targets.filter(
12746
- ({ component }) => shouldShowAllTargets || hoveredComponentIds.includes(component.pcb_component_id)
12747
- );
12761
+ const targetEntries = targets.filter((target) => {
12762
+ if (target.type === "component") {
12763
+ return shouldShowAllTargets || hoveredComponentIds.includes(target.component.pcb_component_id);
12764
+ } else {
12765
+ return shouldShowAllTargets || hoveredGroupIds.has(target.group.pcb_group_id);
12766
+ }
12767
+ });
12748
12768
  if (targetEntries.length === 0) return null;
12749
12769
  const boardAnchorScreens = /* @__PURE__ */ new Map();
12750
12770
  return /* @__PURE__ */ jsx12(
@@ -12772,35 +12792,53 @@ var BoardAnchorOffsetOverlay = ({
12772
12792
  width: containerWidth,
12773
12793
  height: containerHeight,
12774
12794
  children: [
12775
- targetEntries.map(({ component, board }) => {
12776
- const anchorPosition = board.center;
12777
- const componentCenter = component.center;
12778
- const anchorKey = board.pcb_board_id;
12795
+ targetEntries.map((target) => {
12796
+ const anchorPosition = target.board.center;
12797
+ const anchorKey = target.board.pcb_board_id;
12798
+ let targetCenter;
12799
+ let targetId;
12800
+ let displayOffsetX;
12801
+ let displayOffsetY;
12802
+ if (target.type === "component") {
12803
+ targetCenter = target.component.center;
12804
+ targetId = target.component.pcb_component_id;
12805
+ displayOffsetX = target.component.display_offset_x;
12806
+ displayOffsetY = target.component.display_offset_y;
12807
+ } else {
12808
+ if (!target.group.center) return null;
12809
+ targetCenter = {
12810
+ x: target.group.center.x,
12811
+ y: target.group.center.y
12812
+ };
12813
+ targetId = target.group.pcb_group_id;
12814
+ displayOffsetX = target.group.display_offset_x;
12815
+ displayOffsetY = target.group.display_offset_y;
12816
+ }
12779
12817
  if (!boardAnchorScreens.has(anchorKey)) {
12780
12818
  const screenPoint = applyToPoint12(transform, anchorPosition);
12781
12819
  boardAnchorScreens.set(anchorKey, screenPoint);
12782
12820
  }
12783
12821
  const anchorMarkerScreen = boardAnchorScreens.get(anchorKey);
12784
- const componentScreen = applyToPoint12(transform, componentCenter);
12785
- const offsetX = componentCenter.x - anchorPosition.x;
12786
- const offsetY = componentCenter.y - anchorPosition.y;
12787
- const xLineLength = Math.abs(componentScreen.x - anchorMarkerScreen.x);
12788
- const yLineLength = Math.abs(componentScreen.y - anchorMarkerScreen.y);
12789
- const isComponentAboveAnchor = componentScreen.y < anchorMarkerScreen.y;
12790
- const isComponentRightOfAnchor = componentScreen.x > anchorMarkerScreen.x;
12791
- const xLabelOffset = isComponentAboveAnchor ? VISUAL_CONFIG.LABEL_OFFSET_ABOVE : VISUAL_CONFIG.LABEL_OFFSET_BELOW;
12792
- const yLabelOffset = isComponentRightOfAnchor ? VISUAL_CONFIG.LABEL_OFFSET_RIGHT : VISUAL_CONFIG.LABEL_OFFSET_LEFT;
12822
+ const targetScreen = applyToPoint12(transform, targetCenter);
12823
+ const offsetX = targetCenter.x - anchorPosition.x;
12824
+ const offsetY = targetCenter.y - anchorPosition.y;
12825
+ const xLineLength = Math.abs(targetScreen.x - anchorMarkerScreen.x);
12826
+ const yLineLength = Math.abs(targetScreen.y - anchorMarkerScreen.y);
12827
+ const isTargetAboveAnchor = targetScreen.y < anchorMarkerScreen.y;
12828
+ const isTargetRightOfAnchor = targetScreen.x > anchorMarkerScreen.x;
12829
+ const xLabelOffset = isTargetAboveAnchor ? VISUAL_CONFIG.LABEL_OFFSET_ABOVE : VISUAL_CONFIG.LABEL_OFFSET_BELOW;
12830
+ const yLabelOffset = isTargetRightOfAnchor ? VISUAL_CONFIG.LABEL_OFFSET_RIGHT : VISUAL_CONFIG.LABEL_OFFSET_LEFT;
12793
12831
  const shouldShowXLabel = xLineLength > VISUAL_CONFIG.MIN_LINE_LENGTH_FOR_LABEL;
12794
12832
  const shouldShowYLabel = yLineLength > VISUAL_CONFIG.MIN_LINE_LENGTH_FOR_LABEL;
12795
- const xLabelText = component.display_offset_x ?? `Board \u0394x: ${offsetX.toFixed(2)}mm`;
12796
- const yLabelText = component.display_offset_y ?? `Board \u0394y: ${offsetY.toFixed(2)}mm`;
12833
+ const xLabelText = displayOffsetX ?? `Board \u0394x: ${offsetX.toFixed(2)}mm`;
12834
+ const yLabelText = displayOffsetY ?? `Board \u0394y: ${offsetY.toFixed(2)}mm`;
12797
12835
  return /* @__PURE__ */ jsxs9("g", { children: [
12798
12836
  /* @__PURE__ */ jsx12(
12799
12837
  "line",
12800
12838
  {
12801
12839
  x1: anchorMarkerScreen.x,
12802
12840
  y1: anchorMarkerScreen.y,
12803
- x2: componentScreen.x,
12841
+ x2: targetScreen.x,
12804
12842
  y2: anchorMarkerScreen.y,
12805
12843
  stroke: COLORS.OFFSET_LINE,
12806
12844
  strokeWidth: VISUAL_CONFIG.LINE_STROKE_WIDTH,
@@ -12810,10 +12848,10 @@ var BoardAnchorOffsetOverlay = ({
12810
12848
  /* @__PURE__ */ jsx12(
12811
12849
  "line",
12812
12850
  {
12813
- x1: componentScreen.x,
12851
+ x1: targetScreen.x,
12814
12852
  y1: anchorMarkerScreen.y,
12815
- x2: componentScreen.x,
12816
- y2: componentScreen.y,
12853
+ x2: targetScreen.x,
12854
+ y2: targetScreen.y,
12817
12855
  stroke: COLORS.OFFSET_LINE,
12818
12856
  strokeWidth: VISUAL_CONFIG.LINE_STROKE_WIDTH,
12819
12857
  strokeDasharray: VISUAL_CONFIG.LINE_DASH_PATTERN
@@ -12822,8 +12860,8 @@ var BoardAnchorOffsetOverlay = ({
12822
12860
  /* @__PURE__ */ jsx12(
12823
12861
  "circle",
12824
12862
  {
12825
- cx: componentScreen.x,
12826
- cy: componentScreen.y,
12863
+ cx: targetScreen.x,
12864
+ cy: targetScreen.y,
12827
12865
  r: VISUAL_CONFIG.COMPONENT_MARKER_RADIUS,
12828
12866
  fill: COLORS.COMPONENT_MARKER_FILL,
12829
12867
  stroke: COLORS.COMPONENT_MARKER_STROKE,
@@ -12833,9 +12871,9 @@ var BoardAnchorOffsetOverlay = ({
12833
12871
  shouldShowXLabel && /* @__PURE__ */ jsx12(
12834
12872
  "foreignObject",
12835
12873
  {
12836
- x: Math.min(anchorMarkerScreen.x, componentScreen.x),
12874
+ x: Math.min(anchorMarkerScreen.x, targetScreen.x),
12837
12875
  y: anchorMarkerScreen.y + xLabelOffset,
12838
- width: Math.abs(componentScreen.x - anchorMarkerScreen.x),
12876
+ width: Math.abs(targetScreen.x - anchorMarkerScreen.x),
12839
12877
  height: 20,
12840
12878
  style: { overflow: "visible" },
12841
12879
  children: /* @__PURE__ */ jsx12("div", { style: { ...labelStyle, textAlign: "center" }, children: xLabelText })
@@ -12844,10 +12882,10 @@ var BoardAnchorOffsetOverlay = ({
12844
12882
  shouldShowYLabel && /* @__PURE__ */ jsx12(
12845
12883
  "foreignObject",
12846
12884
  {
12847
- x: componentScreen.x + yLabelOffset,
12848
- y: Math.min(anchorMarkerScreen.y, componentScreen.y),
12885
+ x: targetScreen.x + yLabelOffset,
12886
+ y: Math.min(anchorMarkerScreen.y, targetScreen.y),
12849
12887
  width: 20,
12850
- height: Math.abs(componentScreen.y - anchorMarkerScreen.y),
12888
+ height: Math.abs(targetScreen.y - anchorMarkerScreen.y),
12851
12889
  style: { overflow: "visible" },
12852
12890
  children: /* @__PURE__ */ jsx12(
12853
12891
  "div",
@@ -12863,7 +12901,7 @@ var BoardAnchorOffsetOverlay = ({
12863
12901
  )
12864
12902
  }
12865
12903
  )
12866
- ] }, `${board.pcb_board_id}-${component.pcb_component_id}`);
12904
+ ] }, `${target.board.pcb_board_id}-${targetId}-${target.type}`);
12867
12905
  }),
12868
12906
  Array.from(boardAnchorScreens.entries()).map(
12869
12907
  ([boardId, anchorScreen]) => /* @__PURE__ */ jsxs9("g", { children: [
@@ -12900,26 +12938,6 @@ var BoardAnchorOffsetOverlay = ({
12900
12938
 
12901
12939
  // src/components/AnchorOffsetOverlay/Group/index.tsx
12902
12940
  import { applyToPoint as applyToPoint13 } from "transformation-matrix";
12903
-
12904
- // src/components/AnchorOffsetOverlay/Group/calculateGroupBoundingBox.ts
12905
- import { distance as distance3 } from "circuit-json";
12906
- var calculateGroupBoundingBox = (groupComponents) => {
12907
- const points = [];
12908
- for (const comp of groupComponents) {
12909
- if (!comp.center) {
12910
- continue;
12911
- }
12912
- const width = typeof comp.width === "number" ? comp.width : distance3.parse(comp.width);
12913
- const height = typeof comp.height === "number" ? comp.height : distance3.parse(comp.height);
12914
- const halfWidth = width / 2;
12915
- const halfHeight = height / 2;
12916
- points.push({ x: comp.center.x - halfWidth, y: comp.center.y - halfHeight });
12917
- points.push({ x: comp.center.x + halfWidth, y: comp.center.y + halfHeight });
12918
- }
12919
- return getBoundsFromPoints(points);
12920
- };
12921
-
12922
- // src/components/AnchorOffsetOverlay/Group/index.tsx
12923
12941
  import { jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
12924
12942
  var GroupAnchorOffsetOverlay = ({
12925
12943
  elements,
@@ -12941,29 +12959,53 @@ var GroupAnchorOffsetOverlay = ({
12941
12959
  }
12942
12960
  return null;
12943
12961
  }).filter((id) => Boolean(id));
12962
+ const hoveredGroupIds = /* @__PURE__ */ new Set();
12963
+ hoveredComponentIds.forEach((componentId) => {
12964
+ const component = components.find((c) => c.pcb_component_id === componentId);
12965
+ if (component?.pcb_group_id) {
12966
+ hoveredGroupIds.add(component.pcb_group_id);
12967
+ }
12968
+ if (component?.position_mode === "relative_to_group_anchor" && component.positioned_relative_to_pcb_group_id) {
12969
+ hoveredGroupIds.add(component.positioned_relative_to_pcb_group_id);
12970
+ }
12971
+ });
12944
12972
  const isShowingAnchorOffsets = useGlobalStore(
12945
12973
  (s) => s.is_showing_group_anchor_offsets
12946
12974
  );
12947
12975
  if (!isShowingAnchorOffsets && hoveredComponentIds.length === 0) {
12948
12976
  return null;
12949
12977
  }
12950
- const targets = components.map((component) => {
12978
+ const componentTargets = components.map((component) => {
12951
12979
  if (component.position_mode === "relative_to_group_anchor" && component.positioned_relative_to_pcb_group_id) {
12952
12980
  const parentGroup = groups.find(
12953
12981
  (group) => group.pcb_group_id === component.positioned_relative_to_pcb_group_id
12954
12982
  );
12955
- return parentGroup && parentGroup.anchor_position ? { component, parentGroup } : null;
12983
+ return parentGroup && parentGroup.anchor_position ? { component, parentGroup, type: "component" } : null;
12956
12984
  }
12957
12985
  if (component.pcb_group_id) {
12958
12986
  const parentGroup = groups.find(
12959
12987
  (group) => group.pcb_group_id === component.pcb_group_id
12960
12988
  );
12961
- return parentGroup && parentGroup.anchor_position ? { component, parentGroup } : null;
12989
+ return parentGroup && parentGroup.anchor_position ? { component, parentGroup, type: "component" } : null;
12962
12990
  }
12963
12991
  return null;
12964
12992
  }).filter(
12965
12993
  (target) => Boolean(target)
12966
12994
  );
12995
+ const groupTargets = groups.map((group) => {
12996
+ if (group.position_mode === "relative_to_group_anchor" && group.positioned_relative_to_pcb_group_id) {
12997
+ const parentGroup = groups.find(
12998
+ (g) => g.pcb_group_id === group.positioned_relative_to_pcb_group_id
12999
+ );
13000
+ if (parentGroup && parentGroup.anchor_position && group.center) {
13001
+ return { group, parentGroup, type: "group" };
13002
+ }
13003
+ }
13004
+ return null;
13005
+ }).filter(
13006
+ (target) => Boolean(target)
13007
+ );
13008
+ const targets = [...componentTargets, ...groupTargets];
12967
13009
  if (targets.length === 0) return null;
12968
13010
  const shouldShowAllTargets = hoveredComponentIds.length === 0;
12969
13011
  const labelStyle = {
@@ -12974,15 +13016,22 @@ var GroupAnchorOffsetOverlay = ({
12974
13016
  fontFamily: "monospace",
12975
13017
  fontWeight: "bold"
12976
13018
  };
12977
- const targetEntries = targets.filter(
12978
- ({ component }) => shouldShowAllTargets || hoveredComponentIds.includes(component.pcb_component_id)
12979
- );
13019
+ const targetEntries = targets.filter((target) => {
13020
+ if (target.type === "component") {
13021
+ return shouldShowAllTargets || hoveredComponentIds.includes(target.component.pcb_component_id);
13022
+ } else {
13023
+ return shouldShowAllTargets || hoveredGroupIds.has(target.group.pcb_group_id) || hoveredGroupIds.has(target.parentGroup.pcb_group_id);
13024
+ }
13025
+ });
12980
13026
  if (targetEntries.length === 0) return null;
12981
13027
  const groupAnchorScreens = /* @__PURE__ */ new Map();
12982
- targetEntries.forEach(({ parentGroup }) => {
12983
- if (!parentGroup.anchor_position) return;
12984
- const anchorScreen = applyToPoint13(transform, parentGroup.anchor_position);
12985
- groupAnchorScreens.set(parentGroup.pcb_group_id, anchorScreen);
13028
+ targetEntries.forEach((target) => {
13029
+ if (!target.parentGroup.anchor_position) return;
13030
+ const anchorScreen = applyToPoint13(
13031
+ transform,
13032
+ target.parentGroup.anchor_position
13033
+ );
13034
+ groupAnchorScreens.set(target.parentGroup.pcb_group_id, anchorScreen);
12986
13035
  });
12987
13036
  return /* @__PURE__ */ jsx13(
12988
13037
  "div",
@@ -13009,34 +13058,48 @@ var GroupAnchorOffsetOverlay = ({
13009
13058
  width: containerWidth,
13010
13059
  height: containerHeight,
13011
13060
  children: [
13012
- targetEntries.map(({ component, parentGroup }) => {
13013
- const anchor = parentGroup.anchor_position;
13014
- const center = component.center;
13015
- if (!anchor || !center) return null;
13061
+ targetEntries.map((target) => {
13062
+ const anchor = target.parentGroup.anchor_position;
13063
+ if (!anchor) return null;
13016
13064
  const anchorMarkerPosition = { x: anchor.x, y: anchor.y };
13017
- const targetCenter = { x: center.x, y: center.y };
13018
- const groupComponents = components.filter(
13019
- (comp) => comp.pcb_group_id === parentGroup.pcb_group_id
13020
- );
13021
- const boundingBox = calculateGroupBoundingBox(groupComponents);
13022
- if (!boundingBox) return null;
13065
+ let targetCenter = null;
13066
+ let targetId;
13067
+ let displayOffsetX;
13068
+ let displayOffsetY;
13069
+ if (target.type === "component") {
13070
+ const center = target.component.center;
13071
+ if (!center) return null;
13072
+ targetCenter = { x: center.x, y: center.y };
13073
+ targetId = target.component.pcb_component_id;
13074
+ displayOffsetX = target.component.display_offset_x;
13075
+ displayOffsetY = target.component.display_offset_y;
13076
+ } else {
13077
+ if (!target.group.center) return null;
13078
+ targetCenter = {
13079
+ x: target.group.center.x,
13080
+ y: target.group.center.y
13081
+ };
13082
+ targetId = target.group.pcb_group_id;
13083
+ displayOffsetX = target.group.display_offset_x;
13084
+ displayOffsetY = target.group.display_offset_y;
13085
+ }
13023
13086
  const offsetX = targetCenter.x - anchorMarkerPosition.x;
13024
13087
  const offsetY = targetCenter.y - anchorMarkerPosition.y;
13025
13088
  const anchorMarkerScreen = applyToPoint13(
13026
13089
  transform,
13027
13090
  anchorMarkerPosition
13028
13091
  );
13029
- const componentScreen = applyToPoint13(transform, targetCenter);
13030
- const xLineLength = Math.abs(componentScreen.x - anchorMarkerScreen.x);
13031
- const yLineLength = Math.abs(componentScreen.y - anchorMarkerScreen.y);
13032
- const isComponentAboveAnchor = componentScreen.y < anchorMarkerScreen.y;
13033
- const isComponentRightOfAnchor = componentScreen.x > anchorMarkerScreen.x;
13034
- const xLabelOffset = isComponentAboveAnchor ? VISUAL_CONFIG.LABEL_OFFSET_ABOVE : VISUAL_CONFIG.LABEL_OFFSET_BELOW;
13035
- const yLabelOffset = isComponentRightOfAnchor ? VISUAL_CONFIG.LABEL_OFFSET_RIGHT : VISUAL_CONFIG.LABEL_OFFSET_LEFT;
13092
+ const targetScreen = applyToPoint13(transform, targetCenter);
13093
+ const xLineLength = Math.abs(targetScreen.x - anchorMarkerScreen.x);
13094
+ const yLineLength = Math.abs(targetScreen.y - anchorMarkerScreen.y);
13095
+ const isTargetAboveAnchor = targetScreen.y < anchorMarkerScreen.y;
13096
+ const isTargetRightOfAnchor = targetScreen.x > anchorMarkerScreen.x;
13097
+ const xLabelOffset = isTargetAboveAnchor ? VISUAL_CONFIG.LABEL_OFFSET_ABOVE : VISUAL_CONFIG.LABEL_OFFSET_BELOW;
13098
+ const yLabelOffset = isTargetRightOfAnchor ? VISUAL_CONFIG.LABEL_OFFSET_RIGHT : VISUAL_CONFIG.LABEL_OFFSET_LEFT;
13036
13099
  const shouldShowXLabel = xLineLength > VISUAL_CONFIG.MIN_LINE_LENGTH_FOR_LABEL;
13037
13100
  const shouldShowYLabel = yLineLength > VISUAL_CONFIG.MIN_LINE_LENGTH_FOR_LABEL;
13038
- const xLabelText = component.display_offset_x ?? `\u0394x: ${offsetX.toFixed(2)}mm`;
13039
- const yLabelText = component.display_offset_y ?? `\u0394y: ${offsetY.toFixed(2)}mm`;
13101
+ const xLabelText = displayOffsetX ?? `\u0394x: ${offsetX.toFixed(2)}mm`;
13102
+ const yLabelText = displayOffsetY ?? `\u0394y: ${offsetY.toFixed(2)}mm`;
13040
13103
  return /* @__PURE__ */ jsxs10(
13041
13104
  "g",
13042
13105
  {
@@ -13046,7 +13109,7 @@ var GroupAnchorOffsetOverlay = ({
13046
13109
  {
13047
13110
  x1: anchorMarkerScreen.x,
13048
13111
  y1: anchorMarkerScreen.y,
13049
- x2: componentScreen.x,
13112
+ x2: targetScreen.x,
13050
13113
  y2: anchorMarkerScreen.y,
13051
13114
  stroke: COLORS.OFFSET_LINE,
13052
13115
  strokeWidth: VISUAL_CONFIG.LINE_STROKE_WIDTH,
@@ -13056,10 +13119,10 @@ var GroupAnchorOffsetOverlay = ({
13056
13119
  /* @__PURE__ */ jsx13(
13057
13120
  "line",
13058
13121
  {
13059
- x1: componentScreen.x,
13122
+ x1: targetScreen.x,
13060
13123
  y1: anchorMarkerScreen.y,
13061
- x2: componentScreen.x,
13062
- y2: componentScreen.y,
13124
+ x2: targetScreen.x,
13125
+ y2: targetScreen.y,
13063
13126
  stroke: COLORS.OFFSET_LINE,
13064
13127
  strokeWidth: VISUAL_CONFIG.LINE_STROKE_WIDTH,
13065
13128
  strokeDasharray: VISUAL_CONFIG.LINE_DASH_PATTERN
@@ -13068,8 +13131,8 @@ var GroupAnchorOffsetOverlay = ({
13068
13131
  /* @__PURE__ */ jsx13(
13069
13132
  "circle",
13070
13133
  {
13071
- cx: componentScreen.x,
13072
- cy: componentScreen.y,
13134
+ cx: targetScreen.x,
13135
+ cy: targetScreen.y,
13073
13136
  r: VISUAL_CONFIG.COMPONENT_MARKER_RADIUS,
13074
13137
  fill: COLORS.COMPONENT_MARKER_FILL,
13075
13138
  stroke: COLORS.COMPONENT_MARKER_STROKE,
@@ -13079,9 +13142,9 @@ var GroupAnchorOffsetOverlay = ({
13079
13142
  shouldShowXLabel && /* @__PURE__ */ jsx13(
13080
13143
  "foreignObject",
13081
13144
  {
13082
- x: Math.min(anchorMarkerScreen.x, componentScreen.x),
13145
+ x: Math.min(anchorMarkerScreen.x, targetScreen.x),
13083
13146
  y: anchorMarkerScreen.y + xLabelOffset,
13084
- width: Math.abs(componentScreen.x - anchorMarkerScreen.x),
13147
+ width: Math.abs(targetScreen.x - anchorMarkerScreen.x),
13085
13148
  height: 20,
13086
13149
  style: { overflow: "visible" },
13087
13150
  children: /* @__PURE__ */ jsx13("div", { style: { ...labelStyle, textAlign: "center" }, children: xLabelText })
@@ -13090,10 +13153,10 @@ var GroupAnchorOffsetOverlay = ({
13090
13153
  shouldShowYLabel && /* @__PURE__ */ jsx13(
13091
13154
  "foreignObject",
13092
13155
  {
13093
- x: componentScreen.x + yLabelOffset,
13094
- y: Math.min(anchorMarkerScreen.y, componentScreen.y),
13156
+ x: targetScreen.x + yLabelOffset,
13157
+ y: Math.min(anchorMarkerScreen.y, targetScreen.y),
13095
13158
  width: 20,
13096
- height: Math.abs(componentScreen.y - anchorMarkerScreen.y),
13159
+ height: Math.abs(targetScreen.y - anchorMarkerScreen.y),
13097
13160
  style: { overflow: "visible" },
13098
13161
  children: /* @__PURE__ */ jsx13(
13099
13162
  "div",
@@ -13111,7 +13174,7 @@ var GroupAnchorOffsetOverlay = ({
13111
13174
  )
13112
13175
  ]
13113
13176
  },
13114
- `${parentGroup.pcb_group_id}-${component.pcb_component_id}`
13177
+ `${target.parentGroup.pcb_group_id}-${targetId}-${target.type}`
13115
13178
  );
13116
13179
  }),
13117
13180
  Array.from(groupAnchorScreens.entries()).map(
@@ -13190,22 +13253,22 @@ var getPrimitivesUnderPoint = (primitives, rwPoint, transform) => {
13190
13253
  for (const primitive of primitives) {
13191
13254
  if (!primitive._element) continue;
13192
13255
  if ("x1" in primitive && primitive._element?.type === "pcb_trace") {
13193
- const distance5 = pointToSegmentDistance(
13256
+ const distance4 = pointToSegmentDistance(
13194
13257
  { x: rwPoint.x, y: rwPoint.y },
13195
13258
  { x: primitive.x1, y: primitive.y1 },
13196
13259
  { x: primitive.x2, y: primitive.y2 }
13197
13260
  );
13198
13261
  const lineWidth = primitive.width || 0.5;
13199
13262
  const detectionThreshold = Math.max(lineWidth * 25, 2) / transform.a;
13200
- if (distance5 < detectionThreshold) {
13263
+ if (distance4 < detectionThreshold) {
13201
13264
  newMousedPrimitives.push(primitive);
13202
13265
  }
13203
13266
  continue;
13204
13267
  }
13205
13268
  if (primitive.pcb_drawing_type === "polygon") {
13206
13269
  const points = primitive.points.map((point) => ({
13207
- x: distance4.parse(point.x),
13208
- y: distance4.parse(point.y)
13270
+ x: distance3.parse(point.x),
13271
+ y: distance3.parse(point.y)
13209
13272
  }));
13210
13273
  const boundingBox = getPolygonBoundingBox(points);
13211
13274
  if (!boundingBox) continue;
@@ -13219,8 +13282,8 @@ var getPrimitivesUnderPoint = (primitives, rwPoint, transform) => {
13219
13282
  }
13220
13283
  if (primitive.pcb_drawing_type === "polygon_with_arcs") {
13221
13284
  const points = primitive.brep_shape.outer_ring.vertices.map((v) => ({
13222
- x: distance4.parse(v.x),
13223
- y: distance4.parse(v.y)
13285
+ x: distance3.parse(v.x),
13286
+ y: distance3.parse(v.y)
13224
13287
  }));
13225
13288
  const boundingBox = getPolygonBoundingBox(points);
13226
13289
  if (!boundingBox) continue;
@@ -13668,11 +13731,11 @@ var RatsNestOverlay = ({ transform, soup, children }) => {
13668
13731
  connectedIds.forEach((id) => {
13669
13732
  const pos = getElementPosition(id);
13670
13733
  if (pos) {
13671
- const distance5 = Math.sqrt(
13734
+ const distance4 = Math.sqrt(
13672
13735
  (sourcePoint.x - pos.x) ** 2 + (sourcePoint.y - pos.y) ** 2
13673
13736
  );
13674
- if (distance5 < minDistance && distance5 > 0) {
13675
- minDistance = distance5;
13737
+ if (distance4 < minDistance && distance4 > 0) {
13738
+ minDistance = distance4;
13676
13739
  nearestPoint = pos;
13677
13740
  }
13678
13741
  }
@@ -13752,7 +13815,7 @@ import { css as css3 } from "@emotion/css";
13752
13815
  // package.json
13753
13816
  var package_default = {
13754
13817
  name: "@tscircuit/pcb-viewer",
13755
- version: "1.11.281",
13818
+ version: "1.11.282",
13756
13819
  main: "dist/index.js",
13757
13820
  type: "module",
13758
13821
  repository: "tscircuit/pcb-viewer",