← Commit history

demo: the Fusion library card proves all three artifacts too (symbol + footprint + 3D package), only 3/3 passes

John Lauer ·cdee907c01 ·2mo ago ·parent 240a740
1 file changed +74−2
web-control-demo.html+74−2
@@ -1824,7 +1824,12 @@ for (const w of mine) {   ].forEach(function (s) {     var cc = card("grp-kicad", "verb", labelOf(s));     PART_CARDS.push({ cc: cc, label: labelFnOf(s) });-    if (s.proof) { cc.btn.onclick = function () { showLibraryProof(cc); }; return; }+    if (s.proof) {+      // proof:"fusion" drives the Fusion verbs; anything else is the KiCad card.+      var proofFn = (s.proof === "fusion") ? showFusionLibraryProof : showLibraryProof;+      cc.btn.onclick = function () { proofFn(cc); };+      return;+    }     cc.btn.onclick = function () {       showSurface(cc, {         showCmd: s.cmd,@@ -1868,6 +1873,73 @@ for (const w of mine) {    // Fusion component staging: the SAME wiki part's .lbr + .step, written onto the   // PC (the fusion_show_* verbs take a libraryPath / stepPath).+  // The same standard as the KiCad library card, applied to Fusion: a library IS+  // a symbol plus a footprint plus a 3D package, so proving one means opening all+  // three and capturing each. John, 2026-08-20: "a library is all 3 of those items".+  function showFusionLibraryProof(c) {+    c.btn.disabled = true;+    cardLog(c.card).textContent = "";+    var sb = c.card.querySelector("div.shots"); if (sb) sb.innerHTML = "";+    setAwaiting(c.res, "asking permission (choose “Allow 1 hr”) ...",+      "on " + esc(selfLabel()) + " - opens the symbol, the footprint and the 3D package as proof",+      "on " + esc(selfLabel()) + " - opens the symbol, the footprint and the 3D package as proof");+    clog(c, "Target machine: " + selfLabel());+    startSurfaceProgress(c, "fusion_show_library");+    var results = [];+    stageFusionPart(c).then(function () {+      clog(c, "Opening the library " + PART.name + ".lbr ...");+      return postVerb("fusion_show_library", { libraryPath: PART.lbrPath });+    }).then(function () {+      var steps = [+        { cmd: "fusion_show_symbol", label: "symbol",+          args: function () { return { name: PART.name, libraryPath: PART.lbrPath }; } },+        { cmd: "fusion_show_footprint", label: "footprint",+          args: function () { return { name: PART.name, libraryPath: PART.lbrPath }; } },+        { cmd: "fusion_show_3d_package", label: "3D package",+          args: function () { return { name: PART.name, libraryPath: PART.lbrPath, stepPath: PART.stepPath }; } }+      ];+      return steps.reduce(function (chain, st) {+        return chain.then(function () {+          clog(c, "Proving the " + st.label + " ...");+          return postVerb(st.cmd, st.args()).then(function (r) {+            var jj = r.j || {};+            var ok = r.s === 200 && jj.success !== false && !jj.errorCode &&+              !(typeof jj.error === "string" && jj.error.trim() !== "");+            results.push({ label: st.label, ok: ok });+            if (!ok) {+              clog(c, "  " + st.label + " FAILED: " + (jj.error || jj.errorCode || ("HTTP " + r.s)));+              return;+            }+            // Fusion drives ONE window, so the part name in the title is the+            // identity check available here - there is no LIB:NAME prefix.+            return settleThenCapture(c, "fusion_state").then(function (sr) {+              var got = sr.s === 200 && sr.j && appendPicked(c, sr.j, "", st.label, PART.name);+              if (!got) {+                clog(c, "  " + st.label + ": reported success but the capture did not prove it");+                for (var i = results.length - 1; i >= 0; i--) {+                  if (results[i].label === st.label) { results[i].ok = false; break; }+                }+              }+            });+          });+        });+      }, Promise.resolve());+    }).then(function () {+      finishSurfaceBar(c);+      var good = results.filter(function (r) { return r.ok; }).length;+      var missing = results.filter(function (r) { return !r.ok; }).map(function (r) { return r.label; });+      if (good === 3) setRes(c.res, "ok", "Done - all 3 library artifacts opened",+        "symbol + footprint + 3D package, each captured below");+      else setRes(c.res, "err", good + "/3 library artifacts opened",+        "missing: " + missing.join(", ") + " - a library is only proven when all three open");+      c.btn.disabled = false;+    }).catch(function (e) {+      finishSurfaceBar(c);+      setRes(c.res, "err", "library proof failed", (e && e.message) || String(e));+      c.btn.disabled = false;+    });+  }+   var _fusionPart = null;   function stageFusionPart(c) {     if (_fusionPart) { clog(c, "Part already staged this session (reusing)."); return _fusionPart; }@@ -1918,7 +1990,7 @@ for (const w of mine) {     { label: function () { return "Symbol (" + PART.name + ")"; }, cmd: "fusion_show_symbol", args: function () { return { name: PART.name, libraryPath: PART.lbrPath }; }, stage: stageFusionPart, note: "full pinout in the symbol editor" },     { label: function () { return "Footprint (" + PART.name + ")"; }, cmd: "fusion_show_footprint", args: function () { return { name: PART.name, libraryPath: PART.lbrPath }; }, stage: stageFusionPart, note: "pads + layers in the footprint editor" },     { label: function () { return "3D package (" + PART.name + ")"; }, cmd: "fusion_show_3d_package", args: function () { return { name: PART.name, libraryPath: PART.lbrPath, stepPath: PART.stepPath }; }, stage: stageFusionPart, note: "attaches the part's STEP to its footprint" },-    { label: function () { return "Library (" + PART.name + ".lbr)"; }, cmd: "fusion_show_library", args: function () { return { libraryPath: PART.lbrPath }; }, stage: stageFusionPart, note: "the Electronics Library with symbol + footprint + 3D" },+    { label: function () { return "Library (" + PART.name + ".lbr) - proves all 3"; }, cmd: "fusion_show_library", proof: "fusion", stage: stageFusionPart, note: "a library IS a symbol + a footprint + a 3D package, so this opens all three and captures one screenshot of each. Only 3/3 is a pass." },     { label: function () { return "Schematic (just the " + PART.name + ")"; }, cmd: "fusion_show_schematic", args: function () { return {}; }, stage: stageFusionProject, note: "the generated single-component design's schematic view" },     { label: "2D board (part placed)", cmd: "fusion_show_2d_board", args: function () { return {}; }, stage: stageFusionProject, note: "the PCB editor view of the staged design" },     { label: "3D board (real 3D body)", cmd: "fusion_show_3d_board", args: function () { return {}; }, stage: stageFusionProject, note: "populated board in 3D: the bound urn renders the real component" },