← Commit history

Refresh asset hashes and verify independent fan instances

John Lauer ·0f6d815532 ·12d ago ·parent 3be0ac3
2 files changed +25−1
provenance/assets.json+15−1
@@ -75,7 +75,7 @@     },     {       "file": "states/controller.mjs",-      "sha256": "0fe8d265caa6554cdbba7fa7adc968896b08d224249176ddcd957aea5fa291e6",+      "sha256": "33876be5454e99b27cf0bef706ce81ab0a05775fc6dc292e87facbee16ca0519",       "classification": "AI-created",       "source": "Sunon D04114960G-01 pages 6 and 8; retrieved 2026-10-08",       "units": "STEP/footprint mm; GLB metres, Z-up source",@@ -90,6 +90,20 @@       "units": "STEP/footprint mm; GLB metres, Z-up source",       "license": "MIT for Adom-authored asset",       "limits": "Nominal mounting envelope; rotor geometry/colors illustrative; native EDA and physical fit pending"+    },+    {+      "file": "states/controller.js",+      "sha256": "33876be5454e99b27cf0bef706ce81ab0a05775fc6dc292e87facbee16ca0519",+      "classification": "Adom-authored runtime or generated preview",+      "license": "MIT",+      "limits": "Simulated motion demonstration; no hardware control or physical qualification"+    },+    {+      "file": "viewer/index.html",+      "sha256": "bb3043e256eaef449d2953e7fb60a804119f044d9f2e656c68c88b6f8c1631fc",+      "classification": "Adom-authored runtime or generated preview",+      "license": "MIT",+      "limits": "Simulated motion demonstration; no hardware control or physical qualification"     }   ],   "manufacturer_reference": "https://www.sunonusa.com/wp-content/uploads/2026/02/MF4020-Doc-0248743-2-0-3D.zip",
tests/test_motion.mjs+10
@@ -5,3 +5,13 @@ assert.equal(c.apply({state:'on',speed:6000}).playbackRate,100);assert.equal(c.a c.apply({state:'off',speed:0});assert(group.paused);assert.throws(()=>c.apply({state:'off',speed:7000}));assert.throws(()=>c.apply({state:'on',speed:NaN}));assert.throws(()=>c.apply({state:'on',speed:10001}));assert.equal(c.apply({state:'on',speed:null,valid:false,source:'measured'}).state,'unknown');assert(group.paused); assert.throws(()=>bindFanMotion({animationGroups:[group,group],transformNodes:[rotor]},manifest)); console.log('motion adapter: rate mapping, off, invalid/stale and ambiguous binding checks passed');+// Repeated component instances with identical GLB names must remain independent.+const rotor2={name:'Fan.Rotor'};+const group2={...group,targetedAnimations:[{target:rotor2}],isStarted:false,paused:true};+const c2=bindFanMotion({animationGroups:[group2],transformNodes:[rotor2]},manifest);+c.apply({state:'on',speed:3000});c2.apply({state:'on',speed:7000});+assert.equal(group.speedRatio,50);assert.equal(group2.speedRatio,7000/60);+c.apply({state:'off',speed:0});assert(group.paused);assert.equal(group2.paused,false);+assert.throws(()=>c2.apply({state:'on',speed:Infinity}));assert(group2.paused);assert.equal(c2.status().state,'unknown');+assert.throws(()=>bindFanMotion({animationGroups:[{...group,targetedAnimations:[{target:{name:'Fan.Housing'}}]}],transformNodes:[rotor]},manifest));+console.log('instance isolation and fail-closed motion checks passed');