Files
Wiring-Designer/frontend/js/connectorLibrary.js
T
Kyle cca03cd2f3 feat: standard parts library, fuse box configurator, and theming
Standard parts (partsLibrary.js)
- ACDC TXL palette: 15 solids plus the 16 stocked stripe combinations
- 29 wire functions fix colour, stripe and gauge per signal, so a wire
  drawn from a given pin comes out identical on every build
- 16 pre-labelled parts: Skudak VCU (GRAY/BLACK), openinverter LDU
  23-pin, Dilong OBC/DCDC, BMW pedal, Honeywell CSSV1500, Bender
  ISO175, Bosch iBooster, Prius EPS, Volvo PS pump, cluster, DNR
  switch, 32-way enclosure bulkhead, contactors, VW MEB BMS
- OEM colours override the in-house standard where we splice into a
  factory loom (VW MEB LV connector, recovered from the VW bms diagram)
- Brown is ground, matching the MEB loom and European practice; orange
  is reserved for AC mains and OEM high-voltage runs

Fuse box configurator (pdmLibrary.js)
- GEP FRH-A12/A24 and the 48-way PDM as 280-footprint cavity grids
- Place, drag and rotate fuses, relays, diodes, breakers and bus bars
- Bus bars occupy their own collision layer and feed the blades they
  cross, suppressing those inputs so one wire supplies the run
- Cavity capacity is tracked; Apply is blocked while a placement
  overlaps or overhangs
- Naming a circuit renames its pins: "VCU" gives "VCU in" / "VCU out"

Theming (theme.js)
- Light and dark modes; canvas background, grid dots, part fill and
  part outline are configurable and persisted
- CSS converted to custom properties with property-aware light-mode
  pairs, since a colour used as text and as a surface must flip
  differently; no rule falls below 3:1 contrast in either theme
- Canvas devices, pins, labels, cable rows and the harness view are
  themed too, since Konva bakes colours in at draw time and cannot
  read CSS variables

Also
- Pass-through bulkheads: one device covering both connector faces,
  with a single centred label per circuit
- Pin labels scale with the device font instead of a fixed 8px
- Keyboard handling is modal-scoped, so Delete no longer removes the
  canvas device while the fuse box editor is open

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-19 10:54:49 -04:00

307 lines
20 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Automotive / EV connector library
// Each entry: { id, name, manufacturer, partNumber, pinCount, pinLabels?, description }
const CONNECTOR_LIBRARY = {
"Deutsch DT": [
{ id: "dt-2p", name: "DT04-2P", manufacturer: "TE Connectivity", partNumber: "DT04-2P-P012", pinCount: 2, description: "2-pin weatherproof plug, 2014 AWG" },
{ id: "dt-3p", name: "DT04-3P", manufacturer: "TE Connectivity", partNumber: "DT04-3P-P012", pinCount: 3, description: "3-pin weatherproof plug, 2014 AWG" },
{ id: "dt-4p", name: "DT04-4P", manufacturer: "TE Connectivity", partNumber: "DT04-4P-P012", pinCount: 4, description: "4-pin weatherproof plug, 2014 AWG" },
{ id: "dt-6p", name: "DT04-6P", manufacturer: "TE Connectivity", partNumber: "DT04-6P-P012", pinCount: 6, description: "6-pin weatherproof plug, 2014 AWG" },
{ id: "dt-8p", name: "DT04-8P", manufacturer: "TE Connectivity", partNumber: "DT04-8P-P012", pinCount: 8, description: "8-pin weatherproof plug, 2014 AWG" },
{ id: "dt-12p", name: "DT04-12P", manufacturer: "TE Connectivity", partNumber: "DT04-12P-P014", pinCount: 12, description: "12-pin weatherproof plug, 2014 AWG" },
{ id: "dt-2s", name: "DT06-2S", manufacturer: "TE Connectivity", partNumber: "DT06-2S", pinCount: 2, description: "2-pin weatherproof socket (receptacle)" },
{ id: "dt-4s", name: "DT06-4S", manufacturer: "TE Connectivity", partNumber: "DT06-4S", pinCount: 4, description: "4-pin weatherproof socket (receptacle)" },
{ id: "dt-6s", name: "DT06-6S", manufacturer: "TE Connectivity", partNumber: "DT06-6S", pinCount: 6, description: "6-pin weatherproof socket (receptacle)" },
{ id: "dt-8s", name: "DT06-8S", manufacturer: "TE Connectivity", partNumber: "DT06-8S", pinCount: 8, description: "8-pin weatherproof socket (receptacle)" },
],
"Deutsch DTM (Miniature)": [
{ id: "dtm-2p", name: "DTM04-2P", manufacturer: "TE Connectivity", partNumber: "DTM04-2P", pinCount: 2, description: "2-pin miniature weatherproof, 2420 AWG" },
{ id: "dtm-3p", name: "DTM04-3P", manufacturer: "TE Connectivity", partNumber: "DTM04-3P", pinCount: 3, description: "3-pin miniature weatherproof" },
{ id: "dtm-4p", name: "DTM04-4P", manufacturer: "TE Connectivity", partNumber: "DTM04-4P", pinCount: 4, description: "4-pin miniature weatherproof" },
{ id: "dtm-6p", name: "DTM04-6P", manufacturer: "TE Connectivity", partNumber: "DTM04-6P", pinCount: 6, description: "6-pin miniature weatherproof" },
{ id: "dtm-8p", name: "DTM04-8P", manufacturer: "TE Connectivity", partNumber: "DTM04-8P", pinCount: 8, description: "8-pin miniature weatherproof" },
{ id: "dtm-2s", name: "DTM06-2S", manufacturer: "TE Connectivity", partNumber: "DTM06-2S", pinCount: 2, description: "2-pin miniature socket" },
{ id: "dtm-4s", name: "DTM06-4S", manufacturer: "TE Connectivity", partNumber: "DTM06-4S", pinCount: 4, description: "4-pin miniature socket" },
],
"Deutsch DTP (High Current)": [
{ id: "dtp-2p", name: "DTP04-2P", manufacturer: "TE Connectivity", partNumber: "DTP04-2P-E003", pinCount: 2, description: "2-pin high current plug, up to 40A per pin, 1210 AWG", pinLabels: ["+", ""] },
{ id: "dtp-4p", name: "DTP04-4P", manufacturer: "TE Connectivity", partNumber: "DTP04-4P-E003", pinCount: 4, description: "4-pin high current plug, up to 40A per pin" },
{ id: "dtp-2s", name: "DTP06-2S", manufacturer: "TE Connectivity", partNumber: "DTP06-2S-E003", pinCount: 2, description: "2-pin high current socket" },
{ id: "dtp-4s", name: "DTP06-4S", manufacturer: "TE Connectivity", partNumber: "DTP06-4S-E003", pinCount: 4, description: "4-pin high current socket" },
],
"Deutsch HD (Heavy Duty)": [
{ id: "hd-9", name: "HD30-9", manufacturer: "TE Connectivity", partNumber: "HD30-9-1939P", pinCount: 9, description: "9-pin heavy duty, SAE J1939 CAN" },
{ id: "hd-18", name: "HD30-18", manufacturer: "TE Connectivity", partNumber: "HD30-18-14P", pinCount: 18, description: "18-pin heavy duty" },
{ id: "hd-24", name: "HD30-24", manufacturer: "TE Connectivity", partNumber: "HD30-24-14P", pinCount: 24, description: "24-pin heavy duty" },
],
"Anderson Powerpole": [
{ id: "ap-pp15", name: "PP15/30", manufacturer: "Anderson Power", partNumber: "1327G6", pinCount: 2, description: "15/30 A Powerpole, 1512 AWG", pinLabels: ["+", ""] },
{ id: "ap-pp45", name: "PP45", manufacturer: "Anderson Power", partNumber: "1338G6", pinCount: 2, description: "45 A Powerpole, 1210 AWG", pinLabels: ["+", ""] },
{ id: "ap-pp75", name: "PP75", manufacturer: "Anderson Power", partNumber: "5913G2", pinCount: 2, description: "75 A Powerpole, 84 AWG", pinLabels: ["+", ""] },
{ id: "ap-sb50", name: "SB 50", manufacturer: "Anderson Power", partNumber: "6319G1", pinCount: 2, description: "50 A SB connector, 62 AWG", pinLabels: ["+", ""] },
{ id: "ap-sb120", name: "SB 120", manufacturer: "Anderson Power", partNumber: "6352G1", pinCount: 2, description: "120 A SB connector, 24/0 AWG", pinLabels: ["+", ""] },
{ id: "ap-sb175", name: "SB 175", manufacturer: "Anderson Power", partNumber: "6321G1", pinCount: 2, description: "175 A SB connector, 24/0 AWG", pinLabels: ["+", ""] },
{ id: "ap-sb350", name: "SB 350", manufacturer: "Anderson Power", partNumber: "6348G1", pinCount: 2, description: "350 A SB connector, 4/0 AWG", pinLabels: ["+", ""] },
],
"Molex Micro-Fit 3.0": [
{ id: "mf-2", name: "Micro-Fit 2-pin", manufacturer: "Molex", partNumber: "43045-0200", pinCount: 2, description: "600 V, 5 A, 3.0 mm pitch" },
{ id: "mf-4", name: "Micro-Fit 4-pin", manufacturer: "Molex", partNumber: "43045-0400", pinCount: 4, description: "600 V, 5 A" },
{ id: "mf-6", name: "Micro-Fit 6-pin", manufacturer: "Molex", partNumber: "43045-0600", pinCount: 6, description: "600 V, 5 A" },
{ id: "mf-8", name: "Micro-Fit 8-pin", manufacturer: "Molex", partNumber: "43045-0800", pinCount: 8, description: "600 V, 5 A" },
{ id: "mf-10", name: "Micro-Fit 10-pin", manufacturer: "Molex", partNumber: "43045-1000", pinCount: 10, description: "600 V, 5 A" },
{ id: "mf-12", name: "Micro-Fit 12-pin", manufacturer: "Molex", partNumber: "43045-1200", pinCount: 12, description: "600 V, 5 A" },
],
"Molex Mini-Fit Jr.": [
{ id: "mfj-2", name: "Mini-Fit Jr. 2-pin", manufacturer: "Molex", partNumber: "39012020", pinCount: 2, description: "600 V, 9 A, 4.20 mm pitch" },
{ id: "mfj-4", name: "Mini-Fit Jr. 4-pin", manufacturer: "Molex", partNumber: "39012040", pinCount: 4, description: "600 V, 9 A" },
{ id: "mfj-6", name: "Mini-Fit Jr. 6-pin", manufacturer: "Molex", partNumber: "39012060", pinCount: 6, description: "600 V, 9 A" },
{ id: "mfj-8", name: "Mini-Fit Jr. 8-pin", manufacturer: "Molex", partNumber: "39012080", pinCount: 8, description: "600 V, 9 A" },
{ id: "mfj-12", name: "Mini-Fit Jr. 12-pin", manufacturer: "Molex", partNumber: "39012120", pinCount: 12, description: "600 V, 9 A" },
],
"Molex MX150 (Automotive)": [
{ id: "mx-2", name: "MX150 2-pin", manufacturer: "Molex", partNumber: "33472-0201", pinCount: 2, description: "Sealed automotive, 600 V, 13 A" },
{ id: "mx-4", name: "MX150 4-pin", manufacturer: "Molex", partNumber: "33472-0401", pinCount: 4, description: "Sealed automotive" },
{ id: "mx-6", name: "MX150 6-pin", manufacturer: "Molex", partNumber: "33472-0601", pinCount: 6, description: "Sealed automotive" },
{ id: "mx-8", name: "MX150 8-pin", manufacturer: "Molex", partNumber: "33472-0801", pinCount: 8, description: "Sealed automotive" },
],
"TE Superseal 1.5 mm (IP67)": [
{ id: "ss-1", name: "Superseal 1-pin", manufacturer: "TE Connectivity", partNumber: "1-967616-1", pinCount: 1, description: "IP67, 0.51.0 mm², 8.5 A" },
{ id: "ss-2", name: "Superseal 2-pin", manufacturer: "TE Connectivity", partNumber: "1-967616-2", pinCount: 2, description: "IP67, 0.51.0 mm²" },
{ id: "ss-3", name: "Superseal 3-pin", manufacturer: "TE Connectivity", partNumber: "1-967616-3", pinCount: 3, description: "IP67, 0.51.0 mm²" },
{ id: "ss-4", name: "Superseal 4-pin", manufacturer: "TE Connectivity", partNumber: "1-967616-4", pinCount: 4, description: "IP67, 0.51.0 mm²" },
{ id: "ss-6", name: "Superseal 6-pin", manufacturer: "TE Connectivity", partNumber: "1-967616-6", pinCount: 6, description: "IP67, 0.51.0 mm²" },
],
"Delphi / Aptiv Weatherpack": [
{ id: "wp-1", name: "Weatherpack 1-pin", manufacturer: "Aptiv (Delphi)", partNumber: "12015793", pinCount: 1, description: "GT series, 100 °C rated, 2018 AWG" },
{ id: "wp-2", name: "Weatherpack 2-pin", manufacturer: "Aptiv (Delphi)", partNumber: "12010299", pinCount: 2, description: "GT series, 100 °C rated" },
{ id: "wp-3", name: "Weatherpack 3-pin", manufacturer: "Aptiv (Delphi)", partNumber: "12010325", pinCount: 3, description: "GT series" },
{ id: "wp-4", name: "Weatherpack 4-pin", manufacturer: "Aptiv (Delphi)", partNumber: "12010298", pinCount: 4, description: "GT series" },
{ id: "wp-6", name: "Weatherpack 6-pin", manufacturer: "Aptiv (Delphi)", partNumber: "12010973", pinCount: 6, description: "GT series" },
],
"Delphi Metripack": [
{ id: "mp150-2", name: "Metripack 150 2-pin", manufacturer: "Aptiv (Delphi)", partNumber: "12162825", pinCount: 2, description: "Metripack 150, sealed" },
{ id: "mp150-3", name: "Metripack 150 3-pin", manufacturer: "Aptiv (Delphi)", partNumber: "12162193", pinCount: 3, description: "Metripack 150, sealed" },
{ id: "mp280-2", name: "Metripack 280 2-pin", manufacturer: "Aptiv (Delphi)", partNumber: "12010973", pinCount: 2, description: "Metripack 280 (larger terminal, higher current)" },
{ id: "mp630-1", name: "Metripack 630 1-pin", manufacturer: "Aptiv (Delphi)", partNumber: "12110293", pinCount: 1, description: "Metripack 630, high current single contact" },
],
"Tesla (Proprietary / Approximate)": [
{
id: "tesla-hv23", name: "HV Battery 23-pin", manufacturer: "Tesla", partNumber: "Tesla OEM",
pinCount: 23, description: "Model S/X HV battery main connector (proprietary pinout — verify with service manual)",
pinLabels: ["HV+","HV+","HV","HV","SH","SH","HVIL+","HVIL","CAN H","CAN L","CANH2","CANL2","12V","GND","GND","TP","TP","TP","TP","TP","TP","TP","TP"],
},
{
id: "tesla-hvil2", name: "HV Interlock 2-pin", manufacturer: "Tesla", partNumber: "Tesla OEM",
pinCount: 2, description: "High voltage interlock loop", pinLabels: ["HVIL+", "HVIL"],
},
{
id: "tesla-charge-m3", name: "Charge Port (Model 3/Y)", manufacturer: "Tesla", partNumber: "Tesla OEM",
pinCount: 5, description: "AC charge port, Model 3 / Y (proprietary, similar to J1772)", pinLabels: ["L1","L2/N","GND","PP","CP"],
},
{
id: "tesla-can4", name: "CAN Bus 4-pin", manufacturer: "Tesla", partNumber: "Tesla OEM",
pinCount: 4, description: "Typical CAN bus connector (varies by model/year)", pinLabels: ["CAN H","CAN L","GND","12V"],
},
{
id: "tesla-hv2", name: "HV 2-pin (Phase)", manufacturer: "Tesla", partNumber: "Tesla OEM",
pinCount: 2, description: "HV 2-pin power connector (motor/inverter phase, approximate)", pinLabels: ["+",""],
},
],
"EV Charging Standards": [
{
id: "ev-j1772", name: "SAE J1772 Type 1", manufacturer: "Standard", partNumber: "SAE J1772",
pinCount: 5, description: "AC Level 1/2 charging — North America", pinLabels: ["L1","N","GND","PP","CP"],
},
{
id: "ev-type2", name: "IEC 62196 Type 2", manufacturer: "Standard", partNumber: "IEC 62196-2",
pinCount: 7, description: "AC charging — Europe / international", pinLabels: ["L1","L2","L3","N","GND","PP","CP"],
},
{
id: "ev-chademo", name: "CHAdeMO DC Fast", manufacturer: "Standard", partNumber: "CHAdeMO",
pinCount: 10, description: "DC fast charge (up to 400 A / 500 V)", pinLabels: ["DC+","DC","GND","CAN H","CAN L","Charge enable","Car ready","Charge stop","FG","Shield"],
},
{
id: "ev-ccs1", name: "CCS Combo 1 (DC)", manufacturer: "Standard", partNumber: "SAE J1772 CCS",
pinCount: 2, description: "CCS DC fast charge pins (2 large pins below J1772)", pinLabels: ["DC+","DC"],
},
],
"CAN / Network": [
{ id: "can-dt2", name: "CAN Deutsch 2-pin", manufacturer: "TE Connectivity", partNumber: "DT04-2P", pinCount: 2, description: "Deutsch DT 2-pin for CAN bus", pinLabels: ["CAN H","CAN L"] },
{ id: "can-j1939", name: "SAE J1939 9-pin", manufacturer: "Amphenol", partNumber: "HD10-9-1939P", pinCount: 9, description: "J1939 CAN heavy-vehicle datalink", pinLabels: ["Battery","+Battery","GND","CAN H","Shield","GND","CAN L","NC","NC"] },
{ id: "can-obd2", name: "OBD-II 16-pin", manufacturer: "Standard", partNumber: "SAE J1962", pinCount: 16, description: "On-board diagnostics port", pinLabels: ["Mfr","Mfr","GND","Mfr","Sig GND","CAN H","K-Line","Mfr","Bat+","Mfr","Mfr","Mfr","Mfr","CAN L","L-Line","OBD+"] },
],
"Deutsch DRC (Round)": [
{
id: "drc-30p", name: "DRC04-30P", manufacturer: "TE Connectivity",
partNumber: "DRC04-30P-A191", pinCount: 30, shape: "circular",
pinRings: [14, 10, 6],
description: "30-pin circular environmental plug (pin contacts), IP67, 1220 AWG",
},
{
id: "drc-30s", name: "DRC06-30S", manufacturer: "TE Connectivity",
partNumber: "DRC06-30S-A191", pinCount: 30, shape: "circular",
pinRings: [14, 10, 6],
description: "30-pin circular environmental socket (receptacle), IP67, 1220 AWG",
},
],
"General Automotive / EV": [
{ id: "ga-motor3", name: "Motor Phase 3-pin", manufacturer: "varies", partNumber: "varies", pinCount: 3, description: "3-phase motor connections", pinLabels: ["U","V","W"] },
{ id: "ga-res2", name: "Resolver 2-pin", manufacturer: "varies", partNumber: "varies", pinCount: 2, description: "Motor resolver position sensor", pinLabels: ["SIN","COS"] },
{ id: "ga-therm2", name: "Temperature Sensor 2-pin",manufacturer: "varies", partNumber: "varies", pinCount: 2, description: "NTC/PTC thermistor", pinLabels: ["SIG","GND"] },
{ id: "ga-hall3", name: "Hall Sensor 3-pin", manufacturer: "varies", partNumber: "varies", pinCount: 3, description: "Hall effect position sensor", pinLabels: ["VCC","GND","SIG"] },
{ id: "ga-batt2", name: "12 V Battery 2-pin", manufacturer: "varies", partNumber: "varies", pinCount: 2, description: "12 V battery / accessory supply", pinLabels: ["+12V","GND"] },
{ id: "ga-ctrlr4", name: "Controller 4-pin", manufacturer: "varies", partNumber: "varies", pinCount: 4, description: "Generic 4-pin controller interface", pinLabels: ["VCC","GND","SIG","EN"] },
{ id: "ga-fuse2", name: "Fuse Holder 2-pin", manufacturer: "varies", partNumber: "varies", pinCount: 2, description: "Inline fuse holder connections", pinLabels: ["IN","OUT"] },
{ id: "ga-relay5", name: "Relay 5-pin (SPDT)", manufacturer: "varies", partNumber: "varies", pinCount: 5, description: "SPDT automotive relay", pinLabels: ["85","86","30","87","87a"] },
],
};
// Build a flat lookup map for quick access by id
const _CONN_BY_ID = {};
for (const conns of Object.values(CONNECTOR_LIBRARY)) {
for (const c of conns) { _CONN_BY_ID[c.id] = c; }
}
function getConnectorById(id) { return _CONN_BY_ID[id] || null; }
function connectorToDevice(connId, diagramId) {
const conn = getConnectorById(connId);
if (!conn) return null;
const pinCount = conn.pinCount || 2;
if (conn.shape === "circular") {
const size = 140;
const cx = size / 2, cy = size / 2;
const pinR = size * 0.471; // pins outside the body circle (body uses 0.386 ratio)
const pins = Array.from({ length: pinCount }, (_, i) => {
const angle = -Math.PI / 2 + (2 * Math.PI * i / pinCount);
const x = cx + pinR * Math.cos(angle);
const y = cy + pinR * Math.sin(angle);
let side;
if (angle >= -3 * Math.PI / 4 && angle < -Math.PI / 4) side = "top";
else if (angle >= -Math.PI / 4 && angle < Math.PI / 4) side = "right";
else if (angle >= Math.PI / 4 && angle < 3 * Math.PI / 4) side = "bottom";
else side = "left";
return {
id: `pin_${i + 1}`,
name: conn.pinLabels ? (conn.pinLabels[i] || String(i + 1)) : String(i + 1),
side,
x_offset: Math.round(x * 10) / 10,
y_offset: Math.round(y * 10) / 10,
};
});
return {
diagram_id: diagramId,
device_type: "connector",
label: conn.name,
reference: "",
x: 200, y: 200,
width: size, height: size,
properties: {
pinCount,
shape: "circular",
pinRings: conn.pinRings || [],
orientation: "right",
partNumber: conn.partNumber || "",
manufacturer: conn.manufacturer || "",
connectorLibraryId: connId,
},
pins,
};
}
// Standard rectangular connector.
// Parts carrying pinSpecs (see partsLibrary.js) get their standard wire
// function stamped onto each pin, so wires drawn off them always come out the
// same colour, stripe and gauge.
const specs = conn.pinSpecs || null;
// Pass-through parts (bulkheads) present both faces of the same connector as
// one device: every circuit gets an IN pin on the left and an OUT pin on the
// right at the same height, sharing a single centred label. Wiring both sides
// of a bulkhead then needs one device, not a mated pair.
if (conn.passThrough) {
const w = 240;
const h = Math.max(60, pinCount * 18 + 24);
const pins = [];
(specs || Array.from({ length: pinCount })).forEach((spec, i) => {
const y = ((i + 1) / (pinCount + 1)) * h;
const base = {
name: spec ? spec.name : String(i + 1),
pin_number: spec ? spec.pin : String(i + 1),
wire_fn: spec ? spec.fn : null,
wire_oem: spec && spec.oem ? spec.oem : null,
note: spec ? spec.note : "",
};
pins.push({ ...base, id: `pin_${i + 1}_in`, side: "left", x_offset: 0, y_offset: y, center_label: true });
pins.push({ ...base, id: `pin_${i + 1}_out`, side: "right", x_offset: w, y_offset: y, hide_label: true });
});
return {
diagram_id: diagramId,
device_type: "connector",
label: conn.name,
reference: "",
x: 200, y: 200,
width: w, height: h,
properties: {
pinCount,
orientation: "right",
passThrough: true,
partNumber: conn.partNumber || "",
manufacturer: conn.manufacturer || "",
connectorLibraryId: connId,
standardPart: !!specs,
verifyPinout: !!conn.verify,
},
pins,
};
}
// Wide parts get two columns so a 20- or 32-way body stays readable.
const split = pinCount > 12;
const perSide = split ? Math.ceil(pinCount / 2) : pinCount;
const w = split ? 200 : 120;
const h = Math.max(60, perSide * 18 + 20);
const pins = Array.from({ length: pinCount }, (_, i) => {
const spec = specs ? specs[i] : null;
const onRight = !split || i >= perSide;
const idx = onRight && split ? i - perSide : i;
const count = onRight && split ? pinCount - perSide : perSide;
return {
id: `pin_${i + 1}`,
name: spec ? spec.name : (conn.pinLabels ? (conn.pinLabels[i] || String(i + 1)) : String(i + 1)),
side: onRight ? "right" : "left",
x_offset: onRight ? w : 0,
y_offset: ((idx + 1) / (count + 1)) * h,
// Standard-parts metadata — consumed by createWire() and the props panel.
pin_number: spec ? spec.pin : String(i + 1),
wire_fn: spec ? spec.fn : null,
wire_oem: spec && spec.oem ? spec.oem : null,
note: spec ? spec.note : "",
};
});
return {
diagram_id: diagramId,
device_type: "connector",
label: conn.name,
reference: "",
x: 200, y: 200,
width: w, height: h,
properties: {
pinCount,
orientation: "right",
partNumber: conn.partNumber || "",
manufacturer: conn.manufacturer || "",
connectorLibraryId: connId,
standardPart: !!specs,
verifyPinout: !!conn.verify,
},
pins,
};
}