← Commit history
.gitignoreadded+6
@@ -0,0 +1,6 @@+*.step+viewer/adom-3d-viewer.min.js+viewer/sch-root.html+viewer/layout.html+viewer/board-detailed.glb+src/
README.htmladded+720
@@ -0,0 +1,720 @@+<meta charset="utf-8">+<title>Feeder Reader — Feeder Pin Input Module</title>+<style>+  :root{ --bg:#151b23; --card:#1b232d; --ink:#e8eef5; --dim:#9fb0c3; --dim2:#7f92a6;+         --line:rgba(255,255,255,.10); --acc:#22c55e; }+  *{box-sizing:border-box}+  body{margin:0;background:var(--bg);color:var(--ink);+    font-family:ui-sans-serif,-apple-system,"Segoe UI",Inter,system-ui,sans-serif;+    font-size:15px;line-height:1.62;-webkit-font-smoothing:antialiased}+  .wrap{max-width:960px;margin:0 auto;padding:0 24px}+  a{color:#7fb2ff;text-decoration:none} a:hover{text-decoration:underline}+  h2{font-size:13px;letter-spacing:.15em;text-transform:uppercase;color:var(--dim2);+     margin:56px 0 18px;font-weight:700}+  h3{font-size:16px;margin:0;font-weight:650}+  p{margin:0 0 15px}+  .lede{font-size:17px;line-height:1.65;color:#cfdae7}+  .mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12.5px}+  .dot{display:inline-block;width:9px;height:9px;border-radius:2px;margin-right:7px;vertical-align:0}++  /* ---------- viewer ---------- */+  .viewer-card{width:100%;background:#2a3340;border-bottom:1px solid var(--line);position:relative}+  .viewer-card iframe{width:100%;border:0;display:block}+  .viewer-hint{position:absolute;left:0;right:0;bottom:0;padding:7px 20px;font-size:11px;+    color:#8fa2b6;background:linear-gradient(transparent,rgba(10,15,22,.75));pointer-events:none}++  /* ---------- title ---------- */+  .title{padding:38px 0 6px}+  .title h1{font-size:38px;line-height:1.12;margin:0 0 6px;font-weight:680;letter-spacing:-.015em}+  .title .sub{font-size:15px;color:var(--dim);margin-bottom:18px}+  .facts{display:flex;flex-wrap:wrap;gap:7px;margin-bottom:20px}+  .facts span{background:var(--card);border:1px solid var(--line);border-radius:7px;+    padding:5px 10px;font-size:12px;color:#cfdae7}+  .facts span b{color:#fff;font-weight:600}+  .prov{background:rgba(59,130,246,.09);border:1px solid rgba(59,130,246,.28);+    border-radius:10px;padding:13px 15px;font-size:13px;color:#b9c7d7;margin:6px 0 8px}+  .prov b{color:#dce6f2}++  /* ---------- generic blocks ---------- */+  .grid2{display:grid;grid-template-columns:1fr 1fr;gap:16px}+  .card{background:var(--card);border:1px solid var(--line);border-radius:12px;padding:17px 19px}+  .card h3{margin-bottom:8px}+  .card p:last-child{margin-bottom:0}+  .sec{background:var(--card);border:1px solid var(--line);border-left:3px solid var(--c);+    border-radius:10px;padding:15px 17px;margin-bottom:11px}+  .sec-h{display:flex;align-items:center;gap:0;margin-bottom:7px}+  .sec-h .count{margin-left:auto;font-size:11.5px;color:var(--dim2);+    font-variant-numeric:tabular-nums}+  .sec p{margin:0 0 10px;font-size:14px;color:#c2d0de}+  .chips{display:flex;flex-wrap:wrap;gap:5px}+  .chip{background:rgba(255,255,255,.05);border:1px solid var(--line);border-radius:6px;+    padding:3px 8px;font:600 11.5px/1.4 ui-monospace,SFMono-Regular,Menlo,monospace;color:#dce6f2}+  .chip i{font-style:normal;color:var(--dim2);font-weight:400}++  table{width:100%;border-collapse:collapse;font-size:13.5px}+  th{text-align:left;font-size:11px;letter-spacing:.09em;text-transform:uppercase;+    color:var(--dim2);font-weight:700;padding:0 10px 8px 0;border-bottom:1px solid var(--line)}+  td{padding:8px 10px 8px 0;border-bottom:1px solid rgba(255,255,255,.05);vertical-align:top}+  td.num{font-variant-numeric:tabular-nums;color:var(--dim);width:34px}+  td.refs{color:var(--dim2);font-size:11.5px}+  .tag{display:inline-block;font:700 9.5px/1 inherit;letter-spacing:.06em;padding:3px 5px;+    border-radius:4px;vertical-align:1px;margin-left:6px}+  .tag.dnp{background:rgba(239,68,68,.16);color:#f8a6a6;border:1px solid rgba(239,68,68,.3)}++  figure{margin:0 0 18px}+  figure img{width:100%;display:block;background:#0b1220;border:1px solid var(--line);border-radius:10px}+  figcaption{font-size:12px;color:var(--dim2);margin-top:8px}+  .legend{display:flex;flex-wrap:wrap;gap:12px;margin:12px 0 0;font-size:12px;color:#c2d0de}+  .legend span{display:flex;align-items:center}++  .note{background:rgba(245,165,36,.08);border:1px solid rgba(245,165,36,.26);+    border-radius:10px;padding:13px 15px;font-size:13.5px;color:#e5d3b4;margin:0 0 14px}+  .note b{color:#f5d9a8}+  ul{margin:0 0 15px;padding-left:20px} li{margin-bottom:6px}+  footer{margin:64px 0 60px;padding-top:20px;border-top:1px solid var(--line);+    font-size:12px;color:var(--dim2)}+  @media (max-width:720px){ .grid2{grid-template-columns:1fr} .title h1{font-size:29px} }+</style>++<!-- ============================ VIEWER (the centrepiece) ============================ -->+<div class="viewer-card">+  <iframe id="board-viewer" title="Feeder Reader interactive board viewer"+    sandbox="allow-scripts" data-viewer-src="<meta charset=&quot;utf-8&quot;>+<title>Feeder Reader — interactive board viewer</title>+<meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1&quot;>+<style>+  :root{ --bg:#2a3340; --ink:#e8eef5; --dim:#9fb0c3; --line:rgba(255,255,255,.14); }+  *{box-sizing:border-box}+  html,body{margin:0;height:100%;background:var(--bg);color:var(--ink);+    font-family:ui-sans-serif,-apple-system,&quot;Segoe UI&quot;,Inter,system-ui,sans-serif;overflow:hidden}+  #app{position:absolute;inset:0}+  canvas{outline:none;display:block;width:100%;height:100%;touch-action:none}+  #status{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);color:var(--dim);+    font-size:13px;letter-spacing:.02em;text-align:center;pointer-events:none}+  .panel{position:absolute;background:rgba(16,22,31,.82);backdrop-filter:blur(9px);+    border:1px solid var(--line);border-radius:12px}++  /* mode switch */+  #modes{top:14px;left:50%;transform:translateX(-50%);display:flex;gap:2px;padding:3px;z-index:6}+  #modes button{appearance:none;background:transparent;border:0;color:var(--dim);cursor:pointer;+    font:600 12px/1 inherit;padding:8px 14px;border-radius:9px;letter-spacing:.02em}+  #modes button.on{background:rgba(255,255,255,.13);color:#fff}++  /* caption card */+  #caption{left:20px;bottom:64px;max-width:min(430px,42vw);padding:14px 16px;z-index:5;+    opacity:0;transition:opacity .45s ease;pointer-events:none}+  #caption.show{opacity:1}+  #caption .eyebrow{font:700 10px/1 inherit;letter-spacing:.14em;text-transform:uppercase;color:var(--dim);margin-bottom:7px}+  #caption .head{font:650 17px/1.3 inherit;margin-bottom:9px;color:#fff}+  #caption .rows{display:grid;grid-template-columns:auto 1fr;gap:3px 12px;font-size:12px;margin-bottom:9px}+  #caption .rows b{color:var(--dim);font-weight:500;white-space:nowrap}+  #caption .rows span{color:#dce6f2;font-variant-numeric:tabular-nums}+  #caption .note{font-size:12px;line-height:1.5;color:#b9c7d7}+  #caption .chip{display:inline-block;width:8px;height:8px;border-radius:2px;margin-right:7px;vertical-align:1px}+++  /* legend + layers */+  #legend{left:20px;top:64px;padding:11px 13px;z-index:5;font-size:11.5px}+  #legend h3{margin:0 0 8px;font:700 10px/1 inherit;letter-spacing:.14em;text-transform:uppercase;color:var(--dim)}+  #legend .row{display:flex;align-items:center;gap:8px;padding:3px 0;cursor:pointer;color:#c6d3e1}+  #legend .row:hover{color:#fff}+  #legend .row.off{opacity:.38}+  #legend .sw{width:9px;height:9px;border-radius:2px;flex:none}+  #legend .n{margin-left:auto;color:#7f92a6;font-variant-numeric:tabular-nums;font-size:10.5px}++  /* buttons + scrubber */+  .btn-row{position:absolute;right:20px;bottom:20px;display:flex;gap:7px;z-index:6}+  .btn{appearance:none;background:rgba(16,22,31,.82);border:1px solid var(--line);color:var(--dim);+    border-radius:9px;padding:8px 12px;font:600 11.5px/1 inherit;cursor:pointer;backdrop-filter:blur(9px)}+  .btn:hover{color:#fff}+  .btn.on{background:rgba(255,255,255,.15);color:#fff}+  #topbar{position:absolute;left:0;right:0;top:0;height:3px;background:rgba(255,255,255,.08);cursor:pointer;z-index:7}+  #topbar-fill{height:100%;width:0;background:linear-gradient(90deg,#3b82f6,#22c55e)}+  /* ticks only — the chapter NAME already leads the caption card, so labels here just+     collided with the mode switch */+  #marks{position:absolute;left:0;right:0;top:3px;height:6px;z-index:7;pointer-events:none}+  #marks i{position:absolute;top:0;width:1px;height:6px;background:rgba(255,255,255,.32)}+  #tip{position:absolute;pointer-events:none;z-index:8;padding:8px 10px;max-width:230px;+    background:rgba(10,15,22,.94);border:1px solid var(--line);border-radius:9px;+    font-size:11.5px;line-height:1.45;color:#dce6f2;opacity:0;transition:opacity .12s}+  #tip .t{font-weight:650;color:#fff;margin-bottom:3px}+  #tip .m{color:#8fa2b6;font-size:10.5px;font-variant-numeric:tabular-nums}+  @media (max-width:760px){ #legend{display:none!important} #caption{max-width:calc(100vw - 40px);bottom:58px} }+  /* embedded in a short frame the legend (top-left) and the caption (bottom-left) collide —+     the caption is the one that carries the narrative, so the legend yields */+  @media (max-height:640px){ #legend{display:none} }+</style>++<div id=&quot;app&quot;></div>+<div id=&quot;status&quot;>loading board…</div>+<div id=&quot;topbar&quot;><div id=&quot;topbar-fill&quot;></div></div>+<div id=&quot;marks&quot;></div>+<div class=&quot;panel&quot; id=&quot;modes&quot;></div>+<div class=&quot;panel&quot; id=&quot;legend&quot;><h3>Sections</h3><div id=&quot;legend-list&quot;></div></div>+<div class=&quot;panel&quot; id=&quot;caption&quot;><div class=&quot;eyebrow&quot;></div><div class=&quot;head&quot;></div><div class=&quot;rows&quot;></div><div class=&quot;note&quot;></div></div>+<div class=&quot;btn-row&quot;>+  <button class=&quot;btn&quot; id=&quot;btn-power&quot; style=&quot;display:none&quot;>⏻ Power</button>+  <button class=&quot;btn on&quot; id=&quot;btn-play&quot;>⏸ Pause</button>+  <button class=&quot;btn&quot; id=&quot;btn-replay&quot;>↺ Replay</button>+  <button class=&quot;btn on&quot; id=&quot;btn-ground&quot;>Ground</button>+  <button class=&quot;btn on&quot; id=&quot;btn-labels&quot;>Labels</button>+</div>+<div id=&quot;tip&quot;></div>++<script>+(async () => {+const statusEl = document.getElementById('status');++// Wiki blobs render SANDBOXED (no allow-same-origin) → localStorage/sessionStorage throw on+// ACCESS, which aborts the bundle's SceneBuilder (no lights/IBL/shadows). Shim before load.+for (const k of ['localStorage','sessionStorage']) {+  try { window[k] &amp;&amp; window[k].getItem('x'); }+  catch (e) { try { Object.defineProperty(window,k,{configurable:true,value:{getItem:()=>null,setItem:()=>{},removeItem:()=>{},clear:()=>{},key:()=>null,length:0}}); } catch(_){} }+}+// Blob storage serves .js as application/octet-stream + nosniff → <script src> is refused.+// Fetch as text, inject inline.+if (!window.Adom3DViewer) {+  try {+    const code = await (await fetch('https://wiki.adom.inc/blob/component/carrier-fc-rp2350a-mini/viewer/adom-3d-viewer.min.js?cap=__WIKICAP__')).text();+    const s = document.createElement('script'); s.textContent = code; document.head.appendChild(s);+  } catch (e) { statusEl.textContent = 'viewer bundle fetch failed: ' + e.message; return; }+}+const V = window.Adom3DViewer;+if (!V) { statusEl.textContent = 'Adom3DViewer bundle failed to load'; return; }+const B = V.BABYLON;++try {+// ---------------------------------------------------------------- config + index+const CFG = await (await fetch('https://wiki.adom.inc/blob/component/carrier-fc-rp2350a-mini/viewer/viewer-config.json?cap=__WIKICAP__',{cache:'no-store'})).json();+const IDX = await (await fetch('https://wiki.adom.inc/blob/component/carrier-fc-rp2350a-mini/viewer/board-index.json?cap=__WIKICAP__',{cache:'no-store'})).json();+const BLOCKS = CFG.blocks;+const BCOL   = Object.fromEntries(BLOCKS.map(b => [b.id, b.color]));+const BLAB   = Object.fromEntries(BLOCKS.map(b => [b.id, b.label]));++// ---------------------------------------------------------------- scene+const viewer = V.init(document.getElementById('app'), { zUp:true, showViewCube:true, showGround:true });+await viewer.loadModel('https://wiki.adom.inc/blob/component/carrier-fc-rp2350a-mini/viewer/board-detailed.glb?cap=__WIKICAP__');+const scene = viewer.getScene();+scene.animationGroups.slice().forEach(g => g.dispose());     // we drive all motion++// Match Colby's current native viewer: flat #2a3340, no skybox mesh, soft radial ground.+const bgBot = new B.Color3(0.165,0.200,0.251);+const Color4 = scene.clearColor &amp;&amp; scene.clearColor.constructor;+let _fade=null;+const groundFadeTex = () => {+  if (_fade) return _fade;+  const t=new B.DynamicTexture('groundFadeTex',256,scene,true), c=t.getContext();+  const g=c.createRadialGradient(128,128,6,128,128,128);+  g.addColorStop(0,'rgba(255,255,255,1)'); g.addColorStop(.55,'rgba(255,255,255,.6)'); g.addColorStop(1,'rgba(255,255,255,0)');+  c.fillStyle=g; c.fillRect(0,0,256,256); t.update(); t.hasAlpha=true; _fade=t; return t;+};+const matchColby = () => {+  if (Color4) scene.clearColor = new Color4(bgBot.r,bgBot.g,bgBot.b,1);+  scene.environmentIntensity = 1.0;+  scene.meshes.filter(m=>/^Background/.test(m.name)).forEach(m=>m.setEnabled(false));+  const gnd = scene.getMeshByName('shadowGround');+  if (gnd &amp;&amp; gnd.material) {+    const m = gnd.material;+    if (!(m.baseTexture &amp;&amp; m.baseTexture.name==='groundFadeTex')) {+      if ('baseTexture' in m) m.baseTexture = groundFadeTex();+      m.alpha=0.2; m.transparencyMode=2; m.backFaceCulling=false;+    }+    gnd.receiveShadows = true;+  }+};+matchColby();++// ---------------------------------------------------------------- group meshes+// Every mesh is named &quot;<block>|<ref>|<i>&quot; (transforms baked at export, so a plain+// position offset is a rigid move — see bake2.py).+const parts = new Map();          // ref -> {ref, blk, meshes[], home:Vector3, centre}+const byBlock = new Map();        // blk -> [part]+for (const m of scene.meshes) {+  const nm = (m.name||'').split('_primitive')[0];+  if (nm.indexOf('|') < 0) continue;+  const [blk, ref] = nm.split('|');+  m.rotationQuaternion = null;                       // glTF quaternion would override Euler+  let p = parts.get(ref);+  if (!p) { p = { ref, blk, meshes:[], home:m.position.clone() }; parts.set(ref, p); (byBlock.get(blk)||byBlock.set(blk,[]).get(blk)).push(p); }+  p.meshes.push(m);+}+for (const p of parts.values()) {+  let lo=null, hi=null;+  for (const m of p.meshes) {+    m.computeWorldMatrix(true);+    const bb = m.getBoundingInfo().boundingBox;+    lo = lo ? B.Vector3.Minimize(lo, bb.minimumWorld) : bb.minimumWorld.clone();+    hi = hi ? B.Vector3.Maximize(hi, bb.maximumWorld) : bb.maximumWorld.clone();+  }+  p.lo=lo; p.hi=hi; p.centre=lo.add(hi).scale(0.5); p.size=hi.subtract(lo);+}+const blockBox = blk => {+  let lo=null,hi=null;+  for (const p of (byBlock.get(blk)||[])) {+    lo = lo ? B.Vector3.Minimize(lo,p.lo) : p.lo.clone();+    hi = hi ? B.Vector3.Maximize(hi,p.hi) : p.hi.clone();+  }+  // fold in footprints that have no 3D body (feeder pads, switches, jumpers…)+  for (const f of Object.values(IDX.fps)) {+    if (f.blk!==blk || f.has3d) continue;+    const v=new B.Vector3(f.x,f.y,0.0015);+    lo = lo ? B.Vector3.Minimize(lo,v) : v.clone(); hi = hi ? B.Vector3.Maximize(hi,v) : v.clone();+  }+  return lo ? {lo,hi,c:lo.add(hi).scale(.5),s:hi.subtract(lo)} : null;+};+const SUB = ['PCB','COPPER','MASK','SILK'].map(r=>parts.get(r)).filter(Boolean);+const COMPONENTS = [...parts.values()].filter(p => p.blk!=='substrate');+statusEl.textContent = '';++// ---------------------------------------------------------------- camera+const cam = scene.activeCamera;+const home = { a:-Math.PI/2 - 0.55, b:0.92, r:0.165, t:new B.Vector3(0,0,0.004) };+const setCam = (o,ease) => {+  const tgt = { alpha:o.a, beta:o.b, radius:o.r, target:o.t };+  if (!ease) { cam.alpha=tgt.alpha; cam.beta=tgt.beta; cam.radius=tgt.radius; cam.target.copyFrom(tgt.target); return; }+  camGoal = tgt;+};+let camGoal = null, userHold = 0;+setCam(home,false);+cam.lowerRadiusLimit = 0.03; cam.upperRadiusLimit = 1.2; cam.wheelDeltaPercentage = 0.02;+// Depth-precision fix: the bundle's camera sets minZ = radius/1000, which makes one 24-bit+// depth step ~10 um at board-viewing distance — exactly the gap between mask/silk/copper+// sheets, so coplanar-ish layers shimmer. radius/100 gives ~1 um steps and the near plane is+// still only 0.3 mm out at the closest zoom. (Bake-side the layers are also nudged apart.)+scene.onBeforeRenderObservable.add(() => { cam.minZ = Math.max(cam.radius / 100, 2e-4); });+cam.panningSensibility = 6000;+// The camera is &quot;yours for 5 s&quot;: any drag/wheel pauses the scripted chase (assembly only),+// which then eases back — same convention as the single-component Timeline viewer. In static+// mode there is no scripted camera at all, so input is simply never fought.+['pointerdown','wheel'].forEach(ev => scene.getEngine().getRenderingCanvas()+  .addEventListener(ev, () => { userHold = 5; }, {passive:true}));++// ---------------------------------------------------------------- helpers+const emissive = (col, alpha) => {+  const m = new B.StandardMaterial('em'+Math.random(), scene);+  m.emissiveColor = col; m.diffuseColor = new B.Color3(0,0,0); m.specularColor = new B.Color3(0,0,0);+  m.disableLighting = true; m.alpha = alpha==null?1:alpha; if (alpha!=null) m.alphaMode = 1;+  return m;+};+const hex2c3 = h => new B.Color3(parseInt(h.slice(1,3),16)/255, parseInt(h.slice(3,5),16)/255, parseInt(h.slice(5,7),16)/255);++// Section outline boxes (wireframe) — one per block, hidden by default.+const outlines = new Map();+for (const b of BLOCKS) {+  const bb = blockBox(b.id); if (!bb) continue;+  const pad = 0.0018;+  const box = B.MeshBuilder.CreateBox('outline_'+b.id, {+    width: Math.max(bb.s.x,0.002)+pad*2, height: Math.max(bb.s.y,0.002)+pad*2, depth: Math.max(bb.s.z,0.002)+pad*2 }, scene);+  box.position.copyFrom(bb.c);+  const mt = emissive(hex2c3(b.color)); mt.wireframe = true; mt.alpha = .45; mt.alphaMode = 1;+  box.material = mt; box.isPickable = false; box.setEnabled(false);+  outlines.set(b.id, box);+}++// Static-mode visual function (AUTHOR-SPECIFIED, see viewer-config): e.g. the rail LEDs+// lighting when &quot;Power&quot; is toggled. Purely illustrative of the powered state.+const FN = (CFG.modes.static &amp;&amp; CFG.modes.static.functions &amp;&amp; CFG.modes.static.functions.power_leds) || null;+const glows = new Map();+let powerOn = !!(FN &amp;&amp; FN.default);+for (const ref of (FN ? FN.refs : [])) {+  const f = IDX.fps[ref]; if (!f) continue;+  const d = B.MeshBuilder.CreateBox('glow_'+ref, {width:.0028,height:.0028,depth:.0009}, scene);+  d.position.set(f.x, f.y, 0.0022); d.material = emissive(hex2c3(FN.color), .95); d.isPickable=false; d.setEnabled(false);+  glows.set(ref, d);+}++// DOM labels for sections+const labelLayer = document.createElement('div');+labelLayer.style.cssText = 'position:absolute;inset:0;pointer-events:none;z-index:4';+document.body.appendChild(labelLayer);+const labels = new Map();+for (const b of BLOCKS) {+  const bb = blockBox(b.id); if (!bb) continue;+  const el = document.createElement('div');+  el.style.cssText = 'position:absolute;transform:translate(-50%,-50%);font:650 10.5px/1 ui-sans-serif,system-ui;'++    'letter-spacing:.03em;padding:3px 7px;border-radius:6px;white-space:nowrap;opacity:0;transition:opacity .3s;'++    'background:rgba(10,15,22,.82);border:1px solid '+b.color+'66;color:'+b.color;+  el.textContent = b.label;+  labelLayer.appendChild(el); labels.set(b.id, {el, pos:bb.c.clone()});+}+let labelsOn = true;+// Only ONE section label is drawn at a time — the block the current chapter is about.+// (Blocks overlap heavily in plan view: feeder-io alone spans the whole board, so every+// centroid lands near the middle and all eight labels stack on top of each other.)+let focusBlk = null, hoverBlk = null;++// ---------------------------------------------------------------- visibility control+const setPartVis = (p, v) => { for (const m of p.meshes) m.visibility = v; };+const showAllComponents = v => COMPONENTS.forEach(p => setPartVis(p, v));+const layerOn = { PCB:true, COPPER:true, SILK:true, MASK:true };+const blockOn = Object.fromEntries(BLOCKS.map(b=>[b.id,true]));+const applyLayers = () => {+  for (const p of SUB) { const on = layerOn[p.ref]!==false; p.meshes.forEach(m=>m.setEnabled(on)); }+  for (const p of COMPONENTS) { const on = blockOn[p.blk]!==false; p.meshes.forEach(m=>m.setEnabled(on)); }+};++// ---------------------------------------------------------------- legend+const legendList = document.getElementById('legend-list');+const counts = {};+for (const f of Object.values(IDX.fps)) counts[f.blk] = (counts[f.blk]||0)+1;+for (const b of BLOCKS) {+  const row = document.createElement('div'); row.className='row';+  row.innerHTML = `<span class=&quot;sw&quot; style=&quot;background:${b.color}&quot;></span><span>${b.label}</span><span class=&quot;n&quot;>${counts[b.id]||0}</span>`;+  row.onclick = () => { blockOn[b.id] = !blockOn[b.id]; row.classList.toggle('off', !blockOn[b.id]); applyLayers(); };+  row.onmouseenter = () => { hoverBlk = b.id; outlines.get(b.id)?.setEnabled(true); };+  row.onmouseleave = () => { hoverBlk = null; if (focusBlk!==b.id) outlines.get(b.id)?.setEnabled(false); };+  legendList.appendChild(row);+}+const subRow = document.createElement('div'); subRow.className='row';+subRow.innerHTML = `<span class=&quot;sw&quot; style=&quot;background:#b78227&quot;></span><span>Copper &amp;amp; silkscreen</span><span class=&quot;n&quot;>4</span>`;+subRow.onclick = () => { const on = !(layerOn.COPPER &amp;&amp; layerOn.SILK); layerOn.COPPER=layerOn.SILK=on; subRow.classList.toggle('off',!on); applyLayers(); };+legendList.appendChild(subRow);++// ---------------------------------------------------------------- caption+const capEl = document.getElementById('caption');+const showCap = (c) => {+  if (!c) { capEl.classList.remove('show'); return; }+  const dot = c.block ? `<span class=&quot;chip&quot; style=&quot;background:${BCOL[c.block]}&quot;></span>` : '';+  capEl.querySelector('.eyebrow').innerHTML = dot + (c.eyebrow||'');+  capEl.querySelector('.head').textContent = c.head||'';+  capEl.querySelector('.rows').innerHTML = (c.rows||[]).map(r=>`<b>${r[0]}</b><span>${r[1]}</span>`).join('');+  capEl.querySelector('.note').textContent = c.note||'';+  capEl.classList.add('show');+};+let lastCapKey = null;+const showCapOnce = (key,c) => { if (key!==lastCapKey) { lastCapKey=key; showCap(c); } };++// ---------------------------------------------------------------- modes+const A = CFG.modes.assembly, S = CFG.modes.static;+// Assembly schedule — the GROUP is the unit: all of a grouping's parts fall together+// (tiny in-group stagger for texture) while that grouping's caption explains it.+const T = A.timing;+const sched = [];                 // {p, t, blk} — individual part drops+const groups = [];                // {id, t0, t1} — caption/camera windows+let tA = (A.intro &amp;&amp; A.intro.d) || 6;+for (const bid of A.order) {+  const ps = (byBlock.get(bid)||[]).slice().sort((p,q)=>p.centre.x-q.centre.x);+  ps.forEach((p,i)=> sched.push({p, t: tA + i*T.stagger_s, blk:bid}));+  const dwell = (A.captions[bid] &amp;&amp; A.captions[bid].d) || T.dwell_s;+  groups.push({ id: bid, t0: tA, t1: tA + dwell });+  tA += dwell;+}+const A_LEN = tA + T.rest_s;+const LEN = { assembly: A_LEN, static: 1 };   // static has NO timeline++let mode = 'assembly', t = 0, playing = true;++const modesEl = document.getElementById('modes');+for (const k of ['assembly','static']) {+  const b = document.createElement('button'); b.textContent = CFG.modes[k].label; b.dataset.k = k;+  b.onclick = () => setMode(k);+  modesEl.appendChild(b);+}+const marksEl = document.getElementById('marks');+function drawMarks() {+  marksEl.innerHTML = '';+  if (mode!=='assembly') return;+  for (const g of groups) marksEl.insertAdjacentHTML('beforeend', `<i style=&quot;left:${100*g.t0/A_LEN}%&quot;></i>`);+}+function setMode(k) {+  mode = k; t = 0; lastCapKey = null; camGoal = null; userHold = 0; focusBlk = null;+  [...modesEl.children].forEach(b => b.classList.toggle('on', b.dataset.k===k));+  outlines.forEach(o => o.setEnabled(false));+  COMPONENTS.forEach(p => { setPartVis(p, k==='assembly' ? 0 : 1);+                            p.meshes.forEach(m => m.position.copyFrom(p.home)); });+  // static: no timeline, no scripted camera — the camera is entirely the user's+  const isA = k==='assembly';+  document.getElementById('topbar').style.display = isA ? 'block' : 'none';+  document.getElementById('btn-play').style.display = isA ? '' : 'none';+  document.getElementById('btn-replay').style.display = isA ? '' : 'none';+  document.getElementById('btn-power').style.display = (!isA &amp;&amp; FN) ? '' : 'none';+  glows.forEach(g => g.setEnabled(!isA &amp;&amp; powerOn));+  setCam(home,false);+  drawMarks(); applyLayers(); showCap(null);+  if (!isA &amp;&amp; S.blurb) showCap({ eyebrow:'Static', head:'Inspect the board', note:S.blurb });+}++// ---------------------------------------------------------------- render loop+// B exposes only MeshBuilder/StandardMaterial/Vector3/Color3/DynamicTexture — Matrix is NOT+// on it (§5b). Harvest it from a live instance instead of reaching for B.Matrix.+const Matrix = scene.getTransformMatrix().constructor;+const IDM = Matrix.Identity();+const worldToScreen = (v) => {+  try {+    const e = scene.getEngine();+    return B.Vector3.Project(v, IDM, scene.getTransformMatrix(),+      cam.viewport.toGlobal(e.getRenderWidth(), e.getRenderHeight()));+  } catch (_) { return null; }+};+let last = performance.now();+scene.onBeforeRenderObservable.add(() => {+  const now = performance.now(); const dt = Math.min((now-last)/1000, .05); last = now;+  if (playing) t = (t + dt) % LEN[mode];+  if (userHold > 0) userHold -= dt;++  // camera easing — assembly only; static never steers+  if (mode==='assembly' &amp;&amp; camGoal &amp;&amp; userHold <= 0 &amp;&amp;+      Number.isFinite(camGoal.alpha) &amp;&amp; Number.isFinite(camGoal.beta) &amp;&amp; Number.isFinite(camGoal.radius)) {+    const k = 1 - Math.pow(0.0016, dt);+    cam.alpha  += (camGoal.alpha  - cam.alpha)  * k;+    cam.beta   += (camGoal.beta   - cam.beta)   * k;+    cam.radius += (camGoal.radius - cam.radius) * k;+    cam.target.x += (camGoal.target.x - cam.target.x) * k;+    cam.target.y += (camGoal.target.y - cam.target.y) * k;+    cam.target.z += (camGoal.target.z - cam.target.z) * k;+  }+  if (mode==='assembly' &amp;&amp; userHold <= 0) cam.alpha += dt * 0.005;   // gentle drift++  if (mode === 'assembly') {+    // drops+    for (const d of sched) {+      const u = (t - d.t) / T.fall_s;+      if (u < 0) { setPartVis(d.p, 0); continue; }+      const k = Math.min(u, 1), e = 1 - Math.pow(1-k, 3);      // easeOutCubic+      setPartVis(d.p, Math.min(1, k*2.2));+      const dz = (1-e) * T.drop_height_mm/1000;+      for (const m of d.p.meshes) { m.position.copyFrom(d.p.home); m.position.z += dz; }+    }+    // caption + focus + camera per GROUP window (intro before, rest after)+    const g = groups.find(g => t>=g.t0 &amp;&amp; t<g.t1);+    if (t < groups[0].t0) {+      showCapOnce('a-intro', A.intro); focusBlk = null;+      outlines.forEach((o,id)=>o.setEnabled(id===hoverBlk));+      camGoal = { alpha:home.a, beta:home.b, radius:home.r, target:home.t };+    } else if (g) {+      const c = A.captions[g.id] || {};+      showCapOnce('a'+g.id, { ...c, block:g.id });+      focusBlk = g.id;+      outlines.forEach((o,id)=>o.setEnabled(id===g.id || id===hoverBlk));+      const bb = blockBox(g.id);+      if (bb) camGoal = { alpha: home.a + 0.25*Math.sin(t*0.12), beta: 0.86,+                          radius: Math.max(0.105, Math.min(0.24, bb.s.length()*2.6)),+                          target: bb.c };+    } else {           // rest: whole board seated+      showCapOnce('a-rest', null); focusBlk = null;+      outlines.forEach((o,id)=>o.setEnabled(id===hoverBlk));+      camGoal = { alpha:home.a, beta:home.b, radius:home.r, target:home.t };+    }+  }+  // static mode: nothing per-frame — no timeline, no captions changing, no camera goals.+  // Hover tooltips, legend isolate, labels and the Power toggle all work event-driven.++  // scrub + labels+  if (mode==='assembly') document.getElementById('topbar-fill').style.width = (100*t/A_LEN) + '%';+  for (const [id, L] of labels) {+    const vis = labelsOn &amp;&amp; blockOn[id]!==false &amp;&amp; (id===focusBlk || id===hoverBlk);+    if (!vis) { L.el.style.opacity = 0; continue; }+    const p = worldToScreen(L.pos);+    if (!p || p.z > 1 || p.z < 0) { L.el.style.opacity = 0; continue; }+    L.el.style.left = p.x+'px'; L.el.style.top = p.y+'px'; L.el.style.opacity = 0.92;+  }+});++// ---------------------------------------------------------------- hover tooltip+const tipEl = document.getElementById('tip');+scene.getEngine().getRenderingCanvas().addEventListener('pointermove', ev => {+  const pick = scene.pick(scene.pointerX, scene.pointerY, m => (m.name||'').indexOf('|')>=0);+  if (!pick || !pick.hit) { tipEl.style.opacity = 0; return; }+  const nm = pick.pickedMesh.name.split('_primitive')[0];+  const [blk, ref] = nm.split('|');+  const f = IDX.fps[ref];+  const p = parts.get(ref);+  const mm = v => (v*1000).toFixed(2);+  if (blk === 'substrate') {+    tipEl.innerHTML = `<div class=&quot;t&quot;>Bare board</div><div class=&quot;m&quot;>130.00 × 50.00 mm · 1.6 mm · 4 layers<br>`++      `${{PCB:'FR-4 substrate',COPPER:'copper (all 4 layers)',MASK:'soldermask',SILK:'silkscreen'}[ref]||ref}</div>`;+  } else if (f) {+    tipEl.innerHTML = `<div class=&quot;t&quot;>${ref} · ${f.val}</div>`++      `<div class=&quot;m&quot;>${f.fp}<br>${BLAB[blk]||blk} · ${f.layer==='F.Cu'?'top':'bottom'} · ${f.rot?f.rot+'°':'0°'}`++      (p? `<br>extent ${mm(p.size.x)} × ${mm(p.size.y)} × ${mm(p.size.z)} mm` : '')+`</div>`;+  } else return;+  tipEl.style.opacity = 1;+  tipEl.style.left = Math.min(ev.clientX+14, innerWidth-244)+'px';+  tipEl.style.top  = Math.min(ev.clientY+14, innerHeight-90)+'px';+});+scene.getEngine().getRenderingCanvas().addEventListener('pointerleave', ()=> tipEl.style.opacity=0);++// ---------------------------------------------------------------- controls+document.getElementById('btn-play').onclick = e => { playing=!playing; e.target.classList.toggle('on',playing); e.target.textContent = playing?'⏸ Pause':'▶ Play'; };+document.getElementById('btn-replay').onclick = () => { t=0; lastCapKey=null; if(mode==='assembly') COMPONENTS.forEach(p=>setPartVis(p,0)); };+document.getElementById('btn-ground').onclick = e => {+  const g = scene.getMeshByName('shadowGround'); if (!g) return;+  const on = !g.isEnabled(); g.setEnabled(on); e.target.classList.toggle('on',on); matchColby();+};+document.getElementById('btn-labels').onclick = e => { labelsOn=!labelsOn; e.target.classList.toggle('on',labelsOn); };+document.getElementById('btn-power').onclick = e => {+  powerOn = !powerOn; e.target.classList.toggle('on', powerOn);+  glows.forEach(g => g.setEnabled(mode!=='assembly' &amp;&amp; powerOn));+};+document.getElementById('topbar').onclick = ev => { if (mode==='assembly') { t = A_LEN * (ev.clientX/innerWidth); lastCapKey=null; } };++// debug handle (harmless; also handy from the console)+window.__dbg = { parts, COMPONENTS, byBlock, sched, groups, outlines, labels, cam,+                 get t(){return t}, set t(v){t=v; lastCapKey=null;},+                 get mode(){return mode}, get focus(){return focusBlk},+                 setMode, A_LEN, LEN,+                 // jump the camera straight to its goal — the eased chase needs many frames,+                 // and headless swiftshader renders this board at well under 1 fps.+                 snap(){ if (camGoal) { cam.alpha=camGoal.alpha; cam.beta=camGoal.beta;+                          cam.radius=camGoal.radius; cam.target.copyFrom(camGoal.target); } },+                 pause(){ playing=false; }, play(){ playing=true; } };++setMode('assembly');+addEventListener('resize', () => scene.getEngine().resize());++} catch (err) {+  statusEl.textContent = 'viewer error: ' + (err &amp;&amp; err.message ? err.message : err);+  console.error(err);+}+})();+</script>+"></iframe>+<script>+/* wiki#73 caps: the injected bootstrap patches THIS document, but a sandboxed srcdoc child is a+   separate document with its own unpatched fetch and no __wikiCap. The bootstrap is appended at+   the END of the served document, so wait for it before substituting the cap into the template. */+(function(){+  var tries=0;+  function go(){+    var f=document.getElementById('board-viewer'); if(!f) return;+    var tpl=f.getAttribute('data-viewer-src'); if(!tpl) return;+    var cap=window.__wikiCap||'';+    if(!cap && tries++ < 60) return setTimeout(go,50);+    f.srcdoc=tpl.replace(/__WIKICAP__/g,cap);+    f.removeAttribute('data-viewer-src');+    /* The bootstrap rewrites img/source/video/audio srcs, but NOT iframe srcs — an iframe load is+       a navigation, so a self-contained app embed on a private page needs the cap appended here. */+    Array.prototype.forEach.call(document.querySelectorAll('iframe[data-cap-src]'),function(el){+      var u=el.getAttribute('data-cap-src');+      /* Mirror the wiki bootstrap's own needs()/add() semantics exactly, rather than inventing+         our own: (1) never touch data:/blob:/#/javascript:, (2) SAME-HOST only - compared against+         location.host, not a hardcoded domain, so it holds on any deployment, (3) emit a RELATIVE+         url so the token cannot ride a redirect to another origin. The cap is a bearer credential+         for this page's files; handing it to a third-party origin would be a real leak. */+      var out=u;+      try {+        if (!/^(data:|blob:|#|javascript:)/i.test(u)) {+          var a=new URL(u, location.href);+          if (cap && a.host===location.host && !a.searchParams.has('cap')) {+            a.searchParams.set('cap', cap);+            out = a.pathname + a.search + a.hash;+          }+        }+      } catch(e) { out=u; }+      el.src = out;+      el.removeAttribute('data-cap-src');+    });+  }+  if(document.readyState==='loading') document.addEventListener('DOMContentLoaded',go); else go();+})();+</script>+  <div class="viewer-hint">Assembly — each grouping drops in while its caption explains it · Static — the camera is yours — drag to orbit, scroll to zoom, hover any part</div>+</div>++<div class="wrap">+  <div class="title">+    <h1>FC Carrier (RP2350A-Mini)</h1>+    <div class="sub">Carrier-FC-RP2350A-Mini v1.0 · flight-controller carrier for the single-motor cell</div>+    <div class="facts">+      <span><b>38.8 × 70.8</b> mm</span><span><b>4</b>-layer, 1.6 mm</span>+      <span><b>32 × 64</b> mm datum</span><span><b>hosts</b> RP2350A-Mini</span>+    </div>+  </div>++  <h2>What it does</h2>+  <p>Hosts the <b>RP2350A-Mini</b> flight controller, bridges 5&nbsp;V to two loads, monitors the 5&nbsp;V+  rail into the mini's ADC, and carries a <b>hardware E-stop</b> that drives the ESC's brake line in+  silicon. It breaks out all of the cell's I/O to the flight controller across a 32&nbsp;×&nbsp;64&nbsp;mm+  machine-pin datum.</p>++  <h2>The board, section by section</h2>++  <h3>Flight-controller nest</h3>+  <p><b>U2 — the RP2350A-Mini molecule</b> seats here as a populated sub-assembly. The RP2350 has two+  UARTs, two SPI, two I²C and PIO; the cell needs three UARTs, so <span class="mono">UART0 → ESC</span>+  (carries AM32 flashing) and <span class="mono">UART1 → motor module</span> (carries DFU flashing) are on+  the hardware UARTs, and PIO drives the RX module, DSHOT and a WS2812 — 18 of 28 broken-out GPIO used.</p>++  <h3>Power in / protect</h3>+  <p>5&nbsp;V enters at the contacts, is clamped by a <b>SMF6.0A TVS (D1)</b> and bulked (a 22&nbsp;µF plus+  four 10&nbsp;µF distributed on the rail, 10&nbsp;µF per VBUS out), and an <b>AP2112K-3.3 (U1)</b> makes the+  3.3&nbsp;V the mini runs on. "5&nbsp;V Present" is indicated.</p>++  <h3>E-stop</h3>+  <p>A <b>hardware</b> E-stop: <b>SW2</b> drives the ESC's brake line (<span class="mono">TIM1_BKIN</span>),+  killing the gate outputs in silicon — not in firmware. A red indicator (LED1, ≈0.48&nbsp;mA) shows its+  state.</p>++  <h3>Reset</h3>+  <p>A local reset tact, <b>SW1</b> (SKRPACE010), with its FC_RST idle fixed by a 10&nbsp;k / 100&nbsp;n RC+  against the mini's internal pull-up.</p>++  <h3>Status LEDs</h3>+  <p><b>LED2</b> is a <b>WS2812B-2020</b> addressable RGB used for STATUS; <b>LED3</b> is a green+  5&nbsp;V-present indicator (≈0.48&nbsp;mA); <b>LED1</b> is the red E-stop indicator. LED currents are as+  annotated on the schematic. <span class="prov">Illustrative: the <em>Power</em> toggle in Static mode+  lights these.</span></p>++  <h3>5&nbsp;V monitor</h3>+  <p>A 51&nbsp;k / 51&nbsp;k divider (+ 100&nbsp;n) drops the 5&nbsp;V rail to <b>2.50&nbsp;V at 5.00&nbsp;V+  in</b> for the mini's <span class="mono">ADC2</span> — no buffer needed, the ADC's effective impedance is+  over 100&nbsp;kΩ even at 500&nbsp;kS/s.</p>++  <h3>Debug</h3>+  <p><b>J1</b> is a <b>BM03B-SRSS-TB</b> JST connector — the SWD debug landing.</p>++  <h3>Machine pins</h3>+  <p>The <b>32&nbsp;×&nbsp;64&nbsp;mm machine-pin datum</b> locates the carrier and breaks out the cell I/O;+  the external contacts carry the passives noted on the schematic (pull-ups/downs for the ToF INT/EN, bulk+  per VBUS out).</p>++  <h2>Layout</h2>+  <p>Interactive PCB — click any pad, trace or zone to highlight its whole net; hover for pad and live part data.</p>+  <div class="embed-card">+    <iframe class="app-embed" title="FC carrier — interactive PCB layout" loading="lazy"+      data-cap-src="https://wiki.adom.inc/blob/component/carrier-fc-rp2350a-mini/viewer/layout.html"+      style="width:100%;height:720px;border:0;display:block;background:#1b232d"></iframe>+  </div>++  <h2>Schematic</h2>+  <p>Interactive schematic — hover a symbol for its KiCad highlight plus live MPN / stock / price / LCSC.</p>+  <div class="embed-card">+    <iframe class="app-embed" title="FC carrier — interactive schematic" loading="lazy"+      data-cap-src="https://wiki.adom.inc/blob/component/carrier-fc-rp2350a-mini/viewer/sch-root.html"+      style="width:100%;height:720px;border:0;display:block;background:#fff"></iframe>+  </div>++  <h2>How this page was built</h2>+  <ul>+    <li><b>Generated from the design files.</b> Model, sections and part list derive from+    <span class="mono">carrier-fc-rp2350a-mini.kicad_pcb</span> / the schematic / the STEP export. Coverage:+    265 solids, 80 refs, all resolved.</li>+    <li><b>Author-asserted.</b> The narrative (peripheral allocation, E-stop path, monitor divider) comes+    from the designer's schematic notes and the project overview.</li>+    <li><b>Illustrative.</b> The Static-mode Power toggle is a visual aid.</li>+    <li><b>LEDs.</b> The red and green 0402 indicators use the Adom <span class="mono">in-s42atr</span> LED+    model recoloured per value; the WS2812 keeps its real geometry.</li>+  </ul>++  <footer>+    FC Carrier (RP2350A-Mini) · Carrier-FC-RP2350A-Mini v1.0 · drawn in KiCad · board page generated from+    <span class="mono">carrier-fc-rp2350a-mini.kicad_pcb</span>.<br>+    Interactive viewer built on the Adom 3D viewer bundle.+  </footer>+</div>++<script>+  // Self-sizing (publish skill §8k-0b): the wiki's app.js listens for `readme-height` and grows+  // #readme-frame to fit, which is what makes this one seamless full-page document.+  (function () {+    var f = document.getElementById('board-viewer');+    // the sandbox cannot read the parent viewport, so size the viewer off the screen+    f.style.height = Math.max(520, (screen.availHeight || 900) - 200) + 'px';+    function post() {+      var h = document.documentElement.scrollHeight;+      parent.postMessage({ type: 'readme-height', height: h }, '*');+    }+    addEventListener('load', post); addEventListener('resize', post);+    setTimeout(post, 400); setTimeout(post, 1600);+  })();+</script>
carrier-fc-rp2350a-mini.glbadded
⋯ 1 unchanged line ⋯
package.jsonadded+1
@@ -0,0 +1 @@+{"slug":"carrier-fc-rp2350a-mini","version":"1.0.0","type":"component","description":"Flight-controller carrier for the drone motor cell: hosts the RP2350A-Mini, bridges 5 V, monitors the rail to the mini ADC, carries a hardware E-stop into the ESC brake. 38.8 x 70.8 mm, 4-layer.","tags":["molecule","board","kicad","carrier","rp2350","flight-controller","e-stop","adom-machine-pins","drone"],"component":{"mpn":"carrier-fc-rp2350a-mini","manufacturer":"Adom","package":"PCBA 38.8 x 70.8 mm, 4-layer","category":"board","model_3d_path":"carrier-fc-rp2350a-mini.glb"},"dependencies":{},"hero":{"type":"image","path":"screenshots/hero.png"}}
screenshots/hero.pngadded
⋯ 1 unchanged line ⋯
viewer/board-index.jsonadded+2410
@@ -0,0 +1,2410 @@+{+"groups": {+"substrate|PCB": {+"blk": "substrate",+"ref": "PCB",+"lo": [+-0.01939999967366314,+-0.035400001163618085,+0.0+],+"hi": [+0.01939999960810089,+0.03539999963806439,+0.0015162000199779868+],+"n": 1+},+"substrate|MASK": {+"blk": "substrate",+"ref": "MASK",+"lo": [+-0.01939999967366314,+-0.035400001163618085,+-6.499999873689376e-05+],+"hi": [+0.01939999960810089,+0.03539999963806439,+0.0015812000514566899+],+"n": 2+},+"substrate|SILK": {+"blk": "substrate",+"ref": "SILK",+"lo": [+-0.018724999423323632,+-0.03504999896420669,+0.0016062000089883805+],+"hi": [+0.019049999271334647,+0.035049999301298145,+0.0016062000089883805+],+"n": 1+},+"substrate|COPPER": {+"blk": "substrate",+"ref": "COPPER",+"lo": [+-0.01900000035315609,+-0.03509509732855987,+-3.9999998989515007e-05+],+"hi": [+0.019100000117720603,+0.034900000487430576,+0.0015561999753117561+],+"n": 1+},+"pins|MC22": {+"blk": "pins",+"ref": "MC22",+"lo": [+-0.006335000074653386,+0.005566365428710908,+-4.880002234131098e-05+],+"hi": [+0.01843500011814901,+0.018308634863677054,+0.004236100013107061+],+"n": 2+},+"reset|SW1": {+"blk": "reset",+"ref": "SW1",+"lo": [+-0.0029697674654409916,+-0.012755000446015418,+0.0013915287152788368+],+"hi": [+0.014899999685400664,+0.02174892642626035,+0.0067360999572277066+],+"n": 2+},+"pins|MC31": {+"blk": "pins",+"ref": "MC31",+"lo": [+-0.008335000402478934,+-0.02443363273658362,+-4.880002234131098e-05+],+"hi": [+0.01843500011814901,+0.00030863447438421975,+0.004236100013107061+],+"n": 2+},+"pins|MC11": {+"blk": "pins",+"ref": "MC11",+"lo": [+0.007665000357480287,+0.007441365561424374,+-4.880002234131098e-05+],+"hi": [+0.01843500011814901,+0.022433634550287008,+0.004236100013107061+],+"n": 2+},+"pins|MC34": {+"blk": "pins",+"ref": "MC34",+"lo": [+-0.008335000402478936,+-0.006558634405048011,+-4.880002234131098e-05+],+"hi": [+-0.005566365583984614,+0.0344350001481125,+0.004236100013107061+],+"n": 2+},+"power|R3": {+"blk": "power",+"ref": "R3",+"lo": [+-0.005330330197225145,+0.013384669842368222,+0.0016311999687179924+],+"hi": [+0.016349999637856646,+0.021000000758538574,+0.0045861000006273385+],+"n": 6+},+"reset|C8": {+"blk": "reset",+"ref": "C8",+"lo": [+0.0024900000389213987,+-0.0067249997579729255,+0.0016311999687179924+],+"hi": [+0.016349999637856646,+0.01802000041909012,+0.004736100036855787+],+"n": 4+},+"pins|MC26": {+"blk": "pins",+"ref": "MC26",+"lo": [+-0.008335000402478933,+-0.0024336347184380587,+-4.880002234131098e-05+],+"hi": [+0.01843500011814901,+0.010308634483697447,+0.004236100013107061+],+"n": 2+},+"pins|MC9": {+"blk": "pins",+"ref": "MC9",+"lo": [+0.007665000357480287,+0.003441365371434569,+-4.880002234131098e-05+],+"hi": [+0.018433634682839303,+0.024435000371629923,+0.004236100013107061+],+"n": 2+},+"pins|MC38": {+"blk": "pins",+"ref": "MC38",+"lo": [+-0.00633500007465339,+-0.014558633853705049,+-4.880002234131098e-05+],+"hi": [+0.01843500011814901,+-0.009566365980101198,+0.004236100013107061+],+"n": 2+},+"pins|MC10": {+"blk": "pins",+"ref": "MC10",+"lo": [+0.007665000357480287,+0.005441365699260115,+-4.880002234131098e-05+],+"hi": [+0.01843500011814901,+0.026433635205938104,+0.004236100013107061+],+"n": 2+},+"pins|MC25": {+"blk": "pins",+"ref": "MC25",+"lo": [+-0.008335000402478933,+-0.0004336343906125124,+-4.880002234131098e-05+],+"hi": [+0.01843500011814901,+0.012308634811522993,+0.004236100013107061+],+"n": 2+},+"pins|MC30": {+"blk": "pins",+"ref": "MC30",+"lo": [+-0.008335000402478934,+-0.022433634271403224,+-4.880002234131098e-05+],+"hi": [+0.01843500011814901,+0.002308634527542366,+0.004236100013107061+],+"n": 2+},+"reset|R2": {+"blk": "reset",+"ref": "R2",+"lo": [+0.0007499999446343029,+-0.004269999719947025,+0.0016311999687179924+],+"hi": [+0.014390000982490866,+0.008575000212038487,+0.0045861000006273385+],+"n": 6+},+"pins|MC14": {+"blk": "pins",+"ref": "MC14",+"lo": [+-0.018433634748401553,+-0.01843500091370699,+-4.880002234131098e-05+],+"hi": [+0.008535000346416176,+0.014308634208025962,+0.004236100013107061+],+"n": 2+},+"pins|MC37": {+"blk": "pins",+"ref": "MC37",+"lo": [+-0.008335000402478936,+-0.012558634457202077,+-4.880002234131098e-05+],+"hi": [+0.01843500011814901,+-0.01156636537660417,+0.004236100013107061+],+"n": 2+},+"pins|MC3": {+"blk": "pins",+"ref": "MC3",+"lo": [+0.007665000357480285,+-0.00855863473287356,+-4.880002234131098e-05+],+"hi": [+0.018433634682839303,+0.012434999801660507,+0.004236100013107061+],+"n": 2+},+"pins|MC39": {+"blk": "pins",+"ref": "MC39",+"lo": [+-0.004335000212489131,+-0.014558633853705049,+-4.880002234131098e-05+],+"hi": [+0.01843500011814901,+-0.007566366583598226,+0.004236100013107061+],+"n": 2+},+"power|U1": {+"blk": "power",+"ref": "U1",+"lo": [+-0.002900000112316074,+-0.02165000088887793,+0.0016311999687179924+],+"hi": [+0.00533749998062992,+0.004675000085006089,+0.005186100029125809+],+"n": 6+},+"pins|MC16": {+"blk": "pins",+"ref": "MC16",+"lo": [+0.0015650000095381723,+0.017441365803568244,+-4.880002234131098e-05+],+"hi": [+0.00653500001859063,+0.03443363465459513,+0.004236100013107061+],+"n": 2+},+"status|LED2": {+"blk": "status",+"ref": "LED2",+"lo": [+0.00509999980200225,+-0.025499999238201797,+0.0016111999692232349+],+"hi": [+0.007109999856726765,+-0.023499999143206895,+0.002451199984382838+],+"n": 5+},+"reset|C9": {+"blk": "reset",+"ref": "C9",+"lo": [+-0.006480330106328064,+-0.0034999998812800344,+0.0016311999687179924+],+"hi": [+0.016450000399305983,+0.002225330074915604,+0.004736100036855787+],+"n": 4+},+"pins|MC19": {+"blk": "pins",+"ref": "MC19",+"lo": [+-0.01843500018371126,+-0.014433634822746188,+-4.880002234131098e-05+],+"hi": [+0.0005349999664365655,+0.018308634863677054,+0.004236100013107061+],+"n": 2+},+"power|R7": {+"blk": "power",+"ref": "R7",+"lo": [+-0.008600000266636222,+-0.030649998493283436,+0.0016311999687179924+],+"hi": [+0.0019499999434235819,+-0.005724999710475474,+0.0045861000006273385+],+"n": 6+},+"power|R8": {+"blk": "power",+"ref": "R8",+"lo": [+-0.005049999806981967,+-0.019919999648374886,+0.0016311999687179924+],+"hi": [+0.0009500000123414523,+-0.005724999710475474,+0.0045861000006273385+],+"n": 6+},+"reset|R1": {+"blk": "reset",+"ref": "R1",+"lo": [+0.005180000032811924,+0.004775000031548172,+0.0016311999687179924+],+"hi": [+0.014299999831525178,+0.016349999839183494,+0.0045861000006273385+],+"n": 6+},+"estop|SW2": {+"blk": "estop",+"ref": "SW2",+"lo": [+0.011699999766239463,+-0.002768926852406382,+0.0013915287152788368+],+"hi": [+0.014899999685400664,+0.001728926721005321,+0.00390295670225285+],+"n": 1+},+"estop|R4": {+"blk": "estop",+"ref": "R4",+"lo": [+0.011390000607167869,+-0.004269999719947025,+0.0016311999687179924+],+"hi": [+0.01239000065466532,+-0.003769999696198299,+0.00198119995623827+],+"n": 3+},+"debug|J1": {+"blk": "debug",+"ref": "J1",+"lo": [+0.007875000792370676,+0.022500000596954107,+0.0016311999687179924+],+"hi": [+0.011475000730530857,+0.027500000485195398,+0.005951199801377952+],+"n": 2+},+"pins|MC15": {+"blk": "pins",+"ref": "MC15",+"lo": [+0.007665000357480288,+-0.034433634375711356,+-4.880002234131098e-05+],+"hi": [+0.010434999738169401,+0.016308634535851508,+0.004236100013107061+],+"n": 2+},+"power|D1": {+"blk": "power",+"ref": "D1",+"lo": [+-0.0007500000538522987,+0.006895000108959704,+0.0016311999687179924+],+"hi": [+0.00620999990129055,+0.03179999964169654,+0.004736100036855787+],+"n": 6+},+"pins|MC29": {+"blk": "pins",+"ref": "MC29",+"lo": [+-0.008335000402478934,+-0.020433633885370017,+-4.880002234131098e-05+],+"hi": [+0.01843500011814901,+0.004308634431543381,+0.004236100013107061+],+"n": 2+},+"pins|MC20": {+"blk": "pins",+"ref": "MC20",+"lo": [+-0.0023350001174942247,+0.009566365385870069,+-4.880002234131098e-05+],+"hi": [+0.01843500011814901,+0.018308634863677054,+0.004236100013107061+],+"n": 2+},+"pins|MC1": {+"blk": "pins",+"ref": "MC1",+"lo": [+0.007564999887069254,+-0.034433634375711356,+-4.880002234131098e-05+],+"hi": [+0.008535000346416173,+-0.011691365397093267,+0.004236100013107061+],+"n": 2+},+"pins|MC21": {+"blk": "pins",+"ref": "MC21",+"lo": [+-0.004335000212489127,+0.007566365523705811,+-4.880002234131098e-05+],+"hi": [+0.01843500011814901,+0.018308634863677054,+0.004236100013107061+],+"n": 2+},+"pins|MC28": {+"blk": "pins",+"ref": "MC28",+"lo": [+-0.008335000402478934,+-0.01843363542018962,+-4.880002234131098e-05+],+"hi": [+0.01843500011814901,+0.006308634759368928,+0.004236100013107061+],+"n": 2+},+"pins|MC5": {+"blk": "pins",+"ref": "MC5",+"lo": [+-0.018433634748401553,+-0.01643500058588144,+-4.880002234131098e-05+],+"hi": [+0.008535000346416174,+-0.0036913654827749427,+0.004236100013107061+],+"n": 2+},+"pins|MC27": {+"blk": "pins",+"ref": "MC27",+"lo": [+-0.008335000402478934,+-0.00443363411494103,+-4.880002234131098e-05+],+"hi": [+0.01843500011814901,+0.008308634621533187,+0.004236100013107061+],+"n": 2+},+"fcnest|R6": {+"blk": "fcnest",+"ref": "R6",+"lo": [+-0.0037999998349216445,+-0.009884999605385032,+0.0016311999687179924+],+"hi": [+0.0030099999821293476,+0.02959999965361747,+0.0045861000006273385+],+"n": 6+},+"pins|MC32": {+"blk": "pins",+"ref": "MC32",+"lo": [+-0.008335000402478934,+-0.026433634927054316,+-4.880002234131098e-05+],+"hi": [+0.01843500011814901,+-0.0016913656206106829,+0.004236100013107061+],+"n": 2+},+"pins|MP3": {+"blk": "pins",+"ref": "MP3",+"lo": [+-0.018399999975411654,+-0.034382500750036356,+-0.008748800144530833+],+"hi": [+-0.0071000004282206885,+0.018669167411024302,+0.010031199669204653+],+"n": 4+},+"pins|MC46": {+"blk": "pins",+"ref": "MC46",+"lo": [+0.005566365460214703,+-0.034434999811021064,+-4.880002234131098e-05+],+"hi": [+0.006433634520323514,+-0.033564999822085176,+0.0016011999687179923+],+"n": 1+},+"pins|MC2": {+"blk": "pins",+"ref": "MC2",+"lo": [+-0.00043500002724906916,+-0.010558634129376531,+-4.880002234131098e-05+],+"hi": [+0.008535000346416173,+0.03443363465459513,+0.004236100013107061+],+"n": 2+},+"pins|MC24": {+"blk": "pins",+"ref": "MC24",+"lo": [+-0.008335000402478933,+0.0015663654715517466,+-4.880002234131098e-05+],+"hi": [+0.01843500011814901,+0.014308634208025965,+0.004236100013107061+],+"n": 2+},+"pins|MC44": {+"blk": "pins",+"ref": "MC44",+"lo": [+0.0015663654448478804,+-0.034434999811021064,+-4.880002234131098e-05+],+"hi": [+0.0065350000185906264,+-0.013691364793596238,+0.004236100013107061+],+"n": 2+},+"pins|MC41": {+"blk": "pins",+"ref": "MC41",+"lo": [+-0.004433634781929166,+-0.034434999811021064,+-4.880002234131098e-05+],+"hi": [+0.0005349999664365616,+-0.013691364793596238,+0.004236100013107061+],+"n": 2+},+"pins|MC13": {+"blk": "pins",+"ref": "MC13",+"lo": [+0.007665000357480288,+0.01144136575141418,+-4.880002234131098e-05+],+"hi": [+0.01843500011814901,+0.01843363482595849,+0.004236100013107061+],+"n": 2+},+"reset|C4": {+"blk": "reset",+"ref": "C4",+"lo": [+0.002150000011130735,+0.006724999745818407,+0.0016311999687179924+],+"hi": [+0.01622499953005606,+0.013850000739073932,+0.004736100036855787+],+"n": 4+},+"pins|MP4": {+"blk": "pins",+"ref": "MP4",+"lo": [+-0.008700000387801292,+-0.034382500750036356,+-0.008748800144530833+],+"hi": [+0.018399999909849404,+-0.01333083224624899,+0.010031199669204653+],+"n": 4+},+"pins|MC40": {+"blk": "pins",+"ref": "MC40",+"lo": [+-0.002335000117494229,+-0.014558633853705049,+-4.880002234131098e-05+],+"hi": [+0.01843500011814901,+-0.00556636625577268,+0.004236100013107061+],+"n": 2+},+"pins|MC48": {+"blk": "pins",+"ref": "MC48",+"lo": [+-0.008433635903241546,+-0.034434999811021064,+-4.880002234131098e-05+],+"hi": [+-0.007566366843132735,+-0.033564999822085176,+0.0016011999687179923+],+"n": 1+},+"pins|MC7": {+"blk": "pins",+"ref": "MC7",+"lo": [+0.007566365380586623,+-0.0005586345857245927,+-4.880002234131098e-05+],+"hi": [+0.008535000346416174,+0.0344350001481125,+0.004236100013107061+],+"n": 2+},+"pins|MC23": {+"blk": "pins",+"ref": "MC23",+"lo": [+-0.008335000402478933,+0.0035663654501313273,+-4.880002234131098e-05+],+"hi": [+0.01843500011814901,+0.01630863453585151,+0.004236100013107061+],+"n": 2+},+"pins|MC43": {+"blk": "pins",+"ref": "MC43",+"lo": [+-0.00243363445410362,+-0.034434999811021064,+-4.880002234131098e-05+],+"hi": [+0.0045350001564263675,+-0.013691364793596238,+0.004236100013107061+],+"n": 2+},+"pins|MC33": {+"blk": "pins",+"ref": "MC33",+"lo": [+-0.010433636172859431,+-0.004558634542883753,+-4.880002234131098e-05+],+"hi": [+-0.0074650004135430464,+0.0344350001481125,+0.004236100013107061+],+"n": 2+},+"power|C6": {+"blk": "power",+"ref": "C6",+"lo": [+-0.004560329922000698,+-0.03222500015425068,+0.0016311999687179924+],+"hi": [+0.00979999996703261,+0.0066253301238333225,+0.004736100036855787+],+"n": 4+},+"pins|MP1": {+"blk": "pins",+"ref": "MP1",+"lo": [+-0.018399999975411654,+-0.014919166459259958,+-0.008748800144530833+],+"hi": [+0.008900000331738529,+0.03438250108712781,+0.010031199669204653+],+"n": 4+},+"power|C7": {+"blk": "power",+"ref": "C7",+"lo": [+0.0009574999821386622,+-0.020284999866527886,+0.0016311999687179924+],+"hi": [+0.006630330135201923,+0.0035053301153396585,+0.004736100036855787+],+"n": 4+},+"pins|MC35": {+"blk": "pins",+"ref": "MC35",+"lo": [+-0.008433634971918973,+-0.008558634732873556,+-4.880002234131098e-05+],+"hi": [+-0.007465000413543048,+0.0344350001481125,+0.004236100013107061+],+"n": 2+},+"status|LED3": {+"blk": "status",+"ref": "LED3",+"lo": [+-0.0019499999507781728,+0.033300000469642314,+0.0016311999687179924+],+"hi": [+-0.0014499999270294471,+0.034300000517139766,+0.002131199992466718+],+"n": 3+},+"power|R5": {+"blk": "power",+"ref": "R5",+"lo": [+-0.01116826848378262,+-0.028850001551001713,+0.0016311999687179924+],+"hi": [+-0.0033500000172746055,+-0.005225000094180375,+0.0045861000006273385+],+"n": 6+},+"pins|MC42": {+"blk": "pins",+"ref": "MC42",+"lo": [+0.0016650000724955762,+-0.034434999811021064,+-4.880002234131098e-05+],+"hi": [+0.004433634425328611,+-0.013691364793596238,+0.004236100013107061+],+"n": 2+},+"estop|LED1": {+"blk": "estop",+"ref": "LED1",+"lo": [+0.012384999568854957,+-0.00545000032314603,+0.0016311999687179924+],+"hi": [+0.013384999616352408,+-0.004950000299397304,+0.002131199992466718+],+"n": 3+},+"power|C1": {+"blk": "power",+"ref": "C1",+"lo": [+-0.006890329968641334,+-0.020199999917787877,+0.0016311999687179924+],+"hi": [+0.006849999943330451,+0.000995330095074081,+0.004736100036855787+],+"n": 4+},+"pins|MC12": {+"blk": "pins",+"ref": "MC12",+"lo": [+0.007665000357480288,+0.009441365423588633,+-4.880002234131098e-05+],+"hi": [+0.01843500011814901,+0.02043363422246146,+0.004236100013107061+],+"n": 2+},+"power|C3": {+"blk": "power",+"ref": "C3",+"lo": [+-0.016425000187194408,+-0.018000000802823723,+0.0016311999687179924+],+"hi": [+0.006230329883372297,+-0.002614669919231036,+0.004736100036855787+],+"n": 4+},+"pins|MC47": {+"blk": "pins",+"ref": "MC47",+"lo": [+-0.006433634644093425,+-0.034434999811021064,+-4.880002234131098e-05+],+"hi": [+-0.005566365583984614,+-0.033564999822085176,+0.0016011999687179923+],+"n": 1+},+"power|C2": {+"blk": "power",+"ref": "C2",+"lo": [+-0.0005999999594161897,+-0.001204741131344579,+0.0016311999687179924+],+"hi": [+0.006989741020923368,+0.029200000333110418,+0.004736100036855787+],+"n": 4+},+"power|C5": {+"blk": "power",+"ref": "C5",+"lo": [+-0.004950000267893511,+-0.0162000001352517,+0.0016311999687179924+],+"hi": [+0.01622499953005606,+-0.002365000202809839,+0.004736100036855787+],+"n": 4+},+"pins|MC6": {+"blk": "pins",+"ref": "MC6",+"lo": [+0.005566365518422364,+-0.0025586346807194953,+-4.880002234131098e-05+],+"hi": [+0.008535000346416174,+0.0344350001481125,+0.004236100013107061+],+"n": 2+},+"pins|MC8": {+"blk": "pins",+"ref": "MC8",+"lo": [+0.007665000357480287,+0.0014413654674335537,+-4.880002234131098e-05+],+"hi": [+0.010433633371537118,+0.0344350001481125,+0.004236100013107061+],+"n": 2+},+"pins|MC18": {+"blk": "pins",+"ref": "MC18",+"lo": [+0.0016650000724955805,+-0.01643500058588144,+-4.880002234131098e-05+],+"hi": [+0.018433634624631642,+0.018308634863677054,+0.004236100013107061+],+"n": 2+},+"pins|MC45": {+"blk": "pins",+"ref": "MC45",+"lo": [+-0.00043363459193936104,+-0.034434999811021064,+-4.880002234131098e-05+],+"hi": [+0.0004336344681694496,+-0.033564999822085176,+0.0016011999687179923+],+"n": 1+},+"pins|MC36": {+"blk": "pins",+"ref": "MC36",+"lo": [+-0.008335000402478936,+-0.010558634129376528,+-4.880002234131098e-05+],+"hi": [+-0.0035663665949352695,+0.0344350001481125,+0.004236100013107061+],+"n": 2+},+"pins|MP2": {+"blk": "pins",+"ref": "MP2",+"lo": [+0.007300000372157932,+0.017080833198013335,+-0.008748800144530833+],+"hi": [+0.018399999909849404,+0.03438250108712781,+0.010031199669204653+],+"n": 4+},+"pins|MC4": {+"blk": "pins",+"ref": "MC4",+"lo": [+0.007665000357480285,+-0.014434998395410743,+-4.880002234131098e-05+],+"hi": [+0.018433634624631642,+-0.005691365344939203,+0.004236100013107061+],+"n": 2+},+"power|C10": {+"blk": "power",+"ref": "C10",+"lo": [+-0.0028500000517335403,+-0.019919999648374886,+0.0016311999687179924+],+"hi": [+0.0066600000681835535,+-0.009044999844883949,+0.004736100036855787+],+"n": 4+},+"status|R9": {+"blk": "status",+"ref": "R9",+"lo": [+-0.003959999889087365,+-0.019919999648374886,+0.0016311999687179924+],+"hi": [+-0.0034599998653386398,+-0.018919999600877434,+0.00198119995623827+],+"n": 3+},+"fcnest|U2": {+"blk": "fcnest",+"ref": "U2",+"lo": [+-0.009899999804513964,+-0.016099999257387042,+0.002556200012653135+],+"hi": [+0.010099999748451204,+0.019899999192892193,+0.005486099985167384+],+"n": 35+},+"pins|MC17": {+"blk": "pins",+"ref": "MC17",+"lo": [+0.0036650001674904827,+0.013565000606211453,+-4.880002234131098e-05+],+"hi": [+0.018433634682839303,+0.018308634863677054,+0.004236100013107061+],+"n": 2+}+},+"fps": {+"MC17": {+"ref": "MC17",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": 90.0,+"x": 0.018,+"y": 0.014000001000000001,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"U2": {+"ref": "U2",+"val": "Molecule_RP2350A_v1",+"fp": "Molecule_RP2350A_v1",+"layer": "F.Cu",+"rot": 180.0,+"x": 9.999999999999864e-05,+"y": -9.99999999999994e-05,+"blk": "fcnest",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"R9": {+"ref": "R9",+"val": "51k",+"fp": "R_0402_1005Metric",+"layer": "F.Cu",+"rot": 90.0,+"x": -0.003710000000000001,+"y": -0.01942,+"blk": "status",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"C10": {+"ref": "C10",+"val": "100n",+"fp": "C_0402_1005Metric",+"layer": "F.Cu",+"rot": -90.0,+"x": -0.0026000000000000016,+"y": -0.01942,+"blk": "power",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC4": {+"ref": "MC4",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": -90.0,+"x": 0.018,+"y": -0.013999999000000003,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MP2": {+"ref": "MP2",+"val": "~",+"fp": "MachinePinLargeShort",+"layer": "F.Cu",+"rot": 0.0,+"x": 0.015999999999999997,+"y": 0.032,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC36": {+"ref": "MC36",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": 90.0,+"x": -0.004000001000000001,+"y": 0.034,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC45": {+"ref": "MC45",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": -90.0,+"x": -1.5178830414797062e-18,+"y": -0.033999998999999996,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC18": {+"ref": "MC18",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": -90.0,+"x": 0.018,+"y": -0.016,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC8": {+"ref": "MC8",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": 90.0,+"x": 0.009999998999999999,+"y": 0.034,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC6": {+"ref": "MC6",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": 90.0,+"x": 0.005999999999999998,+"y": 0.034,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"C5": {+"ref": "C5",+"val": "10u",+"fp": "C_0805_2012Metric",+"layer": "F.Cu",+"rot": -90.0,+"x": 0.015599999999999998,+"y": -0.015200000000000002,+"blk": "power",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"C2": {+"ref": "C2",+"val": "22u",+"fp": "C_1206_3216Metric",+"layer": "F.Cu",+"rot": 0.0,+"x": 0.0009999999999999987,+"y": 0.028399999999999998,+"blk": "power",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC47": {+"ref": "MC47",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": -90.0,+"x": -0.006,+"y": -0.033999999999999996,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"C3": {+"ref": "C3",+"val": "10u",+"fp": "C_0805_2012Metric",+"layer": "F.Cu",+"rot": -90.0,+"x": -0.0158,+"y": -0.016999999999999998,+"blk": "power",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC12": {+"ref": "MC12",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": 0.0,+"x": 0.018,+"y": 0.02,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"C1": {+"ref": "C1",+"val": "10uF",+"fp": "C_0402_1005Metric",+"layer": "F.Cu",+"rot": -90.0,+"x": 0.006599999999999998,+"y": -0.019700000000000002,+"blk": "power",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"LED1": {+"ref": "LED1",+"val": "RED",+"fp": "LED_0402_1005Metric",+"layer": "F.Cu",+"rot": 180.0,+"x": 0.012884999999999999,+"y": -0.005199999999999999,+"blk": "estop",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC42": {+"ref": "MC42",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": -90.0,+"x": 0.003999999999999998,+"y": -0.033999999999999996,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"R5": {+"ref": "R5",+"val": "10k",+"fp": "R_0402_1005Metric",+"layer": "F.Cu",+"rot": 180.0,+"x": -0.010668268000000002,+"y": -0.028600000000000004,+"blk": "power",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"LED3": {+"ref": "LED3",+"val": "GRN",+"fp": "LED_0402_1005Metric",+"layer": "F.Cu",+"rot": -90.0,+"x": -0.001700000000000001,+"y": 0.0338,+"blk": "status",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC35": {+"ref": "MC35",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": -90.0,+"x": -0.008000000000000002,+"y": 0.034,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"C7": {+"ref": "C7",+"val": "10uF",+"fp": "C_0402_1005Metric",+"layer": "F.Cu",+"rot": -90.0,+"x": 0.0012074999999999987,+"y": -0.019785,+"blk": "power",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MP1": {+"ref": "MP1",+"val": "~",+"fp": "MachinePinLargeShort",+"layer": "F.Cu",+"rot": 0.0,+"x": -0.016,+"y": 0.032,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"C6": {+"ref": "C6",+"val": "10u",+"fp": "C_0805_2012Metric",+"layer": "F.Cu",+"rot": 0.0,+"x": 0.008799999999999999,+"y": -0.0316,+"blk": "power",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC33": {+"ref": "MC33",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": 90.0,+"x": -0.010000002000000001,+"y": 0.034,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC43": {+"ref": "MC43",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": -90.0,+"x": -0.0020000000000000013,+"y": -0.033999998999999996,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC23": {+"ref": "MC23",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": 0.0,+"x": 0.018,+"y": 0.004,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC7": {+"ref": "MC7",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": 90.0,+"x": 0.007999999999999998,+"y": 0.034,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC48": {+"ref": "MC48",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": -90.0,+"x": -0.008000001000000001,+"y": -0.033999999999999996,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC40": {+"ref": "MC40",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": 180.0,+"x": 0.018,+"y": -0.006000000999999999,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MP4": {+"ref": "MP4",+"val": "~",+"fp": "MachinePinLargeShort",+"layer": "F.Cu",+"rot": 0.0,+"x": 0.015999999999999997,+"y": -0.032,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"C4": {+"ref": "C4",+"val": "10u",+"fp": "C_0805_2012Metric",+"layer": "F.Cu",+"rot": 90.0,+"x": 0.015599999999999998,+"y": 0.012850001,+"blk": "reset",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC13": {+"ref": "MC13",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": 0.0,+"x": 0.018,+"y": 0.018,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC41": {+"ref": "MC41",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": -90.0,+"x": -0.004000000000000002,+"y": -0.033999998999999996,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC44": {+"ref": "MC44",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": -90.0,+"x": 0.0019999999999999987,+"y": -0.033999998999999996,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC24": {+"ref": "MC24",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": 0.0,+"x": 0.018,+"y": 0.002,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC2": {+"ref": "MC2",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": 0.0,+"x": -1.5178830414797062e-18,+"y": 0.034,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC46": {+"ref": "MC46",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": -90.0,+"x": 0.005999999999999998,+"y": -0.033999999999999996,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MP3": {+"ref": "MP3",+"val": "~",+"fp": "MachinePinLargeShort",+"layer": "F.Cu",+"rot": 0.0,+"x": -0.016,+"y": -0.032,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC32": {+"ref": "MC32",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": 0.0,+"x": 0.018,+"y": -0.026,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"R6": {+"ref": "R6",+"val": "5.6k",+"fp": "R_0603_1608Metric",+"layer": "F.Cu",+"rot": -90.0,+"x": -0.0034000000000000015,+"y": 0.0288,+"blk": "fcnest",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC27": {+"ref": "MC27",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": 0.0,+"x": 0.018,+"y": -0.003999999999999999,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC5": {+"ref": "MC5",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": -90.0,+"x": -0.018000000000000002,+"y": -0.016,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC28": {+"ref": "MC28",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": 180.0,+"x": 0.018,+"y": -0.018,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC21": {+"ref": "MC21",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": 0.0,+"x": 0.018,+"y": 0.008,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC1": {+"ref": "MC1",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": 0.0,+"x": 0.007999999999999998,+"y": -0.033999999999999996,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC20": {+"ref": "MC20",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": 0.0,+"x": 0.018,+"y": 0.01,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC29": {+"ref": "MC29",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": 180.0,+"x": 0.018,+"y": -0.02,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"D1": {+"ref": "D1",+"val": "SMF6.0A",+"fp": "D_SOD-123F",+"layer": "F.Cu",+"rot": 0.0,+"x": 0.0009999999999999987,+"y": 0.031,+"blk": "power",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC15": {+"ref": "MC15",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": 0.0,+"x": 0.009999999999999998,+"y": -0.033999999999999996,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"J1": {+"ref": "J1",+"val": "BM03B-SRSS-TB",+"fp": "JST_SH_BM03B-SRSS-TB_1x03-1MP_P1.00mm_Vertical",+"layer": "F.Cu",+"rot": 90.0,+"x": 0.009675000999999999,+"y": 0.025,+"blk": "debug",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"R4": {+"ref": "R4",+"val": "3.3k",+"fp": "R_0402_1005Metric",+"layer": "F.Cu",+"rot": 180.0,+"x": 0.011890000999999999,+"y": -0.00402,+"blk": "estop",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"SW2": {+"ref": "SW2",+"val": "SKRPACE010",+"fp": "SW_SKRPACE010",+"layer": "F.Cu",+"rot": -90.0,+"x": 0.0133,+"y": -0.0005199999999999996,+"blk": "estop",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"R1": {+"ref": "R1",+"val": "10k",+"fp": "R_0402_1005Metric",+"layer": "F.Cu",+"rot": 180.0,+"x": 0.0138,+"y": 0.0161,+"blk": "reset",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"R8": {+"ref": "R8",+"val": "51k",+"fp": "R_0402_1005Metric",+"layer": "F.Cu",+"rot": -90.0,+"x": -0.004800000000000002,+"y": -0.01942,+"blk": "power",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"R7": {+"ref": "R7",+"val": "10k",+"fp": "R_0402_1005Metric",+"layer": "F.Cu",+"rot": 180.0,+"x": -0.008100000000000001,+"y": -0.0304,+"blk": "power",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC19": {+"ref": "MC19",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": 0.0,+"x": -0.018000000000000002,+"y": -0.013999999999999999,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"C9": {+"ref": "C9",+"val": "100n",+"fp": "C_0402_1005Metric",+"layer": "F.Cu",+"rot": 90.0,+"x": 0.0162,+"y": -0.003,+"blk": "reset",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"LED2": {+"ref": "LED2",+"val": "WS2812B-2020-V6",+"fp": "LED_WS2812B-2020_PLCC4_2.0x2.0mm",+"layer": "F.Cu",+"rot": 90.0,+"x": 0.0060999999999999995,+"y": -0.024499999999999997,+"blk": "status",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC16": {+"ref": "MC16",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": 0.0,+"x": 0.0019999999999999987,+"y": 0.034,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"U1": {+"ref": "U1",+"val": "AP2112K-3.3",+"fp": "SOT-23-5",+"layer": "F.Cu",+"rot": 0.0,+"x": 0.003937499999999998,+"y": -0.020200000000000003,+"blk": "power",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC39": {+"ref": "MC39",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": 180.0,+"x": 0.018,+"y": -0.008000001,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC3": {+"ref": "MC3",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": 90.0,+"x": 0.018,+"y": 0.012,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC37": {+"ref": "MC37",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": 180.0,+"x": 0.018,+"y": -0.012,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC14": {+"ref": "MC14",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": -90.0,+"x": -0.018000000000000002,+"y": -0.018000001,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"R2": {+"ref": "R2",+"val": "10k",+"fp": "R_0402_1005Metric",+"layer": "F.Cu",+"rot": 180.0,+"x": 0.013890000999999999,+"y": -0.00402,+"blk": "reset",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC30": {+"ref": "MC30",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": 0.0,+"x": 0.018,+"y": -0.022,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC25": {+"ref": "MC25",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": 0.0,+"x": 0.018,+"y": 0.0,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC10": {+"ref": "MC10",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": 0.0,+"x": 0.018,+"y": 0.026000000000000002,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC38": {+"ref": "MC38",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": 180.0,+"x": 0.018,+"y": -0.010000000999999998,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC9": {+"ref": "MC9",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": 90.0,+"x": 0.018,+"y": 0.024,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC26": {+"ref": "MC26",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": 0.0,+"x": 0.018,+"y": -0.002,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"C8": {+"ref": "C8",+"val": "100n",+"fp": "C_0402_1005Metric",+"layer": "F.Cu",+"rot": -90.0,+"x": 0.016099999999999996,+"y": 0.01752,+"blk": "reset",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"R3": {+"ref": "R3",+"val": "10k",+"fp": "R_0402_1005Metric",+"layer": "F.Cu",+"rot": 90.0,+"x": 0.016099999999999996,+"y": 0.0205,+"blk": "power",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC34": {+"ref": "MC34",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": -90.0,+"x": -0.006,+"y": 0.034,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC11": {+"ref": "MC11",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": 0.0,+"x": 0.018,+"y": 0.022000000000000002,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC31": {+"ref": "MC31",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": 0.0,+"x": 0.018,+"y": -0.023999999,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"SW1": {+"ref": "SW1",+"val": "SKRPACE010",+"fp": "SW_SKRPACE010",+"layer": "F.Cu",+"rot": -90.0,+"x": 0.0133,+"y": 0.0195,+"blk": "reset",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+},+"MC22": {+"ref": "MC22",+"val": "~",+"fp": "MachineContactMedium",+"layer": "F.Cu",+"rot": 0.0,+"x": 0.018,+"y": 0.006,+"blk": "pins",+"sheet": "root",+"dnp": false,+"stale_mm": null,+"has3d": true+}+},+"centre_mm": [+-1.0402639999999987,+4.319383+],+"coverage": {+"solids": 265,+"refs_tagged": 80,+"missing_real": [],+"bodiless_ok": [],+"stale_geometry": {},+"unmatched_solids": [+"Carrier-FC-RP2350A-Mini_v1.0_silkscreen_1"+],+"dnp": [],+"sections": {+"pins": 52,+"fcnest": 2,+"status": 3,+"power": 13,+"estop": 3,+"reset": 6,+"debug": 1+}+}+}\ No newline at end of file
viewer/viewer-config.jsonadded+249
@@ -0,0 +1,249 @@+{+ "$shape": "adom-board-viewer-config/0.2",+ "_note": "Path B FC-carrier viewer; content from the schematic notes + Overview; captions author-asserted; behaviours illustrative.",+ "board": {+  "name": "FC Carrier (RP2350A-Mini)",+  "subtitle": "Carrier-FC-RP2350A-Mini v1.0",+  "rev": "as-drawn from Carrier-FC-RP2350A-Mini_v1.0.kicad_pcb",+  "source": "KiCad project (4-layer PCB + STEP export)",+  "size_mm": [+   38.8,+   70.8+  ],+  "thickness_mm": 1.6,+  "copper_layers": 4+ },+ "blocks": [+  {+   "id": "power",+   "label": "Power in / protect",+   "color": "#f5a524",+   "short": "AP2112K-3.3, SMF6.0A TVS, VBUS bulk"+  },+  {+   "id": "fcnest",+   "label": "Flight controller nest",+   "color": "#3b82f6",+   "short": "RP2350A-Mini molecule (U2)"+  },+  {+   "id": "estop",+   "label": "E-stop",+   "color": "#ef4444",+   "short": "SW2 + red indicator, drives the ESC brake"+  },+  {+   "id": "reset",+   "label": "Reset",+   "color": "#22c55e",+   "short": "SW1 tact"+  },+  {+   "id": "status",+   "label": "Status LEDs",+   "color": "#eab308",+   "short": "WS2812 STATUS + green 5V-present"+  },+  {+   "id": "monitor",+   "label": "5V monitor",+   "color": "#06b6d4",+   "short": "divider to the mini's ADC2"+  },+  {+   "id": "debug",+   "label": "Debug",+   "color": "#8b5cf6",+   "short": "J1 JST SWD"+  },+  {+   "id": "pins",+   "label": "Machine pins",+   "color": "#64748b",+   "short": "32 x 64 mm datum + external contacts"+  },+  {+   "id": "mounting",+   "label": "Mounting",+   "color": "#94a3b8",+   "short": "base-plate holes"+  }+ ],+ "modes": {+  "assembly": {+   "label": "Assembly",+   "blurb": "Each grouping seats onto the carrier while its caption explains it.",+   "order": [+    "pins",+    "power",+    "estop",+    "reset",+    "status",+    "debug",+    "fcnest"+   ],+   "timing": {+    "fall_s": 0.47,+    "stagger_s": 0.027,+    "dwell_s": 6.3,+    "rest_s": 4.0,+    "drop_height_mm": 16+   },+   "intro": {+    "d": 6,+    "eyebrow": "FC Carrier",+    "head": "Hosts the RP2350A-Mini flight controller and carries the E-stop",+    "rows": [+     [+      "Board",+      "38.8 x 70.8 mm, 4-layer"+     ],+     [+      "Datum",+      "machine pins 32 x 64 mm"+     ],+     [+      "Hosts",+      "RP2350A-Mini"+     ]+    ],+    "note": "Bridges 5 V to two loads, monitors the 5 V rail into the mini's ADC, and carries a hardware E-stop that drives the ESC brake."+   },+   "captions": {+    "pins": {+     "eyebrow": "Datum",+     "head": "Machine-pin nest + external contacts",+     "rows": [+      [+       "Datum",+       "32 x 64 mm"+      ]+     ],+     "note": "Locates the carrier and breaks out the cell I/O; passives sit at the external contacts, 10 uF per VBUS out."+    },+    "power": {+     "eyebrow": "Power",+     "head": "Bulk, clamp, 3.3 V",+     "rows": [+      [+       "LDO",+       "AP2112K-3.3 (U1)"+      ],+      [+       "Protection",+       "SMF6.0A TVS (D1)"+      ],+      [+       "Bulk",+       "distributed on the 5 V rail"+      ]+     ],+     "note": "5 V enters, is clamped by the TVS and bulked, and the AP2112K makes 3.3 V for the mini. '5V Present' is indicated."+    },+    "monitor": {+     "eyebrow": "Telemetry",+     "head": "5 V rail into the ADC",+     "rows": [+      [+       "Divider",+       "51k / 51k + 100n"+      ],+      [+       "To",+       "the mini's ADC2"+      ]+     ],+     "note": "2.50 V at 5.00 V in; no buffer needed, the ADC's effective impedance is over 100 kohm."+    },+    "estop": {+     "eyebrow": "Safety",+     "head": "Hardware E-stop",+     "rows": [+      [+       "Switch",+       "SW2"+      ],+      [+       "Indicator",+       "LED1 red, ~0.48 mA"+      ],+      [+       "Drives",+       "the ESC brake (TIM1_BKIN)"+      ]+     ],+     "note": "A hardware E-stop: the switch drives the ESC's brake line, killing the gate outputs in silicon. Red indicator per the schematic."+    },+    "reset": {+     "eyebrow": "Control",+     "head": "Local reset",+     "rows": [+      [+       "Switch",+       "SW1 (SKRPACE010)"+      ]+     ],+     "note": "Local reset for the flight controller."+    },+    "status": {+     "eyebrow": "Indicators",+     "head": "Status + rail LEDs",+     "rows": [+      [+       "RGB",+       "LED2 WS2812 STATUS"+      ],+      [+       "Green",+       "LED3 ~0.48 mA, 5V present"+      ]+     ],+     "note": "Illustrative: the WS2812 is the status indicator; the green LED shows the rail. LED currents as annotated."+    },+    "debug": {+     "eyebrow": "Debug",+     "head": "SWD landing",+     "rows": [+      [+       "Connector",+       "J1 BM03B-SRSS-TB (JST)"+      ]+     ],+     "note": "JST debug connector for SWD."+    },+    "fcnest": {+     "eyebrow": "Nest",+     "head": "The RP2350A-Mini",+     "rows": [+      [+       "Nest",+       "U2 Molecule_RP2350A"+      ]+     ],+     "note": "The RP2350A-Mini flight controller seats here as a populated molecule; it runs three UARTs (ESC, motor, RX) plus DSHOT, WS2812 and the E-stop."+    }+   }+  },+  "static": {+   "label": "Static",+   "blurb": "The seated carrier. Camera is yours; hover a part, click legend rows to isolate a section.",+   "functions": {+    "power_leds": {+     "label": "Power",+     "refs": [+      "LED1",+      "LED2",+      "LED3"+     ],+     "color": "#39ff88",+     "default": false,+     "_src": "AUTHOR/illustrative: LED1 red (E-stop), LED2 WS2812 STATUS, LED3 green 5V-present, per the schematic notes."+    }+   }+  }+ },+ "tooltips": {+  "enabled": true,+  "_note": "Measured from geometry + schematic notes; no datasheet citations."+ }+}\ No newline at end of file