// part.js — part detail. Left: a tabbed visualization (real 3D model / schematic symbol / footprint),
// all built from the curated data. Right: the full record (specs, pins, SPICE, downloads).
import { mountViewer } from '/assets/viewer.js';
const esc = (s) => (s == null ? '' : String(s).replace(/[&<>"]/g, (c) => ({ '&': '&', '<': '<', '>': '>', '"': '"' }[c])));
const id = new URLSearchParams(location.search).get('id');
function dl(name, text, mime = 'text/plain') { const a = document.createElement('a'); a.href = URL.createObjectURL(new Blob([text], { type: mime })); a.download = name; a.click(); }
function spendCredit() { let c = parseInt(localStorage.getItem('ppcb_credits') || '5', 10); if (c <= 0) { alert('Out of download credits — contribute a curated part to earn 5 more.'); return false; } localStorage.setItem('ppcb_credits', --c); document.getElementById('cred-n').textContent = c; return true; }
// ---- footprint SVG from real pad geometry (top-down, copper pads, pad numbers, outline) ----
function footprintSVG(p) {
const pads = p.footprint_pads || []; if (!pads.length) return '
no footprint data
';
let minx = 1e9, miny = 1e9, maxx = -1e9, maxy = -1e9;
for (const d of pads) { minx = Math.min(minx, d.x - d.w / 2); maxx = Math.max(maxx, d.x + d.w / 2); miny = Math.min(miny, d.y - d.h / 2); maxy = Math.max(maxy, d.y + d.h / 2); }
const m = Math.max(maxx - minx, maxy - miny) * 0.14 + 0.4;
minx -= m; miny -= m; maxx += m; maxy += m;
const vb = `${minx} ${miny} ${maxx - minx} ${maxy - miny}`;
const fs = Math.max((maxx - minx), (maxy - miny)) * 0.035;
let s = `';
}
// ---- schematic symbol from pins (labelled box; pins split L/R) ----
function schematicSVG(p) {
const pins = p.pins || []; if (!pins.length) return '
no pin data
';
const L = pins.filter((_, i) => i % 2 === 0), R = pins.filter((_, i) => i % 2 === 1);
const rows = Math.max(L.length, R.length), rh = 26, bw = 150, bx = 120, by = 40, bh = rows * rh + 20;
const W = bx + bw + 120, H = by + bh + 40;
let s = `';
}
window.ppcbReady(async () => {
const parts = await window.getCatalog();
const p = parts.find((x) => x.id === id);
const root = document.getElementById('root');
if (!p) { root.innerHTML = '