kicadts 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (195) hide show
  1. package/dist/index.d.ts +4466 -0
  2. package/dist/index.js +14253 -0
  3. package/package.json +5 -2
  4. package/.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc +0 -111
  5. package/.github/workflows/bun-formatcheck.yml +0 -26
  6. package/.github/workflows/bun-pver-release.yml +0 -70
  7. package/.github/workflows/bun-test.yml +0 -32
  8. package/.github/workflows/bun-typecheck.yml +0 -26
  9. package/.vscode/settings.json +0 -16
  10. package/AGENTS.md +0 -31
  11. package/TODO.md +0 -46
  12. package/biome.json +0 -93
  13. package/bunfig.toml +0 -5
  14. package/lib/index.ts +0 -1
  15. package/lib/sexpr/base-classes/SxClass.ts +0 -164
  16. package/lib/sexpr/base-classes/SxPrimitiveBoolean.ts +0 -35
  17. package/lib/sexpr/base-classes/SxPrimitiveNumber.ts +0 -26
  18. package/lib/sexpr/base-classes/SxPrimitiveString.ts +0 -26
  19. package/lib/sexpr/classes/At.ts +0 -53
  20. package/lib/sexpr/classes/Bus.ts +0 -103
  21. package/lib/sexpr/classes/BusEntry.ts +0 -169
  22. package/lib/sexpr/classes/Color.ts +0 -29
  23. package/lib/sexpr/classes/Dnp.ts +0 -8
  24. package/lib/sexpr/classes/EmbeddedFonts.ts +0 -68
  25. package/lib/sexpr/classes/ExcludeFromSim.ts +0 -8
  26. package/lib/sexpr/classes/FieldsAutoplaced.ts +0 -8
  27. package/lib/sexpr/classes/Footprint.ts +0 -849
  28. package/lib/sexpr/classes/FootprintAttr.ts +0 -104
  29. package/lib/sexpr/classes/FootprintAutoplaceCost180.ts +0 -9
  30. package/lib/sexpr/classes/FootprintAutoplaceCost90.ts +0 -9
  31. package/lib/sexpr/classes/FootprintClearance.ts +0 -9
  32. package/lib/sexpr/classes/FootprintDescr.ts +0 -44
  33. package/lib/sexpr/classes/FootprintLocked.ts +0 -32
  34. package/lib/sexpr/classes/FootprintModel.ts +0 -142
  35. package/lib/sexpr/classes/FootprintNetTiePadGroups.ts +0 -52
  36. package/lib/sexpr/classes/FootprintPad.ts +0 -857
  37. package/lib/sexpr/classes/FootprintPath.ts +0 -44
  38. package/lib/sexpr/classes/FootprintPlaced.ts +0 -32
  39. package/lib/sexpr/classes/FootprintPrivateLayers.ts +0 -56
  40. package/lib/sexpr/classes/FootprintSheetfile.ts +0 -44
  41. package/lib/sexpr/classes/FootprintSheetname.ts +0 -44
  42. package/lib/sexpr/classes/FootprintSolderMaskMargin.ts +0 -9
  43. package/lib/sexpr/classes/FootprintSolderPasteMargin.ts +0 -9
  44. package/lib/sexpr/classes/FootprintSolderPasteRatio.ts +0 -9
  45. package/lib/sexpr/classes/FootprintTags.ts +0 -44
  46. package/lib/sexpr/classes/FootprintTedit.ts +0 -21
  47. package/lib/sexpr/classes/FootprintThermalGap.ts +0 -9
  48. package/lib/sexpr/classes/FootprintThermalWidth.ts +0 -9
  49. package/lib/sexpr/classes/FootprintZoneConnect.ts +0 -9
  50. package/lib/sexpr/classes/FpArc.ts +0 -312
  51. package/lib/sexpr/classes/FpCircle.ts +0 -314
  52. package/lib/sexpr/classes/FpLine.ts +0 -316
  53. package/lib/sexpr/classes/FpPoly.ts +0 -286
  54. package/lib/sexpr/classes/FpPolyFill.ts +0 -48
  55. package/lib/sexpr/classes/FpPolyLocked.ts +0 -40
  56. package/lib/sexpr/classes/FpRect.ts +0 -314
  57. package/lib/sexpr/classes/FpText.ts +0 -375
  58. package/lib/sexpr/classes/FpTextBox.ts +0 -450
  59. package/lib/sexpr/classes/GrLine.ts +0 -264
  60. package/lib/sexpr/classes/GrLineAngle.ts +0 -32
  61. package/lib/sexpr/classes/GrLineEnd.ts +0 -61
  62. package/lib/sexpr/classes/GrLineLocked.ts +0 -40
  63. package/lib/sexpr/classes/GrLineStart.ts +0 -61
  64. package/lib/sexpr/classes/GrText.ts +0 -228
  65. package/lib/sexpr/classes/Image.ts +0 -283
  66. package/lib/sexpr/classes/InBom.ts +0 -8
  67. package/lib/sexpr/classes/Junction.ts +0 -166
  68. package/lib/sexpr/classes/KicadPcb.ts +0 -361
  69. package/lib/sexpr/classes/KicadSch.ts +0 -397
  70. package/lib/sexpr/classes/KicadSchGenerator.ts +0 -32
  71. package/lib/sexpr/classes/KicadSchGeneratorVersion.ts +0 -30
  72. package/lib/sexpr/classes/KicadSchVersion.ts +0 -22
  73. package/lib/sexpr/classes/Label.ts +0 -176
  74. package/lib/sexpr/classes/Layer.ts +0 -51
  75. package/lib/sexpr/classes/Layers.ts +0 -47
  76. package/lib/sexpr/classes/LibSymbols.ts +0 -61
  77. package/lib/sexpr/classes/NoConnect.ts +0 -90
  78. package/lib/sexpr/classes/OnBoard.ts +0 -8
  79. package/lib/sexpr/classes/PadChamfer.ts +0 -50
  80. package/lib/sexpr/classes/PadChamferRatio.ts +0 -9
  81. package/lib/sexpr/classes/PadClearance.ts +0 -9
  82. package/lib/sexpr/classes/PadDieLength.ts +0 -9
  83. package/lib/sexpr/classes/PadDrill.ts +0 -145
  84. package/lib/sexpr/classes/PadDrillOffset.ts +0 -54
  85. package/lib/sexpr/classes/PadLayers.ts +0 -71
  86. package/lib/sexpr/classes/PadNet.ts +0 -56
  87. package/lib/sexpr/classes/PadOptions.ts +0 -181
  88. package/lib/sexpr/classes/PadPinFunction.ts +0 -9
  89. package/lib/sexpr/classes/PadPinType.ts +0 -9
  90. package/lib/sexpr/classes/PadPrimitiveGrArc.ts +0 -272
  91. package/lib/sexpr/classes/PadPrimitiveGrCircle.ts +0 -298
  92. package/lib/sexpr/classes/PadPrimitiveGrLine.ts +0 -126
  93. package/lib/sexpr/classes/PadPrimitives.ts +0 -291
  94. package/lib/sexpr/classes/PadRectDelta.ts +0 -57
  95. package/lib/sexpr/classes/PadRoundrectRratio.ts +0 -9
  96. package/lib/sexpr/classes/PadSize.ts +0 -69
  97. package/lib/sexpr/classes/PadSolderMaskMargin.ts +0 -9
  98. package/lib/sexpr/classes/PadSolderPasteMargin.ts +0 -9
  99. package/lib/sexpr/classes/PadSolderPasteMarginRatio.ts +0 -9
  100. package/lib/sexpr/classes/PadTeardrops.ts +0 -210
  101. package/lib/sexpr/classes/PadThermalBridgeAngle.ts +0 -9
  102. package/lib/sexpr/classes/PadThermalGap.ts +0 -9
  103. package/lib/sexpr/classes/PadThermalWidth.ts +0 -9
  104. package/lib/sexpr/classes/PadZoneConnect.ts +0 -9
  105. package/lib/sexpr/classes/Paper.ts +0 -119
  106. package/lib/sexpr/classes/PcbGeneral.ts +0 -82
  107. package/lib/sexpr/classes/PcbGeneralLegacyTeardrops.ts +0 -44
  108. package/lib/sexpr/classes/PcbGeneralThickness.ts +0 -9
  109. package/lib/sexpr/classes/PcbGenerator.ts +0 -16
  110. package/lib/sexpr/classes/PcbGeneratorVersion.ts +0 -16
  111. package/lib/sexpr/classes/PcbLayerDefinition.ts +0 -106
  112. package/lib/sexpr/classes/PcbLayers.ts +0 -34
  113. package/lib/sexpr/classes/PcbNet.ts +0 -56
  114. package/lib/sexpr/classes/PcbVersion.ts +0 -9
  115. package/lib/sexpr/classes/Property.ts +0 -301
  116. package/lib/sexpr/classes/PropertyHide.ts +0 -9
  117. package/lib/sexpr/classes/PropertyUnlocked.ts +0 -9
  118. package/lib/sexpr/classes/Pts.ts +0 -67
  119. package/lib/sexpr/classes/RenderCache.ts +0 -221
  120. package/lib/sexpr/classes/SchematicText.ts +0 -171
  121. package/lib/sexpr/classes/Segment.ts +0 -243
  122. package/lib/sexpr/classes/SegmentEnd.ts +0 -59
  123. package/lib/sexpr/classes/SegmentLocked.ts +0 -33
  124. package/lib/sexpr/classes/SegmentNet.ts +0 -64
  125. package/lib/sexpr/classes/SegmentStart.ts +0 -59
  126. package/lib/sexpr/classes/Setup/PcbPlotParams.ts +0 -689
  127. package/lib/sexpr/classes/Setup/PcbPlotParamsBase.ts +0 -9
  128. package/lib/sexpr/classes/Setup/PcbPlotParamsNumericProperties.ts +0 -105
  129. package/lib/sexpr/classes/Setup/PcbPlotParamsStringPropertiesA.ts +0 -104
  130. package/lib/sexpr/classes/Setup/PcbPlotParamsStringPropertiesB.ts +0 -105
  131. package/lib/sexpr/classes/Setup/Setup.ts +0 -574
  132. package/lib/sexpr/classes/Setup/SetupPropertyTypes.ts +0 -119
  133. package/lib/sexpr/classes/Setup/Stackup.ts +0 -135
  134. package/lib/sexpr/classes/Setup/StackupLayer.ts +0 -233
  135. package/lib/sexpr/classes/Setup/StackupLayerProperties.ts +0 -80
  136. package/lib/sexpr/classes/Setup/StackupProperties.ts +0 -40
  137. package/lib/sexpr/classes/Setup/base.ts +0 -165
  138. package/lib/sexpr/classes/Setup/index.ts +0 -14
  139. package/lib/sexpr/classes/Setup/setupMultiValueProperties.ts +0 -53
  140. package/lib/sexpr/classes/Setup/setupNumericProperties.ts +0 -151
  141. package/lib/sexpr/classes/Setup/setupPropertyHandlers.ts +0 -90
  142. package/lib/sexpr/classes/Setup/setupStringProperties.ts +0 -75
  143. package/lib/sexpr/classes/Sheet.ts +0 -287
  144. package/lib/sexpr/classes/SheetFill.ts +0 -44
  145. package/lib/sexpr/classes/SheetInstances.ts +0 -168
  146. package/lib/sexpr/classes/SheetInstancesRoot.ts +0 -165
  147. package/lib/sexpr/classes/SheetPin.ts +0 -125
  148. package/lib/sexpr/classes/SheetProperty.ts +0 -115
  149. package/lib/sexpr/classes/SheetSize.ts +0 -44
  150. package/lib/sexpr/classes/Stroke.ts +0 -58
  151. package/lib/sexpr/classes/StrokeType.ts +0 -34
  152. package/lib/sexpr/classes/Symbol.ts +0 -1666
  153. package/lib/sexpr/classes/TextEffects.ts +0 -461
  154. package/lib/sexpr/classes/TitleBlock.ts +0 -369
  155. package/lib/sexpr/classes/Unit.ts +0 -28
  156. package/lib/sexpr/classes/Uuid.ts +0 -8
  157. package/lib/sexpr/classes/Via.ts +0 -363
  158. package/lib/sexpr/classes/ViaNet.ts +0 -60
  159. package/lib/sexpr/classes/Width.ts +0 -8
  160. package/lib/sexpr/classes/Wire.ts +0 -111
  161. package/lib/sexpr/classes/Xy.ts +0 -33
  162. package/lib/sexpr/classes/Zone.ts +0 -39
  163. package/lib/sexpr/index.ts +0 -130
  164. package/lib/sexpr/parseKicadSexpr.ts +0 -5
  165. package/lib/sexpr/parseToPrimitiveSExpr.ts +0 -245
  166. package/lib/sexpr/utils/indentLines.ts +0 -3
  167. package/lib/sexpr/utils/parseYesNo.ts +0 -12
  168. package/lib/sexpr/utils/quoteSExprString.ts +0 -8
  169. package/lib/sexpr/utils/strokeFromArgs.ts +0 -18
  170. package/lib/sexpr/utils/toNumberValue.ts +0 -13
  171. package/lib/sexpr/utils/toStringValue.ts +0 -11
  172. package/scripts/download-references.ts +0 -68
  173. package/tests/fixtures/expectEqualPrimitiveSExpr.ts +0 -199
  174. package/tests/fixtures/png-matcher.ts +0 -109
  175. package/tests/fixtures/preload.ts +0 -1
  176. package/tests/sexpr/KicadPcbDemos.test.ts +0 -48
  177. package/tests/sexpr/KicadSchDemos.test.ts +0 -49
  178. package/tests/sexpr/classes/Footprint.test.ts +0 -277
  179. package/tests/sexpr/classes/FootprintPad.test.ts +0 -78
  180. package/tests/sexpr/classes/FpArc.test.ts +0 -45
  181. package/tests/sexpr/classes/FpCircle.test.ts +0 -39
  182. package/tests/sexpr/classes/FpPoly.test.ts +0 -43
  183. package/tests/sexpr/classes/FpRect.test.ts +0 -40
  184. package/tests/sexpr/classes/FpTextBox.test.ts +0 -84
  185. package/tests/sexpr/classes/Image.test.ts +0 -58
  186. package/tests/sexpr/classes/KicadSch.test.ts +0 -95
  187. package/tests/sexpr/classes/Paper.test.ts +0 -30
  188. package/tests/sexpr/classes/Property.test.ts +0 -48
  189. package/tests/sexpr/classes/Setup.test.ts +0 -188
  190. package/tests/sexpr/classes/Sheet.test.ts +0 -107
  191. package/tests/sexpr/classes/Stroke.test.ts +0 -15
  192. package/tests/sexpr/classes/Symbol.test.ts +0 -96
  193. package/tests/sexpr/classes/TextEffects.test.ts +0 -56
  194. package/tests/sexpr/classes/TitleBlock.test.ts +0 -40
  195. package/tsconfig.json +0 -35
@@ -1,857 +0,0 @@
1
- import { SxClass } from "../base-classes/SxClass"
2
- import { SxPrimitiveBoolean } from "../base-classes/SxPrimitiveBoolean"
3
- import type { PrimitiveSExpr } from "../parseToPrimitiveSExpr"
4
- import { printSExpr } from "../parseToPrimitiveSExpr"
5
- import { quoteSExprString } from "../utils/quoteSExprString"
6
- import { toStringValue } from "../utils/toStringValue"
7
- import { At, type AtInput } from "./At"
8
- import { PadChamfer } from "./PadChamfer"
9
- import { PadChamferRatio } from "./PadChamferRatio"
10
- import { PadClearance } from "./PadClearance"
11
- import { PadDieLength } from "./PadDieLength"
12
- import { PadDrill } from "./PadDrill"
13
- import { PadLayers, type PadLayersInput } from "./PadLayers"
14
- import { PadNet } from "./PadNet"
15
- import { PadOptions } from "./PadOptions"
16
- import { PadPinFunction } from "./PadPinFunction"
17
- import { PadPinType } from "./PadPinType"
18
- import { PadPrimitives } from "./PadPrimitives"
19
- import { PadRoundrectRratio } from "./PadRoundrectRratio"
20
- import { PadSize, type PadSizeInput } from "./PadSize"
21
- import { PadSolderMaskMargin } from "./PadSolderMaskMargin"
22
- import { PadSolderPasteMargin } from "./PadSolderPasteMargin"
23
- import { PadSolderPasteMarginRatio } from "./PadSolderPasteMarginRatio"
24
- import { PadThermalGap } from "./PadThermalGap"
25
- import { PadThermalWidth } from "./PadThermalWidth"
26
- import { PadThermalBridgeAngle } from "./PadThermalBridgeAngle"
27
- import { PadZoneConnect } from "./PadZoneConnect"
28
- import { Property } from "./Property"
29
- import { Stroke } from "./Stroke"
30
- import { Uuid } from "./Uuid"
31
- import { Width } from "./Width"
32
- import { PadTeardrops } from "./PadTeardrops"
33
- import { PadRectDelta } from "./PadRectDelta"
34
-
35
- const SINGLE_TOKENS = new Set([
36
- "at",
37
- "size",
38
- "drill",
39
- "layers",
40
- "width",
41
- "stroke",
42
- "rect_delta",
43
- "roundrect_rratio",
44
- "chamfer_ratio",
45
- "chamfer",
46
- "net",
47
- "uuid",
48
- "pinfunction",
49
- "pintype",
50
- "die_length",
51
- "solder_mask_margin",
52
- "solder_paste_margin",
53
- "solder_paste_margin_ratio",
54
- "clearance",
55
- "zone_connect",
56
- "thermal_width",
57
- "thermal_gap",
58
- "thermal_bridge_angle",
59
- "options",
60
- "primitives",
61
- "remove_unused_layers",
62
- "keep_end_layers",
63
- "teardrops",
64
- ])
65
-
66
- const MULTI_TOKENS = new Set(["property"])
67
-
68
- const SUPPORTED_TOKENS = new Set([...SINGLE_TOKENS, ...MULTI_TOKENS])
69
-
70
- const ensureSingle = (
71
- arrayPropertyMap: Record<string, SxClass[]>,
72
- token: string,
73
- ) => {
74
- const entries = arrayPropertyMap[token]
75
- if (entries && entries.length > 1) {
76
- throw new Error(`pad does not support repeated "${token}" children`)
77
- }
78
- }
79
-
80
- export interface FootprintPadConstructorParams {
81
- number?: string
82
- padType?: string
83
- shape?: string
84
- locked?: boolean
85
- removeUnusedLayers?: boolean
86
- keepEndLayers?: boolean
87
- at?: AtInput
88
- size?: PadSizeInput
89
- drill?: PadDrill
90
- layers?: PadLayersInput
91
- width?: Width | number
92
- stroke?: Stroke
93
- properties?: Property[]
94
- roundrectRatio?: number | PadRoundrectRratio
95
- chamferRatio?: number | PadChamferRatio
96
- chamfer?: PadChamfer
97
- rectDelta?: PadRectDelta
98
- net?: PadNet
99
- uuid?: Uuid | string
100
- pinFunction?: string | PadPinFunction
101
- pinType?: string | PadPinType
102
- dieLength?: number | PadDieLength
103
- solderMaskMargin?: number | PadSolderMaskMargin
104
- solderPasteMargin?: number | PadSolderPasteMargin
105
- solderPasteMarginRatio?: number | PadSolderPasteMarginRatio
106
- clearance?: number | PadClearance
107
- zoneConnect?: number | PadZoneConnect
108
- thermalWidth?: number | PadThermalWidth
109
- thermalGap?: number | PadThermalGap
110
- thermalBridgeAngle?: number | PadThermalBridgeAngle
111
- options?: PadOptions
112
- primitives?: PadPrimitives
113
- teardrops?: PadTeardrops
114
- }
115
-
116
- export class FootprintPad extends SxClass {
117
- static override token = "pad"
118
- token = "pad"
119
-
120
- private _number = ""
121
- private _padType = ""
122
- private _shape = ""
123
- private _locked = false
124
- private _sxRemoveUnusedLayers?: PadRemoveUnusedLayers
125
- private _sxKeepEndLayers?: PadKeepEndLayers
126
-
127
- private _sxAt?: At
128
- private _sxSize?: PadSize
129
- private _sxDrill?: PadDrill
130
- private _sxLayers?: PadLayers
131
- private _sxWidth?: Width
132
- private _sxStroke?: Stroke
133
- private _properties: Property[] = []
134
- private _sxRoundrectRatio?: PadRoundrectRratio
135
- private _sxChamferRatio?: PadChamferRatio
136
- private _sxChamfer?: PadChamfer
137
- private _sxRectDelta?: PadRectDelta
138
- private _sxNet?: PadNet
139
- private _sxUuid?: Uuid
140
- private _sxPinFunction?: PadPinFunction
141
- private _sxPinType?: PadPinType
142
- private _sxDieLength?: PadDieLength
143
- private _sxSolderMaskMargin?: PadSolderMaskMargin
144
- private _sxSolderPasteMargin?: PadSolderPasteMargin
145
- private _sxSolderPasteMarginRatio?: PadSolderPasteMarginRatio
146
- private _sxClearance?: PadClearance
147
- private _sxZoneConnect?: PadZoneConnect
148
- private _sxThermalWidth?: PadThermalWidth
149
- private _sxThermalGap?: PadThermalGap
150
- private _sxThermalBridgeAngle?: PadThermalBridgeAngle
151
- private _sxOptions?: PadOptions
152
- private _sxPrimitives?: PadPrimitives
153
- private _sxTeardrops?: PadTeardrops
154
-
155
- constructor(
156
- params?: FootprintPadConstructorParams | string,
157
- padType?: string,
158
- shape?: string,
159
- ) {
160
- super()
161
-
162
- // Support legacy string-based constructor
163
- if (typeof params === "string") {
164
- this._number = params
165
- this._padType = padType || ""
166
- this._shape = shape || ""
167
- return
168
- }
169
-
170
- // Modern params-based constructor
171
- const p = params || {}
172
- if (p.number !== undefined) this.number = p.number
173
- if (p.padType !== undefined) this.padType = p.padType
174
- if (p.shape !== undefined) this.shape = p.shape
175
- if (p.locked !== undefined) this.locked = p.locked
176
- if (p.removeUnusedLayers !== undefined)
177
- this.removeUnusedLayer = p.removeUnusedLayers
178
- if (p.keepEndLayers !== undefined) this.keepEndLayers = p.keepEndLayers
179
- if (p.at !== undefined) this.at = p.at
180
- if (p.size !== undefined) this.size = p.size
181
- if (p.drill !== undefined) this.drill = p.drill
182
- if (p.layers !== undefined) this.layers = p.layers
183
- if (p.width !== undefined) this.width = p.width
184
- if (p.stroke !== undefined) this.stroke = p.stroke
185
- if (p.properties !== undefined) this.properties = p.properties
186
- if (p.roundrectRatio !== undefined) this.roundrectRatio = p.roundrectRatio
187
- if (p.chamferRatio !== undefined) this.chamferRatio = p.chamferRatio
188
- if (p.chamfer !== undefined) this.chamfer = p.chamfer
189
- if (p.rectDelta !== undefined) this.rectDelta = p.rectDelta
190
- if (p.net !== undefined) this.net = p.net
191
- if (p.uuid !== undefined) this.uuid = p.uuid
192
- if (p.pinFunction !== undefined) this.pinfunction = p.pinFunction
193
- if (p.pinType !== undefined) this.pintype = p.pinType
194
- if (p.dieLength !== undefined) this.dieLength = p.dieLength
195
- if (p.solderMaskMargin !== undefined)
196
- this.solderMaskMargin = p.solderMaskMargin
197
- if (p.solderPasteMargin !== undefined)
198
- this.solderPasteMargin = p.solderPasteMargin
199
- if (p.solderPasteMarginRatio !== undefined)
200
- this.solderPasteMarginRatio = p.solderPasteMarginRatio
201
- if (p.clearance !== undefined) this.clearance = p.clearance
202
- if (p.zoneConnect !== undefined) this.zoneConnect = p.zoneConnect
203
- if (p.thermalWidth !== undefined) this.thermalWidth = p.thermalWidth
204
- if (p.thermalGap !== undefined) this.thermalGap = p.thermalGap
205
- if (p.thermalBridgeAngle !== undefined)
206
- this.thermalBridgeAngle = p.thermalBridgeAngle
207
- if (p.options !== undefined) this.options = p.options
208
- if (p.primitives !== undefined) this.primitives = p.primitives
209
- if (p.teardrops !== undefined) this.teardrops = p.teardrops
210
- }
211
-
212
- static override fromSexprPrimitives(
213
- primitiveSexprs: PrimitiveSExpr[],
214
- ): FootprintPad {
215
- if (primitiveSexprs.length < 3) {
216
- throw new Error("pad requires number, type, and shape arguments")
217
- }
218
-
219
- const [rawNumber, rawType, rawShape, ...rest] = primitiveSexprs
220
- const number = toStringValue(rawNumber)
221
- const padType = toStringValue(rawType)
222
- const shape = toStringValue(rawShape)
223
- if (number === undefined || padType === undefined || shape === undefined) {
224
- throw new Error("pad header tokens must be strings")
225
- }
226
-
227
- const pad = new FootprintPad(number, padType, shape)
228
-
229
- const primitiveStrings: string[] = []
230
- const primitiveNodes: PrimitiveSExpr[] = []
231
-
232
- for (const primitive of rest) {
233
- if (typeof primitive === "string") {
234
- primitiveStrings.push(primitive)
235
- } else if (Array.isArray(primitive)) {
236
- primitiveNodes.push(primitive)
237
- } else {
238
- throw new Error(
239
- `pad encountered unexpected primitive child: ${JSON.stringify(primitive)}`,
240
- )
241
- }
242
- }
243
-
244
- for (const flag of primitiveStrings) {
245
- switch (flag) {
246
- case "locked":
247
- pad._locked = true
248
- break
249
- case "remove_unused_layer":
250
- pad._sxRemoveUnusedLayers = new PadRemoveUnusedLayers({
251
- value: true,
252
- bareToken: "remove_unused_layer",
253
- })
254
- break
255
- case "keep_end_layers":
256
- pad._sxKeepEndLayers = new PadKeepEndLayers({
257
- value: true,
258
- bare: true,
259
- })
260
- break
261
- default:
262
- throw new Error(`pad encountered unsupported flag "${flag}"`)
263
- }
264
- }
265
-
266
- const { propertyMap, arrayPropertyMap } =
267
- SxClass.parsePrimitivesToClassProperties(primitiveNodes, this.token)
268
-
269
- for (const token of Object.keys(propertyMap)) {
270
- if (!SUPPORTED_TOKENS.has(token)) {
271
- throw new Error(`pad encountered unsupported child token "${token}"`)
272
- }
273
- }
274
-
275
- for (const [token, entries] of Object.entries(arrayPropertyMap)) {
276
- if (!SUPPORTED_TOKENS.has(token)) {
277
- throw new Error(`pad encountered unsupported child token "${token}"`)
278
- }
279
- if (!MULTI_TOKENS.has(token) && entries.length > 1) {
280
- throw new Error(`pad does not support repeated child "${token}"`)
281
- }
282
- }
283
-
284
- ensureSingle(arrayPropertyMap, "at")
285
- ensureSingle(arrayPropertyMap, "size")
286
- ensureSingle(arrayPropertyMap, "drill")
287
- ensureSingle(arrayPropertyMap, "layers")
288
- ensureSingle(arrayPropertyMap, "width")
289
- ensureSingle(arrayPropertyMap, "stroke")
290
- ensureSingle(arrayPropertyMap, "rect_delta")
291
- ensureSingle(arrayPropertyMap, "roundrect_rratio")
292
- ensureSingle(arrayPropertyMap, "chamfer_ratio")
293
- ensureSingle(arrayPropertyMap, "chamfer")
294
- ensureSingle(arrayPropertyMap, "net")
295
- ensureSingle(arrayPropertyMap, "uuid")
296
- ensureSingle(arrayPropertyMap, "pinfunction")
297
- ensureSingle(arrayPropertyMap, "pintype")
298
- ensureSingle(arrayPropertyMap, "die_length")
299
- ensureSingle(arrayPropertyMap, "solder_mask_margin")
300
- ensureSingle(arrayPropertyMap, "solder_paste_margin")
301
- ensureSingle(arrayPropertyMap, "solder_paste_margin_ratio")
302
- ensureSingle(arrayPropertyMap, "clearance")
303
- ensureSingle(arrayPropertyMap, "zone_connect")
304
- ensureSingle(arrayPropertyMap, "thermal_width")
305
- ensureSingle(arrayPropertyMap, "thermal_gap")
306
- ensureSingle(arrayPropertyMap, "thermal_bridge_angle")
307
- ensureSingle(arrayPropertyMap, "options")
308
- ensureSingle(arrayPropertyMap, "primitives")
309
-
310
- pad._sxAt = propertyMap.at as At | undefined
311
- pad._sxSize = propertyMap.size as PadSize | undefined
312
- pad._sxDrill = propertyMap.drill as PadDrill | undefined
313
- pad._sxLayers = propertyMap.layers as PadLayers | undefined
314
- pad._sxWidth = propertyMap.width as Width | undefined
315
- pad._sxStroke = propertyMap.stroke as Stroke | undefined
316
- pad._sxRectDelta = propertyMap.rect_delta as PadRectDelta | undefined
317
-
318
- pad._properties = (arrayPropertyMap.property as Property[]) ?? []
319
-
320
- pad._sxRoundrectRatio = propertyMap.roundrect_rratio as
321
- | PadRoundrectRratio
322
- | undefined
323
- pad._sxChamferRatio = propertyMap.chamfer_ratio as
324
- | PadChamferRatio
325
- | undefined
326
- pad._sxChamfer = propertyMap.chamfer as PadChamfer | undefined
327
- pad._sxNet = propertyMap.net as PadNet | undefined
328
- pad._sxUuid = propertyMap.uuid as Uuid | undefined
329
- pad._sxPinFunction = propertyMap.pinfunction as PadPinFunction | undefined
330
- pad._sxPinType = propertyMap.pintype as PadPinType | undefined
331
- pad._sxDieLength = propertyMap.die_length as PadDieLength | undefined
332
- pad._sxSolderMaskMargin = propertyMap.solder_mask_margin as
333
- | PadSolderMaskMargin
334
- | undefined
335
- pad._sxSolderPasteMargin = propertyMap.solder_paste_margin as
336
- | PadSolderPasteMargin
337
- | undefined
338
- pad._sxSolderPasteMarginRatio = propertyMap.solder_paste_margin_ratio as
339
- | PadSolderPasteMarginRatio
340
- | undefined
341
- pad._sxClearance = propertyMap.clearance as PadClearance | undefined
342
- pad._sxZoneConnect = propertyMap.zone_connect as PadZoneConnect | undefined
343
- pad._sxThermalWidth = propertyMap.thermal_width as
344
- | PadThermalWidth
345
- | undefined
346
- pad._sxThermalGap = propertyMap.thermal_gap as PadThermalGap | undefined
347
- pad._sxThermalBridgeAngle = propertyMap.thermal_bridge_angle as
348
- | PadThermalBridgeAngle
349
- | undefined
350
- pad._sxOptions = propertyMap.options as PadOptions | undefined
351
- pad._sxPrimitives = propertyMap.primitives as PadPrimitives | undefined
352
- pad._sxRemoveUnusedLayers =
353
- (arrayPropertyMap.remove_unused_layers?.[0] as
354
- | PadRemoveUnusedLayers
355
- | undefined) ?? pad._sxRemoveUnusedLayers
356
- pad._sxKeepEndLayers =
357
- (arrayPropertyMap.keep_end_layers?.[0] as PadKeepEndLayers | undefined) ??
358
- pad._sxKeepEndLayers
359
- pad._sxTeardrops =
360
- (arrayPropertyMap.teardrops?.[0] as PadTeardrops | undefined) ?? undefined
361
-
362
- return pad
363
- }
364
-
365
- get number(): string {
366
- return this._number
367
- }
368
-
369
- set number(value: string) {
370
- this._number = value
371
- }
372
-
373
- get padType(): string {
374
- return this._padType
375
- }
376
-
377
- set padType(value: string) {
378
- this._padType = value
379
- }
380
-
381
- get shape(): string {
382
- return this._shape
383
- }
384
-
385
- set shape(value: string) {
386
- this._shape = value
387
- }
388
-
389
- get locked(): boolean {
390
- return this._locked
391
- }
392
-
393
- set locked(value: boolean) {
394
- this._locked = value
395
- }
396
-
397
- get removeUnusedLayer(): boolean {
398
- return this._sxRemoveUnusedLayers?.value ?? false
399
- }
400
-
401
- set removeUnusedLayer(value: boolean) {
402
- this._sxRemoveUnusedLayers = value
403
- ? new PadRemoveUnusedLayers({ value })
404
- : undefined
405
- }
406
-
407
- get keepEndLayers(): boolean {
408
- return this._sxKeepEndLayers?.value ?? false
409
- }
410
-
411
- set keepEndLayers(value: boolean) {
412
- this._sxKeepEndLayers = value ? new PadKeepEndLayers({ value }) : undefined
413
- }
414
-
415
- get at(): At | undefined {
416
- return this._sxAt
417
- }
418
-
419
- set at(value: AtInput | undefined) {
420
- this._sxAt = value !== undefined ? At.from(value) : undefined
421
- }
422
-
423
- get size(): PadSize | undefined {
424
- return this._sxSize
425
- }
426
-
427
- set size(value: PadSizeInput | undefined) {
428
- this._sxSize = value !== undefined ? PadSize.from(value) : undefined
429
- }
430
-
431
- get drill(): PadDrill | undefined {
432
- return this._sxDrill
433
- }
434
-
435
- set drill(value: PadDrill | undefined) {
436
- this._sxDrill = value
437
- }
438
-
439
- get layers(): PadLayers | undefined {
440
- return this._sxLayers
441
- }
442
-
443
- set layers(value: PadLayersInput | undefined) {
444
- this._sxLayers = value !== undefined ? PadLayers.from(value) : undefined
445
- }
446
-
447
- get width(): Width | undefined {
448
- return this._sxWidth
449
- }
450
-
451
- set width(value: number | Width | undefined) {
452
- if (value === undefined) {
453
- this._sxWidth = undefined
454
- return
455
- }
456
- this._sxWidth = typeof value === "number" ? new Width(value) : value
457
- }
458
-
459
- get stroke(): Stroke | undefined {
460
- return this._sxStroke
461
- }
462
-
463
- set stroke(value: Stroke | undefined) {
464
- this._sxStroke = value
465
- }
466
-
467
- get properties(): Property[] {
468
- return [...this._properties]
469
- }
470
-
471
- set properties(value: Property[]) {
472
- this._properties = [...value]
473
- }
474
-
475
- get roundrectRatio(): number | undefined {
476
- return this._sxRoundrectRatio?.value
477
- }
478
-
479
- set roundrectRatio(value: number | PadRoundrectRratio | undefined) {
480
- if (value === undefined) {
481
- this._sxRoundrectRatio = undefined
482
- return
483
- }
484
- this._sxRoundrectRatio =
485
- typeof value === "number" ? new PadRoundrectRratio(value) : value
486
- }
487
-
488
- get chamferRatio(): number | undefined {
489
- return this._sxChamferRatio?.value
490
- }
491
-
492
- set chamferRatio(value: number | PadChamferRatio | undefined) {
493
- if (value === undefined) {
494
- this._sxChamferRatio = undefined
495
- return
496
- }
497
- this._sxChamferRatio =
498
- typeof value === "number" ? new PadChamferRatio(value) : value
499
- }
500
-
501
- get chamfer(): PadChamfer | undefined {
502
- return this._sxChamfer
503
- }
504
-
505
- set chamfer(value: PadChamfer | undefined) {
506
- this._sxChamfer = value
507
- }
508
-
509
- get chamferCorners(): string[] | undefined {
510
- return this._sxChamfer?.corners
511
- }
512
-
513
- get rectDelta(): PadRectDelta | undefined {
514
- return this._sxRectDelta
515
- }
516
-
517
- set rectDelta(value: PadRectDelta | { x: number; y: number } | undefined) {
518
- if (value === undefined) {
519
- this._sxRectDelta = undefined
520
- return
521
- }
522
- if (value instanceof PadRectDelta) {
523
- this._sxRectDelta = value
524
- return
525
- }
526
- this._sxRectDelta = new PadRectDelta(value.x, value.y)
527
- }
528
-
529
- get net(): PadNet | undefined {
530
- return this._sxNet
531
- }
532
-
533
- set net(value: PadNet | undefined) {
534
- this._sxNet = value
535
- }
536
-
537
- get uuid(): Uuid | undefined {
538
- return this._sxUuid
539
- }
540
-
541
- set uuid(value: Uuid | string | undefined) {
542
- if (value === undefined) {
543
- this._sxUuid = undefined
544
- return
545
- }
546
- this._sxUuid = value instanceof Uuid ? value : new Uuid(value)
547
- }
548
-
549
- get pinfunction(): string | undefined {
550
- return this._sxPinFunction?.value
551
- }
552
-
553
- set pinfunction(value: string | PadPinFunction | undefined) {
554
- if (value === undefined) {
555
- this._sxPinFunction = undefined
556
- return
557
- }
558
- this._sxPinFunction =
559
- typeof value === "string" ? new PadPinFunction(value) : value
560
- }
561
-
562
- get pintype(): string | undefined {
563
- return this._sxPinType?.value
564
- }
565
-
566
- set pintype(value: string | PadPinType | undefined) {
567
- if (value === undefined) {
568
- this._sxPinType = undefined
569
- return
570
- }
571
- this._sxPinType = typeof value === "string" ? new PadPinType(value) : value
572
- }
573
-
574
- get dieLength(): number | undefined {
575
- return this._sxDieLength?.value
576
- }
577
-
578
- set dieLength(value: number | PadDieLength | undefined) {
579
- if (value === undefined) {
580
- this._sxDieLength = undefined
581
- return
582
- }
583
- this._sxDieLength =
584
- typeof value === "number" ? new PadDieLength(value) : value
585
- }
586
-
587
- get solderMaskMargin(): number | undefined {
588
- return this._sxSolderMaskMargin?.value
589
- }
590
-
591
- set solderMaskMargin(value: number | PadSolderMaskMargin | undefined) {
592
- if (value === undefined) {
593
- this._sxSolderMaskMargin = undefined
594
- return
595
- }
596
- this._sxSolderMaskMargin =
597
- typeof value === "number" ? new PadSolderMaskMargin(value) : value
598
- }
599
-
600
- get solderPasteMargin(): number | undefined {
601
- return this._sxSolderPasteMargin?.value
602
- }
603
-
604
- set solderPasteMargin(value: number | PadSolderPasteMargin | undefined) {
605
- if (value === undefined) {
606
- this._sxSolderPasteMargin = undefined
607
- return
608
- }
609
- this._sxSolderPasteMargin =
610
- typeof value === "number" ? new PadSolderPasteMargin(value) : value
611
- }
612
-
613
- get solderPasteMarginRatio(): number | undefined {
614
- return this._sxSolderPasteMarginRatio?.value
615
- }
616
-
617
- set solderPasteMarginRatio(value:
618
- | number
619
- | PadSolderPasteMarginRatio
620
- | undefined) {
621
- if (value === undefined) {
622
- this._sxSolderPasteMarginRatio = undefined
623
- return
624
- }
625
- this._sxSolderPasteMarginRatio =
626
- typeof value === "number" ? new PadSolderPasteMarginRatio(value) : value
627
- }
628
-
629
- get clearance(): number | undefined {
630
- return this._sxClearance?.value
631
- }
632
-
633
- set clearance(value: number | PadClearance | undefined) {
634
- if (value === undefined) {
635
- this._sxClearance = undefined
636
- return
637
- }
638
- this._sxClearance =
639
- typeof value === "number" ? new PadClearance(value) : value
640
- }
641
-
642
- get zoneConnect(): number | undefined {
643
- return this._sxZoneConnect?.value
644
- }
645
-
646
- set zoneConnect(value: number | PadZoneConnect | undefined) {
647
- if (value === undefined) {
648
- this._sxZoneConnect = undefined
649
- return
650
- }
651
- this._sxZoneConnect =
652
- typeof value === "number" ? new PadZoneConnect(value) : value
653
- }
654
-
655
- get thermalWidth(): number | undefined {
656
- return this._sxThermalWidth?.value
657
- }
658
-
659
- set thermalWidth(value: number | PadThermalWidth | undefined) {
660
- if (value === undefined) {
661
- this._sxThermalWidth = undefined
662
- return
663
- }
664
- this._sxThermalWidth =
665
- typeof value === "number" ? new PadThermalWidth(value) : value
666
- }
667
-
668
- get thermalGap(): number | undefined {
669
- return this._sxThermalGap?.value
670
- }
671
-
672
- set thermalGap(value: number | PadThermalGap | undefined) {
673
- if (value === undefined) {
674
- this._sxThermalGap = undefined
675
- return
676
- }
677
- this._sxThermalGap =
678
- typeof value === "number" ? new PadThermalGap(value) : value
679
- }
680
-
681
- get thermalBridgeAngle(): number | undefined {
682
- return this._sxThermalBridgeAngle?.value
683
- }
684
-
685
- set thermalBridgeAngle(value: number | PadThermalBridgeAngle | undefined) {
686
- if (value === undefined) {
687
- this._sxThermalBridgeAngle = undefined
688
- return
689
- }
690
- this._sxThermalBridgeAngle =
691
- typeof value === "number" ? new PadThermalBridgeAngle(value) : value
692
- }
693
-
694
- get options(): PadOptions | undefined {
695
- return this._sxOptions
696
- }
697
-
698
- set options(value: PadOptions | undefined) {
699
- this._sxOptions = value
700
- }
701
-
702
- get primitives(): PadPrimitives | undefined {
703
- return this._sxPrimitives
704
- }
705
-
706
- set primitives(value: PadPrimitives | undefined) {
707
- this._sxPrimitives = value
708
- }
709
-
710
- get teardrops(): PadTeardrops | undefined {
711
- return this._sxTeardrops
712
- }
713
-
714
- set teardrops(value: PadTeardrops | undefined) {
715
- this._sxTeardrops = value
716
- }
717
-
718
- override getChildren(): SxClass[] {
719
- const children: SxClass[] = []
720
- if (this._sxAt) children.push(this._sxAt)
721
- if (this._sxSize) children.push(this._sxSize)
722
- if (this._sxDrill) children.push(this._sxDrill)
723
- if (this._sxLayers) children.push(this._sxLayers)
724
- if (this._sxWidth) children.push(this._sxWidth)
725
- if (this._sxStroke) children.push(this._sxStroke)
726
- children.push(...this._properties)
727
- if (this._sxRoundrectRatio) children.push(this._sxRoundrectRatio)
728
- if (this._sxChamferRatio) children.push(this._sxChamferRatio)
729
- if (this._sxChamfer) children.push(this._sxChamfer)
730
- if (this._sxRectDelta) children.push(this._sxRectDelta)
731
- if (this._sxNet) children.push(this._sxNet)
732
- if (this._sxPinFunction) children.push(this._sxPinFunction)
733
- if (this._sxPinType) children.push(this._sxPinType)
734
- if (this._sxDieLength) children.push(this._sxDieLength)
735
- if (this._sxSolderMaskMargin) children.push(this._sxSolderMaskMargin)
736
- if (this._sxSolderPasteMargin) children.push(this._sxSolderPasteMargin)
737
- if (this._sxSolderPasteMarginRatio)
738
- children.push(this._sxSolderPasteMarginRatio)
739
- if (this._sxClearance) children.push(this._sxClearance)
740
- if (this._sxZoneConnect) children.push(this._sxZoneConnect)
741
- if (this._sxThermalWidth) children.push(this._sxThermalWidth)
742
- if (this._sxThermalGap) children.push(this._sxThermalGap)
743
- if (this._sxThermalBridgeAngle) children.push(this._sxThermalBridgeAngle)
744
- if (this._sxUuid) children.push(this._sxUuid)
745
- if (this._sxRemoveUnusedLayers) children.push(this._sxRemoveUnusedLayers)
746
- if (this._sxKeepEndLayers) children.push(this._sxKeepEndLayers)
747
- if (this._sxTeardrops) children.push(this._sxTeardrops)
748
- if (this._sxOptions) children.push(this._sxOptions)
749
- if (this._sxPrimitives) children.push(this._sxPrimitives)
750
- return children
751
- }
752
-
753
- override getString(): string {
754
- const lines = [
755
- `(pad ${quoteSExprString(this._number)} ${this._padType} ${this._shape}`,
756
- ]
757
- for (const child of this.getChildren()) {
758
- lines.push(child.getStringIndented())
759
- }
760
- if (this._locked) {
761
- lines.push(" locked")
762
- }
763
- lines.push(")")
764
- return lines.join("\n")
765
- }
766
- }
767
- SxClass.register(FootprintPad)
768
-
769
- class PadRemoveUnusedLayers extends SxPrimitiveBoolean {
770
- static override token = "remove_unused_layers"
771
- static override parentToken = "pad"
772
- override token = "remove_unused_layers"
773
-
774
- private readonly bareToken?: string
775
-
776
- constructor(options: { value?: boolean; bareToken?: string } = {}) {
777
- super(options.value ?? false)
778
- this.bareToken = options.bareToken
779
- }
780
-
781
- static override fromSexprPrimitives(
782
- primitiveSexprs: PrimitiveSExpr[],
783
- ): PadRemoveUnusedLayers {
784
- const [raw] = primitiveSexprs
785
- if (raw === undefined) {
786
- return new PadRemoveUnusedLayers({ value: false })
787
- }
788
- if (typeof raw === "boolean") {
789
- return new PadRemoveUnusedLayers({ value: raw })
790
- }
791
- if (typeof raw === "string") {
792
- const normalized = raw.toLowerCase()
793
- if (normalized === "yes" || normalized === "true") {
794
- return new PadRemoveUnusedLayers({ value: true })
795
- }
796
- if (normalized === "no" || normalized === "false") {
797
- return new PadRemoveUnusedLayers({ value: false })
798
- }
799
- }
800
- throw new Error(
801
- `remove_unused_layers expects yes/no or boolean, received ${JSON.stringify(raw)}`,
802
- )
803
- }
804
-
805
- override getString(): string {
806
- if (this.bareToken) {
807
- return this.bareToken
808
- }
809
- return `(remove_unused_layers ${this.value ? "yes" : "no"})`
810
- }
811
- }
812
- SxClass.register(PadRemoveUnusedLayers)
813
-
814
- class PadKeepEndLayers extends SxPrimitiveBoolean {
815
- static override token = "keep_end_layers"
816
- static override parentToken = "pad"
817
- override token = "keep_end_layers"
818
-
819
- private readonly renderBare: boolean
820
-
821
- constructor(options: { value?: boolean; bare?: boolean } = {}) {
822
- super(options.value ?? false)
823
- this.renderBare = options.bare ?? false
824
- }
825
-
826
- static override fromSexprPrimitives(
827
- primitiveSexprs: PrimitiveSExpr[],
828
- ): PadKeepEndLayers {
829
- const [raw] = primitiveSexprs
830
- if (raw === undefined) {
831
- return new PadKeepEndLayers({ value: false })
832
- }
833
- if (typeof raw === "boolean") {
834
- return new PadKeepEndLayers({ value: raw })
835
- }
836
- if (typeof raw === "string") {
837
- const normalized = raw.toLowerCase()
838
- if (normalized === "yes" || normalized === "true") {
839
- return new PadKeepEndLayers({ value: true })
840
- }
841
- if (normalized === "no" || normalized === "false") {
842
- return new PadKeepEndLayers({ value: false })
843
- }
844
- }
845
- throw new Error(
846
- `keep_end_layers expects yes/no or boolean, received ${JSON.stringify(raw)}`,
847
- )
848
- }
849
-
850
- override getString(): string {
851
- if (this.renderBare) {
852
- return "keep_end_layers"
853
- }
854
- return `(keep_end_layers ${this.value ? "yes" : "no"})`
855
- }
856
- }
857
- SxClass.register(PadKeepEndLayers)