abse/smartwatch-flex-top-only
Three-panel flex smartwatch with two parallel R3.9 bends, all components flat-top, low-profile JST connector harnesses, split heartbeat optical windows and screw-retained PCB mounting. Modeled 39 × 50.5 × 14.5mm prototype; 100% routing, zero native DRC and shorts. Hardware qualification pending.
- Version
- 0.2.20
- License
- unset
- Stars
- 0
scripts/audit-printed-coil.mjs
import fs from 'node:fs'
import {createHash} from 'node:crypto'
import {printedCoilShapes} from './copper-model.mjs'
import {gap} from './copper-geometry.mjs'
const file=process.argv[2]??'dist/seed/circuit.json',source=JSON.parse(fs.readFileSync(file)),shapes=printedCoilShapes(source),failures=[]
const shareEndpoint=(a,b)=>{const aa=a.kind==='segment'?[a.a,a.b]:[a],bb=b.kind==='segment'?[b.a,b.b]:[b];return aa.some(p=>bb.some(q=>Math.hypot(p.x-q.x,p.y-q.y)<1e-6))}
for(let i=0;i<shapes.length;i++)for(let j=i+1;j<shapes.length;j++){
const a=shapes[i],b=shapes[j];if(!a.layers.some(l=>b.layers.includes(l)))continue
if(shareEndpoint(a,b)){
if(a.kind==='segment'&&b.kind==='segment'){
for(const p of [a.a,a.b])for(const q of [b.a,b.b])if(Math.hypot(p.x-q.x,p.y-q.y)<1e-6){const aa=p===a.a?a.b:a.a,bb=q===b.a?b.b:b.a;const u={x:aa.x-p.x,y:aa.y-p.y},v={x:bb.x-q.x,y:bb.y-q.y};if(u.x*v.x+u.y*v.y>1e-7&&Math.abs(u.x*v.y-u.y*v.x)<1e-7)failures.push({a:a.id,b:b.id,error:'Backtracking at shared endpoint'})}
}
continue
}
const d=gap(a,b);if(d<.127-1e-6)failures.push({a:a.id,b:b.id,gapMM:d,error:'Nonadjacent turn or through-via contact'})
}
const report={source:file,sha256:createHash('sha256').update(fs.readFileSync(file)).digest('hex'),windingPrimitives:shapes.length,nonadjacentClearanceMM:.127,failures,status:failures.length?'FAIL':'PASS',qualification:'Geometry only; does not establish inductance, AC resistance, Qi operation, temperature or FOD.'}
fs.writeFileSync('reports/printed-coil-audit.json',JSON.stringify(report,null,2)+'\n');console.log('Printed coil self-short/turn bypass check:',report.status,failures.length);if(failures.length)process.exitCode=1