@tscircuit/pcb-viewer 1.2.25 → 1.3.0

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
@@ -7,6 +7,38 @@ function _array_like_to_array(arr, len) {
7
7
  function _array_with_holes(arr) {
8
8
  if (Array.isArray(arr)) return arr;
9
9
  }
10
+ function _array_without_holes(arr) {
11
+ if (Array.isArray(arr)) return _array_like_to_array(arr);
12
+ }
13
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
14
+ try {
15
+ var info = gen[key](arg);
16
+ var value = info.value;
17
+ } catch (error) {
18
+ reject(error);
19
+ return;
20
+ }
21
+ if (info.done) {
22
+ resolve(value);
23
+ } else {
24
+ Promise.resolve(value).then(_next, _throw);
25
+ }
26
+ }
27
+ function _async_to_generator(fn) {
28
+ return function() {
29
+ var self = this, args = arguments;
30
+ return new Promise(function(resolve, reject) {
31
+ var gen = fn.apply(self, args);
32
+ function _next(value) {
33
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
34
+ }
35
+ function _throw(err) {
36
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
37
+ }
38
+ _next(undefined);
39
+ });
40
+ };
41
+ }
10
42
  function _class_call_check(instance, Constructor) {
11
43
  if (!(instance instanceof Constructor)) {
12
44
  throw new TypeError("Cannot call a class as a function");
@@ -39,6 +71,9 @@ function _define_property(obj, key, value) {
39
71
  }
40
72
  return obj;
41
73
  }
74
+ function _iterable_to_array(iter) {
75
+ if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
76
+ }
42
77
  function _iterable_to_array_limit(arr, i) {
43
78
  var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
44
79
  if (_i == null) return;
@@ -66,6 +101,9 @@ function _iterable_to_array_limit(arr, i) {
66
101
  function _non_iterable_rest() {
67
102
  throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
68
103
  }
104
+ function _non_iterable_spread() {
105
+ throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
106
+ }
69
107
  function _object_spread(target) {
70
108
  for(var i = 1; i < arguments.length; i++){
71
109
  var source = arguments[i] != null ? arguments[i] : {};
@@ -105,9 +143,49 @@ function _object_spread_props(target, source) {
105
143
  }
106
144
  return target;
107
145
  }
146
+ function _object_without_properties(source, excluded) {
147
+ if (source == null) return {};
148
+ var target = _object_without_properties_loose(source, excluded);
149
+ var key, i;
150
+ if (Object.getOwnPropertySymbols) {
151
+ var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
152
+ for(i = 0; i < sourceSymbolKeys.length; i++){
153
+ key = sourceSymbolKeys[i];
154
+ if (excluded.indexOf(key) >= 0) continue;
155
+ if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
156
+ target[key] = source[key];
157
+ }
158
+ }
159
+ return target;
160
+ }
161
+ function _object_without_properties_loose(source, excluded) {
162
+ if (source == null) return {};
163
+ var target = {};
164
+ var sourceKeys = Object.keys(source);
165
+ var key, i;
166
+ for(i = 0; i < sourceKeys.length; i++){
167
+ key = sourceKeys[i];
168
+ if (excluded.indexOf(key) >= 0) continue;
169
+ target[key] = source[key];
170
+ }
171
+ return target;
172
+ }
108
173
  function _sliced_to_array(arr, i) {
109
174
  return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
110
175
  }
176
+ function _tagged_template_literal(strings, raw) {
177
+ if (!raw) {
178
+ raw = strings.slice(0);
179
+ }
180
+ return Object.freeze(Object.defineProperties(strings, {
181
+ raw: {
182
+ value: Object.freeze(raw)
183
+ }
184
+ }));
185
+ }
186
+ function _to_consumable_array(arr) {
187
+ return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread();
188
+ }
111
189
  function _unsupported_iterable_to_array(o, minLen) {
112
190
  if (!o) return;
113
191
  if (typeof o === "string") return _array_like_to_array(o, minLen);
@@ -116,6 +194,101 @@ function _unsupported_iterable_to_array(o, minLen) {
116
194
  if (n === "Map" || n === "Set") return Array.from(n);
117
195
  if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
118
196
  }
197
+ function _ts_generator(thisArg, body) {
198
+ var f, y, t, g, _ = {
199
+ label: 0,
200
+ sent: function() {
201
+ if (t[0] & 1) throw t[1];
202
+ return t[1];
203
+ },
204
+ trys: [],
205
+ ops: []
206
+ };
207
+ return g = {
208
+ next: verb(0),
209
+ "throw": verb(1),
210
+ "return": verb(2)
211
+ }, typeof Symbol === "function" && (g[Symbol.iterator] = function() {
212
+ return this;
213
+ }), g;
214
+ function verb(n) {
215
+ return function(v) {
216
+ return step([
217
+ n,
218
+ v
219
+ ]);
220
+ };
221
+ }
222
+ function step(op) {
223
+ if (f) throw new TypeError("Generator is already executing.");
224
+ while(_)try {
225
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
226
+ if (y = 0, t) op = [
227
+ op[0] & 2,
228
+ t.value
229
+ ];
230
+ switch(op[0]){
231
+ case 0:
232
+ case 1:
233
+ t = op;
234
+ break;
235
+ case 4:
236
+ _.label++;
237
+ return {
238
+ value: op[1],
239
+ done: false
240
+ };
241
+ case 5:
242
+ _.label++;
243
+ y = op[1];
244
+ op = [
245
+ 0
246
+ ];
247
+ continue;
248
+ case 7:
249
+ op = _.ops.pop();
250
+ _.trys.pop();
251
+ continue;
252
+ default:
253
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
254
+ _ = 0;
255
+ continue;
256
+ }
257
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
258
+ _.label = op[1];
259
+ break;
260
+ }
261
+ if (op[0] === 6 && _.label < t[1]) {
262
+ _.label = t[1];
263
+ t = op;
264
+ break;
265
+ }
266
+ if (t && _.label < t[2]) {
267
+ _.label = t[2];
268
+ _.ops.push(op);
269
+ break;
270
+ }
271
+ if (t[2]) _.ops.pop();
272
+ _.trys.pop();
273
+ continue;
274
+ }
275
+ op = body.call(thisArg, _);
276
+ } catch (e) {
277
+ op = [
278
+ 6,
279
+ e
280
+ ];
281
+ y = 0;
282
+ } finally{
283
+ f = t = 0;
284
+ }
285
+ if (op[0] & 5) throw op[1];
286
+ return {
287
+ value: op[0] ? op[1] : void 0,
288
+ done: true
289
+ };
290
+ }
291
+ }
119
292
  var _loop = function(letter) {
120
293
  lineAlphabet[letter] = [];
121
294
  var segs = svgAlphabet[letter].split("M").slice(1).map(function(seg) {
@@ -151,6 +324,15 @@ var _loop = function(letter) {
151
324
  }
152
325
  }
153
326
  };
327
+ function _templateObject() {
328
+ var data = _tagged_template_literal([
329
+ "\n margin-top: 2px;\n padding: 4px;\n padding-left: 8px;\n padding-right: 18px;\n cursor: pointer;\n\n &:hover {\n background-color: rgba(255, 255, 255, 0.1);\n }\n "
330
+ ]);
331
+ _templateObject = function _templateObject() {
332
+ return data;
333
+ };
334
+ return data;
335
+ }
154
336
  var __create = Object.create;
155
337
  var __defProp = Object.defineProperty;
156
338
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -276,20 +458,20 @@ var require_dist = __commonJS({
276
458
  }
277
459
  });
278
460
  module2.exports = __toCommonJS2(src_exports2);
279
- var import_transformation_matrix4 = require("transformation-matrix");
280
- var import_react10 = require("react");
461
+ var import_transformation_matrix5 = require("transformation-matrix");
462
+ var import_react15 = require("react");
281
463
  var useMouseMatrixTransform2 = function() {
282
464
  var props = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
283
- var extRef = (0, import_react10.useRef)(null);
465
+ var extRef = (0, import_react15.useRef)(null);
284
466
  var _props_canvasElm;
285
467
  var outerCanvasElm = (_props_canvasElm = props.canvasElm) !== null && _props_canvasElm !== void 0 ? _props_canvasElm : extRef.current;
286
468
  var _props_initialTransform;
287
- var _ref = _sliced_to_array((0, import_react10.useState)((_props_initialTransform = props.initialTransform) !== null && _props_initialTransform !== void 0 ? _props_initialTransform : (0, import_transformation_matrix4.identity)()), 2), internalTransform = _ref[0], setInternalTransform = _ref[1];
288
- var _ref1 = _sliced_to_array((0, import_react10.useState)(0), 2), waitCounter = _ref1[0], setWaitCounter = _ref1[1];
289
- var _ref2 = _sliced_to_array((0, import_react10.useReducer)(function(s) {
469
+ var _ref = _sliced_to_array((0, import_react15.useState)((_props_initialTransform = props.initialTransform) !== null && _props_initialTransform !== void 0 ? _props_initialTransform : (0, import_transformation_matrix5.identity)()), 2), internalTransform = _ref[0], setInternalTransform = _ref[1];
470
+ var _ref1 = _sliced_to_array((0, import_react15.useState)(0), 2), waitCounter = _ref1[0], setWaitCounter = _ref1[1];
471
+ var _ref2 = _sliced_to_array((0, import_react15.useReducer)(function(s) {
290
472
  return s + 1;
291
473
  }, 0), 2), extChangeCounter = _ref2[0], incExtChangeCounter = _ref2[1];
292
- var setTransform = (0, import_react10.useCallback)(function(newTransform) {
474
+ var setTransform = (0, import_react15.useCallback)(function(newTransform) {
293
475
  if (props.onSetTransform) {
294
476
  props.onSetTransform(newTransform);
295
477
  }
@@ -300,7 +482,7 @@ var require_dist = __commonJS({
300
482
  props.onSetTransform,
301
483
  setInternalTransform
302
484
  ]);
303
- var setTransformExt = (0, import_react10.useCallback)(function(newTransform) {
485
+ var setTransformExt = (0, import_react15.useCallback)(function(newTransform) {
304
486
  setTransform(newTransform);
305
487
  incExtChangeCounter();
306
488
  }, [
@@ -308,7 +490,7 @@ var require_dist = __commonJS({
308
490
  ]);
309
491
  var _props_transform;
310
492
  var transform = (_props_transform = props.transform) !== null && _props_transform !== void 0 ? _props_transform : internalTransform;
311
- (0, import_react10.useEffect)(function() {
493
+ (0, import_react15.useEffect)(function() {
312
494
  var handleMouseDown = function handleMouseDown(e) {
313
495
  m0 = getMousePos(e);
314
496
  md = true;
@@ -316,7 +498,7 @@ var require_dist = __commonJS({
316
498
  };
317
499
  var handleMouseUp = function handleMouseUp(e) {
318
500
  m1 = getMousePos(e);
319
- var new_tf = (0, import_transformation_matrix4.compose)((0, import_transformation_matrix4.translate)(m1.x - m0.x, m1.y - m0.y), init_tf);
501
+ var new_tf = (0, import_transformation_matrix5.compose)((0, import_transformation_matrix5.translate)(m1.x - m0.x, m1.y - m0.y), init_tf);
320
502
  setTransform(new_tf);
321
503
  init_tf = new_tf;
322
504
  md = false;
@@ -325,11 +507,11 @@ var require_dist = __commonJS({
325
507
  mlastrel = getMousePos(e);
326
508
  if (!md) return;
327
509
  m1 = getMousePos(e);
328
- setTransform((0, import_transformation_matrix4.compose)((0, import_transformation_matrix4.translate)(m1.x - m0.x, m1.y - m0.y), init_tf));
510
+ setTransform((0, import_transformation_matrix5.compose)((0, import_transformation_matrix5.translate)(m1.x - m0.x, m1.y - m0.y), init_tf));
329
511
  };
330
512
  var handleMouseWheel = function handleMouseWheel(e) {
331
513
  var center = getMousePos(e);
332
- var new_tf = (0, import_transformation_matrix4.compose)((0, import_transformation_matrix4.translate)(center.x, center.y), (0, import_transformation_matrix4.scale)(1 - e.deltaY / 1e3, 1 - e.deltaY / 1e3), (0, import_transformation_matrix4.translate)(-center.x, -center.y), init_tf);
514
+ var new_tf = (0, import_transformation_matrix5.compose)((0, import_transformation_matrix5.translate)(center.x, center.y), (0, import_transformation_matrix5.scale)(1 - e.deltaY / 1e3, 1 - e.deltaY / 1e3), (0, import_transformation_matrix5.translate)(-center.x, -center.y), init_tf);
333
515
  setTransform(new_tf);
334
516
  init_tf = new_tf;
335
517
  e.preventDefault();
@@ -338,7 +520,7 @@ var require_dist = __commonJS({
338
520
  if (!md) return;
339
521
  md = false;
340
522
  m1 = getMousePos(e);
341
- var new_tf = (0, import_transformation_matrix4.compose)((0, import_transformation_matrix4.translate)(m1.x - m0.x, m1.y - m0.y), init_tf);
523
+ var new_tf = (0, import_transformation_matrix5.compose)((0, import_transformation_matrix5.translate)(m1.x - m0.x, m1.y - m0.y), init_tf);
342
524
  setTransform(new_tf);
343
525
  init_tf = new_tf;
344
526
  };
@@ -391,8 +573,8 @@ var require_dist = __commonJS({
391
573
  waitCounter,
392
574
  extChangeCounter
393
575
  ]);
394
- var applyTransformToPoint = (0, import_react10.useCallback)(function(obj) {
395
- return (0, import_transformation_matrix4.applyToPoint)(transform, obj);
576
+ var applyTransformToPoint = (0, import_react15.useCallback)(function(obj) {
577
+ return (0, import_transformation_matrix5.applyToPoint)(transform, obj);
396
578
  }, [
397
579
  transform
398
580
  ]);
@@ -418,14 +600,14 @@ __export(src_exports, {
418
600
  });
419
601
  module.exports = __toCommonJS(src_exports);
420
602
  // src/PCBViewer.tsx
421
- var import_react9 = __toESM(require("react"));
603
+ var import_react14 = __toESM(require("react"));
422
604
  var import_react_fiber = require("@tscircuit/react-fiber");
423
- var import_builder = require("@tscircuit/builder");
605
+ var import_builder3 = require("@tscircuit/builder");
424
606
  // src/components/CanvasElementsRenderer.tsx
425
- var import_react5 = __toESM(require("react"));
607
+ var import_react10 = __toESM(require("react"));
426
608
  // src/components/CanvasPrimitiveRenderer.tsx
427
609
  var import_react_supergrid = require("react-supergrid");
428
- var import_react = __toESM(require("react"));
610
+ var import_react4 = __toESM(require("react"));
429
611
  // src/assets/alphabet.ts
430
612
  var svgAlphabet = {
431
613
  "0": "M0.4544564813877358 0L0.2723441540828736 0.03592830447352719L0.1086847233315459 0.14528754990019965L0.020630545837255005 0.3040632652221331L0 0.5395277421960205L0.049259221760993496 0.7369487828466779L0.18080513776237842 0.9005494166306564L0.37036887043974215 0.9872116270037247L0.5864663759301132 1L0.8148695622827444 0.9332890276148733L0.9326583645506394 0.8113052246023419L1 0.4031281830668562L0.833288960385582 0.09886798567812842L0.6801767918233781 0.02483708485091681L0.4544564813877358 0",
@@ -837,22 +1019,47 @@ var LAYER_NAME_TO_COLOR = _object_spread({
837
1019
  black: "black",
838
1020
  green: "green",
839
1021
  board: "white",
1022
+ other: "#eee",
840
1023
  // TODO more builtin html colors
841
1024
  // Common eagle names
842
1025
  top: colors_default.board.copper.f,
1026
+ inner1: colors_default.board.copper.in1,
1027
+ inner2: colors_default.board.copper.in2,
1028
+ inner3: colors_default.board.copper.in3,
1029
+ inner4: colors_default.board.copper.in4,
1030
+ inner5: colors_default.board.copper.in5,
1031
+ inner6: colors_default.board.copper.in6,
1032
+ inner7: colors_default.board.copper.in7,
1033
+ inner8: colors_default.board.copper.in8,
843
1034
  bottom: colors_default.board.copper.b,
844
1035
  drill: colors_default.board.anchor,
845
1036
  keepout: colors_default.board.background,
846
1037
  tkeepout: colors_default.board.b_crtyd,
847
1038
  tplace: colors_default.board.b_silks
848
1039
  }, colors_default.board);
1040
+ var DEFAULT_DRAW_ORDER = [
1041
+ "top",
1042
+ "inner1",
1043
+ "inner2",
1044
+ "inner3",
1045
+ "inner4",
1046
+ "inner5",
1047
+ "inner6",
1048
+ "bottom"
1049
+ ];
849
1050
  var Drawer = /*#__PURE__*/ function() {
850
1051
  "use strict";
851
- function Drawer(canvas) {
1052
+ function Drawer(canvasLayerMap) {
852
1053
  _class_call_check(this, Drawer);
853
- this.canvas = canvas;
854
- this.canvas = canvas;
855
- this.ctx = canvas.getContext("2d");
1054
+ this.foregroundLayer = "top";
1055
+ this.canvasLayerMap = canvasLayerMap;
1056
+ this.ctxLayerMap = Object.fromEntries(Object.entries(canvasLayerMap).map(function(param) {
1057
+ var _param = _sliced_to_array(param, 2), name = _param[0], canvas = _param[1];
1058
+ return [
1059
+ name,
1060
+ canvas.getContext("2d")
1061
+ ];
1062
+ }));
856
1063
  this.transform = (0, import_transformation_matrix.identity)();
857
1064
  this.transform.d *= -1;
858
1065
  this.transform = (0, import_transformation_matrix.compose)(this.transform, (0, import_transformation_matrix.translate)(0, -500));
@@ -866,20 +1073,40 @@ var Drawer = /*#__PURE__*/ function() {
866
1073
  {
867
1074
  key: "clear",
868
1075
  value: function clear() {
869
- var _this = this, ctx = _this.ctx, canvas = _this.canvas;
870
- ctx.clearRect(0, 0, canvas.width, canvas.height);
1076
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
1077
+ try {
1078
+ for(var _iterator = Object.values(this.ctxLayerMap)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
1079
+ var ctx = _step.value;
1080
+ ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
1081
+ }
1082
+ } catch (err) {
1083
+ _didIteratorError = true;
1084
+ _iteratorError = err;
1085
+ } finally{
1086
+ try {
1087
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
1088
+ _iterator.return();
1089
+ }
1090
+ } finally{
1091
+ if (_didIteratorError) {
1092
+ throw _iteratorError;
1093
+ }
1094
+ }
1095
+ }
871
1096
  }
872
1097
  },
873
1098
  {
874
1099
  key: "equip",
875
- value: function equip(aperature) {
1100
+ value: function equip(aperture) {
876
1101
  this.aperture = _object_spread({
877
1102
  fontSize: 0,
878
1103
  shape: "circle",
879
1104
  mode: "add",
880
1105
  size: 0,
881
- color: "red"
882
- }, aperature);
1106
+ color: "red",
1107
+ layer: "top",
1108
+ opacity: this.foregroundLayer === aperture.color ? 1 : 0.5
1109
+ }, aperture);
883
1110
  }
884
1111
  },
885
1112
  {
@@ -894,7 +1121,8 @@ var Drawer = /*#__PURE__*/ function() {
894
1121
  y + h / 2
895
1122
  ]), 2), x2$ = _ref1[0], y2$ = _ref1[1];
896
1123
  this.applyAperture();
897
- this.ctx.fillRect(x1$, y1$, x2$ - x1$, y2$ - y1$);
1124
+ var ctx = this.getLayerCtx();
1125
+ ctx.fillRect(x1$, y1$, x2$ - x1$, y2$ - y1$);
898
1126
  }
899
1127
  },
900
1128
  {
@@ -906,10 +1134,11 @@ var Drawer = /*#__PURE__*/ function() {
906
1134
  y
907
1135
  ]), 2), x$ = _ref[0], y$ = _ref[1];
908
1136
  this.applyAperture();
909
- this.ctx.beginPath();
910
- this.ctx.arc(x$, y$, r$, 0, 2 * Math.PI);
911
- this.ctx.fill();
912
- this.ctx.closePath();
1137
+ var ctx = this.getLayerCtx();
1138
+ ctx.beginPath();
1139
+ ctx.arc(x$, y$, r$, 0, 2 * Math.PI);
1140
+ ctx.fill();
1141
+ ctx.closePath();
913
1142
  }
914
1143
  },
915
1144
  {
@@ -920,15 +1149,65 @@ var Drawer = /*#__PURE__*/ function() {
920
1149
  y
921
1150
  ]), 2), x$ = _ref[0], y$ = _ref[1];
922
1151
  this.applyAperture();
923
- this.ctx.font = "10px sans-serif";
924
- this.ctx.fillText(text, x$, y$);
1152
+ var ctx = this.getLayerCtx();
1153
+ ctx.font = "10px sans-serif";
1154
+ ctx.fillText(text, x$, y$);
1155
+ }
1156
+ },
1157
+ {
1158
+ key: "getLayerCtx",
1159
+ value: function getLayerCtx() {
1160
+ var ctx = this.ctxLayerMap[this.aperture.layer];
1161
+ if (!ctx) {
1162
+ throw new Error('No context for layer "'.concat(this.aperture.layer, '"'));
1163
+ }
1164
+ return ctx;
1165
+ }
1166
+ },
1167
+ {
1168
+ /**
1169
+ * Iterate over each canvas and set the z index based on the layer order, but
1170
+ * always render the foreground layer on top.
1171
+ *
1172
+ * Also: Set the opacity of every non-foreground layer to 0.5
1173
+ */ key: "orderAndFadeLayers",
1174
+ value: function orderAndFadeLayers() {
1175
+ var _this = this, canvasLayerMap = _this.canvasLayerMap, foregroundLayer = _this.foregroundLayer;
1176
+ var opaqueLayers = /* @__PURE__ */ new Set([
1177
+ foregroundLayer,
1178
+ "drill",
1179
+ "other",
1180
+ "board"
1181
+ ]);
1182
+ var order = [
1183
+ "drill",
1184
+ "board",
1185
+ foregroundLayer
1186
+ ].concat(_to_consumable_array(DEFAULT_DRAW_ORDER.filter(function(l) {
1187
+ return l !== foregroundLayer;
1188
+ })));
1189
+ order.forEach(function(layer, i) {
1190
+ var canvas = canvasLayerMap[layer];
1191
+ if (!canvas) return;
1192
+ canvas.style.zIndex = "".concat(100 - i);
1193
+ canvas.style.opacity = opaqueLayers.has(layer) ? "1" : "0.5";
1194
+ });
925
1195
  }
926
1196
  },
927
1197
  {
928
1198
  key: "applyAperture",
929
1199
  value: function applyAperture() {
930
- var _this = this, ctx = _this.ctx, transform = _this.transform, aperture = _this.aperture;
1200
+ var _this = this, transform = _this.transform, aperture = _this.aperture;
931
1201
  var size = aperture.size, mode = aperture.mode, color = aperture.color, fontSize = aperture.fontSize;
1202
+ if (color in this.ctxLayerMap) {
1203
+ this.aperture.layer = color;
1204
+ } else {
1205
+ this.aperture.layer = "other";
1206
+ }
1207
+ var ctx = this.getLayerCtx();
1208
+ if (!ctx) {
1209
+ throw new Error('No context for layer "'.concat(this.foregroundLayer, '"'));
1210
+ }
932
1211
  if (!color) color = "undefined";
933
1212
  ctx.lineWidth = scaleOnly(transform, size);
934
1213
  ctx.lineCap = "round";
@@ -966,9 +1245,10 @@ var Drawer = /*#__PURE__*/ function() {
966
1245
  ]), 2), x$ = _ref[0], y$ = _ref[1];
967
1246
  var _this_aperture = this.aperture, size = _this_aperture.size, shape = _this_aperture.shape, mode = _this_aperture.mode;
968
1247
  var size$ = scaleOnly(this.transform, size);
969
- var _this = this, lastPoint = _this.lastPoint, ctx = _this.ctx;
1248
+ var lastPoint = this.lastPoint;
970
1249
  var lastPoint$ = (0, import_transformation_matrix.applyToPoint)(this.transform, lastPoint);
971
1250
  this.applyAperture();
1251
+ var ctx = this.getLayerCtx();
972
1252
  if (shape === "square") ctx.fillRect(lastPoint$.x - size$ / 2, lastPoint$.y - size$ / 2, size$, size$);
973
1253
  ctx.beginPath();
974
1254
  ctx.moveTo(lastPoint$.x, lastPoint$.y);
@@ -985,28 +1265,69 @@ var Drawer = /*#__PURE__*/ function() {
985
1265
  ]);
986
1266
  return Drawer;
987
1267
  }();
1268
+ // src/global-store.ts
1269
+ var import_zustand = require("zustand");
1270
+ // src/components/ContextProviders.tsx
1271
+ var import_react = require("react");
1272
+ var import_react2 = require("react");
1273
+ var StoreContext = (0, import_react2.createContext)(null);
1274
+ var ContextProviders = function(param) {
1275
+ var children = param.children;
1276
+ var store = (0, import_react.useMemo)(function() {
1277
+ return createStore();
1278
+ }, []);
1279
+ return /* @__PURE__ */ React.createElement(StoreContext.Provider, {
1280
+ value: store
1281
+ }, children);
1282
+ };
1283
+ // src/global-store.ts
1284
+ var import_react3 = require("react");
1285
+ var createStore = function() {
1286
+ return (0, import_zustand.createStore)(function(set) {
1287
+ return {
1288
+ selected_layer: "top",
1289
+ selectLayer: function(layer) {
1290
+ return set({
1291
+ selected_layer: layer
1292
+ });
1293
+ }
1294
+ };
1295
+ });
1296
+ };
1297
+ var useStore = function(s) {
1298
+ var store = (0, import_react3.useContext)(StoreContext);
1299
+ return (0, import_zustand.useStore)(store, s);
1300
+ };
988
1301
  // src/components/CanvasPrimitiveRenderer.tsx
1302
+ var import_builder = require("@tscircuit/builder");
989
1303
  var CanvasPrimitiveRenderer = function(param) {
990
1304
  var primitives = param.primitives, transform = param.transform, grid = param.grid, _param_width = param.width, width = _param_width === void 0 ? 500 : _param_width, _param_height = param.height, height = _param_height === void 0 ? 500 : _param_height;
991
- var ref = (0, import_react.useRef)();
992
- (0, import_react.useEffect)(function() {
993
- if (!ref.current) return;
994
- var drawer = new Drawer(ref.current);
1305
+ var canvasRefs = (0, import_react4.useRef)();
1306
+ var selectedLayer = useStore(function(s) {
1307
+ return s.selected_layer;
1308
+ });
1309
+ (0, import_react4.useEffect)(function() {
1310
+ if (!canvasRefs.current) return;
1311
+ if (Object.keys(canvasRefs.current).length === 0) return;
1312
+ var drawer = new Drawer(canvasRefs.current);
995
1313
  if (transform) drawer.transform = transform;
996
1314
  drawer.clear();
1315
+ drawer.foregroundLayer = selectedLayer;
997
1316
  drawPrimitives(drawer, primitives);
1317
+ drawer.orderAndFadeLayers();
998
1318
  }, [
999
1319
  primitives,
1000
- transform
1320
+ transform,
1321
+ selectedLayer
1001
1322
  ]);
1002
- return /* @__PURE__ */ import_react.default.createElement("div", {
1323
+ return /* @__PURE__ */ import_react4.default.createElement("div", {
1003
1324
  style: {
1004
1325
  backgroundColor: "black",
1005
1326
  width: width,
1006
1327
  height: height,
1007
1328
  position: "relative"
1008
1329
  }
1009
- }, /* @__PURE__ */ import_react.default.createElement(import_react_supergrid.SuperGrid, {
1330
+ }, /* @__PURE__ */ import_react4.default.createElement(import_react_supergrid.SuperGrid, {
1010
1331
  textColor: "rgba(0,255,0,0.8)",
1011
1332
  majorColor: "rgba(0,255,0,0.4)",
1012
1333
  minorColor: "rgba(0,255,0,0.2)",
@@ -1017,20 +1338,32 @@ var CanvasPrimitiveRenderer = function(param) {
1017
1338
  stringifyCoord: function(x, y, z) {
1018
1339
  return "".concat((0, import_react_supergrid.toMMSI)(x, z), ", ").concat((0, import_react_supergrid.toMMSI)(y, z));
1019
1340
  }
1020
- }), /* @__PURE__ */ import_react.default.createElement("canvas", {
1021
- ref: ref,
1022
- style: {
1023
- position: "absolute",
1024
- left: 0,
1025
- top: 0,
1026
- pointerEvents: "none"
1027
- },
1028
- width: width,
1029
- height: height
1341
+ }), import_builder.all_layers.map(function(l) {
1342
+ return l.replace(/-/g, "");
1343
+ }).concat([
1344
+ "drill",
1345
+ "other"
1346
+ ]).map(function(layer, i) {
1347
+ return /* @__PURE__ */ import_react4.default.createElement("canvas", {
1348
+ key: layer,
1349
+ ref: function(el) {
1350
+ var _canvasRefs_current;
1351
+ (_canvasRefs_current = canvasRefs.current) !== null && _canvasRefs_current !== void 0 ? _canvasRefs_current : canvasRefs.current = {};
1352
+ canvasRefs.current[layer] = el;
1353
+ },
1354
+ style: {
1355
+ position: "absolute",
1356
+ left: 0,
1357
+ top: 0,
1358
+ pointerEvents: "none"
1359
+ },
1360
+ width: width,
1361
+ height: height
1362
+ });
1030
1363
  }));
1031
1364
  };
1032
1365
  // src/components/CanvasElementsRenderer.tsx
1033
- var import_react6 = require("react");
1366
+ var import_react11 = require("react");
1034
1367
  // src/lib/convert-element-to-primitive.ts
1035
1368
  var convertElementToPrimitives = function(element, allElements) {
1036
1369
  var _parent_pcb_component = "pcb_component_id" in element ? allElements.find(function(elm) {
@@ -1256,11 +1589,11 @@ var convertElementToPrimitives = function(element, allElements) {
1256
1589
  return [];
1257
1590
  };
1258
1591
  // src/components/MouseElementTracker.tsx
1259
- var import_react3 = __toESM(require("react"));
1260
- var import_react4 = require("react");
1592
+ var import_react6 = __toESM(require("react"));
1593
+ var import_react7 = require("react");
1261
1594
  var import_transformation_matrix2 = require("transformation-matrix");
1262
1595
  // src/components/ElementOverlayBox.tsx
1263
- var import_react2 = __toESM(require("react"));
1596
+ var import_react5 = __toESM(require("react"));
1264
1597
  var containerStyle = {
1265
1598
  position: "absolute",
1266
1599
  left: 0,
@@ -1301,8 +1634,8 @@ var layerColorHightlightMap = {
1301
1634
  var HighlightedPrimitiveBoxWithText = function(param) {
1302
1635
  var primitive = param.primitive;
1303
1636
  var _primitive__element;
1304
- var _ref = _sliced_to_array((0, import_react2.useState)(false), 2), finalState = _ref[0], setFinalState = _ref[1];
1305
- (0, import_react2.useEffect)(function() {
1637
+ var _ref = _sliced_to_array((0, import_react5.useState)(false), 2), finalState = _ref[0], setFinalState = _ref[1];
1638
+ (0, import_react5.useEffect)(function() {
1306
1639
  setTimeout(function() {
1307
1640
  setFinalState(true);
1308
1641
  }, 100);
@@ -1318,7 +1651,7 @@ var HighlightedPrimitiveBoxWithText = function(param) {
1318
1651
  var sip = 26;
1319
1652
  var _layerColorHightlightMap_primitive__element_layer;
1320
1653
  var color = (_layerColorHightlightMap_primitive__element_layer = layerColorHightlightMap[primitive === null || primitive === void 0 ? void 0 : (_primitive__element = primitive._element) === null || _primitive__element === void 0 ? void 0 : _primitive__element.layer]) !== null && _layerColorHightlightMap_primitive__element_layer !== void 0 ? _layerColorHightlightMap_primitive__element_layer : "red";
1321
- return /* @__PURE__ */ import_react2.default.createElement("div", {
1654
+ return /* @__PURE__ */ import_react5.default.createElement("div", {
1322
1655
  style: {
1323
1656
  position: "absolute",
1324
1657
  left: x - w / 2 - 8,
@@ -1327,7 +1660,7 @@ var HighlightedPrimitiveBoxWithText = function(param) {
1327
1660
  height: h + 16,
1328
1661
  color: color
1329
1662
  }
1330
- }, /* @__PURE__ */ import_react2.default.createElement("div", {
1663
+ }, /* @__PURE__ */ import_react5.default.createElement("div", {
1331
1664
  style: {
1332
1665
  // width: finalState ? `${100 + 20 * si}%` : "100%",
1333
1666
  // height: finalState ? `${100 + 20 * si}%` : "100%",
@@ -1341,7 +1674,7 @@ var HighlightedPrimitiveBoxWithText = function(param) {
1341
1674
  opacity: finalState ? 1 : si === 0 ? 1 : 0,
1342
1675
  transition: "width 0.2s, height 0.2s, margin-left 0.2s, margin-top 0.2s, opacity 0.2s"
1343
1676
  }
1344
- }, /* @__PURE__ */ import_react2.default.createElement("div", {
1677
+ }, /* @__PURE__ */ import_react5.default.createElement("div", {
1345
1678
  style: {
1346
1679
  position: "absolute",
1347
1680
  left: 0,
@@ -1355,10 +1688,10 @@ var HighlightedPrimitiveBoxWithText = function(param) {
1355
1688
  };
1356
1689
  var ElementOverlayBox = function(param) {
1357
1690
  var highlightedPrimitives = param.highlightedPrimitives;
1358
- return /* @__PURE__ */ import_react2.default.createElement("div", {
1691
+ return /* @__PURE__ */ import_react5.default.createElement("div", {
1359
1692
  style: containerStyle
1360
1693
  }, highlightedPrimitives.map(function(primitive, i) {
1361
- return /* @__PURE__ */ import_react2.default.createElement(HighlightedPrimitiveBoxWithText, {
1694
+ return /* @__PURE__ */ import_react5.default.createElement(HighlightedPrimitiveBoxWithText, {
1362
1695
  key: i,
1363
1696
  primitive: primitive
1364
1697
  });
@@ -1367,8 +1700,8 @@ var ElementOverlayBox = function(param) {
1367
1700
  // src/components/MouseElementTracker.tsx
1368
1701
  var MouseElementTracker = function(param) {
1369
1702
  var children = param.children, transform = param.transform, primitives = param.primitives;
1370
- var _ref = _sliced_to_array((0, import_react3.useState)([]), 2), mousedPrimitives = _ref[0], setMousedPrimitives = _ref[1];
1371
- var highlightedPrimitives = (0, import_react4.useMemo)(function() {
1703
+ var _ref = _sliced_to_array((0, import_react6.useState)([]), 2), mousedPrimitives = _ref[0], setMousedPrimitives = _ref[1];
1704
+ var highlightedPrimitives = (0, import_react7.useMemo)(function() {
1372
1705
  var highlightedPrimitives2 = [];
1373
1706
  var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
1374
1707
  try {
@@ -1381,8 +1714,8 @@ var MouseElementTracker = function(param) {
1381
1714
  var w = "w" in primitive ? primitive.w : "r" in primitive ? primitive.r * 2 : 0;
1382
1715
  var h = "h" in primitive ? primitive.h : "r" in primitive ? primitive.r * 2 : 0;
1383
1716
  var screenSize = {
1384
- w: w * transform.d,
1385
- h: h * transform.d
1717
+ w: w * transform.a,
1718
+ h: h * transform.a
1386
1719
  };
1387
1720
  var same_space_index = highlightedPrimitives2.filter(function(hp) {
1388
1721
  return screenPos.x === hp.screen_x && screenPos.y === hp.screen_y && screenSize.w === hp.screen_w && screenSize.h === hp.screen_h;
@@ -1415,7 +1748,7 @@ var MouseElementTracker = function(param) {
1415
1748
  mousedPrimitives,
1416
1749
  transform
1417
1750
  ]);
1418
- return /* @__PURE__ */ import_react3.default.createElement("div", {
1751
+ return /* @__PURE__ */ import_react6.default.createElement("div", {
1419
1752
  style: {
1420
1753
  position: "relative"
1421
1754
  },
@@ -1458,13 +1791,317 @@ var MouseElementTracker = function(param) {
1458
1791
  setMousedPrimitives(mousedPrimitives2);
1459
1792
  }
1460
1793
  }
1461
- }, children, /* @__PURE__ */ import_react3.default.createElement(ElementOverlayBox, {
1794
+ }, children, /* @__PURE__ */ import_react6.default.createElement(ElementOverlayBox, {
1462
1795
  highlightedPrimitives: highlightedPrimitives
1463
1796
  }));
1464
1797
  };
1798
+ // src/components/DimensionOverlay.tsx
1799
+ var import_react8 = require("react");
1800
+ var import_transformation_matrix3 = require("transformation-matrix");
1801
+ var DimensionOverlay = function(param) {
1802
+ var children = param.children, transform = param.transform;
1803
+ if (!transform) transform = (0, import_transformation_matrix3.identity)();
1804
+ var _ref = _sliced_to_array((0, import_react8.useState)(false), 2), dimensionToolVisible = _ref[0], setDimensionToolVisible = _ref[1];
1805
+ var _ref1 = _sliced_to_array((0, import_react8.useState)(false), 2), dimensionToolStretching = _ref1[0], setDimensionToolStretching = _ref1[1];
1806
+ var _ref2 = _sliced_to_array((0, import_react8.useState)({
1807
+ x: 0,
1808
+ y: 0
1809
+ }), 2), dStart = _ref2[0], setDStart = _ref2[1];
1810
+ var _ref3 = _sliced_to_array((0, import_react8.useState)({
1811
+ x: 0,
1812
+ y: 0
1813
+ }), 2), dEnd = _ref3[0], setDEnd = _ref3[1];
1814
+ var mousePosRef = (0, import_react8.useRef)({
1815
+ x: 0,
1816
+ y: 0
1817
+ });
1818
+ var containerRef = (0, import_react8.useRef)(null);
1819
+ var container = containerRef.current;
1820
+ var containerBounds = container === null || container === void 0 ? void 0 : container.getBoundingClientRect();
1821
+ (0, import_react8.useEffect)(function() {
1822
+ var down = function(e) {
1823
+ if (e.key === "d") {
1824
+ setDStart({
1825
+ x: mousePosRef.current.x,
1826
+ y: mousePosRef.current.y
1827
+ });
1828
+ setDEnd({
1829
+ x: mousePosRef.current.x,
1830
+ y: mousePosRef.current.y
1831
+ });
1832
+ setDimensionToolVisible(function(visible) {
1833
+ return !visible;
1834
+ });
1835
+ setDimensionToolStretching(true);
1836
+ e.preventDefault();
1837
+ }
1838
+ if (e.key === "Escape") {
1839
+ setDimensionToolVisible(false);
1840
+ setDimensionToolStretching(false);
1841
+ }
1842
+ };
1843
+ window.addEventListener("keydown", down);
1844
+ return function() {
1845
+ return window.removeEventListener("keydown", down);
1846
+ };
1847
+ }, [
1848
+ containerRef
1849
+ ]);
1850
+ var screenDStart = (0, import_transformation_matrix3.applyToPoint)(transform, dStart);
1851
+ var screenDEnd = (0, import_transformation_matrix3.applyToPoint)(transform, dEnd);
1852
+ var arrowScreenBounds = {
1853
+ left: Math.min(screenDStart.x, screenDEnd.x),
1854
+ right: Math.max(screenDStart.x, screenDEnd.x),
1855
+ top: Math.min(screenDStart.y, screenDEnd.y),
1856
+ bottom: Math.max(screenDStart.y, screenDEnd.y),
1857
+ flipX: screenDStart.x > screenDEnd.x,
1858
+ flipY: screenDStart.y > screenDEnd.y,
1859
+ width: 0,
1860
+ height: 0
1861
+ };
1862
+ arrowScreenBounds.width = arrowScreenBounds.right - arrowScreenBounds.left;
1863
+ arrowScreenBounds.height = arrowScreenBounds.bottom - arrowScreenBounds.top;
1864
+ return /* @__PURE__ */ React.createElement("div", {
1865
+ ref: containerRef,
1866
+ style: {
1867
+ position: "relative"
1868
+ },
1869
+ onMouseMove: function(e) {
1870
+ var rect = e.currentTarget.getBoundingClientRect();
1871
+ var x = e.clientX - rect.left;
1872
+ var y = e.clientY - rect.top;
1873
+ var rwPoint = (0, import_transformation_matrix3.applyToPoint)((0, import_transformation_matrix3.inverse)(transform), {
1874
+ x: x,
1875
+ y: y
1876
+ });
1877
+ mousePosRef.current.x = rwPoint.x;
1878
+ mousePosRef.current.y = rwPoint.y;
1879
+ if (dimensionToolStretching) {
1880
+ setDEnd({
1881
+ x: rwPoint.x,
1882
+ y: rwPoint.y
1883
+ });
1884
+ }
1885
+ },
1886
+ onMouseDown: function() {
1887
+ if (dimensionToolStretching) {
1888
+ setDimensionToolStretching(false);
1889
+ } else if (dimensionToolVisible) {
1890
+ setDimensionToolVisible(false);
1891
+ }
1892
+ }
1893
+ }, children, dimensionToolVisible && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", {
1894
+ style: {
1895
+ position: "absolute",
1896
+ left: arrowScreenBounds.left,
1897
+ width: arrowScreenBounds.width,
1898
+ textAlign: "center",
1899
+ top: screenDStart.y + 2,
1900
+ color: "red",
1901
+ mixBlendMode: "difference",
1902
+ pointerEvents: "none",
1903
+ marginTop: arrowScreenBounds.flipY ? 0 : -20,
1904
+ fontSize: 12,
1905
+ fontFamily: "sans-serif",
1906
+ zIndex: 1e3
1907
+ }
1908
+ }, Math.abs(dStart.x - dEnd.x).toFixed(2)), /* @__PURE__ */ React.createElement("div", {
1909
+ style: {
1910
+ position: "absolute",
1911
+ left: screenDEnd.x,
1912
+ height: arrowScreenBounds.height,
1913
+ display: "flex",
1914
+ flexDirection: "column",
1915
+ justifyContent: "center",
1916
+ top: arrowScreenBounds.top,
1917
+ color: "red",
1918
+ pointerEvents: "none",
1919
+ mixBlendMode: "difference",
1920
+ fontSize: 12,
1921
+ fontFamily: "sans-serif",
1922
+ zIndex: 1e3
1923
+ }
1924
+ }, /* @__PURE__ */ React.createElement("div", {
1925
+ style: {
1926
+ marginLeft: arrowScreenBounds.flipX ? "-100%" : 4,
1927
+ paddingRight: 4
1928
+ }
1929
+ }, Math.abs(dStart.y - dEnd.y).toFixed(2))), /* @__PURE__ */ React.createElement("svg", {
1930
+ style: {
1931
+ position: "absolute",
1932
+ left: 0,
1933
+ top: 0,
1934
+ pointerEvents: "none",
1935
+ mixBlendMode: "difference",
1936
+ zIndex: 1e3
1937
+ },
1938
+ width: containerBounds.width,
1939
+ height: containerBounds.height
1940
+ }, /* @__PURE__ */ React.createElement("defs", null, /* @__PURE__ */ React.createElement("marker", {
1941
+ id: "head",
1942
+ orient: "auto",
1943
+ markerWidth: "3",
1944
+ markerHeight: "4",
1945
+ refX: "2",
1946
+ refY: "2"
1947
+ }, /* @__PURE__ */ React.createElement("path", {
1948
+ d: "M0,0 V4 L2,2 Z",
1949
+ fill: "red"
1950
+ }))), /* @__PURE__ */ React.createElement("line", {
1951
+ x1: screenDStart.x,
1952
+ y1: screenDStart.y,
1953
+ x2: screenDEnd.x,
1954
+ y2: screenDEnd.y,
1955
+ markerEnd: "url(#head)",
1956
+ strokeWidth: 1.5,
1957
+ fill: "none",
1958
+ stroke: "red"
1959
+ }), /* @__PURE__ */ React.createElement("line", {
1960
+ x1: screenDStart.x,
1961
+ y1: screenDStart.y,
1962
+ x2: screenDEnd.x,
1963
+ y2: screenDStart.y,
1964
+ strokeWidth: 1.5,
1965
+ fill: "none",
1966
+ strokeDasharray: "2,2",
1967
+ stroke: "red"
1968
+ }), /* @__PURE__ */ React.createElement("line", {
1969
+ x1: screenDEnd.x,
1970
+ y1: screenDStart.y,
1971
+ x2: screenDEnd.x,
1972
+ y2: screenDEnd.y,
1973
+ strokeWidth: 1.5,
1974
+ fill: "none",
1975
+ strokeDasharray: "2,2",
1976
+ stroke: "red"
1977
+ })), /* @__PURE__ */ React.createElement("div", {
1978
+ style: {
1979
+ right: 0,
1980
+ bottom: 0,
1981
+ position: "absolute",
1982
+ color: "red",
1983
+ fontFamily: "sans-serif",
1984
+ fontSize: 12,
1985
+ margin: 4
1986
+ }
1987
+ }, "(", dStart.x.toFixed(2), ",", dStart.y.toFixed(2), ")", /* @__PURE__ */ React.createElement("br", null), "(", dEnd.x.toFixed(2), ",", dEnd.y.toFixed(2), ")", /* @__PURE__ */ React.createElement("br", null), "dist:", " ", Math.sqrt(Math.pow(dEnd.x - dStart.x, 2) + Math.pow(dEnd.y - dStart.y, 2)).toFixed(2))));
1988
+ };
1989
+ // src/components/ToolbarOverlay.tsx
1990
+ var import_react9 = require("react");
1991
+ var import_css = require("@emotion/css");
1992
+ var import_builder2 = require("@tscircuit/builder");
1993
+ var LayerButton = function(param) {
1994
+ var name = param.name, selected = param.selected, onClick = param.onClick;
1995
+ return /* @__PURE__ */ React.createElement("div", {
1996
+ className: import_css.css(_templateObject()),
1997
+ onClick: onClick
1998
+ }, /* @__PURE__ */ React.createElement("span", {
1999
+ style: {
2000
+ marginRight: 2,
2001
+ opacity: selected ? 1 : 0
2002
+ }
2003
+ }, "•"), /* @__PURE__ */ React.createElement("span", {
2004
+ style: {
2005
+ marginLeft: 2,
2006
+ fontWeight: 500,
2007
+ color: LAYER_NAME_TO_COLOR[name.replace(/-/, "")]
2008
+ }
2009
+ }, name));
2010
+ };
2011
+ var ToolbarButton = function(_param) {
2012
+ var children = _param.children, props = _object_without_properties(_param, [
2013
+ "children"
2014
+ ]);
2015
+ return /* @__PURE__ */ React.createElement("div", _object_spread_props(_object_spread({}, props), {
2016
+ style: {
2017
+ backgroundColor: "#1F1F1F",
2018
+ border: "1px solid #666",
2019
+ margin: 4,
2020
+ padding: 4,
2021
+ paddingLeft: 6,
2022
+ paddingRight: 6,
2023
+ borderRadius: 2,
2024
+ alignSelf: "start",
2025
+ color: "#eee",
2026
+ cursor: "pointer"
2027
+ }
2028
+ }), children);
2029
+ };
2030
+ var ToolbarOverlay = function(param) {
2031
+ var children = param.children, elements = param.elements;
2032
+ var _ref = _sliced_to_array((0, import_react9.useState)(false), 2), isMouseOverContainer = _ref[0], setIsMouseOverContainer = _ref[1];
2033
+ var _ref1 = _sliced_to_array((0, import_react9.useState)(false), 2), isLayerMenuOpen = _ref1[0], setLayerMenuOpen = _ref1[1];
2034
+ var _useStore = _sliced_to_array(useStore(function(s) {
2035
+ return [
2036
+ s.selected_layer,
2037
+ s.selectLayer
2038
+ ];
2039
+ }), 2), selectedLayer = _useStore[0], selectLayer = _useStore[1];
2040
+ var _elements_filter_length;
2041
+ var errorCount = (_elements_filter_length = elements === null || elements === void 0 ? void 0 : elements.filter(function(e) {
2042
+ return e.type.includes("error");
2043
+ }).length) !== null && _elements_filter_length !== void 0 ? _elements_filter_length : 0;
2044
+ return /* @__PURE__ */ React.createElement("div", {
2045
+ style: {
2046
+ position: "relative"
2047
+ },
2048
+ onMouseEnter: function() {
2049
+ setIsMouseOverContainer(true);
2050
+ },
2051
+ onMouseLeave: function() {
2052
+ setIsMouseOverContainer(false);
2053
+ setLayerMenuOpen(false);
2054
+ }
2055
+ }, children, /* @__PURE__ */ React.createElement("div", {
2056
+ style: {
2057
+ position: "absolute",
2058
+ opacity: isMouseOverContainer ? 1 : 0,
2059
+ top: 16,
2060
+ left: 16,
2061
+ transition: isMouseOverContainer ? "opacity 100ms linear" : "opacity 1s linear",
2062
+ zIndex: 100,
2063
+ color: "red",
2064
+ display: "flex",
2065
+ fontSize: 12,
2066
+ height: 100,
2067
+ fontFamily: "sans-serif"
2068
+ }
2069
+ }, /* @__PURE__ */ React.createElement(ToolbarButton, {
2070
+ onClick: function() {
2071
+ setLayerMenuOpen(!isLayerMenuOpen);
2072
+ },
2073
+ onMouseLeave: function() {
2074
+ if (isLayerMenuOpen) {
2075
+ setLayerMenuOpen(false);
2076
+ }
2077
+ }
2078
+ }, /* @__PURE__ */ React.createElement("div", null, "layer:", " ", /* @__PURE__ */ React.createElement("span", {
2079
+ style: {
2080
+ marginLeft: 2,
2081
+ fontWeight: 500,
2082
+ color: LAYER_NAME_TO_COLOR[selectedLayer]
2083
+ }
2084
+ }, selectedLayer)), isLayerMenuOpen && /* @__PURE__ */ React.createElement("div", {
2085
+ style: {
2086
+ marginTop: 4,
2087
+ minWidth: 120
2088
+ }
2089
+ }, import_builder2.all_layers.map(function(l) {
2090
+ return l.replace(/-/g, "");
2091
+ }).map(function(layer) {
2092
+ return /* @__PURE__ */ React.createElement(LayerButton, {
2093
+ key: layer,
2094
+ name: layer,
2095
+ selected: layer === selectedLayer,
2096
+ onClick: function() {
2097
+ selectLayer(layer.replace(/-/, ""));
2098
+ }
2099
+ });
2100
+ }))), /* @__PURE__ */ React.createElement(ToolbarButton, null, errorCount, " errors")));
2101
+ };
1465
2102
  // src/components/CanvasElementsRenderer.tsx
1466
2103
  var CanvasElementsRenderer = function(props) {
1467
- var primitives = (0, import_react6.useMemo)(function() {
2104
+ var primitives = (0, import_react11.useMemo)(function() {
1468
2105
  var primitives2 = props.elements.flatMap(function(elm) {
1469
2106
  return convertElementToPrimitives(elm, props.elements);
1470
2107
  });
@@ -1472,16 +2109,20 @@ var CanvasElementsRenderer = function(props) {
1472
2109
  }, [
1473
2110
  props.elements
1474
2111
  ]);
1475
- return /* @__PURE__ */ import_react5.default.createElement(MouseElementTracker, {
2112
+ return /* @__PURE__ */ import_react10.default.createElement(MouseElementTracker, {
1476
2113
  transform: props.transform,
1477
2114
  primitives: primitives
1478
- }, /* @__PURE__ */ import_react5.default.createElement(CanvasPrimitiveRenderer, {
2115
+ }, /* @__PURE__ */ import_react10.default.createElement(DimensionOverlay, {
2116
+ transform: props.transform
2117
+ }, /* @__PURE__ */ import_react10.default.createElement(ToolbarOverlay, {
2118
+ elements: props.elements
2119
+ }, /* @__PURE__ */ import_react10.default.createElement(CanvasPrimitiveRenderer, {
1479
2120
  transform: props.transform,
1480
2121
  primitives: primitives,
1481
2122
  width: props.width,
1482
2123
  height: props.height,
1483
2124
  grid: props.grid
1484
- }));
2125
+ }))));
1485
2126
  };
1486
2127
  // src/PCBViewer.tsx
1487
2128
  var import_use_mouse_matrix_transform = __toESM(require_dist());
@@ -1489,11 +2130,11 @@ var import_use_mouse_matrix_transform = __toESM(require_dist());
1489
2130
  var noop = function noop() {};
1490
2131
  var isBrowser = typeof window !== "undefined";
1491
2132
  // node_modules/react-use/esm/useIsomorphicLayoutEffect.js
1492
- var import_react7 = require("react");
1493
- var useIsomorphicLayoutEffect = isBrowser ? import_react7.useLayoutEffect : import_react7.useEffect;
2133
+ var import_react12 = require("react");
2134
+ var useIsomorphicLayoutEffect = isBrowser ? import_react12.useLayoutEffect : import_react12.useEffect;
1494
2135
  var useIsomorphicLayoutEffect_default = useIsomorphicLayoutEffect;
1495
2136
  // node_modules/react-use/esm/useMeasure.js
1496
- var import_react8 = require("react");
2137
+ var import_react13 = require("react");
1497
2138
  var defaultState = {
1498
2139
  x: 0,
1499
2140
  y: 0,
@@ -1505,9 +2146,9 @@ var defaultState = {
1505
2146
  right: 0
1506
2147
  };
1507
2148
  function useMeasure() {
1508
- var _a = (0, import_react8.useState)(null), element = _a[0], ref = _a[1];
1509
- var _b = (0, import_react8.useState)(defaultState), rect = _b[0], setRect = _b[1];
1510
- var observer = (0, import_react8.useMemo)(function() {
2149
+ var _a = (0, import_react13.useState)(null), element = _a[0], ref = _a[1];
2150
+ var _b = (0, import_react13.useState)(defaultState), rect = _b[0], setRect = _b[1];
2151
+ var observer = (0, import_react13.useMemo)(function() {
1511
2152
  return new window.ResizeObserver(function(entries) {
1512
2153
  if (entries[0]) {
1513
2154
  var _a2 = entries[0].contentRect, x = _a2.x, y = _a2.y, width = _a2.width, height = _a2.height, top_1 = _a2.top, left = _a2.left, bottom = _a2.bottom, right = _a2.right;
@@ -1545,19 +2186,19 @@ var useMeasure_default = isBrowser && typeof window.ResizeObserver !== "undefine
1545
2186
  ];
1546
2187
  };
1547
2188
  // src/PCBViewer.tsx
1548
- var import_transformation_matrix3 = require("transformation-matrix");
1549
- var import_builder2 = require("@tscircuit/builder");
1550
- var defaultTransform = (0, import_transformation_matrix3.compose)((0, import_transformation_matrix3.translate)(400, 300), (0, import_transformation_matrix3.scale)(40, 40));
2189
+ var import_transformation_matrix4 = require("transformation-matrix");
2190
+ var import_builder4 = require("@tscircuit/builder");
2191
+ var defaultTransform = (0, import_transformation_matrix4.compose)((0, import_transformation_matrix4.translate)(400, 300), (0, import_transformation_matrix4.scale)(40, -40));
1551
2192
  var PCBViewer = function(param) {
1552
2193
  var children = param.children, soup = param.soup, _param_height = param.height, height = _param_height === void 0 ? 600 : _param_height;
1553
- var _ref = _sliced_to_array((0, import_react9.useState)([]), 2), stateElements = _ref[0], setStateElements = _ref[1];
2194
+ var _ref = _sliced_to_array((0, import_react14.useState)([]), 2), stateElements = _ref[0], setStateElements = _ref[1];
1554
2195
  var _useMeasure_default = _sliced_to_array(useMeasure_default(), 2), ref = _useMeasure_default[0], refDimensions = _useMeasure_default[1];
1555
- var _ref1 = _sliced_to_array((0, import_react9.useState)(defaultTransform), 2), transform = _ref1[0], setTransformInternal = _ref1[1];
2196
+ var _ref1 = _sliced_to_array((0, import_react14.useState)(defaultTransform), 2), transform = _ref1[0], setTransformInternal = _ref1[1];
1556
2197
  var _ref2 = (0, import_use_mouse_matrix_transform.default)({
1557
2198
  transform: transform,
1558
2199
  onSetTransform: setTransformInternal
1559
2200
  }), transformRef = _ref2.ref, setTransform = _ref2.setTransform;
1560
- var _ref3 = _sliced_to_array((0, import_react9.useState)(null), 2), error = _ref3[0], setError = _ref3[1];
2201
+ var _ref3 = _sliced_to_array((0, import_react14.useState)(null), 2), error = _ref3[0], setError = _ref3[1];
1561
2202
  var resetTransform = function() {
1562
2203
  var elmBounds = (refDimensions === null || refDimensions === void 0 ? void 0 : refDimensions.width) > 0 ? refDimensions : {
1563
2204
  width: 500,
@@ -1565,7 +2206,7 @@ var PCBViewer = function(param) {
1565
2206
  };
1566
2207
  var _ref = elements.some(function(e) {
1567
2208
  return e.type.startsWith("pcb_");
1568
- }) ? (0, import_builder2.findBoundsAndCenter)(elements.filter(function(e) {
2209
+ }) ? (0, import_builder4.findBoundsAndCenter)(elements.filter(function(e) {
1569
2210
  return e.type.startsWith("pcb_");
1570
2211
  })) : {
1571
2212
  center: {
@@ -1578,26 +2219,46 @@ var PCBViewer = function(param) {
1578
2219
  var _elmBounds_width, _elmBounds_height;
1579
2220
  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);
1580
2221
  var _elmBounds_width1, _elmBounds_height1;
1581
- setTransform((0, import_transformation_matrix3.compose)((0, import_transformation_matrix3.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),
1582
- (0, import_transformation_matrix3.scale)(scaleFactor, scaleFactor, 0, 0), (0, import_transformation_matrix3.translate)(-center.x, -center.y)));
2222
+ setTransform((0, import_transformation_matrix4.compose)((0, import_transformation_matrix4.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),
2223
+ (0, import_transformation_matrix4.scale)(scaleFactor, -scaleFactor, 0, 0), (0, import_transformation_matrix4.translate)(-center.x, -center.y)));
1583
2224
  };
1584
- (0, import_react9.useEffect)(function() {
2225
+ (0, import_react14.useEffect)(function() {
2226
+ var doRender = function doRender() {
2227
+ return _doRender.apply(this, arguments);
2228
+ };
1585
2229
  if (!children || (children === null || children === void 0 ? void 0 : children.length) === 0) return;
1586
- var projectBuilder = (0, import_builder.createProjectBuilder)();
1587
- (0, import_react_fiber.createRoot)().render(children, projectBuilder).then(function(elements2) {
1588
- console.log({
1589
- elements: elements2
2230
+ function _doRender() {
2231
+ _doRender = _async_to_generator(function() {
2232
+ var projectBuilder;
2233
+ return _ts_generator(this, function(_state) {
2234
+ switch(_state.label){
2235
+ case 0:
2236
+ projectBuilder = (0, import_builder3.createProjectBuilder)();
2237
+ return [
2238
+ 4,
2239
+ (0, import_react_fiber.createRoot)().render(children, projectBuilder).then(function(elements2) {
2240
+ setStateElements(elements2);
2241
+ setError(null);
2242
+ })
2243
+ ];
2244
+ case 1:
2245
+ _state.sent();
2246
+ return [
2247
+ 2
2248
+ ];
2249
+ }
2250
+ });
1590
2251
  });
1591
- setStateElements(elements2);
1592
- setError(null);
1593
- }).catch(function(e) {
2252
+ return _doRender.apply(this, arguments);
2253
+ }
2254
+ doRender().catch(function(e) {
1594
2255
  setError(e.toString());
1595
2256
  console.log(e.toString());
1596
2257
  });
1597
2258
  }, [
1598
2259
  children
1599
2260
  ]);
1600
- (0, import_react9.useEffect)(function() {
2261
+ (0, import_react14.useEffect)(function() {
1601
2262
  if (refDimensions && refDimensions.width !== 0 && children) {
1602
2263
  resetTransform();
1603
2264
  }
@@ -1605,18 +2266,18 @@ var PCBViewer = function(param) {
1605
2266
  children,
1606
2267
  refDimensions
1607
2268
  ]);
1608
- if (error) return /* @__PURE__ */ import_react9.default.createElement("div", {
2269
+ if (error) return /* @__PURE__ */ import_react14.default.createElement("div", {
1609
2270
  style: {
1610
2271
  color: "red"
1611
2272
  }
1612
2273
  }, " ", error, " ");
1613
2274
  var elements = soup !== null && soup !== void 0 ? soup : stateElements;
1614
2275
  if (elements.length === 0) return null;
1615
- return /* @__PURE__ */ import_react9.default.createElement("div", {
2276
+ return /* @__PURE__ */ import_react14.default.createElement("div", {
1616
2277
  ref: transformRef
1617
- }, /* @__PURE__ */ import_react9.default.createElement("div", {
2278
+ }, /* @__PURE__ */ import_react14.default.createElement("div", {
1618
2279
  ref: ref
1619
- }, /* @__PURE__ */ import_react9.default.createElement(CanvasElementsRenderer, {
2280
+ }, /* @__PURE__ */ import_react14.default.createElement(ContextProviders, null, /* @__PURE__ */ import_react14.default.createElement(CanvasElementsRenderer, {
1620
2281
  key: refDimensions.width,
1621
2282
  transform: transform,
1622
2283
  height: height,
@@ -1633,7 +2294,7 @@ var PCBViewer = function(param) {
1633
2294
  elements: elements.filter(function(elm) {
1634
2295
  return elm.type.startsWith("pcb_") || elm.type.startsWith("source_");
1635
2296
  })
1636
- })));
2297
+ }))));
1637
2298
  };
1638
2299
  // Annotate the CommonJS export names for ESM import in node:
1639
2300
  0 && (module.exports = {