@wafertools/wafermap 0.30.0 → 0.30.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +68 -9
- package/CHANGELOG.md +247 -0
- package/README.md +3 -3
- package/dist/packages/canvas-adapter/charts/barPanel.js +1 -1
- package/dist/packages/canvas-adapter/charts/binCluster.js +1 -1
- package/dist/packages/canvas-adapter/charts/boxplot.js +1 -1
- package/dist/packages/canvas-adapter/charts/capability.js +1 -1
- package/dist/packages/canvas-adapter/charts/chartShell.js +1 -1
- package/dist/packages/canvas-adapter/charts/correlation.js +2 -2
- package/dist/packages/canvas-adapter/charts/groupedBarPlot.d.ts +1 -0
- package/dist/packages/canvas-adapter/charts/histogram.js +1 -1
- package/dist/packages/canvas-adapter/charts/scatter.js +1 -1
- package/dist/packages/canvas-adapter/charts/testPassRate.js +1 -1
- package/dist/packages/canvas-adapter/charts/trend.js +1 -1
- package/dist/packages/canvas-adapter/chunked.d.ts +45 -0
- package/dist/packages/canvas-adapter/chunked.js +1 -0
- package/dist/packages/canvas-adapter/deprecated.d.ts +0 -3
- package/dist/packages/canvas-adapter/deprecated.js +1 -1
- package/dist/packages/canvas-adapter/dieList.js +1 -1
- package/dist/packages/canvas-adapter/exportName.d.ts +68 -0
- package/dist/packages/canvas-adapter/exportName.js +1 -0
- package/dist/packages/canvas-adapter/icons.js +2 -2
- package/dist/packages/canvas-adapter/index.d.ts +2 -1
- package/dist/packages/canvas-adapter/index.js +1 -1
- package/dist/packages/canvas-adapter/insightsTab.js +1 -1
- package/dist/packages/canvas-adapter/renderWaferGallery.d.ts +80 -3
- package/dist/packages/canvas-adapter/renderWaferGallery.js +1 -1
- package/dist/packages/canvas-adapter/renderWaferMap.d.ts +24 -2
- package/dist/packages/canvas-adapter/renderWaferMap.js +1 -1
- package/dist/packages/canvas-adapter/summaryPanel.d.ts +76 -15
- package/dist/packages/canvas-adapter/summaryPanel.js +3 -3
- package/dist/packages/canvas-adapter/toCanvas.js +1 -1
- package/dist/packages/canvas-adapter/toolbar.d.ts +6 -0
- package/dist/packages/canvas-adapter/toolbar.js +2 -2
- package/dist/packages/canvas-adapter/userGuideHtml.d.ts +1 -1
- package/dist/packages/canvas-adapter/userGuideHtml.js +15 -8
- package/dist/packages/canvas-adapter/version.d.ts +2 -2
- package/dist/packages/canvas-adapter/version.js +1 -1
- package/dist/packages/canvas-adapter/warnings.js +1 -1
- package/dist/packages/core/aggregates.js +1 -1
- package/dist/packages/core/deprecated.d.ts +8 -12
- package/dist/packages/core/deprecated.js +1 -1
- package/dist/packages/core/index.d.ts +1 -1
- package/dist/packages/core/index.js +1 -1
- package/dist/packages/core/utils.d.ts +67 -0
- package/dist/packages/core/utils.js +1 -1
- package/dist/packages/core/waferLabel.d.ts +12 -2
- package/dist/packages/core/waferLabel.js +1 -1
- package/dist/packages/renderer/binColors.d.ts +52 -0
- package/dist/packages/renderer/binColors.js +1 -1
- package/dist/packages/renderer/buildView.js +1 -1
- package/dist/packages/renderer/buildWaferMap.d.ts +30 -5
- package/dist/packages/renderer/buildWaferMap.js +1 -1
- package/dist/packages/renderer/deprecate.d.ts +7 -0
- package/dist/packages/renderer/deprecate.js +1 -1
- package/dist/packages/renderer/deprecated.d.ts +2 -2
- package/dist/packages/renderer/deprecated.js +1 -1
- package/dist/packages/renderer/index.d.ts +2 -1
- package/dist/packages/renderer/index.js +1 -1
- package/dist/packages/stats/analyzeWaferLot.js +1 -1
- package/dist/packages/stats/analyzeWaferMap.js +1 -1
- package/dist/packages/stats/capability.d.ts +72 -1
- package/dist/packages/stats/capability.js +1 -1
- package/dist/packages/stats/correlation.d.ts +30 -0
- package/dist/packages/stats/correlation.js +1 -1
- package/dist/packages/stats/deprecated.d.ts +30 -35
- package/dist/packages/stats/deprecated.js +1 -1
- package/dist/packages/stats/findingsNarrative.js +1 -1
- package/dist/packages/stats/index.d.ts +4 -2
- package/dist/packages/stats/index.js +1 -1
- package/dist/packages/stats/math.d.ts +27 -2
- package/dist/packages/stats/math.js +1 -1
- package/dist/packages/stats/normalizeInput.d.ts +10 -0
- package/dist/packages/stats/normalizeInput.js +1 -0
- package/dist/packages/stats/regions.d.ts +2 -0
- package/dist/packages/stats/regions.js +1 -1
- package/dist/packages/stats/renderFindingsReport.js +1 -1
- package/dist/packages/stats/renderSummaryReport.d.ts +39 -1
- package/dist/packages/stats/renderSummaryReport.js +27 -27
- package/dist/packages/stats/reportHtml.d.ts +0 -1
- package/dist/packages/stats/reportHtml.js +10 -10
- package/dist/packages/stats/summaryFigures.d.ts +47 -0
- package/dist/packages/stats/summaryFigures.js +1 -0
- package/dist/packages/stats/types.d.ts +118 -0
- package/llms.txt +12 -7
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
import{fontPx as Rt}from"./toolbar.js";import{findTestDef as Re,buildMapTitle as Ce}from"../renderer/buildView.js";import{sortBinsForDisplay as je}from"../stats/binPareto.js";import{affineInvert as Qe,affineVector as _e}from"../core/transforms.js";import{compareNatural as ve}from"../core/utils.js";import{resolveValueColorFn as to}from"../renderer/colorSchemes.js";import{NO_DATA_FILL as eo}from"../renderer/colorMap.js";import{SPEC_PASS_FILL as Be,SPEC_FAIL_LOW as oo,SPEC_FAIL_HIGH as Pe,contrastTextColor as De}from"../renderer/colorMap.js";import{fmt as We,fmtColorbarAxis as no}from"../renderer/fmt.js";import{resolveCanvasTheme as so}from"./canvasTheme.js";import{hitGridDims as lo}from"./hitGrid.js";function Ie(g,e,P,b,r){g.moveTo(e,P+r*b),g.lineTo(e-b*.9,P-r*b*.6),g.lineTo(e+b*.9,P-r*b*.6),g.closePath()}const io=new Set(["value","stackedValues","stackedBins","stackedSoftBins"]),ao=new Set(["hardBin","softBin","metadata"]),J=()=>`${Rt(-2)}px system-ui, sans-serif`,Fe=3,Vt=2,co=6,ro=20,fo=()=>`600 ${Rt()}px system-ui, sans-serif`,Ut=()=>`${Rt(-1)}px system-ui, sans-serif`,ho=()=>`600 ${Rt(-1)}px system-ui, sans-serif`,Kt=128,go=()=>`${Rt(-2)}px system-ui, sans-serif`,Ne=4,D=17,H=11;export const BIN_LEGEND_W=110,BIN_LEGEND_W_COMPACT=64,BIN_LEGEND_ADAPT_COMPACT=280,BIN_LEGEND_ADAPT_FLOATING=180,BIN_LEGEND_MIN_CANVAS_W=150,BIN_LEGEND_MIN_CANVAS_H=120;const qt=28,dt=5,ft=8,Oe=15,Ee=12,He=6;export function toCanvas(g,e,P={}){return drawMapCanvas(g,e,P)}export function drawMapCanvas(g,e,P={}){const b=so(g.parentElement??g),{padding:r=16,showColorbar:G=!0,markFailingDies:X=!1,colorbarWidth:B=16,background:gt=b.background,legendPosition:Z="default",legendOffset:mt,showAxes:ut=!1,diePitchMm:w,viewport:K,activeBin:O,hoverBin:q,fallbackFormat:bt,minRightReserve:Ct,hbinDefs:nt,sbinDefs:pt,metadataFields:xt,showTitle:U=!0}=P,W=Math.floor(g.clientWidth||g.width),Y=Math.floor(g.clientHeight||g.height),Mt=W>=BIN_LEGEND_MIN_CANVAS_W&&Y>=BIN_LEGEND_MIN_CANVAS_H,Tt=G&&Mt&&io.has(e.plotMode)&&e.passFailDisplay==="off",St=G&&Mt&&ao.has(e.plotMode),j=G&&Mt&&e.plotMode==="value"&&(e.passFailDisplay==="spec"&&e.specCounts!==void 0||e.passFailDisplay==="test"&&e.passFailCounts!==void 0),Q=St||j,_t=St&&e.plotMode!=="metadata"&&e.binCounts?je(e.binCounts.entries(),e.plotMode==="softBin"?e.binColors.pass.soft:e.binColors.pass.hard):[],Bt=St&&e.plotMode==="metadata"&&e.metadataCounts?[...e.metadataColorMap?.keys()??[...e.metadataCounts.keys()].sort(ve)].map(o=>[o,e.metadataCounts.get(o)??0]):[],v=[];if(j&&e.passFailDisplay==="test"){const o=e.passFailCounts;v.push({key:-1,color:Be,label:"Pass",compactLabel:"Pass",count:o.pass,tooltip:`Pass \xB7 ${o.pass} dies`}),v.push({key:-2,color:Pe,label:"Fail",compactLabel:"Fail",count:o.fail,tooltip:`Fail \xB7 ${o.fail} dies`})}else if(j){const o=e.specCounts,f=Re(e.testDefs,e.activeTest);v.push({key:-1,color:Be,label:"Pass",compactLabel:"Pass",count:o.pass,tooltip:`Pass \xB7 ${o.pass} dies`}),f?.limitHigh!==void 0&&v.push({key:-2,color:Pe,label:"Fail high",compactLabel:"Fail hi",count:o.failHigh,tooltip:`Fail high \xB7 ${o.failHigh} dies`}),f?.limitLow!==void 0&&v.push({key:-3,color:oo,label:"Fail low",compactLabel:"Fail lo",count:o.failLow,tooltip:`Fail low \xB7 ${o.failLow} dies`})}const Pt=j?v.length:e.plotMode==="metadata"?Bt.length:_t.length,p=(g.ownerDocument.defaultView??window).devicePixelRatio??1;if(W<=0||Y<=0)return{hitTarget:{getDieAtPoint:()=>null},viewport:{originX:0,originY:0,ppm:1,snapDist:1},binLegendRows:[]};const A=Z!=="default"?Z:W<BIN_LEGEND_ADAPT_FLOATING?"floating":W<BIN_LEGEND_ADAPT_COMPACT?"compact":"default",ht=A==="default"||A==="compact",fe=A==="left",Jt=A==="bottom",Lt=A==="top",kt=A==="floating",Dt=A==="compact"||A==="floating"?BIN_LEGEND_W_COMPACT:BIN_LEGEND_W,he=Math.floor((Y-2*r)/D),de=Pt>he?he-1:Pt,ge=Q&&Jt?de*D:0,Zt=Q&&Lt?de*D:0,jt=e.plotMode==="stackedBins"||e.plotMode==="stackedSoftBins",Qt=Re(e.testDefs,e.activeTest),Ye=jt?"Count":Qt?.name??(e.activeTest!=null?`Test ${e.activeTest}`:void 0),Ge=jt?void 0:Qt?.unit,[Wt,It]=e.valueRange,{tickFmt:Xe}=no(It,Ye,Ge,bt),Ft=e.allIntegerValues?o=>String(Math.round(o)):Xe;let vt=0;if(Tt){const o=g.getContext("2d");o.font=J();const f=[Ft(Wt),Ft(It)];Wt<0&&f.push(Ft(-Math.max(Math.abs(Wt),Math.abs(It))));for(const s of f)vt=Math.max(vt,o.measureText(s).width)}const me=Math.max(ro,Math.ceil(vt)+Fe+Vt+co-r),te=Tt?B+me+8:Q&&ht?Dt:0,ee=Q&&fe?Dt:0,oe=ut?32:0,Nt=ut?36:0,$e=Ct!=null?Math.max(te,Ct):te,we=W-2*r-$e-Nt-ee,ue=Y-2*r-oe-ge-Zt;g.width=Math.round(W*p),g.height=Math.round(Y*p);const t=g.getContext("2d");t.scale(p,p),t.fillStyle=gt,t.fillRect(0,0,W,Y);const $=e.hoverPoints;if(!$.length)return{hitTarget:{getDieAtPoint:()=>null},viewport:{originX:0,originY:0,ppm:1,snapDist:1},binLegendRows:[]};const Ot=e.rectangles[0],ne=Ot?Ot.width/2:0,se=Ot?Ot.height/2:0,Et=e.dieBounds,pe=(Et?.minX??0)-ne,Ve=(Et?.maxX??0)+ne,Ue=(Et?.minY??0)-se,xe=(Et?.maxY??0)+se,Me=Ve-pe,ye=xe-Ue;let tt,et,L;if(K)({originX:tt,originY:et,ppm:L}=K);else{const f=e.notchDir,s=f&&f.y>.1?13:0,a=f&&f.y<-.1?13:0,c=f&&f.x<-.1?13:0,h=f&&f.x>.1?13:0,d=we-c-h,i=ue-s-a;L=Math.min(d/Me,i/ye),tt=r+Nt+ee+c+(d-Me*L)/2-pe*L,et=r+Zt+s+(i-ye*L)/2+xe*L}const Ht=K?.snapDist??Math.max(ne,se,1)*1.5,Yt=tt+e.waferCenter.x*L,Ke=et-e.waferCenter.y*L,le=e.waferRadius*L,st=o=>{const f=Math.abs(o-Ke);return f>=le?0:Math.sqrt(le*le-f*f)},lt=(o,f,s,a,c,h,d=fo(),i=b.text)=>{if(!o)return;t.save(),t.fillStyle=i,t.font=d,t.textAlign=a,t.textBaseline=c;const y=a==="right"?f-h:h-f;let l=o;if(y>8&&t.measureText(l).width>y){for(;l.length>1&&t.measureText(l+"\u2026").width>y;)l=l.slice(0,-1);l=l+"\u2026"}y>8&&t.fillText(l,f,s),t.restore()};if(t.save(),t.setTransform(L*p,0,0,-L*p,tt*p,et*p),e.rectangles.length>0){const o=new Map;for(const s of e.rectangles){const a=String(s.fill);let c=o.get(a);c||(c=[],o.set(a,c)),c.push(s)}for(const[s,a]of o){t.beginPath();for(const c of a)t.rect(c.x-c.width/2,c.y-c.height/2,c.width,c.height);t.fillStyle=s,t.fill()}t.strokeStyle="rgba(0,0,0,0.18)",t.lineWidth=.5/(L*p),t.beginPath();for(const s of e.rectangles)t.rect(s.x-s.width/2,s.y-s.height/2,s.width,s.height);if(t.stroke(),X){const s=e.rectangles.filter(a=>a.binFail);if(s.length>0){const a=new Map;for(const c of s){const h=De(String(c.fill));let d=a.get(h);d||(d=[],a.set(h,d)),d.push(c)}t.save(),t.lineCap="butt";for(const[c,h]of a){t.strokeStyle=c,t.globalAlpha=.55,t.lineWidth=Math.max(.6/(L*p),Math.min(h[0].width,h[0].height)*.1);for(const d of h){const i=d.width/2,y=d.height/2,l=Math.max(1.6/(L*p),Math.min(d.width,d.height)/3);t.save(),t.beginPath(),t.rect(d.x-i,d.y-y,d.width,d.height),t.clip(),t.beginPath();for(let T=-(i+y);T<=i+y;T+=l)t.moveTo(d.x-i+T,d.y-y),t.lineTo(d.x-i+T+d.height,d.y+y);t.stroke(),t.restore()}}t.restore()}}const f=e.rectangles.filter(s=>s.specMark);if(f.length>0){const s=new Map;for(const c of f){const h=De(String(c.fill)),d=`${c.specMark}|${h}`;let i=s.get(d);i||(i=[],s.set(d,i)),i.push(c)}const a=2.5/(L*p);t.lineJoin="round";for(const[c,h]of s){const[d,i]=c.split("|"),y=i==="#000000"?"#ffffff":"#000000",l=d==="failHigh"?1:-1,T=Math.min(h[0].width,h[0].height),I=Math.max(2.5/(L*p),T*.3);t.beginPath();for(const R of h)Ie(t,R.x,R.y,I,l);t.strokeStyle=y,t.lineWidth=a,t.stroke(),t.fillStyle=i,t.fill()}}}for(const o of e.overlays){t.beginPath();for(const f of o.points){for(let s=0;s<f.length;s++)s===0?t.moveTo(f[s].x,f[s].y):t.lineTo(f[s].x,f[s].y);o.closed&&t.closePath()}o.fill&&!o.fill.startsWith("rgba(0,0,0,0)")&&(t.fillStyle=o.fill,t.fill()),o.kind==="ring-boundary"||o.kind==="quadrant-boundary"||o.kind==="reticle"?(t.strokeStyle="rgba(0,0,0,0.45)",t.lineWidth=3/(L*p),t.stroke(),t.strokeStyle="rgba(255,255,255,0.8)",t.lineWidth=1/(L*p),t.stroke()):(t.strokeStyle=o.lineColor,t.lineWidth=o.lineWidth/(L*p),t.stroke())}if(t.restore(),e.notchDir){const o=tt+e.waferCenter.x*L,f=et-e.waferCenter.y*L,s=e.notchDir.x,a=-e.notchDir.y,c=e.waferRadius*L,h=4,d=9,i=5,y=o+s*(c+h),l=f+a*(c+h),T=y+s*d,I=l+a*d,R={x:-a,y:s},F=r+Nt+ee,E=W-r-te,V=r+Zt,at=Y-r-ge-oe;t.save(),t.beginPath(),t.rect(F,V,E-F,at-V),t.clip(),t.beginPath(),t.moveTo(y,l),t.lineTo(T+R.x*i,I+R.y*i),t.lineTo(T-R.x*i,I-R.y*i),t.closePath(),t.fillStyle=b.text,t.fill(),t.restore()}t.save(),t.textAlign="center",t.textBaseline="middle";let be=0;if(e.rectangles.length>0){let o=1;for(const h of e.texts)h.role!=="indicator"&&h.text.length>o&&(o=h.text.length);const f=e.rectangles[0].width*L,s=e.rectangles[0].height*L,a=Math.min(f,s),c=f/o;be=Math.max(8,Math.min(64,Math.round(Math.min(a*.55,c*1.8))))}for(const o of e.texts){const f=tt+o.x*L,s=et-o.y*L;t.font=`${o.role==="indicator"?o.fontSize:be}px system-ui, sans-serif`,t.fillStyle=o.color,t.fillText(o.text,f,s)}if(t.restore(),ut&&mo(t,W,Y,tt,et,L,r,oe,Nt,w,e.gridToScreen,e.rotation,b),Tt){const o=to(e.valueColorScheme,e.reverseValueScheme),f=me,s=ue,a=Math.round(s*.75),c=r+Math.round((s-a)/2),h=W-r-B-f,d=Wt,i=It,y=i-d,l=e.plotMode==="stackedSoftBins"?pt:nt,{primary:T,secondary:I}=U?Ce(e,bt,l):{primary:"",secondary:""};if(U){const n=Math.max(c-6,r+11),m=Yt+Math.max(st(n),st(n-12))+8;lt(T,W-r,n,"right","bottom",m)}let R=c+a+4;const F=n=>Yt+Math.max(st(n),st(n+12))+8,E=e.logScale&&d>0?Math.log10(d):0,V=e.logScale&&i>0?Math.log10(i)-E:1,at=n=>e.logScale?(1-(Math.log10(n)-E)/V)*a:(1-(n-d)/y)*a;for(let n=0;n<Kt;n++){const m=1-n/(Kt-1),S=c+n/Kt*a,x=a/Kt+1;t.fillStyle=o(m),t.fillRect(h,S,B,x)}t.strokeStyle="rgba(0,0,0,0.25)",t.lineWidth=.5,t.strokeRect(h,c,B,a),t.fillStyle=b.text,t.font=J(),t.textAlign="left",t.strokeStyle="rgba(0,0,0,0.35)",t.lineWidth=.5;const k=Fe,N=36,ot=14,$t=e.logScale&&V>0?uo(d,i,a,N,ot,E,V):e.allIntegerValues?(()=>{const n=Math.max(1,zt(y*N/a)),m=[],S=Math.ceil(d/n)*n;for(let x=S;x<=i+n*1e-6;x+=n){const u=(1-(x-d)/y)*a;u>ot&&u<a-ot&&m.push(Math.round(x))}return m})():(()=>{const n=y>0?zt(y*N/a):0,m=[];if(n>0){const S=Math.ceil(d/n)*n;for(let x=S;x<=i+n*1e-6;x+=n){const u=(1-(x-d)/y)*a;u>ot&&u<a-ot&&m.push(x)}}return m})(),C=Qt,_=jt,M=Ft;t.textBaseline="middle";for(const n of $t){const m=c+at(n);t.beginPath(),t.moveTo(h+B,m),t.lineTo(h+B+k,m),t.stroke(),t.fillText(M(n),h+B+k+Vt,m)}if(t.beginPath(),t.moveTo(h+B,c),t.lineTo(h+B+k,c),t.stroke(),t.textBaseline="top",t.fillText(M(i),h+B+k+Vt,c),t.beginPath(),t.moveTo(h+B,c+a),t.lineTo(h+B+k,c+a),t.stroke(),t.textBaseline="bottom",t.fillText(M(d),h+B+k+Vt,c+a),!_&&C&&(C.limitLow!==void 0||C.limitHigh!==void 0)){const n=[],m=e.colorbarRangeMode==="spec";for(const[S,x]of[[C.limitLow,"LSL"],[C.limitHigh,"USL"]]){if(S===void 0||e.logScale&&S<=0)continue;const u=at(S);!m&&(u<-ot||u>a+ot)||n.push({value:S,label:x,py:Math.max(0,Math.min(a,u))})}if(n.length>0){t.save(),t.font=J(),t.textAlign="right",t.textBaseline="middle";for(const{py:S,label:x}of n){const u=c+S;m||(t.strokeStyle="rgba(255,255,255,0.85)",t.lineWidth=3,t.beginPath(),t.moveTo(h,u),t.lineTo(h+B,u),t.stroke(),t.strokeStyle="rgba(0,0,0,0.7)",t.lineWidth=1,t.beginPath(),t.moveTo(h,u),t.lineTo(h+B,u),t.stroke()),t.fillStyle=b.text,t.fillText(x,h-3,u);const ct=x==="USL"?-1:1,rt=4,yt=h-3-t.measureText(x).width-rt-4;t.beginPath(),Ie(t,yt,u,rt,ct),t.strokeStyle="#fff",t.lineWidth=2,t.lineJoin="round",t.stroke(),t.fillStyle=b.text,t.fill()}t.restore()}}if(!_){const n=e.logScale?"log\u2081\u2080":e.logScaleRequested?"linear \u2014 log n/a":null;n&&(t.save(),t.fillStyle=b.text,t.font=ho(),t.textAlign="right",t.textBaseline="top",t.fillText(n,W-r,R),t.restore(),R+=15)}U&&I&<(I,W-r,R,"right","top",F(R),Ut(),b.text)}const ie=[];let z;if(Q){const o=A==="compact",f=e.plotMode==="softBin"?pt:nt,s=f?new Map(f.map(l=>[l.bin,l])):null,a=e.plotMode==="softBin"?e.binColors.soft:e.binColors.hard,c=l=>a.get(l)??eo,h=(l,T)=>{const I=t.measureText(l).width,R=o?0:t.measureText(String(T)).width,F=H+dt+I+(R?qt:0);return{labelWidth:I,countWidth:R,totalWidth:F}},d=xt?.find(l=>l.key===e.activeMetadataKey),i=j?v.map(l=>{const T=o?l.compactLabel:l.label;return{key:l.key,color:l.color,count:l.count,label:T,tooltipLabel:l.tooltip,...h(T,l.count)}}):e.plotMode==="metadata"?Bt.map(([l,T])=>{const R=d?.values?.find(V=>V.value===l)?.label??l,F=o?l:R,E=e.metadataColorMap?.get(l)??"#d6d9dd";return{key:l,color:E,count:T,label:F,tooltipLabel:`${R} \xB7 ${T} dies`,...h(F,T)}}):_t.map(([l,T])=>{const I=s?.get(l),R=I?.name?`${l} \xB7 ${I.name}`:`Bin ${l}`,F=o?String(l):R;return{key:l,color:c(l),count:T,label:F,tooltipLabel:`${R} \xB7 ${T} dies`,...h(F,T)}}),y=W-r*2;if(i.length>0){const l=kt?ft*2+(U?Oe:0):U&&!Lt?Ee+He:0,T=Math.max(1,Math.floor((Y-2*r-l)/D));let I=i.length,R=1,F=I*D,E=[],V=0;const at=Jt||Lt;if(at){const C=Math.max(...i.map(M=>M.totalWidth)),_=Math.max(1,Math.min(i.length,Math.floor((y+8)/(C+8))));for(let M=_;M>=1;M--){const n=Math.ceil(i.length/M);if(n>T)continue;const m=new Array(M).fill(0);for(let x=0;x<i.length;x++){const u=x%M;m[u]=Math.max(m[u],i[x].totalWidth)}if(m.reduce((x,u)=>x+u,0)+(M-1)*8<=y||M===1){R=M,E=m,I=n,F=n*D;break}}}else I=Math.min(i.length,T),F=I*D,i.length>T&&(V=i.length-(T-1)),E=[Dt];let k,N;if(kt){const C=Math.max(...i.map(u=>H+dt+t.measureText(u.label).width+qt)),_=Math.ceil(C);E=[_];const M=U?Oe:0,n=_+ft*2,m=F+M+ft*2,S=mt?.x??0,x=mt?.y??0;k=Math.min(Math.max(W-r-n+S,r),W-r-n),N=Math.min(Math.max(Y-r-m+x,r),Y-r-m),z={x:k,y:N,w:n,h:m},t.save(),t.globalAlpha=.92,t.fillStyle=b.surface,t.fillRect(k,N,n,m),t.globalAlpha=1,t.strokeStyle=b.axisLine,t.lineWidth=1,t.strokeRect(k,N,n,m),t.restore(),k+=ft,N+=ft+M}else Jt?(k=r,N=Y-r-F):Lt?(k=r,N=r):fe?(k=r+4,N=Math.max(r+Math.round((Y-2*r-F)/2),r+l)):(k=W-r-Dt+4,N=Math.max(r+Math.round((Y-2*r-F)/2),r+l));if(U){const C=e.plotMode==="softBin"?pt:nt,{primary:_,secondary:M}=Ce(e,bt,C),n=He,m=u=>Yt-Math.max(st(u),st(u-12))-8,S=u=>ht?W-r:m(u),x=kt?z.y+z.h:N+F;if(Lt){const u=x+n;lt(_,k,u,"left","top",Yt-Math.max(st(u),st(u+12))-8),M&<(M,k,u+16,"left","top",m(u+16),Ut(),b.text)}else if(kt)lt(_,z.x+ft,z.y+ft,"left","top",z.x+z.w-ft),M&<(M,z.x,x+n,"left","top",z.x+z.w,Ut(),b.text);else{const u=Math.max(N-n,r+Ee);if(lt(_,k,u,"left","bottom",S(u)),M){const ct=x+n;lt(M,k,ct,"left","top",S(ct),Ut(),b.text)}}}t.save(),t.font=J();const ot=at?8:0,$t=(C,_)=>{if(t.measureText(C).width<=_)return C;let M=0,n=C.length;const m="\u2026",S=t.measureText(m).width;for(;M<n;){const x=M+n+1>>1;t.measureText(C.slice(0,x)).width+S<=_?M=x:n=x-1}return M===0?m:C.slice(0,M)+m};if(at){let C=0;for(let _=0;_<I;_++){let M=k;for(let n=0;n<R;n++){const m=i[C++];if(!m)break;const S=m.key===O,x=!S&&m.key===q,u=M,ct=M+H+dt,rt=N+_*D+D/2,yt=N+_*D+Math.round((D-H)/2),wt=E[n]-H-dt-qt;x&&(t.fillStyle=b.hoverRow,t.fillRect(M,N+_*D,E[n],D)),t.fillStyle=m.color,t.fillRect(u,yt,H,H),t.strokeStyle=S?b.accent:"rgba(0,0,0,0.25)",t.lineWidth=S?2:.75,t.strokeRect(u,yt,H,H),t.fillStyle=S?b.accent:b.text,t.font=S?`bold ${J()}`:J(),t.textAlign="left",t.textBaseline="middle",t.fillText($t(m.label,wt),ct,rt),t.fillStyle=b.textMuted,t.font=J(),t.textAlign="right",t.fillText(String(m.count),M+E[n]-2,rt),ie.push({bin:m.key,x:M,y:N+_*D,w:E[n],h:D,label:m.tooltipLabel}),M+=E[n]+ot}}}else{const C=E[0],_=A!=="compact",M=C-H-dt-(_?qt:0),n=k+C-2;let m=i;V>0&&(m=i.slice(0,T-1));let S=N;for(const x of m){const u=x.key===O,ct=!u&&x.key===q,rt=k,yt=k+H+dt,wt=S+D/2,Ae=S+Math.round((D-H)/2),Ze=x.label;ct&&(t.fillStyle=b.hoverRow,t.fillRect(k-3,S,C+3,D)),t.fillStyle=x.color,t.fillRect(rt,Ae,H,H),t.strokeStyle=u?b.accent:"rgba(0,0,0,0.25)",t.lineWidth=u?2:.75,t.strokeRect(rt,Ae,H,H),t.fillStyle=u?b.accent:b.text,t.font=u?`bold ${J()}`:J(),t.textAlign="left",t.textBaseline="middle",t.fillText($t(Ze,M),yt,wt),(_||kt)&&(t.fillStyle=b.textMuted,t.font=J(),t.textAlign="right",t.fillText(String(x.count),n,wt)),ie.push({bin:x.key,x:k,y:S,w:C,h:D,label:x.tooltipLabel}),S+=D}V>0&&(t.fillStyle=b.textMuted,t.font=J(),t.textAlign="left",t.textBaseline="middle",t.fillText(`+ ${V} more`,k+H+dt,S+D/2))}}i.length>0&&t.restore()}const qe={originX:tt,originY:et,ppm:L,snapDist:Ht},Te=e.rectangles[0]?.width??1,Se=e.rectangles[0]?.height??1,it=e.dieBounds,Gt=it?it.minX:$.length?Math.min(...$.map(o=>o.x)):0,Xt=it?it.minY:$.length?Math.min(...$.map(o=>o.y)):0,ze=it?it.maxX:$.length?Math.max(...$.map(o=>o.x)):1,Je=it?it.maxY:$.length?Math.max(...$.map(o=>o.y)):1,{cellW:ae,cellH:ce,nCols:At,nRows:re}=lo(ze-Gt,Je-Xt,Te*1.5,Se*1.5,$.length),Le=Array.from({length:At*re},()=>[]);for(let o=0;o<$.length;o++){const f=Math.floor(($[o].x-Gt)/ae),s=Math.floor(($[o].y-Xt)/ce),a=Number.isFinite(f)?Math.max(0,Math.min(At-1,f)):0,c=Number.isFinite(s)?Math.max(0,Math.min(re-1,s)):0;Le[c*At+a].push(o)}function ke(o,f,s){const a=Math.max(0,Math.floor((o-s-Gt)/ae)),c=Math.min(At-1,Math.floor((o+s-Gt)/ae)),h=Math.max(0,Math.floor((f-s-Xt)/ce)),d=Math.min(re-1,Math.floor((f+s-Xt)/ce)),i=[];for(let y=h;y<=d;y++)for(let l=a;l<=c;l++)for(const T of Le[y*At+l])i.push(T);return i}return{hitTarget:{getDieAtPoint(o,f){const s=(o-tt)/L,a=(et-f)/L,c=Math.max(Te,Se);for(const i of ke(s,a,c)){const y=e.rectangles[i];if(y&&Math.abs(s-y.x)<=y.width/2&&Math.abs(a-y.y)<=y.height/2)return e.dies[i]??null}let h=null,d=Ht*Ht;for(const i of ke(s,a,Ht)){const y=$[i].x-s,l=$[i].y-a,T=y*y+l*l;T<d&&(d=T,h=e.dies[i]??null)}return h}},viewport:qe,binLegendRows:ie,legendBox:z}}function mo(g,e,P,b,r,G,X,B,gt,Z,mt,ut,w){g.save(),g.font=go(),g.fillStyle=w.text,g.strokeStyle=w.axisLine,g.lineWidth=.5;const K=P-B+4,O=X+gt-4,q=Qe(mt),bt=_e(q,1,0),Ct=_e(q,0,1),nt=1e-9;function pt(p){return Z?Math.abs(p.y)<nt&&Math.abs(p.x)>nt?{pitch:Z.x,sign:Math.sign(p.x)}:Math.abs(p.x)<nt&&Math.abs(p.y)>nt?{pitch:Z.y,sign:Math.sign(p.y)}:null:null}const xt=pt(bt),U=pt(Ct);function W(p){return xt?Math.round(p*xt.sign/xt.pitch):p}function Y(p){return U?Math.round(p*U.sign/U.pitch):p}function Mt(p){if(!p)return zt(50/G);const A=50/(p*G);return Math.max(1,Math.round(A))*p}const Tt=xt?.pitch,St=U?.pitch,j=Mt(Tt),Q=Mt(St);g.textAlign="center",g.textBaseline="top";const _t=Math.ceil((X-b)/G/j)*j,Bt=(e-X-b)/G;for(let p=_t;p<=Bt;p+=j){const A=b+p*G;if(A<X||A>e-X)continue;g.beginPath(),g.moveTo(A,K-Ne),g.lineTo(A,K),g.stroke();const ht=Z?String(W(p)):We(p);g.fillText(ht,A,K+2)}g.textAlign="right",g.textBaseline="middle";const v=Math.ceil((r-(P-X))/G/Q)*Q,Pt=(r-X)/G;for(let p=v;p<=Pt;p+=Q){const A=r-p*G;if(A<X||A>P-X)continue;g.beginPath(),g.moveTo(O,A),g.lineTo(O+Ne,A),g.stroke();const ht=Z?String(Y(p)):We(p);g.fillText(ht,O-2,A)}g.restore()}function zt(g){const e=Math.pow(10,Math.floor(Math.log10(g))),P=g/e;return(P<1.5?1:P<3.5?2:P<7.5?5:10)*e}function uo(g,e,P,b,r,G,X){const B=[],gt=X;if(gt<1){const w=zt((e-g)*b/P);if(w>0){const K=Math.ceil(g/w)*w;for(let O=K;O<=e+w*1e-6;O+=w){if(O<=g||O>=e)continue;const q=(1-(Math.log10(O)-G)/X)*P;q>r&&q<P-r&&B.push(O)}}return B}const Z=gt<3?[1,2,5]:[1],mt=Math.floor(Math.log10(g)),ut=Math.ceil(Math.log10(e));for(let w=mt;w<=ut;w++)for(const K of Z){const O=K*Math.pow(10,w);if(O<=g||O>=e)continue;const q=(1-(Math.log10(O)-G)/X)*P;q>r&&q<P-r&&B.push(O)}return B}export{fmt,fmtColorbarAxis}from"../renderer/fmt.js";
|
|
1
|
+
import{fontPx as Ct}from"./toolbar.js";import{findTestDef as _e,buildMapTitle as Be}from"../renderer/buildView.js";import{sortBinsForDisplay as eo}from"../stats/binPareto.js";import{affineInvert as oo,affineVector as Pe}from"../core/transforms.js";import{compareNatural as no,maxOf as Ut,minOf as De}from"../core/utils.js";import{resolveValueColorFn as so}from"../renderer/colorSchemes.js";import{NO_DATA_FILL as lo}from"../renderer/colorMap.js";import{SPEC_PASS_FILL as We,SPEC_FAIL_LOW as io,SPEC_FAIL_HIGH as Oe,contrastTextColor as Ie}from"../renderer/colorMap.js";import{fmt as Fe,fmtColorbarAxis as ao}from"../renderer/fmt.js";import{resolveCanvasTheme as co}from"./canvasTheme.js";import{hitGridDims as ro}from"./hitGrid.js";function Ne(g,e,P,M,r){g.moveTo(e,P+r*M),g.lineTo(e-M*.9,P-r*M*.6),g.lineTo(e+M*.9,P-r*M*.6),g.closePath()}const fo=new Set(["value","stackedValues","stackedBins","stackedSoftBins"]),ho=new Set(["hardBin","softBin","metadata"]),J=()=>`${Ct(-2)}px system-ui, sans-serif`,Ee=3,Kt=2,go=6,mo=20,uo=()=>`600 ${Ct()}px system-ui, sans-serif`,qt=()=>`${Ct(-1)}px system-ui, sans-serif`,po=()=>`600 ${Ct(-1)}px system-ui, sans-serif`,zt=128,xo=()=>`${Ct(-2)}px system-ui, sans-serif`,He=4,D=17,H=11;export const BIN_LEGEND_W=110,BIN_LEGEND_W_COMPACT=64,BIN_LEGEND_ADAPT_COMPACT=280,BIN_LEGEND_ADAPT_FLOATING=180,BIN_LEGEND_MIN_CANVAS_W=150,BIN_LEGEND_MIN_CANVAS_H=120;const Jt=28,gt=5,ft=8,Ye=15,Ge=12,Xe=6;export function toCanvas(g,e,P={}){return drawMapCanvas(g,e,P)}export function drawMapCanvas(g,e,P={}){const M=co(g.parentElement??g),{padding:r=16,showColorbar:G=!0,markFailingDies:X=!1,colorbarWidth:B=16,background:mt=M.background,legendPosition:Z="default",legendOffset:ut,showAxes:pt=!1,diePitchMm:w,viewport:K,activeBin:N,hoverBin:q,fallbackFormat:Tt,minRightReserve:_t,hbinDefs:nt,sbinDefs:xt,metadataFields:yt,showTitle:U=!0}=P,W=Math.floor(g.clientWidth||g.width),Y=Math.floor(g.clientHeight||g.height),bt=W>=BIN_LEGEND_MIN_CANVAS_W&&Y>=BIN_LEGEND_MIN_CANVAS_H,St=G&&bt&&fo.has(e.plotMode)&&e.passFailDisplay==="off",Lt=G&&bt&&ho.has(e.plotMode),j=G&&bt&&e.plotMode==="value"&&(e.passFailDisplay==="spec"&&e.specCounts!==void 0||e.passFailDisplay==="test"&&e.passFailCounts!==void 0),Q=Lt||j,Bt=Lt&&e.plotMode!=="metadata"&&e.binCounts?eo(e.binCounts.entries(),e.plotMode==="softBin"?e.binColors.pass.soft:e.binColors.pass.hard):[],Pt=Lt&&e.plotMode==="metadata"&&e.metadataCounts?[...e.metadataColorMap?.keys()??[...e.metadataCounts.keys()].sort(no)].map(o=>[o,e.metadataCounts.get(o)??0]):[],v=[];if(j&&e.passFailDisplay==="test"){const o=e.passFailCounts;v.push({key:-1,color:We,label:"Pass",compactLabel:"Pass",count:o.pass,tooltip:`Pass \xB7 ${o.pass} dies`}),v.push({key:-2,color:Oe,label:"Fail",compactLabel:"Fail",count:o.fail,tooltip:`Fail \xB7 ${o.fail} dies`})}else if(j){const o=e.specCounts,f=_e(e.testDefs,e.activeTest);v.push({key:-1,color:We,label:"Pass",compactLabel:"Pass",count:o.pass,tooltip:`Pass \xB7 ${o.pass} dies`}),f?.limitHigh!==void 0&&v.push({key:-2,color:Oe,label:"Fail high",compactLabel:"Fail hi",count:o.failHigh,tooltip:`Fail high \xB7 ${o.failHigh} dies`}),f?.limitLow!==void 0&&v.push({key:-3,color:io,label:"Fail low",compactLabel:"Fail lo",count:o.failLow,tooltip:`Fail low \xB7 ${o.failLow} dies`})}const Dt=j?v.length:e.plotMode==="metadata"?Pt.length:Bt.length,y=(g.ownerDocument.defaultView??window).devicePixelRatio??1;if(W<=0||Y<=0)return{hitTarget:{getDieAtPoint:()=>null},viewport:{originX:0,originY:0,ppm:1,snapDist:1},binLegendRows:[]};const k=Z!=="default"?Z:W<BIN_LEGEND_ADAPT_FLOATING?"floating":W<BIN_LEGEND_ADAPT_COMPACT?"compact":"default",ht=k==="default"||k==="compact",de=k==="left",jt=k==="bottom",kt=k==="top",At=k==="floating",Wt=k==="compact"||k==="floating"?BIN_LEGEND_W_COMPACT:BIN_LEGEND_W,ge=Math.floor((Y-2*r)/D),me=Dt>ge?ge-1:Dt,ue=Q&&jt?me*D:0,Qt=Q&&kt?me*D:0,vt=e.plotMode==="stackedBins"||e.plotMode==="stackedSoftBins",te=_e(e.testDefs,e.activeTest),$e=vt?"Count":te?.name??(e.activeTest!=null?`Test ${e.activeTest}`:void 0),we=vt?void 0:te?.unit,[Ot,It]=e.valueRange,{tickFmt:Ve}=ao(It,$e,we,Tt),Ft=e.allIntegerValues?o=>String(Math.round(o)):Ve;let ee=0;if(St){const o=g.getContext("2d");o.font=J();const f=[Ft(Ot),Ft(It)];Ot<0&&f.push(Ft(-Math.max(Math.abs(Ot),Math.abs(It))));for(const s of f)ee=Math.max(ee,o.measureText(s).width)}const pe=Math.max(mo,Math.ceil(ee)+Ee+Kt+go-r),oe=St?B+pe+8:Q&&ht?Wt:0,ne=Q&&de?Wt:0,se=pt?32:0,Nt=pt?36:0,Ue=_t!=null?Math.max(oe,_t):oe,Ke=W-2*r-Ue-Nt-ne,xe=Y-2*r-se-ue-Qt;g.width=Math.round(W*y),g.height=Math.round(Y*y);const t=g.getContext("2d");t.scale(y,y),t.fillStyle=mt,t.fillRect(0,0,W,Y);const $=e.hoverPoints;if(!$.length)return{hitTarget:{getDieAtPoint:()=>null},viewport:{originX:0,originY:0,ppm:1,snapDist:1},binLegendRows:[]};const Et=e.rectangles[0],le=Et?Et.width/2:0,ie=Et?Et.height/2:0,Ht=e.dieBounds,ye=(Ht?.minX??0)-le,qe=(Ht?.maxX??0)+le,ze=(Ht?.minY??0)-ie,be=(Ht?.maxY??0)+ie,Me=qe-ye,Te=be-ze;let tt,et,A;if(K)({originX:tt,originY:et,ppm:A}=K);else{const f=e.notchDir,s=f&&f.y>.1?13:0,a=f&&f.y<-.1?13:0,c=f&&f.x<-.1?13:0,h=f&&f.x>.1?13:0,d=Ke-c-h,i=xe-s-a;A=Math.min(d/Me,i/Te),tt=r+Nt+ne+c+(d-Me*A)/2-ye*A,et=r+Qt+s+(i-Te*A)/2+be*A}const Yt=K?.snapDist??Math.max(le,ie,1)*1.5,Gt=tt+e.waferCenter.x*A,Je=et-e.waferCenter.y*A,ae=e.waferRadius*A,st=o=>{const f=Math.abs(o-Je);return f>=ae?0:Math.sqrt(ae*ae-f*f)},lt=(o,f,s,a,c,h,d=uo(),i=M.text)=>{if(!o)return;t.save(),t.fillStyle=i,t.font=d,t.textAlign=a,t.textBaseline=c;const b=a==="right"?f-h:h-f;let l=o;if(b>8&&t.measureText(l).width>b){for(;l.length>1&&t.measureText(l+"\u2026").width>b;)l=l.slice(0,-1);l=l+"\u2026"}b>8&&t.fillText(l,f,s),t.restore()};t.save(),t.setTransform(A*y,0,0,-A*y,tt*y,et*y);const dt=1/A,Ze=1/(A*y);if(e.rectangles.length>0){const o=new Map;for(const s of e.rectangles){const a=String(s.fill);let c=o.get(a);c||(c=[],o.set(a,c)),c.push(s)}for(const[s,a]of o){t.beginPath();for(const c of a)t.rect(c.x-c.width/2,c.y-c.height/2,c.width,c.height);t.fillStyle=s,t.fill()}t.strokeStyle="rgba(0,0,0,0.18)",t.lineWidth=.5*Ze,t.beginPath();for(const s of e.rectangles)t.rect(s.x-s.width/2,s.y-s.height/2,s.width,s.height);if(t.stroke(),X){const s=e.rectangles.filter(a=>a.binFail);if(s.length>0){const a=new Map;for(const c of s){const h=Ie(String(c.fill));let d=a.get(h);d||(d=[],a.set(h,d)),d.push(c)}t.save(),t.lineCap="butt";for(const[c,h]of a){t.strokeStyle=c,t.globalAlpha=.55,t.lineWidth=Math.max(.6*dt,Math.min(h[0].width,h[0].height)*.1);for(const d of h){const i=d.width/2,b=d.height/2,l=Math.max(1.6*dt,Math.min(d.width,d.height)/3);t.save(),t.beginPath(),t.rect(d.x-i,d.y-b,d.width,d.height),t.clip(),t.beginPath();for(let T=-(i+b);T<=i+b;T+=l)t.moveTo(d.x-i+T,d.y-b),t.lineTo(d.x-i+T+d.height,d.y+b);t.stroke(),t.restore()}}t.restore()}}const f=e.rectangles.filter(s=>s.specMark);if(f.length>0){const s=new Map;for(const c of f){const h=Ie(String(c.fill)),d=`${c.specMark}|${h}`;let i=s.get(d);i||(i=[],s.set(d,i)),i.push(c)}const a=2.5*dt;t.lineJoin="round";for(const[c,h]of s){const[d,i]=c.split("|"),b=i==="#000000"?"#ffffff":"#000000",l=d==="failHigh"?1:-1,T=Math.min(h[0].width,h[0].height),O=Math.max(2.5*dt,T*.3);t.beginPath();for(const R of h)Ne(t,R.x,R.y,O,l);t.strokeStyle=b,t.lineWidth=a,t.stroke(),t.fillStyle=i,t.fill()}}}for(const o of e.overlays){t.beginPath();for(const f of o.points){for(let s=0;s<f.length;s++)s===0?t.moveTo(f[s].x,f[s].y):t.lineTo(f[s].x,f[s].y);o.closed&&t.closePath()}o.fill&&!o.fill.startsWith("rgba(0,0,0,0)")&&(t.fillStyle=o.fill,t.fill()),o.kind==="ring-boundary"||o.kind==="quadrant-boundary"||o.kind==="reticle"?(t.strokeStyle="rgba(0,0,0,0.45)",t.lineWidth=3*dt,t.stroke(),t.strokeStyle="rgba(255,255,255,0.8)",t.lineWidth=1*dt,t.stroke()):(t.strokeStyle=o.lineColor,t.lineWidth=o.lineWidth*dt,t.stroke())}if(t.restore(),e.notchDir){const o=tt+e.waferCenter.x*A,f=et-e.waferCenter.y*A,s=e.notchDir.x,a=-e.notchDir.y,c=e.waferRadius*A,h=4,d=9,i=5,b=o+s*(c+h),l=f+a*(c+h),T=b+s*d,O=l+a*d,R={x:-a,y:s},I=r+Nt+ne,E=W-r-oe,V=r+Qt,at=Y-r-ue-se;t.save(),t.beginPath(),t.rect(I,V,E-I,at-V),t.clip(),t.beginPath(),t.moveTo(b,l),t.lineTo(T+R.x*i,O+R.y*i),t.lineTo(T-R.x*i,O-R.y*i),t.closePath(),t.fillStyle=M.text,t.fill(),t.restore()}t.save(),t.textAlign="center",t.textBaseline="middle";let Se=0;if(e.rectangles.length>0){let o=1;for(const h of e.texts)h.role!=="indicator"&&h.text.length>o&&(o=h.text.length);const f=e.rectangles[0].width*A,s=e.rectangles[0].height*A,a=Math.min(f,s),c=f/o;Se=Math.max(8,Math.min(64,Math.round(Math.min(a*.55,c*1.8))))}for(const o of e.texts){const f=tt+o.x*A,s=et-o.y*A;t.font=`${o.role==="indicator"?o.fontSize:Se}px system-ui, sans-serif`,t.fillStyle=o.color,t.fillText(o.text,f,s)}if(t.restore(),pt&&yo(t,W,Y,tt,et,A,r,se,Nt,w,e.gridToScreen,e.rotation,M),St){const o=so(e.valueColorScheme,e.reverseValueScheme),f=pe,s=xe,a=Math.round(s*.75),c=r+Math.round((s-a)/2),h=W-r-B-f,d=Ot,i=It,b=i-d,l=e.plotMode==="stackedSoftBins"?xt:nt,{primary:T,secondary:O}=U?Be(e,Tt,l):{primary:"",secondary:""};if(U){const n=Math.max(c-6,r+11),m=Gt+Math.max(st(n),st(n-12))+8;lt(T,W-r,n,"right","bottom",m)}let R=c+a+4;const I=n=>Gt+Math.max(st(n),st(n+12))+8,E=e.logScale&&d>0?Math.log10(d):0,V=e.logScale&&i>0?Math.log10(i)-E:1,at=n=>e.logScale?(1-(Math.log10(n)-E)/V)*a:(1-(n-d)/b)*a;for(let n=0;n<zt;n++){const m=1-n/(zt-1),S=c+n/zt*a,p=a/zt+1;t.fillStyle=o(m),t.fillRect(h,S,B,p)}t.strokeStyle="rgba(0,0,0,0.25)",t.lineWidth=.5,t.strokeRect(h,c,B,a),t.fillStyle=M.text,t.font=J(),t.textAlign="left",t.strokeStyle="rgba(0,0,0,0.35)",t.lineWidth=.5;const L=Ee,F=36,ot=14,wt=e.logScale&&V>0?bo(d,i,a,F,ot,E,V):e.allIntegerValues?(()=>{const n=Math.max(1,Zt(b*F/a)),m=[],S=Math.ceil(d/n)*n;for(let p=S;p<=i+n*1e-6;p+=n){const u=(1-(p-d)/b)*a;u>ot&&u<a-ot&&m.push(Math.round(p))}return m})():(()=>{const n=b>0?Zt(b*F/a):0,m=[];if(n>0){const S=Math.ceil(d/n)*n;for(let p=S;p<=i+n*1e-6;p+=n){const u=(1-(p-d)/b)*a;u>ot&&u<a-ot&&m.push(p)}}return m})(),C=te,_=vt,x=Ft;t.textBaseline="middle";for(const n of wt){const m=c+at(n);t.beginPath(),t.moveTo(h+B,m),t.lineTo(h+B+L,m),t.stroke(),t.fillText(x(n),h+B+L+Kt,m)}if(t.beginPath(),t.moveTo(h+B,c),t.lineTo(h+B+L,c),t.stroke(),t.textBaseline="top",t.fillText(x(i),h+B+L+Kt,c),t.beginPath(),t.moveTo(h+B,c+a),t.lineTo(h+B+L,c+a),t.stroke(),t.textBaseline="bottom",t.fillText(x(d),h+B+L+Kt,c+a),!_&&C&&(C.limitLow!==void 0||C.limitHigh!==void 0)){const n=[],m=e.colorbarRangeMode==="spec";for(const[S,p]of[[C.limitLow,"LSL"],[C.limitHigh,"USL"]]){if(S===void 0||e.logScale&&S<=0)continue;const u=at(S);!m&&(u<-ot||u>a+ot)||n.push({value:S,label:p,py:Math.max(0,Math.min(a,u))})}if(n.length>0){t.save(),t.font=J(),t.textAlign="right",t.textBaseline="middle";for(const{py:S,label:p}of n){const u=c+S;m||(t.strokeStyle="rgba(255,255,255,0.85)",t.lineWidth=3,t.beginPath(),t.moveTo(h,u),t.lineTo(h+B,u),t.stroke(),t.strokeStyle="rgba(0,0,0,0.7)",t.lineWidth=1,t.beginPath(),t.moveTo(h,u),t.lineTo(h+B,u),t.stroke()),t.fillStyle=M.text,t.fillText(p,h-3,u);const ct=p==="USL"?-1:1,rt=4,Mt=h-3-t.measureText(p).width-rt-4;t.beginPath(),Ne(t,Mt,u,rt,ct),t.strokeStyle="#fff",t.lineWidth=2,t.lineJoin="round",t.stroke(),t.fillStyle=M.text,t.fill()}t.restore()}}if(!_){const n=e.logScale?"log\u2081\u2080":e.logScaleRequested?"linear \u2014 log n/a":null;n&&(t.save(),t.fillStyle=M.text,t.font=po(),t.textAlign="right",t.textBaseline="top",t.fillText(n,W-r,R),t.restore(),R+=15)}U&&O&<(O,W-r,R,"right","top",I(R),qt(),M.text)}const ce=[];let z;if(Q){const o=k==="compact",f=e.plotMode==="softBin"?xt:nt,s=f?new Map(f.map(l=>[l.bin,l])):null,a=e.plotMode==="softBin"?e.binColors.soft:e.binColors.hard,c=l=>a.get(l)??lo,h=(l,T)=>{const O=t.measureText(l).width,R=o?0:t.measureText(String(T)).width,I=H+gt+O+(R?Jt:0);return{labelWidth:O,countWidth:R,totalWidth:I}},d=yt?.find(l=>l.key===e.activeMetadataKey),i=j?v.map(l=>{const T=o?l.compactLabel:l.label;return{key:l.key,color:l.color,count:l.count,label:T,tooltipLabel:l.tooltip,...h(T,l.count)}}):e.plotMode==="metadata"?Pt.map(([l,T])=>{const R=d?.values?.find(V=>V.value===l)?.label??l,I=o?l:R,E=e.metadataColorMap?.get(l)??"#d6d9dd";return{key:l,color:E,count:T,label:I,tooltipLabel:`${R} \xB7 ${T} dies`,...h(I,T)}}):Bt.map(([l,T])=>{const O=s?.get(l),R=O?.name?`${l} \xB7 ${O.name}`:`Bin ${l}`,I=o?String(l):R;return{key:l,color:c(l),count:T,label:I,tooltipLabel:`${R} \xB7 ${T} dies`,...h(I,T)}}),b=W-r*2;if(i.length>0){const l=At?ft*2+(U?Ye:0):U&&!kt?Ge+Xe:0,T=Math.max(1,Math.floor((Y-2*r-l)/D));let O=i.length,R=1,I=O*D,E=[],V=0;const at=jt||kt;if(at){const C=Ut(i.map(x=>x.totalWidth)),_=Math.max(1,Math.min(i.length,Math.floor((b+8)/(C+8))));for(let x=_;x>=1;x--){const n=Math.ceil(i.length/x);if(n>T)continue;const m=new Array(x).fill(0);for(let p=0;p<i.length;p++){const u=p%x;m[u]=Math.max(m[u],i[p].totalWidth)}if(m.reduce((p,u)=>p+u,0)+(x-1)*8<=b||x===1){R=x,E=m,O=n,I=n*D;break}}}else O=Math.min(i.length,T),I=O*D,i.length>T&&(V=i.length-(T-1)),E=[Wt];let L,F;if(At){const C=Ut(i.map(u=>H+gt+t.measureText(u.label).width+Jt)),_=Math.ceil(C);E=[_];const x=U?Ye:0,n=_+ft*2,m=I+x+ft*2,S=ut?.x??0,p=ut?.y??0;L=Math.min(Math.max(W-r-n+S,r),W-r-n),F=Math.min(Math.max(Y-r-m+p,r),Y-r-m),z={x:L,y:F,w:n,h:m},t.save(),t.globalAlpha=.92,t.fillStyle=M.surface,t.fillRect(L,F,n,m),t.globalAlpha=1,t.strokeStyle=M.axisLine,t.lineWidth=1,t.strokeRect(L,F,n,m),t.restore(),L+=ft,F+=ft+x}else jt?(L=r,F=Y-r-I):kt?(L=r,F=r):de?(L=r+4,F=Math.max(r+Math.round((Y-2*r-I)/2),r+l)):(L=W-r-Wt+4,F=Math.max(r+Math.round((Y-2*r-I)/2),r+l));if(U){const C=e.plotMode==="softBin"?xt:nt,{primary:_,secondary:x}=Be(e,Tt,C),n=Xe,m=u=>Gt-Math.max(st(u),st(u-12))-8,S=u=>ht?W-r:m(u),p=At?z.y+z.h:F+I;if(kt){const u=p+n;lt(_,L,u,"left","top",Gt-Math.max(st(u),st(u+12))-8),x&<(x,L,u+16,"left","top",m(u+16),qt(),M.text)}else if(At)lt(_,z.x+ft,z.y+ft,"left","top",z.x+z.w-ft),x&<(x,z.x,p+n,"left","top",z.x+z.w,qt(),M.text);else{const u=Math.max(F-n,r+Ge);if(lt(_,L,u,"left","bottom",S(u)),x){const ct=p+n;lt(x,L,ct,"left","top",S(ct),qt(),M.text)}}}t.save(),t.font=J();const ot=at?8:0,wt=(C,_)=>{if(t.measureText(C).width<=_)return C;let x=0,n=C.length;const m="\u2026",S=t.measureText(m).width;for(;x<n;){const p=x+n+1>>1;t.measureText(C.slice(0,p)).width+S<=_?x=p:n=p-1}return x===0?m:C.slice(0,x)+m};if(at){let C=0;for(let _=0;_<O;_++){let x=L;for(let n=0;n<R;n++){const m=i[C++];if(!m)break;const S=m.key===N,p=!S&&m.key===q,u=x,ct=x+H+gt,rt=F+_*D+D/2,Mt=F+_*D+Math.round((D-H)/2),Vt=E[n]-H-gt-Jt;p&&(t.fillStyle=M.hoverRow,t.fillRect(x,F+_*D,E[n],D)),t.fillStyle=m.color,t.fillRect(u,Mt,H,H),t.strokeStyle=S?M.accent:"rgba(0,0,0,0.25)",t.lineWidth=S?2:.75,t.strokeRect(u,Mt,H,H),t.fillStyle=S?M.accent:M.text,t.font=S?`bold ${J()}`:J(),t.textAlign="left",t.textBaseline="middle",t.fillText(wt(m.label,Vt),ct,rt),t.fillStyle=M.textMuted,t.font=J(),t.textAlign="right",t.fillText(String(m.count),x+E[n]-2,rt),ce.push({bin:m.key,x,y:F+_*D,w:E[n],h:D,label:m.tooltipLabel}),x+=E[n]+ot}}}else{const C=E[0],_=k!=="compact",x=C-H-gt-(_?Jt:0),n=L+C-2;let m=i;V>0&&(m=i.slice(0,T-1));let S=F;for(const p of m){const u=p.key===N,ct=!u&&p.key===q,rt=L,Mt=L+H+gt,Vt=S+D/2,Ce=S+Math.round((D-H)/2),to=p.label;ct&&(t.fillStyle=M.hoverRow,t.fillRect(L-3,S,C+3,D)),t.fillStyle=p.color,t.fillRect(rt,Ce,H,H),t.strokeStyle=u?M.accent:"rgba(0,0,0,0.25)",t.lineWidth=u?2:.75,t.strokeRect(rt,Ce,H,H),t.fillStyle=u?M.accent:M.text,t.font=u?`bold ${J()}`:J(),t.textAlign="left",t.textBaseline="middle",t.fillText(wt(to,x),Mt,Vt),(_||At)&&(t.fillStyle=M.textMuted,t.font=J(),t.textAlign="right",t.fillText(String(p.count),n,Vt)),ce.push({bin:p.key,x:L,y:S,w:C,h:D,label:p.tooltipLabel}),S+=D}V>0&&(t.fillStyle=M.textMuted,t.font=J(),t.textAlign="left",t.textBaseline="middle",t.fillText(`+ ${V} more`,L+H+gt,S+D/2))}}i.length>0&&t.restore()}const je={originX:tt,originY:et,ppm:A,snapDist:Yt},Le=e.rectangles[0]?.width??1,ke=e.rectangles[0]?.height??1,it=e.dieBounds,Xt=it?it.minX:$.length?De($.map(o=>o.x)):0,$t=it?it.minY:$.length?De($.map(o=>o.y)):0,Qe=it?it.maxX:$.length?Ut($.map(o=>o.x)):1,ve=it?it.maxY:$.length?Ut($.map(o=>o.y)):1,{cellW:re,cellH:fe,nCols:Rt,nRows:he}=ro(Qe-Xt,ve-$t,Le*1.5,ke*1.5,$.length),Ae=Array.from({length:Rt*he},()=>[]);for(let o=0;o<$.length;o++){const f=Math.floor(($[o].x-Xt)/re),s=Math.floor(($[o].y-$t)/fe),a=Number.isFinite(f)?Math.max(0,Math.min(Rt-1,f)):0,c=Number.isFinite(s)?Math.max(0,Math.min(he-1,s)):0;Ae[c*Rt+a].push(o)}function Re(o,f,s){const a=Math.max(0,Math.floor((o-s-Xt)/re)),c=Math.min(Rt-1,Math.floor((o+s-Xt)/re)),h=Math.max(0,Math.floor((f-s-$t)/fe)),d=Math.min(he-1,Math.floor((f+s-$t)/fe)),i=[];for(let b=h;b<=d;b++)for(let l=a;l<=c;l++)for(const T of Ae[b*Rt+l])i.push(T);return i}return{hitTarget:{getDieAtPoint(o,f){const s=(o-tt)/A,a=(et-f)/A,c=Math.max(Le,ke);for(const i of Re(s,a,c)){const b=e.rectangles[i];if(b&&Math.abs(s-b.x)<=b.width/2&&Math.abs(a-b.y)<=b.height/2)return e.dies[i]??null}let h=null,d=Yt*Yt;for(const i of Re(s,a,Yt)){const b=$[i].x-s,l=$[i].y-a,T=b*b+l*l;T<d&&(d=T,h=e.dies[i]??null)}return h}},viewport:je,binLegendRows:ce,legendBox:z}}function yo(g,e,P,M,r,G,X,B,mt,Z,ut,pt,w){g.save(),g.font=xo(),g.fillStyle=w.text,g.strokeStyle=w.axisLine,g.lineWidth=.5;const K=P-B+4,N=X+mt-4,q=oo(ut),Tt=Pe(q,1,0),_t=Pe(q,0,1),nt=1e-9;function xt(y){return Z?Math.abs(y.y)<nt&&Math.abs(y.x)>nt?{pitch:Z.x,sign:Math.sign(y.x)}:Math.abs(y.x)<nt&&Math.abs(y.y)>nt?{pitch:Z.y,sign:Math.sign(y.y)}:null:null}const yt=xt(Tt),U=xt(_t);function W(y){return yt?Math.round(y*yt.sign/yt.pitch):y}function Y(y){return U?Math.round(y*U.sign/U.pitch):y}function bt(y){if(!y)return Zt(50/G);const k=50/(y*G);return Math.max(1,Math.round(k))*y}const St=yt?.pitch,Lt=U?.pitch,j=bt(St),Q=bt(Lt);g.textAlign="center",g.textBaseline="top";const Bt=Math.ceil((X-M)/G/j)*j,Pt=(e-X-M)/G;for(let y=Bt;y<=Pt;y+=j){const k=M+y*G;if(k<X||k>e-X)continue;g.beginPath(),g.moveTo(k,K-He),g.lineTo(k,K),g.stroke();const ht=Z?String(W(y)):Fe(y);g.fillText(ht,k,K+2)}g.textAlign="right",g.textBaseline="middle";const v=Math.ceil((r-(P-X))/G/Q)*Q,Dt=(r-X)/G;for(let y=v;y<=Dt;y+=Q){const k=r-y*G;if(k<X||k>P-X)continue;g.beginPath(),g.moveTo(N,k),g.lineTo(N+He,k),g.stroke();const ht=Z?String(Y(y)):Fe(y);g.fillText(ht,N-2,k)}g.restore()}function Zt(g){const e=Math.pow(10,Math.floor(Math.log10(g))),P=g/e;return(P<1.5?1:P<3.5?2:P<7.5?5:10)*e}function bo(g,e,P,M,r,G,X){const B=[],mt=X;if(mt<1){const w=Zt((e-g)*M/P);if(w>0){const K=Math.ceil(g/w)*w;for(let N=K;N<=e+w*1e-6;N+=w){if(N<=g||N>=e)continue;const q=(1-(Math.log10(N)-G)/X)*P;q>r&&q<P-r&&B.push(N)}}return B}const Z=mt<3?[1,2,5]:[1],ut=Math.floor(Math.log10(g)),pt=Math.ceil(Math.log10(e));for(let w=ut;w<=pt;w++)for(const K of Z){const N=K*Math.pow(10,w);if(N<=g||N>=e)continue;const q=(1-(Math.log10(N)-G)/X)*P;q>r&&q<P-r&&B.push(N)}return B}export{fmt,fmtColorbarAxis}from"../renderer/fmt.js";
|
|
@@ -320,6 +320,12 @@ export type SaveImageHandler = (blob: Blob, suggestedName: string) => void | Pro
|
|
|
320
320
|
* @param onSaveImage optional host hook; when present, bypasses `<a download>`
|
|
321
321
|
*/
|
|
322
322
|
export declare function saveImageBlob(blob: Blob, filename: string, onSaveImage?: SaveImageHandler): void;
|
|
323
|
+
/**
|
|
324
|
+
* The browser's default save: a `<a download>` click. The one copy, used when
|
|
325
|
+
* no host hook is supplied — by `saveImageBlob`, `saveTextFile`, and the
|
|
326
|
+
* export-naming wrappers in exportName.ts, which must fall back to it too.
|
|
327
|
+
*/
|
|
328
|
+
export declare function downloadBlob(blob: Blob, filename: string): void;
|
|
323
329
|
/**
|
|
324
330
|
* Host hook for saving a text file (CSV, etc). Mirrors `SaveImageHandler` —
|
|
325
331
|
* when provided, `saveTextFile` calls this instead of triggering a browser
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{getUniqueTestNumbers as ve}from"../renderer/buildView.js";import{dieHasTestData as ge}from"../renderer/buildWaferMap.js";import{prettyKey as ye}from"../core/utils.js";import{listBinColorSchemes as we,listValueColorSchemes as ke}from"../renderer/colorSchemes.js";import{ICONS as $}from"./icons.js";import{WMAP_VERSION as Ee,WMAP_BUILD_TIME as Le}from"./version.js";import{openHtmlReport as Ce}from"../stats/renderFindingsReport.js";import{buildWaferMap as Ae}from"../renderer/buildWaferMap.js";import{analyzeWaferMap as Me}from"../stats/analyzeWaferMap.js";let le=!1;export function logWmapVersionOnce(){le||(le=!0,console.log(`[wmap] v${Ee} (built ${Le})`))}export const WMAP_TOKEN_NAMES=["z","icon","icon-hover","icon-active","bg-hover","bg-active","separator","surface","border","control-border","menu-hover","menu-active","font-family","font-size","density","panel-bg","text-muted","text","text-strong","warn-bg","warn-border","warn-text","err-bg","err-border","err-text","info-bg","info-text","selected","finding-indicator","canvas-bg","bar-fill"];const k=(e,n)=>`var(--wmap-${e}, ${n})`,X="var(--wmap-font-size, 12px)",Se="var(--wmap-density, 1)",N=e=>`calc(${e}px * ${Se})`;export function wireControlHover(e,n="outlined"){let t=null;const o=()=>{t&&(e.style.background=t.background,e.style.color=t.color)};e.addEventListener("mouseenter",()=>{e.dataset.on==="true"||e.disabled||(t||(t={background:e.style.background,color:e.style.color}),e.style.background=CLR.bgHover,e.style.color=CLR.iconHover)}),e.addEventListener("mouseleave",o),e.addEventListener("blur",o)}export function controlStyle(e,n=!1){const t={fontSize:FONT.body,cursor:"pointer",borderRadius:RADIUS.control};return e==="bare"?{...t,border:"none",background:"none",padding:"0",color:CLR.icon}:{...t,border:`1px solid ${CLR.controlBorder}`,background:e==="toggle"&&n?CLR.menuActive:"none",color:e==="toggle"&&n?CLR.iconActive:CLR.text,padding:`${SPACE.xxs} ${SPACE.lg}`}}export const SPACE={xxs:N(2),xs:N(4),sm:N(6),md:N(8),lg:N(10),xl:N(12),xxl:N(16),xxxl:N(24)},SHADOW={panel:"0 1px 4px rgba(0,0,0,0.10)",menu:"0 4px 12px rgba(0,0,0,0.15)",modal:"0 20px 60px rgba(0,0,0,0.40)"},MOTION={fast:"0.12s ease",base:"0.2s ease"},LEADING={none:"1",tight:"1.2",base:"1.45"},ALPHA={muted:"0.85",disabled:"0.4"},TRACKING="0.05em",EDGE_GUTTER=SPACE.xl,MAP_CHROME_INSET=SPACE.xs,RADIUS={control:"4px",container:"6px",pill:"999px"},FONT={family:"var(--wmap-font-family, inherit)",meta:`calc(${X} - 1px)`,body:X,sub:`calc(${X} + 1px)`,heading:`calc(${X} + 3px)`,stat:`calc(${X} + 8px)`};export function fontPx(e=0,n){const t=n?.ownerDocument??(typeof document<"u"?document:null);if(!t)return 12+e;const o=getComputedStyle(n??t.documentElement).getPropertyValue("--wmap-font-size").trim(),i=o?parseFloat(o):NaN;return(Number.isFinite(i)?i:12)+e}export const CLR={icon:k("icon","#506784"),iconHover:k("icon-hover","#2a3f5f"),iconActive:k("icon-active","#1a65ca"),bgHover:k("bg-hover","#edf0f8"),bgActive:k("bg-active","#dce8f8"),separator:k("separator","rgba(0,0,0,0.12)"),menuBg:k("surface","#fff"),menuBorder:k("border","rgba(0,0,0,0.12)"),controlBorder:k("control-border","rgba(0,0,0,0.30)"),menuHover:k("menu-hover","#f0f4fc"),menuActive:k("menu-active","#dce8f8"),canvasBg:`var(--wmap-canvas-bg, ${k("surface","#f5f5f5")})`,panelBg:k("panel-bg","#fafbfc"),label:k("text-muted","#647687"),value:k("text-strong","#1f2f43"),text:k("text","#333"),warnBg:k("warn-bg","#fffbe6"),warnBorder:k("warn-border","#f0c040"),warnText:k("warn-text","#7a5800"),errBg:k("err-bg","#fef2f2"),errBorder:k("err-border","#dc8a8a"),errText:k("err-text","#7a1c1c"),infoBg:k("info-bg","#dce8f8"),infoText:k("info-text","#334155"),findingHighlight:k("selected","#e07a20"),findingIndicator:k("finding-indicator","#b7551a"),barFill:k("bar-fill","#2a6fc0")};export function sevColor(e){return e==="unusual"?"#a84112":e==="notable"?"#8a6500":CLR.icon}export const ROTATIONS=[0,90,180,270],INLINE_TEST_LIMIT=6,MENU_SEARCH_THRESHOLD=8,DEFAULT_OVERLAY_Z=6e3,Z_BASE=`var(--wmap-z, ${DEFAULT_OVERLAY_Z})`,Z_ABOVE=`calc(var(--wmap-z, ${DEFAULT_OVERLAY_Z}) + 1)`,Z_MENU=`calc(var(--wmap-z, ${DEFAULT_OVERLAY_Z}) + 2)`,Z_ABOVE2=`calc(var(--wmap-z, ${DEFAULT_OVERLAY_Z}) + 3)`;export function applyOverlayZ(e){if(e==null)return()=>{};const n=document.documentElement,t=n.style.getPropertyValue("--wmap-z");return n.style.setProperty("--wmap-z",String(e)),()=>{t?n.style.setProperty("--wmap-z",t):n.style.removeProperty("--wmap-z")}}export function copyWmapThemeTokens(e,n){const t=getComputedStyle(e);for(const o of WMAP_TOKEN_NAMES){const i=t.getPropertyValue(`--wmap-${o}`).trim();i&&n.style.setProperty(`--wmap-${o}`,i)}}export function syncWmapPopupTheme(e,n,t){const o=()=>{copyWmapThemeTokens(e,n),t?.()},i=new window.MutationObserver(o);i.observe(e,{attributes:!0,attributeFilter:["style","class"]}),i.observe(document.documentElement,{attributes:!0,attributeFilter:["style","class"]});const a=window.matchMedia("(prefers-color-scheme: dark)");return a.addEventListener("change",o),()=>{i.disconnect(),a.removeEventListener("change",o)}}let oe=null;export function setDetachWindowOpener(e){oe=e}export function openDetachWindow(e){return oe?oe(e):window.open("","_blank","width=560,height=600")}export const MODE_LABELS={value:"Test Value",hardBin:"Hard Bin",softBin:"Soft Bin",stackedValues:"Stacked Test Values",stackedBins:"Stacked Hard Bins",stackedSoftBins:"Stacked Soft Bins",metadata:"Metadata"},BIN_LEGEND_MODES=new Set(["hardBin","softBin","metadata"]),STACKED_MODES=new Set(["stackedValues","stackedBins","stackedSoftBins"]);export function saveImageBlob(e,n,t){const o=`${n}.png`;if(t){t(e,o);return}const i=URL.createObjectURL(e),a=document.createElement("a");a.href=i,a.download=o,a.click(),URL.revokeObjectURL(i)}export function saveTextFile(e,n,t,o){if(o){o(e,n,t);return}const i=new Blob([e],{type:t}),a=URL.createObjectURL(i),d=document.createElement("a");d.href=a,d.download=n,d.click(),URL.revokeObjectURL(a)}const Be='[role="menuitem"],[role="menuitemradio"],[role="menuitemcheckbox"]';export function nextFrame(e,n=window){const t=n.requestAnimationFrame;typeof t=="function"?t.call(n,e):setTimeout(e,0)}export function wireListNavigation(e,n,t){e.addEventListener("keydown",o=>{const i=n();if(i.length===0)return;const a=e.ownerDocument.activeElement,d=a?i.indexOf(a):-1;switch(o.key){case"ArrowDown":o.preventDefault(),i[d<0||d===i.length-1?0:d+1].focus();break;case"ArrowUp":o.preventDefault(),i[d<=0?i.length-1:d-1].focus();break;case"Home":o.preventDefault(),i[0].focus();break;case"End":o.preventDefault(),i[i.length-1].focus();break;case"Enter":case" ":d>=0&&(o.preventDefault(),i[d].click());break;case"Escape":case"Tab":o.preventDefault(),t();break}})}function Z(e,n,t){const o=()=>Array.from(e.querySelectorAll(Be));wireListNavigation(e,o,()=>{t(),n?.focus()});const i=o()[0];i&&nextFrame(()=>i.focus())}export function overlayRootFor(e){let n=e;for(;n;){if(n.classList.contains("wmap-overlay-box")||n.tagName==="DIALOG"&&n.matches(":modal"))return n;n=n.parentElement}return e.ownerDocument.body}const ce=new WeakMap;export function menuLayerFor(e){const n=overlayRootFor(e),t=ce.get(n);if(t&&t.isConnected)return t;const i=e.ownerDocument.createElement("div");return i.dataset.wmapMenuLayer="1",Object.assign(i.style,{position:"fixed",inset:"0",zIndex:Z_MENU,pointerEvents:"none"}),n.appendChild(i),ce.set(n,i),i}const ie=new WeakMap;export function getTooltip(e=document){const n=ie.get(e);if(n&&n.isConnected)return n;const t=n??e.createElement("div");return n||(Object.assign(t.style,{position:"fixed",pointerEvents:"none",background:"rgba(30, 32, 40, 0.93)",color:"#f0f0f2",border:"1px solid rgba(255,255,255,0.10)",padding:"7px 11px",borderRadius:RADIUS.control,fontSize:FONT.sub,lineHeight:LEADING.base,maxWidth:"280px",maxHeight:"min(60vh, 480px)",overflow:"hidden",whiteSpace:"pre-wrap",zIndex:Z_ABOVE,display:"none",fontFamily:FONT.family,boxShadow:SHADOW.menu}),ie.set(e,t)),e.body.appendChild(t),t}export function hideTooltip(e=document){const n=ie.get(e);n&&(n.style.display="none")}export function reparentTooltip(e){const n=e?.ownerDocument??document,t=getTooltip(n);(e??n.body).appendChild(t)}export function positionTooltip(e,n,t,o){const i=overlayRootFor(n);e.parentElement!==i&&i.appendChild(e);const a=e.ownerDocument.defaultView??window;e.style.left="0",e.style.top="0";const d=e.offsetWidth,r=e.offsetHeight,f=8,p=a.innerWidth,s=a.innerHeight;let g=t+14,l=o-8;g+d+f>p&&(g=t-d-6);const m=n.getBoundingClientRect();if(m.height>0&&m.height<=s*.4&&l<m.bottom&&l+r>m.top&&g<m.right&&g+d>m.left){const c=m.bottom+f,b=m.top-r-f;c+r+f<=s?l=c:b>=f&&(l=b)}l+r+f>s&&(l=s-r-f),l<f&&(l=f),e.style.left=`${g}px`,e.style.top=`${l}px`}export function wireTooltip(e,n,t={}){const o=()=>(typeof n=="function"?n():n)??e.getAttribute("aria-label")??"";t.asDataPoint&&(e.tabIndex=0,e.setAttribute("role","img"),typeof n=="string"&&e.setAttribute("aria-label",n));const i=d=>{const r=o();if(!r)return;const f=getTooltip(e.ownerDocument);if(f.textContent=r,f.style.display="block",d)positionTooltip(f,e,d.clientX,d.clientY);else{const p=e.getBoundingClientRect();positionTooltip(f,e,p.left+p.width/2,p.top)}},a=()=>hideTooltip(e.ownerDocument);e.addEventListener("mousemove",i),e.addEventListener("mouseleave",a),e.addEventListener("focus",()=>i()),e.addEventListener("blur",a)}export function buildDataModeEntries(e,n,t){const o=e.some(ge),i=e.some(s=>s.testValues!==void 0&&Object.keys(s.testValues).length>0),a=e.some(s=>s.hbin!=null),d=e.some(s=>s.sbin!=null),r=o?n!==void 0?n.map(s=>({plotMode:"value",activeTest:s.testNumber,label:s.unit?`${s.name} (${s.unit})`:s.name,logScale:s.logScale})):ve(e).map(s=>({plotMode:"value",activeTest:s,label:`Test ${s}`})):[],f=[...a?[{plotMode:"hardBin",label:MODE_LABELS.hardBin}]:[],...d?[{plotMode:"softBin",label:MODE_LABELS.softBin}]:[]],p=t.includeStacked?[...i?[{plotMode:"stackedValues",label:MODE_LABELS.stackedValues}]:[],...a?[{plotMode:"stackedBins",label:MODE_LABELS.stackedBins}]:[],...d?[{plotMode:"stackedSoftBins",label:MODE_LABELS.stackedSoftBins}]:[]]:[];return{testEntries:r,binEntries:f,stackedEntries:p}}export function metadataKeyHasData(e,n){return e.some(t=>t.metadata?.[n]!==void 0&&t.metadata?.[n]!==null)}export function metadataModeEntry(e){return{plotMode:"metadata",activeMetadataKey:e.key,label:e.label??ye(e.key)}}export function makeMenuSearchBox(e,n="Filter\u2026",t=document){const o=t.createElement("input");return o.type="text",o.placeholder=n,o.setAttribute("aria-label",n),Object.assign(o.style,{display:"block",width:"calc(100% - 20px)",margin:"2px 10px 6px",padding:`${SPACE.xs} ${SPACE.md}`,fontSize:FONT.body,boxSizing:"border-box",background:CLR.menuBg,color:CLR.text,border:`1px solid ${CLR.menuBorder}`,borderRadius:RADIUS.control,outline:"none"}),o.addEventListener("click",i=>i.stopPropagation()),o.addEventListener("mousedown",i=>i.stopPropagation()),o.addEventListener("keydown",i=>i.stopPropagation()),o.addEventListener("input",()=>e(o.value.trim().toLowerCase())),o.addEventListener("focus",()=>{o.style.borderColor=CLR.iconActive}),o.addEventListener("blur",()=>{o.style.borderColor=CLR.menuBorder}),queueMicrotask(()=>o.focus()),o}export function buildModeMenuEl(e,n,t,o,i,a,d,r,f=window,p=[]){const{makeMenuRow:s,makeMenuSection:g}=d,l=document.createElement("div"),m=180,u=e.left+m<=(f.innerWidth??1/0)?e.left:Math.max(4,e.right-m);if(Object.assign(l.style,{position:"fixed",top:`${e.bottom+4}px`,left:`${u}px`,background:CLR.menuBg,border:`1px solid ${CLR.menuBorder}`,borderRadius:RADIUS.control,boxShadow:SHADOW.menu,zIndex:Z_BASE,minWidth:`${m}px`,padding:"4px 0",pointerEvents:"auto"}),n.length)if(l.appendChild(g("Test Value")),n.length<=INLINE_TEST_LIMIT)for(const c of n)l.appendChild(s(c.label,i(c),!0,b=>{b.stopPropagation(),a(c,l)}));else{const c=r==="value",b=s(MODE_LABELS.value+" \u25B6",c,!1,()=>{});b.style.display="flex",b.style.justifyContent="space-between",b.style.alignItems="center";let v=null,y=null;const C=()=>{y!==null&&(clearTimeout(y),y=null)},w=()=>{C(),v?.remove(),v=null},M=()=>{C(),y=setTimeout(w,300)},T=()=>{if(v)return;const S=b.getBoundingClientRect(),A=160,E=320,V=S.right+2+A<=(f.innerWidth??1/0)?S.right+2:Math.max(4,S.left-2-A),O=Math.min(S.top-4,Math.max(4,(f.innerHeight??1/0)-E-4));if(v=document.createElement("div"),Object.assign(v.style,{position:"fixed",top:`${O}px`,left:`${V}px`,background:CLR.menuBg,border:`1px solid ${CLR.menuBorder}`,borderRadius:RADIUS.control,boxShadow:SHADOW.menu,zIndex:Z_ABOVE,minWidth:`${A}px`,maxHeight:`${E}px`,overflowY:"auto",padding:"4px 0",pointerEvents:"auto"}),n.length>MENU_SEARCH_THRESHOLD){const B=makeMenuSearchBox(H=>{for(const L of D)L.row.style.display=L.label.includes(H)?"":"none"},"Filter tests\u2026");Object.assign(B.style,{position:"sticky",top:"0",zIndex:"1",background:CLR.menuBg}),v.appendChild(B)}const D=[];for(const B of n){const H=s(B.label,i(B),!1,L=>{L.stopPropagation(),w(),a(B,l)});D.push({row:H,label:B.label.toLowerCase()}),v.appendChild(H)}v.addEventListener("mouseenter",C),v.addEventListener("mouseleave",M),(l.parentElement??f.document.body).appendChild(v),f.document.addEventListener("click",w,{once:!0})};b.addEventListener("mouseenter",()=>{C(),T()}),b.addEventListener("mouseleave",M),l.appendChild(b)}if(t.length){l.appendChild(g("Bins"));for(const c of t)l.appendChild(s(c.label,i(c),!1,b=>{b.stopPropagation(),a(c,l)}))}if(p.length){l.appendChild(g("Metadata"));for(const c of p)l.appendChild(s(c.label,i(c),!1,b=>{b.stopPropagation(),a(c,l)}))}if(o.length){l.appendChild(g("Lot Aggregation"));for(const c of o)l.appendChild(s(c.label,i(c),!1,b=>{b.stopPropagation(),a(c,l)}))}return l.setAttribute("role","menu"),l.setAttribute("aria-label","Plot mode"),l}export function markMenuTrigger(e,n){e.setAttribute("aria-haspopup","menu"),e.setAttribute("aria-expanded",n?"true":"false")}export function wireMenuA11y(e,n,t){Z(e,n,t)}export function wireExpandToggle(e,n){const t=e.ownerDocument;let o=!1;function i(p){o!==p&&(o=p,n(o))}function a(){i(!1)}function d(){i(!o),o&&t.addEventListener("click",a,{once:!0})}const r=p=>{p.stopPropagation(),d()},f=p=>{p.key==="Enter"||p.key===" "?(p.preventDefault(),d()):p.key==="Escape"&&a()};return e.setAttribute("role","button"),e.tabIndex<0&&(e.tabIndex=0),e.addEventListener("click",r),e.addEventListener("keydown",f),{isOpen:()=>o,close:a,destroy(){e.removeEventListener("click",r),e.removeEventListener("keydown",f),t.removeEventListener("click",a)}}}export function buildCheckMenuEl(e,n,t,o=window){const{makeMenuSection:i}=t,a=o.document,d=a.createElement("div"),r=168,p=e.left+r<=(o.innerWidth??1/0)?e.left:Math.max(4,e.right-r);Object.assign(d.style,{position:"fixed",top:`${e.bottom+4}px`,left:`${p}px`,background:CLR.menuBg,border:`1px solid ${CLR.menuBorder}`,borderRadius:RADIUS.control,boxShadow:SHADOW.menu,zIndex:Z_BASE,minWidth:`${r}px`,padding:"4px 0",pointerEvents:"auto"});for(const s of n)if("section"in s)d.appendChild(i(s.section));else{const g=s.enabled!==!1;if(!g&&!s.disabledHint)continue;const l=a.createElement("div");s.action?l.setAttribute("role","menuitem"):(l.setAttribute("role","menuitemcheckbox"),l.setAttribute("aria-checked",s.active?"true":"false")),l.tabIndex=-1,g||(l.setAttribute("aria-disabled","true"),wireTooltip(l,s.disabledHint)),Object.assign(l.style,{display:"flex",alignItems:"center",gap:SPACE.sm,padding:"6px 14px",fontSize:FONT.body,cursor:g?"pointer":"default",color:g?s.active?CLR.iconActive:CLR.text:CLR.label,fontWeight:s.active?"700":"400",background:s.active?CLR.menuActive:"transparent",whiteSpace:"nowrap"});const m=a.createElement("span");Object.assign(m.style,{width:"12px",flexShrink:"0",color:CLR.iconActive,visibility:s.active?"visible":"hidden"}),m.textContent=s.action?"":"\u2713",m.setAttribute("aria-hidden","true");const x=a.createElement("span");x.textContent=s.label,l.appendChild(m),l.appendChild(x),g?(l.addEventListener("mouseenter",()=>{s.active||(l.style.background=CLR.menuHover)}),l.addEventListener("mouseleave",()=>{l.style.background=s.active?CLR.menuActive:"transparent"}),l.addEventListener("focus",()=>{s.active||(l.style.background=CLR.menuHover)}),l.addEventListener("blur",()=>{l.style.background=s.active?CLR.menuActive:"transparent"}),l.addEventListener("click",u=>{u.stopPropagation(),s.onClick(u)})):l.addEventListener("click",u=>{u.stopPropagation()}),d.appendChild(l)}return d}export function createToolbarHelpers(e){const n=e.ownerDocument;let t=null;const o=l=>menuLayerFor(l);function i(l,m,x){const u=n.createElement("button");return u.innerHTML=$[l],u.type="button",u.ariaLabel=m,Object.assign(u.style,{display:"flex",alignItems:"center",justifyContent:"center",width:"28px",height:"28px",padding:"0",border:"none",borderRadius:RADIUS.control,background:"transparent",color:CLR.icon,cursor:"pointer",pointerEvents:"auto",transition:`background ${MOTION.fast}, color ${MOTION.fast}`,flexShrink:"0"}),u.addEventListener("mouseenter",c=>{u.dataset.active||(u.style.background=CLR.bgHover,u.style.color=CLR.iconHover),e.innerHTML=u.ariaLabel??m,e.style.display="block",positionTooltip(e,u,c.clientX,c.clientY)}),u.addEventListener("mousemove",c=>{e.style.display==="block"&&positionTooltip(e,u,c.clientX,c.clientY)}),u.addEventListener("mouseleave",()=>{u.dataset.active||(u.style.background="transparent",u.style.color=CLR.icon),e.style.display="none"}),u.addEventListener("click",()=>{e.style.display="none",x()}),u}function a(l,m){m?(l.dataset.active="1",l.style.background=CLR.bgActive,l.style.color=CLR.iconActive):(delete l.dataset.active,l.style.background="transparent",l.style.color=CLR.icon)}function d(){const l=n.createElement("div");return Object.assign(l.style,{width:"1px",height:"18px",background:CLR.separator,margin:"0 2px",flexShrink:"0"}),l}function r(l,m,x,u){const c=n.createElement("div");return c.textContent=l,c.setAttribute("role","menuitemradio"),c.setAttribute("aria-checked",m?"true":"false"),c.tabIndex=-1,Object.assign(c.style,{padding:`6px 14px 6px ${x?"26px":"14px"}`,fontSize:FONT.body,cursor:"pointer",color:m?CLR.iconActive:CLR.text,fontWeight:m?"700":"400",background:m?CLR.menuActive:"transparent",whiteSpace:"nowrap"}),c.addEventListener("mouseenter",()=>{m||(c.style.background=CLR.menuHover)}),c.addEventListener("mouseleave",()=>{c.style.background=m?CLR.menuActive:"transparent"}),c.addEventListener("focus",()=>{m||(c.style.background=CLR.menuHover)}),c.addEventListener("blur",()=>{c.style.background=m?CLR.menuActive:"transparent"}),c.addEventListener("click",u),c}function f(l){const m=n.createElement("div");return m.textContent=l,m.setAttribute("role","presentation"),Object.assign(m.style,{padding:"5px 14px 2px",fontSize:FONT.body,fontWeight:"600",letterSpacing:TRACKING,color:CLR.label,textTransform:"uppercase",pointerEvents:"none",userSelect:"none"}),m}function p(l,m,x,u,c){const b=()=>{t&&(t.remove(),t=null),v.setAttribute("aria-expanded","false")},v=i(l,m,()=>{if(t){b();return}const y=n.createElement("div"),C=v.getBoundingClientRect(),w=v.ownerDocument.defaultView??window,M=148,S=C.left+M<=(w.innerWidth??1/0)?C.left:Math.max(4,C.right-M);Object.assign(y.style,{position:"fixed",top:`${C.bottom+4}px`,left:`${S}px`,background:CLR.menuBg,border:`1px solid ${CLR.menuBorder}`,borderRadius:RADIUS.control,boxShadow:SHADOW.menu,zIndex:Z_BASE,minWidth:`${M}px`,padding:"4px 0",pointerEvents:"auto"});for(const A of x()){const E=n.createElement("div");E.textContent=A.label,E.dataset.wmapDropdownValue=A.value;const F=A.value===u();E.setAttribute("role","menuitemradio"),E.setAttribute("aria-checked",F?"true":"false"),E.tabIndex=-1,Object.assign(E.style,{padding:"6px 14px",fontSize:FONT.body,cursor:"pointer",color:F?CLR.iconActive:CLR.text,fontWeight:F?"700":"400",background:F?CLR.menuActive:"transparent",whiteSpace:"nowrap"});const V=()=>{A.value!==u()&&(E.style.background=CLR.menuHover)},O=()=>{E.style.background=A.value===u()?CLR.menuActive:"transparent"};E.addEventListener("mouseenter",V),E.addEventListener("mouseleave",O),E.addEventListener("focus",V),E.addEventListener("blur",O),E.addEventListener("click",D=>{D.stopPropagation(),c(A.value),b()}),y.appendChild(E)}y.setAttribute("role","menu"),y.setAttribute("aria-label",m),o(v).appendChild(y),t=y,v.setAttribute("aria-expanded","true"),Z(y,v,b)});return v.setAttribute("aria-haspopup","menu"),v.setAttribute("aria-expanded","false"),v}function s(l,m,x,u){function c(){return buildCheckMenuEl(v.getBoundingClientRect(),x().map(y=>"section"in y?y:{...y,onClick:C=>{y.onClick(C),u(v);const w=t;if(!w)return;const M=c();M.setAttribute("role","menu"),M.setAttribute("aria-label",m),w.replaceWith(M),t=M,Z(M,v,b)}}),{makeMenuSection:f},v.ownerDocument.defaultView??window)}const b=()=>{t&&(t.remove(),t=null),v.setAttribute("aria-expanded","false")},v=i(l,m,()=>{if(t){b();return}const y=c();y.setAttribute("role","menu"),y.setAttribute("aria-label",m),o(v).appendChild(y),t=y,v.setAttribute("aria-expanded","true"),Z(y,v,b)});return v.setAttribute("aria-haspopup","menu"),v.setAttribute("aria-expanded","false"),u(v),v}function g(l){if(t&&!t.contains(l.target)&&(t.remove(),t=null,l.target?.getAttribute?.("aria-haspopup")!=="menu"))for(const x of document.querySelectorAll('[aria-haspopup="menu"][aria-expanded="true"]'))x.setAttribute("aria-expanded","false")}return{makeBtn:i,setActive:a,makeSep:d,makeMenuRow:r,makeMenuSection:f,makeDropdown:p,makeCheckMenuBtn:s,closeOpenMenu:g,getOpenMenu:()=>t,setOpenMenu:l=>{t=l}}}const Te=7e3;let De=0;function de(){return Te+ ++De}const He=32,Ie=6;let Oe=0;function Re(){return Oe++%Ie*He}function $e(e,n){if(n===e.body)return()=>{};let t=n;for(;t.parentElement&&t.parentElement!==e.body;)t=t.parentElement;return t===e.body?()=>{}:(t.classList.add("wmap-overlay-ancestor"),()=>t.classList.remove("wmap-overlay-ancestor"))}function ue(e){const n=e.mode==="modal",t=e.ownerDocument??document,o=t.defaultView??window,i=t.body.style.overflow;n&&(t.body.style.overflow="hidden");let a=null;n&&(a=t.createElement("div"),a.id="wmap-modal-backdrop",Object.assign(a.style,{position:"fixed",inset:"0",background:"rgba(0,0,0,0.6)",display:"flex",alignItems:"center",justifyContent:"center",zIndex:Z_ABOVE,backdropFilter:"blur(3px)"}));const d=t.activeElement,r=t.createElement("div");r.className=n?"wmap-modal-box wmap-overlay-box":"wmap-window-box wmap-overlay-box",r.setAttribute("role","dialog"),n&&r.setAttribute("aria-modal","true"),r.setAttribute("aria-label",e.title??"Expanded wafer map"),r.tabIndex=-1;const f=e.boxSize?.width??"min(90vw, 700px)",p=e.boxSize?.height??"min(90vh, 700px)";if(Object.assign(r.style,{position:"relative",background:CLR.menuBg,borderRadius:RADIUS.container,overflow:"hidden",display:"flex",flexDirection:"column",width:f,height:p,boxShadow:SHADOW.modal,minWidth:"320px",minHeight:"240px",maxWidth:"100vw",maxHeight:"100vh",zIndex:n?Z_ABOVE2:String(de())}),!n){const h=Re();Object.assign(r.style,{position:"fixed",top:`${Math.round(o.innerHeight*.08)+h}px`,left:`${Math.round(o.innerWidth*.08)+h}px`})}const s=t.createElement("div");Object.assign(s.style,{display:"flex",alignItems:"center",gap:SPACE.sm,padding:"10px 14px",borderBottom:`1px solid ${CLR.menuBorder}`,flexShrink:"0"});const g={border:`1px solid ${CLR.menuBorder}`,borderRadius:RADIUS.control,background:CLR.panelBg,cursor:"pointer",color:CLR.label,lineHeight:LEADING.none,padding:"0",display:"flex",alignItems:"center",justifyContent:"center",width:"28px",height:"28px"};if(e.title){const h=t.createElement("span");h.textContent=e.title,h.title=e.title,h.dataset.wmapWindowTitle="1",Object.assign(h.style,{fontWeight:"700",fontSize:"14px",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",minWidth:"0"}),s.appendChild(h)}const l=t.createElement("div");l.style.flex="1",s.appendChild(l);let m=null;n||(m=t.createElement("button"),m.type="button",m.innerHTML=$.windowMinimize,m.setAttribute("aria-label","Minimize"),wireTooltip(m),Object.assign(m.style,g),wireControlHover(m),m.addEventListener("click",()=>A(!w)),s.appendChild(m));let x=null;e.printable&&(x=t.createElement("button"),x.type="button",x.innerHTML=$.print,x.setAttribute("aria-label","Print / Save as PDF"),wireTooltip(x),Object.assign(x.style,g),wireControlHover(x),x.addEventListener("click",()=>{typeof e.printable=="function"?e.printable():o.print()}),s.appendChild(x));const u=t.createElement("button");u.type="button",u.innerHTML=$.maximize,u.setAttribute("aria-label","Maximize (F)"),wireTooltip(u),Object.assign(u.style,g),wireControlHover(u),u.addEventListener("click",()=>C(!b));const c=t.createElement("button");c.type="button",c.innerHTML=$.close,c.setAttribute("aria-label","Close (Esc)"),wireTooltip(c),Object.assign(c.style,g),wireControlHover(c),c.addEventListener("click",D),s.appendChild(u),s.appendChild(c);let b=!1,v="",y="";function C(h){b=h,u.innerHTML=b?$.minimize:$.maximize,u.setAttribute("aria-label",b?"Restore (F)":"Maximize (F)"),L.style.display=b?"none":"block",b?(r.style.borderRadius="0",r.style.width="100vw",r.style.height="100vh",n||(v=r.style.top,y=r.style.left,r.style.top="0",r.style.left="0")):(r.style.borderRadius="12px",r.style.width=f,r.style.height=p,n||(r.style.top=v,r.style.left=y)),e.onMaximizeChange?.(b,r)}let w=!1,M="",T="";const S=220;function A(h){w=h,m.innerHTML=w?$.windowRestore:$.windowMinimize,m.setAttribute("aria-label",w?"Restore":"Minimize"),L.style.display=w?"none":"block",w?(M=r.style.height,T=r.style.width,r.style.minHeight="0",r.style.height="auto",r.style.minWidth="0",r.style.width=`${S}px`,u.disabled=!0,u.style.opacity="0.4",u.style.cursor="default",H.style.display="none"):(r.style.minHeight="240px",r.style.height=M||p,r.style.minWidth="320px",r.style.width=T||f,u.disabled=!1,u.style.opacity="1",u.style.cursor="pointer",H.style.display="flex")}function E(){const h=t.body.style.userSelect;return t.body.style.userSelect="none",()=>{t.body.style.userSelect=h}}n||(s.style.cursor="move",s.addEventListener("pointerdown",h=>{if(b||h.target.closest('button, [role="button"]'))return;h.preventDefault();const I=E(),W=h.clientX,z=h.clientY,R=r.offsetTop,_=r.offsetLeft,ee=o.innerHeight-s.offsetHeight,te=o.innerWidth-40,K=40-r.offsetWidth;s.setPointerCapture(h.pointerId);const G=U=>{const ne=Math.min(Math.max(R+(U.clientY-z),0),ee),xe=Math.min(Math.max(_+(U.clientX-W),K),te);r.style.top=`${ne}px`,r.style.left=`${xe}px`},j=U=>{I(),s.releasePointerCapture(U.pointerId),s.removeEventListener("pointermove",G),s.removeEventListener("pointerup",j)};s.addEventListener("pointermove",G),s.addEventListener("pointerup",j)}));const F='button,[href],input,select,textarea,[tabindex]:not([tabindex="-1"]),[role="menuitem"],[role="menuitemradio"],[role="menuitemcheckbox"]';function V(h){const I=Array.from(r.querySelectorAll(F)).filter(_=>_.offsetParent!==null||_===t.activeElement);if(I.length===0){h.preventDefault(),r.focus();return}const W=I[0],z=I[I.length-1],R=t.activeElement;h.shiftKey&&(R===W||!r.contains(R))?(h.preventDefault(),z.focus()):!h.shiftKey&&R===z&&(h.preventDefault(),W.focus())}const O=h=>{if(h.key==="Escape"){D();return}if(n&&(h.key==="e"||h.key==="E")){D();return}if(n&&h.key==="Tab"){V(h);return}(h.key==="f"||h.key==="F")&&!w&&C(!b)};function D(){n?t.removeEventListener("keydown",O):r.removeEventListener("keydown",O),J.remove(),he(),hideTooltip(t),reparentTooltip(t.body),a?a.remove():r.remove(),n&&(t.body.style.overflow=i),d?.focus?.(),e.onClose()}function B(){n||(r.style.zIndex=String(de()))}const H=t.createElement("div");Object.assign(H.style,{flex:"1",minHeight:"0",minWidth:"0",display:"flex",overflow:"hidden"});const L=t.createElement("div");L.tabIndex=0,L.setAttribute("role","separator"),L.setAttribute("aria-label","Resize window (arrow keys, or drag)"),Object.assign(L.style,{position:"absolute",right:"0",bottom:"0",width:"16px",height:"16px",cursor:"nwse-resize",touchAction:"none"}),L.innerHTML='<svg viewBox="0 0 16 16" width="16" height="16" style="display:block"><path d="M15 15 L15 9 M15 15 L9 15 M15 15 L15 3 M15 15 L3 15" stroke="currentColor" stroke-width="1" opacity="0.35" fill="none"/></svg>',L.style.color=CLR.label;const ae=320,se=240,Y=20;function q(h,I){const W=o.innerWidth-r.offsetLeft,z=o.innerHeight-r.offsetTop,R=Math.min(Math.max(r.offsetWidth+h,ae),W),_=Math.min(Math.max(r.offsetHeight+I,se),z);r.style.width=`${R}px`,r.style.height=`${_}px`}L.addEventListener("keydown",h=>{if(!(b||w))switch(h.key){case"ArrowRight":h.preventDefault(),q(Y,0);break;case"ArrowLeft":h.preventDefault(),q(-Y,0);break;case"ArrowDown":h.preventDefault(),q(0,Y);break;case"ArrowUp":h.preventDefault(),q(0,-Y);break}}),L.addEventListener("pointerdown",h=>{if(b||w)return;h.preventDefault();const I=E(),W=h.clientX,z=h.clientY,R=r.offsetWidth,_=r.offsetHeight,ee=o.innerWidth-r.offsetLeft,te=o.innerHeight-r.offsetTop;L.setPointerCapture(h.pointerId);const K=j=>{const U=Math.min(Math.max(R+(j.clientX-W),ae),ee),ne=Math.min(Math.max(_+(j.clientY-z),se),te);r.style.width=`${U}px`,r.style.height=`${ne}px`},G=j=>{I(),L.releasePointerCapture(j.pointerId),L.removeEventListener("pointermove",K),L.removeEventListener("pointerup",G)};L.addEventListener("pointermove",K),L.addEventListener("pointerup",G)}),r.appendChild(s),r.appendChild(H),r.appendChild(L);const Q=e.anchor?overlayRootFor(e.anchor):t.body;a?(a.appendChild(r),Q.appendChild(a)):Q.appendChild(r);const he=$e(t,Q),J=t.createElement("style");return J.textContent=`@media print{
|
|
1
|
+
import{getUniqueTestNumbers as ve}from"../renderer/buildView.js";import{dieHasTestData as ge}from"../renderer/buildWaferMap.js";import{prettyKey as ye}from"../core/utils.js";import{listBinColorSchemes as we,listValueColorSchemes as ke}from"../renderer/colorSchemes.js";import{ICONS as $}from"./icons.js";import{WMAP_VERSION as Ee,WMAP_BUILD_TIME as Ce}from"./version.js";import{openHtmlReport as Le}from"../stats/renderFindingsReport.js";import{buildWaferMap as Ae}from"../renderer/buildWaferMap.js";import{analyzeWaferMap as Me}from"../stats/analyzeWaferMap.js";let le=!1;export function logWmapVersionOnce(){le||(le=!0,console.log(`[wmap] v${Ee} (built ${Ce})`))}export const WMAP_TOKEN_NAMES=["z","icon","icon-hover","icon-active","bg-hover","bg-active","separator","surface","border","control-border","menu-hover","menu-active","font-family","font-size","density","panel-bg","text-muted","text","text-strong","warn-bg","warn-border","warn-text","err-bg","err-border","err-text","info-bg","info-text","selected","finding-indicator","canvas-bg","bar-fill"];const E=(e,n)=>`var(--wmap-${e}, ${n})`,q="var(--wmap-font-size, 12px)",Se="var(--wmap-density, 1)",N=e=>`calc(${e}px * ${Se})`;export function wireControlHover(e,n="outlined"){let t=null;const o=()=>{t&&(e.style.background=t.background,e.style.color=t.color)};e.addEventListener("mouseenter",()=>{e.dataset.on==="true"||e.disabled||(t||(t={background:e.style.background,color:e.style.color}),e.style.background=CLR.bgHover,e.style.color=CLR.iconHover)}),e.addEventListener("mouseleave",o),e.addEventListener("blur",o)}export function controlStyle(e,n=!1){const t={fontSize:FONT.body,cursor:"pointer",borderRadius:RADIUS.control};return e==="bare"?{...t,border:"none",background:"none",padding:"0",color:CLR.icon}:{...t,border:`1px solid ${CLR.controlBorder}`,background:e==="toggle"&&n?CLR.menuActive:"none",color:e==="toggle"&&n?CLR.iconActive:CLR.text,padding:`${SPACE.xxs} ${SPACE.lg}`}}export const SPACE={xxs:N(2),xs:N(4),sm:N(6),md:N(8),lg:N(10),xl:N(12),xxl:N(16),xxxl:N(24)},SHADOW={panel:"0 1px 4px rgba(0,0,0,0.10)",menu:"0 4px 12px rgba(0,0,0,0.15)",modal:"0 20px 60px rgba(0,0,0,0.40)"},MOTION={fast:"0.12s ease",base:"0.2s ease"},LEADING={none:"1",tight:"1.2",base:"1.45"},ALPHA={muted:"0.85",disabled:"0.4"},TRACKING="0.05em",EDGE_GUTTER=SPACE.xl,MAP_CHROME_INSET=SPACE.xs,RADIUS={control:"4px",container:"6px",pill:"999px"},FONT={family:"var(--wmap-font-family, inherit)",meta:`calc(${q} - 1px)`,body:q,sub:`calc(${q} + 1px)`,heading:`calc(${q} + 3px)`,stat:`calc(${q} + 8px)`};export function fontPx(e=0,n){const t=n?.ownerDocument??(typeof document<"u"?document:null);if(!t)return 12+e;const o=getComputedStyle(n??t.documentElement).getPropertyValue("--wmap-font-size").trim(),r=o?parseFloat(o):NaN;return(Number.isFinite(r)?r:12)+e}export const CLR={icon:E("icon","#506784"),iconHover:E("icon-hover","#2a3f5f"),iconActive:E("icon-active","#1a65ca"),bgHover:E("bg-hover","#edf0f8"),bgActive:E("bg-active","#dce8f8"),separator:E("separator","rgba(0,0,0,0.12)"),menuBg:E("surface","#fff"),menuBorder:E("border","rgba(0,0,0,0.12)"),controlBorder:E("control-border",E("border","rgba(0,0,0,0.30)")),menuHover:E("menu-hover","#f0f4fc"),menuActive:E("menu-active","#dce8f8"),canvasBg:`var(--wmap-canvas-bg, ${E("surface","#f5f5f5")})`,panelBg:E("panel-bg","#fafbfc"),label:E("text-muted","#647687"),value:E("text-strong","#1f2f43"),text:E("text","#333"),warnBg:E("warn-bg","#fffbe6"),warnBorder:E("warn-border","#f0c040"),warnText:E("warn-text","#7a5800"),errBg:E("err-bg","#fef2f2"),errBorder:E("err-border","#dc8a8a"),errText:E("err-text","#7a1c1c"),infoBg:E("info-bg","#dce8f8"),infoText:E("info-text","#334155"),findingHighlight:E("selected","#e07a20"),findingIndicator:E("finding-indicator","#b7551a"),barFill:E("bar-fill","#2a6fc0")};export function sevColor(e){return e==="unusual"?"#a84112":e==="notable"?"#8a6500":CLR.icon}export const ROTATIONS=[0,90,180,270],INLINE_TEST_LIMIT=6,MENU_SEARCH_THRESHOLD=8,DEFAULT_OVERLAY_Z=6e3,Z_BASE=`var(--wmap-z, ${DEFAULT_OVERLAY_Z})`,Z_ABOVE=`calc(var(--wmap-z, ${DEFAULT_OVERLAY_Z}) + 1)`,Z_MENU=`calc(var(--wmap-z, ${DEFAULT_OVERLAY_Z}) + 2)`,Z_ABOVE2=`calc(var(--wmap-z, ${DEFAULT_OVERLAY_Z}) + 3)`;export function applyOverlayZ(e){if(e==null)return()=>{};const n=document.documentElement,t=n.style.getPropertyValue("--wmap-z");return n.style.setProperty("--wmap-z",String(e)),()=>{t?n.style.setProperty("--wmap-z",t):n.style.removeProperty("--wmap-z")}}export function copyWmapThemeTokens(e,n){const t=getComputedStyle(e);for(const o of WMAP_TOKEN_NAMES){const r=t.getPropertyValue(`--wmap-${o}`).trim();r&&n.style.setProperty(`--wmap-${o}`,r)}}export function syncWmapPopupTheme(e,n,t){const o=()=>{copyWmapThemeTokens(e,n),t?.()},r=new window.MutationObserver(o);r.observe(e,{attributes:!0,attributeFilter:["style","class"]}),r.observe(document.documentElement,{attributes:!0,attributeFilter:["style","class"]});const l=window.matchMedia("(prefers-color-scheme: dark)");return l.addEventListener("change",o),()=>{r.disconnect(),l.removeEventListener("change",o)}}let re=null;export function setDetachWindowOpener(e){re=e}export function openDetachWindow(e){return re?re(e):window.open("","_blank","width=560,height=600")}export const MODE_LABELS={value:"Test Value",hardBin:"Hard Bin",softBin:"Soft Bin",stackedValues:"Stacked Test Values",stackedBins:"Stacked Hard Bins",stackedSoftBins:"Stacked Soft Bins",metadata:"Metadata"},BIN_LEGEND_MODES=new Set(["hardBin","softBin","metadata"]),STACKED_MODES=new Set(["stackedValues","stackedBins","stackedSoftBins"]);export function saveImageBlob(e,n,t){const o=`${n}.png`;if(t){t(e,o);return}downloadBlob(e,o)}export function downloadBlob(e,n){const t=URL.createObjectURL(e),o=document.createElement("a");o.href=t,o.download=n,o.click(),URL.revokeObjectURL(t)}export function saveTextFile(e,n,t,o){if(o){o(e,n,t);return}downloadBlob(new Blob([e],{type:t}),n)}const Be='[role="menuitem"],[role="menuitemradio"],[role="menuitemcheckbox"]';export function nextFrame(e,n=window){const t=n.requestAnimationFrame;typeof t=="function"?t.call(n,e):setTimeout(e,0)}export function wireListNavigation(e,n,t){e.addEventListener("keydown",o=>{const r=n();if(r.length===0)return;const l=e.ownerDocument.activeElement,u=l?r.indexOf(l):-1;switch(o.key){case"ArrowDown":o.preventDefault(),r[u<0||u===r.length-1?0:u+1].focus();break;case"ArrowUp":o.preventDefault(),r[u<=0?r.length-1:u-1].focus();break;case"Home":o.preventDefault(),r[0].focus();break;case"End":o.preventDefault(),r[r.length-1].focus();break;case"Enter":case" ":u>=0&&(o.preventDefault(),r[u].click());break;case"Escape":case"Tab":o.preventDefault(),t();break}})}function J(e,n,t){const o=()=>Array.from(e.querySelectorAll(Be));wireListNavigation(e,o,()=>{t(),n?.focus()});const r=o()[0];r&&nextFrame(()=>r.focus())}export function overlayRootFor(e){let n=e;for(;n;){if(n.classList.contains("wmap-overlay-box")||n.tagName==="DIALOG"&&n.matches(":modal"))return n;n=n.parentElement}return e.ownerDocument.body}const ce=new WeakMap;export function menuLayerFor(e){const n=overlayRootFor(e),t=ce.get(n);if(t&&t.isConnected)return t;const r=e.ownerDocument.createElement("div");return r.dataset.wmapMenuLayer="1",Object.assign(r.style,{position:"fixed",inset:"0",zIndex:Z_MENU,pointerEvents:"none"}),n.appendChild(r),ce.set(n,r),r}const ae=new WeakMap;export function getTooltip(e=document){const n=ae.get(e);if(n&&n.isConnected)return n;const t=n??e.createElement("div");return n||(Object.assign(t.style,{position:"fixed",pointerEvents:"none",background:"rgba(30, 32, 40, 0.93)",color:"#f0f0f2",border:"1px solid rgba(255,255,255,0.10)",padding:"7px 11px",borderRadius:RADIUS.control,fontSize:FONT.sub,lineHeight:LEADING.base,maxWidth:"280px",maxHeight:"min(60vh, 480px)",overflow:"hidden",whiteSpace:"pre-wrap",zIndex:Z_ABOVE,display:"none",fontFamily:FONT.family,boxShadow:SHADOW.menu}),ae.set(e,t)),e.body.appendChild(t),t}export function hideTooltip(e=document){const n=ae.get(e);n&&(n.style.display="none")}export function reparentTooltip(e){const n=e?.ownerDocument??document,t=getTooltip(n);(e??n.body).appendChild(t)}export function positionTooltip(e,n,t,o){const r=overlayRootFor(n);e.parentElement!==r&&r.appendChild(e);const l=e.ownerDocument.defaultView??window;e.style.left="0",e.style.top="0";const u=e.offsetWidth,i=e.offsetHeight,f=8,m=l.innerWidth,s=l.innerHeight;let y=t+14,a=o-8;y+u+f>m&&(y=t-u-6);const p=n.getBoundingClientRect();if(p.height>0&&p.height<=s*.4&&a<p.bottom&&a+i>p.top&&y<p.right&&y+u>p.left){const c=p.bottom+f,b=p.top-i-f;c+i+f<=s?a=c:b>=f&&(a=b)}a+i+f>s&&(a=s-i-f),a<f&&(a=f),e.style.left=`${y}px`,e.style.top=`${a}px`}export function wireTooltip(e,n,t={}){const o=()=>(typeof n=="function"?n():n)??e.getAttribute("aria-label")??"";t.asDataPoint&&(e.tabIndex=0,e.setAttribute("role","img"),typeof n=="string"&&e.setAttribute("aria-label",n));const r=u=>{const i=o();if(!i)return;const f=getTooltip(e.ownerDocument);if(f.textContent=i,f.style.display="block",u)positionTooltip(f,e,u.clientX,u.clientY);else{const m=e.getBoundingClientRect();positionTooltip(f,e,m.left+m.width/2,m.top)}},l=()=>hideTooltip(e.ownerDocument);e.addEventListener("mousemove",r),e.addEventListener("mouseleave",l),e.addEventListener("focus",()=>r()),e.addEventListener("blur",l)}export function buildDataModeEntries(e,n,t){const o=e.some(ge),r=e.some(s=>s.testValues!==void 0&&Object.keys(s.testValues).length>0),l=e.some(s=>s.hbin!=null),u=e.some(s=>s.sbin!=null),i=o?n!==void 0?n.map(s=>({plotMode:"value",activeTest:s.testNumber,label:s.unit?`${s.name} (${s.unit})`:s.name,logScale:s.logScale})):ve(e).map(s=>({plotMode:"value",activeTest:s,label:`Test ${s}`})):[],f=[...l?[{plotMode:"hardBin",label:MODE_LABELS.hardBin}]:[],...u?[{plotMode:"softBin",label:MODE_LABELS.softBin}]:[]],m=t.includeStacked?[...r?[{plotMode:"stackedValues",label:MODE_LABELS.stackedValues}]:[],...l?[{plotMode:"stackedBins",label:MODE_LABELS.stackedBins}]:[],...u?[{plotMode:"stackedSoftBins",label:MODE_LABELS.stackedSoftBins}]:[]]:[];return{testEntries:i,binEntries:f,stackedEntries:m}}export function metadataKeyHasData(e,n){return e.some(t=>t.metadata?.[n]!==void 0&&t.metadata?.[n]!==null)}export function metadataModeEntry(e){return{plotMode:"metadata",activeMetadataKey:e.key,label:e.label??ye(e.key)}}export function makeMenuSearchBox(e,n="Filter\u2026",t=document){const o=t.createElement("input");return o.type="text",o.placeholder=n,o.setAttribute("aria-label",n),Object.assign(o.style,{display:"block",width:"calc(100% - 20px)",margin:"2px 10px 6px",padding:`${SPACE.xs} ${SPACE.md}`,fontSize:FONT.body,boxSizing:"border-box",background:CLR.menuBg,color:CLR.text,border:`1px solid ${CLR.menuBorder}`,borderRadius:RADIUS.control,outline:"none"}),o.addEventListener("click",r=>r.stopPropagation()),o.addEventListener("mousedown",r=>r.stopPropagation()),o.addEventListener("keydown",r=>r.stopPropagation()),o.addEventListener("input",()=>e(o.value.trim().toLowerCase())),o.addEventListener("focus",()=>{o.style.borderColor=CLR.iconActive}),o.addEventListener("blur",()=>{o.style.borderColor=CLR.menuBorder}),queueMicrotask(()=>o.focus()),o}export function buildModeMenuEl(e,n,t,o,r,l,u,i,f=window,m=[]){const{makeMenuRow:s,makeMenuSection:y}=u,a=document.createElement("div"),p=180,d=e.left+p<=(f.innerWidth??1/0)?e.left:Math.max(4,e.right-p);if(Object.assign(a.style,{position:"fixed",top:`${e.bottom+4}px`,left:`${d}px`,background:CLR.menuBg,border:`1px solid ${CLR.menuBorder}`,borderRadius:RADIUS.control,boxShadow:SHADOW.menu,zIndex:Z_BASE,minWidth:`${p}px`,padding:"4px 0",pointerEvents:"auto"}),n.length)if(a.appendChild(y("Test Value")),n.length<=INLINE_TEST_LIMIT)for(const c of n)a.appendChild(s(c.label,r(c),!0,b=>{b.stopPropagation(),l(c,a)}));else{const c=i==="value",b=s(MODE_LABELS.value+" \u25B6",c,!1,g=>{g.stopPropagation(),A(),M(),g.detail===0&&T()});b.setAttribute("aria-haspopup","menu"),b.style.display="flex",b.style.justifyContent="space-between",b.style.alignItems="center";let v=null,w=null;const A=()=>{w!==null&&(clearTimeout(w),w=null)},C=g=>{const S=g.target;S&&(b.contains(S)||v?.contains(S))||L()},L=()=>{A(),v?.remove(),v=null,f.document.removeEventListener("click",C),b.setAttribute("aria-expanded","false")},T=()=>{const g=v?.querySelector('input, [role="menuitemradio"]');g&&nextFrame(()=>g.focus(),f)},B=()=>{A(),w=setTimeout(L,300)},M=()=>{if(v)return;const g=b.getBoundingClientRect(),S=160,F=320,H=g.right+2+S<=(f.innerWidth??1/0)?g.right+2:Math.max(4,g.left-2-S),X=Math.min(g.top-4,Math.max(4,(f.innerHeight??1/0)-F-4));if(v=document.createElement("div"),v.setAttribute("data-wmap-submenu",""),v.setAttribute("role","menu"),Object.assign(v.style,{position:"fixed",top:`${X}px`,left:`${H}px`,background:CLR.menuBg,border:`1px solid ${CLR.menuBorder}`,borderRadius:RADIUS.control,boxShadow:SHADOW.menu,zIndex:Z_ABOVE,minWidth:`${S}px`,maxHeight:`${F}px`,overflowY:"auto",padding:"4px 0",pointerEvents:"auto"}),n.length>MENU_SEARCH_THRESHOLD){const k=makeMenuSearchBox(j=>{for(const V of I)V.row.style.display=V.label.includes(j)?"":"none"},"Filter tests\u2026");Object.assign(k.style,{position:"sticky",top:"0",zIndex:"1",background:CLR.menuBg}),v.appendChild(k)}const I=[];for(const k of n){const j=s(k.label,r(k),!1,V=>{V.stopPropagation(),L(),l(k,a)});I.push({row:j,label:k.label.toLowerCase()}),v.appendChild(j)}v.addEventListener("mouseenter",A),v.addEventListener("mouseleave",B),wireListNavigation(v,()=>I.filter(k=>k.row.style.display!=="none").map(k=>k.row),()=>{L(),b.focus()}),(a.parentElement??f.document.body).appendChild(v),f.document.addEventListener("click",C),b.setAttribute("aria-expanded","true")};a.addEventListener("keydown",g=>{g.key==="Escape"&&L()}),b.addEventListener("mouseenter",()=>{A(),M()}),b.addEventListener("mouseleave",B),a.appendChild(b)}if(t.length){a.appendChild(y("Bins"));for(const c of t)a.appendChild(s(c.label,r(c),!1,b=>{b.stopPropagation(),l(c,a)}))}if(m.length){a.appendChild(y("Metadata"));for(const c of m)a.appendChild(s(c.label,r(c),!1,b=>{b.stopPropagation(),l(c,a)}))}if(o.length){a.appendChild(y("Lot Aggregation"));for(const c of o)a.appendChild(s(c.label,r(c),!1,b=>{b.stopPropagation(),l(c,a)}))}return a.setAttribute("role","menu"),a.setAttribute("aria-label","Plot mode"),a}export function markMenuTrigger(e,n){e.setAttribute("aria-haspopup","menu"),e.setAttribute("aria-expanded",n?"true":"false")}export function wireMenuA11y(e,n,t){J(e,n,t)}export function wireExpandToggle(e,n){const t=e.ownerDocument;let o=!1;function r(m){o!==m&&(o=m,n(o))}function l(){r(!1)}function u(){r(!o),o&&t.addEventListener("click",l,{once:!0})}const i=m=>{m.stopPropagation(),u()},f=m=>{m.key==="Enter"||m.key===" "?(m.preventDefault(),u()):m.key==="Escape"&&l()};return e.setAttribute("role","button"),e.tabIndex<0&&(e.tabIndex=0),e.addEventListener("click",i),e.addEventListener("keydown",f),{isOpen:()=>o,close:l,destroy(){e.removeEventListener("click",i),e.removeEventListener("keydown",f),t.removeEventListener("click",l)}}}export function buildCheckMenuEl(e,n,t,o=window){const{makeMenuSection:r}=t,l=o.document,u=l.createElement("div"),i=168,m=e.left+i<=(o.innerWidth??1/0)?e.left:Math.max(4,e.right-i);Object.assign(u.style,{position:"fixed",top:`${e.bottom+4}px`,left:`${m}px`,background:CLR.menuBg,border:`1px solid ${CLR.menuBorder}`,borderRadius:RADIUS.control,boxShadow:SHADOW.menu,zIndex:Z_BASE,minWidth:`${i}px`,padding:"4px 0",pointerEvents:"auto"});for(const s of n)if("section"in s)u.appendChild(r(s.section));else{const y=s.enabled!==!1;if(!y&&!s.disabledHint)continue;const a=l.createElement("div");s.action?a.setAttribute("role","menuitem"):(a.setAttribute("role","menuitemcheckbox"),a.setAttribute("aria-checked",s.active?"true":"false")),a.tabIndex=-1,y||(a.setAttribute("aria-disabled","true"),wireTooltip(a,s.disabledHint)),Object.assign(a.style,{display:"flex",alignItems:"center",gap:SPACE.sm,padding:"6px 14px",fontSize:FONT.body,cursor:y?"pointer":"default",color:y?s.active?CLR.iconActive:CLR.text:CLR.label,fontWeight:s.active?"700":"400",background:s.active?CLR.menuActive:"transparent",whiteSpace:"nowrap"});const p=l.createElement("span");Object.assign(p.style,{width:"12px",flexShrink:"0",color:CLR.iconActive,visibility:s.active?"visible":"hidden"}),p.textContent=s.action?"":"\u2713",p.setAttribute("aria-hidden","true");const x=l.createElement("span");x.textContent=s.label,a.appendChild(p),a.appendChild(x),y?(a.addEventListener("mouseenter",()=>{s.active||(a.style.background=CLR.menuHover)}),a.addEventListener("mouseleave",()=>{a.style.background=s.active?CLR.menuActive:"transparent"}),a.addEventListener("focus",()=>{s.active||(a.style.background=CLR.menuHover)}),a.addEventListener("blur",()=>{a.style.background=s.active?CLR.menuActive:"transparent"}),a.addEventListener("click",d=>{d.stopPropagation(),s.onClick(d)})):a.addEventListener("click",d=>{d.stopPropagation()}),u.appendChild(a)}return u}export function createToolbarHelpers(e){const n=e.ownerDocument;let t=null;const o=a=>menuLayerFor(a);function r(a,p,x){const d=n.createElement("button");return d.innerHTML=$[a],d.type="button",d.ariaLabel=p,Object.assign(d.style,{display:"flex",alignItems:"center",justifyContent:"center",width:"28px",height:"28px",padding:"0",border:"none",borderRadius:RADIUS.control,background:"transparent",color:CLR.icon,cursor:"pointer",pointerEvents:"auto",transition:`background ${MOTION.fast}, color ${MOTION.fast}`,flexShrink:"0"}),d.addEventListener("mouseenter",c=>{d.dataset.active||(d.style.background=CLR.bgHover,d.style.color=CLR.iconHover),e.textContent=d.ariaLabel??p,e.style.display="block",positionTooltip(e,d,c.clientX,c.clientY)}),d.addEventListener("mousemove",c=>{e.style.display==="block"&&positionTooltip(e,d,c.clientX,c.clientY)}),d.addEventListener("mouseleave",()=>{d.dataset.active||(d.style.background="transparent",d.style.color=CLR.icon),e.style.display="none"}),d.addEventListener("click",()=>{e.style.display="none",x()}),d}function l(a,p){p?(a.dataset.active="1",a.style.background=CLR.bgActive,a.style.color=CLR.iconActive):(delete a.dataset.active,a.style.background="transparent",a.style.color=CLR.icon)}function u(){const a=n.createElement("div");return Object.assign(a.style,{width:"1px",height:"18px",background:CLR.separator,margin:"0 2px",flexShrink:"0"}),a}function i(a,p,x,d){const c=n.createElement("div");return c.textContent=a,c.setAttribute("role","menuitemradio"),c.setAttribute("aria-checked",p?"true":"false"),c.tabIndex=-1,Object.assign(c.style,{padding:`6px 14px 6px ${x?"26px":"14px"}`,fontSize:FONT.body,cursor:"pointer",color:p?CLR.iconActive:CLR.text,fontWeight:p?"700":"400",background:p?CLR.menuActive:"transparent",whiteSpace:"nowrap"}),c.addEventListener("mouseenter",()=>{p||(c.style.background=CLR.menuHover)}),c.addEventListener("mouseleave",()=>{c.style.background=p?CLR.menuActive:"transparent"}),c.addEventListener("focus",()=>{p||(c.style.background=CLR.menuHover)}),c.addEventListener("blur",()=>{c.style.background=p?CLR.menuActive:"transparent"}),c.addEventListener("click",d),c}function f(a){const p=n.createElement("div");return p.textContent=a,p.setAttribute("role","presentation"),Object.assign(p.style,{padding:"5px 14px 2px",fontSize:FONT.body,fontWeight:"600",letterSpacing:TRACKING,color:CLR.label,textTransform:"uppercase",pointerEvents:"none",userSelect:"none"}),p}function m(a,p,x,d,c){const b=()=>{t&&(t.remove(),t=null),v.setAttribute("aria-expanded","false")},v=r(a,p,()=>{if(t){b();return}const w=n.createElement("div"),A=v.getBoundingClientRect(),C=v.ownerDocument.defaultView??window,L=148,B=A.left+L<=(C.innerWidth??1/0)?A.left:Math.max(4,A.right-L);Object.assign(w.style,{position:"fixed",top:`${A.bottom+4}px`,left:`${B}px`,background:CLR.menuBg,border:`1px solid ${CLR.menuBorder}`,borderRadius:RADIUS.control,boxShadow:SHADOW.menu,zIndex:Z_BASE,minWidth:`${L}px`,padding:"4px 0",pointerEvents:"auto"});for(const M of x()){const g=n.createElement("div");g.textContent=M.label,g.dataset.wmapDropdownValue=M.value;const S=M.value===d();g.setAttribute("role","menuitemradio"),g.setAttribute("aria-checked",S?"true":"false"),g.tabIndex=-1,Object.assign(g.style,{padding:"6px 14px",fontSize:FONT.body,cursor:"pointer",color:S?CLR.iconActive:CLR.text,fontWeight:S?"700":"400",background:S?CLR.menuActive:"transparent",whiteSpace:"nowrap"});const F=()=>{M.value!==d()&&(g.style.background=CLR.menuHover)},R=()=>{g.style.background=M.value===d()?CLR.menuActive:"transparent"};g.addEventListener("mouseenter",F),g.addEventListener("mouseleave",R),g.addEventListener("focus",F),g.addEventListener("blur",R),g.addEventListener("click",H=>{H.stopPropagation(),c(M.value),b()}),w.appendChild(g)}w.setAttribute("role","menu"),w.setAttribute("aria-label",p),o(v).appendChild(w),t=w,v.setAttribute("aria-expanded","true"),J(w,v,b)});return v.setAttribute("aria-haspopup","menu"),v.setAttribute("aria-expanded","false"),v}function s(a,p,x,d){function c(){return buildCheckMenuEl(v.getBoundingClientRect(),x().map(w=>"section"in w?w:{...w,onClick:A=>{w.onClick(A),d(v);const C=t;if(!C)return;const L=c();L.setAttribute("role","menu"),L.setAttribute("aria-label",p),C.replaceWith(L),t=L,J(L,v,b)}}),{makeMenuSection:f},v.ownerDocument.defaultView??window)}const b=()=>{t&&(t.remove(),t=null),v.setAttribute("aria-expanded","false")},v=r(a,p,()=>{if(t){b();return}const w=c();w.setAttribute("role","menu"),w.setAttribute("aria-label",p),o(v).appendChild(w),t=w,v.setAttribute("aria-expanded","true"),J(w,v,b)});return v.setAttribute("aria-haspopup","menu"),v.setAttribute("aria-expanded","false"),d(v),v}function y(a){const p=a.target?.closest?.("[data-wmap-submenu]");if(t&&!t.contains(a.target)&&!p&&(t.remove(),t=null,a.target?.getAttribute?.("aria-haspopup")!=="menu"))for(const d of document.querySelectorAll('[aria-haspopup="menu"][aria-expanded="true"]'))d.setAttribute("aria-expanded","false")}return{makeBtn:r,setActive:l,makeSep:u,makeMenuRow:i,makeMenuSection:f,makeDropdown:m,makeCheckMenuBtn:s,closeOpenMenu:y,getOpenMenu:()=>t,setOpenMenu:a=>{t=a}}}const Te=7e3;let De=0;function de(){return Te+ ++De}const He=32,Ie=6;let Oe=0;function $e(){return Oe++%Ie*He}function Re(e,n){if(n===e.body)return()=>{};let t=n;for(;t.parentElement&&t.parentElement!==e.body;)t=t.parentElement;return t===e.body?()=>{}:(t.classList.add("wmap-overlay-ancestor"),()=>t.classList.remove("wmap-overlay-ancestor"))}function ue(e){const n=e.mode==="modal",t=e.ownerDocument??document,o=t.defaultView??window,r=t.body.style.overflow;n&&(t.body.style.overflow="hidden");let l=null;n&&(l=t.createElement("div"),l.id="wmap-modal-backdrop",Object.assign(l.style,{position:"fixed",inset:"0",background:"rgba(0,0,0,0.6)",display:"flex",alignItems:"center",justifyContent:"center",zIndex:Z_ABOVE,backdropFilter:"blur(3px)"}));const u=t.activeElement,i=t.createElement("div");i.className=n?"wmap-modal-box wmap-overlay-box":"wmap-window-box wmap-overlay-box",i.setAttribute("role","dialog"),n&&i.setAttribute("aria-modal","true"),i.setAttribute("aria-label",e.title??"Expanded wafer map"),i.tabIndex=-1;const f=e.boxSize?.width??"min(90vw, 700px)",m=e.boxSize?.height??"min(90vh, 700px)";if(Object.assign(i.style,{position:"relative",background:CLR.menuBg,borderRadius:RADIUS.container,overflow:"hidden",display:"flex",flexDirection:"column",width:f,height:m,boxShadow:SHADOW.modal,minWidth:"320px",minHeight:"240px",maxWidth:"100vw",maxHeight:"100vh",zIndex:n?Z_ABOVE2:String(de())}),!n){const h=$e();Object.assign(i.style,{position:"fixed",top:`${Math.round(o.innerHeight*.08)+h}px`,left:`${Math.round(o.innerWidth*.08)+h}px`})}const s=t.createElement("div");Object.assign(s.style,{display:"flex",alignItems:"center",gap:SPACE.sm,padding:"10px 14px",borderBottom:`1px solid ${CLR.menuBorder}`,flexShrink:"0"});const y={border:`1px solid ${CLR.menuBorder}`,borderRadius:RADIUS.control,background:CLR.panelBg,cursor:"pointer",color:CLR.label,lineHeight:LEADING.none,padding:"0",display:"flex",alignItems:"center",justifyContent:"center",width:"28px",height:"28px"};if(e.title){const h=t.createElement("span");h.textContent=e.title,h.title=e.title,h.dataset.wmapWindowTitle="1",Object.assign(h.style,{fontWeight:"700",fontSize:"14px",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",minWidth:"0"}),s.appendChild(h)}const a=t.createElement("div");a.style.flex="1",s.appendChild(a);let p=null;n||(p=t.createElement("button"),p.type="button",p.innerHTML=$.collapse,p.setAttribute("aria-label","Collapse"),wireTooltip(p),Object.assign(p.style,y),wireControlHover(p),p.addEventListener("click",()=>M(!C)),s.appendChild(p));let x=null;e.printable&&(x=t.createElement("button"),x.type="button",x.innerHTML=$.print,x.setAttribute("aria-label","Print / Save as PDF"),wireTooltip(x),Object.assign(x.style,y),wireControlHover(x),x.addEventListener("click",()=>{typeof e.printable=="function"?e.printable():o.print()}),s.appendChild(x));const d=t.createElement("button");d.type="button",d.innerHTML=$.maximize,d.setAttribute("aria-label","Maximize (F)"),wireTooltip(d),Object.assign(d.style,y),wireControlHover(d),d.addEventListener("click",()=>A(!b));const c=t.createElement("button");c.type="button",c.innerHTML=$.close,c.setAttribute("aria-label","Close (Esc)"),wireTooltip(c),Object.assign(c.style,y),wireControlHover(c),c.addEventListener("click",H),s.appendChild(d),s.appendChild(c);let b=!1,v="",w="";function A(h){b=h,d.innerHTML=b?$.minimize:$.maximize,d.setAttribute("aria-label",b?"Restore (F)":"Maximize (F)"),p&&(p.style.display=b?"none":""),k.style.display=b?"none":"block",b?(i.style.borderRadius="0",i.style.width="100vw",i.style.height="100vh",n||(v=i.style.top,w=i.style.left,i.style.top="0",i.style.left="0")):(i.style.borderRadius="12px",i.style.width=f,i.style.height=m,n||(i.style.top=v,i.style.left=w)),e.onMaximizeChange?.(b,i)}let C=!1,L="",T="";const B=220;function M(h){C=h,p.innerHTML=C?$.uncollapse:$.collapse,p.setAttribute("aria-label",C?"Show contents":"Collapse"),k.style.display=C?"none":"block",C?(L=i.style.height,T=i.style.width,i.style.minHeight="0",i.style.height="auto",i.style.minWidth="0",i.style.width=`${B}px`,d.disabled=!0,d.style.opacity="0.4",d.style.cursor="default",I.style.display="none"):(i.style.minHeight="240px",i.style.height=L||m,i.style.minWidth="320px",i.style.width=T||f,d.disabled=!1,d.style.opacity="1",d.style.cursor="pointer",I.style.display="flex")}function g(){const h=t.body.style.userSelect;return t.body.style.userSelect="none",()=>{t.body.style.userSelect=h}}n||(s.style.cursor="move",s.addEventListener("pointerdown",h=>{if(b||h.target.closest('button, [role="button"]'))return;h.preventDefault();const D=g(),W=h.clientX,z=h.clientY,O=i.offsetTop,_=i.offsetLeft,ne=o.innerHeight-s.offsetHeight,oe=o.innerWidth-40,Q=40-i.offsetWidth;s.setPointerCapture(h.pointerId);const Y=G=>{const ie=Math.min(Math.max(O+(G.clientY-z),0),ne),xe=Math.min(Math.max(_+(G.clientX-W),Q),oe);i.style.top=`${ie}px`,i.style.left=`${xe}px`},U=G=>{D(),s.releasePointerCapture(G.pointerId),s.removeEventListener("pointermove",Y),s.removeEventListener("pointerup",U)};s.addEventListener("pointermove",Y),s.addEventListener("pointerup",U)}));const S='button,[href],input,select,textarea,[tabindex]:not([tabindex="-1"]),[role="menuitem"],[role="menuitemradio"],[role="menuitemcheckbox"]';function F(h){const D=Array.from(i.querySelectorAll(S)).filter(_=>_.offsetParent!==null||_===t.activeElement);if(D.length===0){h.preventDefault(),i.focus();return}const W=D[0],z=D[D.length-1],O=t.activeElement;h.shiftKey&&(O===W||!i.contains(O))?(h.preventDefault(),z.focus()):!h.shiftKey&&O===z&&(h.preventDefault(),W.focus())}const R=h=>{if(h.key==="Escape"){H();return}if(n&&(h.key==="e"||h.key==="E")){H();return}if(n&&h.key==="Tab"){F(h);return}(h.key==="f"||h.key==="F")&&!C&&A(!b)};function H(){n?t.removeEventListener("keydown",R):i.removeEventListener("keydown",R),te.remove(),he(),hideTooltip(t),reparentTooltip(t.body),l?l.remove():i.remove(),n&&(t.body.style.overflow=r),u?.focus?.(),e.onClose()}function X(){n||(i.style.zIndex=String(de()))}const I=t.createElement("div");Object.assign(I.style,{flex:"1",minHeight:"0",minWidth:"0",display:"flex",overflow:"hidden"});const k=t.createElement("div");k.tabIndex=0,k.setAttribute("role","separator"),k.setAttribute("aria-label","Resize window (arrow keys, or drag)"),Object.assign(k.style,{position:"absolute",right:"0",bottom:"0",width:"16px",height:"16px",cursor:"nwse-resize",touchAction:"none"}),k.innerHTML='<svg viewBox="0 0 16 16" width="16" height="16" style="display:block"><path d="M15 15 L15 9 M15 15 L9 15 M15 15 L15 3 M15 15 L3 15" stroke="currentColor" stroke-width="1" opacity="0.35" fill="none"/></svg>',k.style.color=CLR.label;const j=320,V=240,K=20;function Z(h,D){const W=o.innerWidth-i.offsetLeft,z=o.innerHeight-i.offsetTop,O=Math.min(Math.max(i.offsetWidth+h,j),W),_=Math.min(Math.max(i.offsetHeight+D,V),z);i.style.width=`${O}px`,i.style.height=`${_}px`}k.addEventListener("keydown",h=>{if(!(b||C))switch(h.key){case"ArrowRight":h.preventDefault(),Z(K,0);break;case"ArrowLeft":h.preventDefault(),Z(-K,0);break;case"ArrowDown":h.preventDefault(),Z(0,K);break;case"ArrowUp":h.preventDefault(),Z(0,-K);break}}),k.addEventListener("pointerdown",h=>{if(b||C)return;h.preventDefault();const D=g(),W=h.clientX,z=h.clientY,O=i.offsetWidth,_=i.offsetHeight,ne=o.innerWidth-i.offsetLeft,oe=o.innerHeight-i.offsetTop;k.setPointerCapture(h.pointerId);const Q=U=>{const G=Math.min(Math.max(O+(U.clientX-W),j),ne),ie=Math.min(Math.max(_+(U.clientY-z),V),oe);i.style.width=`${G}px`,i.style.height=`${ie}px`},Y=U=>{D(),k.releasePointerCapture(U.pointerId),k.removeEventListener("pointermove",Q),k.removeEventListener("pointerup",Y)};k.addEventListener("pointermove",Q),k.addEventListener("pointerup",Y)}),i.appendChild(s),i.appendChild(I),i.appendChild(k);const ee=e.anchor?overlayRootFor(e.anchor):t.body;l?(l.appendChild(i),ee.appendChild(l)):ee.appendChild(i);const he=Re(t,ee),te=t.createElement("style");return te.textContent=`@media print{
|
|
2
2
|
body{overflow:visible!important;height:auto!important}
|
|
3
3
|
body>*:not(.wmap-overlay-box):not(#wmap-modal-backdrop):not(.wmap-overlay-ancestor){display:none!important}
|
|
4
4
|
#wmap-modal-backdrop{position:static!important;background:none!important;backdrop-filter:none!important;display:block!important}
|
|
@@ -6,4 +6,4 @@ body>*:not(.wmap-overlay-box):not(#wmap-modal-backdrop):not(.wmap-overlay-ancest
|
|
|
6
6
|
.wmap-overlay-box>div:first-child{display:none!important}
|
|
7
7
|
.wmap-overlay-box>div:nth-child(2){display:block!important;overflow:visible!important;height:auto!important;flex:none!important;min-height:0!important;min-width:0!important}
|
|
8
8
|
.wmap-overlay-box>div:nth-child(3){display:none!important}
|
|
9
|
-
}`,t.head.appendChild(J),reparentTooltip(r),n?(a.addEventListener("click",h=>{h.target===a&&D()}),t.addEventListener("keydown",O)):(r.addEventListener("keydown",O),r.addEventListener("mousedown",B),B()),nextFrame(()=>(c.isConnected?c:r).focus(),o),{backdrop:a,box:r,contentWrap:H,close:D,bringToFront:B}}export function openModal(e){return ue({...e,mode:"modal"})}export function openFloatingWindow(e){return ue({...e,mode:"window"})}const re=new WeakSet;export function openReparentedModal(e,n={}){if(e.length===0||e.some(i=>re.has(i)))return null;const t=e.map(i=>({el:i,parent:i.parentElement,next:i.nextSibling})),o=openModal({ownerDocument:n.ownerDocument,title:n.title,boxSize:n.boxSize,anchor:e[0],onClose:()=>{for(const i of t){if(re.delete(i.el),!i.parent)continue;const a=i.next&&i.next.parentNode===i.parent?i.next:null;i.parent.insertBefore(i.el,a)}n.onClosed?.()}});for(const i of t)re.add(i.el),o.contentWrap.appendChild(i.el);return o}export function makePaletteBtn(e,n,t,o){const i=e.makeCheckMenuBtn("palette","Colour scheme",()=>{const d=n(),r=[];if(d.plotMode==="hardBin"||d.plotMode==="softBin"){const f=d.binColorScheme??"default";r.push({section:"Bin colours"});for(const p of we())r.push({label:p.label,active:f===p.name,onClick:()=>o({binColorScheme:p.name})});if(t()){const p=d.useDefinedBinColors??!0;r.push({section:"Bin definitions"}),r.push({label:"Use colours from bin definitions",active:p,onClick:()=>o({useDefinedBinColors:!p})})}}else{const f=d.valueColorScheme??"default";r.push({section:"Value colours"});for(const s of ke())r.push({label:s.label,active:f===s.name,onClick:()=>o({valueColorScheme:s.name})});const p=d.reverseValueScheme??!1;r.push({section:"Direction"}),r.push({label:"Reverse gradient",active:p,onClick:()=>o({reverseValueScheme:!p})})}return r},()=>{});function a(){i.style.display=n().plotMode==="metadata"?"none":""}return{btn:i,sync:a}}export function requestedPassFailDisplay(e){return e.passFailDisplay??"off"}export function overlayMenuRows(e,n,t,o){return[{label:"Ring boundaries",active:!!e.showRingBoundaries,onClick:()=>o({showRingBoundaries:!e.showRingBoundaries})},{label:"Quadrant lines",active:!!e.showQuadrantBoundaries,onClick:()=>o({showQuadrantBoundaries:!e.showQuadrantBoundaries})},{label:"Die labels",active:!!e.showDieLabels,onClick:()=>o({showDieLabels:!e.showDieLabels})},{label:"Reticle grid",active:!!e.showReticle,enabled:n,onClick:()=>o({showReticle:!e.showReticle})},{label:"XY indicator",active:!!e.showXYIndicator,onClick:()=>o({showXYIndicator:!e.showXYIndicator})},...passFailMenuRows({...t,display:requestedPassFailDisplay(e)},i=>o({passFailDisplay:i})),{label:"Mark failing dies",active:!!e.markFailingDies,enabled:t.binMode,disabledHint:t.binMode?void 0:"Available on hard/soft bin maps",onClick:()=>o({markFailingDies:!e.markFailingDies})},{section:""},{label:"Clear overlays",active:!1,action:!0,enabled:anyOverlayActive(e),disabledHint:"No overlays are active",onClick:()=>o({showRingBoundaries:!1,showQuadrantBoundaries:!1,showDieLabels:!1,showReticle:!1,showXYIndicator:!1,passFailDisplay:"off",markFailingDies:!1})}]}export function anyOverlayActive(e){return!!(e.showRingBoundaries||e.showQuadrantBoundaries||e.showDieLabels||e.showReticle||e.showXYIndicator||e.markFailingDies||requestedPassFailDisplay(e)!=="off")}export function passFailMenuRows(e,n){if(e.functionalActive)return[];const t=[];return e.hasLimits&&t.push({label:"Spec pass/fail",active:e.display==="spec",onClick:()=>n(e.display==="spec"?"off":"spec")}),e.hasRecorded&&t.push({label:"Test pass/fail",active:e.display==="test",onClick:()=>n(e.display==="test"?"off":"test")}),t}export function makeLogScaleBtn(e,n,t){const o=e.makeBtn("logScale","Toggle log scale",()=>{t({logScale:!n().logScale})});function i(){const a=n(),d=a.plotMode,r=d==="value"||d==="stackedValues";o.style.display=r&&requestedPassFailDisplay(a)==="off"&&!a.functionalActive?"":"none",e.setActive(o,!!a.logScale)}return{btn:o,sync:i}}const We=[{value:"default",label:"Default (right)"},{value:"compact",label:"Compact (right)"},{value:"left",label:"Left"},{value:"top",label:"Top"},{value:"bottom",label:"Bottom"},{value:"floating",label:"Floating"}];export function makeLegendStyleBtn(e,n,t,o){const i=e.makeCheckMenuBtn("legend","Legend style",()=>{const d=n().legendPosition??"default",r=[];let f=!0;if(o){const p=o.blockedReason();f=p?!0:o.get(),r.push({label:"Legend on each map",active:f,enabled:!p,disabledHint:p??void 0,onClick:()=>o.set(!o.get())})}if(pe(n().plotMode)){o&&r.push({section:"Position on each map"});for(const p of We)r.push({label:p.label,active:f&&d===p.value,enabled:f,disabledHint:f?void 0:'Turn on "Legend on each map" to position it',onClick:()=>t(p.value)})}return r},()=>{});function a(){i.style.display=o||pe(n().plotMode)?"":"none"}return{btn:i,sync:a}}function pe(e){return e==="hardBin"||e==="softBin"||e==="metadata"}export function makeOverlaysBtn(e,n,t){return e.makeCheckMenuBtn("overlays","Overlays",()=>n(),o=>e.setActive(o,t()))}export function makeOrientationBtn(e,n,t){return e.makeCheckMenuBtn("orient","Orientation",()=>[{section:"Rotate"},{label:"Rotate 90\xB0 clockwise",active:!1,onClick:()=>{const o=n().rotation??0;t({rotation:ROTATIONS[(ROTATIONS.indexOf(o)+1)%4]})}},{section:"Flip"},{label:"Flip horizontal",active:!!n().flipX,onClick:()=>t({flipX:!n().flipX})},{label:"Flip vertical",active:!!n().flipY,onClick:()=>t({flipY:!n().flipY})},{section:""},{label:"Reset orientation",active:!1,action:!0,enabled:!!(n().rotation||n().flipX||n().flipY),disabledHint:"Already in the original orientation",onClick:()=>t({rotation:0,flipX:!1,flipY:!1})}],o=>{const{rotation:i,flipX:a,flipY:d}=n();e.setActive(o,!!(i||a||d))})}let P=null;const fe=40,ze=fe+8;function _e(e,n){const t=e.createElement("div");t.classList.add("wmap-guide-search"),t.style.cssText="display:flex;align-items:center;gap:2px;margin-left:10px;flex:1;min-width:80px;max-width:260px;";const o=e.createElement("input");o.type="text",o.placeholder="Search guide\u2026",o.setAttribute("aria-label","Search guide"),o.style.cssText=`flex:1;min-width:0;padding:4px 8px;font-size:12px;background:${CLR.menuBg};color:${CLR.text};border:1px solid ${CLR.menuBorder};border-radius:${RADIUS.control};outline:none;`,o.addEventListener("focus",()=>{o.style.borderColor=CLR.iconActive}),o.addEventListener("blur",()=>{o.style.borderColor=CLR.menuBorder});const i=e.createElement("span");i.setAttribute("role","status"),i.setAttribute("aria-live","polite"),i.style.cssText=`font-size:12px;color:${CLR.label};min-width:44px;text-align:center;flex-shrink:0;white-space:nowrap;`;function a(x,u){const c=e.createElement("button");return c.type="button",c.textContent=x,c.setAttribute("aria-label",u),c.disabled=!0,c.style.cssText=`border:none;background:none;cursor:pointer;padding:4px 6px;border-radius:${RADIUS.control};font-size:12px;color:${CLR.label};flex-shrink:0;opacity:0.4;`,c.addEventListener("mouseenter",()=>{c.disabled||(c.style.background=CLR.bgHover)}),c.addEventListener("mouseleave",()=>{c.style.background="none"}),c}const d=a("\u25B2","Previous match"),r=a("\u25BC","Next match");let f=[],p=-1;function s(){const x=f.length===0;d.disabled=x,r.disabled=x,d.style.opacity=x?"0.4":"",r.style.opacity=x?"0.4":""}function g(){for(const x of f)x.parentNode?.replaceChild(e.createTextNode(x.textContent??""),x);n.normalize(),f=[],p=-1}function l(x){if(f.length===0)return;p>=0&&(f[p].style.outline="none"),p=(x%f.length+f.length)%f.length;const u=f[p];u.style.outline=`2px solid ${CLR.iconActive}`,u.style.outlineOffset="1px",u.scrollIntoView({behavior:"smooth",block:"center"}),i.textContent=`${p+1}/${f.length}`}function m(x){g();const u=x.trim();if(!u){i.textContent="",s();return}const c=u.toLowerCase(),b=e.createTreeWalker(n,NodeFilter.SHOW_TEXT,{acceptNode(C){const w=C.parentElement;return!w||w.closest("script,style,.wmap-guide-toc")?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT}}),v=[];let y;for(;y=b.nextNode();)v.push(y);for(const C of v){const w=C.textContent??"",M=w.toLowerCase();if(!M.includes(c))continue;const T=e.createDocumentFragment();let S=0,A=M.indexOf(c);for(;A!==-1;){A>S&&T.appendChild(e.createTextNode(w.slice(S,A)));const E=e.createElement("mark");E.textContent=w.slice(A,A+u.length),T.appendChild(E),f.push(E),S=A+u.length,A=M.indexOf(c,S)}S<w.length&&T.appendChild(e.createTextNode(w.slice(S))),C.parentNode?.replaceChild(T,C)}s(),f.length===0?i.textContent="No matches":l(0)}return o.addEventListener("input",()=>m(o.value)),o.addEventListener("keydown",x=>{x.key==="Enter"?(x.preventDefault(),l(p+(x.shiftKey?-1:1))):x.key==="Escape"&&(o.value?(o.value="",m("")):o.blur())}),d.addEventListener("click",()=>l(p-1)),r.addEventListener("click",()=>l(p+1)),t.append(o,i,d,r),t}function Ne(e,n,t){const o=[...n.querySelectorAll("h2[id]")];if(o.length<2)return;for(const u of n.querySelectorAll("h1[id],h2[id],h3[id],h4[id]"))u.style.scrollMarginTop=`${ze}px`;const i=e.createElement("div");i.classList.add("wmap-guide-toc"),i.style.cssText=`position:sticky;top:0;z-index:2;background:${CLR.menuBg};border-bottom:1px solid ${CLR.menuBorder};font-family:system-ui,-apple-system,"Segoe UI",sans-serif;`;const a=e.createElement("div");a.style.cssText=`display:flex;align-items:center;gap:4px;height:${fe}px;padding:0 12px;box-sizing:border-box;`;const d=e.createElement("span");d.innerHTML='<svg viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg>',d.style.cssText=`display:inline-flex;transition:transform ${MOTION.base};flex-shrink:0;`;const r=e.createElement("button");r.type="button";const f="wmap-guide-toc-panel";r.setAttribute("aria-expanded","false"),r.setAttribute("aria-controls",f),r.style.cssText=`display:flex;align-items:center;gap:6px;border:none;background:none;cursor:pointer;padding:6px 8px;margin:0 -8px 0 -8px;border-radius:${RADIUS.control};font-size:13px;font-weight:600;color:${CLR.text};`;const p=e.createElement("span");p.textContent=`Contents (${o.length})`,r.append(d,p),r.addEventListener("mouseenter",()=>{r.style.background=CLR.bgHover}),r.addEventListener("mouseleave",()=>{r.style.background="none"});const s=e.createElement("button");s.type="button",s.textContent="\u2191 Top",s.style.cssText=`margin-left:auto;border:none;background:none;cursor:pointer;padding:6px 8px;border-radius:${RADIUS.control};font-size:12px;color:${CLR.label};`,s.addEventListener("mouseenter",()=>{s.style.background=CLR.bgHover}),s.addEventListener("mouseleave",()=>{s.style.background="none"}),s.addEventListener("click",()=>{x.close(),n.scrollTo({top:0,behavior:"smooth"})}),t?a.append(r,_e(e,n),s):a.append(r,s);const g=e.createElement("div");g.id=f,g.hidden=!0,g.style.cssText="padding:2px 12px 12px;max-height:min(60vh,440px);overflow-y:auto;";const l=/^\s*\d+(?:\.\d+)*\.\s+/;for(const u of n.querySelectorAll("h2[id],h3[id],h4[id]")){const c=u.firstChild;c?.nodeType===Node.TEXT_NODE&&(c.textContent=(c.textContent??"").replace(l,""))}const m=e.createElement("ul");m.setAttribute("role","list"),m.style.cssText="list-style:none;margin:0;padding:0;columns:200px;column-gap:24px;";for(const u of o){const c=e.createElement("li");c.style.cssText="break-inside:avoid;";const b=e.createElement("a");b.href=`#${u.id}`,b.textContent=u.textContent??"",b.style.cssText=`display:block;padding:4px 6px;margin:0 -6px;border-radius:${RADIUS.control};font-size:12.5px;color:${CLR.iconActive};text-decoration:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;`,b.addEventListener("mouseenter",()=>{b.style.background=CLR.bgHover}),b.addEventListener("mouseleave",()=>{b.style.background="none"}),b.addEventListener("click",v=>{v.preventDefault(),x.close(),u.scrollIntoView({behavior:"smooth",block:"start"})}),c.appendChild(b),m.appendChild(c)}g.appendChild(m);const x=wireExpandToggle(r,u=>{g.hidden=!u,r.setAttribute("aria-expanded",String(u)),d.style.transform=u?"rotate(180deg)":"none"});i.append(a,g),n.prepend(i)}function me(e,n,t,o,i){const a=n,d=a.__wmapDemoApi;a.__wmapDemoApi=o;const r=e.createElement("div");return r.classList.add("wmap-guide-content"),r.innerHTML=t,Ne(e,r,i),{content:r,restoreApi:()=>{a.__wmapDemoApi===o&&(a.__wmapDemoApi=d)}}}function be(e,n){const t=n,o=e.querySelector("script");if(o){const i=e.ownerDocument.createElement("script");i.textContent=o.textContent,e.appendChild(i);const a=e.querySelector(".wmap-guide");return a&&t.__wmapPopulateGuideDemos?.(a),t.__wmapDestroyGuideDemos}}function Pe(e,n,t,o){const i=o?.ownerDocument??document,a=i.defaultView??window,{content:d,restoreApi:r}=me(i,a,n,t,!0);Object.assign(d.style,{flex:"1",overflow:"auto",minHeight:"0",minWidth:"0"});let f;const p=openFloatingWindow({title:e,anchor:o,ownerDocument:i,printable:!0,onMaximizeChange:s=>{d.style.setProperty("--wmap-guide-reading-width",s?"1000px":"720px")},onClose:()=>{P===p&&(P=null),f?.(),r()}});return p.contentWrap.appendChild(d),f=be(d,a),p}function Fe(e,n,t,o){const i=e.document;i.title=n,Object.assign(i.documentElement.style,{height:"100%"}),Object.assign(i.body.style,{margin:"0",height:"100vh",overflow:"hidden",display:"flex",flexDirection:"column",fontFamily:FONT.family}),copyWmapThemeTokens(document.documentElement,i.documentElement);const a=syncWmapPopupTheme(document.documentElement,i.documentElement),{content:d,restoreApi:r}=me(i,e,t,o,!1);Object.assign(d.style,{flex:"1",overflow:"auto",minHeight:"0",minWidth:"0"}),i.body.appendChild(d);const f=be(d,e);let p=!1;const s=()=>{if(!p){p=!0,clearInterval(g),a();try{f?.()}catch{}r(),P===l&&(P=null)}},g=setInterval(()=>{e.closed&&s()},400);e.addEventListener("pagehide",s);const l={close:()=>{e.closed||e.close(),s()}};return l}export function openUserGuideWindow(e,n,t,o){P&&(P.close(),P=null);const i=t?.title??"Wafer Map \u2014 User Guide",a=(t?.html??"")+n,r=(o?.ownerDocument.defaultView??window).open("","_blank","width=800,height=820");P=r?Fe(r,i,a,e):Pe(i,a,e,o)}export function openWaferMapGuide(e,n){Promise.all([import("./userGuideHtml.js"),import("./renderWaferMap.js"),import("./renderWaferGallery.js")]).then(([t,o,i])=>{openUserGuideWindow({buildWaferMap:Ae,renderWaferMap:o.renderWaferMap,renderWaferGallery:i.renderWaferGallery,analyzeWaferMap:Me},t.USER_GUIDE_HTML,e,n)})}export function openReportModal(e,n){const t=n?.ownerDocument??document,o=t.createElement("iframe");o.srcdoc=e,o.title="Summary report",Object.assign(o.style,{border:"0",width:"100%",flex:"1",minHeight:"0",background:"#fff"});const i=t.createElement("div");Object.assign(i.style,{display:"flex",justifyContent:"flex-end",padding:"6px 14px",borderBottom:`1px solid ${CLR.menuBorder}`,flexShrink:"0"});const a=t.createElement("button");a.type="button",wireControlHover(a,"bare"),a.textContent="Open as full page \u2197",Object.assign(a.style,{border:"none",background:"none",color:CLR.iconActive,cursor:"pointer",fontSize:FONT.body,textDecoration:"underline",padding:"0"}),a.addEventListener("click",()=>Ce(e)),i.appendChild(a);const d=openModal({title:"Summary report",anchor:n?.anchor,ownerDocument:t,printable:()=>o.contentWindow?.print(),onClose:()=>{}});return d.contentWrap.style.flexDirection="column",d.contentWrap.appendChild(i),d.contentWrap.appendChild(o),d}
|
|
9
|
+
}`,t.head.appendChild(te),reparentTooltip(i),n?(l.addEventListener("click",h=>{h.target===l&&H()}),t.addEventListener("keydown",R)):(i.addEventListener("keydown",R),i.addEventListener("mousedown",X),X()),nextFrame(()=>(c.isConnected?c:i).focus(),o),{backdrop:l,box:i,contentWrap:I,close:H,bringToFront:X}}export function openModal(e){return ue({...e,mode:"modal"})}export function openFloatingWindow(e){return ue({...e,mode:"window"})}const se=new WeakSet;export function openReparentedModal(e,n={}){if(e.length===0||e.some(r=>se.has(r)))return null;const t=e.map(r=>({el:r,parent:r.parentElement,next:r.nextSibling})),o=openModal({ownerDocument:n.ownerDocument,title:n.title,boxSize:n.boxSize,anchor:e[0],onClose:()=>{for(const r of t){if(se.delete(r.el),!r.parent)continue;const l=r.next&&r.next.parentNode===r.parent?r.next:null;r.parent.insertBefore(r.el,l)}n.onClosed?.()}});for(const r of t)se.add(r.el),o.contentWrap.appendChild(r.el);return o}export function makePaletteBtn(e,n,t,o){const r=e.makeCheckMenuBtn("palette","Colour scheme",()=>{const u=n(),i=[];if(u.plotMode==="hardBin"||u.plotMode==="softBin"){const f=u.binColorScheme??"default";i.push({section:"Bin colours"});for(const m of we())i.push({label:m.label,active:f===m.name,onClick:()=>o({binColorScheme:m.name})});if(t()){const m=u.useDefinedBinColors??!0;i.push({section:"Bin definitions"}),i.push({label:"Use colours from bin definitions",active:m,onClick:()=>o({useDefinedBinColors:!m})})}}else{const f=u.valueColorScheme??"default";i.push({section:"Value colours"});for(const s of ke())i.push({label:s.label,active:f===s.name,onClick:()=>o({valueColorScheme:s.name})});const m=u.reverseValueScheme??!1;i.push({section:"Direction"}),i.push({label:"Reverse gradient",active:m,onClick:()=>o({reverseValueScheme:!m})})}return i},()=>{});function l(){r.style.display=n().plotMode==="metadata"?"none":""}return{btn:r,sync:l}}export function requestedPassFailDisplay(e){return e.passFailDisplay??"off"}export function overlayMenuRows(e,n,t,o){return[{label:"Ring boundaries",active:!!e.showRingBoundaries,onClick:()=>o({showRingBoundaries:!e.showRingBoundaries})},{label:"Quadrant lines",active:!!e.showQuadrantBoundaries,onClick:()=>o({showQuadrantBoundaries:!e.showQuadrantBoundaries})},{label:"Die labels",active:!!e.showDieLabels,onClick:()=>o({showDieLabels:!e.showDieLabels})},{label:"Reticle grid",active:!!e.showReticle,enabled:n,onClick:()=>o({showReticle:!e.showReticle})},{label:"XY indicator",active:!!e.showXYIndicator,onClick:()=>o({showXYIndicator:!e.showXYIndicator})},...passFailMenuRows({...t,display:requestedPassFailDisplay(e)},r=>o({passFailDisplay:r})),{label:"Mark failing dies",active:!!e.markFailingDies,enabled:t.binMode,disabledHint:t.binMode?void 0:"Available on hard/soft bin maps",onClick:()=>o({markFailingDies:!e.markFailingDies})},{section:""},{label:"Clear overlays",active:!1,action:!0,enabled:anyOverlayActive(e),disabledHint:"No overlays are active",onClick:()=>o({showRingBoundaries:!1,showQuadrantBoundaries:!1,showDieLabels:!1,showReticle:!1,showXYIndicator:!1,passFailDisplay:"off",markFailingDies:!1})}]}export function anyOverlayActive(e){return!!(e.showRingBoundaries||e.showQuadrantBoundaries||e.showDieLabels||e.showReticle||e.showXYIndicator||e.markFailingDies||requestedPassFailDisplay(e)!=="off")}export function passFailMenuRows(e,n){if(e.functionalActive)return[];const t=[];return e.hasLimits&&t.push({label:"Spec pass/fail",active:e.display==="spec",onClick:()=>n(e.display==="spec"?"off":"spec")}),e.hasRecorded&&t.push({label:"Test pass/fail",active:e.display==="test",onClick:()=>n(e.display==="test"?"off":"test")}),t}export function makeLogScaleBtn(e,n,t){const o=e.makeBtn("logScale","Toggle log scale",()=>{t({logScale:!n().logScale})});function r(){const l=n(),u=l.plotMode,i=u==="value"||u==="stackedValues";o.style.display=i&&requestedPassFailDisplay(l)==="off"&&!l.functionalActive?"":"none",e.setActive(o,!!l.logScale)}return{btn:o,sync:r}}const We=[{value:"default",label:"Default (right)"},{value:"compact",label:"Compact (right)"},{value:"left",label:"Left"},{value:"top",label:"Top"},{value:"bottom",label:"Bottom"},{value:"floating",label:"Floating"}];export function makeLegendStyleBtn(e,n,t,o){const r=e.makeCheckMenuBtn("legend","Legend style",()=>{const u=n().legendPosition??"default",i=[];let f=!0;if(o){const m=o.blockedReason();f=m?!0:o.get(),i.push({label:"Legend on each map",active:f,enabled:!m,disabledHint:m??void 0,onClick:()=>o.set(!o.get())})}if(pe(n().plotMode)){o&&i.push({section:"Position on each map"});for(const m of We)i.push({label:m.label,active:f&&u===m.value,enabled:f,disabledHint:f?void 0:'Turn on "Legend on each map" to position it',onClick:()=>t(m.value)})}return i},()=>{});function l(){r.style.display=o||pe(n().plotMode)?"":"none"}return{btn:r,sync:l}}function pe(e){return e==="hardBin"||e==="softBin"||e==="metadata"}export function makeOverlaysBtn(e,n,t){return e.makeCheckMenuBtn("overlays","Overlays",()=>n(),o=>e.setActive(o,t()))}export function makeOrientationBtn(e,n,t){return e.makeCheckMenuBtn("orient","Orientation",()=>[{section:"Rotate"},{label:"Rotate 90\xB0 clockwise",active:!1,onClick:()=>{const o=n().rotation??0;t({rotation:ROTATIONS[(ROTATIONS.indexOf(o)+1)%4]})}},{section:"Flip"},{label:"Flip horizontal",active:!!n().flipX,onClick:()=>t({flipX:!n().flipX})},{label:"Flip vertical",active:!!n().flipY,onClick:()=>t({flipY:!n().flipY})},{section:""},{label:"Reset orientation",active:!1,action:!0,enabled:!!(n().rotation||n().flipX||n().flipY),disabledHint:"Already in the original orientation",onClick:()=>t({rotation:0,flipX:!1,flipY:!1})}],o=>{const{rotation:r,flipX:l,flipY:u}=n();e.setActive(o,!!(r||l||u))})}let P=null;const fe=40,ze=fe+8;function _e(e,n){const t=e.createElement("div");t.classList.add("wmap-guide-search"),t.style.cssText="display:flex;align-items:center;gap:2px;margin-left:10px;flex:1;min-width:80px;max-width:260px;";const o=e.createElement("input");o.type="text",o.placeholder="Search guide\u2026",o.setAttribute("aria-label","Search guide"),o.style.cssText=`flex:1;min-width:0;padding:4px 8px;font-size:12px;background:${CLR.menuBg};color:${CLR.text};border:1px solid ${CLR.menuBorder};border-radius:${RADIUS.control};outline:none;`,o.addEventListener("focus",()=>{o.style.borderColor=CLR.iconActive}),o.addEventListener("blur",()=>{o.style.borderColor=CLR.menuBorder});const r=e.createElement("span");r.setAttribute("role","status"),r.setAttribute("aria-live","polite"),r.style.cssText=`font-size:12px;color:${CLR.label};min-width:44px;text-align:center;flex-shrink:0;white-space:nowrap;`;function l(x,d){const c=e.createElement("button");return c.type="button",c.textContent=x,c.setAttribute("aria-label",d),c.disabled=!0,c.style.cssText=`border:none;background:none;cursor:pointer;padding:4px 6px;border-radius:${RADIUS.control};font-size:12px;color:${CLR.label};flex-shrink:0;opacity:0.4;`,c.addEventListener("mouseenter",()=>{c.disabled||(c.style.background=CLR.bgHover)}),c.addEventListener("mouseleave",()=>{c.style.background="none"}),c}const u=l("\u25B2","Previous match"),i=l("\u25BC","Next match");let f=[],m=-1;function s(){const x=f.length===0;u.disabled=x,i.disabled=x,u.style.opacity=x?"0.4":"",i.style.opacity=x?"0.4":""}function y(){for(const x of f)x.parentNode?.replaceChild(e.createTextNode(x.textContent??""),x);n.normalize(),f=[],m=-1}function a(x){if(f.length===0)return;m>=0&&(f[m].style.outline="none"),m=(x%f.length+f.length)%f.length;const d=f[m];d.style.outline=`2px solid ${CLR.iconActive}`,d.style.outlineOffset="1px",d.scrollIntoView({behavior:"smooth",block:"center"}),r.textContent=`${m+1}/${f.length}`}function p(x){y();const d=x.trim();if(!d){r.textContent="",s();return}const c=d.toLowerCase(),b=e.createTreeWalker(n,NodeFilter.SHOW_TEXT,{acceptNode(A){const C=A.parentElement;return!C||C.closest("script,style,.wmap-guide-toc")?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT}}),v=[];let w;for(;w=b.nextNode();)v.push(w);for(const A of v){const C=A.textContent??"",L=C.toLowerCase();if(!L.includes(c))continue;const T=e.createDocumentFragment();let B=0,M=L.indexOf(c);for(;M!==-1;){M>B&&T.appendChild(e.createTextNode(C.slice(B,M)));const g=e.createElement("mark");g.textContent=C.slice(M,M+d.length),T.appendChild(g),f.push(g),B=M+d.length,M=L.indexOf(c,B)}B<C.length&&T.appendChild(e.createTextNode(C.slice(B))),A.parentNode?.replaceChild(T,A)}s(),f.length===0?r.textContent="No matches":a(0)}return o.addEventListener("input",()=>p(o.value)),o.addEventListener("keydown",x=>{x.key==="Enter"?(x.preventDefault(),a(m+(x.shiftKey?-1:1))):x.key==="Escape"&&(o.value?(o.value="",p("")):o.blur())}),u.addEventListener("click",()=>a(m-1)),i.addEventListener("click",()=>a(m+1)),t.append(o,r,u,i),t}function Ne(e,n,t){const o=[...n.querySelectorAll("h2[id]")];if(o.length<2)return;for(const d of n.querySelectorAll("h1[id],h2[id],h3[id],h4[id]"))d.style.scrollMarginTop=`${ze}px`;const r=e.createElement("div");r.classList.add("wmap-guide-toc"),r.style.cssText=`position:sticky;top:0;z-index:2;background:${CLR.menuBg};border-bottom:1px solid ${CLR.menuBorder};font-family:system-ui,-apple-system,"Segoe UI",sans-serif;`;const l=e.createElement("div");l.style.cssText=`display:flex;align-items:center;gap:4px;height:${fe}px;padding:0 12px;box-sizing:border-box;`;const u=e.createElement("span");u.innerHTML='<svg viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg>',u.style.cssText=`display:inline-flex;transition:transform ${MOTION.base};flex-shrink:0;`;const i=e.createElement("button");i.type="button";const f="wmap-guide-toc-panel";i.setAttribute("aria-expanded","false"),i.setAttribute("aria-controls",f),i.style.cssText=`display:flex;align-items:center;gap:6px;border:none;background:none;cursor:pointer;padding:6px 8px;margin:0 -8px 0 -8px;border-radius:${RADIUS.control};font-size:13px;font-weight:600;color:${CLR.text};`;const m=e.createElement("span");m.textContent=`Contents (${o.length})`,i.append(u,m),i.addEventListener("mouseenter",()=>{i.style.background=CLR.bgHover}),i.addEventListener("mouseleave",()=>{i.style.background="none"});const s=e.createElement("button");s.type="button",s.textContent="\u2191 Top",s.style.cssText=`margin-left:auto;border:none;background:none;cursor:pointer;padding:6px 8px;border-radius:${RADIUS.control};font-size:12px;color:${CLR.label};`,s.addEventListener("mouseenter",()=>{s.style.background=CLR.bgHover}),s.addEventListener("mouseleave",()=>{s.style.background="none"}),s.addEventListener("click",()=>{x.close(),n.scrollTo({top:0,behavior:"smooth"})}),t?l.append(i,_e(e,n),s):l.append(i,s);const y=e.createElement("div");y.id=f,y.hidden=!0,y.style.cssText="padding:2px 12px 12px;max-height:min(60vh,440px);overflow-y:auto;";const a=/^\s*\d+(?:\.\d+)*\.\s+/;for(const d of n.querySelectorAll("h2[id],h3[id],h4[id]")){const c=d.firstChild;c?.nodeType===Node.TEXT_NODE&&(c.textContent=(c.textContent??"").replace(a,""))}const p=e.createElement("ul");p.setAttribute("role","list"),p.style.cssText="list-style:none;margin:0;padding:0;columns:200px;column-gap:24px;";for(const d of o){const c=e.createElement("li");c.style.cssText="break-inside:avoid;";const b=e.createElement("a");b.href=`#${d.id}`,b.textContent=d.textContent??"",b.style.cssText=`display:block;padding:4px 6px;margin:0 -6px;border-radius:${RADIUS.control};font-size:12.5px;color:${CLR.iconActive};text-decoration:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;`,b.addEventListener("mouseenter",()=>{b.style.background=CLR.bgHover}),b.addEventListener("mouseleave",()=>{b.style.background="none"}),b.addEventListener("click",v=>{v.preventDefault(),x.close(),d.scrollIntoView({behavior:"smooth",block:"start"})}),c.appendChild(b),p.appendChild(c)}y.appendChild(p);const x=wireExpandToggle(i,d=>{y.hidden=!d,i.setAttribute("aria-expanded",String(d)),u.style.transform=d?"rotate(180deg)":"none"});r.append(l,y),n.prepend(r)}function me(e,n,t,o,r){const l=n,u=l.__wmapDemoApi;l.__wmapDemoApi=o;const i=e.createElement("div");return i.classList.add("wmap-guide-content"),i.innerHTML=t,Ne(e,i,r),{content:i,restoreApi:()=>{l.__wmapDemoApi===o&&(l.__wmapDemoApi=u)}}}function be(e,n){const t=n,o=e.querySelector("script");if(o){const r=e.ownerDocument.createElement("script");r.textContent=o.textContent,e.appendChild(r);const l=e.querySelector(".wmap-guide");return l&&t.__wmapPopulateGuideDemos?.(l),t.__wmapDestroyGuideDemos}}function Pe(e,n,t,o){const r=o?.ownerDocument??document,l=r.defaultView??window,{content:u,restoreApi:i}=me(r,l,n,t,!0);Object.assign(u.style,{flex:"1",overflow:"auto",minHeight:"0",minWidth:"0"});let f;const m=openFloatingWindow({title:e,anchor:o,ownerDocument:r,printable:!0,onMaximizeChange:s=>{u.style.setProperty("--wmap-guide-reading-width",s?"1000px":"720px")},onClose:()=>{P===m&&(P=null),f?.(),i()}});return m.contentWrap.appendChild(u),f=be(u,l),m}function Fe(e,n,t,o){const r=e.document;r.title=n,Object.assign(r.documentElement.style,{height:"100%"}),Object.assign(r.body.style,{margin:"0",height:"100vh",overflow:"hidden",display:"flex",flexDirection:"column",fontFamily:FONT.family}),copyWmapThemeTokens(document.documentElement,r.documentElement);const l=syncWmapPopupTheme(document.documentElement,r.documentElement),{content:u,restoreApi:i}=me(r,e,t,o,!1);Object.assign(u.style,{flex:"1",overflow:"auto",minHeight:"0",minWidth:"0"}),r.body.appendChild(u);const f=be(u,e);let m=!1;const s=()=>{if(!m){m=!0,clearInterval(y),l();try{f?.()}catch{}i(),P===a&&(P=null)}},y=setInterval(()=>{e.closed&&s()},400);e.addEventListener("pagehide",s);const a={close:()=>{e.closed||e.close(),s()}};return a}export function openUserGuideWindow(e,n,t,o){P&&(P.close(),P=null);const r=t?.title??"Wafer Map \u2014 User Guide",l=(t?.html??"")+n,i=(o?.ownerDocument.defaultView??window).open("","_blank","width=800,height=820");P=i?Fe(i,r,l,e):Pe(r,l,e,o)}export function openWaferMapGuide(e,n){Promise.all([import("./userGuideHtml.js"),import("./renderWaferMap.js"),import("./renderWaferGallery.js")]).then(([t,o,r])=>{openUserGuideWindow({buildWaferMap:Ae,renderWaferMap:o.renderWaferMap,renderWaferGallery:r.renderWaferGallery,analyzeWaferMap:Me},t.USER_GUIDE_HTML,e,n)})}export function openReportModal(e,n){const t=n?.ownerDocument??document,o=t.createElement("iframe");o.srcdoc=e,o.title="Summary report",Object.assign(o.style,{border:"0",width:"100%",flex:"1",minHeight:"0",background:"#fff"});const r=t.createElement("div");Object.assign(r.style,{display:"flex",justifyContent:"flex-end",padding:"6px 14px",borderBottom:`1px solid ${CLR.menuBorder}`,flexShrink:"0"});const l=t.createElement("button");l.type="button",wireControlHover(l,"bare"),l.textContent="Open as full page \u2197",Object.assign(l.style,{border:"none",background:"none",color:CLR.iconActive,cursor:"pointer",fontSize:FONT.body,textDecoration:"underline",padding:"0"}),l.addEventListener("click",()=>Le(e)),r.appendChild(l);const u=openModal({title:"Summary report",anchor:n?.anchor,ownerDocument:t,printable:()=>o.contentWindow?.print(),onClose:()=>{}});return u.contentWrap.style.flexDirection="column",u.contentWrap.appendChild(r),u.contentWrap.appendChild(o),u}
|