diff --git a/benchmarks/prompt-logs/prompt-2025-02-18T12-45-42-158Z.txt b/benchmarks/prompt-logs/prompt-2025-02-18T12-45-42-158Z.txt deleted file mode 100644 index 3006fae..0000000 --- a/benchmarks/prompt-logs/prompt-2025-02-18T12-45-42-158Z.txt +++ /dev/null @@ -1,1250 +0,0 @@ -You are an expert in electronic circuit design and tscircuit, and your job is to create a circuit board in tscircuit with the user-provided description. - -YOU MUST ABIDE BY THE RULES IN THE RULES SECTION - -## tscircuit API overview - -Here's an overview of the tscircuit API: - - // usually the root component - // custom shape instead of rectangle - - - - - - - - - - - - - -### footprint strings - -Footprint strings are a compact way to represent the physical footprint for a -component. Any component can be given a footprint string. Here are example -footprint strings: - -0402 -0603 -0805 -1206 -1210 -cap0402 -res0402 -soic8_p1.27mm -dip16 -pinrow10 -tssop20_p0.5mm -sot23 - -### All available footprints - -- Either use a passive footprint like this (e.g. 0402, 0603, 0805, 1206, 1210), here is a json string with all available footprint passive sizes: - -["01005","0201","0402","0603","0805","1206","1210","2010","2512"] - -- Or create a footprint string like this (e.g. dfn8_w5.3mm_p1.27mm, dip10_w4.00mm_p2.65mm, lqfp64_w10_h10_pl1_pw0.25mm, sot363, stampreceiver_left20_right20_bottom3_top2_w21mm_p2.54mm, tssop20_w6.5mm_p0.65mm, bga7_w8_h8_grid3x3_p1_missing(center,B1), bga64_w10_h10_grid8x8_p1.27mm), here are json objects with the available footprints and their options: - -{"fn":"axial","p":2.54,"id":0.7,"od":1} -{"fn":"bga","num_pins":64,"p":0.8,"missing":[],"grid":{"x":8,"y":8},"origin":"tl"} -{"fn":"breakoutheaders","w":10,"left":20,"right":20,"top":0,"bottom":0,"p":2.54,"id":1,"od":1.5} -{"fn":"dfn","num_pins":8,"w":5.3,"p":1.27,"legsoutside":false,"pw":0.6,"pl":1} -{"fn":"dip","num_pins":6,"p":2.54,"id":1,"od":1.5,"w":7.62} -{"fn":"lqfp","num_pins":64,"p":0.5,"legsoutside":true,"w":10,"h":10,"pw":0.25,"pl":0.25} -{"fn":"mlp","num_pins":64,"p":0.5,"thermalpad":true,"legsoutside":false,"w":10,"h":10,"pw":0.25,"pl":0.25} -{"fn":"ms012","num_pins":8,"w":3.9,"p":1.27,"legsoutside":true,"pw":0.6,"pl":1} -{"fn":"ms013","num_pins":16,"w":7.5,"p":1.27,"legsoutside":true,"pw":0.6,"pl":1} -{"fn":"pinrow","num_pins":6,"p":2.54,"id":1,"od":1.5} -{"fn":"pushbutton","w":4.5,"h":6.5,"id":1,"od":1.2} -{"fn":"qfn","num_pins":64,"p":0.5,"legsoutside":false,"w":10,"h":10,"pw":0.25,"pl":0.25} -{"fn":"qfp","num_pins":64,"p":0.5,"pw":0.25,"pl":1,"legsoutside":true,"w":10,"h":10} -{"fn":"quad","num_pins":64,"p":0.5,"legsoutside":false,"w":10,"h":10,"pw":0.25,"pl":0.25} -{"fn":"sod123","num_pins":2,"w":"2.36mm","h":"1.22mm","pl":"0.9mm","pw":"0.9mm","pad_spacing":"4.19mm"} -{"fn":"soic","num_pins":8,"w":5.3,"p":1.27,"legsoutside":false,"pw":0.6,"pl":1} -{"fn":"sot23","num_pins":3,"w":"1.92mm","h":"2.74mm","pl":"0.8mm","pw":"0.764mm"} -{"fn":"sot235","num_pins":5,"h":"1.6mm","pl":"1mm","pw":"0.7mm","p":"0.95mm"} -{"fn":"sot236","num_pins":6,"w":1.6,"p":0.95,"legsoutside":true,"pw":0.6,"pl":1} -{"fn":"sot363","num_pins":6,"w":1.94,"p":0.65,"pw":0.3,"pl":0.7,"legsoutside":false} -{"fn":"sot563","num_pins":6,"w":1.94,"p":0.5,"pw":0.3,"pl":0.67,"legsoutside":false} -{"fn":"sot723","num_pins":3,"w":"1.2mm","h":"1.2mm","pl":"0.3mm","pw":"0.32mm"} -{"fn":"ssop","num_pins":8,"w":3.9,"p":1.27,"legsoutside":false,"pw":0.6,"pl":1} -{"fn":"stampboard","w":22.58,"left":20,"right":20,"top":2,"bottom":2,"p":2.54,"pw":1.6,"pl":2.4,"innerhole":false,"innerholeedgedistance":1.61} -{"fn":"stampreceiver","w":22.58,"left":20,"right":20,"top":2,"bottom":2,"p":2.54,"pw":1.6,"pl":3.2,"innerhole":false,"innerholeedgedistance":1.61} -{"fn":"tssop","num_pins":8,"w":6.1,"p":0.65,"legsoutside":true,"pw":0.6,"pl":1} - - -- Here is a list of unsupported footprints: - -1- hc - -keep in mind that num_pins can be replaced with a number directly infront of the footprint name like so: dip8_p1.27mm which means num_pins=8, don't do that for footprints with fixed number of pins like ms012 and sot723 - -### Components and Props - -- Here is a documentation of all available components and their types: - - - -```typescript -export const rotationPoint3 = z.object({ - x: z.union([z.number(), z.string()]), - y: z.union([z.number(), z.string()]), - z: z.union([z.number(), z.string()]), -}) -export interface CadModelBase { - rotationOffset?: - | number - | { x: number | string; y: number | string; z: number | string } - positionOffset?: { - x: number | string - y: number | string - z: number | string - } - size?: { x: number | string; y: number | string; z: number | string } -} -export const cadModelBase = z.object({ - rotationOffset: z.number().or(rotationPoint3).optional(), - positionOffset: point3.optional(), - size: point3.optional(), -}) -export interface CadModelStl extends CadModelBase { - stlUrl: string -} -export const cadModelStl = cadModelBase.extend({ - stlUrl: z.string(), -}) -export interface CadModelObj extends CadModelBase { - objUrl: string - mtlUrl?: string -} -export const cadModelObj = cadModelBase.extend({ - objUrl: z.string(), - mtlUrl: z.string().optional(), -}) -export interface CadModelJscad extends CadModelBase { - jscad: Record -} -export const cadModelJscad = cadModelBase.extend({ - jscad: z.record(z.any()), -}) -``` - -```typescript -export type Distance = number | string - -export { distance, length } from "circuit-json" -``` - -```typescript -/** - * This is an abbreviated definition of the soup elements that you can find here: - * https://docs.tscircuit.com/api-reference/advanced/soup#pcb-smtpad - */ -export type FootprintSoupElements = { - type: "pcb_smtpad" | "pcb_plated_hole" - x: string | number - y: string | number - layer?: LayerRef - holeDiameter?: string | number - outerDiameter?: string | number - shape?: "circle" | "rect" - width?: string | number - height?: string | number - portHints?: string[] -} -``` - -```typescript -export interface PcbLayoutProps { - pcbX?: string | number - pcbY?: string | number - pcbRotation?: string | number - layer?: LayerRefInput -} -export interface CommonLayoutProps { - pcbX?: string | number - pcbY?: string | number - pcbRotation?: string | number - - schX?: string | number - schY?: string | number - schRotation?: string | number - - layer?: LayerRefInput - footprint?: Footprint -} -export const pcbLayoutProps = z.object({ - pcbX: distance.optional(), - pcbY: distance.optional(), - pcbRotation: rotation.optional(), - layer: layer_ref.optional(), -}) -export const commonLayoutProps = z.object({ - pcbX: distance.optional(), - pcbY: distance.optional(), - pcbRotation: rotation.optional(), - schX: distance.optional(), - schY: distance.optional(), - schRotation: rotation.optional(), - layer: layer_ref.optional(), - footprint: footprintProp.optional(), -}) -export interface SupplierProps { - supplierPartNumbers?: SupplierPartNumbers -} -export const supplierProps = z.object({ - supplierPartNumbers: z.record(supplier_name, z.array(z.string())).optional(), -}) -export interface CommonComponentProps extends CommonLayoutProps { - key?: any - name: string - supplierPartNumbers?: SupplierPartNumbers - cadModel?: CadModelProp - children?: any - symbolName?: string -} -export const commonComponentProps = commonLayoutProps - .merge(supplierProps) - .extend({ - key: z.any().optional(), - name: z.string(), - cadModel: cadModelProp.optional(), - children: z.any().optional(), - symbolName: z.string().optional(), - }) -export const lrPolarPins = [ - "pin1", - "left", - "anode", - "pos", - "pin2", - "right", - "cathode", - "neg", -] as const -``` - -```typescript -export const point = z.object({ - x: distance, - y: distance, -}) -``` - -```typescript -export const point3 = z.object({ - x: distance, - y: distance, - z: distance, -}) -``` - -```typescript -/** - * @deprecated Use SchematicPortArrangementWithPinCounts instead. - */ -export interface SchematicPortArrangementWithSizes { - leftSize?: number - topSize?: number - rightSize?: number - bottomSize?: number -} -/** - * Specifies the number of pins on each side of the schematic box component. - */ -export interface SchematicPortArrangementWithPinCounts { - leftPinCount?: number - topPinCount?: number - rightPinCount?: number - bottomPinCount?: number -} -export interface PinSideDefinition { - pins: Array - direction: - | "top-to-bottom" - | "left-to-right" - | "bottom-to-top" - | "right-to-left" -} -export interface SchematicPortArrangementWithSides { - leftSide?: PinSideDefinition - topSide?: PinSideDefinition - rightSide?: PinSideDefinition - bottomSide?: PinSideDefinition -} -export interface SchematicPortArrangement - extends SchematicPortArrangementWithSizes, - SchematicPortArrangementWithSides, - SchematicPortArrangementWithPinCounts {} -export const explicitPinSideDefinition = z.object({ - pins: z.array(z.union([z.number(), z.string()])), - direction: z.union([ - z.literal("top-to-bottom"), - z.literal("left-to-right"), - z.literal("bottom-to-top"), - z.literal("right-to-left"), - ]), -}) -export const schematicPortArrangement = z.object({ - leftSize: z.number().optional().describe("@deprecated, use leftPinCount"), - topSize: z.number().optional().describe("@deprecated, use topPinCount"), - rightSize: z.number().optional().describe("@deprecated, use rightPinCount"), - bottomSize: z.number().optional().describe("@deprecated, use bottomPinCount"), - leftPinCount: z.number().optional(), - rightPinCount: z.number().optional(), - topPinCount: z.number().optional(), - bottomPinCount: z.number().optional(), - leftSide: explicitPinSideDefinition.optional(), - rightSide: explicitPinSideDefinition.optional(), - topSide: explicitPinSideDefinition.optional(), - bottomSide: explicitPinSideDefinition.optional(), -}) -``` - -```typescript -export type SchematicPinStyle = Record< - string, - { - leftMargin?: number | string - rightMargin?: number | string - topMargin?: number | string - bottomMargin?: number | string - } -export const schematicPinStyle = z.record( - z.object({ - leftMargin: distance.optional(), - rightMargin: distance.optional(), - topMargin: distance.optional(), - bottomMargin: distance.optional(), - }), -``` - -```typescript -/** @deprecated use battery_capacity from circuit-json when circuit-json is updated */ -export interface BatteryProps extends CommonComponentProps { - capacity?: number | string -} -export const batteryProps = commonComponentProps.extend({ - capacity: capacity.optional(), -}) -``` - -```typescript -export interface BoardProps extends Omit { - width?: number | string - height?: number | string - outline?: Point[] - outlineOffsetX?: number | string - outlineOffsetY?: number | string -} -export const boardProps = subcircuitGroupProps.extend({ - width: distance.optional(), - height: distance.optional(), - outline: z.array(point).optional(), - outlineOffsetX: distance.optional(), - outlineOffsetY: distance.optional(), -}) -``` - -```typescript -export interface CapacitorProps extends CommonComponentProps { - capacitance: number | string - polarized?: boolean - decouplingFor?: string - decouplingTo?: string - bypassFor?: string - bypassTo?: string - maxDecouplingTraceLength?: number -} -export const capacitorProps = commonComponentProps.extend({ - capacitance, - polarized: z.boolean().optional().default(false), - decouplingFor: z.string().optional(), - decouplingTo: z.string().optional(), - bypassFor: z.string().optional(), - bypassTo: z.string().optional(), - maxDecouplingTraceLength: z.number().optional(), -}) -``` - -```typescript -export interface ChipProps extends CommonComponentProps { - manufacturerPartNumber?: string - pinLabels?: Record - schPortArrangement?: SchematicPortArrangement - schPinStyle?: SchematicPinStyle - schPinSpacing?: Distance - schWidth?: Distance - schHeight?: Distance - noSchematicRepresentation?: boolean -} -export const chipProps = commonComponentProps.extend({ - manufacturerPartNumber: z.string().optional(), - pinLabels: z - .record( - z.number().or(z.string()), - z.string().or(z.array(z.string()).readonly()), - ) - .optional(), - schPortArrangement: schematicPortArrangement.optional(), - schPinStyle: schematicPinStyle.optional(), - schPinSpacing: distance.optional(), - schWidth: distance.optional(), - schHeight: distance.optional(), - noSchematicRepresentation: z.boolean().optional(), -}) -``` - -```typescript -export interface ConstrainedLayoutProps { - name?: string - pcbOnly?: boolean - schOnly?: boolean -} -export const constrainedLayoutProps = z.object({ - name: z.string().optional(), - pcbOnly: z.boolean().optional(), - schOnly: z.boolean().optional(), -}) -``` - -```typescript -export type PcbXDistConstraint = { - pcb?: true - xDist: Distance - - left: string - - right: string - - edgeToEdge?: true - - centerToCenter?: true -} -/** - * If true, the provided distance is the distance between the centers of the - * left and right components - */ -export type PcbYDistConstraint = { - pcb?: true - yDist: Distance - - top: string - - bottom: string - - edgeToEdge?: true - centerToCenter?: true -} -/** - * Selector for bottom component, e.g. ".U1" or ".R1", you can also specify the - * edge or center of the component e.g. ".R1 bottomedge", ".R1 center" - */ -export type PcbSameYConstraint = { - pcb?: true - sameY?: true - - for: string[] -} -/** - * Selector for components, e.g. [".U1", ".R1"], you can also specify the - * edge or center of the component e.g. [".R1 leftedge", ".U1 center"] - */ -export type PcbSameXConstraint = { - pcb?: true - sameX?: true - for: string[] -} -export const pcbXDistConstraintProps = z.object({ - pcb: z.literal(true).optional(), - xDist: distance, - left: z.string(), - right: z.string(), - - edgeToEdge: z.literal(true).optional(), - centerToCenter: z.literal(true).optional(), -}) -export const pcbYDistConstraintProps = z.object({ - pcb: z.literal(true).optional(), - yDist: distance, - top: z.string(), - bottom: z.string(), - - edgeToEdge: z.literal(true).optional(), - centerToCenter: z.literal(true).optional(), -}) -export const pcbSameYConstraintProps = z.object({ - pcb: z.literal(true).optional(), - sameY: z.literal(true).optional(), - for: z.array(z.string()), -}) -export const pcbSameXConstraintProps = z.object({ - pcb: z.literal(true).optional(), - sameX: z.literal(true).optional(), - for: z.array(z.string()), -}) -``` - -```typescript -export interface CrystalProps extends CommonComponentProps { - frequency: number | string - loadCapacitance: number | string - pinVariant?: PinVariant -} -export const crystalProps = commonComponentProps.extend({ - frequency: frequency, - loadCapacitance: capacitance, - pinVariant: z.enum(["2pin", "4pin"]).optional(), -}) -``` - -```typescript -export const fabricationNotePathProps = pcbLayoutProps - .omit({ pcbX: true, pcbY: true, pcbRotation: true }) -``` - -```typescript -export const fabricationNoteTextProps = pcbLayoutProps.extend({ - text: z.string(), - anchorAlignment: z - .enum(["center", "top_left", "top_right", "bottom_left", "bottom_right"]) - .default("center"), - font: z.enum(["tscircuit2024"]).optional(), - fontSize: length.optional(), - color: z.string().optional(), -}) -``` - -```typescript -export interface FootprintProps { - originalLayer?: LayerRef -} -/** - * The layer that the footprint is designed for. If you set this to "top" - * then it means the children were intended to represent the top layer. If - * the with this footprint is moved to the bottom layer, then the - * components will be mirrored. - * - * Generally, you shouldn't set this except where it can help prevent - * confusion because you have a complex multi-layer footprint. Default is - * "top" and this is most intuitive. - */ -export const footprintProps = z.object({ - originalLayer: layer_ref.default("top").optional(), -}) -``` - -```typescript -export interface BaseGroupProps extends CommonLayoutProps { - name?: string - key?: any - children?: any -} -export type PartsEngine = { - findPart: (params: { - sourceComponent: AnySourceComponent - footprinterString?: string - }) => Promise | SupplierPartNumbers -} -export interface PcbRouteCache { - pcbTraces: PcbTrace[] - cacheKey: string -} -export interface AutorouterConfig { - serverUrl?: string - inputFormat?: "simplified" | "circuit-json" - serverMode?: "job" | "solve-endpoint" - cache?: PcbRouteCache -} -export const autorouterConfig = z.object({ - serverUrl: z.string().optional(), - inputFormat: z.enum(["simplified", "circuit-json"]).optional(), - serverMode: z.enum(["job", "solve-endpoint"]).optional(), - cache: z.custom((v) => true).optional(), -}) -export interface SubcircuitGroupProps extends BaseGroupProps { - layout?: LayoutBuilder - manualEdits?: ManualEditsFileInput - routingDisabled?: boolean - defaultTraceWidth?: Distance - minTraceWidth?: Distance - pcbRouteCache?: PcbRouteCache - - autorouter?: AutorouterProp - - schAutoLayoutEnabled?: boolean - - schTraceAutoLabelEnabled?: boolean - - partsEngine?: PartsEngine -} -/** - * If true, net labels will automatically be created for complex traces - */ -export interface SubcircuitGroupPropsWithBool extends SubcircuitGroupProps { - subcircuit: true -} -export interface NonSubcircuitGroupProps extends BaseGroupProps { - subcircuit?: false | undefined -} -export const baseGroupProps = commonLayoutProps.extend({ - name: z.string().optional(), - children: z.any().optional(), - key: z.any().optional(), -}) -export const subcircuitGroupProps = baseGroupProps.extend({ - layout: z.custom((v) => true).optional(), - manualEdits: manual_edits_file.optional(), - schAutoLayoutEnabled: z.boolean().optional(), - schTraceAutoLabelEnabled: z.boolean().optional(), - routingDisabled: z.boolean().optional(), - defaultTraceWidth: length.optional(), - minTraceWidth: length.optional(), - partsEngine: z.custom((v) => "findPart" in v).optional(), - pcbRouteCache: z.custom((v) => true).optional(), - autorouter: autorouterProp.optional(), -}) -export const subcircuitGroupPropsWithBool = subcircuitGroupProps.extend({ - subcircuit: z.literal(true), -}) -export const groupProps = z.discriminatedUnion("subcircuit", [ - baseGroupProps.extend({ subcircuit: z.literal(false).optional() }), -``` - -```typescript -export interface HoleProps extends Omit { - name?: string - diameter?: Distance - radius?: Distance -} -export const holeProps = pcbLayoutProps - .omit({ pcbRotation: true }) -``` - -```typescript -export const inductorProps = commonComponentProps.extend({ - inductance, -}) -``` - -```typescript -export interface JumperProps extends CommonComponentProps { - manufacturerPartNumber?: string - pinLabels?: Record - schPinStyle?: SchematicPinStyle - schPinSpacing?: number | string - schWidth?: number | string - schHeight?: number | string - schDirection?: "left" | "right" - schPortArrangement?: SchematicPortArrangement -} -export const jumperProps = commonComponentProps.extend({ - manufacturerPartNumber: z.string().optional(), - pinLabels: z - .record(z.number().or(z.string()), z.string().or(z.array(z.string()))) - .optional(), - schPinStyle: schematicPinStyle.optional(), - schPinSpacing: distance.optional(), - schWidth: distance.optional(), - schHeight: distance.optional(), - schDirection: z.enum(["left", "right"]).optional(), - schPortArrangement: schematicPortArrangement.optional(), -}) -``` - -```typescript -export const ledProps = commonComponentProps.extend({ - color: z.string().optional(), -}) -``` - -```typescript -export interface MosfetProps extends CommonComponentProps { - channelType: "n" | "p" - mosfetMode: "enhancement" | "depletion" -} -export const mosfetProps = commonComponentProps.extend({ - channelType: z.enum(["n", "p"]), - mosfetMode: z.enum(["enhancement", "depletion"]), -}) -export const mosfetPins = [ - "pin1", - "drain", - "pin2", - "source", - "pin3", - "gate", -] as const -``` - -```typescript -export interface NetProps { - name: string -} -export const netProps = z.object({ - name: z.string(), -}) -``` - -```typescript -export interface NetAliasProps { - net?: string - schX?: number | string - schY?: number | string - schRotation?: number | string - anchorSide?: "left" | "up" | "right" | "down" -} -export const netAliasProps = z.object({ - net: z.string().optional(), - schX: distance.optional(), - schY: distance.optional(), - schRotation: rotation.optional(), - anchorSide: z.enum(["left", "up", "right", "down"]).optional(), -}) -``` - -```typescript -export const pcbKeepoutProps = z.union([ - pcbLayoutProps.omit({ pcbRotation: true }).extend({ - shape: z.literal("circle"), - radius: distance, - }), -``` - -```typescript -export const pcbTraceProps = z.object({ - layer: z.string().optional(), - thickness: distance.optional(), - route: z.array(route_hint_point), -}) -``` - -```typescript -export interface PinHeaderProps extends CommonComponentProps { - pinCount: number - - pitch?: number | string - - gender?: "male" | "female" - - showSilkscreenPinLabels?: boolean - - doubleRow?: boolean - - holeDiameter?: number | string - - platedDiameter?: number | string - - pinLabels?: string[] - - facingDirection?: "left" | "right" -} -/** - * Direction the header is facing - */ -export const pinHeaderProps = commonComponentProps.extend({ - pinCount: z.number(), - pitch: distance.optional(), - gender: z.enum(["male", "female"]).optional().default("male"), - showSilkscreenPinLabels: z.boolean().optional(), - doubleRow: z.boolean().optional(), - holeDiameter: distance.optional(), - platedDiameter: distance.optional(), - pinLabels: z.array(z.string()).optional(), - facingDirection: z.enum(["left", "right"]).optional(), -}) -``` - -```typescript -export interface CirclePlatedHoleProps - extends Omit { - name?: string - shape: "circle" - holeDiameter: number | string - outerDiameter: number | string - portHints?: PortHints -} -export interface OvalPlatedHoleProps - extends Omit { - name?: string - shape: "oval" - outerWidth: number | string - outerHeight: number | string - innerWidth: number | string - innerHeight: number | string - portHints?: PortHints -} -export interface PillPlatedHoleProps - extends Omit { - name?: string - shape: "pill" - outerWidth: number | string - outerHeight: number | string - innerWidth: number | string - innerHeight: number | string - portHints?: PortHints -} -export const platedHoleProps = z.discriminatedUnion("shape", [ - pcbLayoutProps.omit({ pcbRotation: true, layer: true }).extend({ - name: z.string().optional(), - shape: z.literal("circle"), - holeDiameter: distance, - outerDiameter: distance, - portHints: portHints.optional(), - }), -``` - -```typescript -export const portProps = commonLayoutProps.extend({ - name: z.string(), - pinNumber: z.number().optional(), - aliases: z.array(z.string()).optional(), - direction: direction, -}) -``` - -```typescript -export interface PotentiometerProps extends CommonComponentProps { - maxResistance: number | string -} -export const potentiometerProps = commonComponentProps.extend({ - maxResistance: resistance, -}) -``` - -```typescript -export const powerSourceProps = commonComponentProps.extend({ - voltage, -}) -``` - -```typescript -export interface ResistorProps extends CommonComponentProps { - resistance: number | string - pullupFor?: string - pullupTo?: string - pulldownFor?: string - pulldownTo?: string -} -export const resistorProps = commonComponentProps.extend({ - resistance, - - pullupFor: z.string().optional(), - pullupTo: z.string().optional(), - - pulldownFor: z.string().optional(), - pulldownTo: z.string().optional(), -}) -``` - -```typescript -export interface ResonatorProps extends CommonComponentProps { - frequency: number | string - loadCapacitance: number | string - pinVariant?: ResonatorPinVariant -} -export const resonatorProps = commonComponentProps.extend({ - frequency: frequency, - loadCapacitance: capacitance, - pinVariant: z.enum(["no_ground", "ground_pin", "two_ground_pins"]).optional(), -}) -``` - -```typescript -export const schematicBoxProps = z.object({ - schX: distance, - schY: distance, - width: distance, - height: distance, -}) -``` - -```typescript -export const schematicLineProps = z.object({ - x1: distance, - y1: distance, - x2: distance, - y2: distance, -}) -``` - -```typescript -export const schematicPathProps = z.object({ - points: z.array(point), - isFilled: z.boolean().optional().default(false), - fillColor: z.enum(["red", "blue"]).optional(), -}) -``` - -```typescript -export const schematicTextProps = z.object({ - schX: distance, - schY: distance, - text: z.string(), -}) -``` - -```typescript -export const silkscreenCircleProps = pcbLayoutProps - .omit({ pcbRotation: true }) -``` - -```typescript -export const silkscreenLineProps = pcbLayoutProps - .omit({ pcbX: true, pcbY: true, pcbRotation: true }) -``` - -```typescript -export const silkscreenPathProps = pcbLayoutProps - .omit({ pcbX: true, pcbY: true, pcbRotation: true }) -``` - -```typescript -export const silkscreenRectProps = pcbLayoutProps - .omit({ pcbRotation: true }) -``` - -```typescript -export const silkscreenTextProps = pcbLayoutProps.extend({ - text: z.string(), - anchorAlignment: z - .enum(["center", "top_left", "top_right", "bottom_left", "bottom_right"]) - .default("center"), - font: z.enum(["tscircuit2024"]).optional(), - fontSize: length.optional(), -}) -``` - -```typescript -export interface RectSmtPadProps extends Omit { - shape: "rect" - width: Distance - height: Distance - portHints?: PortHints -} -export interface RotatedRectSmtPadProps - extends Omit { - shape: "rotated_rect" - width: Distance - height: Distance - ccwRotation: number - portHints?: PortHints -} -export interface CircleSmtPadProps extends Omit { - shape: "circle" - radius: Distance - portHints?: PortHints -} -export const rectSmtPadProps = pcbLayoutProps - .omit({ pcbRotation: true }) -export const rotatedRectSmtPadProps = pcbLayoutProps - .omit({ pcbRotation: true }) -export const circleSmtPadProps = pcbLayoutProps - .omit({ pcbRotation: true }) -``` - -```typescript -export interface RectSolderPasteProps - extends Omit { - shape: "rect" - width: Distance - height: Distance -} -export interface CircleSolderPasteProps - extends Omit { - shape: "circle" - radius: Distance -} -export const rectSolderPasteProps = pcbLayoutProps - .omit({ pcbRotation: true }) -export const circleSolderPasteProps = pcbLayoutProps - .omit({ pcbRotation: true }) -``` - -```typescript -export const switchProps = commonComponentProps.extend({ - ftype: z.literal("switch"), - switchType: z.enum(["spst"]).default("spst"), - isNormallyClosed: z.boolean().default(false), -}) -``` - -```typescript -export const routeHintPointProps = z.object({ - x: distance, - y: distance, - via: z.boolean().optional(), - toLayer: layer_ref.optional(), -}) -export const traceHintProps = z.object({ - for: z - .string() - .optional() - .describe( - "Selector for the port you're targeting, not required if you're inside a trace", - ), - order: z.number().optional(), - offset: route_hint_point.or(routeHintPointProps).optional(), - offsets: z - .array(route_hint_point) - .or(z.array(routeHintPointProps)) - .optional(), - traceWidth: z.number().optional(), -}) -``` - -```typescript -export const portRef = z.union([ - z.string(), - z.custom<{ getPortSelector: () => string }>((v) => -export const traceProps = z.union([ - baseTraceProps.extend({ - path: z.array(portRef), - }), -``` - -```typescript -export interface TransistorProps extends CommonComponentProps { - transistorType: "npn" | "pnp" -} -export const transistorProps = commonComponentProps.extend({ - transistorType: z.enum(["npn", "pnp"]), -}) -export const transistorPins = [ - "pin1", - "emitter", - "pin2", - "collector", - "pin3", - "base", -] as const -``` - -```typescript -export const viaProps = commonLayoutProps.extend({ - fromLayer: layer_ref, - toLayer: layer_ref, - holeDiameter: distance, - outerDiameter: distance, -}) -``` - - - -- Here is a list of unsupported components: - -1- powersource -2- powersourcesimple -3- pinheader - -- Here are examples of how you can take advantage of those props: - - // Example of a custom chip footprint definition - const CustomChipFootprint = () => ( - - // SMT pads for the chip - - - - - - // Silkscreen markings for the chip outline - - // Pin 1 indicator - - - ) - - // Example of a custom resistor footprint - const Resistor0603Footprint = () => ( - - - - - - ) - - // Example of a complete circuit - export const MyCircuit = () => ( - - // Power section group - - // Decoupling capacitor arrangement - - - - - - // Input protection group - - - - - - - // Power nets - - - - // Connections - - - - // Layout constraints - - - ) - - // Example of a custom module/component that can be reused - export const DecouplingCapacitor = ({ - chipRef, - capName, - capValue = "100nF", - distance = "2mm" - }) => ( - - - - - ) - - // Usage of the custom module - export const CircuitWithDecoupling = () => ( - - - - - ) - - -### RULES - -- decouplingFor must contain the selector for the component and the pin(eg. ".U1 .pin1", ".T1 .pin1") -- Never pass the component name alone as a selector for decouplingFor, always use the component name reference and the pin number -- Don't use hole or port components, always connect to the component pins -- Don't use inline comments which are comments in the same line as components, they are forbidden -- Port components must be children to a chip component. -- Never use components in the "Unsupported components" list -- Never use footprints in the "Unsupported footprints" list -- Any component may have a pcbX and/or a pcbY representing the center of the - component on a circuit board. -- Never use footprints that are not supported in the "All available footprints" section -- Some footprints have a fixed number of pins like ms012 and sot723 -- `` components use CSS selectors in the `from` and `to` fields - to connect components. -- Any component can have a `name` prop -- `pcbX` and `pcbY` are optional and default to 0. -- A board is centered on the origin (pcbX=0, pcbY=0), so to place a component - at the center it must be placed at pcbX=0,pcbY=0. Similarly, if you're trying - to layout components around the center, you would make ones to the left of - the center have negative pcbX values, below the center have negative pcbY, - and to the right of the center have positive pcbX values, and above the - center have positive pcbY values. -- Every component that is going to be placed must be given a footprint -- Traces can only take two ports -- Don't use path as prop for trace, only use from, to -- We don't support defining output ports, so don't defined port components -- Don't specify autorouter; don't use the autorouter prop -- Selectors for component pins must be of this format: ".U1 > .pin1" or ".U1 > .pin2" where U1 is the component name, and the pins must be numbers, so don't use names for pins but use pin1, pin2, pin3, pin4 -- And instead of ".T1 > .base" you do do ".T1 > .pin2" -- "for" must have at least two selectors for constraints - -### Trace Reference Syntax - -Traces are created using the `` component. The `from` and `to` -fields are CSS selectors that reference the components to connect. - -Examples: - - - - - -### Output - -Use a codefence with the language "tsx" to wrap the code. You can use the -current_code of the user as a starting point (if provided). - -You must export a higher-order component where the root component is `` -inside the codefence. For example: - -```tsx -export const MyLed = () => ( - - - - - -) -``` \ No newline at end of file diff --git a/benchmarks/prompt-logs/prompt-2025-02-18T12-48-05-585Z.txt b/benchmarks/prompt-logs/prompt-2025-02-18T12-48-05-585Z.txt deleted file mode 100644 index 3006fae..0000000 --- a/benchmarks/prompt-logs/prompt-2025-02-18T12-48-05-585Z.txt +++ /dev/null @@ -1,1250 +0,0 @@ -You are an expert in electronic circuit design and tscircuit, and your job is to create a circuit board in tscircuit with the user-provided description. - -YOU MUST ABIDE BY THE RULES IN THE RULES SECTION - -## tscircuit API overview - -Here's an overview of the tscircuit API: - - // usually the root component - // custom shape instead of rectangle - - - - - - - - - - - - - -### footprint strings - -Footprint strings are a compact way to represent the physical footprint for a -component. Any component can be given a footprint string. Here are example -footprint strings: - -0402 -0603 -0805 -1206 -1210 -cap0402 -res0402 -soic8_p1.27mm -dip16 -pinrow10 -tssop20_p0.5mm -sot23 - -### All available footprints - -- Either use a passive footprint like this (e.g. 0402, 0603, 0805, 1206, 1210), here is a json string with all available footprint passive sizes: - -["01005","0201","0402","0603","0805","1206","1210","2010","2512"] - -- Or create a footprint string like this (e.g. dfn8_w5.3mm_p1.27mm, dip10_w4.00mm_p2.65mm, lqfp64_w10_h10_pl1_pw0.25mm, sot363, stampreceiver_left20_right20_bottom3_top2_w21mm_p2.54mm, tssop20_w6.5mm_p0.65mm, bga7_w8_h8_grid3x3_p1_missing(center,B1), bga64_w10_h10_grid8x8_p1.27mm), here are json objects with the available footprints and their options: - -{"fn":"axial","p":2.54,"id":0.7,"od":1} -{"fn":"bga","num_pins":64,"p":0.8,"missing":[],"grid":{"x":8,"y":8},"origin":"tl"} -{"fn":"breakoutheaders","w":10,"left":20,"right":20,"top":0,"bottom":0,"p":2.54,"id":1,"od":1.5} -{"fn":"dfn","num_pins":8,"w":5.3,"p":1.27,"legsoutside":false,"pw":0.6,"pl":1} -{"fn":"dip","num_pins":6,"p":2.54,"id":1,"od":1.5,"w":7.62} -{"fn":"lqfp","num_pins":64,"p":0.5,"legsoutside":true,"w":10,"h":10,"pw":0.25,"pl":0.25} -{"fn":"mlp","num_pins":64,"p":0.5,"thermalpad":true,"legsoutside":false,"w":10,"h":10,"pw":0.25,"pl":0.25} -{"fn":"ms012","num_pins":8,"w":3.9,"p":1.27,"legsoutside":true,"pw":0.6,"pl":1} -{"fn":"ms013","num_pins":16,"w":7.5,"p":1.27,"legsoutside":true,"pw":0.6,"pl":1} -{"fn":"pinrow","num_pins":6,"p":2.54,"id":1,"od":1.5} -{"fn":"pushbutton","w":4.5,"h":6.5,"id":1,"od":1.2} -{"fn":"qfn","num_pins":64,"p":0.5,"legsoutside":false,"w":10,"h":10,"pw":0.25,"pl":0.25} -{"fn":"qfp","num_pins":64,"p":0.5,"pw":0.25,"pl":1,"legsoutside":true,"w":10,"h":10} -{"fn":"quad","num_pins":64,"p":0.5,"legsoutside":false,"w":10,"h":10,"pw":0.25,"pl":0.25} -{"fn":"sod123","num_pins":2,"w":"2.36mm","h":"1.22mm","pl":"0.9mm","pw":"0.9mm","pad_spacing":"4.19mm"} -{"fn":"soic","num_pins":8,"w":5.3,"p":1.27,"legsoutside":false,"pw":0.6,"pl":1} -{"fn":"sot23","num_pins":3,"w":"1.92mm","h":"2.74mm","pl":"0.8mm","pw":"0.764mm"} -{"fn":"sot235","num_pins":5,"h":"1.6mm","pl":"1mm","pw":"0.7mm","p":"0.95mm"} -{"fn":"sot236","num_pins":6,"w":1.6,"p":0.95,"legsoutside":true,"pw":0.6,"pl":1} -{"fn":"sot363","num_pins":6,"w":1.94,"p":0.65,"pw":0.3,"pl":0.7,"legsoutside":false} -{"fn":"sot563","num_pins":6,"w":1.94,"p":0.5,"pw":0.3,"pl":0.67,"legsoutside":false} -{"fn":"sot723","num_pins":3,"w":"1.2mm","h":"1.2mm","pl":"0.3mm","pw":"0.32mm"} -{"fn":"ssop","num_pins":8,"w":3.9,"p":1.27,"legsoutside":false,"pw":0.6,"pl":1} -{"fn":"stampboard","w":22.58,"left":20,"right":20,"top":2,"bottom":2,"p":2.54,"pw":1.6,"pl":2.4,"innerhole":false,"innerholeedgedistance":1.61} -{"fn":"stampreceiver","w":22.58,"left":20,"right":20,"top":2,"bottom":2,"p":2.54,"pw":1.6,"pl":3.2,"innerhole":false,"innerholeedgedistance":1.61} -{"fn":"tssop","num_pins":8,"w":6.1,"p":0.65,"legsoutside":true,"pw":0.6,"pl":1} - - -- Here is a list of unsupported footprints: - -1- hc - -keep in mind that num_pins can be replaced with a number directly infront of the footprint name like so: dip8_p1.27mm which means num_pins=8, don't do that for footprints with fixed number of pins like ms012 and sot723 - -### Components and Props - -- Here is a documentation of all available components and their types: - - - -```typescript -export const rotationPoint3 = z.object({ - x: z.union([z.number(), z.string()]), - y: z.union([z.number(), z.string()]), - z: z.union([z.number(), z.string()]), -}) -export interface CadModelBase { - rotationOffset?: - | number - | { x: number | string; y: number | string; z: number | string } - positionOffset?: { - x: number | string - y: number | string - z: number | string - } - size?: { x: number | string; y: number | string; z: number | string } -} -export const cadModelBase = z.object({ - rotationOffset: z.number().or(rotationPoint3).optional(), - positionOffset: point3.optional(), - size: point3.optional(), -}) -export interface CadModelStl extends CadModelBase { - stlUrl: string -} -export const cadModelStl = cadModelBase.extend({ - stlUrl: z.string(), -}) -export interface CadModelObj extends CadModelBase { - objUrl: string - mtlUrl?: string -} -export const cadModelObj = cadModelBase.extend({ - objUrl: z.string(), - mtlUrl: z.string().optional(), -}) -export interface CadModelJscad extends CadModelBase { - jscad: Record -} -export const cadModelJscad = cadModelBase.extend({ - jscad: z.record(z.any()), -}) -``` - -```typescript -export type Distance = number | string - -export { distance, length } from "circuit-json" -``` - -```typescript -/** - * This is an abbreviated definition of the soup elements that you can find here: - * https://docs.tscircuit.com/api-reference/advanced/soup#pcb-smtpad - */ -export type FootprintSoupElements = { - type: "pcb_smtpad" | "pcb_plated_hole" - x: string | number - y: string | number - layer?: LayerRef - holeDiameter?: string | number - outerDiameter?: string | number - shape?: "circle" | "rect" - width?: string | number - height?: string | number - portHints?: string[] -} -``` - -```typescript -export interface PcbLayoutProps { - pcbX?: string | number - pcbY?: string | number - pcbRotation?: string | number - layer?: LayerRefInput -} -export interface CommonLayoutProps { - pcbX?: string | number - pcbY?: string | number - pcbRotation?: string | number - - schX?: string | number - schY?: string | number - schRotation?: string | number - - layer?: LayerRefInput - footprint?: Footprint -} -export const pcbLayoutProps = z.object({ - pcbX: distance.optional(), - pcbY: distance.optional(), - pcbRotation: rotation.optional(), - layer: layer_ref.optional(), -}) -export const commonLayoutProps = z.object({ - pcbX: distance.optional(), - pcbY: distance.optional(), - pcbRotation: rotation.optional(), - schX: distance.optional(), - schY: distance.optional(), - schRotation: rotation.optional(), - layer: layer_ref.optional(), - footprint: footprintProp.optional(), -}) -export interface SupplierProps { - supplierPartNumbers?: SupplierPartNumbers -} -export const supplierProps = z.object({ - supplierPartNumbers: z.record(supplier_name, z.array(z.string())).optional(), -}) -export interface CommonComponentProps extends CommonLayoutProps { - key?: any - name: string - supplierPartNumbers?: SupplierPartNumbers - cadModel?: CadModelProp - children?: any - symbolName?: string -} -export const commonComponentProps = commonLayoutProps - .merge(supplierProps) - .extend({ - key: z.any().optional(), - name: z.string(), - cadModel: cadModelProp.optional(), - children: z.any().optional(), - symbolName: z.string().optional(), - }) -export const lrPolarPins = [ - "pin1", - "left", - "anode", - "pos", - "pin2", - "right", - "cathode", - "neg", -] as const -``` - -```typescript -export const point = z.object({ - x: distance, - y: distance, -}) -``` - -```typescript -export const point3 = z.object({ - x: distance, - y: distance, - z: distance, -}) -``` - -```typescript -/** - * @deprecated Use SchematicPortArrangementWithPinCounts instead. - */ -export interface SchematicPortArrangementWithSizes { - leftSize?: number - topSize?: number - rightSize?: number - bottomSize?: number -} -/** - * Specifies the number of pins on each side of the schematic box component. - */ -export interface SchematicPortArrangementWithPinCounts { - leftPinCount?: number - topPinCount?: number - rightPinCount?: number - bottomPinCount?: number -} -export interface PinSideDefinition { - pins: Array - direction: - | "top-to-bottom" - | "left-to-right" - | "bottom-to-top" - | "right-to-left" -} -export interface SchematicPortArrangementWithSides { - leftSide?: PinSideDefinition - topSide?: PinSideDefinition - rightSide?: PinSideDefinition - bottomSide?: PinSideDefinition -} -export interface SchematicPortArrangement - extends SchematicPortArrangementWithSizes, - SchematicPortArrangementWithSides, - SchematicPortArrangementWithPinCounts {} -export const explicitPinSideDefinition = z.object({ - pins: z.array(z.union([z.number(), z.string()])), - direction: z.union([ - z.literal("top-to-bottom"), - z.literal("left-to-right"), - z.literal("bottom-to-top"), - z.literal("right-to-left"), - ]), -}) -export const schematicPortArrangement = z.object({ - leftSize: z.number().optional().describe("@deprecated, use leftPinCount"), - topSize: z.number().optional().describe("@deprecated, use topPinCount"), - rightSize: z.number().optional().describe("@deprecated, use rightPinCount"), - bottomSize: z.number().optional().describe("@deprecated, use bottomPinCount"), - leftPinCount: z.number().optional(), - rightPinCount: z.number().optional(), - topPinCount: z.number().optional(), - bottomPinCount: z.number().optional(), - leftSide: explicitPinSideDefinition.optional(), - rightSide: explicitPinSideDefinition.optional(), - topSide: explicitPinSideDefinition.optional(), - bottomSide: explicitPinSideDefinition.optional(), -}) -``` - -```typescript -export type SchematicPinStyle = Record< - string, - { - leftMargin?: number | string - rightMargin?: number | string - topMargin?: number | string - bottomMargin?: number | string - } -export const schematicPinStyle = z.record( - z.object({ - leftMargin: distance.optional(), - rightMargin: distance.optional(), - topMargin: distance.optional(), - bottomMargin: distance.optional(), - }), -``` - -```typescript -/** @deprecated use battery_capacity from circuit-json when circuit-json is updated */ -export interface BatteryProps extends CommonComponentProps { - capacity?: number | string -} -export const batteryProps = commonComponentProps.extend({ - capacity: capacity.optional(), -}) -``` - -```typescript -export interface BoardProps extends Omit { - width?: number | string - height?: number | string - outline?: Point[] - outlineOffsetX?: number | string - outlineOffsetY?: number | string -} -export const boardProps = subcircuitGroupProps.extend({ - width: distance.optional(), - height: distance.optional(), - outline: z.array(point).optional(), - outlineOffsetX: distance.optional(), - outlineOffsetY: distance.optional(), -}) -``` - -```typescript -export interface CapacitorProps extends CommonComponentProps { - capacitance: number | string - polarized?: boolean - decouplingFor?: string - decouplingTo?: string - bypassFor?: string - bypassTo?: string - maxDecouplingTraceLength?: number -} -export const capacitorProps = commonComponentProps.extend({ - capacitance, - polarized: z.boolean().optional().default(false), - decouplingFor: z.string().optional(), - decouplingTo: z.string().optional(), - bypassFor: z.string().optional(), - bypassTo: z.string().optional(), - maxDecouplingTraceLength: z.number().optional(), -}) -``` - -```typescript -export interface ChipProps extends CommonComponentProps { - manufacturerPartNumber?: string - pinLabels?: Record - schPortArrangement?: SchematicPortArrangement - schPinStyle?: SchematicPinStyle - schPinSpacing?: Distance - schWidth?: Distance - schHeight?: Distance - noSchematicRepresentation?: boolean -} -export const chipProps = commonComponentProps.extend({ - manufacturerPartNumber: z.string().optional(), - pinLabels: z - .record( - z.number().or(z.string()), - z.string().or(z.array(z.string()).readonly()), - ) - .optional(), - schPortArrangement: schematicPortArrangement.optional(), - schPinStyle: schematicPinStyle.optional(), - schPinSpacing: distance.optional(), - schWidth: distance.optional(), - schHeight: distance.optional(), - noSchematicRepresentation: z.boolean().optional(), -}) -``` - -```typescript -export interface ConstrainedLayoutProps { - name?: string - pcbOnly?: boolean - schOnly?: boolean -} -export const constrainedLayoutProps = z.object({ - name: z.string().optional(), - pcbOnly: z.boolean().optional(), - schOnly: z.boolean().optional(), -}) -``` - -```typescript -export type PcbXDistConstraint = { - pcb?: true - xDist: Distance - - left: string - - right: string - - edgeToEdge?: true - - centerToCenter?: true -} -/** - * If true, the provided distance is the distance between the centers of the - * left and right components - */ -export type PcbYDistConstraint = { - pcb?: true - yDist: Distance - - top: string - - bottom: string - - edgeToEdge?: true - centerToCenter?: true -} -/** - * Selector for bottom component, e.g. ".U1" or ".R1", you can also specify the - * edge or center of the component e.g. ".R1 bottomedge", ".R1 center" - */ -export type PcbSameYConstraint = { - pcb?: true - sameY?: true - - for: string[] -} -/** - * Selector for components, e.g. [".U1", ".R1"], you can also specify the - * edge or center of the component e.g. [".R1 leftedge", ".U1 center"] - */ -export type PcbSameXConstraint = { - pcb?: true - sameX?: true - for: string[] -} -export const pcbXDistConstraintProps = z.object({ - pcb: z.literal(true).optional(), - xDist: distance, - left: z.string(), - right: z.string(), - - edgeToEdge: z.literal(true).optional(), - centerToCenter: z.literal(true).optional(), -}) -export const pcbYDistConstraintProps = z.object({ - pcb: z.literal(true).optional(), - yDist: distance, - top: z.string(), - bottom: z.string(), - - edgeToEdge: z.literal(true).optional(), - centerToCenter: z.literal(true).optional(), -}) -export const pcbSameYConstraintProps = z.object({ - pcb: z.literal(true).optional(), - sameY: z.literal(true).optional(), - for: z.array(z.string()), -}) -export const pcbSameXConstraintProps = z.object({ - pcb: z.literal(true).optional(), - sameX: z.literal(true).optional(), - for: z.array(z.string()), -}) -``` - -```typescript -export interface CrystalProps extends CommonComponentProps { - frequency: number | string - loadCapacitance: number | string - pinVariant?: PinVariant -} -export const crystalProps = commonComponentProps.extend({ - frequency: frequency, - loadCapacitance: capacitance, - pinVariant: z.enum(["2pin", "4pin"]).optional(), -}) -``` - -```typescript -export const fabricationNotePathProps = pcbLayoutProps - .omit({ pcbX: true, pcbY: true, pcbRotation: true }) -``` - -```typescript -export const fabricationNoteTextProps = pcbLayoutProps.extend({ - text: z.string(), - anchorAlignment: z - .enum(["center", "top_left", "top_right", "bottom_left", "bottom_right"]) - .default("center"), - font: z.enum(["tscircuit2024"]).optional(), - fontSize: length.optional(), - color: z.string().optional(), -}) -``` - -```typescript -export interface FootprintProps { - originalLayer?: LayerRef -} -/** - * The layer that the footprint is designed for. If you set this to "top" - * then it means the children were intended to represent the top layer. If - * the with this footprint is moved to the bottom layer, then the - * components will be mirrored. - * - * Generally, you shouldn't set this except where it can help prevent - * confusion because you have a complex multi-layer footprint. Default is - * "top" and this is most intuitive. - */ -export const footprintProps = z.object({ - originalLayer: layer_ref.default("top").optional(), -}) -``` - -```typescript -export interface BaseGroupProps extends CommonLayoutProps { - name?: string - key?: any - children?: any -} -export type PartsEngine = { - findPart: (params: { - sourceComponent: AnySourceComponent - footprinterString?: string - }) => Promise | SupplierPartNumbers -} -export interface PcbRouteCache { - pcbTraces: PcbTrace[] - cacheKey: string -} -export interface AutorouterConfig { - serverUrl?: string - inputFormat?: "simplified" | "circuit-json" - serverMode?: "job" | "solve-endpoint" - cache?: PcbRouteCache -} -export const autorouterConfig = z.object({ - serverUrl: z.string().optional(), - inputFormat: z.enum(["simplified", "circuit-json"]).optional(), - serverMode: z.enum(["job", "solve-endpoint"]).optional(), - cache: z.custom((v) => true).optional(), -}) -export interface SubcircuitGroupProps extends BaseGroupProps { - layout?: LayoutBuilder - manualEdits?: ManualEditsFileInput - routingDisabled?: boolean - defaultTraceWidth?: Distance - minTraceWidth?: Distance - pcbRouteCache?: PcbRouteCache - - autorouter?: AutorouterProp - - schAutoLayoutEnabled?: boolean - - schTraceAutoLabelEnabled?: boolean - - partsEngine?: PartsEngine -} -/** - * If true, net labels will automatically be created for complex traces - */ -export interface SubcircuitGroupPropsWithBool extends SubcircuitGroupProps { - subcircuit: true -} -export interface NonSubcircuitGroupProps extends BaseGroupProps { - subcircuit?: false | undefined -} -export const baseGroupProps = commonLayoutProps.extend({ - name: z.string().optional(), - children: z.any().optional(), - key: z.any().optional(), -}) -export const subcircuitGroupProps = baseGroupProps.extend({ - layout: z.custom((v) => true).optional(), - manualEdits: manual_edits_file.optional(), - schAutoLayoutEnabled: z.boolean().optional(), - schTraceAutoLabelEnabled: z.boolean().optional(), - routingDisabled: z.boolean().optional(), - defaultTraceWidth: length.optional(), - minTraceWidth: length.optional(), - partsEngine: z.custom((v) => "findPart" in v).optional(), - pcbRouteCache: z.custom((v) => true).optional(), - autorouter: autorouterProp.optional(), -}) -export const subcircuitGroupPropsWithBool = subcircuitGroupProps.extend({ - subcircuit: z.literal(true), -}) -export const groupProps = z.discriminatedUnion("subcircuit", [ - baseGroupProps.extend({ subcircuit: z.literal(false).optional() }), -``` - -```typescript -export interface HoleProps extends Omit { - name?: string - diameter?: Distance - radius?: Distance -} -export const holeProps = pcbLayoutProps - .omit({ pcbRotation: true }) -``` - -```typescript -export const inductorProps = commonComponentProps.extend({ - inductance, -}) -``` - -```typescript -export interface JumperProps extends CommonComponentProps { - manufacturerPartNumber?: string - pinLabels?: Record - schPinStyle?: SchematicPinStyle - schPinSpacing?: number | string - schWidth?: number | string - schHeight?: number | string - schDirection?: "left" | "right" - schPortArrangement?: SchematicPortArrangement -} -export const jumperProps = commonComponentProps.extend({ - manufacturerPartNumber: z.string().optional(), - pinLabels: z - .record(z.number().or(z.string()), z.string().or(z.array(z.string()))) - .optional(), - schPinStyle: schematicPinStyle.optional(), - schPinSpacing: distance.optional(), - schWidth: distance.optional(), - schHeight: distance.optional(), - schDirection: z.enum(["left", "right"]).optional(), - schPortArrangement: schematicPortArrangement.optional(), -}) -``` - -```typescript -export const ledProps = commonComponentProps.extend({ - color: z.string().optional(), -}) -``` - -```typescript -export interface MosfetProps extends CommonComponentProps { - channelType: "n" | "p" - mosfetMode: "enhancement" | "depletion" -} -export const mosfetProps = commonComponentProps.extend({ - channelType: z.enum(["n", "p"]), - mosfetMode: z.enum(["enhancement", "depletion"]), -}) -export const mosfetPins = [ - "pin1", - "drain", - "pin2", - "source", - "pin3", - "gate", -] as const -``` - -```typescript -export interface NetProps { - name: string -} -export const netProps = z.object({ - name: z.string(), -}) -``` - -```typescript -export interface NetAliasProps { - net?: string - schX?: number | string - schY?: number | string - schRotation?: number | string - anchorSide?: "left" | "up" | "right" | "down" -} -export const netAliasProps = z.object({ - net: z.string().optional(), - schX: distance.optional(), - schY: distance.optional(), - schRotation: rotation.optional(), - anchorSide: z.enum(["left", "up", "right", "down"]).optional(), -}) -``` - -```typescript -export const pcbKeepoutProps = z.union([ - pcbLayoutProps.omit({ pcbRotation: true }).extend({ - shape: z.literal("circle"), - radius: distance, - }), -``` - -```typescript -export const pcbTraceProps = z.object({ - layer: z.string().optional(), - thickness: distance.optional(), - route: z.array(route_hint_point), -}) -``` - -```typescript -export interface PinHeaderProps extends CommonComponentProps { - pinCount: number - - pitch?: number | string - - gender?: "male" | "female" - - showSilkscreenPinLabels?: boolean - - doubleRow?: boolean - - holeDiameter?: number | string - - platedDiameter?: number | string - - pinLabels?: string[] - - facingDirection?: "left" | "right" -} -/** - * Direction the header is facing - */ -export const pinHeaderProps = commonComponentProps.extend({ - pinCount: z.number(), - pitch: distance.optional(), - gender: z.enum(["male", "female"]).optional().default("male"), - showSilkscreenPinLabels: z.boolean().optional(), - doubleRow: z.boolean().optional(), - holeDiameter: distance.optional(), - platedDiameter: distance.optional(), - pinLabels: z.array(z.string()).optional(), - facingDirection: z.enum(["left", "right"]).optional(), -}) -``` - -```typescript -export interface CirclePlatedHoleProps - extends Omit { - name?: string - shape: "circle" - holeDiameter: number | string - outerDiameter: number | string - portHints?: PortHints -} -export interface OvalPlatedHoleProps - extends Omit { - name?: string - shape: "oval" - outerWidth: number | string - outerHeight: number | string - innerWidth: number | string - innerHeight: number | string - portHints?: PortHints -} -export interface PillPlatedHoleProps - extends Omit { - name?: string - shape: "pill" - outerWidth: number | string - outerHeight: number | string - innerWidth: number | string - innerHeight: number | string - portHints?: PortHints -} -export const platedHoleProps = z.discriminatedUnion("shape", [ - pcbLayoutProps.omit({ pcbRotation: true, layer: true }).extend({ - name: z.string().optional(), - shape: z.literal("circle"), - holeDiameter: distance, - outerDiameter: distance, - portHints: portHints.optional(), - }), -``` - -```typescript -export const portProps = commonLayoutProps.extend({ - name: z.string(), - pinNumber: z.number().optional(), - aliases: z.array(z.string()).optional(), - direction: direction, -}) -``` - -```typescript -export interface PotentiometerProps extends CommonComponentProps { - maxResistance: number | string -} -export const potentiometerProps = commonComponentProps.extend({ - maxResistance: resistance, -}) -``` - -```typescript -export const powerSourceProps = commonComponentProps.extend({ - voltage, -}) -``` - -```typescript -export interface ResistorProps extends CommonComponentProps { - resistance: number | string - pullupFor?: string - pullupTo?: string - pulldownFor?: string - pulldownTo?: string -} -export const resistorProps = commonComponentProps.extend({ - resistance, - - pullupFor: z.string().optional(), - pullupTo: z.string().optional(), - - pulldownFor: z.string().optional(), - pulldownTo: z.string().optional(), -}) -``` - -```typescript -export interface ResonatorProps extends CommonComponentProps { - frequency: number | string - loadCapacitance: number | string - pinVariant?: ResonatorPinVariant -} -export const resonatorProps = commonComponentProps.extend({ - frequency: frequency, - loadCapacitance: capacitance, - pinVariant: z.enum(["no_ground", "ground_pin", "two_ground_pins"]).optional(), -}) -``` - -```typescript -export const schematicBoxProps = z.object({ - schX: distance, - schY: distance, - width: distance, - height: distance, -}) -``` - -```typescript -export const schematicLineProps = z.object({ - x1: distance, - y1: distance, - x2: distance, - y2: distance, -}) -``` - -```typescript -export const schematicPathProps = z.object({ - points: z.array(point), - isFilled: z.boolean().optional().default(false), - fillColor: z.enum(["red", "blue"]).optional(), -}) -``` - -```typescript -export const schematicTextProps = z.object({ - schX: distance, - schY: distance, - text: z.string(), -}) -``` - -```typescript -export const silkscreenCircleProps = pcbLayoutProps - .omit({ pcbRotation: true }) -``` - -```typescript -export const silkscreenLineProps = pcbLayoutProps - .omit({ pcbX: true, pcbY: true, pcbRotation: true }) -``` - -```typescript -export const silkscreenPathProps = pcbLayoutProps - .omit({ pcbX: true, pcbY: true, pcbRotation: true }) -``` - -```typescript -export const silkscreenRectProps = pcbLayoutProps - .omit({ pcbRotation: true }) -``` - -```typescript -export const silkscreenTextProps = pcbLayoutProps.extend({ - text: z.string(), - anchorAlignment: z - .enum(["center", "top_left", "top_right", "bottom_left", "bottom_right"]) - .default("center"), - font: z.enum(["tscircuit2024"]).optional(), - fontSize: length.optional(), -}) -``` - -```typescript -export interface RectSmtPadProps extends Omit { - shape: "rect" - width: Distance - height: Distance - portHints?: PortHints -} -export interface RotatedRectSmtPadProps - extends Omit { - shape: "rotated_rect" - width: Distance - height: Distance - ccwRotation: number - portHints?: PortHints -} -export interface CircleSmtPadProps extends Omit { - shape: "circle" - radius: Distance - portHints?: PortHints -} -export const rectSmtPadProps = pcbLayoutProps - .omit({ pcbRotation: true }) -export const rotatedRectSmtPadProps = pcbLayoutProps - .omit({ pcbRotation: true }) -export const circleSmtPadProps = pcbLayoutProps - .omit({ pcbRotation: true }) -``` - -```typescript -export interface RectSolderPasteProps - extends Omit { - shape: "rect" - width: Distance - height: Distance -} -export interface CircleSolderPasteProps - extends Omit { - shape: "circle" - radius: Distance -} -export const rectSolderPasteProps = pcbLayoutProps - .omit({ pcbRotation: true }) -export const circleSolderPasteProps = pcbLayoutProps - .omit({ pcbRotation: true }) -``` - -```typescript -export const switchProps = commonComponentProps.extend({ - ftype: z.literal("switch"), - switchType: z.enum(["spst"]).default("spst"), - isNormallyClosed: z.boolean().default(false), -}) -``` - -```typescript -export const routeHintPointProps = z.object({ - x: distance, - y: distance, - via: z.boolean().optional(), - toLayer: layer_ref.optional(), -}) -export const traceHintProps = z.object({ - for: z - .string() - .optional() - .describe( - "Selector for the port you're targeting, not required if you're inside a trace", - ), - order: z.number().optional(), - offset: route_hint_point.or(routeHintPointProps).optional(), - offsets: z - .array(route_hint_point) - .or(z.array(routeHintPointProps)) - .optional(), - traceWidth: z.number().optional(), -}) -``` - -```typescript -export const portRef = z.union([ - z.string(), - z.custom<{ getPortSelector: () => string }>((v) => -export const traceProps = z.union([ - baseTraceProps.extend({ - path: z.array(portRef), - }), -``` - -```typescript -export interface TransistorProps extends CommonComponentProps { - transistorType: "npn" | "pnp" -} -export const transistorProps = commonComponentProps.extend({ - transistorType: z.enum(["npn", "pnp"]), -}) -export const transistorPins = [ - "pin1", - "emitter", - "pin2", - "collector", - "pin3", - "base", -] as const -``` - -```typescript -export const viaProps = commonLayoutProps.extend({ - fromLayer: layer_ref, - toLayer: layer_ref, - holeDiameter: distance, - outerDiameter: distance, -}) -``` - - - -- Here is a list of unsupported components: - -1- powersource -2- powersourcesimple -3- pinheader - -- Here are examples of how you can take advantage of those props: - - // Example of a custom chip footprint definition - const CustomChipFootprint = () => ( - - // SMT pads for the chip - - - - - - // Silkscreen markings for the chip outline - - // Pin 1 indicator - - - ) - - // Example of a custom resistor footprint - const Resistor0603Footprint = () => ( - - - - - - ) - - // Example of a complete circuit - export const MyCircuit = () => ( - - // Power section group - - // Decoupling capacitor arrangement - - - - - - // Input protection group - - - - - - - // Power nets - - - - // Connections - - - - // Layout constraints - - - ) - - // Example of a custom module/component that can be reused - export const DecouplingCapacitor = ({ - chipRef, - capName, - capValue = "100nF", - distance = "2mm" - }) => ( - - - - - ) - - // Usage of the custom module - export const CircuitWithDecoupling = () => ( - - - - - ) - - -### RULES - -- decouplingFor must contain the selector for the component and the pin(eg. ".U1 .pin1", ".T1 .pin1") -- Never pass the component name alone as a selector for decouplingFor, always use the component name reference and the pin number -- Don't use hole or port components, always connect to the component pins -- Don't use inline comments which are comments in the same line as components, they are forbidden -- Port components must be children to a chip component. -- Never use components in the "Unsupported components" list -- Never use footprints in the "Unsupported footprints" list -- Any component may have a pcbX and/or a pcbY representing the center of the - component on a circuit board. -- Never use footprints that are not supported in the "All available footprints" section -- Some footprints have a fixed number of pins like ms012 and sot723 -- `` components use CSS selectors in the `from` and `to` fields - to connect components. -- Any component can have a `name` prop -- `pcbX` and `pcbY` are optional and default to 0. -- A board is centered on the origin (pcbX=0, pcbY=0), so to place a component - at the center it must be placed at pcbX=0,pcbY=0. Similarly, if you're trying - to layout components around the center, you would make ones to the left of - the center have negative pcbX values, below the center have negative pcbY, - and to the right of the center have positive pcbX values, and above the - center have positive pcbY values. -- Every component that is going to be placed must be given a footprint -- Traces can only take two ports -- Don't use path as prop for trace, only use from, to -- We don't support defining output ports, so don't defined port components -- Don't specify autorouter; don't use the autorouter prop -- Selectors for component pins must be of this format: ".U1 > .pin1" or ".U1 > .pin2" where U1 is the component name, and the pins must be numbers, so don't use names for pins but use pin1, pin2, pin3, pin4 -- And instead of ".T1 > .base" you do do ".T1 > .pin2" -- "for" must have at least two selectors for constraints - -### Trace Reference Syntax - -Traces are created using the `` component. The `from` and `to` -fields are CSS selectors that reference the components to connect. - -Examples: - - - - - -### Output - -Use a codefence with the language "tsx" to wrap the code. You can use the -current_code of the user as a starting point (if provided). - -You must export a higher-order component where the root component is `` -inside the codefence. For example: - -```tsx -export const MyLed = () => ( - - - - - -) -``` \ No newline at end of file diff --git a/benchmarks/prompt-logs/prompt-2025-02-18T12-48-05-645Z.txt b/benchmarks/prompt-logs/prompt-2025-02-18T12-48-05-645Z.txt deleted file mode 100644 index 3006fae..0000000 --- a/benchmarks/prompt-logs/prompt-2025-02-18T12-48-05-645Z.txt +++ /dev/null @@ -1,1250 +0,0 @@ -You are an expert in electronic circuit design and tscircuit, and your job is to create a circuit board in tscircuit with the user-provided description. - -YOU MUST ABIDE BY THE RULES IN THE RULES SECTION - -## tscircuit API overview - -Here's an overview of the tscircuit API: - - // usually the root component - // custom shape instead of rectangle - - - - - - - - - - - - - -### footprint strings - -Footprint strings are a compact way to represent the physical footprint for a -component. Any component can be given a footprint string. Here are example -footprint strings: - -0402 -0603 -0805 -1206 -1210 -cap0402 -res0402 -soic8_p1.27mm -dip16 -pinrow10 -tssop20_p0.5mm -sot23 - -### All available footprints - -- Either use a passive footprint like this (e.g. 0402, 0603, 0805, 1206, 1210), here is a json string with all available footprint passive sizes: - -["01005","0201","0402","0603","0805","1206","1210","2010","2512"] - -- Or create a footprint string like this (e.g. dfn8_w5.3mm_p1.27mm, dip10_w4.00mm_p2.65mm, lqfp64_w10_h10_pl1_pw0.25mm, sot363, stampreceiver_left20_right20_bottom3_top2_w21mm_p2.54mm, tssop20_w6.5mm_p0.65mm, bga7_w8_h8_grid3x3_p1_missing(center,B1), bga64_w10_h10_grid8x8_p1.27mm), here are json objects with the available footprints and their options: - -{"fn":"axial","p":2.54,"id":0.7,"od":1} -{"fn":"bga","num_pins":64,"p":0.8,"missing":[],"grid":{"x":8,"y":8},"origin":"tl"} -{"fn":"breakoutheaders","w":10,"left":20,"right":20,"top":0,"bottom":0,"p":2.54,"id":1,"od":1.5} -{"fn":"dfn","num_pins":8,"w":5.3,"p":1.27,"legsoutside":false,"pw":0.6,"pl":1} -{"fn":"dip","num_pins":6,"p":2.54,"id":1,"od":1.5,"w":7.62} -{"fn":"lqfp","num_pins":64,"p":0.5,"legsoutside":true,"w":10,"h":10,"pw":0.25,"pl":0.25} -{"fn":"mlp","num_pins":64,"p":0.5,"thermalpad":true,"legsoutside":false,"w":10,"h":10,"pw":0.25,"pl":0.25} -{"fn":"ms012","num_pins":8,"w":3.9,"p":1.27,"legsoutside":true,"pw":0.6,"pl":1} -{"fn":"ms013","num_pins":16,"w":7.5,"p":1.27,"legsoutside":true,"pw":0.6,"pl":1} -{"fn":"pinrow","num_pins":6,"p":2.54,"id":1,"od":1.5} -{"fn":"pushbutton","w":4.5,"h":6.5,"id":1,"od":1.2} -{"fn":"qfn","num_pins":64,"p":0.5,"legsoutside":false,"w":10,"h":10,"pw":0.25,"pl":0.25} -{"fn":"qfp","num_pins":64,"p":0.5,"pw":0.25,"pl":1,"legsoutside":true,"w":10,"h":10} -{"fn":"quad","num_pins":64,"p":0.5,"legsoutside":false,"w":10,"h":10,"pw":0.25,"pl":0.25} -{"fn":"sod123","num_pins":2,"w":"2.36mm","h":"1.22mm","pl":"0.9mm","pw":"0.9mm","pad_spacing":"4.19mm"} -{"fn":"soic","num_pins":8,"w":5.3,"p":1.27,"legsoutside":false,"pw":0.6,"pl":1} -{"fn":"sot23","num_pins":3,"w":"1.92mm","h":"2.74mm","pl":"0.8mm","pw":"0.764mm"} -{"fn":"sot235","num_pins":5,"h":"1.6mm","pl":"1mm","pw":"0.7mm","p":"0.95mm"} -{"fn":"sot236","num_pins":6,"w":1.6,"p":0.95,"legsoutside":true,"pw":0.6,"pl":1} -{"fn":"sot363","num_pins":6,"w":1.94,"p":0.65,"pw":0.3,"pl":0.7,"legsoutside":false} -{"fn":"sot563","num_pins":6,"w":1.94,"p":0.5,"pw":0.3,"pl":0.67,"legsoutside":false} -{"fn":"sot723","num_pins":3,"w":"1.2mm","h":"1.2mm","pl":"0.3mm","pw":"0.32mm"} -{"fn":"ssop","num_pins":8,"w":3.9,"p":1.27,"legsoutside":false,"pw":0.6,"pl":1} -{"fn":"stampboard","w":22.58,"left":20,"right":20,"top":2,"bottom":2,"p":2.54,"pw":1.6,"pl":2.4,"innerhole":false,"innerholeedgedistance":1.61} -{"fn":"stampreceiver","w":22.58,"left":20,"right":20,"top":2,"bottom":2,"p":2.54,"pw":1.6,"pl":3.2,"innerhole":false,"innerholeedgedistance":1.61} -{"fn":"tssop","num_pins":8,"w":6.1,"p":0.65,"legsoutside":true,"pw":0.6,"pl":1} - - -- Here is a list of unsupported footprints: - -1- hc - -keep in mind that num_pins can be replaced with a number directly infront of the footprint name like so: dip8_p1.27mm which means num_pins=8, don't do that for footprints with fixed number of pins like ms012 and sot723 - -### Components and Props - -- Here is a documentation of all available components and their types: - - - -```typescript -export const rotationPoint3 = z.object({ - x: z.union([z.number(), z.string()]), - y: z.union([z.number(), z.string()]), - z: z.union([z.number(), z.string()]), -}) -export interface CadModelBase { - rotationOffset?: - | number - | { x: number | string; y: number | string; z: number | string } - positionOffset?: { - x: number | string - y: number | string - z: number | string - } - size?: { x: number | string; y: number | string; z: number | string } -} -export const cadModelBase = z.object({ - rotationOffset: z.number().or(rotationPoint3).optional(), - positionOffset: point3.optional(), - size: point3.optional(), -}) -export interface CadModelStl extends CadModelBase { - stlUrl: string -} -export const cadModelStl = cadModelBase.extend({ - stlUrl: z.string(), -}) -export interface CadModelObj extends CadModelBase { - objUrl: string - mtlUrl?: string -} -export const cadModelObj = cadModelBase.extend({ - objUrl: z.string(), - mtlUrl: z.string().optional(), -}) -export interface CadModelJscad extends CadModelBase { - jscad: Record -} -export const cadModelJscad = cadModelBase.extend({ - jscad: z.record(z.any()), -}) -``` - -```typescript -export type Distance = number | string - -export { distance, length } from "circuit-json" -``` - -```typescript -/** - * This is an abbreviated definition of the soup elements that you can find here: - * https://docs.tscircuit.com/api-reference/advanced/soup#pcb-smtpad - */ -export type FootprintSoupElements = { - type: "pcb_smtpad" | "pcb_plated_hole" - x: string | number - y: string | number - layer?: LayerRef - holeDiameter?: string | number - outerDiameter?: string | number - shape?: "circle" | "rect" - width?: string | number - height?: string | number - portHints?: string[] -} -``` - -```typescript -export interface PcbLayoutProps { - pcbX?: string | number - pcbY?: string | number - pcbRotation?: string | number - layer?: LayerRefInput -} -export interface CommonLayoutProps { - pcbX?: string | number - pcbY?: string | number - pcbRotation?: string | number - - schX?: string | number - schY?: string | number - schRotation?: string | number - - layer?: LayerRefInput - footprint?: Footprint -} -export const pcbLayoutProps = z.object({ - pcbX: distance.optional(), - pcbY: distance.optional(), - pcbRotation: rotation.optional(), - layer: layer_ref.optional(), -}) -export const commonLayoutProps = z.object({ - pcbX: distance.optional(), - pcbY: distance.optional(), - pcbRotation: rotation.optional(), - schX: distance.optional(), - schY: distance.optional(), - schRotation: rotation.optional(), - layer: layer_ref.optional(), - footprint: footprintProp.optional(), -}) -export interface SupplierProps { - supplierPartNumbers?: SupplierPartNumbers -} -export const supplierProps = z.object({ - supplierPartNumbers: z.record(supplier_name, z.array(z.string())).optional(), -}) -export interface CommonComponentProps extends CommonLayoutProps { - key?: any - name: string - supplierPartNumbers?: SupplierPartNumbers - cadModel?: CadModelProp - children?: any - symbolName?: string -} -export const commonComponentProps = commonLayoutProps - .merge(supplierProps) - .extend({ - key: z.any().optional(), - name: z.string(), - cadModel: cadModelProp.optional(), - children: z.any().optional(), - symbolName: z.string().optional(), - }) -export const lrPolarPins = [ - "pin1", - "left", - "anode", - "pos", - "pin2", - "right", - "cathode", - "neg", -] as const -``` - -```typescript -export const point = z.object({ - x: distance, - y: distance, -}) -``` - -```typescript -export const point3 = z.object({ - x: distance, - y: distance, - z: distance, -}) -``` - -```typescript -/** - * @deprecated Use SchematicPortArrangementWithPinCounts instead. - */ -export interface SchematicPortArrangementWithSizes { - leftSize?: number - topSize?: number - rightSize?: number - bottomSize?: number -} -/** - * Specifies the number of pins on each side of the schematic box component. - */ -export interface SchematicPortArrangementWithPinCounts { - leftPinCount?: number - topPinCount?: number - rightPinCount?: number - bottomPinCount?: number -} -export interface PinSideDefinition { - pins: Array - direction: - | "top-to-bottom" - | "left-to-right" - | "bottom-to-top" - | "right-to-left" -} -export interface SchematicPortArrangementWithSides { - leftSide?: PinSideDefinition - topSide?: PinSideDefinition - rightSide?: PinSideDefinition - bottomSide?: PinSideDefinition -} -export interface SchematicPortArrangement - extends SchematicPortArrangementWithSizes, - SchematicPortArrangementWithSides, - SchematicPortArrangementWithPinCounts {} -export const explicitPinSideDefinition = z.object({ - pins: z.array(z.union([z.number(), z.string()])), - direction: z.union([ - z.literal("top-to-bottom"), - z.literal("left-to-right"), - z.literal("bottom-to-top"), - z.literal("right-to-left"), - ]), -}) -export const schematicPortArrangement = z.object({ - leftSize: z.number().optional().describe("@deprecated, use leftPinCount"), - topSize: z.number().optional().describe("@deprecated, use topPinCount"), - rightSize: z.number().optional().describe("@deprecated, use rightPinCount"), - bottomSize: z.number().optional().describe("@deprecated, use bottomPinCount"), - leftPinCount: z.number().optional(), - rightPinCount: z.number().optional(), - topPinCount: z.number().optional(), - bottomPinCount: z.number().optional(), - leftSide: explicitPinSideDefinition.optional(), - rightSide: explicitPinSideDefinition.optional(), - topSide: explicitPinSideDefinition.optional(), - bottomSide: explicitPinSideDefinition.optional(), -}) -``` - -```typescript -export type SchematicPinStyle = Record< - string, - { - leftMargin?: number | string - rightMargin?: number | string - topMargin?: number | string - bottomMargin?: number | string - } -export const schematicPinStyle = z.record( - z.object({ - leftMargin: distance.optional(), - rightMargin: distance.optional(), - topMargin: distance.optional(), - bottomMargin: distance.optional(), - }), -``` - -```typescript -/** @deprecated use battery_capacity from circuit-json when circuit-json is updated */ -export interface BatteryProps extends CommonComponentProps { - capacity?: number | string -} -export const batteryProps = commonComponentProps.extend({ - capacity: capacity.optional(), -}) -``` - -```typescript -export interface BoardProps extends Omit { - width?: number | string - height?: number | string - outline?: Point[] - outlineOffsetX?: number | string - outlineOffsetY?: number | string -} -export const boardProps = subcircuitGroupProps.extend({ - width: distance.optional(), - height: distance.optional(), - outline: z.array(point).optional(), - outlineOffsetX: distance.optional(), - outlineOffsetY: distance.optional(), -}) -``` - -```typescript -export interface CapacitorProps extends CommonComponentProps { - capacitance: number | string - polarized?: boolean - decouplingFor?: string - decouplingTo?: string - bypassFor?: string - bypassTo?: string - maxDecouplingTraceLength?: number -} -export const capacitorProps = commonComponentProps.extend({ - capacitance, - polarized: z.boolean().optional().default(false), - decouplingFor: z.string().optional(), - decouplingTo: z.string().optional(), - bypassFor: z.string().optional(), - bypassTo: z.string().optional(), - maxDecouplingTraceLength: z.number().optional(), -}) -``` - -```typescript -export interface ChipProps extends CommonComponentProps { - manufacturerPartNumber?: string - pinLabels?: Record - schPortArrangement?: SchematicPortArrangement - schPinStyle?: SchematicPinStyle - schPinSpacing?: Distance - schWidth?: Distance - schHeight?: Distance - noSchematicRepresentation?: boolean -} -export const chipProps = commonComponentProps.extend({ - manufacturerPartNumber: z.string().optional(), - pinLabels: z - .record( - z.number().or(z.string()), - z.string().or(z.array(z.string()).readonly()), - ) - .optional(), - schPortArrangement: schematicPortArrangement.optional(), - schPinStyle: schematicPinStyle.optional(), - schPinSpacing: distance.optional(), - schWidth: distance.optional(), - schHeight: distance.optional(), - noSchematicRepresentation: z.boolean().optional(), -}) -``` - -```typescript -export interface ConstrainedLayoutProps { - name?: string - pcbOnly?: boolean - schOnly?: boolean -} -export const constrainedLayoutProps = z.object({ - name: z.string().optional(), - pcbOnly: z.boolean().optional(), - schOnly: z.boolean().optional(), -}) -``` - -```typescript -export type PcbXDistConstraint = { - pcb?: true - xDist: Distance - - left: string - - right: string - - edgeToEdge?: true - - centerToCenter?: true -} -/** - * If true, the provided distance is the distance between the centers of the - * left and right components - */ -export type PcbYDistConstraint = { - pcb?: true - yDist: Distance - - top: string - - bottom: string - - edgeToEdge?: true - centerToCenter?: true -} -/** - * Selector for bottom component, e.g. ".U1" or ".R1", you can also specify the - * edge or center of the component e.g. ".R1 bottomedge", ".R1 center" - */ -export type PcbSameYConstraint = { - pcb?: true - sameY?: true - - for: string[] -} -/** - * Selector for components, e.g. [".U1", ".R1"], you can also specify the - * edge or center of the component e.g. [".R1 leftedge", ".U1 center"] - */ -export type PcbSameXConstraint = { - pcb?: true - sameX?: true - for: string[] -} -export const pcbXDistConstraintProps = z.object({ - pcb: z.literal(true).optional(), - xDist: distance, - left: z.string(), - right: z.string(), - - edgeToEdge: z.literal(true).optional(), - centerToCenter: z.literal(true).optional(), -}) -export const pcbYDistConstraintProps = z.object({ - pcb: z.literal(true).optional(), - yDist: distance, - top: z.string(), - bottom: z.string(), - - edgeToEdge: z.literal(true).optional(), - centerToCenter: z.literal(true).optional(), -}) -export const pcbSameYConstraintProps = z.object({ - pcb: z.literal(true).optional(), - sameY: z.literal(true).optional(), - for: z.array(z.string()), -}) -export const pcbSameXConstraintProps = z.object({ - pcb: z.literal(true).optional(), - sameX: z.literal(true).optional(), - for: z.array(z.string()), -}) -``` - -```typescript -export interface CrystalProps extends CommonComponentProps { - frequency: number | string - loadCapacitance: number | string - pinVariant?: PinVariant -} -export const crystalProps = commonComponentProps.extend({ - frequency: frequency, - loadCapacitance: capacitance, - pinVariant: z.enum(["2pin", "4pin"]).optional(), -}) -``` - -```typescript -export const fabricationNotePathProps = pcbLayoutProps - .omit({ pcbX: true, pcbY: true, pcbRotation: true }) -``` - -```typescript -export const fabricationNoteTextProps = pcbLayoutProps.extend({ - text: z.string(), - anchorAlignment: z - .enum(["center", "top_left", "top_right", "bottom_left", "bottom_right"]) - .default("center"), - font: z.enum(["tscircuit2024"]).optional(), - fontSize: length.optional(), - color: z.string().optional(), -}) -``` - -```typescript -export interface FootprintProps { - originalLayer?: LayerRef -} -/** - * The layer that the footprint is designed for. If you set this to "top" - * then it means the children were intended to represent the top layer. If - * the with this footprint is moved to the bottom layer, then the - * components will be mirrored. - * - * Generally, you shouldn't set this except where it can help prevent - * confusion because you have a complex multi-layer footprint. Default is - * "top" and this is most intuitive. - */ -export const footprintProps = z.object({ - originalLayer: layer_ref.default("top").optional(), -}) -``` - -```typescript -export interface BaseGroupProps extends CommonLayoutProps { - name?: string - key?: any - children?: any -} -export type PartsEngine = { - findPart: (params: { - sourceComponent: AnySourceComponent - footprinterString?: string - }) => Promise | SupplierPartNumbers -} -export interface PcbRouteCache { - pcbTraces: PcbTrace[] - cacheKey: string -} -export interface AutorouterConfig { - serverUrl?: string - inputFormat?: "simplified" | "circuit-json" - serverMode?: "job" | "solve-endpoint" - cache?: PcbRouteCache -} -export const autorouterConfig = z.object({ - serverUrl: z.string().optional(), - inputFormat: z.enum(["simplified", "circuit-json"]).optional(), - serverMode: z.enum(["job", "solve-endpoint"]).optional(), - cache: z.custom((v) => true).optional(), -}) -export interface SubcircuitGroupProps extends BaseGroupProps { - layout?: LayoutBuilder - manualEdits?: ManualEditsFileInput - routingDisabled?: boolean - defaultTraceWidth?: Distance - minTraceWidth?: Distance - pcbRouteCache?: PcbRouteCache - - autorouter?: AutorouterProp - - schAutoLayoutEnabled?: boolean - - schTraceAutoLabelEnabled?: boolean - - partsEngine?: PartsEngine -} -/** - * If true, net labels will automatically be created for complex traces - */ -export interface SubcircuitGroupPropsWithBool extends SubcircuitGroupProps { - subcircuit: true -} -export interface NonSubcircuitGroupProps extends BaseGroupProps { - subcircuit?: false | undefined -} -export const baseGroupProps = commonLayoutProps.extend({ - name: z.string().optional(), - children: z.any().optional(), - key: z.any().optional(), -}) -export const subcircuitGroupProps = baseGroupProps.extend({ - layout: z.custom((v) => true).optional(), - manualEdits: manual_edits_file.optional(), - schAutoLayoutEnabled: z.boolean().optional(), - schTraceAutoLabelEnabled: z.boolean().optional(), - routingDisabled: z.boolean().optional(), - defaultTraceWidth: length.optional(), - minTraceWidth: length.optional(), - partsEngine: z.custom((v) => "findPart" in v).optional(), - pcbRouteCache: z.custom((v) => true).optional(), - autorouter: autorouterProp.optional(), -}) -export const subcircuitGroupPropsWithBool = subcircuitGroupProps.extend({ - subcircuit: z.literal(true), -}) -export const groupProps = z.discriminatedUnion("subcircuit", [ - baseGroupProps.extend({ subcircuit: z.literal(false).optional() }), -``` - -```typescript -export interface HoleProps extends Omit { - name?: string - diameter?: Distance - radius?: Distance -} -export const holeProps = pcbLayoutProps - .omit({ pcbRotation: true }) -``` - -```typescript -export const inductorProps = commonComponentProps.extend({ - inductance, -}) -``` - -```typescript -export interface JumperProps extends CommonComponentProps { - manufacturerPartNumber?: string - pinLabels?: Record - schPinStyle?: SchematicPinStyle - schPinSpacing?: number | string - schWidth?: number | string - schHeight?: number | string - schDirection?: "left" | "right" - schPortArrangement?: SchematicPortArrangement -} -export const jumperProps = commonComponentProps.extend({ - manufacturerPartNumber: z.string().optional(), - pinLabels: z - .record(z.number().or(z.string()), z.string().or(z.array(z.string()))) - .optional(), - schPinStyle: schematicPinStyle.optional(), - schPinSpacing: distance.optional(), - schWidth: distance.optional(), - schHeight: distance.optional(), - schDirection: z.enum(["left", "right"]).optional(), - schPortArrangement: schematicPortArrangement.optional(), -}) -``` - -```typescript -export const ledProps = commonComponentProps.extend({ - color: z.string().optional(), -}) -``` - -```typescript -export interface MosfetProps extends CommonComponentProps { - channelType: "n" | "p" - mosfetMode: "enhancement" | "depletion" -} -export const mosfetProps = commonComponentProps.extend({ - channelType: z.enum(["n", "p"]), - mosfetMode: z.enum(["enhancement", "depletion"]), -}) -export const mosfetPins = [ - "pin1", - "drain", - "pin2", - "source", - "pin3", - "gate", -] as const -``` - -```typescript -export interface NetProps { - name: string -} -export const netProps = z.object({ - name: z.string(), -}) -``` - -```typescript -export interface NetAliasProps { - net?: string - schX?: number | string - schY?: number | string - schRotation?: number | string - anchorSide?: "left" | "up" | "right" | "down" -} -export const netAliasProps = z.object({ - net: z.string().optional(), - schX: distance.optional(), - schY: distance.optional(), - schRotation: rotation.optional(), - anchorSide: z.enum(["left", "up", "right", "down"]).optional(), -}) -``` - -```typescript -export const pcbKeepoutProps = z.union([ - pcbLayoutProps.omit({ pcbRotation: true }).extend({ - shape: z.literal("circle"), - radius: distance, - }), -``` - -```typescript -export const pcbTraceProps = z.object({ - layer: z.string().optional(), - thickness: distance.optional(), - route: z.array(route_hint_point), -}) -``` - -```typescript -export interface PinHeaderProps extends CommonComponentProps { - pinCount: number - - pitch?: number | string - - gender?: "male" | "female" - - showSilkscreenPinLabels?: boolean - - doubleRow?: boolean - - holeDiameter?: number | string - - platedDiameter?: number | string - - pinLabels?: string[] - - facingDirection?: "left" | "right" -} -/** - * Direction the header is facing - */ -export const pinHeaderProps = commonComponentProps.extend({ - pinCount: z.number(), - pitch: distance.optional(), - gender: z.enum(["male", "female"]).optional().default("male"), - showSilkscreenPinLabels: z.boolean().optional(), - doubleRow: z.boolean().optional(), - holeDiameter: distance.optional(), - platedDiameter: distance.optional(), - pinLabels: z.array(z.string()).optional(), - facingDirection: z.enum(["left", "right"]).optional(), -}) -``` - -```typescript -export interface CirclePlatedHoleProps - extends Omit { - name?: string - shape: "circle" - holeDiameter: number | string - outerDiameter: number | string - portHints?: PortHints -} -export interface OvalPlatedHoleProps - extends Omit { - name?: string - shape: "oval" - outerWidth: number | string - outerHeight: number | string - innerWidth: number | string - innerHeight: number | string - portHints?: PortHints -} -export interface PillPlatedHoleProps - extends Omit { - name?: string - shape: "pill" - outerWidth: number | string - outerHeight: number | string - innerWidth: number | string - innerHeight: number | string - portHints?: PortHints -} -export const platedHoleProps = z.discriminatedUnion("shape", [ - pcbLayoutProps.omit({ pcbRotation: true, layer: true }).extend({ - name: z.string().optional(), - shape: z.literal("circle"), - holeDiameter: distance, - outerDiameter: distance, - portHints: portHints.optional(), - }), -``` - -```typescript -export const portProps = commonLayoutProps.extend({ - name: z.string(), - pinNumber: z.number().optional(), - aliases: z.array(z.string()).optional(), - direction: direction, -}) -``` - -```typescript -export interface PotentiometerProps extends CommonComponentProps { - maxResistance: number | string -} -export const potentiometerProps = commonComponentProps.extend({ - maxResistance: resistance, -}) -``` - -```typescript -export const powerSourceProps = commonComponentProps.extend({ - voltage, -}) -``` - -```typescript -export interface ResistorProps extends CommonComponentProps { - resistance: number | string - pullupFor?: string - pullupTo?: string - pulldownFor?: string - pulldownTo?: string -} -export const resistorProps = commonComponentProps.extend({ - resistance, - - pullupFor: z.string().optional(), - pullupTo: z.string().optional(), - - pulldownFor: z.string().optional(), - pulldownTo: z.string().optional(), -}) -``` - -```typescript -export interface ResonatorProps extends CommonComponentProps { - frequency: number | string - loadCapacitance: number | string - pinVariant?: ResonatorPinVariant -} -export const resonatorProps = commonComponentProps.extend({ - frequency: frequency, - loadCapacitance: capacitance, - pinVariant: z.enum(["no_ground", "ground_pin", "two_ground_pins"]).optional(), -}) -``` - -```typescript -export const schematicBoxProps = z.object({ - schX: distance, - schY: distance, - width: distance, - height: distance, -}) -``` - -```typescript -export const schematicLineProps = z.object({ - x1: distance, - y1: distance, - x2: distance, - y2: distance, -}) -``` - -```typescript -export const schematicPathProps = z.object({ - points: z.array(point), - isFilled: z.boolean().optional().default(false), - fillColor: z.enum(["red", "blue"]).optional(), -}) -``` - -```typescript -export const schematicTextProps = z.object({ - schX: distance, - schY: distance, - text: z.string(), -}) -``` - -```typescript -export const silkscreenCircleProps = pcbLayoutProps - .omit({ pcbRotation: true }) -``` - -```typescript -export const silkscreenLineProps = pcbLayoutProps - .omit({ pcbX: true, pcbY: true, pcbRotation: true }) -``` - -```typescript -export const silkscreenPathProps = pcbLayoutProps - .omit({ pcbX: true, pcbY: true, pcbRotation: true }) -``` - -```typescript -export const silkscreenRectProps = pcbLayoutProps - .omit({ pcbRotation: true }) -``` - -```typescript -export const silkscreenTextProps = pcbLayoutProps.extend({ - text: z.string(), - anchorAlignment: z - .enum(["center", "top_left", "top_right", "bottom_left", "bottom_right"]) - .default("center"), - font: z.enum(["tscircuit2024"]).optional(), - fontSize: length.optional(), -}) -``` - -```typescript -export interface RectSmtPadProps extends Omit { - shape: "rect" - width: Distance - height: Distance - portHints?: PortHints -} -export interface RotatedRectSmtPadProps - extends Omit { - shape: "rotated_rect" - width: Distance - height: Distance - ccwRotation: number - portHints?: PortHints -} -export interface CircleSmtPadProps extends Omit { - shape: "circle" - radius: Distance - portHints?: PortHints -} -export const rectSmtPadProps = pcbLayoutProps - .omit({ pcbRotation: true }) -export const rotatedRectSmtPadProps = pcbLayoutProps - .omit({ pcbRotation: true }) -export const circleSmtPadProps = pcbLayoutProps - .omit({ pcbRotation: true }) -``` - -```typescript -export interface RectSolderPasteProps - extends Omit { - shape: "rect" - width: Distance - height: Distance -} -export interface CircleSolderPasteProps - extends Omit { - shape: "circle" - radius: Distance -} -export const rectSolderPasteProps = pcbLayoutProps - .omit({ pcbRotation: true }) -export const circleSolderPasteProps = pcbLayoutProps - .omit({ pcbRotation: true }) -``` - -```typescript -export const switchProps = commonComponentProps.extend({ - ftype: z.literal("switch"), - switchType: z.enum(["spst"]).default("spst"), - isNormallyClosed: z.boolean().default(false), -}) -``` - -```typescript -export const routeHintPointProps = z.object({ - x: distance, - y: distance, - via: z.boolean().optional(), - toLayer: layer_ref.optional(), -}) -export const traceHintProps = z.object({ - for: z - .string() - .optional() - .describe( - "Selector for the port you're targeting, not required if you're inside a trace", - ), - order: z.number().optional(), - offset: route_hint_point.or(routeHintPointProps).optional(), - offsets: z - .array(route_hint_point) - .or(z.array(routeHintPointProps)) - .optional(), - traceWidth: z.number().optional(), -}) -``` - -```typescript -export const portRef = z.union([ - z.string(), - z.custom<{ getPortSelector: () => string }>((v) => -export const traceProps = z.union([ - baseTraceProps.extend({ - path: z.array(portRef), - }), -``` - -```typescript -export interface TransistorProps extends CommonComponentProps { - transistorType: "npn" | "pnp" -} -export const transistorProps = commonComponentProps.extend({ - transistorType: z.enum(["npn", "pnp"]), -}) -export const transistorPins = [ - "pin1", - "emitter", - "pin2", - "collector", - "pin3", - "base", -] as const -``` - -```typescript -export const viaProps = commonLayoutProps.extend({ - fromLayer: layer_ref, - toLayer: layer_ref, - holeDiameter: distance, - outerDiameter: distance, -}) -``` - - - -- Here is a list of unsupported components: - -1- powersource -2- powersourcesimple -3- pinheader - -- Here are examples of how you can take advantage of those props: - - // Example of a custom chip footprint definition - const CustomChipFootprint = () => ( - - // SMT pads for the chip - - - - - - // Silkscreen markings for the chip outline - - // Pin 1 indicator - - - ) - - // Example of a custom resistor footprint - const Resistor0603Footprint = () => ( - - - - - - ) - - // Example of a complete circuit - export const MyCircuit = () => ( - - // Power section group - - // Decoupling capacitor arrangement - - - - - - // Input protection group - - - - - - - // Power nets - - - - // Connections - - - - // Layout constraints - - - ) - - // Example of a custom module/component that can be reused - export const DecouplingCapacitor = ({ - chipRef, - capName, - capValue = "100nF", - distance = "2mm" - }) => ( - - - - - ) - - // Usage of the custom module - export const CircuitWithDecoupling = () => ( - - - - - ) - - -### RULES - -- decouplingFor must contain the selector for the component and the pin(eg. ".U1 .pin1", ".T1 .pin1") -- Never pass the component name alone as a selector for decouplingFor, always use the component name reference and the pin number -- Don't use hole or port components, always connect to the component pins -- Don't use inline comments which are comments in the same line as components, they are forbidden -- Port components must be children to a chip component. -- Never use components in the "Unsupported components" list -- Never use footprints in the "Unsupported footprints" list -- Any component may have a pcbX and/or a pcbY representing the center of the - component on a circuit board. -- Never use footprints that are not supported in the "All available footprints" section -- Some footprints have a fixed number of pins like ms012 and sot723 -- `` components use CSS selectors in the `from` and `to` fields - to connect components. -- Any component can have a `name` prop -- `pcbX` and `pcbY` are optional and default to 0. -- A board is centered on the origin (pcbX=0, pcbY=0), so to place a component - at the center it must be placed at pcbX=0,pcbY=0. Similarly, if you're trying - to layout components around the center, you would make ones to the left of - the center have negative pcbX values, below the center have negative pcbY, - and to the right of the center have positive pcbX values, and above the - center have positive pcbY values. -- Every component that is going to be placed must be given a footprint -- Traces can only take two ports -- Don't use path as prop for trace, only use from, to -- We don't support defining output ports, so don't defined port components -- Don't specify autorouter; don't use the autorouter prop -- Selectors for component pins must be of this format: ".U1 > .pin1" or ".U1 > .pin2" where U1 is the component name, and the pins must be numbers, so don't use names for pins but use pin1, pin2, pin3, pin4 -- And instead of ".T1 > .base" you do do ".T1 > .pin2" -- "for" must have at least two selectors for constraints - -### Trace Reference Syntax - -Traces are created using the `` component. The `from` and `to` -fields are CSS selectors that reference the components to connect. - -Examples: - - - - - -### Output - -Use a codefence with the language "tsx" to wrap the code. You can use the -current_code of the user as a starting point (if provided). - -You must export a higher-order component where the root component is `` -inside the codefence. For example: - -```tsx -export const MyLed = () => ( - - - - - -) -``` \ No newline at end of file diff --git a/benchmarks/prompt-logs/prompt-2025-02-18T12-49-18-664Z.txt b/benchmarks/prompt-logs/prompt-2025-02-18T12-49-18-664Z.txt deleted file mode 100644 index 3006fae..0000000 --- a/benchmarks/prompt-logs/prompt-2025-02-18T12-49-18-664Z.txt +++ /dev/null @@ -1,1250 +0,0 @@ -You are an expert in electronic circuit design and tscircuit, and your job is to create a circuit board in tscircuit with the user-provided description. - -YOU MUST ABIDE BY THE RULES IN THE RULES SECTION - -## tscircuit API overview - -Here's an overview of the tscircuit API: - - // usually the root component - // custom shape instead of rectangle - - - - - - - - - - - - - -### footprint strings - -Footprint strings are a compact way to represent the physical footprint for a -component. Any component can be given a footprint string. Here are example -footprint strings: - -0402 -0603 -0805 -1206 -1210 -cap0402 -res0402 -soic8_p1.27mm -dip16 -pinrow10 -tssop20_p0.5mm -sot23 - -### All available footprints - -- Either use a passive footprint like this (e.g. 0402, 0603, 0805, 1206, 1210), here is a json string with all available footprint passive sizes: - -["01005","0201","0402","0603","0805","1206","1210","2010","2512"] - -- Or create a footprint string like this (e.g. dfn8_w5.3mm_p1.27mm, dip10_w4.00mm_p2.65mm, lqfp64_w10_h10_pl1_pw0.25mm, sot363, stampreceiver_left20_right20_bottom3_top2_w21mm_p2.54mm, tssop20_w6.5mm_p0.65mm, bga7_w8_h8_grid3x3_p1_missing(center,B1), bga64_w10_h10_grid8x8_p1.27mm), here are json objects with the available footprints and their options: - -{"fn":"axial","p":2.54,"id":0.7,"od":1} -{"fn":"bga","num_pins":64,"p":0.8,"missing":[],"grid":{"x":8,"y":8},"origin":"tl"} -{"fn":"breakoutheaders","w":10,"left":20,"right":20,"top":0,"bottom":0,"p":2.54,"id":1,"od":1.5} -{"fn":"dfn","num_pins":8,"w":5.3,"p":1.27,"legsoutside":false,"pw":0.6,"pl":1} -{"fn":"dip","num_pins":6,"p":2.54,"id":1,"od":1.5,"w":7.62} -{"fn":"lqfp","num_pins":64,"p":0.5,"legsoutside":true,"w":10,"h":10,"pw":0.25,"pl":0.25} -{"fn":"mlp","num_pins":64,"p":0.5,"thermalpad":true,"legsoutside":false,"w":10,"h":10,"pw":0.25,"pl":0.25} -{"fn":"ms012","num_pins":8,"w":3.9,"p":1.27,"legsoutside":true,"pw":0.6,"pl":1} -{"fn":"ms013","num_pins":16,"w":7.5,"p":1.27,"legsoutside":true,"pw":0.6,"pl":1} -{"fn":"pinrow","num_pins":6,"p":2.54,"id":1,"od":1.5} -{"fn":"pushbutton","w":4.5,"h":6.5,"id":1,"od":1.2} -{"fn":"qfn","num_pins":64,"p":0.5,"legsoutside":false,"w":10,"h":10,"pw":0.25,"pl":0.25} -{"fn":"qfp","num_pins":64,"p":0.5,"pw":0.25,"pl":1,"legsoutside":true,"w":10,"h":10} -{"fn":"quad","num_pins":64,"p":0.5,"legsoutside":false,"w":10,"h":10,"pw":0.25,"pl":0.25} -{"fn":"sod123","num_pins":2,"w":"2.36mm","h":"1.22mm","pl":"0.9mm","pw":"0.9mm","pad_spacing":"4.19mm"} -{"fn":"soic","num_pins":8,"w":5.3,"p":1.27,"legsoutside":false,"pw":0.6,"pl":1} -{"fn":"sot23","num_pins":3,"w":"1.92mm","h":"2.74mm","pl":"0.8mm","pw":"0.764mm"} -{"fn":"sot235","num_pins":5,"h":"1.6mm","pl":"1mm","pw":"0.7mm","p":"0.95mm"} -{"fn":"sot236","num_pins":6,"w":1.6,"p":0.95,"legsoutside":true,"pw":0.6,"pl":1} -{"fn":"sot363","num_pins":6,"w":1.94,"p":0.65,"pw":0.3,"pl":0.7,"legsoutside":false} -{"fn":"sot563","num_pins":6,"w":1.94,"p":0.5,"pw":0.3,"pl":0.67,"legsoutside":false} -{"fn":"sot723","num_pins":3,"w":"1.2mm","h":"1.2mm","pl":"0.3mm","pw":"0.32mm"} -{"fn":"ssop","num_pins":8,"w":3.9,"p":1.27,"legsoutside":false,"pw":0.6,"pl":1} -{"fn":"stampboard","w":22.58,"left":20,"right":20,"top":2,"bottom":2,"p":2.54,"pw":1.6,"pl":2.4,"innerhole":false,"innerholeedgedistance":1.61} -{"fn":"stampreceiver","w":22.58,"left":20,"right":20,"top":2,"bottom":2,"p":2.54,"pw":1.6,"pl":3.2,"innerhole":false,"innerholeedgedistance":1.61} -{"fn":"tssop","num_pins":8,"w":6.1,"p":0.65,"legsoutside":true,"pw":0.6,"pl":1} - - -- Here is a list of unsupported footprints: - -1- hc - -keep in mind that num_pins can be replaced with a number directly infront of the footprint name like so: dip8_p1.27mm which means num_pins=8, don't do that for footprints with fixed number of pins like ms012 and sot723 - -### Components and Props - -- Here is a documentation of all available components and their types: - - - -```typescript -export const rotationPoint3 = z.object({ - x: z.union([z.number(), z.string()]), - y: z.union([z.number(), z.string()]), - z: z.union([z.number(), z.string()]), -}) -export interface CadModelBase { - rotationOffset?: - | number - | { x: number | string; y: number | string; z: number | string } - positionOffset?: { - x: number | string - y: number | string - z: number | string - } - size?: { x: number | string; y: number | string; z: number | string } -} -export const cadModelBase = z.object({ - rotationOffset: z.number().or(rotationPoint3).optional(), - positionOffset: point3.optional(), - size: point3.optional(), -}) -export interface CadModelStl extends CadModelBase { - stlUrl: string -} -export const cadModelStl = cadModelBase.extend({ - stlUrl: z.string(), -}) -export interface CadModelObj extends CadModelBase { - objUrl: string - mtlUrl?: string -} -export const cadModelObj = cadModelBase.extend({ - objUrl: z.string(), - mtlUrl: z.string().optional(), -}) -export interface CadModelJscad extends CadModelBase { - jscad: Record -} -export const cadModelJscad = cadModelBase.extend({ - jscad: z.record(z.any()), -}) -``` - -```typescript -export type Distance = number | string - -export { distance, length } from "circuit-json" -``` - -```typescript -/** - * This is an abbreviated definition of the soup elements that you can find here: - * https://docs.tscircuit.com/api-reference/advanced/soup#pcb-smtpad - */ -export type FootprintSoupElements = { - type: "pcb_smtpad" | "pcb_plated_hole" - x: string | number - y: string | number - layer?: LayerRef - holeDiameter?: string | number - outerDiameter?: string | number - shape?: "circle" | "rect" - width?: string | number - height?: string | number - portHints?: string[] -} -``` - -```typescript -export interface PcbLayoutProps { - pcbX?: string | number - pcbY?: string | number - pcbRotation?: string | number - layer?: LayerRefInput -} -export interface CommonLayoutProps { - pcbX?: string | number - pcbY?: string | number - pcbRotation?: string | number - - schX?: string | number - schY?: string | number - schRotation?: string | number - - layer?: LayerRefInput - footprint?: Footprint -} -export const pcbLayoutProps = z.object({ - pcbX: distance.optional(), - pcbY: distance.optional(), - pcbRotation: rotation.optional(), - layer: layer_ref.optional(), -}) -export const commonLayoutProps = z.object({ - pcbX: distance.optional(), - pcbY: distance.optional(), - pcbRotation: rotation.optional(), - schX: distance.optional(), - schY: distance.optional(), - schRotation: rotation.optional(), - layer: layer_ref.optional(), - footprint: footprintProp.optional(), -}) -export interface SupplierProps { - supplierPartNumbers?: SupplierPartNumbers -} -export const supplierProps = z.object({ - supplierPartNumbers: z.record(supplier_name, z.array(z.string())).optional(), -}) -export interface CommonComponentProps extends CommonLayoutProps { - key?: any - name: string - supplierPartNumbers?: SupplierPartNumbers - cadModel?: CadModelProp - children?: any - symbolName?: string -} -export const commonComponentProps = commonLayoutProps - .merge(supplierProps) - .extend({ - key: z.any().optional(), - name: z.string(), - cadModel: cadModelProp.optional(), - children: z.any().optional(), - symbolName: z.string().optional(), - }) -export const lrPolarPins = [ - "pin1", - "left", - "anode", - "pos", - "pin2", - "right", - "cathode", - "neg", -] as const -``` - -```typescript -export const point = z.object({ - x: distance, - y: distance, -}) -``` - -```typescript -export const point3 = z.object({ - x: distance, - y: distance, - z: distance, -}) -``` - -```typescript -/** - * @deprecated Use SchematicPortArrangementWithPinCounts instead. - */ -export interface SchematicPortArrangementWithSizes { - leftSize?: number - topSize?: number - rightSize?: number - bottomSize?: number -} -/** - * Specifies the number of pins on each side of the schematic box component. - */ -export interface SchematicPortArrangementWithPinCounts { - leftPinCount?: number - topPinCount?: number - rightPinCount?: number - bottomPinCount?: number -} -export interface PinSideDefinition { - pins: Array - direction: - | "top-to-bottom" - | "left-to-right" - | "bottom-to-top" - | "right-to-left" -} -export interface SchematicPortArrangementWithSides { - leftSide?: PinSideDefinition - topSide?: PinSideDefinition - rightSide?: PinSideDefinition - bottomSide?: PinSideDefinition -} -export interface SchematicPortArrangement - extends SchematicPortArrangementWithSizes, - SchematicPortArrangementWithSides, - SchematicPortArrangementWithPinCounts {} -export const explicitPinSideDefinition = z.object({ - pins: z.array(z.union([z.number(), z.string()])), - direction: z.union([ - z.literal("top-to-bottom"), - z.literal("left-to-right"), - z.literal("bottom-to-top"), - z.literal("right-to-left"), - ]), -}) -export const schematicPortArrangement = z.object({ - leftSize: z.number().optional().describe("@deprecated, use leftPinCount"), - topSize: z.number().optional().describe("@deprecated, use topPinCount"), - rightSize: z.number().optional().describe("@deprecated, use rightPinCount"), - bottomSize: z.number().optional().describe("@deprecated, use bottomPinCount"), - leftPinCount: z.number().optional(), - rightPinCount: z.number().optional(), - topPinCount: z.number().optional(), - bottomPinCount: z.number().optional(), - leftSide: explicitPinSideDefinition.optional(), - rightSide: explicitPinSideDefinition.optional(), - topSide: explicitPinSideDefinition.optional(), - bottomSide: explicitPinSideDefinition.optional(), -}) -``` - -```typescript -export type SchematicPinStyle = Record< - string, - { - leftMargin?: number | string - rightMargin?: number | string - topMargin?: number | string - bottomMargin?: number | string - } -export const schematicPinStyle = z.record( - z.object({ - leftMargin: distance.optional(), - rightMargin: distance.optional(), - topMargin: distance.optional(), - bottomMargin: distance.optional(), - }), -``` - -```typescript -/** @deprecated use battery_capacity from circuit-json when circuit-json is updated */ -export interface BatteryProps extends CommonComponentProps { - capacity?: number | string -} -export const batteryProps = commonComponentProps.extend({ - capacity: capacity.optional(), -}) -``` - -```typescript -export interface BoardProps extends Omit { - width?: number | string - height?: number | string - outline?: Point[] - outlineOffsetX?: number | string - outlineOffsetY?: number | string -} -export const boardProps = subcircuitGroupProps.extend({ - width: distance.optional(), - height: distance.optional(), - outline: z.array(point).optional(), - outlineOffsetX: distance.optional(), - outlineOffsetY: distance.optional(), -}) -``` - -```typescript -export interface CapacitorProps extends CommonComponentProps { - capacitance: number | string - polarized?: boolean - decouplingFor?: string - decouplingTo?: string - bypassFor?: string - bypassTo?: string - maxDecouplingTraceLength?: number -} -export const capacitorProps = commonComponentProps.extend({ - capacitance, - polarized: z.boolean().optional().default(false), - decouplingFor: z.string().optional(), - decouplingTo: z.string().optional(), - bypassFor: z.string().optional(), - bypassTo: z.string().optional(), - maxDecouplingTraceLength: z.number().optional(), -}) -``` - -```typescript -export interface ChipProps extends CommonComponentProps { - manufacturerPartNumber?: string - pinLabels?: Record - schPortArrangement?: SchematicPortArrangement - schPinStyle?: SchematicPinStyle - schPinSpacing?: Distance - schWidth?: Distance - schHeight?: Distance - noSchematicRepresentation?: boolean -} -export const chipProps = commonComponentProps.extend({ - manufacturerPartNumber: z.string().optional(), - pinLabels: z - .record( - z.number().or(z.string()), - z.string().or(z.array(z.string()).readonly()), - ) - .optional(), - schPortArrangement: schematicPortArrangement.optional(), - schPinStyle: schematicPinStyle.optional(), - schPinSpacing: distance.optional(), - schWidth: distance.optional(), - schHeight: distance.optional(), - noSchematicRepresentation: z.boolean().optional(), -}) -``` - -```typescript -export interface ConstrainedLayoutProps { - name?: string - pcbOnly?: boolean - schOnly?: boolean -} -export const constrainedLayoutProps = z.object({ - name: z.string().optional(), - pcbOnly: z.boolean().optional(), - schOnly: z.boolean().optional(), -}) -``` - -```typescript -export type PcbXDistConstraint = { - pcb?: true - xDist: Distance - - left: string - - right: string - - edgeToEdge?: true - - centerToCenter?: true -} -/** - * If true, the provided distance is the distance between the centers of the - * left and right components - */ -export type PcbYDistConstraint = { - pcb?: true - yDist: Distance - - top: string - - bottom: string - - edgeToEdge?: true - centerToCenter?: true -} -/** - * Selector for bottom component, e.g. ".U1" or ".R1", you can also specify the - * edge or center of the component e.g. ".R1 bottomedge", ".R1 center" - */ -export type PcbSameYConstraint = { - pcb?: true - sameY?: true - - for: string[] -} -/** - * Selector for components, e.g. [".U1", ".R1"], you can also specify the - * edge or center of the component e.g. [".R1 leftedge", ".U1 center"] - */ -export type PcbSameXConstraint = { - pcb?: true - sameX?: true - for: string[] -} -export const pcbXDistConstraintProps = z.object({ - pcb: z.literal(true).optional(), - xDist: distance, - left: z.string(), - right: z.string(), - - edgeToEdge: z.literal(true).optional(), - centerToCenter: z.literal(true).optional(), -}) -export const pcbYDistConstraintProps = z.object({ - pcb: z.literal(true).optional(), - yDist: distance, - top: z.string(), - bottom: z.string(), - - edgeToEdge: z.literal(true).optional(), - centerToCenter: z.literal(true).optional(), -}) -export const pcbSameYConstraintProps = z.object({ - pcb: z.literal(true).optional(), - sameY: z.literal(true).optional(), - for: z.array(z.string()), -}) -export const pcbSameXConstraintProps = z.object({ - pcb: z.literal(true).optional(), - sameX: z.literal(true).optional(), - for: z.array(z.string()), -}) -``` - -```typescript -export interface CrystalProps extends CommonComponentProps { - frequency: number | string - loadCapacitance: number | string - pinVariant?: PinVariant -} -export const crystalProps = commonComponentProps.extend({ - frequency: frequency, - loadCapacitance: capacitance, - pinVariant: z.enum(["2pin", "4pin"]).optional(), -}) -``` - -```typescript -export const fabricationNotePathProps = pcbLayoutProps - .omit({ pcbX: true, pcbY: true, pcbRotation: true }) -``` - -```typescript -export const fabricationNoteTextProps = pcbLayoutProps.extend({ - text: z.string(), - anchorAlignment: z - .enum(["center", "top_left", "top_right", "bottom_left", "bottom_right"]) - .default("center"), - font: z.enum(["tscircuit2024"]).optional(), - fontSize: length.optional(), - color: z.string().optional(), -}) -``` - -```typescript -export interface FootprintProps { - originalLayer?: LayerRef -} -/** - * The layer that the footprint is designed for. If you set this to "top" - * then it means the children were intended to represent the top layer. If - * the with this footprint is moved to the bottom layer, then the - * components will be mirrored. - * - * Generally, you shouldn't set this except where it can help prevent - * confusion because you have a complex multi-layer footprint. Default is - * "top" and this is most intuitive. - */ -export const footprintProps = z.object({ - originalLayer: layer_ref.default("top").optional(), -}) -``` - -```typescript -export interface BaseGroupProps extends CommonLayoutProps { - name?: string - key?: any - children?: any -} -export type PartsEngine = { - findPart: (params: { - sourceComponent: AnySourceComponent - footprinterString?: string - }) => Promise | SupplierPartNumbers -} -export interface PcbRouteCache { - pcbTraces: PcbTrace[] - cacheKey: string -} -export interface AutorouterConfig { - serverUrl?: string - inputFormat?: "simplified" | "circuit-json" - serverMode?: "job" | "solve-endpoint" - cache?: PcbRouteCache -} -export const autorouterConfig = z.object({ - serverUrl: z.string().optional(), - inputFormat: z.enum(["simplified", "circuit-json"]).optional(), - serverMode: z.enum(["job", "solve-endpoint"]).optional(), - cache: z.custom((v) => true).optional(), -}) -export interface SubcircuitGroupProps extends BaseGroupProps { - layout?: LayoutBuilder - manualEdits?: ManualEditsFileInput - routingDisabled?: boolean - defaultTraceWidth?: Distance - minTraceWidth?: Distance - pcbRouteCache?: PcbRouteCache - - autorouter?: AutorouterProp - - schAutoLayoutEnabled?: boolean - - schTraceAutoLabelEnabled?: boolean - - partsEngine?: PartsEngine -} -/** - * If true, net labels will automatically be created for complex traces - */ -export interface SubcircuitGroupPropsWithBool extends SubcircuitGroupProps { - subcircuit: true -} -export interface NonSubcircuitGroupProps extends BaseGroupProps { - subcircuit?: false | undefined -} -export const baseGroupProps = commonLayoutProps.extend({ - name: z.string().optional(), - children: z.any().optional(), - key: z.any().optional(), -}) -export const subcircuitGroupProps = baseGroupProps.extend({ - layout: z.custom((v) => true).optional(), - manualEdits: manual_edits_file.optional(), - schAutoLayoutEnabled: z.boolean().optional(), - schTraceAutoLabelEnabled: z.boolean().optional(), - routingDisabled: z.boolean().optional(), - defaultTraceWidth: length.optional(), - minTraceWidth: length.optional(), - partsEngine: z.custom((v) => "findPart" in v).optional(), - pcbRouteCache: z.custom((v) => true).optional(), - autorouter: autorouterProp.optional(), -}) -export const subcircuitGroupPropsWithBool = subcircuitGroupProps.extend({ - subcircuit: z.literal(true), -}) -export const groupProps = z.discriminatedUnion("subcircuit", [ - baseGroupProps.extend({ subcircuit: z.literal(false).optional() }), -``` - -```typescript -export interface HoleProps extends Omit { - name?: string - diameter?: Distance - radius?: Distance -} -export const holeProps = pcbLayoutProps - .omit({ pcbRotation: true }) -``` - -```typescript -export const inductorProps = commonComponentProps.extend({ - inductance, -}) -``` - -```typescript -export interface JumperProps extends CommonComponentProps { - manufacturerPartNumber?: string - pinLabels?: Record - schPinStyle?: SchematicPinStyle - schPinSpacing?: number | string - schWidth?: number | string - schHeight?: number | string - schDirection?: "left" | "right" - schPortArrangement?: SchematicPortArrangement -} -export const jumperProps = commonComponentProps.extend({ - manufacturerPartNumber: z.string().optional(), - pinLabels: z - .record(z.number().or(z.string()), z.string().or(z.array(z.string()))) - .optional(), - schPinStyle: schematicPinStyle.optional(), - schPinSpacing: distance.optional(), - schWidth: distance.optional(), - schHeight: distance.optional(), - schDirection: z.enum(["left", "right"]).optional(), - schPortArrangement: schematicPortArrangement.optional(), -}) -``` - -```typescript -export const ledProps = commonComponentProps.extend({ - color: z.string().optional(), -}) -``` - -```typescript -export interface MosfetProps extends CommonComponentProps { - channelType: "n" | "p" - mosfetMode: "enhancement" | "depletion" -} -export const mosfetProps = commonComponentProps.extend({ - channelType: z.enum(["n", "p"]), - mosfetMode: z.enum(["enhancement", "depletion"]), -}) -export const mosfetPins = [ - "pin1", - "drain", - "pin2", - "source", - "pin3", - "gate", -] as const -``` - -```typescript -export interface NetProps { - name: string -} -export const netProps = z.object({ - name: z.string(), -}) -``` - -```typescript -export interface NetAliasProps { - net?: string - schX?: number | string - schY?: number | string - schRotation?: number | string - anchorSide?: "left" | "up" | "right" | "down" -} -export const netAliasProps = z.object({ - net: z.string().optional(), - schX: distance.optional(), - schY: distance.optional(), - schRotation: rotation.optional(), - anchorSide: z.enum(["left", "up", "right", "down"]).optional(), -}) -``` - -```typescript -export const pcbKeepoutProps = z.union([ - pcbLayoutProps.omit({ pcbRotation: true }).extend({ - shape: z.literal("circle"), - radius: distance, - }), -``` - -```typescript -export const pcbTraceProps = z.object({ - layer: z.string().optional(), - thickness: distance.optional(), - route: z.array(route_hint_point), -}) -``` - -```typescript -export interface PinHeaderProps extends CommonComponentProps { - pinCount: number - - pitch?: number | string - - gender?: "male" | "female" - - showSilkscreenPinLabels?: boolean - - doubleRow?: boolean - - holeDiameter?: number | string - - platedDiameter?: number | string - - pinLabels?: string[] - - facingDirection?: "left" | "right" -} -/** - * Direction the header is facing - */ -export const pinHeaderProps = commonComponentProps.extend({ - pinCount: z.number(), - pitch: distance.optional(), - gender: z.enum(["male", "female"]).optional().default("male"), - showSilkscreenPinLabels: z.boolean().optional(), - doubleRow: z.boolean().optional(), - holeDiameter: distance.optional(), - platedDiameter: distance.optional(), - pinLabels: z.array(z.string()).optional(), - facingDirection: z.enum(["left", "right"]).optional(), -}) -``` - -```typescript -export interface CirclePlatedHoleProps - extends Omit { - name?: string - shape: "circle" - holeDiameter: number | string - outerDiameter: number | string - portHints?: PortHints -} -export interface OvalPlatedHoleProps - extends Omit { - name?: string - shape: "oval" - outerWidth: number | string - outerHeight: number | string - innerWidth: number | string - innerHeight: number | string - portHints?: PortHints -} -export interface PillPlatedHoleProps - extends Omit { - name?: string - shape: "pill" - outerWidth: number | string - outerHeight: number | string - innerWidth: number | string - innerHeight: number | string - portHints?: PortHints -} -export const platedHoleProps = z.discriminatedUnion("shape", [ - pcbLayoutProps.omit({ pcbRotation: true, layer: true }).extend({ - name: z.string().optional(), - shape: z.literal("circle"), - holeDiameter: distance, - outerDiameter: distance, - portHints: portHints.optional(), - }), -``` - -```typescript -export const portProps = commonLayoutProps.extend({ - name: z.string(), - pinNumber: z.number().optional(), - aliases: z.array(z.string()).optional(), - direction: direction, -}) -``` - -```typescript -export interface PotentiometerProps extends CommonComponentProps { - maxResistance: number | string -} -export const potentiometerProps = commonComponentProps.extend({ - maxResistance: resistance, -}) -``` - -```typescript -export const powerSourceProps = commonComponentProps.extend({ - voltage, -}) -``` - -```typescript -export interface ResistorProps extends CommonComponentProps { - resistance: number | string - pullupFor?: string - pullupTo?: string - pulldownFor?: string - pulldownTo?: string -} -export const resistorProps = commonComponentProps.extend({ - resistance, - - pullupFor: z.string().optional(), - pullupTo: z.string().optional(), - - pulldownFor: z.string().optional(), - pulldownTo: z.string().optional(), -}) -``` - -```typescript -export interface ResonatorProps extends CommonComponentProps { - frequency: number | string - loadCapacitance: number | string - pinVariant?: ResonatorPinVariant -} -export const resonatorProps = commonComponentProps.extend({ - frequency: frequency, - loadCapacitance: capacitance, - pinVariant: z.enum(["no_ground", "ground_pin", "two_ground_pins"]).optional(), -}) -``` - -```typescript -export const schematicBoxProps = z.object({ - schX: distance, - schY: distance, - width: distance, - height: distance, -}) -``` - -```typescript -export const schematicLineProps = z.object({ - x1: distance, - y1: distance, - x2: distance, - y2: distance, -}) -``` - -```typescript -export const schematicPathProps = z.object({ - points: z.array(point), - isFilled: z.boolean().optional().default(false), - fillColor: z.enum(["red", "blue"]).optional(), -}) -``` - -```typescript -export const schematicTextProps = z.object({ - schX: distance, - schY: distance, - text: z.string(), -}) -``` - -```typescript -export const silkscreenCircleProps = pcbLayoutProps - .omit({ pcbRotation: true }) -``` - -```typescript -export const silkscreenLineProps = pcbLayoutProps - .omit({ pcbX: true, pcbY: true, pcbRotation: true }) -``` - -```typescript -export const silkscreenPathProps = pcbLayoutProps - .omit({ pcbX: true, pcbY: true, pcbRotation: true }) -``` - -```typescript -export const silkscreenRectProps = pcbLayoutProps - .omit({ pcbRotation: true }) -``` - -```typescript -export const silkscreenTextProps = pcbLayoutProps.extend({ - text: z.string(), - anchorAlignment: z - .enum(["center", "top_left", "top_right", "bottom_left", "bottom_right"]) - .default("center"), - font: z.enum(["tscircuit2024"]).optional(), - fontSize: length.optional(), -}) -``` - -```typescript -export interface RectSmtPadProps extends Omit { - shape: "rect" - width: Distance - height: Distance - portHints?: PortHints -} -export interface RotatedRectSmtPadProps - extends Omit { - shape: "rotated_rect" - width: Distance - height: Distance - ccwRotation: number - portHints?: PortHints -} -export interface CircleSmtPadProps extends Omit { - shape: "circle" - radius: Distance - portHints?: PortHints -} -export const rectSmtPadProps = pcbLayoutProps - .omit({ pcbRotation: true }) -export const rotatedRectSmtPadProps = pcbLayoutProps - .omit({ pcbRotation: true }) -export const circleSmtPadProps = pcbLayoutProps - .omit({ pcbRotation: true }) -``` - -```typescript -export interface RectSolderPasteProps - extends Omit { - shape: "rect" - width: Distance - height: Distance -} -export interface CircleSolderPasteProps - extends Omit { - shape: "circle" - radius: Distance -} -export const rectSolderPasteProps = pcbLayoutProps - .omit({ pcbRotation: true }) -export const circleSolderPasteProps = pcbLayoutProps - .omit({ pcbRotation: true }) -``` - -```typescript -export const switchProps = commonComponentProps.extend({ - ftype: z.literal("switch"), - switchType: z.enum(["spst"]).default("spst"), - isNormallyClosed: z.boolean().default(false), -}) -``` - -```typescript -export const routeHintPointProps = z.object({ - x: distance, - y: distance, - via: z.boolean().optional(), - toLayer: layer_ref.optional(), -}) -export const traceHintProps = z.object({ - for: z - .string() - .optional() - .describe( - "Selector for the port you're targeting, not required if you're inside a trace", - ), - order: z.number().optional(), - offset: route_hint_point.or(routeHintPointProps).optional(), - offsets: z - .array(route_hint_point) - .or(z.array(routeHintPointProps)) - .optional(), - traceWidth: z.number().optional(), -}) -``` - -```typescript -export const portRef = z.union([ - z.string(), - z.custom<{ getPortSelector: () => string }>((v) => -export const traceProps = z.union([ - baseTraceProps.extend({ - path: z.array(portRef), - }), -``` - -```typescript -export interface TransistorProps extends CommonComponentProps { - transistorType: "npn" | "pnp" -} -export const transistorProps = commonComponentProps.extend({ - transistorType: z.enum(["npn", "pnp"]), -}) -export const transistorPins = [ - "pin1", - "emitter", - "pin2", - "collector", - "pin3", - "base", -] as const -``` - -```typescript -export const viaProps = commonLayoutProps.extend({ - fromLayer: layer_ref, - toLayer: layer_ref, - holeDiameter: distance, - outerDiameter: distance, -}) -``` - - - -- Here is a list of unsupported components: - -1- powersource -2- powersourcesimple -3- pinheader - -- Here are examples of how you can take advantage of those props: - - // Example of a custom chip footprint definition - const CustomChipFootprint = () => ( - - // SMT pads for the chip - - - - - - // Silkscreen markings for the chip outline - - // Pin 1 indicator - - - ) - - // Example of a custom resistor footprint - const Resistor0603Footprint = () => ( - - - - - - ) - - // Example of a complete circuit - export const MyCircuit = () => ( - - // Power section group - - // Decoupling capacitor arrangement - - - - - - // Input protection group - - - - - - - // Power nets - - - - // Connections - - - - // Layout constraints - - - ) - - // Example of a custom module/component that can be reused - export const DecouplingCapacitor = ({ - chipRef, - capName, - capValue = "100nF", - distance = "2mm" - }) => ( - - - - - ) - - // Usage of the custom module - export const CircuitWithDecoupling = () => ( - - - - - ) - - -### RULES - -- decouplingFor must contain the selector for the component and the pin(eg. ".U1 .pin1", ".T1 .pin1") -- Never pass the component name alone as a selector for decouplingFor, always use the component name reference and the pin number -- Don't use hole or port components, always connect to the component pins -- Don't use inline comments which are comments in the same line as components, they are forbidden -- Port components must be children to a chip component. -- Never use components in the "Unsupported components" list -- Never use footprints in the "Unsupported footprints" list -- Any component may have a pcbX and/or a pcbY representing the center of the - component on a circuit board. -- Never use footprints that are not supported in the "All available footprints" section -- Some footprints have a fixed number of pins like ms012 and sot723 -- `` components use CSS selectors in the `from` and `to` fields - to connect components. -- Any component can have a `name` prop -- `pcbX` and `pcbY` are optional and default to 0. -- A board is centered on the origin (pcbX=0, pcbY=0), so to place a component - at the center it must be placed at pcbX=0,pcbY=0. Similarly, if you're trying - to layout components around the center, you would make ones to the left of - the center have negative pcbX values, below the center have negative pcbY, - and to the right of the center have positive pcbX values, and above the - center have positive pcbY values. -- Every component that is going to be placed must be given a footprint -- Traces can only take two ports -- Don't use path as prop for trace, only use from, to -- We don't support defining output ports, so don't defined port components -- Don't specify autorouter; don't use the autorouter prop -- Selectors for component pins must be of this format: ".U1 > .pin1" or ".U1 > .pin2" where U1 is the component name, and the pins must be numbers, so don't use names for pins but use pin1, pin2, pin3, pin4 -- And instead of ".T1 > .base" you do do ".T1 > .pin2" -- "for" must have at least two selectors for constraints - -### Trace Reference Syntax - -Traces are created using the `` component. The `from` and `to` -fields are CSS selectors that reference the components to connect. - -Examples: - - - - - -### Output - -Use a codefence with the language "tsx" to wrap the code. You can use the -current_code of the user as a starting point (if provided). - -You must export a higher-order component where the root component is `` -inside the codefence. For example: - -```tsx -export const MyLed = () => ( - - - - - -) -``` \ No newline at end of file diff --git a/benchmarks/prompt-logs/prompt-2025-09-28T16-28-18-507Z.txt b/benchmarks/prompt-logs/prompt-2025-09-28T16-28-18-507Z.txt new file mode 100644 index 0000000..04e706a --- /dev/null +++ b/benchmarks/prompt-logs/prompt-2025-09-28T16-28-18-507Z.txt @@ -0,0 +1,2683 @@ +You are an expert in electronic circuit design and tscircuit, and your job is to create a circuit board in tscircuit with the user-provided description. + +YOU MUST ABIDE BY THE RULES IN THE RULES SECTION + +## tscircuit API overview + +Here's an overview of the tscircuit API: + + // usually the root component + // custom shape instead of rectangle + + + + + + + + + + + + + +### footprint strings + +Footprint strings are a compact way to represent the physical footprint for a +component. Any component can be given a footprint string. Here are example +footprint strings: + +0402 +0603 +0805 +1206 +1210 +cap0402 +res0402 +soic8_p1.27mm +dip16 +pinrow10 +tssop20_p0.5mm +sot23 + +### All available footprints + +- Either use a passive footprint like this (e.g. 0402, 0603, 0805, 1206, 1210), here is a json string with all available footprint passive sizes: + +["01005","0201","0402","0603","0805","1206","1210","2010","2512"] + +- Or create a footprint string like this (e.g. dfn8_w5.3mm_p1.27mm, dip10_w4.00mm_p2.65mm, lqfp64_w10_h10_pl1_pw0.25mm, sot363, stampreceiver_left20_right20_bottom3_top2_w21mm_p2.54mm, tssop20_w6.5mm_p0.65mm, bga7_w8_h8_grid3x3_p1_missing(center,B1), bga64_w10_h10_grid8x8_p1.27mm), here are json objects with the available footprints and their options: + +{"fn":"axial","p":2.54,"id":0.7,"od":1} +{"fn":"bga","num_pins":64,"p":0.8,"missing":[],"grid":{"x":8,"y":8},"origin":"tl"} +{"fn":"breakoutheaders","w":10,"left":20,"right":20,"top":0,"bottom":0,"p":2.54,"id":1,"od":1.5} +{"fn":"dfn","num_pins":8,"w":5.3,"p":1.27,"legsoutside":false,"pw":0.6,"pl":1} +{"fn":"dip","num_pins":6,"p":2.54,"id":1,"od":1.5,"w":7.62} +{"fn":"lqfp","num_pins":64,"p":0.5,"legsoutside":true,"w":10,"h":10,"pw":0.25,"pl":0.25} +{"fn":"mlp","num_pins":64,"p":0.5,"thermalpad":true,"legsoutside":false,"w":10,"h":10,"pw":0.25,"pl":0.25} +{"fn":"ms012","num_pins":8,"w":3.9,"p":1.27,"legsoutside":true,"pw":0.6,"pl":1} +{"fn":"ms013","num_pins":16,"w":7.5,"p":1.27,"legsoutside":true,"pw":0.6,"pl":1} +{"fn":"pinrow","num_pins":6,"p":2.54,"id":1,"od":1.5} +{"fn":"pushbutton","w":4.5,"h":6.5,"id":1,"od":1.2} +{"fn":"qfn","num_pins":64,"p":0.5,"legsoutside":false,"w":10,"h":10,"pw":0.25,"pl":0.25} +{"fn":"qfp","num_pins":64,"p":0.5,"pw":0.25,"pl":1,"legsoutside":true,"w":10,"h":10} +{"fn":"quad","num_pins":64,"p":0.5,"legsoutside":false,"w":10,"h":10,"pw":0.25,"pl":0.25} +{"fn":"sod123","num_pins":2,"w":"2.36mm","h":"1.22mm","pl":"0.9mm","pw":"0.9mm","pad_spacing":"4.19mm"} +{"fn":"soic","num_pins":8,"w":5.3,"p":1.27,"legsoutside":false,"pw":0.6,"pl":1} +{"fn":"sot23","num_pins":3,"w":"1.92mm","h":"2.74mm","pl":"0.8mm","pw":"0.764mm"} +{"fn":"sot235","num_pins":5,"h":"1.6mm","pl":"1mm","pw":"0.7mm","p":"0.95mm"} +{"fn":"sot236","num_pins":6,"w":1.6,"p":0.95,"legsoutside":true,"pw":0.6,"pl":1} +{"fn":"sot363","num_pins":6,"w":1.94,"p":0.65,"pw":0.3,"pl":0.7,"legsoutside":false} +{"fn":"sot563","num_pins":6,"w":1.94,"p":0.5,"pw":0.3,"pl":0.67,"legsoutside":false} +{"fn":"sot723","num_pins":3,"w":"1.2mm","h":"1.2mm","pl":"0.3mm","pw":"0.32mm"} +{"fn":"ssop","num_pins":8,"w":3.9,"p":1.27,"legsoutside":false,"pw":0.6,"pl":1} +{"fn":"stampboard","w":22.58,"left":20,"right":20,"top":2,"bottom":2,"p":2.54,"pw":1.6,"pl":2.4,"innerhole":false,"innerholeedgedistance":1.61} +{"fn":"stampreceiver","w":22.58,"left":20,"right":20,"top":2,"bottom":2,"p":2.54,"pw":1.6,"pl":3.2,"innerhole":false,"innerholeedgedistance":1.61} +{"fn":"tssop","num_pins":8,"w":6.1,"p":0.65,"legsoutside":true,"pw":0.6,"pl":1} + + +- Here is a list of unsupported footprints: + +1- hc + +keep in mind that num_pins can be replaced with a number directly infront of the footprint name like so: dip8_p1.27mm which means num_pins=8, don't do that for footprints with fixed number of pins like ms012 and sot723 + +### Components and Props + +- Here is a documentation of all available components and their types: + + + +```typescript +export const rotationPoint3 = z.object({ + x: z.union([z.number(), z.string()]), + y: z.union([z.number(), z.string()]), + z: z.union([z.number(), z.string()]), +}) +export interface CadModelBase { + rotationOffset?: + | number + | { x: number | string; y: number | string; z: number | string } + positionOffset?: { + x: number | string + y: number | string + z: number | string + } + size?: { x: number | string; y: number | string; z: number | string } + modelUnitToMmScale?: Distance +} +export const cadModelBase = z.object({ + rotationOffset: z.number().or(rotationPoint3).optional(), + positionOffset: point3.optional(), + size: point3.optional(), + modelUnitToMmScale: distance.optional(), +}) +export interface CadModelStl extends CadModelBase { + stlUrl: string +} +export const cadModelStl = cadModelBase.extend({ + stlUrl: z.string(), +}) +export interface CadModelObj extends CadModelBase { + objUrl: string + mtlUrl?: string +} +export const cadModelObj = cadModelBase.extend({ + objUrl: z.string(), + mtlUrl: z.string().optional(), +}) +export interface CadModelGltf extends CadModelBase { + gltfUrl: string +} +export const cadModelGltf = cadModelBase.extend({ + gltfUrl: z.string(), +}) +export interface CadModelGlb extends CadModelBase { + glbUrl: string +} +export const cadModelGlb = cadModelBase.extend({ + glbUrl: z.string(), +}) +export interface CadModelStep extends CadModelBase { + stepUrl: string +} +export const cadModelStep = cadModelBase.extend({ + stepUrl: z.string(), +}) +export interface CadModelWrl extends CadModelBase { + wrlUrl: string +} +export const cadModelWrl = cadModelBase.extend({ + wrlUrl: z.string(), +}) +export interface CadModelJscad extends CadModelBase { + jscad: Record +} +export const cadModelJscad = cadModelBase.extend({ + jscad: z.record(z.any()), +}) +export const cadModelProp = z.union([ + z.null(), + z.string(), + z.custom((v) => { + return v && typeof v === "object" && "type" in v && "props" in v + }), +``` + +```typescript +export const createConnectionsProp = ( + labels: T, +) => { + return z.record(z.enum(labels), connectionTarget) +} +``` + +```typescript +export type Distance = number | string + +export { distance, length } from "circuit-json" +``` + +```typescript +/** + * This is an abbreviated definition of the soup elements that you can find here: + * https://docs.tscircuit.com/api-reference/advanced/soup#pcb-smtpad + */ +export type FootprintSoupElements = { + type: "pcb_smtpad" | "pcb_plated_hole" + x: string | number + y: string | number + layer?: LayerRef + holeDiameter?: string | number + outerDiameter?: string | number + shape?: "circle" | "rect" + width?: string | number + height?: string | number + portHints?: string[] +} +``` + +```typescript +export interface PcbLayoutProps { + pcbX?: string | number + pcbY?: string | number + pcbRotation?: string | number + pcbPositionAnchor?: string + layer?: LayerRefInput + pcbMarginTop?: string | number + pcbMarginRight?: string | number + pcbMarginBottom?: string | number + pcbMarginLeft?: string | number + pcbMarginX?: string | number + pcbMarginY?: string | number + pcbRelative?: boolean + relative?: boolean +} +/** + * If true, both pcb and schematic coordinates will be interpreted relative to the parent group + */ +export interface CommonLayoutProps { + pcbX?: string | number + pcbY?: string | number + pcbRotation?: string | number + pcbPositionAnchor?: string + + pcbMarginTop?: string | number + pcbMarginRight?: string | number + pcbMarginBottom?: string | number + pcbMarginLeft?: string | number + pcbMarginX?: string | number + pcbMarginY?: string | number + + schMarginTop?: string | number + schMarginRight?: string | number + schMarginBottom?: string | number + schMarginLeft?: string | number + schMarginX?: string | number + schMarginY?: string | number + + schX?: string | number + schY?: string | number + schRotation?: string | number + + layer?: LayerRefInput + footprint?: FootprintProp + symbol?: SymbolProp + + relative?: boolean + + schRelative?: boolean + + pcbRelative?: boolean +} +/** + * If true, pcbX/pcbY will be interpreted relative to the parent group + */ +export const pcbLayoutProps = z.object({ + pcbX: distance.optional(), + pcbY: distance.optional(), + pcbRotation: rotation.optional(), + pcbPositionAnchor: z.string().optional(), + layer: layer_ref.optional(), + pcbMarginTop: distance.optional(), + pcbMarginRight: distance.optional(), + pcbMarginBottom: distance.optional(), + pcbMarginLeft: distance.optional(), + pcbMarginX: distance.optional(), + pcbMarginY: distance.optional(), + pcbRelative: z.boolean().optional(), + relative: z.boolean().optional(), +}) +export const commonLayoutProps = z.object({ + pcbX: distance.optional(), + pcbY: distance.optional(), + pcbRotation: rotation.optional(), + pcbPositionAnchor: z.string().optional(), + pcbMarginTop: distance.optional(), + pcbMarginRight: distance.optional(), + pcbMarginBottom: distance.optional(), + pcbMarginLeft: distance.optional(), + pcbMarginX: distance.optional(), + pcbMarginY: distance.optional(), + schMarginTop: distance.optional(), + schMarginRight: distance.optional(), + schMarginBottom: distance.optional(), + schMarginLeft: distance.optional(), + schMarginX: distance.optional(), + schMarginY: distance.optional(), + schX: distance.optional(), + schY: distance.optional(), + schRotation: rotation.optional(), + layer: layer_ref.optional(), + footprint: footprintProp.optional(), + symbol: symbolProp.optional(), + relative: z.boolean().optional(), + schRelative: z.boolean().optional(), + pcbRelative: z.boolean().optional(), +}) +export interface SupplierProps { + supplierPartNumbers?: SupplierPartNumbers +} +export const supplierProps = z.object({ + supplierPartNumbers: z.record(supplier_name, z.array(z.string())).optional(), +}) +export interface PinAttributeMap { + providesPower?: boolean + requiresPower?: boolean + providesGround?: boolean + requiresGround?: boolean + providesVoltage?: string | number + requiresVoltage?: string | number + doNotConnect?: boolean + includeInBoardPinout?: boolean +} +export const pinAttributeMap = z.object({ + providesPower: z.boolean().optional(), + requiresPower: z.boolean().optional(), + providesGround: z.boolean().optional(), + requiresGround: z.boolean().optional(), + providesVoltage: z.union([z.string(), z.number()]).optional(), + requiresVoltage: z.union([z.string(), z.number()]).optional(), + doNotConnect: z.boolean().optional(), + includeInBoardPinout: z.boolean().optional(), +}) +export interface CommonComponentProps + extends CommonLayoutProps { + key?: any + name: string + pinAttributes?: Record + supplierPartNumbers?: SupplierPartNumbers + cadModel?: CadModelProp + children?: any + symbolName?: string + doNotPlace?: boolean +} +.extend({ + key: z.any().optional(), + name: z.string(), + cadModel: cadModelProp.optional(), + children: z.any().optional(), + symbolName: z.string().optional(), + doNotPlace: z.boolean().optional(), + pinAttributes: z.record(z.string(), pinAttributeMap).optional(), + }) +export const lrPolarPins = [ + "pin1", + "left", + "anode", + "pos", + "pin2", + "right", + "cathode", + "neg", +] as const +``` + +```typescript +export const point = z.object({ + x: distance, + y: distance, +}) +``` + +```typescript +export const point3 = z.object({ + x: distance, + y: distance, + z: distance, +}) +``` + +```typescript +/** + * @deprecated Use SchematicPortArrangementWithPinCounts instead. + */ +export interface SchematicPortArrangementWithSizes { + leftSize?: number + topSize?: number + rightSize?: number + bottomSize?: number +} +/** + * Specifies the number of pins on each side of the schematic box component. + */ +export interface SchematicPortArrangementWithPinCounts { + leftPinCount?: number + topPinCount?: number + rightPinCount?: number + bottomPinCount?: number +} +export interface PinSideDefinition { + pins: Array + direction: + | "top-to-bottom" + | "left-to-right" + | "bottom-to-top" + | "right-to-left" +} +export interface SchematicPortArrangementWithSides { + leftSide?: PinSideDefinition + topSide?: PinSideDefinition + rightSide?: PinSideDefinition + bottomSide?: PinSideDefinition +} +export interface SchematicPortArrangement + extends SchematicPortArrangementWithSizes, + SchematicPortArrangementWithSides, + SchematicPortArrangementWithPinCounts {} +export const explicitPinSideDefinition = z.object({ + pins: z.array(z.union([z.number(), z.string()])), + direction: z.union([ + z.literal("top-to-bottom"), + z.literal("left-to-right"), + z.literal("bottom-to-top"), + z.literal("right-to-left"), + ]), +}) +/** + * @deprecated Use schematicPinArrangement instead. + */ +export const schematicPortArrangement = z.object({ + leftSize: z.number().optional().describe("@deprecated, use leftPinCount"), + topSize: z.number().optional().describe("@deprecated, use topPinCount"), + rightSize: z.number().optional().describe("@deprecated, use rightPinCount"), + bottomSize: z.number().optional().describe("@deprecated, use bottomPinCount"), + leftPinCount: z.number().optional(), + rightPinCount: z.number().optional(), + topPinCount: z.number().optional(), + bottomPinCount: z.number().optional(), + leftSide: explicitPinSideDefinition.optional(), + rightSide: explicitPinSideDefinition.optional(), + topSide: explicitPinSideDefinition.optional(), + bottomSide: explicitPinSideDefinition.optional(), +}) +``` + +```typescript +export type SchematicPinStyle = Record< + string, + { + marginTop?: number | string + marginRight?: number | string + marginBottom?: number | string + marginLeft?: number | string + + leftMargin?: number | string + rightMargin?: number | string + topMargin?: number | string + bottomMargin?: number | string + } +/** @deprecated use marginBottom */ +export const schematicPinStyle = z.record( + z.object({ + marginLeft: distance.optional(), + marginRight: distance.optional(), + marginTop: distance.optional(), + marginBottom: distance.optional(), + + leftMargin: distance.optional(), + rightMargin: distance.optional(), + topMargin: distance.optional(), + bottomMargin: distance.optional(), + }), +``` + +```typescript +/** @deprecated use battery_capacity from circuit-json when circuit-json is updated */ +export interface BatteryProps + extends CommonComponentProps { + capacity?: number | string + voltage?: number | string + standard?: "AA" | "AAA" | "9V" | "CR2032" | "18650" | "C" + schOrientation?: SchematicOrientation +} +export const batteryProps = commonComponentProps.extend({ + capacity: capacity.optional(), + voltage: voltage.optional(), + standard: z.enum(["AA", "AAA", "9V", "CR2032", "18650", "C"]).optional(), + schOrientation: schematicOrientation.optional(), +}) +``` + +```typescript +export interface BoardProps extends Omit { + material?: "fr4" | "fr1" + layers?: 2 | 4 + borderRadius?: Distance + boardAnchorPosition?: Point + boardAnchorAlignment?: z.infer +} +/** Number of layers for the PCB */ +export const boardProps = subcircuitGroupProps.extend({ + material: z.enum(["fr4", "fr1"]).default("fr4"), + layers: z.union([z.literal(2), z.literal(4)]).default(2), + borderRadius: distance.optional(), + boardAnchorPosition: point.optional(), + boardAnchorAlignment: ninePointAnchor.optional(), +}) +``` + +```typescript +export interface BreakoutProps + extends Omit { + padding?: Distance + paddingLeft?: Distance + paddingRight?: Distance + paddingTop?: Distance + paddingBottom?: Distance +} +export const breakoutProps = subcircuitGroupProps.extend({ + padding: distance.optional(), + paddingLeft: distance.optional(), + paddingRight: distance.optional(), + paddingTop: distance.optional(), + paddingBottom: distance.optional(), +}) +``` + +```typescript +export interface BreakoutPointProps + extends Omit { + connection: string +} +export const breakoutPointProps = pcbLayoutProps + .omit({ pcbRotation: true, layer: true }) + .extend({ + connection: z.string(), + }) +``` + +```typescript +export interface CadAssemblyProps { + originalLayer?: LayerRef + + children?: any +} +/** + * The layer that the CAD assembly is designed for. If you set this to "top" + * then it means the children were intended to represent the top layer. If + * the with this assembly is moved to the bottom layer, then the + * components will be mirrored. + * + * Generally, you shouldn't set this except where it can help prevent + * confusion because you have a complex multi-layer assembly. Default is + * "top" and this is most intuitive. + */ +export const cadassemblyProps = z.object({ + originalLayer: layer_ref.default("top").optional(), + children: z.any().optional(), +}) +``` + +```typescript +export interface CadModelProps extends CadModelBase { + modelUrl: string + pcbX?: Distance + pcbY?: Distance + pcbZ?: Distance +} +const cadModelBaseWithUrl = cadModelBase.extend({ + modelUrl: z.string(), +}) +``` + +```typescript +export const capacitorPinLabels = [ + "pin1", + "pin2", + "pos", + "neg", + "anode", + "cathode", +] as const +export interface CapacitorProps + extends CommonComponentProps { + capacitance: number | string + maxVoltageRating?: number | string + schShowRatings?: boolean + polarized?: boolean + decouplingFor?: string + decouplingTo?: string + bypassFor?: string + bypassTo?: string + maxDecouplingTraceLength?: number + schOrientation?: SchematicOrientation + connections?: Connections +} +export const capacitorProps = commonComponentProps.extend({ + capacitance, + maxVoltageRating: voltage.optional(), + schShowRatings: z.boolean().optional().default(false), + polarized: z.boolean().optional().default(false), + decouplingFor: z.string().optional(), + decouplingTo: z.string().optional(), + bypassFor: z.string().optional(), + bypassTo: z.string().optional(), + maxDecouplingTraceLength: z.number().optional(), + schOrientation: schematicOrientation.optional(), + connections: createConnectionsProp(capacitorPinLabels).optional(), +}) +``` + +```typescript +export interface PinCompatibleVariant { + manufacturerPartNumber?: string + supplierPartNumber?: SupplierPartNumbers +} +export interface ChipPropsSU< + PinLabel extends SchematicPinLabel = SchematicPinLabel, +> extends CommonComponentProps { + manufacturerPartNumber?: string + pinLabels?: PinLabelsProp + showPinAliases?: boolean + pcbPinLabels?: Record + schPinArrangement?: SchematicPortArrangement + schPortArrangement?: SchematicPortArrangement + pinCompatibleVariants?: PinCompatibleVariant[] + schPinStyle?: SchematicPinStyle + schPinSpacing?: Distance + schWidth?: Distance + schHeight?: Distance + noSchematicRepresentation?: boolean + internallyConnectedPins?: (string | number)[][] + externallyConnectedPins?: string[][] + connections?: Connections +} +/** + * Get the connection prop type for a component + * + * const pinLabels = { pin1: "VCC", pin2: "GND", pin3: "DATA" } as const + * export const MyChip = (props: ChipProps) => { + * // ... + * } + * const connections: ChipConnections = { + * VCC: "...", + * GND: "...", + * DATA: "...", + * } + * + */ +export type ChipConnections) => any> = { + [K in ChipPinLabels]: string +} +export const pinCompatibleVariant = z.object({ + manufacturerPartNumber: z.string().optional(), + supplierPartNumber: z.record(supplier_name, z.array(z.string())).optional(), +}) +export const chipProps = commonComponentProps.extend({ + manufacturerPartNumber: z.string().optional(), + pinLabels: pinLabelsProp.optional(), + showPinAliases: z.boolean().optional(), + pcbPinLabels: z.record(z.string(), z.string()).optional(), + internallyConnectedPins: z + .array(z.array(z.union([z.string(), z.number()]))) + .optional(), + externallyConnectedPins: z.array(z.array(z.string())).optional(), + schPinArrangement: schematicPinArrangement.optional(), + schPortArrangement: schematicPinArrangement.optional(), + pinCompatibleVariants: z.array(pinCompatibleVariant).optional(), + schPinStyle: schematicPinStyle.optional(), + schPinSpacing: distance.optional(), + schWidth: distance.optional(), + schHeight: distance.optional(), + noSchematicRepresentation: z.boolean().optional(), + connections: connectionsProp.optional(), +}) +``` + +```typescript +export interface ConnectorProps extends CommonComponentProps { + manufacturerPartNumber?: string + pinLabels?: Record< + number | SchematicPinLabel, + SchematicPinLabel | SchematicPinLabel[] + > + schPinStyle?: SchematicPinStyle + schPinSpacing?: number | string + schWidth?: number | string + schHeight?: number | string + schDirection?: "left" | "right" + schPortArrangement?: SchematicPortArrangement + internallyConnectedPins?: (string | number)[][] + standard?: "usb_c" | "m2" +} +/** + * Connector standard, e.g. usb_c, m2 + */ +export const connectorProps = commonComponentProps.extend({ + manufacturerPartNumber: z.string().optional(), + pinLabels: z + .record( + z.number().or(schematicPinLabel), + schematicPinLabel.or(z.array(schematicPinLabel)), + ) + .optional(), + schPinStyle: schematicPinStyle.optional(), + schPinSpacing: distance.optional(), + schWidth: distance.optional(), + schHeight: distance.optional(), + schDirection: z.enum(["left", "right"]).optional(), + schPortArrangement: schematicPortArrangement.optional(), + internallyConnectedPins: z + .array(z.array(z.union([z.string(), z.number()]))) + .optional(), + standard: z.enum(["usb_c", "m2"]).optional(), +}) +``` + +```typescript +export interface ConstrainedLayoutProps { + name?: string + pcbOnly?: boolean + schOnly?: boolean +} +export const constrainedLayoutProps = z.object({ + name: z.string().optional(), + pcbOnly: z.boolean().optional(), + schOnly: z.boolean().optional(), +}) +``` + +```typescript +export type PcbXDistConstraint = { + pcb?: true + xDist: Distance + + left: string + + right: string + + edgeToEdge?: true + + centerToCenter?: true +} +/** + * If true, the provided distance is the distance between the centers of the + * left and right components + */ +export type PcbYDistConstraint = { + pcb?: true + yDist: Distance + + top: string + + bottom: string + + edgeToEdge?: true + centerToCenter?: true +} +/** + * Selector for bottom component, e.g. ".U1" or ".R1", you can also specify the + * edge or center of the component e.g. ".R1 bottomedge", ".R1 center" + */ +export type PcbSameYConstraint = { + pcb?: true + sameY?: true + + for: string[] +} +/** + * Selector for components, e.g. [".U1", ".R1"], you can also specify the + * edge or center of the component e.g. [".R1 leftedge", ".U1 center"] + */ +export type PcbSameXConstraint = { + pcb?: true + sameX?: true + for: string[] +} +export const pcbXDistConstraintProps = z.object({ + pcb: z.literal(true).optional(), + xDist: distance, + left: z.string(), + right: z.string(), + + edgeToEdge: z.literal(true).optional(), + centerToCenter: z.literal(true).optional(), +}) +export const pcbYDistConstraintProps = z.object({ + pcb: z.literal(true).optional(), + yDist: distance, + top: z.string(), + bottom: z.string(), + + edgeToEdge: z.literal(true).optional(), + centerToCenter: z.literal(true).optional(), +}) +export const pcbSameYConstraintProps = z.object({ + pcb: z.literal(true).optional(), + sameY: z.literal(true).optional(), + for: z.array(z.string()), +}) +export const pcbSameXConstraintProps = z.object({ + pcb: z.literal(true).optional(), + sameX: z.literal(true).optional(), + for: z.array(z.string()), +}) +``` + +```typescript +export interface CopperPourProps { + name?: string + layer: LayerRefInput + connectsTo: string + padMargin?: Distance + traceMargin?: Distance +} +export const copperPourProps = z.object({ + name: z.string().optional(), + layer: layer_ref, + connectsTo: z.string(), + padMargin: distance.optional(), + traceMargin: distance.optional(), +}) +``` + +```typescript +export interface CrystalProps + extends CommonComponentProps { + frequency: number | string + loadCapacitance: number | string + manufacturerPartNumber?: string + mpn?: string + pinVariant?: PinVariant + schOrientation?: SchematicOrientation + connections?: Connections +} +export const crystalProps = commonComponentProps.extend({ + frequency: frequency, + loadCapacitance: capacitance, + manufacturerPartNumber: z.string().optional(), + mpn: z.string().optional(), + pinVariant: z.enum(["two_pin", "four_pin"]).optional(), + schOrientation: schematicOrientation.optional(), + connections: createConnectionsProp(crystalPins).optional(), +}) +``` + +```typescript +export interface RectCutoutProps + extends Omit { + name?: string + shape: "rect" + width: Distance + height: Distance +} +export const rectCutoutProps = pcbLayoutProps + .omit({ + layer: true, + pcbRotation: true, + }) + .extend({ + name: z.string().optional(), + shape: z.literal("rect"), + width: distance, + height: distance, + }) +export interface CircleCutoutProps + extends Omit { + name?: string + shape: "circle" + radius: Distance +} +export const circleCutoutProps = pcbLayoutProps + .omit({ + layer: true, + pcbRotation: true, + }) + .extend({ + name: z.string().optional(), + shape: z.literal("circle"), + radius: distance, + }) +export interface PolygonCutoutProps + extends Omit { + name?: string + shape: "polygon" + points: Point[] +} +export const polygonCutoutProps = pcbLayoutProps + .omit({ + layer: true, + pcbRotation: true, + }) + .extend({ + name: z.string().optional(), + shape: z.literal("polygon"), + points: z.array(point), + }) +``` + +```typescript +.extend({ + connections: connectionsProp.optional(), + variant: diodeVariant.optional().default("standard"), + standard: z.boolean().optional(), + schottky: z.boolean().optional(), + zener: z.boolean().optional(), + avalanche: z.boolean().optional(), + photo: z.boolean().optional(), + tvs: z.boolean().optional(), + schOrientation: schematicOrientation.optional(), + }) +export interface DiodeProps + extends CommonComponentProps { + connections?: { + anode?: string | string[] | readonly string[] + cathode?: string | string[] | readonly string[] + pin1?: string | string[] | readonly string[] + pin2?: string | string[] | readonly string[] + pos?: string | string[] | readonly string[] + neg?: string | string[] | readonly string[] + } + variant?: "standard" | "schottky" | "zener" | "avalanche" | "photo" | "tvs" + standard?: boolean + schottky?: boolean + zener?: boolean + avalanche?: boolean + photo?: boolean + tvs?: boolean + schOrientation?: SchematicOrientation +} +``` + +```typescript +export const fabricationNotePathProps = pcbLayoutProps + .omit({ pcbX: true, pcbY: true, pcbRotation: true }) + .extend({ + route: z.array(route_hint_point), + strokeWidth: length.optional(), + color: z.string().optional(), + }) +``` + +```typescript +export const fabricationNoteTextProps = pcbLayoutProps.extend({ + text: z.string(), + anchorAlignment: z + .enum(["center", "top_left", "top_right", "bottom_left", "bottom_right"]) + .default("center"), + font: z.enum(["tscircuit2024"]).optional(), + fontSize: length.optional(), + color: z.string().optional(), +}) +``` + +```typescript +export interface FootprintProps { + originalLayer?: LayerRef +} +/** + * The layer that the footprint is designed for. If you set this to "top" + * then it means the children were intended to represent the top layer. If + * the with this footprint is moved to the bottom layer, then the + * components will be mirrored. + * + * Generally, you shouldn't set this except where it can help prevent + * confusion because you have a complex multi-layer footprint. Default is + * "top" and this is most intuitive. + */ +export const footprintProps = z.object({ + originalLayer: layer_ref.default("top").optional(), +}) +``` + +```typescript +export interface FuseProps + extends CommonComponentProps { + currentRating: number | string + + voltageRating?: number | string + + schShowRatings?: boolean + + schOrientation?: SchematicOrientation + + connections?: Connections +} +/** + * Schema for validating fuse props + */ +export const fuseProps = commonComponentProps.extend({ + currentRating: z.union([z.number(), z.string()]), + voltageRating: z.union([z.number(), z.string()]).optional(), + schShowRatings: z.boolean().optional(), + schOrientation: schematicOrientation.optional(), + connections: z + .record( + z.string(), + z.union([ + z.string(), + z.array(z.string()).readonly(), + z.array(z.string()), + ]), + ) + .optional(), +}) +``` + +```typescript +export const layoutConfig = z.object({ + layoutMode: z + .enum(["grid", "flex", "match-adapt", "relative", "none"]) + .optional(), + position: z.enum(["absolute", "relative"]).optional(), + + grid: z.boolean().optional(), + gridCols: z.number().or(z.string()).optional(), + gridRows: z.number().or(z.string()).optional(), + gridTemplateRows: z.string().optional(), + gridTemplateColumns: z.string().optional(), + gridTemplate: z.string().optional(), + gridGap: z.number().or(z.string()).optional(), + gridRowGap: z.number().or(z.string()).optional(), + gridColumnGap: z.number().or(z.string()).optional(), + + flex: z.boolean().or(z.string()).optional(), + flexDirection: z.enum(["row", "column"]).optional(), + alignItems: z.enum(["start", "center", "end", "stretch"]).optional(), + justifyContent: z + .enum([ + "start", + "center", + "end", + "stretch", + "space-between", + "space-around", + "space-evenly", + ]) + .optional(), + flexRow: z.boolean().optional(), + flexColumn: z.boolean().optional(), + gap: z.number().or(z.string()).optional(), + + pack: z + .boolean() + .optional() + .describe("Pack the contents of this group using a packing strategy"), + packOrderStrategy: z + .enum([ + "largest_to_smallest", + "first_to_last", + "highest_to_lowest_pin_count", + ]) + .optional(), + packPlacementStrategy: z + .enum(["shortest_connection_along_outline"]) + .optional(), + + padding: length.optional(), + paddingLeft: length.optional(), + paddingRight: length.optional(), + paddingTop: length.optional(), + paddingBottom: length.optional(), + paddingX: length.optional(), + paddingY: length.optional(), + + width: length.optional(), + height: length.optional(), + + matchAdapt: z.boolean().optional(), + matchAdaptTemplate: z.any().optional(), +}) +export interface LayoutConfig { + layoutMode?: "grid" | "flex" | "match-adapt" | "relative" | "none" + position?: "absolute" | "relative" + + grid?: boolean + gridCols?: number | string + gridRows?: number | string + gridTemplateRows?: string + gridTemplateColumns?: string + gridTemplate?: string + gridGap?: number | string + gridRowGap?: number | string + gridColumnGap?: number | string + + flex?: boolean | string + flexDirection?: "row" | "column" + alignItems?: "start" | "center" | "end" | "stretch" + justifyContent?: + | "start" + | "center" + | "end" + | "stretch" + | "space-between" + | "space-around" + | "space-evenly" + flexRow?: boolean + flexColumn?: boolean + gap?: number | string + + pack?: boolean + packOrderStrategy?: + | "largest_to_smallest" + | "first_to_last" + | "highest_to_lowest_pin_count" + packPlacementStrategy?: "shortest_connection_along_outline" + + padding?: Distance + paddingLeft?: Distance + paddingRight?: Distance + paddingTop?: Distance + paddingBottom?: Distance + paddingX?: Distance + paddingY?: Distance + + width?: Distance + height?: Distance + + matchAdapt?: boolean + matchAdaptTemplate?: any +} +export interface Border { + strokeWidth?: Distance + dashed?: boolean + solid?: boolean +} +export const border = z.object({ + strokeWidth: length.optional(), + dashed: z.boolean().optional(), + solid: z.boolean().optional(), +}) +export interface BaseGroupProps extends CommonLayoutProps, LayoutConfig { + name?: string + key?: any + children?: any + + schTitle?: string + + showAsSchematicBox?: boolean + + connections?: Connections + + schPinArrangement?: SchematicPinArrangement + + schPinSpacing?: Distance + + schPinStyle?: SchematicPinStyle + + pcbWidth?: Distance + pcbHeight?: Distance + schWidth?: Distance + schHeight?: Distance + + pcbLayout?: LayoutConfig + schLayout?: LayoutConfig + cellBorder?: Border | null + border?: Border | null + schPadding?: Distance + schPaddingLeft?: Distance + schPaddingRight?: Distance + schPaddingTop?: Distance + schPaddingBottom?: Distance + + pcbPadding?: Distance + pcbPaddingLeft?: Distance + pcbPaddingRight?: Distance + pcbPaddingTop?: Distance + pcbPaddingBottom?: Distance + + grid?: boolean + flex?: boolean | string + + pcbGrid?: boolean + pcbGridCols?: number | string + pcbGridRows?: number | string + pcbGridTemplateRows?: string + pcbGridTemplateColumns?: string + pcbGridTemplate?: string + pcbGridGap?: number | string + pcbGridRowGap?: number | string + pcbGridColumnGap?: number | string + + pcbFlex?: boolean | string + pcbFlexGap?: number | string + pcbFlexDirection?: "row" | "column" + pcbAlignItems?: "start" | "center" | "end" | "stretch" + pcbJustifyContent?: + | "start" + | "center" + | "end" + | "stretch" + | "space-between" + | "space-around" + | "space-evenly" + pcbFlexRow?: boolean + pcbFlexColumn?: boolean + pcbGap?: number | string + pcbPack?: boolean + pcbPackGap?: number | string + + schGrid?: boolean + schGridCols?: number | string + schGridRows?: number | string + schGridTemplateRows?: string + schGridTemplateColumns?: string + schGridTemplate?: string + schGridGap?: number | string + schGridRowGap?: number | string + schGridColumnGap?: number | string + + schFlex?: boolean | string + schFlexGap?: number | string + schFlexDirection?: "row" | "column" + schAlignItems?: "start" | "center" | "end" | "stretch" + schJustifyContent?: + | "start" + | "center" + | "end" + | "stretch" + | "space-between" + | "space-around" + | "space-evenly" + schFlexRow?: boolean + schFlexColumn?: boolean + schGap?: number | string + schPack?: boolean + schMatchAdapt?: boolean +} +/** @deprecated Use `pcbFlex` */ +export type PartsEngine = { + findPart: (params: { + sourceComponent: AnySourceComponent + footprinterString?: string + }) => Promise | SupplierPartNumbers +} +export interface PcbRouteCache { + pcbTraces: PcbTrace[] + cacheKey: string +} +export interface AutorouterConfig { + serverUrl?: string + inputFormat?: "simplified" | "circuit-json" + serverMode?: "job" | "solve-endpoint" + serverCacheEnabled?: boolean + cache?: PcbRouteCache + traceClearance?: Distance + groupMode?: + | "sequential_trace" + | "subcircuit" + | /** @deprecated Use "sequential_trace" */ "sequential-trace" + local?: boolean + algorithmFn?: (simpleRouteJson: any) => Promise + preset?: + | "sequential_trace" + | "subcircuit" + | "auto" + | "auto_local" + | "auto_cloud" + | "freerouting" + | /** @deprecated Use "sequential_trace" */ "sequential-trace" + | /** @deprecated Use "auto_local" */ "auto-local" + | /** @deprecated Use "auto_cloud" */ "auto-cloud" +} +export const autorouterConfig = z.object({ + serverUrl: z.string().optional(), + inputFormat: z.enum(["simplified", "circuit-json"]).optional(), + serverMode: z.enum(["job", "solve-endpoint"]).optional(), + serverCacheEnabled: z.boolean().optional(), + cache: z.custom((v) => true).optional(), + traceClearance: length.optional(), + groupMode: z + .enum(["sequential_trace", "subcircuit", "sequential-trace"]) + .optional(), + algorithmFn: z + .custom<(simpleRouteJson: any) => Promise>( + (v) => typeof v === "function" || v === undefined, + ) + .optional(), + preset: z + .enum([ + "sequential_trace", + "subcircuit", + "auto", + "auto_local", + "auto_cloud", + "freerouting", + "sequential-trace", + "auto-local", + "auto-cloud", + ]) + .optional(), + local: z.boolean().optional(), +}) +export interface SubcircuitGroupProps extends BaseGroupProps { + manualEdits?: ManualEditsFileInput + routingDisabled?: boolean + defaultTraceWidth?: Distance + minTraceWidth?: Distance + pcbRouteCache?: PcbRouteCache + + autorouter?: AutorouterProp + + schAutoLayoutEnabled?: boolean + + schTraceAutoLabelEnabled?: boolean + + schMaxTraceDistance?: Distance + + partsEngine?: PartsEngine + + square?: boolean + emptyArea?: string + filledArea?: string + + width?: number | string + height?: number | string + outline?: Point[] + outlineOffsetX?: number | string + outlineOffsetY?: number | string +} +/** Desired filled area of the board e.g. "22mm^2" or "20%" */ +export interface SubcircuitGroupPropsWithBool extends SubcircuitGroupProps { + subcircuit: true +} +export interface NonSubcircuitGroupProps extends BaseGroupProps { + subcircuit?: false | undefined +} +export const baseGroupProps = commonLayoutProps.extend({ + name: z.string().optional(), + children: z.any().optional(), + schTitle: z.string().optional(), + key: z.any().optional(), + showAsSchematicBox: z.boolean().optional(), + connections: z.record(z.string(), connectionTarget.optional()).optional(), + schPinArrangement: schematicPinArrangement.optional(), + schPinSpacing: length.optional(), + schPinStyle: schematicPinStyle.optional(), + + ...layoutConfig.shape, + grid: layoutConfig.shape.grid.describe("@deprecated use pcbGrid"), + flex: layoutConfig.shape.flex.describe("@deprecated use pcbFlex"), + pcbGrid: z.boolean().optional(), + pcbGridCols: z.number().or(z.string()).optional(), + pcbGridRows: z.number().or(z.string()).optional(), + pcbGridTemplateRows: z.string().optional(), + pcbGridTemplateColumns: z.string().optional(), + pcbGridTemplate: z.string().optional(), + pcbGridGap: z.number().or(z.string()).optional(), + pcbGridRowGap: z.number().or(z.string()).optional(), + pcbGridColumnGap: z.number().or(z.string()).optional(), + pcbFlex: z.boolean().or(z.string()).optional(), + pcbFlexGap: z.number().or(z.string()).optional(), + pcbFlexDirection: z.enum(["row", "column"]).optional(), + pcbAlignItems: z.enum(["start", "center", "end", "stretch"]).optional(), + pcbJustifyContent: z + .enum([ + "start", + "center", + "end", + "stretch", + "space-between", + "space-around", + "space-evenly", + ]) + .optional(), + pcbFlexRow: z.boolean().optional(), + pcbFlexColumn: z.boolean().optional(), + pcbGap: z.number().or(z.string()).optional(), + pcbPack: z.boolean().optional(), + pcbPackGap: z.number().or(z.string()).optional(), + + schGrid: z.boolean().optional(), + schGridCols: z.number().or(z.string()).optional(), + schGridRows: z.number().or(z.string()).optional(), + schGridTemplateRows: z.string().optional(), + schGridTemplateColumns: z.string().optional(), + schGridTemplate: z.string().optional(), + schGridGap: z.number().or(z.string()).optional(), + schGridRowGap: z.number().or(z.string()).optional(), + schGridColumnGap: z.number().or(z.string()).optional(), + + schFlex: z.boolean().or(z.string()).optional(), + schFlexGap: z.number().or(z.string()).optional(), + schFlexDirection: z.enum(["row", "column"]).optional(), + schAlignItems: z.enum(["start", "center", "end", "stretch"]).optional(), + schJustifyContent: z + .enum([ + "start", + "center", + "end", + "stretch", + "space-between", + "space-around", + "space-evenly", + ]) + .optional(), + schFlexRow: z.boolean().optional(), + schFlexColumn: z.boolean().optional(), + schGap: z.number().or(z.string()).optional(), + schPack: z.boolean().optional(), + schMatchAdapt: z.boolean().optional(), + pcbWidth: length.optional(), + pcbHeight: length.optional(), + schWidth: length.optional(), + schHeight: length.optional(), + pcbLayout: layoutConfig.optional(), + schLayout: layoutConfig.optional(), + cellBorder: border.nullable().optional(), + border: border.nullable().optional(), + schPadding: length.optional(), + schPaddingLeft: length.optional(), + schPaddingRight: length.optional(), + schPaddingTop: length.optional(), + schPaddingBottom: length.optional(), + pcbPadding: length.optional(), + pcbPaddingLeft: length.optional(), + pcbPaddingRight: length.optional(), + pcbPaddingTop: length.optional(), + pcbPaddingBottom: length.optional(), +}) +export const subcircuitGroupProps = baseGroupProps.extend({ + manualEdits: manual_edits_file.optional(), + schAutoLayoutEnabled: z.boolean().optional(), + schTraceAutoLabelEnabled: z.boolean().optional(), + schMaxTraceDistance: distance.optional(), + routingDisabled: z.boolean().optional(), + defaultTraceWidth: length.optional(), + minTraceWidth: length.optional(), + partsEngine: partsEngine.optional(), + pcbRouteCache: z.custom((v) => true).optional(), + autorouter: autorouterProp.optional(), + square: z.boolean().optional(), + emptyArea: z.string().optional(), + filledArea: z.string().optional(), + width: distance.optional(), + height: distance.optional(), + outline: z.array(point).optional(), + outlineOffsetX: distance.optional(), + outlineOffsetY: distance.optional(), +}) +export const subcircuitGroupPropsWithBool = subcircuitGroupProps.extend({ + subcircuit: z.literal(true), +}) +``` + +```typescript +export interface CircleHoleProps extends PcbLayoutProps { + name?: string + shape?: "circle" + diameter?: Distance + radius?: Distance +} +export interface PillHoleProps extends PcbLayoutProps { + name?: string + shape: "pill" + width: Distance + height: Distance +} +export type HoleProps = CircleHoleProps | PillHoleProps +const circleHoleProps = pcbLayoutProps + .extend({ + name: z.string().optional(), + shape: z.literal("circle").optional(), + diameter: distance.optional(), + radius: distance.optional(), + }) + .transform((d) => ({ + ...d, + diameter: d.diameter ?? 2 * d.radius!, + radius: d.radius ?? d.diameter! / 2, + })) +const pillHoleProps = pcbLayoutProps.extend({ + name: z.string().optional(), + shape: z.literal("pill"), + width: distance, + height: distance, +}) +export const holeProps = z.union([circleHoleProps, pillHoleProps]) +``` + +```typescript +export interface InductorProps + extends CommonComponentProps { + inductance: number | string + maxCurrentRating?: number | string + schOrientation?: SchematicOrientation + connections?: Connections +} +export const inductorProps = commonComponentProps.extend({ + inductance, + maxCurrentRating: z.union([z.string(), z.number()]).optional(), + schOrientation: schematicOrientation.optional(), + connections: createConnectionsProp(inductorPins).optional(), +}) +``` + +```typescript +export interface JumperProps extends CommonComponentProps { + manufacturerPartNumber?: string + pinLabels?: Record< + number | SchematicPinLabel, + SchematicPinLabel | SchematicPinLabel[] + > + schPinStyle?: SchematicPinStyle + schPinSpacing?: number | string + schWidth?: number | string + schHeight?: number | string + schDirection?: "left" | "right" + schPinArrangement?: SchematicPortArrangement + schPortArrangement?: SchematicPortArrangement + pcbPinLabels?: Record + pinCount?: 2 | 3 + internallyConnectedPins?: (string | number)[][] + connections?: Connections +} +/** + * Connections to other components + */ +export const jumperProps = commonComponentProps.extend({ + manufacturerPartNumber: z.string().optional(), + pinLabels: z + .record( + z.number().or(schematicPinLabel), + schematicPinLabel.or(z.array(schematicPinLabel)), + ) + .optional(), + schPinStyle: schematicPinStyle.optional(), + schPinSpacing: distance.optional(), + schWidth: distance.optional(), + schHeight: distance.optional(), + schDirection: z.enum(["left", "right"]).optional(), + schPinArrangement: schematicPinArrangement.optional(), + schPortArrangement: schematicPortArrangement.optional(), + pcbPinLabels: z.record(z.string(), z.string()).optional(), + pinCount: z.union([z.literal(2), z.literal(3)]).optional(), + internallyConnectedPins: z + .array(z.array(z.union([z.string(), z.number()]))) + .optional(), + connections: z + .custom() + .pipe(z.record(z.string(), connectionTarget)) + .optional(), +}) +``` + +```typescript +export const ledProps = commonComponentProps.extend({ + color: z.string().optional(), + wavelength: z.string().optional(), + schDisplayValue: z.string().optional(), + schOrientation: schematicOrientation.optional(), + connections: createConnectionsProp(lrPolarPins).optional(), + laser: z.boolean().optional(), +}) +``` + +```typescript +export interface MosfetProps + extends CommonComponentProps { + channelType: "n" | "p" + mosfetMode: "enhancement" | "depletion" +} +export const mosfetProps = commonComponentProps.extend({ + channelType: z.enum(["n", "p"]), + mosfetMode: z.enum(["enhancement", "depletion"]), +}) +export const mosfetPins = [ + "pin1", + "drain", + "pin2", + "source", + "pin3", + "gate", +] as const +``` + +```typescript +export interface NetProps { + name: string + connectsTo?: string | string[] +} +export const netProps = z.object({ + name: z.string(), + connectsTo: z.string().or(z.array(z.string())).optional(), +}) +``` + +```typescript +/** + * @deprecated Use NetLabelProps instead. + */ +export interface NetAliasProps { + net?: string + connection?: string + schX?: number | string + schY?: number | string + schRotation?: number | string + anchorSide?: "left" | "top" | "right" | "bottom" +} +/** @deprecated Use netLabelProps instead. */ +export const netAliasProps = z.object({ + net: z.string().optional(), + connection: z.string().optional(), + schX: distance.optional(), + schY: distance.optional(), + schRotation: rotation.optional(), + anchorSide: z.enum(["left", "top", "right", "bottom"]).optional(), +}) +``` + +```typescript +export interface NetLabelProps { + net?: string + connection?: string + connectsTo?: string | string[] + schX?: number | string + schY?: number | string + schRotation?: number | string + anchorSide?: "left" | "top" | "right" | "bottom" +} +export const netLabelProps = z.object({ + net: z.string().optional(), + connection: z.string().optional(), + connectsTo: z.string().or(z.array(z.string())).optional(), + schX: distance.optional(), + schY: distance.optional(), + schRotation: rotation.optional(), + anchorSide: z.enum(["left", "top", "right", "bottom"]).optional(), +}) +``` + +```typescript +pcbLayoutProps.omit({ pcbRotation: true }).extend({ + shape: z.literal("circle"), + radius: distance, + }), +pcbLayoutProps.extend({ + shape: z.literal("rect"), + width: distance, + height: distance, + }), +``` + +```typescript +export const pcbTraceProps = z.object({ + layer: z.string().optional(), + thickness: distance.optional(), + route: z.array(route_hint_point), +}) +``` + +```typescript +export interface PinHeaderProps extends CommonComponentProps { + pinCount: number + + pitch?: number | string + + schFacingDirection?: "up" | "down" | "left" | "right" + + gender?: "male" | "female" | "unpopulated" + + showSilkscreenPinLabels?: boolean + + pcbPinLabels?: Record + + doubleRow?: boolean + + rightAngle?: boolean + + pcbOrientation?: PcbOrientation + + holeDiameter?: number | string + + platedDiameter?: number | string + + pinLabels?: Record | SchematicPinLabel[] + + connections?: Connections + + facingDirection?: "left" | "right" + + schPinArrangement?: SchematicPinArrangement + + schPinStyle?: SchematicPinStyle + + schPinSpacing?: number | string + + schWidth?: number | string + + schHeight?: number | string +} +/** + * Schematic height + */ +export const pinHeaderProps = commonComponentProps.extend({ + pinCount: z.number(), + pitch: distance.optional(), + schFacingDirection: z.enum(["up", "down", "left", "right"]).optional(), + gender: z.enum(["male", "female", "unpopulated"]).optional().default("male"), + showSilkscreenPinLabels: z.boolean().optional(), + pcbPinLabels: z.record(z.string(), z.string()).optional(), + doubleRow: z.boolean().optional(), + rightAngle: z.boolean().optional(), + pcbOrientation: pcbOrientationProp.optional(), + holeDiameter: distance.optional(), + platedDiameter: distance.optional(), + pinLabels: z + .record(z.string(), schematicPinLabel) + .or(z.array(schematicPinLabel)) + .optional(), + connections: z + .custom() + .pipe(z.record(z.string(), connectionTarget)) + .optional(), + facingDirection: z.enum(["left", "right"]).optional(), + schPinArrangement: schematicPinArrangement.optional(), + schPinStyle: schematicPinStyle.optional(), + schPinSpacing: distance.optional(), + schWidth: distance.optional(), + schHeight: distance.optional(), +}) +``` + +```typescript +export interface PinoutProps< + PinLabelMap extends PinLabelsProp | string = string, +> extends ChipProps {} +``` + +```typescript +export interface CirclePlatedHoleProps + extends Omit { + name?: string + connectsTo?: string | string[] + shape: "circle" + holeDiameter: number | string + outerDiameter: number | string + portHints?: PortHints +} +export interface OvalPlatedHoleProps + extends Omit { + name?: string + connectsTo?: string | string[] + shape: "oval" + outerWidth: number | string + outerHeight: number | string + holeWidth: number | string + holeHeight: number | string + portHints?: PortHints + + innerWidth?: number | string + innerHeight?: number | string +} +/** @deprecated use holeHeight */ +export interface PillPlatedHoleProps extends Omit { + name?: string + rectPad?: boolean + connectsTo?: string | string[] + shape: "pill" + outerWidth: number | string + outerHeight: number | string + holeWidth: number | string + holeHeight: number | string + + innerWidth?: number | string + innerHeight?: number | string + + portHints?: PortHints +} +/** @deprecated use holeHeight */ +export interface CircularHoleWithRectPlatedProps + extends Omit { + name?: string + connectsTo?: string | string[] + shape: "circular_hole_with_rect_pad" + holeDiameter: number | string + rectPadWidth: number | string + rectPadHeight: number | string + holeShape?: "circle" + padShape?: "rect" + portHints?: PortHints + pcbHoleOffsetX?: number | string + pcbHoleOffsetY?: number | string +} +export interface PillWithRectPadPlatedHoleProps + extends Omit { + name?: string + connectsTo?: string | string[] + shape: "pill_hole_with_rect_pad" + holeShape: "pill" + padShape: "rect" + holeWidth: number | string + holeHeight: number | string + rectPadWidth: number | string + rectPadHeight: number | string + portHints?: PortHints +} +export type PlatedHoleProps = + | CirclePlatedHoleProps + | OvalPlatedHoleProps + | PillPlatedHoleProps + | CircularHoleWithRectPlatedProps + | PillWithRectPadPlatedHoleProps + +const distanceHiddenUndefined = z + .custom>() + .transform((a) => { + if (a === undefined) return undefined + return distance.parse(a) + }) +pcbLayoutProps.omit({ pcbRotation: true, layer: true }).extend({ + name: z.string().optional(), + connectsTo: z.string().or(z.array(z.string())).optional(), + shape: z.literal("circle"), + holeDiameter: distance, + outerDiameter: distance, + portHints: portHints.optional(), + }), +pcbLayoutProps.omit({ pcbRotation: true, layer: true }).extend({ + name: z.string().optional(), + connectsTo: z.string().or(z.array(z.string())).optional(), + shape: z.literal("oval"), + outerWidth: distance, + outerHeight: distance, + holeWidth: distanceHiddenUndefined, + holeHeight: distanceHiddenUndefined, + innerWidth: distance.optional().describe("DEPRECATED use holeWidth"), + innerHeight: distance.optional().describe("DEPRECATED use holeHeight"), + portHints: portHints.optional(), + }), +pcbLayoutProps.omit({ layer: true }).extend({ + name: z.string().optional(), + connectsTo: z.string().or(z.array(z.string())).optional(), + shape: z.literal("pill"), + rectPad: z.boolean().optional(), + outerWidth: distance, + outerHeight: distance, + holeWidth: distanceHiddenUndefined, + holeHeight: distanceHiddenUndefined, + innerWidth: distance.optional().describe("DEPRECATED use holeWidth"), + innerHeight: distance.optional().describe("DEPRECATED use holeHeight"), + portHints: portHints.optional(), + }), +pcbLayoutProps.omit({ pcbRotation: true, layer: true }).extend({ + name: z.string().optional(), + connectsTo: z.string().or(z.array(z.string())).optional(), + shape: z.literal("circular_hole_with_rect_pad"), + holeDiameter: distance, + rectPadWidth: distance, + rectPadHeight: distance, + holeShape: z.literal("circle").optional(), + padShape: z.literal("rect").optional(), + portHints: portHints.optional(), + pcbHoleOffsetX: distance.optional(), + pcbHoleOffsetY: distance.optional(), + }), +pcbLayoutProps.omit({ pcbRotation: true, layer: true }).extend({ + name: z.string().optional(), + connectsTo: z.string().or(z.array(z.string())).optional(), + shape: z.literal("pill_hole_with_rect_pad"), + holeShape: z.literal("pill"), + padShape: z.literal("rect"), + holeWidth: distance, + holeHeight: distance, + rectPadWidth: distance, + rectPadHeight: distance, + portHints: portHints.optional(), + }), +``` + +```typescript +export const portProps = commonLayoutProps.extend({ + name: z.string(), + pinNumber: z.number().optional(), + aliases: z.array(z.string()).optional(), + direction: direction, +}) +``` + +```typescript +export interface PotentiometerProps extends CommonComponentProps { + maxResistance: number | string + pinVariant?: PotentiometerPinVariant +} +export const potentiometerProps = commonComponentProps.extend({ + maxResistance: resistance, + pinVariant: z.enum(["two_pin", "three_pin"]).optional(), +}) +``` + +```typescript +export const powerSourceProps = commonComponentProps.extend({ + voltage, +}) +``` + +```typescript +export interface ResistorProps + extends CommonComponentProps { + resistance: number | string + pullupFor?: string + pullupTo?: string + pulldownFor?: string + pulldownTo?: string + schOrientation?: SchematicOrientation + connections?: Connections +} +export const resistorProps = commonComponentProps.extend({ + resistance, + + pullupFor: z.string().optional(), + pullupTo: z.string().optional(), + + pulldownFor: z.string().optional(), + pulldownTo: z.string().optional(), + + schOrientation: schematicOrientation.optional(), + + connections: createConnectionsProp(resistorPinLabels).optional(), +}) +``` + +```typescript +export interface ResonatorProps extends CommonComponentProps { + frequency: number | string + loadCapacitance: number | string + pinVariant?: ResonatorPinVariant +} +export const resonatorProps = commonComponentProps.extend({ + frequency: frequency, + loadCapacitance: capacitance, + pinVariant: z.enum(["no_ground", "ground_pin", "two_ground_pins"]).optional(), +}) +``` + +```typescript +export const schematicBoxProps = z + .object({ + schX: distance.optional(), + schY: distance.optional(), + width: distance.optional(), + height: distance.optional(), + overlay: z.array(z.string()).optional(), + + padding: distance.optional(), + paddingLeft: distance.optional(), + paddingRight: distance.optional(), + paddingTop: distance.optional(), + paddingBottom: distance.optional(), + + title: z.string().optional(), + titleAlignment: ninePointAnchor.default("top_left"), + titleColor: z.string().optional(), + titleFontSize: distance.optional(), + titleInside: z.boolean().default(false), + strokeStyle: z.enum(["solid", "dashed"]).default("solid"), + }) +``` + +```typescript +export const schematicCellProps = z.object({ + children: z.string().optional(), + horizontalAlign: z.enum(["left", "center", "right"]).optional(), + verticalAlign: z.enum(["top", "middle", "bottom"]).optional(), + fontSize: distance.optional(), + rowSpan: z.number().optional(), + colSpan: z.number().optional(), + width: distance.optional(), + text: z.string().optional(), +}) +export interface SchematicCellProps { + children?: string + horizontalAlign?: "left" | "center" | "right" + verticalAlign?: "top" | "middle" | "bottom" + fontSize?: number | string + rowSpan?: number + colSpan?: number + width?: number | string + text?: string +} +``` + +```typescript +export const schematicArcProps = z.object({ + center: point, + radius: distance, + startAngleDegrees: rotation, + endAngleDegrees: rotation, + direction: z.enum(["clockwise", "counterclockwise"]).default( + "counterclockwise", + ), + strokeWidth: distance.optional(), + color: z.string().optional().default("#000000"), + isDashed: z.boolean().optional().default(false), +}) +``` + +```typescript +export const schematicCircleProps = z.object({ + center: point, + radius: distance, + strokeWidth: distance.optional(), + color: z.string().optional().default("#000000"), + isFilled: z.boolean().optional().default(false), + fillColor: z.string().optional(), + isDashed: z.boolean().optional().default(false), +}) +``` + +```typescript +export const schematicLineProps = z.object({ + x1: distance, + y1: distance, + x2: distance, + y2: distance, + strokeWidth: distance.optional(), + color: z.string().optional().default("#000000"), + isDashed: z.boolean().optional().default(false), +}) +``` + +```typescript +export const schematicRectProps = z.object({ + center: point, + width: distance, + height: distance, + rotation: rotation.default(0), + strokeWidth: distance.optional(), + color: z.string().optional().default("#000000"), + isFilled: z.boolean().optional().default(false), + fillColor: z.string().optional(), + isDashed: z.boolean().optional().default(false), +}) +``` + +```typescript +export const schematicPathProps = z.object({ + points: z.array(point), + isFilled: z.boolean().optional().default(false), + fillColor: z.enum(["red", "blue"]).optional(), +}) +``` + +```typescript +export const schematicRowProps = z.object({ + children: z.any().optional(), + height: distance.optional(), +}) +export interface SchematicRowProps { + children?: any + height?: number | string +} +``` + +```typescript +export const schematicTableProps = z.object({ + schX: distance.optional(), + schY: distance.optional(), + children: z.any().optional(), + cellPadding: distance.optional(), + borderWidth: distance.optional(), + anchor: ninePointAnchor.optional(), + fontSize: distance.optional(), +}) +export interface SchematicTableProps { + schX?: number | string + schY?: number | string + children?: any + cellPadding?: number | string + borderWidth?: number | string + anchor?: z.infer + fontSize?: number | string +} +``` + +```typescript +export const schematicTextProps = z.object({ + schX: distance.optional(), + schY: distance.optional(), + text: z.string(), + fontSize: z.number().default(1), + anchor: z + .union([fivePointAnchor.describe("legacy"), ninePointAnchor]) + .default("center"), + color: z.string().default("#000000"), + schRotation: rotation.default(0), +}) +``` + +```typescript +export const silkscreenCircleProps = pcbLayoutProps + .omit({ pcbRotation: true }) + .extend({ + isFilled: z.boolean().optional(), + isOutline: z.boolean().optional(), + strokeWidth: distance.optional(), + radius: distance, + }) +``` + +```typescript +export const silkscreenLineProps = pcbLayoutProps + .omit({ pcbX: true, pcbY: true, pcbRotation: true }) + .extend({ + strokeWidth: distance, + x1: distance, + y1: distance, + x2: distance, + y2: distance, + }) +``` + +```typescript +export const silkscreenPathProps = pcbLayoutProps + .omit({ pcbX: true, pcbY: true, pcbRotation: true }) + .extend({ + route: z.array(route_hint_point), + strokeWidth: length.optional(), + }) +``` + +```typescript +export const silkscreenRectProps = pcbLayoutProps + .omit({ pcbRotation: true }) + .extend({ + filled: z.boolean().default(true).optional(), + stroke: z.enum(["dashed", "solid", "none"]).optional(), + strokeWidth: distance.optional(), + width: distance, + height: distance, + }) +``` + +```typescript +export const silkscreenTextProps = pcbLayoutProps.extend({ + text: z.string(), + anchorAlignment: ninePointAnchor.default("center"), + font: z.enum(["tscircuit2024"]).optional(), + fontSize: length.optional(), + isKnockout: z.boolean().optional(), + knockoutPadding: length.optional(), + knockoutPaddingLeft: length.optional(), + knockoutPaddingRight: length.optional(), + knockoutPaddingTop: length.optional(), + knockoutPaddingBottom: length.optional(), + layers: z.array(layer_ref).optional(), +}) +``` + +```typescript +export interface RectSmtPadProps extends Omit { + name?: string + shape: "rect" + width: Distance + height: Distance + portHints?: PortHints + coveredWithSolderMask?: boolean +} +export interface RotatedRectSmtPadProps + extends Omit { + name?: string + shape: "rotated_rect" + width: Distance + height: Distance + ccwRotation: number + portHints?: PortHints + coveredWithSolderMask?: boolean +} +export interface CircleSmtPadProps extends Omit { + name?: string + shape: "circle" + radius: Distance + portHints?: PortHints + coveredWithSolderMask?: boolean +} +export interface PillSmtPadProps extends Omit { + name?: string + shape: "pill" + width: Distance + height: Distance + radius: Distance + portHints?: PortHints + coveredWithSolderMask?: boolean +} +export interface PolygonSmtPadProps + extends Omit { + name?: string + shape: "polygon" + points: Point[] + portHints?: PortHints + coveredWithSolderMask?: boolean +} +export const rectSmtPadProps = pcbLayoutProps + .omit({ pcbRotation: true }) + .extend({ + name: z.string().optional(), + shape: z.literal("rect"), + width: distance, + height: distance, + portHints: portHints.optional(), + coveredWithSolderMask: z.boolean().optional(), + }) +export const rotatedRectSmtPadProps = pcbLayoutProps + .omit({ pcbRotation: true }) + .extend({ + name: z.string().optional(), + shape: z.literal("rotated_rect"), + width: distance, + height: distance, + ccwRotation: z.number(), + portHints: portHints.optional(), + coveredWithSolderMask: z.boolean().optional(), + }) +export const circleSmtPadProps = pcbLayoutProps + .omit({ pcbRotation: true }) + .extend({ + name: z.string().optional(), + shape: z.literal("circle"), + radius: distance, + portHints: portHints.optional(), + coveredWithSolderMask: z.boolean().optional(), + }) +export const pillSmtPadProps = pcbLayoutProps + .omit({ pcbRotation: true }) + .extend({ + name: z.string().optional(), + shape: z.literal("pill"), + width: distance, + height: distance, + radius: distance, + portHints: portHints.optional(), + coveredWithSolderMask: z.boolean().optional(), + }) +export const polygonSmtPadProps = pcbLayoutProps + .omit({ pcbRotation: true }) + .extend({ + name: z.string().optional(), + shape: z.literal("polygon"), + points: z.array(point), + portHints: portHints.optional(), + coveredWithSolderMask: z.boolean().optional(), + }) +``` + +```typescript +export interface SolderJumperProps extends JumperProps { + bridgedPins?: string[][] + bridged?: boolean +} +/** + * If true, all pins are connected with cuttable traces + */ +export const solderjumperProps = jumperProps.extend({ + bridgedPins: z.array(z.array(z.string())).optional(), + bridged: z.boolean().optional(), +}) +``` + +```typescript +export interface RectSolderPasteProps + extends Omit { + shape: "rect" + width: Distance + height: Distance +} +export interface CircleSolderPasteProps + extends Omit { + shape: "circle" + radius: Distance +} +export const rectSolderPasteProps = pcbLayoutProps + .omit({ pcbRotation: true }) + .extend({ + shape: z.literal("rect"), + width: distance, + height: distance, + }) +export const circleSolderPasteProps = pcbLayoutProps + .omit({ pcbRotation: true }) + .extend({ + shape: z.literal("circle"), + radius: distance, + }) +``` + +```typescript +export interface StampboardProps extends BoardProps { + leftPinCount?: number + rightPinCount?: number + topPinCount?: number + bottomPinCount?: number + leftPins?: string[] + rightPins?: string[] + topPins?: string[] + bottomPins?: string[] + pinPitch?: number | string + innerHoles?: boolean +} +export const stampboardProps = boardProps.extend({ + leftPinCount: z.number().optional(), + rightPinCount: z.number().optional(), + topPinCount: z.number().optional(), + bottomPinCount: z.number().optional(), + leftPins: z.array(z.string()).optional(), + rightPins: z.array(z.string()).optional(), + topPins: z.array(z.string()).optional(), + bottomPins: z.array(z.string()).optional(), + pinPitch: distance.optional(), + innerHoles: z.boolean().optional(), +}) +``` + +```typescript +export interface SwitchProps extends CommonComponentProps { + type?: "spst" | "spdt" | "dpst" | "dpdt" + isNormallyClosed?: boolean + spdt?: boolean + spst?: boolean + dpst?: boolean + dpdt?: boolean +} +.extend({ + type: z.enum(["spst", "spdt", "dpst", "dpdt"]).optional(), + isNormallyClosed: z.boolean().optional().default(false), + spst: z.boolean().optional(), + spdt: z.boolean().optional(), + dpst: z.boolean().optional(), + dpdt: z.boolean().optional(), + }) +``` + +```typescript +export interface SymbolProps { + originalFacingDirection?: "up" | "down" | "left" | "right" +} +/** + * The facing direction that the symbol is designed for. If you set this to "right", + * then it means the children were intended to represent the symbol facing right. + * Generally, you shouldn't set this except where it can help prevent confusion + * because you have a complex symbol. Default is "right" and this is most intuitive. + */ +export const symbolProps = z.object({ + originalFacingDirection: z + .enum(["up", "down", "left", "right"]) + .default("right") + .optional(), +}) +``` + +```typescript +export interface TestpointProps extends CommonComponentProps { + footprintVariant?: "pad" | "through_hole" + padShape?: "rect" | "circle" + padDiameter?: number | string + holeDiameter?: number | string + width?: number | string + height?: number | string +} +.extend({ + footprintVariant: z.enum(["pad", "through_hole"]).optional(), + padShape: z.enum(["rect", "circle"]).optional().default("circle"), + padDiameter: distance.optional(), + holeDiameter: distance.optional(), + width: distance.optional(), + height: distance.optional(), + }) +``` + +```typescript +export const routeHintPointProps = z.object({ + x: distance, + y: distance, + via: z.boolean().optional(), + toLayer: layer_ref.optional(), +}) +export const traceHintProps = z.object({ + for: z + .string() + .optional() + .describe( + "Selector for the port you're targeting, not required if you're inside a trace", + ), + order: z.number().optional(), + offset: route_hint_point.or(routeHintPointProps).optional(), + offsets: z + .array(route_hint_point) + .or(z.array(routeHintPointProps)) + .optional(), + traceWidth: z.number().optional(), +}) +``` + +```typescript +export const portRef = z.union([ + z.string(), + z.custom<{ getPortSelector: () => string }>((v) => +baseTraceProps.extend({ + path: z.array(portRef), + }), +baseTraceProps.extend({ + from: portRef, + to: portRef, + }), +``` + +```typescript +export const transistorPinsLabels = [ + "pin1", + "pin2", + "pin3", + "emitter", + "collector", + "base", + "gate", + "source", + "drain", +] as const +export interface TransistorProps + extends CommonComponentProps { + type: "npn" | "pnp" | "bjt" | "jfet" | "mosfet" | "igbt" + connections?: Connections +} +export const transistorProps = commonComponentProps.extend({ + type: z.enum(["npn", "pnp", "bjt", "jfet", "mosfet", "igbt"]), + connections: createConnectionsProp(transistorPinsLabels).optional(), +}) +export const transistorPins = [ + "pin1", + "emitter", + "pin2", + "collector", + "pin3", + "base", +] as const +``` + +```typescript +export interface ViaProps extends CommonLayoutProps { + name?: string + fromLayer: LayerRefInput + toLayer: LayerRefInput + holeDiameter: number | string + outerDiameter: number | string + connectsTo?: string | string[] +} +export const viaProps = commonLayoutProps.extend({ + name: z.string().optional(), + fromLayer: layer_ref, + toLayer: layer_ref, + holeDiameter: distance, + outerDiameter: distance, + connectsTo: z.string().or(z.array(z.string())).optional(), +}) +``` + +```typescript +export interface VoltageSourceProps + extends CommonComponentProps { + voltage?: number | string + frequency?: number | string + peakToPeakVoltage?: number | string + waveShape?: WaveShape + phase?: number | string + dutyCycle?: number | string + connections?: Connections +} +export const voltageSourceProps = commonComponentProps.extend({ + voltage: voltage.optional(), + frequency: frequency.optional(), + peakToPeakVoltage: voltage.optional(), + waveShape: z.enum(["sinewave", "square", "triangle", "sawtooth"]).optional(), + phase: rotation.optional(), + dutyCycle: percentage.optional(), + connections: createConnectionsProp(voltageSourcePinLabels).optional(), +}) +``` + + + +- Here is a list of unsupported components: + +1- powersource +2- powersourcesimple +3- pinheader + +- Here are examples of how you can take advantage of those props: + + // Example of a custom chip footprint definition + const CustomChipFootprint = () => ( + + // SMT pads for the chip + + + + + + // Silkscreen markings for the chip outline + + // Pin 1 indicator + + + ) + + // Example of a custom resistor footprint + const Resistor0603Footprint = () => ( + + + + + + ) + + // Example of a complete circuit + export const MyCircuit = () => ( + + // Power section group + + // Decoupling capacitor arrangement + + + + + + // Input protection group + + + + + + + // Power nets + + + + // Connections + + + + // Layout constraints + + + ) + + // Example of a custom module/component that can be reused + export const DecouplingCapacitor = ({ + chipRef, + capName, + capValue = "100nF", + distance = "2mm" + }) => ( + + + + + ) + + // Usage of the custom module + export const CircuitWithDecoupling = () => ( + + + + + ) + + +### RULES + +- decouplingFor must contain the selector for the component and the pin(eg. ".U1 .pin1", ".T1 .pin1") +- Never pass the component name alone as a selector for decouplingFor, always use the component name reference and the pin number +- Don't use hole or port components, always connect to the component pins +- Don't use inline comments which are comments in the same line as components, they are forbidden +- Port components must be children to a chip component. +- Never use components in the "Unsupported components" list +- Never use footprints in the "Unsupported footprints" list +- Any component may have a pcbX and/or a pcbY representing the center of the + component on a circuit board. +- Never use footprints that are not supported in the "All available footprints" section +- Some footprints have a fixed number of pins like ms012 and sot723 +- `` components use CSS selectors in the `from` and `to` fields + to connect components. +- Any component can have a `name` prop +- `pcbX` and `pcbY` are optional and default to 0. +- A board is centered on the origin (pcbX=0, pcbY=0), so to place a component + at the center it must be placed at pcbX=0,pcbY=0. Similarly, if you're trying + to layout components around the center, you would make ones to the left of + the center have negative pcbX values, below the center have negative pcbY, + and to the right of the center have positive pcbX values, and above the + center have positive pcbY values. +- Every component that is going to be placed must be given a footprint +- Traces can only take two ports +- Don't use path as prop for trace, only use from, to +- We don't support defining output ports, so don't defined port components +- Don't specify autorouter; don't use the autorouter prop +- Selectors for component pins must be of this format: ".U1 > .pin1" or ".U1 > .pin2" where U1 is the component name, and the pins must be numbers, so don't use names for pins but use pin1, pin2, pin3, pin4 +- And instead of ".T1 > .base" you do do ".T1 > .pin2" +- "for" must have at least two selectors for constraints + +### Trace Reference Syntax + +Traces are created using the `` component. The `from` and `to` +fields are CSS selectors that reference the components to connect. + +Examples: + + + + + +### Output + +Use a codefence with the language "tsx" to wrap the code. You can use the +current_code of the user as a starting point (if provided). + +You must export a higher-order component where the root component is `` +inside the codefence. For example: + +```tsx +export const MyLed = () => ( + + + + + +) +``` \ No newline at end of file diff --git a/benchmarks/prompt-logs/prompt-2025-09-28T16-28-18-742Z.txt b/benchmarks/prompt-logs/prompt-2025-09-28T16-28-18-742Z.txt new file mode 100644 index 0000000..04e706a --- /dev/null +++ b/benchmarks/prompt-logs/prompt-2025-09-28T16-28-18-742Z.txt @@ -0,0 +1,2683 @@ +You are an expert in electronic circuit design and tscircuit, and your job is to create a circuit board in tscircuit with the user-provided description. + +YOU MUST ABIDE BY THE RULES IN THE RULES SECTION + +## tscircuit API overview + +Here's an overview of the tscircuit API: + + // usually the root component + // custom shape instead of rectangle + + + + + + + + + + + + + +### footprint strings + +Footprint strings are a compact way to represent the physical footprint for a +component. Any component can be given a footprint string. Here are example +footprint strings: + +0402 +0603 +0805 +1206 +1210 +cap0402 +res0402 +soic8_p1.27mm +dip16 +pinrow10 +tssop20_p0.5mm +sot23 + +### All available footprints + +- Either use a passive footprint like this (e.g. 0402, 0603, 0805, 1206, 1210), here is a json string with all available footprint passive sizes: + +["01005","0201","0402","0603","0805","1206","1210","2010","2512"] + +- Or create a footprint string like this (e.g. dfn8_w5.3mm_p1.27mm, dip10_w4.00mm_p2.65mm, lqfp64_w10_h10_pl1_pw0.25mm, sot363, stampreceiver_left20_right20_bottom3_top2_w21mm_p2.54mm, tssop20_w6.5mm_p0.65mm, bga7_w8_h8_grid3x3_p1_missing(center,B1), bga64_w10_h10_grid8x8_p1.27mm), here are json objects with the available footprints and their options: + +{"fn":"axial","p":2.54,"id":0.7,"od":1} +{"fn":"bga","num_pins":64,"p":0.8,"missing":[],"grid":{"x":8,"y":8},"origin":"tl"} +{"fn":"breakoutheaders","w":10,"left":20,"right":20,"top":0,"bottom":0,"p":2.54,"id":1,"od":1.5} +{"fn":"dfn","num_pins":8,"w":5.3,"p":1.27,"legsoutside":false,"pw":0.6,"pl":1} +{"fn":"dip","num_pins":6,"p":2.54,"id":1,"od":1.5,"w":7.62} +{"fn":"lqfp","num_pins":64,"p":0.5,"legsoutside":true,"w":10,"h":10,"pw":0.25,"pl":0.25} +{"fn":"mlp","num_pins":64,"p":0.5,"thermalpad":true,"legsoutside":false,"w":10,"h":10,"pw":0.25,"pl":0.25} +{"fn":"ms012","num_pins":8,"w":3.9,"p":1.27,"legsoutside":true,"pw":0.6,"pl":1} +{"fn":"ms013","num_pins":16,"w":7.5,"p":1.27,"legsoutside":true,"pw":0.6,"pl":1} +{"fn":"pinrow","num_pins":6,"p":2.54,"id":1,"od":1.5} +{"fn":"pushbutton","w":4.5,"h":6.5,"id":1,"od":1.2} +{"fn":"qfn","num_pins":64,"p":0.5,"legsoutside":false,"w":10,"h":10,"pw":0.25,"pl":0.25} +{"fn":"qfp","num_pins":64,"p":0.5,"pw":0.25,"pl":1,"legsoutside":true,"w":10,"h":10} +{"fn":"quad","num_pins":64,"p":0.5,"legsoutside":false,"w":10,"h":10,"pw":0.25,"pl":0.25} +{"fn":"sod123","num_pins":2,"w":"2.36mm","h":"1.22mm","pl":"0.9mm","pw":"0.9mm","pad_spacing":"4.19mm"} +{"fn":"soic","num_pins":8,"w":5.3,"p":1.27,"legsoutside":false,"pw":0.6,"pl":1} +{"fn":"sot23","num_pins":3,"w":"1.92mm","h":"2.74mm","pl":"0.8mm","pw":"0.764mm"} +{"fn":"sot235","num_pins":5,"h":"1.6mm","pl":"1mm","pw":"0.7mm","p":"0.95mm"} +{"fn":"sot236","num_pins":6,"w":1.6,"p":0.95,"legsoutside":true,"pw":0.6,"pl":1} +{"fn":"sot363","num_pins":6,"w":1.94,"p":0.65,"pw":0.3,"pl":0.7,"legsoutside":false} +{"fn":"sot563","num_pins":6,"w":1.94,"p":0.5,"pw":0.3,"pl":0.67,"legsoutside":false} +{"fn":"sot723","num_pins":3,"w":"1.2mm","h":"1.2mm","pl":"0.3mm","pw":"0.32mm"} +{"fn":"ssop","num_pins":8,"w":3.9,"p":1.27,"legsoutside":false,"pw":0.6,"pl":1} +{"fn":"stampboard","w":22.58,"left":20,"right":20,"top":2,"bottom":2,"p":2.54,"pw":1.6,"pl":2.4,"innerhole":false,"innerholeedgedistance":1.61} +{"fn":"stampreceiver","w":22.58,"left":20,"right":20,"top":2,"bottom":2,"p":2.54,"pw":1.6,"pl":3.2,"innerhole":false,"innerholeedgedistance":1.61} +{"fn":"tssop","num_pins":8,"w":6.1,"p":0.65,"legsoutside":true,"pw":0.6,"pl":1} + + +- Here is a list of unsupported footprints: + +1- hc + +keep in mind that num_pins can be replaced with a number directly infront of the footprint name like so: dip8_p1.27mm which means num_pins=8, don't do that for footprints with fixed number of pins like ms012 and sot723 + +### Components and Props + +- Here is a documentation of all available components and their types: + + + +```typescript +export const rotationPoint3 = z.object({ + x: z.union([z.number(), z.string()]), + y: z.union([z.number(), z.string()]), + z: z.union([z.number(), z.string()]), +}) +export interface CadModelBase { + rotationOffset?: + | number + | { x: number | string; y: number | string; z: number | string } + positionOffset?: { + x: number | string + y: number | string + z: number | string + } + size?: { x: number | string; y: number | string; z: number | string } + modelUnitToMmScale?: Distance +} +export const cadModelBase = z.object({ + rotationOffset: z.number().or(rotationPoint3).optional(), + positionOffset: point3.optional(), + size: point3.optional(), + modelUnitToMmScale: distance.optional(), +}) +export interface CadModelStl extends CadModelBase { + stlUrl: string +} +export const cadModelStl = cadModelBase.extend({ + stlUrl: z.string(), +}) +export interface CadModelObj extends CadModelBase { + objUrl: string + mtlUrl?: string +} +export const cadModelObj = cadModelBase.extend({ + objUrl: z.string(), + mtlUrl: z.string().optional(), +}) +export interface CadModelGltf extends CadModelBase { + gltfUrl: string +} +export const cadModelGltf = cadModelBase.extend({ + gltfUrl: z.string(), +}) +export interface CadModelGlb extends CadModelBase { + glbUrl: string +} +export const cadModelGlb = cadModelBase.extend({ + glbUrl: z.string(), +}) +export interface CadModelStep extends CadModelBase { + stepUrl: string +} +export const cadModelStep = cadModelBase.extend({ + stepUrl: z.string(), +}) +export interface CadModelWrl extends CadModelBase { + wrlUrl: string +} +export const cadModelWrl = cadModelBase.extend({ + wrlUrl: z.string(), +}) +export interface CadModelJscad extends CadModelBase { + jscad: Record +} +export const cadModelJscad = cadModelBase.extend({ + jscad: z.record(z.any()), +}) +export const cadModelProp = z.union([ + z.null(), + z.string(), + z.custom((v) => { + return v && typeof v === "object" && "type" in v && "props" in v + }), +``` + +```typescript +export const createConnectionsProp = ( + labels: T, +) => { + return z.record(z.enum(labels), connectionTarget) +} +``` + +```typescript +export type Distance = number | string + +export { distance, length } from "circuit-json" +``` + +```typescript +/** + * This is an abbreviated definition of the soup elements that you can find here: + * https://docs.tscircuit.com/api-reference/advanced/soup#pcb-smtpad + */ +export type FootprintSoupElements = { + type: "pcb_smtpad" | "pcb_plated_hole" + x: string | number + y: string | number + layer?: LayerRef + holeDiameter?: string | number + outerDiameter?: string | number + shape?: "circle" | "rect" + width?: string | number + height?: string | number + portHints?: string[] +} +``` + +```typescript +export interface PcbLayoutProps { + pcbX?: string | number + pcbY?: string | number + pcbRotation?: string | number + pcbPositionAnchor?: string + layer?: LayerRefInput + pcbMarginTop?: string | number + pcbMarginRight?: string | number + pcbMarginBottom?: string | number + pcbMarginLeft?: string | number + pcbMarginX?: string | number + pcbMarginY?: string | number + pcbRelative?: boolean + relative?: boolean +} +/** + * If true, both pcb and schematic coordinates will be interpreted relative to the parent group + */ +export interface CommonLayoutProps { + pcbX?: string | number + pcbY?: string | number + pcbRotation?: string | number + pcbPositionAnchor?: string + + pcbMarginTop?: string | number + pcbMarginRight?: string | number + pcbMarginBottom?: string | number + pcbMarginLeft?: string | number + pcbMarginX?: string | number + pcbMarginY?: string | number + + schMarginTop?: string | number + schMarginRight?: string | number + schMarginBottom?: string | number + schMarginLeft?: string | number + schMarginX?: string | number + schMarginY?: string | number + + schX?: string | number + schY?: string | number + schRotation?: string | number + + layer?: LayerRefInput + footprint?: FootprintProp + symbol?: SymbolProp + + relative?: boolean + + schRelative?: boolean + + pcbRelative?: boolean +} +/** + * If true, pcbX/pcbY will be interpreted relative to the parent group + */ +export const pcbLayoutProps = z.object({ + pcbX: distance.optional(), + pcbY: distance.optional(), + pcbRotation: rotation.optional(), + pcbPositionAnchor: z.string().optional(), + layer: layer_ref.optional(), + pcbMarginTop: distance.optional(), + pcbMarginRight: distance.optional(), + pcbMarginBottom: distance.optional(), + pcbMarginLeft: distance.optional(), + pcbMarginX: distance.optional(), + pcbMarginY: distance.optional(), + pcbRelative: z.boolean().optional(), + relative: z.boolean().optional(), +}) +export const commonLayoutProps = z.object({ + pcbX: distance.optional(), + pcbY: distance.optional(), + pcbRotation: rotation.optional(), + pcbPositionAnchor: z.string().optional(), + pcbMarginTop: distance.optional(), + pcbMarginRight: distance.optional(), + pcbMarginBottom: distance.optional(), + pcbMarginLeft: distance.optional(), + pcbMarginX: distance.optional(), + pcbMarginY: distance.optional(), + schMarginTop: distance.optional(), + schMarginRight: distance.optional(), + schMarginBottom: distance.optional(), + schMarginLeft: distance.optional(), + schMarginX: distance.optional(), + schMarginY: distance.optional(), + schX: distance.optional(), + schY: distance.optional(), + schRotation: rotation.optional(), + layer: layer_ref.optional(), + footprint: footprintProp.optional(), + symbol: symbolProp.optional(), + relative: z.boolean().optional(), + schRelative: z.boolean().optional(), + pcbRelative: z.boolean().optional(), +}) +export interface SupplierProps { + supplierPartNumbers?: SupplierPartNumbers +} +export const supplierProps = z.object({ + supplierPartNumbers: z.record(supplier_name, z.array(z.string())).optional(), +}) +export interface PinAttributeMap { + providesPower?: boolean + requiresPower?: boolean + providesGround?: boolean + requiresGround?: boolean + providesVoltage?: string | number + requiresVoltage?: string | number + doNotConnect?: boolean + includeInBoardPinout?: boolean +} +export const pinAttributeMap = z.object({ + providesPower: z.boolean().optional(), + requiresPower: z.boolean().optional(), + providesGround: z.boolean().optional(), + requiresGround: z.boolean().optional(), + providesVoltage: z.union([z.string(), z.number()]).optional(), + requiresVoltage: z.union([z.string(), z.number()]).optional(), + doNotConnect: z.boolean().optional(), + includeInBoardPinout: z.boolean().optional(), +}) +export interface CommonComponentProps + extends CommonLayoutProps { + key?: any + name: string + pinAttributes?: Record + supplierPartNumbers?: SupplierPartNumbers + cadModel?: CadModelProp + children?: any + symbolName?: string + doNotPlace?: boolean +} +.extend({ + key: z.any().optional(), + name: z.string(), + cadModel: cadModelProp.optional(), + children: z.any().optional(), + symbolName: z.string().optional(), + doNotPlace: z.boolean().optional(), + pinAttributes: z.record(z.string(), pinAttributeMap).optional(), + }) +export const lrPolarPins = [ + "pin1", + "left", + "anode", + "pos", + "pin2", + "right", + "cathode", + "neg", +] as const +``` + +```typescript +export const point = z.object({ + x: distance, + y: distance, +}) +``` + +```typescript +export const point3 = z.object({ + x: distance, + y: distance, + z: distance, +}) +``` + +```typescript +/** + * @deprecated Use SchematicPortArrangementWithPinCounts instead. + */ +export interface SchematicPortArrangementWithSizes { + leftSize?: number + topSize?: number + rightSize?: number + bottomSize?: number +} +/** + * Specifies the number of pins on each side of the schematic box component. + */ +export interface SchematicPortArrangementWithPinCounts { + leftPinCount?: number + topPinCount?: number + rightPinCount?: number + bottomPinCount?: number +} +export interface PinSideDefinition { + pins: Array + direction: + | "top-to-bottom" + | "left-to-right" + | "bottom-to-top" + | "right-to-left" +} +export interface SchematicPortArrangementWithSides { + leftSide?: PinSideDefinition + topSide?: PinSideDefinition + rightSide?: PinSideDefinition + bottomSide?: PinSideDefinition +} +export interface SchematicPortArrangement + extends SchematicPortArrangementWithSizes, + SchematicPortArrangementWithSides, + SchematicPortArrangementWithPinCounts {} +export const explicitPinSideDefinition = z.object({ + pins: z.array(z.union([z.number(), z.string()])), + direction: z.union([ + z.literal("top-to-bottom"), + z.literal("left-to-right"), + z.literal("bottom-to-top"), + z.literal("right-to-left"), + ]), +}) +/** + * @deprecated Use schematicPinArrangement instead. + */ +export const schematicPortArrangement = z.object({ + leftSize: z.number().optional().describe("@deprecated, use leftPinCount"), + topSize: z.number().optional().describe("@deprecated, use topPinCount"), + rightSize: z.number().optional().describe("@deprecated, use rightPinCount"), + bottomSize: z.number().optional().describe("@deprecated, use bottomPinCount"), + leftPinCount: z.number().optional(), + rightPinCount: z.number().optional(), + topPinCount: z.number().optional(), + bottomPinCount: z.number().optional(), + leftSide: explicitPinSideDefinition.optional(), + rightSide: explicitPinSideDefinition.optional(), + topSide: explicitPinSideDefinition.optional(), + bottomSide: explicitPinSideDefinition.optional(), +}) +``` + +```typescript +export type SchematicPinStyle = Record< + string, + { + marginTop?: number | string + marginRight?: number | string + marginBottom?: number | string + marginLeft?: number | string + + leftMargin?: number | string + rightMargin?: number | string + topMargin?: number | string + bottomMargin?: number | string + } +/** @deprecated use marginBottom */ +export const schematicPinStyle = z.record( + z.object({ + marginLeft: distance.optional(), + marginRight: distance.optional(), + marginTop: distance.optional(), + marginBottom: distance.optional(), + + leftMargin: distance.optional(), + rightMargin: distance.optional(), + topMargin: distance.optional(), + bottomMargin: distance.optional(), + }), +``` + +```typescript +/** @deprecated use battery_capacity from circuit-json when circuit-json is updated */ +export interface BatteryProps + extends CommonComponentProps { + capacity?: number | string + voltage?: number | string + standard?: "AA" | "AAA" | "9V" | "CR2032" | "18650" | "C" + schOrientation?: SchematicOrientation +} +export const batteryProps = commonComponentProps.extend({ + capacity: capacity.optional(), + voltage: voltage.optional(), + standard: z.enum(["AA", "AAA", "9V", "CR2032", "18650", "C"]).optional(), + schOrientation: schematicOrientation.optional(), +}) +``` + +```typescript +export interface BoardProps extends Omit { + material?: "fr4" | "fr1" + layers?: 2 | 4 + borderRadius?: Distance + boardAnchorPosition?: Point + boardAnchorAlignment?: z.infer +} +/** Number of layers for the PCB */ +export const boardProps = subcircuitGroupProps.extend({ + material: z.enum(["fr4", "fr1"]).default("fr4"), + layers: z.union([z.literal(2), z.literal(4)]).default(2), + borderRadius: distance.optional(), + boardAnchorPosition: point.optional(), + boardAnchorAlignment: ninePointAnchor.optional(), +}) +``` + +```typescript +export interface BreakoutProps + extends Omit { + padding?: Distance + paddingLeft?: Distance + paddingRight?: Distance + paddingTop?: Distance + paddingBottom?: Distance +} +export const breakoutProps = subcircuitGroupProps.extend({ + padding: distance.optional(), + paddingLeft: distance.optional(), + paddingRight: distance.optional(), + paddingTop: distance.optional(), + paddingBottom: distance.optional(), +}) +``` + +```typescript +export interface BreakoutPointProps + extends Omit { + connection: string +} +export const breakoutPointProps = pcbLayoutProps + .omit({ pcbRotation: true, layer: true }) + .extend({ + connection: z.string(), + }) +``` + +```typescript +export interface CadAssemblyProps { + originalLayer?: LayerRef + + children?: any +} +/** + * The layer that the CAD assembly is designed for. If you set this to "top" + * then it means the children were intended to represent the top layer. If + * the with this assembly is moved to the bottom layer, then the + * components will be mirrored. + * + * Generally, you shouldn't set this except where it can help prevent + * confusion because you have a complex multi-layer assembly. Default is + * "top" and this is most intuitive. + */ +export const cadassemblyProps = z.object({ + originalLayer: layer_ref.default("top").optional(), + children: z.any().optional(), +}) +``` + +```typescript +export interface CadModelProps extends CadModelBase { + modelUrl: string + pcbX?: Distance + pcbY?: Distance + pcbZ?: Distance +} +const cadModelBaseWithUrl = cadModelBase.extend({ + modelUrl: z.string(), +}) +``` + +```typescript +export const capacitorPinLabels = [ + "pin1", + "pin2", + "pos", + "neg", + "anode", + "cathode", +] as const +export interface CapacitorProps + extends CommonComponentProps { + capacitance: number | string + maxVoltageRating?: number | string + schShowRatings?: boolean + polarized?: boolean + decouplingFor?: string + decouplingTo?: string + bypassFor?: string + bypassTo?: string + maxDecouplingTraceLength?: number + schOrientation?: SchematicOrientation + connections?: Connections +} +export const capacitorProps = commonComponentProps.extend({ + capacitance, + maxVoltageRating: voltage.optional(), + schShowRatings: z.boolean().optional().default(false), + polarized: z.boolean().optional().default(false), + decouplingFor: z.string().optional(), + decouplingTo: z.string().optional(), + bypassFor: z.string().optional(), + bypassTo: z.string().optional(), + maxDecouplingTraceLength: z.number().optional(), + schOrientation: schematicOrientation.optional(), + connections: createConnectionsProp(capacitorPinLabels).optional(), +}) +``` + +```typescript +export interface PinCompatibleVariant { + manufacturerPartNumber?: string + supplierPartNumber?: SupplierPartNumbers +} +export interface ChipPropsSU< + PinLabel extends SchematicPinLabel = SchematicPinLabel, +> extends CommonComponentProps { + manufacturerPartNumber?: string + pinLabels?: PinLabelsProp + showPinAliases?: boolean + pcbPinLabels?: Record + schPinArrangement?: SchematicPortArrangement + schPortArrangement?: SchematicPortArrangement + pinCompatibleVariants?: PinCompatibleVariant[] + schPinStyle?: SchematicPinStyle + schPinSpacing?: Distance + schWidth?: Distance + schHeight?: Distance + noSchematicRepresentation?: boolean + internallyConnectedPins?: (string | number)[][] + externallyConnectedPins?: string[][] + connections?: Connections +} +/** + * Get the connection prop type for a component + * + * const pinLabels = { pin1: "VCC", pin2: "GND", pin3: "DATA" } as const + * export const MyChip = (props: ChipProps) => { + * // ... + * } + * const connections: ChipConnections = { + * VCC: "...", + * GND: "...", + * DATA: "...", + * } + * + */ +export type ChipConnections) => any> = { + [K in ChipPinLabels]: string +} +export const pinCompatibleVariant = z.object({ + manufacturerPartNumber: z.string().optional(), + supplierPartNumber: z.record(supplier_name, z.array(z.string())).optional(), +}) +export const chipProps = commonComponentProps.extend({ + manufacturerPartNumber: z.string().optional(), + pinLabels: pinLabelsProp.optional(), + showPinAliases: z.boolean().optional(), + pcbPinLabels: z.record(z.string(), z.string()).optional(), + internallyConnectedPins: z + .array(z.array(z.union([z.string(), z.number()]))) + .optional(), + externallyConnectedPins: z.array(z.array(z.string())).optional(), + schPinArrangement: schematicPinArrangement.optional(), + schPortArrangement: schematicPinArrangement.optional(), + pinCompatibleVariants: z.array(pinCompatibleVariant).optional(), + schPinStyle: schematicPinStyle.optional(), + schPinSpacing: distance.optional(), + schWidth: distance.optional(), + schHeight: distance.optional(), + noSchematicRepresentation: z.boolean().optional(), + connections: connectionsProp.optional(), +}) +``` + +```typescript +export interface ConnectorProps extends CommonComponentProps { + manufacturerPartNumber?: string + pinLabels?: Record< + number | SchematicPinLabel, + SchematicPinLabel | SchematicPinLabel[] + > + schPinStyle?: SchematicPinStyle + schPinSpacing?: number | string + schWidth?: number | string + schHeight?: number | string + schDirection?: "left" | "right" + schPortArrangement?: SchematicPortArrangement + internallyConnectedPins?: (string | number)[][] + standard?: "usb_c" | "m2" +} +/** + * Connector standard, e.g. usb_c, m2 + */ +export const connectorProps = commonComponentProps.extend({ + manufacturerPartNumber: z.string().optional(), + pinLabels: z + .record( + z.number().or(schematicPinLabel), + schematicPinLabel.or(z.array(schematicPinLabel)), + ) + .optional(), + schPinStyle: schematicPinStyle.optional(), + schPinSpacing: distance.optional(), + schWidth: distance.optional(), + schHeight: distance.optional(), + schDirection: z.enum(["left", "right"]).optional(), + schPortArrangement: schematicPortArrangement.optional(), + internallyConnectedPins: z + .array(z.array(z.union([z.string(), z.number()]))) + .optional(), + standard: z.enum(["usb_c", "m2"]).optional(), +}) +``` + +```typescript +export interface ConstrainedLayoutProps { + name?: string + pcbOnly?: boolean + schOnly?: boolean +} +export const constrainedLayoutProps = z.object({ + name: z.string().optional(), + pcbOnly: z.boolean().optional(), + schOnly: z.boolean().optional(), +}) +``` + +```typescript +export type PcbXDistConstraint = { + pcb?: true + xDist: Distance + + left: string + + right: string + + edgeToEdge?: true + + centerToCenter?: true +} +/** + * If true, the provided distance is the distance between the centers of the + * left and right components + */ +export type PcbYDistConstraint = { + pcb?: true + yDist: Distance + + top: string + + bottom: string + + edgeToEdge?: true + centerToCenter?: true +} +/** + * Selector for bottom component, e.g. ".U1" or ".R1", you can also specify the + * edge or center of the component e.g. ".R1 bottomedge", ".R1 center" + */ +export type PcbSameYConstraint = { + pcb?: true + sameY?: true + + for: string[] +} +/** + * Selector for components, e.g. [".U1", ".R1"], you can also specify the + * edge or center of the component e.g. [".R1 leftedge", ".U1 center"] + */ +export type PcbSameXConstraint = { + pcb?: true + sameX?: true + for: string[] +} +export const pcbXDistConstraintProps = z.object({ + pcb: z.literal(true).optional(), + xDist: distance, + left: z.string(), + right: z.string(), + + edgeToEdge: z.literal(true).optional(), + centerToCenter: z.literal(true).optional(), +}) +export const pcbYDistConstraintProps = z.object({ + pcb: z.literal(true).optional(), + yDist: distance, + top: z.string(), + bottom: z.string(), + + edgeToEdge: z.literal(true).optional(), + centerToCenter: z.literal(true).optional(), +}) +export const pcbSameYConstraintProps = z.object({ + pcb: z.literal(true).optional(), + sameY: z.literal(true).optional(), + for: z.array(z.string()), +}) +export const pcbSameXConstraintProps = z.object({ + pcb: z.literal(true).optional(), + sameX: z.literal(true).optional(), + for: z.array(z.string()), +}) +``` + +```typescript +export interface CopperPourProps { + name?: string + layer: LayerRefInput + connectsTo: string + padMargin?: Distance + traceMargin?: Distance +} +export const copperPourProps = z.object({ + name: z.string().optional(), + layer: layer_ref, + connectsTo: z.string(), + padMargin: distance.optional(), + traceMargin: distance.optional(), +}) +``` + +```typescript +export interface CrystalProps + extends CommonComponentProps { + frequency: number | string + loadCapacitance: number | string + manufacturerPartNumber?: string + mpn?: string + pinVariant?: PinVariant + schOrientation?: SchematicOrientation + connections?: Connections +} +export const crystalProps = commonComponentProps.extend({ + frequency: frequency, + loadCapacitance: capacitance, + manufacturerPartNumber: z.string().optional(), + mpn: z.string().optional(), + pinVariant: z.enum(["two_pin", "four_pin"]).optional(), + schOrientation: schematicOrientation.optional(), + connections: createConnectionsProp(crystalPins).optional(), +}) +``` + +```typescript +export interface RectCutoutProps + extends Omit { + name?: string + shape: "rect" + width: Distance + height: Distance +} +export const rectCutoutProps = pcbLayoutProps + .omit({ + layer: true, + pcbRotation: true, + }) + .extend({ + name: z.string().optional(), + shape: z.literal("rect"), + width: distance, + height: distance, + }) +export interface CircleCutoutProps + extends Omit { + name?: string + shape: "circle" + radius: Distance +} +export const circleCutoutProps = pcbLayoutProps + .omit({ + layer: true, + pcbRotation: true, + }) + .extend({ + name: z.string().optional(), + shape: z.literal("circle"), + radius: distance, + }) +export interface PolygonCutoutProps + extends Omit { + name?: string + shape: "polygon" + points: Point[] +} +export const polygonCutoutProps = pcbLayoutProps + .omit({ + layer: true, + pcbRotation: true, + }) + .extend({ + name: z.string().optional(), + shape: z.literal("polygon"), + points: z.array(point), + }) +``` + +```typescript +.extend({ + connections: connectionsProp.optional(), + variant: diodeVariant.optional().default("standard"), + standard: z.boolean().optional(), + schottky: z.boolean().optional(), + zener: z.boolean().optional(), + avalanche: z.boolean().optional(), + photo: z.boolean().optional(), + tvs: z.boolean().optional(), + schOrientation: schematicOrientation.optional(), + }) +export interface DiodeProps + extends CommonComponentProps { + connections?: { + anode?: string | string[] | readonly string[] + cathode?: string | string[] | readonly string[] + pin1?: string | string[] | readonly string[] + pin2?: string | string[] | readonly string[] + pos?: string | string[] | readonly string[] + neg?: string | string[] | readonly string[] + } + variant?: "standard" | "schottky" | "zener" | "avalanche" | "photo" | "tvs" + standard?: boolean + schottky?: boolean + zener?: boolean + avalanche?: boolean + photo?: boolean + tvs?: boolean + schOrientation?: SchematicOrientation +} +``` + +```typescript +export const fabricationNotePathProps = pcbLayoutProps + .omit({ pcbX: true, pcbY: true, pcbRotation: true }) + .extend({ + route: z.array(route_hint_point), + strokeWidth: length.optional(), + color: z.string().optional(), + }) +``` + +```typescript +export const fabricationNoteTextProps = pcbLayoutProps.extend({ + text: z.string(), + anchorAlignment: z + .enum(["center", "top_left", "top_right", "bottom_left", "bottom_right"]) + .default("center"), + font: z.enum(["tscircuit2024"]).optional(), + fontSize: length.optional(), + color: z.string().optional(), +}) +``` + +```typescript +export interface FootprintProps { + originalLayer?: LayerRef +} +/** + * The layer that the footprint is designed for. If you set this to "top" + * then it means the children were intended to represent the top layer. If + * the with this footprint is moved to the bottom layer, then the + * components will be mirrored. + * + * Generally, you shouldn't set this except where it can help prevent + * confusion because you have a complex multi-layer footprint. Default is + * "top" and this is most intuitive. + */ +export const footprintProps = z.object({ + originalLayer: layer_ref.default("top").optional(), +}) +``` + +```typescript +export interface FuseProps + extends CommonComponentProps { + currentRating: number | string + + voltageRating?: number | string + + schShowRatings?: boolean + + schOrientation?: SchematicOrientation + + connections?: Connections +} +/** + * Schema for validating fuse props + */ +export const fuseProps = commonComponentProps.extend({ + currentRating: z.union([z.number(), z.string()]), + voltageRating: z.union([z.number(), z.string()]).optional(), + schShowRatings: z.boolean().optional(), + schOrientation: schematicOrientation.optional(), + connections: z + .record( + z.string(), + z.union([ + z.string(), + z.array(z.string()).readonly(), + z.array(z.string()), + ]), + ) + .optional(), +}) +``` + +```typescript +export const layoutConfig = z.object({ + layoutMode: z + .enum(["grid", "flex", "match-adapt", "relative", "none"]) + .optional(), + position: z.enum(["absolute", "relative"]).optional(), + + grid: z.boolean().optional(), + gridCols: z.number().or(z.string()).optional(), + gridRows: z.number().or(z.string()).optional(), + gridTemplateRows: z.string().optional(), + gridTemplateColumns: z.string().optional(), + gridTemplate: z.string().optional(), + gridGap: z.number().or(z.string()).optional(), + gridRowGap: z.number().or(z.string()).optional(), + gridColumnGap: z.number().or(z.string()).optional(), + + flex: z.boolean().or(z.string()).optional(), + flexDirection: z.enum(["row", "column"]).optional(), + alignItems: z.enum(["start", "center", "end", "stretch"]).optional(), + justifyContent: z + .enum([ + "start", + "center", + "end", + "stretch", + "space-between", + "space-around", + "space-evenly", + ]) + .optional(), + flexRow: z.boolean().optional(), + flexColumn: z.boolean().optional(), + gap: z.number().or(z.string()).optional(), + + pack: z + .boolean() + .optional() + .describe("Pack the contents of this group using a packing strategy"), + packOrderStrategy: z + .enum([ + "largest_to_smallest", + "first_to_last", + "highest_to_lowest_pin_count", + ]) + .optional(), + packPlacementStrategy: z + .enum(["shortest_connection_along_outline"]) + .optional(), + + padding: length.optional(), + paddingLeft: length.optional(), + paddingRight: length.optional(), + paddingTop: length.optional(), + paddingBottom: length.optional(), + paddingX: length.optional(), + paddingY: length.optional(), + + width: length.optional(), + height: length.optional(), + + matchAdapt: z.boolean().optional(), + matchAdaptTemplate: z.any().optional(), +}) +export interface LayoutConfig { + layoutMode?: "grid" | "flex" | "match-adapt" | "relative" | "none" + position?: "absolute" | "relative" + + grid?: boolean + gridCols?: number | string + gridRows?: number | string + gridTemplateRows?: string + gridTemplateColumns?: string + gridTemplate?: string + gridGap?: number | string + gridRowGap?: number | string + gridColumnGap?: number | string + + flex?: boolean | string + flexDirection?: "row" | "column" + alignItems?: "start" | "center" | "end" | "stretch" + justifyContent?: + | "start" + | "center" + | "end" + | "stretch" + | "space-between" + | "space-around" + | "space-evenly" + flexRow?: boolean + flexColumn?: boolean + gap?: number | string + + pack?: boolean + packOrderStrategy?: + | "largest_to_smallest" + | "first_to_last" + | "highest_to_lowest_pin_count" + packPlacementStrategy?: "shortest_connection_along_outline" + + padding?: Distance + paddingLeft?: Distance + paddingRight?: Distance + paddingTop?: Distance + paddingBottom?: Distance + paddingX?: Distance + paddingY?: Distance + + width?: Distance + height?: Distance + + matchAdapt?: boolean + matchAdaptTemplate?: any +} +export interface Border { + strokeWidth?: Distance + dashed?: boolean + solid?: boolean +} +export const border = z.object({ + strokeWidth: length.optional(), + dashed: z.boolean().optional(), + solid: z.boolean().optional(), +}) +export interface BaseGroupProps extends CommonLayoutProps, LayoutConfig { + name?: string + key?: any + children?: any + + schTitle?: string + + showAsSchematicBox?: boolean + + connections?: Connections + + schPinArrangement?: SchematicPinArrangement + + schPinSpacing?: Distance + + schPinStyle?: SchematicPinStyle + + pcbWidth?: Distance + pcbHeight?: Distance + schWidth?: Distance + schHeight?: Distance + + pcbLayout?: LayoutConfig + schLayout?: LayoutConfig + cellBorder?: Border | null + border?: Border | null + schPadding?: Distance + schPaddingLeft?: Distance + schPaddingRight?: Distance + schPaddingTop?: Distance + schPaddingBottom?: Distance + + pcbPadding?: Distance + pcbPaddingLeft?: Distance + pcbPaddingRight?: Distance + pcbPaddingTop?: Distance + pcbPaddingBottom?: Distance + + grid?: boolean + flex?: boolean | string + + pcbGrid?: boolean + pcbGridCols?: number | string + pcbGridRows?: number | string + pcbGridTemplateRows?: string + pcbGridTemplateColumns?: string + pcbGridTemplate?: string + pcbGridGap?: number | string + pcbGridRowGap?: number | string + pcbGridColumnGap?: number | string + + pcbFlex?: boolean | string + pcbFlexGap?: number | string + pcbFlexDirection?: "row" | "column" + pcbAlignItems?: "start" | "center" | "end" | "stretch" + pcbJustifyContent?: + | "start" + | "center" + | "end" + | "stretch" + | "space-between" + | "space-around" + | "space-evenly" + pcbFlexRow?: boolean + pcbFlexColumn?: boolean + pcbGap?: number | string + pcbPack?: boolean + pcbPackGap?: number | string + + schGrid?: boolean + schGridCols?: number | string + schGridRows?: number | string + schGridTemplateRows?: string + schGridTemplateColumns?: string + schGridTemplate?: string + schGridGap?: number | string + schGridRowGap?: number | string + schGridColumnGap?: number | string + + schFlex?: boolean | string + schFlexGap?: number | string + schFlexDirection?: "row" | "column" + schAlignItems?: "start" | "center" | "end" | "stretch" + schJustifyContent?: + | "start" + | "center" + | "end" + | "stretch" + | "space-between" + | "space-around" + | "space-evenly" + schFlexRow?: boolean + schFlexColumn?: boolean + schGap?: number | string + schPack?: boolean + schMatchAdapt?: boolean +} +/** @deprecated Use `pcbFlex` */ +export type PartsEngine = { + findPart: (params: { + sourceComponent: AnySourceComponent + footprinterString?: string + }) => Promise | SupplierPartNumbers +} +export interface PcbRouteCache { + pcbTraces: PcbTrace[] + cacheKey: string +} +export interface AutorouterConfig { + serverUrl?: string + inputFormat?: "simplified" | "circuit-json" + serverMode?: "job" | "solve-endpoint" + serverCacheEnabled?: boolean + cache?: PcbRouteCache + traceClearance?: Distance + groupMode?: + | "sequential_trace" + | "subcircuit" + | /** @deprecated Use "sequential_trace" */ "sequential-trace" + local?: boolean + algorithmFn?: (simpleRouteJson: any) => Promise + preset?: + | "sequential_trace" + | "subcircuit" + | "auto" + | "auto_local" + | "auto_cloud" + | "freerouting" + | /** @deprecated Use "sequential_trace" */ "sequential-trace" + | /** @deprecated Use "auto_local" */ "auto-local" + | /** @deprecated Use "auto_cloud" */ "auto-cloud" +} +export const autorouterConfig = z.object({ + serverUrl: z.string().optional(), + inputFormat: z.enum(["simplified", "circuit-json"]).optional(), + serverMode: z.enum(["job", "solve-endpoint"]).optional(), + serverCacheEnabled: z.boolean().optional(), + cache: z.custom((v) => true).optional(), + traceClearance: length.optional(), + groupMode: z + .enum(["sequential_trace", "subcircuit", "sequential-trace"]) + .optional(), + algorithmFn: z + .custom<(simpleRouteJson: any) => Promise>( + (v) => typeof v === "function" || v === undefined, + ) + .optional(), + preset: z + .enum([ + "sequential_trace", + "subcircuit", + "auto", + "auto_local", + "auto_cloud", + "freerouting", + "sequential-trace", + "auto-local", + "auto-cloud", + ]) + .optional(), + local: z.boolean().optional(), +}) +export interface SubcircuitGroupProps extends BaseGroupProps { + manualEdits?: ManualEditsFileInput + routingDisabled?: boolean + defaultTraceWidth?: Distance + minTraceWidth?: Distance + pcbRouteCache?: PcbRouteCache + + autorouter?: AutorouterProp + + schAutoLayoutEnabled?: boolean + + schTraceAutoLabelEnabled?: boolean + + schMaxTraceDistance?: Distance + + partsEngine?: PartsEngine + + square?: boolean + emptyArea?: string + filledArea?: string + + width?: number | string + height?: number | string + outline?: Point[] + outlineOffsetX?: number | string + outlineOffsetY?: number | string +} +/** Desired filled area of the board e.g. "22mm^2" or "20%" */ +export interface SubcircuitGroupPropsWithBool extends SubcircuitGroupProps { + subcircuit: true +} +export interface NonSubcircuitGroupProps extends BaseGroupProps { + subcircuit?: false | undefined +} +export const baseGroupProps = commonLayoutProps.extend({ + name: z.string().optional(), + children: z.any().optional(), + schTitle: z.string().optional(), + key: z.any().optional(), + showAsSchematicBox: z.boolean().optional(), + connections: z.record(z.string(), connectionTarget.optional()).optional(), + schPinArrangement: schematicPinArrangement.optional(), + schPinSpacing: length.optional(), + schPinStyle: schematicPinStyle.optional(), + + ...layoutConfig.shape, + grid: layoutConfig.shape.grid.describe("@deprecated use pcbGrid"), + flex: layoutConfig.shape.flex.describe("@deprecated use pcbFlex"), + pcbGrid: z.boolean().optional(), + pcbGridCols: z.number().or(z.string()).optional(), + pcbGridRows: z.number().or(z.string()).optional(), + pcbGridTemplateRows: z.string().optional(), + pcbGridTemplateColumns: z.string().optional(), + pcbGridTemplate: z.string().optional(), + pcbGridGap: z.number().or(z.string()).optional(), + pcbGridRowGap: z.number().or(z.string()).optional(), + pcbGridColumnGap: z.number().or(z.string()).optional(), + pcbFlex: z.boolean().or(z.string()).optional(), + pcbFlexGap: z.number().or(z.string()).optional(), + pcbFlexDirection: z.enum(["row", "column"]).optional(), + pcbAlignItems: z.enum(["start", "center", "end", "stretch"]).optional(), + pcbJustifyContent: z + .enum([ + "start", + "center", + "end", + "stretch", + "space-between", + "space-around", + "space-evenly", + ]) + .optional(), + pcbFlexRow: z.boolean().optional(), + pcbFlexColumn: z.boolean().optional(), + pcbGap: z.number().or(z.string()).optional(), + pcbPack: z.boolean().optional(), + pcbPackGap: z.number().or(z.string()).optional(), + + schGrid: z.boolean().optional(), + schGridCols: z.number().or(z.string()).optional(), + schGridRows: z.number().or(z.string()).optional(), + schGridTemplateRows: z.string().optional(), + schGridTemplateColumns: z.string().optional(), + schGridTemplate: z.string().optional(), + schGridGap: z.number().or(z.string()).optional(), + schGridRowGap: z.number().or(z.string()).optional(), + schGridColumnGap: z.number().or(z.string()).optional(), + + schFlex: z.boolean().or(z.string()).optional(), + schFlexGap: z.number().or(z.string()).optional(), + schFlexDirection: z.enum(["row", "column"]).optional(), + schAlignItems: z.enum(["start", "center", "end", "stretch"]).optional(), + schJustifyContent: z + .enum([ + "start", + "center", + "end", + "stretch", + "space-between", + "space-around", + "space-evenly", + ]) + .optional(), + schFlexRow: z.boolean().optional(), + schFlexColumn: z.boolean().optional(), + schGap: z.number().or(z.string()).optional(), + schPack: z.boolean().optional(), + schMatchAdapt: z.boolean().optional(), + pcbWidth: length.optional(), + pcbHeight: length.optional(), + schWidth: length.optional(), + schHeight: length.optional(), + pcbLayout: layoutConfig.optional(), + schLayout: layoutConfig.optional(), + cellBorder: border.nullable().optional(), + border: border.nullable().optional(), + schPadding: length.optional(), + schPaddingLeft: length.optional(), + schPaddingRight: length.optional(), + schPaddingTop: length.optional(), + schPaddingBottom: length.optional(), + pcbPadding: length.optional(), + pcbPaddingLeft: length.optional(), + pcbPaddingRight: length.optional(), + pcbPaddingTop: length.optional(), + pcbPaddingBottom: length.optional(), +}) +export const subcircuitGroupProps = baseGroupProps.extend({ + manualEdits: manual_edits_file.optional(), + schAutoLayoutEnabled: z.boolean().optional(), + schTraceAutoLabelEnabled: z.boolean().optional(), + schMaxTraceDistance: distance.optional(), + routingDisabled: z.boolean().optional(), + defaultTraceWidth: length.optional(), + minTraceWidth: length.optional(), + partsEngine: partsEngine.optional(), + pcbRouteCache: z.custom((v) => true).optional(), + autorouter: autorouterProp.optional(), + square: z.boolean().optional(), + emptyArea: z.string().optional(), + filledArea: z.string().optional(), + width: distance.optional(), + height: distance.optional(), + outline: z.array(point).optional(), + outlineOffsetX: distance.optional(), + outlineOffsetY: distance.optional(), +}) +export const subcircuitGroupPropsWithBool = subcircuitGroupProps.extend({ + subcircuit: z.literal(true), +}) +``` + +```typescript +export interface CircleHoleProps extends PcbLayoutProps { + name?: string + shape?: "circle" + diameter?: Distance + radius?: Distance +} +export interface PillHoleProps extends PcbLayoutProps { + name?: string + shape: "pill" + width: Distance + height: Distance +} +export type HoleProps = CircleHoleProps | PillHoleProps +const circleHoleProps = pcbLayoutProps + .extend({ + name: z.string().optional(), + shape: z.literal("circle").optional(), + diameter: distance.optional(), + radius: distance.optional(), + }) + .transform((d) => ({ + ...d, + diameter: d.diameter ?? 2 * d.radius!, + radius: d.radius ?? d.diameter! / 2, + })) +const pillHoleProps = pcbLayoutProps.extend({ + name: z.string().optional(), + shape: z.literal("pill"), + width: distance, + height: distance, +}) +export const holeProps = z.union([circleHoleProps, pillHoleProps]) +``` + +```typescript +export interface InductorProps + extends CommonComponentProps { + inductance: number | string + maxCurrentRating?: number | string + schOrientation?: SchematicOrientation + connections?: Connections +} +export const inductorProps = commonComponentProps.extend({ + inductance, + maxCurrentRating: z.union([z.string(), z.number()]).optional(), + schOrientation: schematicOrientation.optional(), + connections: createConnectionsProp(inductorPins).optional(), +}) +``` + +```typescript +export interface JumperProps extends CommonComponentProps { + manufacturerPartNumber?: string + pinLabels?: Record< + number | SchematicPinLabel, + SchematicPinLabel | SchematicPinLabel[] + > + schPinStyle?: SchematicPinStyle + schPinSpacing?: number | string + schWidth?: number | string + schHeight?: number | string + schDirection?: "left" | "right" + schPinArrangement?: SchematicPortArrangement + schPortArrangement?: SchematicPortArrangement + pcbPinLabels?: Record + pinCount?: 2 | 3 + internallyConnectedPins?: (string | number)[][] + connections?: Connections +} +/** + * Connections to other components + */ +export const jumperProps = commonComponentProps.extend({ + manufacturerPartNumber: z.string().optional(), + pinLabels: z + .record( + z.number().or(schematicPinLabel), + schematicPinLabel.or(z.array(schematicPinLabel)), + ) + .optional(), + schPinStyle: schematicPinStyle.optional(), + schPinSpacing: distance.optional(), + schWidth: distance.optional(), + schHeight: distance.optional(), + schDirection: z.enum(["left", "right"]).optional(), + schPinArrangement: schematicPinArrangement.optional(), + schPortArrangement: schematicPortArrangement.optional(), + pcbPinLabels: z.record(z.string(), z.string()).optional(), + pinCount: z.union([z.literal(2), z.literal(3)]).optional(), + internallyConnectedPins: z + .array(z.array(z.union([z.string(), z.number()]))) + .optional(), + connections: z + .custom() + .pipe(z.record(z.string(), connectionTarget)) + .optional(), +}) +``` + +```typescript +export const ledProps = commonComponentProps.extend({ + color: z.string().optional(), + wavelength: z.string().optional(), + schDisplayValue: z.string().optional(), + schOrientation: schematicOrientation.optional(), + connections: createConnectionsProp(lrPolarPins).optional(), + laser: z.boolean().optional(), +}) +``` + +```typescript +export interface MosfetProps + extends CommonComponentProps { + channelType: "n" | "p" + mosfetMode: "enhancement" | "depletion" +} +export const mosfetProps = commonComponentProps.extend({ + channelType: z.enum(["n", "p"]), + mosfetMode: z.enum(["enhancement", "depletion"]), +}) +export const mosfetPins = [ + "pin1", + "drain", + "pin2", + "source", + "pin3", + "gate", +] as const +``` + +```typescript +export interface NetProps { + name: string + connectsTo?: string | string[] +} +export const netProps = z.object({ + name: z.string(), + connectsTo: z.string().or(z.array(z.string())).optional(), +}) +``` + +```typescript +/** + * @deprecated Use NetLabelProps instead. + */ +export interface NetAliasProps { + net?: string + connection?: string + schX?: number | string + schY?: number | string + schRotation?: number | string + anchorSide?: "left" | "top" | "right" | "bottom" +} +/** @deprecated Use netLabelProps instead. */ +export const netAliasProps = z.object({ + net: z.string().optional(), + connection: z.string().optional(), + schX: distance.optional(), + schY: distance.optional(), + schRotation: rotation.optional(), + anchorSide: z.enum(["left", "top", "right", "bottom"]).optional(), +}) +``` + +```typescript +export interface NetLabelProps { + net?: string + connection?: string + connectsTo?: string | string[] + schX?: number | string + schY?: number | string + schRotation?: number | string + anchorSide?: "left" | "top" | "right" | "bottom" +} +export const netLabelProps = z.object({ + net: z.string().optional(), + connection: z.string().optional(), + connectsTo: z.string().or(z.array(z.string())).optional(), + schX: distance.optional(), + schY: distance.optional(), + schRotation: rotation.optional(), + anchorSide: z.enum(["left", "top", "right", "bottom"]).optional(), +}) +``` + +```typescript +pcbLayoutProps.omit({ pcbRotation: true }).extend({ + shape: z.literal("circle"), + radius: distance, + }), +pcbLayoutProps.extend({ + shape: z.literal("rect"), + width: distance, + height: distance, + }), +``` + +```typescript +export const pcbTraceProps = z.object({ + layer: z.string().optional(), + thickness: distance.optional(), + route: z.array(route_hint_point), +}) +``` + +```typescript +export interface PinHeaderProps extends CommonComponentProps { + pinCount: number + + pitch?: number | string + + schFacingDirection?: "up" | "down" | "left" | "right" + + gender?: "male" | "female" | "unpopulated" + + showSilkscreenPinLabels?: boolean + + pcbPinLabels?: Record + + doubleRow?: boolean + + rightAngle?: boolean + + pcbOrientation?: PcbOrientation + + holeDiameter?: number | string + + platedDiameter?: number | string + + pinLabels?: Record | SchematicPinLabel[] + + connections?: Connections + + facingDirection?: "left" | "right" + + schPinArrangement?: SchematicPinArrangement + + schPinStyle?: SchematicPinStyle + + schPinSpacing?: number | string + + schWidth?: number | string + + schHeight?: number | string +} +/** + * Schematic height + */ +export const pinHeaderProps = commonComponentProps.extend({ + pinCount: z.number(), + pitch: distance.optional(), + schFacingDirection: z.enum(["up", "down", "left", "right"]).optional(), + gender: z.enum(["male", "female", "unpopulated"]).optional().default("male"), + showSilkscreenPinLabels: z.boolean().optional(), + pcbPinLabels: z.record(z.string(), z.string()).optional(), + doubleRow: z.boolean().optional(), + rightAngle: z.boolean().optional(), + pcbOrientation: pcbOrientationProp.optional(), + holeDiameter: distance.optional(), + platedDiameter: distance.optional(), + pinLabels: z + .record(z.string(), schematicPinLabel) + .or(z.array(schematicPinLabel)) + .optional(), + connections: z + .custom() + .pipe(z.record(z.string(), connectionTarget)) + .optional(), + facingDirection: z.enum(["left", "right"]).optional(), + schPinArrangement: schematicPinArrangement.optional(), + schPinStyle: schematicPinStyle.optional(), + schPinSpacing: distance.optional(), + schWidth: distance.optional(), + schHeight: distance.optional(), +}) +``` + +```typescript +export interface PinoutProps< + PinLabelMap extends PinLabelsProp | string = string, +> extends ChipProps {} +``` + +```typescript +export interface CirclePlatedHoleProps + extends Omit { + name?: string + connectsTo?: string | string[] + shape: "circle" + holeDiameter: number | string + outerDiameter: number | string + portHints?: PortHints +} +export interface OvalPlatedHoleProps + extends Omit { + name?: string + connectsTo?: string | string[] + shape: "oval" + outerWidth: number | string + outerHeight: number | string + holeWidth: number | string + holeHeight: number | string + portHints?: PortHints + + innerWidth?: number | string + innerHeight?: number | string +} +/** @deprecated use holeHeight */ +export interface PillPlatedHoleProps extends Omit { + name?: string + rectPad?: boolean + connectsTo?: string | string[] + shape: "pill" + outerWidth: number | string + outerHeight: number | string + holeWidth: number | string + holeHeight: number | string + + innerWidth?: number | string + innerHeight?: number | string + + portHints?: PortHints +} +/** @deprecated use holeHeight */ +export interface CircularHoleWithRectPlatedProps + extends Omit { + name?: string + connectsTo?: string | string[] + shape: "circular_hole_with_rect_pad" + holeDiameter: number | string + rectPadWidth: number | string + rectPadHeight: number | string + holeShape?: "circle" + padShape?: "rect" + portHints?: PortHints + pcbHoleOffsetX?: number | string + pcbHoleOffsetY?: number | string +} +export interface PillWithRectPadPlatedHoleProps + extends Omit { + name?: string + connectsTo?: string | string[] + shape: "pill_hole_with_rect_pad" + holeShape: "pill" + padShape: "rect" + holeWidth: number | string + holeHeight: number | string + rectPadWidth: number | string + rectPadHeight: number | string + portHints?: PortHints +} +export type PlatedHoleProps = + | CirclePlatedHoleProps + | OvalPlatedHoleProps + | PillPlatedHoleProps + | CircularHoleWithRectPlatedProps + | PillWithRectPadPlatedHoleProps + +const distanceHiddenUndefined = z + .custom>() + .transform((a) => { + if (a === undefined) return undefined + return distance.parse(a) + }) +pcbLayoutProps.omit({ pcbRotation: true, layer: true }).extend({ + name: z.string().optional(), + connectsTo: z.string().or(z.array(z.string())).optional(), + shape: z.literal("circle"), + holeDiameter: distance, + outerDiameter: distance, + portHints: portHints.optional(), + }), +pcbLayoutProps.omit({ pcbRotation: true, layer: true }).extend({ + name: z.string().optional(), + connectsTo: z.string().or(z.array(z.string())).optional(), + shape: z.literal("oval"), + outerWidth: distance, + outerHeight: distance, + holeWidth: distanceHiddenUndefined, + holeHeight: distanceHiddenUndefined, + innerWidth: distance.optional().describe("DEPRECATED use holeWidth"), + innerHeight: distance.optional().describe("DEPRECATED use holeHeight"), + portHints: portHints.optional(), + }), +pcbLayoutProps.omit({ layer: true }).extend({ + name: z.string().optional(), + connectsTo: z.string().or(z.array(z.string())).optional(), + shape: z.literal("pill"), + rectPad: z.boolean().optional(), + outerWidth: distance, + outerHeight: distance, + holeWidth: distanceHiddenUndefined, + holeHeight: distanceHiddenUndefined, + innerWidth: distance.optional().describe("DEPRECATED use holeWidth"), + innerHeight: distance.optional().describe("DEPRECATED use holeHeight"), + portHints: portHints.optional(), + }), +pcbLayoutProps.omit({ pcbRotation: true, layer: true }).extend({ + name: z.string().optional(), + connectsTo: z.string().or(z.array(z.string())).optional(), + shape: z.literal("circular_hole_with_rect_pad"), + holeDiameter: distance, + rectPadWidth: distance, + rectPadHeight: distance, + holeShape: z.literal("circle").optional(), + padShape: z.literal("rect").optional(), + portHints: portHints.optional(), + pcbHoleOffsetX: distance.optional(), + pcbHoleOffsetY: distance.optional(), + }), +pcbLayoutProps.omit({ pcbRotation: true, layer: true }).extend({ + name: z.string().optional(), + connectsTo: z.string().or(z.array(z.string())).optional(), + shape: z.literal("pill_hole_with_rect_pad"), + holeShape: z.literal("pill"), + padShape: z.literal("rect"), + holeWidth: distance, + holeHeight: distance, + rectPadWidth: distance, + rectPadHeight: distance, + portHints: portHints.optional(), + }), +``` + +```typescript +export const portProps = commonLayoutProps.extend({ + name: z.string(), + pinNumber: z.number().optional(), + aliases: z.array(z.string()).optional(), + direction: direction, +}) +``` + +```typescript +export interface PotentiometerProps extends CommonComponentProps { + maxResistance: number | string + pinVariant?: PotentiometerPinVariant +} +export const potentiometerProps = commonComponentProps.extend({ + maxResistance: resistance, + pinVariant: z.enum(["two_pin", "three_pin"]).optional(), +}) +``` + +```typescript +export const powerSourceProps = commonComponentProps.extend({ + voltage, +}) +``` + +```typescript +export interface ResistorProps + extends CommonComponentProps { + resistance: number | string + pullupFor?: string + pullupTo?: string + pulldownFor?: string + pulldownTo?: string + schOrientation?: SchematicOrientation + connections?: Connections +} +export const resistorProps = commonComponentProps.extend({ + resistance, + + pullupFor: z.string().optional(), + pullupTo: z.string().optional(), + + pulldownFor: z.string().optional(), + pulldownTo: z.string().optional(), + + schOrientation: schematicOrientation.optional(), + + connections: createConnectionsProp(resistorPinLabels).optional(), +}) +``` + +```typescript +export interface ResonatorProps extends CommonComponentProps { + frequency: number | string + loadCapacitance: number | string + pinVariant?: ResonatorPinVariant +} +export const resonatorProps = commonComponentProps.extend({ + frequency: frequency, + loadCapacitance: capacitance, + pinVariant: z.enum(["no_ground", "ground_pin", "two_ground_pins"]).optional(), +}) +``` + +```typescript +export const schematicBoxProps = z + .object({ + schX: distance.optional(), + schY: distance.optional(), + width: distance.optional(), + height: distance.optional(), + overlay: z.array(z.string()).optional(), + + padding: distance.optional(), + paddingLeft: distance.optional(), + paddingRight: distance.optional(), + paddingTop: distance.optional(), + paddingBottom: distance.optional(), + + title: z.string().optional(), + titleAlignment: ninePointAnchor.default("top_left"), + titleColor: z.string().optional(), + titleFontSize: distance.optional(), + titleInside: z.boolean().default(false), + strokeStyle: z.enum(["solid", "dashed"]).default("solid"), + }) +``` + +```typescript +export const schematicCellProps = z.object({ + children: z.string().optional(), + horizontalAlign: z.enum(["left", "center", "right"]).optional(), + verticalAlign: z.enum(["top", "middle", "bottom"]).optional(), + fontSize: distance.optional(), + rowSpan: z.number().optional(), + colSpan: z.number().optional(), + width: distance.optional(), + text: z.string().optional(), +}) +export interface SchematicCellProps { + children?: string + horizontalAlign?: "left" | "center" | "right" + verticalAlign?: "top" | "middle" | "bottom" + fontSize?: number | string + rowSpan?: number + colSpan?: number + width?: number | string + text?: string +} +``` + +```typescript +export const schematicArcProps = z.object({ + center: point, + radius: distance, + startAngleDegrees: rotation, + endAngleDegrees: rotation, + direction: z.enum(["clockwise", "counterclockwise"]).default( + "counterclockwise", + ), + strokeWidth: distance.optional(), + color: z.string().optional().default("#000000"), + isDashed: z.boolean().optional().default(false), +}) +``` + +```typescript +export const schematicCircleProps = z.object({ + center: point, + radius: distance, + strokeWidth: distance.optional(), + color: z.string().optional().default("#000000"), + isFilled: z.boolean().optional().default(false), + fillColor: z.string().optional(), + isDashed: z.boolean().optional().default(false), +}) +``` + +```typescript +export const schematicLineProps = z.object({ + x1: distance, + y1: distance, + x2: distance, + y2: distance, + strokeWidth: distance.optional(), + color: z.string().optional().default("#000000"), + isDashed: z.boolean().optional().default(false), +}) +``` + +```typescript +export const schematicRectProps = z.object({ + center: point, + width: distance, + height: distance, + rotation: rotation.default(0), + strokeWidth: distance.optional(), + color: z.string().optional().default("#000000"), + isFilled: z.boolean().optional().default(false), + fillColor: z.string().optional(), + isDashed: z.boolean().optional().default(false), +}) +``` + +```typescript +export const schematicPathProps = z.object({ + points: z.array(point), + isFilled: z.boolean().optional().default(false), + fillColor: z.enum(["red", "blue"]).optional(), +}) +``` + +```typescript +export const schematicRowProps = z.object({ + children: z.any().optional(), + height: distance.optional(), +}) +export interface SchematicRowProps { + children?: any + height?: number | string +} +``` + +```typescript +export const schematicTableProps = z.object({ + schX: distance.optional(), + schY: distance.optional(), + children: z.any().optional(), + cellPadding: distance.optional(), + borderWidth: distance.optional(), + anchor: ninePointAnchor.optional(), + fontSize: distance.optional(), +}) +export interface SchematicTableProps { + schX?: number | string + schY?: number | string + children?: any + cellPadding?: number | string + borderWidth?: number | string + anchor?: z.infer + fontSize?: number | string +} +``` + +```typescript +export const schematicTextProps = z.object({ + schX: distance.optional(), + schY: distance.optional(), + text: z.string(), + fontSize: z.number().default(1), + anchor: z + .union([fivePointAnchor.describe("legacy"), ninePointAnchor]) + .default("center"), + color: z.string().default("#000000"), + schRotation: rotation.default(0), +}) +``` + +```typescript +export const silkscreenCircleProps = pcbLayoutProps + .omit({ pcbRotation: true }) + .extend({ + isFilled: z.boolean().optional(), + isOutline: z.boolean().optional(), + strokeWidth: distance.optional(), + radius: distance, + }) +``` + +```typescript +export const silkscreenLineProps = pcbLayoutProps + .omit({ pcbX: true, pcbY: true, pcbRotation: true }) + .extend({ + strokeWidth: distance, + x1: distance, + y1: distance, + x2: distance, + y2: distance, + }) +``` + +```typescript +export const silkscreenPathProps = pcbLayoutProps + .omit({ pcbX: true, pcbY: true, pcbRotation: true }) + .extend({ + route: z.array(route_hint_point), + strokeWidth: length.optional(), + }) +``` + +```typescript +export const silkscreenRectProps = pcbLayoutProps + .omit({ pcbRotation: true }) + .extend({ + filled: z.boolean().default(true).optional(), + stroke: z.enum(["dashed", "solid", "none"]).optional(), + strokeWidth: distance.optional(), + width: distance, + height: distance, + }) +``` + +```typescript +export const silkscreenTextProps = pcbLayoutProps.extend({ + text: z.string(), + anchorAlignment: ninePointAnchor.default("center"), + font: z.enum(["tscircuit2024"]).optional(), + fontSize: length.optional(), + isKnockout: z.boolean().optional(), + knockoutPadding: length.optional(), + knockoutPaddingLeft: length.optional(), + knockoutPaddingRight: length.optional(), + knockoutPaddingTop: length.optional(), + knockoutPaddingBottom: length.optional(), + layers: z.array(layer_ref).optional(), +}) +``` + +```typescript +export interface RectSmtPadProps extends Omit { + name?: string + shape: "rect" + width: Distance + height: Distance + portHints?: PortHints + coveredWithSolderMask?: boolean +} +export interface RotatedRectSmtPadProps + extends Omit { + name?: string + shape: "rotated_rect" + width: Distance + height: Distance + ccwRotation: number + portHints?: PortHints + coveredWithSolderMask?: boolean +} +export interface CircleSmtPadProps extends Omit { + name?: string + shape: "circle" + radius: Distance + portHints?: PortHints + coveredWithSolderMask?: boolean +} +export interface PillSmtPadProps extends Omit { + name?: string + shape: "pill" + width: Distance + height: Distance + radius: Distance + portHints?: PortHints + coveredWithSolderMask?: boolean +} +export interface PolygonSmtPadProps + extends Omit { + name?: string + shape: "polygon" + points: Point[] + portHints?: PortHints + coveredWithSolderMask?: boolean +} +export const rectSmtPadProps = pcbLayoutProps + .omit({ pcbRotation: true }) + .extend({ + name: z.string().optional(), + shape: z.literal("rect"), + width: distance, + height: distance, + portHints: portHints.optional(), + coveredWithSolderMask: z.boolean().optional(), + }) +export const rotatedRectSmtPadProps = pcbLayoutProps + .omit({ pcbRotation: true }) + .extend({ + name: z.string().optional(), + shape: z.literal("rotated_rect"), + width: distance, + height: distance, + ccwRotation: z.number(), + portHints: portHints.optional(), + coveredWithSolderMask: z.boolean().optional(), + }) +export const circleSmtPadProps = pcbLayoutProps + .omit({ pcbRotation: true }) + .extend({ + name: z.string().optional(), + shape: z.literal("circle"), + radius: distance, + portHints: portHints.optional(), + coveredWithSolderMask: z.boolean().optional(), + }) +export const pillSmtPadProps = pcbLayoutProps + .omit({ pcbRotation: true }) + .extend({ + name: z.string().optional(), + shape: z.literal("pill"), + width: distance, + height: distance, + radius: distance, + portHints: portHints.optional(), + coveredWithSolderMask: z.boolean().optional(), + }) +export const polygonSmtPadProps = pcbLayoutProps + .omit({ pcbRotation: true }) + .extend({ + name: z.string().optional(), + shape: z.literal("polygon"), + points: z.array(point), + portHints: portHints.optional(), + coveredWithSolderMask: z.boolean().optional(), + }) +``` + +```typescript +export interface SolderJumperProps extends JumperProps { + bridgedPins?: string[][] + bridged?: boolean +} +/** + * If true, all pins are connected with cuttable traces + */ +export const solderjumperProps = jumperProps.extend({ + bridgedPins: z.array(z.array(z.string())).optional(), + bridged: z.boolean().optional(), +}) +``` + +```typescript +export interface RectSolderPasteProps + extends Omit { + shape: "rect" + width: Distance + height: Distance +} +export interface CircleSolderPasteProps + extends Omit { + shape: "circle" + radius: Distance +} +export const rectSolderPasteProps = pcbLayoutProps + .omit({ pcbRotation: true }) + .extend({ + shape: z.literal("rect"), + width: distance, + height: distance, + }) +export const circleSolderPasteProps = pcbLayoutProps + .omit({ pcbRotation: true }) + .extend({ + shape: z.literal("circle"), + radius: distance, + }) +``` + +```typescript +export interface StampboardProps extends BoardProps { + leftPinCount?: number + rightPinCount?: number + topPinCount?: number + bottomPinCount?: number + leftPins?: string[] + rightPins?: string[] + topPins?: string[] + bottomPins?: string[] + pinPitch?: number | string + innerHoles?: boolean +} +export const stampboardProps = boardProps.extend({ + leftPinCount: z.number().optional(), + rightPinCount: z.number().optional(), + topPinCount: z.number().optional(), + bottomPinCount: z.number().optional(), + leftPins: z.array(z.string()).optional(), + rightPins: z.array(z.string()).optional(), + topPins: z.array(z.string()).optional(), + bottomPins: z.array(z.string()).optional(), + pinPitch: distance.optional(), + innerHoles: z.boolean().optional(), +}) +``` + +```typescript +export interface SwitchProps extends CommonComponentProps { + type?: "spst" | "spdt" | "dpst" | "dpdt" + isNormallyClosed?: boolean + spdt?: boolean + spst?: boolean + dpst?: boolean + dpdt?: boolean +} +.extend({ + type: z.enum(["spst", "spdt", "dpst", "dpdt"]).optional(), + isNormallyClosed: z.boolean().optional().default(false), + spst: z.boolean().optional(), + spdt: z.boolean().optional(), + dpst: z.boolean().optional(), + dpdt: z.boolean().optional(), + }) +``` + +```typescript +export interface SymbolProps { + originalFacingDirection?: "up" | "down" | "left" | "right" +} +/** + * The facing direction that the symbol is designed for. If you set this to "right", + * then it means the children were intended to represent the symbol facing right. + * Generally, you shouldn't set this except where it can help prevent confusion + * because you have a complex symbol. Default is "right" and this is most intuitive. + */ +export const symbolProps = z.object({ + originalFacingDirection: z + .enum(["up", "down", "left", "right"]) + .default("right") + .optional(), +}) +``` + +```typescript +export interface TestpointProps extends CommonComponentProps { + footprintVariant?: "pad" | "through_hole" + padShape?: "rect" | "circle" + padDiameter?: number | string + holeDiameter?: number | string + width?: number | string + height?: number | string +} +.extend({ + footprintVariant: z.enum(["pad", "through_hole"]).optional(), + padShape: z.enum(["rect", "circle"]).optional().default("circle"), + padDiameter: distance.optional(), + holeDiameter: distance.optional(), + width: distance.optional(), + height: distance.optional(), + }) +``` + +```typescript +export const routeHintPointProps = z.object({ + x: distance, + y: distance, + via: z.boolean().optional(), + toLayer: layer_ref.optional(), +}) +export const traceHintProps = z.object({ + for: z + .string() + .optional() + .describe( + "Selector for the port you're targeting, not required if you're inside a trace", + ), + order: z.number().optional(), + offset: route_hint_point.or(routeHintPointProps).optional(), + offsets: z + .array(route_hint_point) + .or(z.array(routeHintPointProps)) + .optional(), + traceWidth: z.number().optional(), +}) +``` + +```typescript +export const portRef = z.union([ + z.string(), + z.custom<{ getPortSelector: () => string }>((v) => +baseTraceProps.extend({ + path: z.array(portRef), + }), +baseTraceProps.extend({ + from: portRef, + to: portRef, + }), +``` + +```typescript +export const transistorPinsLabels = [ + "pin1", + "pin2", + "pin3", + "emitter", + "collector", + "base", + "gate", + "source", + "drain", +] as const +export interface TransistorProps + extends CommonComponentProps { + type: "npn" | "pnp" | "bjt" | "jfet" | "mosfet" | "igbt" + connections?: Connections +} +export const transistorProps = commonComponentProps.extend({ + type: z.enum(["npn", "pnp", "bjt", "jfet", "mosfet", "igbt"]), + connections: createConnectionsProp(transistorPinsLabels).optional(), +}) +export const transistorPins = [ + "pin1", + "emitter", + "pin2", + "collector", + "pin3", + "base", +] as const +``` + +```typescript +export interface ViaProps extends CommonLayoutProps { + name?: string + fromLayer: LayerRefInput + toLayer: LayerRefInput + holeDiameter: number | string + outerDiameter: number | string + connectsTo?: string | string[] +} +export const viaProps = commonLayoutProps.extend({ + name: z.string().optional(), + fromLayer: layer_ref, + toLayer: layer_ref, + holeDiameter: distance, + outerDiameter: distance, + connectsTo: z.string().or(z.array(z.string())).optional(), +}) +``` + +```typescript +export interface VoltageSourceProps + extends CommonComponentProps { + voltage?: number | string + frequency?: number | string + peakToPeakVoltage?: number | string + waveShape?: WaveShape + phase?: number | string + dutyCycle?: number | string + connections?: Connections +} +export const voltageSourceProps = commonComponentProps.extend({ + voltage: voltage.optional(), + frequency: frequency.optional(), + peakToPeakVoltage: voltage.optional(), + waveShape: z.enum(["sinewave", "square", "triangle", "sawtooth"]).optional(), + phase: rotation.optional(), + dutyCycle: percentage.optional(), + connections: createConnectionsProp(voltageSourcePinLabels).optional(), +}) +``` + + + +- Here is a list of unsupported components: + +1- powersource +2- powersourcesimple +3- pinheader + +- Here are examples of how you can take advantage of those props: + + // Example of a custom chip footprint definition + const CustomChipFootprint = () => ( + + // SMT pads for the chip + + + + + + // Silkscreen markings for the chip outline + + // Pin 1 indicator + + + ) + + // Example of a custom resistor footprint + const Resistor0603Footprint = () => ( + + + + + + ) + + // Example of a complete circuit + export const MyCircuit = () => ( + + // Power section group + + // Decoupling capacitor arrangement + + + + + + // Input protection group + + + + + + + // Power nets + + + + // Connections + + + + // Layout constraints + + + ) + + // Example of a custom module/component that can be reused + export const DecouplingCapacitor = ({ + chipRef, + capName, + capValue = "100nF", + distance = "2mm" + }) => ( + + + + + ) + + // Usage of the custom module + export const CircuitWithDecoupling = () => ( + + + + + ) + + +### RULES + +- decouplingFor must contain the selector for the component and the pin(eg. ".U1 .pin1", ".T1 .pin1") +- Never pass the component name alone as a selector for decouplingFor, always use the component name reference and the pin number +- Don't use hole or port components, always connect to the component pins +- Don't use inline comments which are comments in the same line as components, they are forbidden +- Port components must be children to a chip component. +- Never use components in the "Unsupported components" list +- Never use footprints in the "Unsupported footprints" list +- Any component may have a pcbX and/or a pcbY representing the center of the + component on a circuit board. +- Never use footprints that are not supported in the "All available footprints" section +- Some footprints have a fixed number of pins like ms012 and sot723 +- `` components use CSS selectors in the `from` and `to` fields + to connect components. +- Any component can have a `name` prop +- `pcbX` and `pcbY` are optional and default to 0. +- A board is centered on the origin (pcbX=0, pcbY=0), so to place a component + at the center it must be placed at pcbX=0,pcbY=0. Similarly, if you're trying + to layout components around the center, you would make ones to the left of + the center have negative pcbX values, below the center have negative pcbY, + and to the right of the center have positive pcbX values, and above the + center have positive pcbY values. +- Every component that is going to be placed must be given a footprint +- Traces can only take two ports +- Don't use path as prop for trace, only use from, to +- We don't support defining output ports, so don't defined port components +- Don't specify autorouter; don't use the autorouter prop +- Selectors for component pins must be of this format: ".U1 > .pin1" or ".U1 > .pin2" where U1 is the component name, and the pins must be numbers, so don't use names for pins but use pin1, pin2, pin3, pin4 +- And instead of ".T1 > .base" you do do ".T1 > .pin2" +- "for" must have at least two selectors for constraints + +### Trace Reference Syntax + +Traces are created using the `` component. The `from` and `to` +fields are CSS selectors that reference the components to connect. + +Examples: + + + + + +### Output + +Use a codefence with the language "tsx" to wrap the code. You can use the +current_code of the user as a starting point (if provided). + +You must export a higher-order component where the root component is `` +inside the codefence. For example: + +```tsx +export const MyLed = () => ( + + + + + +) +``` \ No newline at end of file diff --git a/benchmarks/prompt-logs/prompt-2025-09-28T16-30-20-378Z.txt b/benchmarks/prompt-logs/prompt-2025-09-28T16-30-20-378Z.txt new file mode 100644 index 0000000..04e706a --- /dev/null +++ b/benchmarks/prompt-logs/prompt-2025-09-28T16-30-20-378Z.txt @@ -0,0 +1,2683 @@ +You are an expert in electronic circuit design and tscircuit, and your job is to create a circuit board in tscircuit with the user-provided description. + +YOU MUST ABIDE BY THE RULES IN THE RULES SECTION + +## tscircuit API overview + +Here's an overview of the tscircuit API: + + // usually the root component + // custom shape instead of rectangle + + + + + + + + + + + + + +### footprint strings + +Footprint strings are a compact way to represent the physical footprint for a +component. Any component can be given a footprint string. Here are example +footprint strings: + +0402 +0603 +0805 +1206 +1210 +cap0402 +res0402 +soic8_p1.27mm +dip16 +pinrow10 +tssop20_p0.5mm +sot23 + +### All available footprints + +- Either use a passive footprint like this (e.g. 0402, 0603, 0805, 1206, 1210), here is a json string with all available footprint passive sizes: + +["01005","0201","0402","0603","0805","1206","1210","2010","2512"] + +- Or create a footprint string like this (e.g. dfn8_w5.3mm_p1.27mm, dip10_w4.00mm_p2.65mm, lqfp64_w10_h10_pl1_pw0.25mm, sot363, stampreceiver_left20_right20_bottom3_top2_w21mm_p2.54mm, tssop20_w6.5mm_p0.65mm, bga7_w8_h8_grid3x3_p1_missing(center,B1), bga64_w10_h10_grid8x8_p1.27mm), here are json objects with the available footprints and their options: + +{"fn":"axial","p":2.54,"id":0.7,"od":1} +{"fn":"bga","num_pins":64,"p":0.8,"missing":[],"grid":{"x":8,"y":8},"origin":"tl"} +{"fn":"breakoutheaders","w":10,"left":20,"right":20,"top":0,"bottom":0,"p":2.54,"id":1,"od":1.5} +{"fn":"dfn","num_pins":8,"w":5.3,"p":1.27,"legsoutside":false,"pw":0.6,"pl":1} +{"fn":"dip","num_pins":6,"p":2.54,"id":1,"od":1.5,"w":7.62} +{"fn":"lqfp","num_pins":64,"p":0.5,"legsoutside":true,"w":10,"h":10,"pw":0.25,"pl":0.25} +{"fn":"mlp","num_pins":64,"p":0.5,"thermalpad":true,"legsoutside":false,"w":10,"h":10,"pw":0.25,"pl":0.25} +{"fn":"ms012","num_pins":8,"w":3.9,"p":1.27,"legsoutside":true,"pw":0.6,"pl":1} +{"fn":"ms013","num_pins":16,"w":7.5,"p":1.27,"legsoutside":true,"pw":0.6,"pl":1} +{"fn":"pinrow","num_pins":6,"p":2.54,"id":1,"od":1.5} +{"fn":"pushbutton","w":4.5,"h":6.5,"id":1,"od":1.2} +{"fn":"qfn","num_pins":64,"p":0.5,"legsoutside":false,"w":10,"h":10,"pw":0.25,"pl":0.25} +{"fn":"qfp","num_pins":64,"p":0.5,"pw":0.25,"pl":1,"legsoutside":true,"w":10,"h":10} +{"fn":"quad","num_pins":64,"p":0.5,"legsoutside":false,"w":10,"h":10,"pw":0.25,"pl":0.25} +{"fn":"sod123","num_pins":2,"w":"2.36mm","h":"1.22mm","pl":"0.9mm","pw":"0.9mm","pad_spacing":"4.19mm"} +{"fn":"soic","num_pins":8,"w":5.3,"p":1.27,"legsoutside":false,"pw":0.6,"pl":1} +{"fn":"sot23","num_pins":3,"w":"1.92mm","h":"2.74mm","pl":"0.8mm","pw":"0.764mm"} +{"fn":"sot235","num_pins":5,"h":"1.6mm","pl":"1mm","pw":"0.7mm","p":"0.95mm"} +{"fn":"sot236","num_pins":6,"w":1.6,"p":0.95,"legsoutside":true,"pw":0.6,"pl":1} +{"fn":"sot363","num_pins":6,"w":1.94,"p":0.65,"pw":0.3,"pl":0.7,"legsoutside":false} +{"fn":"sot563","num_pins":6,"w":1.94,"p":0.5,"pw":0.3,"pl":0.67,"legsoutside":false} +{"fn":"sot723","num_pins":3,"w":"1.2mm","h":"1.2mm","pl":"0.3mm","pw":"0.32mm"} +{"fn":"ssop","num_pins":8,"w":3.9,"p":1.27,"legsoutside":false,"pw":0.6,"pl":1} +{"fn":"stampboard","w":22.58,"left":20,"right":20,"top":2,"bottom":2,"p":2.54,"pw":1.6,"pl":2.4,"innerhole":false,"innerholeedgedistance":1.61} +{"fn":"stampreceiver","w":22.58,"left":20,"right":20,"top":2,"bottom":2,"p":2.54,"pw":1.6,"pl":3.2,"innerhole":false,"innerholeedgedistance":1.61} +{"fn":"tssop","num_pins":8,"w":6.1,"p":0.65,"legsoutside":true,"pw":0.6,"pl":1} + + +- Here is a list of unsupported footprints: + +1- hc + +keep in mind that num_pins can be replaced with a number directly infront of the footprint name like so: dip8_p1.27mm which means num_pins=8, don't do that for footprints with fixed number of pins like ms012 and sot723 + +### Components and Props + +- Here is a documentation of all available components and their types: + + + +```typescript +export const rotationPoint3 = z.object({ + x: z.union([z.number(), z.string()]), + y: z.union([z.number(), z.string()]), + z: z.union([z.number(), z.string()]), +}) +export interface CadModelBase { + rotationOffset?: + | number + | { x: number | string; y: number | string; z: number | string } + positionOffset?: { + x: number | string + y: number | string + z: number | string + } + size?: { x: number | string; y: number | string; z: number | string } + modelUnitToMmScale?: Distance +} +export const cadModelBase = z.object({ + rotationOffset: z.number().or(rotationPoint3).optional(), + positionOffset: point3.optional(), + size: point3.optional(), + modelUnitToMmScale: distance.optional(), +}) +export interface CadModelStl extends CadModelBase { + stlUrl: string +} +export const cadModelStl = cadModelBase.extend({ + stlUrl: z.string(), +}) +export interface CadModelObj extends CadModelBase { + objUrl: string + mtlUrl?: string +} +export const cadModelObj = cadModelBase.extend({ + objUrl: z.string(), + mtlUrl: z.string().optional(), +}) +export interface CadModelGltf extends CadModelBase { + gltfUrl: string +} +export const cadModelGltf = cadModelBase.extend({ + gltfUrl: z.string(), +}) +export interface CadModelGlb extends CadModelBase { + glbUrl: string +} +export const cadModelGlb = cadModelBase.extend({ + glbUrl: z.string(), +}) +export interface CadModelStep extends CadModelBase { + stepUrl: string +} +export const cadModelStep = cadModelBase.extend({ + stepUrl: z.string(), +}) +export interface CadModelWrl extends CadModelBase { + wrlUrl: string +} +export const cadModelWrl = cadModelBase.extend({ + wrlUrl: z.string(), +}) +export interface CadModelJscad extends CadModelBase { + jscad: Record +} +export const cadModelJscad = cadModelBase.extend({ + jscad: z.record(z.any()), +}) +export const cadModelProp = z.union([ + z.null(), + z.string(), + z.custom((v) => { + return v && typeof v === "object" && "type" in v && "props" in v + }), +``` + +```typescript +export const createConnectionsProp = ( + labels: T, +) => { + return z.record(z.enum(labels), connectionTarget) +} +``` + +```typescript +export type Distance = number | string + +export { distance, length } from "circuit-json" +``` + +```typescript +/** + * This is an abbreviated definition of the soup elements that you can find here: + * https://docs.tscircuit.com/api-reference/advanced/soup#pcb-smtpad + */ +export type FootprintSoupElements = { + type: "pcb_smtpad" | "pcb_plated_hole" + x: string | number + y: string | number + layer?: LayerRef + holeDiameter?: string | number + outerDiameter?: string | number + shape?: "circle" | "rect" + width?: string | number + height?: string | number + portHints?: string[] +} +``` + +```typescript +export interface PcbLayoutProps { + pcbX?: string | number + pcbY?: string | number + pcbRotation?: string | number + pcbPositionAnchor?: string + layer?: LayerRefInput + pcbMarginTop?: string | number + pcbMarginRight?: string | number + pcbMarginBottom?: string | number + pcbMarginLeft?: string | number + pcbMarginX?: string | number + pcbMarginY?: string | number + pcbRelative?: boolean + relative?: boolean +} +/** + * If true, both pcb and schematic coordinates will be interpreted relative to the parent group + */ +export interface CommonLayoutProps { + pcbX?: string | number + pcbY?: string | number + pcbRotation?: string | number + pcbPositionAnchor?: string + + pcbMarginTop?: string | number + pcbMarginRight?: string | number + pcbMarginBottom?: string | number + pcbMarginLeft?: string | number + pcbMarginX?: string | number + pcbMarginY?: string | number + + schMarginTop?: string | number + schMarginRight?: string | number + schMarginBottom?: string | number + schMarginLeft?: string | number + schMarginX?: string | number + schMarginY?: string | number + + schX?: string | number + schY?: string | number + schRotation?: string | number + + layer?: LayerRefInput + footprint?: FootprintProp + symbol?: SymbolProp + + relative?: boolean + + schRelative?: boolean + + pcbRelative?: boolean +} +/** + * If true, pcbX/pcbY will be interpreted relative to the parent group + */ +export const pcbLayoutProps = z.object({ + pcbX: distance.optional(), + pcbY: distance.optional(), + pcbRotation: rotation.optional(), + pcbPositionAnchor: z.string().optional(), + layer: layer_ref.optional(), + pcbMarginTop: distance.optional(), + pcbMarginRight: distance.optional(), + pcbMarginBottom: distance.optional(), + pcbMarginLeft: distance.optional(), + pcbMarginX: distance.optional(), + pcbMarginY: distance.optional(), + pcbRelative: z.boolean().optional(), + relative: z.boolean().optional(), +}) +export const commonLayoutProps = z.object({ + pcbX: distance.optional(), + pcbY: distance.optional(), + pcbRotation: rotation.optional(), + pcbPositionAnchor: z.string().optional(), + pcbMarginTop: distance.optional(), + pcbMarginRight: distance.optional(), + pcbMarginBottom: distance.optional(), + pcbMarginLeft: distance.optional(), + pcbMarginX: distance.optional(), + pcbMarginY: distance.optional(), + schMarginTop: distance.optional(), + schMarginRight: distance.optional(), + schMarginBottom: distance.optional(), + schMarginLeft: distance.optional(), + schMarginX: distance.optional(), + schMarginY: distance.optional(), + schX: distance.optional(), + schY: distance.optional(), + schRotation: rotation.optional(), + layer: layer_ref.optional(), + footprint: footprintProp.optional(), + symbol: symbolProp.optional(), + relative: z.boolean().optional(), + schRelative: z.boolean().optional(), + pcbRelative: z.boolean().optional(), +}) +export interface SupplierProps { + supplierPartNumbers?: SupplierPartNumbers +} +export const supplierProps = z.object({ + supplierPartNumbers: z.record(supplier_name, z.array(z.string())).optional(), +}) +export interface PinAttributeMap { + providesPower?: boolean + requiresPower?: boolean + providesGround?: boolean + requiresGround?: boolean + providesVoltage?: string | number + requiresVoltage?: string | number + doNotConnect?: boolean + includeInBoardPinout?: boolean +} +export const pinAttributeMap = z.object({ + providesPower: z.boolean().optional(), + requiresPower: z.boolean().optional(), + providesGround: z.boolean().optional(), + requiresGround: z.boolean().optional(), + providesVoltage: z.union([z.string(), z.number()]).optional(), + requiresVoltage: z.union([z.string(), z.number()]).optional(), + doNotConnect: z.boolean().optional(), + includeInBoardPinout: z.boolean().optional(), +}) +export interface CommonComponentProps + extends CommonLayoutProps { + key?: any + name: string + pinAttributes?: Record + supplierPartNumbers?: SupplierPartNumbers + cadModel?: CadModelProp + children?: any + symbolName?: string + doNotPlace?: boolean +} +.extend({ + key: z.any().optional(), + name: z.string(), + cadModel: cadModelProp.optional(), + children: z.any().optional(), + symbolName: z.string().optional(), + doNotPlace: z.boolean().optional(), + pinAttributes: z.record(z.string(), pinAttributeMap).optional(), + }) +export const lrPolarPins = [ + "pin1", + "left", + "anode", + "pos", + "pin2", + "right", + "cathode", + "neg", +] as const +``` + +```typescript +export const point = z.object({ + x: distance, + y: distance, +}) +``` + +```typescript +export const point3 = z.object({ + x: distance, + y: distance, + z: distance, +}) +``` + +```typescript +/** + * @deprecated Use SchematicPortArrangementWithPinCounts instead. + */ +export interface SchematicPortArrangementWithSizes { + leftSize?: number + topSize?: number + rightSize?: number + bottomSize?: number +} +/** + * Specifies the number of pins on each side of the schematic box component. + */ +export interface SchematicPortArrangementWithPinCounts { + leftPinCount?: number + topPinCount?: number + rightPinCount?: number + bottomPinCount?: number +} +export interface PinSideDefinition { + pins: Array + direction: + | "top-to-bottom" + | "left-to-right" + | "bottom-to-top" + | "right-to-left" +} +export interface SchematicPortArrangementWithSides { + leftSide?: PinSideDefinition + topSide?: PinSideDefinition + rightSide?: PinSideDefinition + bottomSide?: PinSideDefinition +} +export interface SchematicPortArrangement + extends SchematicPortArrangementWithSizes, + SchematicPortArrangementWithSides, + SchematicPortArrangementWithPinCounts {} +export const explicitPinSideDefinition = z.object({ + pins: z.array(z.union([z.number(), z.string()])), + direction: z.union([ + z.literal("top-to-bottom"), + z.literal("left-to-right"), + z.literal("bottom-to-top"), + z.literal("right-to-left"), + ]), +}) +/** + * @deprecated Use schematicPinArrangement instead. + */ +export const schematicPortArrangement = z.object({ + leftSize: z.number().optional().describe("@deprecated, use leftPinCount"), + topSize: z.number().optional().describe("@deprecated, use topPinCount"), + rightSize: z.number().optional().describe("@deprecated, use rightPinCount"), + bottomSize: z.number().optional().describe("@deprecated, use bottomPinCount"), + leftPinCount: z.number().optional(), + rightPinCount: z.number().optional(), + topPinCount: z.number().optional(), + bottomPinCount: z.number().optional(), + leftSide: explicitPinSideDefinition.optional(), + rightSide: explicitPinSideDefinition.optional(), + topSide: explicitPinSideDefinition.optional(), + bottomSide: explicitPinSideDefinition.optional(), +}) +``` + +```typescript +export type SchematicPinStyle = Record< + string, + { + marginTop?: number | string + marginRight?: number | string + marginBottom?: number | string + marginLeft?: number | string + + leftMargin?: number | string + rightMargin?: number | string + topMargin?: number | string + bottomMargin?: number | string + } +/** @deprecated use marginBottom */ +export const schematicPinStyle = z.record( + z.object({ + marginLeft: distance.optional(), + marginRight: distance.optional(), + marginTop: distance.optional(), + marginBottom: distance.optional(), + + leftMargin: distance.optional(), + rightMargin: distance.optional(), + topMargin: distance.optional(), + bottomMargin: distance.optional(), + }), +``` + +```typescript +/** @deprecated use battery_capacity from circuit-json when circuit-json is updated */ +export interface BatteryProps + extends CommonComponentProps { + capacity?: number | string + voltage?: number | string + standard?: "AA" | "AAA" | "9V" | "CR2032" | "18650" | "C" + schOrientation?: SchematicOrientation +} +export const batteryProps = commonComponentProps.extend({ + capacity: capacity.optional(), + voltage: voltage.optional(), + standard: z.enum(["AA", "AAA", "9V", "CR2032", "18650", "C"]).optional(), + schOrientation: schematicOrientation.optional(), +}) +``` + +```typescript +export interface BoardProps extends Omit { + material?: "fr4" | "fr1" + layers?: 2 | 4 + borderRadius?: Distance + boardAnchorPosition?: Point + boardAnchorAlignment?: z.infer +} +/** Number of layers for the PCB */ +export const boardProps = subcircuitGroupProps.extend({ + material: z.enum(["fr4", "fr1"]).default("fr4"), + layers: z.union([z.literal(2), z.literal(4)]).default(2), + borderRadius: distance.optional(), + boardAnchorPosition: point.optional(), + boardAnchorAlignment: ninePointAnchor.optional(), +}) +``` + +```typescript +export interface BreakoutProps + extends Omit { + padding?: Distance + paddingLeft?: Distance + paddingRight?: Distance + paddingTop?: Distance + paddingBottom?: Distance +} +export const breakoutProps = subcircuitGroupProps.extend({ + padding: distance.optional(), + paddingLeft: distance.optional(), + paddingRight: distance.optional(), + paddingTop: distance.optional(), + paddingBottom: distance.optional(), +}) +``` + +```typescript +export interface BreakoutPointProps + extends Omit { + connection: string +} +export const breakoutPointProps = pcbLayoutProps + .omit({ pcbRotation: true, layer: true }) + .extend({ + connection: z.string(), + }) +``` + +```typescript +export interface CadAssemblyProps { + originalLayer?: LayerRef + + children?: any +} +/** + * The layer that the CAD assembly is designed for. If you set this to "top" + * then it means the children were intended to represent the top layer. If + * the with this assembly is moved to the bottom layer, then the + * components will be mirrored. + * + * Generally, you shouldn't set this except where it can help prevent + * confusion because you have a complex multi-layer assembly. Default is + * "top" and this is most intuitive. + */ +export const cadassemblyProps = z.object({ + originalLayer: layer_ref.default("top").optional(), + children: z.any().optional(), +}) +``` + +```typescript +export interface CadModelProps extends CadModelBase { + modelUrl: string + pcbX?: Distance + pcbY?: Distance + pcbZ?: Distance +} +const cadModelBaseWithUrl = cadModelBase.extend({ + modelUrl: z.string(), +}) +``` + +```typescript +export const capacitorPinLabels = [ + "pin1", + "pin2", + "pos", + "neg", + "anode", + "cathode", +] as const +export interface CapacitorProps + extends CommonComponentProps { + capacitance: number | string + maxVoltageRating?: number | string + schShowRatings?: boolean + polarized?: boolean + decouplingFor?: string + decouplingTo?: string + bypassFor?: string + bypassTo?: string + maxDecouplingTraceLength?: number + schOrientation?: SchematicOrientation + connections?: Connections +} +export const capacitorProps = commonComponentProps.extend({ + capacitance, + maxVoltageRating: voltage.optional(), + schShowRatings: z.boolean().optional().default(false), + polarized: z.boolean().optional().default(false), + decouplingFor: z.string().optional(), + decouplingTo: z.string().optional(), + bypassFor: z.string().optional(), + bypassTo: z.string().optional(), + maxDecouplingTraceLength: z.number().optional(), + schOrientation: schematicOrientation.optional(), + connections: createConnectionsProp(capacitorPinLabels).optional(), +}) +``` + +```typescript +export interface PinCompatibleVariant { + manufacturerPartNumber?: string + supplierPartNumber?: SupplierPartNumbers +} +export interface ChipPropsSU< + PinLabel extends SchematicPinLabel = SchematicPinLabel, +> extends CommonComponentProps { + manufacturerPartNumber?: string + pinLabels?: PinLabelsProp + showPinAliases?: boolean + pcbPinLabels?: Record + schPinArrangement?: SchematicPortArrangement + schPortArrangement?: SchematicPortArrangement + pinCompatibleVariants?: PinCompatibleVariant[] + schPinStyle?: SchematicPinStyle + schPinSpacing?: Distance + schWidth?: Distance + schHeight?: Distance + noSchematicRepresentation?: boolean + internallyConnectedPins?: (string | number)[][] + externallyConnectedPins?: string[][] + connections?: Connections +} +/** + * Get the connection prop type for a component + * + * const pinLabels = { pin1: "VCC", pin2: "GND", pin3: "DATA" } as const + * export const MyChip = (props: ChipProps) => { + * // ... + * } + * const connections: ChipConnections = { + * VCC: "...", + * GND: "...", + * DATA: "...", + * } + * + */ +export type ChipConnections) => any> = { + [K in ChipPinLabels]: string +} +export const pinCompatibleVariant = z.object({ + manufacturerPartNumber: z.string().optional(), + supplierPartNumber: z.record(supplier_name, z.array(z.string())).optional(), +}) +export const chipProps = commonComponentProps.extend({ + manufacturerPartNumber: z.string().optional(), + pinLabels: pinLabelsProp.optional(), + showPinAliases: z.boolean().optional(), + pcbPinLabels: z.record(z.string(), z.string()).optional(), + internallyConnectedPins: z + .array(z.array(z.union([z.string(), z.number()]))) + .optional(), + externallyConnectedPins: z.array(z.array(z.string())).optional(), + schPinArrangement: schematicPinArrangement.optional(), + schPortArrangement: schematicPinArrangement.optional(), + pinCompatibleVariants: z.array(pinCompatibleVariant).optional(), + schPinStyle: schematicPinStyle.optional(), + schPinSpacing: distance.optional(), + schWidth: distance.optional(), + schHeight: distance.optional(), + noSchematicRepresentation: z.boolean().optional(), + connections: connectionsProp.optional(), +}) +``` + +```typescript +export interface ConnectorProps extends CommonComponentProps { + manufacturerPartNumber?: string + pinLabels?: Record< + number | SchematicPinLabel, + SchematicPinLabel | SchematicPinLabel[] + > + schPinStyle?: SchematicPinStyle + schPinSpacing?: number | string + schWidth?: number | string + schHeight?: number | string + schDirection?: "left" | "right" + schPortArrangement?: SchematicPortArrangement + internallyConnectedPins?: (string | number)[][] + standard?: "usb_c" | "m2" +} +/** + * Connector standard, e.g. usb_c, m2 + */ +export const connectorProps = commonComponentProps.extend({ + manufacturerPartNumber: z.string().optional(), + pinLabels: z + .record( + z.number().or(schematicPinLabel), + schematicPinLabel.or(z.array(schematicPinLabel)), + ) + .optional(), + schPinStyle: schematicPinStyle.optional(), + schPinSpacing: distance.optional(), + schWidth: distance.optional(), + schHeight: distance.optional(), + schDirection: z.enum(["left", "right"]).optional(), + schPortArrangement: schematicPortArrangement.optional(), + internallyConnectedPins: z + .array(z.array(z.union([z.string(), z.number()]))) + .optional(), + standard: z.enum(["usb_c", "m2"]).optional(), +}) +``` + +```typescript +export interface ConstrainedLayoutProps { + name?: string + pcbOnly?: boolean + schOnly?: boolean +} +export const constrainedLayoutProps = z.object({ + name: z.string().optional(), + pcbOnly: z.boolean().optional(), + schOnly: z.boolean().optional(), +}) +``` + +```typescript +export type PcbXDistConstraint = { + pcb?: true + xDist: Distance + + left: string + + right: string + + edgeToEdge?: true + + centerToCenter?: true +} +/** + * If true, the provided distance is the distance between the centers of the + * left and right components + */ +export type PcbYDistConstraint = { + pcb?: true + yDist: Distance + + top: string + + bottom: string + + edgeToEdge?: true + centerToCenter?: true +} +/** + * Selector for bottom component, e.g. ".U1" or ".R1", you can also specify the + * edge or center of the component e.g. ".R1 bottomedge", ".R1 center" + */ +export type PcbSameYConstraint = { + pcb?: true + sameY?: true + + for: string[] +} +/** + * Selector for components, e.g. [".U1", ".R1"], you can also specify the + * edge or center of the component e.g. [".R1 leftedge", ".U1 center"] + */ +export type PcbSameXConstraint = { + pcb?: true + sameX?: true + for: string[] +} +export const pcbXDistConstraintProps = z.object({ + pcb: z.literal(true).optional(), + xDist: distance, + left: z.string(), + right: z.string(), + + edgeToEdge: z.literal(true).optional(), + centerToCenter: z.literal(true).optional(), +}) +export const pcbYDistConstraintProps = z.object({ + pcb: z.literal(true).optional(), + yDist: distance, + top: z.string(), + bottom: z.string(), + + edgeToEdge: z.literal(true).optional(), + centerToCenter: z.literal(true).optional(), +}) +export const pcbSameYConstraintProps = z.object({ + pcb: z.literal(true).optional(), + sameY: z.literal(true).optional(), + for: z.array(z.string()), +}) +export const pcbSameXConstraintProps = z.object({ + pcb: z.literal(true).optional(), + sameX: z.literal(true).optional(), + for: z.array(z.string()), +}) +``` + +```typescript +export interface CopperPourProps { + name?: string + layer: LayerRefInput + connectsTo: string + padMargin?: Distance + traceMargin?: Distance +} +export const copperPourProps = z.object({ + name: z.string().optional(), + layer: layer_ref, + connectsTo: z.string(), + padMargin: distance.optional(), + traceMargin: distance.optional(), +}) +``` + +```typescript +export interface CrystalProps + extends CommonComponentProps { + frequency: number | string + loadCapacitance: number | string + manufacturerPartNumber?: string + mpn?: string + pinVariant?: PinVariant + schOrientation?: SchematicOrientation + connections?: Connections +} +export const crystalProps = commonComponentProps.extend({ + frequency: frequency, + loadCapacitance: capacitance, + manufacturerPartNumber: z.string().optional(), + mpn: z.string().optional(), + pinVariant: z.enum(["two_pin", "four_pin"]).optional(), + schOrientation: schematicOrientation.optional(), + connections: createConnectionsProp(crystalPins).optional(), +}) +``` + +```typescript +export interface RectCutoutProps + extends Omit { + name?: string + shape: "rect" + width: Distance + height: Distance +} +export const rectCutoutProps = pcbLayoutProps + .omit({ + layer: true, + pcbRotation: true, + }) + .extend({ + name: z.string().optional(), + shape: z.literal("rect"), + width: distance, + height: distance, + }) +export interface CircleCutoutProps + extends Omit { + name?: string + shape: "circle" + radius: Distance +} +export const circleCutoutProps = pcbLayoutProps + .omit({ + layer: true, + pcbRotation: true, + }) + .extend({ + name: z.string().optional(), + shape: z.literal("circle"), + radius: distance, + }) +export interface PolygonCutoutProps + extends Omit { + name?: string + shape: "polygon" + points: Point[] +} +export const polygonCutoutProps = pcbLayoutProps + .omit({ + layer: true, + pcbRotation: true, + }) + .extend({ + name: z.string().optional(), + shape: z.literal("polygon"), + points: z.array(point), + }) +``` + +```typescript +.extend({ + connections: connectionsProp.optional(), + variant: diodeVariant.optional().default("standard"), + standard: z.boolean().optional(), + schottky: z.boolean().optional(), + zener: z.boolean().optional(), + avalanche: z.boolean().optional(), + photo: z.boolean().optional(), + tvs: z.boolean().optional(), + schOrientation: schematicOrientation.optional(), + }) +export interface DiodeProps + extends CommonComponentProps { + connections?: { + anode?: string | string[] | readonly string[] + cathode?: string | string[] | readonly string[] + pin1?: string | string[] | readonly string[] + pin2?: string | string[] | readonly string[] + pos?: string | string[] | readonly string[] + neg?: string | string[] | readonly string[] + } + variant?: "standard" | "schottky" | "zener" | "avalanche" | "photo" | "tvs" + standard?: boolean + schottky?: boolean + zener?: boolean + avalanche?: boolean + photo?: boolean + tvs?: boolean + schOrientation?: SchematicOrientation +} +``` + +```typescript +export const fabricationNotePathProps = pcbLayoutProps + .omit({ pcbX: true, pcbY: true, pcbRotation: true }) + .extend({ + route: z.array(route_hint_point), + strokeWidth: length.optional(), + color: z.string().optional(), + }) +``` + +```typescript +export const fabricationNoteTextProps = pcbLayoutProps.extend({ + text: z.string(), + anchorAlignment: z + .enum(["center", "top_left", "top_right", "bottom_left", "bottom_right"]) + .default("center"), + font: z.enum(["tscircuit2024"]).optional(), + fontSize: length.optional(), + color: z.string().optional(), +}) +``` + +```typescript +export interface FootprintProps { + originalLayer?: LayerRef +} +/** + * The layer that the footprint is designed for. If you set this to "top" + * then it means the children were intended to represent the top layer. If + * the with this footprint is moved to the bottom layer, then the + * components will be mirrored. + * + * Generally, you shouldn't set this except where it can help prevent + * confusion because you have a complex multi-layer footprint. Default is + * "top" and this is most intuitive. + */ +export const footprintProps = z.object({ + originalLayer: layer_ref.default("top").optional(), +}) +``` + +```typescript +export interface FuseProps + extends CommonComponentProps { + currentRating: number | string + + voltageRating?: number | string + + schShowRatings?: boolean + + schOrientation?: SchematicOrientation + + connections?: Connections +} +/** + * Schema for validating fuse props + */ +export const fuseProps = commonComponentProps.extend({ + currentRating: z.union([z.number(), z.string()]), + voltageRating: z.union([z.number(), z.string()]).optional(), + schShowRatings: z.boolean().optional(), + schOrientation: schematicOrientation.optional(), + connections: z + .record( + z.string(), + z.union([ + z.string(), + z.array(z.string()).readonly(), + z.array(z.string()), + ]), + ) + .optional(), +}) +``` + +```typescript +export const layoutConfig = z.object({ + layoutMode: z + .enum(["grid", "flex", "match-adapt", "relative", "none"]) + .optional(), + position: z.enum(["absolute", "relative"]).optional(), + + grid: z.boolean().optional(), + gridCols: z.number().or(z.string()).optional(), + gridRows: z.number().or(z.string()).optional(), + gridTemplateRows: z.string().optional(), + gridTemplateColumns: z.string().optional(), + gridTemplate: z.string().optional(), + gridGap: z.number().or(z.string()).optional(), + gridRowGap: z.number().or(z.string()).optional(), + gridColumnGap: z.number().or(z.string()).optional(), + + flex: z.boolean().or(z.string()).optional(), + flexDirection: z.enum(["row", "column"]).optional(), + alignItems: z.enum(["start", "center", "end", "stretch"]).optional(), + justifyContent: z + .enum([ + "start", + "center", + "end", + "stretch", + "space-between", + "space-around", + "space-evenly", + ]) + .optional(), + flexRow: z.boolean().optional(), + flexColumn: z.boolean().optional(), + gap: z.number().or(z.string()).optional(), + + pack: z + .boolean() + .optional() + .describe("Pack the contents of this group using a packing strategy"), + packOrderStrategy: z + .enum([ + "largest_to_smallest", + "first_to_last", + "highest_to_lowest_pin_count", + ]) + .optional(), + packPlacementStrategy: z + .enum(["shortest_connection_along_outline"]) + .optional(), + + padding: length.optional(), + paddingLeft: length.optional(), + paddingRight: length.optional(), + paddingTop: length.optional(), + paddingBottom: length.optional(), + paddingX: length.optional(), + paddingY: length.optional(), + + width: length.optional(), + height: length.optional(), + + matchAdapt: z.boolean().optional(), + matchAdaptTemplate: z.any().optional(), +}) +export interface LayoutConfig { + layoutMode?: "grid" | "flex" | "match-adapt" | "relative" | "none" + position?: "absolute" | "relative" + + grid?: boolean + gridCols?: number | string + gridRows?: number | string + gridTemplateRows?: string + gridTemplateColumns?: string + gridTemplate?: string + gridGap?: number | string + gridRowGap?: number | string + gridColumnGap?: number | string + + flex?: boolean | string + flexDirection?: "row" | "column" + alignItems?: "start" | "center" | "end" | "stretch" + justifyContent?: + | "start" + | "center" + | "end" + | "stretch" + | "space-between" + | "space-around" + | "space-evenly" + flexRow?: boolean + flexColumn?: boolean + gap?: number | string + + pack?: boolean + packOrderStrategy?: + | "largest_to_smallest" + | "first_to_last" + | "highest_to_lowest_pin_count" + packPlacementStrategy?: "shortest_connection_along_outline" + + padding?: Distance + paddingLeft?: Distance + paddingRight?: Distance + paddingTop?: Distance + paddingBottom?: Distance + paddingX?: Distance + paddingY?: Distance + + width?: Distance + height?: Distance + + matchAdapt?: boolean + matchAdaptTemplate?: any +} +export interface Border { + strokeWidth?: Distance + dashed?: boolean + solid?: boolean +} +export const border = z.object({ + strokeWidth: length.optional(), + dashed: z.boolean().optional(), + solid: z.boolean().optional(), +}) +export interface BaseGroupProps extends CommonLayoutProps, LayoutConfig { + name?: string + key?: any + children?: any + + schTitle?: string + + showAsSchematicBox?: boolean + + connections?: Connections + + schPinArrangement?: SchematicPinArrangement + + schPinSpacing?: Distance + + schPinStyle?: SchematicPinStyle + + pcbWidth?: Distance + pcbHeight?: Distance + schWidth?: Distance + schHeight?: Distance + + pcbLayout?: LayoutConfig + schLayout?: LayoutConfig + cellBorder?: Border | null + border?: Border | null + schPadding?: Distance + schPaddingLeft?: Distance + schPaddingRight?: Distance + schPaddingTop?: Distance + schPaddingBottom?: Distance + + pcbPadding?: Distance + pcbPaddingLeft?: Distance + pcbPaddingRight?: Distance + pcbPaddingTop?: Distance + pcbPaddingBottom?: Distance + + grid?: boolean + flex?: boolean | string + + pcbGrid?: boolean + pcbGridCols?: number | string + pcbGridRows?: number | string + pcbGridTemplateRows?: string + pcbGridTemplateColumns?: string + pcbGridTemplate?: string + pcbGridGap?: number | string + pcbGridRowGap?: number | string + pcbGridColumnGap?: number | string + + pcbFlex?: boolean | string + pcbFlexGap?: number | string + pcbFlexDirection?: "row" | "column" + pcbAlignItems?: "start" | "center" | "end" | "stretch" + pcbJustifyContent?: + | "start" + | "center" + | "end" + | "stretch" + | "space-between" + | "space-around" + | "space-evenly" + pcbFlexRow?: boolean + pcbFlexColumn?: boolean + pcbGap?: number | string + pcbPack?: boolean + pcbPackGap?: number | string + + schGrid?: boolean + schGridCols?: number | string + schGridRows?: number | string + schGridTemplateRows?: string + schGridTemplateColumns?: string + schGridTemplate?: string + schGridGap?: number | string + schGridRowGap?: number | string + schGridColumnGap?: number | string + + schFlex?: boolean | string + schFlexGap?: number | string + schFlexDirection?: "row" | "column" + schAlignItems?: "start" | "center" | "end" | "stretch" + schJustifyContent?: + | "start" + | "center" + | "end" + | "stretch" + | "space-between" + | "space-around" + | "space-evenly" + schFlexRow?: boolean + schFlexColumn?: boolean + schGap?: number | string + schPack?: boolean + schMatchAdapt?: boolean +} +/** @deprecated Use `pcbFlex` */ +export type PartsEngine = { + findPart: (params: { + sourceComponent: AnySourceComponent + footprinterString?: string + }) => Promise | SupplierPartNumbers +} +export interface PcbRouteCache { + pcbTraces: PcbTrace[] + cacheKey: string +} +export interface AutorouterConfig { + serverUrl?: string + inputFormat?: "simplified" | "circuit-json" + serverMode?: "job" | "solve-endpoint" + serverCacheEnabled?: boolean + cache?: PcbRouteCache + traceClearance?: Distance + groupMode?: + | "sequential_trace" + | "subcircuit" + | /** @deprecated Use "sequential_trace" */ "sequential-trace" + local?: boolean + algorithmFn?: (simpleRouteJson: any) => Promise + preset?: + | "sequential_trace" + | "subcircuit" + | "auto" + | "auto_local" + | "auto_cloud" + | "freerouting" + | /** @deprecated Use "sequential_trace" */ "sequential-trace" + | /** @deprecated Use "auto_local" */ "auto-local" + | /** @deprecated Use "auto_cloud" */ "auto-cloud" +} +export const autorouterConfig = z.object({ + serverUrl: z.string().optional(), + inputFormat: z.enum(["simplified", "circuit-json"]).optional(), + serverMode: z.enum(["job", "solve-endpoint"]).optional(), + serverCacheEnabled: z.boolean().optional(), + cache: z.custom((v) => true).optional(), + traceClearance: length.optional(), + groupMode: z + .enum(["sequential_trace", "subcircuit", "sequential-trace"]) + .optional(), + algorithmFn: z + .custom<(simpleRouteJson: any) => Promise>( + (v) => typeof v === "function" || v === undefined, + ) + .optional(), + preset: z + .enum([ + "sequential_trace", + "subcircuit", + "auto", + "auto_local", + "auto_cloud", + "freerouting", + "sequential-trace", + "auto-local", + "auto-cloud", + ]) + .optional(), + local: z.boolean().optional(), +}) +export interface SubcircuitGroupProps extends BaseGroupProps { + manualEdits?: ManualEditsFileInput + routingDisabled?: boolean + defaultTraceWidth?: Distance + minTraceWidth?: Distance + pcbRouteCache?: PcbRouteCache + + autorouter?: AutorouterProp + + schAutoLayoutEnabled?: boolean + + schTraceAutoLabelEnabled?: boolean + + schMaxTraceDistance?: Distance + + partsEngine?: PartsEngine + + square?: boolean + emptyArea?: string + filledArea?: string + + width?: number | string + height?: number | string + outline?: Point[] + outlineOffsetX?: number | string + outlineOffsetY?: number | string +} +/** Desired filled area of the board e.g. "22mm^2" or "20%" */ +export interface SubcircuitGroupPropsWithBool extends SubcircuitGroupProps { + subcircuit: true +} +export interface NonSubcircuitGroupProps extends BaseGroupProps { + subcircuit?: false | undefined +} +export const baseGroupProps = commonLayoutProps.extend({ + name: z.string().optional(), + children: z.any().optional(), + schTitle: z.string().optional(), + key: z.any().optional(), + showAsSchematicBox: z.boolean().optional(), + connections: z.record(z.string(), connectionTarget.optional()).optional(), + schPinArrangement: schematicPinArrangement.optional(), + schPinSpacing: length.optional(), + schPinStyle: schematicPinStyle.optional(), + + ...layoutConfig.shape, + grid: layoutConfig.shape.grid.describe("@deprecated use pcbGrid"), + flex: layoutConfig.shape.flex.describe("@deprecated use pcbFlex"), + pcbGrid: z.boolean().optional(), + pcbGridCols: z.number().or(z.string()).optional(), + pcbGridRows: z.number().or(z.string()).optional(), + pcbGridTemplateRows: z.string().optional(), + pcbGridTemplateColumns: z.string().optional(), + pcbGridTemplate: z.string().optional(), + pcbGridGap: z.number().or(z.string()).optional(), + pcbGridRowGap: z.number().or(z.string()).optional(), + pcbGridColumnGap: z.number().or(z.string()).optional(), + pcbFlex: z.boolean().or(z.string()).optional(), + pcbFlexGap: z.number().or(z.string()).optional(), + pcbFlexDirection: z.enum(["row", "column"]).optional(), + pcbAlignItems: z.enum(["start", "center", "end", "stretch"]).optional(), + pcbJustifyContent: z + .enum([ + "start", + "center", + "end", + "stretch", + "space-between", + "space-around", + "space-evenly", + ]) + .optional(), + pcbFlexRow: z.boolean().optional(), + pcbFlexColumn: z.boolean().optional(), + pcbGap: z.number().or(z.string()).optional(), + pcbPack: z.boolean().optional(), + pcbPackGap: z.number().or(z.string()).optional(), + + schGrid: z.boolean().optional(), + schGridCols: z.number().or(z.string()).optional(), + schGridRows: z.number().or(z.string()).optional(), + schGridTemplateRows: z.string().optional(), + schGridTemplateColumns: z.string().optional(), + schGridTemplate: z.string().optional(), + schGridGap: z.number().or(z.string()).optional(), + schGridRowGap: z.number().or(z.string()).optional(), + schGridColumnGap: z.number().or(z.string()).optional(), + + schFlex: z.boolean().or(z.string()).optional(), + schFlexGap: z.number().or(z.string()).optional(), + schFlexDirection: z.enum(["row", "column"]).optional(), + schAlignItems: z.enum(["start", "center", "end", "stretch"]).optional(), + schJustifyContent: z + .enum([ + "start", + "center", + "end", + "stretch", + "space-between", + "space-around", + "space-evenly", + ]) + .optional(), + schFlexRow: z.boolean().optional(), + schFlexColumn: z.boolean().optional(), + schGap: z.number().or(z.string()).optional(), + schPack: z.boolean().optional(), + schMatchAdapt: z.boolean().optional(), + pcbWidth: length.optional(), + pcbHeight: length.optional(), + schWidth: length.optional(), + schHeight: length.optional(), + pcbLayout: layoutConfig.optional(), + schLayout: layoutConfig.optional(), + cellBorder: border.nullable().optional(), + border: border.nullable().optional(), + schPadding: length.optional(), + schPaddingLeft: length.optional(), + schPaddingRight: length.optional(), + schPaddingTop: length.optional(), + schPaddingBottom: length.optional(), + pcbPadding: length.optional(), + pcbPaddingLeft: length.optional(), + pcbPaddingRight: length.optional(), + pcbPaddingTop: length.optional(), + pcbPaddingBottom: length.optional(), +}) +export const subcircuitGroupProps = baseGroupProps.extend({ + manualEdits: manual_edits_file.optional(), + schAutoLayoutEnabled: z.boolean().optional(), + schTraceAutoLabelEnabled: z.boolean().optional(), + schMaxTraceDistance: distance.optional(), + routingDisabled: z.boolean().optional(), + defaultTraceWidth: length.optional(), + minTraceWidth: length.optional(), + partsEngine: partsEngine.optional(), + pcbRouteCache: z.custom((v) => true).optional(), + autorouter: autorouterProp.optional(), + square: z.boolean().optional(), + emptyArea: z.string().optional(), + filledArea: z.string().optional(), + width: distance.optional(), + height: distance.optional(), + outline: z.array(point).optional(), + outlineOffsetX: distance.optional(), + outlineOffsetY: distance.optional(), +}) +export const subcircuitGroupPropsWithBool = subcircuitGroupProps.extend({ + subcircuit: z.literal(true), +}) +``` + +```typescript +export interface CircleHoleProps extends PcbLayoutProps { + name?: string + shape?: "circle" + diameter?: Distance + radius?: Distance +} +export interface PillHoleProps extends PcbLayoutProps { + name?: string + shape: "pill" + width: Distance + height: Distance +} +export type HoleProps = CircleHoleProps | PillHoleProps +const circleHoleProps = pcbLayoutProps + .extend({ + name: z.string().optional(), + shape: z.literal("circle").optional(), + diameter: distance.optional(), + radius: distance.optional(), + }) + .transform((d) => ({ + ...d, + diameter: d.diameter ?? 2 * d.radius!, + radius: d.radius ?? d.diameter! / 2, + })) +const pillHoleProps = pcbLayoutProps.extend({ + name: z.string().optional(), + shape: z.literal("pill"), + width: distance, + height: distance, +}) +export const holeProps = z.union([circleHoleProps, pillHoleProps]) +``` + +```typescript +export interface InductorProps + extends CommonComponentProps { + inductance: number | string + maxCurrentRating?: number | string + schOrientation?: SchematicOrientation + connections?: Connections +} +export const inductorProps = commonComponentProps.extend({ + inductance, + maxCurrentRating: z.union([z.string(), z.number()]).optional(), + schOrientation: schematicOrientation.optional(), + connections: createConnectionsProp(inductorPins).optional(), +}) +``` + +```typescript +export interface JumperProps extends CommonComponentProps { + manufacturerPartNumber?: string + pinLabels?: Record< + number | SchematicPinLabel, + SchematicPinLabel | SchematicPinLabel[] + > + schPinStyle?: SchematicPinStyle + schPinSpacing?: number | string + schWidth?: number | string + schHeight?: number | string + schDirection?: "left" | "right" + schPinArrangement?: SchematicPortArrangement + schPortArrangement?: SchematicPortArrangement + pcbPinLabels?: Record + pinCount?: 2 | 3 + internallyConnectedPins?: (string | number)[][] + connections?: Connections +} +/** + * Connections to other components + */ +export const jumperProps = commonComponentProps.extend({ + manufacturerPartNumber: z.string().optional(), + pinLabels: z + .record( + z.number().or(schematicPinLabel), + schematicPinLabel.or(z.array(schematicPinLabel)), + ) + .optional(), + schPinStyle: schematicPinStyle.optional(), + schPinSpacing: distance.optional(), + schWidth: distance.optional(), + schHeight: distance.optional(), + schDirection: z.enum(["left", "right"]).optional(), + schPinArrangement: schematicPinArrangement.optional(), + schPortArrangement: schematicPortArrangement.optional(), + pcbPinLabels: z.record(z.string(), z.string()).optional(), + pinCount: z.union([z.literal(2), z.literal(3)]).optional(), + internallyConnectedPins: z + .array(z.array(z.union([z.string(), z.number()]))) + .optional(), + connections: z + .custom() + .pipe(z.record(z.string(), connectionTarget)) + .optional(), +}) +``` + +```typescript +export const ledProps = commonComponentProps.extend({ + color: z.string().optional(), + wavelength: z.string().optional(), + schDisplayValue: z.string().optional(), + schOrientation: schematicOrientation.optional(), + connections: createConnectionsProp(lrPolarPins).optional(), + laser: z.boolean().optional(), +}) +``` + +```typescript +export interface MosfetProps + extends CommonComponentProps { + channelType: "n" | "p" + mosfetMode: "enhancement" | "depletion" +} +export const mosfetProps = commonComponentProps.extend({ + channelType: z.enum(["n", "p"]), + mosfetMode: z.enum(["enhancement", "depletion"]), +}) +export const mosfetPins = [ + "pin1", + "drain", + "pin2", + "source", + "pin3", + "gate", +] as const +``` + +```typescript +export interface NetProps { + name: string + connectsTo?: string | string[] +} +export const netProps = z.object({ + name: z.string(), + connectsTo: z.string().or(z.array(z.string())).optional(), +}) +``` + +```typescript +/** + * @deprecated Use NetLabelProps instead. + */ +export interface NetAliasProps { + net?: string + connection?: string + schX?: number | string + schY?: number | string + schRotation?: number | string + anchorSide?: "left" | "top" | "right" | "bottom" +} +/** @deprecated Use netLabelProps instead. */ +export const netAliasProps = z.object({ + net: z.string().optional(), + connection: z.string().optional(), + schX: distance.optional(), + schY: distance.optional(), + schRotation: rotation.optional(), + anchorSide: z.enum(["left", "top", "right", "bottom"]).optional(), +}) +``` + +```typescript +export interface NetLabelProps { + net?: string + connection?: string + connectsTo?: string | string[] + schX?: number | string + schY?: number | string + schRotation?: number | string + anchorSide?: "left" | "top" | "right" | "bottom" +} +export const netLabelProps = z.object({ + net: z.string().optional(), + connection: z.string().optional(), + connectsTo: z.string().or(z.array(z.string())).optional(), + schX: distance.optional(), + schY: distance.optional(), + schRotation: rotation.optional(), + anchorSide: z.enum(["left", "top", "right", "bottom"]).optional(), +}) +``` + +```typescript +pcbLayoutProps.omit({ pcbRotation: true }).extend({ + shape: z.literal("circle"), + radius: distance, + }), +pcbLayoutProps.extend({ + shape: z.literal("rect"), + width: distance, + height: distance, + }), +``` + +```typescript +export const pcbTraceProps = z.object({ + layer: z.string().optional(), + thickness: distance.optional(), + route: z.array(route_hint_point), +}) +``` + +```typescript +export interface PinHeaderProps extends CommonComponentProps { + pinCount: number + + pitch?: number | string + + schFacingDirection?: "up" | "down" | "left" | "right" + + gender?: "male" | "female" | "unpopulated" + + showSilkscreenPinLabels?: boolean + + pcbPinLabels?: Record + + doubleRow?: boolean + + rightAngle?: boolean + + pcbOrientation?: PcbOrientation + + holeDiameter?: number | string + + platedDiameter?: number | string + + pinLabels?: Record | SchematicPinLabel[] + + connections?: Connections + + facingDirection?: "left" | "right" + + schPinArrangement?: SchematicPinArrangement + + schPinStyle?: SchematicPinStyle + + schPinSpacing?: number | string + + schWidth?: number | string + + schHeight?: number | string +} +/** + * Schematic height + */ +export const pinHeaderProps = commonComponentProps.extend({ + pinCount: z.number(), + pitch: distance.optional(), + schFacingDirection: z.enum(["up", "down", "left", "right"]).optional(), + gender: z.enum(["male", "female", "unpopulated"]).optional().default("male"), + showSilkscreenPinLabels: z.boolean().optional(), + pcbPinLabels: z.record(z.string(), z.string()).optional(), + doubleRow: z.boolean().optional(), + rightAngle: z.boolean().optional(), + pcbOrientation: pcbOrientationProp.optional(), + holeDiameter: distance.optional(), + platedDiameter: distance.optional(), + pinLabels: z + .record(z.string(), schematicPinLabel) + .or(z.array(schematicPinLabel)) + .optional(), + connections: z + .custom() + .pipe(z.record(z.string(), connectionTarget)) + .optional(), + facingDirection: z.enum(["left", "right"]).optional(), + schPinArrangement: schematicPinArrangement.optional(), + schPinStyle: schematicPinStyle.optional(), + schPinSpacing: distance.optional(), + schWidth: distance.optional(), + schHeight: distance.optional(), +}) +``` + +```typescript +export interface PinoutProps< + PinLabelMap extends PinLabelsProp | string = string, +> extends ChipProps {} +``` + +```typescript +export interface CirclePlatedHoleProps + extends Omit { + name?: string + connectsTo?: string | string[] + shape: "circle" + holeDiameter: number | string + outerDiameter: number | string + portHints?: PortHints +} +export interface OvalPlatedHoleProps + extends Omit { + name?: string + connectsTo?: string | string[] + shape: "oval" + outerWidth: number | string + outerHeight: number | string + holeWidth: number | string + holeHeight: number | string + portHints?: PortHints + + innerWidth?: number | string + innerHeight?: number | string +} +/** @deprecated use holeHeight */ +export interface PillPlatedHoleProps extends Omit { + name?: string + rectPad?: boolean + connectsTo?: string | string[] + shape: "pill" + outerWidth: number | string + outerHeight: number | string + holeWidth: number | string + holeHeight: number | string + + innerWidth?: number | string + innerHeight?: number | string + + portHints?: PortHints +} +/** @deprecated use holeHeight */ +export interface CircularHoleWithRectPlatedProps + extends Omit { + name?: string + connectsTo?: string | string[] + shape: "circular_hole_with_rect_pad" + holeDiameter: number | string + rectPadWidth: number | string + rectPadHeight: number | string + holeShape?: "circle" + padShape?: "rect" + portHints?: PortHints + pcbHoleOffsetX?: number | string + pcbHoleOffsetY?: number | string +} +export interface PillWithRectPadPlatedHoleProps + extends Omit { + name?: string + connectsTo?: string | string[] + shape: "pill_hole_with_rect_pad" + holeShape: "pill" + padShape: "rect" + holeWidth: number | string + holeHeight: number | string + rectPadWidth: number | string + rectPadHeight: number | string + portHints?: PortHints +} +export type PlatedHoleProps = + | CirclePlatedHoleProps + | OvalPlatedHoleProps + | PillPlatedHoleProps + | CircularHoleWithRectPlatedProps + | PillWithRectPadPlatedHoleProps + +const distanceHiddenUndefined = z + .custom>() + .transform((a) => { + if (a === undefined) return undefined + return distance.parse(a) + }) +pcbLayoutProps.omit({ pcbRotation: true, layer: true }).extend({ + name: z.string().optional(), + connectsTo: z.string().or(z.array(z.string())).optional(), + shape: z.literal("circle"), + holeDiameter: distance, + outerDiameter: distance, + portHints: portHints.optional(), + }), +pcbLayoutProps.omit({ pcbRotation: true, layer: true }).extend({ + name: z.string().optional(), + connectsTo: z.string().or(z.array(z.string())).optional(), + shape: z.literal("oval"), + outerWidth: distance, + outerHeight: distance, + holeWidth: distanceHiddenUndefined, + holeHeight: distanceHiddenUndefined, + innerWidth: distance.optional().describe("DEPRECATED use holeWidth"), + innerHeight: distance.optional().describe("DEPRECATED use holeHeight"), + portHints: portHints.optional(), + }), +pcbLayoutProps.omit({ layer: true }).extend({ + name: z.string().optional(), + connectsTo: z.string().or(z.array(z.string())).optional(), + shape: z.literal("pill"), + rectPad: z.boolean().optional(), + outerWidth: distance, + outerHeight: distance, + holeWidth: distanceHiddenUndefined, + holeHeight: distanceHiddenUndefined, + innerWidth: distance.optional().describe("DEPRECATED use holeWidth"), + innerHeight: distance.optional().describe("DEPRECATED use holeHeight"), + portHints: portHints.optional(), + }), +pcbLayoutProps.omit({ pcbRotation: true, layer: true }).extend({ + name: z.string().optional(), + connectsTo: z.string().or(z.array(z.string())).optional(), + shape: z.literal("circular_hole_with_rect_pad"), + holeDiameter: distance, + rectPadWidth: distance, + rectPadHeight: distance, + holeShape: z.literal("circle").optional(), + padShape: z.literal("rect").optional(), + portHints: portHints.optional(), + pcbHoleOffsetX: distance.optional(), + pcbHoleOffsetY: distance.optional(), + }), +pcbLayoutProps.omit({ pcbRotation: true, layer: true }).extend({ + name: z.string().optional(), + connectsTo: z.string().or(z.array(z.string())).optional(), + shape: z.literal("pill_hole_with_rect_pad"), + holeShape: z.literal("pill"), + padShape: z.literal("rect"), + holeWidth: distance, + holeHeight: distance, + rectPadWidth: distance, + rectPadHeight: distance, + portHints: portHints.optional(), + }), +``` + +```typescript +export const portProps = commonLayoutProps.extend({ + name: z.string(), + pinNumber: z.number().optional(), + aliases: z.array(z.string()).optional(), + direction: direction, +}) +``` + +```typescript +export interface PotentiometerProps extends CommonComponentProps { + maxResistance: number | string + pinVariant?: PotentiometerPinVariant +} +export const potentiometerProps = commonComponentProps.extend({ + maxResistance: resistance, + pinVariant: z.enum(["two_pin", "three_pin"]).optional(), +}) +``` + +```typescript +export const powerSourceProps = commonComponentProps.extend({ + voltage, +}) +``` + +```typescript +export interface ResistorProps + extends CommonComponentProps { + resistance: number | string + pullupFor?: string + pullupTo?: string + pulldownFor?: string + pulldownTo?: string + schOrientation?: SchematicOrientation + connections?: Connections +} +export const resistorProps = commonComponentProps.extend({ + resistance, + + pullupFor: z.string().optional(), + pullupTo: z.string().optional(), + + pulldownFor: z.string().optional(), + pulldownTo: z.string().optional(), + + schOrientation: schematicOrientation.optional(), + + connections: createConnectionsProp(resistorPinLabels).optional(), +}) +``` + +```typescript +export interface ResonatorProps extends CommonComponentProps { + frequency: number | string + loadCapacitance: number | string + pinVariant?: ResonatorPinVariant +} +export const resonatorProps = commonComponentProps.extend({ + frequency: frequency, + loadCapacitance: capacitance, + pinVariant: z.enum(["no_ground", "ground_pin", "two_ground_pins"]).optional(), +}) +``` + +```typescript +export const schematicBoxProps = z + .object({ + schX: distance.optional(), + schY: distance.optional(), + width: distance.optional(), + height: distance.optional(), + overlay: z.array(z.string()).optional(), + + padding: distance.optional(), + paddingLeft: distance.optional(), + paddingRight: distance.optional(), + paddingTop: distance.optional(), + paddingBottom: distance.optional(), + + title: z.string().optional(), + titleAlignment: ninePointAnchor.default("top_left"), + titleColor: z.string().optional(), + titleFontSize: distance.optional(), + titleInside: z.boolean().default(false), + strokeStyle: z.enum(["solid", "dashed"]).default("solid"), + }) +``` + +```typescript +export const schematicCellProps = z.object({ + children: z.string().optional(), + horizontalAlign: z.enum(["left", "center", "right"]).optional(), + verticalAlign: z.enum(["top", "middle", "bottom"]).optional(), + fontSize: distance.optional(), + rowSpan: z.number().optional(), + colSpan: z.number().optional(), + width: distance.optional(), + text: z.string().optional(), +}) +export interface SchematicCellProps { + children?: string + horizontalAlign?: "left" | "center" | "right" + verticalAlign?: "top" | "middle" | "bottom" + fontSize?: number | string + rowSpan?: number + colSpan?: number + width?: number | string + text?: string +} +``` + +```typescript +export const schematicArcProps = z.object({ + center: point, + radius: distance, + startAngleDegrees: rotation, + endAngleDegrees: rotation, + direction: z.enum(["clockwise", "counterclockwise"]).default( + "counterclockwise", + ), + strokeWidth: distance.optional(), + color: z.string().optional().default("#000000"), + isDashed: z.boolean().optional().default(false), +}) +``` + +```typescript +export const schematicCircleProps = z.object({ + center: point, + radius: distance, + strokeWidth: distance.optional(), + color: z.string().optional().default("#000000"), + isFilled: z.boolean().optional().default(false), + fillColor: z.string().optional(), + isDashed: z.boolean().optional().default(false), +}) +``` + +```typescript +export const schematicLineProps = z.object({ + x1: distance, + y1: distance, + x2: distance, + y2: distance, + strokeWidth: distance.optional(), + color: z.string().optional().default("#000000"), + isDashed: z.boolean().optional().default(false), +}) +``` + +```typescript +export const schematicRectProps = z.object({ + center: point, + width: distance, + height: distance, + rotation: rotation.default(0), + strokeWidth: distance.optional(), + color: z.string().optional().default("#000000"), + isFilled: z.boolean().optional().default(false), + fillColor: z.string().optional(), + isDashed: z.boolean().optional().default(false), +}) +``` + +```typescript +export const schematicPathProps = z.object({ + points: z.array(point), + isFilled: z.boolean().optional().default(false), + fillColor: z.enum(["red", "blue"]).optional(), +}) +``` + +```typescript +export const schematicRowProps = z.object({ + children: z.any().optional(), + height: distance.optional(), +}) +export interface SchematicRowProps { + children?: any + height?: number | string +} +``` + +```typescript +export const schematicTableProps = z.object({ + schX: distance.optional(), + schY: distance.optional(), + children: z.any().optional(), + cellPadding: distance.optional(), + borderWidth: distance.optional(), + anchor: ninePointAnchor.optional(), + fontSize: distance.optional(), +}) +export interface SchematicTableProps { + schX?: number | string + schY?: number | string + children?: any + cellPadding?: number | string + borderWidth?: number | string + anchor?: z.infer + fontSize?: number | string +} +``` + +```typescript +export const schematicTextProps = z.object({ + schX: distance.optional(), + schY: distance.optional(), + text: z.string(), + fontSize: z.number().default(1), + anchor: z + .union([fivePointAnchor.describe("legacy"), ninePointAnchor]) + .default("center"), + color: z.string().default("#000000"), + schRotation: rotation.default(0), +}) +``` + +```typescript +export const silkscreenCircleProps = pcbLayoutProps + .omit({ pcbRotation: true }) + .extend({ + isFilled: z.boolean().optional(), + isOutline: z.boolean().optional(), + strokeWidth: distance.optional(), + radius: distance, + }) +``` + +```typescript +export const silkscreenLineProps = pcbLayoutProps + .omit({ pcbX: true, pcbY: true, pcbRotation: true }) + .extend({ + strokeWidth: distance, + x1: distance, + y1: distance, + x2: distance, + y2: distance, + }) +``` + +```typescript +export const silkscreenPathProps = pcbLayoutProps + .omit({ pcbX: true, pcbY: true, pcbRotation: true }) + .extend({ + route: z.array(route_hint_point), + strokeWidth: length.optional(), + }) +``` + +```typescript +export const silkscreenRectProps = pcbLayoutProps + .omit({ pcbRotation: true }) + .extend({ + filled: z.boolean().default(true).optional(), + stroke: z.enum(["dashed", "solid", "none"]).optional(), + strokeWidth: distance.optional(), + width: distance, + height: distance, + }) +``` + +```typescript +export const silkscreenTextProps = pcbLayoutProps.extend({ + text: z.string(), + anchorAlignment: ninePointAnchor.default("center"), + font: z.enum(["tscircuit2024"]).optional(), + fontSize: length.optional(), + isKnockout: z.boolean().optional(), + knockoutPadding: length.optional(), + knockoutPaddingLeft: length.optional(), + knockoutPaddingRight: length.optional(), + knockoutPaddingTop: length.optional(), + knockoutPaddingBottom: length.optional(), + layers: z.array(layer_ref).optional(), +}) +``` + +```typescript +export interface RectSmtPadProps extends Omit { + name?: string + shape: "rect" + width: Distance + height: Distance + portHints?: PortHints + coveredWithSolderMask?: boolean +} +export interface RotatedRectSmtPadProps + extends Omit { + name?: string + shape: "rotated_rect" + width: Distance + height: Distance + ccwRotation: number + portHints?: PortHints + coveredWithSolderMask?: boolean +} +export interface CircleSmtPadProps extends Omit { + name?: string + shape: "circle" + radius: Distance + portHints?: PortHints + coveredWithSolderMask?: boolean +} +export interface PillSmtPadProps extends Omit { + name?: string + shape: "pill" + width: Distance + height: Distance + radius: Distance + portHints?: PortHints + coveredWithSolderMask?: boolean +} +export interface PolygonSmtPadProps + extends Omit { + name?: string + shape: "polygon" + points: Point[] + portHints?: PortHints + coveredWithSolderMask?: boolean +} +export const rectSmtPadProps = pcbLayoutProps + .omit({ pcbRotation: true }) + .extend({ + name: z.string().optional(), + shape: z.literal("rect"), + width: distance, + height: distance, + portHints: portHints.optional(), + coveredWithSolderMask: z.boolean().optional(), + }) +export const rotatedRectSmtPadProps = pcbLayoutProps + .omit({ pcbRotation: true }) + .extend({ + name: z.string().optional(), + shape: z.literal("rotated_rect"), + width: distance, + height: distance, + ccwRotation: z.number(), + portHints: portHints.optional(), + coveredWithSolderMask: z.boolean().optional(), + }) +export const circleSmtPadProps = pcbLayoutProps + .omit({ pcbRotation: true }) + .extend({ + name: z.string().optional(), + shape: z.literal("circle"), + radius: distance, + portHints: portHints.optional(), + coveredWithSolderMask: z.boolean().optional(), + }) +export const pillSmtPadProps = pcbLayoutProps + .omit({ pcbRotation: true }) + .extend({ + name: z.string().optional(), + shape: z.literal("pill"), + width: distance, + height: distance, + radius: distance, + portHints: portHints.optional(), + coveredWithSolderMask: z.boolean().optional(), + }) +export const polygonSmtPadProps = pcbLayoutProps + .omit({ pcbRotation: true }) + .extend({ + name: z.string().optional(), + shape: z.literal("polygon"), + points: z.array(point), + portHints: portHints.optional(), + coveredWithSolderMask: z.boolean().optional(), + }) +``` + +```typescript +export interface SolderJumperProps extends JumperProps { + bridgedPins?: string[][] + bridged?: boolean +} +/** + * If true, all pins are connected with cuttable traces + */ +export const solderjumperProps = jumperProps.extend({ + bridgedPins: z.array(z.array(z.string())).optional(), + bridged: z.boolean().optional(), +}) +``` + +```typescript +export interface RectSolderPasteProps + extends Omit { + shape: "rect" + width: Distance + height: Distance +} +export interface CircleSolderPasteProps + extends Omit { + shape: "circle" + radius: Distance +} +export const rectSolderPasteProps = pcbLayoutProps + .omit({ pcbRotation: true }) + .extend({ + shape: z.literal("rect"), + width: distance, + height: distance, + }) +export const circleSolderPasteProps = pcbLayoutProps + .omit({ pcbRotation: true }) + .extend({ + shape: z.literal("circle"), + radius: distance, + }) +``` + +```typescript +export interface StampboardProps extends BoardProps { + leftPinCount?: number + rightPinCount?: number + topPinCount?: number + bottomPinCount?: number + leftPins?: string[] + rightPins?: string[] + topPins?: string[] + bottomPins?: string[] + pinPitch?: number | string + innerHoles?: boolean +} +export const stampboardProps = boardProps.extend({ + leftPinCount: z.number().optional(), + rightPinCount: z.number().optional(), + topPinCount: z.number().optional(), + bottomPinCount: z.number().optional(), + leftPins: z.array(z.string()).optional(), + rightPins: z.array(z.string()).optional(), + topPins: z.array(z.string()).optional(), + bottomPins: z.array(z.string()).optional(), + pinPitch: distance.optional(), + innerHoles: z.boolean().optional(), +}) +``` + +```typescript +export interface SwitchProps extends CommonComponentProps { + type?: "spst" | "spdt" | "dpst" | "dpdt" + isNormallyClosed?: boolean + spdt?: boolean + spst?: boolean + dpst?: boolean + dpdt?: boolean +} +.extend({ + type: z.enum(["spst", "spdt", "dpst", "dpdt"]).optional(), + isNormallyClosed: z.boolean().optional().default(false), + spst: z.boolean().optional(), + spdt: z.boolean().optional(), + dpst: z.boolean().optional(), + dpdt: z.boolean().optional(), + }) +``` + +```typescript +export interface SymbolProps { + originalFacingDirection?: "up" | "down" | "left" | "right" +} +/** + * The facing direction that the symbol is designed for. If you set this to "right", + * then it means the children were intended to represent the symbol facing right. + * Generally, you shouldn't set this except where it can help prevent confusion + * because you have a complex symbol. Default is "right" and this is most intuitive. + */ +export const symbolProps = z.object({ + originalFacingDirection: z + .enum(["up", "down", "left", "right"]) + .default("right") + .optional(), +}) +``` + +```typescript +export interface TestpointProps extends CommonComponentProps { + footprintVariant?: "pad" | "through_hole" + padShape?: "rect" | "circle" + padDiameter?: number | string + holeDiameter?: number | string + width?: number | string + height?: number | string +} +.extend({ + footprintVariant: z.enum(["pad", "through_hole"]).optional(), + padShape: z.enum(["rect", "circle"]).optional().default("circle"), + padDiameter: distance.optional(), + holeDiameter: distance.optional(), + width: distance.optional(), + height: distance.optional(), + }) +``` + +```typescript +export const routeHintPointProps = z.object({ + x: distance, + y: distance, + via: z.boolean().optional(), + toLayer: layer_ref.optional(), +}) +export const traceHintProps = z.object({ + for: z + .string() + .optional() + .describe( + "Selector for the port you're targeting, not required if you're inside a trace", + ), + order: z.number().optional(), + offset: route_hint_point.or(routeHintPointProps).optional(), + offsets: z + .array(route_hint_point) + .or(z.array(routeHintPointProps)) + .optional(), + traceWidth: z.number().optional(), +}) +``` + +```typescript +export const portRef = z.union([ + z.string(), + z.custom<{ getPortSelector: () => string }>((v) => +baseTraceProps.extend({ + path: z.array(portRef), + }), +baseTraceProps.extend({ + from: portRef, + to: portRef, + }), +``` + +```typescript +export const transistorPinsLabels = [ + "pin1", + "pin2", + "pin3", + "emitter", + "collector", + "base", + "gate", + "source", + "drain", +] as const +export interface TransistorProps + extends CommonComponentProps { + type: "npn" | "pnp" | "bjt" | "jfet" | "mosfet" | "igbt" + connections?: Connections +} +export const transistorProps = commonComponentProps.extend({ + type: z.enum(["npn", "pnp", "bjt", "jfet", "mosfet", "igbt"]), + connections: createConnectionsProp(transistorPinsLabels).optional(), +}) +export const transistorPins = [ + "pin1", + "emitter", + "pin2", + "collector", + "pin3", + "base", +] as const +``` + +```typescript +export interface ViaProps extends CommonLayoutProps { + name?: string + fromLayer: LayerRefInput + toLayer: LayerRefInput + holeDiameter: number | string + outerDiameter: number | string + connectsTo?: string | string[] +} +export const viaProps = commonLayoutProps.extend({ + name: z.string().optional(), + fromLayer: layer_ref, + toLayer: layer_ref, + holeDiameter: distance, + outerDiameter: distance, + connectsTo: z.string().or(z.array(z.string())).optional(), +}) +``` + +```typescript +export interface VoltageSourceProps + extends CommonComponentProps { + voltage?: number | string + frequency?: number | string + peakToPeakVoltage?: number | string + waveShape?: WaveShape + phase?: number | string + dutyCycle?: number | string + connections?: Connections +} +export const voltageSourceProps = commonComponentProps.extend({ + voltage: voltage.optional(), + frequency: frequency.optional(), + peakToPeakVoltage: voltage.optional(), + waveShape: z.enum(["sinewave", "square", "triangle", "sawtooth"]).optional(), + phase: rotation.optional(), + dutyCycle: percentage.optional(), + connections: createConnectionsProp(voltageSourcePinLabels).optional(), +}) +``` + + + +- Here is a list of unsupported components: + +1- powersource +2- powersourcesimple +3- pinheader + +- Here are examples of how you can take advantage of those props: + + // Example of a custom chip footprint definition + const CustomChipFootprint = () => ( + + // SMT pads for the chip + + + + + + // Silkscreen markings for the chip outline + + // Pin 1 indicator + + + ) + + // Example of a custom resistor footprint + const Resistor0603Footprint = () => ( + + + + + + ) + + // Example of a complete circuit + export const MyCircuit = () => ( + + // Power section group + + // Decoupling capacitor arrangement + + + + + + // Input protection group + + + + + + + // Power nets + + + + // Connections + + + + // Layout constraints + + + ) + + // Example of a custom module/component that can be reused + export const DecouplingCapacitor = ({ + chipRef, + capName, + capValue = "100nF", + distance = "2mm" + }) => ( + + + + + ) + + // Usage of the custom module + export const CircuitWithDecoupling = () => ( + + + + + ) + + +### RULES + +- decouplingFor must contain the selector for the component and the pin(eg. ".U1 .pin1", ".T1 .pin1") +- Never pass the component name alone as a selector for decouplingFor, always use the component name reference and the pin number +- Don't use hole or port components, always connect to the component pins +- Don't use inline comments which are comments in the same line as components, they are forbidden +- Port components must be children to a chip component. +- Never use components in the "Unsupported components" list +- Never use footprints in the "Unsupported footprints" list +- Any component may have a pcbX and/or a pcbY representing the center of the + component on a circuit board. +- Never use footprints that are not supported in the "All available footprints" section +- Some footprints have a fixed number of pins like ms012 and sot723 +- `` components use CSS selectors in the `from` and `to` fields + to connect components. +- Any component can have a `name` prop +- `pcbX` and `pcbY` are optional and default to 0. +- A board is centered on the origin (pcbX=0, pcbY=0), so to place a component + at the center it must be placed at pcbX=0,pcbY=0. Similarly, if you're trying + to layout components around the center, you would make ones to the left of + the center have negative pcbX values, below the center have negative pcbY, + and to the right of the center have positive pcbX values, and above the + center have positive pcbY values. +- Every component that is going to be placed must be given a footprint +- Traces can only take two ports +- Don't use path as prop for trace, only use from, to +- We don't support defining output ports, so don't defined port components +- Don't specify autorouter; don't use the autorouter prop +- Selectors for component pins must be of this format: ".U1 > .pin1" or ".U1 > .pin2" where U1 is the component name, and the pins must be numbers, so don't use names for pins but use pin1, pin2, pin3, pin4 +- And instead of ".T1 > .base" you do do ".T1 > .pin2" +- "for" must have at least two selectors for constraints + +### Trace Reference Syntax + +Traces are created using the `` component. The `from` and `to` +fields are CSS selectors that reference the components to connect. + +Examples: + + + + + +### Output + +Use a codefence with the language "tsx" to wrap the code. You can use the +current_code of the user as a starting point (if provided). + +You must export a higher-order component where the root component is `` +inside the codefence. For example: + +```tsx +export const MyLed = () => ( + + + + + +) +``` \ No newline at end of file diff --git a/benchmarks/prompt-logs/prompt-2025-09-28T16-30-20-422Z.txt b/benchmarks/prompt-logs/prompt-2025-09-28T16-30-20-422Z.txt new file mode 100644 index 0000000..04e706a --- /dev/null +++ b/benchmarks/prompt-logs/prompt-2025-09-28T16-30-20-422Z.txt @@ -0,0 +1,2683 @@ +You are an expert in electronic circuit design and tscircuit, and your job is to create a circuit board in tscircuit with the user-provided description. + +YOU MUST ABIDE BY THE RULES IN THE RULES SECTION + +## tscircuit API overview + +Here's an overview of the tscircuit API: + + // usually the root component + // custom shape instead of rectangle + + + + + + + + + + + + + +### footprint strings + +Footprint strings are a compact way to represent the physical footprint for a +component. Any component can be given a footprint string. Here are example +footprint strings: + +0402 +0603 +0805 +1206 +1210 +cap0402 +res0402 +soic8_p1.27mm +dip16 +pinrow10 +tssop20_p0.5mm +sot23 + +### All available footprints + +- Either use a passive footprint like this (e.g. 0402, 0603, 0805, 1206, 1210), here is a json string with all available footprint passive sizes: + +["01005","0201","0402","0603","0805","1206","1210","2010","2512"] + +- Or create a footprint string like this (e.g. dfn8_w5.3mm_p1.27mm, dip10_w4.00mm_p2.65mm, lqfp64_w10_h10_pl1_pw0.25mm, sot363, stampreceiver_left20_right20_bottom3_top2_w21mm_p2.54mm, tssop20_w6.5mm_p0.65mm, bga7_w8_h8_grid3x3_p1_missing(center,B1), bga64_w10_h10_grid8x8_p1.27mm), here are json objects with the available footprints and their options: + +{"fn":"axial","p":2.54,"id":0.7,"od":1} +{"fn":"bga","num_pins":64,"p":0.8,"missing":[],"grid":{"x":8,"y":8},"origin":"tl"} +{"fn":"breakoutheaders","w":10,"left":20,"right":20,"top":0,"bottom":0,"p":2.54,"id":1,"od":1.5} +{"fn":"dfn","num_pins":8,"w":5.3,"p":1.27,"legsoutside":false,"pw":0.6,"pl":1} +{"fn":"dip","num_pins":6,"p":2.54,"id":1,"od":1.5,"w":7.62} +{"fn":"lqfp","num_pins":64,"p":0.5,"legsoutside":true,"w":10,"h":10,"pw":0.25,"pl":0.25} +{"fn":"mlp","num_pins":64,"p":0.5,"thermalpad":true,"legsoutside":false,"w":10,"h":10,"pw":0.25,"pl":0.25} +{"fn":"ms012","num_pins":8,"w":3.9,"p":1.27,"legsoutside":true,"pw":0.6,"pl":1} +{"fn":"ms013","num_pins":16,"w":7.5,"p":1.27,"legsoutside":true,"pw":0.6,"pl":1} +{"fn":"pinrow","num_pins":6,"p":2.54,"id":1,"od":1.5} +{"fn":"pushbutton","w":4.5,"h":6.5,"id":1,"od":1.2} +{"fn":"qfn","num_pins":64,"p":0.5,"legsoutside":false,"w":10,"h":10,"pw":0.25,"pl":0.25} +{"fn":"qfp","num_pins":64,"p":0.5,"pw":0.25,"pl":1,"legsoutside":true,"w":10,"h":10} +{"fn":"quad","num_pins":64,"p":0.5,"legsoutside":false,"w":10,"h":10,"pw":0.25,"pl":0.25} +{"fn":"sod123","num_pins":2,"w":"2.36mm","h":"1.22mm","pl":"0.9mm","pw":"0.9mm","pad_spacing":"4.19mm"} +{"fn":"soic","num_pins":8,"w":5.3,"p":1.27,"legsoutside":false,"pw":0.6,"pl":1} +{"fn":"sot23","num_pins":3,"w":"1.92mm","h":"2.74mm","pl":"0.8mm","pw":"0.764mm"} +{"fn":"sot235","num_pins":5,"h":"1.6mm","pl":"1mm","pw":"0.7mm","p":"0.95mm"} +{"fn":"sot236","num_pins":6,"w":1.6,"p":0.95,"legsoutside":true,"pw":0.6,"pl":1} +{"fn":"sot363","num_pins":6,"w":1.94,"p":0.65,"pw":0.3,"pl":0.7,"legsoutside":false} +{"fn":"sot563","num_pins":6,"w":1.94,"p":0.5,"pw":0.3,"pl":0.67,"legsoutside":false} +{"fn":"sot723","num_pins":3,"w":"1.2mm","h":"1.2mm","pl":"0.3mm","pw":"0.32mm"} +{"fn":"ssop","num_pins":8,"w":3.9,"p":1.27,"legsoutside":false,"pw":0.6,"pl":1} +{"fn":"stampboard","w":22.58,"left":20,"right":20,"top":2,"bottom":2,"p":2.54,"pw":1.6,"pl":2.4,"innerhole":false,"innerholeedgedistance":1.61} +{"fn":"stampreceiver","w":22.58,"left":20,"right":20,"top":2,"bottom":2,"p":2.54,"pw":1.6,"pl":3.2,"innerhole":false,"innerholeedgedistance":1.61} +{"fn":"tssop","num_pins":8,"w":6.1,"p":0.65,"legsoutside":true,"pw":0.6,"pl":1} + + +- Here is a list of unsupported footprints: + +1- hc + +keep in mind that num_pins can be replaced with a number directly infront of the footprint name like so: dip8_p1.27mm which means num_pins=8, don't do that for footprints with fixed number of pins like ms012 and sot723 + +### Components and Props + +- Here is a documentation of all available components and their types: + + + +```typescript +export const rotationPoint3 = z.object({ + x: z.union([z.number(), z.string()]), + y: z.union([z.number(), z.string()]), + z: z.union([z.number(), z.string()]), +}) +export interface CadModelBase { + rotationOffset?: + | number + | { x: number | string; y: number | string; z: number | string } + positionOffset?: { + x: number | string + y: number | string + z: number | string + } + size?: { x: number | string; y: number | string; z: number | string } + modelUnitToMmScale?: Distance +} +export const cadModelBase = z.object({ + rotationOffset: z.number().or(rotationPoint3).optional(), + positionOffset: point3.optional(), + size: point3.optional(), + modelUnitToMmScale: distance.optional(), +}) +export interface CadModelStl extends CadModelBase { + stlUrl: string +} +export const cadModelStl = cadModelBase.extend({ + stlUrl: z.string(), +}) +export interface CadModelObj extends CadModelBase { + objUrl: string + mtlUrl?: string +} +export const cadModelObj = cadModelBase.extend({ + objUrl: z.string(), + mtlUrl: z.string().optional(), +}) +export interface CadModelGltf extends CadModelBase { + gltfUrl: string +} +export const cadModelGltf = cadModelBase.extend({ + gltfUrl: z.string(), +}) +export interface CadModelGlb extends CadModelBase { + glbUrl: string +} +export const cadModelGlb = cadModelBase.extend({ + glbUrl: z.string(), +}) +export interface CadModelStep extends CadModelBase { + stepUrl: string +} +export const cadModelStep = cadModelBase.extend({ + stepUrl: z.string(), +}) +export interface CadModelWrl extends CadModelBase { + wrlUrl: string +} +export const cadModelWrl = cadModelBase.extend({ + wrlUrl: z.string(), +}) +export interface CadModelJscad extends CadModelBase { + jscad: Record +} +export const cadModelJscad = cadModelBase.extend({ + jscad: z.record(z.any()), +}) +export const cadModelProp = z.union([ + z.null(), + z.string(), + z.custom((v) => { + return v && typeof v === "object" && "type" in v && "props" in v + }), +``` + +```typescript +export const createConnectionsProp = ( + labels: T, +) => { + return z.record(z.enum(labels), connectionTarget) +} +``` + +```typescript +export type Distance = number | string + +export { distance, length } from "circuit-json" +``` + +```typescript +/** + * This is an abbreviated definition of the soup elements that you can find here: + * https://docs.tscircuit.com/api-reference/advanced/soup#pcb-smtpad + */ +export type FootprintSoupElements = { + type: "pcb_smtpad" | "pcb_plated_hole" + x: string | number + y: string | number + layer?: LayerRef + holeDiameter?: string | number + outerDiameter?: string | number + shape?: "circle" | "rect" + width?: string | number + height?: string | number + portHints?: string[] +} +``` + +```typescript +export interface PcbLayoutProps { + pcbX?: string | number + pcbY?: string | number + pcbRotation?: string | number + pcbPositionAnchor?: string + layer?: LayerRefInput + pcbMarginTop?: string | number + pcbMarginRight?: string | number + pcbMarginBottom?: string | number + pcbMarginLeft?: string | number + pcbMarginX?: string | number + pcbMarginY?: string | number + pcbRelative?: boolean + relative?: boolean +} +/** + * If true, both pcb and schematic coordinates will be interpreted relative to the parent group + */ +export interface CommonLayoutProps { + pcbX?: string | number + pcbY?: string | number + pcbRotation?: string | number + pcbPositionAnchor?: string + + pcbMarginTop?: string | number + pcbMarginRight?: string | number + pcbMarginBottom?: string | number + pcbMarginLeft?: string | number + pcbMarginX?: string | number + pcbMarginY?: string | number + + schMarginTop?: string | number + schMarginRight?: string | number + schMarginBottom?: string | number + schMarginLeft?: string | number + schMarginX?: string | number + schMarginY?: string | number + + schX?: string | number + schY?: string | number + schRotation?: string | number + + layer?: LayerRefInput + footprint?: FootprintProp + symbol?: SymbolProp + + relative?: boolean + + schRelative?: boolean + + pcbRelative?: boolean +} +/** + * If true, pcbX/pcbY will be interpreted relative to the parent group + */ +export const pcbLayoutProps = z.object({ + pcbX: distance.optional(), + pcbY: distance.optional(), + pcbRotation: rotation.optional(), + pcbPositionAnchor: z.string().optional(), + layer: layer_ref.optional(), + pcbMarginTop: distance.optional(), + pcbMarginRight: distance.optional(), + pcbMarginBottom: distance.optional(), + pcbMarginLeft: distance.optional(), + pcbMarginX: distance.optional(), + pcbMarginY: distance.optional(), + pcbRelative: z.boolean().optional(), + relative: z.boolean().optional(), +}) +export const commonLayoutProps = z.object({ + pcbX: distance.optional(), + pcbY: distance.optional(), + pcbRotation: rotation.optional(), + pcbPositionAnchor: z.string().optional(), + pcbMarginTop: distance.optional(), + pcbMarginRight: distance.optional(), + pcbMarginBottom: distance.optional(), + pcbMarginLeft: distance.optional(), + pcbMarginX: distance.optional(), + pcbMarginY: distance.optional(), + schMarginTop: distance.optional(), + schMarginRight: distance.optional(), + schMarginBottom: distance.optional(), + schMarginLeft: distance.optional(), + schMarginX: distance.optional(), + schMarginY: distance.optional(), + schX: distance.optional(), + schY: distance.optional(), + schRotation: rotation.optional(), + layer: layer_ref.optional(), + footprint: footprintProp.optional(), + symbol: symbolProp.optional(), + relative: z.boolean().optional(), + schRelative: z.boolean().optional(), + pcbRelative: z.boolean().optional(), +}) +export interface SupplierProps { + supplierPartNumbers?: SupplierPartNumbers +} +export const supplierProps = z.object({ + supplierPartNumbers: z.record(supplier_name, z.array(z.string())).optional(), +}) +export interface PinAttributeMap { + providesPower?: boolean + requiresPower?: boolean + providesGround?: boolean + requiresGround?: boolean + providesVoltage?: string | number + requiresVoltage?: string | number + doNotConnect?: boolean + includeInBoardPinout?: boolean +} +export const pinAttributeMap = z.object({ + providesPower: z.boolean().optional(), + requiresPower: z.boolean().optional(), + providesGround: z.boolean().optional(), + requiresGround: z.boolean().optional(), + providesVoltage: z.union([z.string(), z.number()]).optional(), + requiresVoltage: z.union([z.string(), z.number()]).optional(), + doNotConnect: z.boolean().optional(), + includeInBoardPinout: z.boolean().optional(), +}) +export interface CommonComponentProps + extends CommonLayoutProps { + key?: any + name: string + pinAttributes?: Record + supplierPartNumbers?: SupplierPartNumbers + cadModel?: CadModelProp + children?: any + symbolName?: string + doNotPlace?: boolean +} +.extend({ + key: z.any().optional(), + name: z.string(), + cadModel: cadModelProp.optional(), + children: z.any().optional(), + symbolName: z.string().optional(), + doNotPlace: z.boolean().optional(), + pinAttributes: z.record(z.string(), pinAttributeMap).optional(), + }) +export const lrPolarPins = [ + "pin1", + "left", + "anode", + "pos", + "pin2", + "right", + "cathode", + "neg", +] as const +``` + +```typescript +export const point = z.object({ + x: distance, + y: distance, +}) +``` + +```typescript +export const point3 = z.object({ + x: distance, + y: distance, + z: distance, +}) +``` + +```typescript +/** + * @deprecated Use SchematicPortArrangementWithPinCounts instead. + */ +export interface SchematicPortArrangementWithSizes { + leftSize?: number + topSize?: number + rightSize?: number + bottomSize?: number +} +/** + * Specifies the number of pins on each side of the schematic box component. + */ +export interface SchematicPortArrangementWithPinCounts { + leftPinCount?: number + topPinCount?: number + rightPinCount?: number + bottomPinCount?: number +} +export interface PinSideDefinition { + pins: Array + direction: + | "top-to-bottom" + | "left-to-right" + | "bottom-to-top" + | "right-to-left" +} +export interface SchematicPortArrangementWithSides { + leftSide?: PinSideDefinition + topSide?: PinSideDefinition + rightSide?: PinSideDefinition + bottomSide?: PinSideDefinition +} +export interface SchematicPortArrangement + extends SchematicPortArrangementWithSizes, + SchematicPortArrangementWithSides, + SchematicPortArrangementWithPinCounts {} +export const explicitPinSideDefinition = z.object({ + pins: z.array(z.union([z.number(), z.string()])), + direction: z.union([ + z.literal("top-to-bottom"), + z.literal("left-to-right"), + z.literal("bottom-to-top"), + z.literal("right-to-left"), + ]), +}) +/** + * @deprecated Use schematicPinArrangement instead. + */ +export const schematicPortArrangement = z.object({ + leftSize: z.number().optional().describe("@deprecated, use leftPinCount"), + topSize: z.number().optional().describe("@deprecated, use topPinCount"), + rightSize: z.number().optional().describe("@deprecated, use rightPinCount"), + bottomSize: z.number().optional().describe("@deprecated, use bottomPinCount"), + leftPinCount: z.number().optional(), + rightPinCount: z.number().optional(), + topPinCount: z.number().optional(), + bottomPinCount: z.number().optional(), + leftSide: explicitPinSideDefinition.optional(), + rightSide: explicitPinSideDefinition.optional(), + topSide: explicitPinSideDefinition.optional(), + bottomSide: explicitPinSideDefinition.optional(), +}) +``` + +```typescript +export type SchematicPinStyle = Record< + string, + { + marginTop?: number | string + marginRight?: number | string + marginBottom?: number | string + marginLeft?: number | string + + leftMargin?: number | string + rightMargin?: number | string + topMargin?: number | string + bottomMargin?: number | string + } +/** @deprecated use marginBottom */ +export const schematicPinStyle = z.record( + z.object({ + marginLeft: distance.optional(), + marginRight: distance.optional(), + marginTop: distance.optional(), + marginBottom: distance.optional(), + + leftMargin: distance.optional(), + rightMargin: distance.optional(), + topMargin: distance.optional(), + bottomMargin: distance.optional(), + }), +``` + +```typescript +/** @deprecated use battery_capacity from circuit-json when circuit-json is updated */ +export interface BatteryProps + extends CommonComponentProps { + capacity?: number | string + voltage?: number | string + standard?: "AA" | "AAA" | "9V" | "CR2032" | "18650" | "C" + schOrientation?: SchematicOrientation +} +export const batteryProps = commonComponentProps.extend({ + capacity: capacity.optional(), + voltage: voltage.optional(), + standard: z.enum(["AA", "AAA", "9V", "CR2032", "18650", "C"]).optional(), + schOrientation: schematicOrientation.optional(), +}) +``` + +```typescript +export interface BoardProps extends Omit { + material?: "fr4" | "fr1" + layers?: 2 | 4 + borderRadius?: Distance + boardAnchorPosition?: Point + boardAnchorAlignment?: z.infer +} +/** Number of layers for the PCB */ +export const boardProps = subcircuitGroupProps.extend({ + material: z.enum(["fr4", "fr1"]).default("fr4"), + layers: z.union([z.literal(2), z.literal(4)]).default(2), + borderRadius: distance.optional(), + boardAnchorPosition: point.optional(), + boardAnchorAlignment: ninePointAnchor.optional(), +}) +``` + +```typescript +export interface BreakoutProps + extends Omit { + padding?: Distance + paddingLeft?: Distance + paddingRight?: Distance + paddingTop?: Distance + paddingBottom?: Distance +} +export const breakoutProps = subcircuitGroupProps.extend({ + padding: distance.optional(), + paddingLeft: distance.optional(), + paddingRight: distance.optional(), + paddingTop: distance.optional(), + paddingBottom: distance.optional(), +}) +``` + +```typescript +export interface BreakoutPointProps + extends Omit { + connection: string +} +export const breakoutPointProps = pcbLayoutProps + .omit({ pcbRotation: true, layer: true }) + .extend({ + connection: z.string(), + }) +``` + +```typescript +export interface CadAssemblyProps { + originalLayer?: LayerRef + + children?: any +} +/** + * The layer that the CAD assembly is designed for. If you set this to "top" + * then it means the children were intended to represent the top layer. If + * the with this assembly is moved to the bottom layer, then the + * components will be mirrored. + * + * Generally, you shouldn't set this except where it can help prevent + * confusion because you have a complex multi-layer assembly. Default is + * "top" and this is most intuitive. + */ +export const cadassemblyProps = z.object({ + originalLayer: layer_ref.default("top").optional(), + children: z.any().optional(), +}) +``` + +```typescript +export interface CadModelProps extends CadModelBase { + modelUrl: string + pcbX?: Distance + pcbY?: Distance + pcbZ?: Distance +} +const cadModelBaseWithUrl = cadModelBase.extend({ + modelUrl: z.string(), +}) +``` + +```typescript +export const capacitorPinLabels = [ + "pin1", + "pin2", + "pos", + "neg", + "anode", + "cathode", +] as const +export interface CapacitorProps + extends CommonComponentProps { + capacitance: number | string + maxVoltageRating?: number | string + schShowRatings?: boolean + polarized?: boolean + decouplingFor?: string + decouplingTo?: string + bypassFor?: string + bypassTo?: string + maxDecouplingTraceLength?: number + schOrientation?: SchematicOrientation + connections?: Connections +} +export const capacitorProps = commonComponentProps.extend({ + capacitance, + maxVoltageRating: voltage.optional(), + schShowRatings: z.boolean().optional().default(false), + polarized: z.boolean().optional().default(false), + decouplingFor: z.string().optional(), + decouplingTo: z.string().optional(), + bypassFor: z.string().optional(), + bypassTo: z.string().optional(), + maxDecouplingTraceLength: z.number().optional(), + schOrientation: schematicOrientation.optional(), + connections: createConnectionsProp(capacitorPinLabels).optional(), +}) +``` + +```typescript +export interface PinCompatibleVariant { + manufacturerPartNumber?: string + supplierPartNumber?: SupplierPartNumbers +} +export interface ChipPropsSU< + PinLabel extends SchematicPinLabel = SchematicPinLabel, +> extends CommonComponentProps { + manufacturerPartNumber?: string + pinLabels?: PinLabelsProp + showPinAliases?: boolean + pcbPinLabels?: Record + schPinArrangement?: SchematicPortArrangement + schPortArrangement?: SchematicPortArrangement + pinCompatibleVariants?: PinCompatibleVariant[] + schPinStyle?: SchematicPinStyle + schPinSpacing?: Distance + schWidth?: Distance + schHeight?: Distance + noSchematicRepresentation?: boolean + internallyConnectedPins?: (string | number)[][] + externallyConnectedPins?: string[][] + connections?: Connections +} +/** + * Get the connection prop type for a component + * + * const pinLabels = { pin1: "VCC", pin2: "GND", pin3: "DATA" } as const + * export const MyChip = (props: ChipProps) => { + * // ... + * } + * const connections: ChipConnections = { + * VCC: "...", + * GND: "...", + * DATA: "...", + * } + * + */ +export type ChipConnections) => any> = { + [K in ChipPinLabels]: string +} +export const pinCompatibleVariant = z.object({ + manufacturerPartNumber: z.string().optional(), + supplierPartNumber: z.record(supplier_name, z.array(z.string())).optional(), +}) +export const chipProps = commonComponentProps.extend({ + manufacturerPartNumber: z.string().optional(), + pinLabels: pinLabelsProp.optional(), + showPinAliases: z.boolean().optional(), + pcbPinLabels: z.record(z.string(), z.string()).optional(), + internallyConnectedPins: z + .array(z.array(z.union([z.string(), z.number()]))) + .optional(), + externallyConnectedPins: z.array(z.array(z.string())).optional(), + schPinArrangement: schematicPinArrangement.optional(), + schPortArrangement: schematicPinArrangement.optional(), + pinCompatibleVariants: z.array(pinCompatibleVariant).optional(), + schPinStyle: schematicPinStyle.optional(), + schPinSpacing: distance.optional(), + schWidth: distance.optional(), + schHeight: distance.optional(), + noSchematicRepresentation: z.boolean().optional(), + connections: connectionsProp.optional(), +}) +``` + +```typescript +export interface ConnectorProps extends CommonComponentProps { + manufacturerPartNumber?: string + pinLabels?: Record< + number | SchematicPinLabel, + SchematicPinLabel | SchematicPinLabel[] + > + schPinStyle?: SchematicPinStyle + schPinSpacing?: number | string + schWidth?: number | string + schHeight?: number | string + schDirection?: "left" | "right" + schPortArrangement?: SchematicPortArrangement + internallyConnectedPins?: (string | number)[][] + standard?: "usb_c" | "m2" +} +/** + * Connector standard, e.g. usb_c, m2 + */ +export const connectorProps = commonComponentProps.extend({ + manufacturerPartNumber: z.string().optional(), + pinLabels: z + .record( + z.number().or(schematicPinLabel), + schematicPinLabel.or(z.array(schematicPinLabel)), + ) + .optional(), + schPinStyle: schematicPinStyle.optional(), + schPinSpacing: distance.optional(), + schWidth: distance.optional(), + schHeight: distance.optional(), + schDirection: z.enum(["left", "right"]).optional(), + schPortArrangement: schematicPortArrangement.optional(), + internallyConnectedPins: z + .array(z.array(z.union([z.string(), z.number()]))) + .optional(), + standard: z.enum(["usb_c", "m2"]).optional(), +}) +``` + +```typescript +export interface ConstrainedLayoutProps { + name?: string + pcbOnly?: boolean + schOnly?: boolean +} +export const constrainedLayoutProps = z.object({ + name: z.string().optional(), + pcbOnly: z.boolean().optional(), + schOnly: z.boolean().optional(), +}) +``` + +```typescript +export type PcbXDistConstraint = { + pcb?: true + xDist: Distance + + left: string + + right: string + + edgeToEdge?: true + + centerToCenter?: true +} +/** + * If true, the provided distance is the distance between the centers of the + * left and right components + */ +export type PcbYDistConstraint = { + pcb?: true + yDist: Distance + + top: string + + bottom: string + + edgeToEdge?: true + centerToCenter?: true +} +/** + * Selector for bottom component, e.g. ".U1" or ".R1", you can also specify the + * edge or center of the component e.g. ".R1 bottomedge", ".R1 center" + */ +export type PcbSameYConstraint = { + pcb?: true + sameY?: true + + for: string[] +} +/** + * Selector for components, e.g. [".U1", ".R1"], you can also specify the + * edge or center of the component e.g. [".R1 leftedge", ".U1 center"] + */ +export type PcbSameXConstraint = { + pcb?: true + sameX?: true + for: string[] +} +export const pcbXDistConstraintProps = z.object({ + pcb: z.literal(true).optional(), + xDist: distance, + left: z.string(), + right: z.string(), + + edgeToEdge: z.literal(true).optional(), + centerToCenter: z.literal(true).optional(), +}) +export const pcbYDistConstraintProps = z.object({ + pcb: z.literal(true).optional(), + yDist: distance, + top: z.string(), + bottom: z.string(), + + edgeToEdge: z.literal(true).optional(), + centerToCenter: z.literal(true).optional(), +}) +export const pcbSameYConstraintProps = z.object({ + pcb: z.literal(true).optional(), + sameY: z.literal(true).optional(), + for: z.array(z.string()), +}) +export const pcbSameXConstraintProps = z.object({ + pcb: z.literal(true).optional(), + sameX: z.literal(true).optional(), + for: z.array(z.string()), +}) +``` + +```typescript +export interface CopperPourProps { + name?: string + layer: LayerRefInput + connectsTo: string + padMargin?: Distance + traceMargin?: Distance +} +export const copperPourProps = z.object({ + name: z.string().optional(), + layer: layer_ref, + connectsTo: z.string(), + padMargin: distance.optional(), + traceMargin: distance.optional(), +}) +``` + +```typescript +export interface CrystalProps + extends CommonComponentProps { + frequency: number | string + loadCapacitance: number | string + manufacturerPartNumber?: string + mpn?: string + pinVariant?: PinVariant + schOrientation?: SchematicOrientation + connections?: Connections +} +export const crystalProps = commonComponentProps.extend({ + frequency: frequency, + loadCapacitance: capacitance, + manufacturerPartNumber: z.string().optional(), + mpn: z.string().optional(), + pinVariant: z.enum(["two_pin", "four_pin"]).optional(), + schOrientation: schematicOrientation.optional(), + connections: createConnectionsProp(crystalPins).optional(), +}) +``` + +```typescript +export interface RectCutoutProps + extends Omit { + name?: string + shape: "rect" + width: Distance + height: Distance +} +export const rectCutoutProps = pcbLayoutProps + .omit({ + layer: true, + pcbRotation: true, + }) + .extend({ + name: z.string().optional(), + shape: z.literal("rect"), + width: distance, + height: distance, + }) +export interface CircleCutoutProps + extends Omit { + name?: string + shape: "circle" + radius: Distance +} +export const circleCutoutProps = pcbLayoutProps + .omit({ + layer: true, + pcbRotation: true, + }) + .extend({ + name: z.string().optional(), + shape: z.literal("circle"), + radius: distance, + }) +export interface PolygonCutoutProps + extends Omit { + name?: string + shape: "polygon" + points: Point[] +} +export const polygonCutoutProps = pcbLayoutProps + .omit({ + layer: true, + pcbRotation: true, + }) + .extend({ + name: z.string().optional(), + shape: z.literal("polygon"), + points: z.array(point), + }) +``` + +```typescript +.extend({ + connections: connectionsProp.optional(), + variant: diodeVariant.optional().default("standard"), + standard: z.boolean().optional(), + schottky: z.boolean().optional(), + zener: z.boolean().optional(), + avalanche: z.boolean().optional(), + photo: z.boolean().optional(), + tvs: z.boolean().optional(), + schOrientation: schematicOrientation.optional(), + }) +export interface DiodeProps + extends CommonComponentProps { + connections?: { + anode?: string | string[] | readonly string[] + cathode?: string | string[] | readonly string[] + pin1?: string | string[] | readonly string[] + pin2?: string | string[] | readonly string[] + pos?: string | string[] | readonly string[] + neg?: string | string[] | readonly string[] + } + variant?: "standard" | "schottky" | "zener" | "avalanche" | "photo" | "tvs" + standard?: boolean + schottky?: boolean + zener?: boolean + avalanche?: boolean + photo?: boolean + tvs?: boolean + schOrientation?: SchematicOrientation +} +``` + +```typescript +export const fabricationNotePathProps = pcbLayoutProps + .omit({ pcbX: true, pcbY: true, pcbRotation: true }) + .extend({ + route: z.array(route_hint_point), + strokeWidth: length.optional(), + color: z.string().optional(), + }) +``` + +```typescript +export const fabricationNoteTextProps = pcbLayoutProps.extend({ + text: z.string(), + anchorAlignment: z + .enum(["center", "top_left", "top_right", "bottom_left", "bottom_right"]) + .default("center"), + font: z.enum(["tscircuit2024"]).optional(), + fontSize: length.optional(), + color: z.string().optional(), +}) +``` + +```typescript +export interface FootprintProps { + originalLayer?: LayerRef +} +/** + * The layer that the footprint is designed for. If you set this to "top" + * then it means the children were intended to represent the top layer. If + * the with this footprint is moved to the bottom layer, then the + * components will be mirrored. + * + * Generally, you shouldn't set this except where it can help prevent + * confusion because you have a complex multi-layer footprint. Default is + * "top" and this is most intuitive. + */ +export const footprintProps = z.object({ + originalLayer: layer_ref.default("top").optional(), +}) +``` + +```typescript +export interface FuseProps + extends CommonComponentProps { + currentRating: number | string + + voltageRating?: number | string + + schShowRatings?: boolean + + schOrientation?: SchematicOrientation + + connections?: Connections +} +/** + * Schema for validating fuse props + */ +export const fuseProps = commonComponentProps.extend({ + currentRating: z.union([z.number(), z.string()]), + voltageRating: z.union([z.number(), z.string()]).optional(), + schShowRatings: z.boolean().optional(), + schOrientation: schematicOrientation.optional(), + connections: z + .record( + z.string(), + z.union([ + z.string(), + z.array(z.string()).readonly(), + z.array(z.string()), + ]), + ) + .optional(), +}) +``` + +```typescript +export const layoutConfig = z.object({ + layoutMode: z + .enum(["grid", "flex", "match-adapt", "relative", "none"]) + .optional(), + position: z.enum(["absolute", "relative"]).optional(), + + grid: z.boolean().optional(), + gridCols: z.number().or(z.string()).optional(), + gridRows: z.number().or(z.string()).optional(), + gridTemplateRows: z.string().optional(), + gridTemplateColumns: z.string().optional(), + gridTemplate: z.string().optional(), + gridGap: z.number().or(z.string()).optional(), + gridRowGap: z.number().or(z.string()).optional(), + gridColumnGap: z.number().or(z.string()).optional(), + + flex: z.boolean().or(z.string()).optional(), + flexDirection: z.enum(["row", "column"]).optional(), + alignItems: z.enum(["start", "center", "end", "stretch"]).optional(), + justifyContent: z + .enum([ + "start", + "center", + "end", + "stretch", + "space-between", + "space-around", + "space-evenly", + ]) + .optional(), + flexRow: z.boolean().optional(), + flexColumn: z.boolean().optional(), + gap: z.number().or(z.string()).optional(), + + pack: z + .boolean() + .optional() + .describe("Pack the contents of this group using a packing strategy"), + packOrderStrategy: z + .enum([ + "largest_to_smallest", + "first_to_last", + "highest_to_lowest_pin_count", + ]) + .optional(), + packPlacementStrategy: z + .enum(["shortest_connection_along_outline"]) + .optional(), + + padding: length.optional(), + paddingLeft: length.optional(), + paddingRight: length.optional(), + paddingTop: length.optional(), + paddingBottom: length.optional(), + paddingX: length.optional(), + paddingY: length.optional(), + + width: length.optional(), + height: length.optional(), + + matchAdapt: z.boolean().optional(), + matchAdaptTemplate: z.any().optional(), +}) +export interface LayoutConfig { + layoutMode?: "grid" | "flex" | "match-adapt" | "relative" | "none" + position?: "absolute" | "relative" + + grid?: boolean + gridCols?: number | string + gridRows?: number | string + gridTemplateRows?: string + gridTemplateColumns?: string + gridTemplate?: string + gridGap?: number | string + gridRowGap?: number | string + gridColumnGap?: number | string + + flex?: boolean | string + flexDirection?: "row" | "column" + alignItems?: "start" | "center" | "end" | "stretch" + justifyContent?: + | "start" + | "center" + | "end" + | "stretch" + | "space-between" + | "space-around" + | "space-evenly" + flexRow?: boolean + flexColumn?: boolean + gap?: number | string + + pack?: boolean + packOrderStrategy?: + | "largest_to_smallest" + | "first_to_last" + | "highest_to_lowest_pin_count" + packPlacementStrategy?: "shortest_connection_along_outline" + + padding?: Distance + paddingLeft?: Distance + paddingRight?: Distance + paddingTop?: Distance + paddingBottom?: Distance + paddingX?: Distance + paddingY?: Distance + + width?: Distance + height?: Distance + + matchAdapt?: boolean + matchAdaptTemplate?: any +} +export interface Border { + strokeWidth?: Distance + dashed?: boolean + solid?: boolean +} +export const border = z.object({ + strokeWidth: length.optional(), + dashed: z.boolean().optional(), + solid: z.boolean().optional(), +}) +export interface BaseGroupProps extends CommonLayoutProps, LayoutConfig { + name?: string + key?: any + children?: any + + schTitle?: string + + showAsSchematicBox?: boolean + + connections?: Connections + + schPinArrangement?: SchematicPinArrangement + + schPinSpacing?: Distance + + schPinStyle?: SchematicPinStyle + + pcbWidth?: Distance + pcbHeight?: Distance + schWidth?: Distance + schHeight?: Distance + + pcbLayout?: LayoutConfig + schLayout?: LayoutConfig + cellBorder?: Border | null + border?: Border | null + schPadding?: Distance + schPaddingLeft?: Distance + schPaddingRight?: Distance + schPaddingTop?: Distance + schPaddingBottom?: Distance + + pcbPadding?: Distance + pcbPaddingLeft?: Distance + pcbPaddingRight?: Distance + pcbPaddingTop?: Distance + pcbPaddingBottom?: Distance + + grid?: boolean + flex?: boolean | string + + pcbGrid?: boolean + pcbGridCols?: number | string + pcbGridRows?: number | string + pcbGridTemplateRows?: string + pcbGridTemplateColumns?: string + pcbGridTemplate?: string + pcbGridGap?: number | string + pcbGridRowGap?: number | string + pcbGridColumnGap?: number | string + + pcbFlex?: boolean | string + pcbFlexGap?: number | string + pcbFlexDirection?: "row" | "column" + pcbAlignItems?: "start" | "center" | "end" | "stretch" + pcbJustifyContent?: + | "start" + | "center" + | "end" + | "stretch" + | "space-between" + | "space-around" + | "space-evenly" + pcbFlexRow?: boolean + pcbFlexColumn?: boolean + pcbGap?: number | string + pcbPack?: boolean + pcbPackGap?: number | string + + schGrid?: boolean + schGridCols?: number | string + schGridRows?: number | string + schGridTemplateRows?: string + schGridTemplateColumns?: string + schGridTemplate?: string + schGridGap?: number | string + schGridRowGap?: number | string + schGridColumnGap?: number | string + + schFlex?: boolean | string + schFlexGap?: number | string + schFlexDirection?: "row" | "column" + schAlignItems?: "start" | "center" | "end" | "stretch" + schJustifyContent?: + | "start" + | "center" + | "end" + | "stretch" + | "space-between" + | "space-around" + | "space-evenly" + schFlexRow?: boolean + schFlexColumn?: boolean + schGap?: number | string + schPack?: boolean + schMatchAdapt?: boolean +} +/** @deprecated Use `pcbFlex` */ +export type PartsEngine = { + findPart: (params: { + sourceComponent: AnySourceComponent + footprinterString?: string + }) => Promise | SupplierPartNumbers +} +export interface PcbRouteCache { + pcbTraces: PcbTrace[] + cacheKey: string +} +export interface AutorouterConfig { + serverUrl?: string + inputFormat?: "simplified" | "circuit-json" + serverMode?: "job" | "solve-endpoint" + serverCacheEnabled?: boolean + cache?: PcbRouteCache + traceClearance?: Distance + groupMode?: + | "sequential_trace" + | "subcircuit" + | /** @deprecated Use "sequential_trace" */ "sequential-trace" + local?: boolean + algorithmFn?: (simpleRouteJson: any) => Promise + preset?: + | "sequential_trace" + | "subcircuit" + | "auto" + | "auto_local" + | "auto_cloud" + | "freerouting" + | /** @deprecated Use "sequential_trace" */ "sequential-trace" + | /** @deprecated Use "auto_local" */ "auto-local" + | /** @deprecated Use "auto_cloud" */ "auto-cloud" +} +export const autorouterConfig = z.object({ + serverUrl: z.string().optional(), + inputFormat: z.enum(["simplified", "circuit-json"]).optional(), + serverMode: z.enum(["job", "solve-endpoint"]).optional(), + serverCacheEnabled: z.boolean().optional(), + cache: z.custom((v) => true).optional(), + traceClearance: length.optional(), + groupMode: z + .enum(["sequential_trace", "subcircuit", "sequential-trace"]) + .optional(), + algorithmFn: z + .custom<(simpleRouteJson: any) => Promise>( + (v) => typeof v === "function" || v === undefined, + ) + .optional(), + preset: z + .enum([ + "sequential_trace", + "subcircuit", + "auto", + "auto_local", + "auto_cloud", + "freerouting", + "sequential-trace", + "auto-local", + "auto-cloud", + ]) + .optional(), + local: z.boolean().optional(), +}) +export interface SubcircuitGroupProps extends BaseGroupProps { + manualEdits?: ManualEditsFileInput + routingDisabled?: boolean + defaultTraceWidth?: Distance + minTraceWidth?: Distance + pcbRouteCache?: PcbRouteCache + + autorouter?: AutorouterProp + + schAutoLayoutEnabled?: boolean + + schTraceAutoLabelEnabled?: boolean + + schMaxTraceDistance?: Distance + + partsEngine?: PartsEngine + + square?: boolean + emptyArea?: string + filledArea?: string + + width?: number | string + height?: number | string + outline?: Point[] + outlineOffsetX?: number | string + outlineOffsetY?: number | string +} +/** Desired filled area of the board e.g. "22mm^2" or "20%" */ +export interface SubcircuitGroupPropsWithBool extends SubcircuitGroupProps { + subcircuit: true +} +export interface NonSubcircuitGroupProps extends BaseGroupProps { + subcircuit?: false | undefined +} +export const baseGroupProps = commonLayoutProps.extend({ + name: z.string().optional(), + children: z.any().optional(), + schTitle: z.string().optional(), + key: z.any().optional(), + showAsSchematicBox: z.boolean().optional(), + connections: z.record(z.string(), connectionTarget.optional()).optional(), + schPinArrangement: schematicPinArrangement.optional(), + schPinSpacing: length.optional(), + schPinStyle: schematicPinStyle.optional(), + + ...layoutConfig.shape, + grid: layoutConfig.shape.grid.describe("@deprecated use pcbGrid"), + flex: layoutConfig.shape.flex.describe("@deprecated use pcbFlex"), + pcbGrid: z.boolean().optional(), + pcbGridCols: z.number().or(z.string()).optional(), + pcbGridRows: z.number().or(z.string()).optional(), + pcbGridTemplateRows: z.string().optional(), + pcbGridTemplateColumns: z.string().optional(), + pcbGridTemplate: z.string().optional(), + pcbGridGap: z.number().or(z.string()).optional(), + pcbGridRowGap: z.number().or(z.string()).optional(), + pcbGridColumnGap: z.number().or(z.string()).optional(), + pcbFlex: z.boolean().or(z.string()).optional(), + pcbFlexGap: z.number().or(z.string()).optional(), + pcbFlexDirection: z.enum(["row", "column"]).optional(), + pcbAlignItems: z.enum(["start", "center", "end", "stretch"]).optional(), + pcbJustifyContent: z + .enum([ + "start", + "center", + "end", + "stretch", + "space-between", + "space-around", + "space-evenly", + ]) + .optional(), + pcbFlexRow: z.boolean().optional(), + pcbFlexColumn: z.boolean().optional(), + pcbGap: z.number().or(z.string()).optional(), + pcbPack: z.boolean().optional(), + pcbPackGap: z.number().or(z.string()).optional(), + + schGrid: z.boolean().optional(), + schGridCols: z.number().or(z.string()).optional(), + schGridRows: z.number().or(z.string()).optional(), + schGridTemplateRows: z.string().optional(), + schGridTemplateColumns: z.string().optional(), + schGridTemplate: z.string().optional(), + schGridGap: z.number().or(z.string()).optional(), + schGridRowGap: z.number().or(z.string()).optional(), + schGridColumnGap: z.number().or(z.string()).optional(), + + schFlex: z.boolean().or(z.string()).optional(), + schFlexGap: z.number().or(z.string()).optional(), + schFlexDirection: z.enum(["row", "column"]).optional(), + schAlignItems: z.enum(["start", "center", "end", "stretch"]).optional(), + schJustifyContent: z + .enum([ + "start", + "center", + "end", + "stretch", + "space-between", + "space-around", + "space-evenly", + ]) + .optional(), + schFlexRow: z.boolean().optional(), + schFlexColumn: z.boolean().optional(), + schGap: z.number().or(z.string()).optional(), + schPack: z.boolean().optional(), + schMatchAdapt: z.boolean().optional(), + pcbWidth: length.optional(), + pcbHeight: length.optional(), + schWidth: length.optional(), + schHeight: length.optional(), + pcbLayout: layoutConfig.optional(), + schLayout: layoutConfig.optional(), + cellBorder: border.nullable().optional(), + border: border.nullable().optional(), + schPadding: length.optional(), + schPaddingLeft: length.optional(), + schPaddingRight: length.optional(), + schPaddingTop: length.optional(), + schPaddingBottom: length.optional(), + pcbPadding: length.optional(), + pcbPaddingLeft: length.optional(), + pcbPaddingRight: length.optional(), + pcbPaddingTop: length.optional(), + pcbPaddingBottom: length.optional(), +}) +export const subcircuitGroupProps = baseGroupProps.extend({ + manualEdits: manual_edits_file.optional(), + schAutoLayoutEnabled: z.boolean().optional(), + schTraceAutoLabelEnabled: z.boolean().optional(), + schMaxTraceDistance: distance.optional(), + routingDisabled: z.boolean().optional(), + defaultTraceWidth: length.optional(), + minTraceWidth: length.optional(), + partsEngine: partsEngine.optional(), + pcbRouteCache: z.custom((v) => true).optional(), + autorouter: autorouterProp.optional(), + square: z.boolean().optional(), + emptyArea: z.string().optional(), + filledArea: z.string().optional(), + width: distance.optional(), + height: distance.optional(), + outline: z.array(point).optional(), + outlineOffsetX: distance.optional(), + outlineOffsetY: distance.optional(), +}) +export const subcircuitGroupPropsWithBool = subcircuitGroupProps.extend({ + subcircuit: z.literal(true), +}) +``` + +```typescript +export interface CircleHoleProps extends PcbLayoutProps { + name?: string + shape?: "circle" + diameter?: Distance + radius?: Distance +} +export interface PillHoleProps extends PcbLayoutProps { + name?: string + shape: "pill" + width: Distance + height: Distance +} +export type HoleProps = CircleHoleProps | PillHoleProps +const circleHoleProps = pcbLayoutProps + .extend({ + name: z.string().optional(), + shape: z.literal("circle").optional(), + diameter: distance.optional(), + radius: distance.optional(), + }) + .transform((d) => ({ + ...d, + diameter: d.diameter ?? 2 * d.radius!, + radius: d.radius ?? d.diameter! / 2, + })) +const pillHoleProps = pcbLayoutProps.extend({ + name: z.string().optional(), + shape: z.literal("pill"), + width: distance, + height: distance, +}) +export const holeProps = z.union([circleHoleProps, pillHoleProps]) +``` + +```typescript +export interface InductorProps + extends CommonComponentProps { + inductance: number | string + maxCurrentRating?: number | string + schOrientation?: SchematicOrientation + connections?: Connections +} +export const inductorProps = commonComponentProps.extend({ + inductance, + maxCurrentRating: z.union([z.string(), z.number()]).optional(), + schOrientation: schematicOrientation.optional(), + connections: createConnectionsProp(inductorPins).optional(), +}) +``` + +```typescript +export interface JumperProps extends CommonComponentProps { + manufacturerPartNumber?: string + pinLabels?: Record< + number | SchematicPinLabel, + SchematicPinLabel | SchematicPinLabel[] + > + schPinStyle?: SchematicPinStyle + schPinSpacing?: number | string + schWidth?: number | string + schHeight?: number | string + schDirection?: "left" | "right" + schPinArrangement?: SchematicPortArrangement + schPortArrangement?: SchematicPortArrangement + pcbPinLabels?: Record + pinCount?: 2 | 3 + internallyConnectedPins?: (string | number)[][] + connections?: Connections +} +/** + * Connections to other components + */ +export const jumperProps = commonComponentProps.extend({ + manufacturerPartNumber: z.string().optional(), + pinLabels: z + .record( + z.number().or(schematicPinLabel), + schematicPinLabel.or(z.array(schematicPinLabel)), + ) + .optional(), + schPinStyle: schematicPinStyle.optional(), + schPinSpacing: distance.optional(), + schWidth: distance.optional(), + schHeight: distance.optional(), + schDirection: z.enum(["left", "right"]).optional(), + schPinArrangement: schematicPinArrangement.optional(), + schPortArrangement: schematicPortArrangement.optional(), + pcbPinLabels: z.record(z.string(), z.string()).optional(), + pinCount: z.union([z.literal(2), z.literal(3)]).optional(), + internallyConnectedPins: z + .array(z.array(z.union([z.string(), z.number()]))) + .optional(), + connections: z + .custom() + .pipe(z.record(z.string(), connectionTarget)) + .optional(), +}) +``` + +```typescript +export const ledProps = commonComponentProps.extend({ + color: z.string().optional(), + wavelength: z.string().optional(), + schDisplayValue: z.string().optional(), + schOrientation: schematicOrientation.optional(), + connections: createConnectionsProp(lrPolarPins).optional(), + laser: z.boolean().optional(), +}) +``` + +```typescript +export interface MosfetProps + extends CommonComponentProps { + channelType: "n" | "p" + mosfetMode: "enhancement" | "depletion" +} +export const mosfetProps = commonComponentProps.extend({ + channelType: z.enum(["n", "p"]), + mosfetMode: z.enum(["enhancement", "depletion"]), +}) +export const mosfetPins = [ + "pin1", + "drain", + "pin2", + "source", + "pin3", + "gate", +] as const +``` + +```typescript +export interface NetProps { + name: string + connectsTo?: string | string[] +} +export const netProps = z.object({ + name: z.string(), + connectsTo: z.string().or(z.array(z.string())).optional(), +}) +``` + +```typescript +/** + * @deprecated Use NetLabelProps instead. + */ +export interface NetAliasProps { + net?: string + connection?: string + schX?: number | string + schY?: number | string + schRotation?: number | string + anchorSide?: "left" | "top" | "right" | "bottom" +} +/** @deprecated Use netLabelProps instead. */ +export const netAliasProps = z.object({ + net: z.string().optional(), + connection: z.string().optional(), + schX: distance.optional(), + schY: distance.optional(), + schRotation: rotation.optional(), + anchorSide: z.enum(["left", "top", "right", "bottom"]).optional(), +}) +``` + +```typescript +export interface NetLabelProps { + net?: string + connection?: string + connectsTo?: string | string[] + schX?: number | string + schY?: number | string + schRotation?: number | string + anchorSide?: "left" | "top" | "right" | "bottom" +} +export const netLabelProps = z.object({ + net: z.string().optional(), + connection: z.string().optional(), + connectsTo: z.string().or(z.array(z.string())).optional(), + schX: distance.optional(), + schY: distance.optional(), + schRotation: rotation.optional(), + anchorSide: z.enum(["left", "top", "right", "bottom"]).optional(), +}) +``` + +```typescript +pcbLayoutProps.omit({ pcbRotation: true }).extend({ + shape: z.literal("circle"), + radius: distance, + }), +pcbLayoutProps.extend({ + shape: z.literal("rect"), + width: distance, + height: distance, + }), +``` + +```typescript +export const pcbTraceProps = z.object({ + layer: z.string().optional(), + thickness: distance.optional(), + route: z.array(route_hint_point), +}) +``` + +```typescript +export interface PinHeaderProps extends CommonComponentProps { + pinCount: number + + pitch?: number | string + + schFacingDirection?: "up" | "down" | "left" | "right" + + gender?: "male" | "female" | "unpopulated" + + showSilkscreenPinLabels?: boolean + + pcbPinLabels?: Record + + doubleRow?: boolean + + rightAngle?: boolean + + pcbOrientation?: PcbOrientation + + holeDiameter?: number | string + + platedDiameter?: number | string + + pinLabels?: Record | SchematicPinLabel[] + + connections?: Connections + + facingDirection?: "left" | "right" + + schPinArrangement?: SchematicPinArrangement + + schPinStyle?: SchematicPinStyle + + schPinSpacing?: number | string + + schWidth?: number | string + + schHeight?: number | string +} +/** + * Schematic height + */ +export const pinHeaderProps = commonComponentProps.extend({ + pinCount: z.number(), + pitch: distance.optional(), + schFacingDirection: z.enum(["up", "down", "left", "right"]).optional(), + gender: z.enum(["male", "female", "unpopulated"]).optional().default("male"), + showSilkscreenPinLabels: z.boolean().optional(), + pcbPinLabels: z.record(z.string(), z.string()).optional(), + doubleRow: z.boolean().optional(), + rightAngle: z.boolean().optional(), + pcbOrientation: pcbOrientationProp.optional(), + holeDiameter: distance.optional(), + platedDiameter: distance.optional(), + pinLabels: z + .record(z.string(), schematicPinLabel) + .or(z.array(schematicPinLabel)) + .optional(), + connections: z + .custom() + .pipe(z.record(z.string(), connectionTarget)) + .optional(), + facingDirection: z.enum(["left", "right"]).optional(), + schPinArrangement: schematicPinArrangement.optional(), + schPinStyle: schematicPinStyle.optional(), + schPinSpacing: distance.optional(), + schWidth: distance.optional(), + schHeight: distance.optional(), +}) +``` + +```typescript +export interface PinoutProps< + PinLabelMap extends PinLabelsProp | string = string, +> extends ChipProps {} +``` + +```typescript +export interface CirclePlatedHoleProps + extends Omit { + name?: string + connectsTo?: string | string[] + shape: "circle" + holeDiameter: number | string + outerDiameter: number | string + portHints?: PortHints +} +export interface OvalPlatedHoleProps + extends Omit { + name?: string + connectsTo?: string | string[] + shape: "oval" + outerWidth: number | string + outerHeight: number | string + holeWidth: number | string + holeHeight: number | string + portHints?: PortHints + + innerWidth?: number | string + innerHeight?: number | string +} +/** @deprecated use holeHeight */ +export interface PillPlatedHoleProps extends Omit { + name?: string + rectPad?: boolean + connectsTo?: string | string[] + shape: "pill" + outerWidth: number | string + outerHeight: number | string + holeWidth: number | string + holeHeight: number | string + + innerWidth?: number | string + innerHeight?: number | string + + portHints?: PortHints +} +/** @deprecated use holeHeight */ +export interface CircularHoleWithRectPlatedProps + extends Omit { + name?: string + connectsTo?: string | string[] + shape: "circular_hole_with_rect_pad" + holeDiameter: number | string + rectPadWidth: number | string + rectPadHeight: number | string + holeShape?: "circle" + padShape?: "rect" + portHints?: PortHints + pcbHoleOffsetX?: number | string + pcbHoleOffsetY?: number | string +} +export interface PillWithRectPadPlatedHoleProps + extends Omit { + name?: string + connectsTo?: string | string[] + shape: "pill_hole_with_rect_pad" + holeShape: "pill" + padShape: "rect" + holeWidth: number | string + holeHeight: number | string + rectPadWidth: number | string + rectPadHeight: number | string + portHints?: PortHints +} +export type PlatedHoleProps = + | CirclePlatedHoleProps + | OvalPlatedHoleProps + | PillPlatedHoleProps + | CircularHoleWithRectPlatedProps + | PillWithRectPadPlatedHoleProps + +const distanceHiddenUndefined = z + .custom>() + .transform((a) => { + if (a === undefined) return undefined + return distance.parse(a) + }) +pcbLayoutProps.omit({ pcbRotation: true, layer: true }).extend({ + name: z.string().optional(), + connectsTo: z.string().or(z.array(z.string())).optional(), + shape: z.literal("circle"), + holeDiameter: distance, + outerDiameter: distance, + portHints: portHints.optional(), + }), +pcbLayoutProps.omit({ pcbRotation: true, layer: true }).extend({ + name: z.string().optional(), + connectsTo: z.string().or(z.array(z.string())).optional(), + shape: z.literal("oval"), + outerWidth: distance, + outerHeight: distance, + holeWidth: distanceHiddenUndefined, + holeHeight: distanceHiddenUndefined, + innerWidth: distance.optional().describe("DEPRECATED use holeWidth"), + innerHeight: distance.optional().describe("DEPRECATED use holeHeight"), + portHints: portHints.optional(), + }), +pcbLayoutProps.omit({ layer: true }).extend({ + name: z.string().optional(), + connectsTo: z.string().or(z.array(z.string())).optional(), + shape: z.literal("pill"), + rectPad: z.boolean().optional(), + outerWidth: distance, + outerHeight: distance, + holeWidth: distanceHiddenUndefined, + holeHeight: distanceHiddenUndefined, + innerWidth: distance.optional().describe("DEPRECATED use holeWidth"), + innerHeight: distance.optional().describe("DEPRECATED use holeHeight"), + portHints: portHints.optional(), + }), +pcbLayoutProps.omit({ pcbRotation: true, layer: true }).extend({ + name: z.string().optional(), + connectsTo: z.string().or(z.array(z.string())).optional(), + shape: z.literal("circular_hole_with_rect_pad"), + holeDiameter: distance, + rectPadWidth: distance, + rectPadHeight: distance, + holeShape: z.literal("circle").optional(), + padShape: z.literal("rect").optional(), + portHints: portHints.optional(), + pcbHoleOffsetX: distance.optional(), + pcbHoleOffsetY: distance.optional(), + }), +pcbLayoutProps.omit({ pcbRotation: true, layer: true }).extend({ + name: z.string().optional(), + connectsTo: z.string().or(z.array(z.string())).optional(), + shape: z.literal("pill_hole_with_rect_pad"), + holeShape: z.literal("pill"), + padShape: z.literal("rect"), + holeWidth: distance, + holeHeight: distance, + rectPadWidth: distance, + rectPadHeight: distance, + portHints: portHints.optional(), + }), +``` + +```typescript +export const portProps = commonLayoutProps.extend({ + name: z.string(), + pinNumber: z.number().optional(), + aliases: z.array(z.string()).optional(), + direction: direction, +}) +``` + +```typescript +export interface PotentiometerProps extends CommonComponentProps { + maxResistance: number | string + pinVariant?: PotentiometerPinVariant +} +export const potentiometerProps = commonComponentProps.extend({ + maxResistance: resistance, + pinVariant: z.enum(["two_pin", "three_pin"]).optional(), +}) +``` + +```typescript +export const powerSourceProps = commonComponentProps.extend({ + voltage, +}) +``` + +```typescript +export interface ResistorProps + extends CommonComponentProps { + resistance: number | string + pullupFor?: string + pullupTo?: string + pulldownFor?: string + pulldownTo?: string + schOrientation?: SchematicOrientation + connections?: Connections +} +export const resistorProps = commonComponentProps.extend({ + resistance, + + pullupFor: z.string().optional(), + pullupTo: z.string().optional(), + + pulldownFor: z.string().optional(), + pulldownTo: z.string().optional(), + + schOrientation: schematicOrientation.optional(), + + connections: createConnectionsProp(resistorPinLabels).optional(), +}) +``` + +```typescript +export interface ResonatorProps extends CommonComponentProps { + frequency: number | string + loadCapacitance: number | string + pinVariant?: ResonatorPinVariant +} +export const resonatorProps = commonComponentProps.extend({ + frequency: frequency, + loadCapacitance: capacitance, + pinVariant: z.enum(["no_ground", "ground_pin", "two_ground_pins"]).optional(), +}) +``` + +```typescript +export const schematicBoxProps = z + .object({ + schX: distance.optional(), + schY: distance.optional(), + width: distance.optional(), + height: distance.optional(), + overlay: z.array(z.string()).optional(), + + padding: distance.optional(), + paddingLeft: distance.optional(), + paddingRight: distance.optional(), + paddingTop: distance.optional(), + paddingBottom: distance.optional(), + + title: z.string().optional(), + titleAlignment: ninePointAnchor.default("top_left"), + titleColor: z.string().optional(), + titleFontSize: distance.optional(), + titleInside: z.boolean().default(false), + strokeStyle: z.enum(["solid", "dashed"]).default("solid"), + }) +``` + +```typescript +export const schematicCellProps = z.object({ + children: z.string().optional(), + horizontalAlign: z.enum(["left", "center", "right"]).optional(), + verticalAlign: z.enum(["top", "middle", "bottom"]).optional(), + fontSize: distance.optional(), + rowSpan: z.number().optional(), + colSpan: z.number().optional(), + width: distance.optional(), + text: z.string().optional(), +}) +export interface SchematicCellProps { + children?: string + horizontalAlign?: "left" | "center" | "right" + verticalAlign?: "top" | "middle" | "bottom" + fontSize?: number | string + rowSpan?: number + colSpan?: number + width?: number | string + text?: string +} +``` + +```typescript +export const schematicArcProps = z.object({ + center: point, + radius: distance, + startAngleDegrees: rotation, + endAngleDegrees: rotation, + direction: z.enum(["clockwise", "counterclockwise"]).default( + "counterclockwise", + ), + strokeWidth: distance.optional(), + color: z.string().optional().default("#000000"), + isDashed: z.boolean().optional().default(false), +}) +``` + +```typescript +export const schematicCircleProps = z.object({ + center: point, + radius: distance, + strokeWidth: distance.optional(), + color: z.string().optional().default("#000000"), + isFilled: z.boolean().optional().default(false), + fillColor: z.string().optional(), + isDashed: z.boolean().optional().default(false), +}) +``` + +```typescript +export const schematicLineProps = z.object({ + x1: distance, + y1: distance, + x2: distance, + y2: distance, + strokeWidth: distance.optional(), + color: z.string().optional().default("#000000"), + isDashed: z.boolean().optional().default(false), +}) +``` + +```typescript +export const schematicRectProps = z.object({ + center: point, + width: distance, + height: distance, + rotation: rotation.default(0), + strokeWidth: distance.optional(), + color: z.string().optional().default("#000000"), + isFilled: z.boolean().optional().default(false), + fillColor: z.string().optional(), + isDashed: z.boolean().optional().default(false), +}) +``` + +```typescript +export const schematicPathProps = z.object({ + points: z.array(point), + isFilled: z.boolean().optional().default(false), + fillColor: z.enum(["red", "blue"]).optional(), +}) +``` + +```typescript +export const schematicRowProps = z.object({ + children: z.any().optional(), + height: distance.optional(), +}) +export interface SchematicRowProps { + children?: any + height?: number | string +} +``` + +```typescript +export const schematicTableProps = z.object({ + schX: distance.optional(), + schY: distance.optional(), + children: z.any().optional(), + cellPadding: distance.optional(), + borderWidth: distance.optional(), + anchor: ninePointAnchor.optional(), + fontSize: distance.optional(), +}) +export interface SchematicTableProps { + schX?: number | string + schY?: number | string + children?: any + cellPadding?: number | string + borderWidth?: number | string + anchor?: z.infer + fontSize?: number | string +} +``` + +```typescript +export const schematicTextProps = z.object({ + schX: distance.optional(), + schY: distance.optional(), + text: z.string(), + fontSize: z.number().default(1), + anchor: z + .union([fivePointAnchor.describe("legacy"), ninePointAnchor]) + .default("center"), + color: z.string().default("#000000"), + schRotation: rotation.default(0), +}) +``` + +```typescript +export const silkscreenCircleProps = pcbLayoutProps + .omit({ pcbRotation: true }) + .extend({ + isFilled: z.boolean().optional(), + isOutline: z.boolean().optional(), + strokeWidth: distance.optional(), + radius: distance, + }) +``` + +```typescript +export const silkscreenLineProps = pcbLayoutProps + .omit({ pcbX: true, pcbY: true, pcbRotation: true }) + .extend({ + strokeWidth: distance, + x1: distance, + y1: distance, + x2: distance, + y2: distance, + }) +``` + +```typescript +export const silkscreenPathProps = pcbLayoutProps + .omit({ pcbX: true, pcbY: true, pcbRotation: true }) + .extend({ + route: z.array(route_hint_point), + strokeWidth: length.optional(), + }) +``` + +```typescript +export const silkscreenRectProps = pcbLayoutProps + .omit({ pcbRotation: true }) + .extend({ + filled: z.boolean().default(true).optional(), + stroke: z.enum(["dashed", "solid", "none"]).optional(), + strokeWidth: distance.optional(), + width: distance, + height: distance, + }) +``` + +```typescript +export const silkscreenTextProps = pcbLayoutProps.extend({ + text: z.string(), + anchorAlignment: ninePointAnchor.default("center"), + font: z.enum(["tscircuit2024"]).optional(), + fontSize: length.optional(), + isKnockout: z.boolean().optional(), + knockoutPadding: length.optional(), + knockoutPaddingLeft: length.optional(), + knockoutPaddingRight: length.optional(), + knockoutPaddingTop: length.optional(), + knockoutPaddingBottom: length.optional(), + layers: z.array(layer_ref).optional(), +}) +``` + +```typescript +export interface RectSmtPadProps extends Omit { + name?: string + shape: "rect" + width: Distance + height: Distance + portHints?: PortHints + coveredWithSolderMask?: boolean +} +export interface RotatedRectSmtPadProps + extends Omit { + name?: string + shape: "rotated_rect" + width: Distance + height: Distance + ccwRotation: number + portHints?: PortHints + coveredWithSolderMask?: boolean +} +export interface CircleSmtPadProps extends Omit { + name?: string + shape: "circle" + radius: Distance + portHints?: PortHints + coveredWithSolderMask?: boolean +} +export interface PillSmtPadProps extends Omit { + name?: string + shape: "pill" + width: Distance + height: Distance + radius: Distance + portHints?: PortHints + coveredWithSolderMask?: boolean +} +export interface PolygonSmtPadProps + extends Omit { + name?: string + shape: "polygon" + points: Point[] + portHints?: PortHints + coveredWithSolderMask?: boolean +} +export const rectSmtPadProps = pcbLayoutProps + .omit({ pcbRotation: true }) + .extend({ + name: z.string().optional(), + shape: z.literal("rect"), + width: distance, + height: distance, + portHints: portHints.optional(), + coveredWithSolderMask: z.boolean().optional(), + }) +export const rotatedRectSmtPadProps = pcbLayoutProps + .omit({ pcbRotation: true }) + .extend({ + name: z.string().optional(), + shape: z.literal("rotated_rect"), + width: distance, + height: distance, + ccwRotation: z.number(), + portHints: portHints.optional(), + coveredWithSolderMask: z.boolean().optional(), + }) +export const circleSmtPadProps = pcbLayoutProps + .omit({ pcbRotation: true }) + .extend({ + name: z.string().optional(), + shape: z.literal("circle"), + radius: distance, + portHints: portHints.optional(), + coveredWithSolderMask: z.boolean().optional(), + }) +export const pillSmtPadProps = pcbLayoutProps + .omit({ pcbRotation: true }) + .extend({ + name: z.string().optional(), + shape: z.literal("pill"), + width: distance, + height: distance, + radius: distance, + portHints: portHints.optional(), + coveredWithSolderMask: z.boolean().optional(), + }) +export const polygonSmtPadProps = pcbLayoutProps + .omit({ pcbRotation: true }) + .extend({ + name: z.string().optional(), + shape: z.literal("polygon"), + points: z.array(point), + portHints: portHints.optional(), + coveredWithSolderMask: z.boolean().optional(), + }) +``` + +```typescript +export interface SolderJumperProps extends JumperProps { + bridgedPins?: string[][] + bridged?: boolean +} +/** + * If true, all pins are connected with cuttable traces + */ +export const solderjumperProps = jumperProps.extend({ + bridgedPins: z.array(z.array(z.string())).optional(), + bridged: z.boolean().optional(), +}) +``` + +```typescript +export interface RectSolderPasteProps + extends Omit { + shape: "rect" + width: Distance + height: Distance +} +export interface CircleSolderPasteProps + extends Omit { + shape: "circle" + radius: Distance +} +export const rectSolderPasteProps = pcbLayoutProps + .omit({ pcbRotation: true }) + .extend({ + shape: z.literal("rect"), + width: distance, + height: distance, + }) +export const circleSolderPasteProps = pcbLayoutProps + .omit({ pcbRotation: true }) + .extend({ + shape: z.literal("circle"), + radius: distance, + }) +``` + +```typescript +export interface StampboardProps extends BoardProps { + leftPinCount?: number + rightPinCount?: number + topPinCount?: number + bottomPinCount?: number + leftPins?: string[] + rightPins?: string[] + topPins?: string[] + bottomPins?: string[] + pinPitch?: number | string + innerHoles?: boolean +} +export const stampboardProps = boardProps.extend({ + leftPinCount: z.number().optional(), + rightPinCount: z.number().optional(), + topPinCount: z.number().optional(), + bottomPinCount: z.number().optional(), + leftPins: z.array(z.string()).optional(), + rightPins: z.array(z.string()).optional(), + topPins: z.array(z.string()).optional(), + bottomPins: z.array(z.string()).optional(), + pinPitch: distance.optional(), + innerHoles: z.boolean().optional(), +}) +``` + +```typescript +export interface SwitchProps extends CommonComponentProps { + type?: "spst" | "spdt" | "dpst" | "dpdt" + isNormallyClosed?: boolean + spdt?: boolean + spst?: boolean + dpst?: boolean + dpdt?: boolean +} +.extend({ + type: z.enum(["spst", "spdt", "dpst", "dpdt"]).optional(), + isNormallyClosed: z.boolean().optional().default(false), + spst: z.boolean().optional(), + spdt: z.boolean().optional(), + dpst: z.boolean().optional(), + dpdt: z.boolean().optional(), + }) +``` + +```typescript +export interface SymbolProps { + originalFacingDirection?: "up" | "down" | "left" | "right" +} +/** + * The facing direction that the symbol is designed for. If you set this to "right", + * then it means the children were intended to represent the symbol facing right. + * Generally, you shouldn't set this except where it can help prevent confusion + * because you have a complex symbol. Default is "right" and this is most intuitive. + */ +export const symbolProps = z.object({ + originalFacingDirection: z + .enum(["up", "down", "left", "right"]) + .default("right") + .optional(), +}) +``` + +```typescript +export interface TestpointProps extends CommonComponentProps { + footprintVariant?: "pad" | "through_hole" + padShape?: "rect" | "circle" + padDiameter?: number | string + holeDiameter?: number | string + width?: number | string + height?: number | string +} +.extend({ + footprintVariant: z.enum(["pad", "through_hole"]).optional(), + padShape: z.enum(["rect", "circle"]).optional().default("circle"), + padDiameter: distance.optional(), + holeDiameter: distance.optional(), + width: distance.optional(), + height: distance.optional(), + }) +``` + +```typescript +export const routeHintPointProps = z.object({ + x: distance, + y: distance, + via: z.boolean().optional(), + toLayer: layer_ref.optional(), +}) +export const traceHintProps = z.object({ + for: z + .string() + .optional() + .describe( + "Selector for the port you're targeting, not required if you're inside a trace", + ), + order: z.number().optional(), + offset: route_hint_point.or(routeHintPointProps).optional(), + offsets: z + .array(route_hint_point) + .or(z.array(routeHintPointProps)) + .optional(), + traceWidth: z.number().optional(), +}) +``` + +```typescript +export const portRef = z.union([ + z.string(), + z.custom<{ getPortSelector: () => string }>((v) => +baseTraceProps.extend({ + path: z.array(portRef), + }), +baseTraceProps.extend({ + from: portRef, + to: portRef, + }), +``` + +```typescript +export const transistorPinsLabels = [ + "pin1", + "pin2", + "pin3", + "emitter", + "collector", + "base", + "gate", + "source", + "drain", +] as const +export interface TransistorProps + extends CommonComponentProps { + type: "npn" | "pnp" | "bjt" | "jfet" | "mosfet" | "igbt" + connections?: Connections +} +export const transistorProps = commonComponentProps.extend({ + type: z.enum(["npn", "pnp", "bjt", "jfet", "mosfet", "igbt"]), + connections: createConnectionsProp(transistorPinsLabels).optional(), +}) +export const transistorPins = [ + "pin1", + "emitter", + "pin2", + "collector", + "pin3", + "base", +] as const +``` + +```typescript +export interface ViaProps extends CommonLayoutProps { + name?: string + fromLayer: LayerRefInput + toLayer: LayerRefInput + holeDiameter: number | string + outerDiameter: number | string + connectsTo?: string | string[] +} +export const viaProps = commonLayoutProps.extend({ + name: z.string().optional(), + fromLayer: layer_ref, + toLayer: layer_ref, + holeDiameter: distance, + outerDiameter: distance, + connectsTo: z.string().or(z.array(z.string())).optional(), +}) +``` + +```typescript +export interface VoltageSourceProps + extends CommonComponentProps { + voltage?: number | string + frequency?: number | string + peakToPeakVoltage?: number | string + waveShape?: WaveShape + phase?: number | string + dutyCycle?: number | string + connections?: Connections +} +export const voltageSourceProps = commonComponentProps.extend({ + voltage: voltage.optional(), + frequency: frequency.optional(), + peakToPeakVoltage: voltage.optional(), + waveShape: z.enum(["sinewave", "square", "triangle", "sawtooth"]).optional(), + phase: rotation.optional(), + dutyCycle: percentage.optional(), + connections: createConnectionsProp(voltageSourcePinLabels).optional(), +}) +``` + + + +- Here is a list of unsupported components: + +1- powersource +2- powersourcesimple +3- pinheader + +- Here are examples of how you can take advantage of those props: + + // Example of a custom chip footprint definition + const CustomChipFootprint = () => ( + + // SMT pads for the chip + + + + + + // Silkscreen markings for the chip outline + + // Pin 1 indicator + + + ) + + // Example of a custom resistor footprint + const Resistor0603Footprint = () => ( + + + + + + ) + + // Example of a complete circuit + export const MyCircuit = () => ( + + // Power section group + + // Decoupling capacitor arrangement + + + + + + // Input protection group + + + + + + + // Power nets + + + + // Connections + + + + // Layout constraints + + + ) + + // Example of a custom module/component that can be reused + export const DecouplingCapacitor = ({ + chipRef, + capName, + capValue = "100nF", + distance = "2mm" + }) => ( + + + + + ) + + // Usage of the custom module + export const CircuitWithDecoupling = () => ( + + + + + ) + + +### RULES + +- decouplingFor must contain the selector for the component and the pin(eg. ".U1 .pin1", ".T1 .pin1") +- Never pass the component name alone as a selector for decouplingFor, always use the component name reference and the pin number +- Don't use hole or port components, always connect to the component pins +- Don't use inline comments which are comments in the same line as components, they are forbidden +- Port components must be children to a chip component. +- Never use components in the "Unsupported components" list +- Never use footprints in the "Unsupported footprints" list +- Any component may have a pcbX and/or a pcbY representing the center of the + component on a circuit board. +- Never use footprints that are not supported in the "All available footprints" section +- Some footprints have a fixed number of pins like ms012 and sot723 +- `` components use CSS selectors in the `from` and `to` fields + to connect components. +- Any component can have a `name` prop +- `pcbX` and `pcbY` are optional and default to 0. +- A board is centered on the origin (pcbX=0, pcbY=0), so to place a component + at the center it must be placed at pcbX=0,pcbY=0. Similarly, if you're trying + to layout components around the center, you would make ones to the left of + the center have negative pcbX values, below the center have negative pcbY, + and to the right of the center have positive pcbX values, and above the + center have positive pcbY values. +- Every component that is going to be placed must be given a footprint +- Traces can only take two ports +- Don't use path as prop for trace, only use from, to +- We don't support defining output ports, so don't defined port components +- Don't specify autorouter; don't use the autorouter prop +- Selectors for component pins must be of this format: ".U1 > .pin1" or ".U1 > .pin2" where U1 is the component name, and the pins must be numbers, so don't use names for pins but use pin1, pin2, pin3, pin4 +- And instead of ".T1 > .base" you do do ".T1 > .pin2" +- "for" must have at least two selectors for constraints + +### Trace Reference Syntax + +Traces are created using the `` component. The `from` and `to` +fields are CSS selectors that reference the components to connect. + +Examples: + + + + + +### Output + +Use a codefence with the language "tsx" to wrap the code. You can use the +current_code of the user as a starting point (if provided). + +You must export a higher-order component where the root component is `` +inside the codefence. For example: + +```tsx +export const MyLed = () => ( + + + + + +) +``` \ No newline at end of file diff --git a/lib/prompt-templates/create-local-circuit-prompt.ts b/lib/prompt-templates/create-local-circuit-prompt.ts index a93f11f..90c1444 100644 --- a/lib/prompt-templates/create-local-circuit-prompt.ts +++ b/lib/prompt-templates/create-local-circuit-prompt.ts @@ -3,6 +3,7 @@ import { getFootprintSizes, fp, } from "@tscircuit/footprinter" +import { fetchTSCircuitAIDocs } from "../utils/fetch-tscircuit-context" async function fetchFileContent(url: string): Promise { try { @@ -44,12 +45,17 @@ export const createLocalCircuitPrompt = async () => { .join("\n") .replace(/\n\n+/g, "\n\n") + // Fetch comprehensive TSCircuit AI documentation + const tscircuitAIDocs = await fetchTSCircuitAIDocs() + return ` You are an expert in electronic circuit design and tscircuit, and your job is to create a circuit board in tscircuit with the user-provided description. YOU MUST ABIDE BY THE RULES IN THE RULES SECTION -## tscircuit API overview +## TSCircuit Comprehensive Documentation + +${tscircuitAIDocs ? `${tscircuitAIDocs}\n\n` : ''}## tscircuit API overview Here's an overview of the tscircuit API: diff --git a/lib/utils/fetch-tscircuit-context.ts b/lib/utils/fetch-tscircuit-context.ts new file mode 100644 index 0000000..406e8e9 --- /dev/null +++ b/lib/utils/fetch-tscircuit-context.ts @@ -0,0 +1,28 @@ +/** + * Utility to fetch TSCircuit AI documentation + */ + +export async function fetchTSCircuitAIDocs(): Promise { + try { + console.log("Fetching TSCircuit AI documentation from docs.tscircuit.com/ai.txt") + + const response = await fetch("https://docs.tscircuit.com/ai.txt", { + headers: { + 'User-Agent': 'tscircuit-prompt-benchmarks' + } + }) + + if (!response.ok) { + throw new Error(`HTTP ${response.status}: ${response.statusText}`) + } + + const docs = await response.text() + console.log(`Successfully fetched TSCircuit AI docs (${docs.length} characters)`) + return docs + + } catch (error) { + console.warn("Failed to fetch TSCircuit AI docs:", error) + console.log("Continuing without TSCircuit AI context") + return "" + } +} \ No newline at end of file