@tscircuit/core 0.0.1883 → 0.0.1884

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
@@ -2,7 +2,7 @@ import * as circuit_json from 'circuit-json';
2
2
  import { PcbGroup, PcbTraceError, PcbPlacementError, PcbManualEditConflictWarning, PcbViaClearanceError, PcbVia as PcbVia$1, LayerRef, AnyCircuitElement, Size, PcbTrace as PcbTrace$1, PcbTraceRoutePoint, AnySourceComponent, PcbComponent, SchematicPort, SchematicComponent, SimulationVoltageSource, SimulationCurrentSource, PcbSilkscreenGraphic, RouteHintPoint, PcbBoard, SchematicSheet as SchematicSheet$1, SchematicGraphic as SchematicGraphic$1, SimulationExperiment, SimulationParameterSweep, CircuitJson } from 'circuit-json';
3
3
  import * as _tscircuit_props from '@tscircuit/props';
4
4
  import { PlatformConfig, traceProps, netProps, AutoroutingPhaseProps, AutorouterProp, subcircuitGroupProps, AutorouterConfig, PcbSx, portProps, PinAttributeMap, SupplierPartNumbers, CadModelProp, SchematicPortArrangement, groupProps, platedHoleProps, BoardOutlinePoint, boardProps, subcircuitProps, subpanelProps, capacitorProps, antennaProps, chipProps, pinoutProps, diodeProps, fuseProps, jumperProps, interconnectProps, solderjumperProps, ledProps, powerSourceProps, voltageSourceProps, currentSourceProps, ammeterProps, resistorProps, constraintProps, drcCheckProps, autoroutingPhaseProps, fabricationNoteRectProps, fabricationNotePathProps, fabricationNoteTextProps, fabricationNoteDimensionProps, pcbNoteLineProps, pcbNoteRectProps, pcbNoteTextProps, pcbNotePathProps, pcbNoteDimensionProps, footprintProps, breakoutProps, breakoutPointProps, holeProps, pcbKeepoutProps, netLabelProps, cadmodelProps, cadassemblyProps, courtyardCircleProps, courtyardOutlineProps, courtyardRectProps, silkscreenCircleProps, silkscreenPathProps, silkscreenRectProps, silkscreenTextProps, silkscreenLineProps, silkscreenGraphicProps, smtPadProps, fiducialProps, busProps, differentialPairProps, traceHintProps, viaProps, copperPourProps, copperTextProps, cutoutProps, assemblyDeviceProps, enclosureCutoutApertureProps, enclosureFdmBoxProps, batteryProps, pinHeaderProps, resonatorProps, inductorProps, potentiometerProps, pushButtonProps, crystalProps, CrystalPinLabels, transistorProps, mosfetProps, opampProps, OpAmpPinLabels, switchProps, SwitchProps, testpointProps, schematicTextProps, schematicLineProps, schematicRectProps, schematicArcProps, schematicCircleProps, schematicPathProps, schematicBoxProps, schematicSymbolProps, schematicSectionProps, schematicSheetProps, schematicGraphicProps, schematicTableProps, schematicRowProps, schematicCellProps, symbolProps, analogSimulationProps, analogTransientSimulationProps, analogDcOperatingPointSimulationProps, analogDcSweepSimulationProps, analogAcSweepSimulationProps, analogSweepParameterProps, voltageProbeProps, spicemodelProps, AnalogTransientSimulationProps, AnalogDcSweepSimulationProps, AnalogAcSweepSimulationProps, AnalogSweepParameterProps, AssemblyDevicePropsInput, EnclosureCutoutApertureProps, EnclosureFdmBoxProps, CapacitorProps, ChipProps, DiodeProps, ResistorProps, ManualEditEvent, ManualEditsFile, ChipConnections, manual_edits_file } from '@tscircuit/props';
5
- export { kicadFootprintStrings } from '@tscircuit/props';
5
+ export { FanoutTracePath, fanoutTracePath, kicadFootprintStrings } from '@tscircuit/props';
6
6
  import * as react from 'react';
7
7
  import react__default, { ReactElement, ReactNode } from 'react';
8
8
  export { createElement } from 'react';
@@ -11,7 +11,7 @@ import { z, ZodType } from 'zod';
11
11
  import { symbols, SchSymbol, BaseSymbolName } from 'schematic-symbols';
12
12
  import { CircuitJsonUtilObjects } from '@tscircuit/circuit-json-util';
13
13
  import { Matrix } from 'transformation-matrix';
14
- import { AutoroutingPipelineSolver, AssignableAutoroutingPipeline2, AssignableAutoroutingPipeline3, AutoroutingPipeline1_OriginalUnravel, AutoroutingPipelineSolver3_HgPortPointPathing, AutoroutingPipelineSolver4, AutoroutingPipelineSolver5, AutoroutingPipelineSolver8, AutoroutingPipelineSolver9_PreloadedTraceGraph, AutoroutingPipelineSolver9_Networked, AutoroutingPipelineSolver11_Simplification, SimplifiedPcbTrace as SimplifiedPcbTrace$1, SimpleRouteJson as SimpleRouteJson$1 } from '@tscircuit/capacity-autorouter';
14
+ import { AutoroutingPipelineSolver, AssignableAutoroutingPipeline2, AssignableAutoroutingPipeline3, AutoroutingPipeline1_OriginalUnravel, AutoroutingPipelineSolver3_HgPortPointPathing, AutoroutingPipelineSolver4, AutoroutingPipelineSolver5, AutoroutingPipelineSolver8, AutoroutingPipelineSolver9_PreloadedTraceGraph, AutoroutingPipelineSolver9_Networked, AutoroutingPipelineSolver11_Simplification, SimpleRouteJson as SimpleRouteJson$1, SimplifiedPcbTrace as SimplifiedPcbTrace$1 } from '@tscircuit/capacity-autorouter';
15
15
  import { CopperPourPipelineSolver } from '@tscircuit/copper-pour-solver';
16
16
  import { CreateFdmEnclosureSolver, EnclosureApertureInput } from '@tscircuit/create-fdm-enclosure';
17
17
  import { FanoutSolver } from '@tscircuit/fanout-solver';
@@ -1590,6 +1590,7 @@ interface RoutingPhaseDrcTolerances {
1590
1590
  minViaPadDiameter?: number;
1591
1591
  }
1592
1592
  interface RoutingPhasePlan {
1593
+ getPrecomputedTraces?: (input: SimpleRouteJson) => SimplifiedPcbTrace[];
1593
1594
  routingPhaseIndex: number | null;
1594
1595
  phaseName?: AutoroutingPhaseProps["name"];
1595
1596
  routingPcbGroupId?: PcbGroupId;
@@ -93541,6 +93542,7 @@ declare class AutoroutingPhase extends PrimitiveComponent<typeof autoroutingPhas
93541
93542
  minViaHoleDiameter?: number | undefined;
93542
93543
  minViaPadDiameter?: number | undefined;
93543
93544
  autorouter?: _tscircuit_props.AutorouterProp | undefined;
93545
+ connection?: string | undefined;
93544
93546
  busFanoutDirections?: Record<string, "top_left" | "top_center" | "top_right" | "center_left" | "center" | "center_right" | "bottom_left" | "bottom_center" | "bottom_right" | "topside_left" | "topside_center" | "topside_right" | "rightside_top" | "rightside_center" | "rightside_bottom" | "bottomside_right" | "bottomside_center" | "bottomside_left" | "leftside_bottom" | "leftside_center" | "leftside_top" | {
93545
93547
  direction: "top_left" | "top_center" | "top_right" | "center_left" | "center" | "center_right" | "bottom_left" | "bottom_center" | "bottom_right" | "topside_left" | "topside_center" | "topside_right" | "rightside_top" | "rightside_center" | "rightside_bottom" | "bottomside_right" | "bottomside_center" | "bottomside_left" | "leftside_bottom" | "leftside_center" | "leftside_top";
93546
93548
  }> | undefined;
@@ -93552,7 +93554,6 @@ declare class AutoroutingPhase extends PrimitiveComponent<typeof autoroutingPhas
93552
93554
  } | undefined;
93553
93555
  fanoutRoutingLayers?: ("top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8")[] | undefined;
93554
93556
  fanoutPourNetMap?: Partial<Record<"top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8", string | string[]>> | undefined;
93555
- connection?: string | undefined;
93556
93557
  phaseIndex?: number | undefined;
93557
93558
  region?: {
93558
93559
  minX: number;
@@ -93576,6 +93577,7 @@ declare class AutoroutingPhase extends PrimitiveComponent<typeof autoroutingPhas
93576
93577
  minViaHoleDiameter?: string | number | undefined;
93577
93578
  minViaPadDiameter?: string | number | undefined;
93578
93579
  autorouter?: _tscircuit_props.AutorouterProp | undefined;
93580
+ connection?: string | undefined;
93579
93581
  busFanoutDirections?: Record<string, "top_left" | "top_center" | "top_right" | "center_left" | "center" | "center_right" | "bottom_left" | "bottom_center" | "bottom_right" | "topside_left" | "topside_center" | "topside_right" | "rightside_top" | "rightside_center" | "rightside_bottom" | "bottomside_right" | "bottomside_center" | "bottomside_left" | "leftside_bottom" | "leftside_center" | "leftside_top" | {
93580
93582
  direction: "top_left" | "top_center" | "top_right" | "center_left" | "center" | "center_right" | "bottom_left" | "bottom_center" | "bottom_right" | "topside_left" | "topside_center" | "topside_right" | "rightside_top" | "rightside_center" | "rightside_bottom" | "bottomside_right" | "bottomside_center" | "bottomside_left" | "leftside_bottom" | "leftside_center" | "leftside_top";
93581
93583
  }> | undefined;
@@ -93591,7 +93593,6 @@ declare class AutoroutingPhase extends PrimitiveComponent<typeof autoroutingPhas
93591
93593
  fanoutPourNetMap?: Partial<Record<"top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8" | {
93592
93594
  name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8";
93593
93595
  }, string | string[]>> | undefined;
93594
- connection?: string | undefined;
93595
93596
  phaseIndex?: number | undefined;
93596
93597
  region?: {
93597
93598
  minX: number;
@@ -93615,6 +93616,7 @@ declare class AutoroutingPhase extends PrimitiveComponent<typeof autoroutingPhas
93615
93616
  minViaHoleDiameter?: number | undefined;
93616
93617
  minViaPadDiameter?: number | undefined;
93617
93618
  autorouter?: _tscircuit_props.AutorouterProp | undefined;
93619
+ connection?: string | undefined;
93618
93620
  busFanoutDirections?: Record<string, "top_left" | "top_center" | "top_right" | "center_left" | "center" | "center_right" | "bottom_left" | "bottom_center" | "bottom_right" | "topside_left" | "topside_center" | "topside_right" | "rightside_top" | "rightside_center" | "rightside_bottom" | "bottomside_right" | "bottomside_center" | "bottomside_left" | "leftside_bottom" | "leftside_center" | "leftside_top" | {
93619
93621
  direction: "top_left" | "top_center" | "top_right" | "center_left" | "center" | "center_right" | "bottom_left" | "bottom_center" | "bottom_right" | "topside_left" | "topside_center" | "topside_right" | "rightside_top" | "rightside_center" | "rightside_bottom" | "bottomside_right" | "bottomside_center" | "bottomside_left" | "leftside_bottom" | "leftside_center" | "leftside_top";
93620
93622
  }> | undefined;
@@ -93626,7 +93628,6 @@ declare class AutoroutingPhase extends PrimitiveComponent<typeof autoroutingPhas
93626
93628
  } | undefined;
93627
93629
  fanoutRoutingLayers?: ("top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8")[] | undefined;
93628
93630
  fanoutPourNetMap?: Partial<Record<"top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8", string | string[]>> | undefined;
93629
- connection?: string | undefined;
93630
93631
  phaseIndex?: number | undefined;
93631
93632
  region?: {
93632
93633
  minX: number;
@@ -93650,6 +93651,7 @@ declare class AutoroutingPhase extends PrimitiveComponent<typeof autoroutingPhas
93650
93651
  minViaHoleDiameter?: string | number | undefined;
93651
93652
  minViaPadDiameter?: string | number | undefined;
93652
93653
  autorouter?: _tscircuit_props.AutorouterProp | undefined;
93654
+ connection?: string | undefined;
93653
93655
  busFanoutDirections?: Record<string, "top_left" | "top_center" | "top_right" | "center_left" | "center" | "center_right" | "bottom_left" | "bottom_center" | "bottom_right" | "topside_left" | "topside_center" | "topside_right" | "rightside_top" | "rightside_center" | "rightside_bottom" | "bottomside_right" | "bottomside_center" | "bottomside_left" | "leftside_bottom" | "leftside_center" | "leftside_top" | {
93654
93656
  direction: "top_left" | "top_center" | "top_right" | "center_left" | "center" | "center_right" | "bottom_left" | "bottom_center" | "bottom_right" | "topside_left" | "topside_center" | "topside_right" | "rightside_top" | "rightside_center" | "rightside_bottom" | "bottomside_right" | "bottomside_center" | "bottomside_left" | "leftside_bottom" | "leftside_center" | "leftside_top";
93655
93657
  }> | undefined;
@@ -93665,7 +93667,6 @@ declare class AutoroutingPhase extends PrimitiveComponent<typeof autoroutingPhas
93665
93667
  fanoutPourNetMap?: Partial<Record<"top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8" | {
93666
93668
  name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8";
93667
93669
  }, string | string[]>> | undefined;
93668
- connection?: string | undefined;
93669
93670
  phaseIndex?: number | undefined;
93670
93671
  region?: {
93671
93672
  minX: number;
@@ -96143,6 +96144,156 @@ declare class Breakout extends Group<typeof breakoutProps> {
96143
96144
  name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8";
96144
96145
  }>, zod.ZodUnion<[zod.ZodString, zod.ZodArray<zod.ZodString, "many">]>>>;
96145
96146
  autorouter: zod.ZodDefault<zod.ZodType<_tscircuit_props.AutorouterProp, zod.ZodTypeDef, _tscircuit_props.AutorouterProp>>;
96147
+ pcbTracePaths: zod.ZodOptional<zod.ZodArray<zod.ZodObject<{
96148
+ connection: zod.ZodString;
96149
+ route: zod.ZodEffects<zod.ZodArray<zod.ZodDiscriminatedUnion<"route_type", [zod.ZodObject<{
96150
+ route_type: zod.ZodLiteral<"wire">;
96151
+ x: zod.ZodEffects<zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>, number, string | number>;
96152
+ y: zod.ZodEffects<zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>, number, string | number>;
96153
+ width: zod.ZodEffects<zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>, number, string | number>;
96154
+ layer: zod.ZodEffects<zod.ZodUnion<[zod.ZodEnum<["top", "bottom", "inner1", "inner2", "inner3", "inner4", "inner5", "inner6", "inner7", "inner8"]>, zod.ZodObject<{
96155
+ name: zod.ZodEnum<["top", "bottom", "inner1", "inner2", "inner3", "inner4", "inner5", "inner6", "inner7", "inner8"]>;
96156
+ }, "strip", zod.ZodTypeAny, {
96157
+ name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8";
96158
+ }, {
96159
+ name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8";
96160
+ }>]>, "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8", "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8" | {
96161
+ name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8";
96162
+ }>;
96163
+ }, "strip", zod.ZodTypeAny, {
96164
+ width: number;
96165
+ x: number;
96166
+ y: number;
96167
+ layer: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8";
96168
+ route_type: "wire";
96169
+ }, {
96170
+ width: string | number;
96171
+ x: string | number;
96172
+ y: string | number;
96173
+ layer: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8" | {
96174
+ name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8";
96175
+ };
96176
+ route_type: "wire";
96177
+ }>, zod.ZodObject<{
96178
+ route_type: zod.ZodLiteral<"via">;
96179
+ x: zod.ZodEffects<zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>, number, string | number>;
96180
+ y: zod.ZodEffects<zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>, number, string | number>;
96181
+ from_layer: zod.ZodEffects<zod.ZodUnion<[zod.ZodEnum<["top", "bottom", "inner1", "inner2", "inner3", "inner4", "inner5", "inner6", "inner7", "inner8"]>, zod.ZodObject<{
96182
+ name: zod.ZodEnum<["top", "bottom", "inner1", "inner2", "inner3", "inner4", "inner5", "inner6", "inner7", "inner8"]>;
96183
+ }, "strip", zod.ZodTypeAny, {
96184
+ name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8";
96185
+ }, {
96186
+ name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8";
96187
+ }>]>, "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8", "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8" | {
96188
+ name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8";
96189
+ }>;
96190
+ to_layer: zod.ZodEffects<zod.ZodUnion<[zod.ZodEnum<["top", "bottom", "inner1", "inner2", "inner3", "inner4", "inner5", "inner6", "inner7", "inner8"]>, zod.ZodObject<{
96191
+ name: zod.ZodEnum<["top", "bottom", "inner1", "inner2", "inner3", "inner4", "inner5", "inner6", "inner7", "inner8"]>;
96192
+ }, "strip", zod.ZodTypeAny, {
96193
+ name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8";
96194
+ }, {
96195
+ name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8";
96196
+ }>]>, "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8", "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8" | {
96197
+ name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8";
96198
+ }>;
96199
+ via_diameter: zod.ZodOptional<zod.ZodEffects<zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>, number, string | number>>;
96200
+ via_hole_diameter: zod.ZodOptional<zod.ZodEffects<zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>, number, string | number>>;
96201
+ }, "strip", zod.ZodTypeAny, {
96202
+ x: number;
96203
+ y: number;
96204
+ route_type: "via";
96205
+ from_layer: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8";
96206
+ to_layer: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8";
96207
+ via_diameter?: number | undefined;
96208
+ via_hole_diameter?: number | undefined;
96209
+ }, {
96210
+ x: string | number;
96211
+ y: string | number;
96212
+ route_type: "via";
96213
+ from_layer: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8" | {
96214
+ name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8";
96215
+ };
96216
+ to_layer: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8" | {
96217
+ name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8";
96218
+ };
96219
+ via_diameter?: string | number | undefined;
96220
+ via_hole_diameter?: string | number | undefined;
96221
+ }>]>, "many">, ({
96222
+ width: number;
96223
+ x: number;
96224
+ y: number;
96225
+ layer: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8";
96226
+ route_type: "wire";
96227
+ } | {
96228
+ x: number;
96229
+ y: number;
96230
+ route_type: "via";
96231
+ from_layer: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8";
96232
+ to_layer: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8";
96233
+ via_diameter?: number | undefined;
96234
+ via_hole_diameter?: number | undefined;
96235
+ })[], ({
96236
+ width: string | number;
96237
+ x: string | number;
96238
+ y: string | number;
96239
+ layer: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8" | {
96240
+ name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8";
96241
+ };
96242
+ route_type: "wire";
96243
+ } | {
96244
+ x: string | number;
96245
+ y: string | number;
96246
+ route_type: "via";
96247
+ from_layer: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8" | {
96248
+ name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8";
96249
+ };
96250
+ to_layer: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8" | {
96251
+ name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8";
96252
+ };
96253
+ via_diameter?: string | number | undefined;
96254
+ via_hole_diameter?: string | number | undefined;
96255
+ })[]>;
96256
+ }, "strip", zod.ZodTypeAny, {
96257
+ route: ({
96258
+ width: number;
96259
+ x: number;
96260
+ y: number;
96261
+ layer: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8";
96262
+ route_type: "wire";
96263
+ } | {
96264
+ x: number;
96265
+ y: number;
96266
+ route_type: "via";
96267
+ from_layer: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8";
96268
+ to_layer: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8";
96269
+ via_diameter?: number | undefined;
96270
+ via_hole_diameter?: number | undefined;
96271
+ })[];
96272
+ connection: string;
96273
+ }, {
96274
+ route: ({
96275
+ width: string | number;
96276
+ x: string | number;
96277
+ y: string | number;
96278
+ layer: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8" | {
96279
+ name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8";
96280
+ };
96281
+ route_type: "wire";
96282
+ } | {
96283
+ x: string | number;
96284
+ y: string | number;
96285
+ route_type: "via";
96286
+ from_layer: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8" | {
96287
+ name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8";
96288
+ };
96289
+ to_layer: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8" | {
96290
+ name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8";
96291
+ };
96292
+ via_diameter?: string | number | undefined;
96293
+ via_hole_diameter?: string | number | undefined;
96294
+ })[];
96295
+ connection: string;
96296
+ }>, "many">>;
96146
96297
  padding: zod.ZodOptional<zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>>;
96147
96298
  paddingLeft: zod.ZodOptional<zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>>;
96148
96299
  paddingRight: zod.ZodOptional<zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>>;
@@ -96479,6 +96630,24 @@ declare class Breakout extends Group<typeof breakoutProps> {
96479
96630
  } | undefined;
96480
96631
  fanoutRoutingLayers?: ("top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8")[] | undefined;
96481
96632
  fanoutPourNetMap?: Partial<Record<"top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8", string | string[]>> | undefined;
96633
+ pcbTracePaths?: {
96634
+ route: ({
96635
+ width: number;
96636
+ x: number;
96637
+ y: number;
96638
+ layer: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8";
96639
+ route_type: "wire";
96640
+ } | {
96641
+ x: number;
96642
+ y: number;
96643
+ route_type: "via";
96644
+ from_layer: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8";
96645
+ to_layer: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8";
96646
+ via_diameter?: number | undefined;
96647
+ via_hole_diameter?: number | undefined;
96648
+ })[];
96649
+ connection: string;
96650
+ }[] | undefined;
96482
96651
  fanoutMargin?: number | undefined;
96483
96652
  }, {
96484
96653
  symbol?: _tscircuit_props.SymbolProp | undefined;
@@ -96818,6 +96987,30 @@ declare class Breakout extends Group<typeof breakoutProps> {
96818
96987
  fanoutPourNetMap?: Partial<Record<"top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8" | {
96819
96988
  name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8";
96820
96989
  }, string | string[]>> | undefined;
96990
+ pcbTracePaths?: {
96991
+ route: ({
96992
+ width: string | number;
96993
+ x: string | number;
96994
+ y: string | number;
96995
+ layer: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8" | {
96996
+ name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8";
96997
+ };
96998
+ route_type: "wire";
96999
+ } | {
97000
+ x: string | number;
97001
+ y: string | number;
97002
+ route_type: "via";
97003
+ from_layer: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8" | {
97004
+ name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8";
97005
+ };
97006
+ to_layer: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8" | {
97007
+ name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | "inner7" | "inner8";
97008
+ };
97009
+ via_diameter?: string | number | undefined;
97010
+ via_hole_diameter?: string | number | undefined;
97011
+ })[];
97012
+ connection: string;
97013
+ }[] | undefined;
96821
97014
  fanoutMargin?: string | number | undefined;
96822
97015
  }>;
96823
97016
  componentName: string;
@@ -98223,8 +98416,8 @@ declare class NetLabel extends PrimitiveComponent<typeof netLabelProps> {
98223
98416
  schX?: number | undefined;
98224
98417
  schY?: number | undefined;
98225
98418
  schRotation?: number | undefined;
98226
- net?: string | undefined;
98227
98419
  connection?: string | undefined;
98420
+ net?: string | undefined;
98228
98421
  anchorSide?: "left" | "right" | "top" | "bottom" | undefined;
98229
98422
  inline?: boolean | undefined;
98230
98423
  }, {
@@ -98232,8 +98425,8 @@ declare class NetLabel extends PrimitiveComponent<typeof netLabelProps> {
98232
98425
  schX?: string | number | undefined;
98233
98426
  schY?: string | number | undefined;
98234
98427
  schRotation?: string | number | undefined;
98235
- net?: string | undefined;
98236
98428
  connection?: string | undefined;
98429
+ net?: string | undefined;
98237
98430
  anchorSide?: "left" | "right" | "top" | "bottom" | undefined;
98238
98431
  inline?: boolean | undefined;
98239
98432
  }>;
package/dist/index.js CHANGED
@@ -16586,7 +16586,7 @@ import {
16586
16586
  } from "@tscircuit/checks";
16587
16587
  import { getBoundsFromPoints as getBoundsFromPoints10 } from "@tscircuit/math-utils";
16588
16588
  import { boardProps } from "@tscircuit/props";
16589
- import { compose as compose13, translate as translate13 } from "transformation-matrix";
16589
+ import { compose as compose14, translate as translate14 } from "transformation-matrix";
16590
16590
 
16591
16591
  // lib/utils/autorouting/getAncestorSubcircuitIds.ts
16592
16592
  var getDescendantSubcircuitIds = (db, root_subcircuit_id) => {
@@ -18228,6 +18228,70 @@ function inflateSourceFiducial(sourceElm, inflatorContext) {
18228
18228
  }
18229
18229
  }
18230
18230
 
18231
+ // lib/utils/autorouting/with-fixed-fanout-traces.ts
18232
+ function withFixedFanoutTraces(input, fixedTraceIds) {
18233
+ if (fixedTraceIds.size === 0) return input;
18234
+ const fixedTraces = (input.traces ?? []).filter(
18235
+ (trace) => fixedTraceIds.has(trace.pcb_trace_id)
18236
+ );
18237
+ if (fixedTraces.length === 0) return input;
18238
+ const obstacles = [];
18239
+ for (const trace of fixedTraces) {
18240
+ const connectedTo = [
18241
+ trace.connection_name ?? trace.pcb_trace_id,
18242
+ ...trace.connectsTo ?? []
18243
+ ];
18244
+ for (const [index, point6] of trace.route.entries()) {
18245
+ if (point6.route_type === "via") {
18246
+ const boardLayers = getViaBoardLayers(input.layerCount);
18247
+ const from = boardLayers.findIndex(
18248
+ (layer2) => layer2 === point6.from_layer
18249
+ );
18250
+ const to = boardLayers.findIndex((layer2) => layer2 === point6.to_layer);
18251
+ const diameter = point6.via_diameter ?? input.minViaPadDiameter ?? input.minViaDiameter ?? 0.6;
18252
+ obstacles.push({
18253
+ type: "rect",
18254
+ center: { x: point6.x, y: point6.y },
18255
+ width: diameter,
18256
+ height: diameter,
18257
+ layers: boardLayers.slice(Math.min(from, to), Math.max(from, to) + 1),
18258
+ connectedTo
18259
+ });
18260
+ }
18261
+ const next = trace.route[index + 1];
18262
+ if (!next || point6.route_type !== "wire" && point6.route_type !== "via" || next.route_type !== "wire" && next.route_type !== "via")
18263
+ continue;
18264
+ const width = point6.route_type === "wire" ? point6.width : next.route_type === "wire" ? next.width : input.minTraceWidth;
18265
+ const layer = point6.route_type === "wire" ? point6.layer : point6.to_layer;
18266
+ const steps = point6.x === next.x || point6.y === next.y ? 1 : Math.max(
18267
+ 1,
18268
+ Math.ceil(Math.hypot(next.x - point6.x, next.y - point6.y) / width)
18269
+ );
18270
+ for (let step = 0; step < steps; step++) {
18271
+ const x1 = point6.x + (next.x - point6.x) * step / steps;
18272
+ const y1 = point6.y + (next.y - point6.y) * step / steps;
18273
+ const x2 = point6.x + (next.x - point6.x) * (step + 1) / steps;
18274
+ const y2 = point6.y + (next.y - point6.y) * (step + 1) / steps;
18275
+ obstacles.push({
18276
+ type: "rect",
18277
+ center: { x: (x1 + x2) / 2, y: (y1 + y2) / 2 },
18278
+ width: Math.abs(x2 - x1) + width,
18279
+ height: Math.abs(y2 - y1) + width,
18280
+ layers: [layer],
18281
+ connectedTo
18282
+ });
18283
+ }
18284
+ }
18285
+ }
18286
+ return {
18287
+ ...input,
18288
+ traces: input.traces?.filter(
18289
+ (trace) => !fixedTraceIds.has(trace.pcb_trace_id)
18290
+ ),
18291
+ obstacles: [...input.obstacles, ...obstacles]
18292
+ };
18293
+ }
18294
+
18231
18295
  // lib/utils/schematic/assign-schematic-net-label-superscripts.ts
18232
18296
  import {
18233
18297
  getFullConnectivityMapFromCircuitJson as getFullConnectivityMapFromCircuitJson3
@@ -60915,6 +60979,9 @@ var Group_getFanoutPourNetMap = (group, routingPhasePlans) => {
60915
60979
  // lib/components/primitive-components/Group/Group_getRoutingPhasePlans.ts
60916
60980
  import { getBoundsFromPoints as getBoundsFromPoints8 } from "@tscircuit/math-utils";
60917
60981
 
60982
+ // lib/components/primitive-components/Breakout/get-saved-fanout-traces.ts
60983
+ import { applyToPoint as applyToPoint30, compose as compose12, translate as translate12 } from "transformation-matrix";
60984
+
60918
60985
  // lib/components/primitive-components/BreakoutPoint.ts
60919
60986
  import { breakoutPointProps } from "@tscircuit/props";
60920
60987
 
@@ -61037,6 +61104,152 @@ var BreakoutPoint = class extends BaseBreakoutPoint {
61037
61104
  }
61038
61105
  };
61039
61106
 
61107
+ // lib/components/primitive-components/Breakout/SavedFanoutPoint.ts
61108
+ var SavedFanoutPoint = class extends BreakoutPoint {
61109
+ exitLayer = "top";
61110
+ doInitialPcbPrimitiveRender() {
61111
+ this._matchConnection();
61112
+ this._renderPcbBreakoutPoint({ layer: this.exitLayer });
61113
+ }
61114
+ };
61115
+
61116
+ // lib/components/primitive-components/Breakout/get-saved-fanout-traces.ts
61117
+ function getSavedFanoutTraces(breakout, input) {
61118
+ const { db } = breakout.root;
61119
+ const boardLayers = getViaBoardLayers(input.layerCount);
61120
+ const coveredConnections = /* @__PURE__ */ new Set();
61121
+ const exits = breakout.children.filter(
61122
+ (child) => child instanceof SavedFanoutPoint
61123
+ );
61124
+ const traces = (breakout._parsedProps.pcbTracePaths ?? []).map(
61125
+ (path, pathIndex) => {
61126
+ for (const point6 of path.route) {
61127
+ const layers = point6.route_type === "wire" ? [point6.layer] : [point6.from_layer, point6.to_layer];
61128
+ if (layers.some((layer) => !boardLayers.includes(layer))) {
61129
+ throw new Error(
61130
+ `Saved fanout path "${path.connection}" uses a layer unavailable on this board`
61131
+ );
61132
+ }
61133
+ }
61134
+ const exit = exits[pathIndex];
61135
+ const port = exit.matchedPort;
61136
+ const connection = input.connections.find(
61137
+ (connection2) => connection2.pointsToConnect.some(
61138
+ (point6) => point6.pcb_port_id === port.pcb_port_id
61139
+ )
61140
+ );
61141
+ if (!connection)
61142
+ throw new Error(
61143
+ `No fanout connection for saved path "${path.connection}"`
61144
+ );
61145
+ const pcbExit = db.pcb_breakout_point.get(exit.pcb_breakout_point_id);
61146
+ const localExit = path.route.at(-1);
61147
+ const transform = compose12(
61148
+ exit._computePcbGlobalTransformBeforeLayout(),
61149
+ translate12(-localExit.x, -localExit.y)
61150
+ );
61151
+ const originalExit = applyToPoint30(transform, localExit);
61152
+ const route = path.route.map((point6) => {
61153
+ const position = applyToPoint30(transform, point6);
61154
+ return {
61155
+ ...point6,
61156
+ x: position.x + pcbExit.x - originalExit.x,
61157
+ y: position.y + pcbExit.y - originalExit.y
61158
+ };
61159
+ });
61160
+ const first = route[0];
61161
+ const firstLayer = first.route_type === "wire" ? first.layer : first.from_layer;
61162
+ const portPosition = port._getGlobalPcbPositionAfterLayout();
61163
+ if (Math.hypot(first.x - portPosition.x, first.y - portPosition.y) > 1e-4 || !port.getAvailablePcbLayers().includes(firstLayer)) {
61164
+ throw new Error(
61165
+ `Saved fanout path "${path.connection}" must start at its PCB port on an available layer`
61166
+ );
61167
+ }
61168
+ if (first.route_type === "via" && !input.allowViaInPad) {
61169
+ throw new Error(
61170
+ `Saved fanout path "${path.connection}" starts with a via at a pad; enable allowViaInPad`
61171
+ );
61172
+ }
61173
+ const last = route.at(-1);
61174
+ const lastLayer = last.route_type === "wire" ? last.layer : last.to_layer;
61175
+ const endpoints = [
61176
+ { ...first, layer: firstLayer },
61177
+ { ...last, layer: lastLayer }
61178
+ ];
61179
+ if (connection.pointsToConnect.some(
61180
+ (point6) => !endpoints.some(
61181
+ (endpoint) => Math.hypot(point6.x - endpoint.x, point6.y - endpoint.y) < 1e-4 && (point6.layers ?? [point6.layer]).includes(endpoint.layer)
61182
+ )
61183
+ ))
61184
+ throw new Error(
61185
+ `Saved fanout path "${path.connection}" does not cover its connection endpoints`
61186
+ );
61187
+ const width = route.find((point6) => point6.route_type === "wire")?.width ?? input.minTraceWidth;
61188
+ if (first.route_type === "via") {
61189
+ route.splice(1, 0, {
61190
+ route_type: "wire",
61191
+ x: first.x,
61192
+ y: first.y,
61193
+ layer: first.to_layer,
61194
+ width
61195
+ });
61196
+ route.unshift({
61197
+ route_type: "wire",
61198
+ x: first.x,
61199
+ y: first.y,
61200
+ layer: first.from_layer,
61201
+ width
61202
+ });
61203
+ }
61204
+ if (last.route_type === "via") {
61205
+ route.splice(route.length - 1, 0, {
61206
+ route_type: "wire",
61207
+ x: last.x,
61208
+ y: last.y,
61209
+ layer: last.from_layer,
61210
+ width
61211
+ });
61212
+ route.push({
61213
+ route_type: "wire",
61214
+ x: last.x,
61215
+ y: last.y,
61216
+ layer: last.to_layer,
61217
+ width
61218
+ });
61219
+ }
61220
+ if (last.route_type === "via") {
61221
+ route.push({
61222
+ route_type: "wire",
61223
+ x: last.x,
61224
+ y: last.y,
61225
+ layer: last.to_layer,
61226
+ width
61227
+ });
61228
+ }
61229
+ coveredConnections.add(connection);
61230
+ return {
61231
+ type: "pcb_trace",
61232
+ pcb_trace_id: `saved_fanout_${breakout.pcb_group_id}_${pathIndex}`,
61233
+ connection_name: connection.name,
61234
+ source_trace_id: connection.source_trace_id,
61235
+ connectsTo: [
61236
+ connection.source_trace_id,
61237
+ ...connection.pointsToConnect.map((point6) => point6.pointId)
61238
+ ].filter((id) => Boolean(id)),
61239
+ route
61240
+ };
61241
+ }
61242
+ );
61243
+ const missing = input.connections.filter(
61244
+ (connection) => !coveredConnections.has(connection)
61245
+ );
61246
+ if (missing.length)
61247
+ throw new Error(
61248
+ `pcbTracePaths must cover every fanout connection; missing: ${missing.map((connection) => connection.name).join(", ")}`
61249
+ );
61250
+ return traces;
61251
+ }
61252
+
61040
61253
  // lib/components/primitive-components/Group/Group_getRoutingPhasePlans.ts
61041
61254
  function getPhaseSortValue(routingPhaseIndex) {
61042
61255
  return routingPhaseIndex === null ? Number.POSITIVE_INFINITY : routingPhaseIndex;
@@ -61313,6 +61526,18 @@ function Group_getRoutingPhasePlans(group) {
61313
61526
  nets: nets.filter((net) => breakoutByNet.get(net) === breakout),
61314
61527
  traces: breakoutTraces
61315
61528
  };
61529
+ if (breakout._parsedProps.pcbTracePaths !== void 0) {
61530
+ breakoutPlans.push({
61531
+ ...breakoutPlan,
61532
+ autorouter: {
61533
+ local: true,
61534
+ groupMode: "subcircuit",
61535
+ allowViaInPad: (typeof breakoutProps2.autorouter === "object" ? breakoutProps2.autorouter.allowViaInPad : void 0) ?? group._getAutorouterConfig().allowViaInPad
61536
+ },
61537
+ getPrecomputedTraces: (input) => getSavedFanoutTraces(breakout, input)
61538
+ });
61539
+ continue;
61540
+ }
61316
61541
  if (!shouldUseDefaultAutorouterForBreakoutPoints) {
61317
61542
  breakoutPlans.push(breakoutPlan);
61318
61543
  continue;
@@ -61371,7 +61596,7 @@ function Group_getRoutingPhasePlans(group) {
61371
61596
  var package_default = {
61372
61597
  name: "@tscircuit/core",
61373
61598
  type: "module",
61374
- version: "0.0.1882",
61599
+ version: "0.0.1883",
61375
61600
  types: "dist/index.d.ts",
61376
61601
  main: "dist/index.js",
61377
61602
  module: "dist/index.js",
@@ -61424,7 +61649,7 @@ var package_default = {
61424
61649
  "@tscircuit/math-utils": "^0.0.36",
61425
61650
  "@tscircuit/miniflex": "^0.0.4",
61426
61651
  "@tscircuit/ngspice-spice-engine": "^0.0.20",
61427
- "@tscircuit/props": "^0.0.647",
61652
+ "@tscircuit/props": "^0.0.649",
61428
61653
  "@tscircuit/schematic-match-adapt": "^0.0.18",
61429
61654
  "@tscircuit/schematic-trace-solver": "^0.0.189",
61430
61655
  "@tscircuit/solver-utils": "^0.0.16",
@@ -61503,7 +61728,7 @@ var package_default = {
61503
61728
  },
61504
61729
  overrides: {
61505
61730
  "@tscircuit/circuit-json-util": "^0.0.113",
61506
- "@tscircuit/props": "^0.0.647",
61731
+ "@tscircuit/props": "^0.0.649",
61507
61732
  "circuit-json": "^0.0.484"
61508
61733
  }
61509
61734
  };
@@ -63389,6 +63614,7 @@ var Group5 = class extends NormalComponent3 {
63389
63614
  );
63390
63615
  });
63391
63616
  };
63617
+ const fixedFanoutTraceIds = /* @__PURE__ */ new Set();
63392
63618
  let previousStageOutputSimpleRouteJson;
63393
63619
  for (const [
63394
63620
  routingStageIndex,
@@ -63489,6 +63715,10 @@ var Group5 = class extends NormalComponent3 {
63489
63715
  traces: [...phaseInput.traces ?? [], ...outputTraces]
63490
63716
  };
63491
63717
  }
63718
+ simpleRouteJson = withFixedFanoutTraces(
63719
+ simpleRouteJson,
63720
+ fixedFanoutTraceIds
63721
+ );
63492
63722
  simpleRouteJson = Group_applyDrcTolerancesToSimpleRouteJson(
63493
63723
  simpleRouteJson,
63494
63724
  routingPhasePlan.drcTolerances
@@ -63559,8 +63789,8 @@ var Group5 = class extends NormalComponent3 {
63559
63789
  autorouterVersion: autorouterVersion2,
63560
63790
  effort
63561
63791
  };
63562
- const autorouterName = phaseAutorouterConfig.algorithmFn ? "custom" : localAutorouterStrategy.name;
63563
- const solverName = phaseAutorouterConfig.algorithmFn ? void 0 : localAutorouterStrategy.getSolverName(commonAutorouterOptions);
63792
+ const autorouterName = routingPhasePlan.getPrecomputedTraces ? "precomputed" : phaseAutorouterConfig.algorithmFn ? "custom" : localAutorouterStrategy.name;
63793
+ const solverName = routingPhasePlan.getPrecomputedTraces || phaseAutorouterConfig.algorithmFn ? void 0 : localAutorouterStrategy.getSolverName(commonAutorouterOptions);
63564
63794
  const localAutoroutingCacheSolverOptions = {
63565
63795
  autorouterName,
63566
63796
  solverName,
@@ -63573,13 +63803,13 @@ var Group5 = class extends NormalComponent3 {
63573
63803
  autorouterVersion: commonAutorouterOptions.autorouterVersion,
63574
63804
  effort: commonAutorouterOptions.effort
63575
63805
  };
63576
- const cacheEngine = phaseAutorouterConfig.algorithmFn || !localAutorouterStrategy.cacheable ? void 0 : this.root?.platform?.localCacheEngine;
63806
+ const cacheEngine = routingPhasePlan.getPrecomputedTraces || phaseAutorouterConfig.algorithmFn || !localAutorouterStrategy.cacheable ? void 0 : this.root?.platform?.localCacheEngine;
63577
63807
  const cacheKey = cacheEngine ? getLocalAutoroutingCacheKey(
63578
63808
  simpleRouteJson,
63579
63809
  localAutoroutingCacheSolverOptions
63580
63810
  ) : void 0;
63581
63811
  const cachedResult = cacheKey ? await getCachedLocalAutoroutingPhaseResult({ cacheEngine, cacheKey }) : null;
63582
- const cacheDisabledReason = phaseAutorouterConfig.algorithmFn ? "custom_algorithm" : !localAutorouterStrategy.cacheable ? "strategy_not_cacheable" : !cacheEngine ? "no_cache_engine" : void 0;
63812
+ const cacheDisabledReason = routingPhasePlan.getPrecomputedTraces ? "precomputed" : phaseAutorouterConfig.algorithmFn ? "custom_algorithm" : !localAutorouterStrategy.cacheable ? "strategy_not_cacheable" : !cacheEngine ? "no_cache_engine" : void 0;
63583
63813
  const autoroutingMetadata = {
63584
63814
  routingPhaseIndex: routingStageIndex,
63585
63815
  phaseOrdinal: routingStageIndex + 1,
@@ -63611,7 +63841,11 @@ var Group5 = class extends NormalComponent3 {
63611
63841
  let autorouter;
63612
63842
  try {
63613
63843
  let traces;
63614
- if (cachedResult) {
63844
+ if (routingPhasePlan.getPrecomputedTraces) {
63845
+ traces = routingPhasePlan.getPrecomputedTraces(simpleRouteJson);
63846
+ for (const trace of traces)
63847
+ fixedFanoutTraceIds.add(trace.pcb_trace_id);
63848
+ } else if (cachedResult) {
63615
63849
  debug13(`[${this.getString()}] using cached local autorouting result`);
63616
63850
  traces = cachedResult.traces;
63617
63851
  } else {
@@ -66683,10 +66917,10 @@ import {
66683
66917
  Polygon as Polygon2,
66684
66918
  Segment
66685
66919
  } from "@flatten-js/core";
66686
- import { compose as compose12, rotate as rotate6, translate as translate12 } from "transformation-matrix";
66920
+ import { compose as compose13, rotate as rotate6, translate as translate13 } from "transformation-matrix";
66687
66921
  var placePolygon = (polygon, center, degrees = 0) => {
66688
- const { a, b, c, d, e, f } = compose12(
66689
- translate12(center.x, center.y),
66922
+ const { a, b, c, d, e, f } = compose13(
66923
+ translate13(center.x, center.y),
66690
66924
  rotate6(degrees * Math.PI / 180)
66691
66925
  );
66692
66926
  return polygon.transform(new Matrix(a, b, c, d, e, f));
@@ -67368,9 +67602,9 @@ var Board = class extends Group5 {
67368
67602
  _computePcbGlobalTransformBeforeLayout() {
67369
67603
  if (this._panelPositionOffset) {
67370
67604
  const parentTransform = this.parent?._computePcbGlobalTransformBeforeLayout?.() ?? { a: 1, b: 0, c: 0, d: 1, e: 0, f: 0 };
67371
- return compose13(
67605
+ return compose14(
67372
67606
  parentTransform,
67373
- translate13(this._panelPositionOffset.x, this._panelPositionOffset.y)
67607
+ translate14(this._panelPositionOffset.x, this._panelPositionOffset.y)
67374
67608
  );
67375
67609
  }
67376
67610
  return super._computePcbGlobalTransformBeforeLayout();
@@ -67991,7 +68225,7 @@ import { distance as distance20 } from "circuit-json";
67991
68225
  // lib/components/normal-components/Subpanel.ts
67992
68226
  import { subpanelProps } from "@tscircuit/props";
67993
68227
  import { distance as distance19 } from "circuit-json";
67994
- import { compose as compose14, identity as identity8, translate as translate14 } from "transformation-matrix";
68228
+ import { compose as compose15, identity as identity8, translate as translate15 } from "transformation-matrix";
67995
68229
 
67996
68230
  // lib/utils/panels/generate-panel-tabs-and-mouse-bites.ts
67997
68231
  import * as Flatten from "@flatten-js/core";
@@ -68503,9 +68737,9 @@ var Subpanel = class _Subpanel extends Group5 {
68503
68737
  _computePcbGlobalTransformBeforeLayout() {
68504
68738
  if (this._panelPositionOffset) {
68505
68739
  const parentTransform = this.parent?._computePcbGlobalTransformBeforeLayout?.() ?? identity8();
68506
- return compose14(
68740
+ return compose15(
68507
68741
  parentTransform,
68508
- translate14(this._panelPositionOffset.x, this._panelPositionOffset.y)
68742
+ translate15(this._panelPositionOffset.x, this._panelPositionOffset.y)
68509
68743
  );
68510
68744
  }
68511
68745
  return super._computePcbGlobalTransformBeforeLayout();
@@ -70172,7 +70406,7 @@ var AutoroutingPhase = class extends PrimitiveComponent2 {
70172
70406
 
70173
70407
  // lib/components/primitive-components/FabricationNoteDimension.ts
70174
70408
  import { fabricationNoteDimensionProps } from "@tscircuit/props";
70175
- import { applyToPoint as applyToPoint30 } from "transformation-matrix";
70409
+ import { applyToPoint as applyToPoint31 } from "transformation-matrix";
70176
70410
  var FabricationNoteDimension = class extends PrimitiveComponent2 {
70177
70411
  fabrication_note_dimension_id = null;
70178
70412
  isPcbPrimitive = true;
@@ -70191,13 +70425,13 @@ var FabricationNoteDimension = class extends PrimitiveComponent2 {
70191
70425
  this.renderError(
70192
70426
  `FabricationNoteDimension could not find selector "${input}"`
70193
70427
  );
70194
- return applyToPoint30(transform, { x: 0, y: 0 });
70428
+ return applyToPoint31(transform, { x: 0, y: 0 });
70195
70429
  }
70196
70430
  return target._getGlobalPcbPositionBeforeLayout();
70197
70431
  }
70198
70432
  const numericX = typeof input.x === "string" ? parseFloat(input.x) : input.x;
70199
70433
  const numericY = typeof input.y === "string" ? parseFloat(input.y) : input.y;
70200
- return applyToPoint30(transform, { x: numericX, y: numericY });
70434
+ return applyToPoint31(transform, { x: numericX, y: numericY });
70201
70435
  }
70202
70436
  doInitialPcbPrimitiveRender() {
70203
70437
  if (this.root?.pcbDisabled) return;
@@ -70292,7 +70526,7 @@ var FabricationNoteDimension = class extends PrimitiveComponent2 {
70292
70526
 
70293
70527
  // lib/components/primitive-components/PcbNoteDimension.ts
70294
70528
  import { pcbNoteDimensionProps } from "@tscircuit/props";
70295
- import { applyToPoint as applyToPoint31 } from "transformation-matrix";
70529
+ import { applyToPoint as applyToPoint32 } from "transformation-matrix";
70296
70530
  var PcbNoteDimension = class extends PrimitiveComponent2 {
70297
70531
  pcb_note_dimension_id = null;
70298
70532
  isPcbPrimitive = true;
@@ -70309,7 +70543,7 @@ var PcbNoteDimension = class extends PrimitiveComponent2 {
70309
70543
  );
70310
70544
  if (!target) {
70311
70545
  this.renderError(`PcbNoteDimension could not find selector "${input}"`);
70312
- return applyToPoint31(transform, { x: 0, y: 0 });
70546
+ return applyToPoint32(transform, { x: 0, y: 0 });
70313
70547
  }
70314
70548
  const targetPcbComponentId = target.pcb_component_id;
70315
70549
  const root = this.root;
@@ -70326,7 +70560,7 @@ var PcbNoteDimension = class extends PrimitiveComponent2 {
70326
70560
  }
70327
70561
  const numericX = typeof input.x === "string" ? parseFloat(input.x) : input.x;
70328
70562
  const numericY = typeof input.y === "string" ? parseFloat(input.y) : input.y;
70329
- return applyToPoint31(transform, { x: numericX, y: numericY });
70563
+ return applyToPoint32(transform, { x: numericX, y: numericY });
70330
70564
  }
70331
70565
  doInitialPcbPrimitiveRender() {
70332
70566
  if (this.root?.pcbDisabled) return;
@@ -72951,6 +73185,29 @@ var Breakout = class extends Group5 {
72951
73185
  * after PcbLayout.
72952
73186
  */
72953
73187
  doInitialCreateAutoplacedBreakoutPoints() {
73188
+ for (const path of this._parsedProps.pcbTracePaths ?? []) {
73189
+ const exit = path.route.at(-1);
73190
+ const point6 = new SavedFanoutPoint({
73191
+ connection: path.connection,
73192
+ pcbX: exit.x,
73193
+ pcbY: exit.y
73194
+ });
73195
+ point6.exitLayer = exit.route_type === "wire" ? exit.layer : exit.to_layer;
73196
+ this.add(point6);
73197
+ point6._matchConnection();
73198
+ if (!point6.matchedPort || !this.selectAll("port").includes(point6.matchedPort)) {
73199
+ throw new Error(
73200
+ `Fanout trace path "${path.connection}" must select a port inside the fanout`
73201
+ );
73202
+ }
73203
+ const duplicate = this.children.some((child) => {
73204
+ if (!(child instanceof BreakoutPoint) || child === point6) return false;
73205
+ child._matchConnection();
73206
+ return child.matchedPort === point6.matchedPort;
73207
+ });
73208
+ if (duplicate)
73209
+ throw new Error(`Duplicate fanout exit for "${path.connection}"`);
73210
+ }
72954
73211
  const portsInBreakout = this.selectAll("port");
72955
73212
  const breakoutPortSet = new Set(portsInBreakout);
72956
73213
  const manualBreakoutPoints = this.children.filter(
@@ -73054,7 +73311,7 @@ import {
73054
73311
  getTransformedSvgPathRoutes,
73055
73312
  loadImageSource
73056
73313
  } from "@tscircuit/image-utils";
73057
- import { applyToPoint as applyToPoint32 } from "transformation-matrix";
73314
+ import { applyToPoint as applyToPoint33 } from "transformation-matrix";
73058
73315
  var SilkscreenGraphic = class extends PrimitiveComponent2 {
73059
73316
  pcb_silkscreen_graphic_id = null;
73060
73317
  pcb_silkscreen_graphic_ids = [];
@@ -73156,7 +73413,7 @@ var SilkscreenGraphic = class extends PrimitiveComponent2 {
73156
73413
  { x: halfWidth, y: -halfHeight },
73157
73414
  { x: -halfWidth, y: -halfHeight }
73158
73415
  ]).map(
73159
- (point6) => applyToPoint32(transform, point6)
73416
+ (point6) => applyToPoint33(transform, point6)
73160
73417
  )
73161
73418
  },
73162
73419
  inner_rings: []
@@ -75943,6 +76200,9 @@ extendCatalogue({
75943
76200
  Fanout: Breakout,
75944
76201
  FanoutPoint: BreakoutPoint
75945
76202
  });
76203
+
76204
+ // lib/index.ts
76205
+ import { fanoutTracePath } from "@tscircuit/props";
75946
76206
  export {
75947
76207
  Ammeter,
75948
76208
  AnalogAcSweepSimulation,
@@ -76068,6 +76328,7 @@ export {
76068
76328
  createElement2 as createElement,
76069
76329
  createUseComponent,
76070
76330
  enclosure,
76331
+ fanoutTracePath,
76071
76332
  getPhaseTimingsFromRenderEvents,
76072
76333
  getSimpleRouteJsonFromCircuitJson,
76073
76334
  kicadFootprintStrings,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tscircuit/core",
3
3
  "type": "module",
4
- "version": "0.0.1883",
4
+ "version": "0.0.1884",
5
5
  "types": "dist/index.d.ts",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",
@@ -54,7 +54,7 @@
54
54
  "@tscircuit/math-utils": "^0.0.36",
55
55
  "@tscircuit/miniflex": "^0.0.4",
56
56
  "@tscircuit/ngspice-spice-engine": "^0.0.20",
57
- "@tscircuit/props": "^0.0.647",
57
+ "@tscircuit/props": "^0.0.649",
58
58
  "@tscircuit/schematic-match-adapt": "^0.0.18",
59
59
  "@tscircuit/schematic-trace-solver": "^0.0.189",
60
60
  "@tscircuit/solver-utils": "^0.0.16",
@@ -133,7 +133,7 @@
133
133
  },
134
134
  "overrides": {
135
135
  "@tscircuit/circuit-json-util": "^0.0.113",
136
- "@tscircuit/props": "^0.0.647",
136
+ "@tscircuit/props": "^0.0.649",
137
137
  "circuit-json": "^0.0.484"
138
138
  }
139
139
  }