@tscircuit/core 0.0.892 → 0.0.893
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +12 -4
- package/dist/index.js +2151 -2142
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -143,6 +143,7 @@ var orderedRenderPhases = [
|
|
|
143
143
|
"PcbComponentAnchorAlignment",
|
|
144
144
|
"PcbLayout",
|
|
145
145
|
"PcbBoardAutoSize",
|
|
146
|
+
"PanelLayout",
|
|
146
147
|
"PcbTraceHintRender",
|
|
147
148
|
"PcbManualTraceRender",
|
|
148
149
|
"PcbTraceRender",
|
|
@@ -3618,7 +3619,7 @@ var createComponentsFromCircuitJson = ({
|
|
|
3618
3619
|
components.push(
|
|
3619
3620
|
new SilkscreenText({
|
|
3620
3621
|
anchorAlignment: elm.anchor_alignment || "center",
|
|
3621
|
-
text: componentName,
|
|
3622
|
+
text: componentName || elm.text,
|
|
3622
3623
|
fontSize: elm.font_size + 0.2,
|
|
3623
3624
|
pcbX: Number.isNaN(elm.anchor_position.x) ? 0 : elm.anchor_position.x,
|
|
3624
3625
|
pcbY: elm.anchor_position.y,
|
|
@@ -14487,327 +14488,1219 @@ var Group6 = class extends NormalComponent3 {
|
|
|
14487
14488
|
}
|
|
14488
14489
|
};
|
|
14489
14490
|
|
|
14490
|
-
// lib/
|
|
14491
|
-
import {
|
|
14492
|
-
|
|
14493
|
-
|
|
14494
|
-
|
|
14495
|
-
|
|
14496
|
-
|
|
14497
|
-
|
|
14498
|
-
|
|
14499
|
-
|
|
14500
|
-
|
|
14501
|
-
import { getBoundsFromPoints as getBoundsFromPoints4 } from "@tscircuit/math-utils";
|
|
14502
|
-
var MIN_EFFECTIVE_BORDER_RADIUS_MM = 0.01;
|
|
14503
|
-
var getRoundedRectOutline = (width, height, radius) => {
|
|
14504
|
-
const w2 = width / 2;
|
|
14505
|
-
const h2 = height / 2;
|
|
14506
|
-
const r = Math.min(radius, w2, h2);
|
|
14507
|
-
if (r < MIN_EFFECTIVE_BORDER_RADIUS_MM) {
|
|
14508
|
-
return [
|
|
14509
|
-
{ x: -w2, y: -h2 },
|
|
14510
|
-
{ x: w2, y: -h2 },
|
|
14511
|
-
{ x: w2, y: h2 },
|
|
14512
|
-
{ x: -w2, y: h2 }
|
|
14513
|
-
];
|
|
14514
|
-
}
|
|
14515
|
-
const maxArcLengthPerSegment = 0.1;
|
|
14516
|
-
const segments = Math.max(
|
|
14517
|
-
1,
|
|
14518
|
-
Math.ceil(Math.PI / 2 * r / maxArcLengthPerSegment)
|
|
14519
|
-
);
|
|
14520
|
-
const step = Math.PI / 2 / segments;
|
|
14521
|
-
const outline = [];
|
|
14522
|
-
outline.push({ x: -w2 + r, y: -h2 });
|
|
14523
|
-
outline.push({ x: w2 - r, y: -h2 });
|
|
14524
|
-
for (let i = 1; i <= segments; i++) {
|
|
14525
|
-
const theta = -Math.PI / 2 + i * step;
|
|
14526
|
-
outline.push({
|
|
14527
|
-
x: w2 - r + r * Math.cos(theta),
|
|
14528
|
-
y: -h2 + r + r * Math.sin(theta)
|
|
14529
|
-
});
|
|
14530
|
-
}
|
|
14531
|
-
outline.push({ x: w2, y: h2 - r });
|
|
14532
|
-
for (let i = 1; i <= segments; i++) {
|
|
14533
|
-
const theta = 0 + i * step;
|
|
14534
|
-
outline.push({
|
|
14535
|
-
x: w2 - r + r * Math.cos(theta),
|
|
14536
|
-
y: h2 - r + r * Math.sin(theta)
|
|
14537
|
-
});
|
|
14538
|
-
}
|
|
14539
|
-
outline.push({ x: -w2 + r, y: h2 });
|
|
14540
|
-
for (let i = 1; i <= segments; i++) {
|
|
14541
|
-
const theta = Math.PI / 2 + i * step;
|
|
14542
|
-
outline.push({
|
|
14543
|
-
x: -w2 + r + r * Math.cos(theta),
|
|
14544
|
-
y: h2 - r + r * Math.sin(theta)
|
|
14545
|
-
});
|
|
14546
|
-
}
|
|
14547
|
-
outline.push({ x: -w2, y: -h2 + r });
|
|
14548
|
-
for (let i = 1; i <= segments; i++) {
|
|
14549
|
-
const theta = Math.PI + i * step;
|
|
14550
|
-
outline.push({
|
|
14551
|
-
x: -w2 + r + r * Math.cos(theta),
|
|
14552
|
-
y: -h2 + r + r * Math.sin(theta)
|
|
14553
|
-
});
|
|
14554
|
-
}
|
|
14555
|
-
return outline;
|
|
14556
|
-
};
|
|
14557
|
-
var Board = class extends Group6 {
|
|
14558
|
-
pcb_board_id = null;
|
|
14559
|
-
source_board_id = null;
|
|
14560
|
-
_drcChecksComplete = false;
|
|
14561
|
-
_connectedSchematicPortPairs = /* @__PURE__ */ new Set();
|
|
14562
|
-
get isSubcircuit() {
|
|
14563
|
-
return true;
|
|
14564
|
-
}
|
|
14565
|
-
get isGroup() {
|
|
14566
|
-
return true;
|
|
14491
|
+
// lib/utils/circuit-json/inflate-circuit-json.ts
|
|
14492
|
+
import { cju } from "@tscircuit/circuit-json-util";
|
|
14493
|
+
|
|
14494
|
+
// lib/components/normal-components/Capacitor.ts
|
|
14495
|
+
import { capacitorProps } from "@tscircuit/props";
|
|
14496
|
+
|
|
14497
|
+
// lib/utils/constants.ts
|
|
14498
|
+
var stringProxy = new Proxy(
|
|
14499
|
+
{},
|
|
14500
|
+
{
|
|
14501
|
+
get: (target, prop) => prop
|
|
14567
14502
|
}
|
|
14503
|
+
);
|
|
14504
|
+
var FTYPE = stringProxy;
|
|
14505
|
+
var SCHEMATIC_COMPONENT_OUTLINE_COLOR = "rgba(132, 0, 0)";
|
|
14506
|
+
var SCHEMATIC_COMPONENT_OUTLINE_STROKE_WIDTH = 0.12;
|
|
14507
|
+
|
|
14508
|
+
// lib/components/normal-components/Capacitor.ts
|
|
14509
|
+
import { formatSiUnit } from "format-si-unit";
|
|
14510
|
+
var Capacitor = class extends NormalComponent3 {
|
|
14511
|
+
_adjustSilkscreenTextAutomatically = true;
|
|
14512
|
+
// @ts-ignore (cause the symbolName is string and not fixed)
|
|
14568
14513
|
get config() {
|
|
14569
14514
|
return {
|
|
14570
|
-
componentName: "
|
|
14571
|
-
|
|
14515
|
+
componentName: "Capacitor",
|
|
14516
|
+
schematicSymbolName: this.props.polarized ? "capacitor_polarized" : this.props.symbolName ?? "capacitor",
|
|
14517
|
+
zodProps: capacitorProps,
|
|
14518
|
+
sourceFtype: FTYPE.simple_capacitor
|
|
14572
14519
|
};
|
|
14573
14520
|
}
|
|
14574
|
-
|
|
14575
|
-
|
|
14576
|
-
|
|
14577
|
-
|
|
14578
|
-
|
|
14579
|
-
|
|
14580
|
-
|
|
14581
|
-
|
|
14582
|
-
|
|
14521
|
+
initPorts() {
|
|
14522
|
+
if (typeof this.props.footprint === "string") {
|
|
14523
|
+
super.initPorts({
|
|
14524
|
+
additionalAliases: {
|
|
14525
|
+
pin1: ["anode", "pos"],
|
|
14526
|
+
pin2: ["cathode", "neg"]
|
|
14527
|
+
}
|
|
14528
|
+
});
|
|
14529
|
+
} else {
|
|
14530
|
+
super.initPorts();
|
|
14531
|
+
}
|
|
14583
14532
|
}
|
|
14584
|
-
|
|
14585
|
-
|
|
14586
|
-
|
|
14587
|
-
|
|
14588
|
-
|
|
14589
|
-
if (layerCount === 4) {
|
|
14590
|
-
return ["top", "bottom", "inner1", "inner2"];
|
|
14533
|
+
_getSchematicSymbolDisplayValue() {
|
|
14534
|
+
const inputCapacitance = this.props.capacitance;
|
|
14535
|
+
const capacitanceDisplay = typeof inputCapacitance === "string" ? inputCapacitance : `${formatSiUnit(this._parsedProps.capacitance)}F`;
|
|
14536
|
+
if (this._parsedProps.schShowRatings && this._parsedProps.maxVoltageRating) {
|
|
14537
|
+
return `${capacitanceDisplay}/${formatSiUnit(this._parsedProps.maxVoltageRating)}V`;
|
|
14591
14538
|
}
|
|
14592
|
-
return
|
|
14539
|
+
return capacitanceDisplay;
|
|
14593
14540
|
}
|
|
14594
|
-
|
|
14595
|
-
|
|
14541
|
+
doInitialCreateNetsFromProps() {
|
|
14542
|
+
this._createNetsFromProps([
|
|
14543
|
+
this.props.decouplingFor,
|
|
14544
|
+
this.props.decouplingTo,
|
|
14545
|
+
...this._getNetsFromConnectionsProp()
|
|
14546
|
+
]);
|
|
14596
14547
|
}
|
|
14597
|
-
|
|
14598
|
-
|
|
14599
|
-
|
|
14600
|
-
|
|
14601
|
-
|
|
14602
|
-
|
|
14603
|
-
|
|
14604
|
-
|
|
14605
|
-
|
|
14606
|
-
|
|
14607
|
-
|
|
14608
|
-
|
|
14609
|
-
|
|
14548
|
+
doInitialCreateTracesFromProps() {
|
|
14549
|
+
if (this.props.decouplingFor && this.props.decouplingTo) {
|
|
14550
|
+
this.add(
|
|
14551
|
+
new Trace3({
|
|
14552
|
+
from: `${this.getSubcircuitSelector()} > port.1`,
|
|
14553
|
+
to: this.props.decouplingFor
|
|
14554
|
+
})
|
|
14555
|
+
);
|
|
14556
|
+
this.add(
|
|
14557
|
+
new Trace3({
|
|
14558
|
+
from: `${this.getSubcircuitSelector()} > port.2`,
|
|
14559
|
+
to: this.props.decouplingTo
|
|
14560
|
+
})
|
|
14561
|
+
);
|
|
14610
14562
|
}
|
|
14611
|
-
|
|
14612
|
-
const center = dbBoard?.center ?? {
|
|
14613
|
-
x: pcbX + (props.outlineOffsetX ?? 0),
|
|
14614
|
-
y: pcbY + (props.outlineOffsetY ?? 0)
|
|
14615
|
-
};
|
|
14616
|
-
const resolvedWidth = width ?? 0;
|
|
14617
|
-
const resolvedHeight = height ?? 0;
|
|
14618
|
-
return {
|
|
14619
|
-
"board.minx": center.x - resolvedWidth / 2,
|
|
14620
|
-
"board.maxx": center.x + resolvedWidth / 2,
|
|
14621
|
-
"board.miny": center.y - resolvedHeight / 2,
|
|
14622
|
-
"board.maxy": center.y + resolvedHeight / 2
|
|
14623
|
-
};
|
|
14563
|
+
this._createTracesFromConnectionsProp();
|
|
14624
14564
|
}
|
|
14625
|
-
|
|
14626
|
-
if (this.root?.pcbDisabled) return;
|
|
14627
|
-
if (!this.pcb_board_id) return;
|
|
14565
|
+
doInitialSourceRender() {
|
|
14628
14566
|
const { db } = this.root;
|
|
14629
14567
|
const { _parsedProps: props } = this;
|
|
14630
|
-
const
|
|
14631
|
-
|
|
14632
|
-
|
|
14633
|
-
|
|
14634
|
-
|
|
14568
|
+
const source_component = db.source_component.insert({
|
|
14569
|
+
ftype: "simple_capacitor",
|
|
14570
|
+
name: this.name,
|
|
14571
|
+
// @ts-ignore
|
|
14572
|
+
manufacturer_part_number: props.manufacturerPartNumber ?? props.mfn,
|
|
14573
|
+
supplier_part_numbers: props.supplierPartNumbers,
|
|
14574
|
+
capacitance: props.capacitance,
|
|
14575
|
+
max_voltage_rating: props.maxVoltageRating,
|
|
14576
|
+
max_decoupling_trace_length: props.maxDecouplingTraceLength,
|
|
14577
|
+
display_capacitance: this._getSchematicSymbolDisplayValue(),
|
|
14578
|
+
are_pins_interchangeable: !props.polarized
|
|
14635
14579
|
});
|
|
14636
|
-
|
|
14637
|
-
let minX = Infinity;
|
|
14638
|
-
let minY = Infinity;
|
|
14639
|
-
let maxX = -Infinity;
|
|
14640
|
-
let maxY = -Infinity;
|
|
14641
|
-
const descendantIds = getDescendantSubcircuitIds(db, this.subcircuit_id);
|
|
14642
|
-
const allowedSubcircuitIds = /* @__PURE__ */ new Set([this.subcircuit_id, ...descendantIds]);
|
|
14643
|
-
const allPcbComponents = db.pcb_component.list().filter(
|
|
14644
|
-
(c) => c.subcircuit_id && allowedSubcircuitIds.has(c.subcircuit_id)
|
|
14645
|
-
);
|
|
14646
|
-
const allPcbGroups = db.pcb_group.list().filter(
|
|
14647
|
-
(g) => g.subcircuit_id && allowedSubcircuitIds.has(g.subcircuit_id)
|
|
14648
|
-
);
|
|
14649
|
-
let hasComponents = false;
|
|
14650
|
-
const updateBounds = (center2, width, height) => {
|
|
14651
|
-
if (width === 0 || height === 0) return;
|
|
14652
|
-
hasComponents = true;
|
|
14653
|
-
minX = Math.min(minX, center2.x - width / 2);
|
|
14654
|
-
minY = Math.min(minY, center2.y - height / 2);
|
|
14655
|
-
maxX = Math.max(maxX, center2.x + width / 2);
|
|
14656
|
-
maxY = Math.max(maxY, center2.y + height / 2);
|
|
14657
|
-
};
|
|
14658
|
-
for (const pcbComponent of allPcbComponents) {
|
|
14659
|
-
updateBounds(pcbComponent.center, pcbComponent.width, pcbComponent.height);
|
|
14660
|
-
}
|
|
14661
|
-
for (const pcbGroup of allPcbGroups) {
|
|
14662
|
-
let width = pcbGroup.width ?? 0;
|
|
14663
|
-
let height = pcbGroup.height ?? 0;
|
|
14664
|
-
if (pcbGroup.outline && pcbGroup.outline.length > 0) {
|
|
14665
|
-
const bounds = getBoundsFromPoints4(pcbGroup.outline);
|
|
14666
|
-
if (bounds) {
|
|
14667
|
-
width = bounds.maxX - bounds.minX;
|
|
14668
|
-
height = bounds.maxY - bounds.minY;
|
|
14669
|
-
}
|
|
14670
|
-
}
|
|
14671
|
-
updateBounds(pcbGroup.center, width, height);
|
|
14672
|
-
}
|
|
14673
|
-
if (props.boardAnchorPosition) {
|
|
14674
|
-
const { x, y } = props.boardAnchorPosition;
|
|
14675
|
-
minX = Math.min(minX, x);
|
|
14676
|
-
minY = Math.min(minY, y);
|
|
14677
|
-
maxX = Math.max(maxX, x);
|
|
14678
|
-
maxY = Math.max(maxY, y);
|
|
14679
|
-
}
|
|
14680
|
-
const padding = 2;
|
|
14681
|
-
const computedWidth = hasComponents ? maxX - minX + padding * 2 : 0;
|
|
14682
|
-
const computedHeight = hasComponents ? maxY - minY + padding * 2 : 0;
|
|
14683
|
-
const center = {
|
|
14684
|
-
x: hasComponents ? (minX + maxX) / 2 + (props.outlineOffsetX ?? 0) : (props.outlineOffsetX ?? 0) + pcbX,
|
|
14685
|
-
y: hasComponents ? (minY + maxY) / 2 + (props.outlineOffsetY ?? 0) : (props.outlineOffsetY ?? 0) + pcbY
|
|
14686
|
-
};
|
|
14687
|
-
const finalWidth = props.width ?? computedWidth;
|
|
14688
|
-
const finalHeight = props.height ?? computedHeight;
|
|
14689
|
-
let outline = props.outline;
|
|
14690
|
-
if (!outline && props.borderRadius != null && finalWidth > 0 && finalHeight > 0) {
|
|
14691
|
-
outline = getRoundedRectOutline(
|
|
14692
|
-
finalWidth,
|
|
14693
|
-
finalHeight,
|
|
14694
|
-
props.borderRadius
|
|
14695
|
-
);
|
|
14696
|
-
}
|
|
14697
|
-
const update = {
|
|
14698
|
-
width: finalWidth,
|
|
14699
|
-
height: finalHeight,
|
|
14700
|
-
center
|
|
14701
|
-
};
|
|
14702
|
-
if (outline) {
|
|
14703
|
-
update.outline = outline.map((point) => ({
|
|
14704
|
-
x: point.x + (props.outlineOffsetX ?? 0),
|
|
14705
|
-
y: point.y + (props.outlineOffsetY ?? 0)
|
|
14706
|
-
}));
|
|
14707
|
-
}
|
|
14708
|
-
db.pcb_board.update(this.pcb_board_id, update);
|
|
14580
|
+
this.source_component_id = source_component.source_component_id;
|
|
14709
14581
|
}
|
|
14710
|
-
|
|
14711
|
-
|
|
14712
|
-
|
|
14582
|
+
};
|
|
14583
|
+
|
|
14584
|
+
// lib/components/primitive-components/Group/Subcircuit/inflators/inflatePcbComponent.ts
|
|
14585
|
+
import { compose as compose5, translate as translate6, rotate as rotate3, inverse } from "transformation-matrix";
|
|
14586
|
+
import { transformPCBElements as transformPCBElements2 } from "@tscircuit/circuit-json-util";
|
|
14587
|
+
var inflatePcbComponent = (pcbElm, inflatorContext) => {
|
|
14588
|
+
const { injectionDb, normalComponent } = inflatorContext;
|
|
14589
|
+
if (!normalComponent) return;
|
|
14590
|
+
const componentCenter = pcbElm.center || { x: 0, y: 0 };
|
|
14591
|
+
const componentRotation = pcbElm.rotation || 0;
|
|
14592
|
+
const absoluteToComponentRelativeTransform = inverse(
|
|
14593
|
+
compose5(
|
|
14594
|
+
translate6(componentCenter.x, componentCenter.y),
|
|
14595
|
+
rotate3(componentRotation * Math.PI / 180)
|
|
14596
|
+
)
|
|
14597
|
+
);
|
|
14598
|
+
const relativeElements = injectionDb.toArray().filter(
|
|
14599
|
+
(elm) => "pcb_component_id" in elm && elm.pcb_component_id === pcbElm.pcb_component_id
|
|
14600
|
+
);
|
|
14601
|
+
transformPCBElements2(relativeElements, absoluteToComponentRelativeTransform);
|
|
14602
|
+
const components = createComponentsFromCircuitJson(
|
|
14603
|
+
{
|
|
14604
|
+
componentName: normalComponent.name,
|
|
14605
|
+
componentRotation: "0deg"
|
|
14606
|
+
},
|
|
14607
|
+
relativeElements
|
|
14608
|
+
);
|
|
14609
|
+
normalComponent.addAll(components);
|
|
14610
|
+
};
|
|
14611
|
+
|
|
14612
|
+
// lib/components/primitive-components/Group/Subcircuit/inflators/inflateSourceCapacitor.ts
|
|
14613
|
+
function inflateSourceCapacitor(sourceElm, inflatorContext) {
|
|
14614
|
+
const { injectionDb, subcircuit, groupsMap } = inflatorContext;
|
|
14615
|
+
const pcbElm = injectionDb.pcb_component.getWhere({
|
|
14616
|
+
source_component_id: sourceElm.source_component_id
|
|
14617
|
+
});
|
|
14618
|
+
const cadElm = injectionDb.cad_component.getWhere({
|
|
14619
|
+
source_component_id: sourceElm.source_component_id
|
|
14620
|
+
});
|
|
14621
|
+
const capacitor = new Capacitor({
|
|
14622
|
+
name: sourceElm.name,
|
|
14623
|
+
capacitance: sourceElm.capacitance,
|
|
14624
|
+
layer: pcbElm?.layer,
|
|
14625
|
+
pcbX: pcbElm?.center?.x,
|
|
14626
|
+
pcbY: pcbElm?.center?.y,
|
|
14627
|
+
pcbRotation: pcbElm?.rotation,
|
|
14628
|
+
doNotPlace: pcbElm?.do_not_place,
|
|
14629
|
+
obstructsWithinBounds: pcbElm?.obstructs_within_bounds
|
|
14630
|
+
});
|
|
14631
|
+
if (pcbElm) {
|
|
14632
|
+
inflatePcbComponent(pcbElm, {
|
|
14633
|
+
...inflatorContext,
|
|
14634
|
+
normalComponent: capacitor
|
|
14635
|
+
});
|
|
14713
14636
|
}
|
|
14714
|
-
|
|
14715
|
-
|
|
14716
|
-
|
|
14717
|
-
|
|
14718
|
-
|
|
14719
|
-
|
|
14720
|
-
|
|
14721
|
-
|
|
14722
|
-
|
|
14723
|
-
|
|
14724
|
-
|
|
14725
|
-
|
|
14726
|
-
|
|
14727
|
-
|
|
14728
|
-
|
|
14729
|
-
|
|
14730
|
-
|
|
14731
|
-
|
|
14732
|
-
|
|
14733
|
-
|
|
14637
|
+
if (sourceElm.source_group_id && groupsMap?.has(sourceElm.source_group_id)) {
|
|
14638
|
+
const group = groupsMap.get(sourceElm.source_group_id);
|
|
14639
|
+
group.add(capacitor);
|
|
14640
|
+
} else {
|
|
14641
|
+
subcircuit.add(capacitor);
|
|
14642
|
+
}
|
|
14643
|
+
}
|
|
14644
|
+
|
|
14645
|
+
// lib/components/normal-components/Chip.ts
|
|
14646
|
+
import { chipProps as chipProps2 } from "@tscircuit/props";
|
|
14647
|
+
import { pcb_component_invalid_layer_error as pcb_component_invalid_layer_error2 } from "circuit-json";
|
|
14648
|
+
var Chip = class extends NormalComponent3 {
|
|
14649
|
+
schematicBoxDimensions = null;
|
|
14650
|
+
constructor(props) {
|
|
14651
|
+
super(props);
|
|
14652
|
+
}
|
|
14653
|
+
get config() {
|
|
14654
|
+
return {
|
|
14655
|
+
componentName: "Chip",
|
|
14656
|
+
zodProps: chipProps2,
|
|
14657
|
+
shouldRenderAsSchematicBox: true
|
|
14734
14658
|
};
|
|
14735
|
-
|
|
14736
|
-
|
|
14737
|
-
|
|
14738
|
-
|
|
14739
|
-
|
|
14740
|
-
|
|
14741
|
-
|
|
14742
|
-
|
|
14743
|
-
|
|
14744
|
-
|
|
14659
|
+
}
|
|
14660
|
+
initPorts(opts = {}) {
|
|
14661
|
+
super.initPorts(opts);
|
|
14662
|
+
const { _parsedProps: props } = this;
|
|
14663
|
+
const { pcbX, pcbY } = this.getResolvedPcbPositionProp();
|
|
14664
|
+
if (props.externallyConnectedPins) {
|
|
14665
|
+
const requiredPorts = /* @__PURE__ */ new Set();
|
|
14666
|
+
for (const [pin1, pin2] of props.externallyConnectedPins) {
|
|
14667
|
+
requiredPorts.add(pin1);
|
|
14668
|
+
requiredPorts.add(pin2);
|
|
14669
|
+
}
|
|
14670
|
+
for (const pinIdentifier of requiredPorts) {
|
|
14671
|
+
const existingPort = this.children.find(
|
|
14672
|
+
(child) => child instanceof Port && child.isMatchingAnyOf([pinIdentifier])
|
|
14673
|
+
);
|
|
14674
|
+
if (!existingPort) {
|
|
14675
|
+
const pinMatch = pinIdentifier.match(/^pin(\d+)$/);
|
|
14676
|
+
if (pinMatch) {
|
|
14677
|
+
const pinNumber = parseInt(pinMatch[1]);
|
|
14678
|
+
this.add(
|
|
14679
|
+
new Port({
|
|
14680
|
+
pinNumber,
|
|
14681
|
+
aliases: [pinIdentifier]
|
|
14682
|
+
})
|
|
14683
|
+
);
|
|
14684
|
+
} else {
|
|
14685
|
+
this.add(
|
|
14686
|
+
new Port({
|
|
14687
|
+
name: pinIdentifier,
|
|
14688
|
+
aliases: [pinIdentifier]
|
|
14689
|
+
})
|
|
14690
|
+
);
|
|
14691
|
+
}
|
|
14692
|
+
}
|
|
14693
|
+
}
|
|
14694
|
+
}
|
|
14695
|
+
}
|
|
14696
|
+
doInitialSchematicComponentRender() {
|
|
14697
|
+
const { _parsedProps: props } = this;
|
|
14698
|
+
if (props?.noSchematicRepresentation === true) return;
|
|
14699
|
+
super.doInitialSchematicComponentRender();
|
|
14745
14700
|
}
|
|
14746
14701
|
doInitialSourceRender() {
|
|
14747
|
-
super.doInitialSourceRender();
|
|
14748
14702
|
const { db } = this.root;
|
|
14749
|
-
const
|
|
14750
|
-
|
|
14751
|
-
|
|
14703
|
+
const { _parsedProps: props } = this;
|
|
14704
|
+
const { pcbX, pcbY } = this.getResolvedPcbPositionProp();
|
|
14705
|
+
const source_component = db.source_component.insert({
|
|
14706
|
+
ftype: "simple_chip",
|
|
14707
|
+
name: this.name,
|
|
14708
|
+
manufacturer_part_number: props.manufacturerPartNumber,
|
|
14709
|
+
supplier_part_numbers: props.supplierPartNumbers
|
|
14752
14710
|
});
|
|
14753
|
-
this.
|
|
14711
|
+
this.source_component_id = source_component.source_component_id;
|
|
14754
14712
|
}
|
|
14755
14713
|
doInitialPcbComponentRender() {
|
|
14756
14714
|
if (this.root?.pcbDisabled) return;
|
|
14757
14715
|
const { db } = this.root;
|
|
14758
14716
|
const { _parsedProps: props } = this;
|
|
14759
|
-
let computedWidth = props.width ?? 0;
|
|
14760
|
-
let computedHeight = props.height ?? 0;
|
|
14761
14717
|
const { pcbX, pcbY } = this.getResolvedPcbPositionProp();
|
|
14762
|
-
|
|
14763
|
-
|
|
14764
|
-
|
|
14765
|
-
|
|
14766
|
-
|
|
14767
|
-
|
|
14768
|
-
|
|
14769
|
-
|
|
14770
|
-
|
|
14771
|
-
width: computedWidth,
|
|
14772
|
-
height: computedHeight
|
|
14718
|
+
const componentLayer = props.layer ?? "top";
|
|
14719
|
+
if (componentLayer !== "top" && componentLayer !== "bottom") {
|
|
14720
|
+
const subcircuit = this.getSubcircuit();
|
|
14721
|
+
const error = pcb_component_invalid_layer_error2.parse({
|
|
14722
|
+
type: "pcb_component_invalid_layer_error",
|
|
14723
|
+
message: `Component cannot be placed on layer '${componentLayer}'. Components can only be placed on 'top' or 'bottom' layers.`,
|
|
14724
|
+
source_component_id: this.source_component_id,
|
|
14725
|
+
layer: componentLayer,
|
|
14726
|
+
subcircuit_id: subcircuit.subcircuit_id ?? void 0
|
|
14773
14727
|
});
|
|
14728
|
+
db.pcb_component_invalid_layer_error.insert(error);
|
|
14774
14729
|
}
|
|
14775
|
-
|
|
14776
|
-
|
|
14777
|
-
|
|
14778
|
-
|
|
14779
|
-
|
|
14780
|
-
|
|
14781
|
-
|
|
14782
|
-
|
|
14783
|
-
|
|
14784
|
-
|
|
14785
|
-
|
|
14786
|
-
|
|
14787
|
-
};
|
|
14788
|
-
}
|
|
14789
|
-
let outline = props.outline;
|
|
14790
|
-
if (!outline && props.borderRadius != null && computedWidth > 0 && computedHeight > 0) {
|
|
14791
|
-
outline = getRoundedRectOutline(
|
|
14792
|
-
computedWidth,
|
|
14793
|
-
computedHeight,
|
|
14794
|
-
props.borderRadius
|
|
14795
|
-
);
|
|
14796
|
-
}
|
|
14797
|
-
const pcb_board = db.pcb_board.insert({
|
|
14798
|
-
center,
|
|
14799
|
-
thickness: this.boardThickness,
|
|
14800
|
-
num_layers: this.allLayers.length,
|
|
14801
|
-
width: computedWidth,
|
|
14802
|
-
height: computedHeight,
|
|
14803
|
-
outline: outline?.map((point) => ({
|
|
14804
|
-
x: point.x + (props.outlineOffsetX ?? 0),
|
|
14805
|
-
y: point.y + (props.outlineOffsetY ?? 0)
|
|
14806
|
-
})),
|
|
14807
|
-
material: props.material
|
|
14730
|
+
const pcb_component = db.pcb_component.insert({
|
|
14731
|
+
center: { x: pcbX, y: pcbY },
|
|
14732
|
+
width: 2,
|
|
14733
|
+
// Default width, adjust as needed
|
|
14734
|
+
height: 3,
|
|
14735
|
+
// Default height, adjust as needed
|
|
14736
|
+
layer: componentLayer === "top" || componentLayer === "bottom" ? componentLayer : "top",
|
|
14737
|
+
rotation: props.pcbRotation ?? 0,
|
|
14738
|
+
source_component_id: this.source_component_id,
|
|
14739
|
+
subcircuit_id: this.getSubcircuit().subcircuit_id ?? void 0,
|
|
14740
|
+
do_not_place: props.doNotPlace ?? false,
|
|
14741
|
+
obstructs_within_bounds: props.obstructsWithinBounds ?? true
|
|
14808
14742
|
});
|
|
14809
|
-
this.
|
|
14810
|
-
|
|
14743
|
+
this.pcb_component_id = pcb_component.pcb_component_id;
|
|
14744
|
+
}
|
|
14745
|
+
doInitialCreateTracesFromProps() {
|
|
14746
|
+
const { _parsedProps: props } = this;
|
|
14747
|
+
if (props.externallyConnectedPins) {
|
|
14748
|
+
for (const [pin1, pin2] of props.externallyConnectedPins) {
|
|
14749
|
+
this.add(
|
|
14750
|
+
new Trace3({
|
|
14751
|
+
from: `${this.getSubcircuitSelector()} > port.${pin1}`,
|
|
14752
|
+
to: `${this.getSubcircuitSelector()} > port.${pin2}`
|
|
14753
|
+
})
|
|
14754
|
+
);
|
|
14755
|
+
}
|
|
14756
|
+
}
|
|
14757
|
+
this._createTracesFromConnectionsProp();
|
|
14758
|
+
}
|
|
14759
|
+
doInitialSimulationRender() {
|
|
14760
|
+
const { db } = this.root;
|
|
14761
|
+
const { pinAttributes } = this.props;
|
|
14762
|
+
if (!pinAttributes) return;
|
|
14763
|
+
let powerPort = null;
|
|
14764
|
+
let groundPort = null;
|
|
14765
|
+
let voltage;
|
|
14766
|
+
const ports = this.selectAll("port");
|
|
14767
|
+
for (const port of ports) {
|
|
14768
|
+
for (const alias of port.getNameAndAliases()) {
|
|
14769
|
+
if (pinAttributes[alias]) {
|
|
14770
|
+
const attributes = pinAttributes[alias];
|
|
14771
|
+
if (attributes.providesPower) {
|
|
14772
|
+
powerPort = port;
|
|
14773
|
+
voltage = attributes.providesVoltage;
|
|
14774
|
+
}
|
|
14775
|
+
if (attributes.providesGround) {
|
|
14776
|
+
groundPort = port;
|
|
14777
|
+
}
|
|
14778
|
+
}
|
|
14779
|
+
}
|
|
14780
|
+
}
|
|
14781
|
+
if (!powerPort || !groundPort || voltage === void 0) {
|
|
14782
|
+
return;
|
|
14783
|
+
}
|
|
14784
|
+
const powerSourcePort = db.source_port.get(powerPort.source_port_id);
|
|
14785
|
+
if (!powerSourcePort?.subcircuit_connectivity_map_key) return;
|
|
14786
|
+
const groundSourcePort = db.source_port.get(groundPort.source_port_id);
|
|
14787
|
+
if (!groundSourcePort?.subcircuit_connectivity_map_key) return;
|
|
14788
|
+
const powerNet = db.source_net.getWhere({
|
|
14789
|
+
subcircuit_connectivity_map_key: powerSourcePort.subcircuit_connectivity_map_key
|
|
14790
|
+
});
|
|
14791
|
+
const groundNet = db.source_net.getWhere({
|
|
14792
|
+
subcircuit_connectivity_map_key: groundSourcePort.subcircuit_connectivity_map_key
|
|
14793
|
+
});
|
|
14794
|
+
if (!powerNet || !groundNet) {
|
|
14795
|
+
return;
|
|
14796
|
+
}
|
|
14797
|
+
;
|
|
14798
|
+
db.simulation_voltage_source.insert({
|
|
14799
|
+
type: "simulation_voltage_source",
|
|
14800
|
+
positive_source_port_id: powerPort.source_port_id,
|
|
14801
|
+
positive_source_net_id: powerNet.source_net_id,
|
|
14802
|
+
negative_source_port_id: groundPort.source_port_id,
|
|
14803
|
+
negative_source_net_id: groundNet.source_net_id,
|
|
14804
|
+
voltage
|
|
14805
|
+
});
|
|
14806
|
+
}
|
|
14807
|
+
};
|
|
14808
|
+
|
|
14809
|
+
// lib/components/primitive-components/Group/Subcircuit/inflators/inflateSourceChip.ts
|
|
14810
|
+
var mapInternallyConnectedSourcePortIdsToPinLabels = (sourcePortIds, inflatorContext) => {
|
|
14811
|
+
if (!sourcePortIds || sourcePortIds.length === 0) return void 0;
|
|
14812
|
+
const { injectionDb } = inflatorContext;
|
|
14813
|
+
const mapped = sourcePortIds.map(
|
|
14814
|
+
(group) => group.map((sourcePortId) => {
|
|
14815
|
+
const port = injectionDb.source_port.get(
|
|
14816
|
+
sourcePortId
|
|
14817
|
+
);
|
|
14818
|
+
if (!port) return null;
|
|
14819
|
+
if (port.pin_number !== void 0 && port.pin_number !== null) {
|
|
14820
|
+
return `pin${port.pin_number}`;
|
|
14821
|
+
}
|
|
14822
|
+
return port.name;
|
|
14823
|
+
}).filter((value) => value !== null)
|
|
14824
|
+
).filter((group) => group.length > 0);
|
|
14825
|
+
return mapped.length > 0 ? mapped : void 0;
|
|
14826
|
+
};
|
|
14827
|
+
var inflateSourceChip = (sourceElm, inflatorContext) => {
|
|
14828
|
+
const { injectionDb, subcircuit, groupsMap } = inflatorContext;
|
|
14829
|
+
const pcbElm = injectionDb.pcb_component.getWhere({
|
|
14830
|
+
source_component_id: sourceElm.source_component_id
|
|
14831
|
+
});
|
|
14832
|
+
const schematicElm = injectionDb.schematic_component.getWhere({
|
|
14833
|
+
source_component_id: sourceElm.source_component_id
|
|
14834
|
+
});
|
|
14835
|
+
const cadElm = injectionDb.cad_component.getWhere({
|
|
14836
|
+
source_component_id: sourceElm.source_component_id
|
|
14837
|
+
});
|
|
14838
|
+
const internallyConnectedPins = mapInternallyConnectedSourcePortIdsToPinLabels(
|
|
14839
|
+
sourceElm.internally_connected_source_port_ids,
|
|
14840
|
+
inflatorContext
|
|
14841
|
+
);
|
|
14842
|
+
const chip = new Chip({
|
|
14843
|
+
name: sourceElm.name,
|
|
14844
|
+
manufacturerPartNumber: sourceElm.manufacturer_part_number,
|
|
14845
|
+
supplierPartNumbers: sourceElm.supplier_part_numbers ?? void 0,
|
|
14846
|
+
pinLabels: schematicElm?.port_labels ?? void 0,
|
|
14847
|
+
schWidth: schematicElm?.size?.width,
|
|
14848
|
+
schHeight: schematicElm?.size?.height,
|
|
14849
|
+
schPinSpacing: schematicElm?.pin_spacing,
|
|
14850
|
+
schX: schematicElm?.center?.x,
|
|
14851
|
+
schY: schematicElm?.center?.y,
|
|
14852
|
+
layer: pcbElm?.layer,
|
|
14853
|
+
pcbX: pcbElm?.center?.x,
|
|
14854
|
+
pcbY: pcbElm?.center?.y,
|
|
14855
|
+
pcbRotation: pcbElm?.rotation,
|
|
14856
|
+
doNotPlace: pcbElm?.do_not_place,
|
|
14857
|
+
obstructsWithinBounds: pcbElm?.obstructs_within_bounds,
|
|
14858
|
+
internallyConnectedPins
|
|
14859
|
+
});
|
|
14860
|
+
const footprint = cadElm?.footprinter_string ?? null;
|
|
14861
|
+
if (footprint) {
|
|
14862
|
+
Object.assign(chip.props, { footprint });
|
|
14863
|
+
Object.assign(chip._parsedProps, { footprint });
|
|
14864
|
+
if (!cadElm) {
|
|
14865
|
+
;
|
|
14866
|
+
chip._addChildrenFromStringFootprint?.();
|
|
14867
|
+
}
|
|
14868
|
+
}
|
|
14869
|
+
if (pcbElm) {
|
|
14870
|
+
inflatePcbComponent(pcbElm, {
|
|
14871
|
+
...inflatorContext,
|
|
14872
|
+
normalComponent: chip
|
|
14873
|
+
});
|
|
14874
|
+
}
|
|
14875
|
+
if (sourceElm.source_group_id && groupsMap?.has(sourceElm.source_group_id)) {
|
|
14876
|
+
const group = groupsMap.get(sourceElm.source_group_id);
|
|
14877
|
+
group.add(chip);
|
|
14878
|
+
} else {
|
|
14879
|
+
subcircuit.add(chip);
|
|
14880
|
+
}
|
|
14881
|
+
};
|
|
14882
|
+
|
|
14883
|
+
// lib/components/normal-components/Diode.ts
|
|
14884
|
+
import { diodeProps } from "@tscircuit/props";
|
|
14885
|
+
var Diode = class extends NormalComponent3 {
|
|
14886
|
+
// @ts-ignore
|
|
14887
|
+
get config() {
|
|
14888
|
+
const symbolMap = {
|
|
14889
|
+
schottky: "schottky_diode",
|
|
14890
|
+
avalanche: "avalanche_diode",
|
|
14891
|
+
zener: "zener_diode",
|
|
14892
|
+
photodiode: "photodiode"
|
|
14893
|
+
};
|
|
14894
|
+
const variantSymbol = this.props.schottky ? "schottky" : this.props.avalanche ? "avalanche" : this.props.zener ? "zener" : this.props.photo ? "photodiode" : null;
|
|
14895
|
+
return {
|
|
14896
|
+
schematicSymbolName: variantSymbol ? symbolMap[variantSymbol] : this.props.symbolName ?? "diode",
|
|
14897
|
+
componentName: "Diode",
|
|
14898
|
+
zodProps: diodeProps,
|
|
14899
|
+
sourceFtype: "simple_diode"
|
|
14900
|
+
};
|
|
14901
|
+
}
|
|
14902
|
+
initPorts() {
|
|
14903
|
+
super.initPorts({
|
|
14904
|
+
additionalAliases: {
|
|
14905
|
+
pin1: ["anode", "pos", "left"],
|
|
14906
|
+
pin2: ["cathode", "neg", "right"]
|
|
14907
|
+
}
|
|
14908
|
+
});
|
|
14909
|
+
}
|
|
14910
|
+
doInitialSourceRender() {
|
|
14911
|
+
const { db } = this.root;
|
|
14912
|
+
const { _parsedProps: props } = this;
|
|
14913
|
+
const source_component = db.source_component.insert({
|
|
14914
|
+
ftype: "simple_diode",
|
|
14915
|
+
name: this.name,
|
|
14916
|
+
// @ts-ignore
|
|
14917
|
+
manufacturer_part_number: props.manufacturerPartNumber ?? props.mfn,
|
|
14918
|
+
supplier_part_numbers: props.supplierPartNumbers,
|
|
14919
|
+
are_pins_interchangeable: false
|
|
14920
|
+
});
|
|
14921
|
+
this.source_component_id = source_component.source_component_id;
|
|
14922
|
+
}
|
|
14923
|
+
pos = this.portMap.pin1;
|
|
14924
|
+
anode = this.portMap.pin1;
|
|
14925
|
+
neg = this.portMap.pin2;
|
|
14926
|
+
cathode = this.portMap.pin2;
|
|
14927
|
+
};
|
|
14928
|
+
|
|
14929
|
+
// lib/components/primitive-components/Group/Subcircuit/inflators/inflateSourceDiode.ts
|
|
14930
|
+
function inflateSourceDiode(sourceElm, inflatorContext) {
|
|
14931
|
+
const { injectionDb, subcircuit, groupsMap } = inflatorContext;
|
|
14932
|
+
const pcbElm = injectionDb.pcb_component.getWhere({
|
|
14933
|
+
source_component_id: sourceElm.source_component_id
|
|
14934
|
+
});
|
|
14935
|
+
const cadElm = injectionDb.cad_component.getWhere({
|
|
14936
|
+
source_component_id: sourceElm.source_component_id
|
|
14937
|
+
});
|
|
14938
|
+
const diode = new Diode({
|
|
14939
|
+
name: sourceElm.name,
|
|
14940
|
+
layer: pcbElm?.layer,
|
|
14941
|
+
pcbX: pcbElm?.center?.x,
|
|
14942
|
+
pcbY: pcbElm?.center?.y,
|
|
14943
|
+
pcbRotation: pcbElm?.rotation,
|
|
14944
|
+
doNotPlace: pcbElm?.do_not_place,
|
|
14945
|
+
obstructsWithinBounds: pcbElm?.obstructs_within_bounds
|
|
14946
|
+
});
|
|
14947
|
+
if (pcbElm) {
|
|
14948
|
+
inflatePcbComponent(pcbElm, {
|
|
14949
|
+
...inflatorContext,
|
|
14950
|
+
normalComponent: diode
|
|
14951
|
+
});
|
|
14952
|
+
}
|
|
14953
|
+
if (sourceElm.source_group_id && groupsMap?.has(sourceElm.source_group_id)) {
|
|
14954
|
+
const group = groupsMap.get(sourceElm.source_group_id);
|
|
14955
|
+
group.add(diode);
|
|
14956
|
+
} else {
|
|
14957
|
+
subcircuit.add(diode);
|
|
14958
|
+
}
|
|
14959
|
+
}
|
|
14960
|
+
|
|
14961
|
+
// lib/components/primitive-components/Group/Subcircuit/inflators/inflateSourceGroup.ts
|
|
14962
|
+
function inflateSourceGroup(sourceGroup, inflatorContext) {
|
|
14963
|
+
const { subcircuit, groupsMap } = inflatorContext;
|
|
14964
|
+
const group = new Group6({
|
|
14965
|
+
name: sourceGroup.name
|
|
14966
|
+
});
|
|
14967
|
+
group.source_group_id = sourceGroup.source_group_id;
|
|
14968
|
+
subcircuit.add(group);
|
|
14969
|
+
if (groupsMap) {
|
|
14970
|
+
groupsMap.set(sourceGroup.source_group_id, group);
|
|
14971
|
+
}
|
|
14972
|
+
return group;
|
|
14973
|
+
}
|
|
14974
|
+
|
|
14975
|
+
// lib/components/normal-components/Inductor.ts
|
|
14976
|
+
import { inductorProps } from "@tscircuit/props";
|
|
14977
|
+
import { formatSiUnit as formatSiUnit2 } from "format-si-unit";
|
|
14978
|
+
var Inductor = class extends NormalComponent3 {
|
|
14979
|
+
_adjustSilkscreenTextAutomatically = true;
|
|
14980
|
+
get config() {
|
|
14981
|
+
return {
|
|
14982
|
+
componentName: "Inductor",
|
|
14983
|
+
schematicSymbolName: this.props.symbolName ?? "inductor",
|
|
14984
|
+
zodProps: inductorProps,
|
|
14985
|
+
sourceFtype: FTYPE.simple_inductor
|
|
14986
|
+
};
|
|
14987
|
+
}
|
|
14988
|
+
_getSchematicSymbolDisplayValue() {
|
|
14989
|
+
return `${formatSiUnit2(this._parsedProps.inductance)}H`;
|
|
14990
|
+
}
|
|
14991
|
+
initPorts() {
|
|
14992
|
+
super.initPorts({
|
|
14993
|
+
additionalAliases: {
|
|
14994
|
+
pin1: ["anode", "pos", "left"],
|
|
14995
|
+
pin2: ["cathode", "neg", "right"]
|
|
14996
|
+
}
|
|
14997
|
+
});
|
|
14998
|
+
}
|
|
14999
|
+
doInitialSourceRender() {
|
|
15000
|
+
const { db } = this.root;
|
|
15001
|
+
const { _parsedProps: props } = this;
|
|
15002
|
+
const source_component = db.source_component.insert({
|
|
15003
|
+
name: this.name,
|
|
15004
|
+
ftype: FTYPE.simple_inductor,
|
|
15005
|
+
inductance: props.inductance,
|
|
15006
|
+
supplier_part_numbers: props.supplierPartNumbers,
|
|
15007
|
+
are_pins_interchangeable: true
|
|
15008
|
+
});
|
|
15009
|
+
this.source_component_id = source_component.source_component_id;
|
|
15010
|
+
}
|
|
15011
|
+
};
|
|
15012
|
+
|
|
15013
|
+
// lib/components/primitive-components/Group/Subcircuit/inflators/inflateSourceInductor.ts
|
|
15014
|
+
function inflateSourceInductor(sourceElm, inflatorContext) {
|
|
15015
|
+
const { injectionDb, subcircuit, groupsMap } = inflatorContext;
|
|
15016
|
+
const pcbElm = injectionDb.pcb_component.getWhere({
|
|
15017
|
+
source_component_id: sourceElm.source_component_id
|
|
15018
|
+
});
|
|
15019
|
+
const cadElm = injectionDb.cad_component.getWhere({
|
|
15020
|
+
source_component_id: sourceElm.source_component_id
|
|
15021
|
+
});
|
|
15022
|
+
const inductor = new Inductor({
|
|
15023
|
+
name: sourceElm.name,
|
|
15024
|
+
inductance: sourceElm.inductance,
|
|
15025
|
+
layer: pcbElm?.layer,
|
|
15026
|
+
pcbX: pcbElm?.center?.x,
|
|
15027
|
+
pcbY: pcbElm?.center?.y,
|
|
15028
|
+
pcbRotation: pcbElm?.rotation,
|
|
15029
|
+
doNotPlace: pcbElm?.do_not_place,
|
|
15030
|
+
obstructsWithinBounds: pcbElm?.obstructs_within_bounds
|
|
15031
|
+
});
|
|
15032
|
+
if (pcbElm) {
|
|
15033
|
+
inflatePcbComponent(pcbElm, {
|
|
15034
|
+
...inflatorContext,
|
|
15035
|
+
normalComponent: inductor
|
|
15036
|
+
});
|
|
15037
|
+
}
|
|
15038
|
+
if (sourceElm.source_group_id && groupsMap?.has(sourceElm.source_group_id)) {
|
|
15039
|
+
const group = groupsMap.get(sourceElm.source_group_id);
|
|
15040
|
+
group.add(inductor);
|
|
15041
|
+
} else {
|
|
15042
|
+
subcircuit.add(inductor);
|
|
15043
|
+
}
|
|
15044
|
+
}
|
|
15045
|
+
|
|
15046
|
+
// lib/components/primitive-components/Group/Subcircuit/inflators/inflateSourcePort.ts
|
|
15047
|
+
function inflateSourcePort(sourcePort, inflatorContext) {
|
|
15048
|
+
const { injectionDb, subcircuit } = inflatorContext;
|
|
15049
|
+
if (sourcePort.source_component_id !== null) {
|
|
15050
|
+
return;
|
|
15051
|
+
}
|
|
15052
|
+
const pcbPortFromInjection = injectionDb.pcb_port.getWhere({
|
|
15053
|
+
source_port_id: sourcePort.source_port_id
|
|
15054
|
+
});
|
|
15055
|
+
const port = new Port({
|
|
15056
|
+
name: sourcePort.name,
|
|
15057
|
+
pinNumber: sourcePort.pin_number
|
|
15058
|
+
});
|
|
15059
|
+
subcircuit.add(port);
|
|
15060
|
+
port.source_port_id = sourcePort.source_port_id;
|
|
15061
|
+
const root = subcircuit.root;
|
|
15062
|
+
if (root && pcbPortFromInjection) {
|
|
15063
|
+
const { db } = root;
|
|
15064
|
+
const pcb_port = db.pcb_port.insert({
|
|
15065
|
+
pcb_component_id: void 0,
|
|
15066
|
+
layers: pcbPortFromInjection.layers,
|
|
15067
|
+
subcircuit_id: subcircuit.subcircuit_id ?? void 0,
|
|
15068
|
+
pcb_group_id: subcircuit.getGroup()?.pcb_group_id ?? void 0,
|
|
15069
|
+
x: pcbPortFromInjection.x,
|
|
15070
|
+
y: pcbPortFromInjection.y,
|
|
15071
|
+
source_port_id: sourcePort.source_port_id,
|
|
15072
|
+
is_board_pinout: false
|
|
15073
|
+
});
|
|
15074
|
+
port.pcb_port_id = pcb_port.pcb_port_id;
|
|
15075
|
+
}
|
|
15076
|
+
}
|
|
15077
|
+
|
|
15078
|
+
// lib/components/normal-components/Resistor.ts
|
|
15079
|
+
import { resistorProps } from "@tscircuit/props";
|
|
15080
|
+
import { formatSiUnit as formatSiUnit3 } from "format-si-unit";
|
|
15081
|
+
var Resistor = class extends NormalComponent3 {
|
|
15082
|
+
_adjustSilkscreenTextAutomatically = true;
|
|
15083
|
+
get config() {
|
|
15084
|
+
return {
|
|
15085
|
+
componentName: "Resistor",
|
|
15086
|
+
schematicSymbolName: this.props.symbolName ?? "boxresistor",
|
|
15087
|
+
zodProps: resistorProps,
|
|
15088
|
+
sourceFtype: "simple_resistor"
|
|
15089
|
+
};
|
|
15090
|
+
}
|
|
15091
|
+
initPorts() {
|
|
15092
|
+
super.initPorts({
|
|
15093
|
+
additionalAliases: {
|
|
15094
|
+
pin1: ["anode", "pos", "left"],
|
|
15095
|
+
pin2: ["cathode", "neg", "right"]
|
|
15096
|
+
}
|
|
15097
|
+
});
|
|
15098
|
+
}
|
|
15099
|
+
_getSchematicSymbolDisplayValue() {
|
|
15100
|
+
return `${formatSiUnit3(this._parsedProps.resistance)}\u03A9`;
|
|
15101
|
+
}
|
|
15102
|
+
doInitialCreateNetsFromProps() {
|
|
15103
|
+
this._createNetsFromProps([
|
|
15104
|
+
this.props.pullupFor,
|
|
15105
|
+
this.props.pullupTo,
|
|
15106
|
+
this.props.pulldownFor,
|
|
15107
|
+
this.props.pulldownTo,
|
|
15108
|
+
...this._getNetsFromConnectionsProp()
|
|
15109
|
+
]);
|
|
15110
|
+
}
|
|
15111
|
+
doInitialCreateTracesFromProps() {
|
|
15112
|
+
if (this.props.pullupFor && this.props.pullupTo) {
|
|
15113
|
+
this.add(
|
|
15114
|
+
new Trace3({
|
|
15115
|
+
from: `${this.getSubcircuitSelector()} > port.1`,
|
|
15116
|
+
to: this.props.pullupFor
|
|
15117
|
+
})
|
|
15118
|
+
);
|
|
15119
|
+
this.add(
|
|
15120
|
+
new Trace3({
|
|
15121
|
+
from: `${this.getSubcircuitSelector()} > port.2`,
|
|
15122
|
+
to: this.props.pullupTo
|
|
15123
|
+
})
|
|
15124
|
+
);
|
|
15125
|
+
}
|
|
15126
|
+
if (this.props.pulldownFor && this.props.pulldownTo) {
|
|
15127
|
+
this.add(
|
|
15128
|
+
new Trace3({
|
|
15129
|
+
from: `${this.getSubcircuitSelector()} > port.1`,
|
|
15130
|
+
to: this.props.pulldownFor
|
|
15131
|
+
})
|
|
15132
|
+
);
|
|
15133
|
+
this.add(
|
|
15134
|
+
new Trace3({
|
|
15135
|
+
from: `${this.getSubcircuitSelector()} > port.2`,
|
|
15136
|
+
to: this.props.pulldownTo
|
|
15137
|
+
})
|
|
15138
|
+
);
|
|
15139
|
+
}
|
|
15140
|
+
this._createTracesFromConnectionsProp();
|
|
15141
|
+
}
|
|
15142
|
+
doInitialSourceRender() {
|
|
15143
|
+
const { db } = this.root;
|
|
15144
|
+
const { _parsedProps: props } = this;
|
|
15145
|
+
const source_component = db.source_component.insert({
|
|
15146
|
+
ftype: "simple_resistor",
|
|
15147
|
+
name: this.name,
|
|
15148
|
+
// @ts-ignore
|
|
15149
|
+
manufacturer_part_number: props.manufacturerPartNumber ?? props.mfn,
|
|
15150
|
+
supplier_part_numbers: props.supplierPartNumbers,
|
|
15151
|
+
resistance: props.resistance,
|
|
15152
|
+
display_resistance: this._getSchematicSymbolDisplayValue(),
|
|
15153
|
+
are_pins_interchangeable: true
|
|
15154
|
+
});
|
|
15155
|
+
this.source_component_id = source_component.source_component_id;
|
|
15156
|
+
}
|
|
15157
|
+
};
|
|
15158
|
+
|
|
15159
|
+
// lib/components/primitive-components/Group/Subcircuit/inflators/inflateSourceResistor.ts
|
|
15160
|
+
function inflateSourceResistor(sourceElm, inflatorContext) {
|
|
15161
|
+
const { injectionDb, subcircuit, groupsMap } = inflatorContext;
|
|
15162
|
+
const pcbElm = injectionDb.pcb_component.getWhere({
|
|
15163
|
+
source_component_id: sourceElm.source_component_id
|
|
15164
|
+
});
|
|
15165
|
+
const cadElm = injectionDb.cad_component.getWhere({
|
|
15166
|
+
source_component_id: sourceElm.source_component_id
|
|
15167
|
+
});
|
|
15168
|
+
const resistor = new Resistor({
|
|
15169
|
+
name: sourceElm.name,
|
|
15170
|
+
resistance: sourceElm.resistance,
|
|
15171
|
+
layer: pcbElm?.layer,
|
|
15172
|
+
pcbX: pcbElm?.center?.x,
|
|
15173
|
+
pcbY: pcbElm?.center?.y,
|
|
15174
|
+
pcbRotation: pcbElm?.rotation,
|
|
15175
|
+
doNotPlace: pcbElm?.do_not_place,
|
|
15176
|
+
obstructsWithinBounds: pcbElm?.obstructs_within_bounds
|
|
15177
|
+
});
|
|
15178
|
+
if (pcbElm) {
|
|
15179
|
+
inflatePcbComponent(pcbElm, {
|
|
15180
|
+
...inflatorContext,
|
|
15181
|
+
normalComponent: resistor
|
|
15182
|
+
});
|
|
15183
|
+
}
|
|
15184
|
+
if (sourceElm.source_group_id && groupsMap?.has(sourceElm.source_group_id)) {
|
|
15185
|
+
const group = groupsMap.get(sourceElm.source_group_id);
|
|
15186
|
+
group.add(resistor);
|
|
15187
|
+
} else {
|
|
15188
|
+
subcircuit.add(resistor);
|
|
15189
|
+
}
|
|
15190
|
+
}
|
|
15191
|
+
|
|
15192
|
+
// lib/components/primitive-components/Group/Subcircuit/inflators/inflateSourceTrace.ts
|
|
15193
|
+
var getSelectorPath = (component, db) => {
|
|
15194
|
+
const path_parts = [];
|
|
15195
|
+
let currentGroupId = component.source_group_id;
|
|
15196
|
+
while (currentGroupId) {
|
|
15197
|
+
const group = db.source_group.get(currentGroupId);
|
|
15198
|
+
if (!group) break;
|
|
15199
|
+
path_parts.unshift(`.${group.name}`);
|
|
15200
|
+
currentGroupId = group.parent_source_group_id;
|
|
15201
|
+
}
|
|
15202
|
+
path_parts.push(`.${component.name}`);
|
|
15203
|
+
return path_parts.join(" > ");
|
|
15204
|
+
};
|
|
15205
|
+
function inflateSourceTrace(sourceTrace, inflatorContext) {
|
|
15206
|
+
const { injectionDb, subcircuit } = inflatorContext;
|
|
15207
|
+
const connectedSelectors = [];
|
|
15208
|
+
for (const sourcePortId of sourceTrace.connected_source_port_ids) {
|
|
15209
|
+
const sourcePort = injectionDb.source_port.get(sourcePortId);
|
|
15210
|
+
if (!sourcePort) continue;
|
|
15211
|
+
let selector;
|
|
15212
|
+
if (sourcePort.source_component_id) {
|
|
15213
|
+
const sourceComponent = injectionDb.source_component.get(
|
|
15214
|
+
sourcePort.source_component_id
|
|
15215
|
+
);
|
|
15216
|
+
if (sourceComponent) {
|
|
15217
|
+
const path = getSelectorPath(
|
|
15218
|
+
{
|
|
15219
|
+
name: sourceComponent.name,
|
|
15220
|
+
source_group_id: sourceComponent.source_group_id
|
|
15221
|
+
},
|
|
15222
|
+
injectionDb
|
|
15223
|
+
);
|
|
15224
|
+
selector = `${path} > .${sourcePort.name}`;
|
|
15225
|
+
}
|
|
15226
|
+
} else {
|
|
15227
|
+
selector = `.${sourcePort.name}`;
|
|
15228
|
+
}
|
|
15229
|
+
if (selector) {
|
|
15230
|
+
connectedSelectors.push(selector);
|
|
15231
|
+
}
|
|
15232
|
+
}
|
|
15233
|
+
for (const sourceNetId of sourceTrace.connected_source_net_ids) {
|
|
15234
|
+
const sourceNet = injectionDb.source_net.get(sourceNetId);
|
|
15235
|
+
if (sourceNet) {
|
|
15236
|
+
connectedSelectors.push(`net.${sourceNet.name}`);
|
|
15237
|
+
}
|
|
15238
|
+
}
|
|
15239
|
+
if (connectedSelectors.length < 2) return;
|
|
15240
|
+
const trace = new Trace3({
|
|
15241
|
+
path: connectedSelectors
|
|
15242
|
+
});
|
|
15243
|
+
trace.source_trace_id = sourceTrace.source_trace_id;
|
|
15244
|
+
subcircuit.add(trace);
|
|
15245
|
+
}
|
|
15246
|
+
|
|
15247
|
+
// lib/components/normal-components/Transistor.ts
|
|
15248
|
+
import { transistorProps } from "@tscircuit/props";
|
|
15249
|
+
var Transistor = class extends NormalComponent3 {
|
|
15250
|
+
get config() {
|
|
15251
|
+
const baseSymbolName = this.props.type === "npn" ? "npn_bipolar_transistor" : "pnp_bipolar_transistor";
|
|
15252
|
+
return {
|
|
15253
|
+
componentName: "Transistor",
|
|
15254
|
+
schematicSymbolName: this.props.symbolName ?? baseSymbolName,
|
|
15255
|
+
zodProps: transistorProps,
|
|
15256
|
+
sourceFtype: "simple_transistor",
|
|
15257
|
+
shouldRenderAsSchematicBox: false
|
|
15258
|
+
};
|
|
15259
|
+
}
|
|
15260
|
+
initPorts() {
|
|
15261
|
+
const pinAliases = {
|
|
15262
|
+
pin1: ["collector", "c"],
|
|
15263
|
+
pin2: ["emitter", "e"],
|
|
15264
|
+
pin3: ["base", "b"]
|
|
15265
|
+
};
|
|
15266
|
+
super.initPorts({
|
|
15267
|
+
pinCount: 3,
|
|
15268
|
+
additionalAliases: pinAliases
|
|
15269
|
+
});
|
|
15270
|
+
}
|
|
15271
|
+
emitter = this.portMap.pin1;
|
|
15272
|
+
collector = this.portMap.pin2;
|
|
15273
|
+
base = this.portMap.pin3;
|
|
15274
|
+
doInitialCreateNetsFromProps() {
|
|
15275
|
+
this._createNetsFromProps([...this._getNetsFromConnectionsProp()]);
|
|
15276
|
+
}
|
|
15277
|
+
doInitialCreateTracesFromProps() {
|
|
15278
|
+
this._createTracesFromConnectionsProp();
|
|
15279
|
+
}
|
|
15280
|
+
doInitialSourceRender() {
|
|
15281
|
+
const { db } = this.root;
|
|
15282
|
+
const { _parsedProps: props } = this;
|
|
15283
|
+
const source_component = db.source_component.insert({
|
|
15284
|
+
ftype: "simple_transistor",
|
|
15285
|
+
name: this.name,
|
|
15286
|
+
transistor_type: props.type
|
|
15287
|
+
});
|
|
15288
|
+
this.source_component_id = source_component.source_component_id;
|
|
15289
|
+
}
|
|
15290
|
+
};
|
|
15291
|
+
|
|
15292
|
+
// lib/components/primitive-components/Group/Subcircuit/inflators/inflateSourceTransistor.ts
|
|
15293
|
+
function inflateSourceTransistor(sourceElm, inflatorContext) {
|
|
15294
|
+
const { injectionDb, subcircuit, groupsMap } = inflatorContext;
|
|
15295
|
+
const pcbElm = injectionDb.pcb_component.getWhere({
|
|
15296
|
+
source_component_id: sourceElm.source_component_id
|
|
15297
|
+
});
|
|
15298
|
+
const cadElm = injectionDb.cad_component.getWhere({
|
|
15299
|
+
source_component_id: sourceElm.source_component_id
|
|
15300
|
+
});
|
|
15301
|
+
const transistor = new Transistor({
|
|
15302
|
+
name: sourceElm.name,
|
|
15303
|
+
type: sourceElm.transistor_type,
|
|
15304
|
+
layer: pcbElm?.layer,
|
|
15305
|
+
pcbX: pcbElm?.center?.x,
|
|
15306
|
+
pcbY: pcbElm?.center?.y,
|
|
15307
|
+
pcbRotation: pcbElm?.rotation,
|
|
15308
|
+
doNotPlace: pcbElm?.do_not_place,
|
|
15309
|
+
obstructsWithinBounds: pcbElm?.obstructs_within_bounds
|
|
15310
|
+
});
|
|
15311
|
+
if (pcbElm) {
|
|
15312
|
+
inflatePcbComponent(pcbElm, {
|
|
15313
|
+
...inflatorContext,
|
|
15314
|
+
normalComponent: transistor
|
|
15315
|
+
});
|
|
15316
|
+
}
|
|
15317
|
+
if (sourceElm.source_group_id && groupsMap?.has(sourceElm.source_group_id)) {
|
|
15318
|
+
const group = groupsMap.get(sourceElm.source_group_id);
|
|
15319
|
+
group.add(transistor);
|
|
15320
|
+
} else {
|
|
15321
|
+
subcircuit.add(transistor);
|
|
15322
|
+
}
|
|
15323
|
+
}
|
|
15324
|
+
|
|
15325
|
+
// lib/utils/circuit-json/inflate-circuit-json.ts
|
|
15326
|
+
var inflateCircuitJson = (target, circuitJson, children) => {
|
|
15327
|
+
if (!circuitJson) return;
|
|
15328
|
+
const injectionDb = cju(circuitJson);
|
|
15329
|
+
if (circuitJson && children?.length > 0) {
|
|
15330
|
+
throw new Error("Component cannot have both circuitJson and children");
|
|
15331
|
+
}
|
|
15332
|
+
const groupsMap = /* @__PURE__ */ new Map();
|
|
15333
|
+
const inflationCtx = {
|
|
15334
|
+
injectionDb,
|
|
15335
|
+
subcircuit: target,
|
|
15336
|
+
groupsMap
|
|
15337
|
+
};
|
|
15338
|
+
const sourceGroups = injectionDb.source_group.list();
|
|
15339
|
+
for (const sourceGroup of sourceGroups) {
|
|
15340
|
+
inflateSourceGroup(sourceGroup, inflationCtx);
|
|
15341
|
+
}
|
|
15342
|
+
const sourceComponents = injectionDb.source_component.list();
|
|
15343
|
+
for (const sourceComponent of sourceComponents) {
|
|
15344
|
+
switch (sourceComponent.ftype) {
|
|
15345
|
+
case "simple_resistor":
|
|
15346
|
+
inflateSourceResistor(sourceComponent, inflationCtx);
|
|
15347
|
+
break;
|
|
15348
|
+
case "simple_capacitor":
|
|
15349
|
+
inflateSourceCapacitor(sourceComponent, inflationCtx);
|
|
15350
|
+
break;
|
|
15351
|
+
case "simple_inductor":
|
|
15352
|
+
inflateSourceInductor(sourceComponent, inflationCtx);
|
|
15353
|
+
break;
|
|
15354
|
+
case "simple_diode":
|
|
15355
|
+
inflateSourceDiode(sourceComponent, inflationCtx);
|
|
15356
|
+
break;
|
|
15357
|
+
case "simple_chip":
|
|
15358
|
+
inflateSourceChip(sourceComponent, inflationCtx);
|
|
15359
|
+
break;
|
|
15360
|
+
case "simple_transistor":
|
|
15361
|
+
inflateSourceTransistor(sourceComponent, inflationCtx);
|
|
15362
|
+
break;
|
|
15363
|
+
default:
|
|
15364
|
+
throw new Error(
|
|
15365
|
+
`No inflator implemented for source component ftype: "${sourceComponent.ftype}"`
|
|
15366
|
+
);
|
|
15367
|
+
}
|
|
15368
|
+
}
|
|
15369
|
+
const sourcePorts = injectionDb.source_port.list();
|
|
15370
|
+
for (const sourcePort of sourcePorts) {
|
|
15371
|
+
inflateSourcePort(sourcePort, inflationCtx);
|
|
15372
|
+
}
|
|
15373
|
+
const sourceTraces = injectionDb.source_trace.list();
|
|
15374
|
+
for (const sourceTrace of sourceTraces) {
|
|
15375
|
+
inflateSourceTrace(sourceTrace, inflationCtx);
|
|
15376
|
+
}
|
|
15377
|
+
};
|
|
15378
|
+
|
|
15379
|
+
// lib/components/normal-components/Board.ts
|
|
15380
|
+
import {
|
|
15381
|
+
checkEachPcbPortConnectedToPcbTraces,
|
|
15382
|
+
checkEachPcbTraceNonOverlapping,
|
|
15383
|
+
checkPcbComponentsOutOfBoard,
|
|
15384
|
+
checkPcbTracesOutOfBoard,
|
|
15385
|
+
checkDifferentNetViaSpacing,
|
|
15386
|
+
checkSameNetViaSpacing,
|
|
15387
|
+
checkPcbComponentOverlap,
|
|
15388
|
+
checkPinMustBeConnected
|
|
15389
|
+
} from "@tscircuit/checks";
|
|
15390
|
+
import { getBoundsFromPoints as getBoundsFromPoints4 } from "@tscircuit/math-utils";
|
|
15391
|
+
var MIN_EFFECTIVE_BORDER_RADIUS_MM = 0.01;
|
|
15392
|
+
var getRoundedRectOutline = (width, height, radius) => {
|
|
15393
|
+
const w2 = width / 2;
|
|
15394
|
+
const h2 = height / 2;
|
|
15395
|
+
const r = Math.min(radius, w2, h2);
|
|
15396
|
+
if (r < MIN_EFFECTIVE_BORDER_RADIUS_MM) {
|
|
15397
|
+
return [
|
|
15398
|
+
{ x: -w2, y: -h2 },
|
|
15399
|
+
{ x: w2, y: -h2 },
|
|
15400
|
+
{ x: w2, y: h2 },
|
|
15401
|
+
{ x: -w2, y: h2 }
|
|
15402
|
+
];
|
|
15403
|
+
}
|
|
15404
|
+
const maxArcLengthPerSegment = 0.1;
|
|
15405
|
+
const segments = Math.max(
|
|
15406
|
+
1,
|
|
15407
|
+
Math.ceil(Math.PI / 2 * r / maxArcLengthPerSegment)
|
|
15408
|
+
);
|
|
15409
|
+
const step = Math.PI / 2 / segments;
|
|
15410
|
+
const outline = [];
|
|
15411
|
+
outline.push({ x: -w2 + r, y: -h2 });
|
|
15412
|
+
outline.push({ x: w2 - r, y: -h2 });
|
|
15413
|
+
for (let i = 1; i <= segments; i++) {
|
|
15414
|
+
const theta = -Math.PI / 2 + i * step;
|
|
15415
|
+
outline.push({
|
|
15416
|
+
x: w2 - r + r * Math.cos(theta),
|
|
15417
|
+
y: -h2 + r + r * Math.sin(theta)
|
|
15418
|
+
});
|
|
15419
|
+
}
|
|
15420
|
+
outline.push({ x: w2, y: h2 - r });
|
|
15421
|
+
for (let i = 1; i <= segments; i++) {
|
|
15422
|
+
const theta = 0 + i * step;
|
|
15423
|
+
outline.push({
|
|
15424
|
+
x: w2 - r + r * Math.cos(theta),
|
|
15425
|
+
y: h2 - r + r * Math.sin(theta)
|
|
15426
|
+
});
|
|
15427
|
+
}
|
|
15428
|
+
outline.push({ x: -w2 + r, y: h2 });
|
|
15429
|
+
for (let i = 1; i <= segments; i++) {
|
|
15430
|
+
const theta = Math.PI / 2 + i * step;
|
|
15431
|
+
outline.push({
|
|
15432
|
+
x: -w2 + r + r * Math.cos(theta),
|
|
15433
|
+
y: h2 - r + r * Math.sin(theta)
|
|
15434
|
+
});
|
|
15435
|
+
}
|
|
15436
|
+
outline.push({ x: -w2, y: -h2 + r });
|
|
15437
|
+
for (let i = 1; i <= segments; i++) {
|
|
15438
|
+
const theta = Math.PI + i * step;
|
|
15439
|
+
outline.push({
|
|
15440
|
+
x: -w2 + r + r * Math.cos(theta),
|
|
15441
|
+
y: -h2 + r + r * Math.sin(theta)
|
|
15442
|
+
});
|
|
15443
|
+
}
|
|
15444
|
+
return outline;
|
|
15445
|
+
};
|
|
15446
|
+
var Board = class extends Group6 {
|
|
15447
|
+
pcb_board_id = null;
|
|
15448
|
+
source_board_id = null;
|
|
15449
|
+
_drcChecksComplete = false;
|
|
15450
|
+
_connectedSchematicPortPairs = /* @__PURE__ */ new Set();
|
|
15451
|
+
get isSubcircuit() {
|
|
15452
|
+
return true;
|
|
15453
|
+
}
|
|
15454
|
+
get isGroup() {
|
|
15455
|
+
return true;
|
|
15456
|
+
}
|
|
15457
|
+
get config() {
|
|
15458
|
+
return {
|
|
15459
|
+
componentName: "Board",
|
|
15460
|
+
zodProps: boardProps
|
|
15461
|
+
};
|
|
15462
|
+
}
|
|
15463
|
+
get boardThickness() {
|
|
15464
|
+
const { _parsedProps: props } = this;
|
|
15465
|
+
const pcbX = this._resolvePcbCoordinate(props.pcbX, "pcbX", {
|
|
15466
|
+
allowBoardVariables: false
|
|
15467
|
+
});
|
|
15468
|
+
const pcbY = this._resolvePcbCoordinate(props.pcbY, "pcbY", {
|
|
15469
|
+
allowBoardVariables: false
|
|
15470
|
+
});
|
|
15471
|
+
return props.thickness ?? 1.4;
|
|
15472
|
+
}
|
|
15473
|
+
/**
|
|
15474
|
+
* Get all available layers for the board
|
|
15475
|
+
*/
|
|
15476
|
+
get allLayers() {
|
|
15477
|
+
const layerCount = this._parsedProps.layers ?? 2;
|
|
15478
|
+
if (layerCount === 4) {
|
|
15479
|
+
return ["top", "bottom", "inner1", "inner2"];
|
|
15480
|
+
}
|
|
15481
|
+
return ["top", "bottom"];
|
|
15482
|
+
}
|
|
15483
|
+
_getSubcircuitLayerCount() {
|
|
15484
|
+
return this._parsedProps.layers ?? 2;
|
|
15485
|
+
}
|
|
15486
|
+
_getBoardCalcVariables() {
|
|
15487
|
+
const { _parsedProps: props } = this;
|
|
15488
|
+
const isAutoSized = (props.width == null || props.height == null) && !props.outline;
|
|
15489
|
+
if (isAutoSized) return {};
|
|
15490
|
+
const dbBoard = this.pcb_board_id ? this.root?.db.pcb_board.get(this.pcb_board_id) : null;
|
|
15491
|
+
let width = dbBoard?.width ?? props.width;
|
|
15492
|
+
let height = dbBoard?.height ?? props.height;
|
|
15493
|
+
if ((width == null || height == null) && props.outline?.length) {
|
|
15494
|
+
const outlineBounds = getBoundsFromPoints4(props.outline);
|
|
15495
|
+
if (outlineBounds) {
|
|
15496
|
+
width ??= outlineBounds.maxX - outlineBounds.minX;
|
|
15497
|
+
height ??= outlineBounds.maxY - outlineBounds.minY;
|
|
15498
|
+
}
|
|
15499
|
+
}
|
|
15500
|
+
const { pcbX, pcbY } = this.getResolvedPcbPositionProp();
|
|
15501
|
+
const center = dbBoard?.center ?? {
|
|
15502
|
+
x: pcbX + (props.outlineOffsetX ?? 0),
|
|
15503
|
+
y: pcbY + (props.outlineOffsetY ?? 0)
|
|
15504
|
+
};
|
|
15505
|
+
const resolvedWidth = width ?? 0;
|
|
15506
|
+
const resolvedHeight = height ?? 0;
|
|
15507
|
+
return {
|
|
15508
|
+
"board.minx": center.x - resolvedWidth / 2,
|
|
15509
|
+
"board.maxx": center.x + resolvedWidth / 2,
|
|
15510
|
+
"board.miny": center.y - resolvedHeight / 2,
|
|
15511
|
+
"board.maxy": center.y + resolvedHeight / 2
|
|
15512
|
+
};
|
|
15513
|
+
}
|
|
15514
|
+
doInitialPcbBoardAutoSize() {
|
|
15515
|
+
if (this.root?.pcbDisabled) return;
|
|
15516
|
+
if (!this.pcb_board_id) return;
|
|
15517
|
+
const { db } = this.root;
|
|
15518
|
+
const { _parsedProps: props } = this;
|
|
15519
|
+
const pcbX = this._resolvePcbCoordinate(props.pcbX, "pcbX", {
|
|
15520
|
+
allowBoardVariables: false
|
|
15521
|
+
});
|
|
15522
|
+
const pcbY = this._resolvePcbCoordinate(props.pcbY, "pcbY", {
|
|
15523
|
+
allowBoardVariables: false
|
|
15524
|
+
});
|
|
15525
|
+
if (props.width && props.height || props.outline) return;
|
|
15526
|
+
let minX = Infinity;
|
|
15527
|
+
let minY = Infinity;
|
|
15528
|
+
let maxX = -Infinity;
|
|
15529
|
+
let maxY = -Infinity;
|
|
15530
|
+
const descendantIds = getDescendantSubcircuitIds(db, this.subcircuit_id);
|
|
15531
|
+
const allowedSubcircuitIds = /* @__PURE__ */ new Set([this.subcircuit_id, ...descendantIds]);
|
|
15532
|
+
const allPcbComponents = db.pcb_component.list().filter(
|
|
15533
|
+
(c) => c.subcircuit_id && allowedSubcircuitIds.has(c.subcircuit_id)
|
|
15534
|
+
);
|
|
15535
|
+
const allPcbGroups = db.pcb_group.list().filter(
|
|
15536
|
+
(g) => g.subcircuit_id && allowedSubcircuitIds.has(g.subcircuit_id)
|
|
15537
|
+
);
|
|
15538
|
+
let hasComponents = false;
|
|
15539
|
+
const updateBounds = (center2, width, height) => {
|
|
15540
|
+
if (width === 0 || height === 0) return;
|
|
15541
|
+
hasComponents = true;
|
|
15542
|
+
minX = Math.min(minX, center2.x - width / 2);
|
|
15543
|
+
minY = Math.min(minY, center2.y - height / 2);
|
|
15544
|
+
maxX = Math.max(maxX, center2.x + width / 2);
|
|
15545
|
+
maxY = Math.max(maxY, center2.y + height / 2);
|
|
15546
|
+
};
|
|
15547
|
+
for (const pcbComponent of allPcbComponents) {
|
|
15548
|
+
updateBounds(pcbComponent.center, pcbComponent.width, pcbComponent.height);
|
|
15549
|
+
}
|
|
15550
|
+
for (const pcbGroup of allPcbGroups) {
|
|
15551
|
+
let width = pcbGroup.width ?? 0;
|
|
15552
|
+
let height = pcbGroup.height ?? 0;
|
|
15553
|
+
if (pcbGroup.outline && pcbGroup.outline.length > 0) {
|
|
15554
|
+
const bounds = getBoundsFromPoints4(pcbGroup.outline);
|
|
15555
|
+
if (bounds) {
|
|
15556
|
+
width = bounds.maxX - bounds.minX;
|
|
15557
|
+
height = bounds.maxY - bounds.minY;
|
|
15558
|
+
}
|
|
15559
|
+
}
|
|
15560
|
+
updateBounds(pcbGroup.center, width, height);
|
|
15561
|
+
}
|
|
15562
|
+
if (props.boardAnchorPosition) {
|
|
15563
|
+
const { x, y } = props.boardAnchorPosition;
|
|
15564
|
+
minX = Math.min(minX, x);
|
|
15565
|
+
minY = Math.min(minY, y);
|
|
15566
|
+
maxX = Math.max(maxX, x);
|
|
15567
|
+
maxY = Math.max(maxY, y);
|
|
15568
|
+
}
|
|
15569
|
+
const padding = 2;
|
|
15570
|
+
const computedWidth = hasComponents ? maxX - minX + padding * 2 : 0;
|
|
15571
|
+
const computedHeight = hasComponents ? maxY - minY + padding * 2 : 0;
|
|
15572
|
+
const center = {
|
|
15573
|
+
x: hasComponents ? (minX + maxX) / 2 + (props.outlineOffsetX ?? 0) : (props.outlineOffsetX ?? 0) + pcbX,
|
|
15574
|
+
y: hasComponents ? (minY + maxY) / 2 + (props.outlineOffsetY ?? 0) : (props.outlineOffsetY ?? 0) + pcbY
|
|
15575
|
+
};
|
|
15576
|
+
const finalWidth = props.width ?? computedWidth;
|
|
15577
|
+
const finalHeight = props.height ?? computedHeight;
|
|
15578
|
+
let outline = props.outline;
|
|
15579
|
+
if (!outline && props.borderRadius != null && finalWidth > 0 && finalHeight > 0) {
|
|
15580
|
+
outline = getRoundedRectOutline(
|
|
15581
|
+
finalWidth,
|
|
15582
|
+
finalHeight,
|
|
15583
|
+
props.borderRadius
|
|
15584
|
+
);
|
|
15585
|
+
}
|
|
15586
|
+
const update = {
|
|
15587
|
+
width: finalWidth,
|
|
15588
|
+
height: finalHeight,
|
|
15589
|
+
center
|
|
15590
|
+
};
|
|
15591
|
+
if (outline) {
|
|
15592
|
+
update.outline = outline.map((point) => ({
|
|
15593
|
+
x: point.x + (props.outlineOffsetX ?? 0),
|
|
15594
|
+
y: point.y + (props.outlineOffsetY ?? 0)
|
|
15595
|
+
}));
|
|
15596
|
+
}
|
|
15597
|
+
db.pcb_board.update(this.pcb_board_id, update);
|
|
15598
|
+
}
|
|
15599
|
+
// Recompute autosize after child components update (e.g., async footprints)
|
|
15600
|
+
updatePcbBoardAutoSize() {
|
|
15601
|
+
this.doInitialPcbBoardAutoSize();
|
|
15602
|
+
}
|
|
15603
|
+
/**
|
|
15604
|
+
* Update the board information silkscreen text if platform config is set and
|
|
15605
|
+
* the project name, version, or url is set.
|
|
15606
|
+
*/
|
|
15607
|
+
_addBoardInformationToSilkscreen() {
|
|
15608
|
+
const platform = this.root?.platform;
|
|
15609
|
+
if (!platform?.printBoardInformationToSilkscreen) return;
|
|
15610
|
+
const pcbBoard = this.root.db.pcb_board.get(this.pcb_board_id);
|
|
15611
|
+
if (!pcbBoard) return;
|
|
15612
|
+
const boardInformation = [];
|
|
15613
|
+
if (platform.projectName) boardInformation.push(platform.projectName);
|
|
15614
|
+
if (platform.version) boardInformation.push(`v${platform.version}`);
|
|
15615
|
+
if (platform.url) boardInformation.push(platform.url);
|
|
15616
|
+
if (boardInformation.length === 0) return;
|
|
15617
|
+
const text = boardInformation.join("\n");
|
|
15618
|
+
const marginX = 0.25;
|
|
15619
|
+
const marginY = 1;
|
|
15620
|
+
const position = {
|
|
15621
|
+
x: pcbBoard.center.x + pcbBoard.width / 2 - marginX,
|
|
15622
|
+
y: pcbBoard.center.y - pcbBoard.height / 2 + marginY
|
|
15623
|
+
};
|
|
15624
|
+
this.root.db.pcb_silkscreen_text.insert({
|
|
15625
|
+
pcb_component_id: this.pcb_board_id,
|
|
15626
|
+
layer: "top",
|
|
15627
|
+
font: "tscircuit2024",
|
|
15628
|
+
font_size: 0.45,
|
|
15629
|
+
text,
|
|
15630
|
+
ccw_rotation: 0,
|
|
15631
|
+
anchor_alignment: "bottom_right",
|
|
15632
|
+
anchor_position: position
|
|
15633
|
+
});
|
|
15634
|
+
}
|
|
15635
|
+
doInitialSourceRender() {
|
|
15636
|
+
super.doInitialSourceRender();
|
|
15637
|
+
const { db } = this.root;
|
|
15638
|
+
const source_board = db.source_board.insert({
|
|
15639
|
+
source_group_id: this.source_group_id,
|
|
15640
|
+
title: this.props.title || this.props.name
|
|
15641
|
+
});
|
|
15642
|
+
this.source_board_id = source_board.source_board_id;
|
|
15643
|
+
}
|
|
15644
|
+
doInitialInflateSubcircuitCircuitJson() {
|
|
15645
|
+
const { circuitJson, children } = this._parsedProps;
|
|
15646
|
+
inflateCircuitJson(this, circuitJson, children);
|
|
15647
|
+
}
|
|
15648
|
+
doInitialPcbComponentRender() {
|
|
15649
|
+
if (this.root?.pcbDisabled) return;
|
|
15650
|
+
const { db } = this.root;
|
|
15651
|
+
const { _parsedProps: props } = this;
|
|
15652
|
+
let computedWidth = props.width ?? 0;
|
|
15653
|
+
let computedHeight = props.height ?? 0;
|
|
15654
|
+
const { pcbX, pcbY } = this.getResolvedPcbPositionProp();
|
|
15655
|
+
let center = {
|
|
15656
|
+
x: pcbX + (props.outlineOffsetX ?? 0),
|
|
15657
|
+
y: pcbY + (props.outlineOffsetY ?? 0)
|
|
15658
|
+
};
|
|
15659
|
+
const { boardAnchorPosition, boardAnchorAlignment } = props;
|
|
15660
|
+
if (boardAnchorPosition) {
|
|
15661
|
+
center = getBoardCenterFromAnchor({
|
|
15662
|
+
boardAnchorPosition,
|
|
15663
|
+
boardAnchorAlignment: boardAnchorAlignment ?? "center",
|
|
15664
|
+
width: computedWidth,
|
|
15665
|
+
height: computedHeight
|
|
15666
|
+
});
|
|
15667
|
+
}
|
|
15668
|
+
if (props.outline) {
|
|
15669
|
+
const xValues = props.outline.map((point) => point.x);
|
|
15670
|
+
const yValues = props.outline.map((point) => point.y);
|
|
15671
|
+
const minX = Math.min(...xValues);
|
|
15672
|
+
const maxX = Math.max(...xValues);
|
|
15673
|
+
const minY = Math.min(...yValues);
|
|
15674
|
+
const maxY = Math.max(...yValues);
|
|
15675
|
+
computedWidth = maxX - minX;
|
|
15676
|
+
computedHeight = maxY - minY;
|
|
15677
|
+
center = {
|
|
15678
|
+
x: (minX + maxX) / 2 + (props.outlineOffsetX ?? 0),
|
|
15679
|
+
y: (minY + maxY) / 2 + (props.outlineOffsetY ?? 0)
|
|
15680
|
+
};
|
|
15681
|
+
}
|
|
15682
|
+
let outline = props.outline;
|
|
15683
|
+
if (!outline && props.borderRadius != null && computedWidth > 0 && computedHeight > 0) {
|
|
15684
|
+
outline = getRoundedRectOutline(
|
|
15685
|
+
computedWidth,
|
|
15686
|
+
computedHeight,
|
|
15687
|
+
props.borderRadius
|
|
15688
|
+
);
|
|
15689
|
+
}
|
|
15690
|
+
const pcb_board = db.pcb_board.insert({
|
|
15691
|
+
center,
|
|
15692
|
+
thickness: this.boardThickness,
|
|
15693
|
+
num_layers: this.allLayers.length,
|
|
15694
|
+
width: computedWidth,
|
|
15695
|
+
height: computedHeight,
|
|
15696
|
+
outline: outline?.map((point) => ({
|
|
15697
|
+
x: point.x + (props.outlineOffsetX ?? 0),
|
|
15698
|
+
y: point.y + (props.outlineOffsetY ?? 0)
|
|
15699
|
+
})),
|
|
15700
|
+
material: props.material
|
|
15701
|
+
});
|
|
15702
|
+
this.pcb_board_id = pcb_board.pcb_board_id;
|
|
15703
|
+
this._addBoardInformationToSilkscreen();
|
|
14811
15704
|
}
|
|
14812
15705
|
removePcbComponentRender() {
|
|
14813
15706
|
const { db } = this.root;
|
|
@@ -15026,529 +15919,274 @@ function generateMouseBitesForEdge({
|
|
|
15026
15919
|
mouseBitePosition = boardBottom;
|
|
15027
15920
|
} else if (edge === "right") {
|
|
15028
15921
|
mouseBitePosition = boardRight;
|
|
15029
|
-
} else {
|
|
15030
|
-
mouseBitePosition = boardLeft;
|
|
15031
|
-
}
|
|
15032
|
-
const sortedTabs = [...edgeTabs].sort((a, b) => {
|
|
15033
|
-
if (isHorizontal) {
|
|
15034
|
-
return a.center.x - b.center.x;
|
|
15035
|
-
} else {
|
|
15036
|
-
return a.center.y - b.center.y;
|
|
15037
|
-
}
|
|
15038
|
-
});
|
|
15039
|
-
for (let i = 0; i < sortedTabs.length - 1; i++) {
|
|
15040
|
-
const tab1 = sortedTabs[i];
|
|
15041
|
-
const tab2 = sortedTabs[i + 1];
|
|
15042
|
-
let gapStart;
|
|
15043
|
-
let gapEnd;
|
|
15044
|
-
if (isHorizontal) {
|
|
15045
|
-
gapStart = tab1.center.x + tab1.width / 2;
|
|
15046
|
-
gapEnd = tab2.center.x - tab2.width / 2;
|
|
15047
|
-
} else {
|
|
15048
|
-
gapStart = tab1.center.y + tab1.height / 2;
|
|
15049
|
-
gapEnd = tab2.center.y - tab2.height / 2;
|
|
15050
|
-
}
|
|
15051
|
-
const gapLength = gapEnd - gapStart;
|
|
15052
|
-
const totalMouseBiteWidth = mouseBitesPerGap * mouseBiteDiameter;
|
|
15053
|
-
const totalSpacing = (mouseBitesPerGap - 1) * mouseBiteSpacing;
|
|
15054
|
-
if (gapLength < totalMouseBiteWidth + totalSpacing) continue;
|
|
15055
|
-
const gapCenter = (gapStart + gapEnd) / 2;
|
|
15056
|
-
for (let j = 0; j < mouseBitesPerGap; j++) {
|
|
15057
|
-
const posOffset = (j - (mouseBitesPerGap - 1) / 2) * (mouseBiteDiameter + mouseBiteSpacing);
|
|
15058
|
-
const newMouseBite = isHorizontal ? { x: gapCenter + posOffset, y: mouseBitePosition } : { x: mouseBitePosition, y: gapCenter + posOffset };
|
|
15059
|
-
const radius2 = mouseBiteDiameter / 2;
|
|
15060
|
-
let overlapsBoard = false;
|
|
15061
|
-
for (const otherBoard of allBoards) {
|
|
15062
|
-
if (!otherBoard.width || !otherBoard.height) continue;
|
|
15063
|
-
const boardRect = {
|
|
15064
|
-
center: otherBoard.center,
|
|
15065
|
-
width: otherBoard.width,
|
|
15066
|
-
height: otherBoard.height
|
|
15067
|
-
};
|
|
15068
|
-
if (pointOverlapsRectangle(newMouseBite, radius2, boardRect)) {
|
|
15069
|
-
overlapsBoard = true;
|
|
15070
|
-
break;
|
|
15071
|
-
}
|
|
15072
|
-
}
|
|
15073
|
-
if (overlapsBoard) continue;
|
|
15074
|
-
mouseBites.push(newMouseBite);
|
|
15075
|
-
}
|
|
15076
|
-
}
|
|
15077
|
-
return mouseBites;
|
|
15078
|
-
}
|
|
15079
|
-
function generatePanelTabsAndMouseBites(boards, options) {
|
|
15080
|
-
const allTabCutouts = [];
|
|
15081
|
-
const allMouseBites = [];
|
|
15082
|
-
for (let boardIndex = 0; boardIndex < boards.length; boardIndex++) {
|
|
15083
|
-
const board = boards[boardIndex];
|
|
15084
|
-
const otherBoards = boards.filter((_, i) => i !== boardIndex);
|
|
15085
|
-
for (const edge of ["top", "bottom", "left", "right"]) {
|
|
15086
|
-
const edgeTabs = generateTabsForEdge({
|
|
15087
|
-
board,
|
|
15088
|
-
edge,
|
|
15089
|
-
otherBoards,
|
|
15090
|
-
options
|
|
15091
|
-
});
|
|
15092
|
-
allTabCutouts.push(...edgeTabs);
|
|
15093
|
-
if (options.mouseBites) {
|
|
15094
|
-
const edgeMouseBites = generateMouseBitesForEdge({
|
|
15095
|
-
board,
|
|
15096
|
-
edge,
|
|
15097
|
-
edgeTabs,
|
|
15098
|
-
allBoards: otherBoards,
|
|
15099
|
-
options
|
|
15100
|
-
});
|
|
15101
|
-
allMouseBites.push(...edgeMouseBites);
|
|
15102
|
-
}
|
|
15103
|
-
}
|
|
15104
|
-
}
|
|
15105
|
-
const tabCutouts = allTabCutouts.map((tab, index) => {
|
|
15106
|
-
const tabWidthDimension = Math.min(tab.width, tab.height);
|
|
15107
|
-
return {
|
|
15108
|
-
type: "pcb_cutout",
|
|
15109
|
-
pcb_cutout_id: `panel_tab_${index}`,
|
|
15110
|
-
shape: "rect",
|
|
15111
|
-
center: tab.center,
|
|
15112
|
-
width: tab.width,
|
|
15113
|
-
height: tab.height,
|
|
15114
|
-
corner_radius: tabWidthDimension / 2
|
|
15115
|
-
};
|
|
15116
|
-
});
|
|
15117
|
-
const mouseBiteDiameter = options.tabWidth * 0.45;
|
|
15118
|
-
const mouseBiteHoles = allMouseBites.map((bite, index) => ({
|
|
15119
|
-
type: "pcb_hole",
|
|
15120
|
-
pcb_hole_id: `panel_mouse_bite_${index}`,
|
|
15121
|
-
hole_shape: "circle",
|
|
15122
|
-
hole_diameter: mouseBiteDiameter,
|
|
15123
|
-
x: bite.x,
|
|
15124
|
-
y: bite.y
|
|
15125
|
-
}));
|
|
15126
|
-
return {
|
|
15127
|
-
tabCutouts,
|
|
15128
|
-
mouseBiteHoles
|
|
15129
|
-
};
|
|
15130
|
-
}
|
|
15131
|
-
|
|
15132
|
-
// lib/components/normal-components/Panel.ts
|
|
15133
|
-
var Panel = class extends Group6 {
|
|
15134
|
-
pcb_panel_id = null;
|
|
15135
|
-
_tabsAndMouseBitesGenerated = false;
|
|
15136
|
-
get config() {
|
|
15137
|
-
return {
|
|
15138
|
-
componentName: "Panel",
|
|
15139
|
-
zodProps: panelProps
|
|
15140
|
-
};
|
|
15141
|
-
}
|
|
15142
|
-
get isGroup() {
|
|
15143
|
-
return true;
|
|
15144
|
-
}
|
|
15145
|
-
get isSubcircuit() {
|
|
15146
|
-
return true;
|
|
15147
|
-
}
|
|
15148
|
-
add(component) {
|
|
15149
|
-
if (component.lowercaseComponentName !== "board") {
|
|
15150
|
-
throw new Error("<panel> can only contain <board> elements");
|
|
15151
|
-
}
|
|
15152
|
-
super.add(component);
|
|
15153
|
-
}
|
|
15154
|
-
doInitialPcbComponentAnchorAlignment() {
|
|
15155
|
-
if (this.root?.pcbDisabled) return;
|
|
15156
|
-
super.doInitialPcbComponentAnchorAlignment();
|
|
15157
|
-
const { db } = this.root;
|
|
15158
|
-
const childBoardInstances = this.children.filter(
|
|
15159
|
-
(c) => c instanceof Board
|
|
15160
|
-
);
|
|
15161
|
-
const hasAnyPositionedBoards = childBoardInstances.some(
|
|
15162
|
-
(b) => b.props.pcbX !== void 0 || b.props.pcbY !== void 0
|
|
15163
|
-
);
|
|
15164
|
-
const unpositionedBoards = childBoardInstances.filter(
|
|
15165
|
-
(b) => b.props.pcbX === void 0 && b.props.pcbY === void 0
|
|
15166
|
-
);
|
|
15167
|
-
if (unpositionedBoards.length > 0 && !hasAnyPositionedBoards) {
|
|
15168
|
-
const tabWidth = this._parsedProps.tabWidth ?? DEFAULT_TAB_WIDTH;
|
|
15169
|
-
const boardGap = this._parsedProps.boardGap ?? tabWidth;
|
|
15170
|
-
const gridCols = Math.ceil(Math.sqrt(unpositionedBoards.length));
|
|
15171
|
-
const gridRows = Math.ceil(unpositionedBoards.length / gridCols);
|
|
15172
|
-
const colWidths = Array(gridCols).fill(0);
|
|
15173
|
-
const rowHeights = Array(gridRows).fill(0);
|
|
15174
|
-
unpositionedBoards.forEach((board, i) => {
|
|
15175
|
-
const col = i % gridCols;
|
|
15176
|
-
const row = Math.floor(i / gridCols);
|
|
15177
|
-
const pcbBoard = db.pcb_board.get(board.pcb_board_id);
|
|
15178
|
-
if (!pcbBoard || pcbBoard.width === void 0 || pcbBoard.height === void 0)
|
|
15179
|
-
return;
|
|
15180
|
-
colWidths[col] = Math.max(colWidths[col], pcbBoard.width);
|
|
15181
|
-
rowHeights[row] = Math.max(rowHeights[row], pcbBoard.height);
|
|
15182
|
-
});
|
|
15183
|
-
const totalGridWidth = colWidths.reduce((a, b) => a + b, 0) + (gridCols > 1 ? (gridCols - 1) * boardGap : 0);
|
|
15184
|
-
const totalGridHeight = rowHeights.reduce((a, b) => a + b, 0) + (gridRows > 1 ? (gridRows - 1) * boardGap : 0);
|
|
15185
|
-
const startX = -totalGridWidth / 2;
|
|
15186
|
-
const startY = -totalGridHeight / 2;
|
|
15187
|
-
const rowYOffsets = [startY];
|
|
15188
|
-
for (let i = 0; i < gridRows - 1; i++) {
|
|
15189
|
-
rowYOffsets.push(rowYOffsets[i] + rowHeights[i] + boardGap);
|
|
15190
|
-
}
|
|
15191
|
-
const colXOffsets = [startX];
|
|
15192
|
-
for (let i = 0; i < gridCols - 1; i++) {
|
|
15193
|
-
colXOffsets.push(colXOffsets[i] + colWidths[i] + boardGap);
|
|
15194
|
-
}
|
|
15195
|
-
unpositionedBoards.forEach((board, i) => {
|
|
15196
|
-
const col = i % gridCols;
|
|
15197
|
-
const row = Math.floor(i / gridCols);
|
|
15198
|
-
const pcbBoard = db.pcb_board.get(board.pcb_board_id);
|
|
15199
|
-
if (!pcbBoard || !pcbBoard.width || !pcbBoard.height) return;
|
|
15200
|
-
const xPos = colXOffsets[col] + colWidths[col] / 2;
|
|
15201
|
-
const yPos = rowYOffsets[row] + rowHeights[row] / 2;
|
|
15202
|
-
board._repositionOnPcb({ x: xPos, y: yPos });
|
|
15203
|
-
db.pcb_board.update(board.pcb_board_id, {
|
|
15204
|
-
center: { x: xPos, y: yPos }
|
|
15205
|
-
});
|
|
15206
|
-
});
|
|
15207
|
-
const allBoardPcbIds = childBoardInstances.map((b) => b.pcb_board_id).filter((id) => !!id);
|
|
15208
|
-
const allBoardsInPanel = db.pcb_board.list().filter((b) => allBoardPcbIds.includes(b.pcb_board_id));
|
|
15209
|
-
let minX = Infinity;
|
|
15210
|
-
let minY = Infinity;
|
|
15211
|
-
let maxX = -Infinity;
|
|
15212
|
-
let maxY = -Infinity;
|
|
15213
|
-
for (const board of allBoardsInPanel) {
|
|
15214
|
-
if (board.width === void 0 || board.height === void 0 || !isFinite(board.width) || !isFinite(board.height))
|
|
15215
|
-
continue;
|
|
15216
|
-
const left = board.center.x - board.width / 2;
|
|
15217
|
-
const right = board.center.x + board.width / 2;
|
|
15218
|
-
const bottom = board.center.y - board.height / 2;
|
|
15219
|
-
const top = board.center.y + board.height / 2;
|
|
15220
|
-
minX = Math.min(minX, left);
|
|
15221
|
-
maxX = Math.max(maxX, right);
|
|
15222
|
-
minY = Math.min(minY, bottom);
|
|
15223
|
-
maxY = Math.max(maxY, top);
|
|
15224
|
-
}
|
|
15225
|
-
if (isFinite(minX)) {
|
|
15226
|
-
const boundsWidth = maxX - minX;
|
|
15227
|
-
const boundsHeight = maxY - minY;
|
|
15228
|
-
const newPanelWidth = boundsWidth + 2 * DEFAULT_PANEL_MARGIN;
|
|
15229
|
-
const newPanelHeight = boundsHeight + 2 * DEFAULT_PANEL_MARGIN;
|
|
15230
|
-
db.pcb_panel.update(this.pcb_panel_id, {
|
|
15231
|
-
width: newPanelWidth,
|
|
15232
|
-
height: newPanelHeight
|
|
15233
|
-
});
|
|
15234
|
-
}
|
|
15922
|
+
} else {
|
|
15923
|
+
mouseBitePosition = boardLeft;
|
|
15924
|
+
}
|
|
15925
|
+
const sortedTabs = [...edgeTabs].sort((a, b) => {
|
|
15926
|
+
if (isHorizontal) {
|
|
15927
|
+
return a.center.x - b.center.x;
|
|
15928
|
+
} else {
|
|
15929
|
+
return a.center.y - b.center.y;
|
|
15235
15930
|
}
|
|
15236
|
-
|
|
15237
|
-
|
|
15238
|
-
const
|
|
15239
|
-
|
|
15240
|
-
|
|
15241
|
-
|
|
15242
|
-
|
|
15243
|
-
|
|
15244
|
-
|
|
15245
|
-
|
|
15246
|
-
|
|
15247
|
-
|
|
15248
|
-
|
|
15249
|
-
|
|
15250
|
-
|
|
15251
|
-
|
|
15931
|
+
});
|
|
15932
|
+
for (let i = 0; i < sortedTabs.length - 1; i++) {
|
|
15933
|
+
const tab1 = sortedTabs[i];
|
|
15934
|
+
const tab2 = sortedTabs[i + 1];
|
|
15935
|
+
let gapStart;
|
|
15936
|
+
let gapEnd;
|
|
15937
|
+
if (isHorizontal) {
|
|
15938
|
+
gapStart = tab1.center.x + tab1.width / 2;
|
|
15939
|
+
gapEnd = tab2.center.x - tab2.width / 2;
|
|
15940
|
+
} else {
|
|
15941
|
+
gapStart = tab1.center.y + tab1.height / 2;
|
|
15942
|
+
gapEnd = tab2.center.y - tab2.height / 2;
|
|
15943
|
+
}
|
|
15944
|
+
const gapLength = gapEnd - gapStart;
|
|
15945
|
+
const totalMouseBiteWidth = mouseBitesPerGap * mouseBiteDiameter;
|
|
15946
|
+
const totalSpacing = (mouseBitesPerGap - 1) * mouseBiteSpacing;
|
|
15947
|
+
if (gapLength < totalMouseBiteWidth + totalSpacing) continue;
|
|
15948
|
+
const gapCenter = (gapStart + gapEnd) / 2;
|
|
15949
|
+
for (let j = 0; j < mouseBitesPerGap; j++) {
|
|
15950
|
+
const posOffset = (j - (mouseBitesPerGap - 1) / 2) * (mouseBiteDiameter + mouseBiteSpacing);
|
|
15951
|
+
const newMouseBite = isHorizontal ? { x: gapCenter + posOffset, y: mouseBitePosition } : { x: mouseBitePosition, y: gapCenter + posOffset };
|
|
15952
|
+
const radius2 = mouseBiteDiameter / 2;
|
|
15953
|
+
let overlapsBoard = false;
|
|
15954
|
+
for (const otherBoard of allBoards) {
|
|
15955
|
+
if (!otherBoard.width || !otherBoard.height) continue;
|
|
15956
|
+
const boardRect = {
|
|
15957
|
+
center: otherBoard.center,
|
|
15958
|
+
width: otherBoard.width,
|
|
15959
|
+
height: otherBoard.height
|
|
15960
|
+
};
|
|
15961
|
+
if (pointOverlapsRectangle(newMouseBite, radius2, boardRect)) {
|
|
15962
|
+
overlapsBoard = true;
|
|
15963
|
+
break;
|
|
15252
15964
|
}
|
|
15253
|
-
);
|
|
15254
|
-
for (const tabCutout of tabCutouts) {
|
|
15255
|
-
db.pcb_cutout.insert(tabCutout);
|
|
15256
|
-
}
|
|
15257
|
-
for (const mouseBiteHole of mouseBiteHoles) {
|
|
15258
|
-
db.pcb_hole.insert(mouseBiteHole);
|
|
15259
15965
|
}
|
|
15966
|
+
if (overlapsBoard) continue;
|
|
15967
|
+
mouseBites.push(newMouseBite);
|
|
15260
15968
|
}
|
|
15261
|
-
this._tabsAndMouseBitesGenerated = true;
|
|
15262
15969
|
}
|
|
15263
|
-
|
|
15264
|
-
|
|
15265
|
-
|
|
15970
|
+
return mouseBites;
|
|
15971
|
+
}
|
|
15972
|
+
function generatePanelTabsAndMouseBites(boards, options) {
|
|
15973
|
+
const allTabCutouts = [];
|
|
15974
|
+
const allMouseBites = [];
|
|
15975
|
+
for (let boardIndex = 0; boardIndex < boards.length; boardIndex++) {
|
|
15976
|
+
const board = boards[boardIndex];
|
|
15977
|
+
const otherBoards = boards.filter((_, i) => i !== boardIndex);
|
|
15978
|
+
for (const edge of ["top", "bottom", "left", "right"]) {
|
|
15979
|
+
const edgeTabs = generateTabsForEdge({
|
|
15980
|
+
board,
|
|
15981
|
+
edge,
|
|
15982
|
+
otherBoards,
|
|
15983
|
+
options
|
|
15984
|
+
});
|
|
15985
|
+
allTabCutouts.push(...edgeTabs);
|
|
15986
|
+
if (options.mouseBites) {
|
|
15987
|
+
const edgeMouseBites = generateMouseBitesForEdge({
|
|
15988
|
+
board,
|
|
15989
|
+
edge,
|
|
15990
|
+
edgeTabs,
|
|
15991
|
+
allBoards: otherBoards,
|
|
15992
|
+
options
|
|
15993
|
+
});
|
|
15994
|
+
allMouseBites.push(...edgeMouseBites);
|
|
15995
|
+
}
|
|
15266
15996
|
}
|
|
15267
|
-
super.runRenderCycle();
|
|
15268
|
-
}
|
|
15269
|
-
doInitialPcbComponentRender() {
|
|
15270
|
-
super.doInitialPcbComponentRender();
|
|
15271
|
-
if (this.root?.pcbDisabled) return;
|
|
15272
|
-
const { db } = this.root;
|
|
15273
|
-
const props = this._parsedProps;
|
|
15274
|
-
const inserted = db.pcb_panel.insert({
|
|
15275
|
-
width: distance9.parse(props.width),
|
|
15276
|
-
height: distance9.parse(props.height),
|
|
15277
|
-
center: this._getGlobalPcbPositionBeforeLayout(),
|
|
15278
|
-
covered_with_solder_mask: !(props.noSolderMask ?? false)
|
|
15279
|
-
});
|
|
15280
|
-
this.pcb_panel_id = inserted.pcb_panel_id;
|
|
15281
|
-
}
|
|
15282
|
-
updatePcbComponentRender() {
|
|
15283
|
-
if (this.root?.pcbDisabled) return;
|
|
15284
|
-
if (!this.pcb_panel_id) return;
|
|
15285
|
-
const { db } = this.root;
|
|
15286
|
-
const props = this._parsedProps;
|
|
15287
|
-
db.pcb_panel.update(this.pcb_panel_id, {
|
|
15288
|
-
width: distance9.parse(props.width),
|
|
15289
|
-
height: distance9.parse(props.height),
|
|
15290
|
-
center: this._getGlobalPcbPositionBeforeLayout(),
|
|
15291
|
-
covered_with_solder_mask: !(props.noSolderMask ?? false)
|
|
15292
|
-
});
|
|
15293
|
-
}
|
|
15294
|
-
removePcbComponentRender() {
|
|
15295
|
-
if (!this.pcb_panel_id) return;
|
|
15296
|
-
this.root?.db.pcb_panel.delete(this.pcb_panel_id);
|
|
15297
|
-
this.pcb_panel_id = null;
|
|
15298
|
-
}
|
|
15299
|
-
};
|
|
15300
|
-
|
|
15301
|
-
// lib/components/normal-components/Capacitor.ts
|
|
15302
|
-
import { capacitorProps } from "@tscircuit/props";
|
|
15303
|
-
|
|
15304
|
-
// lib/utils/constants.ts
|
|
15305
|
-
var stringProxy = new Proxy(
|
|
15306
|
-
{},
|
|
15307
|
-
{
|
|
15308
|
-
get: (target, prop) => prop
|
|
15309
15997
|
}
|
|
15310
|
-
)
|
|
15311
|
-
|
|
15312
|
-
var SCHEMATIC_COMPONENT_OUTLINE_COLOR = "rgba(132, 0, 0)";
|
|
15313
|
-
var SCHEMATIC_COMPONENT_OUTLINE_STROKE_WIDTH = 0.12;
|
|
15314
|
-
|
|
15315
|
-
// lib/components/normal-components/Capacitor.ts
|
|
15316
|
-
import { formatSiUnit } from "format-si-unit";
|
|
15317
|
-
var Capacitor = class extends NormalComponent3 {
|
|
15318
|
-
_adjustSilkscreenTextAutomatically = true;
|
|
15319
|
-
// @ts-ignore (cause the symbolName is string and not fixed)
|
|
15320
|
-
get config() {
|
|
15998
|
+
const tabCutouts = allTabCutouts.map((tab, index) => {
|
|
15999
|
+
const tabWidthDimension = Math.min(tab.width, tab.height);
|
|
15321
16000
|
return {
|
|
15322
|
-
|
|
15323
|
-
|
|
15324
|
-
|
|
15325
|
-
|
|
16001
|
+
type: "pcb_cutout",
|
|
16002
|
+
pcb_cutout_id: `panel_tab_${index}`,
|
|
16003
|
+
shape: "rect",
|
|
16004
|
+
center: tab.center,
|
|
16005
|
+
width: tab.width,
|
|
16006
|
+
height: tab.height,
|
|
16007
|
+
corner_radius: tabWidthDimension / 2
|
|
15326
16008
|
};
|
|
15327
|
-
}
|
|
15328
|
-
|
|
15329
|
-
|
|
15330
|
-
|
|
15331
|
-
|
|
15332
|
-
|
|
15333
|
-
|
|
15334
|
-
|
|
15335
|
-
|
|
15336
|
-
|
|
15337
|
-
|
|
15338
|
-
|
|
15339
|
-
|
|
15340
|
-
|
|
15341
|
-
|
|
15342
|
-
const capacitanceDisplay = typeof inputCapacitance === "string" ? inputCapacitance : `${formatSiUnit(this._parsedProps.capacitance)}F`;
|
|
15343
|
-
if (this._parsedProps.schShowRatings && this._parsedProps.maxVoltageRating) {
|
|
15344
|
-
return `${capacitanceDisplay}/${formatSiUnit(this._parsedProps.maxVoltageRating)}V`;
|
|
15345
|
-
}
|
|
15346
|
-
return capacitanceDisplay;
|
|
15347
|
-
}
|
|
15348
|
-
doInitialCreateNetsFromProps() {
|
|
15349
|
-
this._createNetsFromProps([
|
|
15350
|
-
this.props.decouplingFor,
|
|
15351
|
-
this.props.decouplingTo,
|
|
15352
|
-
...this._getNetsFromConnectionsProp()
|
|
15353
|
-
]);
|
|
15354
|
-
}
|
|
15355
|
-
doInitialCreateTracesFromProps() {
|
|
15356
|
-
if (this.props.decouplingFor && this.props.decouplingTo) {
|
|
15357
|
-
this.add(
|
|
15358
|
-
new Trace3({
|
|
15359
|
-
from: `${this.getSubcircuitSelector()} > port.1`,
|
|
15360
|
-
to: this.props.decouplingFor
|
|
15361
|
-
})
|
|
15362
|
-
);
|
|
15363
|
-
this.add(
|
|
15364
|
-
new Trace3({
|
|
15365
|
-
from: `${this.getSubcircuitSelector()} > port.2`,
|
|
15366
|
-
to: this.props.decouplingTo
|
|
15367
|
-
})
|
|
15368
|
-
);
|
|
15369
|
-
}
|
|
15370
|
-
this._createTracesFromConnectionsProp();
|
|
15371
|
-
}
|
|
15372
|
-
doInitialSourceRender() {
|
|
15373
|
-
const { db } = this.root;
|
|
15374
|
-
const { _parsedProps: props } = this;
|
|
15375
|
-
const source_component = db.source_component.insert({
|
|
15376
|
-
ftype: "simple_capacitor",
|
|
15377
|
-
name: this.name,
|
|
15378
|
-
// @ts-ignore
|
|
15379
|
-
manufacturer_part_number: props.manufacturerPartNumber ?? props.mfn,
|
|
15380
|
-
supplier_part_numbers: props.supplierPartNumbers,
|
|
15381
|
-
capacitance: props.capacitance,
|
|
15382
|
-
max_voltage_rating: props.maxVoltageRating,
|
|
15383
|
-
max_decoupling_trace_length: props.maxDecouplingTraceLength,
|
|
15384
|
-
display_capacitance: this._getSchematicSymbolDisplayValue(),
|
|
15385
|
-
are_pins_interchangeable: !props.polarized
|
|
15386
|
-
});
|
|
15387
|
-
this.source_component_id = source_component.source_component_id;
|
|
15388
|
-
}
|
|
15389
|
-
};
|
|
16009
|
+
});
|
|
16010
|
+
const mouseBiteDiameter = options.tabWidth * 0.45;
|
|
16011
|
+
const mouseBiteHoles = allMouseBites.map((bite, index) => ({
|
|
16012
|
+
type: "pcb_hole",
|
|
16013
|
+
pcb_hole_id: `panel_mouse_bite_${index}`,
|
|
16014
|
+
hole_shape: "circle",
|
|
16015
|
+
hole_diameter: mouseBiteDiameter,
|
|
16016
|
+
x: bite.x,
|
|
16017
|
+
y: bite.y
|
|
16018
|
+
}));
|
|
16019
|
+
return {
|
|
16020
|
+
tabCutouts,
|
|
16021
|
+
mouseBiteHoles
|
|
16022
|
+
};
|
|
16023
|
+
}
|
|
15390
16024
|
|
|
15391
|
-
// lib/components/normal-components/
|
|
15392
|
-
|
|
15393
|
-
|
|
15394
|
-
|
|
15395
|
-
schematicBoxDimensions = null;
|
|
15396
|
-
constructor(props) {
|
|
15397
|
-
super(props);
|
|
15398
|
-
}
|
|
16025
|
+
// lib/components/normal-components/Panel.ts
|
|
16026
|
+
var Panel = class extends Group6 {
|
|
16027
|
+
pcb_panel_id = null;
|
|
16028
|
+
_tabsAndMouseBitesGenerated = false;
|
|
15399
16029
|
get config() {
|
|
15400
16030
|
return {
|
|
15401
|
-
componentName: "
|
|
15402
|
-
zodProps:
|
|
15403
|
-
shouldRenderAsSchematicBox: true
|
|
16031
|
+
componentName: "Panel",
|
|
16032
|
+
zodProps: panelProps
|
|
15404
16033
|
};
|
|
15405
16034
|
}
|
|
15406
|
-
|
|
15407
|
-
|
|
15408
|
-
const { _parsedProps: props } = this;
|
|
15409
|
-
const { pcbX, pcbY } = this.getResolvedPcbPositionProp();
|
|
15410
|
-
if (props.externallyConnectedPins) {
|
|
15411
|
-
const requiredPorts = /* @__PURE__ */ new Set();
|
|
15412
|
-
for (const [pin1, pin2] of props.externallyConnectedPins) {
|
|
15413
|
-
requiredPorts.add(pin1);
|
|
15414
|
-
requiredPorts.add(pin2);
|
|
15415
|
-
}
|
|
15416
|
-
for (const pinIdentifier of requiredPorts) {
|
|
15417
|
-
const existingPort = this.children.find(
|
|
15418
|
-
(child) => child instanceof Port && child.isMatchingAnyOf([pinIdentifier])
|
|
15419
|
-
);
|
|
15420
|
-
if (!existingPort) {
|
|
15421
|
-
const pinMatch = pinIdentifier.match(/^pin(\d+)$/);
|
|
15422
|
-
if (pinMatch) {
|
|
15423
|
-
const pinNumber = parseInt(pinMatch[1]);
|
|
15424
|
-
this.add(
|
|
15425
|
-
new Port({
|
|
15426
|
-
pinNumber,
|
|
15427
|
-
aliases: [pinIdentifier]
|
|
15428
|
-
})
|
|
15429
|
-
);
|
|
15430
|
-
} else {
|
|
15431
|
-
this.add(
|
|
15432
|
-
new Port({
|
|
15433
|
-
name: pinIdentifier,
|
|
15434
|
-
aliases: [pinIdentifier]
|
|
15435
|
-
})
|
|
15436
|
-
);
|
|
15437
|
-
}
|
|
15438
|
-
}
|
|
15439
|
-
}
|
|
15440
|
-
}
|
|
16035
|
+
get isGroup() {
|
|
16036
|
+
return true;
|
|
15441
16037
|
}
|
|
15442
|
-
|
|
15443
|
-
|
|
15444
|
-
if (props?.noSchematicRepresentation === true) return;
|
|
15445
|
-
super.doInitialSchematicComponentRender();
|
|
16038
|
+
get isSubcircuit() {
|
|
16039
|
+
return true;
|
|
15446
16040
|
}
|
|
15447
|
-
|
|
15448
|
-
|
|
15449
|
-
|
|
15450
|
-
|
|
15451
|
-
|
|
15452
|
-
ftype: "simple_chip",
|
|
15453
|
-
name: this.name,
|
|
15454
|
-
manufacturer_part_number: props.manufacturerPartNumber,
|
|
15455
|
-
supplier_part_numbers: props.supplierPartNumbers
|
|
15456
|
-
});
|
|
15457
|
-
this.source_component_id = source_component.source_component_id;
|
|
16041
|
+
add(component) {
|
|
16042
|
+
if (component.lowercaseComponentName !== "board") {
|
|
16043
|
+
throw new Error("<panel> can only contain <board> elements");
|
|
16044
|
+
}
|
|
16045
|
+
super.add(component);
|
|
15458
16046
|
}
|
|
15459
|
-
|
|
16047
|
+
doInitialPanelLayout() {
|
|
15460
16048
|
if (this.root?.pcbDisabled) return;
|
|
15461
16049
|
const { db } = this.root;
|
|
15462
|
-
const
|
|
15463
|
-
|
|
15464
|
-
|
|
15465
|
-
|
|
15466
|
-
|
|
15467
|
-
|
|
15468
|
-
|
|
15469
|
-
|
|
15470
|
-
|
|
15471
|
-
|
|
15472
|
-
|
|
16050
|
+
const childBoardInstances = this.children.filter(
|
|
16051
|
+
(c) => c instanceof Board
|
|
16052
|
+
);
|
|
16053
|
+
const hasAnyPositionedBoards = childBoardInstances.some(
|
|
16054
|
+
(b) => b.props.pcbX !== void 0 || b.props.pcbY !== void 0
|
|
16055
|
+
);
|
|
16056
|
+
const unpositionedBoards = childBoardInstances.filter(
|
|
16057
|
+
(b) => b.props.pcbX === void 0 && b.props.pcbY === void 0
|
|
16058
|
+
);
|
|
16059
|
+
if (unpositionedBoards.length > 0 && !hasAnyPositionedBoards) {
|
|
16060
|
+
const tabWidth = this._parsedProps.tabWidth ?? DEFAULT_TAB_WIDTH;
|
|
16061
|
+
const boardGap = this._parsedProps.boardGap ?? tabWidth;
|
|
16062
|
+
const gridCols = Math.ceil(Math.sqrt(unpositionedBoards.length));
|
|
16063
|
+
const gridRows = Math.ceil(unpositionedBoards.length / gridCols);
|
|
16064
|
+
const colWidths = Array(gridCols).fill(0);
|
|
16065
|
+
const rowHeights = Array(gridRows).fill(0);
|
|
16066
|
+
unpositionedBoards.forEach((board, i) => {
|
|
16067
|
+
const col = i % gridCols;
|
|
16068
|
+
const row = Math.floor(i / gridCols);
|
|
16069
|
+
const pcbBoard = db.pcb_board.get(board.pcb_board_id);
|
|
16070
|
+
if (!pcbBoard || pcbBoard.width === void 0 || pcbBoard.height === void 0)
|
|
16071
|
+
return;
|
|
16072
|
+
colWidths[col] = Math.max(colWidths[col], pcbBoard.width);
|
|
16073
|
+
rowHeights[row] = Math.max(rowHeights[row], pcbBoard.height);
|
|
15473
16074
|
});
|
|
15474
|
-
|
|
15475
|
-
|
|
15476
|
-
|
|
15477
|
-
|
|
15478
|
-
|
|
15479
|
-
|
|
15480
|
-
|
|
15481
|
-
|
|
15482
|
-
|
|
15483
|
-
|
|
15484
|
-
|
|
15485
|
-
|
|
15486
|
-
|
|
15487
|
-
|
|
15488
|
-
|
|
15489
|
-
|
|
15490
|
-
|
|
15491
|
-
|
|
15492
|
-
|
|
15493
|
-
|
|
15494
|
-
|
|
15495
|
-
|
|
15496
|
-
|
|
15497
|
-
|
|
15498
|
-
|
|
15499
|
-
|
|
15500
|
-
|
|
16075
|
+
const totalGridWidth = colWidths.reduce((a, b) => a + b, 0) + (gridCols > 1 ? (gridCols - 1) * boardGap : 0);
|
|
16076
|
+
const totalGridHeight = rowHeights.reduce((a, b) => a + b, 0) + (gridRows > 1 ? (gridRows - 1) * boardGap : 0);
|
|
16077
|
+
const startX = -totalGridWidth / 2;
|
|
16078
|
+
const startY = -totalGridHeight / 2;
|
|
16079
|
+
const rowYOffsets = [startY];
|
|
16080
|
+
for (let i = 0; i < gridRows - 1; i++) {
|
|
16081
|
+
rowYOffsets.push(rowYOffsets[i] + rowHeights[i] + boardGap);
|
|
16082
|
+
}
|
|
16083
|
+
const colXOffsets = [startX];
|
|
16084
|
+
for (let i = 0; i < gridCols - 1; i++) {
|
|
16085
|
+
colXOffsets.push(colXOffsets[i] + colWidths[i] + boardGap);
|
|
16086
|
+
}
|
|
16087
|
+
unpositionedBoards.forEach((board, i) => {
|
|
16088
|
+
const col = i % gridCols;
|
|
16089
|
+
const row = Math.floor(i / gridCols);
|
|
16090
|
+
const pcbBoard = db.pcb_board.get(board.pcb_board_id);
|
|
16091
|
+
if (!pcbBoard || !pcbBoard.width || !pcbBoard.height) return;
|
|
16092
|
+
const xPos = colXOffsets[col] + colWidths[col] / 2;
|
|
16093
|
+
const yPos = rowYOffsets[row] + rowHeights[row] / 2;
|
|
16094
|
+
board._repositionOnPcb({ x: xPos, y: yPos });
|
|
16095
|
+
db.pcb_board.update(board.pcb_board_id, {
|
|
16096
|
+
center: { x: xPos, y: yPos }
|
|
16097
|
+
});
|
|
16098
|
+
});
|
|
16099
|
+
const allBoardPcbIds = childBoardInstances.map((b) => b.pcb_board_id).filter((id) => !!id);
|
|
16100
|
+
const allBoardsInPanel = db.pcb_board.list().filter((b) => allBoardPcbIds.includes(b.pcb_board_id));
|
|
16101
|
+
let minX = Infinity;
|
|
16102
|
+
let minY = Infinity;
|
|
16103
|
+
let maxX = -Infinity;
|
|
16104
|
+
let maxY = -Infinity;
|
|
16105
|
+
for (const board of allBoardsInPanel) {
|
|
16106
|
+
if (board.width === void 0 || board.height === void 0 || !isFinite(board.width) || !isFinite(board.height))
|
|
16107
|
+
continue;
|
|
16108
|
+
const left = board.center.x - board.width / 2;
|
|
16109
|
+
const right = board.center.x + board.width / 2;
|
|
16110
|
+
const bottom = board.center.y - board.height / 2;
|
|
16111
|
+
const top = board.center.y + board.height / 2;
|
|
16112
|
+
minX = Math.min(minX, left);
|
|
16113
|
+
maxX = Math.max(maxX, right);
|
|
16114
|
+
minY = Math.min(minY, bottom);
|
|
16115
|
+
maxY = Math.max(maxY, top);
|
|
16116
|
+
}
|
|
16117
|
+
if (isFinite(minX)) {
|
|
16118
|
+
const boundsWidth = maxX - minX;
|
|
16119
|
+
const boundsHeight = maxY - minY;
|
|
16120
|
+
const newPanelWidth = boundsWidth + 2 * DEFAULT_PANEL_MARGIN;
|
|
16121
|
+
const newPanelHeight = boundsHeight + 2 * DEFAULT_PANEL_MARGIN;
|
|
16122
|
+
db.pcb_panel.update(this.pcb_panel_id, {
|
|
16123
|
+
width: newPanelWidth,
|
|
16124
|
+
height: newPanelHeight
|
|
16125
|
+
});
|
|
15501
16126
|
}
|
|
15502
16127
|
}
|
|
15503
|
-
this.
|
|
15504
|
-
|
|
15505
|
-
|
|
15506
|
-
|
|
15507
|
-
|
|
15508
|
-
|
|
15509
|
-
|
|
15510
|
-
|
|
15511
|
-
|
|
15512
|
-
|
|
15513
|
-
|
|
15514
|
-
|
|
15515
|
-
|
|
15516
|
-
|
|
15517
|
-
|
|
15518
|
-
|
|
15519
|
-
voltage = attributes.providesVoltage;
|
|
15520
|
-
}
|
|
15521
|
-
if (attributes.providesGround) {
|
|
15522
|
-
groundPort = port;
|
|
15523
|
-
}
|
|
16128
|
+
if (this._tabsAndMouseBitesGenerated) return;
|
|
16129
|
+
const props = this._parsedProps;
|
|
16130
|
+
const panelizationMethod = props.panelizationMethod ?? "tab-routing";
|
|
16131
|
+
if (panelizationMethod !== "none") {
|
|
16132
|
+
const childBoardIds = childBoardInstances.map((c) => c.pcb_board_id).filter((id) => !!id);
|
|
16133
|
+
const boardsInPanel = db.pcb_board.list().filter((b) => childBoardIds.includes(b.pcb_board_id));
|
|
16134
|
+
if (boardsInPanel.length === 0) return;
|
|
16135
|
+
const tabWidth = props.tabWidth ?? DEFAULT_TAB_WIDTH;
|
|
16136
|
+
const boardGap = props.boardGap ?? tabWidth;
|
|
16137
|
+
const { tabCutouts, mouseBiteHoles } = generatePanelTabsAndMouseBites(
|
|
16138
|
+
boardsInPanel,
|
|
16139
|
+
{
|
|
16140
|
+
boardGap,
|
|
16141
|
+
tabWidth,
|
|
16142
|
+
tabLength: props.tabLength ?? DEFAULT_TAB_LENGTH,
|
|
16143
|
+
mouseBites: props.mouseBites ?? true
|
|
15524
16144
|
}
|
|
16145
|
+
);
|
|
16146
|
+
for (const tabCutout of tabCutouts) {
|
|
16147
|
+
db.pcb_cutout.insert(tabCutout);
|
|
16148
|
+
}
|
|
16149
|
+
for (const mouseBiteHole of mouseBiteHoles) {
|
|
16150
|
+
db.pcb_hole.insert(mouseBiteHole);
|
|
15525
16151
|
}
|
|
15526
16152
|
}
|
|
15527
|
-
|
|
15528
|
-
|
|
15529
|
-
|
|
15530
|
-
|
|
15531
|
-
|
|
15532
|
-
const groundSourcePort = db.source_port.get(groundPort.source_port_id);
|
|
15533
|
-
if (!groundSourcePort?.subcircuit_connectivity_map_key) return;
|
|
15534
|
-
const powerNet = db.source_net.getWhere({
|
|
15535
|
-
subcircuit_connectivity_map_key: powerSourcePort.subcircuit_connectivity_map_key
|
|
15536
|
-
});
|
|
15537
|
-
const groundNet = db.source_net.getWhere({
|
|
15538
|
-
subcircuit_connectivity_map_key: groundSourcePort.subcircuit_connectivity_map_key
|
|
15539
|
-
});
|
|
15540
|
-
if (!powerNet || !groundNet) {
|
|
15541
|
-
return;
|
|
16153
|
+
this._tabsAndMouseBitesGenerated = true;
|
|
16154
|
+
}
|
|
16155
|
+
runRenderCycle() {
|
|
16156
|
+
if (!this.children.some((child) => child.componentName === "Board")) {
|
|
16157
|
+
throw new Error("<panel> must contain at least one <board>");
|
|
15542
16158
|
}
|
|
15543
|
-
;
|
|
15544
|
-
|
|
15545
|
-
|
|
15546
|
-
|
|
15547
|
-
|
|
15548
|
-
|
|
15549
|
-
|
|
15550
|
-
|
|
16159
|
+
super.runRenderCycle();
|
|
16160
|
+
}
|
|
16161
|
+
doInitialPcbComponentRender() {
|
|
16162
|
+
super.doInitialPcbComponentRender();
|
|
16163
|
+
if (this.root?.pcbDisabled) return;
|
|
16164
|
+
const { db } = this.root;
|
|
16165
|
+
const props = this._parsedProps;
|
|
16166
|
+
const inserted = db.pcb_panel.insert({
|
|
16167
|
+
width: distance9.parse(props.width),
|
|
16168
|
+
height: distance9.parse(props.height),
|
|
16169
|
+
center: this._getGlobalPcbPositionBeforeLayout(),
|
|
16170
|
+
covered_with_solder_mask: !(props.noSolderMask ?? false)
|
|
15551
16171
|
});
|
|
16172
|
+
this.pcb_panel_id = inserted.pcb_panel_id;
|
|
16173
|
+
}
|
|
16174
|
+
updatePcbComponentRender() {
|
|
16175
|
+
if (this.root?.pcbDisabled) return;
|
|
16176
|
+
if (!this.pcb_panel_id) return;
|
|
16177
|
+
const { db } = this.root;
|
|
16178
|
+
const props = this._parsedProps;
|
|
16179
|
+
db.pcb_panel.update(this.pcb_panel_id, {
|
|
16180
|
+
width: distance9.parse(props.width),
|
|
16181
|
+
height: distance9.parse(props.height),
|
|
16182
|
+
center: this._getGlobalPcbPositionBeforeLayout(),
|
|
16183
|
+
covered_with_solder_mask: !(props.noSolderMask ?? false)
|
|
16184
|
+
});
|
|
16185
|
+
}
|
|
16186
|
+
removePcbComponentRender() {
|
|
16187
|
+
if (!this.pcb_panel_id) return;
|
|
16188
|
+
this.root?.db.pcb_panel.delete(this.pcb_panel_id);
|
|
16189
|
+
this.pcb_panel_id = null;
|
|
15552
16190
|
}
|
|
15553
16191
|
};
|
|
15554
16192
|
|
|
@@ -15578,55 +16216,9 @@ var Pinout = class extends Chip {
|
|
|
15578
16216
|
}
|
|
15579
16217
|
};
|
|
15580
16218
|
|
|
15581
|
-
// lib/components/normal-components/Diode.ts
|
|
15582
|
-
import { diodeProps } from "@tscircuit/props";
|
|
15583
|
-
var Diode = class extends NormalComponent3 {
|
|
15584
|
-
// @ts-ignore
|
|
15585
|
-
get config() {
|
|
15586
|
-
const symbolMap = {
|
|
15587
|
-
schottky: "schottky_diode",
|
|
15588
|
-
avalanche: "avalanche_diode",
|
|
15589
|
-
zener: "zener_diode",
|
|
15590
|
-
photodiode: "photodiode"
|
|
15591
|
-
};
|
|
15592
|
-
const variantSymbol = this.props.schottky ? "schottky" : this.props.avalanche ? "avalanche" : this.props.zener ? "zener" : this.props.photo ? "photodiode" : null;
|
|
15593
|
-
return {
|
|
15594
|
-
schematicSymbolName: variantSymbol ? symbolMap[variantSymbol] : this.props.symbolName ?? "diode",
|
|
15595
|
-
componentName: "Diode",
|
|
15596
|
-
zodProps: diodeProps,
|
|
15597
|
-
sourceFtype: "simple_diode"
|
|
15598
|
-
};
|
|
15599
|
-
}
|
|
15600
|
-
initPorts() {
|
|
15601
|
-
super.initPorts({
|
|
15602
|
-
additionalAliases: {
|
|
15603
|
-
pin1: ["anode", "pos", "left"],
|
|
15604
|
-
pin2: ["cathode", "neg", "right"]
|
|
15605
|
-
}
|
|
15606
|
-
});
|
|
15607
|
-
}
|
|
15608
|
-
doInitialSourceRender() {
|
|
15609
|
-
const { db } = this.root;
|
|
15610
|
-
const { _parsedProps: props } = this;
|
|
15611
|
-
const source_component = db.source_component.insert({
|
|
15612
|
-
ftype: "simple_diode",
|
|
15613
|
-
name: this.name,
|
|
15614
|
-
// @ts-ignore
|
|
15615
|
-
manufacturer_part_number: props.manufacturerPartNumber ?? props.mfn,
|
|
15616
|
-
supplier_part_numbers: props.supplierPartNumbers,
|
|
15617
|
-
are_pins_interchangeable: false
|
|
15618
|
-
});
|
|
15619
|
-
this.source_component_id = source_component.source_component_id;
|
|
15620
|
-
}
|
|
15621
|
-
pos = this.portMap.pin1;
|
|
15622
|
-
anode = this.portMap.pin1;
|
|
15623
|
-
neg = this.portMap.pin2;
|
|
15624
|
-
cathode = this.portMap.pin2;
|
|
15625
|
-
};
|
|
15626
|
-
|
|
15627
16219
|
// lib/components/normal-components/Fuse.ts
|
|
15628
16220
|
import { fuseProps } from "@tscircuit/props";
|
|
15629
|
-
import { formatSiUnit as
|
|
16221
|
+
import { formatSiUnit as formatSiUnit4 } from "format-si-unit";
|
|
15630
16222
|
var Fuse = class extends NormalComponent3 {
|
|
15631
16223
|
get config() {
|
|
15632
16224
|
return {
|
|
@@ -15641,7 +16233,7 @@ var Fuse = class extends NormalComponent3 {
|
|
|
15641
16233
|
const rawVoltage = this._parsedProps.voltageRating;
|
|
15642
16234
|
const current = typeof rawCurrent === "string" ? parseFloat(rawCurrent) : rawCurrent;
|
|
15643
16235
|
const voltage = typeof rawVoltage === "string" ? parseFloat(rawVoltage) : rawVoltage;
|
|
15644
|
-
return `${
|
|
16236
|
+
return `${formatSiUnit4(current)}A / ${formatSiUnit4(voltage)}V`;
|
|
15645
16237
|
}
|
|
15646
16238
|
doInitialSourceRender() {
|
|
15647
16239
|
const { db } = this.root;
|
|
@@ -15653,8 +16245,8 @@ var Fuse = class extends NormalComponent3 {
|
|
|
15653
16245
|
ftype: FTYPE.simple_fuse,
|
|
15654
16246
|
current_rating_amps: currentRating,
|
|
15655
16247
|
voltage_rating_volts: voltageRating,
|
|
15656
|
-
display_current_rating: `${
|
|
15657
|
-
display_voltage_rating: `${
|
|
16248
|
+
display_current_rating: `${formatSiUnit4(currentRating)}A`,
|
|
16249
|
+
display_voltage_rating: `${formatSiUnit4(voltageRating)}V`
|
|
15658
16250
|
});
|
|
15659
16251
|
this.source_component_id = source_component.source_component_id;
|
|
15660
16252
|
}
|
|
@@ -15763,944 +16355,583 @@ var Jumper = class extends NormalComponent3 {
|
|
|
15763
16355
|
}
|
|
15764
16356
|
};
|
|
15765
16357
|
|
|
15766
|
-
// lib/components/normal-components/Interconnect.ts
|
|
15767
|
-
import { interconnectProps } from "@tscircuit/props";
|
|
15768
|
-
var INTERCONNECT_STANDARD_FOOTPRINTS = {
|
|
15769
|
-
"0603": "0603",
|
|
15770
|
-
"0805": "0805",
|
|
15771
|
-
"1206": "1206"
|
|
15772
|
-
};
|
|
15773
|
-
var Interconnect = class extends NormalComponent3 {
|
|
15774
|
-
get config() {
|
|
15775
|
-
return {
|
|
15776
|
-
componentName: "Interconnect",
|
|
15777
|
-
zodProps: interconnectProps,
|
|
15778
|
-
shouldRenderAsSchematicBox: true,
|
|
15779
|
-
sourceFtype: "interconnect"
|
|
15780
|
-
};
|
|
15781
|
-
}
|
|
15782
|
-
_getImpliedFootprintString() {
|
|
15783
|
-
const { standard } = this._parsedProps;
|
|
15784
|
-
if (!standard) return null;
|
|
15785
|
-
return INTERCONNECT_STANDARD_FOOTPRINTS[standard] ?? null;
|
|
15786
|
-
}
|
|
15787
|
-
doInitialSourceRender() {
|
|
15788
|
-
const { db } = this.root;
|
|
15789
|
-
const source_component = db.source_component.insert({
|
|
15790
|
-
ftype: "interconnect",
|
|
15791
|
-
name: this.name,
|
|
15792
|
-
are_pins_interchangeable: true
|
|
15793
|
-
});
|
|
15794
|
-
this.source_component_id = source_component.source_component_id;
|
|
15795
|
-
}
|
|
15796
|
-
};
|
|
15797
|
-
|
|
15798
|
-
// lib/components/normal-components/SolderJumper.ts
|
|
15799
|
-
import { solderjumperProps } from "@tscircuit/props";
|
|
15800
|
-
var SolderJumper = class extends NormalComponent3 {
|
|
15801
|
-
schematicDimensions = null;
|
|
15802
|
-
_getPinNumberFromBridgedPinName(pinName) {
|
|
15803
|
-
const port = this.selectOne(`port.${pinName}`, {
|
|
15804
|
-
type: "port"
|
|
15805
|
-
});
|
|
15806
|
-
return port?._parsedProps.pinNumber ?? null;
|
|
15807
|
-
}
|
|
15808
|
-
get defaultInternallyConnectedPinNames() {
|
|
15809
|
-
if (this._parsedProps.bridged) {
|
|
15810
|
-
const pins = this.children.filter((c) => c.componentName === "Port").map((p) => p.name);
|
|
15811
|
-
return pins.length > 0 ? [pins] : [];
|
|
15812
|
-
}
|
|
15813
|
-
return this._parsedProps.bridgedPins ?? [];
|
|
15814
|
-
}
|
|
15815
|
-
get config() {
|
|
15816
|
-
const props = this._parsedProps ?? this.props;
|
|
15817
|
-
let resolvedPinCount = props.pinCount;
|
|
15818
|
-
if (props.pinCount == null && !props.footprint) {
|
|
15819
|
-
resolvedPinCount = 2;
|
|
15820
|
-
}
|
|
15821
|
-
if (props.pinCount == null) {
|
|
15822
|
-
const nums = (props.bridgedPins ?? []).flat().map((p_str) => this._getPinNumberFromBridgedPinName(p_str)).filter((n) => n !== null);
|
|
15823
|
-
const maxPinFromBridged = nums.length > 0 ? Math.max(...nums) : 0;
|
|
15824
|
-
const pinCountFromLabels = props.pinLabels ? Object.keys(props.pinLabels).length : 0;
|
|
15825
|
-
const finalPinCount = Math.max(maxPinFromBridged, pinCountFromLabels);
|
|
15826
|
-
if (finalPinCount === 2 || finalPinCount === 3) {
|
|
15827
|
-
resolvedPinCount = finalPinCount;
|
|
15828
|
-
}
|
|
15829
|
-
if (resolvedPinCount == null && props.footprint && [2, 3].includes(this.getPortsFromFootprint().length)) {
|
|
15830
|
-
resolvedPinCount = this.getPortsFromFootprint().length;
|
|
15831
|
-
}
|
|
15832
|
-
}
|
|
15833
|
-
let symbolName = "";
|
|
15834
|
-
if (resolvedPinCount) {
|
|
15835
|
-
symbolName += `solderjumper${resolvedPinCount}`;
|
|
15836
|
-
} else {
|
|
15837
|
-
symbolName = "solderjumper";
|
|
15838
|
-
}
|
|
15839
|
-
let bridgedPinNumbers = [];
|
|
15840
|
-
if (Array.isArray(props.bridgedPins) && props.bridgedPins.length > 0) {
|
|
15841
|
-
bridgedPinNumbers = Array.from(
|
|
15842
|
-
new Set(
|
|
15843
|
-
props.bridgedPins.flat().map((pinName) => this._getPinNumberFromBridgedPinName(pinName)).filter((n) => n !== null)
|
|
15844
|
-
)
|
|
15845
|
-
).sort((a, b) => a - b);
|
|
15846
|
-
} else if (props.bridged && resolvedPinCount) {
|
|
15847
|
-
bridgedPinNumbers = Array.from(
|
|
15848
|
-
{ length: resolvedPinCount },
|
|
15849
|
-
(_, i) => i + 1
|
|
15850
|
-
);
|
|
15851
|
-
}
|
|
15852
|
-
if (bridgedPinNumbers.length > 0) {
|
|
15853
|
-
symbolName += `_bridged${bridgedPinNumbers.join("")}`;
|
|
15854
|
-
}
|
|
15855
|
-
return {
|
|
15856
|
-
schematicSymbolName: props.symbolName ?? symbolName,
|
|
15857
|
-
componentName: "SolderJumper",
|
|
15858
|
-
zodProps: solderjumperProps,
|
|
15859
|
-
shouldRenderAsSchematicBox: true
|
|
15860
|
-
};
|
|
15861
|
-
}
|
|
15862
|
-
_getSchematicPortArrangement() {
|
|
15863
|
-
const arrangement = super._getSchematicPortArrangement();
|
|
15864
|
-
if (arrangement && Object.keys(arrangement).length > 0) return arrangement;
|
|
15865
|
-
let pinCount = this._parsedProps.pinCount ?? (Array.isArray(this._parsedProps.pinLabels) ? this._parsedProps.pinLabels.length : this._parsedProps.pinLabels ? Object.keys(this._parsedProps.pinLabels).length : this.getPortsFromFootprint().length);
|
|
15866
|
-
if (pinCount == null && !this._parsedProps.footprint) {
|
|
15867
|
-
pinCount = 2;
|
|
15868
|
-
}
|
|
15869
|
-
const direction = this._parsedProps.schDirection ?? "right";
|
|
15870
|
-
return {
|
|
15871
|
-
leftSize: direction === "left" ? pinCount : 0,
|
|
15872
|
-
rightSize: direction === "right" ? pinCount : 0
|
|
15873
|
-
};
|
|
15874
|
-
}
|
|
15875
|
-
doInitialSourceRender() {
|
|
15876
|
-
const { db } = this.root;
|
|
15877
|
-
const { _parsedProps: props } = this;
|
|
15878
|
-
const { pcbX, pcbY } = this.getResolvedPcbPositionProp();
|
|
15879
|
-
const source_component = db.source_component.insert({
|
|
15880
|
-
ftype: "simple_chip",
|
|
15881
|
-
// TODO unknown or jumper
|
|
15882
|
-
name: this.name,
|
|
15883
|
-
manufacturer_part_number: props.manufacturerPartNumber,
|
|
15884
|
-
supplier_part_numbers: props.supplierPartNumbers,
|
|
15885
|
-
are_pins_interchangeable: true
|
|
15886
|
-
});
|
|
15887
|
-
this.source_component_id = source_component.source_component_id;
|
|
15888
|
-
}
|
|
15889
|
-
doInitialPcbComponentRender() {
|
|
15890
|
-
if (this.root?.pcbDisabled) return;
|
|
15891
|
-
const { db } = this.root;
|
|
15892
|
-
const { _parsedProps: props } = this;
|
|
15893
|
-
const { pcbX, pcbY } = this.getResolvedPcbPositionProp();
|
|
15894
|
-
const pcb_component = db.pcb_component.insert({
|
|
15895
|
-
center: { x: pcbX, y: pcbY },
|
|
15896
|
-
width: 2,
|
|
15897
|
-
// Default width, adjust as needed
|
|
15898
|
-
height: 3,
|
|
15899
|
-
// Default height, adjust as needed
|
|
15900
|
-
layer: props.layer ?? "top",
|
|
15901
|
-
rotation: props.pcbRotation ?? 0,
|
|
15902
|
-
source_component_id: this.source_component_id,
|
|
15903
|
-
subcircuit_id: this.getSubcircuit().subcircuit_id ?? void 0,
|
|
15904
|
-
do_not_place: props.doNotPlace ?? false,
|
|
15905
|
-
obstructs_within_bounds: props.obstructsWithinBounds ?? true
|
|
15906
|
-
});
|
|
15907
|
-
this.pcb_component_id = pcb_component.pcb_component_id;
|
|
15908
|
-
}
|
|
15909
|
-
doInitialPcbTraceRender() {
|
|
15910
|
-
const { db } = this.root;
|
|
15911
|
-
const pcb_ports = db.pcb_port.list({
|
|
15912
|
-
pcb_component_id: this.pcb_component_id
|
|
15913
|
-
});
|
|
15914
|
-
const pinLabelToPortId = {};
|
|
15915
|
-
for (let i = 0; i < pcb_ports.length; i++) {
|
|
15916
|
-
const port = pcb_ports[i];
|
|
15917
|
-
const sourcePort = db.source_port.get(port.source_port_id);
|
|
15918
|
-
let pinLabel = "";
|
|
15919
|
-
if (typeof sourcePort?.pin_number === "number") {
|
|
15920
|
-
pinLabel = sourcePort.pin_number.toString();
|
|
15921
|
-
} else if (Array.isArray(sourcePort?.port_hints)) {
|
|
15922
|
-
let matchedHint = sourcePort.port_hints.find(
|
|
15923
|
-
(h) => /^(pin)?\d+$/.test(h)
|
|
15924
|
-
);
|
|
15925
|
-
if (matchedHint) {
|
|
15926
|
-
if (/^pin\d+$/.test(matchedHint)) {
|
|
15927
|
-
pinLabel = matchedHint.replace(/^pin/, "");
|
|
15928
|
-
} else {
|
|
15929
|
-
pinLabel = matchedHint;
|
|
15930
|
-
}
|
|
15931
|
-
}
|
|
15932
|
-
}
|
|
15933
|
-
pinLabelToPortId[pinLabel] = port.pcb_port_id;
|
|
15934
|
-
}
|
|
15935
|
-
const traces = db.pcb_trace.list({
|
|
15936
|
-
pcb_component_id: this.pcb_component_id
|
|
15937
|
-
});
|
|
15938
|
-
const updatePortId = (portId) => {
|
|
15939
|
-
if (portId && typeof portId === "string" && portId.startsWith("{PIN")) {
|
|
15940
|
-
const pin = portId.replace("{PIN", "").replace("}", "");
|
|
15941
|
-
return pinLabelToPortId[pin] || portId;
|
|
15942
|
-
}
|
|
15943
|
-
return portId;
|
|
15944
|
-
};
|
|
15945
|
-
for (const trace of traces) {
|
|
15946
|
-
if (!trace.route) continue;
|
|
15947
|
-
for (const segment of trace.route) {
|
|
15948
|
-
if (segment.route_type !== "wire") continue;
|
|
15949
|
-
segment.start_pcb_port_id = updatePortId(segment.start_pcb_port_id);
|
|
15950
|
-
segment.end_pcb_port_id = updatePortId(segment.end_pcb_port_id);
|
|
15951
|
-
}
|
|
15952
|
-
}
|
|
15953
|
-
}
|
|
15954
|
-
};
|
|
15955
|
-
|
|
15956
|
-
// lib/components/normal-components/Led.ts
|
|
15957
|
-
import { ledProps } from "@tscircuit/props";
|
|
15958
|
-
var Led = class extends NormalComponent3 {
|
|
15959
|
-
get config() {
|
|
15960
|
-
const symbolMap = {
|
|
15961
|
-
laser: "laser_diode"
|
|
15962
|
-
};
|
|
15963
|
-
const variantSymbol = this.props.laser ? "laser" : null;
|
|
15964
|
-
return {
|
|
15965
|
-
schematicSymbolName: variantSymbol ? symbolMap[variantSymbol] : this.props.symbolName ?? "led",
|
|
15966
|
-
componentName: "Led",
|
|
15967
|
-
zodProps: ledProps,
|
|
15968
|
-
sourceFtype: "simple_led"
|
|
15969
|
-
};
|
|
15970
|
-
}
|
|
15971
|
-
initPorts() {
|
|
15972
|
-
super.initPorts({
|
|
15973
|
-
additionalAliases: {
|
|
15974
|
-
pin1: ["anode", "pos", "left"],
|
|
15975
|
-
pin2: ["cathode", "neg", "right"]
|
|
15976
|
-
}
|
|
15977
|
-
});
|
|
15978
|
-
}
|
|
15979
|
-
_getSchematicSymbolDisplayValue() {
|
|
15980
|
-
return this._parsedProps.schDisplayValue || this._parsedProps.color || void 0;
|
|
15981
|
-
}
|
|
15982
|
-
getFootprinterString() {
|
|
15983
|
-
const baseFootprint = super.getFootprinterString();
|
|
15984
|
-
if (baseFootprint && this.props.color) {
|
|
15985
|
-
return `${baseFootprint}_color(${this.props.color})`;
|
|
15986
|
-
}
|
|
15987
|
-
return baseFootprint;
|
|
15988
|
-
}
|
|
15989
|
-
doInitialSourceRender() {
|
|
15990
|
-
const { db } = this.root;
|
|
15991
|
-
const { _parsedProps: props } = this;
|
|
15992
|
-
const source_component = db.source_component.insert({
|
|
15993
|
-
ftype: "simple_led",
|
|
15994
|
-
name: this.name,
|
|
15995
|
-
wave_length: props.wavelength,
|
|
15996
|
-
color: props.color,
|
|
15997
|
-
symbol_display_value: this._getSchematicSymbolDisplayValue(),
|
|
15998
|
-
// @ts-ignore
|
|
15999
|
-
manufacturer_part_number: props.manufacturerPartNumber ?? props.mfn,
|
|
16000
|
-
supplier_part_numbers: props.supplierPartNumbers,
|
|
16001
|
-
are_pins_interchangeable: false
|
|
16002
|
-
});
|
|
16003
|
-
this.source_component_id = source_component.source_component_id;
|
|
16004
|
-
}
|
|
16005
|
-
pos = this.portMap.pin1;
|
|
16006
|
-
anode = this.portMap.pin1;
|
|
16007
|
-
neg = this.portMap.pin2;
|
|
16008
|
-
cathode = this.portMap.pin2;
|
|
16358
|
+
// lib/components/normal-components/Interconnect.ts
|
|
16359
|
+
import { interconnectProps } from "@tscircuit/props";
|
|
16360
|
+
var INTERCONNECT_STANDARD_FOOTPRINTS = {
|
|
16361
|
+
"0603": "0603",
|
|
16362
|
+
"0805": "0805",
|
|
16363
|
+
"1206": "1206"
|
|
16009
16364
|
};
|
|
16010
|
-
|
|
16011
|
-
// lib/components/normal-components/PowerSource.ts
|
|
16012
|
-
import { powerSourceProps } from "@tscircuit/props";
|
|
16013
|
-
var PowerSource = class extends NormalComponent3 {
|
|
16014
|
-
// @ts-ignore
|
|
16365
|
+
var Interconnect = class extends NormalComponent3 {
|
|
16015
16366
|
get config() {
|
|
16016
16367
|
return {
|
|
16017
|
-
|
|
16018
|
-
|
|
16019
|
-
|
|
16020
|
-
|
|
16021
|
-
sourceFtype: "simple_power_source"
|
|
16368
|
+
componentName: "Interconnect",
|
|
16369
|
+
zodProps: interconnectProps,
|
|
16370
|
+
shouldRenderAsSchematicBox: true,
|
|
16371
|
+
sourceFtype: "interconnect"
|
|
16022
16372
|
};
|
|
16023
16373
|
}
|
|
16024
|
-
|
|
16025
|
-
this.
|
|
16026
|
-
|
|
16027
|
-
|
|
16028
|
-
this.add(
|
|
16029
|
-
new Port({ name: "pin2", pinNumber: 2, aliases: ["negative", "neg"] })
|
|
16030
|
-
);
|
|
16374
|
+
_getImpliedFootprintString() {
|
|
16375
|
+
const { standard } = this._parsedProps;
|
|
16376
|
+
if (!standard) return null;
|
|
16377
|
+
return INTERCONNECT_STANDARD_FOOTPRINTS[standard] ?? null;
|
|
16031
16378
|
}
|
|
16032
16379
|
doInitialSourceRender() {
|
|
16033
16380
|
const { db } = this.root;
|
|
16034
|
-
const { _parsedProps: props } = this;
|
|
16035
16381
|
const source_component = db.source_component.insert({
|
|
16036
|
-
ftype: "
|
|
16382
|
+
ftype: "interconnect",
|
|
16037
16383
|
name: this.name,
|
|
16038
|
-
|
|
16039
|
-
supplier_part_numbers: props.supplierPartNumbers,
|
|
16040
|
-
are_pins_interchangeable: false
|
|
16384
|
+
are_pins_interchangeable: true
|
|
16041
16385
|
});
|
|
16042
16386
|
this.source_component_id = source_component.source_component_id;
|
|
16043
16387
|
}
|
|
16044
|
-
pos = this.portMap.pin1;
|
|
16045
|
-
positive = this.portMap.pin1;
|
|
16046
|
-
neg = this.portMap.pin2;
|
|
16047
|
-
negative = this.portMap.pin2;
|
|
16048
16388
|
};
|
|
16049
16389
|
|
|
16050
|
-
// lib/components/normal-components/
|
|
16051
|
-
import {
|
|
16052
|
-
var
|
|
16053
|
-
|
|
16054
|
-
|
|
16055
|
-
|
|
16056
|
-
|
|
16057
|
-
schematicSymbolName: isSquare ? "square_wave" : "ac_voltmeter",
|
|
16058
|
-
zodProps: voltageSourceProps,
|
|
16059
|
-
sourceFtype: "simple_voltage_source"
|
|
16060
|
-
};
|
|
16061
|
-
}
|
|
16062
|
-
runRenderPhaseForChildren(phase) {
|
|
16063
|
-
if (phase.startsWith("Pcb")) {
|
|
16064
|
-
return;
|
|
16065
|
-
}
|
|
16066
|
-
for (const child of this.children) {
|
|
16067
|
-
child.runRenderPhaseForChildren(phase);
|
|
16068
|
-
child.runRenderPhase(phase);
|
|
16069
|
-
}
|
|
16070
|
-
}
|
|
16071
|
-
doInitialPcbComponentRender() {
|
|
16072
|
-
}
|
|
16073
|
-
initPorts() {
|
|
16074
|
-
super.initPorts({
|
|
16075
|
-
additionalAliases: {
|
|
16076
|
-
pin1: ["terminal1"],
|
|
16077
|
-
pin2: ["terminal2"]
|
|
16078
|
-
}
|
|
16079
|
-
});
|
|
16080
|
-
}
|
|
16081
|
-
doInitialSourceRender() {
|
|
16082
|
-
const { db } = this.root;
|
|
16083
|
-
const { _parsedProps: props } = this;
|
|
16084
|
-
const source_component = db.source_component.insert({
|
|
16085
|
-
ftype: "simple_voltage_source",
|
|
16086
|
-
name: this.name,
|
|
16087
|
-
voltage: props.voltage,
|
|
16088
|
-
frequency: props.frequency,
|
|
16089
|
-
peak_to_peak_voltage: props.peakToPeakVoltage,
|
|
16090
|
-
wave_shape: props.waveShape,
|
|
16091
|
-
phase: props.phase,
|
|
16092
|
-
duty_cycle: props.dutyCycle,
|
|
16093
|
-
supplier_part_numbers: props.supplierPartNumbers,
|
|
16094
|
-
are_pins_interchangeable: true
|
|
16390
|
+
// lib/components/normal-components/SolderJumper.ts
|
|
16391
|
+
import { solderjumperProps } from "@tscircuit/props";
|
|
16392
|
+
var SolderJumper = class extends NormalComponent3 {
|
|
16393
|
+
schematicDimensions = null;
|
|
16394
|
+
_getPinNumberFromBridgedPinName(pinName) {
|
|
16395
|
+
const port = this.selectOne(`port.${pinName}`, {
|
|
16396
|
+
type: "port"
|
|
16095
16397
|
});
|
|
16096
|
-
|
|
16398
|
+
return port?._parsedProps.pinNumber ?? null;
|
|
16097
16399
|
}
|
|
16098
|
-
|
|
16099
|
-
|
|
16100
|
-
|
|
16101
|
-
|
|
16102
|
-
|
|
16103
|
-
|
|
16104
|
-
type: "simulation_voltage_source",
|
|
16105
|
-
is_dc_source: false,
|
|
16106
|
-
terminal1_source_port_id: terminal1Port.source_port_id,
|
|
16107
|
-
terminal2_source_port_id: terminal2Port.source_port_id,
|
|
16108
|
-
voltage: props.voltage,
|
|
16109
|
-
frequency: props.frequency,
|
|
16110
|
-
peak_to_peak_voltage: props.peakToPeakVoltage,
|
|
16111
|
-
wave_shape: props.waveShape,
|
|
16112
|
-
phase: props.phase,
|
|
16113
|
-
duty_cycle: props.dutyCycle
|
|
16114
|
-
});
|
|
16400
|
+
get defaultInternallyConnectedPinNames() {
|
|
16401
|
+
if (this._parsedProps.bridged) {
|
|
16402
|
+
const pins = this.children.filter((c) => c.componentName === "Port").map((p) => p.name);
|
|
16403
|
+
return pins.length > 0 ? [pins] : [];
|
|
16404
|
+
}
|
|
16405
|
+
return this._parsedProps.bridgedPins ?? [];
|
|
16115
16406
|
}
|
|
16116
|
-
terminal1 = this.portMap.terminal1;
|
|
16117
|
-
terminal2 = this.portMap.terminal2;
|
|
16118
|
-
};
|
|
16119
|
-
|
|
16120
|
-
// lib/components/normal-components/Resistor.ts
|
|
16121
|
-
import { resistorProps } from "@tscircuit/props";
|
|
16122
|
-
import { formatSiUnit as formatSiUnit3 } from "format-si-unit";
|
|
16123
|
-
var Resistor = class extends NormalComponent3 {
|
|
16124
|
-
_adjustSilkscreenTextAutomatically = true;
|
|
16125
16407
|
get config() {
|
|
16126
|
-
|
|
16127
|
-
|
|
16128
|
-
|
|
16129
|
-
|
|
16130
|
-
|
|
16131
|
-
|
|
16132
|
-
|
|
16133
|
-
|
|
16134
|
-
|
|
16135
|
-
|
|
16136
|
-
|
|
16137
|
-
|
|
16408
|
+
const props = this._parsedProps ?? this.props;
|
|
16409
|
+
let resolvedPinCount = props.pinCount;
|
|
16410
|
+
if (props.pinCount == null && !props.footprint) {
|
|
16411
|
+
resolvedPinCount = 2;
|
|
16412
|
+
}
|
|
16413
|
+
if (props.pinCount == null) {
|
|
16414
|
+
const nums = (props.bridgedPins ?? []).flat().map((p_str) => this._getPinNumberFromBridgedPinName(p_str)).filter((n) => n !== null);
|
|
16415
|
+
const maxPinFromBridged = nums.length > 0 ? Math.max(...nums) : 0;
|
|
16416
|
+
const pinCountFromLabels = props.pinLabels ? Object.keys(props.pinLabels).length : 0;
|
|
16417
|
+
const finalPinCount = Math.max(maxPinFromBridged, pinCountFromLabels);
|
|
16418
|
+
if (finalPinCount === 2 || finalPinCount === 3) {
|
|
16419
|
+
resolvedPinCount = finalPinCount;
|
|
16420
|
+
}
|
|
16421
|
+
if (resolvedPinCount == null && props.footprint && [2, 3].includes(this.getPortsFromFootprint().length)) {
|
|
16422
|
+
resolvedPinCount = this.getPortsFromFootprint().length;
|
|
16138
16423
|
}
|
|
16139
|
-
});
|
|
16140
|
-
}
|
|
16141
|
-
_getSchematicSymbolDisplayValue() {
|
|
16142
|
-
return `${formatSiUnit3(this._parsedProps.resistance)}\u03A9`;
|
|
16143
|
-
}
|
|
16144
|
-
doInitialCreateNetsFromProps() {
|
|
16145
|
-
this._createNetsFromProps([
|
|
16146
|
-
this.props.pullupFor,
|
|
16147
|
-
this.props.pullupTo,
|
|
16148
|
-
this.props.pulldownFor,
|
|
16149
|
-
this.props.pulldownTo,
|
|
16150
|
-
...this._getNetsFromConnectionsProp()
|
|
16151
|
-
]);
|
|
16152
|
-
}
|
|
16153
|
-
doInitialCreateTracesFromProps() {
|
|
16154
|
-
if (this.props.pullupFor && this.props.pullupTo) {
|
|
16155
|
-
this.add(
|
|
16156
|
-
new Trace3({
|
|
16157
|
-
from: `${this.getSubcircuitSelector()} > port.1`,
|
|
16158
|
-
to: this.props.pullupFor
|
|
16159
|
-
})
|
|
16160
|
-
);
|
|
16161
|
-
this.add(
|
|
16162
|
-
new Trace3({
|
|
16163
|
-
from: `${this.getSubcircuitSelector()} > port.2`,
|
|
16164
|
-
to: this.props.pullupTo
|
|
16165
|
-
})
|
|
16166
|
-
);
|
|
16167
16424
|
}
|
|
16168
|
-
|
|
16169
|
-
|
|
16170
|
-
|
|
16171
|
-
|
|
16172
|
-
|
|
16173
|
-
|
|
16174
|
-
|
|
16175
|
-
|
|
16176
|
-
|
|
16177
|
-
|
|
16178
|
-
|
|
16179
|
-
|
|
16425
|
+
let symbolName = "";
|
|
16426
|
+
if (resolvedPinCount) {
|
|
16427
|
+
symbolName += `solderjumper${resolvedPinCount}`;
|
|
16428
|
+
} else {
|
|
16429
|
+
symbolName = "solderjumper";
|
|
16430
|
+
}
|
|
16431
|
+
let bridgedPinNumbers = [];
|
|
16432
|
+
if (Array.isArray(props.bridgedPins) && props.bridgedPins.length > 0) {
|
|
16433
|
+
bridgedPinNumbers = Array.from(
|
|
16434
|
+
new Set(
|
|
16435
|
+
props.bridgedPins.flat().map((pinName) => this._getPinNumberFromBridgedPinName(pinName)).filter((n) => n !== null)
|
|
16436
|
+
)
|
|
16437
|
+
).sort((a, b) => a - b);
|
|
16438
|
+
} else if (props.bridged && resolvedPinCount) {
|
|
16439
|
+
bridgedPinNumbers = Array.from(
|
|
16440
|
+
{ length: resolvedPinCount },
|
|
16441
|
+
(_, i) => i + 1
|
|
16180
16442
|
);
|
|
16181
16443
|
}
|
|
16182
|
-
|
|
16444
|
+
if (bridgedPinNumbers.length > 0) {
|
|
16445
|
+
symbolName += `_bridged${bridgedPinNumbers.join("")}`;
|
|
16446
|
+
}
|
|
16447
|
+
return {
|
|
16448
|
+
schematicSymbolName: props.symbolName ?? symbolName,
|
|
16449
|
+
componentName: "SolderJumper",
|
|
16450
|
+
zodProps: solderjumperProps,
|
|
16451
|
+
shouldRenderAsSchematicBox: true
|
|
16452
|
+
};
|
|
16453
|
+
}
|
|
16454
|
+
_getSchematicPortArrangement() {
|
|
16455
|
+
const arrangement = super._getSchematicPortArrangement();
|
|
16456
|
+
if (arrangement && Object.keys(arrangement).length > 0) return arrangement;
|
|
16457
|
+
let pinCount = this._parsedProps.pinCount ?? (Array.isArray(this._parsedProps.pinLabels) ? this._parsedProps.pinLabels.length : this._parsedProps.pinLabels ? Object.keys(this._parsedProps.pinLabels).length : this.getPortsFromFootprint().length);
|
|
16458
|
+
if (pinCount == null && !this._parsedProps.footprint) {
|
|
16459
|
+
pinCount = 2;
|
|
16460
|
+
}
|
|
16461
|
+
const direction = this._parsedProps.schDirection ?? "right";
|
|
16462
|
+
return {
|
|
16463
|
+
leftSize: direction === "left" ? pinCount : 0,
|
|
16464
|
+
rightSize: direction === "right" ? pinCount : 0
|
|
16465
|
+
};
|
|
16183
16466
|
}
|
|
16184
16467
|
doInitialSourceRender() {
|
|
16185
16468
|
const { db } = this.root;
|
|
16186
16469
|
const { _parsedProps: props } = this;
|
|
16470
|
+
const { pcbX, pcbY } = this.getResolvedPcbPositionProp();
|
|
16187
16471
|
const source_component = db.source_component.insert({
|
|
16188
|
-
ftype: "
|
|
16472
|
+
ftype: "simple_chip",
|
|
16473
|
+
// TODO unknown or jumper
|
|
16189
16474
|
name: this.name,
|
|
16190
|
-
|
|
16191
|
-
manufacturer_part_number: props.manufacturerPartNumber ?? props.mfn,
|
|
16475
|
+
manufacturer_part_number: props.manufacturerPartNumber,
|
|
16192
16476
|
supplier_part_numbers: props.supplierPartNumbers,
|
|
16193
|
-
resistance: props.resistance,
|
|
16194
|
-
display_resistance: this._getSchematicSymbolDisplayValue(),
|
|
16195
16477
|
are_pins_interchangeable: true
|
|
16196
16478
|
});
|
|
16197
16479
|
this.source_component_id = source_component.source_component_id;
|
|
16198
16480
|
}
|
|
16199
|
-
|
|
16200
|
-
|
|
16201
|
-
|
|
16202
|
-
|
|
16203
|
-
|
|
16204
|
-
|
|
16205
|
-
|
|
16206
|
-
|
|
16207
|
-
|
|
16208
|
-
|
|
16209
|
-
|
|
16210
|
-
|
|
16211
|
-
|
|
16212
|
-
|
|
16213
|
-
|
|
16214
|
-
|
|
16215
|
-
|
|
16216
|
-
};
|
|
16481
|
+
doInitialPcbComponentRender() {
|
|
16482
|
+
if (this.root?.pcbDisabled) return;
|
|
16483
|
+
const { db } = this.root;
|
|
16484
|
+
const { _parsedProps: props } = this;
|
|
16485
|
+
const { pcbX, pcbY } = this.getResolvedPcbPositionProp();
|
|
16486
|
+
const pcb_component = db.pcb_component.insert({
|
|
16487
|
+
center: { x: pcbX, y: pcbY },
|
|
16488
|
+
width: 2,
|
|
16489
|
+
// Default width, adjust as needed
|
|
16490
|
+
height: 3,
|
|
16491
|
+
// Default height, adjust as needed
|
|
16492
|
+
layer: props.layer ?? "top",
|
|
16493
|
+
rotation: props.pcbRotation ?? 0,
|
|
16494
|
+
source_component_id: this.source_component_id,
|
|
16495
|
+
subcircuit_id: this.getSubcircuit().subcircuit_id ?? void 0,
|
|
16496
|
+
do_not_place: props.doNotPlace ?? false,
|
|
16497
|
+
obstructs_within_bounds: props.obstructsWithinBounds ?? true
|
|
16498
|
+
});
|
|
16499
|
+
this.pcb_component_id = pcb_component.pcb_component_id;
|
|
16217
16500
|
}
|
|
16218
|
-
|
|
16219
|
-
|
|
16220
|
-
|
|
16221
|
-
|
|
16222
|
-
|
|
16223
|
-
|
|
16501
|
+
doInitialPcbTraceRender() {
|
|
16502
|
+
const { db } = this.root;
|
|
16503
|
+
const pcb_ports = db.pcb_port.list({
|
|
16504
|
+
pcb_component_id: this.pcb_component_id
|
|
16505
|
+
});
|
|
16506
|
+
const pinLabelToPortId = {};
|
|
16507
|
+
for (let i = 0; i < pcb_ports.length; i++) {
|
|
16508
|
+
const port = pcb_ports[i];
|
|
16509
|
+
const sourcePort = db.source_port.get(port.source_port_id);
|
|
16510
|
+
let pinLabel = "";
|
|
16511
|
+
if (typeof sourcePort?.pin_number === "number") {
|
|
16512
|
+
pinLabel = sourcePort.pin_number.toString();
|
|
16513
|
+
} else if (Array.isArray(sourcePort?.port_hints)) {
|
|
16514
|
+
let matchedHint = sourcePort.port_hints.find(
|
|
16515
|
+
(h) => /^(pin)?\d+$/.test(h)
|
|
16224
16516
|
);
|
|
16517
|
+
if (matchedHint) {
|
|
16518
|
+
if (/^pin\d+$/.test(matchedHint)) {
|
|
16519
|
+
pinLabel = matchedHint.replace(/^pin/, "");
|
|
16520
|
+
} else {
|
|
16521
|
+
pinLabel = matchedHint;
|
|
16522
|
+
}
|
|
16523
|
+
}
|
|
16225
16524
|
}
|
|
16525
|
+
pinLabelToPortId[pinLabel] = port.pcb_port_id;
|
|
16226
16526
|
}
|
|
16227
|
-
|
|
16228
|
-
|
|
16229
|
-
}
|
|
16230
|
-
|
|
16231
|
-
|
|
16232
|
-
|
|
16233
|
-
|
|
16234
|
-
function addComponentFromSelector(selector) {
|
|
16235
|
-
const maybeEdge = selector.split(" ").pop();
|
|
16236
|
-
const edge = edgeSpecifiers.includes(maybeEdge) ? maybeEdge : void 0;
|
|
16237
|
-
const componentSelector = edge ? selector.replace(` ${edge}`, "") : selector;
|
|
16238
|
-
const component = container.selectOne(componentSelector, {
|
|
16239
|
-
pcbPrimitive: true
|
|
16240
|
-
});
|
|
16241
|
-
if (component) {
|
|
16242
|
-
componentsWithSelectors.push({
|
|
16243
|
-
selector,
|
|
16244
|
-
component,
|
|
16245
|
-
componentSelector,
|
|
16246
|
-
edge
|
|
16247
|
-
});
|
|
16248
|
-
}
|
|
16249
|
-
}
|
|
16250
|
-
for (const key of ["left", "right", "top", "bottom"]) {
|
|
16251
|
-
if (key in this._parsedProps) {
|
|
16252
|
-
addComponentFromSelector(this._parsedProps[key]);
|
|
16527
|
+
const traces = db.pcb_trace.list({
|
|
16528
|
+
pcb_component_id: this.pcb_component_id
|
|
16529
|
+
});
|
|
16530
|
+
const updatePortId = (portId) => {
|
|
16531
|
+
if (portId && typeof portId === "string" && portId.startsWith("{PIN")) {
|
|
16532
|
+
const pin = portId.replace("{PIN", "").replace("}", "");
|
|
16533
|
+
return pinLabelToPortId[pin] || portId;
|
|
16253
16534
|
}
|
|
16254
|
-
|
|
16255
|
-
|
|
16256
|
-
|
|
16257
|
-
|
|
16535
|
+
return portId;
|
|
16536
|
+
};
|
|
16537
|
+
for (const trace of traces) {
|
|
16538
|
+
if (!trace.route) continue;
|
|
16539
|
+
for (const segment of trace.route) {
|
|
16540
|
+
if (segment.route_type !== "wire") continue;
|
|
16541
|
+
segment.start_pcb_port_id = updatePortId(segment.start_pcb_port_id);
|
|
16542
|
+
segment.end_pcb_port_id = updatePortId(segment.end_pcb_port_id);
|
|
16258
16543
|
}
|
|
16259
16544
|
}
|
|
16260
|
-
return { componentsWithSelectors };
|
|
16261
16545
|
}
|
|
16262
16546
|
};
|
|
16263
16547
|
|
|
16264
|
-
// lib/components/
|
|
16265
|
-
import {
|
|
16266
|
-
|
|
16267
|
-
var FabricationNoteRect = class extends PrimitiveComponent2 {
|
|
16268
|
-
fabrication_note_rect_id = null;
|
|
16548
|
+
// lib/components/normal-components/Led.ts
|
|
16549
|
+
import { ledProps } from "@tscircuit/props";
|
|
16550
|
+
var Led = class extends NormalComponent3 {
|
|
16269
16551
|
get config() {
|
|
16270
|
-
|
|
16271
|
-
|
|
16272
|
-
zodProps: fabricationNoteRectProps
|
|
16552
|
+
const symbolMap = {
|
|
16553
|
+
laser: "laser_diode"
|
|
16273
16554
|
};
|
|
16274
|
-
|
|
16275
|
-
doInitialPcbPrimitiveRender() {
|
|
16276
|
-
if (this.root?.pcbDisabled) return;
|
|
16277
|
-
const { db } = this.root;
|
|
16278
|
-
const { _parsedProps: props } = this;
|
|
16279
|
-
const { pcbX, pcbY } = this.getResolvedPcbPositionProp();
|
|
16280
|
-
const { maybeFlipLayer } = this._getPcbPrimitiveFlippedHelpers();
|
|
16281
|
-
const layer = maybeFlipLayer(props.layer ?? "top");
|
|
16282
|
-
if (layer !== "top" && layer !== "bottom") {
|
|
16283
|
-
throw new Error(
|
|
16284
|
-
`Invalid layer "${layer}" for FabricationNoteRect. Must be "top" or "bottom".`
|
|
16285
|
-
);
|
|
16286
|
-
}
|
|
16287
|
-
const pcb_component_id = this.parent?.pcb_component_id ?? this.getPrimitiveContainer()?.pcb_component_id;
|
|
16288
|
-
const subcircuit = this.getSubcircuit();
|
|
16289
|
-
const hasStroke = props.hasStroke ?? (props.strokeWidth !== void 0 && props.strokeWidth !== null);
|
|
16290
|
-
const fabrication_note_rect = db.pcb_fabrication_note_rect.insert({
|
|
16291
|
-
pcb_component_id,
|
|
16292
|
-
layer,
|
|
16293
|
-
color: props.color,
|
|
16294
|
-
center: {
|
|
16295
|
-
x: pcbX,
|
|
16296
|
-
y: pcbY
|
|
16297
|
-
},
|
|
16298
|
-
width: props.width,
|
|
16299
|
-
height: props.height,
|
|
16300
|
-
stroke_width: props.strokeWidth ?? 1,
|
|
16301
|
-
is_filled: props.isFilled ?? false,
|
|
16302
|
-
has_stroke: hasStroke,
|
|
16303
|
-
is_stroke_dashed: props.isStrokeDashed ?? false,
|
|
16304
|
-
subcircuit_id: subcircuit?.subcircuit_id ?? void 0,
|
|
16305
|
-
pcb_group_id: this.getGroup()?.pcb_group_id ?? void 0,
|
|
16306
|
-
corner_radius: props.cornerRadius ?? void 0
|
|
16307
|
-
});
|
|
16308
|
-
this.fabrication_note_rect_id = fabrication_note_rect.pcb_fabrication_note_rect_id;
|
|
16309
|
-
}
|
|
16310
|
-
getPcbSize() {
|
|
16311
|
-
const { _parsedProps: props } = this;
|
|
16312
|
-
return { width: props.width, height: props.height };
|
|
16313
|
-
}
|
|
16314
|
-
};
|
|
16315
|
-
|
|
16316
|
-
// lib/components/primitive-components/FabricationNotePath.ts
|
|
16317
|
-
import { fabricationNotePathProps } from "@tscircuit/props";
|
|
16318
|
-
import { applyToPoint as applyToPoint10 } from "transformation-matrix";
|
|
16319
|
-
var FabricationNotePath = class extends PrimitiveComponent2 {
|
|
16320
|
-
fabrication_note_path_id = null;
|
|
16321
|
-
get config() {
|
|
16555
|
+
const variantSymbol = this.props.laser ? "laser" : null;
|
|
16322
16556
|
return {
|
|
16323
|
-
|
|
16324
|
-
|
|
16557
|
+
schematicSymbolName: variantSymbol ? symbolMap[variantSymbol] : this.props.symbolName ?? "led",
|
|
16558
|
+
componentName: "Led",
|
|
16559
|
+
zodProps: ledProps,
|
|
16560
|
+
sourceFtype: "simple_led"
|
|
16325
16561
|
};
|
|
16326
16562
|
}
|
|
16327
|
-
|
|
16328
|
-
|
|
16329
|
-
|
|
16330
|
-
|
|
16331
|
-
|
|
16332
|
-
|
|
16333
|
-
if (layer !== "top" && layer !== "bottom") {
|
|
16334
|
-
throw new Error(
|
|
16335
|
-
`Invalid layer "${layer}" for SilkscreenPath. Must be "top" or "bottom".`
|
|
16336
|
-
);
|
|
16337
|
-
}
|
|
16338
|
-
const transform = this._computePcbGlobalTransformBeforeLayout();
|
|
16339
|
-
const pcb_component_id = this.parent?.pcb_component_id ?? this.getPrimitiveContainer()?.pcb_component_id;
|
|
16340
|
-
const fabrication_note_path = db.pcb_fabrication_note_path.insert({
|
|
16341
|
-
pcb_component_id,
|
|
16342
|
-
layer,
|
|
16343
|
-
color: props.color,
|
|
16344
|
-
route: props.route.map((p) => {
|
|
16345
|
-
const transformedPosition = applyToPoint10(transform, {
|
|
16346
|
-
x: p.x,
|
|
16347
|
-
y: p.y
|
|
16348
|
-
});
|
|
16349
|
-
return {
|
|
16350
|
-
...p,
|
|
16351
|
-
x: transformedPosition.x,
|
|
16352
|
-
y: transformedPosition.y
|
|
16353
|
-
};
|
|
16354
|
-
}),
|
|
16355
|
-
stroke_width: props.strokeWidth ?? 0.1,
|
|
16356
|
-
subcircuit_id: subcircuit?.subcircuit_id ?? void 0
|
|
16563
|
+
initPorts() {
|
|
16564
|
+
super.initPorts({
|
|
16565
|
+
additionalAliases: {
|
|
16566
|
+
pin1: ["anode", "pos", "left"],
|
|
16567
|
+
pin2: ["cathode", "neg", "right"]
|
|
16568
|
+
}
|
|
16357
16569
|
});
|
|
16358
|
-
this.fabrication_note_path_id = fabrication_note_path.pcb_fabrication_note_path_id;
|
|
16359
16570
|
}
|
|
16360
|
-
|
|
16361
|
-
|
|
16362
|
-
// lib/components/primitive-components/FabricationNoteText.ts
|
|
16363
|
-
import { fabricationNoteTextProps } from "@tscircuit/props";
|
|
16364
|
-
var FabricationNoteText = class extends PrimitiveComponent2 {
|
|
16365
|
-
get config() {
|
|
16366
|
-
return {
|
|
16367
|
-
componentName: "FabricationNoteText",
|
|
16368
|
-
zodProps: fabricationNoteTextProps
|
|
16369
|
-
};
|
|
16571
|
+
_getSchematicSymbolDisplayValue() {
|
|
16572
|
+
return this._parsedProps.schDisplayValue || this._parsedProps.color || void 0;
|
|
16370
16573
|
}
|
|
16371
|
-
|
|
16372
|
-
|
|
16574
|
+
getFootprinterString() {
|
|
16575
|
+
const baseFootprint = super.getFootprinterString();
|
|
16576
|
+
if (baseFootprint && this.props.color) {
|
|
16577
|
+
return `${baseFootprint}_color(${this.props.color})`;
|
|
16578
|
+
}
|
|
16579
|
+
return baseFootprint;
|
|
16580
|
+
}
|
|
16581
|
+
doInitialSourceRender() {
|
|
16373
16582
|
const { db } = this.root;
|
|
16374
16583
|
const { _parsedProps: props } = this;
|
|
16375
|
-
const
|
|
16376
|
-
|
|
16377
|
-
|
|
16378
|
-
|
|
16379
|
-
anchor_alignment: props.anchorAlignment,
|
|
16380
|
-
anchor_position: {
|
|
16381
|
-
x: pcbX,
|
|
16382
|
-
y: pcbY
|
|
16383
|
-
},
|
|
16384
|
-
font: props.font ?? "tscircuit2024",
|
|
16385
|
-
font_size: props.fontSize ?? 1,
|
|
16386
|
-
layer: "top",
|
|
16584
|
+
const source_component = db.source_component.insert({
|
|
16585
|
+
ftype: "simple_led",
|
|
16586
|
+
name: this.name,
|
|
16587
|
+
wave_length: props.wavelength,
|
|
16387
16588
|
color: props.color,
|
|
16388
|
-
|
|
16389
|
-
|
|
16390
|
-
|
|
16391
|
-
|
|
16589
|
+
symbol_display_value: this._getSchematicSymbolDisplayValue(),
|
|
16590
|
+
// @ts-ignore
|
|
16591
|
+
manufacturer_part_number: props.manufacturerPartNumber ?? props.mfn,
|
|
16592
|
+
supplier_part_numbers: props.supplierPartNumbers,
|
|
16593
|
+
are_pins_interchangeable: false
|
|
16392
16594
|
});
|
|
16595
|
+
this.source_component_id = source_component.source_component_id;
|
|
16393
16596
|
}
|
|
16597
|
+
pos = this.portMap.pin1;
|
|
16598
|
+
anode = this.portMap.pin1;
|
|
16599
|
+
neg = this.portMap.pin2;
|
|
16600
|
+
cathode = this.portMap.pin2;
|
|
16394
16601
|
};
|
|
16395
16602
|
|
|
16396
|
-
// lib/components/
|
|
16397
|
-
import {
|
|
16398
|
-
|
|
16399
|
-
|
|
16400
|
-
fabrication_note_dimension_id = null;
|
|
16401
|
-
isPcbPrimitive = true;
|
|
16603
|
+
// lib/components/normal-components/PowerSource.ts
|
|
16604
|
+
import { powerSourceProps } from "@tscircuit/props";
|
|
16605
|
+
var PowerSource = class extends NormalComponent3 {
|
|
16606
|
+
// @ts-ignore
|
|
16402
16607
|
get config() {
|
|
16403
16608
|
return {
|
|
16404
|
-
|
|
16405
|
-
|
|
16609
|
+
// TBD in schematic_symbol and replace then
|
|
16610
|
+
schematicSymbolName: this.props.symbolName ?? "power_factor_meter_horz",
|
|
16611
|
+
componentName: "PowerSource",
|
|
16612
|
+
zodProps: powerSourceProps,
|
|
16613
|
+
sourceFtype: "simple_power_source"
|
|
16406
16614
|
};
|
|
16407
16615
|
}
|
|
16408
|
-
|
|
16409
|
-
|
|
16410
|
-
|
|
16411
|
-
|
|
16412
|
-
|
|
16413
|
-
|
|
16414
|
-
|
|
16415
|
-
`FabricationNoteDimension could not find selector "${input}"`
|
|
16416
|
-
);
|
|
16417
|
-
return applyToPoint11(transform, { x: 0, y: 0 });
|
|
16418
|
-
}
|
|
16419
|
-
return target._getGlobalPcbPositionBeforeLayout();
|
|
16420
|
-
}
|
|
16421
|
-
const numericX = typeof input.x === "string" ? parseFloat(input.x) : input.x;
|
|
16422
|
-
const numericY = typeof input.y === "string" ? parseFloat(input.y) : input.y;
|
|
16423
|
-
return applyToPoint11(transform, { x: numericX, y: numericY });
|
|
16616
|
+
initPorts() {
|
|
16617
|
+
this.add(
|
|
16618
|
+
new Port({ name: "pin1", pinNumber: 1, aliases: ["positive", "pos"] })
|
|
16619
|
+
);
|
|
16620
|
+
this.add(
|
|
16621
|
+
new Port({ name: "pin2", pinNumber: 2, aliases: ["negative", "neg"] })
|
|
16622
|
+
);
|
|
16424
16623
|
}
|
|
16425
|
-
|
|
16426
|
-
if (this.root?.pcbDisabled) return;
|
|
16624
|
+
doInitialSourceRender() {
|
|
16427
16625
|
const { db } = this.root;
|
|
16428
16626
|
const { _parsedProps: props } = this;
|
|
16429
|
-
const
|
|
16430
|
-
|
|
16431
|
-
|
|
16432
|
-
|
|
16433
|
-
|
|
16434
|
-
|
|
16435
|
-
|
|
16436
|
-
|
|
16437
|
-
throw new Error(
|
|
16438
|
-
`Invalid layer "${layer}" for FabricationNoteDimension. Must be "top" or "bottom".`
|
|
16439
|
-
);
|
|
16440
|
-
}
|
|
16441
|
-
const pcb_component_id = this.parent?.pcb_component_id ?? this.getPrimitiveContainer()?.pcb_component_id;
|
|
16442
|
-
const text = props.text ?? this._formatDistanceText({ from, to, units: props.units ?? "mm" });
|
|
16443
|
-
const fabrication_note_dimension = db.pcb_fabrication_note_dimension.insert(
|
|
16444
|
-
{
|
|
16445
|
-
pcb_component_id,
|
|
16446
|
-
subcircuit_id: subcircuit?.subcircuit_id ?? void 0,
|
|
16447
|
-
pcb_group_id: group?.pcb_group_id ?? void 0,
|
|
16448
|
-
layer,
|
|
16449
|
-
from,
|
|
16450
|
-
to,
|
|
16451
|
-
text,
|
|
16452
|
-
offset: props.offset,
|
|
16453
|
-
font: props.font ?? "tscircuit2024",
|
|
16454
|
-
font_size: props.fontSize ?? 1,
|
|
16455
|
-
color: props.color,
|
|
16456
|
-
arrow_size: props.arrowSize ?? 1
|
|
16457
|
-
}
|
|
16458
|
-
);
|
|
16459
|
-
this.fabrication_note_dimension_id = fabrication_note_dimension.pcb_fabrication_note_dimension_id;
|
|
16460
|
-
}
|
|
16461
|
-
getPcbSize() {
|
|
16462
|
-
const transform = this._computePcbGlobalTransformBeforeLayout();
|
|
16463
|
-
const from = this._resolvePoint(this._parsedProps.from, transform);
|
|
16464
|
-
const to = this._resolvePoint(this._parsedProps.to, transform);
|
|
16465
|
-
return {
|
|
16466
|
-
width: Math.abs(to.x - from.x),
|
|
16467
|
-
height: Math.abs(to.y - from.y)
|
|
16468
|
-
};
|
|
16469
|
-
}
|
|
16470
|
-
_formatDistanceText({
|
|
16471
|
-
from,
|
|
16472
|
-
to,
|
|
16473
|
-
units
|
|
16474
|
-
}) {
|
|
16475
|
-
const dx = to.x - from.x;
|
|
16476
|
-
const dy = to.y - from.y;
|
|
16477
|
-
const distanceInMillimeters = Math.sqrt(dx * dx + dy * dy);
|
|
16478
|
-
const distanceInUnits = units === "in" ? distanceInMillimeters / 25.4 : distanceInMillimeters;
|
|
16479
|
-
const roundedDistance = Math.round(distanceInUnits);
|
|
16480
|
-
const isWholeNumber = Math.abs(distanceInUnits - roundedDistance) < 1e-9;
|
|
16481
|
-
if (isWholeNumber) {
|
|
16482
|
-
return `${roundedDistance}${units}`;
|
|
16483
|
-
}
|
|
16484
|
-
const decimalPlaces = units === "in" ? 3 : 2;
|
|
16485
|
-
const valueText = units === "in" ? Number(distanceInUnits.toFixed(decimalPlaces)).toString() : distanceInUnits.toFixed(decimalPlaces);
|
|
16486
|
-
return `${valueText}${units}`;
|
|
16627
|
+
const source_component = db.source_component.insert({
|
|
16628
|
+
ftype: "simple_power_source",
|
|
16629
|
+
name: this.name,
|
|
16630
|
+
voltage: props.voltage,
|
|
16631
|
+
supplier_part_numbers: props.supplierPartNumbers,
|
|
16632
|
+
are_pins_interchangeable: false
|
|
16633
|
+
});
|
|
16634
|
+
this.source_component_id = source_component.source_component_id;
|
|
16487
16635
|
}
|
|
16636
|
+
pos = this.portMap.pin1;
|
|
16637
|
+
positive = this.portMap.pin1;
|
|
16638
|
+
neg = this.portMap.pin2;
|
|
16639
|
+
negative = this.portMap.pin2;
|
|
16488
16640
|
};
|
|
16489
16641
|
|
|
16490
|
-
// lib/components/
|
|
16491
|
-
import {
|
|
16492
|
-
|
|
16493
|
-
var PcbNoteLine = class extends PrimitiveComponent2 {
|
|
16494
|
-
pcb_note_line_id = null;
|
|
16495
|
-
isPcbPrimitive = true;
|
|
16642
|
+
// lib/components/normal-components/VoltageSource.ts
|
|
16643
|
+
import { voltageSourceProps } from "@tscircuit/props";
|
|
16644
|
+
var VoltageSource = class extends NormalComponent3 {
|
|
16496
16645
|
get config() {
|
|
16646
|
+
const isSquare = this.props.waveShape === "square";
|
|
16497
16647
|
return {
|
|
16498
|
-
componentName: "
|
|
16499
|
-
|
|
16648
|
+
componentName: "VoltageSource",
|
|
16649
|
+
schematicSymbolName: isSquare ? "square_wave" : "ac_voltmeter",
|
|
16650
|
+
zodProps: voltageSourceProps,
|
|
16651
|
+
sourceFtype: "simple_voltage_source"
|
|
16500
16652
|
};
|
|
16501
16653
|
}
|
|
16502
|
-
|
|
16503
|
-
if (
|
|
16654
|
+
runRenderPhaseForChildren(phase) {
|
|
16655
|
+
if (phase.startsWith("Pcb")) {
|
|
16656
|
+
return;
|
|
16657
|
+
}
|
|
16658
|
+
for (const child of this.children) {
|
|
16659
|
+
child.runRenderPhaseForChildren(phase);
|
|
16660
|
+
child.runRenderPhase(phase);
|
|
16661
|
+
}
|
|
16662
|
+
}
|
|
16663
|
+
doInitialPcbComponentRender() {
|
|
16664
|
+
}
|
|
16665
|
+
initPorts() {
|
|
16666
|
+
super.initPorts({
|
|
16667
|
+
additionalAliases: {
|
|
16668
|
+
pin1: ["terminal1"],
|
|
16669
|
+
pin2: ["terminal2"]
|
|
16670
|
+
}
|
|
16671
|
+
});
|
|
16672
|
+
}
|
|
16673
|
+
doInitialSourceRender() {
|
|
16504
16674
|
const { db } = this.root;
|
|
16505
16675
|
const { _parsedProps: props } = this;
|
|
16506
|
-
const
|
|
16507
|
-
|
|
16508
|
-
|
|
16509
|
-
|
|
16510
|
-
|
|
16511
|
-
|
|
16512
|
-
|
|
16513
|
-
|
|
16514
|
-
|
|
16515
|
-
|
|
16516
|
-
|
|
16517
|
-
y1: start.y,
|
|
16518
|
-
x2: end.x,
|
|
16519
|
-
y2: end.y,
|
|
16520
|
-
stroke_width: props.strokeWidth ?? 0.1,
|
|
16521
|
-
color: props.color,
|
|
16522
|
-
is_dashed: props.isDashed
|
|
16676
|
+
const source_component = db.source_component.insert({
|
|
16677
|
+
ftype: "simple_voltage_source",
|
|
16678
|
+
name: this.name,
|
|
16679
|
+
voltage: props.voltage,
|
|
16680
|
+
frequency: props.frequency,
|
|
16681
|
+
peak_to_peak_voltage: props.peakToPeakVoltage,
|
|
16682
|
+
wave_shape: props.waveShape,
|
|
16683
|
+
phase: props.phase,
|
|
16684
|
+
duty_cycle: props.dutyCycle,
|
|
16685
|
+
supplier_part_numbers: props.supplierPartNumbers,
|
|
16686
|
+
are_pins_interchangeable: true
|
|
16523
16687
|
});
|
|
16524
|
-
this.
|
|
16688
|
+
this.source_component_id = source_component.source_component_id;
|
|
16525
16689
|
}
|
|
16526
|
-
|
|
16690
|
+
doInitialSimulationRender() {
|
|
16691
|
+
const { db } = this.root;
|
|
16527
16692
|
const { _parsedProps: props } = this;
|
|
16693
|
+
const terminal1Port = this.portMap.terminal1;
|
|
16694
|
+
const terminal2Port = this.portMap.terminal2;
|
|
16695
|
+
db.simulation_voltage_source.insert({
|
|
16696
|
+
type: "simulation_voltage_source",
|
|
16697
|
+
is_dc_source: false,
|
|
16698
|
+
terminal1_source_port_id: terminal1Port.source_port_id,
|
|
16699
|
+
terminal2_source_port_id: terminal2Port.source_port_id,
|
|
16700
|
+
voltage: props.voltage,
|
|
16701
|
+
frequency: props.frequency,
|
|
16702
|
+
peak_to_peak_voltage: props.peakToPeakVoltage,
|
|
16703
|
+
wave_shape: props.waveShape,
|
|
16704
|
+
phase: props.phase,
|
|
16705
|
+
duty_cycle: props.dutyCycle
|
|
16706
|
+
});
|
|
16707
|
+
}
|
|
16708
|
+
terminal1 = this.portMap.terminal1;
|
|
16709
|
+
terminal2 = this.portMap.terminal2;
|
|
16710
|
+
};
|
|
16711
|
+
|
|
16712
|
+
// lib/components/primitive-components/Constraint.ts
|
|
16713
|
+
import { constraintProps } from "@tscircuit/props";
|
|
16714
|
+
import "zod";
|
|
16715
|
+
var edgeSpecifiers = [
|
|
16716
|
+
"leftedge",
|
|
16717
|
+
"rightedge",
|
|
16718
|
+
"topedge",
|
|
16719
|
+
"bottomedge",
|
|
16720
|
+
"center"
|
|
16721
|
+
];
|
|
16722
|
+
var Constraint3 = class extends PrimitiveComponent2 {
|
|
16723
|
+
get config() {
|
|
16528
16724
|
return {
|
|
16529
|
-
|
|
16530
|
-
|
|
16725
|
+
componentName: "Constraint",
|
|
16726
|
+
zodProps: constraintProps
|
|
16531
16727
|
};
|
|
16532
16728
|
}
|
|
16729
|
+
constructor(props) {
|
|
16730
|
+
super(props);
|
|
16731
|
+
if ("xdist" in props || "ydist" in props) {
|
|
16732
|
+
if (!("edgeToEdge" in props) && !("centerToCenter" in props)) {
|
|
16733
|
+
throw new Error(
|
|
16734
|
+
`edgeToEdge, centerToCenter must be set for xDist or yDist for ${this}`
|
|
16735
|
+
);
|
|
16736
|
+
}
|
|
16737
|
+
}
|
|
16738
|
+
if ("for" in props && props.for.length < 2) {
|
|
16739
|
+
throw new Error(`"for" must have at least two selectors for ${this}`);
|
|
16740
|
+
}
|
|
16741
|
+
}
|
|
16742
|
+
_getAllReferencedComponents() {
|
|
16743
|
+
const componentsWithSelectors = [];
|
|
16744
|
+
const container = this.getPrimitiveContainer();
|
|
16745
|
+
function addComponentFromSelector(selector) {
|
|
16746
|
+
const maybeEdge = selector.split(" ").pop();
|
|
16747
|
+
const edge = edgeSpecifiers.includes(maybeEdge) ? maybeEdge : void 0;
|
|
16748
|
+
const componentSelector = edge ? selector.replace(` ${edge}`, "") : selector;
|
|
16749
|
+
const component = container.selectOne(componentSelector, {
|
|
16750
|
+
pcbPrimitive: true
|
|
16751
|
+
});
|
|
16752
|
+
if (component) {
|
|
16753
|
+
componentsWithSelectors.push({
|
|
16754
|
+
selector,
|
|
16755
|
+
component,
|
|
16756
|
+
componentSelector,
|
|
16757
|
+
edge
|
|
16758
|
+
});
|
|
16759
|
+
}
|
|
16760
|
+
}
|
|
16761
|
+
for (const key of ["left", "right", "top", "bottom"]) {
|
|
16762
|
+
if (key in this._parsedProps) {
|
|
16763
|
+
addComponentFromSelector(this._parsedProps[key]);
|
|
16764
|
+
}
|
|
16765
|
+
}
|
|
16766
|
+
if ("for" in this._parsedProps) {
|
|
16767
|
+
for (const selector of this._parsedProps.for) {
|
|
16768
|
+
addComponentFromSelector(selector);
|
|
16769
|
+
}
|
|
16770
|
+
}
|
|
16771
|
+
return { componentsWithSelectors };
|
|
16772
|
+
}
|
|
16533
16773
|
};
|
|
16534
16774
|
|
|
16535
|
-
// lib/components/primitive-components/
|
|
16536
|
-
import {
|
|
16537
|
-
import
|
|
16538
|
-
var
|
|
16539
|
-
|
|
16540
|
-
isPcbPrimitive = true;
|
|
16775
|
+
// lib/components/primitive-components/FabricationNoteRect.ts
|
|
16776
|
+
import { fabricationNoteRectProps } from "@tscircuit/props";
|
|
16777
|
+
import "transformation-matrix";
|
|
16778
|
+
var FabricationNoteRect = class extends PrimitiveComponent2 {
|
|
16779
|
+
fabrication_note_rect_id = null;
|
|
16541
16780
|
get config() {
|
|
16542
16781
|
return {
|
|
16543
|
-
componentName: "
|
|
16544
|
-
zodProps:
|
|
16782
|
+
componentName: "FabricationNoteRect",
|
|
16783
|
+
zodProps: fabricationNoteRectProps
|
|
16545
16784
|
};
|
|
16546
16785
|
}
|
|
16547
16786
|
doInitialPcbPrimitiveRender() {
|
|
16548
16787
|
if (this.root?.pcbDisabled) return;
|
|
16549
16788
|
const { db } = this.root;
|
|
16550
16789
|
const { _parsedProps: props } = this;
|
|
16551
|
-
const
|
|
16552
|
-
const
|
|
16790
|
+
const { pcbX, pcbY } = this.getResolvedPcbPositionProp();
|
|
16791
|
+
const { maybeFlipLayer } = this._getPcbPrimitiveFlippedHelpers();
|
|
16792
|
+
const layer = maybeFlipLayer(props.layer ?? "top");
|
|
16793
|
+
if (layer !== "top" && layer !== "bottom") {
|
|
16794
|
+
throw new Error(
|
|
16795
|
+
`Invalid layer "${layer}" for FabricationNoteRect. Must be "top" or "bottom".`
|
|
16796
|
+
);
|
|
16797
|
+
}
|
|
16798
|
+
const pcb_component_id = this.parent?.pcb_component_id ?? this.getPrimitiveContainer()?.pcb_component_id;
|
|
16553
16799
|
const subcircuit = this.getSubcircuit();
|
|
16554
|
-
const
|
|
16555
|
-
const
|
|
16556
|
-
const pcb_note_rect = db.pcb_note_rect.insert({
|
|
16800
|
+
const hasStroke = props.hasStroke ?? (props.strokeWidth !== void 0 && props.strokeWidth !== null);
|
|
16801
|
+
const fabrication_note_rect = db.pcb_fabrication_note_rect.insert({
|
|
16557
16802
|
pcb_component_id,
|
|
16558
|
-
|
|
16559
|
-
|
|
16560
|
-
center
|
|
16803
|
+
layer,
|
|
16804
|
+
color: props.color,
|
|
16805
|
+
center: {
|
|
16806
|
+
x: pcbX,
|
|
16807
|
+
y: pcbY
|
|
16808
|
+
},
|
|
16561
16809
|
width: props.width,
|
|
16562
16810
|
height: props.height,
|
|
16563
|
-
stroke_width: props.strokeWidth ??
|
|
16811
|
+
stroke_width: props.strokeWidth ?? 1,
|
|
16564
16812
|
is_filled: props.isFilled ?? false,
|
|
16565
|
-
has_stroke:
|
|
16813
|
+
has_stroke: hasStroke,
|
|
16566
16814
|
is_stroke_dashed: props.isStrokeDashed ?? false,
|
|
16567
|
-
|
|
16815
|
+
subcircuit_id: subcircuit?.subcircuit_id ?? void 0,
|
|
16816
|
+
pcb_group_id: this.getGroup()?.pcb_group_id ?? void 0,
|
|
16568
16817
|
corner_radius: props.cornerRadius ?? void 0
|
|
16569
16818
|
});
|
|
16570
|
-
this.
|
|
16819
|
+
this.fabrication_note_rect_id = fabrication_note_rect.pcb_fabrication_note_rect_id;
|
|
16571
16820
|
}
|
|
16572
16821
|
getPcbSize() {
|
|
16573
16822
|
const { _parsedProps: props } = this;
|
|
16574
|
-
|
|
16575
|
-
const height = typeof props.height === "string" ? parseFloat(props.height) : props.height;
|
|
16576
|
-
return { width, height };
|
|
16823
|
+
return { width: props.width, height: props.height };
|
|
16577
16824
|
}
|
|
16578
16825
|
};
|
|
16579
16826
|
|
|
16580
|
-
// lib/components/primitive-components/
|
|
16581
|
-
import {
|
|
16582
|
-
import { applyToPoint as
|
|
16583
|
-
var
|
|
16584
|
-
|
|
16585
|
-
isPcbPrimitive = true;
|
|
16827
|
+
// lib/components/primitive-components/FabricationNotePath.ts
|
|
16828
|
+
import { fabricationNotePathProps } from "@tscircuit/props";
|
|
16829
|
+
import { applyToPoint as applyToPoint10 } from "transformation-matrix";
|
|
16830
|
+
var FabricationNotePath = class extends PrimitiveComponent2 {
|
|
16831
|
+
fabrication_note_path_id = null;
|
|
16586
16832
|
get config() {
|
|
16587
16833
|
return {
|
|
16588
|
-
componentName: "
|
|
16589
|
-
zodProps:
|
|
16834
|
+
componentName: "FabricationNotePath",
|
|
16835
|
+
zodProps: fabricationNotePathProps
|
|
16590
16836
|
};
|
|
16591
16837
|
}
|
|
16592
16838
|
doInitialPcbPrimitiveRender() {
|
|
16593
16839
|
if (this.root?.pcbDisabled) return;
|
|
16594
16840
|
const { db } = this.root;
|
|
16841
|
+
const subcircuit = this.getSubcircuit();
|
|
16595
16842
|
const { _parsedProps: props } = this;
|
|
16843
|
+
const layer = props.layer ?? "top";
|
|
16844
|
+
if (layer !== "top" && layer !== "bottom") {
|
|
16845
|
+
throw new Error(
|
|
16846
|
+
`Invalid layer "${layer}" for SilkscreenPath. Must be "top" or "bottom".`
|
|
16847
|
+
);
|
|
16848
|
+
}
|
|
16596
16849
|
const transform = this._computePcbGlobalTransformBeforeLayout();
|
|
16597
|
-
const
|
|
16598
|
-
const
|
|
16599
|
-
const group = this.getGroup();
|
|
16600
|
-
const pcb_component_id = this.parent?.pcb_component_id ?? this.getPrimitiveContainer()?.pcb_component_id ?? void 0;
|
|
16601
|
-
const pcb_note_text = db.pcb_note_text.insert({
|
|
16850
|
+
const pcb_component_id = this.parent?.pcb_component_id ?? this.getPrimitiveContainer()?.pcb_component_id;
|
|
16851
|
+
const fabrication_note_path = db.pcb_fabrication_note_path.insert({
|
|
16602
16852
|
pcb_component_id,
|
|
16603
|
-
|
|
16604
|
-
|
|
16605
|
-
|
|
16606
|
-
|
|
16607
|
-
|
|
16608
|
-
|
|
16609
|
-
|
|
16610
|
-
|
|
16853
|
+
layer,
|
|
16854
|
+
color: props.color,
|
|
16855
|
+
route: props.route.map((p) => {
|
|
16856
|
+
const transformedPosition = applyToPoint10(transform, {
|
|
16857
|
+
x: p.x,
|
|
16858
|
+
y: p.y
|
|
16859
|
+
});
|
|
16860
|
+
return {
|
|
16861
|
+
...p,
|
|
16862
|
+
x: transformedPosition.x,
|
|
16863
|
+
y: transformedPosition.y
|
|
16864
|
+
};
|
|
16865
|
+
}),
|
|
16866
|
+
stroke_width: props.strokeWidth ?? 0.1,
|
|
16867
|
+
subcircuit_id: subcircuit?.subcircuit_id ?? void 0
|
|
16611
16868
|
});
|
|
16612
|
-
this.
|
|
16613
|
-
}
|
|
16614
|
-
getPcbSize() {
|
|
16615
|
-
const { _parsedProps: props } = this;
|
|
16616
|
-
const fontSize = typeof props.fontSize === "string" ? parseFloat(props.fontSize) : props.fontSize ?? 1;
|
|
16617
|
-
const charWidth = fontSize * 0.6;
|
|
16618
|
-
const width = props.text.length * charWidth;
|
|
16619
|
-
const height = fontSize;
|
|
16620
|
-
return { width, height };
|
|
16869
|
+
this.fabrication_note_path_id = fabrication_note_path.pcb_fabrication_note_path_id;
|
|
16621
16870
|
}
|
|
16622
16871
|
};
|
|
16623
16872
|
|
|
16624
|
-
// lib/components/primitive-components/
|
|
16625
|
-
import {
|
|
16626
|
-
|
|
16627
|
-
var PcbNotePath = class extends PrimitiveComponent2 {
|
|
16628
|
-
pcb_note_path_id = null;
|
|
16629
|
-
isPcbPrimitive = true;
|
|
16873
|
+
// lib/components/primitive-components/FabricationNoteText.ts
|
|
16874
|
+
import { fabricationNoteTextProps } from "@tscircuit/props";
|
|
16875
|
+
var FabricationNoteText = class extends PrimitiveComponent2 {
|
|
16630
16876
|
get config() {
|
|
16631
16877
|
return {
|
|
16632
|
-
componentName: "
|
|
16633
|
-
zodProps:
|
|
16878
|
+
componentName: "FabricationNoteText",
|
|
16879
|
+
zodProps: fabricationNoteTextProps
|
|
16634
16880
|
};
|
|
16635
16881
|
}
|
|
16636
16882
|
doInitialPcbPrimitiveRender() {
|
|
16637
16883
|
if (this.root?.pcbDisabled) return;
|
|
16638
16884
|
const { db } = this.root;
|
|
16639
16885
|
const { _parsedProps: props } = this;
|
|
16640
|
-
const
|
|
16886
|
+
const { pcbX, pcbY } = this.getResolvedPcbPositionProp();
|
|
16887
|
+
const container = this.getPrimitiveContainer();
|
|
16641
16888
|
const subcircuit = this.getSubcircuit();
|
|
16642
|
-
|
|
16643
|
-
|
|
16644
|
-
|
|
16645
|
-
|
|
16646
|
-
|
|
16647
|
-
|
|
16648
|
-
|
|
16649
|
-
|
|
16650
|
-
|
|
16651
|
-
|
|
16652
|
-
|
|
16889
|
+
db.pcb_fabrication_note_text.insert({
|
|
16890
|
+
anchor_alignment: props.anchorAlignment,
|
|
16891
|
+
anchor_position: {
|
|
16892
|
+
x: pcbX,
|
|
16893
|
+
y: pcbY
|
|
16894
|
+
},
|
|
16895
|
+
font: props.font ?? "tscircuit2024",
|
|
16896
|
+
font_size: props.fontSize ?? 1,
|
|
16897
|
+
layer: "top",
|
|
16898
|
+
color: props.color,
|
|
16899
|
+
text: props.text ?? "",
|
|
16900
|
+
pcb_component_id: container.pcb_component_id,
|
|
16653
16901
|
subcircuit_id: subcircuit?.subcircuit_id ?? void 0,
|
|
16654
|
-
pcb_group_id:
|
|
16655
|
-
route: transformedRoute,
|
|
16656
|
-
stroke_width: props.strokeWidth ?? 0.1,
|
|
16657
|
-
color: props.color
|
|
16902
|
+
pcb_group_id: this.getGroup()?.pcb_group_id ?? void 0
|
|
16658
16903
|
});
|
|
16659
|
-
this.pcb_note_path_id = pcb_note_path.pcb_note_path_id;
|
|
16660
|
-
}
|
|
16661
|
-
getPcbSize() {
|
|
16662
|
-
const { _parsedProps: props } = this;
|
|
16663
|
-
if (props.route.length === 0) return { width: 0, height: 0 };
|
|
16664
|
-
const xs = props.route.map(
|
|
16665
|
-
(point) => typeof point.x === "string" ? parseFloat(point.x) : point.x
|
|
16666
|
-
);
|
|
16667
|
-
const ys = props.route.map(
|
|
16668
|
-
(point) => typeof point.y === "string" ? parseFloat(point.y) : point.y
|
|
16669
|
-
);
|
|
16670
|
-
const minX = Math.min(...xs);
|
|
16671
|
-
const maxX = Math.max(...xs);
|
|
16672
|
-
const minY = Math.min(...ys);
|
|
16673
|
-
const maxY = Math.max(...ys);
|
|
16674
|
-
return { width: maxX - minX, height: maxY - minY };
|
|
16675
16904
|
}
|
|
16676
16905
|
};
|
|
16677
16906
|
|
|
16678
|
-
// lib/components/primitive-components/
|
|
16679
|
-
import {
|
|
16680
|
-
import { applyToPoint as
|
|
16681
|
-
var
|
|
16682
|
-
|
|
16907
|
+
// lib/components/primitive-components/FabricationNoteDimension.ts
|
|
16908
|
+
import { fabricationNoteDimensionProps } from "@tscircuit/props";
|
|
16909
|
+
import { applyToPoint as applyToPoint11 } from "transformation-matrix";
|
|
16910
|
+
var FabricationNoteDimension = class extends PrimitiveComponent2 {
|
|
16911
|
+
fabrication_note_dimension_id = null;
|
|
16683
16912
|
isPcbPrimitive = true;
|
|
16684
16913
|
get config() {
|
|
16685
16914
|
return {
|
|
16686
|
-
componentName: "
|
|
16687
|
-
zodProps:
|
|
16915
|
+
componentName: "FabricationNoteDimension",
|
|
16916
|
+
zodProps: fabricationNoteDimensionProps
|
|
16688
16917
|
};
|
|
16689
16918
|
}
|
|
16690
16919
|
_resolvePoint(input, transform) {
|
|
16691
16920
|
if (typeof input === "string") {
|
|
16692
16921
|
const target = this.getSubcircuit().selectOne(
|
|
16693
|
-
|
|
16922
|
+
input
|
|
16694
16923
|
);
|
|
16695
|
-
if (!target) {
|
|
16696
|
-
this.renderError(
|
|
16697
|
-
|
|
16924
|
+
if (!target) {
|
|
16925
|
+
this.renderError(
|
|
16926
|
+
`FabricationNoteDimension could not find selector "${input}"`
|
|
16927
|
+
);
|
|
16928
|
+
return applyToPoint11(transform, { x: 0, y: 0 });
|
|
16698
16929
|
}
|
|
16699
16930
|
return target._getGlobalPcbPositionBeforeLayout();
|
|
16700
16931
|
}
|
|
16701
16932
|
const numericX = typeof input.x === "string" ? parseFloat(input.x) : input.x;
|
|
16702
16933
|
const numericY = typeof input.y === "string" ? parseFloat(input.y) : input.y;
|
|
16703
|
-
return
|
|
16934
|
+
return applyToPoint11(transform, { x: numericX, y: numericY });
|
|
16704
16935
|
}
|
|
16705
16936
|
doInitialPcbPrimitiveRender() {
|
|
16706
16937
|
if (this.root?.pcbDisabled) return;
|
|
@@ -16711,506 +16942,333 @@ var PcbNoteDimension = class extends PrimitiveComponent2 {
|
|
|
16711
16942
|
const to = this._resolvePoint(props.to, transform);
|
|
16712
16943
|
const subcircuit = this.getSubcircuit();
|
|
16713
16944
|
const group = this.getGroup();
|
|
16714
|
-
const
|
|
16715
|
-
const
|
|
16716
|
-
|
|
16717
|
-
|
|
16718
|
-
|
|
16719
|
-
pcb_group_id: group?.pcb_group_id ?? void 0,
|
|
16720
|
-
from,
|
|
16721
|
-
to,
|
|
16722
|
-
text,
|
|
16723
|
-
font: props.font ?? "tscircuit2024",
|
|
16724
|
-
font_size: props.fontSize ?? 1,
|
|
16725
|
-
color: props.color,
|
|
16726
|
-
arrow_size: props.arrowSize ?? 1
|
|
16727
|
-
});
|
|
16728
|
-
this.pcb_note_dimension_id = pcb_note_dimension.pcb_note_dimension_id;
|
|
16729
|
-
}
|
|
16730
|
-
getPcbSize() {
|
|
16731
|
-
const transform = this._computePcbGlobalTransformBeforeLayout();
|
|
16732
|
-
const from = this._resolvePoint(this._parsedProps.from, transform);
|
|
16733
|
-
const to = this._resolvePoint(this._parsedProps.to, transform);
|
|
16734
|
-
return {
|
|
16735
|
-
width: Math.abs(to.x - from.x),
|
|
16736
|
-
height: Math.abs(to.y - from.y)
|
|
16737
|
-
};
|
|
16738
|
-
}
|
|
16739
|
-
_formatDistanceText({
|
|
16740
|
-
from,
|
|
16741
|
-
to,
|
|
16742
|
-
units
|
|
16743
|
-
}) {
|
|
16744
|
-
const dx = to.x - from.x;
|
|
16745
|
-
const dy = to.y - from.y;
|
|
16746
|
-
const distanceInMillimeters = Math.sqrt(dx * dx + dy * dy);
|
|
16747
|
-
const distanceInUnits = units === "in" ? distanceInMillimeters / 25.4 : distanceInMillimeters;
|
|
16748
|
-
const roundedDistance = Math.round(distanceInUnits);
|
|
16749
|
-
const isWholeNumber = Math.abs(distanceInUnits - roundedDistance) < 1e-9;
|
|
16750
|
-
if (isWholeNumber) {
|
|
16751
|
-
return `${roundedDistance}${units}`;
|
|
16752
|
-
}
|
|
16753
|
-
const decimalPlaces = units === "in" ? 3 : 2;
|
|
16754
|
-
const valueText = units === "in" ? Number(distanceInUnits.toFixed(decimalPlaces)).toString() : distanceInUnits.toFixed(decimalPlaces);
|
|
16755
|
-
return `${valueText}${units}`;
|
|
16756
|
-
}
|
|
16757
|
-
};
|
|
16758
|
-
|
|
16759
|
-
// lib/components/primitive-components/Group/Subcircuit/Subcircuit.ts
|
|
16760
|
-
import "@tscircuit/props";
|
|
16761
|
-
import { cju } from "@tscircuit/circuit-json-util";
|
|
16762
|
-
|
|
16763
|
-
// lib/components/primitive-components/Group/Subcircuit/inflators/inflatePcbComponent.ts
|
|
16764
|
-
import { compose as compose5, translate as translate6, rotate as rotate3, inverse } from "transformation-matrix";
|
|
16765
|
-
import { transformPCBElements as transformPCBElements2 } from "@tscircuit/circuit-json-util";
|
|
16766
|
-
var inflatePcbComponent = (pcbElm, inflatorContext) => {
|
|
16767
|
-
const { injectionDb, normalComponent } = inflatorContext;
|
|
16768
|
-
if (!normalComponent) return;
|
|
16769
|
-
const componentCenter = pcbElm.center || { x: 0, y: 0 };
|
|
16770
|
-
const componentRotation = pcbElm.rotation || 0;
|
|
16771
|
-
const absoluteToComponentRelativeTransform = inverse(
|
|
16772
|
-
compose5(
|
|
16773
|
-
translate6(componentCenter.x, componentCenter.y),
|
|
16774
|
-
rotate3(componentRotation * Math.PI / 180)
|
|
16775
|
-
)
|
|
16776
|
-
);
|
|
16777
|
-
const relativeElements = injectionDb.toArray().filter(
|
|
16778
|
-
(elm) => "pcb_component_id" in elm && elm.pcb_component_id === pcbElm.pcb_component_id
|
|
16779
|
-
);
|
|
16780
|
-
transformPCBElements2(relativeElements, absoluteToComponentRelativeTransform);
|
|
16781
|
-
const components = createComponentsFromCircuitJson(
|
|
16782
|
-
{
|
|
16783
|
-
componentName: normalComponent.name,
|
|
16784
|
-
componentRotation: "0deg"
|
|
16785
|
-
},
|
|
16786
|
-
relativeElements
|
|
16787
|
-
);
|
|
16788
|
-
normalComponent.addAll(components);
|
|
16789
|
-
};
|
|
16790
|
-
|
|
16791
|
-
// lib/components/primitive-components/Group/Subcircuit/inflators/inflateSourceResistor.ts
|
|
16792
|
-
function inflateSourceResistor(sourceElm, inflatorContext) {
|
|
16793
|
-
const { injectionDb, subcircuit, groupsMap } = inflatorContext;
|
|
16794
|
-
const pcbElm = injectionDb.pcb_component.getWhere({
|
|
16795
|
-
source_component_id: sourceElm.source_component_id
|
|
16796
|
-
});
|
|
16797
|
-
const cadElm = injectionDb.cad_component.getWhere({
|
|
16798
|
-
source_component_id: sourceElm.source_component_id
|
|
16799
|
-
});
|
|
16800
|
-
const resistor = new Resistor({
|
|
16801
|
-
name: sourceElm.name,
|
|
16802
|
-
resistance: sourceElm.resistance,
|
|
16803
|
-
layer: pcbElm?.layer,
|
|
16804
|
-
pcbX: pcbElm?.center?.x,
|
|
16805
|
-
pcbY: pcbElm?.center?.y,
|
|
16806
|
-
pcbRotation: pcbElm?.rotation,
|
|
16807
|
-
doNotPlace: pcbElm?.do_not_place,
|
|
16808
|
-
obstructsWithinBounds: pcbElm?.obstructs_within_bounds
|
|
16809
|
-
});
|
|
16810
|
-
if (pcbElm) {
|
|
16811
|
-
inflatePcbComponent(pcbElm, {
|
|
16812
|
-
...inflatorContext,
|
|
16813
|
-
normalComponent: resistor
|
|
16814
|
-
});
|
|
16815
|
-
}
|
|
16816
|
-
if (sourceElm.source_group_id && groupsMap?.has(sourceElm.source_group_id)) {
|
|
16817
|
-
const group = groupsMap.get(sourceElm.source_group_id);
|
|
16818
|
-
group.add(resistor);
|
|
16819
|
-
} else {
|
|
16820
|
-
subcircuit.add(resistor);
|
|
16821
|
-
}
|
|
16822
|
-
}
|
|
16823
|
-
|
|
16824
|
-
// lib/components/primitive-components/Group/Subcircuit/inflators/inflateSourcePort.ts
|
|
16825
|
-
function inflateSourcePort(sourcePort, inflatorContext) {
|
|
16826
|
-
const { injectionDb, subcircuit } = inflatorContext;
|
|
16827
|
-
if (sourcePort.source_component_id !== null) {
|
|
16828
|
-
return;
|
|
16829
|
-
}
|
|
16830
|
-
const pcbPortFromInjection = injectionDb.pcb_port.getWhere({
|
|
16831
|
-
source_port_id: sourcePort.source_port_id
|
|
16832
|
-
});
|
|
16833
|
-
const port = new Port({
|
|
16834
|
-
name: sourcePort.name,
|
|
16835
|
-
pinNumber: sourcePort.pin_number
|
|
16836
|
-
});
|
|
16837
|
-
subcircuit.add(port);
|
|
16838
|
-
port.source_port_id = sourcePort.source_port_id;
|
|
16839
|
-
const root = subcircuit.root;
|
|
16840
|
-
if (root && pcbPortFromInjection) {
|
|
16841
|
-
const { db } = root;
|
|
16842
|
-
const pcb_port = db.pcb_port.insert({
|
|
16843
|
-
pcb_component_id: void 0,
|
|
16844
|
-
layers: pcbPortFromInjection.layers,
|
|
16845
|
-
subcircuit_id: subcircuit.subcircuit_id ?? void 0,
|
|
16846
|
-
pcb_group_id: subcircuit.getGroup()?.pcb_group_id ?? void 0,
|
|
16847
|
-
x: pcbPortFromInjection.x,
|
|
16848
|
-
y: pcbPortFromInjection.y,
|
|
16849
|
-
source_port_id: sourcePort.source_port_id,
|
|
16850
|
-
is_board_pinout: false
|
|
16851
|
-
});
|
|
16852
|
-
port.pcb_port_id = pcb_port.pcb_port_id;
|
|
16853
|
-
}
|
|
16854
|
-
}
|
|
16855
|
-
|
|
16856
|
-
// lib/components/primitive-components/Group/Subcircuit/inflators/inflateSourceGroup.ts
|
|
16857
|
-
function inflateSourceGroup(sourceGroup, inflatorContext) {
|
|
16858
|
-
const { subcircuit, groupsMap } = inflatorContext;
|
|
16859
|
-
const group = new Group6({
|
|
16860
|
-
name: sourceGroup.name
|
|
16861
|
-
});
|
|
16862
|
-
group.source_group_id = sourceGroup.source_group_id;
|
|
16863
|
-
subcircuit.add(group);
|
|
16864
|
-
if (groupsMap) {
|
|
16865
|
-
groupsMap.set(sourceGroup.source_group_id, group);
|
|
16866
|
-
}
|
|
16867
|
-
return group;
|
|
16868
|
-
}
|
|
16869
|
-
|
|
16870
|
-
// lib/components/primitive-components/Group/Subcircuit/inflators/inflateSourceChip.ts
|
|
16871
|
-
var mapInternallyConnectedSourcePortIdsToPinLabels = (sourcePortIds, inflatorContext) => {
|
|
16872
|
-
if (!sourcePortIds || sourcePortIds.length === 0) return void 0;
|
|
16873
|
-
const { injectionDb } = inflatorContext;
|
|
16874
|
-
const mapped = sourcePortIds.map(
|
|
16875
|
-
(group) => group.map((sourcePortId) => {
|
|
16876
|
-
const port = injectionDb.source_port.get(
|
|
16877
|
-
sourcePortId
|
|
16945
|
+
const { maybeFlipLayer } = this._getPcbPrimitiveFlippedHelpers();
|
|
16946
|
+
const layer = maybeFlipLayer(props.layer ?? "top");
|
|
16947
|
+
if (layer !== "top" && layer !== "bottom") {
|
|
16948
|
+
throw new Error(
|
|
16949
|
+
`Invalid layer "${layer}" for FabricationNoteDimension. Must be "top" or "bottom".`
|
|
16878
16950
|
);
|
|
16879
|
-
if (!port) return null;
|
|
16880
|
-
if (port.pin_number !== void 0 && port.pin_number !== null) {
|
|
16881
|
-
return `pin${port.pin_number}`;
|
|
16882
|
-
}
|
|
16883
|
-
return port.name;
|
|
16884
|
-
}).filter((value) => value !== null)
|
|
16885
|
-
).filter((group) => group.length > 0);
|
|
16886
|
-
return mapped.length > 0 ? mapped : void 0;
|
|
16887
|
-
};
|
|
16888
|
-
var inflateSourceChip = (sourceElm, inflatorContext) => {
|
|
16889
|
-
const { injectionDb, subcircuit, groupsMap } = inflatorContext;
|
|
16890
|
-
const pcbElm = injectionDb.pcb_component.getWhere({
|
|
16891
|
-
source_component_id: sourceElm.source_component_id
|
|
16892
|
-
});
|
|
16893
|
-
const schematicElm = injectionDb.schematic_component.getWhere({
|
|
16894
|
-
source_component_id: sourceElm.source_component_id
|
|
16895
|
-
});
|
|
16896
|
-
const cadElm = injectionDb.cad_component.getWhere({
|
|
16897
|
-
source_component_id: sourceElm.source_component_id
|
|
16898
|
-
});
|
|
16899
|
-
const internallyConnectedPins = mapInternallyConnectedSourcePortIdsToPinLabels(
|
|
16900
|
-
sourceElm.internally_connected_source_port_ids,
|
|
16901
|
-
inflatorContext
|
|
16902
|
-
);
|
|
16903
|
-
const chip = new Chip({
|
|
16904
|
-
name: sourceElm.name,
|
|
16905
|
-
manufacturerPartNumber: sourceElm.manufacturer_part_number,
|
|
16906
|
-
supplierPartNumbers: sourceElm.supplier_part_numbers ?? void 0,
|
|
16907
|
-
pinLabels: schematicElm?.port_labels ?? void 0,
|
|
16908
|
-
schWidth: schematicElm?.size?.width,
|
|
16909
|
-
schHeight: schematicElm?.size?.height,
|
|
16910
|
-
schPinSpacing: schematicElm?.pin_spacing,
|
|
16911
|
-
schX: schematicElm?.center?.x,
|
|
16912
|
-
schY: schematicElm?.center?.y,
|
|
16913
|
-
layer: pcbElm?.layer,
|
|
16914
|
-
pcbX: pcbElm?.center?.x,
|
|
16915
|
-
pcbY: pcbElm?.center?.y,
|
|
16916
|
-
pcbRotation: pcbElm?.rotation,
|
|
16917
|
-
doNotPlace: pcbElm?.do_not_place,
|
|
16918
|
-
obstructsWithinBounds: pcbElm?.obstructs_within_bounds,
|
|
16919
|
-
internallyConnectedPins
|
|
16920
|
-
});
|
|
16921
|
-
const footprint = cadElm?.footprinter_string ?? null;
|
|
16922
|
-
if (footprint) {
|
|
16923
|
-
Object.assign(chip.props, { footprint });
|
|
16924
|
-
Object.assign(chip._parsedProps, { footprint });
|
|
16925
|
-
if (!cadElm) {
|
|
16926
|
-
;
|
|
16927
|
-
chip._addChildrenFromStringFootprint?.();
|
|
16928
16951
|
}
|
|
16952
|
+
const pcb_component_id = this.parent?.pcb_component_id ?? this.getPrimitiveContainer()?.pcb_component_id;
|
|
16953
|
+
const text = props.text ?? this._formatDistanceText({ from, to, units: props.units ?? "mm" });
|
|
16954
|
+
const fabrication_note_dimension = db.pcb_fabrication_note_dimension.insert(
|
|
16955
|
+
{
|
|
16956
|
+
pcb_component_id,
|
|
16957
|
+
subcircuit_id: subcircuit?.subcircuit_id ?? void 0,
|
|
16958
|
+
pcb_group_id: group?.pcb_group_id ?? void 0,
|
|
16959
|
+
layer,
|
|
16960
|
+
from,
|
|
16961
|
+
to,
|
|
16962
|
+
text,
|
|
16963
|
+
offset: props.offset,
|
|
16964
|
+
font: props.font ?? "tscircuit2024",
|
|
16965
|
+
font_size: props.fontSize ?? 1,
|
|
16966
|
+
color: props.color,
|
|
16967
|
+
arrow_size: props.arrowSize ?? 1
|
|
16968
|
+
}
|
|
16969
|
+
);
|
|
16970
|
+
this.fabrication_note_dimension_id = fabrication_note_dimension.pcb_fabrication_note_dimension_id;
|
|
16929
16971
|
}
|
|
16930
|
-
|
|
16931
|
-
|
|
16932
|
-
|
|
16933
|
-
|
|
16934
|
-
|
|
16935
|
-
|
|
16936
|
-
|
|
16937
|
-
|
|
16938
|
-
group.add(chip);
|
|
16939
|
-
} else {
|
|
16940
|
-
subcircuit.add(chip);
|
|
16941
|
-
}
|
|
16942
|
-
};
|
|
16943
|
-
|
|
16944
|
-
// lib/components/primitive-components/Group/Subcircuit/inflators/inflateSourceCapacitor.ts
|
|
16945
|
-
function inflateSourceCapacitor(sourceElm, inflatorContext) {
|
|
16946
|
-
const { injectionDb, subcircuit, groupsMap } = inflatorContext;
|
|
16947
|
-
const pcbElm = injectionDb.pcb_component.getWhere({
|
|
16948
|
-
source_component_id: sourceElm.source_component_id
|
|
16949
|
-
});
|
|
16950
|
-
const cadElm = injectionDb.cad_component.getWhere({
|
|
16951
|
-
source_component_id: sourceElm.source_component_id
|
|
16952
|
-
});
|
|
16953
|
-
const capacitor = new Capacitor({
|
|
16954
|
-
name: sourceElm.name,
|
|
16955
|
-
capacitance: sourceElm.capacitance,
|
|
16956
|
-
layer: pcbElm?.layer,
|
|
16957
|
-
pcbX: pcbElm?.center?.x,
|
|
16958
|
-
pcbY: pcbElm?.center?.y,
|
|
16959
|
-
pcbRotation: pcbElm?.rotation,
|
|
16960
|
-
doNotPlace: pcbElm?.do_not_place,
|
|
16961
|
-
obstructsWithinBounds: pcbElm?.obstructs_within_bounds
|
|
16962
|
-
});
|
|
16963
|
-
if (pcbElm) {
|
|
16964
|
-
inflatePcbComponent(pcbElm, {
|
|
16965
|
-
...inflatorContext,
|
|
16966
|
-
normalComponent: capacitor
|
|
16967
|
-
});
|
|
16972
|
+
getPcbSize() {
|
|
16973
|
+
const transform = this._computePcbGlobalTransformBeforeLayout();
|
|
16974
|
+
const from = this._resolvePoint(this._parsedProps.from, transform);
|
|
16975
|
+
const to = this._resolvePoint(this._parsedProps.to, transform);
|
|
16976
|
+
return {
|
|
16977
|
+
width: Math.abs(to.x - from.x),
|
|
16978
|
+
height: Math.abs(to.y - from.y)
|
|
16979
|
+
};
|
|
16968
16980
|
}
|
|
16969
|
-
|
|
16970
|
-
|
|
16971
|
-
|
|
16972
|
-
|
|
16973
|
-
|
|
16981
|
+
_formatDistanceText({
|
|
16982
|
+
from,
|
|
16983
|
+
to,
|
|
16984
|
+
units
|
|
16985
|
+
}) {
|
|
16986
|
+
const dx = to.x - from.x;
|
|
16987
|
+
const dy = to.y - from.y;
|
|
16988
|
+
const distanceInMillimeters = Math.sqrt(dx * dx + dy * dy);
|
|
16989
|
+
const distanceInUnits = units === "in" ? distanceInMillimeters / 25.4 : distanceInMillimeters;
|
|
16990
|
+
const roundedDistance = Math.round(distanceInUnits);
|
|
16991
|
+
const isWholeNumber = Math.abs(distanceInUnits - roundedDistance) < 1e-9;
|
|
16992
|
+
if (isWholeNumber) {
|
|
16993
|
+
return `${roundedDistance}${units}`;
|
|
16994
|
+
}
|
|
16995
|
+
const decimalPlaces = units === "in" ? 3 : 2;
|
|
16996
|
+
const valueText = units === "in" ? Number(distanceInUnits.toFixed(decimalPlaces)).toString() : distanceInUnits.toFixed(decimalPlaces);
|
|
16997
|
+
return `${valueText}${units}`;
|
|
16974
16998
|
}
|
|
16975
|
-
}
|
|
16999
|
+
};
|
|
16976
17000
|
|
|
16977
|
-
// lib/components/
|
|
16978
|
-
import {
|
|
16979
|
-
import {
|
|
16980
|
-
var
|
|
16981
|
-
|
|
17001
|
+
// lib/components/primitive-components/PcbNoteLine.ts
|
|
17002
|
+
import { pcbNoteLineProps } from "@tscircuit/props";
|
|
17003
|
+
import { applyToPoint as applyToPoint12 } from "transformation-matrix";
|
|
17004
|
+
var PcbNoteLine = class extends PrimitiveComponent2 {
|
|
17005
|
+
pcb_note_line_id = null;
|
|
17006
|
+
isPcbPrimitive = true;
|
|
16982
17007
|
get config() {
|
|
16983
17008
|
return {
|
|
16984
|
-
componentName: "
|
|
16985
|
-
|
|
16986
|
-
zodProps: inductorProps,
|
|
16987
|
-
sourceFtype: FTYPE.simple_inductor
|
|
17009
|
+
componentName: "PcbNoteLine",
|
|
17010
|
+
zodProps: pcbNoteLineProps
|
|
16988
17011
|
};
|
|
16989
17012
|
}
|
|
16990
|
-
|
|
16991
|
-
|
|
16992
|
-
}
|
|
16993
|
-
initPorts() {
|
|
16994
|
-
super.initPorts({
|
|
16995
|
-
additionalAliases: {
|
|
16996
|
-
pin1: ["anode", "pos", "left"],
|
|
16997
|
-
pin2: ["cathode", "neg", "right"]
|
|
16998
|
-
}
|
|
16999
|
-
});
|
|
17000
|
-
}
|
|
17001
|
-
doInitialSourceRender() {
|
|
17013
|
+
doInitialPcbPrimitiveRender() {
|
|
17014
|
+
if (this.root?.pcbDisabled) return;
|
|
17002
17015
|
const { db } = this.root;
|
|
17003
17016
|
const { _parsedProps: props } = this;
|
|
17004
|
-
const
|
|
17005
|
-
|
|
17006
|
-
|
|
17007
|
-
|
|
17008
|
-
|
|
17009
|
-
|
|
17010
|
-
|
|
17011
|
-
|
|
17012
|
-
|
|
17013
|
-
|
|
17014
|
-
|
|
17015
|
-
|
|
17016
|
-
|
|
17017
|
-
|
|
17018
|
-
|
|
17019
|
-
|
|
17020
|
-
|
|
17021
|
-
const cadElm = injectionDb.cad_component.getWhere({
|
|
17022
|
-
source_component_id: sourceElm.source_component_id
|
|
17023
|
-
});
|
|
17024
|
-
const inductor = new Inductor({
|
|
17025
|
-
name: sourceElm.name,
|
|
17026
|
-
inductance: sourceElm.inductance,
|
|
17027
|
-
layer: pcbElm?.layer,
|
|
17028
|
-
pcbX: pcbElm?.center?.x,
|
|
17029
|
-
pcbY: pcbElm?.center?.y,
|
|
17030
|
-
pcbRotation: pcbElm?.rotation,
|
|
17031
|
-
doNotPlace: pcbElm?.do_not_place,
|
|
17032
|
-
obstructsWithinBounds: pcbElm?.obstructs_within_bounds
|
|
17033
|
-
});
|
|
17034
|
-
if (pcbElm) {
|
|
17035
|
-
inflatePcbComponent(pcbElm, {
|
|
17036
|
-
...inflatorContext,
|
|
17037
|
-
normalComponent: inductor
|
|
17038
|
-
});
|
|
17039
|
-
}
|
|
17040
|
-
if (sourceElm.source_group_id && groupsMap?.has(sourceElm.source_group_id)) {
|
|
17041
|
-
const group = groupsMap.get(sourceElm.source_group_id);
|
|
17042
|
-
group.add(inductor);
|
|
17043
|
-
} else {
|
|
17044
|
-
subcircuit.add(inductor);
|
|
17045
|
-
}
|
|
17046
|
-
}
|
|
17047
|
-
|
|
17048
|
-
// lib/components/primitive-components/Group/Subcircuit/inflators/inflateSourceDiode.ts
|
|
17049
|
-
function inflateSourceDiode(sourceElm, inflatorContext) {
|
|
17050
|
-
const { injectionDb, subcircuit, groupsMap } = inflatorContext;
|
|
17051
|
-
const pcbElm = injectionDb.pcb_component.getWhere({
|
|
17052
|
-
source_component_id: sourceElm.source_component_id
|
|
17053
|
-
});
|
|
17054
|
-
const cadElm = injectionDb.cad_component.getWhere({
|
|
17055
|
-
source_component_id: sourceElm.source_component_id
|
|
17056
|
-
});
|
|
17057
|
-
const diode = new Diode({
|
|
17058
|
-
name: sourceElm.name,
|
|
17059
|
-
layer: pcbElm?.layer,
|
|
17060
|
-
pcbX: pcbElm?.center?.x,
|
|
17061
|
-
pcbY: pcbElm?.center?.y,
|
|
17062
|
-
pcbRotation: pcbElm?.rotation,
|
|
17063
|
-
doNotPlace: pcbElm?.do_not_place,
|
|
17064
|
-
obstructsWithinBounds: pcbElm?.obstructs_within_bounds
|
|
17065
|
-
});
|
|
17066
|
-
if (pcbElm) {
|
|
17067
|
-
inflatePcbComponent(pcbElm, {
|
|
17068
|
-
...inflatorContext,
|
|
17069
|
-
normalComponent: diode
|
|
17017
|
+
const subcircuit = this.getSubcircuit();
|
|
17018
|
+
const group = this.getGroup();
|
|
17019
|
+
const transform = this._computePcbGlobalTransformBeforeLayout();
|
|
17020
|
+
const start = applyToPoint12(transform, { x: props.x1, y: props.y1 });
|
|
17021
|
+
const end = applyToPoint12(transform, { x: props.x2, y: props.y2 });
|
|
17022
|
+
const pcb_component_id = this.parent?.pcb_component_id ?? this.getPrimitiveContainer()?.pcb_component_id ?? void 0;
|
|
17023
|
+
const pcb_note_line = db.pcb_note_line.insert({
|
|
17024
|
+
pcb_component_id,
|
|
17025
|
+
subcircuit_id: subcircuit?.subcircuit_id ?? void 0,
|
|
17026
|
+
pcb_group_id: group?.pcb_group_id ?? void 0,
|
|
17027
|
+
x1: start.x,
|
|
17028
|
+
y1: start.y,
|
|
17029
|
+
x2: end.x,
|
|
17030
|
+
y2: end.y,
|
|
17031
|
+
stroke_width: props.strokeWidth ?? 0.1,
|
|
17032
|
+
color: props.color,
|
|
17033
|
+
is_dashed: props.isDashed
|
|
17070
17034
|
});
|
|
17035
|
+
this.pcb_note_line_id = pcb_note_line.pcb_note_line_id;
|
|
17071
17036
|
}
|
|
17072
|
-
|
|
17073
|
-
const
|
|
17074
|
-
|
|
17075
|
-
|
|
17076
|
-
|
|
17037
|
+
getPcbSize() {
|
|
17038
|
+
const { _parsedProps: props } = this;
|
|
17039
|
+
return {
|
|
17040
|
+
width: Math.abs(props.x2 - props.x1),
|
|
17041
|
+
height: Math.abs(props.y2 - props.y1)
|
|
17042
|
+
};
|
|
17077
17043
|
}
|
|
17078
|
-
}
|
|
17044
|
+
};
|
|
17079
17045
|
|
|
17080
|
-
// lib/components/primitive-components/
|
|
17081
|
-
|
|
17082
|
-
|
|
17083
|
-
|
|
17084
|
-
|
|
17085
|
-
|
|
17086
|
-
|
|
17087
|
-
|
|
17088
|
-
|
|
17046
|
+
// lib/components/primitive-components/PcbNoteRect.ts
|
|
17047
|
+
import { pcbNoteRectProps } from "@tscircuit/props";
|
|
17048
|
+
import { applyToPoint as applyToPoint13 } from "transformation-matrix";
|
|
17049
|
+
var PcbNoteRect = class extends PrimitiveComponent2 {
|
|
17050
|
+
pcb_note_rect_id = null;
|
|
17051
|
+
isPcbPrimitive = true;
|
|
17052
|
+
get config() {
|
|
17053
|
+
return {
|
|
17054
|
+
componentName: "PcbNoteRect",
|
|
17055
|
+
zodProps: pcbNoteRectProps
|
|
17056
|
+
};
|
|
17089
17057
|
}
|
|
17090
|
-
|
|
17091
|
-
|
|
17092
|
-
};
|
|
17093
|
-
|
|
17094
|
-
|
|
17095
|
-
|
|
17096
|
-
|
|
17097
|
-
const
|
|
17098
|
-
|
|
17099
|
-
|
|
17100
|
-
|
|
17101
|
-
|
|
17102
|
-
|
|
17103
|
-
|
|
17104
|
-
|
|
17105
|
-
|
|
17106
|
-
|
|
17107
|
-
|
|
17108
|
-
|
|
17109
|
-
|
|
17110
|
-
|
|
17111
|
-
|
|
17112
|
-
|
|
17113
|
-
|
|
17114
|
-
} else {
|
|
17115
|
-
selector = `.${sourcePort.name}`;
|
|
17116
|
-
}
|
|
17117
|
-
if (selector) {
|
|
17118
|
-
connectedSelectors.push(selector);
|
|
17119
|
-
}
|
|
17058
|
+
doInitialPcbPrimitiveRender() {
|
|
17059
|
+
if (this.root?.pcbDisabled) return;
|
|
17060
|
+
const { db } = this.root;
|
|
17061
|
+
const { _parsedProps: props } = this;
|
|
17062
|
+
const transform = this._computePcbGlobalTransformBeforeLayout();
|
|
17063
|
+
const center = applyToPoint13(transform, { x: 0, y: 0 });
|
|
17064
|
+
const subcircuit = this.getSubcircuit();
|
|
17065
|
+
const group = this.getGroup();
|
|
17066
|
+
const pcb_component_id = this.parent?.pcb_component_id ?? this.getPrimitiveContainer()?.pcb_component_id ?? void 0;
|
|
17067
|
+
const pcb_note_rect = db.pcb_note_rect.insert({
|
|
17068
|
+
pcb_component_id,
|
|
17069
|
+
subcircuit_id: subcircuit?.subcircuit_id ?? void 0,
|
|
17070
|
+
pcb_group_id: group?.pcb_group_id ?? void 0,
|
|
17071
|
+
center,
|
|
17072
|
+
width: props.width,
|
|
17073
|
+
height: props.height,
|
|
17074
|
+
stroke_width: props.strokeWidth ?? 0.1,
|
|
17075
|
+
is_filled: props.isFilled ?? false,
|
|
17076
|
+
has_stroke: props.hasStroke ?? true,
|
|
17077
|
+
is_stroke_dashed: props.isStrokeDashed ?? false,
|
|
17078
|
+
color: props.color,
|
|
17079
|
+
corner_radius: props.cornerRadius ?? void 0
|
|
17080
|
+
});
|
|
17081
|
+
this.pcb_note_rect_id = pcb_note_rect.pcb_note_rect_id;
|
|
17120
17082
|
}
|
|
17121
|
-
|
|
17122
|
-
const
|
|
17123
|
-
|
|
17124
|
-
|
|
17125
|
-
}
|
|
17083
|
+
getPcbSize() {
|
|
17084
|
+
const { _parsedProps: props } = this;
|
|
17085
|
+
const width = typeof props.width === "string" ? parseFloat(props.width) : props.width;
|
|
17086
|
+
const height = typeof props.height === "string" ? parseFloat(props.height) : props.height;
|
|
17087
|
+
return { width, height };
|
|
17126
17088
|
}
|
|
17127
|
-
|
|
17128
|
-
const trace = new Trace3({
|
|
17129
|
-
path: connectedSelectors
|
|
17130
|
-
});
|
|
17131
|
-
trace.source_trace_id = sourceTrace.source_trace_id;
|
|
17132
|
-
subcircuit.add(trace);
|
|
17133
|
-
}
|
|
17089
|
+
};
|
|
17134
17090
|
|
|
17135
|
-
// lib/components/
|
|
17136
|
-
import {
|
|
17137
|
-
|
|
17091
|
+
// lib/components/primitive-components/PcbNoteText.ts
|
|
17092
|
+
import { pcbNoteTextProps } from "@tscircuit/props";
|
|
17093
|
+
import { applyToPoint as applyToPoint14 } from "transformation-matrix";
|
|
17094
|
+
var PcbNoteText = class extends PrimitiveComponent2 {
|
|
17095
|
+
pcb_note_text_id = null;
|
|
17096
|
+
isPcbPrimitive = true;
|
|
17138
17097
|
get config() {
|
|
17139
|
-
const baseSymbolName = this.props.type === "npn" ? "npn_bipolar_transistor" : "pnp_bipolar_transistor";
|
|
17140
17098
|
return {
|
|
17141
|
-
componentName: "
|
|
17142
|
-
|
|
17143
|
-
zodProps: transistorProps,
|
|
17144
|
-
sourceFtype: "simple_transistor",
|
|
17145
|
-
shouldRenderAsSchematicBox: false
|
|
17099
|
+
componentName: "PcbNoteText",
|
|
17100
|
+
zodProps: pcbNoteTextProps
|
|
17146
17101
|
};
|
|
17147
17102
|
}
|
|
17148
|
-
|
|
17149
|
-
|
|
17150
|
-
|
|
17151
|
-
|
|
17152
|
-
|
|
17153
|
-
};
|
|
17154
|
-
|
|
17155
|
-
|
|
17156
|
-
|
|
17103
|
+
doInitialPcbPrimitiveRender() {
|
|
17104
|
+
if (this.root?.pcbDisabled) return;
|
|
17105
|
+
const { db } = this.root;
|
|
17106
|
+
const { _parsedProps: props } = this;
|
|
17107
|
+
const transform = this._computePcbGlobalTransformBeforeLayout();
|
|
17108
|
+
const anchorPosition = applyToPoint14(transform, { x: 0, y: 0 });
|
|
17109
|
+
const subcircuit = this.getSubcircuit();
|
|
17110
|
+
const group = this.getGroup();
|
|
17111
|
+
const pcb_component_id = this.parent?.pcb_component_id ?? this.getPrimitiveContainer()?.pcb_component_id ?? void 0;
|
|
17112
|
+
const pcb_note_text = db.pcb_note_text.insert({
|
|
17113
|
+
pcb_component_id,
|
|
17114
|
+
subcircuit_id: subcircuit?.subcircuit_id ?? void 0,
|
|
17115
|
+
pcb_group_id: group?.pcb_group_id ?? void 0,
|
|
17116
|
+
font: props.font ?? "tscircuit2024",
|
|
17117
|
+
font_size: props.fontSize ?? 1,
|
|
17118
|
+
text: props.text,
|
|
17119
|
+
anchor_position: anchorPosition,
|
|
17120
|
+
anchor_alignment: props.anchorAlignment ?? "center",
|
|
17121
|
+
color: props.color
|
|
17157
17122
|
});
|
|
17123
|
+
this.pcb_note_text_id = pcb_note_text.pcb_note_text_id;
|
|
17158
17124
|
}
|
|
17159
|
-
|
|
17160
|
-
|
|
17161
|
-
|
|
17162
|
-
|
|
17163
|
-
|
|
17125
|
+
getPcbSize() {
|
|
17126
|
+
const { _parsedProps: props } = this;
|
|
17127
|
+
const fontSize = typeof props.fontSize === "string" ? parseFloat(props.fontSize) : props.fontSize ?? 1;
|
|
17128
|
+
const charWidth = fontSize * 0.6;
|
|
17129
|
+
const width = props.text.length * charWidth;
|
|
17130
|
+
const height = fontSize;
|
|
17131
|
+
return { width, height };
|
|
17164
17132
|
}
|
|
17165
|
-
|
|
17166
|
-
|
|
17133
|
+
};
|
|
17134
|
+
|
|
17135
|
+
// lib/components/primitive-components/PcbNotePath.ts
|
|
17136
|
+
import { pcbNotePathProps } from "@tscircuit/props";
|
|
17137
|
+
import { applyToPoint as applyToPoint15 } from "transformation-matrix";
|
|
17138
|
+
var PcbNotePath = class extends PrimitiveComponent2 {
|
|
17139
|
+
pcb_note_path_id = null;
|
|
17140
|
+
isPcbPrimitive = true;
|
|
17141
|
+
get config() {
|
|
17142
|
+
return {
|
|
17143
|
+
componentName: "PcbNotePath",
|
|
17144
|
+
zodProps: pcbNotePathProps
|
|
17145
|
+
};
|
|
17167
17146
|
}
|
|
17168
|
-
|
|
17147
|
+
doInitialPcbPrimitiveRender() {
|
|
17148
|
+
if (this.root?.pcbDisabled) return;
|
|
17169
17149
|
const { db } = this.root;
|
|
17170
17150
|
const { _parsedProps: props } = this;
|
|
17171
|
-
const
|
|
17172
|
-
|
|
17173
|
-
|
|
17174
|
-
|
|
17151
|
+
const transform = this._computePcbGlobalTransformBeforeLayout();
|
|
17152
|
+
const subcircuit = this.getSubcircuit();
|
|
17153
|
+
const group = this.getGroup();
|
|
17154
|
+
const pcb_component_id = this.parent?.pcb_component_id ?? this.getPrimitiveContainer()?.pcb_component_id ?? void 0;
|
|
17155
|
+
const transformedRoute = props.route.map((point) => {
|
|
17156
|
+
const { x, y, ...rest } = point;
|
|
17157
|
+
const numericX = typeof x === "string" ? parseFloat(x) : x;
|
|
17158
|
+
const numericY = typeof y === "string" ? parseFloat(y) : y;
|
|
17159
|
+
const transformed = applyToPoint15(transform, { x: numericX, y: numericY });
|
|
17160
|
+
return { ...rest, x: transformed.x, y: transformed.y };
|
|
17175
17161
|
});
|
|
17176
|
-
|
|
17162
|
+
const pcb_note_path = db.pcb_note_path.insert({
|
|
17163
|
+
pcb_component_id,
|
|
17164
|
+
subcircuit_id: subcircuit?.subcircuit_id ?? void 0,
|
|
17165
|
+
pcb_group_id: group?.pcb_group_id ?? void 0,
|
|
17166
|
+
route: transformedRoute,
|
|
17167
|
+
stroke_width: props.strokeWidth ?? 0.1,
|
|
17168
|
+
color: props.color
|
|
17169
|
+
});
|
|
17170
|
+
this.pcb_note_path_id = pcb_note_path.pcb_note_path_id;
|
|
17171
|
+
}
|
|
17172
|
+
getPcbSize() {
|
|
17173
|
+
const { _parsedProps: props } = this;
|
|
17174
|
+
if (props.route.length === 0) return { width: 0, height: 0 };
|
|
17175
|
+
const xs = props.route.map(
|
|
17176
|
+
(point) => typeof point.x === "string" ? parseFloat(point.x) : point.x
|
|
17177
|
+
);
|
|
17178
|
+
const ys = props.route.map(
|
|
17179
|
+
(point) => typeof point.y === "string" ? parseFloat(point.y) : point.y
|
|
17180
|
+
);
|
|
17181
|
+
const minX = Math.min(...xs);
|
|
17182
|
+
const maxX = Math.max(...xs);
|
|
17183
|
+
const minY = Math.min(...ys);
|
|
17184
|
+
const maxY = Math.max(...ys);
|
|
17185
|
+
return { width: maxX - minX, height: maxY - minY };
|
|
17177
17186
|
}
|
|
17178
17187
|
};
|
|
17179
17188
|
|
|
17180
|
-
// lib/components/primitive-components/
|
|
17181
|
-
|
|
17182
|
-
|
|
17183
|
-
|
|
17184
|
-
|
|
17185
|
-
|
|
17186
|
-
|
|
17187
|
-
|
|
17188
|
-
|
|
17189
|
-
|
|
17190
|
-
|
|
17191
|
-
|
|
17192
|
-
|
|
17193
|
-
|
|
17194
|
-
|
|
17195
|
-
|
|
17196
|
-
|
|
17197
|
-
|
|
17198
|
-
|
|
17199
|
-
|
|
17200
|
-
|
|
17201
|
-
|
|
17202
|
-
|
|
17189
|
+
// lib/components/primitive-components/PcbNoteDimension.ts
|
|
17190
|
+
import { pcbNoteDimensionProps } from "@tscircuit/props";
|
|
17191
|
+
import { applyToPoint as applyToPoint16 } from "transformation-matrix";
|
|
17192
|
+
var PcbNoteDimension = class extends PrimitiveComponent2 {
|
|
17193
|
+
pcb_note_dimension_id = null;
|
|
17194
|
+
isPcbPrimitive = true;
|
|
17195
|
+
get config() {
|
|
17196
|
+
return {
|
|
17197
|
+
componentName: "PcbNoteDimension",
|
|
17198
|
+
zodProps: pcbNoteDimensionProps
|
|
17199
|
+
};
|
|
17200
|
+
}
|
|
17201
|
+
_resolvePoint(input, transform) {
|
|
17202
|
+
if (typeof input === "string") {
|
|
17203
|
+
const target = this.getSubcircuit().selectOne(
|
|
17204
|
+
`.${input}`
|
|
17205
|
+
);
|
|
17206
|
+
if (!target) {
|
|
17207
|
+
this.renderError(`PcbNoteDimension could not find selector "${input}"`);
|
|
17208
|
+
return applyToPoint16(transform, { x: 0, y: 0 });
|
|
17209
|
+
}
|
|
17210
|
+
return target._getGlobalPcbPositionBeforeLayout();
|
|
17211
|
+
}
|
|
17212
|
+
const numericX = typeof input.x === "string" ? parseFloat(input.x) : input.x;
|
|
17213
|
+
const numericY = typeof input.y === "string" ? parseFloat(input.y) : input.y;
|
|
17214
|
+
return applyToPoint16(transform, { x: numericX, y: numericY });
|
|
17215
|
+
}
|
|
17216
|
+
doInitialPcbPrimitiveRender() {
|
|
17217
|
+
if (this.root?.pcbDisabled) return;
|
|
17218
|
+
const { db } = this.root;
|
|
17219
|
+
const { _parsedProps: props } = this;
|
|
17220
|
+
const transform = this._computePcbGlobalTransformBeforeLayout();
|
|
17221
|
+
const from = this._resolvePoint(props.from, transform);
|
|
17222
|
+
const to = this._resolvePoint(props.to, transform);
|
|
17223
|
+
const subcircuit = this.getSubcircuit();
|
|
17224
|
+
const group = this.getGroup();
|
|
17225
|
+
const pcb_component_id = this.parent?.pcb_component_id ?? this.getPrimitiveContainer()?.pcb_component_id ?? void 0;
|
|
17226
|
+
const text = props.text ?? this._formatDistanceText({ from, to, units: props.units ?? "mm" });
|
|
17227
|
+
const pcb_note_dimension = db.pcb_note_dimension.insert({
|
|
17228
|
+
pcb_component_id,
|
|
17229
|
+
subcircuit_id: subcircuit?.subcircuit_id ?? void 0,
|
|
17230
|
+
pcb_group_id: group?.pcb_group_id ?? void 0,
|
|
17231
|
+
from,
|
|
17232
|
+
to,
|
|
17233
|
+
text,
|
|
17234
|
+
font: props.font ?? "tscircuit2024",
|
|
17235
|
+
font_size: props.fontSize ?? 1,
|
|
17236
|
+
color: props.color,
|
|
17237
|
+
arrow_size: props.arrowSize ?? 1
|
|
17203
17238
|
});
|
|
17239
|
+
this.pcb_note_dimension_id = pcb_note_dimension.pcb_note_dimension_id;
|
|
17204
17240
|
}
|
|
17205
|
-
|
|
17206
|
-
const
|
|
17207
|
-
|
|
17208
|
-
|
|
17209
|
-
|
|
17241
|
+
getPcbSize() {
|
|
17242
|
+
const transform = this._computePcbGlobalTransformBeforeLayout();
|
|
17243
|
+
const from = this._resolvePoint(this._parsedProps.from, transform);
|
|
17244
|
+
const to = this._resolvePoint(this._parsedProps.to, transform);
|
|
17245
|
+
return {
|
|
17246
|
+
width: Math.abs(to.x - from.x),
|
|
17247
|
+
height: Math.abs(to.y - from.y)
|
|
17248
|
+
};
|
|
17210
17249
|
}
|
|
17211
|
-
|
|
17250
|
+
_formatDistanceText({
|
|
17251
|
+
from,
|
|
17252
|
+
to,
|
|
17253
|
+
units
|
|
17254
|
+
}) {
|
|
17255
|
+
const dx = to.x - from.x;
|
|
17256
|
+
const dy = to.y - from.y;
|
|
17257
|
+
const distanceInMillimeters = Math.sqrt(dx * dx + dy * dy);
|
|
17258
|
+
const distanceInUnits = units === "in" ? distanceInMillimeters / 25.4 : distanceInMillimeters;
|
|
17259
|
+
const roundedDistance = Math.round(distanceInUnits);
|
|
17260
|
+
const isWholeNumber = Math.abs(distanceInUnits - roundedDistance) < 1e-9;
|
|
17261
|
+
if (isWholeNumber) {
|
|
17262
|
+
return `${roundedDistance}${units}`;
|
|
17263
|
+
}
|
|
17264
|
+
const decimalPlaces = units === "in" ? 3 : 2;
|
|
17265
|
+
const valueText = units === "in" ? Number(distanceInUnits.toFixed(decimalPlaces)).toString() : distanceInUnits.toFixed(decimalPlaces);
|
|
17266
|
+
return `${valueText}${units}`;
|
|
17267
|
+
}
|
|
17268
|
+
};
|
|
17212
17269
|
|
|
17213
17270
|
// lib/components/primitive-components/Group/Subcircuit/Subcircuit.ts
|
|
17271
|
+
import "@tscircuit/props";
|
|
17214
17272
|
var Subcircuit = class extends Group6 {
|
|
17215
17273
|
constructor(props) {
|
|
17216
17274
|
super({
|
|
@@ -17233,57 +17291,8 @@ var Subcircuit = class extends Group6 {
|
|
|
17233
17291
|
* - Add components to groups in the appropriate hierarchy
|
|
17234
17292
|
*/
|
|
17235
17293
|
doInitialInflateSubcircuitCircuitJson() {
|
|
17236
|
-
const { circuitJson
|
|
17237
|
-
|
|
17238
|
-
const injectionDb = cju(injectionCircuitJson);
|
|
17239
|
-
if (injectionCircuitJson && children?.length > 0) {
|
|
17240
|
-
throw new Error("Subcircuit cannot have both circuitJson and children");
|
|
17241
|
-
}
|
|
17242
|
-
const groupsMap = /* @__PURE__ */ new Map();
|
|
17243
|
-
const inflationCtx = {
|
|
17244
|
-
injectionDb,
|
|
17245
|
-
subcircuit: this,
|
|
17246
|
-
groupsMap
|
|
17247
|
-
};
|
|
17248
|
-
const sourceGroups = injectionDb.source_group.list();
|
|
17249
|
-
for (const sourceGroup of sourceGroups) {
|
|
17250
|
-
inflateSourceGroup(sourceGroup, inflationCtx);
|
|
17251
|
-
}
|
|
17252
|
-
const sourceComponents = injectionDb.source_component.list();
|
|
17253
|
-
for (const sourceComponent of sourceComponents) {
|
|
17254
|
-
switch (sourceComponent.ftype) {
|
|
17255
|
-
case "simple_resistor":
|
|
17256
|
-
inflateSourceResistor(sourceComponent, inflationCtx);
|
|
17257
|
-
break;
|
|
17258
|
-
case "simple_capacitor":
|
|
17259
|
-
inflateSourceCapacitor(sourceComponent, inflationCtx);
|
|
17260
|
-
break;
|
|
17261
|
-
case "simple_inductor":
|
|
17262
|
-
inflateSourceInductor(sourceComponent, inflationCtx);
|
|
17263
|
-
break;
|
|
17264
|
-
case "simple_diode":
|
|
17265
|
-
inflateSourceDiode(sourceComponent, inflationCtx);
|
|
17266
|
-
break;
|
|
17267
|
-
case "simple_chip":
|
|
17268
|
-
inflateSourceChip(sourceComponent, inflationCtx);
|
|
17269
|
-
break;
|
|
17270
|
-
case "simple_transistor":
|
|
17271
|
-
inflateSourceTransistor(sourceComponent, inflationCtx);
|
|
17272
|
-
break;
|
|
17273
|
-
default:
|
|
17274
|
-
throw new Error(
|
|
17275
|
-
`No inflator implemented for source component ftype: "${sourceComponent.ftype}"`
|
|
17276
|
-
);
|
|
17277
|
-
}
|
|
17278
|
-
}
|
|
17279
|
-
const sourcePorts = injectionDb.source_port.list();
|
|
17280
|
-
for (const sourcePort of sourcePorts) {
|
|
17281
|
-
inflateSourcePort(sourcePort, inflationCtx);
|
|
17282
|
-
}
|
|
17283
|
-
const sourceTraces = injectionDb.source_trace.list();
|
|
17284
|
-
for (const sourceTrace of sourceTraces) {
|
|
17285
|
-
inflateSourceTrace(sourceTrace, inflationCtx);
|
|
17286
|
-
}
|
|
17294
|
+
const { circuitJson, children } = this._parsedProps;
|
|
17295
|
+
inflateCircuitJson(this, circuitJson, children);
|
|
17287
17296
|
}
|
|
17288
17297
|
};
|
|
17289
17298
|
|
|
@@ -19193,7 +19202,7 @@ import { identity as identity6 } from "transformation-matrix";
|
|
|
19193
19202
|
var package_default = {
|
|
19194
19203
|
name: "@tscircuit/core",
|
|
19195
19204
|
type: "module",
|
|
19196
|
-
version: "0.0.
|
|
19205
|
+
version: "0.0.892",
|
|
19197
19206
|
types: "dist/index.d.ts",
|
|
19198
19207
|
main: "dist/index.js",
|
|
19199
19208
|
module: "dist/index.js",
|