@tscircuit/footprinter 0.0.342 → 0.0.344

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -181,6 +181,101 @@ var u_curve = Array.from(
181
181
  y: -Math.sqrt(1 - x ** 2)
182
182
  }));
183
183
 
184
+ // src/helpers/rect-union-outline.ts
185
+ var createRectUnionOutline = (rectBoundsFromOuterToInner) => {
186
+ if (rectBoundsFromOuterToInner.length < 2) {
187
+ throw new Error("Rect union outline requires at least two bounds");
188
+ }
189
+ for (const bounds of rectBoundsFromOuterToInner) {
190
+ if (bounds.minX >= bounds.maxX || bounds.minY >= bounds.maxY) {
191
+ throw new Error("Each rectangle bound must have min < max on both axes");
192
+ }
193
+ }
194
+ for (let i = 1; i < rectBoundsFromOuterToInner.length; i++) {
195
+ const previous = rectBoundsFromOuterToInner[i - 1];
196
+ const current = rectBoundsFromOuterToInner[i];
197
+ if (current.minX < previous.minX || current.maxX > previous.maxX || current.minY > previous.minY || current.maxY < previous.maxY) {
198
+ throw new Error(
199
+ "Bounds must be ordered outer-to-inner with tighter X and larger Y span"
200
+ );
201
+ }
202
+ }
203
+ const buildTopLeftRouteFromInnerToOuter = () => {
204
+ const route = [];
205
+ let index = rectBoundsFromOuterToInner.length - 1;
206
+ route.push({
207
+ x: rectBoundsFromOuterToInner[index].minX,
208
+ y: rectBoundsFromOuterToInner[index].maxY
209
+ });
210
+ while (index > 0) {
211
+ const current = rectBoundsFromOuterToInner[index];
212
+ const previous = rectBoundsFromOuterToInner[index - 1];
213
+ route.push({ x: current.minX, y: previous.maxY });
214
+ route.push({ x: previous.minX, y: previous.maxY });
215
+ index -= 1;
216
+ }
217
+ return route;
218
+ };
219
+ const buildTopRightRouteFromInnerToOuter = () => {
220
+ const route = [];
221
+ let index = rectBoundsFromOuterToInner.length - 1;
222
+ route.push({
223
+ x: rectBoundsFromOuterToInner[index].maxX,
224
+ y: rectBoundsFromOuterToInner[index].maxY
225
+ });
226
+ while (index > 0) {
227
+ const current = rectBoundsFromOuterToInner[index];
228
+ const previous = rectBoundsFromOuterToInner[index - 1];
229
+ route.push({ x: current.maxX, y: previous.maxY });
230
+ route.push({ x: previous.maxX, y: previous.maxY });
231
+ index -= 1;
232
+ }
233
+ return route;
234
+ };
235
+ const buildBottomRightRouteFromInnerToOuter = () => {
236
+ const route = [];
237
+ let index = rectBoundsFromOuterToInner.length - 1;
238
+ route.push({
239
+ x: rectBoundsFromOuterToInner[index].maxX,
240
+ y: rectBoundsFromOuterToInner[index].minY
241
+ });
242
+ while (index > 0) {
243
+ const current = rectBoundsFromOuterToInner[index];
244
+ const previous = rectBoundsFromOuterToInner[index - 1];
245
+ route.push({ x: current.maxX, y: previous.minY });
246
+ route.push({ x: previous.maxX, y: previous.minY });
247
+ index -= 1;
248
+ }
249
+ return route;
250
+ };
251
+ const buildBottomLeftRouteFromInnerToOuter = () => {
252
+ const route = [];
253
+ let index = rectBoundsFromOuterToInner.length - 1;
254
+ route.push({
255
+ x: rectBoundsFromOuterToInner[index].minX,
256
+ y: rectBoundsFromOuterToInner[index].minY
257
+ });
258
+ while (index > 0) {
259
+ const current = rectBoundsFromOuterToInner[index];
260
+ const previous = rectBoundsFromOuterToInner[index - 1];
261
+ route.push({ x: current.minX, y: previous.minY });
262
+ route.push({ x: previous.minX, y: previous.minY });
263
+ index -= 1;
264
+ }
265
+ return route;
266
+ };
267
+ const topLeftInnerToOuter = buildTopLeftRouteFromInnerToOuter();
268
+ const topRightInnerToOuter = buildTopRightRouteFromInnerToOuter();
269
+ const bottomRightInnerToOuter = buildBottomRightRouteFromInnerToOuter();
270
+ const bottomLeftInnerToOuter = buildBottomLeftRouteFromInnerToOuter();
271
+ return [
272
+ ...topLeftInnerToOuter.reverse(),
273
+ ...topRightInnerToOuter,
274
+ ...bottomRightInnerToOuter.reverse(),
275
+ ...bottomLeftInnerToOuter
276
+ ];
277
+ };
278
+
184
279
  // src/fn/dip.ts
185
280
  function convertMilToMm(value) {
186
281
  if (typeof value === "string") {
@@ -316,18 +411,31 @@ var dip = (raw_params) => {
316
411
  });
317
412
  }
318
413
  const silkscreenRefText = silkscreenRef(0, sh / 2 + 0.5, 0.4);
319
- const courtyardPadding = 0.25;
320
- const crtMinX = -(parameters.w / 2 + parameters.od / 2) - courtyardPadding;
321
- const crtMaxX = parameters.w / 2 + parameters.od / 2 + courtyardPadding;
322
- const crtMinY = -sh / 2 - courtyardPadding;
323
- const crtMaxY = sh / 2 + courtyardPadding;
414
+ const roundToCourtyardGrid = (value) => Math.round(value / 0.01) * 0.01;
415
+ const pinRowSpanX = parameters.w + parameters.od;
416
+ const pinRowSpanY = padEdgeHeight;
417
+ const courtyardStepOuterHalfX = roundToCourtyardGrid(pinRowSpanX / 2 + 0.25);
418
+ const courtyardStepInnerHalfX = courtyardStepOuterHalfX;
419
+ const courtyardStepOuterHalfY = roundToCourtyardGrid(pinRowSpanY / 2 + 0.72);
420
+ const courtyardStepInnerHalfY = courtyardStepOuterHalfY;
324
421
  const courtyard = {
325
- type: "pcb_courtyard_rect",
326
- pcb_courtyard_rect_id: "",
422
+ type: "pcb_courtyard_outline",
423
+ pcb_courtyard_outline_id: "",
327
424
  pcb_component_id: "",
328
- center: { x: (crtMinX + crtMaxX) / 2, y: (crtMinY + crtMaxY) / 2 },
329
- width: crtMaxX - crtMinX,
330
- height: crtMaxY - crtMinY,
425
+ outline: createRectUnionOutline([
426
+ {
427
+ minX: -courtyardStepOuterHalfX,
428
+ maxX: courtyardStepOuterHalfX,
429
+ minY: -courtyardStepInnerHalfY,
430
+ maxY: courtyardStepInnerHalfY
431
+ },
432
+ {
433
+ minX: -courtyardStepInnerHalfX,
434
+ maxX: courtyardStepInnerHalfX,
435
+ minY: -courtyardStepOuterHalfY,
436
+ maxY: courtyardStepOuterHalfY
437
+ }
438
+ ]),
331
439
  layer: "top"
332
440
  };
333
441
  return {
@@ -1182,14 +1290,41 @@ var bga = (raw_params) => {
1182
1290
  route: markerRoute,
1183
1291
  stroke_width: 0.05
1184
1292
  };
1185
- const courtyardPadding = 0.25;
1293
+ const roundToCourtyardGrid = (value) => Math.round(value / 0.01) * 0.01;
1294
+ const padSpanX = (grid.x - 1) * p + pad2;
1295
+ const padSpanY = (grid.y - 1) * p + pad2;
1296
+ const bodySpanX = w ?? padSpanX;
1297
+ const bodySpanY = h ?? padSpanY;
1298
+ const courtyardEnvelopeHalfX = Math.max(padSpanX / 2, bodySpanX / 2);
1299
+ const courtyardEnvelopeHalfY = Math.max(padSpanY / 2, bodySpanY / 2);
1300
+ const courtyardClearanceX = 1.715;
1301
+ const courtyardClearanceY = 1.765;
1302
+ const courtyardStepOuterHalfX = roundToCourtyardGrid(
1303
+ courtyardEnvelopeHalfX + courtyardClearanceX
1304
+ );
1305
+ const courtyardStepInnerHalfX = courtyardStepOuterHalfX;
1306
+ const courtyardStepOuterHalfY = roundToCourtyardGrid(
1307
+ courtyardEnvelopeHalfY + courtyardClearanceY
1308
+ );
1309
+ const courtyardStepInnerHalfY = courtyardStepOuterHalfY;
1186
1310
  const courtyard = {
1187
- type: "pcb_courtyard_rect",
1188
- pcb_courtyard_rect_id: "",
1311
+ type: "pcb_courtyard_outline",
1312
+ pcb_courtyard_outline_id: "",
1189
1313
  pcb_component_id: "",
1190
- center: { x: 0, y: 0 },
1191
- width: 2 * (edgeX + courtyardPadding),
1192
- height: 2 * (edgeY + courtyardPadding),
1314
+ outline: createRectUnionOutline([
1315
+ {
1316
+ minX: -courtyardStepOuterHalfX,
1317
+ maxX: courtyardStepOuterHalfX,
1318
+ minY: -courtyardStepInnerHalfY,
1319
+ maxY: courtyardStepInnerHalfY
1320
+ },
1321
+ {
1322
+ minX: -courtyardStepInnerHalfX,
1323
+ maxX: courtyardStepInnerHalfX,
1324
+ minY: -courtyardStepOuterHalfY,
1325
+ maxY: courtyardStepOuterHalfY
1326
+ }
1327
+ ]),
1193
1328
  layer: "top"
1194
1329
  };
1195
1330
  return {
@@ -1223,101 +1358,6 @@ var pillpad = (pn, x, y, w, h) => {
1223
1358
  };
1224
1359
  };
1225
1360
 
1226
- // src/helpers/rect-union-outline.ts
1227
- var createRectUnionOutline = (rectBoundsFromOuterToInner) => {
1228
- if (rectBoundsFromOuterToInner.length < 2) {
1229
- throw new Error("Rect union outline requires at least two bounds");
1230
- }
1231
- for (const bounds of rectBoundsFromOuterToInner) {
1232
- if (bounds.minX >= bounds.maxX || bounds.minY >= bounds.maxY) {
1233
- throw new Error("Each rectangle bound must have min < max on both axes");
1234
- }
1235
- }
1236
- for (let i = 1; i < rectBoundsFromOuterToInner.length; i++) {
1237
- const previous = rectBoundsFromOuterToInner[i - 1];
1238
- const current = rectBoundsFromOuterToInner[i];
1239
- if (current.minX < previous.minX || current.maxX > previous.maxX || current.minY > previous.minY || current.maxY < previous.maxY) {
1240
- throw new Error(
1241
- "Bounds must be ordered outer-to-inner with tighter X and larger Y span"
1242
- );
1243
- }
1244
- }
1245
- const buildTopLeftRouteFromInnerToOuter = () => {
1246
- const route = [];
1247
- let index = rectBoundsFromOuterToInner.length - 1;
1248
- route.push({
1249
- x: rectBoundsFromOuterToInner[index].minX,
1250
- y: rectBoundsFromOuterToInner[index].maxY
1251
- });
1252
- while (index > 0) {
1253
- const current = rectBoundsFromOuterToInner[index];
1254
- const previous = rectBoundsFromOuterToInner[index - 1];
1255
- route.push({ x: current.minX, y: previous.maxY });
1256
- route.push({ x: previous.minX, y: previous.maxY });
1257
- index -= 1;
1258
- }
1259
- return route;
1260
- };
1261
- const buildTopRightRouteFromInnerToOuter = () => {
1262
- const route = [];
1263
- let index = rectBoundsFromOuterToInner.length - 1;
1264
- route.push({
1265
- x: rectBoundsFromOuterToInner[index].maxX,
1266
- y: rectBoundsFromOuterToInner[index].maxY
1267
- });
1268
- while (index > 0) {
1269
- const current = rectBoundsFromOuterToInner[index];
1270
- const previous = rectBoundsFromOuterToInner[index - 1];
1271
- route.push({ x: current.maxX, y: previous.maxY });
1272
- route.push({ x: previous.maxX, y: previous.maxY });
1273
- index -= 1;
1274
- }
1275
- return route;
1276
- };
1277
- const buildBottomRightRouteFromInnerToOuter = () => {
1278
- const route = [];
1279
- let index = rectBoundsFromOuterToInner.length - 1;
1280
- route.push({
1281
- x: rectBoundsFromOuterToInner[index].maxX,
1282
- y: rectBoundsFromOuterToInner[index].minY
1283
- });
1284
- while (index > 0) {
1285
- const current = rectBoundsFromOuterToInner[index];
1286
- const previous = rectBoundsFromOuterToInner[index - 1];
1287
- route.push({ x: current.maxX, y: previous.minY });
1288
- route.push({ x: previous.maxX, y: previous.minY });
1289
- index -= 1;
1290
- }
1291
- return route;
1292
- };
1293
- const buildBottomLeftRouteFromInnerToOuter = () => {
1294
- const route = [];
1295
- let index = rectBoundsFromOuterToInner.length - 1;
1296
- route.push({
1297
- x: rectBoundsFromOuterToInner[index].minX,
1298
- y: rectBoundsFromOuterToInner[index].minY
1299
- });
1300
- while (index > 0) {
1301
- const current = rectBoundsFromOuterToInner[index];
1302
- const previous = rectBoundsFromOuterToInner[index - 1];
1303
- route.push({ x: current.minX, y: previous.minY });
1304
- route.push({ x: previous.minX, y: previous.minY });
1305
- index -= 1;
1306
- }
1307
- return route;
1308
- };
1309
- const topLeftInnerToOuter = buildTopLeftRouteFromInnerToOuter();
1310
- const topRightInnerToOuter = buildTopRightRouteFromInnerToOuter();
1311
- const bottomRightInnerToOuter = buildBottomRightRouteFromInnerToOuter();
1312
- const bottomLeftInnerToOuter = buildBottomLeftRouteFromInnerToOuter();
1313
- return [
1314
- ...topLeftInnerToOuter.reverse(),
1315
- ...topRightInnerToOuter,
1316
- ...bottomRightInnerToOuter.reverse(),
1317
- ...bottomLeftInnerToOuter
1318
- ];
1319
- };
1320
-
1321
1361
  // src/fn/soic.ts
1322
1362
  var extendSoicDef = (newDefaults) => base_def.extend({
1323
1363
  fn: z13.string(),
@@ -2039,21 +2079,32 @@ var ssop = (raw_params) => {
2039
2079
  { x: -sw / 2, y: -sh / 2 }
2040
2080
  ]
2041
2081
  };
2042
- const courtyardPadding = 0.25;
2043
- const silkXs = silkscreenBorder.route.map((pt) => pt.x);
2044
- const silkYs = silkscreenBorder.route.map((pt) => pt.y);
2045
- const padXExtent = parameters.legsoutside ? parameters.w / 2 + parameters.pl : (parameters.w + 0.2) / 2 + parameters.pl / 2;
2046
- const crtMinX = Math.min(-padXExtent, ...silkXs) - courtyardPadding;
2047
- const crtMaxX = Math.max(padXExtent, ...silkXs) + courtyardPadding;
2048
- const crtMinY = Math.min(...silkYs) - courtyardPadding;
2049
- const crtMaxY = Math.max(...silkYs) + courtyardPadding;
2082
+ const roundToCourtyardGrid = (value) => Math.round(value / 0.01) * 0.01;
2083
+ const pinRowSpanY = (parameters.num_pins / 2 - 1) * parameters.p + parameters.pw;
2084
+ const padToeHalfX = parameters.legsoutside ? parameters.w / 2 + parameters.pl : (parameters.w + 0.2) / 2 + parameters.pl / 2;
2085
+ const pinRowHalfY = pinRowSpanY / 2;
2086
+ const courtyardStepOuterHalfX = roundToCourtyardGrid(padToeHalfX + 0.25);
2087
+ const courtyardStepInnerHalfX = courtyardStepOuterHalfX;
2088
+ const courtyardStepOuterHalfY = roundToCourtyardGrid(pinRowHalfY + 0.445);
2089
+ const courtyardStepInnerHalfY = courtyardStepOuterHalfY;
2050
2090
  const courtyard = {
2051
- type: "pcb_courtyard_rect",
2052
- pcb_courtyard_rect_id: "",
2091
+ type: "pcb_courtyard_outline",
2092
+ pcb_courtyard_outline_id: "",
2053
2093
  pcb_component_id: "",
2054
- center: { x: (crtMinX + crtMaxX) / 2, y: (crtMinY + crtMaxY) / 2 },
2055
- width: crtMaxX - crtMinX,
2056
- height: crtMaxY - crtMinY,
2094
+ outline: createRectUnionOutline([
2095
+ {
2096
+ minX: -courtyardStepOuterHalfX,
2097
+ maxX: courtyardStepOuterHalfX,
2098
+ minY: -courtyardStepInnerHalfY,
2099
+ maxY: courtyardStepInnerHalfY
2100
+ },
2101
+ {
2102
+ minX: -courtyardStepInnerHalfX,
2103
+ maxX: courtyardStepInnerHalfX,
2104
+ minY: -courtyardStepOuterHalfY,
2105
+ maxY: courtyardStepOuterHalfY
2106
+ }
2107
+ ]),
2057
2108
  layer: "top"
2058
2109
  };
2059
2110
  return {
@@ -3409,18 +3460,39 @@ var axial = (raw_params) => {
3409
3460
  pcb_silkscreen_path_id: ""
3410
3461
  };
3411
3462
  const silkscreenRefText = silkscreenRef(0, 1.5, 0.5);
3412
- const courtyardPadding = 0.25;
3413
- const crtMinX = -(p / 2 + od / 2 + courtyardPadding);
3414
- const crtMaxX = p / 2 + od / 2 + courtyardPadding;
3415
- const crtMinY = -(od / 2 + courtyardPadding);
3416
- const crtMaxY = od / 2 + courtyardPadding;
3463
+ const roundToCourtyardGrid = (value) => Math.round(value / 0.01) * 0.01;
3464
+ const pin1CenterX = -p / 2;
3465
+ const pin2CenterX = p / 2;
3466
+ const pinPadHalfX = od / 2;
3467
+ const pinPadHalfY = od / 2;
3468
+ const courtyardStepOuterMinX = roundToCourtyardGrid(
3469
+ pin1CenterX - pinPadHalfX - 0.35
3470
+ );
3471
+ const courtyardStepOuterMaxX = roundToCourtyardGrid(
3472
+ pin2CenterX + pinPadHalfX + 0.26
3473
+ );
3474
+ const courtyardStepOuterHalfY = roundToCourtyardGrid(pinPadHalfY + 0.35);
3475
+ const courtyardStepInnerMinX = courtyardStepOuterMinX;
3476
+ const courtyardStepInnerMaxX = courtyardStepOuterMaxX;
3477
+ const courtyardStepInnerHalfY = courtyardStepOuterHalfY;
3417
3478
  const courtyard = {
3418
- type: "pcb_courtyard_rect",
3419
- pcb_courtyard_rect_id: "",
3479
+ type: "pcb_courtyard_outline",
3480
+ pcb_courtyard_outline_id: "",
3420
3481
  pcb_component_id: "",
3421
- center: { x: (crtMinX + crtMaxX) / 2, y: (crtMinY + crtMaxY) / 2 },
3422
- width: crtMaxX - crtMinX,
3423
- height: crtMaxY - crtMinY,
3482
+ outline: createRectUnionOutline([
3483
+ {
3484
+ minX: courtyardStepOuterMinX,
3485
+ maxX: courtyardStepOuterMaxX,
3486
+ minY: -courtyardStepInnerHalfY,
3487
+ maxY: courtyardStepInnerHalfY
3488
+ },
3489
+ {
3490
+ minX: courtyardStepInnerMinX,
3491
+ maxX: courtyardStepInnerMaxX,
3492
+ minY: -courtyardStepOuterHalfY,
3493
+ maxY: courtyardStepOuterHalfY
3494
+ }
3495
+ ]),
3424
3496
  layer: "top"
3425
3497
  };
3426
3498
  return {
@@ -5309,45 +5381,76 @@ var sod_def5 = base_def.extend({
5309
5381
  });
5310
5382
  var sod923 = (raw_params) => {
5311
5383
  const parameters = sod_def5.parse(raw_params);
5312
- const silkscreenRefText = silkscreenRef(
5313
- 0,
5314
- length31.parse(parameters.h),
5315
- 0.3
5316
- );
5384
+ const w = length31.parse(parameters.w);
5385
+ const h = length31.parse(parameters.h);
5386
+ const pl = length31.parse(parameters.pl);
5387
+ const pw = length31.parse(parameters.pw);
5388
+ const p = length31.parse(parameters.p);
5389
+ const silkscreenRefText = silkscreenRef(0, h, 0.3);
5317
5390
  const silkscreenLine = {
5318
5391
  type: "pcb_silkscreen_path",
5319
5392
  layer: "top",
5320
5393
  pcb_component_id: "",
5321
5394
  route: [
5322
5395
  {
5323
- x: length31.parse(parameters.p) / 2 + 0.15,
5324
- y: length31.parse(parameters.h) / 2
5396
+ x: p / 2 + 0.15,
5397
+ y: h / 2
5325
5398
  },
5326
5399
  {
5327
- x: -length31.parse(parameters.w) / 2 - 0.15,
5328
- y: length31.parse(parameters.h) / 2
5400
+ x: -w / 2 - 0.15,
5401
+ y: h / 2
5329
5402
  },
5330
5403
  {
5331
- x: -length31.parse(parameters.w) / 2 - 0.15,
5332
- y: -length31.parse(parameters.h) / 2
5404
+ x: -w / 2 - 0.15,
5405
+ y: -h / 2
5333
5406
  },
5334
5407
  {
5335
- x: length31.parse(parameters.p) / 2 + 0.15,
5336
- y: -length31.parse(parameters.h) / 2
5408
+ x: p / 2 + 0.15,
5409
+ y: -h / 2
5337
5410
  }
5338
5411
  ],
5339
5412
  stroke_width: 0.1,
5340
5413
  pcb_silkscreen_path_id: ""
5341
5414
  };
5342
- const courtyardWidthMm = 1.5;
5343
- const courtyardHeightMm = 0.9;
5415
+ const roundToCourtyardGrid = (value) => Math.round(value / 0.01) * 0.01;
5416
+ const pinRowSpanX = p + pl;
5417
+ const pinRowSpanY = pw;
5418
+ const bodyHalfX = w / 2;
5419
+ const bodyHalfY = h / 2;
5420
+ const pinToeHalfX = pinRowSpanX / 2;
5421
+ const pinRowHalfY = pinRowSpanY / 2;
5422
+ const courtyardEnvelopeHalfX = Math.max(bodyHalfX, pinToeHalfX);
5423
+ const courtyardEnvelopeHalfY = Math.max(bodyHalfY, pinRowHalfY);
5424
+ const courtyardNarrowHalfX = Math.min(bodyHalfX, pinToeHalfX);
5425
+ const courtyardNarrowHalfY = Math.min(bodyHalfY, pinRowHalfY);
5426
+ const courtyardStepOuterHalfX = roundToCourtyardGrid(
5427
+ courtyardEnvelopeHalfX + 0.05
5428
+ );
5429
+ const courtyardStepInnerHalfX = roundToCourtyardGrid(
5430
+ courtyardNarrowHalfX - 0.055
5431
+ );
5432
+ const courtyardStepOuterHalfY = roundToCourtyardGrid(courtyardEnvelopeHalfY);
5433
+ const courtyardStepInnerHalfY = roundToCourtyardGrid(
5434
+ courtyardNarrowHalfY + 0.155
5435
+ );
5344
5436
  const courtyard = {
5345
- type: "pcb_courtyard_rect",
5346
- pcb_courtyard_rect_id: "",
5437
+ type: "pcb_courtyard_outline",
5438
+ pcb_courtyard_outline_id: "",
5347
5439
  pcb_component_id: "",
5348
- center: { x: 0, y: 0 },
5349
- width: courtyardWidthMm,
5350
- height: courtyardHeightMm,
5440
+ outline: createRectUnionOutline([
5441
+ {
5442
+ minX: -courtyardStepOuterHalfX,
5443
+ maxX: courtyardStepOuterHalfX,
5444
+ minY: -courtyardStepInnerHalfY,
5445
+ maxY: courtyardStepInnerHalfY
5446
+ },
5447
+ {
5448
+ minX: -courtyardStepInnerHalfX,
5449
+ maxX: courtyardStepInnerHalfX,
5450
+ minY: -courtyardStepOuterHalfY,
5451
+ maxY: courtyardStepOuterHalfY
5452
+ }
5453
+ ]),
5351
5454
  layer: "top"
5352
5455
  };
5353
5456
  return {
@@ -7146,6 +7249,8 @@ var get2CcwSot2235Coords = (parameters) => {
7146
7249
  };
7147
7250
  var sot223_5 = (parameters) => {
7148
7251
  const pads = [];
7252
+ let padOuterHalfX = 0;
7253
+ let padOuterHalfY = 0;
7149
7254
  for (let i = 1; i <= parameters.num_pins; i++) {
7150
7255
  const { x, y } = get2CcwSot2235Coords({
7151
7256
  h: Number.parseFloat(parameters.h),
@@ -7162,6 +7267,8 @@ var sot223_5 = (parameters) => {
7162
7267
  pinWidth = 1;
7163
7268
  pinLength = 2.2;
7164
7269
  }
7270
+ padOuterHalfX = Math.max(padOuterHalfX, Math.abs(x) + pinLength / 2);
7271
+ padOuterHalfY = Math.max(padOuterHalfY, Math.abs(y) + pinWidth / 2);
7165
7272
  pads.push(rectpad(i, x, y, pinLength, pinWidth));
7166
7273
  }
7167
7274
  const width = Number.parseFloat(parameters.w) / 2 - 2.4;
@@ -7191,21 +7298,29 @@ var sot223_5 = (parameters) => {
7191
7298
  stroke_width: 0.1
7192
7299
  };
7193
7300
  const silkscreenRefText = silkscreenRef(0, 0, 0.3);
7194
- const w = Number.parseFloat(parameters.w);
7195
- const courtyardPadding = 0.25;
7196
- const padOuterX = w / 2 - 1.2 + 2.2 / 2;
7197
- const crtMinX = -(padOuterX + courtyardPadding);
7198
- const crtMaxX = padOuterX + courtyardPadding;
7199
- const h5 = Number.parseFloat(parameters.h);
7200
- const crtMinY = -(Math.max(h5 / 2, 2.25 + 0.5) + courtyardPadding);
7201
- const crtMaxY = Math.max(h5 / 2, 2.25 + 0.5) + courtyardPadding;
7301
+ const roundToCourtyardGrid = (value) => Math.round(value / 0.01) * 0.01;
7302
+ const courtyardStepOuterHalfX = roundToCourtyardGrid(padOuterHalfX + 0.25);
7303
+ const courtyardStepInnerHalfX = courtyardStepOuterHalfX;
7304
+ const courtyardStepOuterHalfY = roundToCourtyardGrid(padOuterHalfY + 0.85);
7305
+ const courtyardStepInnerHalfY = courtyardStepOuterHalfY;
7202
7306
  const courtyard = {
7203
- type: "pcb_courtyard_rect",
7204
- pcb_courtyard_rect_id: "",
7307
+ type: "pcb_courtyard_outline",
7308
+ pcb_courtyard_outline_id: "",
7205
7309
  pcb_component_id: "",
7206
- center: { x: (crtMinX + crtMaxX) / 2, y: (crtMinY + crtMaxY) / 2 },
7207
- width: crtMaxX - crtMinX,
7208
- height: crtMaxY - crtMinY,
7310
+ outline: createRectUnionOutline([
7311
+ {
7312
+ minX: -courtyardStepOuterHalfX,
7313
+ maxX: courtyardStepOuterHalfX,
7314
+ minY: -courtyardStepInnerHalfY,
7315
+ maxY: courtyardStepInnerHalfY
7316
+ },
7317
+ {
7318
+ minX: -courtyardStepInnerHalfX,
7319
+ maxX: courtyardStepInnerHalfX,
7320
+ minY: -courtyardStepOuterHalfY,
7321
+ maxY: courtyardStepOuterHalfY
7322
+ }
7323
+ ]),
7209
7324
  layer: "top"
7210
7325
  };
7211
7326
  return [
@@ -7959,20 +8074,33 @@ var vssop = (raw_params) => {
7959
8074
  silkscreenBoxHeight / 2 + 0.5,
7960
8075
  0.3
7961
8076
  );
7962
- const courtyardPadding = 0.25;
7963
- const padCenterX = parameters.num_pins === 10 ? length50.parse("2.2mm") : length50.parse("1.8mm");
7964
- const crtMinX = -(padCenterX + pl / 2) - courtyardPadding;
7965
- const crtMaxX = padCenterX + pl / 2 + courtyardPadding;
7966
- const crtMinY = -silkscreenBoxHeight / 2 - courtyardPadding;
7967
- const crtMaxY = silkscreenBoxHeight / 2 + courtyardPadding;
8077
+ const roundToCourtyardGrid = (value) => Math.round(value / 0.01) * 0.01;
8078
+ const pinRowSpanY = (parameters.num_pins / 2 - 1) * p + pw;
8079
+ const courtyardStepInnerHalfX = roundToCourtyardGrid(w / 2 + 0.25);
8080
+ const courtyardStepOuterHalfX = roundToCourtyardGrid(
8081
+ courtyardStepInnerHalfX + 1.43
8082
+ );
8083
+ const courtyardStepInnerHalfY = roundToCourtyardGrid(pinRowSpanY / 2 + 0.255);
8084
+ const courtyardStepOuterHalfY = roundToCourtyardGrid(h / 2 + 0.25);
7968
8085
  const courtyard = {
7969
- type: "pcb_courtyard_rect",
7970
- pcb_courtyard_rect_id: "",
8086
+ type: "pcb_courtyard_outline",
8087
+ pcb_courtyard_outline_id: "",
7971
8088
  pcb_component_id: "",
7972
- center: { x: (crtMinX + crtMaxX) / 2, y: (crtMinY + crtMaxY) / 2 },
7973
- width: crtMaxX - crtMinX,
7974
- height: crtMaxY - crtMinY,
7975
- layer: "top"
8089
+ layer: "top",
8090
+ outline: createRectUnionOutline([
8091
+ {
8092
+ minX: -courtyardStepOuterHalfX,
8093
+ maxX: courtyardStepOuterHalfX,
8094
+ minY: -courtyardStepInnerHalfY,
8095
+ maxY: courtyardStepInnerHalfY
8096
+ },
8097
+ {
8098
+ minX: -courtyardStepInnerHalfX,
8099
+ maxX: courtyardStepInnerHalfX,
8100
+ minY: -courtyardStepOuterHalfY,
8101
+ maxY: courtyardStepOuterHalfY
8102
+ }
8103
+ ])
7976
8104
  };
7977
8105
  return {
7978
8106
  circuitJson: [