@wafertools/wafermap 0.25.0 → 0.26.1

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.
@@ -1,3 +1,3 @@
1
- import{isParametricTest as xt}from"../renderer/buildWaferMap.js";import{buildRingRegions as K,buildQuadrantRegions as Z,buildRegionYieldData as bt}from"../stats/regions.js";import{computeFunctionalYield as vt}from"../stats/analyzeWaferMap.js";import{openHtmlReport as J}from"../stats/renderFindingsReport.js";import{renderSummaryReportHtml as wt,renderLotSummaryReportHtml as yt}from"../stats/renderSummaryReport.js";import{buildFindingsNarrative as Ct}from"../stats/findingsNarrative.js";import{filterFindings as St}from"../stats/filterFindings.js";import{buildFacetTable as kt,prettyKey as tt}from"../stats/facets.js";import{commonMetadata as et}from"../stats/facets.js";import{resolveMetadataColumns as Bt}from"../stats/metadataColumns.js";import{getColorScheme as $t}from"../renderer/colorSchemes.js";import{buildWarningsBanner as _,collectWarnings as nt}from"./warnings.js";export{_ as buildWarningsBanner};import{fmt as it,fmtAggregationMethod as Lt,plainBinTerms as P}from"../renderer/fmt.js";import{getUniqueTestNumbers as Dt}from"../renderer/buildView.js";import{quantile as Q}from"../stats/math.js";import{makeLabeledSelect as ot}from"./charts/chartShell.js";import{CLR as v,sevColor as G,openModal as at,saveTextFile as rt}from"./toolbar.js";import{buildDieListSection as Rt}from"./dieList.js";import{medianOfSorted as Ft}from"../core/utils.js";import{metadataDisplayValue as Tt}from"../core/metadata.js";const Et=v.panelBg,Y=`1px solid ${v.menuBorder}`,Nt="12px",I=v.label,z=v.value,st="10px";function l(t,i,n,e=document){const o=e.createElement(t);return i&&Object.assign(o.style,i),n!==void 0&&(o.textContent=n),o}function H(t){return l("div",{fontSize:st,fontWeight:"700",letterSpacing:"0.06em",textTransform:"uppercase",color:I,marginBottom:"6px"},t)}function lt(t,i=!0,n){const e=l("div"),o=document.createElement("button");o.type="button",Object.assign(o.style,{display:"flex",alignItems:"center",gap:"4px",width:"100%",background:"none",border:"none",cursor:"pointer",padding:"0 0 6px",textAlign:"left"});const d=l("span",{fontSize:"9px",color:I,transition:"transform 0.15s",transform:i?"rotate(90deg)":"rotate(0deg)",display:"inline-block",lineHeight:"1",marginRight:"1px"},"\u25B6"),f=l("span",{fontSize:st,fontWeight:"700",letterSpacing:"0.06em",textTransform:"uppercase",color:I,flex:"1"},t);if(o.setAttribute("aria-expanded",i?"true":"false"),o.appendChild(d),o.appendChild(f),n){const a=l("span",{fontSize:"9px",fontWeight:"700",background:v.warnBg,color:v.warnText,borderRadius:"10px",padding:"1px 5px"},n);o.appendChild(a)}const c=l("div");c.style.display=i?"block":"none";let s=i;return o.addEventListener("click",()=>{s=!s,c.style.display=s?"block":"none",d.style.transform=s?"rotate(90deg)":"rotate(0deg)",o.setAttribute("aria-expanded",s?"true":"false")}),e.appendChild(o),e.appendChild(c),{outer:e,content:c}}function dt(){return l("div",{height:"1px",background:v.separator,margin:`${Nt} 0`,flexShrink:"0"})}function U(t,i,n=v.barFill,e,o,d){const f=l("div",{marginBottom:"5px"}),c=l("div",{display:"flex",justifyContent:"space-between",fontSize:"11px",color:z,marginBottom:"2px"}),s=l("span",{},t),a=l("span",{fontWeight:"600"},`${i.toFixed(1)}%`);c.appendChild(s),c.appendChild(a);const p=e!==void 0?e:Math.min(100,Math.max(0,i)),h=d?v.barFillMuted:n,g=l("div",{position:"relative",height:"9px",background:v.bgActive,borderRadius:"4px",overflow:"hidden"}),T=l("div",{height:"100%",width:`${p}%`,background:h,borderRadius:"4px",transition:"width 0.3s ease"});if(g.appendChild(T),o!==void 0){const N=l("div",{position:"absolute",top:"0",bottom:"0",left:`${o}%`,width:"1px",background:v.infoText,opacity:"0.5"});g.appendChild(N)}return f.appendChild(c),f.appendChild(g),f}function O(t,i,n){const e=l("div",{background:v.menuBg,border:Y,borderRadius:"6px",padding:"8px 10px",textAlign:"center",flex:"1"}),o=l("div",{fontSize:"20px",fontWeight:"700",color:z,lineHeight:"1.2"},t),d=l("div",{fontSize:"10px",color:I,marginTop:"2px"},i);return e.appendChild(o),e.appendChild(d),n&&e.appendChild(l("div",{fontSize:"9px",color:I,opacity:"0.85"},n)),e}function Mt(t,i){const n=l("div",{display:"flex",justifyContent:"space-between",fontSize:"11px",gap:"8px",marginBottom:"3px"}),e=l("span",{color:I,flexShrink:"0"},t),o=l("span",{color:z,textAlign:"right",fontWeight:"500",wordBreak:"break-all"},i);return n.appendChild(e),n.appendChild(o),n}function Wt(t,i){const n=l("div",{display:"flex",fontSize:"11px",gap:"6px",marginBottom:"3px"}),e=l("span",{color:I,flexShrink:"0"},`${t}:`),o=l("span",{color:z,fontWeight:"500",wordBreak:"break-all"},i);return n.appendChild(e),n.appendChild(o),n}export function metadataEntries(t){const i=[];for(const[n,e]of Object.entries(t)){const o=Tt(e);o!==void 0&&i.push([n,o])}return i}export function buildFacetSummaryChips(t,i=3){if(!t.length)return null;const n=l("div",{display:"flex",flexWrap:"wrap",alignItems:"baseline",gap:"4px 10px",fontSize:"11px"});for(const e of t){const o=l("span",{whiteSpace:"nowrap"}),d=l("span",{color:I},`${tt(e.key)}: `);o.appendChild(d);const f=e.values.slice(0,i),c=e.values.length-f.length;let s=f.map(a=>a.value).join(", ");c>0&&(s+=` +${c} more`),o.appendChild(document.createTextNode(s)),n.appendChild(o)}return n}export function buildMetadataStripRow(t,i,n){const e=kt(t,n),o=buildFacetSummaryChips(e);if(!o&&!i)return null;const d=l("div",{display:"flex",flexWrap:"wrap",alignItems:"baseline",gap:"4px 14px"});if(i){const f=l("span",{fontWeight:"500",whiteSpace:"nowrap"},i.aggrMethod?`${i.lotSize} wafers stacked \xB7 ${i.aggrMethod}`:`${i.lotSize} wafers stacked`);d.appendChild(f)}return o&&d.appendChild(o),d}const It={display:"flex",flexDirection:"column",gap:"6px",background:v.menuBg,border:`1px solid ${v.menuBorder}`,borderRadius:"6px",padding:"6px 10px",boxShadow:"0 1px 4px rgba(0,0,0,0.10)",fontSize:"12px",lineHeight:"1",boxSizing:"border-box",width:"100%",minWidth:"0"};export function buildMetadataStripBox(t,i,n){const e=buildMetadataStripRow(t,i,n);if(!e)return null;const o=l("div",It);return o.appendChild(e),o}export function buildCompactMetadataRows(t){const i=metadataEntries(t);if(!i.length)return null;const n=l("div");for(const[e,o]of i)n.appendChild(Wt(tt(e),o));return n}export function buildMetadataInfoSection(t,i){const n=buildMetadataStripRow(t,i,{facetableOnly:t.length>1});if(!n)return null;const e=l("div");return e.appendChild(H("Wafer Info")),e.appendChild(n),e}export function buildYieldSection(t,i,n=[1]){const e=l("div");e.appendChild(H("Summary"));const o=l("div",{display:"flex",gap:"6px",marginBottom:"8px"});if(o.appendChild(O(String(t.totalDies),"Total dies")),t.partialDies>0&&o.appendChild(O(String(t.partialDies),"Partial")),t.yieldPercent!==null){const d=n.length===1?`bin ${n[0]}`:`bins ${n.join(", ")}`;o.appendChild(O(`${t.yieldPercent.toFixed(1)}%`,"Yield",`pass: ${d}`))}return e.appendChild(o),t.edgeExcludedDies>0&&e.appendChild(Mt("Edge excluded (outer zone)",String(t.edgeExcludedDies))),e}export function buildBinSection(t,i,n,e,o){const d=new Map;if(o)for(const[p,h]of Object.entries(o))d.set(Number(p),h);else for(const p of t){if(p.partial||p.edgeExcluded)continue;const h=n==="hard"?p.hbin:p.sbin;h!=null&&d.set(h,(d.get(h)??0)+1)}if(!d.size)return null;const f=[...d.values()].reduce((p,h)=>p+h,0),c=i?new Map(i.map(p=>[p.bin,p])):null,s=[...d.entries()].sort((p,h)=>p[0]-h[0]),a=l("div");a.appendChild(H(n==="hard"?"Hard Bin Breakdown":"Soft Bin Breakdown"));for(const[p,h]of s){const g=c?.get(p),T=g?.name?`Bin ${p} \xB7 ${g.name}`:`Bin ${p}`,N=h/f*100,B=$t(e),E=(e==="custom"?g?.color:void 0)??B.forBin(p);a.appendChild(U(`${T} (${h})`,N,E))}return a}export function buildLotBinSection(t,i,n,e){return buildBinSection(t,i,n,e)}function j(t,i,n,e,o,d){const f=bt(t,i,n,e,o);if(!f.length)return null;const c=l("div");c.appendChild(H(d));for(const{label:s,n:a,yieldPercent:p}of f)c.appendChild(U(`${s} (N=${a})`,p));return c}export function buildRingSection(t,i,n,e){return j([t],[i],n,e,K,"Ring Yield")}export function buildQuadrantSection(t,i,n,e){return j([t],[i],n,e,Z,"Quadrant Yield")}export function buildLotRingSection(t,i,n,e){return j(t,i,n,e,K,"Ring Yield")}export function buildLotQuadrantSection(t,i,n,e){return j(t,i,n,e,Z,"Quadrant Yield")}export function buildLotOverviewSection(t){const i=l("div");i.appendChild(H("Lot Summary"));const n=l("div",{display:"flex",gap:"6px",marginBottom:"8px"});n.appendChild(O(String(t.stats.waferCount),"Wafers"));const e=t.perWafer.map(o=>o.summary.stats.yieldPercent).filter(o=>o!==null);if(e.length){const o=e.reduce((d,f)=>d+f,0)/e.length;n.appendChild(O(`${o.toFixed(1)}%`,"Mean wafer yield"))}return i.appendChild(n),i}export function buildPerWaferYieldSection(t,i,n){const e=t.perWafer.map(a=>({waferIndex:a.waferIndex,label:(i[a.waferIndex]?.label??`W${a.waferIndex+1}`).replace(/\s*·\s*\d+(\.\d+)?%$/,""),yieldPct:a.summary.stats.yieldPercent})).filter(a=>a.yieldPct!==null);if(!e.length)return null;const o=Math.min(...e.map(a=>a.yieldPct)),d=Math.max(...e.map(a=>a.yieldPct)),f=o===d?"":` (${o.toFixed(1)}\u2013${d.toFixed(1)}%)`,c=Ft([...e.map(a=>a.yieldPct)].sort((a,p)=>a-p)),s=l("div");s.appendChild(H("Wafer Yield"+f));for(const{waferIndex:a,label:p,yieldPct:h}of e){const g=U(p,h,void 0,void 0,c,h<c);n&&(g.style.cursor="pointer",g.style.borderRadius="4px",g.style.padding="2px 3px",g.style.marginLeft="-3px",g.style.marginRight="-3px",g.setAttribute("role","button"),g.setAttribute("aria-label",`${p}, ${h.toFixed(1)}% yield \u2014 view wafer`),g.tabIndex=0,g.addEventListener("mouseenter",()=>{g.style.background=v.bgHover}),g.addEventListener("mouseleave",()=>{g.style.background=""}),g.addEventListener("focus",()=>{g.style.background=v.bgHover}),g.addEventListener("blur",()=>{g.style.background=""}),g.addEventListener("click",()=>n(a)),g.addEventListener("keydown",T=>{(T.key==="Enter"||T.key===" ")&&(T.preventDefault(),n(a))})),s.appendChild(g)}return s}function zt(t){const i=[...t].sort((o,d)=>o-d),n=t.reduce((o,d)=>o+d,0)/t.length,e=t.reduce((o,d)=>o+(d-n)**2,0)/t.length;return{min:i[0],max:i[i.length-1],mean:n,count:t.length,stddev:Math.sqrt(e),median:Q(i,.5),q1:Q(i,.25),q3:Q(i,.75)}}function pt(t,i){if(!t)return[];const n=t.waferMetadata??(t.perWaferMetadata?et(t.perWaferMetadata.map(e=>({metadata:e}))):void 0);return!n||!Object.keys(n).length?[]:Bt({waferMetadata:n,waferPlacement:"csv",reservedLabels:i}).columns}export function csvField(t){return/[",\n]/.test(t)?`"${t.replace(/"/g,'""')}"`:t}export function buildTestSection(t,i,n,e,o,d){const f=t.filter(r=>!r.partial&&!r.edgeExcluded),c=new Map((e?.perTestStats??[]).map(r=>[r.testNumber,r])),s=new Map((e?.testSpecYield??[]).map(r=>[r.testNumber,r]));let a;if(i?.length?a=i.filter(xt).map(r=>({testNumber:r.testNumber,name:r.name,unit:r.unit,limitLow:r.limitLow,limitHigh:r.limitHigh})):a=Dt(f).map(m=>({testNumber:m,name:`Test ${m}`})),!a.length)return null;const p=a.filter(r=>f.some(m=>{const D=m.testValues?.[r.testNumber];return D!==void 0&&isFinite(D)}));if(!p.length)return null;const h=p.some(r=>r.limitLow!==void 0||r.limitHigh!==void 0),g=[];for(const r of p){const m=c.get(r.testNumber),D=m&&m.stddev!==void 0&&m.median!==void 0&&m.q1!==void 0&&m.q3!==void 0;let y;if(D){const b=m;y={testNumber:r.testNumber,min:b.min,max:b.max,mean:b.mean,count:b.count,stddev:b.stddev,median:b.median,q1:b.q1,q3:b.q3}}else{const b=f.map(F=>F.testValues?.[r.testNumber]).filter(F=>F!==void 0&&isFinite(F));if(!b.length)continue;y={testNumber:r.testNumber,...zt(b)}}let x=null,S=0;if(r.limitLow!==void 0||r.limitHigh!==void 0){const b=s.get(r.testNumber);if(b)({yieldPercent:x,totalDies:S}=b);else{const F=f.map(w=>w.testValues?.[r.testNumber]).filter(w=>w!==void 0&&isFinite(w)),W=F.filter(w=>r.limitLow!==void 0&&w<r.limitLow||r.limitHigh!==void 0&&w>r.limitHigh).length;S=F.length,x=F.length>0?(F.length-W)/F.length*100:null}}g.push({entry:r,stats:y,specYieldPct:x,specN:S})}if(!g.length)return null;const T=l("div"),N=l("div",{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:"6px"}),B=H(d?.populationLabel?`Test Values (${g.length}) \u2014 ${d.populationLabel}`:`Test Values (${g.length})`);B.style.marginBottom="0",N.appendChild(B);const E=document.createElement("button");E.type="button",E.textContent="Export CSV",Object.assign(E.style,{background:"none",border:Y,borderRadius:"4px",cursor:"pointer",fontSize:"10px",color:v.iconHover,padding:"2px 7px"}),E.addEventListener("click",()=>{const r=["Test","Unit","N","Min","Q1","Median","Mean","Q3","Max","StdDev"];h&&r.push("LSL","USL","Spec Yield %","Spec Yield N");const m=pt(d,r),y=[[...m.map(S=>S.label),...r].map(csvField).join(",")],x=S=>it(S,void 0,"engineering");for(const{entry:S,stats:b,specYieldPct:F,specN:W}of g){const w=[...m.map(M=>M.constant??""),S.name,S.unit??"",String(b.count),x(b.min),x(b.q1),x(b.median),x(b.mean),x(b.q3),x(b.max),x(b.stddev)];h&&w.push(S.limitLow!==void 0?x(S.limitLow):"",S.limitHigh!==void 0?x(S.limitHigh):"",F!==null?F.toFixed(1):"",S.limitLow!==void 0||S.limitHigh!==void 0?String(W):""),y.push(w.map(csvField).join(","))}rt(y.join(`
2
- `),"test-values.csv","text/csv",o)}),N.appendChild(E),T.appendChild(N);const R=l("table",{width:"100%",borderCollapse:"collapse",fontSize:"11px"}),L=document.createElement("thead"),u=document.createElement("tr"),$=["Test","N","Min","Q1","Median","Mean","Q3","Max","StdDev"];h&&$.push("LSL","USL","Spec yield");for(const r of $){const m=l("th",{textAlign:r==="Test"?"left":"right",fontWeight:"700",fontSize:"10px",letterSpacing:"0.03em",textTransform:"uppercase",color:I,padding:"3px 8px 5px",borderBottom:`1px solid ${v.menuBorder}`,whiteSpace:"nowrap"},r);u.appendChild(m)}L.appendChild(u),R.appendChild(L);const k=document.createElement("tbody");for(const{entry:r,stats:m,specYieldPct:D,specN:y}of g){const x=F=>it(F,r.unit,n),S=document.createElement("tr"),b=(F,W="right")=>{const w=l("td",{textAlign:W,padding:"4px 8px",borderBottom:`1px solid ${v.menuBorder}`,color:z,whiteSpace:"nowrap"},F);S.appendChild(w)};b(r.name,"left"),b(`${m.count}`),b(x(m.min)),b(x(m.q1)),b(x(m.median)),b(x(m.mean)),b(x(m.q3)),b(x(m.max)),b(x(m.stddev)),h&&(b(r.limitLow!==void 0?x(r.limitLow):"\u2014"),b(r.limitHigh!==void 0?x(r.limitHigh):"\u2014"),b(D!==null?`${D.toFixed(1)}% (N=${y})`:"\u2014")),k.appendChild(S)}R.appendChild(k);const C=l("div",{overflowX:"auto"});return C.appendChild(R),T.appendChild(C),T}export function buildFunctionalTestSection(t,i,n,e,o){const d=n??vt(t,i);if(!d?.length)return null;const f=l("div"),c=l("div",{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:"6px"}),s=H(o?.populationLabel?`Functional Tests (${d.length}) \u2014 ${o.populationLabel}`:`Functional Tests (${d.length})`);s.style.marginBottom="0",c.appendChild(s);const a=document.createElement("button");a.type="button",a.textContent="Export CSV",Object.assign(a.style,{background:"none",border:Y,borderRadius:"4px",cursor:"pointer",fontSize:"10px",color:v.iconHover,padding:"2px 7px"}),a.addEventListener("click",()=>{const B=["Test","N","Pass","Fail","Pass Rate %"],E=pt(o,B),R=[[...E.map(L=>L.label),...B].map(csvField).join(",")];for(const L of d)R.push([...E.map(u=>u.constant??""),L.label,String(L.totalDies),String(L.passDies),String(L.failDies),L.passRatePercent!==null?L.passRatePercent.toFixed(1):""].map(csvField).join(","));rt(R.join(`
3
- `),"functional-tests.csv","text/csv",e)}),c.appendChild(a),f.appendChild(c);const p=l("table",{width:"100%",borderCollapse:"collapse",fontSize:"11px"}),h=document.createElement("thead"),g=document.createElement("tr");for(const B of["Test","N","Pass","Fail","Pass rate"])g.appendChild(l("th",{textAlign:B==="Test"?"left":"right",fontWeight:"700",fontSize:"10px",letterSpacing:"0.03em",textTransform:"uppercase",color:I,padding:"3px 8px 5px",borderBottom:`1px solid ${v.menuBorder}`,whiteSpace:"nowrap"},B));h.appendChild(g),p.appendChild(h);const T=document.createElement("tbody");for(const B of d){const E=document.createElement("tr"),R=(L,u="right")=>{E.appendChild(l("td",{textAlign:u,padding:"4px 8px",borderBottom:`1px solid ${v.menuBorder}`,color:z,whiteSpace:"nowrap"},L))};R(B.label,"left"),R(String(B.totalDies)),R(String(B.passDies)),R(String(B.failDies)),R(B.passRatePercent!==null?`${B.passRatePercent.toFixed(1)}% (N=${B.totalDies})`:"\u2014"),T.appendChild(E)}p.appendChild(T);const N=l("div",{overflowX:"auto"});return N.appendChild(p),f.appendChild(N),f}export function buildLotFunctionalSection(t,i,n,e){const o=n?.length?{perWaferMetadata:n.map(d=>d.wafer??{}),populationLabel:`${n.length} wafer${n.length===1?"":"s"} pooled`}:void 0;if(n?.length&&n.every(d=>d.stats.functionalYield!==void 0)){const d=new Map;for(const c of n)for(const s of c.stats.functionalYield??[]){const a=d.get(s.testNumber)??{label:s.label,passDies:0,failDies:0,totalDies:0};a.passDies+=s.passDies,a.failDies+=s.failDies,a.totalDies+=s.totalDies,d.set(s.testNumber,a)}const f=[...d.entries()].map(([c,s])=>({testNumber:c,...s,passRatePercent:s.totalDies>0?s.passDies/s.totalDies*100:null}));if(f.length)return buildFunctionalTestSection(t,i,f,e,o)}return buildFunctionalTestSection(t,i,void 0,e,o)}const A={unusual:0,notable:1,info:2};function X(t){return l("span",{display:"inline-block",width:"7px",height:"7px",borderRadius:"50%",background:G(t),flexShrink:"0"})}function ct(t,i){let n=t.summary;return i&&(n.startsWith(`${i} has `)?n=n.slice(i.length+5):n.startsWith(`${i} `)&&(n=n.slice(i.length+1))),n=P(n),n.length?n[0].toUpperCase()+n.slice(1):n}export function buildFindingsSection(t,i,n,e,o=!1){if(!t.length)return null;const d=t.some(u=>u.severity==="unusual"||u.severity==="notable"),f=d?t.filter(u=>u.severity!=="info").length.toString():void 0,{outer:c,content:s}=o?(()=>{const u=l("div");return{outer:u,content:u}})():lt(`Findings (${t.length})`,d,f);function a(u){return u.reduce(($,k)=>A[k.severity]<A[$]?k.severity:$,"info")}function p(u){const $=new Map;for(const C of u){const r=`${C.comparison.family}\0${C.comparison.left}`,m=$.get(r)??[];m.push(C),$.set(r,m)}const k=[...$.entries()].map(([C,r])=>{const m=[...r].sort((D,y)=>A[D.severity]-A[y.severity]);return{key:C,findings:m,worst:a(m)}});return k.sort((C,r)=>A[C.worst]-A[r.worst]),k}function h(u,$){const C={ring:"Ring",quadrant:"Quadrant",sector:"Sector","reticle-position":"Reticle","test-site":"Test site",cluster:"Cluster","edge-arc":"Edge arc",wafer:"Wafer"}[u]??u;return $.toLowerCase().startsWith(C.toLowerCase())?$:`${C}: ${$}`}const g=t.filter(u=>u.comparison.family==="spatial-pattern"),T=new Set([...g.flatMap(u=>u.relatedIds??[]),...t.flatMap(u=>u.absorbedIds??[])]),N=t.filter(u=>u.comparison.family!=="spatial-pattern"&&!T.has(u.id)),B=p(N);function E(u,$=!1,k){const C=e===u.id,r=document.createElement("button");return r.type="button",r.dataset.wmapFinding=u.id,r.textContent=ct(u,k),r.title=u.summary,r.setAttribute("aria-current",C?"true":"false"),Object.assign(r.style,{border:`1px solid ${v.menuBorder}`,borderLeft:`3px solid ${G(u.severity)}`,background:C?v.bgActive:v.menuBg,borderRadius:"6px",padding:$?"6px 10px":"8px 10px",textAlign:"left",fontSize:$?"10px":"11px",fontWeight:C?"600":"400",color:v.iconHover,cursor:"pointer",width:"100%",marginBottom:"4px"}),r.addEventListener("click",()=>n(u,r)),r}const R=P(Ct(t)??"");if(R){const u=l("div",{background:v.bgActive,borderRadius:"6px",padding:"8px 10px",marginBottom:"8px",display:"flex",gap:"8px",alignItems:"flex-start"}),$=l("span",{flex:"1",fontSize:"12px",lineHeight:"1.5",color:v.iconHover},R);u.appendChild($);const k=l("button",{flexShrink:"0",border:"none",background:"none",fontSize:"10px",color:v.icon,cursor:"pointer",padding:"0",lineHeight:"1.5",whiteSpace:"nowrap"},"Detail \u25B8");k.type="button",k.addEventListener("click",()=>{const C=at({title:"Findings Summary",onClose:()=>{},anchor:k}),r=l("p",{fontSize:"16px",lineHeight:"1.6",color:v.iconHover,padding:"20px 24px 16px",margin:"0",borderBottom:`1px solid ${v.menuBorder}`,flexShrink:"0"},R);C.contentWrap.appendChild(r);const m=l("div",{overflowY:"auto",padding:"16px 24px",flex:"1"}),D=(y,x)=>{const S=l("div",{display:"flex",alignItems:"center",gap:"7px",fontSize:"13px",fontWeight:"600",color:z,marginTop:"10px",marginBottom:"4px"});return S.appendChild(X(y)),S.appendChild(l("span",{},x)),S};for(const y of g){m.appendChild(D(y.severity,y.comparison.left)),m.appendChild(l("div",{fontSize:"13px",color:v.iconHover,padding:"3px 0 3px 15px",marginBottom:"2px"},P(y.summary)));const x=t.filter(S=>y.relatedIds?.includes(S.id));for(const S of x)m.appendChild(l("div",{fontSize:"12px",color:v.icon,padding:"2px 0 2px 23px",marginBottom:"2px"},P(S.summary)))}for(const y of B){const[x,S]=y.key.split("\0");m.appendChild(D(y.worst,h(x,S)));for(const b of y.findings)m.appendChild(l("div",{fontSize:"13px",color:v.iconHover,padding:"3px 0 3px 15px",marginBottom:"2px"},ct(b,S)))}C.contentWrap.appendChild(m),Object.assign(C.contentWrap.style,{flexDirection:"column",overflow:"hidden"})}),u.appendChild(k),s.appendChild(u)}let L=!0;for(const u of g){L||s.appendChild(l("div",{height:"1px",background:v.separator,margin:"4px 0"})),L=!1;const $=t.filter(D=>u.relatedIds?.includes(D.id)),k=$.length>0,C=l("div",{position:"relative",marginBottom:k?"2px":"4px"}),r=e===u.id,m=document.createElement("button");if(m.type="button",m.dataset.wmapFinding=u.id,Object.assign(m.style,{border:`1px solid ${v.menuBorder}`,borderLeft:`3px solid ${G(u.severity)}`,background:r?v.bgActive:v.menuBg,borderRadius:"6px",padding:"8px 32px 8px 10px",textAlign:"left",fontSize:"11px",fontWeight:r?"600":"500",color:v.iconHover,cursor:"pointer",width:"100%"}),m.textContent=P(u.summary),m.title=u.summary,m.setAttribute("aria-current",r?"true":"false"),m.addEventListener("click",()=>n(u,m)),C.appendChild(m),k){const D=l("div",{display:"none",paddingLeft:"12px",marginBottom:"4px"});for(const S of $)D.appendChild(E(S,!0));C.appendChild(D);let y=!1;const x=l("button",{position:"absolute",top:"50%",right:"8px",transform:"translateY(-50%)",border:"none",background:"none",fontSize:"10px",color:v.icon,cursor:"pointer",padding:"2px 4px",lineHeight:"1"},"\u25B8");x.type="button",x.title="Show supporting findings",x.setAttribute("aria-label","Show supporting findings"),x.setAttribute("aria-expanded","false"),x.addEventListener("click",S=>{S.stopPropagation(),y=!y,D.style.display=y?"block":"none",x.textContent=y?"\u25BE":"\u25B8";const b=y?"Hide supporting findings":"Show supporting findings";x.title=b,x.setAttribute("aria-label",b),x.setAttribute("aria-expanded",String(y))}),C.appendChild(x)}s.appendChild(C)}for(const u of B){L||s.appendChild(l("div",{height:"1px",background:v.separator,margin:"4px 0"})),L=!1;const[$,k]=u.key.split("\0"),C=l("div",{display:"flex",alignItems:"center",gap:"6px",fontSize:"11px",fontWeight:"600",color:z,margin:"2px 0 4px"});C.appendChild(X(u.worst)),C.appendChild(l("span",{},h($,k))),s.appendChild(C);for(const r of u.findings)s.appendChild(E(r,!1,k))}return c}const Ht=[{value:"",label:"All kinds"},{value:"yield",label:"Yield"},{value:"hardBin",label:"Hard bin"},{value:"softBin",label:"Soft bin"},{value:"test",label:"Test value"},{value:"functionalTest",label:"Functional test"},{value:"spatialPattern",label:"Spatial pattern"}],At=[{value:"",label:"All regions"},{value:"ring",label:"Ring"},{value:"quadrant",label:"Quadrant"},{value:"reticle-position",label:"Reticle position"},{value:"test-site",label:"Test site"},{value:"wafer",label:"Wafer"},{value:"sector",label:"Sector"},{value:"cluster",label:"Cluster"},{value:"edge-arc",label:"Edge arc"},{value:"spatial-pattern",label:"Spatial pattern"}],Pt=["unusual","notable","info"],Yt={unusual:"Unusual",notable:"Notable",info:"Info"};function Ot(t,i,n){const e=l("div",{display:"flex",flexWrap:"wrap",alignItems:"center",gap:"10px",marginBottom:"10px",paddingBottom:"10px",borderBottom:`1px solid ${v.separator}`}),o={unusual:0,notable:0,info:0};for(const s of t)o[s.severity]++;const d=Pt.filter(s=>o[s]>0),f=new Set(i.severity===void 0?d:Array.isArray(i.severity)?i.severity:[i.severity]),c=l("div",{display:"flex",gap:"4px",flexWrap:"wrap"});for(const s of d){const a=document.createElement("button");a.type="button";const p=()=>{const h=f.has(s);a.setAttribute("aria-pressed",h?"true":"false"),Object.assign(a.style,{display:"inline-flex",alignItems:"center",gap:"5px",border:`1px solid ${v.menuBorder}`,borderRadius:"10px",background:h?v.bgActive:"none",opacity:h?"1":"0.5",color:v.text,fontSize:"11px",padding:"2px 8px",cursor:"pointer"})};a.appendChild(X(s)),a.appendChild(l("span",{},`${Yt[s]} ${o[s]}`)),a.title=f.has(s)?"Click to hide these findings":"Click to show these findings",p(),a.addEventListener("click",()=>{f.has(s)?f.delete(s):f.add(s),i.severity=f.size===d.length?void 0:[...f],n()}),c.appendChild(a)}return e.appendChild(c),e.appendChild(ot("Kind:",Ht,i.kind??"",s=>{i.kind=s||void 0,n()},{maxWidth:"130px"})),e.appendChild(ot("Region:",At,i.family??"",s=>{i.family=s||void 0,n()},{maxWidth:"150px"})),e}export function buildFindingsSectionWithFilter(t,i,n,e,o){if(!t.findings.length)return null;const d=t.findings.some(h=>h.severity==="unusual"||h.severity==="notable"),f=d?t.findings.filter(h=>h.severity!=="info").length.toString():void 0,{outer:c,content:s}=lt(`Findings (${t.findings.length})`,d,f);s.appendChild(Ot(t.findings,e,o));const a=St(t,e);if(!a.length)return s.appendChild(l("div",{color:I,fontSize:"11px",textAlign:"center",padding:"16px 8px"},"No findings match the current filter.")),c;const p=buildFindingsSection(a,t,i,n,!0);return p&&s.appendChild(p),c}export function buildLotTestSection(t,i,n,e,o){const d=e?.length?{perWaferMetadata:e.map(c=>c.wafer??{}),populationLabel:`${e.length} wafer${e.length===1?"":"s"} pooled`}:void 0;let f;if(e?.length&&e.every(c=>c.stats.perTestStats!==void 0)){const c=new Map;for(const s of e)for(const a of s.stats.perTestStats??[]){const p=c.get(a.testNumber);p?(p.n+=a.count,p.sum+=a.mean*a.count,p.min=Math.min(p.min,a.min),p.max=Math.max(p.max,a.max)):c.set(a.testNumber,{n:a.count,sum:a.mean*a.count,min:a.min,max:a.max})}f={perTestStats:[...c.entries()].map(([s,a])=>({testNumber:s,count:a.n,min:a.min,max:a.max,mean:a.sum/a.n}))}}if(e?.length&&e.every(c=>c.stats.testSpecYield!==void 0)){const c=new Map;for(const s of e)for(const a of s.stats.testSpecYield??[]){const p=c.get(a.testNumber);p?(p.passDies+=a.passDies,p.totalDies+=a.totalDies):c.set(a.testNumber,{passDies:a.passDies,totalDies:a.totalDies})}f={...f,testSpecYield:[...c.entries()].map(([s,a])=>({testNumber:s,totalDies:a.totalDies,yieldPercent:a.totalDies>0?a.passDies/a.totalDies*100:null}))}}return buildTestSection(t,i,n,f,o,d)}export function createSummaryPanelEl(t,i=document){const n=t==="top"||t==="bottom",e=l("div",{background:Et,border:Y,borderRadius:"6px",padding:"12px",overflowY:n?"hidden":"auto",overflowX:n?"auto":"hidden",flexShrink:"0",boxSizing:"border-box",fontFamily:"system-ui, sans-serif",fontSize:"12px",boxShadow:"0 1px 4px rgba(0,0,0,0.08)"},void 0,i);return n?(e.style.height="180px",e.style.width="100%"):(e.style.width="260px",e.style.maxHeight="100%"),e}export function wrapWithSummaryPanel(t,i,n){const e=n==="top"||n==="bottom",o=l("div",{display:"flex",flexDirection:e?"column":"row",gap:"8px",width:"100%",height:"100%",flex:"1 1 0",minHeight:"0",boxSizing:"border-box",alignItems:e?"flex-start":"stretch"});return t.style.flex="1 1 0",t.style.minWidth="0",t.style.minHeight="0",n==="right"||n==="bottom"?(o.appendChild(t),o.appendChild(i)):(o.appendChild(i),o.appendChild(t)),o}function ut(t){return l("div",{fontSize:"13px",fontWeight:"700",color:z,marginBottom:"10px"},t)}function q(t,i){const n=l("button",{background:"none",border:Y,borderRadius:"4px",cursor:"pointer",fontSize:"10px",color:v.iconHover,padding:"2px 7px"},t);return n.type="button",n.addEventListener("click",i),n}function ft(...t){const i=t.filter(e=>!!e);if(!i.length)return null;const n=l("div",{display:"flex",flexWrap:"wrap",gap:"6px",marginBottom:"10px"});for(const e of i)n.appendChild(e);return n}function mt(t,i,n,e,o,d,f,c,s){const a=t.ownerDocument,p=at({title:"Die list",onClose:()=>{},anchor:t,ownerDocument:a});p.contentWrap.style.padding="14px 16px";const h=Rt(i,n,{...f,title:e,onSaveText:c,waferMetadata:o,metadataFields:d,extraColumn:s,ownerDocument:a});h&&p.contentWrap.appendChild(h)}export function renderWaferSummaryContent(t,i){const n=t.scrollTop;t.innerHTML="";const{wafer:e,dies:o,yieldSummary:d,dataCoverage:f,hbinDefs:c,sbinDefs:s,testDefs:a,statsSummary:p,passBins:h=[1],ringCount:g=4,colorScheme:T,fallbackFormat:N,onFindingClick:B,activeFindingId:E=null,findingsFilter:R,onFindingsFilterChange:L,onSaveText:u,metadataFields:$,dieListOptions:k}=i;t.appendChild(ut("Wafer Summary"));const C=i.warnings??nt({statsSummary:p});C.length&&t.appendChild(_(C,t.ownerDocument));const r=d&&f?q("Summary report",()=>{J(wt({wafer:e,dies:o,yieldSummary:d,dataCoverage:f,hbinDefs:c,sbinDefs:s,testDefs:a,statsSummary:p,passBins:h,ringCount:g}))}):null,m=(k?.enabled??!0)&&o.length?q("View die list",()=>{mt(t,o,a,`Die list \u2014 ${o.length} dies`,e.metadata,$,k,u)}):null,D=ft(r,m);D&&t.appendChild(D);const y=[],x=p?.stats.isLotStack?p.stats:void 0,S=x?.lotSize!==void 0?{lotSize:x.lotSize,aggrMethod:Lt(x.aggregationMethod)}:void 0;y.push(buildMetadataInfoSection([{metadata:e.metadata??void 0}],S)),d&&f&&y.push(buildYieldSection(d,f,h));const b=o.some(M=>M.hbin!=null),F=o.some(M=>M.sbin!=null);b?y.push(buildBinSection(o,c,"hard",T,p?.stats.hardBinCounts)):F&&y.push(buildBinSection(o,s,"soft",T,p?.stats.softBinCounts)),y.push(buildRingSection(o,e,g,h)),y.push(buildQuadrantSection(o,e,g,h));const W=e.metadata?{waferMetadata:e.metadata}:void 0;y.push(buildTestSection(o,a,N,p?.stats,u,W)),y.push(buildFunctionalTestSection(o,a,p?.stats.functionalYield,u,W)),p&&B&&R&&L&&y.push(buildFindingsSectionWithFilter(p,B,E,R,L));let w=!0;for(const M of y)M&&(w||t.appendChild(dt()),w=!1,t.appendChild(M));t.appendChild(l("div",{height:"12px",flexShrink:"0"})),t.scrollTop=n}export function renderLotSummaryContent(t,i){const n=t.scrollTop;t.innerHTML="";const{lotSummary:e,items:o,hbinDefs:d,sbinDefs:f,testDefs:c,passBins:s=[1],ringCount:a=4,colorScheme:p,fallbackFormat:h,onFindingClick:g,activeFindingId:T=null,onWaferClick:N,findingsFilter:B,onFindingsFilterChange:E,onSaveText:R,dieListOptions:L}=i;t.appendChild(ut(`Lot Summary \u2014 ${e.stats.waferCount} wafer${e.stats.waferCount===1?"":"s"}`));const u=i.warnings??nt({lotStatsSummary:e});u.length&&t.appendChild(_(u,t.ownerDocument));const $=q("Summary report",()=>{J(yt({items:o.map((w,M)=>({label:w?.label??`W${M+1}`,wafer:w?.wafer,dies:w?.dies,statsSummary:w?.statsSummary})),hbinDefs:d,sbinDefs:f,testDefs:c,passBins:s,ringCount:a}))}),k=[],C=[],r=[],m=new WeakMap;for(let w=0;w<o.length;w++){const M=o[w];if(!M){C.push([]);continue}M.wafer&&k.push(M.wafer);const V=M.dies??[],ht=M.label??`W${w+1}`;for(const gt of V)m.set(gt,ht);C.push(V),r.push(...V)}const D=L?.enabled??!0?q("View die list",()=>{r.length&&mt(t,r,c,`Die list \u2014 ${r.length} dies across ${o.length} wafer${o.length===1?"":"s"}`,et(o.filter(w=>!!w).map(w=>({metadata:w.wafer?.metadata}))),o.find(w=>w?.metadataFields?.length)?.metadataFields,L,R,{label:"Wafer",get:w=>m.get(w)})}):null,y=ft($,D);y&&t.appendChild(y);const x=r.some(w=>w.hbin!=null),S=r.some(w=>w.sbin!=null),b=o.map(w=>w?.statsSummary).filter(w=>!!w),F=[buildLotOverviewSection(e),buildPerWaferYieldSection(e,o,N),x?buildLotBinSection(r,d,"hard",p):S?buildLotBinSection(r,f,"soft",p):null,buildLotRingSection(C,k,a,s),buildLotQuadrantSection(C,k,a,s),c?.length?buildLotTestSection(r,c,h,b,R):null,c?.length?buildLotFunctionalSection(r,c,b,R):null];g&&B&&E&&F.push(buildFindingsSectionWithFilter(e,g,T,B,E));let W=!0;for(const w of F)w&&(W||t.appendChild(dt()),W=!1,t.appendChild(w));t.appendChild(l("div",{height:"12px",flexShrink:"0"})),t.scrollTop=n}
1
+ import{isParametricTest as bt}from"../renderer/buildWaferMap.js";import{buildRingRegions as J,buildQuadrantRegions as tt,buildRegionYieldData as wt}from"../stats/regions.js";import{computeFunctionalYield as vt}from"../stats/analyzeWaferMap.js";import{renderSummaryReportHtml as yt,renderLotSummaryReportHtml as Ct}from"../stats/renderSummaryReport.js";import{buildFindingsNarrative as St}from"../stats/findingsNarrative.js";import{filterFindings as kt}from"../stats/filterFindings.js";import{buildFacetTable as Bt,prettyKey as et}from"../stats/facets.js";import{commonMetadata as nt}from"../stats/facets.js";import{resolveMetadataColumns as Lt}from"../stats/metadataColumns.js";import{getColorScheme as $t}from"../renderer/colorSchemes.js";import{buildWarningsBanner as Q,collectWarnings as it}from"./warnings.js";export{Q as buildWarningsBanner};import{fmt as ot,fmtAggregationMethod as Dt,plainBinTerms as Y}from"../renderer/fmt.js";import{getUniqueTestNumbers as Rt}from"../renderer/buildView.js";import{quantile as G}from"../stats/math.js";import{makeLabeledSelect as at}from"./charts/chartShell.js";import{CLR as b,sevColor as U,openModal as rt,openReportModal as st,saveTextFile as lt}from"./toolbar.js";import{buildDieListSection as Ft}from"./dieList.js";import{medianOfSorted as Nt}from"../core/utils.js";import{metadataDisplayValue as Tt}from"../core/metadata.js";const Et=b.panelBg,O=`1px solid ${b.menuBorder}`,Mt="12px",I=b.label,H=b.value,dt="10px";function l(t,i,n,e=document){const o=e.createElement(t);return i&&Object.assign(o.style,i),n!==void 0&&(o.textContent=n),o}function A(t){return l("div",{fontSize:dt,fontWeight:"700",letterSpacing:"0.06em",textTransform:"uppercase",color:I,marginBottom:"6px"},t)}function pt(t,i=!0,n){const e=l("div"),o=document.createElement("button");o.type="button",Object.assign(o.style,{display:"flex",alignItems:"center",gap:"4px",width:"100%",background:"none",border:"none",cursor:"pointer",padding:"0 0 6px",textAlign:"left"});const d=l("span",{fontSize:"9px",color:I,transition:"transform 0.15s",transform:i?"rotate(90deg)":"rotate(0deg)",display:"inline-block",lineHeight:"1",marginRight:"1px"},"\u25B6"),f=l("span",{fontSize:dt,fontWeight:"700",letterSpacing:"0.06em",textTransform:"uppercase",color:I,flex:"1"},t);if(o.setAttribute("aria-expanded",i?"true":"false"),o.appendChild(d),o.appendChild(f),n){const a=l("span",{fontSize:"9px",fontWeight:"700",background:b.warnBg,color:b.warnText,borderRadius:"10px",padding:"1px 5px"},n);o.appendChild(a)}const c=l("div");c.style.display=i?"block":"none";let s=i;return o.addEventListener("click",()=>{s=!s,c.style.display=s?"block":"none",d.style.transform=s?"rotate(90deg)":"rotate(0deg)",o.setAttribute("aria-expanded",s?"true":"false")}),e.appendChild(o),e.appendChild(c),{outer:e,content:c}}function ct(){return l("div",{height:"1px",background:b.separator,margin:`${Mt} 0`,flexShrink:"0"})}function X(t,i,n=b.barFill,e,o,d){const f=l("div",{marginBottom:"5px"}),c=l("div",{display:"flex",justifyContent:"space-between",fontSize:"11px",color:H,marginBottom:"2px"}),s=l("span",{},t),a=l("span",{fontWeight:"600"},`${i.toFixed(1)}%`);c.appendChild(s),c.appendChild(a);const p=e!==void 0?e:Math.min(100,Math.max(0,i)),g=d?b.barFillMuted:n,h=l("div",{position:"relative",height:"9px",background:b.bgActive,borderRadius:"4px",overflow:"hidden"}),D=l("div",{height:"100%",width:`${p}%`,background:g,borderRadius:"4px",transition:"width 0.3s ease"});if(h.appendChild(D),o!==void 0){const M=l("div",{position:"absolute",top:"0",bottom:"0",left:`${o}%`,width:"1px",background:b.infoText,opacity:"0.5"});h.appendChild(M)}return f.appendChild(c),f.appendChild(h),f}function j(t,i,n){const e=l("div",{background:b.menuBg,border:O,borderRadius:"6px",padding:"8px 10px",textAlign:"center",flex:"1"}),o=l("div",{fontSize:"20px",fontWeight:"700",color:H,lineHeight:"1.2"},t),d=l("div",{fontSize:"10px",color:I,marginTop:"2px"},i);return e.appendChild(o),e.appendChild(d),n&&e.appendChild(l("div",{fontSize:"9px",color:I,opacity:"0.85"},n)),e}function Wt(t,i){const n=l("div",{display:"flex",justifyContent:"space-between",fontSize:"11px",gap:"8px",marginBottom:"3px"}),e=l("span",{color:I,flexShrink:"0"},t),o=l("span",{color:H,textAlign:"right",fontWeight:"500",wordBreak:"break-all"},i);return n.appendChild(e),n.appendChild(o),n}function It(t,i){const n=l("div",{display:"flex",fontSize:"11px",gap:"6px",marginBottom:"3px"}),e=l("span",{color:I,flexShrink:"0"},`${t}:`),o=l("span",{color:H,fontWeight:"500",wordBreak:"break-all"},i);return n.appendChild(e),n.appendChild(o),n}export function metadataEntries(t){const i=[];for(const[n,e]of Object.entries(t)){const o=Tt(e);o!==void 0&&i.push([n,o])}return i}export function buildFacetSummaryChips(t,i=3){if(!t.length)return null;const n=l("div",{display:"flex",flexWrap:"wrap",alignItems:"baseline",gap:"4px 10px",fontSize:"11px"});for(const e of t){const o=l("span",{whiteSpace:"nowrap"}),d=l("span",{color:I},`${et(e.key)}: `);o.appendChild(d);const f=e.values.slice(0,i),c=e.values.length-f.length;let s=f.map(a=>a.value).join(", ");c>0&&(s+=` +${c} more`),o.appendChild(document.createTextNode(s)),n.appendChild(o)}return n}export function buildMetadataStripRow(t,i,n){const e=Bt(t,n),o=buildFacetSummaryChips(e);if(!o&&!i)return null;const d=l("div",{display:"flex",flexWrap:"wrap",alignItems:"baseline",gap:"4px 14px"});if(i){const f=l("span",{fontWeight:"500",whiteSpace:"nowrap"},i.aggrMethod?`${i.lotSize} wafers stacked \xB7 ${i.aggrMethod}`:`${i.lotSize} wafers stacked`);d.appendChild(f)}return o&&d.appendChild(o),d}const zt={display:"flex",flexDirection:"column",gap:"6px",background:b.menuBg,border:`1px solid ${b.menuBorder}`,borderRadius:"6px",padding:"6px 10px",boxShadow:"0 1px 4px rgba(0,0,0,0.10)",fontSize:"12px",lineHeight:"1",boxSizing:"border-box",width:"100%",minWidth:"0"};export function buildMetadataStripBox(t,i,n){const e=buildMetadataStripRow(t,i,n);if(!e)return null;const o=l("div",zt);return o.appendChild(e),o}export function buildCompactMetadataRows(t){const i=metadataEntries(t);if(!i.length)return null;const n=l("div");for(const[e,o]of i)n.appendChild(It(et(e),o));return n}export function buildMetadataInfoSection(t,i){const n=buildMetadataStripRow(t,i,{facetableOnly:t.length>1});if(!n)return null;const e=l("div");return e.appendChild(A("Wafer Info")),e.appendChild(n),e}export function buildYieldSection(t,i,n=[1]){const e=l("div");e.appendChild(A("Summary"));const o=l("div",{display:"flex",gap:"6px",marginBottom:"8px"});if(o.appendChild(j(String(t.totalDies),"Total dies")),t.partialDies>0&&o.appendChild(j(String(t.partialDies),"Partial")),t.yieldPercent!==null){const d=n.length===1?`bin ${n[0]}`:`bins ${n.join(", ")}`;o.appendChild(j(`${t.yieldPercent.toFixed(1)}%`,"Yield",`pass: ${d}`))}return e.appendChild(o),t.edgeExcludedDies>0&&e.appendChild(Wt("Edge excluded (outer zone)",String(t.edgeExcludedDies))),e}export function buildBinSection(t,i,n,e,o){const d=new Map;if(o)for(const[p,g]of Object.entries(o))d.set(Number(p),g);else for(const p of t){if(p.partial||p.edgeExcluded)continue;const g=n==="hard"?p.hbin:p.sbin;g!=null&&d.set(g,(d.get(g)??0)+1)}if(!d.size)return null;const f=[...d.values()].reduce((p,g)=>p+g,0),c=i?new Map(i.map(p=>[p.bin,p])):null,s=[...d.entries()].sort((p,g)=>p[0]-g[0]),a=l("div");a.appendChild(A(n==="hard"?"Hard Bin Breakdown":"Soft Bin Breakdown"));for(const[p,g]of s){const h=c?.get(p),D=h?.name?`Bin ${p} \xB7 ${h.name}`:`Bin ${p}`,M=g/f*100,B=$t(e),T=(e==="custom"?h?.color:void 0)??B.forBin(p);a.appendChild(X(`${D} (${g})`,M,T))}return a}export function buildLotBinSection(t,i,n,e){return buildBinSection(t,i,n,e)}function q(t,i,n,e,o,d){const f=wt(t,i,n,e,o);if(!f.length)return null;const c=l("div");c.appendChild(A(d));for(const{label:s,n:a,yieldPercent:p}of f)c.appendChild(X(`${s} (N=${a})`,p));return c}export function buildRingSection(t,i,n,e){return q([t],[i],n,e,J,"Ring Yield")}export function buildQuadrantSection(t,i,n,e){return q([t],[i],n,e,tt,"Quadrant Yield")}export function buildLotRingSection(t,i,n,e){return q(t,i,n,e,J,"Ring Yield")}export function buildLotQuadrantSection(t,i,n,e){return q(t,i,n,e,tt,"Quadrant Yield")}export function buildLotOverviewSection(t){const i=l("div");i.appendChild(A("Lot Summary"));const n=l("div",{display:"flex",gap:"6px",marginBottom:"8px"});n.appendChild(j(String(t.stats.waferCount),"Wafers"));const e=t.perWafer.map(o=>o.summary.stats.yieldPercent).filter(o=>o!==null);if(e.length){const o=e.reduce((d,f)=>d+f,0)/e.length;n.appendChild(j(`${o.toFixed(1)}%`,"Mean wafer yield"))}return i.appendChild(n),i}export function buildPerWaferYieldSection(t,i,n){const e=t.perWafer.map(a=>({waferIndex:a.waferIndex,label:(i[a.waferIndex]?.label??`W${a.waferIndex+1}`).replace(/\s*·\s*\d+(\.\d+)?%$/,""),yieldPct:a.summary.stats.yieldPercent})).filter(a=>a.yieldPct!==null);if(!e.length)return null;const o=Math.min(...e.map(a=>a.yieldPct)),d=Math.max(...e.map(a=>a.yieldPct)),f=o===d?"":` (${o.toFixed(1)}\u2013${d.toFixed(1)}%)`,c=Nt([...e.map(a=>a.yieldPct)].sort((a,p)=>a-p)),s=l("div");s.appendChild(A("Wafer Yield"+f));for(const{waferIndex:a,label:p,yieldPct:g}of e){const h=X(p,g,void 0,void 0,c,g<c);n&&(h.style.cursor="pointer",h.style.borderRadius="4px",h.style.padding="2px 3px",h.style.marginLeft="-3px",h.style.marginRight="-3px",h.setAttribute("role","button"),h.setAttribute("aria-label",`${p}, ${g.toFixed(1)}% yield \u2014 view wafer`),h.tabIndex=0,h.addEventListener("mouseenter",()=>{h.style.background=b.bgHover}),h.addEventListener("mouseleave",()=>{h.style.background=""}),h.addEventListener("focus",()=>{h.style.background=b.bgHover}),h.addEventListener("blur",()=>{h.style.background=""}),h.addEventListener("click",()=>n(a)),h.addEventListener("keydown",D=>{(D.key==="Enter"||D.key===" ")&&(D.preventDefault(),n(a))})),s.appendChild(h)}return s}function Ht(t){const i=[...t].sort((o,d)=>o-d),n=t.reduce((o,d)=>o+d,0)/t.length,e=t.reduce((o,d)=>o+(d-n)**2,0)/t.length;return{min:i[0],max:i[i.length-1],mean:n,count:t.length,stddev:Math.sqrt(e),median:G(i,.5),q1:G(i,.25),q3:G(i,.75)}}function ut(t,i){if(!t)return[];const n=t.waferMetadata??(t.perWaferMetadata?nt(t.perWaferMetadata.map(e=>({metadata:e}))):void 0);return!n||!Object.keys(n).length?[]:Lt({waferMetadata:n,waferPlacement:"csv",reservedLabels:i}).columns}const At=/^[=+\-@]/;export function csvField(t){const i=At.test(t)&&Number.isNaN(Number(t))?`'${t}`:t;return/[",\n\r]/.test(i)?`"${i.replace(/"/g,'""')}"`:i}export function buildTestSection(t,i,n,e,o,d){const f=t.filter(r=>!r.partial&&!r.edgeExcluded),c=new Map((e?.perTestStats??[]).map(r=>[r.testNumber,r])),s=new Map((e?.testSpecYield??[]).map(r=>[r.testNumber,r]));let a;if(i?.length?a=i.filter(bt).map(r=>({testNumber:r.testNumber,name:r.name,unit:r.unit,limitLow:r.limitLow,limitHigh:r.limitHigh})):a=Rt(f).map(m=>({testNumber:m,name:`Test ${m}`})),!a.length)return null;const p=a.filter(r=>f.some(m=>{const $=m.testValues?.[r.testNumber];return $!==void 0&&isFinite($)}));if(!p.length)return null;const g=p.some(r=>r.limitLow!==void 0||r.limitHigh!==void 0),h=[];for(const r of p){const m=c.get(r.testNumber),$=m&&m.stddev!==void 0&&m.median!==void 0&&m.q1!==void 0&&m.q3!==void 0;let v;if($){const w=m;v={testNumber:r.testNumber,min:w.min,max:w.max,mean:w.mean,count:w.count,stddev:w.stddev,median:w.median,q1:w.q1,q3:w.q3}}else{const w=f.map(N=>N.testValues?.[r.testNumber]).filter(N=>N!==void 0&&isFinite(N));if(!w.length)continue;v={testNumber:r.testNumber,...Ht(w)}}let x=null,S=0;if(r.limitLow!==void 0||r.limitHigh!==void 0){const w=s.get(r.testNumber);if(w)({yieldPercent:x,totalDies:S}=w);else{const N=f.map(E=>E.testValues?.[r.testNumber]).filter(E=>E!==void 0&&isFinite(E)),W=N.filter(E=>r.limitLow!==void 0&&E<r.limitLow||r.limitHigh!==void 0&&E>r.limitHigh).length;S=N.length,x=N.length>0?(N.length-W)/N.length*100:null}}h.push({entry:r,stats:v,specYieldPct:x,specN:S})}if(!h.length)return null;const D=l("div"),M=l("div",{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:"6px"}),B=A(d?.populationLabel?`Test Values (${h.length}) \u2014 ${d.populationLabel}`:`Test Values (${h.length})`);B.style.marginBottom="0",M.appendChild(B);const T=document.createElement("button");T.type="button",T.textContent="Export CSV",Object.assign(T.style,{background:"none",border:O,borderRadius:"4px",cursor:"pointer",fontSize:"10px",color:b.iconHover,padding:"2px 7px"}),T.addEventListener("click",()=>{const r=["Test","Unit","N","Min","Q1","Median","Mean","Q3","Max","StdDev"];g&&r.push("LSL","USL","Spec Yield %","Spec Yield N");const m=ut(d,r),v=[[...m.map(S=>S.label),...r].map(csvField).join(",")],x=S=>ot(S,void 0,"engineering");for(const{entry:S,stats:w,specYieldPct:N,specN:W}of h){const E=[...m.map(y=>y.constant??""),S.name,S.unit??"",String(w.count),x(w.min),x(w.q1),x(w.median),x(w.mean),x(w.q3),x(w.max),x(w.stddev)];g&&E.push(S.limitLow!==void 0?x(S.limitLow):"",S.limitHigh!==void 0?x(S.limitHigh):"",N!==null?N.toFixed(1):"",S.limitLow!==void 0||S.limitHigh!==void 0?String(W):""),v.push(E.map(csvField).join(","))}lt(v.join(`
2
+ `),"test-values.csv","text/csv",o)}),M.appendChild(T),D.appendChild(M);const F=l("table",{width:"100%",borderCollapse:"collapse",fontSize:"11px"}),R=document.createElement("thead"),u=document.createElement("tr"),L=["Test","N","Min","Q1","Median","Mean","Q3","Max","StdDev"];g&&L.push("LSL","USL","Spec yield");for(const r of L){const m=l("th",{textAlign:r==="Test"?"left":"right",fontWeight:"700",fontSize:"10px",letterSpacing:"0.03em",textTransform:"uppercase",color:I,padding:"3px 8px 5px",borderBottom:`1px solid ${b.menuBorder}`,whiteSpace:"nowrap"},r);u.appendChild(m)}R.appendChild(u),F.appendChild(R);const k=document.createElement("tbody");for(const{entry:r,stats:m,specYieldPct:$,specN:v}of h){const x=N=>ot(N,r.unit,n),S=document.createElement("tr"),w=(N,W="right")=>{const E=l("td",{textAlign:W,padding:"4px 8px",borderBottom:`1px solid ${b.menuBorder}`,color:H,whiteSpace:"nowrap"},N);S.appendChild(E)};w(r.name,"left"),w(`${m.count}`),w(x(m.min)),w(x(m.q1)),w(x(m.median)),w(x(m.mean)),w(x(m.q3)),w(x(m.max)),w(x(m.stddev)),g&&(w(r.limitLow!==void 0?x(r.limitLow):"\u2014"),w(r.limitHigh!==void 0?x(r.limitHigh):"\u2014"),w($!==null?`${$.toFixed(1)}% (N=${v})`:"\u2014")),k.appendChild(S)}F.appendChild(k);const C=l("div",{overflowX:"auto"});return C.appendChild(F),D.appendChild(C),D}export function buildFunctionalTestSection(t,i,n,e,o){const d=n??vt(t,i);if(!d?.length)return null;const f=l("div"),c=l("div",{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:"6px"}),s=A(o?.populationLabel?`Functional Tests (${d.length}) \u2014 ${o.populationLabel}`:`Functional Tests (${d.length})`);s.style.marginBottom="0",c.appendChild(s);const a=document.createElement("button");a.type="button",a.textContent="Export CSV",Object.assign(a.style,{background:"none",border:O,borderRadius:"4px",cursor:"pointer",fontSize:"10px",color:b.iconHover,padding:"2px 7px"}),a.addEventListener("click",()=>{const B=["Test","N","Pass","Fail","Pass Rate %"],T=ut(o,B),F=[[...T.map(R=>R.label),...B].map(csvField).join(",")];for(const R of d)F.push([...T.map(u=>u.constant??""),R.label,String(R.totalDies),String(R.passDies),String(R.failDies),R.passRatePercent!==null?R.passRatePercent.toFixed(1):""].map(csvField).join(","));lt(F.join(`
3
+ `),"functional-tests.csv","text/csv",e)}),c.appendChild(a),f.appendChild(c);const p=l("table",{width:"100%",borderCollapse:"collapse",fontSize:"11px"}),g=document.createElement("thead"),h=document.createElement("tr");for(const B of["Test","N","Pass","Fail","Pass rate"])h.appendChild(l("th",{textAlign:B==="Test"?"left":"right",fontWeight:"700",fontSize:"10px",letterSpacing:"0.03em",textTransform:"uppercase",color:I,padding:"3px 8px 5px",borderBottom:`1px solid ${b.menuBorder}`,whiteSpace:"nowrap"},B));g.appendChild(h),p.appendChild(g);const D=document.createElement("tbody");for(const B of d){const T=document.createElement("tr"),F=(R,u="right")=>{T.appendChild(l("td",{textAlign:u,padding:"4px 8px",borderBottom:`1px solid ${b.menuBorder}`,color:H,whiteSpace:"nowrap"},R))};F(B.label,"left"),F(String(B.totalDies)),F(String(B.passDies)),F(String(B.failDies)),F(B.passRatePercent!==null?`${B.passRatePercent.toFixed(1)}% (N=${B.totalDies})`:"\u2014"),D.appendChild(T)}p.appendChild(D);const M=l("div",{overflowX:"auto"});return M.appendChild(p),f.appendChild(M),f}export function buildLotFunctionalSection(t,i,n,e){const o=n?.length?{perWaferMetadata:n.map(d=>d.wafer??{}),populationLabel:`${n.length} wafer${n.length===1?"":"s"} pooled`}:void 0;if(n?.length&&n.every(d=>d.stats.functionalYield!==void 0)){const d=new Map;for(const c of n)for(const s of c.stats.functionalYield??[]){const a=d.get(s.testNumber)??{label:s.label,passDies:0,failDies:0,totalDies:0};a.passDies+=s.passDies,a.failDies+=s.failDies,a.totalDies+=s.totalDies,d.set(s.testNumber,a)}const f=[...d.entries()].map(([c,s])=>({testNumber:c,...s,passRatePercent:s.totalDies>0?s.passDies/s.totalDies*100:null}));if(f.length)return buildFunctionalTestSection(t,i,f,e,o)}return buildFunctionalTestSection(t,i,void 0,e,o)}const P={unusual:0,notable:1,info:2};function K(t){return l("span",{display:"inline-block",width:"7px",height:"7px",borderRadius:"50%",background:U(t),flexShrink:"0"})}function ft(t,i){let n=t.summary;return i&&(n.startsWith(`${i} has `)?n=n.slice(i.length+5):n.startsWith(`${i} `)&&(n=n.slice(i.length+1))),n=Y(n),n.length?n[0].toUpperCase()+n.slice(1):n}export function buildFindingsSection(t,i,n,e,o=!1){if(!t.length)return null;const d=t.some(u=>u.severity==="unusual"||u.severity==="notable"),f=d?t.filter(u=>u.severity!=="info").length.toString():void 0,{outer:c,content:s}=o?(()=>{const u=l("div");return{outer:u,content:u}})():pt(`Findings (${t.length})`,d,f);function a(u){return u.reduce((L,k)=>P[k.severity]<P[L]?k.severity:L,"info")}function p(u){const L=new Map;for(const C of u){const r=`${C.comparison.family}\0${C.comparison.left}`,m=L.get(r)??[];m.push(C),L.set(r,m)}const k=[...L.entries()].map(([C,r])=>{const m=[...r].sort(($,v)=>P[$.severity]-P[v.severity]);return{key:C,findings:m,worst:a(m)}});return k.sort((C,r)=>P[C.worst]-P[r.worst]),k}function g(u,L){const C={ring:"Ring",quadrant:"Quadrant",sector:"Sector","reticle-position":"Reticle","test-site":"Test site",cluster:"Cluster","edge-arc":"Edge arc",wafer:"Wafer"}[u]??u;return L.toLowerCase().startsWith(C.toLowerCase())?L:`${C}: ${L}`}const h=t.filter(u=>u.comparison.family==="spatial-pattern"),D=new Set([...h.flatMap(u=>u.relatedIds??[]),...t.flatMap(u=>u.absorbedIds??[])]),M=t.filter(u=>u.comparison.family!=="spatial-pattern"&&!D.has(u.id)),B=p(M);function T(u,L=!1,k){const C=e===u.id,r=document.createElement("button");return r.type="button",r.dataset.wmapFinding=u.id,r.textContent=ft(u,k),r.title=u.summary,r.setAttribute("aria-current",C?"true":"false"),Object.assign(r.style,{border:`1px solid ${b.menuBorder}`,borderLeft:`3px solid ${U(u.severity)}`,background:C?b.bgActive:b.menuBg,borderRadius:"6px",padding:L?"6px 10px":"8px 10px",textAlign:"left",fontSize:L?"10px":"11px",fontWeight:C?"600":"400",color:b.iconHover,cursor:"pointer",width:"100%",marginBottom:"4px"}),r.addEventListener("click",()=>n(u,r)),r}const F=Y(St(t)??"");if(F){const u=l("div",{background:b.bgActive,borderRadius:"6px",padding:"8px 10px",marginBottom:"8px",display:"flex",gap:"8px",alignItems:"flex-start"}),L=l("span",{flex:"1",fontSize:"12px",lineHeight:"1.5",color:b.iconHover},F);u.appendChild(L);const k=l("button",{flexShrink:"0",border:"none",background:"none",fontSize:"10px",color:b.icon,cursor:"pointer",padding:"0",lineHeight:"1.5",whiteSpace:"nowrap"},"Detail \u25B8");k.type="button",k.addEventListener("click",()=>{const C=rt({title:"Findings Summary",onClose:()=>{},anchor:k}),r=l("p",{fontSize:"16px",lineHeight:"1.6",color:b.iconHover,padding:"20px 24px 16px",margin:"0",borderBottom:`1px solid ${b.menuBorder}`,flexShrink:"0"},F);C.contentWrap.appendChild(r);const m=l("div",{overflowY:"auto",padding:"16px 24px",flex:"1"}),$=(v,x)=>{const S=l("div",{display:"flex",alignItems:"center",gap:"7px",fontSize:"13px",fontWeight:"600",color:H,marginTop:"10px",marginBottom:"4px"});return S.appendChild(K(v)),S.appendChild(l("span",{},x)),S};for(const v of h){m.appendChild($(v.severity,v.comparison.left)),m.appendChild(l("div",{fontSize:"13px",color:b.iconHover,padding:"3px 0 3px 15px",marginBottom:"2px"},Y(v.summary)));const x=t.filter(S=>v.relatedIds?.includes(S.id));for(const S of x)m.appendChild(l("div",{fontSize:"12px",color:b.icon,padding:"2px 0 2px 23px",marginBottom:"2px"},Y(S.summary)))}for(const v of B){const[x,S]=v.key.split("\0");m.appendChild($(v.worst,g(x,S)));for(const w of v.findings)m.appendChild(l("div",{fontSize:"13px",color:b.iconHover,padding:"3px 0 3px 15px",marginBottom:"2px"},ft(w,S)))}C.contentWrap.appendChild(m),Object.assign(C.contentWrap.style,{flexDirection:"column",overflow:"hidden"})}),u.appendChild(k),s.appendChild(u)}let R=!0;for(const u of h){R||s.appendChild(l("div",{height:"1px",background:b.separator,margin:"4px 0"})),R=!1;const L=t.filter($=>u.relatedIds?.includes($.id)),k=L.length>0,C=l("div",{position:"relative",marginBottom:k?"2px":"4px"}),r=e===u.id,m=document.createElement("button");if(m.type="button",m.dataset.wmapFinding=u.id,Object.assign(m.style,{border:`1px solid ${b.menuBorder}`,borderLeft:`3px solid ${U(u.severity)}`,background:r?b.bgActive:b.menuBg,borderRadius:"6px",padding:"8px 32px 8px 10px",textAlign:"left",fontSize:"11px",fontWeight:r?"600":"500",color:b.iconHover,cursor:"pointer",width:"100%"}),m.textContent=Y(u.summary),m.title=u.summary,m.setAttribute("aria-current",r?"true":"false"),m.addEventListener("click",()=>n(u,m)),C.appendChild(m),k){const $=l("div",{display:"none",paddingLeft:"12px",marginBottom:"4px"});for(const S of L)$.appendChild(T(S,!0));C.appendChild($);let v=!1;const x=l("button",{position:"absolute",top:"50%",right:"8px",transform:"translateY(-50%)",border:"none",background:"none",fontSize:"10px",color:b.icon,cursor:"pointer",padding:"2px 4px",lineHeight:"1"},"\u25B8");x.type="button",x.title="Show supporting findings",x.setAttribute("aria-label","Show supporting findings"),x.setAttribute("aria-expanded","false"),x.addEventListener("click",S=>{S.stopPropagation(),v=!v,$.style.display=v?"block":"none",x.textContent=v?"\u25BE":"\u25B8";const w=v?"Hide supporting findings":"Show supporting findings";x.title=w,x.setAttribute("aria-label",w),x.setAttribute("aria-expanded",String(v))}),C.appendChild(x)}s.appendChild(C)}for(const u of B){R||s.appendChild(l("div",{height:"1px",background:b.separator,margin:"4px 0"})),R=!1;const[L,k]=u.key.split("\0"),C=l("div",{display:"flex",alignItems:"center",gap:"6px",fontSize:"11px",fontWeight:"600",color:H,margin:"2px 0 4px"});C.appendChild(K(u.worst)),C.appendChild(l("span",{},g(L,k))),s.appendChild(C);for(const r of u.findings)s.appendChild(T(r,!1,k))}return c}const Pt=[{value:"",label:"All kinds"},{value:"yield",label:"Yield"},{value:"hardBin",label:"Hard bin"},{value:"softBin",label:"Soft bin"},{value:"test",label:"Test value"},{value:"functionalTest",label:"Functional test"},{value:"spatialPattern",label:"Spatial pattern"}],Yt=[{value:"",label:"All regions"},{value:"ring",label:"Ring"},{value:"quadrant",label:"Quadrant"},{value:"reticle-position",label:"Reticle position"},{value:"test-site",label:"Test site"},{value:"wafer",label:"Wafer"},{value:"sector",label:"Sector"},{value:"cluster",label:"Cluster"},{value:"edge-arc",label:"Edge arc"},{value:"spatial-pattern",label:"Spatial pattern"}],Ot=["unusual","notable","info"],jt={unusual:"Unusual",notable:"Notable",info:"Info"};function qt(t,i,n){const e=l("div",{display:"flex",flexWrap:"wrap",alignItems:"center",gap:"10px",marginBottom:"10px",paddingBottom:"10px",borderBottom:`1px solid ${b.separator}`}),o={unusual:0,notable:0,info:0};for(const s of t)o[s.severity]++;const d=Ot.filter(s=>o[s]>0),f=new Set(i.severity===void 0?d:Array.isArray(i.severity)?i.severity:[i.severity]),c=l("div",{display:"flex",gap:"4px",flexWrap:"wrap"});for(const s of d){const a=document.createElement("button");a.type="button";const p=()=>{const g=f.has(s);a.setAttribute("aria-pressed",g?"true":"false"),Object.assign(a.style,{display:"inline-flex",alignItems:"center",gap:"5px",border:`1px solid ${b.menuBorder}`,borderRadius:"10px",background:g?b.bgActive:"none",opacity:g?"1":"0.5",color:b.text,fontSize:"11px",padding:"2px 8px",cursor:"pointer"})};a.appendChild(K(s)),a.appendChild(l("span",{},`${jt[s]} ${o[s]}`)),a.title=f.has(s)?"Click to hide these findings":"Click to show these findings",p(),a.addEventListener("click",()=>{f.has(s)?f.delete(s):f.add(s),i.severity=f.size===d.length?void 0:[...f],n()}),c.appendChild(a)}return e.appendChild(c),e.appendChild(at("Kind:",Pt,i.kind??"",s=>{i.kind=s||void 0,n()},{maxWidth:"130px"})),e.appendChild(at("Region:",Yt,i.family??"",s=>{i.family=s||void 0,n()},{maxWidth:"150px"})),e}export function buildFindingsSectionWithFilter(t,i,n,e,o){if(!t.findings.length)return null;const d=t.findings.some(g=>g.severity==="unusual"||g.severity==="notable"),f=d?t.findings.filter(g=>g.severity!=="info").length.toString():void 0,{outer:c,content:s}=pt(`Findings (${t.findings.length})`,d,f);s.appendChild(qt(t.findings,e,o));const a=kt(t,e);if(!a.length)return s.appendChild(l("div",{color:I,fontSize:"11px",textAlign:"center",padding:"16px 8px"},"No findings match the current filter.")),c;const p=buildFindingsSection(a,t,i,n,!0);return p&&s.appendChild(p),c}export function buildLotTestSection(t,i,n,e,o){const d=e?.length?{perWaferMetadata:e.map(c=>c.wafer??{}),populationLabel:`${e.length} wafer${e.length===1?"":"s"} pooled`}:void 0;let f;if(e?.length&&e.every(c=>c.stats.perTestStats!==void 0)){const c=new Map;for(const s of e)for(const a of s.stats.perTestStats??[]){const p=c.get(a.testNumber);p?(p.n+=a.count,p.sum+=a.mean*a.count,p.min=Math.min(p.min,a.min),p.max=Math.max(p.max,a.max)):c.set(a.testNumber,{n:a.count,sum:a.mean*a.count,min:a.min,max:a.max})}f={perTestStats:[...c.entries()].map(([s,a])=>({testNumber:s,count:a.n,min:a.min,max:a.max,mean:a.sum/a.n}))}}if(e?.length&&e.every(c=>c.stats.testSpecYield!==void 0)){const c=new Map;for(const s of e)for(const a of s.stats.testSpecYield??[]){const p=c.get(a.testNumber);p?(p.passDies+=a.passDies,p.totalDies+=a.totalDies):c.set(a.testNumber,{passDies:a.passDies,totalDies:a.totalDies})}f={...f,testSpecYield:[...c.entries()].map(([s,a])=>({testNumber:s,totalDies:a.totalDies,yieldPercent:a.totalDies>0?a.passDies/a.totalDies*100:null}))}}return buildTestSection(t,i,n,f,o,d)}export function createSummaryPanelEl(t,i=document){const n=t==="top"||t==="bottom",e=l("div",{background:Et,border:O,borderRadius:"6px",padding:"12px",overflowY:n?"hidden":"auto",overflowX:n?"auto":"hidden",flexShrink:"0",boxSizing:"border-box",fontFamily:"system-ui, sans-serif",fontSize:"12px",boxShadow:"0 1px 4px rgba(0,0,0,0.08)"},void 0,i);return n?(e.style.height="180px",e.style.width="100%"):(e.style.width="260px",e.style.maxHeight="100%"),e}export function wrapWithSummaryPanel(t,i,n){const e=n==="top"||n==="bottom",o=l("div",{display:"flex",flexDirection:e?"column":"row",gap:"8px",width:"100%",height:"100%",flex:"1 1 0",minHeight:"0",boxSizing:"border-box",alignItems:e?"flex-start":"stretch"});return t.style.flex="1 1 0",t.style.minWidth="0",t.style.minHeight="0",n==="right"||n==="bottom"?(o.appendChild(t),o.appendChild(i)):(o.appendChild(i),o.appendChild(t)),o}function mt(t){return l("div",{fontSize:"13px",fontWeight:"700",color:H,marginBottom:"10px"},t)}function V(t,i){const n=l("button",{background:"none",border:O,borderRadius:"4px",cursor:"pointer",fontSize:"10px",color:b.iconHover,padding:"2px 7px"},t);return n.type="button",n.addEventListener("click",i),n}function ht(...t){const i=t.filter(e=>!!e);if(!i.length)return null;const n=l("div",{display:"flex",flexWrap:"wrap",gap:"6px",marginBottom:"10px"});for(const e of i)n.appendChild(e);return n}function gt(t,i,n,e,o,d,f,c,s,a,p){const g=t.ownerDocument,h=rt({title:"Die list",onClose:()=>{},anchor:t,ownerDocument:g});h.contentWrap.style.padding="14px 16px";const D=Ft(i,n,{...f,title:e,onSaveText:c,waferMetadata:o,metadataFields:d,extraColumn:s,getWafer:a,ringCount:p,ownerDocument:g});D&&h.contentWrap.appendChild(D)}export function renderWaferSummaryContent(t,i){const n=t.scrollTop;t.innerHTML="";const{wafer:e,dies:o,yieldSummary:d,dataCoverage:f,hbinDefs:c,sbinDefs:s,testDefs:a,statsSummary:p,passBins:g=[1],ringCount:h=4,colorScheme:D,fallbackFormat:M,onFindingClick:B,activeFindingId:T=null,findingsFilter:F,onFindingsFilterChange:R,onSaveText:u,metadataFields:L,dieListOptions:k}=i;t.appendChild(mt("Wafer Summary"));const C=i.warnings??it({statsSummary:p});C.length&&t.appendChild(Q(C,t.ownerDocument));const r=d&&f?V("Summary report",()=>{st(yt({wafer:e,dies:o,yieldSummary:d,dataCoverage:f,hbinDefs:c,sbinDefs:s,testDefs:a,statsSummary:p,passBins:g,ringCount:h}),{anchor:t})}):null,m=(k?.enabled??!0)&&o.length?V("View die list",()=>{gt(t,o,a,`Die list \u2014 ${o.length} dies`,e.metadata,L,k,u,void 0,()=>e,h)}):null,$=ht(r,m);$&&t.appendChild($);const v=[],x=p?.stats.isLotStack?p.stats:void 0,S=x?.lotSize!==void 0?{lotSize:x.lotSize,aggrMethod:Dt(x.aggregationMethod)}:void 0;v.push(buildMetadataInfoSection([{metadata:e.metadata??void 0}],S)),d&&f&&v.push(buildYieldSection(d,f,g));const w=o.some(y=>y.hbin!=null),N=o.some(y=>y.sbin!=null);w?v.push(buildBinSection(o,c,"hard",D,p?.stats.hardBinCounts)):N&&v.push(buildBinSection(o,s,"soft",D,p?.stats.softBinCounts)),v.push(buildRingSection(o,e,h,g)),v.push(buildQuadrantSection(o,e,h,g));const W=e.metadata?{waferMetadata:e.metadata}:void 0;v.push(buildTestSection(o,a,M,p?.stats,u,W)),v.push(buildFunctionalTestSection(o,a,p?.stats.functionalYield,u,W)),p&&B&&F&&R&&v.push(buildFindingsSectionWithFilter(p,B,T,F,R));let E=!0;for(const y of v)y&&(E||t.appendChild(ct()),E=!1,t.appendChild(y));t.appendChild(l("div",{height:"12px",flexShrink:"0"})),t.scrollTop=n}export function renderLotSummaryContent(t,i){const n=t.scrollTop;t.innerHTML="";const{lotSummary:e,items:o,hbinDefs:d,sbinDefs:f,testDefs:c,passBins:s=[1],ringCount:a=4,colorScheme:p,fallbackFormat:g,onFindingClick:h,activeFindingId:D=null,onWaferClick:M,findingsFilter:B,onFindingsFilterChange:T,onSaveText:F,dieListOptions:R}=i;t.appendChild(mt(`Lot Summary \u2014 ${e.stats.waferCount} wafer${e.stats.waferCount===1?"":"s"}`));const u=i.warnings??it({lotStatsSummary:e});u.length&&t.appendChild(Q(u,t.ownerDocument));const L=V("Summary report",()=>{st(Ct({items:o.map((y,z)=>({label:y?.label??`W${z+1}`,wafer:y?.wafer,dies:y?.dies,statsSummary:y?.statsSummary})),hbinDefs:d,sbinDefs:f,testDefs:c,passBins:s,ringCount:a}),{anchor:t})}),k=[],C=[],r=[],m=new WeakMap,$=new WeakMap;for(let y=0;y<o.length;y++){const z=o[y];if(!z){C.push([]);continue}z.wafer&&k.push(z.wafer);const _=z.dies??[],xt=z.label??`W${y+1}`;for(const Z of _)m.set(Z,xt),z.wafer&&$.set(Z,z.wafer);C.push(_),r.push(..._)}const v=R?.enabled??!0?V("View die list",()=>{r.length&&gt(t,r,c,`Die list \u2014 ${r.length} dies across ${o.length} wafer${o.length===1?"":"s"}`,nt(o.filter(y=>!!y).map(y=>({metadata:y.wafer?.metadata}))),o.find(y=>y?.metadataFields?.length)?.metadataFields,R,F,{label:"Wafer",get:y=>m.get(y)},y=>$.get(y),a)}):null,x=ht(L,v);x&&t.appendChild(x);const S=r.some(y=>y.hbin!=null),w=r.some(y=>y.sbin!=null),N=o.map(y=>y?.statsSummary).filter(y=>!!y),W=[buildLotOverviewSection(e),buildPerWaferYieldSection(e,o,M),S?buildLotBinSection(r,d,"hard",p):w?buildLotBinSection(r,f,"soft",p):null,buildLotRingSection(C,k,a,s),buildLotQuadrantSection(C,k,a,s),c?.length?buildLotTestSection(r,c,g,N,F):null,c?.length?buildLotFunctionalSection(r,c,N,F):null];h&&B&&T&&W.push(buildFindingsSectionWithFilter(e,h,D,B,T));let E=!0;for(const y of W)y&&(E||t.appendChild(ct()),E=!1,t.appendChild(y));t.appendChild(l("div",{height:"12px",flexShrink:"0"})),t.scrollTop=n}
@@ -374,6 +374,22 @@ export interface OverlayOptions {
374
374
  * overlay then falls back to `doc.body`, matching prior behaviour exactly.
375
375
  */
376
376
  anchor?: Element;
377
+ /**
378
+ * Adds a "Print / Save as PDF" header button that calls the host page's
379
+ * native `window.print()` — identical behaviour in a plain browser tab and
380
+ * inside a Tauri/Electron/WebView2 webview, since both just hand the
381
+ * rendered DOM to the OS print dialog. No host wiring required: this
382
+ * button is purely a discoverability affordance for the `@media print`
383
+ * stylesheet already injected below, which makes ANY open overlay print
384
+ * cleanly (just this box's content, not the rest of the page) whether the
385
+ * user finds Ctrl+P/Cmd+P themselves or clicks this button.
386
+ *
387
+ * `true` calls the overlay's own `window.print()`. Pass a function instead
388
+ * when the overlay's real content lives in a child document the sibling-
389
+ * hiding print stylesheet doesn't reach — e.g. `openReportModal`'s iframe,
390
+ * where printing must target `iframe.contentWindow.print()`.
391
+ */
392
+ printable?: boolean | (() => void);
377
393
  }
378
394
  export interface OverlayHandle {
379
395
  /** null in 'window' mode — there is no backdrop to block the page. */
@@ -544,5 +560,44 @@ export interface UserGuideExtension {
544
560
  * documentation.
545
561
  */
546
562
  export declare function openUserGuideWindow(api: GuideApi, html: string, extension?: UserGuideExtension, anchor?: Element): void;
563
+ /**
564
+ * Opens wmap's own guide window with no live `WaferMapController`/
565
+ * `GalleryController` required — `WaferMapController.openUserGuide()`/
566
+ * `GalleryController.openUserGuide()` are thin wrappers around this exact
567
+ * same call (see their own `openGuideWindow` closures in `renderWaferMap.ts`/
568
+ * `renderWaferGallery.ts`), built from the library's own top-level functions
569
+ * rather than anything derived from a specific render — so a host with
570
+ * nothing rendered yet (e.g. an empty-state "Help" menu, before any file is
571
+ * loaded) can reach the same guide, with the same `extension` content, the
572
+ * same way. Prefer the controller method when one exists — this is for the
573
+ * gap it can't cover.
574
+ *
575
+ * `renderWaferMap`/`renderWaferGallery` are dynamically imported (like
576
+ * `USER_GUIDE_HTML` below) since `toolbar.ts` is itself imported BY both of
577
+ * them — a static import here would cycle back.
578
+ */
579
+ export declare function openWaferMapGuide(extension?: UserGuideExtension, anchor?: Element): void;
580
+ /**
581
+ * Opens report HTML (from `renderSummaryReportHtml`/`renderLotSummaryReportHtml`)
582
+ * in an in-app modal — no host-registered `setReportOpener` required just to
583
+ * *view* a report. `setReportOpener`/`openHtmlReport` remain available as an
584
+ * "Open as full page" action inside this modal (its header's print button, plus
585
+ * a link in the toolbar strip below it), for a host that wants the report as a
586
+ * real separate page — to keep it open outside this modal, or as a fallback if
587
+ * in-app printing misbehaves on a given platform.
588
+ *
589
+ * The report HTML is a complete standalone document (its own `<style>`, its own
590
+ * `<!DOCTYPE html>`) — rendered via `<iframe srcdoc>` rather than parsed apart
591
+ * and inserted into the modal's own DOM (the way the guide's `buildGuideContent`
592
+ * does it). This keeps the report's stylesheet naturally isolated from the host
593
+ * page with no parsing, and lets `iframe.contentWindow.print()` scope printing
594
+ * to just the report — `openOverlay`'s sibling-hiding print stylesheet (built
595
+ * for content that lives directly in the host document, like the guide) isn't
596
+ * needed here and wouldn't reach into the iframe's own document anyway.
597
+ */
598
+ export declare function openReportModal(html: string, opts?: {
599
+ anchor?: Element;
600
+ ownerDocument?: Document;
601
+ }): OverlayHandle;
547
602
  export {};
548
603
  //# sourceMappingURL=toolbar.d.ts.map
@@ -1,4 +1,4 @@
1
- import{getUniqueTestNumbers as fe}from"../renderer/buildView.js";import{dieHasTestData as me}from"../renderer/buildWaferMap.js";import{prettyKey as be}from"../core/utils.js";import{listColorSchemes as oe}from"../renderer/colorSchemes.js";import{ICONS as $}from"./icons.js";import{WMAP_VERSION as he,WMAP_BUILD_TIME as xe}from"./version.js";let ie=!1;export function logWmapVersionOnce(){ie||(ie=!0,console.log(`[wmap] v${he} (built ${xe})`))}export const WMAP_TOKEN_NAMES=["z","icon","icon-hover","icon-active","bg-hover","bg-active","separator","surface","border","menu-hover","menu-active","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","bar-fill-muted"];const w=(e,n)=>`var(--wmap-${e}, ${n})`;export const CLR={icon:w("icon","#506784"),iconHover:w("icon-hover","#2a3f5f"),iconActive:w("icon-active","#1a65ca"),bgHover:w("bg-hover","#edf0f8"),bgActive:w("bg-active","#dce8f8"),separator:w("separator","rgba(0,0,0,0.12)"),menuBg:w("surface","#fff"),menuBorder:w("border","rgba(0,0,0,0.12)"),menuHover:w("menu-hover","#f0f4fc"),menuActive:w("menu-active","#dce8f8"),panelBg:w("panel-bg","#fafbfc"),label:w("text-muted","#647687"),value:w("text-strong","#1f2f43"),text:w("text","#333"),warnBg:w("warn-bg","#fffbe6"),warnBorder:w("warn-border","#f0c040"),warnText:w("warn-text","#7a5800"),errBg:w("err-bg","#fef2f2"),errBorder:w("err-border","#dc8a8a"),errText:w("err-text","#7a1c1c"),infoBg:w("info-bg","#dce8f8"),infoText:w("info-text","#334155"),findingHighlight:w("selected","#e07a20"),findingIndicator:w("finding-indicator","#b7551a"),barFill:w("bar-fill","#2a6fc0"),barFillMuted:w("bar-fill-muted","#94a3b8")};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 a=t.getPropertyValue(`--wmap-${o}`).trim();a&&n.style.setProperty(`--wmap-${o}`,a)}}export function syncWmapPopupTheme(e,n,t){const o=()=>{copyWmapThemeTokens(e,n),t?.()},a=new window.MutationObserver(o);a.observe(e,{attributes:!0,attributeFilter:["style","class"]}),a.observe(document.documentElement,{attributes:!0,attributeFilter:["style","class"]});const r=window.matchMedia("(prefers-color-scheme: dark)");return r.addEventListener("change",o),()=>{a.disconnect(),r.removeEventListener("change",o)}}let ee=null;export function setDetachWindowOpener(e){ee=e}export function openDetachWindow(e){return ee?ee(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 a=URL.createObjectURL(e),r=document.createElement("a");r.href=a,r.download=o,r.click(),URL.revokeObjectURL(a)}export function saveTextFile(e,n,t,o){if(o){o(e,n,t);return}const a=new Blob([e],{type:t}),r=URL.createObjectURL(a),d=document.createElement("a");d.href=r,d.download=n,d.click(),URL.revokeObjectURL(r)}const ve='[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)}function We(e,n,t){e.setAttribute("role","menu"),e.setAttribute("aria-label",n);for(const o of Array.from(e.children)){const a=t(o);a&&(o.setAttribute("role",a),o.tabIndex=-1)}}function X(e,n,t){const o=()=>Array.from(e.querySelectorAll(ve));e.addEventListener("keydown",r=>{const d=o();if(d.length===0)return;const i=e.ownerDocument.activeElement,l=i?d.indexOf(i):-1;switch(r.key){case"ArrowDown":r.preventDefault(),d[l<0||l===d.length-1?0:l+1].focus();break;case"ArrowUp":r.preventDefault(),d[l<=0?d.length-1:l-1].focus();break;case"Home":r.preventDefault(),d[0].focus();break;case"End":r.preventDefault(),d[d.length-1].focus();break;case"Enter":case" ":l>=0&&(r.preventDefault(),d[l].click());break;case"Escape":case"Tab":r.preventDefault(),t(),n?.focus();break}});const a=o()[0];a&&nextFrame(()=>a.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 ae=new WeakMap;export function menuLayerFor(e){const n=overlayRootFor(e),t=ae.get(n);if(t&&t.isConnected)return t;const a=e.ownerDocument.createElement("div");return a.dataset.wmapMenuLayer="1",Object.assign(a.style,{position:"fixed",inset:"0",zIndex:Z_MENU,pointerEvents:"none"}),n.appendChild(a),ae.set(n,a),a}const te=new WeakMap;export function getTooltip(e=document){const n=te.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:"5px",fontSize:"13px",lineHeight:"1.55",maxWidth:"280px",maxHeight:"min(60vh, 480px)",overflow:"hidden",whiteSpace:"pre-wrap",zIndex:Z_ABOVE,display:"none",fontFamily:"system-ui, sans-serif",boxShadow:"0 3px 10px rgba(0,0,0,0.45)"}),te.set(e,t)),e.body.appendChild(t),t}export function hideTooltip(e=document){const n=te.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 a=overlayRootFor(n);e.parentElement!==a&&a.appendChild(e);const r=e.ownerDocument.defaultView??window;e.style.left="0",e.style.top="0";const d=e.offsetWidth,i=e.offsetHeight,l=8;let x=t+14,f=o-8;x+d+l>r.innerWidth&&(x=t-d-6),f+i+l>r.innerHeight&&(f=r.innerHeight-i-l),f<l&&(f=l),e.style.left=`${x}px`,e.style.top=`${f}px`}export function buildDataModeEntries(e,n,t){const o=e.some(me),a=e.some(f=>f.testValues!==void 0&&Object.keys(f.testValues).length>0),r=e.some(f=>f.hbin!=null),d=e.some(f=>f.sbin!=null),i=o?n?.length?n.map(f=>({plotMode:"value",activeTest:f.testNumber,label:f.unit?`${f.name} (${f.unit})`:f.name,logScale:f.logScale})):fe(e).map(f=>({plotMode:"value",activeTest:f,label:`Test ${f}`})):[],l=[...r?[{plotMode:"hardBin",label:MODE_LABELS.hardBin}]:[],...d?[{plotMode:"softBin",label:MODE_LABELS.softBin}]:[]],x=t.includeStacked?[...a?[{plotMode:"stackedValues",label:MODE_LABELS.stackedValues}]:[],...r?[{plotMode:"stackedBins",label:MODE_LABELS.stackedBins}]:[],...d?[{plotMode:"stackedSoftBins",label:MODE_LABELS.stackedSoftBins}]:[]]:[];return{testEntries:i,binEntries:l,stackedEntries:x}}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??be(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:"4px 8px",fontSize:"12px",boxSizing:"border-box",background:CLR.menuBg,color:CLR.text,border:`1px solid ${CLR.menuBorder}`,borderRadius:"4px",outline:"none"}),o.addEventListener("click",a=>a.stopPropagation()),o.addEventListener("mousedown",a=>a.stopPropagation()),o.addEventListener("keydown",a=>a.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,a,r,d,i,l=window,x=[]){const{makeMenuRow:f,makeMenuSection:m}=d,s=document.createElement("div"),c=180,h=e.left+c<=(l.innerWidth??1/0)?e.left:Math.max(4,e.right-c);if(Object.assign(s.style,{position:"fixed",top:`${e.bottom+4}px`,left:`${h}px`,background:CLR.menuBg,border:`1px solid ${CLR.menuBorder}`,borderRadius:"4px",boxShadow:"0 4px 12px rgba(0,0,0,0.15)",zIndex:Z_BASE,minWidth:`${c}px`,padding:"4px 0",pointerEvents:"auto"}),n.length)if(s.appendChild(m("Test Value")),n.length<=INLINE_TEST_LIMIT)for(const u of n)s.appendChild(f(u.label,a(u),!0,g=>{g.stopPropagation(),r(u,s)}));else{const u=i==="value",g=f(MODE_LABELS.value+" \u25B6",u,!1,()=>{});g.style.display="flex",g.style.justifyContent="space-between",g.style.alignItems="center";let b=null,y=null;const L=()=>{y!==null&&(clearTimeout(y),y=null)},S=()=>{L(),b?.remove(),b=null},M=()=>{L(),y=setTimeout(S,300)},N=()=>{if(b)return;const I=g.getBoundingClientRect(),A=160,k=320,W=I.right+2+A<=(l.innerWidth??1/0)?I.right+2:Math.max(4,I.left-2-A),B=Math.min(I.top-4,Math.max(4,(l.innerHeight??1/0)-k-4));if(b=document.createElement("div"),Object.assign(b.style,{position:"fixed",top:`${B}px`,left:`${W}px`,background:CLR.menuBg,border:`1px solid ${CLR.menuBorder}`,borderRadius:"4px",boxShadow:"0 4px 12px rgba(0,0,0,0.15)",zIndex:Z_ABOVE,minWidth:`${A}px`,maxHeight:`${k}px`,overflowY:"auto",padding:"4px 0",pointerEvents:"auto"}),n.length>MENU_SEARCH_THRESHOLD){const D=makeMenuSearchBox(j=>{for(const H of E)H.row.style.display=H.label.includes(j)?"":"none"},"Filter tests\u2026");Object.assign(D.style,{position:"sticky",top:"0",zIndex:"1",background:CLR.menuBg}),b.appendChild(D)}const E=[];for(const D of n){const j=f(D.label,a(D),!1,H=>{H.stopPropagation(),S(),r(D,s)});E.push({row:j,label:D.label.toLowerCase()}),b.appendChild(j)}b.addEventListener("mouseenter",L),b.addEventListener("mouseleave",M),(s.parentElement??l.document.body).appendChild(b),l.document.addEventListener("click",S,{once:!0})};g.addEventListener("mouseenter",()=>{L(),N()}),g.addEventListener("mouseleave",M),s.appendChild(g)}if(t.length){s.appendChild(m("Bins"));for(const u of t)s.appendChild(f(u.label,a(u),!1,g=>{g.stopPropagation(),r(u,s)}))}if(x.length){s.appendChild(m("Metadata"));for(const u of x)s.appendChild(f(u.label,a(u),!1,g=>{g.stopPropagation(),r(u,s)}))}if(o.length){s.appendChild(m("Lot Aggregation"));for(const u of o)s.appendChild(f(u.label,a(u),!1,g=>{g.stopPropagation(),r(u,s)}))}return s.setAttribute("role","menu"),s.setAttribute("aria-label","Plot mode"),s}export function markMenuTrigger(e,n){e.setAttribute("aria-haspopup","menu"),e.setAttribute("aria-expanded",n?"true":"false")}export function wireMenuA11y(e,n,t){X(e,n,t)}export function wireExpandToggle(e,n){const t=e.ownerDocument;let o=!1;function a(x){o!==x&&(o=x,n(o))}function r(){a(!1)}function d(){a(!o),o&&t.addEventListener("click",r,{once:!0})}const i=x=>{x.stopPropagation(),d()},l=x=>{x.key==="Enter"||x.key===" "?(x.preventDefault(),d()):x.key==="Escape"&&r()};return e.setAttribute("role","button"),e.tabIndex<0&&(e.tabIndex=0),e.addEventListener("click",i),e.addEventListener("keydown",l),{isOpen:()=>o,close:r,destroy(){e.removeEventListener("click",i),e.removeEventListener("keydown",l),t.removeEventListener("click",r)}}}export function buildCheckMenuEl(e,n,t,o=window){const{makeMenuRow:a,makeMenuSection:r}=t,d=o.document,i=d.createElement("div"),l=168,f=e.left+l<=(o.innerWidth??1/0)?e.left:Math.max(4,e.right-l);Object.assign(i.style,{position:"fixed",top:`${e.bottom+4}px`,left:`${f}px`,background:CLR.menuBg,border:`1px solid ${CLR.menuBorder}`,borderRadius:"4px",boxShadow:"0 4px 12px rgba(0,0,0,0.15)",zIndex:Z_BASE,minWidth:`${l}px`,padding:"4px 0",pointerEvents:"auto"});for(const m of n)if("section"in m)i.appendChild(r(m.section));else{const s=m.enabled!==!1;if(!s&&!m.disabledHint)continue;const c=d.createElement("div");c.setAttribute("role","menuitemcheckbox"),c.setAttribute("aria-checked",m.active?"true":"false"),c.tabIndex=-1,s||(c.setAttribute("aria-disabled","true"),c.title=m.disabledHint),Object.assign(c.style,{display:"flex",alignItems:"center",gap:"6px",padding:"6px 14px",fontSize:"12px",cursor:s?"pointer":"default",color:s?m.active?CLR.iconActive:CLR.text:CLR.label,fontWeight:m.active?"700":"400",background:m.active?CLR.menuActive:"transparent",whiteSpace:"nowrap",outline:"none"});const v=d.createElement("span");Object.assign(v.style,{width:"12px",flexShrink:"0",color:CLR.iconActive,visibility:m.active?"visible":"hidden"}),v.textContent="\u2713",v.setAttribute("aria-hidden","true");const h=d.createElement("span");h.textContent=m.label,c.appendChild(v),c.appendChild(h),s?(c.addEventListener("mouseenter",()=>{m.active||(c.style.background=CLR.menuHover)}),c.addEventListener("mouseleave",()=>{c.style.background=m.active?CLR.menuActive:"transparent"}),c.addEventListener("focus",()=>{m.active||(c.style.background=CLR.menuHover)}),c.addEventListener("blur",()=>{c.style.background=m.active?CLR.menuActive:"transparent"}),c.addEventListener("click",u=>{u.stopPropagation(),m.onClick(u)})):c.addEventListener("click",u=>{u.stopPropagation()}),i.appendChild(c)}return i}export function createToolbarHelpers(e){const n=e.ownerDocument;let t=null;const o=s=>menuLayerFor(s);function a(s,c,v){const h=n.createElement("button");return h.innerHTML=$[s],h.type="button",h.ariaLabel=c,Object.assign(h.style,{display:"flex",alignItems:"center",justifyContent:"center",width:"28px",height:"28px",padding:"0",border:"none",borderRadius:"3px",background:"transparent",color:CLR.icon,cursor:"pointer",pointerEvents:"auto",transition:"background 0.12s, color 0.12s",flexShrink:"0"}),h.addEventListener("mouseenter",u=>{h.dataset.active||(h.style.background=CLR.bgHover,h.style.color=CLR.iconHover),e.innerHTML=h.ariaLabel??c,e.style.display="block",positionTooltip(e,h,u.clientX,u.clientY)}),h.addEventListener("mousemove",u=>{e.style.display==="block"&&positionTooltip(e,h,u.clientX,u.clientY)}),h.addEventListener("mouseleave",()=>{h.dataset.active||(h.style.background="transparent",h.style.color=CLR.icon),e.style.display="none"}),h.addEventListener("click",()=>{e.style.display="none",v()}),h}function r(s,c){c?(s.dataset.active="1",s.style.background=CLR.bgActive,s.style.color=CLR.iconActive):(delete s.dataset.active,s.style.background="transparent",s.style.color=CLR.icon)}function d(){const s=n.createElement("div");return Object.assign(s.style,{width:"1px",height:"18px",background:CLR.separator,margin:"0 2px",flexShrink:"0"}),s}function i(s,c,v,h){const u=n.createElement("div");return u.textContent=s,u.setAttribute("role","menuitemradio"),u.setAttribute("aria-checked",c?"true":"false"),u.tabIndex=-1,Object.assign(u.style,{padding:`6px 14px 6px ${v?"26px":"14px"}`,fontSize:"12px",cursor:"pointer",color:c?CLR.iconActive:CLR.text,fontWeight:c?"700":"400",background:c?CLR.menuActive:"transparent",whiteSpace:"nowrap",outline:"none"}),u.addEventListener("mouseenter",()=>{c||(u.style.background=CLR.menuHover)}),u.addEventListener("mouseleave",()=>{u.style.background=c?CLR.menuActive:"transparent"}),u.addEventListener("focus",()=>{c||(u.style.background=CLR.menuHover)}),u.addEventListener("blur",()=>{u.style.background=c?CLR.menuActive:"transparent"}),u.addEventListener("click",h),u}function l(s){const c=n.createElement("div");return c.textContent=s,c.setAttribute("role","presentation"),Object.assign(c.style,{padding:"5px 14px 2px",fontSize:"10px",fontWeight:"600",letterSpacing:"0.05em",color:CLR.label,textTransform:"uppercase",pointerEvents:"none",userSelect:"none"}),c}function x(s,c,v,h,u){const g=()=>{t&&(t.remove(),t=null),b.setAttribute("aria-expanded","false")},b=a(s,c,()=>{if(t){g();return}const y=n.createElement("div"),L=b.getBoundingClientRect(),S=b.ownerDocument.defaultView??window,M=148,I=L.left+M<=(S.innerWidth??1/0)?L.left:Math.max(4,L.right-M);Object.assign(y.style,{position:"fixed",top:`${L.bottom+4}px`,left:`${I}px`,background:CLR.menuBg,border:`1px solid ${CLR.menuBorder}`,borderRadius:"4px",boxShadow:"0 4px 12px rgba(0,0,0,0.15)",zIndex:Z_BASE,minWidth:`${M}px`,padding:"4px 0",pointerEvents:"auto"});for(const A of v()){const k=n.createElement("div");k.textContent=A.label,k.dataset.wmapDropdownValue=A.value;const C=A.value===h();k.setAttribute("role","menuitemradio"),k.setAttribute("aria-checked",C?"true":"false"),k.tabIndex=-1,Object.assign(k.style,{padding:"6px 14px",fontSize:"12px",cursor:"pointer",color:C?CLR.iconActive:CLR.text,fontWeight:C?"700":"400",background:C?CLR.menuActive:"transparent",whiteSpace:"nowrap",outline:"none"});const W=()=>{A.value!==h()&&(k.style.background=CLR.menuHover)},B=()=>{k.style.background=A.value===h()?CLR.menuActive:"transparent"};k.addEventListener("mouseenter",W),k.addEventListener("mouseleave",B),k.addEventListener("focus",W),k.addEventListener("blur",B),k.addEventListener("click",E=>{E.stopPropagation(),u(A.value),g()}),y.appendChild(k)}y.setAttribute("role","menu"),y.setAttribute("aria-label",c),o(b).appendChild(y),t=y,b.setAttribute("aria-expanded","true"),X(y,b,g)});return b.setAttribute("aria-haspopup","menu"),b.setAttribute("aria-expanded","false"),b}function f(s,c,v,h){function u(){return buildCheckMenuEl(b.getBoundingClientRect(),v().map(y=>"section"in y?y:{...y,onClick:L=>{y.onClick(L),h(b);const S=t;if(!S)return;const M=u();M.setAttribute("role","menu"),M.setAttribute("aria-label",c),S.replaceWith(M),t=M,X(M,b,g)}}),{makeMenuRow:i,makeMenuSection:l},b.ownerDocument.defaultView??window)}const g=()=>{t&&(t.remove(),t=null),b.setAttribute("aria-expanded","false")},b=a(s,c,()=>{if(t){g();return}const y=u();y.setAttribute("role","menu"),y.setAttribute("aria-label",c),o(b).appendChild(y),t=y,b.setAttribute("aria-expanded","true"),X(y,b,g)});return b.setAttribute("aria-haspopup","menu"),b.setAttribute("aria-expanded","false"),h(b),b}function m(s){if(t&&!t.contains(s.target)&&(t.remove(),t=null,s.target?.getAttribute?.("aria-haspopup")!=="menu"))for(const v of document.querySelectorAll('[aria-haspopup="menu"][aria-expanded="true"]'))v.setAttribute("aria-expanded","false")}return{makeBtn:a,setActive:r,makeSep:d,makeMenuRow:i,makeMenuSection:l,makeDropdown:x,makeCheckMenuBtn:f,closeOpenMenu:m,getOpenMenu:()=>t,setOpenMenu:s=>{t=s}}}const ge=7e3;let ye=0;function re(){return ge+ ++ye}const we=32,ke=6;let Ee=0;function Le(){return Ee++%ke*we}function Me(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 se(e){const n=e.mode==="modal",t=e.ownerDocument??document,o=t.defaultView??window,a=t.body.style.overflow;n&&(t.body.style.overflow="hidden");let r=null;n&&(r=t.createElement("div"),r.id="wmap-modal-backdrop",Object.assign(r.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,i=t.createElement("div");if(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,Object.assign(i.style,{position:"relative",background:CLR.menuBg,borderRadius:"12px",overflow:"hidden",display:"flex",flexDirection:"column",width:"min(90vw, 700px)",height:"min(90vh, 700px)",boxShadow:"0 20px 60px rgba(0,0,0,0.4)",minWidth:"320px",minHeight:"240px",maxWidth:"100vw",maxHeight:"100vh",zIndex:n?Z_ABOVE2:String(re())}),!n){const p=Le();Object.assign(i.style,{position:"fixed",top:`${Math.round(o.innerHeight*.08)+p}px`,left:`${Math.round(o.innerWidth*.08)+p}px`})}const l=t.createElement("div");Object.assign(l.style,{display:"flex",alignItems:"center",gap:"6px",padding:"10px 14px",borderBottom:`1px solid ${CLR.menuBorder}`,flexShrink:"0"});const x={border:`1px solid ${CLR.menuBorder}`,borderRadius:"4px",background:CLR.panelBg,cursor:"pointer",color:CLR.label,lineHeight:"1",padding:"0",display:"flex",alignItems:"center",justifyContent:"center",width:"28px",height:"28px"};if(e.title){const p=t.createElement("span");p.textContent=e.title,p.title=e.title,p.dataset.wmapWindowTitle="1",Object.assign(p.style,{fontWeight:"700",fontSize:"14px",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",minWidth:"0"}),l.appendChild(p)}const f=t.createElement("div");f.style.flex="1",l.appendChild(f);let m=null;n||(m=t.createElement("button"),m.type="button",m.innerHTML=$.windowMinimize,m.title="Minimize",m.setAttribute("aria-label","Minimize"),Object.assign(m.style,x),m.addEventListener("click",()=>M(!b)),l.appendChild(m));const s=t.createElement("button");s.type="button",s.innerHTML=$.maximize,s.title="Maximize (F)",s.setAttribute("aria-label","Maximize"),Object.assign(s.style,x),s.addEventListener("click",()=>g(!v));const c=t.createElement("button");c.type="button",c.innerHTML=$.close,c.title="Close (Esc)",c.setAttribute("aria-label","Close"),Object.assign(c.style,x),c.addEventListener("click",C),l.appendChild(s),l.appendChild(c);let v=!1,h="",u="";function g(p){v=p,s.innerHTML=v?$.minimize:$.maximize,s.title=v?"Restore (F)":"Maximize (F)",s.setAttribute("aria-label",v?"Restore":"Maximize"),E.style.display=v?"none":"block",v?(i.style.borderRadius="0",i.style.width="100vw",i.style.height="100vh",n||(h=i.style.top,u=i.style.left,i.style.top="0",i.style.left="0")):(i.style.borderRadius="12px",i.style.width="min(90vw, 700px)",i.style.height="min(90vh, 700px)",n||(i.style.top=h,i.style.left=u)),e.onMaximizeChange?.(v,i)}let b=!1,y="",L="";const S=220;function M(p){b=p,m.innerHTML=b?$.windowRestore:$.windowMinimize,m.title=b?"Restore":"Minimize",m.setAttribute("aria-label",b?"Restore":"Minimize"),E.style.display=b?"none":"block",b?(y=i.style.height,L=i.style.width,i.style.minHeight="0",i.style.height="auto",i.style.minWidth="0",i.style.width=`${S}px`,s.disabled=!0,s.style.opacity="0.4",s.style.cursor="default",B.style.display="none"):(i.style.minHeight="240px",i.style.height=y||"min(90vh, 700px)",i.style.minWidth="320px",i.style.width=L||"min(90vw, 700px)",s.disabled=!1,s.style.opacity="1",s.style.cursor="pointer",B.style.display="flex")}function N(){const p=t.body.style.userSelect;return t.body.style.userSelect="none",()=>{t.body.style.userSelect=p}}n||(l.style.cursor="move",l.addEventListener("pointerdown",p=>{if(v||p.target.closest('button, [role="button"]'))return;p.preventDefault();const T=N(),z=p.clientX,R=p.clientY,O=i.offsetTop,_=i.offsetLeft,q=o.innerHeight-l.offsetHeight,Q=o.innerWidth-40,G=40-i.offsetWidth;l.setPointerCapture(p.pointerId);const U=V=>{const J=Math.min(Math.max(O+(V.clientY-R),0),q),pe=Math.min(Math.max(_+(V.clientX-z),G),Q);i.style.top=`${J}px`,i.style.left=`${pe}px`},F=V=>{T(),l.releasePointerCapture(V.pointerId),l.removeEventListener("pointermove",U),l.removeEventListener("pointerup",F)};l.addEventListener("pointermove",U),l.addEventListener("pointerup",F)}));const I='button,[href],input,select,textarea,[tabindex]:not([tabindex="-1"]),[role="menuitem"],[role="menuitemradio"],[role="menuitemcheckbox"]';function A(p){const T=Array.from(i.querySelectorAll(I)).filter(_=>_.offsetParent!==null||_===t.activeElement);if(T.length===0){p.preventDefault(),i.focus();return}const z=T[0],R=T[T.length-1],O=t.activeElement;p.shiftKey&&(O===z||!i.contains(O))?(p.preventDefault(),R.focus()):!p.shiftKey&&O===R&&(p.preventDefault(),z.focus())}const k=p=>{if(p.key==="Escape"){C();return}if(n&&(p.key==="e"||p.key==="E")){C();return}if(n&&p.key==="Tab"){A(p);return}(p.key==="f"||p.key==="F")&&!b&&g(!v)};function C(){n?t.removeEventListener("keydown",k):i.removeEventListener("keydown",k),Z.remove(),ue(),hideTooltip(t),reparentTooltip(t.body),r?r.remove():i.remove(),n&&(t.body.style.overflow=a),d?.focus?.(),e.onClose()}function W(){n||(i.style.zIndex=String(re()))}const B=t.createElement("div");Object.assign(B.style,{flex:"1",minHeight:"0",minWidth:"0",display:"flex",overflow:"hidden"});const E=t.createElement("div");E.tabIndex=0,E.setAttribute("role","separator"),E.setAttribute("aria-label","Resize window (arrow keys, or drag)"),Object.assign(E.style,{position:"absolute",right:"0",bottom:"0",width:"16px",height:"16px",cursor:"nwse-resize",touchAction:"none"}),E.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>',E.style.color=CLR.label;const D=320,j=240,H=20;function Y(p,T){const z=o.innerWidth-i.offsetLeft,R=o.innerHeight-i.offsetTop,O=Math.min(Math.max(i.offsetWidth+p,D),z),_=Math.min(Math.max(i.offsetHeight+T,j),R);i.style.width=`${O}px`,i.style.height=`${_}px`}E.addEventListener("keydown",p=>{if(!(v||b))switch(p.key){case"ArrowRight":p.preventDefault(),Y(H,0);break;case"ArrowLeft":p.preventDefault(),Y(-H,0);break;case"ArrowDown":p.preventDefault(),Y(0,H);break;case"ArrowUp":p.preventDefault(),Y(0,-H);break}}),E.addEventListener("pointerdown",p=>{if(v||b)return;p.preventDefault();const T=N(),z=p.clientX,R=p.clientY,O=i.offsetWidth,_=i.offsetHeight,q=o.innerWidth-i.offsetLeft,Q=o.innerHeight-i.offsetTop;E.setPointerCapture(p.pointerId);const G=F=>{const V=Math.min(Math.max(O+(F.clientX-z),D),q),J=Math.min(Math.max(_+(F.clientY-R),j),Q);i.style.width=`${V}px`,i.style.height=`${J}px`},U=F=>{T(),E.releasePointerCapture(F.pointerId),E.removeEventListener("pointermove",G),E.removeEventListener("pointerup",U)};E.addEventListener("pointermove",G),E.addEventListener("pointerup",U)}),i.appendChild(l),i.appendChild(B),i.appendChild(E);const K=e.anchor?overlayRootFor(e.anchor):t.body;r?(r.appendChild(i),K.appendChild(r)):K.appendChild(i);const ue=Me(t,K),Z=t.createElement("style");return Z.textContent=`@media print{
1
+ import{getUniqueTestNumbers as be}from"../renderer/buildView.js";import{dieHasTestData as xe}from"../renderer/buildWaferMap.js";import{prettyKey as he}from"../core/utils.js";import{listColorSchemes as ie}from"../renderer/colorSchemes.js";import{ICONS as I}from"./icons.js";import{WMAP_VERSION as ge,WMAP_BUILD_TIME as ve}from"./version.js";import{openHtmlReport as ye}from"../stats/renderFindingsReport.js";import{buildWaferMap as we}from"../renderer/buildWaferMap.js";import{analyzeWaferMap as ke}from"../stats/analyzeWaferMap.js";let re=!1;export function logWmapVersionOnce(){re||(re=!0,console.log(`[wmap] v${ge} (built ${ve})`))}export const WMAP_TOKEN_NAMES=["z","icon","icon-hover","icon-active","bg-hover","bg-active","separator","surface","border","menu-hover","menu-active","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","bar-fill-muted"];const w=(e,n)=>`var(--wmap-${e}, ${n})`;export const CLR={icon:w("icon","#506784"),iconHover:w("icon-hover","#2a3f5f"),iconActive:w("icon-active","#1a65ca"),bgHover:w("bg-hover","#edf0f8"),bgActive:w("bg-active","#dce8f8"),separator:w("separator","rgba(0,0,0,0.12)"),menuBg:w("surface","#fff"),menuBorder:w("border","rgba(0,0,0,0.12)"),menuHover:w("menu-hover","#f0f4fc"),menuActive:w("menu-active","#dce8f8"),panelBg:w("panel-bg","#fafbfc"),label:w("text-muted","#647687"),value:w("text-strong","#1f2f43"),text:w("text","#333"),warnBg:w("warn-bg","#fffbe6"),warnBorder:w("warn-border","#f0c040"),warnText:w("warn-text","#7a5800"),errBg:w("err-bg","#fef2f2"),errBorder:w("err-border","#dc8a8a"),errText:w("err-text","#7a1c1c"),infoBg:w("info-bg","#dce8f8"),infoText:w("info-text","#334155"),findingHighlight:w("selected","#e07a20"),findingIndicator:w("finding-indicator","#b7551a"),barFill:w("bar-fill","#2a6fc0"),barFillMuted:w("bar-fill-muted","#94a3b8")};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 a=window.matchMedia("(prefers-color-scheme: dark)");return a.addEventListener("change",o),()=>{r.disconnect(),a.removeEventListener("change",o)}}let te=null;export function setDetachWindowOpener(e){te=e}export function openDetachWindow(e){return te?te(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 r=URL.createObjectURL(e),a=document.createElement("a");a.href=r,a.download=o,a.click(),URL.revokeObjectURL(r)}export function saveTextFile(e,n,t,o){if(o){o(e,n,t);return}const r=new Blob([e],{type:t}),a=URL.createObjectURL(r),p=document.createElement("a");p.href=a,p.download=n,p.click(),URL.revokeObjectURL(a)}const Ee='[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)}function Ge(e,n,t){e.setAttribute("role","menu"),e.setAttribute("aria-label",n);for(const o of Array.from(e.children)){const r=t(o);r&&(o.setAttribute("role",r),o.tabIndex=-1)}}function q(e,n,t){const o=()=>Array.from(e.querySelectorAll(Ee));e.addEventListener("keydown",a=>{const p=o();if(p.length===0)return;const i=e.ownerDocument.activeElement,l=i?p.indexOf(i):-1;switch(a.key){case"ArrowDown":a.preventDefault(),p[l<0||l===p.length-1?0:l+1].focus();break;case"ArrowUp":a.preventDefault(),p[l<=0?p.length-1:l-1].focus();break;case"Home":a.preventDefault(),p[0].focus();break;case"End":a.preventDefault(),p[p.length-1].focus();break;case"Enter":case" ":l>=0&&(a.preventDefault(),p[l].click());break;case"Escape":case"Tab":a.preventDefault(),t(),n?.focus();break}});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 ae=new WeakMap;export function menuLayerFor(e){const n=overlayRootFor(e),t=ae.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),ae.set(n,r),r}const ne=new WeakMap;export function getTooltip(e=document){const n=ne.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:"5px",fontSize:"13px",lineHeight:"1.55",maxWidth:"280px",maxHeight:"min(60vh, 480px)",overflow:"hidden",whiteSpace:"pre-wrap",zIndex:Z_ABOVE,display:"none",fontFamily:"system-ui, sans-serif",boxShadow:"0 3px 10px rgba(0,0,0,0.45)"}),ne.set(e,t)),e.body.appendChild(t),t}export function hideTooltip(e=document){const n=ne.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 a=e.ownerDocument.defaultView??window;e.style.left="0",e.style.top="0";const p=e.offsetWidth,i=e.offsetHeight,l=8;let h=t+14,f=o-8;h+p+l>a.innerWidth&&(h=t-p-6),f+i+l>a.innerHeight&&(f=a.innerHeight-i-l),f<l&&(f=l),e.style.left=`${h}px`,e.style.top=`${f}px`}export function buildDataModeEntries(e,n,t){const o=e.some(xe),r=e.some(f=>f.testValues!==void 0&&Object.keys(f.testValues).length>0),a=e.some(f=>f.hbin!=null),p=e.some(f=>f.sbin!=null),i=o?n?.length?n.map(f=>({plotMode:"value",activeTest:f.testNumber,label:f.unit?`${f.name} (${f.unit})`:f.name,logScale:f.logScale})):be(e).map(f=>({plotMode:"value",activeTest:f,label:`Test ${f}`})):[],l=[...a?[{plotMode:"hardBin",label:MODE_LABELS.hardBin}]:[],...p?[{plotMode:"softBin",label:MODE_LABELS.softBin}]:[]],h=t.includeStacked?[...r?[{plotMode:"stackedValues",label:MODE_LABELS.stackedValues}]:[],...a?[{plotMode:"stackedBins",label:MODE_LABELS.stackedBins}]:[],...p?[{plotMode:"stackedSoftBins",label:MODE_LABELS.stackedSoftBins}]:[]]:[];return{testEntries:i,binEntries:l,stackedEntries:h}}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??he(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:"4px 8px",fontSize:"12px",boxSizing:"border-box",background:CLR.menuBg,color:CLR.text,border:`1px solid ${CLR.menuBorder}`,borderRadius:"4px",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,a,p,i,l=window,h=[]){const{makeMenuRow:f,makeMenuSection:b}=p,s=document.createElement("div"),d=180,u=e.left+d<=(l.innerWidth??1/0)?e.left:Math.max(4,e.right-d);if(Object.assign(s.style,{position:"fixed",top:`${e.bottom+4}px`,left:`${u}px`,background:CLR.menuBg,border:`1px solid ${CLR.menuBorder}`,borderRadius:"4px",boxShadow:"0 4px 12px rgba(0,0,0,0.15)",zIndex:Z_BASE,minWidth:`${d}px`,padding:"4px 0",pointerEvents:"auto"}),n.length)if(s.appendChild(b("Test Value")),n.length<=INLINE_TEST_LIMIT)for(const c of n)s.appendChild(f(c.label,r(c),!0,y=>{y.stopPropagation(),a(c,s)}));else{const c=i==="value",y=f(MODE_LABELS.value+" \u25B6",c,!1,()=>{});y.style.display="flex",y.style.justifyContent="space-between",y.style.alignItems="center";let g=null,v=null;const L=()=>{v!==null&&(clearTimeout(v),v=null)},C=()=>{L(),g?.remove(),g=null},A=()=>{L(),v=setTimeout(C,300)},O=()=>{if(g)return;const S=y.getBoundingClientRect(),M=160,E=320,T=S.right+2+M<=(l.innerWidth??1/0)?S.right+2:Math.max(4,S.left-2-M),z=Math.min(S.top-4,Math.max(4,(l.innerHeight??1/0)-E-4));if(g=document.createElement("div"),Object.assign(g.style,{position:"fixed",top:`${z}px`,left:`${T}px`,background:CLR.menuBg,border:`1px solid ${CLR.menuBorder}`,borderRadius:"4px",boxShadow:"0 4px 12px rgba(0,0,0,0.15)",zIndex:Z_ABOVE,minWidth:`${M}px`,maxHeight:`${E}px`,overflowY:"auto",padding:"4px 0",pointerEvents:"auto"}),n.length>MENU_SEARCH_THRESHOLD){const k=makeMenuSearchBox(j=>{for(const F of D)F.row.style.display=F.label.includes(j)?"":"none"},"Filter tests\u2026");Object.assign(k.style,{position:"sticky",top:"0",zIndex:"1",background:CLR.menuBg}),g.appendChild(k)}const D=[];for(const k of n){const j=f(k.label,r(k),!1,F=>{F.stopPropagation(),C(),a(k,s)});D.push({row:j,label:k.label.toLowerCase()}),g.appendChild(j)}g.addEventListener("mouseenter",L),g.addEventListener("mouseleave",A),(s.parentElement??l.document.body).appendChild(g),l.document.addEventListener("click",C,{once:!0})};y.addEventListener("mouseenter",()=>{L(),O()}),y.addEventListener("mouseleave",A),s.appendChild(y)}if(t.length){s.appendChild(b("Bins"));for(const c of t)s.appendChild(f(c.label,r(c),!1,y=>{y.stopPropagation(),a(c,s)}))}if(h.length){s.appendChild(b("Metadata"));for(const c of h)s.appendChild(f(c.label,r(c),!1,y=>{y.stopPropagation(),a(c,s)}))}if(o.length){s.appendChild(b("Lot Aggregation"));for(const c of o)s.appendChild(f(c.label,r(c),!1,y=>{y.stopPropagation(),a(c,s)}))}return s.setAttribute("role","menu"),s.setAttribute("aria-label","Plot mode"),s}export function markMenuTrigger(e,n){e.setAttribute("aria-haspopup","menu"),e.setAttribute("aria-expanded",n?"true":"false")}export function wireMenuA11y(e,n,t){q(e,n,t)}export function wireExpandToggle(e,n){const t=e.ownerDocument;let o=!1;function r(h){o!==h&&(o=h,n(o))}function a(){r(!1)}function p(){r(!o),o&&t.addEventListener("click",a,{once:!0})}const i=h=>{h.stopPropagation(),p()},l=h=>{h.key==="Enter"||h.key===" "?(h.preventDefault(),p()):h.key==="Escape"&&a()};return e.setAttribute("role","button"),e.tabIndex<0&&(e.tabIndex=0),e.addEventListener("click",i),e.addEventListener("keydown",l),{isOpen:()=>o,close:a,destroy(){e.removeEventListener("click",i),e.removeEventListener("keydown",l),t.removeEventListener("click",a)}}}export function buildCheckMenuEl(e,n,t,o=window){const{makeMenuRow:r,makeMenuSection:a}=t,p=o.document,i=p.createElement("div"),l=168,f=e.left+l<=(o.innerWidth??1/0)?e.left:Math.max(4,e.right-l);Object.assign(i.style,{position:"fixed",top:`${e.bottom+4}px`,left:`${f}px`,background:CLR.menuBg,border:`1px solid ${CLR.menuBorder}`,borderRadius:"4px",boxShadow:"0 4px 12px rgba(0,0,0,0.15)",zIndex:Z_BASE,minWidth:`${l}px`,padding:"4px 0",pointerEvents:"auto"});for(const b of n)if("section"in b)i.appendChild(a(b.section));else{const s=b.enabled!==!1;if(!s&&!b.disabledHint)continue;const d=p.createElement("div");d.setAttribute("role","menuitemcheckbox"),d.setAttribute("aria-checked",b.active?"true":"false"),d.tabIndex=-1,s||(d.setAttribute("aria-disabled","true"),d.title=b.disabledHint),Object.assign(d.style,{display:"flex",alignItems:"center",gap:"6px",padding:"6px 14px",fontSize:"12px",cursor:s?"pointer":"default",color:s?b.active?CLR.iconActive:CLR.text:CLR.label,fontWeight:b.active?"700":"400",background:b.active?CLR.menuActive:"transparent",whiteSpace:"nowrap",outline:"none"});const m=p.createElement("span");Object.assign(m.style,{width:"12px",flexShrink:"0",color:CLR.iconActive,visibility:b.active?"visible":"hidden"}),m.textContent="\u2713",m.setAttribute("aria-hidden","true");const u=p.createElement("span");u.textContent=b.label,d.appendChild(m),d.appendChild(u),s?(d.addEventListener("mouseenter",()=>{b.active||(d.style.background=CLR.menuHover)}),d.addEventListener("mouseleave",()=>{d.style.background=b.active?CLR.menuActive:"transparent"}),d.addEventListener("focus",()=>{b.active||(d.style.background=CLR.menuHover)}),d.addEventListener("blur",()=>{d.style.background=b.active?CLR.menuActive:"transparent"}),d.addEventListener("click",c=>{c.stopPropagation(),b.onClick(c)})):d.addEventListener("click",c=>{c.stopPropagation()}),i.appendChild(d)}return i}export function createToolbarHelpers(e){const n=e.ownerDocument;let t=null;const o=s=>menuLayerFor(s);function r(s,d,m){const u=n.createElement("button");return u.innerHTML=I[s],u.type="button",u.ariaLabel=d,Object.assign(u.style,{display:"flex",alignItems:"center",justifyContent:"center",width:"28px",height:"28px",padding:"0",border:"none",borderRadius:"3px",background:"transparent",color:CLR.icon,cursor:"pointer",pointerEvents:"auto",transition:"background 0.12s, color 0.12s",flexShrink:"0"}),u.addEventListener("mouseenter",c=>{u.dataset.active||(u.style.background=CLR.bgHover,u.style.color=CLR.iconHover),e.innerHTML=u.ariaLabel??d,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",m()}),u}function a(s,d){d?(s.dataset.active="1",s.style.background=CLR.bgActive,s.style.color=CLR.iconActive):(delete s.dataset.active,s.style.background="transparent",s.style.color=CLR.icon)}function p(){const s=n.createElement("div");return Object.assign(s.style,{width:"1px",height:"18px",background:CLR.separator,margin:"0 2px",flexShrink:"0"}),s}function i(s,d,m,u){const c=n.createElement("div");return c.textContent=s,c.setAttribute("role","menuitemradio"),c.setAttribute("aria-checked",d?"true":"false"),c.tabIndex=-1,Object.assign(c.style,{padding:`6px 14px 6px ${m?"26px":"14px"}`,fontSize:"12px",cursor:"pointer",color:d?CLR.iconActive:CLR.text,fontWeight:d?"700":"400",background:d?CLR.menuActive:"transparent",whiteSpace:"nowrap",outline:"none"}),c.addEventListener("mouseenter",()=>{d||(c.style.background=CLR.menuHover)}),c.addEventListener("mouseleave",()=>{c.style.background=d?CLR.menuActive:"transparent"}),c.addEventListener("focus",()=>{d||(c.style.background=CLR.menuHover)}),c.addEventListener("blur",()=>{c.style.background=d?CLR.menuActive:"transparent"}),c.addEventListener("click",u),c}function l(s){const d=n.createElement("div");return d.textContent=s,d.setAttribute("role","presentation"),Object.assign(d.style,{padding:"5px 14px 2px",fontSize:"10px",fontWeight:"600",letterSpacing:"0.05em",color:CLR.label,textTransform:"uppercase",pointerEvents:"none",userSelect:"none"}),d}function h(s,d,m,u,c){const y=()=>{t&&(t.remove(),t=null),g.setAttribute("aria-expanded","false")},g=r(s,d,()=>{if(t){y();return}const v=n.createElement("div"),L=g.getBoundingClientRect(),C=g.ownerDocument.defaultView??window,A=148,S=L.left+A<=(C.innerWidth??1/0)?L.left:Math.max(4,L.right-A);Object.assign(v.style,{position:"fixed",top:`${L.bottom+4}px`,left:`${S}px`,background:CLR.menuBg,border:`1px solid ${CLR.menuBorder}`,borderRadius:"4px",boxShadow:"0 4px 12px rgba(0,0,0,0.15)",zIndex:Z_BASE,minWidth:`${A}px`,padding:"4px 0",pointerEvents:"auto"});for(const M of m()){const E=n.createElement("div");E.textContent=M.label,E.dataset.wmapDropdownValue=M.value;const B=M.value===u();E.setAttribute("role","menuitemradio"),E.setAttribute("aria-checked",B?"true":"false"),E.tabIndex=-1,Object.assign(E.style,{padding:"6px 14px",fontSize:"12px",cursor:"pointer",color:B?CLR.iconActive:CLR.text,fontWeight:B?"700":"400",background:B?CLR.menuActive:"transparent",whiteSpace:"nowrap",outline:"none"});const T=()=>{M.value!==u()&&(E.style.background=CLR.menuHover)},z=()=>{E.style.background=M.value===u()?CLR.menuActive:"transparent"};E.addEventListener("mouseenter",T),E.addEventListener("mouseleave",z),E.addEventListener("focus",T),E.addEventListener("blur",z),E.addEventListener("click",D=>{D.stopPropagation(),c(M.value),y()}),v.appendChild(E)}v.setAttribute("role","menu"),v.setAttribute("aria-label",d),o(g).appendChild(v),t=v,g.setAttribute("aria-expanded","true"),q(v,g,y)});return g.setAttribute("aria-haspopup","menu"),g.setAttribute("aria-expanded","false"),g}function f(s,d,m,u){function c(){return buildCheckMenuEl(g.getBoundingClientRect(),m().map(v=>"section"in v?v:{...v,onClick:L=>{v.onClick(L),u(g);const C=t;if(!C)return;const A=c();A.setAttribute("role","menu"),A.setAttribute("aria-label",d),C.replaceWith(A),t=A,q(A,g,y)}}),{makeMenuRow:i,makeMenuSection:l},g.ownerDocument.defaultView??window)}const y=()=>{t&&(t.remove(),t=null),g.setAttribute("aria-expanded","false")},g=r(s,d,()=>{if(t){y();return}const v=c();v.setAttribute("role","menu"),v.setAttribute("aria-label",d),o(g).appendChild(v),t=v,g.setAttribute("aria-expanded","true"),q(v,g,y)});return g.setAttribute("aria-haspopup","menu"),g.setAttribute("aria-expanded","false"),u(g),g}function b(s){if(t&&!t.contains(s.target)&&(t.remove(),t=null,s.target?.getAttribute?.("aria-haspopup")!=="menu"))for(const m of document.querySelectorAll('[aria-haspopup="menu"][aria-expanded="true"]'))m.setAttribute("aria-expanded","false")}return{makeBtn:r,setActive:a,makeSep:p,makeMenuRow:i,makeMenuSection:l,makeDropdown:h,makeCheckMenuBtn:f,closeOpenMenu:b,getOpenMenu:()=>t,setOpenMenu:s=>{t=s}}}const Le=7e3;let Ce=0;function se(){return Le+ ++Ce}const Me=32,Ae=6;let Se=0;function Be(){return Se++%Ae*Me}function Te(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 le(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 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 p=t.activeElement,i=t.createElement("div");if(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,Object.assign(i.style,{position:"relative",background:CLR.menuBg,borderRadius:"12px",overflow:"hidden",display:"flex",flexDirection:"column",width:"min(90vw, 700px)",height:"min(90vh, 700px)",boxShadow:"0 20px 60px rgba(0,0,0,0.4)",minWidth:"320px",minHeight:"240px",maxWidth:"100vw",maxHeight:"100vh",zIndex:n?Z_ABOVE2:String(se())}),!n){const x=Be();Object.assign(i.style,{position:"fixed",top:`${Math.round(o.innerHeight*.08)+x}px`,left:`${Math.round(o.innerWidth*.08)+x}px`})}const l=t.createElement("div");Object.assign(l.style,{display:"flex",alignItems:"center",gap:"6px",padding:"10px 14px",borderBottom:`1px solid ${CLR.menuBorder}`,flexShrink:"0"});const h={border:`1px solid ${CLR.menuBorder}`,borderRadius:"4px",background:CLR.panelBg,cursor:"pointer",color:CLR.label,lineHeight:"1",padding:"0",display:"flex",alignItems:"center",justifyContent:"center",width:"28px",height:"28px"};if(e.title){const x=t.createElement("span");x.textContent=e.title,x.title=e.title,x.dataset.wmapWindowTitle="1",Object.assign(x.style,{fontWeight:"700",fontSize:"14px",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",minWidth:"0"}),l.appendChild(x)}const f=t.createElement("div");f.style.flex="1",l.appendChild(f);let b=null;n||(b=t.createElement("button"),b.type="button",b.innerHTML=I.windowMinimize,b.title="Minimize",b.setAttribute("aria-label","Minimize"),Object.assign(b.style,h),b.addEventListener("click",()=>O(!v)),l.appendChild(b));let s=null;e.printable&&(s=t.createElement("button"),s.type="button",s.innerHTML=I.print,s.title="Print / Save as PDF",s.setAttribute("aria-label","Print / Save as PDF"),Object.assign(s.style,h),s.addEventListener("click",()=>{typeof e.printable=="function"?e.printable():o.print()}),l.appendChild(s));const d=t.createElement("button");d.type="button",d.innerHTML=I.maximize,d.title="Maximize (F)",d.setAttribute("aria-label","Maximize"),Object.assign(d.style,h),d.addEventListener("click",()=>g(!u));const m=t.createElement("button");m.type="button",m.innerHTML=I.close,m.title="Close (Esc)",m.setAttribute("aria-label","Close"),Object.assign(m.style,h),m.addEventListener("click",T),l.appendChild(d),l.appendChild(m);let u=!1,c="",y="";function g(x){u=x,d.innerHTML=u?I.minimize:I.maximize,d.title=u?"Restore (F)":"Maximize (F)",d.setAttribute("aria-label",u?"Restore":"Maximize"),k.style.display=u?"none":"block",u?(i.style.borderRadius="0",i.style.width="100vw",i.style.height="100vh",n||(c=i.style.top,y=i.style.left,i.style.top="0",i.style.left="0")):(i.style.borderRadius="12px",i.style.width="min(90vw, 700px)",i.style.height="min(90vh, 700px)",n||(i.style.top=c,i.style.left=y)),e.onMaximizeChange?.(u,i)}let v=!1,L="",C="";const A=220;function O(x){v=x,b.innerHTML=v?I.windowRestore:I.windowMinimize,b.title=v?"Restore":"Minimize",b.setAttribute("aria-label",v?"Restore":"Minimize"),k.style.display=v?"none":"block",v?(L=i.style.height,C=i.style.width,i.style.minHeight="0",i.style.height="auto",i.style.minWidth="0",i.style.width=`${A}px`,d.disabled=!0,d.style.opacity="0.4",d.style.cursor="default",D.style.display="none"):(i.style.minHeight="240px",i.style.height=L||"min(90vh, 700px)",i.style.minWidth="320px",i.style.width=C||"min(90vw, 700px)",d.disabled=!1,d.style.opacity="1",d.style.cursor="pointer",D.style.display="flex")}function S(){const x=t.body.style.userSelect;return t.body.style.userSelect="none",()=>{t.body.style.userSelect=x}}n||(l.style.cursor="move",l.addEventListener("pointerdown",x=>{if(u||x.target.closest('button, [role="button"]'))return;x.preventDefault();const H=S(),R=x.clientX,$=x.clientY,W=i.offsetTop,_=i.offsetLeft,J=o.innerHeight-l.offsetHeight,Q=o.innerWidth-40,Y=40-i.offsetWidth;l.setPointerCapture(x.pointerId);const V=U=>{const ee=Math.min(Math.max(W+(U.clientY-$),0),J),me=Math.min(Math.max(_+(U.clientX-R),Y),Q);i.style.top=`${ee}px`,i.style.left=`${me}px`},N=U=>{H(),l.releasePointerCapture(U.pointerId),l.removeEventListener("pointermove",V),l.removeEventListener("pointerup",N)};l.addEventListener("pointermove",V),l.addEventListener("pointerup",N)}));const M='button,[href],input,select,textarea,[tabindex]:not([tabindex="-1"]),[role="menuitem"],[role="menuitemradio"],[role="menuitemcheckbox"]';function E(x){const H=Array.from(i.querySelectorAll(M)).filter(_=>_.offsetParent!==null||_===t.activeElement);if(H.length===0){x.preventDefault(),i.focus();return}const R=H[0],$=H[H.length-1],W=t.activeElement;x.shiftKey&&(W===R||!i.contains(W))?(x.preventDefault(),$.focus()):!x.shiftKey&&W===$&&(x.preventDefault(),R.focus())}const B=x=>{if(x.key==="Escape"){T();return}if(n&&(x.key==="e"||x.key==="E")){T();return}if(n&&x.key==="Tab"){E(x);return}(x.key==="f"||x.key==="F")&&!v&&g(!u)};function T(){n?t.removeEventListener("keydown",B):i.removeEventListener("keydown",B),Z.remove(),fe(),hideTooltip(t),reparentTooltip(t.body),a?a.remove():i.remove(),n&&(t.body.style.overflow=r),p?.focus?.(),e.onClose()}function z(){n||(i.style.zIndex=String(se()))}const D=t.createElement("div");Object.assign(D.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,F=240,G=20;function X(x,H){const R=o.innerWidth-i.offsetLeft,$=o.innerHeight-i.offsetTop,W=Math.min(Math.max(i.offsetWidth+x,j),R),_=Math.min(Math.max(i.offsetHeight+H,F),$);i.style.width=`${W}px`,i.style.height=`${_}px`}k.addEventListener("keydown",x=>{if(!(u||v))switch(x.key){case"ArrowRight":x.preventDefault(),X(G,0);break;case"ArrowLeft":x.preventDefault(),X(-G,0);break;case"ArrowDown":x.preventDefault(),X(0,G);break;case"ArrowUp":x.preventDefault(),X(0,-G);break}}),k.addEventListener("pointerdown",x=>{if(u||v)return;x.preventDefault();const H=S(),R=x.clientX,$=x.clientY,W=i.offsetWidth,_=i.offsetHeight,J=o.innerWidth-i.offsetLeft,Q=o.innerHeight-i.offsetTop;k.setPointerCapture(x.pointerId);const Y=N=>{const U=Math.min(Math.max(W+(N.clientX-R),j),J),ee=Math.min(Math.max(_+(N.clientY-$),F),Q);i.style.width=`${U}px`,i.style.height=`${ee}px`},V=N=>{H(),k.releasePointerCapture(N.pointerId),k.removeEventListener("pointermove",Y),k.removeEventListener("pointerup",V)};k.addEventListener("pointermove",Y),k.addEventListener("pointerup",V)}),i.appendChild(l),i.appendChild(D),i.appendChild(k);const K=e.anchor?overlayRootFor(e.anchor):t.body;a?(a.appendChild(i),K.appendChild(a)):K.appendChild(i);const fe=Te(t,K),Z=t.createElement("style");return Z.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(Z),reparentTooltip(i),n?(r.addEventListener("click",p=>{p.target===r&&C()}),t.addEventListener("keydown",k)):(i.addEventListener("keydown",k),i.addEventListener("mousedown",W),W()),nextFrame(()=>(c.isConnected?c:i).focus(),o),{backdrop:r,box:i,contentWrap:B,close:C,bringToFront:W}}export function openModal(e){return se({...e,mode:"modal"})}export function openFloatingWindow(e){return se({...e,mode:"window"})}const ne=new WeakSet;export function openReparentedModal(e,n={}){if(e.length===0||e.some(a=>ne.has(a)))return null;const t=e.map(a=>({el:a,parent:a.parentElement,next:a.nextSibling})),o=openModal({ownerDocument:n.ownerDocument,title:n.title,anchor:e[0],onClose:()=>{for(const a of t){if(ne.delete(a.el),!a.parent)continue;const r=a.next&&a.next.parentNode===a.parent?a.next:null;a.parent.insertBefore(a.el,r)}n.onClosed?.()}});for(const a of t)ne.add(a.el),o.contentWrap.appendChild(a.el);return o}export function makePaletteBtn(e,n,t,o,a,r){const d=()=>n()==="hardBin"||n()==="softBin",i=e.makeCheckMenuBtn("palette","Colour scheme",()=>{const x=d()?oe().filter(s=>s.name==="default"||s.name==="accessible"):oe(),f=t(),m=[];r&&m.push({section:"Scheme"}),o()&&m.push({label:"Custom",active:f==="custom",onClick:()=>a("custom")});for(const s of x)m.push({label:s.label,active:f===s.name,onClick:()=>a(s.name)});return r&&(m.push({section:"Encoding"}),m.push({label:"Mark failing dies",active:r.get(),enabled:d(),disabledHint:d()?void 0:"Available on hard/soft bin maps",onClick:()=>r.set(!r.get())})),m},()=>{});function l(){i.style.display=n()==="metadata"?"none":""}return{btn:i,sync:l}}export function requestedPassFailDisplay(e){return e.passFailDisplay??"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 a(){const r=n(),d=r.plotMode,i=d==="value"||d==="stackedValues";o.style.display=i&&requestedPassFailDisplay(r)==="off"&&!r.functionalActive?"":"none",e.setActive(o,!!r.logScale)}return{btn:o,sync:a}}const Ae=[{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 a=e.makeCheckMenuBtn("legend","Legend style",()=>{const d=n().legendPosition??"default",i=[];if(le(n().plotMode)){o&&i.push({section:"Position"});for(const l of Ae)i.push({label:l.label,active:d===l.value,onClick:()=>t(l.value)})}if(o){const l=o.blockedReason();i.push({section:"Per map"}),i.push({label:"Legend on each map",active:l?!0:o.get(),enabled:!l,disabledHint:l??void 0,onClick:()=>o.set(!o.get())})}return i},()=>{});function r(){a.style.display=o||le(n().plotMode)?"":"none"}return{btn:a,sync:r}}function le(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})}],o=>{const{rotation:a,flipX:r,flipY:d}=n();e.setActive(o,!!(a||r||d))})}let P=null;function ce(e,n,t,o){const a=n,r=a.__wmapDemoApi;a.__wmapDemoApi=o;const d=e.createElement("div");return d.classList.add("wmap-guide-content"),d.innerHTML=t,{content:d,restoreApi:()=>{a.__wmapDemoApi===o&&(a.__wmapDemoApi=r)}}}function de(e,n){const t=n,o=e.querySelector("script");if(o){const a=e.ownerDocument.createElement("script");a.textContent=o.textContent,e.appendChild(a);const r=e.querySelector(".wmap-guide");return r&&t.__wmapPopulateGuideDemos?.(r),t.__wmapDestroyGuideDemos}}function Ce(e,n,t,o){const a=o?.ownerDocument??document,r=a.defaultView??window,{content:d,restoreApi:i}=ce(a,r,n,t);Object.assign(d.style,{flex:"1",overflow:"auto",minHeight:"0",minWidth:"0"});let l;const x=openFloatingWindow({title:e,anchor:o,ownerDocument:a,onMaximizeChange:f=>{d.querySelector(".wmap-guide")?.classList.toggle("wmap-guide--max",f)},onClose:()=>{P===x&&(P=null),l?.(),i()}});return x.contentWrap.appendChild(d),l=de(d,r),x}function Se(e,n,t,o){const a=e.document;a.title=n,Object.assign(a.documentElement.style,{height:"100%"}),Object.assign(a.body.style,{margin:"0",height:"100vh",overflow:"hidden",display:"flex",flexDirection:"column",fontFamily:'system-ui, -apple-system, "Segoe UI", sans-serif'}),copyWmapThemeTokens(document.documentElement,a.documentElement);const r=syncWmapPopupTheme(document.documentElement,a.documentElement),{content:d,restoreApi:i}=ce(a,e,t,o);Object.assign(d.style,{flex:"1",overflow:"auto",minHeight:"0",minWidth:"0"}),a.body.appendChild(d);const l=de(d,e);let x=!1;const f=()=>{if(!x){x=!0,clearInterval(m),r();try{l?.()}catch{}i(),P===s&&(P=null)}},m=setInterval(()=>{e.closed&&f()},400);e.addEventListener("pagehide",f);const s={close:()=>{e.closed||e.close(),f()}};return s}export function openUserGuideWindow(e,n,t,o){P&&(P.close(),P=null);const a=t?.title??"Wafer Map \u2014 User Guide",r=(t?.html??"")+n,i=(o?.ownerDocument.defaultView??window).open("","_blank","width=800,height=820");P=i?Se(i,a,r,e):Ce(a,r,e,o)}
9
+ }`,t.head.appendChild(Z),reparentTooltip(i),n?(a.addEventListener("click",x=>{x.target===a&&T()}),t.addEventListener("keydown",B)):(i.addEventListener("keydown",B),i.addEventListener("mousedown",z),z()),nextFrame(()=>(m.isConnected?m:i).focus(),o),{backdrop:a,box:i,contentWrap:D,close:T,bringToFront:z}}export function openModal(e){return le({...e,mode:"modal"})}export function openFloatingWindow(e){return le({...e,mode:"window"})}const oe=new WeakSet;export function openReparentedModal(e,n={}){if(e.length===0||e.some(r=>oe.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,anchor:e[0],onClose:()=>{for(const r of t){if(oe.delete(r.el),!r.parent)continue;const a=r.next&&r.next.parentNode===r.parent?r.next:null;r.parent.insertBefore(r.el,a)}n.onClosed?.()}});for(const r of t)oe.add(r.el),o.contentWrap.appendChild(r.el);return o}export function makePaletteBtn(e,n,t,o,r,a){const p=()=>n()==="hardBin"||n()==="softBin",i=e.makeCheckMenuBtn("palette","Colour scheme",()=>{const h=p()?ie().filter(s=>s.name==="default"||s.name==="accessible"):ie(),f=t(),b=[];a&&b.push({section:"Scheme"}),o()&&b.push({label:"Custom",active:f==="custom",onClick:()=>r("custom")});for(const s of h)b.push({label:s.label,active:f===s.name,onClick:()=>r(s.name)});return a&&(b.push({section:"Encoding"}),b.push({label:"Mark failing dies",active:a.get(),enabled:p(),disabledHint:p()?void 0:"Available on hard/soft bin maps",onClick:()=>a.set(!a.get())})),b},()=>{});function l(){i.style.display=n()==="metadata"?"none":""}return{btn:i,sync:l}}export function requestedPassFailDisplay(e){return e.passFailDisplay??"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 a=n(),p=a.plotMode,i=p==="value"||p==="stackedValues";o.style.display=i&&requestedPassFailDisplay(a)==="off"&&!a.functionalActive?"":"none",e.setActive(o,!!a.logScale)}return{btn:o,sync:r}}const De=[{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 p=n().legendPosition??"default",i=[];if(ce(n().plotMode)){o&&i.push({section:"Position"});for(const l of De)i.push({label:l.label,active:p===l.value,onClick:()=>t(l.value)})}if(o){const l=o.blockedReason();i.push({section:"Per map"}),i.push({label:"Legend on each map",active:l?!0:o.get(),enabled:!l,disabledHint:l??void 0,onClick:()=>o.set(!o.get())})}return i},()=>{});function a(){r.style.display=o||ce(n().plotMode)?"":"none"}return{btn:r,sync:a}}function ce(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})}],o=>{const{rotation:r,flipX:a,flipY:p}=n();e.setActive(o,!!(r||a||p))})}let P=null;const de=40,He=de+8;function Oe(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:4px;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:11px;color:${CLR.label};min-width:44px;text-align:center;flex-shrink:0;white-space:nowrap;`;function a(m,u){const c=e.createElement("button");return c.type="button",c.textContent=m,c.setAttribute("aria-label",u),c.disabled=!0,c.style.cssText=`border:none;background:none;cursor:pointer;padding:3px 5px;border-radius:3px;font-size:10px;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 p=a("\u25B2","Previous match"),i=a("\u25BC","Next match");let l=[],h=-1;function f(){const m=l.length===0;p.disabled=m,i.disabled=m,p.style.opacity=m?"0.4":"",i.style.opacity=m?"0.4":""}function b(){for(const m of l)m.parentNode?.replaceChild(e.createTextNode(m.textContent??""),m);n.normalize(),l=[],h=-1}function s(m){if(l.length===0)return;h>=0&&(l[h].style.outline="none"),h=(m%l.length+l.length)%l.length;const u=l[h];u.style.outline=`2px solid ${CLR.iconActive}`,u.style.outlineOffset="1px",u.scrollIntoView({behavior:"smooth",block:"center"}),r.textContent=`${h+1}/${l.length}`}function d(m){b();const u=m.trim();if(!u){r.textContent="",f();return}const c=u.toLowerCase(),y=e.createTreeWalker(n,NodeFilter.SHOW_TEXT,{acceptNode(L){const C=L.parentElement;return!C||C.closest("script,style,.wmap-guide-toc")?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT}}),g=[];let v;for(;v=y.nextNode();)g.push(v);for(const L of g){const C=L.textContent??"",A=C.toLowerCase();if(!A.includes(c))continue;const O=e.createDocumentFragment();let S=0,M=A.indexOf(c);for(;M!==-1;){M>S&&O.appendChild(e.createTextNode(C.slice(S,M)));const E=e.createElement("mark");E.textContent=C.slice(M,M+u.length),O.appendChild(E),l.push(E),S=M+u.length,M=A.indexOf(c,S)}S<C.length&&O.appendChild(e.createTextNode(C.slice(S))),L.parentNode?.replaceChild(O,L)}f(),l.length===0?r.textContent="No matches":s(0)}return o.addEventListener("input",()=>d(o.value)),o.addEventListener("keydown",m=>{m.key==="Enter"?(m.preventDefault(),s(h+(m.shiftKey?-1:1))):m.key==="Escape"&&(o.value?(o.value="",d("")):o.blur())}),p.addEventListener("click",()=>s(h-1)),i.addEventListener("click",()=>s(h+1)),t.append(o,r,p,i),t}function We(e,n,t){const o=[...n.querySelectorAll("h2[id]")];if(o.length<2)return;for(const m of n.querySelectorAll("h1[id],h2[id],h3[id],h4[id]"))m.style.scrollMarginTop=`${He}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 a=e.createElement("div");a.style.cssText=`display:flex;align-items:center;gap:4px;height:${de}px;padding:0 14px;box-sizing:border-box;`;const p=e.createElement("span");p.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>',p.style.cssText="display:inline-flex;transition:transform 0.15s ease;flex-shrink:0;";const i=e.createElement("button");i.type="button";const l="wmap-guide-toc-panel";i.setAttribute("aria-expanded","false"),i.setAttribute("aria-controls",l),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:4px;font-size:13px;font-weight:600;color:${CLR.text};`;const h=e.createElement("span");h.textContent=`Contents (${o.length})`,i.append(p,h),i.addEventListener("mouseenter",()=>{i.style.background=CLR.bgHover}),i.addEventListener("mouseleave",()=>{i.style.background="none"});const f=e.createElement("button");f.type="button",f.textContent="\u2191 Top",f.style.cssText=`margin-left:auto;border:none;background:none;cursor:pointer;padding:6px 8px;border-radius:4px;font-size:12px;color:${CLR.label};`,f.addEventListener("mouseenter",()=>{f.style.background=CLR.bgHover}),f.addEventListener("mouseleave",()=>{f.style.background="none"}),f.addEventListener("click",()=>{d.close(),n.scrollTo({top:0,behavior:"smooth"})}),t?a.append(i,Oe(e,n),f):a.append(i,f);const b=e.createElement("div");b.id=l,b.hidden=!0,b.style.cssText="padding:2px 14px 14px;max-height:min(60vh,440px);overflow-y:auto;";const s=e.createElement("ul");s.setAttribute("role","list"),s.style.cssText="list-style:none;margin:0;padding:0;columns:200px;column-gap:20px;";for(const m of o){const u=e.createElement("li");u.style.cssText="break-inside:avoid;";const c=e.createElement("a");c.href=`#${m.id}`,c.textContent=(m.textContent??"").replace(/^\d+\.\s+/,""),c.style.cssText=`display:block;padding:4px 6px;margin:0 -6px;border-radius:3px;font-size:12.5px;color:${CLR.iconActive};text-decoration:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;`,c.addEventListener("mouseenter",()=>{c.style.background=CLR.bgHover}),c.addEventListener("mouseleave",()=>{c.style.background="none"}),c.addEventListener("click",y=>{y.preventDefault(),d.close(),m.scrollIntoView({behavior:"smooth",block:"start"})}),u.appendChild(c),s.appendChild(u)}b.appendChild(s);const d=wireExpandToggle(i,m=>{b.hidden=!m,i.setAttribute("aria-expanded",String(m)),p.style.transform=m?"rotate(180deg)":"none"});r.append(a,b),n.prepend(r)}function pe(e,n,t,o,r){const a=n,p=a.__wmapDemoApi;a.__wmapDemoApi=o;const i=e.createElement("div");return i.classList.add("wmap-guide-content"),i.innerHTML=t,We(e,i,r),{content:i,restoreApi:()=>{a.__wmapDemoApi===o&&(a.__wmapDemoApi=p)}}}function ue(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 a=e.querySelector(".wmap-guide");return a&&t.__wmapPopulateGuideDemos?.(a),t.__wmapDestroyGuideDemos}}function Ie(e,n,t,o){const r=o?.ownerDocument??document,a=r.defaultView??window,{content:p,restoreApi:i}=pe(r,a,n,t,!0);Object.assign(p.style,{flex:"1",overflow:"auto",minHeight:"0",minWidth:"0"});let l;const h=openFloatingWindow({title:e,anchor:o,ownerDocument:r,printable:!0,onMaximizeChange:f=>{p.style.setProperty("--wmap-guide-reading-width",f?"1000px":"720px")},onClose:()=>{P===h&&(P=null),l?.(),i()}});return h.contentWrap.appendChild(p),l=ue(p,a),h}function ze(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:'system-ui, -apple-system, "Segoe UI", sans-serif'}),copyWmapThemeTokens(document.documentElement,r.documentElement);const a=syncWmapPopupTheme(document.documentElement,r.documentElement),{content:p,restoreApi:i}=pe(r,e,t,o,!1);Object.assign(p.style,{flex:"1",overflow:"auto",minHeight:"0",minWidth:"0"}),r.body.appendChild(p);const l=ue(p,e);let h=!1;const f=()=>{if(!h){h=!0,clearInterval(b),a();try{l?.()}catch{}i(),P===s&&(P=null)}},b=setInterval(()=>{e.closed&&f()},400);e.addEventListener("pagehide",f);const s={close:()=>{e.closed||e.close(),f()}};return s}export function openUserGuideWindow(e,n,t,o){P&&(P.close(),P=null);const r=t?.title??"Wafer Map \u2014 User Guide",a=(t?.html??"")+n,i=(o?.ownerDocument.defaultView??window).open("","_blank","width=800,height=820");P=i?ze(i,r,a,e):Ie(r,a,e,o)}export function openWaferMapGuide(e,n){Promise.all([import("./userGuideHtml.js"),import("./renderWaferMap.js"),import("./renderWaferGallery.js")]).then(([t,o,r])=>{openUserGuideWindow({buildWaferMap:we,renderWaferMap:o.renderWaferMap,renderWaferGallery:r.renderWaferGallery,analyzeWaferMap:ke},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 a=t.createElement("button");a.type="button",a.textContent="Open as full page \u2197",Object.assign(a.style,{border:"none",background:"none",color:CLR.iconActive,cursor:"pointer",fontSize:"12px",textDecoration:"underline",padding:"0"}),a.addEventListener("click",()=>ye(e)),r.appendChild(a);const p=openModal({title:"Summary report",anchor:n?.anchor,ownerDocument:t,printable:()=>o.contentWindow?.print(),onClose:()=>{}});return p.contentWrap.style.flexDirection="column",p.contentWrap.appendChild(r),p.contentWrap.appendChild(o),p}