@tscircuit/pcb-viewer 1.4.3 → 1.4.5

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/README.md CHANGED
@@ -4,7 +4,9 @@
4
4
 
5
5
  [Examples](https://pcb-viewer.vercel.app/) · [TSCircuit](https://tscircuit.com) · [Open in CodeSandbox](https://codesandbox.io/p/github/tscircuit/pcb-viewer)
6
6
 
7
- Render PCBs w/ React
7
+ Render Printed Circuit Boards w/ React
8
+
9
+ If you want to render to an image, check out [circuit-to-png](https://github.com/tscircuit/circuit-to-png)
8
10
 
9
11
  ![image](https://github.com/tscircuit/pcb-viewer/assets/1910070/e010f44e-b8c0-4e1d-9d59-1ea66716427f)
10
12
 
package/dist/index.d.ts CHANGED
@@ -33,15 +33,34 @@ type EditTraceHintEvent = {
33
33
  };
34
34
  type EditEvent = EditComponentLocationEvent | EditTraceHintEvent;
35
35
 
36
+ interface State {
37
+ selected_layer: LayerRef;
38
+ in_edit_mode: boolean;
39
+ in_move_footprint_mode: boolean;
40
+ in_draw_trace_mode: boolean;
41
+ is_moving_component: boolean;
42
+ is_drawing_trace: boolean;
43
+ is_showing_rats_nest: boolean;
44
+ selectLayer: (layer: LayerRef) => void;
45
+ setEditMode: (mode: "off" | "move_footprint" | "draw_trace") => void;
46
+ setIsMovingComponent: (is_moving: boolean) => void;
47
+ setIsDrawingTrace: (is_drawing: boolean) => void;
48
+ setIsShowingRatsNest: (is_showing: boolean) => void;
49
+ }
50
+ type StateProps = {
51
+ [key in keyof State]: State[key] extends boolean ? boolean : never;
52
+ };
53
+
36
54
  type Props = {
37
55
  children?: any;
38
56
  soup?: any;
39
57
  height?: number;
40
58
  allowEditing?: boolean;
41
59
  editEvents?: EditEvent[];
60
+ initialState?: Partial<StateProps>;
42
61
  onEditEventsChanged?: (editEvents: EditEvent[]) => void;
43
62
  };
44
- declare const PCBViewer: ({ children, soup, height, allowEditing, editEvents: editEventsProp, onEditEventsChanged, }: Props) => react_jsx_runtime.JSX.Element;
63
+ declare const PCBViewer: ({ children, soup, height, initialState, allowEditing, editEvents: editEventsProp, onEditEventsChanged, }: Props) => react_jsx_runtime.JSX.Element;
45
64
 
46
65
  declare const applyEditEvents: (soup: AnySoupElement[], edit_events: EditEvent[]) => AnySoupElement[];
47
66
 
package/dist/index.js CHANGED
@@ -870,10 +870,10 @@ var require_lodash14 = __commonJS({
870
870
  // node_modules/lodash.identity/index.js
871
871
  var require_lodash15 = __commonJS({
872
872
  "node_modules/lodash.identity/index.js": function(exports2, module2) {
873
- function identity6(value) {
873
+ function identity7(value) {
874
874
  return value;
875
875
  }
876
- module2.exports = identity6;
876
+ module2.exports = identity7;
877
877
  }
878
878
  });
879
879
  // node_modules/lodash.support/index.js
@@ -893,7 +893,7 @@ var require_lodash16 = __commonJS({
893
893
  var require_lodash17 = __commonJS({
894
894
  "node_modules/lodash._basecreatecallback/index.js": function(exports2, module2) {
895
895
  var bind = require_lodash14();
896
- var identity6 = require_lodash15();
896
+ var identity7 = require_lodash15();
897
897
  var setBindData = require_lodash8();
898
898
  var support = require_lodash16();
899
899
  var reFuncName = /^\s*function[ \n\r\t]+\w/;
@@ -901,7 +901,7 @@ var require_lodash17 = __commonJS({
901
901
  var fnToString = Function.prototype.toString;
902
902
  function baseCreateCallback(func, thisArg, argCount) {
903
903
  if (typeof func != "function") {
904
- return identity6;
904
+ return identity7;
905
905
  }
906
906
  if (typeof thisArg == "undefined" || !("prototype" in func)) {
907
907
  return func;
@@ -10918,7 +10918,7 @@ var require_dist2 = __commonJS({
10918
10918
  }
10919
10919
  });
10920
10920
  module2.exports = __toCommonJS2(soup_util_exports);
10921
- var su4 = function(soup) {
10921
+ var su5 = function(soup) {
10922
10922
  var su22 = new Proxy({}, {
10923
10923
  get: function(proxy_target, component_type) {
10924
10924
  return {
@@ -10991,8 +10991,8 @@ var require_dist2 = __commonJS({
10991
10991
  });
10992
10992
  return su22;
10993
10993
  };
10994
- su4.unparsed = su4;
10995
- var su_default = su4;
10994
+ su5.unparsed = su5;
10995
+ var su_default = su5;
10996
10996
  var directionToVec = function(direction) {
10997
10997
  if (direction === "up") return {
10998
10998
  x: 0,
@@ -11061,30 +11061,30 @@ var require_dist2 = __commonJS({
11061
11061
  else if (sideOrDir === "right") return "left";
11062
11062
  throw new Error("Invalid sideOrDir: ".concat(sideOrDir));
11063
11063
  };
11064
- var import_transformation_matrix9 = require("transformation-matrix");
11064
+ var import_transformation_matrix10 = require("transformation-matrix");
11065
11065
  var transformSchematicElement = function(elm, matrix) {
11066
11066
  if (elm.type === "schematic_component") {
11067
- elm.center = (0, import_transformation_matrix9.applyToPoint)(matrix, elm.center);
11067
+ elm.center = (0, import_transformation_matrix10.applyToPoint)(matrix, elm.center);
11068
11068
  } else if (elm.type === "schematic_port") {
11069
- elm.center = (0, import_transformation_matrix9.applyToPoint)(matrix, elm.center);
11069
+ elm.center = (0, import_transformation_matrix10.applyToPoint)(matrix, elm.center);
11070
11070
  if (elm.facing_direction) {
11071
11071
  elm.facing_direction = rotateDirection(elm.facing_direction, -(Math.atan2(matrix.b, matrix.a) / Math.PI) * 2);
11072
11072
  }
11073
11073
  } else if (elm.type === "schematic_text") {
11074
- elm.position = (0, import_transformation_matrix9.applyToPoint)(matrix, elm.position);
11074
+ elm.position = (0, import_transformation_matrix10.applyToPoint)(matrix, elm.position);
11075
11075
  } else if (elm.type === "schematic_trace") {} else if (elm.type === "schematic_box") {
11076
- var _ref = (0, import_transformation_matrix9.applyToPoint)(matrix, {
11076
+ var _ref = (0, import_transformation_matrix10.applyToPoint)(matrix, {
11077
11077
  x: elm.x,
11078
11078
  y: elm.y
11079
11079
  }), x = _ref.x, y = _ref.y;
11080
11080
  elm.x = x;
11081
11081
  elm.y = y;
11082
11082
  } else if (elm.type === "schematic_line") {
11083
- var _ref1 = (0, import_transformation_matrix9.applyToPoint)(matrix, {
11083
+ var _ref1 = (0, import_transformation_matrix10.applyToPoint)(matrix, {
11084
11084
  x: elm.x1,
11085
11085
  y: elm.y1
11086
11086
  }), x1 = _ref1.x, y1 = _ref1.y;
11087
- var _ref2 = (0, import_transformation_matrix9.applyToPoint)(matrix, {
11087
+ var _ref2 = (0, import_transformation_matrix10.applyToPoint)(matrix, {
11088
11088
  x: elm.x2,
11089
11089
  y: elm.y2
11090
11090
  }), x2 = _ref2.x, y2 = _ref2.y;
@@ -11102,19 +11102,19 @@ var require_dist2 = __commonJS({
11102
11102
  };
11103
11103
  var transformPCBElement2 = function(elm, matrix) {
11104
11104
  if (elm.type === "pcb_plated_hole" || elm.type === "pcb_hole" || elm.type === "pcb_via" || elm.type === "pcb_smtpad" || elm.type === "pcb_port") {
11105
- var _ref = (0, import_transformation_matrix9.applyToPoint)(matrix, {
11105
+ var _ref = (0, import_transformation_matrix10.applyToPoint)(matrix, {
11106
11106
  x: elm.x,
11107
11107
  y: elm.y
11108
11108
  }), x = _ref.x, y = _ref.y;
11109
11109
  elm.x = x;
11110
11110
  elm.y = y;
11111
11111
  } else if (elm.type === "pcb_silkscreen_text" || elm.type === "pcb_fabrication_note_text") {
11112
- elm.anchor_position = (0, import_transformation_matrix9.applyToPoint)(matrix, elm.anchor_position);
11112
+ elm.anchor_position = (0, import_transformation_matrix10.applyToPoint)(matrix, elm.anchor_position);
11113
11113
  } else if (elm.type === "pcb_silkscreen_circle" || elm.type === "pcb_silkscreen_rect" || elm.type === "pcb_component") {
11114
- elm.center = (0, import_transformation_matrix9.applyToPoint)(matrix, elm.center);
11114
+ elm.center = (0, import_transformation_matrix10.applyToPoint)(matrix, elm.center);
11115
11115
  } else if (elm.type === "pcb_silkscreen_path" || elm.type === "pcb_trace" || elm.type === "pcb_fabrication_note_path") {
11116
11116
  elm.route = elm.route.map(function(rp) {
11117
- var tp = (0, import_transformation_matrix9.applyToPoint)(matrix, rp);
11117
+ var tp = (0, import_transformation_matrix10.applyToPoint)(matrix, rp);
11118
11118
  rp.x = tp.x;
11119
11119
  rp.y = tp.y;
11120
11120
  return rp;
@@ -11128,14 +11128,14 @@ var require_dist2 = __commonJS({
11128
11128
  x: elm.x2,
11129
11129
  y: elm.y2
11130
11130
  };
11131
- var p1t = (0, import_transformation_matrix9.applyToPoint)(matrix, p1);
11132
- var p2t = (0, import_transformation_matrix9.applyToPoint)(matrix, p2);
11131
+ var p1t = (0, import_transformation_matrix10.applyToPoint)(matrix, p1);
11132
+ var p2t = (0, import_transformation_matrix10.applyToPoint)(matrix, p2);
11133
11133
  elm.x1 = p1t.x;
11134
11134
  elm.y1 = p1t.y;
11135
11135
  elm.x2 = p2t.x;
11136
11136
  elm.y2 = p2t.y;
11137
11137
  } else if (elm.type === "cad_component") {
11138
- var newPos = (0, import_transformation_matrix9.applyToPoint)(matrix, {
11138
+ var newPos = (0, import_transformation_matrix10.applyToPoint)(matrix, {
11139
11139
  x: elm.position.x,
11140
11140
  y: elm.position.y
11141
11141
  });
@@ -11145,7 +11145,7 @@ var require_dist2 = __commonJS({
11145
11145
  return elm;
11146
11146
  };
11147
11147
  var transformPCBElements2 = function(elms, matrix) {
11148
- var tsr = (0, import_transformation_matrix9.decomposeTSR)(matrix);
11148
+ var tsr = (0, import_transformation_matrix10.decomposeTSR)(matrix);
11149
11149
  var flipPadWidthHeight = Math.round(tsr.rotation.angle / (Math.PI / 2)) % 2 === 1;
11150
11150
  var transformedElms = elms.map(function(elm) {
11151
11151
  return transformPCBElement2(elm, matrix);
@@ -11331,7 +11331,7 @@ var require_dist3 = __commonJS({
11331
11331
  }
11332
11332
  });
11333
11333
  module2.exports = __toCommonJS2(src_exports2);
11334
- var import_transformation_matrix9 = require("transformation-matrix");
11334
+ var import_transformation_matrix10 = require("transformation-matrix");
11335
11335
  var import_react18 = require("react");
11336
11336
  var useMouseMatrixTransform2 = function() {
11337
11337
  var props = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
@@ -11340,7 +11340,7 @@ var require_dist3 = __commonJS({
11340
11340
  var _props_canvasElm;
11341
11341
  var outerCanvasElm = (_props_canvasElm = props.canvasElm) !== null && _props_canvasElm !== void 0 ? _props_canvasElm : extRef.current;
11342
11342
  var _props_initialTransform;
11343
- var _ref1 = _sliced_to_array((0, import_react18.useState)((_props_initialTransform = props.initialTransform) !== null && _props_initialTransform !== void 0 ? _props_initialTransform : (0, import_transformation_matrix9.identity)()), 2), internalTransform = _ref1[0], setInternalTransform = _ref1[1];
11343
+ var _ref1 = _sliced_to_array((0, import_react18.useState)((_props_initialTransform = props.initialTransform) !== null && _props_initialTransform !== void 0 ? _props_initialTransform : (0, import_transformation_matrix10.identity)()), 2), internalTransform = _ref1[0], setInternalTransform = _ref1[1];
11344
11344
  var _ref2 = _sliced_to_array((0, import_react18.useState)(0), 2), waitCounter = _ref2[0], setWaitCounter = _ref2[1];
11345
11345
  var _ref3 = _sliced_to_array((0, import_react18.useReducer)(function(s) {
11346
11346
  return s + 1;
@@ -11377,7 +11377,7 @@ var require_dist3 = __commonJS({
11377
11377
  var handleMouseUp = function handleMouseUp(e) {
11378
11378
  if (!md) return;
11379
11379
  m1 = getMousePos(e);
11380
- var new_tf = (0, import_transformation_matrix9.compose)((0, import_transformation_matrix9.translate)(m1.x - m0.x, m1.y - m0.y), init_tf);
11380
+ var new_tf = (0, import_transformation_matrix10.compose)((0, import_transformation_matrix10.translate)(m1.x - m0.x, m1.y - m0.y), init_tf);
11381
11381
  setTransform(new_tf);
11382
11382
  init_tf = new_tf;
11383
11383
  md = false;
@@ -11386,11 +11386,11 @@ var require_dist3 = __commonJS({
11386
11386
  mlastrel = getMousePos(e);
11387
11387
  if (!md) return;
11388
11388
  m1 = getMousePos(e);
11389
- setTransform((0, import_transformation_matrix9.compose)((0, import_transformation_matrix9.translate)(m1.x - m0.x, m1.y - m0.y), init_tf));
11389
+ setTransform((0, import_transformation_matrix10.compose)((0, import_transformation_matrix10.translate)(m1.x - m0.x, m1.y - m0.y), init_tf));
11390
11390
  };
11391
11391
  var handleMouseWheel = function handleMouseWheel(e) {
11392
11392
  var center = getMousePos(e);
11393
- var new_tf = (0, import_transformation_matrix9.compose)((0, import_transformation_matrix9.translate)(center.x, center.y), (0, import_transformation_matrix9.scale)(1 - e.deltaY / 1e3, 1 - e.deltaY / 1e3), (0, import_transformation_matrix9.translate)(-center.x, -center.y), init_tf);
11393
+ var new_tf = (0, import_transformation_matrix10.compose)((0, import_transformation_matrix10.translate)(center.x, center.y), (0, import_transformation_matrix10.scale)(1 - e.deltaY / 1e3, 1 - e.deltaY / 1e3), (0, import_transformation_matrix10.translate)(-center.x, -center.y), init_tf);
11394
11394
  setTransform(new_tf);
11395
11395
  init_tf = new_tf;
11396
11396
  e.preventDefault();
@@ -11405,7 +11405,7 @@ var require_dist3 = __commonJS({
11405
11405
  }
11406
11406
  md = false;
11407
11407
  m1 = getMousePos(e);
11408
- var new_tf = (0, import_transformation_matrix9.compose)((0, import_transformation_matrix9.translate)(m1.x - m0.x, m1.y - m0.y), init_tf);
11408
+ var new_tf = (0, import_transformation_matrix10.compose)((0, import_transformation_matrix10.translate)(m1.x - m0.x, m1.y - m0.y), init_tf);
11409
11409
  setTransform(new_tf);
11410
11410
  init_tf = new_tf;
11411
11411
  };
@@ -11460,7 +11460,7 @@ var require_dist3 = __commonJS({
11460
11460
  lastDragCancelTime
11461
11461
  ]);
11462
11462
  var applyTransformToPoint = (0, import_react18.useCallback)(function(obj) {
11463
- return (0, import_transformation_matrix9.applyToPoint)(transform, obj);
11463
+ return (0, import_transformation_matrix10.applyToPoint)(transform, obj);
11464
11464
  }, [
11465
11465
  transform
11466
11466
  ]);
@@ -11979,7 +11979,9 @@ var LAYER_NAME_TO_COLOR = _object_spread({
11979
11979
  tkeepout: colors_default.board.b_crtyd,
11980
11980
  tplace: colors_default.board.b_silks,
11981
11981
  top_silkscreen: colors_default.board.f_silks,
11982
- bottom_silkscreen: colors_default.board.b_silks
11982
+ bottom_silkscreen: colors_default.board.b_silks,
11983
+ top_fabrication: colors_default.board.f_fab,
11984
+ bottom_fabrication: colors_default.board.b_fab
11983
11985
  }, colors_default.board);
11984
11986
  var DEFAULT_DRAW_ORDER = [
11985
11987
  "top",
@@ -12255,9 +12257,9 @@ var import_react2 = require("react");
12255
12257
  var import_jsx_runtime = require("react/jsx-runtime");
12256
12258
  var StoreContext = (0, import_react2.createContext)(null);
12257
12259
  var ContextProviders = function(param) {
12258
- var children = param.children;
12260
+ var children = param.children, initialState = param.initialState;
12259
12261
  var store = (0, import_react.useMemo)(function() {
12260
- return createStore();
12262
+ return createStore(initialState);
12261
12263
  }, []);
12262
12264
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StoreContext.Provider, {
12263
12265
  value: store,
@@ -12267,14 +12269,17 @@ var ContextProviders = function(param) {
12267
12269
  // src/global-store.ts
12268
12270
  var import_react3 = require("react");
12269
12271
  var createStore = function() {
12272
+ var initialState = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
12270
12273
  return (0, import_zustand.createStore)(function(set) {
12271
- return {
12274
+ return _object_spread_props(_object_spread({
12272
12275
  selected_layer: "top",
12273
12276
  in_edit_mode: false,
12274
12277
  in_move_footprint_mode: false,
12275
12278
  in_draw_trace_mode: false,
12276
12279
  is_moving_component: false,
12277
12280
  is_drawing_trace: false,
12281
+ is_showing_rats_nest: false
12282
+ }, initialState), {
12278
12283
  selectLayer: function(layer) {
12279
12284
  return set({
12280
12285
  selected_layer: layer
@@ -12289,6 +12294,11 @@ var createStore = function() {
12289
12294
  is_drawing_trace: false
12290
12295
  });
12291
12296
  },
12297
+ setIsShowingRatsNest: function(is_showing) {
12298
+ return set({
12299
+ is_showing_rats_nest: is_showing
12300
+ });
12301
+ },
12292
12302
  setIsMovingComponent: function(is_moving) {
12293
12303
  return set({
12294
12304
  is_moving_component: is_moving
@@ -12299,7 +12309,7 @@ var createStore = function() {
12299
12309
  is_drawing_trace: is_drawing
12300
12310
  });
12301
12311
  }
12302
- };
12312
+ });
12303
12313
  });
12304
12314
  };
12305
12315
  var useGlobalStore = function(s) {
@@ -12738,14 +12748,14 @@ var convertElementToPrimitives = function(element, allElements) {
12738
12748
  }
12739
12749
  return route1.slice(0, -1).map(function(point, index) {
12740
12750
  var nextPoint = route1[index + 1];
12751
+ var _element_stroke_width;
12741
12752
  return {
12742
12753
  pcb_drawing_type: "line",
12743
12754
  x1: point.x,
12744
12755
  y1: point.y,
12745
12756
  x2: nextPoint.x,
12746
12757
  y2: nextPoint.y,
12747
- width: 0.1,
12748
- // TODO add strokewidth
12758
+ width: (_element_stroke_width = element.stroke_width) !== null && _element_stroke_width !== void 0 ? _element_stroke_width : 0.1,
12749
12759
  squareCap: false,
12750
12760
  layer: layer2,
12751
12761
  _element: element,
@@ -13280,7 +13290,7 @@ var import_soup2 = __toESM(require_dist());
13280
13290
  // package.json
13281
13291
  var package_default = {
13282
13292
  name: "@tscircuit/pcb-viewer",
13283
- version: "1.4.2",
13293
+ version: "1.4.4",
13284
13294
  main: "dist/index.js",
13285
13295
  repository: "tscircuit/pcb-viewer",
13286
13296
  license: "MIT",
@@ -13395,12 +13405,16 @@ var ToolbarOverlay = function(param) {
13395
13405
  var _useGlobalStore1 = _sliced_to_array(useGlobalStore(function(s) {
13396
13406
  return [
13397
13407
  s.in_move_footprint_mode,
13398
- s.in_draw_trace_mode
13408
+ s.in_draw_trace_mode,
13409
+ s.is_showing_rats_nest
13399
13410
  ];
13400
- }), 2), in_move_footprint_mode = _useGlobalStore1[0], in_draw_trace_mode = _useGlobalStore1[1];
13411
+ }), 3), in_move_footprint_mode = _useGlobalStore1[0], in_draw_trace_mode = _useGlobalStore1[1], is_showing_rats_nest = _useGlobalStore1[2];
13401
13412
  var setEditMode = useGlobalStore(function(s) {
13402
13413
  return s.setEditMode;
13403
13414
  });
13415
+ var setIsShowingRatsNest = useGlobalStore(function(s) {
13416
+ return s.setIsShowingRatsNest;
13417
+ });
13404
13418
  var _elements_filter_length;
13405
13419
  var errorCount = (_elements_filter_length = elements === null || elements === void 0 ? void 0 : elements.filter(function(e) {
13406
13420
  return e.type.includes("error");
@@ -13556,6 +13570,18 @@ var ToolbarOverlay = function(param) {
13556
13570
  "Move Components"
13557
13571
  ]
13558
13572
  })
13573
+ }),
13574
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ToolbarButton, {
13575
+ style: {},
13576
+ onClick: function() {
13577
+ setIsShowingRatsNest(!is_showing_rats_nest);
13578
+ },
13579
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", {
13580
+ children: [
13581
+ is_showing_rats_nest ? "✖ " : "",
13582
+ "Rats Nest"
13583
+ ]
13584
+ })
13559
13585
  })
13560
13586
  ]
13561
13587
  })
@@ -14183,9 +14209,84 @@ var EditTraceHintOverlay = function(param) {
14183
14209
  ]
14184
14210
  });
14185
14211
  };
14186
- // src/components/CanvasElementsRenderer.tsx
14212
+ // src/components/RatsNestOverlay.tsx
14213
+ var import_transformation_matrix7 = require("transformation-matrix");
14214
+ var import_soup_util3 = __toESM(require_dist2());
14187
14215
  var import_jsx_runtime11 = require("react/jsx-runtime");
14216
+ var RatsNestOverlay = function(param) {
14217
+ var transform = param.transform, soup = param.soup, children = param.children;
14218
+ var isShowingRatsNest = useGlobalStore(function(s) {
14219
+ return s.is_showing_rats_nest;
14220
+ });
14221
+ if (!soup || !isShowingRatsNest) return children;
14222
+ if (!transform) transform = (0, import_transformation_matrix7.identity)();
14223
+ var sourceTraces = (0, import_soup_util3.su)(soup).source_trace.list();
14224
+ var groups = [];
14225
+ sourceTraces.forEach(function(sourceTrace) {
14226
+ if (sourceTrace.connected_source_port_ids) {
14227
+ var group = [];
14228
+ sourceTrace.connected_source_port_ids.forEach(function(source_port_id) {
14229
+ var pcbPort = (0, import_soup_util3.su)(soup).pcb_port.getWhere({
14230
+ source_port_id: source_port_id
14231
+ });
14232
+ if (pcbPort) group.push(pcbPort);
14233
+ });
14234
+ groups.push(group);
14235
+ }
14236
+ });
14237
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", {
14238
+ style: {
14239
+ position: "relative"
14240
+ },
14241
+ children: [
14242
+ children,
14243
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("svg", {
14244
+ style: {
14245
+ position: "absolute",
14246
+ left: 0,
14247
+ top: 0,
14248
+ width: "100%",
14249
+ height: "100%",
14250
+ pointerEvents: "none",
14251
+ opacity: 0.5,
14252
+ zIndex: 100
14253
+ },
14254
+ children: groups.map(function(group, index) {
14255
+ var points = group.map(function(port) {
14256
+ return (0, import_transformation_matrix7.applyToPoint)(transform, {
14257
+ x: port.x,
14258
+ y: port.y
14259
+ });
14260
+ });
14261
+ var lines = [];
14262
+ for(var i = 0; i < points.length; i++){
14263
+ for(var j = i + 1; j < points.length; j++){
14264
+ lines.push([
14265
+ points[i],
14266
+ points[j]
14267
+ ]);
14268
+ }
14269
+ }
14270
+ return lines.map(function(param, index2) {
14271
+ var _param = _sliced_to_array(param, 2), start = _param[0], end = _param[1];
14272
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("line", {
14273
+ x1: start.x,
14274
+ y1: start.y,
14275
+ x2: end.x,
14276
+ y2: end.y,
14277
+ stroke: "white",
14278
+ strokeWidth: "1"
14279
+ }, index2);
14280
+ });
14281
+ })
14282
+ })
14283
+ ]
14284
+ });
14285
+ };
14286
+ // src/components/CanvasElementsRenderer.tsx
14287
+ var import_jsx_runtime12 = require("react/jsx-runtime");
14188
14288
  var CanvasElementsRenderer = function(props) {
14289
+ var transform = props.transform, elements = props.elements;
14189
14290
  var primitives = (0, import_react14.useMemo)(function() {
14190
14291
  var primitives2 = props.elements.flatMap(function(elm) {
14191
14292
  return convertElementToPrimitives(elm, props.elements);
@@ -14194,36 +14295,40 @@ var CanvasElementsRenderer = function(props) {
14194
14295
  }, [
14195
14296
  props.elements
14196
14297
  ]);
14197
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(MouseElementTracker, {
14198
- transform: props.transform,
14298
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(MouseElementTracker, {
14299
+ transform: transform,
14199
14300
  primitives: primitives,
14200
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(EditPlacementOverlay, {
14301
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(EditPlacementOverlay, {
14201
14302
  disabled: !props.allowEditing,
14202
- transform: props.transform,
14203
- soup: props.elements,
14303
+ transform: transform,
14304
+ soup: elements,
14204
14305
  cancelPanDrag: props.cancelPanDrag,
14205
14306
  onCreateEditEvent: props.onCreateEditEvent,
14206
14307
  onModifyEditEvent: props.onModifyEditEvent,
14207
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(EditTraceHintOverlay, {
14308
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(EditTraceHintOverlay, {
14208
14309
  disabled: !props.allowEditing,
14209
- transform: props.transform,
14210
- soup: props.elements,
14310
+ transform: transform,
14311
+ soup: elements,
14211
14312
  cancelPanDrag: props.cancelPanDrag,
14212
14313
  onCreateEditEvent: props.onCreateEditEvent,
14213
14314
  onModifyEditEvent: props.onModifyEditEvent,
14214
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(DimensionOverlay, {
14215
- transform: props.transform,
14216
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ToolbarOverlay, {
14217
- elements: props.elements,
14218
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ErrorOverlay, {
14219
- transform: props.transform,
14220
- elements: props.elements,
14221
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(CanvasPrimitiveRenderer, {
14222
- transform: props.transform,
14223
- primitives: primitives,
14224
- width: props.width,
14225
- height: props.height,
14226
- grid: props.grid
14315
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(DimensionOverlay, {
14316
+ transform: transform,
14317
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ToolbarOverlay, {
14318
+ elements: elements,
14319
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ErrorOverlay, {
14320
+ transform: transform,
14321
+ elements: elements,
14322
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(RatsNestOverlay, {
14323
+ transform: transform,
14324
+ soup: elements,
14325
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(CanvasPrimitiveRenderer, {
14326
+ transform: transform,
14327
+ primitives: primitives,
14328
+ width: props.width,
14329
+ height: props.height,
14330
+ grid: props.grid
14331
+ })
14227
14332
  })
14228
14333
  })
14229
14334
  })
@@ -14294,13 +14399,13 @@ var useMeasure_default = isBrowser && typeof window.ResizeObserver !== "undefine
14294
14399
  ];
14295
14400
  };
14296
14401
  // src/PCBViewer.tsx
14297
- var import_transformation_matrix8 = require("transformation-matrix");
14402
+ var import_transformation_matrix9 = require("transformation-matrix");
14298
14403
  var import_builder3 = require("@tscircuit/builder");
14299
14404
  // src/lib/apply-edit-events.ts
14300
14405
  var import_builder = require("@tscircuit/builder");
14301
- var import_transformation_matrix7 = require("transformation-matrix");
14406
+ var import_transformation_matrix8 = require("transformation-matrix");
14302
14407
  // src/lib/apply-edit-events/apply-edit-trace-hint-event.ts
14303
- var import_soup_util3 = __toESM(require_dist2());
14408
+ var import_soup_util4 = __toESM(require_dist2());
14304
14409
  var applyTraceHintEditEvent = function(soup, edit_event) {
14305
14410
  var existing_trace_hint = soup.find(function(th) {
14306
14411
  return th.type === "pcb_trace_hint" && th.pcb_trace_hint_id === edit_event.pcb_trace_hint_id;
@@ -14312,7 +14417,7 @@ var applyTraceHintEditEvent = function(soup, edit_event) {
14312
14417
  }) : e;
14313
14418
  });
14314
14419
  } else {
14315
- var pcb_port = (0, import_soup_util3.su)(soup).pcb_port.get(edit_event.pcb_port_id);
14420
+ var pcb_port = (0, import_soup_util4.su)(soup).pcb_port.get(edit_event.pcb_port_id);
14316
14421
  soup = soup.filter(function(e) {
14317
14422
  return !(e.type === "pcb_trace_hint" && e.pcb_port_id === edit_event.pcb_port_id);
14318
14423
  }).concat([
@@ -14335,7 +14440,7 @@ var applyEditEvents = function(soup, edit_events) {
14335
14440
  var _loop = function() {
14336
14441
  var edit_event = _step.value;
14337
14442
  if (edit_event.pcb_edit_event_type === "edit_component_location") {
14338
- var mat = (0, import_transformation_matrix7.translate)(edit_event.new_center.x - edit_event.original_center.x, edit_event.new_center.y - edit_event.original_center.y);
14443
+ var mat = (0, import_transformation_matrix8.translate)(edit_event.new_center.x - edit_event.original_center.x, edit_event.new_center.y - edit_event.original_center.y);
14339
14444
  soup = soup.map(function(e) {
14340
14445
  return e.pcb_component_id !== edit_event.pcb_component_id ? e : (0, import_builder.transformPCBElement)(e, mat);
14341
14446
  });
@@ -14361,10 +14466,10 @@ var applyEditEvents = function(soup, edit_events) {
14361
14466
  return soup;
14362
14467
  };
14363
14468
  // src/PCBViewer.tsx
14364
- var import_jsx_runtime12 = require("react/jsx-runtime");
14365
- var defaultTransform = (0, import_transformation_matrix8.compose)((0, import_transformation_matrix8.translate)(400, 300), (0, import_transformation_matrix8.scale)(40, -40));
14469
+ var import_jsx_runtime13 = require("react/jsx-runtime");
14470
+ var defaultTransform = (0, import_transformation_matrix9.compose)((0, import_transformation_matrix9.translate)(400, 300), (0, import_transformation_matrix9.scale)(40, -40));
14366
14471
  var PCBViewer = function(param) {
14367
- var children = param.children, soup = param.soup, _param_height = param.height, height = _param_height === void 0 ? 600 : _param_height, _param_allowEditing = param.allowEditing, allowEditing = _param_allowEditing === void 0 ? true : _param_allowEditing, editEventsProp = param.editEvents, onEditEventsChanged = param.onEditEventsChanged;
14472
+ var children = param.children, soup = param.soup, _param_height = param.height, height = _param_height === void 0 ? 600 : _param_height, initialState = param.initialState, _param_allowEditing = param.allowEditing, allowEditing = _param_allowEditing === void 0 ? true : _param_allowEditing, editEventsProp = param.editEvents, onEditEventsChanged = param.onEditEventsChanged;
14368
14473
  var _ref = _sliced_to_array((0, import_react17.useState)([]), 2), stateElements = _ref[0], setStateElements = _ref[1];
14369
14474
  var _useMeasure_default = _sliced_to_array(useMeasure_default(), 2), ref = _useMeasure_default[0], refDimensions = _useMeasure_default[1];
14370
14475
  var _ref1 = _sliced_to_array((0, import_react17.useState)(defaultTransform), 2), transform = _ref1[0], setTransformInternal = _ref1[1];
@@ -14395,8 +14500,8 @@ var PCBViewer = function(param) {
14395
14500
  var _elmBounds_width, _elmBounds_height;
14396
14501
  var scaleFactor = Math.min(((_elmBounds_width = elmBounds.width) !== null && _elmBounds_width !== void 0 ? _elmBounds_width : 0) / width, ((_elmBounds_height = elmBounds.height) !== null && _elmBounds_height !== void 0 ? _elmBounds_height : 0) / height2, 100) * 0.75;
14397
14502
  var _elmBounds_width1, _elmBounds_height1;
14398
- setTransform((0, import_transformation_matrix8.compose)((0, import_transformation_matrix8.translate)(((_elmBounds_width1 = elmBounds.width) !== null && _elmBounds_width1 !== void 0 ? _elmBounds_width1 : 0) / 2, ((_elmBounds_height1 = elmBounds.height) !== null && _elmBounds_height1 !== void 0 ? _elmBounds_height1 : 0) / 2), // translate(100, 0),
14399
- (0, import_transformation_matrix8.scale)(scaleFactor, -scaleFactor, 0, 0), (0, import_transformation_matrix8.translate)(-center.x, -center.y)));
14503
+ setTransform((0, import_transformation_matrix9.compose)((0, import_transformation_matrix9.translate)(((_elmBounds_width1 = elmBounds.width) !== null && _elmBounds_width1 !== void 0 ? _elmBounds_width1 : 0) / 2, ((_elmBounds_height1 = elmBounds.height) !== null && _elmBounds_height1 !== void 0 ? _elmBounds_height1 : 0) / 2), // translate(100, 0),
14504
+ (0, import_transformation_matrix9.scale)(scaleFactor, -scaleFactor, 0, 0), (0, import_transformation_matrix9.translate)(-center.x, -center.y)));
14400
14505
  };
14401
14506
  (0, import_react17.useEffect)(function() {
14402
14507
  var doRender = function doRender() {
@@ -14442,7 +14547,7 @@ var PCBViewer = function(param) {
14442
14547
  children,
14443
14548
  refDimensions
14444
14549
  ]);
14445
- if (error) return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", {
14550
+ if (error) return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", {
14446
14551
  style: {
14447
14552
  color: "red"
14448
14553
  },
@@ -14476,12 +14581,13 @@ var PCBViewer = function(param) {
14476
14581
  setEditEvents(newEditEvents);
14477
14582
  onEditEventsChanged === null || onEditEventsChanged === void 0 ? void 0 : onEditEventsChanged(newEditEvents);
14478
14583
  };
14479
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", {
14584
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", {
14480
14585
  ref: transformRef,
14481
- children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", {
14586
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", {
14482
14587
  ref: ref,
14483
- children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ContextProviders, {
14484
- children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(CanvasElementsRenderer, {
14588
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ContextProviders, {
14589
+ initialState: initialState,
14590
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(CanvasElementsRenderer, {
14485
14591
  transform: transform,
14486
14592
  height: height,
14487
14593
  width: refDimensions.width,