Steam and cooling, plant operation: show the launch plant (1 Duplex + 1 Classic)
Deploy test site / deploy (push) Successful in 43s

User (October 2026): "launch plant should be 1x duplex system and 1x
classic". The calculator already did; these two pages did not.

- steam-cooling.html: default case is now "Launch plant" (D1-A, D1-B,
  Classic; B-1 and B-2; CH-1 and CH-2: 450 to 540 kg/h on 1,000 kg/h,
  391.5 kW on 500 kW). Other cases: Duplex first (commissioning), Second
  Duplex (growth option, five presses), One module down (launch plant
  with B-2 and CH-2 out). Idle boxes say "reserved position" / "growth
  option". Phasing table: launch plant, second Duplex, options;
  galvanics cooling is launch scope. Five-press figures labelled as the
  growth case or backbone sizing; chiller cost per the CSV 2-module row.
- plant-operation.html: the launch plant: Classic C2 removed everywhere
  (press, trimmer, routes, conveyor, lamps, texts), Classic re-centred;
  one PDPU (2 cells) as in total-investment; boilers 2 x 500 kg/h,
  chillers 2 x 250 kW; title arrivals scaled to three presses; phone
  legend in one column.
- Landing entries and README bullets for both pages.

Verified headless (Edge): skill checks pw_sc_check and pw_plant_check
with launch-plant expectations, 90-day runs, perf unchanged; 390 / 1024
/ 1440 px dark and light without page errors or overflow.
This commit is contained in:
grabowski committed 2026-10-16 16:58:37 +07:00
1 parent 71e30b0633
commit d7380919e4
4 files changed
+139 -125

No files matched your search

+56 -53
View File
@@ -93,6 +93,9 @@ footer{flex:0 0 clamp(150px,26vh,210px);display:grid;grid-template-columns:1.1fr
#hint{display:block}
header h1{white-space:normal}
.ctl{flex-wrap:wrap}
.legend{grid-template-columns:minmax(0,1fr)}
.legend div{overflow-wrap:anywhere}
.legend .note{grid-column:auto}
}
/* SVG */
@@ -213,7 +216,7 @@ html[data-theme=light] .screw{stroke:#7d8aa0}
</head>
<body>
<header>
<h1>CNX Vinyl <span>· Poy Records · Plant overview · mature fleet</span></h1>
<h1>CNX Vinyl <span>· Poy Records · Plant overview · launch plant</span></h1>
<div class="ctl">
<button id="btnPlay" class="on">Pause</button>
<button data-speed="1" class="on" title="Real time: every cycle at its actual duration">1×</button>
@@ -230,7 +233,7 @@ html[data-theme=light] .screw{stroke:#7d8aa0}
<div class="kpis">
<div class="kpi"><b id="kClock">D1 08:00:00</b><small>sim clock</small></div>
<div class="kpi"><b id="kShift">--</b><small>shift</small></div>
<div class="kpi"><b id="kPress">0/4</b><small>presses</small></div>
<div class="kpi"><b id="kPress">0/3</b><small>presses</small></div>
<div class="kpi"><b id="kRate">--</b><small>cycles/h</small></div>
<div class="kpi"><b id="kGood">0</b><small>good today</small></div>
<div class="kpi"><b id="kRej">0</b><small>rejects</small></div>
@@ -269,7 +272,7 @@ html[data-theme=light] .screw{stroke:#7d8aa0}
</div>
<div class="panel" id="detail">
<h2>Click any station</h2>
<p>The mature plant: the Newbilt Duplex (two HRP 12 presses on one VEX 50 extruder, with an EX 35 for colour effects), two Newbilt Classic automatic presses, the Pheenix Alpha electroforming line and Sibert stamper prep. At 1× everything runs at its real duration: press cycles of 28 s (Classic) and about 30 s (Duplex), 45 to 75 minutes of plating per part, artist approvals in days. Speed up to watch whole days (3600× runs a day in 24 s). Click a station for what happens there, its checks, and where its figures come from; durations without a published source are marked as estimates. Simulated from this repository (equipment/galvanics.md, equipment/pressing-line.md, production-timeline.md, scale.md); nothing here is live.</p>
<p>The launch plant decided in October 2026: one Newbilt Duplex system (two HRP 12 presses on one VEX 50 extruder, with an EX 35 for colour effects), one Newbilt Classic automatic press, the Pheenix Alpha electroforming line with one PDPU and Sibert stamper prep, on two boiler and two chiller modules. A second Duplex system is a growth option and is not shown. At 1× everything runs at its real duration: press cycles of 28 s (Classic) and about 30 s (Duplex), 45 to 75 minutes of plating per part, artist approvals in days. Speed up to watch whole days (3600× runs a day in 24 s). Click a station for what happens there, its checks, and where its figures come from; durations without a published source are marked as estimates. Simulated from this repository (finance/total-investment.md, equipment/galvanics.md, equipment/pressing-line.md, production-timeline.md, scale.md); nothing here is live.</p>
</div>
<div class="panel" id="logPanel"><h2>Event log</h2><div class="log" id="log"></div></div>
<div class="panel" id="legendPanel"><h2>Legend</h2>
@@ -349,6 +352,9 @@ const visHop=()=>!S.quiet&&S.speed<=600;
/* ================================================================ titles and upstream stages */
const UP=[['intake',1,2],['gate1',2,10],['master',2,4],['gate2',2,10],['cut',1,2]]; // days, min to max
// a new title every 0.75 to 1.15 days: ~380 a year, between the revenue model's 300 and 400 titles for the launch plant
// (the four-press rate scaled by press capacity; presses run ~64 to 73 % of shift time over 90 simulated days)
const ARRIVE=[0.75,1.15];
const UPI={};UP.forEach((u,i)=>UPI[u[0]]=i);
const QTY=[300,500,1000,1000,2000,3000,3000,5000,5000,10000]; // mean ~3,100
const TITLES=[];let titleN=40;
@@ -364,7 +370,7 @@ function mkTitle(o){o=o||{};titleN++;const r=Math.random();
const cntStage=st=>TITLES.reduce((n,T)=>n+(T.stage===st?1:0),0);
function nextUp(st){let m=Infinity;for(const T of TITLES)if(T.stage===st&&T.tEnd<m)m=T.tEnd;return m===Infinity?'-':dur(m-S.t);}
function upTick(){
if(S.t>=S.nextArrival){const T=mkTitle();T.tEnd=S.t+rnd(1,2)*DAY;S.nextArrival=S.t+rnd(0.55,0.85)*DAY;
if(S.t>=S.nextArrival){const T=mkTitle();T.tEnd=S.t+rnd(1,2)*DAY;S.nextArrival=S.t+rnd(ARRIVE[0],ARRIVE[1])*DAY;
log(T.id+' received: '+T.qty+' × 12" '+T.wt+' g '+T.kind+', checksums verified','info');}
for(const T of TITLES){
const i=UPI[T.stage];
@@ -426,18 +432,19 @@ const NOM={};for(const g in GROW){const G=GROW[g];let m=0,t=0;const tgt=massFor(
const PLATEQ=[];
const PRIO={F:0,R:1,M:2,S:3}; // lacquers first (they age), then remakes
function plateEnq(j,from){j.prio=j.grow==='S'&&j.remake?PRIO.R:PRIO[j.grow];j.from=from;j.tq=S.t;PLATEQ.push(j);PLATEQ.sort((a,b)=>a.prio-b.prio||a.tq-b.tq);}
const CELLS=[0,1,2,3].map(i=>({i,u:i>>1,c:i&1,job:null,ph:'idle',tIn:0,I:0,V:0,mass:0,target:1,tPlate:0}));
// launch plant: one PDPU with two cells (total-investment.md; one covers full-capacity demand, galvanics.md)
const CELLS=[0,1].map(i=>({i,u:i>>1,c:i&1,job:null,ph:'idle',tIn:0,I:0,V:0,mass:0,target:1,tPlate:0}));
function cellTick(c,ds){
if(c.ph==='idle'){
if(shiftOn()&&PLATEQ.length){const j=PLATEQ.shift();c.job=j;c.ph='load';c.tIn=0;c.mass=0;c.target=massFor(GROW[j.grow].th);
if(j.grow==='S'){j.T.made[j.side]++;j.st={T:j.T,side:j.side,gen:'S',n:j.T.made[j.side]};}
if(j.from)hop(j.from,'pdpu'+(c.u+1),j.mand);
log('PDPU '+(c.u+1)+' cell '+(c.c+1)+': '+(j.grow==='F'?'father on lacquer ':j.grow==='M'?'mother on father ':'stamper on mother ')+j.T.sid+j.side+(j.remake?' (from the archive)':''),'info');}
log('PDPU cell '+(c.c+1)+': '+(j.grow==='F'?'father on lacquer ':j.grow==='M'?'mother on father ':'stamper on mother ')+j.T.sid+j.side+(j.remake?' (from the archive)':''),'info');}
return;}
c.tIn+=ds;
if(c.ph==='load'){if(c.tIn>=5*MIN){c.ph='plate';c.tIn=0;}return;}
if(c.ph==='plate'){const g=GROW[c.job.grow];c.I=Math.min(g.Imax,20+(g.Imax-20)*c.tIn/g.ramp);c.V=8.5+c.I*0.016;c.mass+=c.I*ds/HOUR*GPAH;
if(c.mass>=c.target){c.ph='done';c.tPlate=c.tIn;c.tIn=0;c.I=0;c.V=0;log(jl(c.job)+': plated to '+f2(g.th)+' mm in '+dur(c.tPlate)+', PDPU '+(c.u+1)+' cell '+(c.c+1),'ok');}
if(c.mass>=c.target){c.ph='done';c.tPlate=c.tIn;c.tIn=0;c.I=0;c.V=0;log(jl(c.job)+': plated to '+f2(g.th)+' mm in '+dur(c.tPlate)+', PDPU cell '+(c.c+1),'ok');}
return;}
if(c.ph==='done'){if(shiftOn()){c.ph='unload';c.tIn=0;}return;}
if(c.ph==='unload'&&c.tIn>=10*MIN){const j=c.job;c.job=null;c.ph='idle';c.tIn=0;enq('pmpb',j,'pdpu'+(c.u+1));}
@@ -470,8 +477,7 @@ const CSEQ=[['LOAD',3],['CLOSE',2],['STEAM',7],['COOL',11],['OPEN',2],['EJECT',3
const PRESS=[
{id:'pDA',name:'Duplex A',type:'duplex',seq:DSEQ},
{id:'pDB',name:'Duplex B',type:'duplex',seq:DSEQ},
{id:'pC1',name:'Classic C1',type:'classic',seq:CSEQ},
{id:'pC2',name:'Classic C2',type:'classic',seq:CSEQ}];
{id:'pC1',name:'Classic',type:'classic',seq:CSEQ}];
PRESS.forEach(P=>Object.assign(P,{state:'OFF',tIn:0,set:null,mode:null,run:0,life:0,tpLeft:0,open:1,force:0,moldT:58,peakT:0,lastCycle:0,cycleStart:0,prevStart:0,waiting:false,changeDur:0,lastT:null,cyc:0,after:null,restart:false,cake:false,cakeKg:0}));
const RUNSTATES=['LOAD','CLOSE','STEAM','COOL','OPEN','EJECT'];
// Unplanned stops, about one per 4 running hours, 15 to 45 min each (estimate): with stamper changes and
@@ -559,18 +565,17 @@ function outcome(T,tp){
/* ================================================================ layout */
const MACH=[
// metal path
{id:'audio',x:20,y:56,w:110,h:120,t:'Audio intake',s:'checksums · tech QA',tags:[()=>'titles '+cntStage('intake'),()=>'next '+nextUp('intake'),()=>'~1.4 new/day']},
{id:'audio',x:20,y:56,w:110,h:120,t:'Audio intake',s:'checksums · tech QA',tags:[()=>'titles '+cntStage('intake'),()=>'next '+nextUp('intake'),()=>'~1 new/day']},
{id:'master',x:190,y:56,w:110,h:120,t:'Mastering',s:'vinyl master',tags:[()=>'titles '+cntStage('master'),()=>'next '+nextUp('master'),()=>'2 to 4 days']},
{id:'cut',x:360,y:56,w:110,h:120,t:'Lathe cutting',s:'lacquer · scribe',tags:[()=>'titles '+cntStage('cut'),()=>'next '+nextUp('cut'),()=>'plate < 72 h']},
{id:'pasu',x:488,y:46,w:112,h:150,t:'PASU silver',s:'clean · spray Ag',st:'pasu',bar:true,tags:[()=>stTxt('pasu'),()=>stLeft('pasu'),()=>'queue '+ST.pasu.q.length,()=>'15 min (est.)']},
{id:'pppu',x:610,y:46,w:146,h:150,t:'PPPU pre-plate',s:'4 positions · 20 A',custom:'pppu',tags:[()=>'queue '+ST.pppu.q.length+' · 35 °C',()=>'20 min each']},
{id:'pdpu1',x:766,y:46,w:158,h:150,t:'PDPU 1 plating',s:'2 cells · up to 200 A',custom:'pdpu',u:0,det:'pdpu',tags:[()=>pdpuT1(0),()=>pdpuT2(0)]},
{id:'pdpu2',x:934,y:46,w:158,h:150,t:'PDPU 2 plating',s:'2 cells · up to 200 A',custom:'pdpu',u:1,det:'pdpu',tags:[()=>pdpuT1(1),()=>pdpuT2(1)]},
{id:'pmpb',x:1102,y:46,w:120,h:150,t:'PMPB bench',s:'separate · passivate',st:'pmpb',bar:true,tags:[()=>stTxt('pmpb'),()=>stLeft('pmpb'),()=>'queue '+ST.pmpb.q.length,()=>'DI tank '+f0(S.diro.tank*100)+' %']},
{id:'qc',x:1232,y:46,w:108,h:150,t:'Part QC',s:'XRF · listening',st:'qc',bar:true,tags:[()=>stTxt('qc'),()=>stLeft('qc'),()=>'queue '+ST.qc.q.length,()=>S.lastXRF]},
{id:'vsf',x:1368,y:46,w:132,h:150,t:'VSF finisher',s:'Sibert · back-finish',st:'vsf',bar:true,tags:[()=>stTxt('vsf'),()=>stLeft('vsf'),()=>'queue '+ST.vsf.q.length,()=>'8 min (est.)']},
{id:'vsp',x:1510,y:46,w:132,h:150,t:'VSP punch',s:'Sibert · ×100 optics',st:'vsp',bar:true,tags:[()=>stTxt('vsp'),()=>stLeft('vsp'),()=>'queue '+ST.vsp.q.length,()=>'conc. '+(S.lastConc?f0(S.lastConc)+' µm':'-')]},
{id:'vsc',x:1652,y:46,w:132,h:150,t:'VSC coiner',s:'Sibert · centre + edge',st:'vsc',bar:true,tags:[()=>stTxt('vsc'),()=>stLeft('vsc'),()=>'queue '+ST.vsc.q.length,()=>'today '+S.day.stampers+' done']},
{id:'pdpu1',x:766,y:46,w:158,h:150,t:'PDPU plating',s:'2 cells · up to 200 A',custom:'pdpu',u:0,det:'pdpu',tags:[()=>pdpuT1(0),()=>pdpuT2(0)]},
{id:'pmpb',x:934,y:46,w:120,h:150,t:'PMPB bench',s:'separate · passivate',st:'pmpb',bar:true,tags:[()=>stTxt('pmpb'),()=>stLeft('pmpb'),()=>'queue '+ST.pmpb.q.length,()=>'DI tank '+f0(S.diro.tank*100)+' %']},
{id:'qc',x:1064,y:46,w:108,h:150,t:'Part QC',s:'XRF · listening',st:'qc',bar:true,tags:[()=>stTxt('qc'),()=>stLeft('qc'),()=>'queue '+ST.qc.q.length,()=>S.lastXRF]},
{id:'vsf',x:1200,y:46,w:188,h:150,t:'VSF finisher',s:'Sibert · back-finish',st:'vsf',bar:true,tags:[()=>stTxt('vsf'),()=>stLeft('vsf'),()=>'queue '+ST.vsf.q.length,()=>'8 min (est.)']},
{id:'vsp',x:1398,y:46,w:188,h:150,t:'VSP punch',s:'Sibert · ×100 optics',st:'vsp',bar:true,tags:[()=>stTxt('vsp'),()=>stLeft('vsp'),()=>'queue '+ST.vsp.q.length,()=>'conc. '+(S.lastConc?f0(S.lastConc)+' µm':'-')]},
{id:'vsc',x:1596,y:46,w:188,h:150,t:'VSC coiner',s:'Sibert · centre + edge',st:'vsc',bar:true,tags:[()=>stTxt('vsc'),()=>stLeft('vsc'),()=>'queue '+ST.vsc.q.length,()=>'today '+S.day.stampers+' done']},
{id:'archive',x:1812,y:46,w:130,h:150,t:'Archive',s:'fathers · mothers',tags:[()=>'fathers '+S.archive.F,()=>'mothers '+S.archive.M,()=>'pulled '+S.pulled,()=>'3-step plating']},
{id:'rack',x:1952,y:46,w:130,h:150,t:'Stamper rack',s:'press-ready sets',tags:[()=>'ready '+rackReady(),()=>'at gate 3 '+rackWait(),()=>'for TP '+rackTP(),()=>'next '+rackNext()]},
// pressing hall
@@ -583,12 +588,10 @@ const MACH=[
{id:'vex',x:484,y:316,w:140,h:128,custom:'vex'},
{id:'ex35',x:484,y:452,w:140,h:58,t:'EX 35 colour',s:'auxiliary extruder',tags:[()=>S.ex35?'strands ON':'strands idle']},
{id:'pDB',x:634,y:316,w:124,h:196,custom:'press',t:'HRP 12 · B',s:'Duplex · semi-auto',det:'duplex'},
{id:'pC1',x:784,y:316,w:150,h:196,custom:'press',t:'Classic C1',s:'automatic · 3-column',det:'classic',c3:true},
{id:'pC2',x:946,y:316,w:150,h:196,custom:'press',t:'Classic C2',s:'automatic · 3-column',det:'classic',c3:true},
{id:'pC1',x:864,y:316,w:150,h:196,custom:'press',t:'Classic',s:'automatic · 3-column',det:'classic',c3:true},
{id:'tA',x:350,y:522,w:84,h:44,t:'Trimmer A',det:'trim',tags:[()=>trimTag('pDA')]},
{id:'tB',x:634,y:522,w:84,h:44,t:'Trimmer B',det:'trim',tags:[()=>trimTag('pDB')]},
{id:'tC1',x:784,y:522,w:110,h:44,t:'Trimmer C1',det:'trim',tags:[()=>trimTag('pC1')]},
{id:'tC2',x:946,y:522,w:110,h:44,t:'Trimmer C2',det:'trim',tags:[()=>trimTag('pC2')]},
{id:'tC1',x:864,y:522,w:110,h:44,t:'Trimmer C',det:'trim',tags:[()=>trimTag('pC1')]},
{id:'audioqc',x:1120,y:338,w:130,h:70,t:'Audio compare',s:'all TPs + 1 in 50',tags:[()=>'n '+S.samples+' · '+S.audioLast]},
{id:'punch',x:1264,y:338,w:130,h:70,t:'Label punch',s:'106 mm · rejects',tags:[()=>'punched '+S.punched]},
{id:'gran',x:1408,y:320,w:164,h:104,t:'Granulator 400',s:'edge trim + rejects',tags:[()=>'bin '+f1(S.gran.bin)+' kg',()=>S.gran.run?'BATCH '+f1(S.gran.run)+' kg':'waits for 12 kg',()=>'ground '+f0(S.gran.total)+' kg',()=>'200 to 250 kg/h']},
@@ -598,8 +601,8 @@ const MACH=[
{id:'pack',x:1408,y:452,w:150,h:96,t:'Packaging',s:'matrix vs barcode',tags:[()=>'assembled '+S.assembled,()=>'mismatch '+S.mismatch,()=>'barcode 100 %']},
{id:'ship',x:1572,y:452,w:200,h:96,t:'Fulfillment',s:'bulk pallet · dropship',tags:[()=>'pallet '+S.pallet+' / 300',()=>'dropship '+S.parcels+' parcels',()=>'TPs to artists '+S.tpToArtist]},
// utilities
{id:'boiler',x:20,y:676,w:160,h:132,t:'Steam boiler',s:'10 bar · 180 °C',tags:[()=>'P '+f2(S.boiler.p)+' bar',()=>'flow '+f0(S.boiler.F*HOUR)+' kg/h',()=>'cap 800 kg/h est.',()=>'press 150-180 kg/h',()=>'fuel: open']},
{id:'chiller',x:192,y:676,w:176,h:132,t:'Process cooling',s:'chiller · cooling tower',tags:[()=>'supply '+f1(S.chiller.sup)+' °C',()=>'return '+f1(S.chiller.ret)+' °C',()=>'flow '+f0(S.chiller.flow)+' l/min',()=>'load '+f0(S.chiller.load)+' kW',()=>'cap 500 kW est.']},
{id:'boiler',x:20,y:676,w:160,h:132,t:'Steam boilers',s:'B-1 + B-2 · 10 bar · 180 °C',tags:[()=>'P '+f2(S.boiler.p)+' bar',()=>'flow '+f0(S.boiler.F*HOUR)+' kg/h',()=>'cap 2 × 500 kg/h',()=>'press 150-180 kg/h',()=>'fuel: open']},
{id:'chiller',x:192,y:676,w:176,h:132,t:'Process cooling',s:'CH-1 + CH-2 · air-cooled',tags:[()=>'supply '+f1(S.chiller.sup)+' °C',()=>'return '+f1(S.chiller.ret)+' °C',()=>'flow '+f0(S.chiller.flow)+' l/min',()=>'load '+f0(S.chiller.load)+' kW',()=>'cap 2 × 250 kW']},
{id:'comp',x:380,y:676,w:120,h:132,t:'Compressed air',s:'6 to 10 bar, dry',tags:[()=>'P '+f1(S.comp.p)+' bar',()=>'dew '+f1(jit(2.5,.4))+' °C',()=>'presses',()=>'Sibert, PASU']},
{id:'hyd',x:512,y:676,w:124,h:132,t:'Hydraulics',s:'Duplex aggregate',tags:[()=>'P '+f0(S.hyd.p)+' bar',()=>'oil '+f1(S.hyd.oil)+' °C',()=>'HLP 46 · 200 l',()=>'presses A + B']},
{id:'diro',x:648,y:676,w:136,h:132,t:'RO / DI water',s:'galvanics rinse',tags:[()=>'tank '+f0(S.diro.tank*100)+' %',()=>'cond '+f1(S.diro.cond)+' µS/cm',()=>'to PMPB, PASU',()=>'0.2 m³/h est.']},
@@ -635,10 +638,10 @@ function lane(x,y,txt){el('text',{x,y,class:'lane'},L.mach,txt);}
lane(20,24,'Metal path · audio file to stamper');
lane(20,300,'Pressing hall · Newbilt · material and record path');
lane(20,668,'Utilities and plant systems');
el('rect',{x:478,y:30,width:870,height:176,rx:6,class:'room'},L.pipes);
el('rect',{x:478,y:30,width:702,height:176,rx:6,class:'room'},L.pipes);
el('text',{x:488,y:24,class:'roomlbl'},L.mach,'Galvanics clean room · Pheenix Alpha');
el('rect',{x:1358,y:30,width:436,height:176,rx:6,class:'room'},L.pipes);
el('text',{x:1368,y:24,class:'roomlbl'},L.mach,'Stamper prep · Sibert');
el('rect',{x:1190,y:30,width:604,height:176,rx:6,class:'room'},L.pipes);
el('text',{x:1200,y:24,class:'roomlbl'},L.mach,'Stamper prep · Sibert');
function boxBase(m){const g=el('g',{class:'machine',id:'m_'+m.id});
el('rect',{x:m.x,y:m.y,width:m.w,height:m.h,rx:4,class:'mbox'},g);
@@ -697,7 +700,7 @@ function drawPdpu(m){m.tagY=m.y+126;const g=drawBox(m);
m.cells=[0,1].map(i=>{const cx=m.x+7+i*74,cy=m.y+38,cw=70,ch=76;const cg=el('g',{class:'cell'},g);
el('rect',{x:cx,y:cy,width:cw,height:ch,rx:2,class:'cellr'},cg);
el('rect',{x:cx+3,y:cy+20,width:cw-6,height:ch-23,class:'liquid'},cg);
for(let b=0;b<3;b++)FX.bubbles.push({x:cx+10+b*18,y:cy+ch-5,d:rnd(0,2.2),cell:(m.id==='pdpu2'?2:0)+i});
for(let b=0;b<3;b++)FX.bubbles.push({x:cx+10+b*18,y:cy+ch-5,d:rnd(0,2.2),cell:i});
el('rect',{x:cx+cw-11,y:cy+22,width:6,height:50,class:'thk'},cg);
const tv=el('rect',{x:cx+cw-11,y:cy+72,width:6,height:0,class:'thkv'},cg);
const t=[0,1,2,3].map(k=>el('text',{x:cx+4,y:cy+12+k*15,class:'ctxt'},cg,''));
@@ -730,28 +733,28 @@ function flow(d,cls){const c=cls.split(' ');FX.flows.push({k:'flow',c:c[0],thin:
function route(id,d,cls){PATHS[id]=poly(d);flow(d,cls);}
function pipe(d,cls,thin){FX.flows.push({k:'pipe',c:cls,p2:new Path2D(d)});flow(d,cls+(thin?' thin':''));}
// pipe rack y 616 to 650, drops into each press from below
pipe('M100,676 V616 H1074','steam');['456','740','912','1074'].forEach(x=>pipe(`M${x},616 V512`,'steam'));
pipe('M1080,621 H112 V676','cond',true);
pipe('M262,676 V626 H1086','cw');['466','750','924','1086'].forEach(x=>pipe(`M${x},626 V512`,'cw'));
pipe('M1092,631 H282 V676','cwr',true);
pipe('M100,676 V616 H992','steam');['456','740','992'].forEach(x=>pipe(`M${x},616 V512`,'steam'));
pipe('M998,621 H112 V676','cond',true);
pipe('M262,676 V626 H1004','cw');['466','750','1004'].forEach(x=>pipe(`M${x},626 V512`,'cw'));
pipe('M1010,631 H282 V676','cwr',true);
pipe('M574,676 V636 H444 V512','hyd');pipe('M574,636 H728 V512','hyd');
// galvanics services: up the right-hand side to headers over the clean room
pipe('M300,676 V644 H2088 V34 H845 V46','chw',true);pipe('M1013,34 V46','chw',true);
pipe('M716,676 V650 H2094 V40 H544 V46','di',true);pipe('M1162,40 V46','di',true);
pipe('M300,676 V644 H2088 V34 H845 V46','chw',true);
pipe('M716,676 V650 H2094 V40 H544 V46','di',true);pipe('M994,40 V46','di',true);
// record conveyor and edge-trim collection
FX.flows.push({k:'conv',p2:new Path2D('M370,590 H1772')},{k:'convd',p2:new Path2D('M370,590 H1772')});
flow('M392,574 H1104','scrap thin');
// material
route('s_v','M47,436 V444 H272 V428','mat thin');route('s_r','M107,436 V444 H272 V428','reg thin');route('s_c','M167,436 V444 H272 V428','col thin');
route('f_vex','M272,316 V308 H554 V366','mat thin');route('f_c1','M272,316 V308 H859 V316','mat thin');route('f_c2','M272,316 V308 H1021 V316','mat thin');
route('f_vex','M272,316 V308 H554 V366','mat thin');route('f_c1','M272,316 V308 H939 V316','mat thin');
route('f_ex35','M272,316 V308 H629 V481 H624','col thin');route('ex2vex','M554,452 V444','col thin');
route('l_pDA','M194,482 H350','lbl thin');route('l_pDB','M194,500 H340 V517 H646 V512','lbl thin');
route('l_pC1','M194,500 H340 V517 H796 V512','lbl thin');route('l_pC2','M194,500 H340 V517 H958 V512','lbl thin');
route('l_pC1','M194,500 H340 V517 H876 V512','lbl thin');
route('trimcart','M1104,574 V444 H1440 V424','scrap thin');
route('reject','M1200,590 V570 H1257 V432 H1329 V408','scrap thin');route('sample','M1170,590 V570 H1112 V373 H1120','route thin');
route('p2g','M1394,371 H1408','scrap thin');route('regrind','M1490,320 V284 H107 V316','reg thin');
route('carton','M1685,408 V430 H1483 V452','route thin');
['pDA:412','pDB:696','pC1:859','pC2:1021'].forEach(s=>{const [id,x]=s.split(':');route('st_'+id,`M2017,196 V278 H${x} V316`,'metal thin');});
['pDA:412','pDB:696','pC1:939'].forEach(s=>{const [id,x]=s.split(':');route('st_'+id,`M2017,196 V278 H${x} V316`,'metal thin');});
[[180,612,'steam 10 bar'],[1250,640,'galvanics services: cooling water 12 to 20 °C · DI water'],[1500,274,'stamper sets to presses'],[130,280,'regrind to silo'],
[1120,438,'edge trim, in batches'],[1262,428,'rejects'],[1116,332,'samples'],[200,478,'labels']].forEach(a=>el('text',{x:a[0],y:a[1],class:'small'},L.top,a[2]));
@@ -766,7 +769,7 @@ function ctr(id){const m=M[id];return m?{x:m.x+m.w/2,y:m.y+m.h/2}:null;}
function hop(from,to,it){if(!visHop()||!from)return;const a=ctr(from),b=ctr(to);if(!a||!b)return;
const kind=it.grow?it.grow:it.gen==='L'?(it.silvered?'Ls':'L'):it.gen;const n=shape(kind);hops.push({n,a,b,t:0,d:1.1});place(n,a);}
function routeHop(pid,kind){mover(pid,shape(kind),320,m=>m.node.remove());}
const RECS=[];const CONV0=370,CONVEND=1772,CONVY=590;const DROPX={pDA:392,pDB:676,pC1:839,pC2:1001};
const RECS=[];const CONV0=370,CONVEND=1772,CONVY=590;const DROPX={pDA:392,pDB:676,pC1:919};
const STATIONS=[{id:'optical',at:1185,dwell:2.2},{id:'finish',at:1329,dwell:2.5},{id:'pack',at:1483,dwell:3},{id:'ship',at:1672,dwell:0.5}];
function mkRec(P,tp){const T=P.set.T;const g=spr('rec',{r:9,lr:3.2,vinyl:T.vinyl,label:T.label});if(tp)g.classList.add('tp');
const r={node:g,T,tp,ph:'trim',dwell:6,x:DROPX[P.id],y:544,pos:0,visited:{},n:P.cyc,pname:P.name};RECS.push(r);place(g,r);return r;}
@@ -818,11 +821,11 @@ function matTick(){
/* ================================================================ utilities */
function utilTick(ds){
let draw=0;PRESS.forEach(P=>{if(P.state==='STEAM'&&!P.waiting)draw+=STEAM_KG/seqDur(P,'STEAM');});
// header holds ~10 kg of steam per bar; boiler shown at 800 kg/h (estimate, see detail)
const B=S.boiler,fault=S.t<B.faultUntil,Fmax=fault?0:800/HOUR;
// header holds ~10 kg of steam per bar; boiler bank B-1 + B-2 at 2 x 500 kg/h (scale.md, steam-cooling.html)
const B=S.boiler,fault=S.t<B.faultUntil,Fmax=fault?0:1000/HOUR;
const F=B.p<10.05?Fmax:Math.min(Fmax,draw);B.p=Math.min(10.12,B.p+(F-draw)/10*ds);B.F=lag(B.F,F,0.02,ds);
if(B.faultUntil>0&&!fault&&B.p>9.6){B.faultUntil=-1;log('Boiler: feedwater pump back, '+f2(B.p)+' bar, presses resume','ok');}
let heat=0,flow=20;PRESS.forEach(P=>{if(running(P)){heat+=72;flow+=53;}});
let heat=0,flow=20;PRESS.forEach(P=>{if(running(P)){heat+=72;flow+=53;}}); // average per running press; CH-1 + CH-2 = 500 kW below
heat+=CELLS.filter(c=>c.ph==='plate').length*1.5;
const C=S.chiller;C.load=lag(C.load,heat,1/600,ds);C.flow=lag(C.flow,flow,0.05,ds);C.sup=lag(C.sup,22+Math.max(0,C.load-500)/40,1/300,ds);C.ret=C.sup+C.load/(C.flow/60*4.186);
S.comp.p=lag(S.comp.p,PRESS.some(P=>P.state==='LOAD'||P.state==='EJECT')?7.2:7.7,0.9,ds);
@@ -858,7 +861,7 @@ function animate(dt){
for(let i=hops.length-1;i>=0;i--){const h=hops[i];h.t+=dt;const k=Math.min(1,h.t/h.d);place(h.n,{x:h.a.x+(h.b.x-h.a.x)*k,y:h.a.y+(h.b.y-h.a.y)*k-Math.sin(k*Math.PI)*18});if(k>=1){h.n.remove();hops.splice(i,1);}}
RECS.forEach(r=>{if(!r.gone)place(r.node,r.ph==='conv'?{x:CONV0+r.pos,y:CONVY}:{x:r.x,y:r.y});});
if(S.running&&!S.quiet&&S.speed<=600){feedAcc+=dt;
if(feedAcc>0.7&&PRESS.some(running)){feedAcc=0;const k=pick(['s_v','s_v','s_r','s_c','f_vex','f_c1','f_c2']);
if(feedAcc>0.7&&PRESS.some(running)){feedAcc=0;const k=pick(['s_v','s_v','s_r','s_c','f_vex','f_vex','f_c1']);
const col=k==='s_r'?'#8ea36f':k==='s_c'?'#c86bff':'#b9c2d0';mover(k,dot(col),110,m=>m.node.remove());
if(S.ex35&&Math.random()<0.5)mover('f_ex35',dot('#c86bff'),110,m=>{m.node.remove();mover('ex2vex',dot('#c86bff'),20,mm=>mm.node.remove());});}
cartonAcc+=dt;if(cartonAcc>7){cartonAcc=0;mover('carton',spr('rect',{w:12,h:8,fill:'#8a6d3b',stroke:'#c9a24a'}),50,m=>m.node.remove());}}
@@ -878,13 +881,13 @@ function renderTags(){
setT(m.tagEls[1],T?T.id+' · '+P.set.k:(P.state==='OFF'?'':'waiting for a set'));
setT(m.tagEls[2],!T?'':P.mode==='tp'?'test press '+(TP_N-P.tpLeft)+'/'+TP_N:P.mode==='fa'?'first article':'run '+T.cycles+'/'+T.target);
lampSet(P.id,P.state==='NOPVC'||P.state==='STOP'?'alarm':amber?'warn':running(P)?'run':'idle');});
['tA','tB','tC1','tC2'].forEach((id,i)=>lampSet(id,running(PRESS[i])?'run':'idle'));
['tA','tB','tC1'].forEach((id,i)=>lampSet(id,running(PRESS[i])?'run':'idle'));
const dRun=PRESS.slice(0,2).some(running);
M.vex.zoneT.forEach((t,i)=>setT(t,f0(dRun?jit([132,146,156][i],1):[92,96,98][i])+'°'));
M.vex.zoneEls.forEach((z,i)=>{setS(z,'fill',dRun?'var(--z'+(i+1)+')':'var(--z0)');});lampSet('vex',dRun?'run':'idle');lampSet('ex35',S.ex35?'run':'idle');
M.pppu.pos.forEach((p,i)=>{const w=ST.pppu.slots[i];setA(p.r,'class','pos'+(w?' on':''));setT(p.a,w?w.it.T.sid+w.it.side+' 20 A':'free');setT(p.b,w?dur(w.end-S.t):'');});
lampSet('pppu',ST.pppu.slots.some(Boolean)?'run':ST.pppu.q.length?'warn':'idle');
[0,1].forEach(u=>{const m=M['pdpu'+(u+1)];let any=false,done=false;
[0].forEach(u=>{const m=M['pdpu'+(u+1)];let any=false,done=false;
m.cells.forEach((cv,i)=>{const c=CELLS[u*2+i];const j=c.job;setA(cv.g,'class','cell'+(c.ph==='plate'?' on':c.ph==='done'?' done':''));
if(c.ph!=='idle')any=true;if(c.ph==='done')done=true;
const hh=50*(j?Math.min(1,c.mass/c.target):0);setA(cv.tv,'y',(cv.cy+72-hh).toFixed(1));setA(cv.tv,'height',hh.toFixed(1));
@@ -903,7 +906,7 @@ function renderTags(){
['comp','diro','zld','energy','trace','hvac','exh'].forEach(id=>lampSet(id,'run'));lampSet('hyd',dRun?'run':'idle');
setT(GATES.g1.c,cntStage('gate1')+' waiting');setT(GATES.g2.c,cntStage('gate2')+' waiting');setT(GATES.g3.c,TITLES.filter(T=>T.tp==='sent').length+' waiting');
setT($('kClock'),clockStr());setT($('kShift'),shiftOn()?(hourOf()<14?'1 (06-14)':'2 (14-22)'):'night');
setT($('kPress'),PRESS.filter(running).length+'/4');
setT($('kPress'),PRESS.filter(running).length+'/'+PRESS.length);
setT($('kRate'),S.cyc.length);setT($('kGood'),S.day.good);setT($('kRej'),S.day.rej);setT($('kYield'),yieldStr());
setT($('kGalv'),galvCount());setT($('kRack'),rackReady());
setT($('kSteam'),f2(S.boiler.p)+' bar');setS($('kSteam'),'color',S.boiler.p<9.5?'#ff3b3b':'');
@@ -918,12 +921,12 @@ function log(msg,lvl){S.events++;if(S.quiet)return;
/* ================================================================ details */
const DETAILS={
audio:{t:'1 · Audio intake',w:'Files arrive from the label or artist; checksums and format are verified and a technical QA pass checks levels, clipping and side length against the format. Nothing is cut until the artist confirms the master plan (gate 1, 2 to 10 days on the customer side).',c:['Checksums and format','Technical QA: levels, clipping, side length','Artist gate 1: master plan approved'],f:['1 to 2 days (production timeline)','A new title every 0.55 to 0.85 days here, ~520 a year (revenue model at full capacity: 300 to 600)','Runs of 300 to 10,000, ~3,100 records per title on average (revenue model: 2,500 to 3,300)']},
audio:{t:'1 · Audio intake',w:'Files arrive from the label or artist; checksums and format are verified and a technical QA pass checks levels, clipping and side length against the format. Nothing is cut until the artist confirms the master plan (gate 1, 2 to 10 days on the customer side).',c:['Checksums and format','Technical QA: levels, clipping, side length','Artist gate 1: master plan approved'],f:['1 to 2 days (production timeline)','A new title every 0.75 to 1.15 days here, ~380 a year, between the revenue model\'s 300 (central) and 400 (favourable) titles for the launch plant; in 90-day test runs the presses run ~64 to 73 % of shift time, about scale.md\'s 60 to 70 % effectiveness (estimate)','Runs of 300 to 10,000, ~3,100 records per title on average (revenue model: 2,500 to 3,300)']},
master:{t:'2 · Vinyl mastering',w:'The audio is mastered for the physical limits of the groove. The artist approves the vinyl master (gate 2, 2 to 10 days) before anything is cut.',c:['Engineer QA of the vinyl master','Artist gate 2: master approved'],f:['2 to 4 days in-house (production timeline)','Mastering room ~40 to 60 m²','Mastering and lathe cutting are the planned Payap student-programme subjects (payap-partnership.md)']},
cut:{t:'3 · Lathe cutting',w:'The master is cut into a nitrocellulose lacquer per side: grooves 40 to 80 µm wide, ~28 µm deep. The dead-wax matrix code and an angular fiducial are scribed cold (never with a laser: the lacquer is flammable), and the scribe carries through every metal generation onto every record. Both lacquers go to silvering together and must be plated within roughly 24 to 72 hours.',c:['Groove microscope','Test cut','Dead-wax scribe and fiducial'],f:['1 to 2 days','Sillitoe SDMS or Agnew lathe (vendor landscape)']},
pasu:{t:'4a · PASU automatic silvering (Pheenix Alpha)',w:'The lacquer is cleaned on the bench station, sensitised, then turned at 45 rpm under four nozzles that spray the silver in an automatic sequence, making the groove conductive for the nickel. Silver is the first metal to touch the groove.',c:['Silvering chemistry logged per batch','Lacquer inspected before silvering'],f:['~15 min per lacquer (estimate; no published figure)','W 2188 × D 715 × H 1835 mm, single-phase 10 A, air 6 bar, exhaust Ø125 mm at 150 m³/h (2024 flyer)']},
pppu:{t:'4b · PPPU pre-plating (Pheenix Alpha)',w:'A thin first nickel layer over the silver at low current, before production plating. Up to four masters at once, each position with its own control and cathode movement, PID temperature control.',c:['Bath temperature PID-controlled','Current and time logged per position'],f:['15 to 30 min at 10 to 20 A in published practice; 20 min at 20 A and 35 °C here (galvanics.md)','Up to 15 VDC and 30 A per position, 385 L tank, 4.5 kW heater (2024 flyer)']},
pdpu:{t:'4c · PDPU dual plating unit (Pheenix Alpha)',w:'Production electroforming: father on the pre-plated lacquer, mother on the father, stampers on the mother. Each cell has its own rotating cathode and digitally controlled rectifier; the current ramps up and the part grows to its thickness. The simulation deposits nickel by Faraday\'s law (1.095 g per ampere-hour at ~97 % efficiency, ~9.6 dm² for a Ø350 mm part), so the times follow from the current: father 0.25 mm in ~1 h 15 min on a slow ramp to 185 A, mother 0.25 mm in ~1 h and stamper 0.20 mm in ~50 min at 200 A. Loading takes 5 min, rinsing and unloading 10 min per part. A part that finishes after the shift waits in the cell until morning.',c:['Current, voltage and ampere-hours per cell (PLC with network access)','Bath temperature, filters, nickel top-up and anode basket alerts','Extraction interlock: no extraction, no plating'],f:['Up to 15 VDC and 200 A per cell, 40 L per cell, 385 L tank, parts up to Ø355 mm, cooling water 12 to 20 °C at 10 L/min (2024 flyer)','Published practice: father ~1 h 15 min, mother 1 to 1¼ h, stamper ~45 min (galvanics.md)','One PDPU covers full-capacity demand (20 to 32 parts a day); the second buys redundancy rather than capacity','Bath at 55 °C on screen is an estimate']},
pdpu:{t:'4c · PDPU dual plating unit (Pheenix Alpha)',w:'Production electroforming: father on the pre-plated lacquer, mother on the father, stampers on the mother. Each cell has its own rotating cathode and digitally controlled rectifier; the current ramps up and the part grows to its thickness. The simulation deposits nickel by Faraday\'s law (1.095 g per ampere-hour at ~97 % efficiency, ~9.6 dm² for a Ø350 mm part), so the times follow from the current: father 0.25 mm in ~1 h 15 min on a slow ramp to 185 A, mother 0.25 mm in ~1 h and stamper 0.20 mm in ~50 min at 200 A. Loading takes 5 min, rinsing and unloading 10 min per part. A part that finishes after the shift waits in the cell until morning.',c:['Current, voltage and ampere-hours per cell (PLC with network access)','Bath temperature, filters, nickel top-up and anode basket alerts','Extraction interlock: no extraction, no plating'],f:['Up to 15 VDC and 200 A per cell, 40 L per cell, 385 L tank, parts up to Ø355 mm, cooling water 12 to 20 °C at 10 L/min (2024 flyer)','Published practice: father ~1 h 15 min, mother 1 to 1¼ h, stamper ~45 min (galvanics.md)','The launch plant has one PDPU (total-investment.md); it covers full-capacity demand of 20 to 32 parts a day, a second would buy redundancy rather than capacity (galvanics.md)','Bath at 55 °C on screen is an estimate']},
pmpb:{t:'4d · PMPB preparation bench (Pheenix Alpha)',w:'Between generations the new part is separated, cleaned, passivated anodically so the next generation will part from it, and spun dry. The lacquer is consumed when the father comes off; in 3-step plating the father, and later the mother, go to the archive.',c:['Passivation logged per part','Rinse water to treatment, never the drain'],f:['~10 to 15 min per part (estimate)','Spin table up to 120 rpm, DI water G3/4", single-phase 10 A (2024 flyer)']},
qc:{t:'4e · Part QC: XRF and mother listening',w:'Every father, mother and stamper gets an XRF thickness reading against its serial; every mother is played before stampers are grown from it, since the mother is the playable positive.',c:['XRF nickel thickness per part, 0.2 to 0.3 mm','Mother listening check'],f:['~3 min per XRF reading, ~25 min for a mother with listening (estimates)']},
vsf:{t:'5a · VSF back-finish (Sibert)',w:'The stamper back is wet-sanded through a sequence of abrasive grades and cleaned, so it seats evenly on the mould and no back-side defect presses through. First of the three Sibert steps: finish, punch, coin (the order Gotta Groove runs its Sibert machines in).',c:['Back visual check','Closed water loop with filtration; the nickel-bearing water goes to treatment'],f:['~5 to 10 min (estimate; Sibert publishes none), 8 min here','P120 to P2500 in nine grades, 4-station disc head, 150 to 1500 rpm, 1200 VA, 250 kg (2022 spec)']},
@@ -937,7 +940,7 @@ const DETAILS={
lab:{t:'M · Material lab gate',w:'Every incoming lot is quarantined and tested before release; production keeps running on released stock meanwhile. New lots and new suppliers are released only after a release pressing passes optical and audio QC.',c:['Moisture (halogen analyser), heat stability, density, colour','Release pressing'],f:['~2 h from start of tests to release here (estimate)','Instruments and costs: quality-automation.md']},
oven:{t:'L · Label dry oven',w:'Centre labels are pressed into the record, not glued on. Moisture in the paper causes bubbles, so labels are pre-dried before they reach a press, and the label lot is logged per press cycle.',c:['Print inspection per label lot','Label identity and centring checked by the optical inspection'],f:['France Etuves XU 112 class oven (Newbilt quote)']},
duplex:{t:'6 · Duplex: HRP 12 presses A and B (Newbilt)',w:'Two semi-automatic presses on one VEX 50 extruder and one hydraulic unit. Each cycle the operator places the bottom label, the cake and the top label; the press closes, steam at 10 bar heats the mould and ~150 t flows the vinyl into the grooves, cooling water sets it, it opens and ejects. Newbilt recommends the Duplex for splatter, so colour and splatter titles come here first; splatter runs the EX 35.',c:['Per cycle: temperatures, pressures, cycle time, cake weight, label lot','10 test pressings for every new title, then gate 3','Record key: stamper + press + cycle timestamp + side'],f:['~30 s average cycle (Newbilt website); here LOAD 4 to 6.5 (by hand), CLOSE 2, STEAM 8, COOL 10, OPEN 2, EJECT 3 s (split is an estimate)','scale.md assumes only 60 to 80 records/h per semi-automatic press with operator handling (estimate); Newbilt\'s 30 s is 120/h','HRP 12: four columns, Ø330 mm cylinder, ~150 t (2024 quote)','Steam 150 to 180 kg/h, cooling up to 100 l/min and 125 kW per press (site requirements)','Stamper change ~20 min, new title ~40 min (estimates)','Unplanned stops about one per 4 running hours, 15 to 45 min each (estimate, sized so overall effectiveness lands near scale.md\'s 60 to 70 %)']},
classic:{t:'6 · Classic automatic presses C1 and C2 (Newbilt)',w:'Fully automatic, on a 3-column frame derived from the Toolex Alpha: built-in extruder, automatic cake and label loading, cooling-plate handling and spindle stacking. Cooling can end by time or by delivered water volume, and the target volume rises as the cooling water warms, so the cycle stretches when the chiller supply runs above design (modelled at 5 % per °C over 22 °C). Black and solid colour titles; Newbilt sends splatter to the Duplex.',c:['Steam temperature, cooling water temperature and flow monitored','Cycle and trend recording; SCADA interface over OPC UA'],f:['28 s even at 180 g, claimed ≥95 % yield and ≥95 % uptime (2024 flyer); here LOAD 3, CLOSE 2, STEAM 7, COOL 11, OPEN 2, EJECT 3 s','12" at 110 to 180 g, 7" in development, inserts shared with the Duplex (2026 flyer)','Built-in extruder: three zones, 7.5 kW motor (2024 flyer)','Unplanned stops as for the Duplex (estimate)']},
classic:{t:'6 · Classic automatic press (Newbilt)',w:'Fully automatic, on a 3-column frame derived from the Toolex Alpha: built-in extruder, automatic cake and label loading, cooling-plate handling and spindle stacking. Cooling can end by time or by delivered water volume, and the target volume rises as the cooling water warms, so the cycle stretches when the chiller supply runs above design (modelled at 5 % per °C over 22 °C). Black and solid colour titles; Newbilt sends splatter to the Duplex.',c:['Steam temperature, cooling water temperature and flow monitored','Cycle and trend recording; SCADA interface over OPC UA'],f:['28 s even at 180 g, claimed ≥95 % yield and ≥95 % uptime (2024 flyer); here LOAD 3, CLOSE 2, STEAM 7, COOL 11, OPEN 2, EJECT 3 s','12" at 110 to 180 g, 7" in development, inserts shared with the Duplex (2026 flyer)','Built-in extruder: three zones, 7.5 kW motor (2024 flyer)','Unplanned stops as for the Duplex (estimate)']},
vex:{t:'6a · VEX 50 extruder (Newbilt)',w:'Feeds both Duplex presses: granulate from the hopper melts through three heated zones and leaves as a cake 20 to 40 g heavier than the record, the surplus becoming edge trim. The two presses draw cakes alternately.',c:['Zone temperatures and screw speed logged','Cake weight per cycle','Regrind ratio verified here'],f:['50 mm screw, three zones, 7.5 kW motor, 45° mounting (2024 quote)','15 kVA connected, 8 kW average (site requirements)']},
ex35:{t:'6b · EX 35 auxiliary extruder (Newbilt)',w:'Runs beside the VEX 50 and adds a second or third colour as PVC strands for splatter, marble and other effects. Active here whenever a Duplex press runs a splatter title.',c:['Colour lot logged per cycle'],f:['35 mm screw, three zones, two fans, frequency-controlled screw speed (2026 flyer)','Not in the 2024 quote']},
trim:{t:'7a · Edge trimmers (Newbilt)',w:'A heated blade trims each record to its final diameter straight after the press. The trim drops into bins that go to the granulator in batches.',c:['Trim quality on every record'],f:['~6 s per record (estimate; no published figure)','Heated blade, 7"/10"/12" plates, standalone or in the Duplex emergency-stop circuit (2026 flyer)']},
@@ -949,13 +952,13 @@ const DETAILS={
finish:{t:'7b · Finishing',w:'Inner sleeve and, once assembled, the shrink wrapper. The labels are already on: they were pressed in.',c:['Inner sleeve scuff check per lot','Shrink wrap sampled'],f:['2 to 3 days per order (production timeline)']},
pack:{t:'8 · Packaging and assembly',w:'The runout matrix code is scanned against the jacket barcode, so the wrong record in the right jacket is caught every time.',c:['Matrix code vs jacket barcode on every unit','Barcode verification'],f:['Packaging and finished goods ~300 to 500 m²']},
ship:{t:'9 · Fulfillment',w:'Bulk pallets, or per-parcel dropship for the label; carrier tracking joins the traceability record. Test pressings leave here for the artists.',c:['Consignment vs bill of materials','Tracking per shipment or per end customer'],f:['Quoted lead time 7 to 9 weeks mature, 2 to 3 weeks for a repress']},
boiler:{t:'Steam boiler',w:'Saturated steam at 10 bar / 180 °C heats the moulds; each press draws ~1.3 kg per cycle. Four presses need 600 to 720 kg/h at Newbilt\'s 150 to 180 kg/h per press, so the boiler is shown at 800 kg/h. That is an estimate for this four-press page; the five-press plan (scale.md, steam-cooling.html) is a bank of two 500 kg/h modules. Below 9.5 bar the presses hold in STEAM (Steam dip button).',c:['Pressure held between 9.5 and 10.5 bar at the press','Feedwater treatment, condensate return'],f:['Fuel decision open: biomass, LPG or electric','Detached boiler hall with a 14 m flue','Five-press plan: 750 to 900 kg/h on a 2 × 500 kg/h boiler bank (steam-cooling.html)']},
chiller:{t:'Process cooling',w:'Cooling water sets the vinyl after the steam phase. The four presses here can need up to 125 kW each, so the chiller is shown at 500 kW (estimate for this four-press page; the five-press plan is a 3 × 250 kW chiller bank, steam-cooling.html). If the supply water runs warm, the Classics stretch their cooling and their cycle. The galvanics plating units take a small branch at 12 to 20 °C.',c:['Supply 20 to 25 °C, closed loop','Up to 100 l/min per press, ~53 l/min average (site requirements)'],f:['~80 to 125 kW electrical per 250 kW of cooling','PDPU coil: 10 L/min at 12 to 20 °C (2024 flyer)']},
boiler:{t:'Steam boilers B-1 and B-2',w:'Saturated steam at 10 bar / 180 °C heats the moulds; each press draws ~1.3 kg per cycle. The launch plant\'s three presses need 450 to 540 kg/h at Newbilt\'s 150 to 180 kg/h per press, on two 500 kg/h boiler modules running lead and lag in a boiler hall built for four (scale.md, steam-cooling.html). Below 9.5 bar the presses hold in STEAM (Steam dip button).',c:['Pressure held between 9.5 and 10.5 bar at the press','Feedwater treatment, condensate return'],f:['Launch plant 450 to 540 kg/h against 1,000 kg/h installed (scale.md)','Fuel decision open: biomass, LPG or electric','Detached boiler hall with a 14 m flue','Second Duplex (growth option, five presses): 750 to 900 kg/h on the same two modules (steam-cooling.html)']},
chiller:{t:'Process cooling CH-1 and CH-2',w:'Cooling water sets the vinyl after the steam phase. The launch plant\'s three presses peak at ~390 kW on a hot afternoon (391.5 kW: up to 125 kW per press, 3 kW per extruder, 2.5 kW per press for hydraulics; scale.md), on two 250 kW air-cooled chiller modules, CH-1 and CH-2, 500 kW in a compound built for four (steam-cooling.html). If the supply water runs warm, the Classic stretches its cooling and its cycle. The galvanics plating unit takes a small branch at 12 to 20 °C.',c:['Supply 20 to 25 °C, closed loop','Up to 100 l/min per press, ~53 l/min average (site requirements)'],f:['~80 to 125 kW electrical per 250 kW of cooling: ~125 to 196 kW at the launch plant\'s peak (scale.md, estimate)','Second Duplex (growth option, five presses): ~650 kW on 3 × 250 kW, CH-3 in its reserved position (scale.md)','PDPU coil: 10 L/min at 12 to 20 °C (2024 flyer)']},
comp:{t:'Compressed air',w:'Dry, filtered air for the press and extruder actuators, the Sibert machines and the silvering unit.',c:['Dew point max 3 °C, impurities max 5 µm'],f:['14 m³/h for a Duplex system (site requirements)','Sibert: 6 to 8 bar, 3.1 to 4.5 L/s per machine in use; PASU 6 bar']},
hyd:{t:'Hydraulic aggregate (Duplex)',w:'One aggregate supplies ~150 t to both Duplex presses at 180 bar from a gas-loaded accumulator. A larger central supply shared by several systems is possible (Duplex flyer); how the Classics are supplied is a re-quote question.',c:['Oil temperature and pressure logged'],f:['200 l HLP 46, 15 kVA, 12 kW average, 600 kg (site requirements)']},
hyd:{t:'Hydraulic aggregate (Duplex)',w:'One aggregate supplies ~150 t to both Duplex presses at 180 bar from a gas-loaded accumulator. A larger central supply shared by several systems is possible (Duplex flyer); whether the Classic runs from it is a re-quote question.',c:['Oil temperature and pressure logged'],f:['200 l HLP 46, 15 kVA, 12 kW average, 600 kg (site requirements)']},
diro:{t:'RO / DI water',w:'Plating rinses need deionised water: the PMPB bench has a DI connection and the silvering chemistry is made up with it.',c:['Conductivity logged'],f:['The RO skid in the utilities CSV is an option row sized for boiler feed, not for this (galvanics.md)','0.2 m³/h make-up here (estimate)']},
zld:{t:'Water treatment, zero discharge',w:'Galvanics rinse water and the VSF\'s nickel-bearing loop water go through closed-loop treatment and metal recovery with an evaporator; nothing goes to the drain. Neither Pheenix nor Digital Matrix supplies this; it is a separate vendor.',c:['Rinse conductivity, evaporator state'],f:['Zero contaminated water commitment (sustainability.md)','USD 90k to 240k (total investment)']},
energy:{t:'Energy',w:'247 kWp of roof PV, a 271 kWh battery for ride-through, and a medium-voltage PEA connection. Solar follows the clock; the battery covers the evening.',c:['Plant peak ~430 to 700 kW without an electric boiler (five-press plan, scale.md)'],f:['Galvanics ~27 kVA connected per line, far less drawn (galvanics.md)','PV covers roughly 28 to 45 % of consumption without electric steam']},
energy:{t:'Energy',w:'247 kWp of roof PV, a 271 kWh battery for ride-through, and a medium-voltage PEA connection. Solar follows the clock; the battery covers the evening.',c:['Plant peak ~430 to 700 kW without an electric boiler (scale.md, sized for the five-press layout the backbone is built for)'],f:['Galvanics ~27 kVA connected per line, far less drawn (galvanics.md)','PV covers roughly 28 to 45 % of consumption without electric steam']},
trace:{t:'Traceability',w:'Every step logs at the source: press and rectifier PLCs, the lab, the XRF, the vision station; manual steps check in. Append-only, kept for the life of the customer relationship.',c:['Record key: stamper + press + cycle timestamp + side','Every part knows its parents: stamper, mother, father, lacquer'],f:['The part of the plan the industry responded to at Making Vinyl Europe 2026']},
hvac:{t:'Plant HVAC',w:'The press hall at 20 to 26 °C and 35 to 60 % RH; galvanics, archive and audio rooms in their own zones, logged on the production timeline.',c:['T, RH and PM per zone'],f:['~100 to 200 kW peak (estimate)']},
exh:{t:'Galvanics extraction',w:'Every tank unit is extracted (Ø63 mm per plating unit, Ø125 mm at 150 m³/h on the silvering unit) through a scrubber. The interlock is hard-wired: no extraction, no plating.',c:['Fan status logged, interlock hard-wired'],f:['Facility security: fume-extraction interlocks']},
@@ -1076,12 +1079,12 @@ function seed(){
seed();
// Two days of warm-up, then run on to a mid-shift moment with work on the metal path
// and the presses (at ~25 % plating load an arbitrary 08:00 often shows idle cells).
const busy=()=>{const h=hourOf();return h>=7&&h<19&&CELLS.some(c=>c.ph==='plate')&&galvCount()>=3&&PRESS.filter(running).length>=3;};
const busy=()=>{const h=hourOf();return h>=7&&h<19&&CELLS.some(c=>c.ph==='plate')&&galvCount()>=3&&PRESS.filter(running).length>=2;};
const t0=performance.now();while(S.t<2*DAY)tick(2);
while(S.t<6*DAY&&!busy())tick(2);
for(let i=0;i<480;i++)tick(0.25); // last two minutes at the 1x step
S.quiet=false;
log('Two shifts, 06:00 to 22:00: Pheenix line, Sibert prep and four Newbilt presses at real duration (warm-up '+f0(performance.now()-t0)+' ms)','ok');
log('Launch plant, two shifts 06:00 to 22:00: Pheenix line, Sibert prep and three Newbilt presses at real duration (warm-up '+f0(performance.now()-t0)+' ms)','ok');
log('Material lab: lot '+S.lab.lot+' released, moisture 0.03 %, heat stability OK','ok');
select('pC1',true);renderTags();
+63 -56
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>CNX Vinyl · Steam and cooling plant (five-press fleet)</title>
<title>CNX Vinyl · Steam and cooling plant (launch plant)</title>
<script>
(function(){var t=null;try{t=localStorage.getItem("cnx-theme")}catch(e){}
if(t!=="light"&&t!=="dark")t=window.matchMedia&&matchMedia("(prefers-color-scheme: light)").matches?"light":"dark";
@@ -80,11 +80,11 @@ td.low{color:var(--warn);font-weight:600}
</head>
<body>
<header>
<h1>CNX Vinyl <span>· Steam and cooling plant · five-press fleet · proposed concept</span></h1>
<h1>CNX Vinyl <span>· Steam and cooling plant · launch plant, backbone for five presses · proposed concept</span></h1>
<div class="ctl" id="cases">
<button data-case="launch">Launch</button>
<button data-case="d1">Duplex system 1</button>
<button data-case="full" class="on">Start fleet, 5 presses</button>
<button data-case="launch" class="on">Launch plant</button>
<button data-case="d1">Duplex first (commissioning)</button>
<button data-case="growth">Second Duplex (growth option, five presses)</button>
<button data-case="down">One module down</button>
<button id="themeBtn" title="Switch light / dark mode">☀</button>
</div>
@@ -108,7 +108,8 @@ td.low{color:var(--warn);font-weight:600}
<h2>Design basis</h2>
<table>
<tr><th>Item</th><th>Figure</th><th>Source</th></tr>
<tr><td>Fleet</td><td>2 Duplex systems (4 HRP 12, 2 EX 50, 2 EX 35) + 1 Classic with built-in extruder; one central hydraulic and one air plant</td><td>pressing-line.md<span class="b">doc</span></td></tr>
<tr><td>Launch plant</td><td>1 Duplex system (2 HRP 12, EX 50 + EX 35) + 1 Classic with built-in extruder; one central hydraulic and one air plant</td><td>total-investment.md, pressing-line.md<span class="b">doc</span></td></tr>
<tr><td>Growth option</td><td>a second Duplex system (2 HRP 12, EX 50 + EX 35) in reserved positions: five presses; room reserved, not in the investment</td><td>scale.md, total-investment.md<span class="b">doc</span></td></tr>
<tr><td>Steam per press</td><td class="n">150 to 180 kg/h, min. 10 bar, 9.5 to 10.5 bar operating</td><td>Newbilt site requirements 3.2.3<span class="b v">vendor</span></td></tr>
<tr><td>Press cooling water</td><td class="n">up to 100 l/min, ~53 l/min used, in 20 to 25 °C at 10 bar, out ~60 °C, max. 2 bar (open)</td><td>site requirements 3.2.2<span class="b v">vendor</span></td></tr>
<tr><td>Press cooling capacity</td><td class="n">up to 125 kW per press, by cycle time</td><td>site requirements 3.2.2<span class="b v">vendor</span></td></tr>
@@ -116,12 +117,13 @@ td.low{color:var(--warn);font-weight:600}
<tr><td>Hydraulic oil cooler</td><td class="n">~8 l/min, up to 5 kW per aggregate (2.5 kW per press)</td><td>site requirements 3.4.2<span class="b v">vendor</span></td></tr>
<tr><td>Cooling water quality</td><td class="n">7 to 8 °dH, pH 7 to 9, ≤ 200 µm, ≤ 500 µS/cm, Cl ≤ 20 mg/l</td><td>site requirements 3.1.2<span class="b v">vendor</span></td></tr>
<tr><td>Classic</td><td>counted as one HRP 12 + one extruder; Toolex Alpha cross-check 1.2 kg steam, 15 l water per cycle</td><td>fleet calculator<span class="b e">estimate</span></td></tr>
<tr><td>Five presses, full demand</td><td class="n">steam 750 to 900 kg/h · cooling 652.5 kW · water 305 to 540 l/min</td><td>sum of the above<span class="b">doc</span></td></tr>
<tr><td>Launch plant, full demand</td><td class="n">steam 450 to 540 kg/h · cooling 391.5 kW (~390 kW) · water 183 to 324 l/min</td><td>scale.md, sum of the above<span class="b">doc</span></td></tr>
<tr><td>Five presses (growth option), full demand</td><td class="n">steam 750 to 900 kg/h · cooling 652.5 kW · water 305 to 540 l/min</td><td>sum of the above<span class="b">doc</span></td></tr>
<tr><td>Chiller electrical input</td><td class="n">~80 to 125 kW per 250 kW of cooling (air-cooled, hot season)</td><td>scale.md<span class="b e">estimate</span></td></tr>
<tr><td>Electric boiler alternative</td><td class="n">~0.68 kWh per kg of steam at 98 %</td><td>fleet calculator<span class="b e">estimate</span></td></tr>
<tr><td>Annual steam heat</td><td class="n">~1,170 MWh at 1.0 M records, ~1,750 MWh at the start fleet's full ~1.5 M</td><td>fleet calculator, biomass.md<span class="b e">estimate</span></td></tr>
<tr><td>Annual steam heat</td><td class="n">~1,170 MWh at 1.0 M records (the launch plant makes ~0.71 to 0.97 M), ~1,750 MWh at ~1.5 M with the second Duplex</td><td>fleet calculator, biomass.md<span class="b e">estimate</span></td></tr>
</table>
<p class="note">Circulating water is not consumption: the loop recirculates. Boiler make-up is about 0.75 to 0.9 m³/h before condensate return, much less with it.</p>
<p class="note">Circulating water is not consumption: the loop recirculates. Boiler make-up is about 0.45 to 0.54 m³/h for the launch plant before condensate return (0.75 to 0.9 m³/h with five presses), much less with it.</p>
</div>
<div class="card">
<h2>Equipment schedule (proposed)</h2>
@@ -130,31 +132,30 @@ td.low{color:var(--warn);font-weight:600}
<tr><td>WT-1</td><td>Duplex softener, dosing</td><td class="n">~1.0 to 1.2 m³/h</td><td>launch</td><td>estimate</td></tr>
<tr><td>T-1</td><td>Feed tank / hotwell</td><td class="n">~1.5 m³, 90 to 95 °C</td><td>launch</td><td>estimate</td></tr>
<tr><td>P-1</td><td>Feed pumps, duty/standby</td><td class="n">~1 m³/h, ~13 bar</td><td>launch</td><td>estimate</td></tr>
<tr><td>B-1, B-2</td><td>Boiler modules, lead/lag</td><td class="n">2 × 500 kg/h, 10.5 bar</td><td>B-1 launch, B-2 with Duplex 2</td><td>proposal</td></tr>
<tr><td>B-3</td><td>Third module for N+1</td><td class="n">500 kg/h</td><td>option; position built at launch</td><td>RFQ option</td></tr>
<tr><td>B-1, B-2</td><td>Boiler modules, lead/lag</td><td class="n">2 × 500 kg/h, 10.5 bar</td><td>launch plant</td><td>proposal</td></tr>
<tr><td>B-3</td><td>Third module, N+1 with five presses</td><td class="n">500 kg/h</td><td>option; position built at launch</td><td>RFQ option</td></tr>
<tr><td>B-4</td><td>Fourth position: pad, header branch, feeder</td><td class="n">500 kg/h</td><td>growth, ~3 more presses</td><td>position only</td></tr>
<tr><td>ECON-1</td><td>Flue-gas economizer, fired boilers</td><td class="n">feed in 90 to 95 °C, out by vendor</td><td>with a fired bank</td><td>1st measure</td></tr>
<tr><td>ACC-1</td><td>Steam accumulator</td><td class="n">by cycle overlap</td><td>option</td><td>Newbilt option</td></tr>
<tr><td>HP-1</td><td>Heat-recovery heat pump</td><td class="n">feed tank to 90 to 95 °C</td><td>if it pays</td><td>3rd measure</td></tr>
<tr><td>CH-1 to CH-3</td><td>Air-cooled chillers at 40 °C ambient</td><td class="n">3 × 250 kW</td><td>one per press stage</td><td>proposal</td></tr>
<tr><td>CH-4</td><td>Fourth module for N+1</td><td class="n">250 kW</td><td>option; pad built at launch</td><td>RFQ option</td></tr>
<tr><td>HX-1</td><td>Plate heat exchanger</td><td class="n">~650 kW, ~2 K approach</td><td>launch: frame for 5, plates as presses arrive</td><td>estimate</td></tr>
<tr><td>CH-1, CH-2</td><td>Air-cooled chillers at 40 °C ambient</td><td class="n">2 × 250 kW</td><td>launch plant</td><td>proposal</td></tr>
<tr><td>CH-3</td><td>Third chiller, for the second Duplex</td><td class="n">250 kW</td><td>growth option; pad built at launch</td><td>reserved position</td></tr>
<tr><td>CH-4</td><td>Fourth module, N+1 with five presses</td><td class="n">250 kW</td><td>option; pad built at launch</td><td>RFQ option</td></tr>
<tr><td>HX-1</td><td>Plate heat exchanger</td><td class="n">~650 kW, ~2 K approach</td><td>launch: frame for five presses, plates for the launch plant</td><td>estimate</td></tr>
<tr><td>TK-3, TK-2</td><td>Warm return / cold buffer tanks</td><td class="n">~5 m³ each</td><td>launch</td><td>estimate</td></tr>
<tr><td>P-2, P-3, P-4</td><td>Transfer, VFD supply, primary pumps</td><td class="n">up to ~540 l/min</td><td>launch, staged</td><td>estimate</td></tr>
<tr><td>TC-1</td><td>Dry cooler ahead of HX-1</td><td class="n">~650 to 750 kW reject</td><td>option</td><td>RFQ option</td></tr>
<tr><td>GC</td><td>Galvanics cooling, separate</td><td class="n">12 to 20 °C, 10 L/min per PDPU</td><td>phase 5</td><td>open</td></tr>
<tr><td>GC</td><td>Galvanics cooling, separate</td><td class="n">12 to 20 °C, 10 L/min per PDPU</td><td>launch plant</td><td>open</td></tr>
</table>
</div>
<div class="card" id="phasing">
<h2>Phasing: backbone once, modules with the presses</h2>
<p>Everything that is cheap to oversize now and costly to change in a running plant is built for the five-press fleet at launch; boilers, chillers and hydraulic pump sets come in identical modules as presses arrive. One controller sequences them lead and lag from the first module.</p>
<p>Everything that is cheap to oversize now and costly to change in a running plant is built for the five-press layout fleet at launch. The launch plant (one Duplex system and the Classic, commissioned in sequence) starts on two boiler and two chiller modules; boilers, chillers and hydraulic pump sets come in identical modules if the second Duplex follows. One controller sequences them lead and lag from the first module.</p>
<table>
<tr><th>Stage</th><th>Steam</th><th>Cooling</th><th>Hydraulics, air</th></tr>
<tr><td>Launch (Single 2.1, one press)</td><td>hall for four modules; T-1, WT-1, P-1; mains with a valved, blanked branch per press position; <b>B-1</b></td><td>compound with four pads; TK-2, TK-3 full size; HX-1 frame for ~650 kW, plates for one press; P-2 to P-4 on VFDs; <b>CH-1</b></td><td>plant room full size; ring mains for the fleet, a capped tee per position; the Single 2.1 unit as the first pump set; one compressor</td></tr>
<tr><td>Duplex system 1</td><td>B-1 at 60 to 72 % load</td><td>CH-1 covers ~96 % of the peak: cold tank and cycle overlap, or CH-2 earlier</td><td>tap the ring main</td></tr>
<tr><td>Duplex system 2</td><td><b>B-2</b></td><td><b>CH-2</b></td><td>pump set on the manifold</td></tr>
<tr><td>Classic</td><td>B-1 and B-2</td><td><b>CH-3</b></td><td>pump set, if the Classic runs from the central plant</td></tr>
<tr><td>Options</td><td>B-3 (N+1), B-4 (growth), ACC-1, ECON-1</td><td>CH-4 (N+1), TC-1, pads for ~350 kW units</td><td>standby pump set</td></tr>
<tr><td>Launch plant (Duplex system 1 + Classic)</td><td>hall for four modules; T-1, WT-1, P-1; mains with a valved, blanked branch per press position; <b>B-1</b>, <b>B-2</b> (450 to 540 kg/h on 1,000)</td><td>compound with four pads; TK-2, TK-3 full size; HX-1 frame for ~650 kW, plates for the launch plant; P-2 to P-4 on VFDs; <b>CH-1</b>, <b>CH-2</b> (~390 kW peak on 500)</td><td>plant room full size; ring mains for five presses, a capped tee per position; the Duplex aggregate as the first pump set, the Classic's beside it if it runs from the central plant; one compressor</td></tr>
<tr><td>Second Duplex (growth option)</td><td>B-1 and B-2 at higher load (750 to 900 kg/h on 1,000)</td><td><b>CH-3</b> (~650 kW peak on 750)</td><td>pump set on the manifold; a second compressor if the air demand needs it</td></tr>
<tr><td>Options</td><td>B-3 (N+1 with five presses), B-4 (growth), ACC-1, ECON-1</td><td>CH-4 (N+1 with five presses), TC-1, pads for ~350 kW units</td><td>standby pump set</td></tr>
</table>
<h3>Rooms, four modules each (estimate)</h3>
<table>
@@ -163,14 +164,14 @@ td.low{color:var(--warn);font-weight:600}
<tr><td>Chiller compound</td><td class="n">~12.5 × 10.8 m, open</td><td>four pads 4.0 × 2.6 m in two rows, screened; 250 kW at 40 °C is about a Carrier 30RB 080 to 090, 2.4 to 3.6 × 2.24 m</td></tr>
<tr><td>Pump and HX room</td><td class="n">~8 × 5 m</td><td>HX-1, TK-2, P-2 to P-4, drives</td></tr>
</table>
<p class="note">Four boilers carry about eight presses with one in reserve. Four 250 kW chillers carry the five presses with CH-4 in reserve and leave no growth position, unless the pads take the larger frame (scale.md).</p>
<p class="note">The launch plant uses two of the four positions in each room. Four boilers carry about eight presses with one in reserve. Four 250 kW chillers carry the five presses with CH-4 in reserve and leave no growth position, unless the pads take the larger frame (scale.md).</p>
</div>
<div class="card">
<h2>Open for the RFQs</h2>
<h3>Newbilt (re-quote)</h3>
<ul>
<li>Classic: steam, cooling, power, weight; can it run from the central hydraulic plant?</li>
<li>Central hydraulics: pressure at the presses over the ring-main lengths, filtration and isolation per branch, and whether the Single 2.1 unit can be the first central pump set.</li>
<li>Central hydraulics: pressure at the presses over the ring-main lengths, filtration and isolation per branch, and whether the Duplex system's aggregate (the Single 2.1 unit of the 2024 quote) can be the first central pump set.</li>
<li>Press return temperature over the cycle: 53 l/min at ~60 °C out of 20 to 25 °C is ~140 kW, more than the stated 125 kW peak. The real profile sizes HP-1, HX-1 and TC-1.</li>
<li>Is the accumulator needed with a modular boiler bank, and how big?</li>
<li>Condensate: the 2024 offer has one steam/water outlet valve and a steam trap per mould. How much cooling water reaches the trap per cycle, and can that condensate go back to boiler feed?</li>
@@ -178,21 +179,21 @@ td.low{color:var(--warn);font-weight:600}
<h3>Boilers (Miura, Bangkok Industrial Boilers, STE)</h3>
<ul>
<li>2 × 500 kg/h against 3 × 500 kg/h and 1 × 1 t/h: price, footprint, lead/lag control, service from Chiang Mai.</li>
<li>Fuel: electric, biomass or LPG (sustainability.md, biomass.md); the electric bank draws ~520 to 625 kW.</li>
<li>Fuel: electric, biomass or LPG (sustainability.md, biomass.md); an electric bank draws ~312 to 375 kW for the launch plant, ~520 to 625 kW with five presses.</li>
<li>Economizer on a fired bank: outlet feed and stack temperature, corrosion limit, pressure drop; rice husk ash is high in silica and abrasive, so fouling, cleaning, wear protection and a bypass.</li>
<li>Blowdown cooling to the effluent limit; boiler registration and licensed operator (facility-security.md).</li>
<li>Footprint per module with fuel feed, dust collector and fan, against the ~18 × 9 m hall laid out for four modules.</li>
</ul>
<h3>Chillers (Trane, Carrier, Daikin Applied, Hitachi)</h3>
<ul>
<li>3 × 250 kW against 3 × 350 kW (N+1), rated at 40 °C ambient; part-load efficiency.</li>
<li>2 × 250 kW for the launch plant (a third for the second Duplex) against ~350 kW frames for N+1, rated at 40 °C ambient; part-load efficiency.</li>
<li>Plate heat exchanger and tanks in scope; dry cooler TC-1 as a priced option.</li>
<li>Clearance drawing for four units in two rows of two; pads for the ~350 kW frame as a priced option (four would then carry about eight presses with one in reserve).</li>
</ul>
<h3>Site</h3>
<ul>
<li>Water analysis before either RFQ: it decides softener or RO and the loop treatment.</li>
<li>Grid: ~800 to 1,000 kVA without electric steam, 1,250 to 1,600 kVA with it (scale.md).</li>
<li>Grid: ~800 to 1,000 kVA without electric steam, 1,250 to 1,600 kVA with it (scale.md, sized for the five-press backbone).</li>
</ul>
</div>
<div class="card">
@@ -267,10 +268,11 @@ pipe('M1200,152 H1740 V350 H620','st');arrow(1500,152,'e','st');arrow(1740,250,'
lbl(1430,172,'steam main 10 bar · insulated · falls with the flow');
/* ---------------- band B: consumers */
lane(20,336,'CONSUMERS · FIVE PRESSES, EXTRUDERS, HYDRAULICS');
lane(20,336,'CONSUMERS · LAUNCH PLANT + TWO RESERVED PRESS POSITIONS');
lbl(700,340,'steam header, branch from top');
const PR=[['D1A','D1-A · HRP 12','Duplex 1 · EX 50 + EX 35'],['D1B','D1-B · HRP 12','Duplex 1 · shared extruders'],
['D2A','D2-A · HRP 12','Duplex 2 · EX 50 + EX 35'],['D2B','D2-B · HRP 12','Duplex 2 · shared extruders'],['C1','C · Classic, automatic','built-in extruder']];
// launch plant first (Duplex system 1, Classic), then the two positions reserved for the second Duplex
const PR=[['D1A','D1-A · HRP 12','Duplex 1 · EX 50 + EX 35'],['D1B','D1-B · HRP 12','Duplex 1 · shared extruders'],['C1','C · Classic, automatic','built-in extruder'],
['D2A','D2-A · HRP 12','Duplex 2 · growth option'],['D2B','D2-B · HRP 12','Duplex 2 · growth option']];
PR.forEach(([id,t,s],i)=>{const px=640+i*220,c=id==='C1';
box(id,px,420,190,120,t,[s,c?'steam 150 to 180 (est.)':'steam 150 to 180 kg/h',c?'cooling ≤ 125 kW (est.)':'cooling ≤ 125 kW',c?'water ≤ 100 l/min (est.)':'water 53 to 100 l/min','running'],{det:c?'classic':'press'});
pipe(`M${px+40},350 V420`,'st');valve(px+40,364,true);strainer(px+40,382);cvalve(px+40,402);bubble(px+72,390,'PT',px+56,398);
@@ -279,7 +281,7 @@ PR.forEach(([id,t,s],i)=>{const px=640+i*220,c=id==='C1';
pipe(`M${px+160},540 V690`,'cwr');valve(px+160,566,true);bubble(px+180,598,'FT',px+160,598);bubble(px+180,622,'TT',px+160,622);});
pipe('M620,350 V580','cd');trap(620,372);pipe('M1740,350 V580','cd');trap(1740,372);
pipe('M1740,580 H590 V135 H570','cd');arrow(1110,580,'w','cd');lbl(642,598,'condensate return to T-1');bubble(566,430,'AT',590,430);
box('EX1',30,400,180,76,'EX · extruder cooling',['~4 l/min · 2 to 3 kW each','2 EX 50, 2 EX 35, Classic']);
box('EX1',30,400,180,76,'EX · extruder cooling',['~4 l/min · 2 to 3 kW each','EX 50, EX 35, Classic']);
box('HY1',230,400,180,76,'HY · oil cooler',['central hydraulic plant','~8 l/min per aggregate']);
pipe('M90,650 V476 M270,650 V476','cws');pipe('M170,476 V690 M350,476 V690','cwr');
@@ -297,7 +299,7 @@ box('TK2',960,760,160,76,'TK-2 · cold tank',['buffer, 20 to 25 °C','~5 m³ (es
box('P3',1150,770,150,56,'P-3 · supply',['VFD duty / standby','~10 bar at presses']);
box('P4',1150,860,150,56,'P-4 · primary',['duty / standby','constant flow']);
[['CH1',712],['CH2',776],['CH3',840],['CH4',904]].forEach(([id,y])=>box(id,1380,y,190,56,id.replace('CH','CH-')+' · chiller',
id==='CH4'?['250 kW · for N+1','RFQ option']:['250 kW · air-cooled','running'],id==='CH4'?{opt:true}:{det:'chiller'}));
id==='CH4'?['250 kW · for N+1','RFQ option']:id==='CH3'?['250 kW · growth option','reserved position']:['250 kW · air-cooled','running'],id==='CH4'?{opt:true}:{det:'chiller'}));
box('AS1',1625,900,160,56,'AS-1 · air separator',['expansion vessel','pressurised, closed']);
pipe('M200,798 H230','cwr');pipe('M380,798 H440 V270','cwr');pipe('M530,270 V798 H760','cwr');arrow(440,560,'n','cwr');arrow(530,560,'s','cwr');
pipe('M410,880 V798','cwr');pipe('M600,798 V860 M690,860 V798','cwr opt');
@@ -329,47 +331,52 @@ temp(1240,957,'TBD','t'); // chiller loop return
/* ---------------- details */
const D={
RW:{t:'RW · Raw water',w:'Mains or well water feeds the boiler make-up and the cooling loop make-up. Which one depends on the site, and the water analysis decides how much treatment both need.',f:['Boiler make-up ~0.75 to 0.9 m³/h at full output before condensate return, far less with it (estimate)','Cooling make-up is small: the chillers are closed, losses are the open return tank and side-stream blowdown','Raw water ~28 to 30 °C: the ground sits at 28 to 30 °C year-round (sustainability.md, estimate)'],q:['Water analysis (hardness, silica, TDS, chloride) for the site, before the boiler and chiller RFQs']},
WT1:{t:'WT-1 · Boiler feedwater treatment',w:'A duplex softener (one regenerates while the other works) and chemical dosing (oxygen scavenger, pH) protect the boilers. RO only if the analysis demands low TDS; it is an option row, not the baseline.',f:['Duplex softener 120k to 300k THB, sized up for the five-press fleet (utilities CSV, market estimate)','RO skid 200k to 500k THB, option only (utilities CSV)'],q:['Softener alone or softener plus RO, after the water analysis']},
T1:{t:'T-1 · Feed tank and hotwell',w:'Collects the condensate returning from the presses and the treated make-up, warmed by HP-1, and holds the feedwater at 90 to 95 °C so little oxygen stays dissolved. The boiler then only does the final lift to 180 °C.',f:['Feedwater at 90 to 95 °C and the boiler only doing the final lift (sustainability.md)','Heat recovery plus condensate return save roughly 10 to 15 % of steam energy (sustainability.md)','~1.5 m³, about 1.5 h of feed at full output (estimate); level LT logged','Condensate leaves each trap near saturation (~180 °C at the press) and flashes to about 100 °C in the atmospheric return (estimate); the flash steam is heat that could be recovered','Steam and cooling water share the mould channels, with one outlet valve and steam trap per mould (Newbilt offer 240620-04): the condensate is only as clean as the cooling loop, so AT conductivity on the return diverts off-spec condensate to the warm tank (proposal)','Order of heat recovery for the feedwater: flue-gas economizer, condensate return, then HP-1 (sustainability.md)'],q:['Atmospheric hotwell or pressurised deaerator: boiler vendor\'s call at this size']},
RW:{t:'RW · Raw water',w:'Mains or well water feeds the boiler make-up and the cooling loop make-up. Which one depends on the site, and the water analysis decides how much treatment both need.',f:['Boiler make-up ~0.45 to 0.54 m³/h for the launch plant at full output (0.75 to 0.9 m³/h with five presses) before condensate return, far less with it (estimate)','Cooling make-up is small: the chillers are closed, losses are the open return tank and side-stream blowdown','Raw water ~28 to 30 °C: the ground sits at 28 to 30 °C year-round (sustainability.md, estimate)'],q:['Water analysis (hardness, silica, TDS, chloride) for the site, before the boiler and chiller RFQs']},
WT1:{t:'WT-1 · Boiler feedwater treatment',w:'A duplex softener (one regenerates while the other works) and chemical dosing (oxygen scavenger, pH) protect the boilers. RO only if the analysis demands low TDS; it is an option row, not the baseline.',f:['Duplex softener 120k to 300k THB, sized for the five-press backbone (utilities CSV, market estimate)','RO skid 200k to 500k THB, option only (utilities CSV)'],q:['Softener alone or softener plus RO, after the water analysis']},
T1:{t:'T-1 · Feed tank and hotwell',w:'Collects the condensate returning from the presses and the treated make-up, warmed by HP-1, and holds the feedwater at 90 to 95 °C so little oxygen stays dissolved. The boiler then only does the final lift to 180 °C.',f:['Feedwater at 90 to 95 °C and the boiler only doing the final lift (sustainability.md)','Heat recovery plus condensate return save roughly 10 to 15 % of steam energy (sustainability.md)','~1.5 m³: about 1.5 h of feed with five presses at full output, nearly 3 h for the launch plant (estimate); level LT logged','Condensate leaves each trap near saturation (~180 °C at the press) and flashes to about 100 °C in the atmospheric return (estimate); the flash steam is heat that could be recovered','Steam and cooling water share the mould channels, with one outlet valve and steam trap per mould (Newbilt offer 240620-04): the condensate is only as clean as the cooling loop, so AT conductivity on the return diverts off-spec condensate to the warm tank (proposal)','Order of heat recovery for the feedwater: flue-gas economizer, condensate return, then HP-1 (sustainability.md)'],q:['Atmospheric hotwell or pressurised deaerator: boiler vendor\'s call at this size']},
P1:{t:'P-1 · Boiler feed pumps',w:'Duty and standby multistage pumps feed every boiler module through one manifold, so a pump failure never stops steam.',f:['~1 m³/h each against ~13 bar (estimate, above the 10.5 bar boiler pressure)'],q:['Supplied with the boiler bank or separately']},
boiler:{t:'B-1 and B-2 · Boiler modules, 500 kg/h each',w:'Two modules run lead and lag at ~10.5 bar so the presses see 9.5 to 10.5 bar after the line. B-1 comes with the launch press and covers all of Duplex system 1 (300 to 360 kg/h); B-2 comes with Duplex system 2 and also carries the Classic. Fuel is open: electric, biomass or LPG.',f:['Newbilt: 150 to 180 kg/h per press, Duplex up to 360 kg/h, min. 10 bar, 9.5 to 10.5 bar operating (site requirements 3.2.3, vendor)','Five presses: 750 to 900 kg/h, against 1,000 kg/h installed (111 to 133 %)','The 2024 Newbilt quote excludes a ~400 kg/h steam generator: one Duplex system (pressing-line.md)','Electric alternative ~350 kW input per module, 520 to 625 kW at full demand (0.68 kWh/kg at 98 %, estimate)','With one module down, 500 kg/h runs about three presses','Boiler bank 4.5M to 7M THB installed (utilities CSV, estimate)','Boiler hall laid out for four modules (~18 × 9 m, estimate): B-3 and B-4 drop onto waiting pads and header branches (scale.md)'],q:['2 × 500 kg/h against 3 × 500 kg/h (B-3) and a single 1 t/h boiler: price, footprint, the cost of a lost shift','Footprint per module with fuel feed, dust collector and fan, against the four-module hall','Fuel decision (biomass.md, sustainability.md)','Service response from Chiang Mai: the candidates are Bangkok-based']},
boiler:{t:'B-1 and B-2 · Boiler modules, 500 kg/h each',w:'Two modules run lead and lag at ~10.5 bar so the presses see 9.5 to 10.5 bar after the line. Both come with the launch plant: B-1 carries the Duplex system (300 to 360 kg/h) while it is commissioned, B-2 joins with the Classic, and together they carry the launch plant\'s 450 to 540 kg/h. The same two modules would carry the second Duplex (growth option) at higher load. Fuel is open: electric, biomass or LPG.',f:['Newbilt: 150 to 180 kg/h per press, Duplex up to 360 kg/h, min. 10 bar, 9.5 to 10.5 bar operating (site requirements 3.2.3, vendor)','Launch plant: 450 to 540 kg/h against 1,000 kg/h installed (185 to 222 %); one module alone covers 93 to 111 % (scale.md)','Five presses (growth option): 750 to 900 kg/h on the same 1,000 kg/h (111 to 133 %)','The 2024 Newbilt quote excludes a ~400 kg/h steam generator: one Duplex system (pressing-line.md)','Electric alternative ~350 kW input per module: ~312 to 375 kW for the launch plant, 520 to 625 kW for five presses (0.68 kWh/kg at 98 %, estimate)','With one module down, 500 kg/h runs about three presses','Boiler bank 4.5M to 7M THB installed (utilities CSV, estimate)','Boiler hall laid out for four modules (~18 × 9 m, estimate): B-3 and B-4 drop onto waiting pads and header branches (scale.md)'],q:['2 × 500 kg/h against 3 × 500 kg/h (B-3) and a single 1 t/h boiler: price, footprint, the cost of a lost shift','Footprint per module with fuel feed, dust collector and fan, against the four-module hall','Fuel decision (biomass.md, sustainability.md)','Service response from Chiang Mai: the candidates are Bangkok-based']},
ECON1:{t:'ECON-1 · Flue-gas economizer (fired boilers)',w:'On a fired boiler bank (biomass such as rice husk, or LPG) the flue gas leaves hot. An economizer between the feed pumps and the boilers recovers part of that heat into the feedwater: the first of the three heat-recovery measures to investigate. An electric boiler has no flue gas and runs on the bypass.',f:['Feedwater in at 90 to 95 °C from T-1 (sustainability.md)','Outlet feed and stack temperatures are vendor figures: how far the gas can be cooled depends on its temperature and the corrosion limit','The gas-fired package row in the utilities CSV already includes an economizer; the biomass row does not yet'],q:['Outlet feed and stack temperature, pressure drop, corrosion limit','Rice husk ash is high in silica and abrasive: fouling, cleaning, wear protection and a bypass']},
B3:{t:'B-3 · Third boiler module (option)',w:'A third 500 kg/h module keeps all five presses running with any one module out. Without it a boiler fault costs about two presses until it is fixed.',f:['3 × 500 kg/h = 1,500 kg/h, full demand with one module out','Its pad, header branch and feeder space are built at launch; a fourth position (B-4) is kept for about three more presses'],q:['Priced as an option in the boiler RFQ; decided against measured cycle overlap and the cost of a lost shift']},
B3:{t:'B-3 · Third boiler module (option)',w:'In the launch plant either module alone carries 93 to 111 % of the steam demand, so B-3 matters once the second Duplex runs: then it keeps all five presses running with any one module out. Without it a boiler fault in the five-press case costs about two presses until it is fixed.',f:['3 × 500 kg/h = 1,500 kg/h, full demand with one module out','Its pad, header branch and feeder space are built at launch; a fourth position (B-4) is kept for about three more presses'],q:['Priced as an option in the boiler RFQ; decided against measured cycle overlap and the cost of a lost shift']},
BD1:{t:'BD-1 · Blowdown vessel and safety-valve discharge',w:'Boiler blowdown and drains flash in a vessel; the flash steam vents outside, the water is cooled before it reaches the drain. Safety valves discharge to a safe place outside the boiler hall.',f:['Boiler in its own room, Department of Industrial Works rules, licensed boiler operator (facility-security.md)','Detached boiler hall of ~162 m² (18 × 9 m) laid out for four modules, with a 14 m flue (scale.md, estimate)'],q:['Drain temperature and quality against the industrial effluent limit']},
SEP1:{t:'SEP-1 · Separator and steam metering',w:'Removes entrained water so the moulds get dry steam. FT-101 and PT-101 log steam flow and pressure: steam per record pressed becomes a plant KPI next to the traceability record.',f:['Telegraf/MQTT acquisition into the plant data platform (digital-factory.md)','Saturated steam: Newbilt states 10 bar and 180 °C; 180 °C is saturation at 10 bar absolute, at 10 bar gauge it would be ~184 °C (to confirm which Newbilt means)'],q:['Meter type and turndown for 150 to 1,000 kg/h']},
ACC1:{t:'ACC-1 · Steam accumulator (option)',w:'Each press draws steam in bursts during its steam phase. An accumulator rides those peaks so the boilers see a steadier load. It does not add capacity: the bank must still cover the hourly demand.',f:['Already a Newbilt option (sustainability.md)'],q:['Needed at all with two modules? Size from the presses\' cycle overlap (Newbilt re-quote)']},
HP1:{t:'HP-1 · Heat-recovery heat pump',w:'Third of the three heat-recovery measures for the feedwater, after the flue-gas economizer and condensate return. A water-to-water heat pump takes heat from the warm press return before it reaches the chillers and heats the feed tank. It runs only where the tank still needs heat, the press return has enough of it, and the combined saving on boiler fuel and chiller power beats its own electricity. With most condensate returned the remaining tank load is small, so HP-1 may not pay.',f:['Press return ~60 °C, feedwater 90 to 95 °C, 10 to 15 % steam saving with condensate return (sustainability.md)','Heating all make-up from 20 to 90 °C at full output is only ~70 kW thermal, small against ~650 kW of cooling (estimate)','Source side in up to ~60 °C from the return header, out set by the heat pump vendor; feed loop back to T-1 at up to 95 °C (sustainability.md)','About 15 % of the condensate flashes to steam when it drops from ~180 °C to atmospheric pressure (estimate); with the rest returned the feed tank needs only a fraction of the ~70 kW'],q:['Real return temperature profile from Newbilt: it sets the heat pump\'s lift and COP','Second use for recovered heat: label oven, HVAC reheat (sustainability.md)']},
press:{t:'Duplex presses · HRP 12 (Newbilt)',w:'Each press takes steam from the top of the header through an isolation valve, strainer and control valve, with its own pressure transmitter, and returns condensate through its own trap. Cooling water comes from the 10 bar supply header and drains open to the warm tank; flow and return temperature on each branch give that press\'s cooling load.',f:['Steam 150 to 180 kg/h, min. 10 bar, G 1 connection (site requirements 3.2.3, vendor)','Cooling water up to 100 l/min, ~53 l/min used, in 20 to 25 °C at 10 bar, out max. 2 bar open, average outlet ~60 °C, up to 125 kW (site requirements 3.2.2, vendor)','Water quality 7 to 8 °dH, pH 7 to 9, particles ≤ 200 µm, ≤ 500 µS/cm (site requirements 3.1.2, vendor)'],q:['53 l/min warming from 20 to 25 °C to ~60 °C is ~140 kW, above the stated 125 kW peak: ask for the measured return profile over a cycle']},
HP1:{t:'HP-1 · Heat-recovery heat pump',w:'Third of the three heat-recovery measures for the feedwater, after the flue-gas economizer and condensate return. A water-to-water heat pump takes heat from the warm press return before it reaches the chillers and heats the feed tank. It runs only where the tank still needs heat, the press return has enough of it, and the combined saving on boiler fuel and chiller power beats its own electricity. With most condensate returned the remaining tank load is small, so HP-1 may not pay.',f:['Press return ~60 °C, feedwater 90 to 95 °C, 10 to 15 % steam saving with condensate return (sustainability.md)','Heating all make-up from 20 to 90 °C is ~70 kW thermal with five presses at full output, ~45 kW for the launch plant, small against the cooling load (estimate)','Source side in up to ~60 °C from the return header, out set by the heat pump vendor; feed loop back to T-1 at up to 95 °C (sustainability.md)','About 15 % of the condensate flashes to steam when it drops from ~180 °C to atmospheric pressure (estimate); with the rest returned the feed tank needs only a fraction of that'],q:['Real return temperature profile from Newbilt: it sets the heat pump\'s lift and COP','Second use for recovered heat: label oven, HVAC reheat (sustainability.md)']},
press:{t:'Duplex presses · HRP 12 (Newbilt)',w:'Each press takes steam from the top of the header through an isolation valve, strainer and control valve, with its own pressure transmitter, and returns condensate through its own trap. Cooling water comes from the 10 bar supply header and drains open to the warm tank; flow and return temperature on each branch give that press\'s cooling load.',f:['D1-A and D1-B are the launch plant\'s Duplex system; D2-A and D2-B are the positions reserved for a second Duplex (growth option, not in the investment; total-investment.md)','Steam 150 to 180 kg/h, min. 10 bar, G 1 connection (site requirements 3.2.3, vendor)','Cooling water up to 100 l/min, ~53 l/min used, in 20 to 25 °C at 10 bar, out max. 2 bar open, average outlet ~60 °C, up to 125 kW (site requirements 3.2.2, vendor)','Water quality 7 to 8 °dH, pH 7 to 9, particles ≤ 200 µm, ≤ 500 µS/cm (site requirements 3.1.2, vendor)'],q:['53 l/min warming from 20 to 25 °C to ~60 °C is ~140 kW, above the stated 125 kW peak: ask for the measured return profile over a cycle']},
classic:{t:'Classic · automatic press (Newbilt)',w:'Fully automatic, with its own extruder. Newbilt has published no steam, cooling or power figures, so it is drawn and counted as one HRP 12 press plus one extruder.',f:['Toolex Alpha leaflet (the Classic\'s base): 1.2 kg steam and 15 l cooling water per cycle, ~144 kg/h of steam at 2 cycles a minute (fleet calculator, cross-check)','Monitors steam temperature, cooling water temperature and flow; cooling by time or delivered volume (2024 flyer)'],q:['Steam, cooling, power and weight for the re-quote; whether it runs from the central hydraulic plant']},
EX1:{t:'EX · Extruder cooling',w:'Every extruder needs a little cooling water at the same 20 to 25 °C. The EX 35 and the Classic\'s built-in extruder are counted like the EX 50 until Newbilt states theirs.',f:['~4 l/min, 2 to 3 kW, in 20 to 25 °C at 5 to 10 bar, outlet nearly without pressure (site requirements 3.3.3, vendor)','Five extruders at the start fleet: ~20 l/min, ~15 kW','Outlet ~30 to 35 °C: 2 to 3 kW at 4 l/min is a 7 to 11 K rise (estimate)'],q:['EX 35 and Classic extruder cooling figures']},
HY1:{t:'HY · Hydraulic oil cooler (central plant)',w:'The central hydraulic plant feeding all presses rejects its heat through one oil cooler on the same loop.',f:['Per aggregate ~8 l/min, ΔT max ~10 °C, up to 5 kW (site requirements 3.4.2, vendor); 2.5 kW per press in the calculator','~12.5 kW and ~20 l/min for five presses (estimate)','Pump sets in parallel on one manifold, added as presses arrive; the Single 2.1 unit is the first (pressing-line.md, proposal)','Outlet at most ~35 °C: supply 20 to 25 °C plus the maximum ~10 °C rise (site requirements 3.4.2)'],q:['Central plant cooler duty from Newbilt']},
EX1:{t:'EX · Extruder cooling',w:'Every extruder needs a little cooling water at the same 20 to 25 °C. The EX 35 and the Classic\'s built-in extruder are counted like the EX 50 until Newbilt states theirs.',f:['~4 l/min, 2 to 3 kW, in 20 to 25 °C at 5 to 10 bar, outlet nearly without pressure (site requirements 3.3.3, vendor)','Three extruders in the launch plant (EX 50, EX 35, the Classic\'s): ~12 l/min, ~9 kW; five with the second Duplex: ~20 l/min, ~15 kW','Outlet ~30 to 35 °C: 2 to 3 kW at 4 l/min is a 7 to 11 K rise (estimate)'],q:['EX 35 and Classic extruder cooling figures']},
HY1:{t:'HY · Hydraulic oil cooler (central plant)',w:'The central hydraulic plant feeding all presses rejects its heat through one oil cooler on the same loop.',f:['Per aggregate ~8 l/min, ΔT max ~10 °C, up to 5 kW (site requirements 3.4.2, vendor); 2.5 kW per press in the calculator','~7.5 kW and ~12 l/min for the launch plant\'s three presses, ~12.5 kW and ~20 l/min for five (estimate)','Pump sets in parallel on one manifold: the Duplex system\'s aggregate (the Single 2.1 unit of the 2024 quote) is the first, the Classic\'s follows if it runs from the central plant, a second Duplex adds one (pressing-line.md, proposal)','Outlet at most ~35 °C: supply 20 to 25 °C plus the maximum ~10 °C rise (site requirements 3.4.2)'],q:['Central plant cooler duty from Newbilt']},
TK3:{t:'TK-3 · Warm return tank',w:'Newbilt\'s press outlets run open at max. 2 bar with ideally no back pressure, so the returns drain into a vented tank instead of a pressurised header. Transfer pumps take it on through heat recovery and the heat exchanger.',f:['Outlet max. 2 bar, open system (site requirements 3.2.2, vendor)','~5 m³ (estimate); level and TT-302 logged','Mixed temperature below the ~60 °C press outlet, because the extruder and oil cooler returns are cooler; set it from the measured return profile Newbilt is asked for'],q:['Height of the return header above the tank, from the hall layout']},
P2:{t:'P-2 · Transfer pumps',w:'Duty and standby pumps move the warm return at a steady flow through HP-1, the optional dry cooler and HX-1 into the cold tank, so neither the heat exchanger nor the chillers see the presses\' flow swings.',f:['Up to ~540 l/min for five presses (estimate)'],q:[]},
P2:{t:'P-2 · Transfer pumps',w:'Duty and standby pumps move the warm return at a steady flow through HP-1, the optional dry cooler and HX-1 into the cold tank, so neither the heat exchanger nor the chillers see the presses\' flow swings.',f:['183 to 324 l/min for the launch plant, sized for up to ~540 l/min with five presses (estimate)'],q:[]},
TC1:{t:'TC-1 · Dry cooler (option)',w:'With returns near 40 to 60 °C, outside air removes much of the heat for most of the year before the chillers trim the rest. A hybrid of tower or dry cooler plus trim chiller is the efficiency-optimal design; the chiller is the safe choice for the hot-season wet bulb.',f:['Utilities CSV: tower + HX alternative 2M to 3.5M THB at ~650 to 750 kW reject, not in the baseline'],q:['Priced as an option with the chillers; savings against Chiang Mai weather']},
HX1:{t:'HX-1 · Plate heat exchanger',w:'Separates the open process side (air and dust get in at the warm tank) from the closed, clean chiller loop, so the chiller evaporators never see dirty, oxygenated water.',f:['~650 kW at ~2 K approach (estimate)','Frame bought for the full duty, plates added as presses arrive (proposal)'],q:['Single or two plates for maintenance without stopping production']},
HX1:{t:'HX-1 · Plate heat exchanger',w:'Separates the open process side (air and dust get in at the warm tank) from the closed, clean chiller loop, so the chiller evaporators never see dirty, oxygenated water.',f:['Frame for ~650 kW (five presses) at ~2 K approach, plates for the launch plant\'s ~390 kW (estimate)','More plates if the second Duplex follows (proposal)'],q:['Single or two plates for maintenance without stopping production']},
TK2:{t:'TK-2 · Cold buffer tank',w:'Holds water at 20 to 25 °C between the steady chiller side and the bursty presses: overlapping cooling phases draw from the tank, and the chillers do not short-cycle.',f:['Newbilt inlet 20 to 25 °C (site requirements 3.2.2, vendor)','~5 m³ (estimate)'],q:[]},
P3:{t:'P-3 · Supply pumps',w:'Variable-speed duty and standby pumps hold ~10 bar at the press inlets however many presses run. PT-301, TT-301 and FT-301 log the supply.',f:['Press inlet 10 bar, extruders and oil cooler 5 to 10 bar (site requirements, vendor)','Up to ~540 l/min for five presses (estimate)'],q:[]},
P3:{t:'P-3 · Supply pumps',w:'Variable-speed duty and standby pumps hold ~10 bar at the press inlets however many presses run. PT-301, TT-301 and FT-301 log the supply.',f:['Press inlet 10 bar, extruders and oil cooler 5 to 10 bar (site requirements, vendor)','183 to 324 l/min for the launch plant, sized for up to ~540 l/min with five presses (estimate)'],q:[]},
P4:{t:'P-4 · Primary pumps',w:'Duty and standby pumps circulate the closed chiller loop between the chiller bank and HX-1.',f:['Sized with the chiller bank (estimate)'],q:[]},
chiller:{t:'CH-1 to CH-3 · Air-cooled chillers, 250 kW each',w:'Three modules phased with the presses: CH-1 with the launch press and Duplex system 1, CH-2 with system 2, CH-3 with the Classic. Rated at 40 °C ambient, because Chiang Mai\'s April afternoons are when all presses cool hardest.',f:['Five presses up to 652.5 kW (625 presses, 15 extruders, 12.5 hydraulics) against 750 kW installed (115 %)','Electrical input ~80 to 125 kW per 250 kW: ~210 to 325 kW at the peak (scale.md, estimate)','One 250 kW module matches the ~250 kW cooling system the 2024 quote excludes for one Duplex (pressing-line.md)','Open, screened compound with four pads (~12.5 × 10.8 m) next to a ~40 m² pump and HX room (scale.md, estimate)','Chiller bank 6.5M to 10.5M THB installed with HX, tanks and pumps (utilities CSV, estimate)','Chiller loop to HX-1 ~18 to 23 °C for a 20 to 25 °C process supply at a ~2 K approach (estimate); its return temperature comes with the chiller selection'],q:['3 × 250 kW against 3 × 350 kW for N+1; part-load efficiency; derating at 40 °C']},
CH4:{t:'CH-4 · Fourth chiller (option)',w:'Without it one chiller out leaves 500 kW, ~77 % of the peak: the cold tank and the presses\' cycle diversity carry most hours, not the hottest afternoons. A fourth module, or 3 × 350 kW, makes it N+1. Its pad is built at launch.',f:['4 × 250 kW = 1,000 kW','The five presses already use three modules, so CH-4 is the reserve and the compound has no growth position unless the pads take the ~350 kW frame (scale.md)'],q:['Priced as an option']},
chiller:{t:'CH-1 to CH-3 · Air-cooled chillers, 250 kW each',w:'CH-1 and CH-2 come with the launch plant: CH-1 cools the Duplex system while it is commissioned, CH-2 joins with the Classic, together 500 kW against the ~390 kW hot-afternoon peak. CH-3 has its pad reserved for the second Duplex (growth option). Rated at 40 °C ambient, because Chiang Mai\'s April afternoons are when all presses cool hardest.',f:['Launch plant up to 391.5 kW (375 presses, 9 extruders, 7.5 hydraulics) against 500 kW installed (128 %; scale.md, fleet calculator)','Five presses (growth option) up to 652.5 kW (625 presses, 15 extruders, 12.5 hydraulics) against 750 kW with CH-3 (115 %)','Electrical input ~80 to 125 kW per 250 kW: ~125 to 196 kW at the launch plant\'s peak, ~210 to 325 kW with five presses (scale.md, estimate)','One 250 kW module matches the ~250 kW cooling system the 2024 quote excludes for one Duplex (pressing-line.md)','Open, screened compound with four pads (~12.5 × 10.8 m) next to a ~40 m² pump and HX room (scale.md, estimate)','Chiller bank of two modules 4.9M to 7.9M THB installed with HX, tanks and pumps; 6.5M to 10.5M with three for five presses (utilities CSV, estimate)','Chiller loop to HX-1 ~18 to 23 °C for a 20 to 25 °C process supply at a ~2 K approach (estimate); its return temperature comes with the chiller selection'],q:['2 × 250 kW for the launch plant (3 × 250 kW with the second Duplex) against ~350 kW frames for N+1; part-load efficiency; derating at 40 °C']},
CH4:{t:'CH-4 · Fourth chiller (option)',w:'With five presses (growth option), one chiller out leaves 500 kW, ~77 % of the peak: the cold tank and the presses\' cycle diversity carry most hours, not the hottest afternoons. A fourth module, or 3 × 350 kW, makes it N+1. In the launch plant one chiller out leaves 250 kW, ~64 % of the ~390 kW peak; a module in CH-3\'s reserved position would make that N+1. Its pad is built at launch.',f:['4 × 250 kW = 1,000 kW','The five presses already use three modules, so CH-4 is the reserve and the compound has no growth position unless the pads take the ~350 kW frame (scale.md)'],q:['Priced as an option']},
AS1:{t:'AS-1 · Air and dirt separator, expansion vessel',w:'Keeps the closed chiller loop pressurised and free of air and debris.',f:[],q:[]},
WT2:{t:'WT-2 · Loop treatment',w:'The open return tank picks up air and dust, so side-stream filtration and dosing keep the process water inside Newbilt\'s limits. Make-up comes softened from WT-1.',f:['7 to 8 °dH, pH 7 to 9, particles ≤ 200 µm, ≤ 500 µS/cm, chlorine ≤ 20 mg/l (site requirements 3.1.2, vendor)','200k to 500k THB (utilities CSV, estimate)'],q:[]},
GC1:{t:'GC · Galvanics cooling (separate circuit)',w:'The Pheenix PDPU wants colder water than the presses and very little of it, so it does not share the press loop: either a small dedicated chiller or a separately controlled branch through its own heat exchanger. Phase 5.',f:['PDPU: 12 to 20 °C at 5 bar, 10 L/min through its titanium coil (galvanics.md, vendor)','OMS thinks passive cooling may do; open whether that holds above 30 °C ambient (galvanics.md)'],q:['Galvanics vendor\'s final requirement; HVAC for the clean room is separate']},
GC1:{t:'GC · Galvanics cooling (separate circuit)',w:'The Pheenix PDPU wants colder water than the presses and very little of it, so it does not share the press loop: either a small dedicated chiller or a separately controlled branch through its own heat exchanger. The galvanics line is part of the launch plant (total-investment.md), so this circuit is built at launch.',f:['PDPU: 12 to 20 °C at 5 bar, 10 L/min through its titanium coil (galvanics.md, vendor)','OMS thinks passive cooling may do; open whether that holds above 30 °C ambient (galvanics.md)'],q:['Galvanics vendor\'s final requirement; HVAC for the clean room is separate']},
};
// launch plant decided October 2026 (total-investment.md, scale.md): 1 Duplex system + 1 Classic on B-1, B-2 and CH-1, CH-2
const CASES={
launch:{t:'Launch',s:'One press (Newbilt Single 2.1, the first half of Duplex system 1)',P:['D1A'],E:1,B:['B1'],C:['CH1'],out:[],ex:'EX 50'},
d1:{t:'Duplex system 1',s:'Two presses on the EX 50 with the EX 35 for colour',P:['D1A','D1B'],E:2,B:['B1'],C:['CH1'],out:[],ex:'EX 50 + EX 35'},
full:{t:'Start fleet, five presses',s:'Two Duplex systems and the Classic, all cooling on a hot afternoon',P:['D1A','D1B','D2A','D2B','C1'],E:5,B:['B1','B2'],C:['CH1','CH2','CH3'],out:[],ex:'2 EX 50, 2 EX 35, Classic'},
down:{t:'One module down',s:'Start fleet with B-2 and CH-2 out at once (worst-case drill)',P:['D1A','D1B','D2A','D2B','C1'],E:5,B:['B1'],C:['CH1','CH3'],out:['B2','CH2'],ex:'2 EX 50, 2 EX 35, Classic'}};
launch:{t:'Launch plant',s:'One Duplex system (D1-A and D1-B on the EX 50, EX 35 for colour) and the Classic, all cooling on a hot afternoon',P:['D1A','D1B','C1'],E:3,B:['B1','B2'],C:['CH1','CH2'],out:[],ex:'EX 50, EX 35, Classic'},
d1:{t:'Duplex first (commissioning)',s:'The Duplex system commissioned ahead of the Classic: two presses on the EX 50 with the EX 35 for colour, on B-1 and CH-1',P:['D1A','D1B'],E:2,B:['B1'],C:['CH1'],out:[],ex:'EX 50 + EX 35'},
growth:{t:'Second Duplex (growth option, five presses)',s:'A second Duplex system in the reserved positions next to the launch plant, all five presses cooling on a hot afternoon',P:['D1A','D1B','C1','D2A','D2B'],E:5,B:['B1','B2'],C:['CH1','CH2','CH3'],out:[],ex:'2 EX 50, 2 EX 35, Classic'},
down:{t:'One module down',s:'Launch plant with B-2 and CH-2 out at once (worst-case drill)',P:['D1A','D1B','C1'],E:3,B:['B1'],C:['CH1'],out:['B2','CH2'],ex:'EX 50, EX 35, Classic'}};
const LAUNCH=CASES.launch;
const f0=v=>Math.round(v).toLocaleString('en-US');
const fk=v=>Number.isInteger(v)?f0(v):v.toLocaleString('en-US',{maximumFractionDigits:1});
function setCase(k){const c=CASES[k];
document.querySelectorAll('#cases [data-case]').forEach(b=>b.classList.toggle('on',b.dataset.case===k));
PR.forEach(([id])=>{const on=c.P.includes(id);BOX[id].g.classList.toggle('dim',!on);BOX[id].t[4].textContent=on?'running':'not yet installed';});
// not running: a launch-plant module still being commissioned, or a position reserved for the growth option
const idle=id=>LAUNCH.P.includes(id)||LAUNCH.B.includes(id)||LAUNCH.C.includes(id)?'not yet commissioned':'reserved position';
PR.forEach(([id])=>{const on=c.P.includes(id);BOX[id].g.classList.toggle('dim',!on);BOX[id].t[4].textContent=on?'running':idle(id);});
['B1','B2'].forEach(id=>{const out=c.out.includes(id),on=c.B.includes(id);BOX[id].g.classList.toggle('out',out);BOX[id].g.classList.toggle('dim',!on&&!out);
BOX[id].t[1].textContent=out?'OUT (fault drill)':on?'running':'with Duplex 2';});
BOX[id].t[1].textContent=out?'OUT (fault drill)':on?'running':idle(id);});
['CH1','CH2','CH3'].forEach(id=>{const out=c.out.includes(id),on=c.C.includes(id);BOX[id].g.classList.toggle('out',out);BOX[id].g.classList.toggle('dim',!on&&!out);
BOX[id].t[1].textContent=out?'OUT (fault drill)':on?'running':'later stage';});
BOX[id].t[1].textContent=out?'OUT (fault drill)':on?'running':idle(id);});
BOX.EX1.t[1].textContent=c.ex;
PR.forEach(([id])=>PRT[id].classList.toggle('dim',!c.P.includes(id)));
const P=c.P.length,E=c.E,st=[150*P,180*P],cool=125*P+3*E+2.5*P,fl=[53*P+4*E+4*P,100*P+4*E+4*P];
@@ -378,18 +385,18 @@ function setCase(k){const c=CASES[k];
$('caseCard').innerHTML=`<h2>${c.t}</h2><p>${c.s}.</p><table>
<tr><th></th><th>Demand</th><th>Installed</th><th>Covers</th></tr>
<tr><td>Steam, kg/h</td><td class="n">${f0(st[0])} to ${f0(st[1])}</td><td class="n">${f0(bc)}</td><td class="n pc${stLo?' low':''}">${pc(bc,st[1])} to ${pc(bc,st[0])} %</td></tr>
<tr><td>Cooling peak, kW</td><td class="n">${f0(cool)}</td><td class="n">${f0(cc)}</td><td class="n pc${ccLo?' low':''}">${pc(cc,cool)} %</td></tr>
<tr><td>Cooling peak, kW</td><td class="n">${fk(cool)}</td><td class="n">${f0(cc)}</td><td class="n pc${ccLo?' low':''}">${pc(cc,cool)} %</td></tr>
<tr><td>Circulating water</td><td class="n" colspan="3">${f0(fl[0])} to ${f0(fl[1])} l/min</td></tr>
<tr><td>Chiller input at peak</td><td class="n" colspan="3">~${f0(cool*0.32)} to ${f0(cool*0.5)} kW electrical</td></tr>
<tr><td>Electric boilers instead</td><td class="n" colspan="3">~${f0(st[0]*0.68/0.98)} to ${f0(st[1]*0.68/0.98)} kW electrical</td></tr></table>
<p class="note">${ccLo&&k==='d1'?'Just under the peak: the cold tank carries overlapping cooling phases, or CH-2 comes forward. ':''}${k==='down'?'The cold tank and cycle diversity carry most hours; a boiler fault costs about two presses until fixed, which is what B-3 and CH-4 would buy back. ':''}Demand at Newbilt's per-machine figures; installed capacity is the proposal on this page.</p>`;}
<p class="note">${ccLo&&k==='d1'?'Just under the peak: the cold tank carries overlapping cooling phases until CH-2 runs with the Classic. ':''}${k==='down'?'One boiler still covers most of the steam. One chiller covers about the Duplex system\'s 261 kW peak, so on a hot afternoon the cold tank and cycle diversity carry part of the Classic; a module in CH-3\'s reserved position would make cooling N+1. ':''}${k==='growth'?'Growth option with room reserved, not in the investment (total-investment.md); B-3 and CH-4 would make it N+1. ':''}Demand at Newbilt's per-machine figures; installed capacity is the proposal on this page.</p>`;}
let sel=null;
function select(id){const b=BOX[id];if(sel)sel.g.classList.remove('sel');sel=b;b.g.classList.add('sel');const d=D[b.det];const p=$('detail');p.innerHTML='';
const add=(t,txt)=>{const e=document.createElement(t);e.textContent=txt;p.appendChild(e);return e;};
add('h2',d.t);add('p',d.w);
[['Figures and sources',d.f],['Open for the RFQ',d.q]].forEach(([h,a])=>{if(!a||!a.length)return;add('h3',h);const ul=document.createElement('ul');a.forEach(x=>{const li=document.createElement('li');li.textContent=x;ul.appendChild(li);});p.appendChild(ul);});}
document.querySelectorAll('#cases [data-case]').forEach(b=>b.addEventListener('click',()=>setCase(b.dataset.case)));
setCase('full');
setCase('launch');
window.__sc={BOX,BUB,D,CASES,setCase};
})();
(function(){