@tscircuit/core 0.0.1475 → 0.0.1477

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
@@ -1,7 +1,7 @@
1
1
  import * as circuit_json from 'circuit-json';
2
- import { PcbTraceError, PcbPlacementError, PcbManualEditConflictWarning, PcbViaClearanceError, LayerRef, AnyCircuitElement, Size, PcbTrace as PcbTrace$1, PcbVia as PcbVia$1, PcbTraceRoutePoint, AnySourceComponent, PcbComponent, SchematicPort, SchematicComponent, PcbSilkscreenGraphic, RouteHintPoint, CircuitJson } from 'circuit-json';
2
+ import { PcbTraceError, PcbPlacementError, PcbManualEditConflictWarning, PcbViaClearanceError, LayerRef, AnyCircuitElement, Size, PcbTrace as PcbTrace$1, PcbVia as PcbVia$1, PcbTraceRoutePoint, AnySourceComponent, PcbComponent, SchematicPort, SchematicComponent, PcbSilkscreenGraphic, RouteHintPoint, PcbBoard, CircuitJson } from 'circuit-json';
3
3
  import * as _tscircuit_props from '@tscircuit/props';
4
- import { PlatformConfig, traceProps, netProps, AutorouterProp, AutoroutingPhaseProps, subcircuitGroupProps, AutorouterConfig, PcbSx, portProps, SupplierPartNumbers, CadModelProp, SchematicPortArrangement, groupProps, boardProps, subcircuitProps, subpanelProps, capacitorProps, chipProps, pinoutProps, diodeProps, fuseProps, jumperProps, interconnectProps, solderjumperProps, ledProps, powerSourceProps, voltageSourceProps, currentSourceProps, ammeterProps, resistorProps, constraintProps, internalCircuitProps, drcCheckProps, autoroutingPhaseProps, 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, silkscreenGraphicProps, smtPadProps, fiducialProps, differentialPairProps, traceHintProps, viaProps, copperPourProps, copperTextProps, cutoutProps, batteryProps, pinHeaderProps, resonatorProps, inductorProps, potentiometerProps, pushButtonProps, crystalProps, CrystalPinLabels, transistorProps, mosfetProps, opampProps, OpAmpPinLabels, switchProps, SwitchProps, testpointProps, schematicTextProps, schematicLineProps, schematicRectProps, schematicArcProps, schematicCircleProps, schematicPathProps, schematicBoxProps, schematicSectionProps, schematicSheetProps, schematicTableProps, schematicRowProps, schematicCellProps, symbolProps, analogSimulationProps, voltageProbeProps, spicemodelProps, CapacitorProps, ChipProps, DiodeProps, ResistorProps, ManualEditEvent, ManualEditsFile, ChipConnections, manual_edits_file } from '@tscircuit/props';
4
+ import { PlatformConfig, traceProps, netProps, AutorouterProp, AutoroutingPhaseProps, subcircuitGroupProps, AutorouterConfig, PcbSx, portProps, SupplierPartNumbers, CadModelProp, SchematicPortArrangement, groupProps, boardProps, subcircuitProps, subpanelProps, capacitorProps, chipProps, pinoutProps, diodeProps, fuseProps, jumperProps, interconnectProps, solderjumperProps, ledProps, powerSourceProps, voltageSourceProps, currentSourceProps, ammeterProps, resistorProps, constraintProps, internalCircuitProps, drcCheckProps, autoroutingPhaseProps, 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, silkscreenGraphicProps, smtPadProps, fiducialProps, differentialPairProps, traceHintProps, viaProps, copperPourProps, copperTextProps, cutoutProps, enclosureCutoutApertureProps, enclosureFdmBoxProps, batteryProps, pinHeaderProps, resonatorProps, inductorProps, potentiometerProps, pushButtonProps, crystalProps, CrystalPinLabels, transistorProps, mosfetProps, opampProps, OpAmpPinLabels, switchProps, SwitchProps, testpointProps, schematicTextProps, schematicLineProps, schematicRectProps, schematicArcProps, schematicCircleProps, schematicPathProps, schematicBoxProps, schematicSectionProps, schematicSheetProps, schematicTableProps, schematicRowProps, schematicCellProps, symbolProps, analogSimulationProps, voltageProbeProps, spicemodelProps, EnclosureCutoutApertureProps, EnclosureFdmBoxProps, 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 } from 'react';
@@ -11,10 +11,11 @@ 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 { PackSolver2 } from 'calculate-packing';
15
14
  import { AutoroutingPipelineSolver, AssignableAutoroutingPipeline2, AssignableAutoroutingPipeline3, AutoroutingPipeline1_OriginalUnravel, AutoroutingPipelineSolver3_HgPortPointPathing, AutoroutingPipelineSolver4, AutoroutingPipelineSolver5, AutoroutingPipelineSolver8, SimplifiedPcbTrace as SimplifiedPcbTrace$1, SimpleRouteJson as SimpleRouteJson$1 } from '@tscircuit/capacity-autorouter';
16
15
  import { CopperPourPipelineSolver } from '@tscircuit/copper-pour-solver';
16
+ import { CreateFdmEnclosureSolver, EnclosureApertureInput } from '@tscircuit/create-fdm-enclosure';
17
17
  import { SchematicTracePipelineSolver } from '@tscircuit/schematic-trace-solver';
18
+ import { PackSolver2 } from 'calculate-packing';
18
19
  import { Bounds } from '@tscircuit/math-utils';
19
20
  import { ConnectivityMap } from 'circuit-json-to-connectivity-map';
20
21
  import { GraphicsObject } from 'graphics-debug';
@@ -31,6 +32,7 @@ declare const SOLVERS: {
31
32
  AutoroutingPipelineSolver7_MultiGraph: typeof AutoroutingPipelineSolver;
32
33
  AutoroutingPipelineSolver8: typeof AutoroutingPipelineSolver8;
33
34
  CopperPourPipelineSolver: typeof CopperPourPipelineSolver;
35
+ CreateFdmEnclosureSolver: typeof CreateFdmEnclosureSolver;
34
36
  SchematicTracePipelineSolver: typeof SchematicTracePipelineSolver;
35
37
  };
36
38
  type SolverName = keyof typeof SOLVERS;
@@ -6320,7 +6322,7 @@ declare class Subpanel extends Group<typeof subpanelProps> {
6320
6322
  topMargin?: string | number | undefined;
6321
6323
  bottomMargin?: string | number | undefined;
6322
6324
  }>>>;
6323
- }, "width" | "children" | "height" | "layoutMode"> & {
6325
+ }, "width" | "height" | "children" | "layoutMode"> & {
6324
6326
  width: zod.ZodOptional<zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>>;
6325
6327
  height: zod.ZodOptional<zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>>;
6326
6328
  children: zod.ZodOptional<zod.ZodAny>;
@@ -7524,7 +7526,7 @@ declare class Panel extends Subpanel {
7524
7526
  topMargin?: string | number | undefined;
7525
7527
  bottomMargin?: string | number | undefined;
7526
7528
  }>>>;
7527
- }, "width" | "children" | "height" | "layoutMode"> & {
7529
+ }, "width" | "height" | "children" | "layoutMode"> & {
7528
7530
  width: zod.ZodOptional<zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>>;
7529
7531
  height: zod.ZodOptional<zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>>;
7530
7532
  children: zod.ZodOptional<zod.ZodAny>;
@@ -90489,6 +90491,98 @@ declare class Cutout extends PrimitiveComponent<typeof cutoutProps> {
90489
90491
  }): void;
90490
90492
  }
90491
90493
 
90494
+ interface GetFdmEnclosureSolverInputParams {
90495
+ board: Board;
90496
+ pcbBoard: PcbBoard;
90497
+ floorThickness: number;
90498
+ }
90499
+
90500
+ /**
90501
+ * Metadata consumed by enclosure generators. The aperture itself does not emit
90502
+ * Circuit JSON; its nearest ancestor with a pcb_component determines where the
90503
+ * enclosure opening is placed.
90504
+ */
90505
+ declare class EnclosureCutoutAperture extends PrimitiveComponent<typeof enclosureCutoutApertureProps> {
90506
+ get config(): {
90507
+ componentName: string;
90508
+ zodProps: zod.ZodDiscriminatedUnion<"shape", [zod.ZodObject<{
90509
+ shape: zod.ZodLiteral<"pill">;
90510
+ width: zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>;
90511
+ height: zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>;
90512
+ } & {
90513
+ margin: zod.ZodOptional<zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>>;
90514
+ }, "strip", zod.ZodTypeAny, {
90515
+ shape: "pill";
90516
+ width: number;
90517
+ height: number;
90518
+ margin?: number | undefined;
90519
+ }, {
90520
+ shape: "pill";
90521
+ width: string | number;
90522
+ height: string | number;
90523
+ margin?: string | number | undefined;
90524
+ }>, zod.ZodObject<{
90525
+ shape: zod.ZodLiteral<"rect">;
90526
+ width: zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>;
90527
+ height: zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>;
90528
+ } & {
90529
+ margin: zod.ZodOptional<zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>>;
90530
+ }, "strip", zod.ZodTypeAny, {
90531
+ shape: "rect";
90532
+ width: number;
90533
+ height: number;
90534
+ margin?: number | undefined;
90535
+ }, {
90536
+ shape: "rect";
90537
+ width: string | number;
90538
+ height: string | number;
90539
+ margin?: string | number | undefined;
90540
+ }>, zod.ZodObject<{
90541
+ shape: zod.ZodLiteral<"circle">;
90542
+ radius: zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>;
90543
+ } & {
90544
+ margin: zod.ZodOptional<zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>>;
90545
+ }, "strip", zod.ZodTypeAny, {
90546
+ shape: "circle";
90547
+ radius: number;
90548
+ margin?: number | undefined;
90549
+ }, {
90550
+ shape: "circle";
90551
+ radius: string | number;
90552
+ margin?: string | number | undefined;
90553
+ }>]>;
90554
+ };
90555
+ getFdmEnclosureSolverInput(params: GetFdmEnclosureSolverInputParams): EnclosureApertureInput;
90556
+ }
90557
+
90558
+ declare class EnclosureFdmBox extends PrimitiveComponent<typeof enclosureFdmBoxProps> {
90559
+ get config(): {
90560
+ componentName: string;
90561
+ zodProps: zod.ZodObject<{
90562
+ boardRef: zod.ZodString;
90563
+ width: zod.ZodOptional<zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>>;
90564
+ height: zod.ZodOptional<zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>>;
90565
+ depth: zod.ZodOptional<zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>>;
90566
+ wallThickness: zod.ZodDefault<zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>>;
90567
+ }, "strip", zod.ZodTypeAny, {
90568
+ boardRef: string;
90569
+ wallThickness: number;
90570
+ width?: number | undefined;
90571
+ height?: number | undefined;
90572
+ depth?: number | undefined;
90573
+ }, {
90574
+ boardRef: string;
90575
+ width?: string | number | undefined;
90576
+ height?: string | number | undefined;
90577
+ depth?: string | number | undefined;
90578
+ wallThickness?: string | number | undefined;
90579
+ }>;
90580
+ };
90581
+ doInitialSourceRender(): void;
90582
+ doInitialPcbComponentRender(): void;
90583
+ doInitialCadModelRender(): void;
90584
+ }
90585
+
90492
90586
  declare class Battery extends NormalComponent<typeof batteryProps, PassivePorts> {
90493
90587
  get config(): {
90494
90588
  componentName: string;
@@ -153236,6 +153330,7 @@ declare class SchematicBox extends PrimitiveComponent<typeof schematicBoxProps>
153236
153330
  }>;
153237
153331
  shouldRenderAsSchematicBox: boolean;
153238
153332
  };
153333
+ doInitialSchematicComponentRender(): void;
153239
153334
  doInitialSchematicPrimitiveRender(): void;
153240
153335
  }
153241
153336
 
@@ -158042,6 +158137,14 @@ declare class SpiceModel extends PrimitiveComponent<typeof spicemodelProps> {
158042
158137
  private _insertSpiceModelError;
158043
158138
  }
158044
158139
 
158140
+ declare const enclosure: {
158141
+ readonly cutoutaperture: react.FunctionComponent<EnclosureCutoutApertureProps>;
158142
+ readonly fdm: {
158143
+ readonly box: react.FunctionComponent<EnclosureFdmBoxProps>;
158144
+ readonly Box: react.FunctionComponent<EnclosureFdmBoxProps>;
158145
+ };
158146
+ };
158147
+
158045
158148
  declare function resolveStaticFileImport(path: string, platform?: PlatformConfig): Promise<string>;
158046
158149
 
158047
158150
  declare class RootCircuit extends IsolatedCircuit {
@@ -159574,4 +159677,4 @@ declare module "react/jsx-runtime" {
159574
159677
  }
159575
159678
  }
159576
159679
 
159577
- export { Ammeter, AnalogSimulation, type AsyncEffect, type AutorouterCompleteEvent, type AutorouterErrorEvent, type AutorouterEvent, type AutorouterProgressEvent, type AutoroutingEndEvent, type AutoroutingErrorEvent, AutoroutingPhase, type AutoroutingProgressEvent, type AutoroutingStartEvent, Battery, Board, Breakout, BreakoutPoint, CadAssembly, CadModel, Capacitor, Chip, Circuit, type ComponentWithPins, Connector, Constraint, CopperPour, CopperText, CourtyardCircle, CourtyardOutline, CourtyardRect, Crystal, CurrentSource, Cutout, type DebugLogOutputEvent, DifferentialPair, Diode, DrcCheck, FabricationNoteDimension, FabricationNotePath, FabricationNoteRect, FabricationNoteText, Breakout as Fanout, BreakoutPoint as FanoutPoint, Fiducial, Footprint, Fuse, type GenericConnectionsAndSelectorsSel, type GenericLocalAutorouter, Group, Hole, type IIsolatedCircuit, type IRenderable, type IRootCircuit, Inductor, Interconnect, InternalCircuit, InternalCircuitMosfet, IsolatedCircuit, Jumper, Keepout, Led, type LocalCacheEngine, Mosfet, MountedBoard, Net, NetLabel, NormalComponent, type Obstacle, OpAmp, type PackingEndEvent, type PackingErrorEvent, type PackingStartEvent, Panel, PcbNoteDimension, PcbNoteLine, PcbNotePath, PcbNoteRect, PcbNoteText, PcbTrace, PcbVia, PinHeader, type PinLabelSpec, Pinout, PlatedHole, Port, Potentiometer, PowerSource, PrimitiveComponent, Project, PushButton, type RenderPhase, type RenderPhaseFn, type RenderPhaseFunctions, type RenderPhaseStates, Renderable, Resistor, Resonator, RootCircuit, type RootCircuitEventName, SOLVERS, SchematicArc, SchematicBox, SchematicCell, SchematicCircle, SchematicLine, SchematicPath, SchematicRect, SchematicRow, SchematicSection, SchematicSheet, SchematicTable, SchematicText, type Sel, SilkscreenCircle, SilkscreenGraphic, SilkscreenLine, SilkscreenPath, SilkscreenRect, SilkscreenText, type SimpleRouteConnection, type SimpleRouteDifferentialPair, type SimpleRouteJson, type SimplifiedPcbTrace, SmtPad, SolderJumper, type SolverName, type SolverStartedEvent, SpiceModel, type SrjConnectionName, Subcircuit, Subpanel, Switch, SymbolComponent as Symbol, TestPoint, Trace, TraceHint, Transistor, Via, VoltageProbe, VoltageSource, applyEditEvents, applyEditEventsToManualEditsFile, applyPcbEditEventsToManualEditsFile, applySchematicEditEventsToManualEditsFile, createUseComponent, getPhaseTimingsFromRenderEvents, getSimpleRouteJsonFromCircuitJson, normalizePinLabels, orderedRenderPhases, renderPhaseIndexMap, resolveStaticFileImport, sel, unrouteCircuitJson, useCapacitor, useChip, useDiode, useLed, useRenderedCircuit, useResistor };
159680
+ export { Ammeter, AnalogSimulation, type AsyncEffect, type AutorouterCompleteEvent, type AutorouterErrorEvent, type AutorouterEvent, type AutorouterProgressEvent, type AutoroutingEndEvent, type AutoroutingErrorEvent, AutoroutingPhase, type AutoroutingProgressEvent, type AutoroutingStartEvent, Battery, Board, Breakout, BreakoutPoint, CadAssembly, CadModel, Capacitor, Chip, Circuit, type ComponentWithPins, Connector, Constraint, CopperPour, CopperText, CourtyardCircle, CourtyardOutline, CourtyardRect, Crystal, CurrentSource, Cutout, type DebugLogOutputEvent, DifferentialPair, Diode, DrcCheck, EnclosureCutoutAperture, EnclosureFdmBox, FabricationNoteDimension, FabricationNotePath, FabricationNoteRect, FabricationNoteText, Breakout as Fanout, BreakoutPoint as FanoutPoint, Fiducial, Footprint, Fuse, type GenericConnectionsAndSelectorsSel, type GenericLocalAutorouter, Group, Hole, type IIsolatedCircuit, type IRenderable, type IRootCircuit, Inductor, Interconnect, InternalCircuit, InternalCircuitMosfet, IsolatedCircuit, Jumper, Keepout, Led, type LocalCacheEngine, Mosfet, MountedBoard, Net, NetLabel, NormalComponent, type Obstacle, OpAmp, type PackingEndEvent, type PackingErrorEvent, type PackingStartEvent, Panel, PcbNoteDimension, PcbNoteLine, PcbNotePath, PcbNoteRect, PcbNoteText, PcbTrace, PcbVia, PinHeader, type PinLabelSpec, Pinout, PlatedHole, Port, Potentiometer, PowerSource, PrimitiveComponent, Project, PushButton, type RenderPhase, type RenderPhaseFn, type RenderPhaseFunctions, type RenderPhaseStates, Renderable, Resistor, Resonator, RootCircuit, type RootCircuitEventName, SOLVERS, SchematicArc, SchematicBox, SchematicCell, SchematicCircle, SchematicLine, SchematicPath, SchematicRect, SchematicRow, SchematicSection, SchematicSheet, SchematicTable, SchematicText, type Sel, SilkscreenCircle, SilkscreenGraphic, SilkscreenLine, SilkscreenPath, SilkscreenRect, SilkscreenText, type SimpleRouteConnection, type SimpleRouteDifferentialPair, type SimpleRouteJson, type SimplifiedPcbTrace, SmtPad, SolderJumper, type SolverName, type SolverStartedEvent, SpiceModel, type SrjConnectionName, Subcircuit, Subpanel, Switch, SymbolComponent as Symbol, TestPoint, Trace, TraceHint, Transistor, Via, VoltageProbe, VoltageSource, applyEditEvents, applyEditEventsToManualEditsFile, applyPcbEditEventsToManualEditsFile, applySchematicEditEventsToManualEditsFile, createUseComponent, enclosure, getPhaseTimingsFromRenderEvents, getSimpleRouteJsonFromCircuitJson, normalizePinLabels, orderedRenderPhases, renderPhaseIndexMap, resolveStaticFileImport, sel, unrouteCircuitJson, useCapacitor, useChip, useDiode, useLed, useRenderedCircuit, useResistor };
package/dist/index.js CHANGED
@@ -31,6 +31,8 @@ __export(components_exports, {
31
31
  DifferentialPair: () => DifferentialPair,
32
32
  Diode: () => Diode,
33
33
  DrcCheck: () => DrcCheck,
34
+ EnclosureCutoutAperture: () => EnclosureCutoutAperture,
35
+ EnclosureFdmBox: () => EnclosureFdmBox,
34
36
  FabricationNoteDimension: () => FabricationNoteDimension,
35
37
  FabricationNotePath: () => FabricationNotePath,
36
38
  FabricationNoteRect: () => FabricationNoteRect,
@@ -5116,7 +5118,33 @@ var Trace_doInitialSchematicTraceRender = (trace) => {
5116
5118
  }
5117
5119
  const { netsWithSelectors } = trace._findConnectedNets();
5118
5120
  if (!allPortsFound) return;
5119
- const portIds = connectedPorts.map((p) => p.port.schematic_port_id).sort();
5121
+ const resolveSchematicPortForSheet = (port) => {
5122
+ if (schematicSheetId && port.source_port_id) {
5123
+ const sheetSchematicPort = db.schematic_port.getWhere({
5124
+ source_port_id: port.source_port_id,
5125
+ schematic_sheet_id: schematicSheetId
5126
+ });
5127
+ if (sheetSchematicPort) return sheetSchematicPort;
5128
+ }
5129
+ if (!port.schematic_port_id) return null;
5130
+ return db.schematic_port.get(port.schematic_port_id) ?? null;
5131
+ };
5132
+ const portsWithPosition = connectedPorts.flatMap(({ port }) => {
5133
+ const schematicPort = resolveSchematicPortForSheet(port);
5134
+ if (!schematicPort) return [];
5135
+ return [
5136
+ {
5137
+ port,
5138
+ position: schematicPort.center,
5139
+ schematic_port_id: schematicPort.schematic_port_id,
5140
+ facingDirection: schematicPort.facing_direction ?? null
5141
+ }
5142
+ ];
5143
+ });
5144
+ const portIds = portsWithPosition.map(({ schematic_port_id }) => schematic_port_id).sort();
5145
+ const hasSheetLocalSchematicPortRepresentation = portsWithPosition.some(
5146
+ ({ port, schematic_port_id }) => port.schematic_port_id !== schematic_port_id
5147
+ );
5120
5148
  const portPairKey = portIds.join(",");
5121
5149
  const board = trace.root?._getBoard();
5122
5150
  if (board?._connectedSchematicPortPairs) {
@@ -5129,12 +5157,6 @@ var Trace_doInitialSchematicTraceRender = (trace) => {
5129
5157
  pointsToConnect: []
5130
5158
  };
5131
5159
  const obstacles = getSchematicObstaclesForTrace(trace);
5132
- const portsWithPosition = connectedPorts.filter(({ port }) => port.schematic_port_id !== null).map(({ port }) => ({
5133
- port,
5134
- position: port._getGlobalSchematicPositionAfterLayout(),
5135
- schematic_port_id: port.schematic_port_id ?? void 0,
5136
- facingDirection: port.facingDirection
5137
- }));
5138
5160
  const isPortAndNetConnection = portsWithPosition.length === 1 && netsWithSelectors.length === 1;
5139
5161
  if (isPortAndNetConnection) {
5140
5162
  const net = netsWithSelectors[0].net;
@@ -5219,7 +5241,7 @@ var Trace_doInitialSchematicTraceRender = (trace) => {
5219
5241
  });
5220
5242
  return;
5221
5243
  }
5222
- if (schematicNetLabelText) {
5244
+ if (schematicNetLabelText && !hasSheetLocalSchematicPortRepresentation) {
5223
5245
  if ("from" in trace.props && "to" in trace.props || "path" in trace.props) {
5224
5246
  trace._doInitialSchematicTraceRenderWithDisplayLabel();
5225
5247
  return;
@@ -5353,7 +5375,7 @@ var Trace_doInitialSchematicTraceRender = (trace) => {
5353
5375
  });
5354
5376
  let results = autorouter.solveAndMapToTraces();
5355
5377
  if (results.length === 0) {
5356
- if (trace._isSymbolToChipConnection() || trace._isSymbolToSymbolConnection() || trace._isChipToChipConnection()) {
5378
+ if (!hasSheetLocalSchematicPortRepresentation && (trace._isSymbolToChipConnection() || trace._isSymbolToSymbolConnection() || trace._isChipToChipConnection())) {
5357
5379
  trace._doInitialSchematicTraceRenderWithDisplayLabel();
5358
5380
  return;
5359
5381
  }
@@ -5418,7 +5440,7 @@ var Trace_doInitialSchematicTraceRender = (trace) => {
5418
5440
  if (!trace.source_trace_id) {
5419
5441
  throw new Error("Missing source_trace_id for schematic trace insertion.");
5420
5442
  }
5421
- if (trace.getSubcircuit()._parsedProps.schTraceAutoLabelEnabled && countComplexElements(junctions, edges) >= 5 && (trace._isSymbolToChipConnection() || trace._isSymbolToSymbolConnection() || trace._isChipToChipConnection())) {
5443
+ if (!hasSheetLocalSchematicPortRepresentation && trace.getSubcircuit()._parsedProps.schTraceAutoLabelEnabled && countComplexElements(junctions, edges) >= 5 && (trace._isSymbolToChipConnection() || trace._isSymbolToSymbolConnection() || trace._isChipToChipConnection())) {
5422
5444
  trace._doInitialSchematicTraceRenderWithDisplayLabel();
5423
5445
  return;
5424
5446
  }
@@ -5430,10 +5452,8 @@ var Trace_doInitialSchematicTraceRender = (trace) => {
5430
5452
  schematic_sheet_id: schematicSheetId
5431
5453
  });
5432
5454
  trace.schematic_trace_id = dbTrace.schematic_trace_id;
5433
- for (const { port } of connectedPorts) {
5434
- if (port.schematic_port_id) {
5435
- db.schematic_port.update(port.schematic_port_id, { is_connected: true });
5436
- }
5455
+ for (const { schematic_port_id } of portsWithPosition) {
5456
+ db.schematic_port.update(schematic_port_id, { is_connected: true });
5437
5457
  }
5438
5458
  if (board?._connectedSchematicPortPairs)
5439
5459
  board._connectedSchematicPortPairs.add(portPairKey);
@@ -15750,12 +15770,11 @@ import Debug14 from "debug";
15750
15770
  import "@tscircuit/capacity-autorouter";
15751
15771
 
15752
15772
  // lib/solvers.ts
15753
- import { PackSolver2 } from "calculate-packing";
15754
15773
  import {
15755
- AutoroutingPipelineSolver,
15756
15774
  AssignableAutoroutingPipeline2,
15757
- AutoroutingPipeline1_OriginalUnravel,
15758
15775
  AssignableAutoroutingPipeline3,
15776
+ AutoroutingPipeline1_OriginalUnravel,
15777
+ AutoroutingPipelineSolver,
15759
15778
  AutoroutingPipelineSolver3_HgPortPointPathing,
15760
15779
  AutoroutingPipelineSolver4,
15761
15780
  AutoroutingPipelineSolver5,
@@ -15763,7 +15782,9 @@ import {
15763
15782
  AutoroutingPipelineSolver8
15764
15783
  } from "@tscircuit/capacity-autorouter";
15765
15784
  import { CopperPourPipelineSolver } from "@tscircuit/copper-pour-solver";
15785
+ import { CreateFdmEnclosureSolver } from "@tscircuit/create-fdm-enclosure";
15766
15786
  import { SchematicTracePipelineSolver } from "@tscircuit/schematic-trace-solver";
15787
+ import { PackSolver2 } from "calculate-packing";
15767
15788
  var SOLVERS = {
15768
15789
  PackSolver2,
15769
15790
  AutoroutingPipelineSolver,
@@ -15776,6 +15797,7 @@ var SOLVERS = {
15776
15797
  AutoroutingPipelineSolver7_MultiGraph,
15777
15798
  AutoroutingPipelineSolver8,
15778
15799
  CopperPourPipelineSolver,
15800
+ CreateFdmEnclosureSolver,
15779
15801
  SchematicTracePipelineSolver
15780
15802
  };
15781
15803
 
@@ -20240,9 +20262,9 @@ function applySchematicMatchPackLayoutToTree(group, tree, opts = {}) {
20240
20262
  import {
20241
20263
  getCircuitJsonTree as getCircuitJsonTree2
20242
20264
  } from "@tscircuit/circuit-json-util";
20243
- function getSchematicSheetIdBySourceGroupId({
20265
+ function getSchematicSheetIdsBySourceGroupId({
20244
20266
  circuitJson,
20245
- schematicSheetIdBySourceComponentId
20267
+ schematicSheetIdsBySourceComponentId
20246
20268
  }) {
20247
20269
  const parentBySourceGroupId = /* @__PURE__ */ new Map();
20248
20270
  for (const element of circuitJson) {
@@ -20253,36 +20275,45 @@ function getSchematicSheetIdBySourceGroupId({
20253
20275
  );
20254
20276
  }
20255
20277
  }
20256
- const schematicSheetIdBySourceGroupId = /* @__PURE__ */ new Map();
20278
+ const schematicSheetIdsBySourceGroupId = /* @__PURE__ */ new Map();
20257
20279
  for (const element of circuitJson) {
20258
20280
  if (element.type !== "source_component") continue;
20259
20281
  if (!element.source_group_id) continue;
20260
- const schematicSheetId = schematicSheetIdBySourceComponentId.get(
20282
+ const schematicSheetIds = schematicSheetIdsBySourceComponentId.get(
20261
20283
  element.source_component_id
20262
20284
  );
20263
- if (schematicSheetId === void 0) continue;
20264
- let sourceGroupId = element.source_group_id;
20265
- while (sourceGroupId && !schematicSheetIdBySourceGroupId.has(sourceGroupId)) {
20266
- schematicSheetIdBySourceGroupId.set(sourceGroupId, schematicSheetId);
20267
- sourceGroupId = parentBySourceGroupId.get(sourceGroupId);
20285
+ if (schematicSheetIds === void 0) continue;
20286
+ for (const schematicSheetId of schematicSheetIds) {
20287
+ let sourceGroupId = element.source_group_id;
20288
+ const visitedSourceGroupIds = /* @__PURE__ */ new Set();
20289
+ while (sourceGroupId && !visitedSourceGroupIds.has(sourceGroupId)) {
20290
+ visitedSourceGroupIds.add(sourceGroupId);
20291
+ const groupSchematicSheetIds = schematicSheetIdsBySourceGroupId.get(sourceGroupId) ?? /* @__PURE__ */ new Set();
20292
+ groupSchematicSheetIds.add(schematicSheetId);
20293
+ schematicSheetIdsBySourceGroupId.set(
20294
+ sourceGroupId,
20295
+ groupSchematicSheetIds
20296
+ );
20297
+ sourceGroupId = parentBySourceGroupId.get(sourceGroupId);
20298
+ }
20268
20299
  }
20269
20300
  }
20270
- return schematicSheetIdBySourceGroupId;
20301
+ return schematicSheetIdsBySourceGroupId;
20271
20302
  }
20272
20303
  function getCircuitJsonScopedToSchematicSheet({
20273
20304
  circuitJson,
20274
20305
  schematicSheetId,
20275
20306
  rootSourceGroupId,
20276
- schematicSheetIdBySourceComponentId,
20277
- schematicSheetIdBySourceGroupId
20307
+ schematicSheetIdsBySourceComponentId,
20308
+ schematicSheetIdsBySourceGroupId
20278
20309
  }) {
20279
- const isGroupOnSheet = (sourceGroupId) => sourceGroupId === rootSourceGroupId || schematicSheetIdBySourceGroupId.get(sourceGroupId) === schematicSheetId;
20310
+ const isGroupOnSheet = (sourceGroupId) => sourceGroupId === rootSourceGroupId || schematicSheetIdsBySourceGroupId.get(sourceGroupId)?.has(schematicSheetId) === true;
20280
20311
  return circuitJson.filter((element) => {
20281
20312
  if (element.type === "source_group") {
20282
20313
  return isGroupOnSheet(element.source_group_id);
20283
20314
  }
20284
20315
  if (element.type === "source_component") {
20285
- if (schematicSheetIdBySourceComponentId.get(element.source_component_id) !== schematicSheetId) {
20316
+ if (schematicSheetIdsBySourceComponentId.get(element.source_component_id)?.has(schematicSheetId) !== true) {
20286
20317
  return false;
20287
20318
  }
20288
20319
  return element.source_group_id ? isGroupOnSheet(element.source_group_id) : true;
@@ -20292,19 +20323,24 @@ function getCircuitJsonScopedToSchematicSheet({
20292
20323
  }
20293
20324
  function getSchematicCircuitJsonTrees(circuitJson, opts) {
20294
20325
  const { source_group_id } = opts;
20295
- const schematicSheetIdBySourceComponentId = /* @__PURE__ */ new Map();
20326
+ const schematicSheetIdsBySourceComponentId = /* @__PURE__ */ new Map();
20296
20327
  for (const element of circuitJson) {
20297
20328
  if (element.type !== "schematic_component") continue;
20298
20329
  if (!element.source_component_id) continue;
20299
20330
  if (!element.schematic_sheet_id) continue;
20300
- schematicSheetIdBySourceComponentId.set(
20331
+ const schematicSheetIds2 = schematicSheetIdsBySourceComponentId.get(element.source_component_id) ?? /* @__PURE__ */ new Set();
20332
+ schematicSheetIds2.add(element.schematic_sheet_id);
20333
+ schematicSheetIdsBySourceComponentId.set(
20301
20334
  element.source_component_id,
20302
- element.schematic_sheet_id
20335
+ schematicSheetIds2
20303
20336
  );
20304
20337
  }
20305
- const schematicSheetIds = new Set(
20306
- schematicSheetIdBySourceComponentId.values()
20307
- );
20338
+ const schematicSheetIds = /* @__PURE__ */ new Set();
20339
+ for (const componentSchematicSheetIds of schematicSheetIdsBySourceComponentId.values()) {
20340
+ for (const schematicSheetId of componentSchematicSheetIds) {
20341
+ schematicSheetIds.add(schematicSheetId);
20342
+ }
20343
+ }
20308
20344
  if (schematicSheetIds.size <= 1) {
20309
20345
  return [
20310
20346
  {
@@ -20313,9 +20349,9 @@ function getSchematicCircuitJsonTrees(circuitJson, opts) {
20313
20349
  }
20314
20350
  ];
20315
20351
  }
20316
- const schematicSheetIdBySourceGroupId = getSchematicSheetIdBySourceGroupId({
20352
+ const schematicSheetIdsBySourceGroupId = getSchematicSheetIdsBySourceGroupId({
20317
20353
  circuitJson,
20318
- schematicSheetIdBySourceComponentId
20354
+ schematicSheetIdsBySourceComponentId
20319
20355
  });
20320
20356
  return Array.from(schematicSheetIds).map((schematicSheetId) => ({
20321
20357
  tree: getCircuitJsonTree2(
@@ -20323,8 +20359,8 @@ function getSchematicCircuitJsonTrees(circuitJson, opts) {
20323
20359
  circuitJson,
20324
20360
  schematicSheetId,
20325
20361
  rootSourceGroupId: source_group_id,
20326
- schematicSheetIdBySourceComponentId,
20327
- schematicSheetIdBySourceGroupId
20362
+ schematicSheetIdsBySourceComponentId,
20363
+ schematicSheetIdsBySourceGroupId
20328
20364
  }),
20329
20365
  { source_group_id }
20330
20366
  ),
@@ -20645,7 +20681,7 @@ var getSchematicPortSelector = ({
20645
20681
  // lib/components/primitive-components/Group/Group_doInitialSchematicTraceRender/createSchematicTraceSolverInputProblem.ts
20646
20682
  var DEFAULT_MAX_MSP_PAIR_DISTANCE = 2.4;
20647
20683
  var SCHEMATIC_RAIL_NET_LABEL_HEIGHT = 0.42;
20648
- function createSchematicTraceSolverInputProblem(group) {
20684
+ function createSchematicTraceSolverInputProblem(group, opts = {}) {
20649
20685
  const { db } = group.root;
20650
20686
  const connKeyToSourceNet = /* @__PURE__ */ new Map();
20651
20687
  const childGroups = [];
@@ -20665,7 +20701,9 @@ function createSchematicTraceSolverInputProblem(group) {
20665
20701
  group.schematic_group_id,
20666
20702
  ...childGroups.map((a) => a.schematic_group_id)
20667
20703
  ];
20668
- const schematicComponents = db.schematic_component.list().filter((a) => allSchematicGroupIds.includes(a.schematic_group_id));
20704
+ const schematicComponents = db.schematic_component.list().filter((a) => allSchematicGroupIds.includes(a.schematic_group_id)).filter(
20705
+ (schematicComponent) => opts.schematicSheetId === void 0 || schematicComponent.schematic_sheet_id === opts.schematicSheetId
20706
+ );
20669
20707
  const schematicComponentIds = new Set(
20670
20708
  schematicComponents.map((component) => component.schematic_component_id)
20671
20709
  );
@@ -20807,8 +20845,8 @@ function createSchematicTraceSolverInputProblem(group) {
20807
20845
  if (st.subcircuit_id && !allowedSubcircuitIds.has(st.subcircuit_id)) {
20808
20846
  continue;
20809
20847
  }
20810
- const connected = (st.connected_source_port_ids ?? []).map((srcId) => sourcePortIdToSchPortId.get(srcId)).filter(
20811
- (sourcePortId) => Boolean(sourcePortId) && allSourceAndSchematicPortIdsInScope.has(sourcePortId)
20848
+ const connected = (st.connected_source_port_ids ?? []).map((sourcePortId) => sourcePortIdToSchPortId.get(sourcePortId)).filter(
20849
+ (schematicPortId) => Boolean(schematicPortId) && allSourceAndSchematicPortIdsInScope.has(schematicPortId)
20812
20850
  );
20813
20851
  if (connected.length >= 2) {
20814
20852
  const [a, b] = connected.slice(0, 2);
@@ -22082,10 +22120,10 @@ var getSchematicPortIdsWithRoutedTraces = ({
22082
22120
 
22083
22121
  // lib/components/primitive-components/Group/Group_doInitialSchematicTraceRender/Group_doInitialSchematicTraceRender.ts
22084
22122
  var debug10 = Debug12("Group_doInitialSchematicTraceRender");
22085
- var Group_doInitialSchematicTraceRender = (group) => {
22086
- if (!group.root?._featureMspSchematicTraceRouting) return;
22087
- if (!group.isSubcircuit) return;
22088
- if (group.root?.schematicDisabled) return;
22123
+ var renderSchematicTracesForSheet = ({
22124
+ group,
22125
+ schematicSheetId
22126
+ }) => {
22089
22127
  const {
22090
22128
  inputProblem,
22091
22129
  pinIdToSchematicPortId,
@@ -22094,7 +22132,7 @@ var Group_doInitialSchematicTraceRender = (group) => {
22094
22132
  schPortIdToSourcePortId,
22095
22133
  userNetIdToConnKey,
22096
22134
  connKeysWithExplicitPortNetTraces
22097
- } = createSchematicTraceSolverInputProblem(group);
22135
+ } = createSchematicTraceSolverInputProblem(group, { schematicSheetId });
22098
22136
  if (inputProblem.chips.length === 0) return;
22099
22137
  const schematicPortIdsWithPreExistingNetLabels = getSchematicPortIdsWithAssignedNetLabels(group);
22100
22138
  const hasRouteableSchematicConnections = inputProblem.directConnections.length > 0 || inputProblem.netConnections.length > 0;
@@ -22152,6 +22190,35 @@ var Group_doInitialSchematicTraceRender = (group) => {
22152
22190
  connKeyToSourceNet
22153
22191
  });
22154
22192
  };
22193
+ var Group_doInitialSchematicTraceRender = (group) => {
22194
+ if (!group.root?._featureMspSchematicTraceRouting) return;
22195
+ if (!group.isSubcircuit) return;
22196
+ if (group.root?.schematicDisabled) return;
22197
+ const schematicGroupIds = new Set(
22198
+ [
22199
+ group,
22200
+ ...group.getDescendants().filter(
22201
+ (component) => component instanceof Group
22202
+ )
22203
+ ].map((schematicGroup) => schematicGroup.schematic_group_id).filter(
22204
+ (schematicGroupId) => Boolean(schematicGroupId)
22205
+ )
22206
+ );
22207
+ const schematicSheetIds = new Set(
22208
+ group.root.db.schematic_component.list().filter(
22209
+ (schematicComponent) => schematicGroupIds.has(schematicComponent.schematic_group_id)
22210
+ ).map((schematicComponent) => schematicComponent.schematic_sheet_id).filter(
22211
+ (schematicSheetId) => Boolean(schematicSheetId)
22212
+ )
22213
+ );
22214
+ if (schematicSheetIds.size === 0) {
22215
+ renderSchematicTracesForSheet({ group });
22216
+ return;
22217
+ }
22218
+ for (const schematicSheetId of schematicSheetIds) {
22219
+ renderSchematicTracesForSheet({ group, schematicSheetId });
22220
+ }
22221
+ };
22155
22222
 
22156
22223
  // lib/components/primitive-components/Group/Group_doInitialSimulationSpiceEngineRender.ts
22157
22224
  import { circuitJsonToSpice } from "circuit-json-to-spice";
@@ -22911,7 +22978,7 @@ function Group_getRoutingPhasePlans(group) {
22911
22978
  var package_default = {
22912
22979
  name: "@tscircuit/core",
22913
22980
  type: "module",
22914
- version: "0.0.1474",
22981
+ version: "0.0.1476",
22915
22982
  types: "dist/index.d.ts",
22916
22983
  main: "dist/index.js",
22917
22984
  module: "dist/index.js",
@@ -22949,6 +23016,7 @@ var package_default = {
22949
23016
  "@tscircuit/circuit-json-util": "^0.0.97",
22950
23017
  "@tscircuit/common": "^0.0.20",
22951
23018
  "@tscircuit/copper-pour-solver": "0.0.39",
23019
+ "@tscircuit/create-fdm-enclosure": "0.0.2",
22952
23020
  "@tscircuit/footprinter": "^0.0.380",
22953
23021
  "@tscircuit/image-utils": "^0.0.8",
22954
23022
  "@tscircuit/infer-cable-insertion-point": "^0.0.2",
@@ -22977,7 +23045,7 @@ var package_default = {
22977
23045
  "circuit-json": "^0.0.450",
22978
23046
  "circuit-json-to-bpc": "^0.0.13",
22979
23047
  "circuit-json-to-connectivity-map": "^0.0.23",
22980
- "circuit-json-to-gltf": "^0.0.105",
23048
+ "circuit-json-to-gltf": "^0.0.107",
22981
23049
  "circuit-json-to-spice": "^0.0.43",
22982
23050
  "circuit-to-svg": "^0.0.391",
22983
23051
  concurrently: "^9.1.2",
@@ -23006,6 +23074,7 @@ var package_default = {
23006
23074
  "@tscircuit/capacity-autorouter": "*",
23007
23075
  "@tscircuit/checks": "*",
23008
23076
  "@tscircuit/circuit-json-util": "*",
23077
+ "@tscircuit/create-fdm-enclosure": "*",
23009
23078
  "@tscircuit/footprinter": "*",
23010
23079
  "@tscircuit/infgrid-ijump-astar": "*",
23011
23080
  "@tscircuit/math-utils": "*",
@@ -31653,6 +31722,228 @@ var CopperPour = class extends PrimitiveComponent2 {
31653
31722
  }
31654
31723
  };
31655
31724
 
31725
+ // lib/components/primitive-components/EnclosureCutoutAperture/EnclosureCutoutAperture.ts
31726
+ import { enclosureCutoutApertureProps } from "@tscircuit/props";
31727
+
31728
+ // lib/components/primitive-components/EnclosureCutoutAperture/get-aperture-height.ts
31729
+ var getApertureHeight = (aperture) => {
31730
+ const margin = aperture.margin ?? 0;
31731
+ return aperture.shape === "circle" ? 2 * (aperture.radius + margin) : aperture.height + margin * 2;
31732
+ };
31733
+
31734
+ // lib/components/primitive-components/EnclosureCutoutAperture/get-nearest-board-wall.ts
31735
+ var getNearestBoardWall = ({
31736
+ point: point6,
31737
+ board
31738
+ }) => {
31739
+ const halfWidth = (board.width ?? 0) / 2;
31740
+ const halfHeight = (board.height ?? 0) / 2;
31741
+ const distances = [
31742
+ ["left", Math.abs(point6.x - (board.center.x - halfWidth))],
31743
+ ["right", Math.abs(point6.x - (board.center.x + halfWidth))],
31744
+ ["front", Math.abs(point6.y - (board.center.y - halfHeight))],
31745
+ ["back", Math.abs(point6.y - (board.center.y + halfHeight))]
31746
+ ];
31747
+ distances.sort((a, b) => a[1] - b[1]);
31748
+ return distances[0][0];
31749
+ };
31750
+
31751
+ // lib/components/primitive-components/EnclosureCutoutAperture/get-solver-wall.ts
31752
+ var getSolverWall = (boardWall) => {
31753
+ if (boardWall === "front") return "back";
31754
+ if (boardWall === "back") return "front";
31755
+ return boardWall;
31756
+ };
31757
+
31758
+ // lib/components/primitive-components/EnclosureCutoutAperture/get-fdm-enclosure-solver-input.ts
31759
+ var getFdmEnclosureSolverInput = (apertureComponent, { board, pcbBoard, floorThickness }) => {
31760
+ let owner = apertureComponent.parent;
31761
+ while (owner && owner !== board && !owner.pcb_component_id) {
31762
+ owner = owner.parent;
31763
+ }
31764
+ const pcbComponent = owner?.pcb_component_id ? apertureComponent.root?.db.pcb_component.get(owner.pcb_component_id) : null;
31765
+ if (!pcbComponent) {
31766
+ throw new Error(
31767
+ "<enclosure.cutoutaperture /> must be nested inside a component with a PCB footprint"
31768
+ );
31769
+ }
31770
+ const point6 = pcbComponent.cable_insertion_center ?? pcbComponent.center;
31771
+ const boardWall = getNearestBoardWall({ point: point6, board: pcbBoard });
31772
+ const aperture = apertureComponent._parsedProps;
31773
+ const commonInput = {
31774
+ wall: getSolverWall(boardWall),
31775
+ offset: boardWall === "left" || boardWall === "right" ? -(point6.y - pcbBoard.center.y) : point6.x - pcbBoard.center.x,
31776
+ centerZ: floorThickness + (pcbBoard.thickness ?? board.boardThickness) + getApertureHeight(aperture) / 2,
31777
+ margin: aperture.margin
31778
+ };
31779
+ switch (aperture.shape) {
31780
+ case "pill":
31781
+ case "rect":
31782
+ return {
31783
+ ...commonInput,
31784
+ shape: aperture.shape,
31785
+ width: aperture.width,
31786
+ height: aperture.height
31787
+ };
31788
+ case "circle":
31789
+ return {
31790
+ ...commonInput,
31791
+ shape: "circle",
31792
+ radius: aperture.radius
31793
+ };
31794
+ }
31795
+ };
31796
+
31797
+ // lib/components/primitive-components/EnclosureCutoutAperture/EnclosureCutoutAperture.ts
31798
+ var EnclosureCutoutAperture = class extends PrimitiveComponent2 {
31799
+ get config() {
31800
+ return {
31801
+ componentName: "EnclosureCutoutAperture",
31802
+ zodProps: enclosureCutoutApertureProps
31803
+ };
31804
+ }
31805
+ getFdmEnclosureSolverInput(params) {
31806
+ return getFdmEnclosureSolverInput(this, params);
31807
+ }
31808
+ };
31809
+
31810
+ // lib/components/primitive-components/EnclosureFdmBox.ts
31811
+ import { enclosureFdmBoxProps } from "@tscircuit/props";
31812
+
31813
+ // lib/components/primitive-components/EnclosureFdmBox_doInitialCadModelRender.ts
31814
+ import {
31815
+ CreateFdmEnclosureSolver as CreateFdmEnclosureSolver2
31816
+ } from "@tscircuit/create-fdm-enclosure";
31817
+
31818
+ // lib/components/primitive-components/get-referenced-enclosure-board.ts
31819
+ import { selectOne as selectOne2 } from "css-select";
31820
+ var getReferencedEnclosureBoard = (component, boardRef) => {
31821
+ const rootComponent = component.root?.firstChild;
31822
+ const selectedComponent = rootComponent ? selectOne2(boardRef, rootComponent, {
31823
+ adapter: cssSelectPrimitiveComponentAdapter
31824
+ }) : null;
31825
+ const board = selectedComponent instanceof Board ? selectedComponent : [rootComponent, ...rootComponent?.getDescendants() ?? []].find(
31826
+ (descendant) => descendant instanceof Board && descendant.isMatchingNameOrAlias(boardRef)
31827
+ );
31828
+ if (!(board instanceof Board)) {
31829
+ throw new Error(
31830
+ `Could not find a <board /> matching enclosure boardRef "${boardRef}"`
31831
+ );
31832
+ }
31833
+ return board;
31834
+ };
31835
+
31836
+ // lib/components/primitive-components/EnclosureFdmBox_doInitialCadModelRender.ts
31837
+ var EnclosureFdmBox_doInitialCadModelRender = (component) => {
31838
+ const root = component.root;
31839
+ if (!root || root.pcbDisabled || !component.source_component_id || !component.pcb_component_id) {
31840
+ return;
31841
+ }
31842
+ const { db } = root;
31843
+ const props = component._parsedProps;
31844
+ const board = getReferencedEnclosureBoard(component, props.boardRef);
31845
+ const pcbBoard = board.pcb_board_id ? db.pcb_board.get(board.pcb_board_id) : null;
31846
+ if (!pcbBoard?.width || !pcbBoard.height) {
31847
+ throw new Error(
31848
+ `Could not resolve dimensions for boardRef "${props.boardRef}"`
31849
+ );
31850
+ }
31851
+ const boardThickness = pcbBoard.thickness ?? board.boardThickness;
31852
+ const inputProblem = {
31853
+ board: {
31854
+ width: pcbBoard.width,
31855
+ height: pcbBoard.height,
31856
+ thickness: boardThickness
31857
+ },
31858
+ width: props.width,
31859
+ height: props.height,
31860
+ depth: props.depth,
31861
+ wallThickness: props.wallThickness,
31862
+ apertures: board.getDescendants().filter(
31863
+ (descendant) => descendant instanceof EnclosureCutoutAperture
31864
+ ).map(
31865
+ (aperture) => aperture.getFdmEnclosureSolverInput({
31866
+ board,
31867
+ pcbBoard,
31868
+ floorThickness: props.wallThickness
31869
+ })
31870
+ )
31871
+ };
31872
+ const solver = new CreateFdmEnclosureSolver2(inputProblem);
31873
+ root.emit("solver:started", {
31874
+ type: "solver:started",
31875
+ solverName: "CreateFdmEnclosureSolver",
31876
+ solverParams: solver.getConstructorParams()[0],
31877
+ componentName: component.getString()
31878
+ });
31879
+ solver.solve();
31880
+ if (solver.failed) {
31881
+ throw new Error(solver.error ?? "Failed to create FDM enclosure");
31882
+ }
31883
+ const output = solver.getOutput();
31884
+ db.pcb_component.update(component.pcb_component_id, {
31885
+ center: pcbBoard.center,
31886
+ width: output.dimensions.width,
31887
+ height: output.dimensions.height
31888
+ });
31889
+ const cadComponent = db.cad_component.insert({
31890
+ position: {
31891
+ x: pcbBoard.center.x,
31892
+ y: pcbBoard.center.y,
31893
+ z: -boardThickness / 2 - output.dimensions.floorThickness
31894
+ },
31895
+ rotation: { x: 0, y: 0, z: 0 },
31896
+ pcb_component_id: component.pcb_component_id,
31897
+ source_component_id: component.source_component_id,
31898
+ model_jscad: output.jscadPlan,
31899
+ model_unit_to_mm_scale_factor: 1,
31900
+ model_object_fit: "contain_within_bounds",
31901
+ model_origin_alignment: "bottom_center_of_component",
31902
+ anchor_alignment: "center",
31903
+ show_as_translucent_model: false
31904
+ });
31905
+ component.cad_component_id = cadComponent.cad_component_id;
31906
+ };
31907
+
31908
+ // lib/components/primitive-components/EnclosureFdmBox.ts
31909
+ var EnclosureFdmBox = class extends PrimitiveComponent2 {
31910
+ get config() {
31911
+ return {
31912
+ componentName: "EnclosureFdmBox",
31913
+ zodProps: enclosureFdmBoxProps
31914
+ };
31915
+ }
31916
+ doInitialSourceRender() {
31917
+ const sourceComponent = this.root.db.source_component.insert({
31918
+ ftype: "simple_chip",
31919
+ name: this.name
31920
+ });
31921
+ this.source_component_id = sourceComponent.source_component_id;
31922
+ }
31923
+ doInitialPcbComponentRender() {
31924
+ const root = this.root;
31925
+ if (!root || root.pcbDisabled || !this.source_component_id) return;
31926
+ const board = getReferencedEnclosureBoard(this, this._parsedProps.boardRef);
31927
+ const pcbBoard = board.pcb_board_id ? root.db.pcb_board.get(board.pcb_board_id) : null;
31928
+ const center = pcbBoard?.center ?? board._getGlobalPcbPositionBeforeLayout();
31929
+ const pcbComponent = root.db.pcb_component.insert({
31930
+ center,
31931
+ width: 0,
31932
+ height: 0,
31933
+ layer: "top",
31934
+ rotation: 0,
31935
+ source_component_id: this.source_component_id,
31936
+ obstructs_within_bounds: false,
31937
+ do_not_place: true,
31938
+ is_allowed_to_be_off_board: true
31939
+ });
31940
+ this.pcb_component_id = pcbComponent.pcb_component_id;
31941
+ }
31942
+ doInitialCadModelRender() {
31943
+ EnclosureFdmBox_doInitialCadModelRender(this);
31944
+ }
31945
+ };
31946
+
31656
31947
  // lib/components/normal-components/Battery.ts
31657
31948
  import { batteryProps } from "@tscircuit/props";
31658
31949
  var Battery = class extends NormalComponent3 {
@@ -32839,6 +33130,133 @@ function getTitleAnchorAndPosition({
32839
33130
  }
32840
33131
  }
32841
33132
 
33133
+ // lib/components/primitive-components/SchematicBox/SchematicBox_doInitialSchematicComponentRender.ts
33134
+ var getSchematicBoxPinLabels = (pinLabels) => {
33135
+ if (!pinLabels) return [];
33136
+ return Object.entries(pinLabels).map(([pinKey, pinLabel]) => {
33137
+ const pinNumber = getPinNumberFromPinLabelsKey(pinKey);
33138
+ if (pinNumber === null) {
33139
+ throw new Error(
33140
+ `Invalid schematicbox pinLabels key "${pinKey}". Expected pin<number>.`
33141
+ );
33142
+ }
33143
+ const pinAliases = typeof pinLabel === "string" ? [pinLabel] : [...pinLabel];
33144
+ return {
33145
+ pinNumber,
33146
+ displayPinLabel: pinAliases[0] ?? pinKey,
33147
+ pinAliases
33148
+ };
33149
+ });
33150
+ };
33151
+ var SchematicBox_doInitialSchematicComponentRender = (schematicBox) => {
33152
+ if (schematicBox.root?.schematicDisabled) return;
33153
+ const { db } = schematicBox.root;
33154
+ const props = schematicBox._parsedProps;
33155
+ if (!props.chipRef) return;
33156
+ const referencedChip = schematicBox.getSubcircuit().selectOne(props.chipRef);
33157
+ if (!referencedChip?.source_component_id) {
33158
+ throw new Error(
33159
+ `Could not resolve chipRef "${props.chipRef}" for ${schematicBox.getString()}`
33160
+ );
33161
+ }
33162
+ const schematicBoxPinLabels = getSchematicBoxPinLabels(props.pinLabels);
33163
+ const pinLabelsByPinKey = Object.fromEntries(
33164
+ schematicBoxPinLabels.map(({ pinNumber, displayPinLabel }) => [
33165
+ `pin${pinNumber}`,
33166
+ displayPinLabel
33167
+ ])
33168
+ );
33169
+ const sourcePorts = db.source_port.list({
33170
+ source_component_id: referencedChip.source_component_id
33171
+ });
33172
+ const dimensions = getAllDimensionsForSchematicBox({
33173
+ schWidth: props.width,
33174
+ schHeight: props.height,
33175
+ schPinSpacing: 0.2,
33176
+ pinCount: schematicBoxPinLabels.length,
33177
+ schPortArrangement: props.schPinArrangement,
33178
+ pinLabels: pinLabelsByPinKey
33179
+ });
33180
+ const center = schematicBox._getGlobalSchematicPositionBeforeLayout();
33181
+ const size = dimensions.getSize();
33182
+ const schematicSheetId = schematicBox._resolveSchematicSheetId();
33183
+ const portLabels = Object.fromEntries(
33184
+ schematicBoxPinLabels.map(({ pinNumber, displayPinLabel }) => [
33185
+ String(pinNumber),
33186
+ displayPinLabel
33187
+ ])
33188
+ );
33189
+ const schematicComponent = db.schematic_component.insert({
33190
+ center,
33191
+ size,
33192
+ source_component_id: referencedChip.source_component_id,
33193
+ is_box_with_pins: true,
33194
+ port_arrangement: underscorifyPortArrangement(props.schPinArrangement),
33195
+ port_labels: portLabels,
33196
+ pin_spacing: 0.2,
33197
+ schematic_sheet_id: schematicSheetId
33198
+ });
33199
+ schematicBox.schematic_component_id = schematicComponent.schematic_component_id;
33200
+ for (const {
33201
+ pinNumber,
33202
+ displayPinLabel,
33203
+ pinAliases
33204
+ } of schematicBoxPinLabels) {
33205
+ const referencedSourcePort = sourcePorts.find(
33206
+ (sourcePort) => pinAliases.some(
33207
+ (pinAlias) => sourcePort.name === pinAlias || sourcePort.port_hints?.includes(pinAlias)
33208
+ )
33209
+ );
33210
+ if (!referencedSourcePort) {
33211
+ throw new Error(
33212
+ `Could not find pin "${displayPinLabel}" on chipRef "${props.chipRef}"`
33213
+ );
33214
+ }
33215
+ const portPosition = dimensions.getPortPositionByPinNumber(pinNumber);
33216
+ if (!portPosition) {
33217
+ throw new Error(
33218
+ `Could not determine schematic position for ${schematicBox.getString()} pin${pinNumber}`
33219
+ );
33220
+ }
33221
+ const facingDirection = {
33222
+ left: "left",
33223
+ right: "right",
33224
+ top: "up",
33225
+ bottom: "down"
33226
+ }[portPosition.side];
33227
+ db.schematic_port.insert({
33228
+ schematic_component_id: schematicComponent.schematic_component_id,
33229
+ center: {
33230
+ x: center.x + portPosition.x,
33231
+ y: center.y + portPosition.y
33232
+ },
33233
+ source_port_id: referencedSourcePort.source_port_id,
33234
+ facing_direction: facingDirection,
33235
+ distance_from_component_edge: 0.4,
33236
+ side_of_component: portPosition.side,
33237
+ pin_number: pinNumber,
33238
+ true_ccw_index: portPosition.trueIndex,
33239
+ display_pin_label: displayPinLabel,
33240
+ is_connected: false,
33241
+ schematic_sheet_id: schematicSheetId
33242
+ });
33243
+ }
33244
+ const sectionName = props.name ?? props.chipRef;
33245
+ db.schematic_text.insert({
33246
+ text: sectionName,
33247
+ schematic_component_id: schematicComponent.schematic_component_id,
33248
+ anchor: "left",
33249
+ rotation: 0,
33250
+ position: {
33251
+ x: center.x - size.width / 2,
33252
+ y: center.y + size.height / 2 + 0.13
33253
+ },
33254
+ color: "#006464",
33255
+ font_size: 0.18,
33256
+ schematic_sheet_id: schematicSheetId
33257
+ });
33258
+ };
33259
+
32842
33260
  // lib/components/primitive-components/SchematicBox/SchematicBox.ts
32843
33261
  var SchematicBox = class extends PrimitiveComponent2 {
32844
33262
  isSchematicPrimitive = true;
@@ -32849,11 +33267,15 @@ var SchematicBox = class extends PrimitiveComponent2 {
32849
33267
  shouldRenderAsSchematicBox: true
32850
33268
  };
32851
33269
  }
33270
+ doInitialSchematicComponentRender() {
33271
+ SchematicBox_doInitialSchematicComponentRender(this);
33272
+ }
32852
33273
  doInitialSchematicPrimitiveRender() {
32853
33274
  if (this.root?.schematicDisabled) return;
32854
33275
  if (this.getCollapsedSchematicBoxAncestor()) return;
32855
33276
  const { db } = this.root;
32856
33277
  const { _parsedProps: props } = this;
33278
+ if (props.chipRef) return;
32857
33279
  const basePadding = 0.6;
32858
33280
  const generalPadding = typeof props.padding === "number" ? props.padding : 0;
32859
33281
  const paddingTop = typeof props.paddingTop === "number" ? props.paddingTop : generalPadding;
@@ -32919,7 +33341,8 @@ var SchematicBox = class extends PrimitiveComponent2 {
32919
33341
  width,
32920
33342
  x,
32921
33343
  y,
32922
- is_dashed: props.strokeStyle === "dashed"
33344
+ is_dashed: props.strokeStyle === "dashed",
33345
+ schematic_sheet_id: this._resolveSchematicSheetId()
32923
33346
  });
32924
33347
  if (props.title) {
32925
33348
  const isInside = props.titleInside;
@@ -33706,6 +34129,26 @@ var SpiceModel = class extends PrimitiveComponent2 {
33706
34129
  }
33707
34130
  };
33708
34131
 
34132
+ // lib/namespaced-elements/create-namespaced-element.ts
34133
+ import { createElement } from "react";
34134
+ var createNamespacedElement = (hostType) => {
34135
+ const Component2 = (props) => createElement(hostType, props);
34136
+ Component2.displayName = hostType;
34137
+ return Component2;
34138
+ };
34139
+
34140
+ // lib/namespaced-elements/enclosure.ts
34141
+ var EnclosureFdmBoxElement = createNamespacedElement("enclosure.fdm.box");
34142
+ var enclosure = {
34143
+ cutoutaperture: createNamespacedElement(
34144
+ "enclosure.cutoutaperture"
34145
+ ),
34146
+ fdm: {
34147
+ box: EnclosureFdmBoxElement,
34148
+ Box: EnclosureFdmBoxElement
34149
+ }
34150
+ };
34151
+
33709
34152
  // lib/RootCircuit.ts
33710
34153
  var RootCircuit = class extends IsolatedCircuit {
33711
34154
  isRootCircuit = true;
@@ -33924,13 +34367,15 @@ var sel = new Proxy(
33924
34367
  );
33925
34368
 
33926
34369
  // lib/index.ts
33927
- import { createElement } from "react";
34370
+ import { createElement as createElement2 } from "react";
33928
34371
  import { kicadFootprintStrings } from "@tscircuit/props";
33929
34372
 
33930
34373
  // lib/register-catalogue.ts
33931
34374
  extendCatalogue(components_exports);
33932
34375
  extendCatalogue({
33933
34376
  Bug: Chip,
34377
+ "enclosure.cutoutaperture": EnclosureCutoutAperture,
34378
+ "enclosure.fdm.box": EnclosureFdmBox,
33934
34379
  Fanout: Breakout,
33935
34380
  FanoutPoint: BreakoutPoint
33936
34381
  });
@@ -33963,6 +34408,8 @@ export {
33963
34408
  DifferentialPair,
33964
34409
  Diode,
33965
34410
  DrcCheck,
34411
+ EnclosureCutoutAperture,
34412
+ EnclosureFdmBox,
33966
34413
  FabricationNoteDimension,
33967
34414
  FabricationNotePath,
33968
34415
  FabricationNoteRect,
@@ -34046,8 +34493,9 @@ export {
34046
34493
  applyEditEventsToManualEditsFile,
34047
34494
  applyPcbEditEventsToManualEditsFile,
34048
34495
  applySchematicEditEventsToManualEditsFile,
34049
- createElement,
34496
+ createElement2 as createElement,
34050
34497
  createUseComponent,
34498
+ enclosure,
34051
34499
  getPhaseTimingsFromRenderEvents,
34052
34500
  getSimpleRouteJsonFromCircuitJson,
34053
34501
  kicadFootprintStrings,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tscircuit/core",
3
3
  "type": "module",
4
- "version": "0.0.1475",
4
+ "version": "0.0.1477",
5
5
  "types": "dist/index.d.ts",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",
@@ -39,6 +39,7 @@
39
39
  "@tscircuit/circuit-json-util": "^0.0.97",
40
40
  "@tscircuit/common": "^0.0.20",
41
41
  "@tscircuit/copper-pour-solver": "0.0.39",
42
+ "@tscircuit/create-fdm-enclosure": "0.0.2",
42
43
  "@tscircuit/footprinter": "^0.0.380",
43
44
  "@tscircuit/image-utils": "^0.0.8",
44
45
  "@tscircuit/infer-cable-insertion-point": "^0.0.2",
@@ -67,7 +68,7 @@
67
68
  "circuit-json": "^0.0.450",
68
69
  "circuit-json-to-bpc": "^0.0.13",
69
70
  "circuit-json-to-connectivity-map": "^0.0.23",
70
- "circuit-json-to-gltf": "^0.0.105",
71
+ "circuit-json-to-gltf": "^0.0.107",
71
72
  "circuit-json-to-spice": "^0.0.43",
72
73
  "circuit-to-svg": "^0.0.391",
73
74
  "concurrently": "^9.1.2",
@@ -96,6 +97,7 @@
96
97
  "@tscircuit/capacity-autorouter": "*",
97
98
  "@tscircuit/checks": "*",
98
99
  "@tscircuit/circuit-json-util": "*",
100
+ "@tscircuit/create-fdm-enclosure": "*",
99
101
  "@tscircuit/footprinter": "*",
100
102
  "@tscircuit/infgrid-ijump-astar": "*",
101
103
  "@tscircuit/math-utils": "*",