@tscircuit/core 0.0.1242 → 0.0.1244

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.d.ts CHANGED
@@ -83031,6 +83031,83 @@ declare const pcbTraceProps: z.ZodObject<{
83031
83031
  outer_diameter?: string | number | undefined;
83032
83032
  copper_pour_id?: string | undefined;
83033
83033
  is_inside_copper_pour?: boolean | undefined;
83034
+ }>, z.ZodObject<{
83035
+ route_type: z.ZodLiteral<"through_pad">;
83036
+ start: z.ZodObject<{
83037
+ x: z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber]>, number, string | number>;
83038
+ y: z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber]>, number, string | number>;
83039
+ }, "strip", z.ZodTypeAny, {
83040
+ x: number;
83041
+ y: number;
83042
+ }, {
83043
+ x: string | number;
83044
+ y: string | number;
83045
+ }>;
83046
+ end: z.ZodObject<{
83047
+ x: z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber]>, number, string | number>;
83048
+ y: z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber]>, number, string | number>;
83049
+ }, "strip", z.ZodTypeAny, {
83050
+ x: number;
83051
+ y: number;
83052
+ }, {
83053
+ x: string | number;
83054
+ y: string | number;
83055
+ }>;
83056
+ width: z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber]>, number, string | number>;
83057
+ start_layer: z.ZodEffects<z.ZodUnion<[z.ZodEnum<["top", "bottom", "inner1", "inner2", "inner3", "inner4", "inner5", "inner6"]>, z.ZodObject<{
83058
+ name: z.ZodEnum<["top", "bottom", "inner1", "inner2", "inner3", "inner4", "inner5", "inner6"]>;
83059
+ }, "strip", z.ZodTypeAny, {
83060
+ name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6";
83061
+ }, {
83062
+ name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6";
83063
+ }>]>, "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6", "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | {
83064
+ name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6";
83065
+ }>;
83066
+ end_layer: z.ZodEffects<z.ZodUnion<[z.ZodEnum<["top", "bottom", "inner1", "inner2", "inner3", "inner4", "inner5", "inner6"]>, z.ZodObject<{
83067
+ name: z.ZodEnum<["top", "bottom", "inner1", "inner2", "inner3", "inner4", "inner5", "inner6"]>;
83068
+ }, "strip", z.ZodTypeAny, {
83069
+ name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6";
83070
+ }, {
83071
+ name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6";
83072
+ }>]>, "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6", "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | {
83073
+ name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6";
83074
+ }>;
83075
+ pcb_smtpad_id: z.ZodOptional<z.ZodString>;
83076
+ pcb_plated_hole_id: z.ZodOptional<z.ZodString>;
83077
+ }, "strip", z.ZodTypeAny, {
83078
+ width: number;
83079
+ route_type: "through_pad";
83080
+ start: {
83081
+ x: number;
83082
+ y: number;
83083
+ };
83084
+ end: {
83085
+ x: number;
83086
+ y: number;
83087
+ };
83088
+ start_layer: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6";
83089
+ end_layer: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6";
83090
+ pcb_plated_hole_id?: string | undefined;
83091
+ pcb_smtpad_id?: string | undefined;
83092
+ }, {
83093
+ width: string | number;
83094
+ route_type: "through_pad";
83095
+ start: {
83096
+ x: string | number;
83097
+ y: string | number;
83098
+ };
83099
+ end: {
83100
+ x: string | number;
83101
+ y: string | number;
83102
+ };
83103
+ start_layer: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | {
83104
+ name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6";
83105
+ };
83106
+ end_layer: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | {
83107
+ name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6";
83108
+ };
83109
+ pcb_plated_hole_id?: string | undefined;
83110
+ pcb_smtpad_id?: string | undefined;
83034
83111
  }>]>, "many">;
83035
83112
  source_trace_id: z.ZodOptional<z.ZodString>;
83036
83113
  }, "strip", z.ZodTypeAny, {
@@ -83054,6 +83131,21 @@ declare const pcbTraceProps: z.ZodObject<{
83054
83131
  outer_diameter?: number | undefined;
83055
83132
  copper_pour_id?: string | undefined;
83056
83133
  is_inside_copper_pour?: boolean | undefined;
83134
+ } | {
83135
+ width: number;
83136
+ route_type: "through_pad";
83137
+ start: {
83138
+ x: number;
83139
+ y: number;
83140
+ };
83141
+ end: {
83142
+ x: number;
83143
+ y: number;
83144
+ };
83145
+ start_layer: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6";
83146
+ end_layer: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6";
83147
+ pcb_plated_hole_id?: string | undefined;
83148
+ pcb_smtpad_id?: string | undefined;
83057
83149
  })[];
83058
83150
  source_trace_id?: string | undefined;
83059
83151
  }, {
@@ -83083,6 +83175,25 @@ declare const pcbTraceProps: z.ZodObject<{
83083
83175
  outer_diameter?: string | number | undefined;
83084
83176
  copper_pour_id?: string | undefined;
83085
83177
  is_inside_copper_pour?: boolean | undefined;
83178
+ } | {
83179
+ width: string | number;
83180
+ route_type: "through_pad";
83181
+ start: {
83182
+ x: string | number;
83183
+ y: string | number;
83184
+ };
83185
+ end: {
83186
+ x: string | number;
83187
+ y: string | number;
83188
+ };
83189
+ start_layer: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | {
83190
+ name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6";
83191
+ };
83192
+ end_layer: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | {
83193
+ name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6";
83194
+ };
83195
+ pcb_plated_hole_id?: string | undefined;
83196
+ pcb_smtpad_id?: string | undefined;
83086
83197
  })[];
83087
83198
  source_trace_id?: string | undefined;
83088
83199
  }>;
@@ -83182,6 +83293,83 @@ declare class PcbTrace extends PrimitiveComponent<typeof pcbTraceProps> {
83182
83293
  outer_diameter?: string | number | undefined;
83183
83294
  copper_pour_id?: string | undefined;
83184
83295
  is_inside_copper_pour?: boolean | undefined;
83296
+ }>, z.ZodObject<{
83297
+ route_type: z.ZodLiteral<"through_pad">;
83298
+ start: z.ZodObject<{
83299
+ x: z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber]>, number, string | number>;
83300
+ y: z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber]>, number, string | number>;
83301
+ }, "strip", z.ZodTypeAny, {
83302
+ x: number;
83303
+ y: number;
83304
+ }, {
83305
+ x: string | number;
83306
+ y: string | number;
83307
+ }>;
83308
+ end: z.ZodObject<{
83309
+ x: z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber]>, number, string | number>;
83310
+ y: z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber]>, number, string | number>;
83311
+ }, "strip", z.ZodTypeAny, {
83312
+ x: number;
83313
+ y: number;
83314
+ }, {
83315
+ x: string | number;
83316
+ y: string | number;
83317
+ }>;
83318
+ width: z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber]>, number, string | number>;
83319
+ start_layer: z.ZodEffects<z.ZodUnion<[z.ZodEnum<["top", "bottom", "inner1", "inner2", "inner3", "inner4", "inner5", "inner6"]>, z.ZodObject<{
83320
+ name: z.ZodEnum<["top", "bottom", "inner1", "inner2", "inner3", "inner4", "inner5", "inner6"]>;
83321
+ }, "strip", z.ZodTypeAny, {
83322
+ name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6";
83323
+ }, {
83324
+ name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6";
83325
+ }>]>, "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6", "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | {
83326
+ name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6";
83327
+ }>;
83328
+ end_layer: z.ZodEffects<z.ZodUnion<[z.ZodEnum<["top", "bottom", "inner1", "inner2", "inner3", "inner4", "inner5", "inner6"]>, z.ZodObject<{
83329
+ name: z.ZodEnum<["top", "bottom", "inner1", "inner2", "inner3", "inner4", "inner5", "inner6"]>;
83330
+ }, "strip", z.ZodTypeAny, {
83331
+ name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6";
83332
+ }, {
83333
+ name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6";
83334
+ }>]>, "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6", "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | {
83335
+ name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6";
83336
+ }>;
83337
+ pcb_smtpad_id: z.ZodOptional<z.ZodString>;
83338
+ pcb_plated_hole_id: z.ZodOptional<z.ZodString>;
83339
+ }, "strip", z.ZodTypeAny, {
83340
+ width: number;
83341
+ route_type: "through_pad";
83342
+ start: {
83343
+ x: number;
83344
+ y: number;
83345
+ };
83346
+ end: {
83347
+ x: number;
83348
+ y: number;
83349
+ };
83350
+ start_layer: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6";
83351
+ end_layer: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6";
83352
+ pcb_plated_hole_id?: string | undefined;
83353
+ pcb_smtpad_id?: string | undefined;
83354
+ }, {
83355
+ width: string | number;
83356
+ route_type: "through_pad";
83357
+ start: {
83358
+ x: string | number;
83359
+ y: string | number;
83360
+ };
83361
+ end: {
83362
+ x: string | number;
83363
+ y: string | number;
83364
+ };
83365
+ start_layer: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | {
83366
+ name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6";
83367
+ };
83368
+ end_layer: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | {
83369
+ name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6";
83370
+ };
83371
+ pcb_plated_hole_id?: string | undefined;
83372
+ pcb_smtpad_id?: string | undefined;
83185
83373
  }>]>, "many">;
83186
83374
  source_trace_id: z.ZodOptional<z.ZodString>;
83187
83375
  }, "strip", z.ZodTypeAny, {
@@ -83205,6 +83393,21 @@ declare class PcbTrace extends PrimitiveComponent<typeof pcbTraceProps> {
83205
83393
  outer_diameter?: number | undefined;
83206
83394
  copper_pour_id?: string | undefined;
83207
83395
  is_inside_copper_pour?: boolean | undefined;
83396
+ } | {
83397
+ width: number;
83398
+ route_type: "through_pad";
83399
+ start: {
83400
+ x: number;
83401
+ y: number;
83402
+ };
83403
+ end: {
83404
+ x: number;
83405
+ y: number;
83406
+ };
83407
+ start_layer: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6";
83408
+ end_layer: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6";
83409
+ pcb_plated_hole_id?: string | undefined;
83410
+ pcb_smtpad_id?: string | undefined;
83208
83411
  })[];
83209
83412
  source_trace_id?: string | undefined;
83210
83413
  }, {
@@ -83234,6 +83437,25 @@ declare class PcbTrace extends PrimitiveComponent<typeof pcbTraceProps> {
83234
83437
  outer_diameter?: string | number | undefined;
83235
83438
  copper_pour_id?: string | undefined;
83236
83439
  is_inside_copper_pour?: boolean | undefined;
83440
+ } | {
83441
+ width: string | number;
83442
+ route_type: "through_pad";
83443
+ start: {
83444
+ x: string | number;
83445
+ y: string | number;
83446
+ };
83447
+ end: {
83448
+ x: string | number;
83449
+ y: string | number;
83450
+ };
83451
+ start_layer: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | {
83452
+ name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6";
83453
+ };
83454
+ end_layer: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | {
83455
+ name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6";
83456
+ };
83457
+ pcb_plated_hole_id?: string | undefined;
83458
+ pcb_smtpad_id?: string | undefined;
83237
83459
  })[];
83238
83460
  source_trace_id?: string | undefined;
83239
83461
  }>;
package/dist/index.js CHANGED
@@ -233,9 +233,21 @@ function getDominantDirection(edge) {
233
233
  return delta.y > 0 ? "down" : "up";
234
234
  }
235
235
 
236
+ // lib/utils/pcb-trace-route-point-utils.ts
237
+ var getRoutePointPosition = (point6) => {
238
+ if (point6.route_type === "through_pad") return point6.start;
239
+ return { x: point6.x, y: point6.y };
240
+ };
241
+ var getRoutePointPositions = (point6) => {
242
+ if (point6.route_type === "through_pad") return [point6.start, point6.end];
243
+ return [{ x: point6.x, y: point6.y }];
244
+ };
245
+
236
246
  // lib/utils/autorouting/mergeRoutes.ts
237
247
  function pdist(a, b) {
238
- return Math.hypot(a.x - b.x, a.y - b.y);
248
+ const aPosition = getRoutePointPosition(a);
249
+ const bPosition = getRoutePointPosition(b);
250
+ return Math.hypot(aPosition.x - bPosition.x, aPosition.y - bPosition.y);
239
251
  }
240
252
  var mergeRoutes = (routes) => {
241
253
  if (routes.length === 1) return routes[0];
@@ -2578,8 +2590,10 @@ var isRouteOutsideBoard = ({
2578
2590
  const pcbBoard = db.pcb_board.get(pcbBoardId);
2579
2591
  if (!pcbBoard) return false;
2580
2592
  const boardOutlinePolygon = getPcbBoardOutlinePolygon(pcbBoard);
2581
- return !mergedRoute.flat().every(
2582
- (routePoint) => boardOutlinePolygon.contains(point2(routePoint.x, routePoint.y))
2593
+ return !mergedRoute.flatMap(getRoutePointPositions).every(
2594
+ (routePointPosition) => boardOutlinePolygon.contains(
2595
+ point2(routePointPosition.x, routePointPosition.y)
2596
+ )
2583
2597
  );
2584
2598
  };
2585
2599
 
@@ -3015,11 +3029,29 @@ var getObstaclesFromCircuitJson = (soup, connMap) => {
3015
3029
  }
3016
3030
  } else if (element.type === "pcb_trace") {
3017
3031
  const traceObstacles = getObstaclesFromRoute(
3018
- element.route.map((rp) => ({
3019
- x: rp.x,
3020
- y: rp.y,
3021
- layer: "layer" in rp ? rp.layer : rp.from_layer
3022
- })),
3032
+ element.route.flatMap((rp) => {
3033
+ if (rp.route_type === "through_pad") {
3034
+ return [
3035
+ {
3036
+ x: rp.start.x,
3037
+ y: rp.start.y,
3038
+ layer: rp.start_layer
3039
+ },
3040
+ {
3041
+ x: rp.end.x,
3042
+ y: rp.end.y,
3043
+ layer: rp.end_layer
3044
+ }
3045
+ ];
3046
+ }
3047
+ return [
3048
+ {
3049
+ x: rp.x,
3050
+ y: rp.y,
3051
+ layer: rp.route_type === "wire" ? rp.layer : rp.from_layer
3052
+ }
3053
+ ];
3054
+ }),
3023
3055
  element.source_trace_id
3024
3056
  );
3025
3057
  obstacles.push(...traceObstacles);
@@ -3945,8 +3977,10 @@ function getTraceLength(route) {
3945
3977
  if (point6.route_type === "wire") {
3946
3978
  const nextPoint = route[i + 1];
3947
3979
  if (nextPoint) {
3948
- const dx = nextPoint.x - point6.x;
3949
- const dy = nextPoint.y - point6.y;
3980
+ const nextPosition = getRoutePointPosition(nextPoint);
3981
+ const position = getRoutePointPosition(point6);
3982
+ const dx = nextPosition.x - position.x;
3983
+ const dy = nextPosition.y - position.y;
3950
3984
  totalLength += Math.sqrt(dx * dx + dy * dy);
3951
3985
  }
3952
3986
  } else if (point6.route_type === "via") {
@@ -4559,6 +4593,13 @@ var findInflatedPcbViaForPoint = (vias, point6) => {
4559
4593
  (via) => Math.abs(via.x - point6.x) < 1e-4 && Math.abs(via.y - point6.y) < 1e-4 && (!via.from_layer || via.from_layer === point6.from_layer) && (!via.to_layer || via.to_layer === point6.to_layer)
4560
4594
  );
4561
4595
  };
4596
+ var getViaDiameterFromRoutePoint = (point6) => {
4597
+ const viaPoint = point6;
4598
+ return {
4599
+ holeDiameter: viaPoint.hole_diameter ?? viaPoint.via_hole_diameter,
4600
+ outerDiameter: viaPoint.outer_diameter ?? viaPoint.via_diameter
4601
+ };
4602
+ };
4562
4603
  function Trace_doInitialPcbManualTraceRender(trace) {
4563
4604
  if (trace.root?.pcbDisabled) return;
4564
4605
  const { db } = trace.root;
@@ -4624,16 +4665,32 @@ function Trace_doInitialPcbManualTraceRender(trace) {
4624
4665
  const { maybeFlipLayer } = trace._getPcbPrimitiveFlippedHelpers();
4625
4666
  const transform2 = trace._computePcbGlobalTransformBeforeLayout();
4626
4667
  const transformedRoute = inflatedPcbTrace.route.map((point6) => {
4627
- const { x, y, ...restOfPoint } = point6;
4628
- const transformedPoint = applyToPoint2(transform2, { x, y });
4629
- if (point6.route_type === "wire" && point6.layer) {
4668
+ if (point6.route_type === "wire") {
4669
+ const { x, y, ...restOfPoint } = point6;
4670
+ const transformedPoint = applyToPoint2(transform2, { x, y });
4630
4671
  return {
4631
- ...transformedPoint,
4632
4672
  ...restOfPoint,
4673
+ ...transformedPoint,
4633
4674
  layer: maybeFlipLayer(point6.layer)
4634
4675
  };
4635
4676
  }
4636
- return { ...transformedPoint, ...restOfPoint };
4677
+ if (point6.route_type === "via") {
4678
+ const { x, y, ...restOfPoint } = point6;
4679
+ const transformedPoint = applyToPoint2(transform2, { x, y });
4680
+ return {
4681
+ ...restOfPoint,
4682
+ ...transformedPoint,
4683
+ from_layer: maybeFlipLayer(point6.from_layer),
4684
+ to_layer: maybeFlipLayer(point6.to_layer)
4685
+ };
4686
+ }
4687
+ return {
4688
+ ...point6,
4689
+ start: applyToPoint2(transform2, point6.start),
4690
+ end: applyToPoint2(transform2, point6.end),
4691
+ start_layer: maybeFlipLayer(point6.start_layer),
4692
+ end_layer: maybeFlipLayer(point6.end_layer)
4693
+ };
4637
4694
  });
4638
4695
  const pcb_trace2 = db.pcb_trace.insert({
4639
4696
  ...inflatedPcbTrace,
@@ -4652,6 +4709,7 @@ function Trace_doInitialPcbManualTraceRender(trace) {
4652
4709
  trace._inflatedPcbVias,
4653
4710
  originalPoint
4654
4711
  );
4712
+ const routePointViaDiameter = getViaDiameterFromRoutePoint(point6);
4655
4713
  const fromLayer = maybeFlipLayer(
4656
4714
  inflatedPcbVia?.from_layer ?? point6.from_layer
4657
4715
  );
@@ -4666,8 +4724,8 @@ function Trace_doInitialPcbManualTraceRender(trace) {
4666
4724
  pcb_trace_id: pcb_trace2.pcb_trace_id,
4667
4725
  x: point6.x,
4668
4726
  y: point6.y,
4669
- hole_diameter: inflatedPcbVia?.hole_diameter ?? holeDiameter2,
4670
- outer_diameter: inflatedPcbVia?.outer_diameter ?? padDiameter2,
4727
+ hole_diameter: inflatedPcbVia?.hole_diameter ?? routePointViaDiameter.holeDiameter ?? holeDiameter2,
4728
+ outer_diameter: inflatedPcbVia?.outer_diameter ?? routePointViaDiameter.outerDiameter ?? padDiameter2,
4671
4729
  layers,
4672
4730
  from_layer: fromLayer,
4673
4731
  to_layer: toLayer,
@@ -6898,16 +6956,32 @@ var PcbTrace = class extends PrimitiveComponent2 {
6898
6956
  const { maybeFlipLayer } = this._getPcbPrimitiveFlippedHelpers();
6899
6957
  const parentTransform = this._computePcbGlobalTransformBeforeLayout();
6900
6958
  const transformedRoute = props.route.map((point6) => {
6901
- const { x, y, ...restOfPoint } = point6;
6902
- const transformedPoint = applyToPoint11(parentTransform, { x, y });
6903
- if (point6.route_type === "wire" && point6.layer) {
6959
+ if (point6.route_type === "wire") {
6960
+ const { x, y, ...restOfPoint } = point6;
6961
+ const transformedPoint = applyToPoint11(parentTransform, { x, y });
6904
6962
  return {
6905
- ...transformedPoint,
6906
6963
  ...restOfPoint,
6964
+ ...transformedPoint,
6907
6965
  layer: maybeFlipLayer(point6.layer)
6908
6966
  };
6909
6967
  }
6910
- return { ...transformedPoint, ...restOfPoint };
6968
+ if (point6.route_type === "via") {
6969
+ const { x, y, ...restOfPoint } = point6;
6970
+ const transformedPoint = applyToPoint11(parentTransform, { x, y });
6971
+ return {
6972
+ ...restOfPoint,
6973
+ ...transformedPoint,
6974
+ from_layer: maybeFlipLayer(point6.from_layer),
6975
+ to_layer: maybeFlipLayer(point6.to_layer)
6976
+ };
6977
+ }
6978
+ return {
6979
+ ...point6,
6980
+ start: applyToPoint11(parentTransform, point6.start),
6981
+ end: applyToPoint11(parentTransform, point6.end),
6982
+ start_layer: maybeFlipLayer(point6.start_layer),
6983
+ end_layer: maybeFlipLayer(point6.end_layer)
6984
+ };
6911
6985
  });
6912
6986
  const pcb_trace = db.pcb_trace.insert({
6913
6987
  pcb_component_id: container.pcb_component_id,
@@ -6925,15 +6999,43 @@ var PcbTrace = class extends PrimitiveComponent2 {
6925
6999
  }
6926
7000
  let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;
6927
7001
  for (const point6 of props.route) {
6928
- minX = Math.min(minX, point6.x);
6929
- maxX = Math.max(maxX, point6.x);
6930
- minY = Math.min(minY, point6.y);
6931
- maxY = Math.max(maxY, point6.y);
7002
+ if (point6.route_type === "through_pad") {
7003
+ minX = Math.min(minX, point6.start.x, point6.end.x);
7004
+ maxX = Math.max(maxX, point6.start.x, point6.end.x);
7005
+ minY = Math.min(minY, point6.start.y, point6.end.y);
7006
+ maxY = Math.max(maxY, point6.start.y, point6.end.y);
7007
+ } else {
7008
+ minX = Math.min(minX, point6.x);
7009
+ maxX = Math.max(maxX, point6.x);
7010
+ minY = Math.min(minY, point6.y);
7011
+ maxY = Math.max(maxY, point6.y);
7012
+ }
6932
7013
  if (point6.route_type === "wire") {
6933
7014
  minX = Math.min(minX, point6.x - point6.width / 2);
6934
7015
  maxX = Math.max(maxX, point6.x + point6.width / 2);
6935
7016
  minY = Math.min(minY, point6.y - point6.width / 2);
6936
7017
  maxY = Math.max(maxY, point6.y + point6.width / 2);
7018
+ } else if (point6.route_type === "through_pad") {
7019
+ minX = Math.min(
7020
+ minX,
7021
+ point6.start.x - point6.width / 2,
7022
+ point6.end.x - point6.width / 2
7023
+ );
7024
+ maxX = Math.max(
7025
+ maxX,
7026
+ point6.start.x + point6.width / 2,
7027
+ point6.end.x + point6.width / 2
7028
+ );
7029
+ minY = Math.min(
7030
+ minY,
7031
+ point6.start.y - point6.width / 2,
7032
+ point6.end.y - point6.width / 2
7033
+ );
7034
+ maxY = Math.max(
7035
+ maxY,
7036
+ point6.start.y + point6.width / 2,
7037
+ point6.end.y + point6.width / 2
7038
+ );
6937
7039
  }
6938
7040
  }
6939
7041
  if (minX === Infinity || maxX === -Infinity || minY === Infinity || maxY === -Infinity) {
@@ -7785,7 +7887,7 @@ var SilkscreenRect = class extends PrimitiveComponent2 {
7785
7887
  import { silkscreenTextProps } from "@tscircuit/props";
7786
7888
  import {
7787
7889
  applyToPoint as applyToPoint14,
7788
- compose as compose3,
7890
+ compose as compose2,
7789
7891
  decomposeTSR as decomposeTSR5,
7790
7892
  flipY as flipY2,
7791
7893
  identity as identity4
@@ -7842,7 +7944,7 @@ var SilkscreenText = class extends PrimitiveComponent2 {
7842
7944
  const fontSize = props.fontSize ?? resolvedPcbSxFontSize ?? this.getInheritedProperty("pcbStyle")?.silkscreenFontSize ?? this._footprinterFontSize ?? 1;
7843
7945
  const hasResolvedPcbSxPosition = resolvedPcbSxPcbX !== void 0 || resolvedPcbSxPcbY !== void 0;
7844
7946
  const position = hasResolvedPcbSxPosition && this._footprinterFontSize !== void 0 ? applyToPoint14(
7845
- compose3(
7947
+ compose2(
7846
7948
  this.parent?._computePcbGlobalTransformBeforeLayout() ?? identity4(),
7847
7949
  isFlipped ? flipY2() : identity4()
7848
7950
  ),
@@ -8995,7 +9097,7 @@ var SCHEMATIC_COMPONENT_OUTLINE_STROKE_WIDTH = 0.12;
8995
9097
 
8996
9098
  // lib/components/primitive-components/Port/Port.ts
8997
9099
  import "schematic-symbols";
8998
- import { applyToPoint as applyToPoint16, compose as compose4, translate as translate3 } from "transformation-matrix";
9100
+ import { applyToPoint as applyToPoint16, compose as compose3, translate as translate2 } from "transformation-matrix";
8999
9101
  import "zod";
9000
9102
 
9001
9103
  // lib/components/primitive-components/Port/getCenterOfPcbPrimitives.ts
@@ -9242,9 +9344,9 @@ var Port = class extends PrimitiveComponent2 {
9242
9344
  );
9243
9345
  }
9244
9346
  }
9245
- const transform = compose4(
9347
+ const transform = compose3(
9246
9348
  parentNormalComponent.computeSchematicGlobalTransform(),
9247
- translate3(-symbol.center.x, -symbol.center.y)
9349
+ translate2(-symbol.center.x, -symbol.center.y)
9248
9350
  );
9249
9351
  return applyToPoint16(transform, schematicSymbolPortDef);
9250
9352
  }
@@ -12449,7 +12551,6 @@ var NormalComponent3 = class extends PrimitiveComponent2 {
12449
12551
  const cadModel = cadModelProp2 === void 0 ? this._asyncFootprintCadModel : cadModelProp2;
12450
12552
  const footprint = this.getFootprinterString() ?? this._getImpliedFootprintString();
12451
12553
  if (!this.pcb_component_id) return;
12452
- if (!cadModel && !footprint) return;
12453
12554
  if (cadModel === null) return;
12454
12555
  const bounds = this._getPcbCircuitJsonBounds();
12455
12556
  if (typeof cadModel === "string") {
@@ -12478,6 +12579,28 @@ var NormalComponent3 = class extends PrimitiveComponent2 {
12478
12579
  const preLayoutRotation = decomposedTransform.rotation.angle * 180 / Math.PI;
12479
12580
  const totalRotation = pcbComponent?.position_mode === "packed" ? pcbComponent.rotation ?? preLayoutRotation : preLayoutRotation;
12480
12581
  const isBottomLayer = computedLayer === "bottom";
12582
+ if (!cadModel && !footprint) {
12583
+ const cad_component = db.cad_component.insert({
12584
+ position: {
12585
+ x: bounds.center.x,
12586
+ y: bounds.center.y,
12587
+ z: computedLayer === "bottom" ? -boardThickness / 2 : boardThickness / 2
12588
+ },
12589
+ rotation: {
12590
+ x: 0,
12591
+ y: isBottomLayer ? 180 : 0,
12592
+ z: normalizeDegrees2(isBottomLayer ? -totalRotation : totalRotation)
12593
+ },
12594
+ pcb_component_id: this.pcb_component_id,
12595
+ source_component_id: this.source_component_id,
12596
+ model_origin_alignment: "center_of_component_on_board_surface",
12597
+ anchor_alignment: "center_of_component_on_board_surface",
12598
+ show_as_bounding_box: true,
12599
+ show_as_translucent_model: this._parsedProps.showAsTranslucentModel
12600
+ });
12601
+ this.cad_component_id = cad_component.cad_component_id;
12602
+ return;
12603
+ }
12481
12604
  const rotationWithOffset = totalRotation + (rotationOffset.z ?? 0);
12482
12605
  const cadRotationZ = normalizeDegrees2(rotationWithOffset);
12483
12606
  const cad_model = db.cad_component.insert({
@@ -12789,7 +12912,7 @@ import {
12789
12912
  } from "@tscircuit/checks";
12790
12913
  import { getBoundsFromPoints as getBoundsFromPoints5 } from "@tscircuit/math-utils";
12791
12914
  import { boardProps } from "@tscircuit/props";
12792
- import { compose as compose7, translate as translate7 } from "transformation-matrix";
12915
+ import { compose as compose6, translate as translate6 } from "transformation-matrix";
12793
12916
 
12794
12917
  // lib/utils/autorouting/getAncestorSubcircuitIds.ts
12795
12918
  var getDescendantSubcircuitIds = (db, root_subcircuit_id) => {
@@ -12968,7 +13091,7 @@ var Capacitor = class extends NormalComponent3 {
12968
13091
 
12969
13092
  // lib/utils/extractPcbPrimitivesFromCircuitJson.ts
12970
13093
  import { transformPCBElements } from "@tscircuit/circuit-json-util";
12971
- import { compose as compose5, inverse, rotate as rotate2, translate as translate4 } from "transformation-matrix";
13094
+ import { compose as compose4, inverse, rotate as rotate2, translate as translate3 } from "transformation-matrix";
12972
13095
  var extractPcbPrimitivesFromCircuitJson = ({
12973
13096
  pcbComponent,
12974
13097
  db,
@@ -12977,8 +13100,8 @@ var extractPcbPrimitivesFromCircuitJson = ({
12977
13100
  const componentCenter = pcbComponent.center || { x: 0, y: 0 };
12978
13101
  const componentRotation = pcbComponent.rotation || 0;
12979
13102
  const absoluteToComponentRelativeTransform = inverse(
12980
- compose5(
12981
- translate4(componentCenter.x, componentCenter.y),
13103
+ compose4(
13104
+ translate3(componentCenter.x, componentCenter.y),
12982
13105
  rotate2(componentRotation * Math.PI / 180)
12983
13106
  )
12984
13107
  );
@@ -13952,7 +14075,7 @@ var applyEditEventsToManualEditsFile = ({
13952
14075
 
13953
14076
  // lib/utils/edit-events/apply-edit-events-to-circuit-json.ts
13954
14077
  import { transformPCBElement } from "@tscircuit/circuit-json-util";
13955
- import { translate as translate5 } from "transformation-matrix";
14078
+ import { translate as translate4 } from "transformation-matrix";
13956
14079
 
13957
14080
  // lib/utils/edit-events/apply-trace-hint-edit-event.ts
13958
14081
  import { su as su3 } from "@tscircuit/circuit-json-util";
@@ -13997,7 +14120,7 @@ var applyEditEvents = ({
13997
14120
  );
13998
14121
  const needsMovement = !component || component.center.x !== editEvent.new_center.x || component.center.y !== editEvent.new_center.y;
13999
14122
  if (needsMovement && editEvent.original_center) {
14000
- const mat = translate5(
14123
+ const mat = translate4(
14001
14124
  editEvent.new_center.x - editEvent.original_center.x,
14002
14125
  editEvent.new_center.y - editEvent.original_center.y
14003
14126
  );
@@ -15708,7 +15831,7 @@ var applyComponentConstraintClusters = (group, packInput) => {
15708
15831
  };
15709
15832
 
15710
15833
  // lib/components/primitive-components/Group/Group_doInitialPcbLayoutPack/applyPackOutput.ts
15711
- import { translate as translate6, rotate as rotate3, compose as compose6 } from "transformation-matrix";
15834
+ import { translate as translate5, rotate as rotate3, compose as compose5 } from "transformation-matrix";
15712
15835
  import {
15713
15836
  transformPCBElements as transformPCBElements2
15714
15837
  } from "@tscircuit/circuit-json-util";
@@ -15763,11 +15886,11 @@ var applyPackOutput = (group, packOutput, clusterMap) => {
15763
15886
  const member = db.pcb_component.get(memberId);
15764
15887
  if (!member) continue;
15765
15888
  const originalCenter2 = member.center;
15766
- const transformMatrix2 = compose6(
15889
+ const transformMatrix2 = compose5(
15767
15890
  group._computePcbGlobalTransformBeforeLayout(),
15768
- translate6(center.x + rotatedRel.x, center.y + rotatedRel.y),
15891
+ translate5(center.x + rotatedRel.x, center.y + rotatedRel.y),
15769
15892
  rotate3(angleRad),
15770
- translate6(-originalCenter2.x, -originalCenter2.y)
15893
+ translate5(-originalCenter2.x, -originalCenter2.y)
15771
15894
  );
15772
15895
  const related = db.toArray().filter(
15773
15896
  (elm) => "pcb_component_id" in elm && elm.pcb_component_id === memberId
@@ -15797,11 +15920,11 @@ var applyPackOutput = (group, packOutput, clusterMap) => {
15797
15920
  }
15798
15921
  const originalCenter2 = pcbComponent.center;
15799
15922
  const rotationDegrees2 = ccwRotationDegrees ?? ccwRotationOffset ?? 0;
15800
- const transformMatrix2 = compose6(
15923
+ const transformMatrix2 = compose5(
15801
15924
  group._computePcbGlobalTransformBeforeLayout(),
15802
- translate6(center.x, center.y),
15925
+ translate5(center.x, center.y),
15803
15926
  rotate3(rotationDegrees2 * Math.PI / 180),
15804
- translate6(-originalCenter2.x, -originalCenter2.y)
15927
+ translate5(-originalCenter2.x, -originalCenter2.y)
15805
15928
  );
15806
15929
  const related = db.toArray().filter(
15807
15930
  (elm) => "pcb_component_id" in elm && elm.pcb_component_id === componentId
@@ -15819,11 +15942,11 @@ var applyPackOutput = (group, packOutput, clusterMap) => {
15819
15942
  if (!pcbGroup) continue;
15820
15943
  const originalCenter = pcbGroup.center;
15821
15944
  const rotationDegrees = ccwRotationDegrees ?? ccwRotationOffset ?? 0;
15822
- const transformMatrix = compose6(
15945
+ const transformMatrix = compose5(
15823
15946
  group._computePcbGlobalTransformBeforeLayout(),
15824
- translate6(center.x, center.y),
15947
+ translate5(center.x, center.y),
15825
15948
  rotate3(rotationDegrees * Math.PI / 180),
15826
- translate6(-originalCenter.x, -originalCenter.y)
15949
+ translate5(-originalCenter.x, -originalCenter.y)
15827
15950
  );
15828
15951
  const relatedElements = db.toArray().filter((elm) => {
15829
15952
  if ("source_group_id" in elm && elm.source_group_id) {
@@ -18542,10 +18665,14 @@ function getDrcTolerancesFromAutoroutingPhaseProps(phaseProps) {
18542
18665
  function Group_getRoutingPhasePlans(group) {
18543
18666
  const traces = group.selectAll("trace");
18544
18667
  const nets = group.selectAll("net");
18545
- if (traces.length === 0 && nets.length === 0) return [];
18546
18668
  const plansByPhaseIndex = /* @__PURE__ */ new Map();
18547
18669
  const autoroutersByPhaseIndex = getAutoroutersByPhaseIndex(group);
18548
18670
  const phasePropsByPhaseIndex = getAutoroutingPhasePropsByPhaseIndex(group);
18671
+ const hasDirectRoutingTargets = traces.length > 0 || nets.length > 0;
18672
+ const hasReroutePhase = Array.from(phasePropsByPhaseIndex.values()).some(
18673
+ (phaseProps) => phaseProps.reroute
18674
+ );
18675
+ if (!hasDirectRoutingTargets && !hasReroutePhase) return [];
18549
18676
  for (const net of nets) {
18550
18677
  const routingPhaseIndex = getNetRoutingPhaseIndex(net);
18551
18678
  getOrCreateRoutingPhasePlan(plansByPhaseIndex, routingPhaseIndex).nets.push(
@@ -18575,7 +18702,7 @@ function Group_getRoutingPhasePlans(group) {
18575
18702
  plan.drcTolerances = phaseProps ? getDrcTolerancesFromAutoroutingPhaseProps(phaseProps) : void 0;
18576
18703
  }
18577
18704
  const defaultPhaseProps = phasePropsByPhaseIndex.get(null);
18578
- if (phasePropsByPhaseIndex.size === 1 && defaultPhaseProps?.reroute && plans.length === 1 && plans[0]?.routingPhaseIndex === null) {
18705
+ if (hasDirectRoutingTargets && phasePropsByPhaseIndex.size === 1 && defaultPhaseProps?.reroute && plans.length === 1 && plans[0]?.routingPhaseIndex === null) {
18579
18706
  const reroutePlan = plans[0];
18580
18707
  return [
18581
18708
  {
@@ -19004,6 +19131,110 @@ function insertAutoplacedJumpers(params) {
19004
19131
  }
19005
19132
  }
19006
19133
 
19134
+ // lib/components/primitive-components/Group/region-replacement/convert-pcb-trace-to-simplified-pcb-trace.ts
19135
+ function convertPcbTraceToSimplifiedPcbTrace(trace) {
19136
+ return {
19137
+ ...trace,
19138
+ type: "pcb_trace",
19139
+ pcb_trace_id: trace.pcb_trace_id,
19140
+ connection_name: trace.connection_name ?? trace.source_trace_id ?? trace.pcb_trace_id,
19141
+ route: trace.route.map((point6) => ({ ...point6 }))
19142
+ };
19143
+ }
19144
+
19145
+ // lib/components/primitive-components/Group/region-replacement/get-relevant-subcircuit-ids-for-reroute.ts
19146
+ function getRelevantSubcircuitIdsForReroute(group) {
19147
+ const relevantSubcircuitIds = /* @__PURE__ */ new Set();
19148
+ if (!group.subcircuit_id) return relevantSubcircuitIds;
19149
+ relevantSubcircuitIds.add(group.subcircuit_id);
19150
+ const db = group.root?.db;
19151
+ if (!db) return relevantSubcircuitIds;
19152
+ for (const subcircuitId of getDescendantSubcircuitIds(
19153
+ db,
19154
+ group.subcircuit_id
19155
+ )) {
19156
+ relevantSubcircuitIds.add(subcircuitId);
19157
+ }
19158
+ return relevantSubcircuitIds;
19159
+ }
19160
+
19161
+ // lib/components/primitive-components/Group/region-replacement/get-existing-pcb-traces-for-reroute.ts
19162
+ function getExistingPcbTracesForReroute(group) {
19163
+ const db = group.root?.db;
19164
+ if (!db) return [];
19165
+ const relevantSubcircuitIds = getRelevantSubcircuitIdsForReroute(group);
19166
+ return db.pcb_trace.list().filter((trace) => {
19167
+ if (!trace.route || trace.route.length < 2) return false;
19168
+ if (!group.subcircuit_id) return true;
19169
+ return Boolean(
19170
+ trace.subcircuit_id && relevantSubcircuitIds.has(trace.subcircuit_id)
19171
+ );
19172
+ });
19173
+ }
19174
+
19175
+ // lib/components/primitive-components/Group/region-replacement/delete-existing-pcb-traces-replaced-by.ts
19176
+ function addPossibleReplacementSourceTraceId(sourceTraceIds, value) {
19177
+ if (typeof value !== "string" || value.length === 0) return;
19178
+ sourceTraceIds.add(value);
19179
+ const rerouteSuffixIndex = value.indexOf("_reroute_");
19180
+ if (rerouteSuffixIndex > 0) {
19181
+ sourceTraceIds.add(value.slice(0, rerouteSuffixIndex));
19182
+ }
19183
+ }
19184
+ function deleteExistingPcbTracesReplacedBy({
19185
+ group,
19186
+ outputPcbTraces
19187
+ }) {
19188
+ const db = group.root?.db;
19189
+ if (!db) return;
19190
+ const replacementPcbTraceIds = /* @__PURE__ */ new Set();
19191
+ const replacementSourceTraceIds = /* @__PURE__ */ new Set();
19192
+ for (const trace of outputPcbTraces) {
19193
+ if (trace.type !== "pcb_trace") continue;
19194
+ const replacementTrace = trace;
19195
+ replacementPcbTraceIds.add(replacementTrace.pcb_trace_id);
19196
+ addPossibleReplacementSourceTraceId(
19197
+ replacementSourceTraceIds,
19198
+ replacementTrace.source_trace_id
19199
+ );
19200
+ addPossibleReplacementSourceTraceId(
19201
+ replacementSourceTraceIds,
19202
+ replacementTrace.connection_name
19203
+ );
19204
+ addPossibleReplacementSourceTraceId(
19205
+ replacementSourceTraceIds,
19206
+ replacementTrace.rootConnectionName
19207
+ );
19208
+ }
19209
+ if (replacementPcbTraceIds.size === 0 && replacementSourceTraceIds.size === 0) {
19210
+ return;
19211
+ }
19212
+ const tracesToDelete = getExistingPcbTracesForReroute(group).filter(
19213
+ (trace) => replacementPcbTraceIds.has(trace.pcb_trace_id) || Boolean(
19214
+ trace.source_trace_id && replacementSourceTraceIds.has(trace.source_trace_id)
19215
+ )
19216
+ );
19217
+ if (tracesToDelete.length === 0) return;
19218
+ const deletedPcbTraceIds = new Set(
19219
+ tracesToDelete.map((trace) => trace.pcb_trace_id)
19220
+ );
19221
+ for (const via of db.pcb_via.list()) {
19222
+ if (via.pcb_trace_id && deletedPcbTraceIds.has(via.pcb_trace_id)) {
19223
+ db.pcb_via.delete(via.pcb_via_id);
19224
+ }
19225
+ }
19226
+ for (const trace of tracesToDelete) {
19227
+ db.pcb_trace.delete(trace.pcb_trace_id);
19228
+ }
19229
+ }
19230
+
19231
+ // lib/components/primitive-components/Group/region-replacement/get-existing-simplified-pcb-traces-for-reroute.ts
19232
+ function getExistingSimplifiedPcbTracesForReroute(group) {
19233
+ return getExistingPcbTracesForReroute(group).map(
19234
+ convertPcbTraceToSimplifiedPcbTrace
19235
+ );
19236
+ }
19237
+
19007
19238
  // lib/components/primitive-components/Group/split-pcb-traces-on-jumper-segments.ts
19008
19239
  function splitPcbTracesOnJumperSegments(route) {
19009
19240
  const jumperRoutes = route.filter(
@@ -19449,11 +19680,23 @@ var Group6 = class extends NormalComponent3 {
19449
19680
  const debug11 = Debug13("tscircuit:core:_hasTracesToRoute");
19450
19681
  const routingPhasePlans = this._getRoutingPhasePlans();
19451
19682
  let traceCount = 0;
19683
+ let hasReroutePhaseWithRegion = false;
19452
19684
  for (const routingPhasePlan of routingPhasePlans) {
19453
19685
  traceCount += routingPhasePlan.traces.length;
19686
+ hasReroutePhaseWithRegion ||= Boolean(
19687
+ routingPhasePlan.reroute && routingPhasePlan.region
19688
+ );
19454
19689
  }
19455
19690
  debug11(`[${this.getString()}] has ${traceCount} traces to route`);
19456
- return traceCount > 0;
19691
+ if (traceCount > 0) return true;
19692
+ if (hasReroutePhaseWithRegion) {
19693
+ const existingTraceCount = getExistingPcbTracesForReroute(this).length;
19694
+ debug11(
19695
+ `[${this.getString()}] has ${existingTraceCount} existing pcb traces available for reroute`
19696
+ );
19697
+ return existingTraceCount > 0;
19698
+ }
19699
+ return false;
19457
19700
  }
19458
19701
  async _runEffectMakeHttpAutoroutingRequest() {
19459
19702
  const { db } = this.root;
@@ -19598,6 +19841,7 @@ var Group6 = class extends NormalComponent3 {
19598
19841
  const hasPhasedAutorouting = Group_hasPhasedAutorouting(routingPhasePlans);
19599
19842
  const outputTraces = [];
19600
19843
  const outputJumpers = [];
19844
+ const existingRerouteSeedTraces = getExistingSimplifiedPcbTracesForReroute(this);
19601
19845
  for (const routingPhasePlan of routingPhasePlans) {
19602
19846
  const phaseAutorouterConfig = routingPhasePlan.autorouter ? getPresetAutoroutingConfig(
19603
19847
  routingPhasePlan.autorouter,
@@ -19609,7 +19853,7 @@ var Group6 = class extends NormalComponent3 {
19609
19853
  );
19610
19854
  const rerouteOriginalSrj = isReroutePhase ? {
19611
19855
  ...baseSimpleRouteJson,
19612
- traces: outputTraces
19856
+ traces: [...existingRerouteSeedTraces, ...outputTraces]
19613
19857
  } : null;
19614
19858
  if (isReroutePhase && rerouteOriginalSrj) {
19615
19859
  simpleRouteJson = getRerouteSimpleRouteJson(
@@ -19633,7 +19877,7 @@ var Group6 = class extends NormalComponent3 {
19633
19877
  simpleRouteJson,
19634
19878
  routingPhasePlan.drcTolerances
19635
19879
  );
19636
- if (hasPhasedAutorouting && simpleRouteJson.connections.length === 0) {
19880
+ if ((hasPhasedAutorouting || isReroutePhase) && simpleRouteJson.connections.length === 0) {
19637
19881
  continue;
19638
19882
  }
19639
19883
  const phaseIsAutoJumperPreset = routingPhasePlan.autorouter !== void 0 ? this._isAutoJumperAutorouter(phaseAutorouterConfig) : isAutoJumperPreset;
@@ -19864,13 +20108,17 @@ var Group6 = class extends NormalComponent3 {
19864
20108
  subcircuit_id: this.subcircuit_id
19865
20109
  });
19866
20110
  }
20111
+ deleteExistingPcbTracesReplacedBy({
20112
+ group: this,
20113
+ outputPcbTraces: output_pcb_traces
20114
+ });
19867
20115
  for (const pcb_trace of output_pcb_traces) {
19868
20116
  if (pcb_trace.type !== "pcb_trace") continue;
19869
- pcb_trace.subcircuit_id = this.subcircuit_id;
19870
- if (pcb_trace.connection_name) {
19871
- const sourceTraceId = pcb_trace.connection_name;
20117
+ const sourceTraceId = pcb_trace.source_trace_id ?? pcb_trace.connection_name;
20118
+ if (sourceTraceId) {
19872
20119
  pcb_trace.source_trace_id = sourceTraceId;
19873
20120
  }
20121
+ pcb_trace.subcircuit_id ??= (sourceTraceId ? db.source_trace.get(sourceTraceId)?.subcircuit_id : void 0) ?? this.subcircuit_id;
19874
20122
  let segments = splitPcbTracesOnJumperSegments(pcb_trace.route);
19875
20123
  if (segments === null) {
19876
20124
  segments = [pcb_trace.route];
@@ -20645,8 +20893,11 @@ function pcbTraceRouteToPcbPath(route) {
20645
20893
  const firstPoint = route[0];
20646
20894
  const lastPoint = route[route.length - 1];
20647
20895
  return route.slice(1, -1).filter((point6) => {
20648
- const isSameAsFirst = point6.x === firstPoint.x && point6.y === firstPoint.y;
20649
- const isSameAsLast = point6.x === lastPoint.x && point6.y === lastPoint.y;
20896
+ const position = getRoutePointPosition(point6);
20897
+ const firstPosition = getRoutePointPosition(firstPoint);
20898
+ const lastPosition = getRoutePointPosition(lastPoint);
20899
+ const isSameAsFirst = position.x === firstPosition.x && position.y === firstPosition.y;
20900
+ const isSameAsLast = position.x === lastPosition.x && position.y === lastPosition.y;
20650
20901
  return !isSameAsFirst && !isSameAsLast;
20651
20902
  }).map((point6) => {
20652
20903
  if (point6.route_type === "via") {
@@ -20658,7 +20909,8 @@ function pcbTraceRouteToPcbPath(route) {
20658
20909
  toLayer: point6.to_layer
20659
20910
  };
20660
20911
  }
20661
- return { x: point6.x, y: point6.y };
20912
+ const position = getRoutePointPosition(point6);
20913
+ return { x: position.x, y: position.y };
20662
20914
  });
20663
20915
  }
20664
20916
 
@@ -20965,7 +21217,7 @@ import { identity as identity5 } from "transformation-matrix";
20965
21217
  var package_default = {
20966
21218
  name: "@tscircuit/core",
20967
21219
  type: "module",
20968
- version: "0.0.1241",
21220
+ version: "0.0.1243",
20969
21221
  types: "dist/index.d.ts",
20970
21222
  main: "dist/index.js",
20971
21223
  module: "dist/index.js",
@@ -21025,7 +21277,7 @@ var package_default = {
21025
21277
  "bun-match-svg": "0.0.12",
21026
21278
  "calculate-elbow": "^0.0.12",
21027
21279
  "chokidar-cli": "^3.0.0",
21028
- "circuit-json": "^0.0.423",
21280
+ "circuit-json": "^0.0.425",
21029
21281
  "circuit-json-to-bpc": "^0.0.13",
21030
21282
  "circuit-json-to-connectivity-map": "^0.0.23",
21031
21283
  "circuit-json-to-gltf": "^0.0.96",
@@ -21039,7 +21291,7 @@ var package_default = {
21039
21291
  flatbush: "^4.5.0",
21040
21292
  "graphics-debug": "^0.0.89",
21041
21293
  howfat: "^0.3.8",
21042
- "kicad-to-circuit-json": "^0.0.59",
21294
+ "kicad-to-circuit-json": "^0.0.60",
21043
21295
  kicadts: "^0.0.35",
21044
21296
  "live-server": "^1.2.2",
21045
21297
  "looks-same": "^9.0.1",
@@ -21050,6 +21302,7 @@ var package_default = {
21050
21302
  "react-dom": "^19.1.0",
21051
21303
  "schematic-symbols": "^0.0.208",
21052
21304
  spicey: "^0.0.14",
21305
+ "stack-svgs": "^0.0.1",
21053
21306
  "ts-expect": "^1.3.0",
21054
21307
  tsup: "^8.2.4"
21055
21308
  },
@@ -21616,9 +21869,9 @@ var Board = class extends Group6 {
21616
21869
  _computePcbGlobalTransformBeforeLayout() {
21617
21870
  if (this._panelPositionOffset) {
21618
21871
  const parentTransform = this.parent?._computePcbGlobalTransformBeforeLayout?.() ?? { a: 1, b: 0, c: 0, d: 1, e: 0, f: 0 };
21619
- return compose7(
21872
+ return compose6(
21620
21873
  parentTransform,
21621
- translate7(this._panelPositionOffset.x, this._panelPositionOffset.y)
21874
+ translate6(this._panelPositionOffset.x, this._panelPositionOffset.y)
21622
21875
  );
21623
21876
  }
21624
21877
  return super._computePcbGlobalTransformBeforeLayout();
@@ -22136,7 +22389,7 @@ import { distance as distance13 } from "circuit-json";
22136
22389
  // lib/components/normal-components/Subpanel.ts
22137
22390
  import { subpanelProps } from "@tscircuit/props";
22138
22391
  import { distance as distance12 } from "circuit-json";
22139
- import { compose as compose8, identity as identity6, translate as translate8 } from "transformation-matrix";
22392
+ import { compose as compose7, identity as identity6, translate as translate7 } from "transformation-matrix";
22140
22393
 
22141
22394
  // lib/utils/panels/generate-panel-tabs-and-mouse-bites.ts
22142
22395
  import * as Flatten from "@flatten-js/core";
@@ -22597,9 +22850,9 @@ var Subpanel = class _Subpanel extends Group6 {
22597
22850
  _computePcbGlobalTransformBeforeLayout() {
22598
22851
  if (this._panelPositionOffset) {
22599
22852
  const parentTransform = this.parent?._computePcbGlobalTransformBeforeLayout?.() ?? identity6();
22600
- return compose8(
22853
+ return compose7(
22601
22854
  parentTransform,
22602
- translate8(this._panelPositionOffset.x, this._panelPositionOffset.y)
22855
+ translate7(this._panelPositionOffset.x, this._panelPositionOffset.y)
22603
22856
  );
22604
22857
  }
22605
22858
  return super._computePcbGlobalTransformBeforeLayout();
@@ -24088,7 +24341,7 @@ import { netLabelProps } from "@tscircuit/props";
24088
24341
  import {
24089
24342
  applyToPoint as applyToPoint20,
24090
24343
  identity as identity7,
24091
- translate as translate9
24344
+ translate as translate8
24092
24345
  } from "transformation-matrix";
24093
24346
  import { calculateElbow as calculateElbow2 } from "calculate-elbow";
24094
24347
  var NetLabel = class extends PrimitiveComponent2 {
@@ -24141,7 +24394,7 @@ var NetLabel = class extends PrimitiveComponent2 {
24141
24394
  this.parent?.computeSchematicGlobalTransform?.() ?? identity7(),
24142
24395
  { x: 0, y: 0 }
24143
24396
  );
24144
- return translate9(portPos.x - parentCenter.x, portPos.y - parentCenter.y);
24397
+ return translate8(portPos.x - parentCenter.x, portPos.y - parentCenter.y);
24145
24398
  }
24146
24399
  }
24147
24400
  return super.computeSchematicPropsTransform();
@@ -26820,7 +27073,7 @@ var SchematicCell = class extends PrimitiveComponent2 {
26820
27073
 
26821
27074
  // lib/components/primitive-components/Symbol/Symbol.ts
26822
27075
  import { symbolProps } from "@tscircuit/props";
26823
- import { compose as compose9, translate as translate10, scale as scale2 } from "transformation-matrix";
27076
+ import { compose as compose8, translate as translate9, scale } from "transformation-matrix";
26824
27077
  var SymbolComponent = class extends PrimitiveComponent2 {
26825
27078
  isPrimitiveContainer = true;
26826
27079
  schematic_symbol_id;
@@ -26930,10 +27183,10 @@ var SymbolComponent = class extends PrimitiveComponent2 {
26930
27183
  const scaleX = targetWidth !== void 0 && currentWidth > 0 ? targetWidth / currentWidth : 1;
26931
27184
  const scaleY = targetHeight !== void 0 && currentHeight > 0 ? targetHeight / currentHeight : 1;
26932
27185
  const globalPos = this._getGlobalSchematicPositionBeforeLayout();
26933
- this.userCoordinateToResizedSymbolTransformMat = compose9(
26934
- translate10(globalPos.x, globalPos.y),
26935
- scale2(scaleX, scaleY),
26936
- translate10(-currentCenterX, -currentCenterY)
27186
+ this.userCoordinateToResizedSymbolTransformMat = compose8(
27187
+ translate9(globalPos.x, globalPos.y),
27188
+ scale(scaleX, scaleY),
27189
+ translate9(-currentCenterX, -currentCenterY)
26937
27190
  );
26938
27191
  }
26939
27192
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tscircuit/core",
3
3
  "type": "module",
4
- "version": "0.0.1242",
4
+ "version": "0.0.1244",
5
5
  "types": "dist/index.d.ts",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",
@@ -61,7 +61,7 @@
61
61
  "bun-match-svg": "0.0.12",
62
62
  "calculate-elbow": "^0.0.12",
63
63
  "chokidar-cli": "^3.0.0",
64
- "circuit-json": "^0.0.423",
64
+ "circuit-json": "^0.0.425",
65
65
  "circuit-json-to-bpc": "^0.0.13",
66
66
  "circuit-json-to-connectivity-map": "^0.0.23",
67
67
  "circuit-json-to-gltf": "^0.0.96",
@@ -75,7 +75,7 @@
75
75
  "flatbush": "^4.5.0",
76
76
  "graphics-debug": "^0.0.89",
77
77
  "howfat": "^0.3.8",
78
- "kicad-to-circuit-json": "^0.0.59",
78
+ "kicad-to-circuit-json": "^0.0.60",
79
79
  "kicadts": "^0.0.35",
80
80
  "live-server": "^1.2.2",
81
81
  "looks-same": "^9.0.1",
@@ -86,6 +86,7 @@
86
86
  "react-dom": "^19.1.0",
87
87
  "schematic-symbols": "^0.0.208",
88
88
  "spicey": "^0.0.14",
89
+ "stack-svgs": "^0.0.1",
89
90
  "ts-expect": "^1.3.0",
90
91
  "tsup": "^8.2.4"
91
92
  },