@tscircuit/core 0.0.1160 → 0.0.1162

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.
Files changed (3) hide show
  1. package/dist/index.d.ts +61 -52
  2. package/dist/index.js +406 -175
  3. package/package.json +1 -1
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as circuit_json from 'circuit-json';
2
2
  import { PcbTraceError, PcbPlacementError, PcbManualEditConflictWarning, PcbViaClearanceError, LayerRef, AnyCircuitElement, Size, PcbTraceRoutePoint, AnySourceComponent, PcbTrace as PcbTrace$1, PcbVia, SchematicPort, SchematicComponent, RouteHintPoint, CircuitJson } from 'circuit-json';
3
3
  import * as _tscircuit_props from '@tscircuit/props';
4
- import { PlatformConfig, traceProps, subcircuitGroupProps, AutorouterConfig, PcbSx, SupplierPartNumbers, CadModelProp, SchematicPortArrangement, groupProps, boardProps, subcircuitProps, subpanelProps, capacitorProps, chipProps, pinoutProps, diodeProps, fuseProps, jumperProps, interconnectProps, solderjumperProps, ledProps, powerSourceProps, voltageSourceProps, currentSourceProps, resistorProps, constraintProps, fabricationNoteRectProps, fabricationNotePathProps, fabricationNoteTextProps, fabricationNoteDimensionProps, pcbNoteLineProps, pcbNoteRectProps, pcbNoteTextProps, pcbNotePathProps, pcbNoteDimensionProps, footprintProps, breakoutProps, breakoutPointProps, holeProps, pcbKeepoutProps, netLabelProps, cadmodelProps, cadassemblyProps, platedHoleProps, courtyardCircleProps, courtyardOutlineProps, courtyardRectProps, silkscreenCircleProps, silkscreenPathProps, silkscreenRectProps, silkscreenTextProps, silkscreenLineProps, smtPadProps, fiducialProps, traceHintProps, viaProps, copperPourProps, copperTextProps, cutoutProps, batteryProps, pinHeaderProps, resonatorProps, inductorProps, potentiometerProps, pushButtonProps, crystalProps, transistorProps, mosfetProps, opampProps, OpAmpPinLabels, switchProps, SwitchProps, testpointProps, schematicTextProps, schematicLineProps, schematicRectProps, schematicArcProps, schematicCircleProps, schematicPathProps, schematicBoxProps, schematicTableProps, schematicRowProps, schematicCellProps, symbolProps, analogSimulationProps, voltageProbeProps, CapacitorProps, ChipProps, DiodeProps, ResistorProps, ManualEditEvent, ManualEditsFile, ChipConnections, manual_edits_file } from '@tscircuit/props';
4
+ import { PlatformConfig, traceProps, netProps, subcircuitGroupProps, AutorouterConfig, PcbSx, SupplierPartNumbers, CadModelProp, SchematicPortArrangement, groupProps, boardProps, subcircuitProps, subpanelProps, capacitorProps, chipProps, pinoutProps, diodeProps, fuseProps, jumperProps, interconnectProps, solderjumperProps, ledProps, powerSourceProps, voltageSourceProps, currentSourceProps, resistorProps, constraintProps, fabricationNoteRectProps, fabricationNotePathProps, fabricationNoteTextProps, fabricationNoteDimensionProps, pcbNoteLineProps, pcbNoteRectProps, pcbNoteTextProps, pcbNotePathProps, pcbNoteDimensionProps, footprintProps, breakoutProps, breakoutPointProps, holeProps, pcbKeepoutProps, netLabelProps, cadmodelProps, cadassemblyProps, platedHoleProps, courtyardCircleProps, courtyardOutlineProps, courtyardRectProps, silkscreenCircleProps, silkscreenPathProps, silkscreenRectProps, silkscreenTextProps, silkscreenLineProps, smtPadProps, fiducialProps, traceHintProps, viaProps, copperPourProps, copperTextProps, cutoutProps, batteryProps, pinHeaderProps, resonatorProps, inductorProps, potentiometerProps, pushButtonProps, crystalProps, transistorProps, mosfetProps, opampProps, OpAmpPinLabels, switchProps, SwitchProps, testpointProps, schematicTextProps, schematicLineProps, schematicRectProps, schematicArcProps, schematicCircleProps, schematicPathProps, schematicBoxProps, schematicTableProps, schematicRowProps, schematicCellProps, symbolProps, analogSimulationProps, voltageProbeProps, CapacitorProps, ChipProps, DiodeProps, ResistorProps, ManualEditEvent, ManualEditsFile, ChipConnections, manual_edits_file } from '@tscircuit/props';
5
5
  export { kicadFootprintStrings } from '@tscircuit/props';
6
6
  import * as react from 'react';
7
7
  import react__default, { ReactElement, DetailedHTMLProps, SVGProps } from 'react';
@@ -397,57 +397,6 @@ interface IGroup extends PrimitiveComponent {
397
397
  }): void;
398
398
  }
399
399
 
400
- declare const netProps: z.ZodObject<{
401
- name: z.ZodEffects<z.ZodString, string, string>;
402
- }, "strip", z.ZodTypeAny, {
403
- name: string;
404
- }, {
405
- name: string;
406
- }>;
407
- declare class Net extends PrimitiveComponent<typeof netProps> {
408
- source_net_id?: string;
409
- subcircuit_connectivity_map_key: string | null;
410
- get config(): {
411
- componentName: string;
412
- zodProps: z.ZodObject<{
413
- name: z.ZodEffects<z.ZodString, string, string>;
414
- }, "strip", z.ZodTypeAny, {
415
- name: string;
416
- }, {
417
- name: string;
418
- }>;
419
- };
420
- getPortSelector(): string;
421
- doInitialSourceRender(): void;
422
- doInitialSourceParentAttachment(): void;
423
- /**
424
- * Get all ports connected to this net.
425
- *
426
- * TODO currently we're not checking for indirect connections (traces that are
427
- * connected to other traces that are in turn connected to the net)
428
- */
429
- getAllConnectedPorts(): Port[];
430
- /**
431
- * Get all traces that are directly connected to this net, i.e. they list
432
- * this net in their path, from, or to props
433
- */
434
- _getAllDirectlyConnectedTraces(): Trace[];
435
- /**
436
- * Add PCB Traces to connect net islands together. A net island is a set of
437
- * ports that are connected to each other. If a there are multiple net islands
438
- * that means that the net is not fully connected and we need to add traces
439
- * such that the nets are fully connected
440
- *
441
- * Sometimes this phase doesn't find any net islands if the autorouter did
442
- * a good job and connected the islands. In some sense this is a "backup"
443
- * routing phase for autorouters that don't care about connecting nets.
444
- *
445
- * This should only run if the autorouter is sequential-trace
446
- */
447
- doInitialPcbRouteNetIslands(): void;
448
- renderError(message: Parameters<typeof PrimitiveComponent.prototype.renderError>[0]): void;
449
- }
450
-
451
400
  interface TraceI extends PrimitiveComponent<typeof traceProps> {
452
401
  source_trace_id: string | null;
453
402
  subcircuit_connectivity_map_key: string | null;
@@ -1049,8 +998,68 @@ declare class Trace extends PrimitiveComponent<typeof traceProps> implements Tra
1049
998
  doInitialSchematicTraceRender(): void;
1050
999
  }
1051
1000
 
1001
+ declare class Net extends PrimitiveComponent<typeof netProps> {
1002
+ source_net_id?: string;
1003
+ subcircuit_connectivity_map_key: string | null;
1004
+ get config(): {
1005
+ componentName: string;
1006
+ zodProps: zod.ZodObject<{
1007
+ name: zod.ZodString;
1008
+ connectsTo: zod.ZodOptional<zod.ZodUnion<[zod.ZodString, zod.ZodArray<zod.ZodString, "many">]>>;
1009
+ routingPhaseIndex: zod.ZodOptional<zod.ZodNullable<zod.ZodNumber>>;
1010
+ highlightColor: zod.ZodOptional<zod.ZodString>;
1011
+ isPowerNet: zod.ZodOptional<zod.ZodBoolean>;
1012
+ isGroundNet: zod.ZodOptional<zod.ZodBoolean>;
1013
+ }, "strip", zod.ZodTypeAny, {
1014
+ name: string;
1015
+ highlightColor?: string | undefined;
1016
+ connectsTo?: string | string[] | undefined;
1017
+ routingPhaseIndex?: number | null | undefined;
1018
+ isPowerNet?: boolean | undefined;
1019
+ isGroundNet?: boolean | undefined;
1020
+ }, {
1021
+ name: string;
1022
+ highlightColor?: string | undefined;
1023
+ connectsTo?: string | string[] | undefined;
1024
+ routingPhaseIndex?: number | null | undefined;
1025
+ isPowerNet?: boolean | undefined;
1026
+ isGroundNet?: boolean | undefined;
1027
+ }>;
1028
+ };
1029
+ getPortSelector(): string;
1030
+ doInitialSourceRender(): void;
1031
+ doInitialSourceParentAttachment(): void;
1032
+ /**
1033
+ * Get all ports connected to this net.
1034
+ *
1035
+ * TODO currently we're not checking for indirect connections (traces that are
1036
+ * connected to other traces that are in turn connected to the net)
1037
+ */
1038
+ getAllConnectedPorts(): Port[];
1039
+ /**
1040
+ * Get all traces that are directly connected to this net, i.e. they list
1041
+ * this net in their path, from, or to props
1042
+ */
1043
+ _getAllDirectlyConnectedTraces(): Trace[];
1044
+ /**
1045
+ * Add PCB Traces to connect net islands together. A net island is a set of
1046
+ * ports that are connected to each other. If a there are multiple net islands
1047
+ * that means that the net is not fully connected and we need to add traces
1048
+ * such that the nets are fully connected
1049
+ *
1050
+ * Sometimes this phase doesn't find any net islands if the autorouter did
1051
+ * a good job and connected the islands. In some sense this is a "backup"
1052
+ * routing phase for autorouters that don't care about connecting nets.
1053
+ *
1054
+ * This should only run if the autorouter is sequential-trace
1055
+ */
1056
+ doInitialPcbRouteNetIslands(): void;
1057
+ renderError(message: Parameters<typeof PrimitiveComponent.prototype.renderError>[0]): void;
1058
+ }
1059
+
1052
1060
  interface RoutingPhasePlan {
1053
1061
  routingPhaseIndex: number | null;
1062
+ nets: Net[];
1054
1063
  traces: Trace[];
1055
1064
  }
1056
1065
 
package/dist/index.js CHANGED
@@ -288,6 +288,9 @@ var mergeRoutes = (routes) => {
288
288
  return merged;
289
289
  };
290
290
 
291
+ // lib/components/primitive-components/Net.ts
292
+ import { netProps } from "@tscircuit/props";
293
+
291
294
  // lib/components/base-components/PrimitiveComponent/PrimitiveComponent.ts
292
295
  import { selectAll, selectOne } from "css-select";
293
296
  import "debug";
@@ -2113,9 +2116,6 @@ var PrimitiveComponent2 = class extends Renderable {
2113
2116
  }
2114
2117
  };
2115
2118
 
2116
- // lib/components/primitive-components/Net.ts
2117
- import { z as z2 } from "zod";
2118
-
2119
2119
  // lib/utils/pairs.ts
2120
2120
  function pairs(arr) {
2121
2121
  const result = [];
@@ -2127,14 +2127,6 @@ function pairs(arr) {
2127
2127
 
2128
2128
  // lib/components/primitive-components/Net.ts
2129
2129
  import { autoroute } from "@tscircuit/infgrid-ijump-astar";
2130
- var netProps = z2.object({
2131
- name: z2.string().refine(
2132
- (val) => !/[+-]/.test(val),
2133
- (val) => ({
2134
- message: `Net names cannot contain "+" or "-" (component "Net" received "${val}"). Try using underscores instead, e.g. VCC_P`
2135
- })
2136
- )
2137
- });
2138
2130
  var Net = class extends PrimitiveComponent2 {
2139
2131
  source_net_id;
2140
2132
  subcircuit_connectivity_map_key = null;
@@ -4588,7 +4580,7 @@ function Trace_doInitialPcbManualTraceRender(trace) {
4588
4580
  for (const pt of pcbPath) {
4589
4581
  let coordinates;
4590
4582
  let isGlobalPosition = false;
4591
- const isViaPoint = typeof pt !== "string" && pt.via;
4583
+ const isViaPoint2 = typeof pt !== "string" && pt.via;
4592
4584
  let viaFromLayer;
4593
4585
  let viaToLayer;
4594
4586
  if (typeof pt === "string") {
@@ -4630,7 +4622,7 @@ function Trace_doInitialPcbManualTraceRender(trace) {
4630
4622
  }
4631
4623
  }
4632
4624
  const finalCoordinates = isGlobalPosition ? coordinates : applyToPoint2(transform, coordinates);
4633
- if (isViaPoint) {
4625
+ if (isViaPoint2) {
4634
4626
  route.push({
4635
4627
  route_type: "via",
4636
4628
  x: finalCoordinates.x,
@@ -5124,7 +5116,7 @@ var extendCatalogue = (objects) => {
5124
5116
  import { identity as identity3 } from "transformation-matrix";
5125
5117
 
5126
5118
  // lib/components/primitive-components/ErrorPlaceholder.ts
5127
- import { z as z4 } from "zod";
5119
+ import { z as z3 } from "zod";
5128
5120
  var ErrorPlaceholderComponent = class extends PrimitiveComponent2 {
5129
5121
  constructor(props, error) {
5130
5122
  super(props);
@@ -5196,7 +5188,7 @@ var ErrorPlaceholderComponent = class extends PrimitiveComponent2 {
5196
5188
  get config() {
5197
5189
  return {
5198
5190
  componentName: "ErrorPlaceholder",
5199
- zodProps: z4.object({}).passthrough()
5191
+ zodProps: z3.object({}).passthrough()
5200
5192
  };
5201
5193
  }
5202
5194
  doInitialSourceRender() {
@@ -6678,14 +6670,14 @@ var PcbNoteText = class extends PrimitiveComponent2 {
6678
6670
  };
6679
6671
 
6680
6672
  // lib/components/primitive-components/PcbTrace.ts
6681
- import { z as z6 } from "zod";
6673
+ import { z as z5 } from "zod";
6682
6674
  import { pcb_trace_route_point } from "circuit-json";
6683
6675
  import { applyToPoint as applyToPoint11 } from "transformation-matrix";
6684
- var pcbTraceProps = z6.object({
6685
- route: z6.array(pcb_trace_route_point),
6676
+ var pcbTraceProps = z5.object({
6677
+ route: z5.array(pcb_trace_route_point),
6686
6678
  // If this primitive PcbTrace needs to be associated with a source_trace_id
6687
6679
  // it can be added as a prop here. For footprints, it's often not needed.
6688
- source_trace_id: z6.string().optional()
6680
+ source_trace_id: z5.string().optional()
6689
6681
  });
6690
6682
  var PcbTrace = class extends PrimitiveComponent2 {
6691
6683
  pcb_trace_id = null;
@@ -8512,7 +8504,7 @@ var SCHEMATIC_COMPONENT_OUTLINE_STROKE_WIDTH = 0.12;
8512
8504
  // lib/components/primitive-components/Port/Port.ts
8513
8505
  import "schematic-symbols";
8514
8506
  import { applyToPoint as applyToPoint16, compose as compose4, translate as translate3 } from "transformation-matrix";
8515
- import { z as z7 } from "zod";
8507
+ import { z as z6 } from "zod";
8516
8508
 
8517
8509
  // lib/components/primitive-components/Port/getCenterOfPcbPrimitives.ts
8518
8510
  var getCenterOfPcbPrimitives = (pcbPrimitives) => {
@@ -8596,17 +8588,17 @@ var applyPinAttributesToSourcePort = (sourcePortProps, attributes) => {
8596
8588
  };
8597
8589
 
8598
8590
  // lib/components/primitive-components/Port/Port.ts
8599
- var portProps = z7.object({
8600
- name: z7.string().optional(),
8601
- pinNumber: z7.number().optional(),
8602
- schStemLength: z7.number().optional(),
8603
- aliases: z7.array(z7.string()).optional(),
8604
- layer: z7.string().optional(),
8605
- layers: z7.array(z7.string()).optional(),
8606
- schX: z7.number().optional(),
8607
- schY: z7.number().optional(),
8608
- direction: z7.enum(["up", "down", "left", "right"]).optional(),
8609
- connectsTo: z7.union([z7.string(), z7.array(z7.string())]).optional()
8591
+ var portProps = z6.object({
8592
+ name: z6.string().optional(),
8593
+ pinNumber: z6.number().optional(),
8594
+ schStemLength: z6.number().optional(),
8595
+ aliases: z6.array(z6.string()).optional(),
8596
+ layer: z6.string().optional(),
8597
+ layers: z6.array(z6.string()).optional(),
8598
+ schX: z6.number().optional(),
8599
+ schY: z6.number().optional(),
8600
+ direction: z6.enum(["up", "down", "left", "right"]).optional(),
8601
+ connectsTo: z6.union([z6.string(), z6.array(z6.string())]).optional()
8610
8602
  });
8611
8603
  var Port = class extends PrimitiveComponent2 {
8612
8604
  source_port_id = null;
@@ -9573,7 +9565,7 @@ import {
9573
9565
  } from "react";
9574
9566
  import { symbols as symbols2 } from "schematic-symbols";
9575
9567
  import { decomposeTSR as decomposeTSR8 } from "transformation-matrix";
9576
- import { z as z9 } from "zod";
9568
+ import { z as z8 } from "zod";
9577
9569
 
9578
9570
  // lib/components/primitive-components/CadAssembly.ts
9579
9571
  import { cadassemblyProps } from "@tscircuit/props";
@@ -9589,7 +9581,7 @@ var CadAssembly = class extends PrimitiveComponent2 {
9589
9581
 
9590
9582
  // lib/components/primitive-components/CadModel.ts
9591
9583
  import { cadmodelProps, point3 } from "@tscircuit/props";
9592
- import { z as z8 } from "zod";
9584
+ import { z as z7 } from "zod";
9593
9585
  import { distance as distance7 } from "circuit-json";
9594
9586
  import { decomposeTSR as decomposeTSR7 } from "transformation-matrix";
9595
9587
 
@@ -9631,8 +9623,8 @@ var constructAssetUrl = (targetUrl, baseUrl) => {
9631
9623
  };
9632
9624
 
9633
9625
  // lib/components/primitive-components/CadModel.ts
9634
- var rotation = z8.union([z8.number(), z8.string()]);
9635
- var rotation3 = z8.object({ x: rotation, y: rotation, z: rotation });
9626
+ var rotation = z7.union([z7.number(), z7.string()]);
9627
+ var rotation3 = z7.object({ x: rotation, y: rotation, z: rotation });
9636
9628
  var CadModel = class extends PrimitiveComponent2 {
9637
9629
  get config() {
9638
9630
  return {
@@ -10524,9 +10516,42 @@ var shouldCheckPortForMissingTrace = (component, port) => {
10524
10516
  return true;
10525
10517
  };
10526
10518
 
10519
+ // lib/components/base-components/NormalComponent/utils/getLogicalPortsFromPortHintGroups.ts
10520
+ function getLogicalPortsFromPortHintGroups(portHintGroups, opts) {
10521
+ let implicitPinNumber = 1;
10522
+ const portsByPinNumber = /* @__PURE__ */ new Map();
10523
+ for (const portHintGroup of portHintGroups) {
10524
+ const filteredPortHints = portHintGroup.hints.filter(
10525
+ (hint) => hint && hint.trim() !== ""
10526
+ );
10527
+ if (filteredPortHints.length === 0) continue;
10528
+ let portHintsList = filteredPortHints;
10529
+ const hasPinIdentifier = portHintsList.some(
10530
+ (hint) => hint.startsWith("pin") || /^(?:pin)?\d+$/.test(hint)
10531
+ );
10532
+ if (!hasPinIdentifier) {
10533
+ portHintsList = [...portHintsList, `pin${implicitPinNumber}`];
10534
+ }
10535
+ implicitPinNumber++;
10536
+ const newPort = getPortFromHints(portHintsList, opts);
10537
+ if (!newPort) continue;
10538
+ newPort.originDescription = portHintGroup.originDescription;
10539
+ const pinNumber = newPort._parsedProps.pinNumber;
10540
+ if (pinNumber === void 0) continue;
10541
+ const existingPort = portsByPinNumber.get(pinNumber);
10542
+ if (!existingPort) {
10543
+ portsByPinNumber.set(pinNumber, newPort);
10544
+ continue;
10545
+ }
10546
+ const mergedAliases = newPort.getNameAndAliases().filter((alias) => !existingPort.getNameAndAliases().includes(alias));
10547
+ existingPort.externallyAddedAliases.push(...mergedAliases);
10548
+ }
10549
+ return Array.from(portsByPinNumber.values());
10550
+ }
10551
+
10527
10552
  // lib/components/base-components/NormalComponent/NormalComponent.ts
10528
10553
  var debug3 = Debug5("tscircuit:core");
10529
- var rotation32 = z9.object({
10554
+ var rotation32 = z8.object({
10530
10555
  x: rotation2,
10531
10556
  y: rotation2,
10532
10557
  z: rotation2
@@ -11372,41 +11397,31 @@ var NormalComponent3 = class extends PrimitiveComponent2 {
11372
11397
  this._queueInvalidFootprintPropMessage(footprint, error);
11373
11398
  return [];
11374
11399
  }
11375
- const newPorts2 = [];
11376
- for (const elm of fpCircuitJson) {
11377
- if ("port_hints" in elm && elm.port_hints) {
11378
- const newPort = getPortFromHints(elm.port_hints, opts);
11379
- if (!newPort) continue;
11380
- newPort.originDescription = `footprint:string:${footprint}:port_hints[0]:${elm.port_hints[0]}`;
11381
- newPorts2.push(newPort);
11382
- }
11383
- }
11384
- return newPorts2;
11400
+ return getLogicalPortsFromPortHintGroups(
11401
+ fpCircuitJson.flatMap(
11402
+ (elm) => "port_hints" in elm && elm.port_hints ? [
11403
+ {
11404
+ hints: elm.port_hints,
11405
+ originDescription: `footprint:string:${footprint}:port_hints[0]:${elm.port_hints[0]}`
11406
+ }
11407
+ ] : []
11408
+ ),
11409
+ opts
11410
+ );
11385
11411
  }
11386
11412
  if (!isValidElement(footprint) && footprint && footprint.componentName === "Footprint") {
11387
11413
  const fp2 = footprint;
11388
- let pinNumber = 1;
11389
- const newPorts2 = [];
11390
- for (const fpChild of fp2.children) {
11391
- if (!fpChild.props.portHints) continue;
11392
- const filteredPortHints = fpChild.props.portHints.filter(
11393
- (hint) => hint && hint.trim() !== ""
11394
- );
11395
- if (filteredPortHints.length === 0) continue;
11396
- let portHintsList = filteredPortHints;
11397
- const hasPinIdentifier = portHintsList.some(
11398
- (hint) => hint.startsWith("pin") || /^(?:pin)?\d+$/.test(hint)
11399
- );
11400
- if (!hasPinIdentifier) {
11401
- portHintsList = [...portHintsList, `pin${pinNumber}`];
11402
- }
11403
- pinNumber++;
11404
- const newPort = getPortFromHints(portHintsList);
11405
- if (!newPort) continue;
11406
- newPort.originDescription = `footprint:${footprint}`;
11407
- newPorts2.push(newPort);
11408
- }
11409
- return newPorts2;
11414
+ return getLogicalPortsFromPortHintGroups(
11415
+ fp2.children.flatMap(
11416
+ (fpChild) => fpChild.props.portHints ? [
11417
+ {
11418
+ hints: fpChild.props.portHints,
11419
+ originDescription: `footprint:${footprint}`
11420
+ }
11421
+ ] : []
11422
+ ),
11423
+ opts
11424
+ );
11410
11425
  }
11411
11426
  const newPorts = [];
11412
11427
  if (!footprint) {
@@ -13496,8 +13511,18 @@ var getSimpleRouteJsonFromCircuitJson = ({
13496
13511
  const connectionsFromNets = [];
13497
13512
  for (const net of source_nets) {
13498
13513
  const connectedSourceTraces = db.source_trace.list().filter((st) => st.connected_source_net_ids?.includes(net.source_net_id));
13514
+ let nominalTraceWidthFromConnectedTraces;
13515
+ for (const sourceTrace of connectedSourceTraces) {
13516
+ if (sourceTrace.min_trace_thickness === void 0) continue;
13517
+ nominalTraceWidthFromConnectedTraces = Math.max(
13518
+ nominalTraceWidthFromConnectedTraces ?? 0,
13519
+ sourceTrace.min_trace_thickness
13520
+ );
13521
+ }
13499
13522
  connectionsFromNets.push({
13500
13523
  name: net.source_net_id ?? connMap.getNetConnectedToId(net.source_net_id),
13524
+ nominalTraceWidth: nominalTraceWidthFromConnectedTraces,
13525
+ width: nominalTraceWidthFromConnectedTraces,
13501
13526
  pointsToConnect: connectedSourceTraces.flatMap((st) => {
13502
13527
  const pcb_ports = db.pcb_port.list().filter(
13503
13528
  (p) => st.connected_source_port_ids.includes(p.source_port_id)
@@ -17329,15 +17354,201 @@ function Group_doInitialSourceAddConnectivityMapKey(group) {
17329
17354
  }
17330
17355
 
17331
17356
  // lib/components/primitive-components/Group/Group_getRoutingPhasePlans.ts
17357
+ function getPhaseSortValue(routingPhaseIndex) {
17358
+ return routingPhaseIndex === null ? Number.POSITIVE_INFINITY : routingPhaseIndex;
17359
+ }
17360
+ function compareRoutingPhasePlans(a, b) {
17361
+ return getPhaseSortValue(a.routingPhaseIndex) - getPhaseSortValue(b.routingPhaseIndex);
17362
+ }
17363
+ function getOrCreateRoutingPhasePlan(plansByPhaseIndex, routingPhaseIndex) {
17364
+ let plan = plansByPhaseIndex.get(routingPhaseIndex);
17365
+ if (!plan) {
17366
+ plan = { routingPhaseIndex, nets: [], traces: [] };
17367
+ plansByPhaseIndex.set(routingPhaseIndex, plan);
17368
+ }
17369
+ return plan;
17370
+ }
17371
+ function getNetRoutingPhaseIndex(net) {
17372
+ return net.props.routingPhaseIndex ?? null;
17373
+ }
17374
+ function getTraceRoutingPhaseIndex(trace) {
17375
+ const traceRoutingPhaseIndex = trace.props.routingPhaseIndex;
17376
+ if (traceRoutingPhaseIndex !== void 0) return traceRoutingPhaseIndex;
17377
+ let routingPhaseIndex = null;
17378
+ const connectedNets = trace._findConnectedNets().nets;
17379
+ for (const net of connectedNets) {
17380
+ const netRoutingPhaseIndex = net.props.routingPhaseIndex;
17381
+ if (typeof netRoutingPhaseIndex === "number") {
17382
+ if (routingPhaseIndex === null || netRoutingPhaseIndex < routingPhaseIndex) {
17383
+ routingPhaseIndex = netRoutingPhaseIndex;
17384
+ }
17385
+ }
17386
+ }
17387
+ return routingPhaseIndex;
17388
+ }
17332
17389
  function Group_getRoutingPhasePlans(group) {
17333
17390
  const traces = group.selectAll("trace");
17334
- if (traces.length === 0) return [];
17335
- return [
17336
- {
17337
- routingPhaseIndex: null,
17338
- traces
17391
+ const nets = group.selectAll("net");
17392
+ if (traces.length === 0 && nets.length === 0) return [];
17393
+ const plansByPhaseIndex = /* @__PURE__ */ new Map();
17394
+ for (const net of nets) {
17395
+ const routingPhaseIndex = getNetRoutingPhaseIndex(net);
17396
+ getOrCreateRoutingPhasePlan(plansByPhaseIndex, routingPhaseIndex).nets.push(
17397
+ net
17398
+ );
17399
+ }
17400
+ for (const trace of traces) {
17401
+ const routingPhaseIndex = getTraceRoutingPhaseIndex(trace);
17402
+ getOrCreateRoutingPhasePlan(
17403
+ plansByPhaseIndex,
17404
+ routingPhaseIndex
17405
+ ).traces.push(trace);
17406
+ }
17407
+ return Array.from(plansByPhaseIndex.values()).sort(compareRoutingPhasePlans);
17408
+ }
17409
+
17410
+ // lib/components/primitive-components/Group/Group_phasedAutoroutingUtils.ts
17411
+ function isWirePoint(point6) {
17412
+ return point6.route_type === "wire";
17413
+ }
17414
+ function isViaPoint(point6) {
17415
+ return point6.route_type === "via";
17416
+ }
17417
+ function isJumperPoint(point6) {
17418
+ return point6.route_type === "jumper";
17419
+ }
17420
+ function getTraceConnectionName(trace) {
17421
+ return trace.connection_name ?? trace.pcb_trace_id;
17422
+ }
17423
+ function getWireWidth(start, end) {
17424
+ if (isWirePoint(start)) return start.width;
17425
+ if (isWirePoint(end)) return end.width;
17426
+ return 0.1;
17427
+ }
17428
+ function getSegmentLayer(start, end) {
17429
+ if (isWirePoint(start)) return start.layer;
17430
+ if (isWirePoint(end)) return end.layer;
17431
+ if (isJumperPoint(start)) return start.layer;
17432
+ if (isJumperPoint(end)) return end.layer;
17433
+ return null;
17434
+ }
17435
+ function getRoutePointX(point6) {
17436
+ if (isJumperPoint(point6)) return null;
17437
+ return point6.x;
17438
+ }
17439
+ function getRoutePointY(point6) {
17440
+ if (isJumperPoint(point6)) return null;
17441
+ return point6.y;
17442
+ }
17443
+ function createWireObstacle(start, end, connectedTo, obstacleIndex) {
17444
+ const startX = getRoutePointX(start);
17445
+ const startY = getRoutePointY(start);
17446
+ const endX = getRoutePointX(end);
17447
+ const endY = getRoutePointY(end);
17448
+ const layer = getSegmentLayer(start, end);
17449
+ if (startX === null || startY === null) return null;
17450
+ if (endX === null || endY === null) return null;
17451
+ if (!layer) return null;
17452
+ const width = getWireWidth(start, end);
17453
+ const dx = Math.abs(startX - endX);
17454
+ const dy = Math.abs(startY - endY);
17455
+ return {
17456
+ obstacleId: `${connectedTo}_phase_obstacle_${obstacleIndex}`,
17457
+ type: "rect",
17458
+ layers: [layer],
17459
+ center: {
17460
+ x: (startX + endX) / 2,
17461
+ y: (startY + endY) / 2
17462
+ },
17463
+ width: dx + width,
17464
+ height: dy + width,
17465
+ connectedTo: [connectedTo]
17466
+ };
17467
+ }
17468
+ function createJumperObstacle(point6, connectedTo, obstacleIndex) {
17469
+ const dx = Math.abs(point6.start.x - point6.end.x);
17470
+ const dy = Math.abs(point6.start.y - point6.end.y);
17471
+ const width = 0.6;
17472
+ return {
17473
+ obstacleId: `${connectedTo}_phase_jumper_obstacle_${obstacleIndex}`,
17474
+ type: "rect",
17475
+ layers: [point6.layer],
17476
+ center: {
17477
+ x: (point6.start.x + point6.end.x) / 2,
17478
+ y: (point6.start.y + point6.end.y) / 2
17479
+ },
17480
+ width: dx + width,
17481
+ height: dy + width,
17482
+ connectedTo: [connectedTo]
17483
+ };
17484
+ }
17485
+ function createViaObstacle(point6, connectedTo, obstacleIndex) {
17486
+ return {
17487
+ obstacleId: `${connectedTo}_phase_via_obstacle_${obstacleIndex}`,
17488
+ type: "rect",
17489
+ layers: [point6.from_layer, point6.to_layer],
17490
+ center: { x: point6.x, y: point6.y },
17491
+ width: 0.6,
17492
+ height: 0.6,
17493
+ connectedTo: [connectedTo]
17494
+ };
17495
+ }
17496
+ function addTraceObstacles(obstacles, trace) {
17497
+ const connectedTo = getTraceConnectionName(trace);
17498
+ for (let routeIndex = 0; routeIndex < trace.route.length; routeIndex++) {
17499
+ const routePoint = trace.route[routeIndex];
17500
+ if (isViaPoint(routePoint)) {
17501
+ obstacles.push(createViaObstacle(routePoint, connectedTo, routeIndex));
17502
+ } else if (isJumperPoint(routePoint)) {
17503
+ obstacles.push(createJumperObstacle(routePoint, connectedTo, routeIndex));
17504
+ }
17505
+ if (routeIndex === trace.route.length - 1) continue;
17506
+ const nextPoint = trace.route[routeIndex + 1];
17507
+ const obstacle = createWireObstacle(
17508
+ routePoint,
17509
+ nextPoint,
17510
+ connectedTo,
17511
+ routeIndex
17512
+ );
17513
+ if (obstacle) obstacles.push(obstacle);
17514
+ }
17515
+ }
17516
+ function connectionIsInRoutingPhase(connection, phasePlan) {
17517
+ for (const trace of phasePlan.traces) {
17518
+ if (!trace.source_trace_id) continue;
17519
+ if (connection.source_trace_id === trace.source_trace_id) return true;
17520
+ if (connection.name === trace.source_trace_id) return true;
17521
+ }
17522
+ for (const net of phasePlan.nets) {
17523
+ if (!net.source_net_id) continue;
17524
+ if (connection.name === net.source_net_id) return true;
17525
+ }
17526
+ return false;
17527
+ }
17528
+ function Group_hasPhasedAutorouting(routingPhasePlans) {
17529
+ for (const plan of routingPhasePlans) {
17530
+ if (plan.routingPhaseIndex !== null) return true;
17531
+ }
17532
+ return false;
17533
+ }
17534
+ function Group_filterSimpleRouteJsonForPhase(simpleRouteJson, phasePlan) {
17535
+ const connections = [];
17536
+ for (const connection of simpleRouteJson.connections) {
17537
+ if (connectionIsInRoutingPhase(connection, phasePlan)) {
17538
+ connections.push(connection);
17339
17539
  }
17340
- ];
17540
+ }
17541
+ return {
17542
+ ...simpleRouteJson,
17543
+ connections
17544
+ };
17545
+ }
17546
+ function Group_getObstaclesFromRoutedTraces(traces) {
17547
+ const obstacles = [];
17548
+ for (const trace of traces) {
17549
+ addTraceObstacles(obstacles, trace);
17550
+ }
17551
+ return obstacles;
17341
17552
  }
17342
17553
 
17343
17554
  // lib/components/primitive-components/Group/add-port-ids-to-traces-at-jumper-pads.ts
@@ -18029,123 +18240,143 @@ var Group6 = class extends NormalComponent3 {
18029
18240
  const isLaserPrefabPreset = this._isLaserPrefabAutorouter(autorouterConfig);
18030
18241
  const isAutoJumperPreset = this._isAutoJumperAutorouter(autorouterConfig);
18031
18242
  const isSingleLayerBoard = this._getSubcircuitLayerCount() === 1;
18032
- const { simpleRouteJson } = getSimpleRouteJsonFromCircuitJson({
18243
+ const { simpleRouteJson: baseSimpleRouteJson } = getSimpleRouteJsonFromCircuitJson({
18033
18244
  db,
18034
18245
  minTraceWidth: this.props.autorouter?.minTraceWidth ?? 0.15,
18035
18246
  nominalTraceWidth: this.props.nominalTraceWidth,
18036
18247
  subcircuit_id: this.subcircuit_id,
18037
18248
  subcircuitComponent: this
18038
18249
  });
18039
- if (isAutoJumperPreset) {
18040
- simpleRouteJson.allowJumpers = true;
18041
- if (autorouterConfig.availableJumperTypes) {
18042
- simpleRouteJson.availableJumperTypes = autorouterConfig.availableJumperTypes;
18250
+ const routingPhasePlans = this._getRoutingPhasePlans();
18251
+ const hasPhasedAutorouting = Group_hasPhasedAutorouting(routingPhasePlans);
18252
+ const outputTraces = [];
18253
+ const outputJumpers = [];
18254
+ for (const routingPhasePlan of routingPhasePlans) {
18255
+ let simpleRouteJson = baseSimpleRouteJson;
18256
+ if (hasPhasedAutorouting) {
18257
+ simpleRouteJson = Group_filterSimpleRouteJsonForPhase(
18258
+ baseSimpleRouteJson,
18259
+ routingPhasePlan
18260
+ );
18261
+ simpleRouteJson.obstacles = [
18262
+ ...simpleRouteJson.obstacles,
18263
+ ...Group_getObstaclesFromRoutedTraces(outputTraces)
18264
+ ];
18043
18265
  }
18044
- }
18045
- if (debug11.enabled) {
18046
- ;
18047
- global.debugOutputArray?.push({
18048
- name: `simpleroutejson-${this.props.name}.json`,
18049
- obj: simpleRouteJson
18050
- });
18051
- }
18052
- if (debug11.enabled) {
18053
- const graphicsObject = convertSrjToGraphicsObject(
18054
- simpleRouteJson
18055
- );
18056
- graphicsObject.title = `autorouting-${this.props.name}`;
18057
- global.debugGraphics?.push(graphicsObject);
18058
- }
18059
- this.root?.emit("autorouting:start", {
18060
- subcircuit_id: this.subcircuit_id,
18061
- componentDisplayName: this.getString(),
18062
- simpleRouteJson
18063
- });
18064
- let autorouter;
18065
- if (autorouterConfig.algorithmFn) {
18066
- autorouter = await autorouterConfig.algorithmFn(simpleRouteJson);
18067
- } else {
18068
- const autorouterVersion2 = this.props.autorouterVersion;
18069
- const effortLevel = this.props.autorouterEffortLevel;
18070
- const effort = effortLevel ? Number.parseInt(effortLevel.replace("x", ""), 10) : void 0;
18071
- autorouter = new TscircuitAutorouter(simpleRouteJson, {
18072
- // Optional configuration parameters
18073
- capacityDepth: this.props.autorouter?.capacityDepth,
18074
- targetMinCapacity: this.props.autorouter?.targetMinCapacity,
18075
- useAssignableSolver: isLaserPrefabPreset || isSingleLayerBoard,
18076
- useAutoJumperSolver: isAutoJumperPreset,
18077
- autorouterVersion: autorouterVersion2,
18078
- effort,
18079
- onSolverStarted: ({ solverName, solverParams }) => this.root?.emit("solver:started", {
18080
- type: "solver:started",
18081
- solverName,
18082
- solverParams,
18083
- componentName: this.getString()
18084
- })
18085
- });
18086
- }
18087
- const routingPromise = new Promise(
18088
- (resolve, reject) => {
18089
- autorouter.on("complete", (event) => {
18090
- debug11(`[${this.getString()}] local autorouting complete`);
18091
- resolve(event.traces);
18092
- });
18093
- autorouter.on("error", (event) => {
18094
- debug11(
18095
- `[${this.getString()}] local autorouting error: ${event.error.message}`
18096
- );
18097
- reject(event.error);
18266
+ if (hasPhasedAutorouting && simpleRouteJson.connections.length === 0) {
18267
+ continue;
18268
+ }
18269
+ if (isAutoJumperPreset) {
18270
+ simpleRouteJson.allowJumpers = true;
18271
+ if (autorouterConfig.availableJumperTypes) {
18272
+ simpleRouteJson.availableJumperTypes = autorouterConfig.availableJumperTypes;
18273
+ }
18274
+ }
18275
+ if (debug11.enabled) {
18276
+ ;
18277
+ global.debugOutputArray?.push({
18278
+ name: `simpleroutejson-${this.props.name}.json`,
18279
+ obj: simpleRouteJson
18098
18280
  });
18099
18281
  }
18100
- );
18101
- autorouter.on("progress", (event) => {
18102
- this.root?.emit("autorouting:progress", {
18282
+ if (debug11.enabled) {
18283
+ const graphicsObject = convertSrjToGraphicsObject(
18284
+ simpleRouteJson
18285
+ );
18286
+ graphicsObject.title = `autorouting-${this.props.name}`;
18287
+ global.debugGraphics?.push(graphicsObject);
18288
+ }
18289
+ this.root?.emit("autorouting:start", {
18103
18290
  subcircuit_id: this.subcircuit_id,
18104
18291
  componentDisplayName: this.getString(),
18105
- ...event
18292
+ simpleRouteJson
18106
18293
  });
18107
- });
18108
- autorouter.start();
18109
- try {
18110
- const traces = await routingPromise;
18111
- if (autorouter.getConnectedOffboardObstacles) {
18112
- const connectedOffboardObstacles = autorouter.getConnectedOffboardObstacles();
18113
- createSourceTracesFromOffboardConnections({
18114
- db,
18115
- connectedOffboardObstacles,
18116
- simpleRouteJson,
18117
- subcircuit_id: this.subcircuit_id
18294
+ let autorouter;
18295
+ if (autorouterConfig.algorithmFn) {
18296
+ autorouter = await autorouterConfig.algorithmFn(simpleRouteJson);
18297
+ } else {
18298
+ const autorouterVersion2 = this.props.autorouterVersion;
18299
+ const effortLevel = this.props.autorouterEffortLevel;
18300
+ const effort = effortLevel ? Number.parseInt(effortLevel.replace("x", ""), 10) : void 0;
18301
+ autorouter = new TscircuitAutorouter(simpleRouteJson, {
18302
+ // Optional configuration parameters
18303
+ capacityDepth: this.props.autorouter?.capacityDepth,
18304
+ targetMinCapacity: this.props.autorouter?.targetMinCapacity,
18305
+ useAssignableSolver: isLaserPrefabPreset || isSingleLayerBoard,
18306
+ useAutoJumperSolver: isAutoJumperPreset,
18307
+ autorouterVersion: autorouterVersion2,
18308
+ effort,
18309
+ onSolverStarted: ({ solverName, solverParams }) => this.root?.emit("solver:started", {
18310
+ type: "solver:started",
18311
+ solverName,
18312
+ solverParams,
18313
+ componentName: this.getString()
18314
+ })
18118
18315
  });
18119
18316
  }
18120
- let outputJumpers = [];
18121
- const solver = autorouter.solver;
18122
- if (solver?.getOutputJumpers) {
18123
- outputJumpers = solver.getOutputJumpers() || [];
18124
- }
18125
- this._asyncAutoroutingResult = {
18126
- output_pcb_traces: traces,
18127
- output_jumpers: outputJumpers
18128
- };
18129
- this._markDirty("PcbTraceRender");
18130
- } catch (error) {
18131
- const { db: db2 } = this.root;
18132
- db2.pcb_autorouting_error.insert({
18133
- pcb_error_id: `pcb_autorouter_error_subcircuit_${this.subcircuit_id}`,
18134
- error_type: "pcb_autorouting_error",
18135
- message: error instanceof Error ? error.message : String(error)
18317
+ const routingPromise = new Promise(
18318
+ (resolve, reject) => {
18319
+ autorouter.on("complete", (event) => {
18320
+ debug11(`[${this.getString()}] local autorouting complete`);
18321
+ resolve(event.traces);
18322
+ });
18323
+ autorouter.on("error", (event) => {
18324
+ debug11(
18325
+ `[${this.getString()}] local autorouting error: ${event.error.message}`
18326
+ );
18327
+ reject(event.error);
18328
+ });
18329
+ }
18330
+ );
18331
+ autorouter.on("progress", (event) => {
18332
+ this.root?.emit("autorouting:progress", {
18333
+ subcircuit_id: this.subcircuit_id,
18334
+ componentDisplayName: this.getString(),
18335
+ ...event
18336
+ });
18136
18337
  });
18137
- this.root?.emit("autorouting:error", {
18138
- subcircuit_id: this.subcircuit_id,
18139
- componentDisplayName: this.getString(),
18140
- error: {
18338
+ autorouter.start();
18339
+ try {
18340
+ const traces = await routingPromise;
18341
+ if (autorouter.getConnectedOffboardObstacles) {
18342
+ const connectedOffboardObstacles = autorouter.getConnectedOffboardObstacles();
18343
+ createSourceTracesFromOffboardConnections({
18344
+ db,
18345
+ connectedOffboardObstacles,
18346
+ simpleRouteJson,
18347
+ subcircuit_id: this.subcircuit_id
18348
+ });
18349
+ }
18350
+ const solver = autorouter.solver;
18351
+ if (solver?.getOutputJumpers) {
18352
+ outputJumpers.push(...solver.getOutputJumpers() || []);
18353
+ }
18354
+ outputTraces.push(...traces);
18355
+ } catch (error) {
18356
+ const { db: db2 } = this.root;
18357
+ db2.pcb_autorouting_error.insert({
18358
+ pcb_error_id: `pcb_autorouter_error_subcircuit_${this.subcircuit_id}`,
18359
+ error_type: "pcb_autorouting_error",
18141
18360
  message: error instanceof Error ? error.message : String(error)
18142
- },
18143
- simpleRouteJson
18144
- });
18145
- throw error;
18146
- } finally {
18147
- autorouter.stop();
18361
+ });
18362
+ this.root?.emit("autorouting:error", {
18363
+ subcircuit_id: this.subcircuit_id,
18364
+ componentDisplayName: this.getString(),
18365
+ error: {
18366
+ message: error instanceof Error ? error.message : String(error)
18367
+ },
18368
+ simpleRouteJson
18369
+ });
18370
+ throw error;
18371
+ } finally {
18372
+ autorouter.stop();
18373
+ }
18148
18374
  }
18375
+ this._asyncAutoroutingResult = {
18376
+ output_pcb_traces: outputTraces,
18377
+ output_jumpers: outputJumpers
18378
+ };
18379
+ this._markDirty("PcbTraceRender");
18149
18380
  }
18150
18381
  _startAsyncAutorouting() {
18151
18382
  if (this._hasStartedAsyncAutorouting) return;
@@ -19322,7 +19553,7 @@ import { identity as identity5 } from "transformation-matrix";
19322
19553
  var package_default = {
19323
19554
  name: "@tscircuit/core",
19324
19555
  type: "module",
19325
- version: "0.0.1159",
19556
+ version: "0.0.1161",
19326
19557
  types: "dist/index.d.ts",
19327
19558
  main: "dist/index.js",
19328
19559
  module: "dist/index.js",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tscircuit/core",
3
3
  "type": "module",
4
- "version": "0.0.1160",
4
+ "version": "0.0.1162",
5
5
  "types": "dist/index.d.ts",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",