@wafertools/wafermap 0.22.0 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +16 -5
- package/CHANGELOG.md +101 -0
- package/dist/packages/canvas-adapter/charts/histogram.js +1 -1
- package/dist/packages/canvas-adapter/charts/scatter.js +1 -1
- package/dist/packages/canvas-adapter/dieList.d.ts +41 -0
- package/dist/packages/canvas-adapter/dieList.js +2 -0
- package/dist/packages/canvas-adapter/index.d.ts +2 -0
- package/dist/packages/canvas-adapter/index.js +1 -1
- package/dist/packages/canvas-adapter/maplessSummary.d.ts +34 -0
- package/dist/packages/canvas-adapter/maplessSummary.js +1 -0
- package/dist/packages/canvas-adapter/renderWaferGallery.d.ts +2 -18
- package/dist/packages/canvas-adapter/renderWaferGallery.js +8 -8
- package/dist/packages/canvas-adapter/renderWaferMap.d.ts +17 -1
- package/dist/packages/canvas-adapter/renderWaferMap.js +1 -1
- package/dist/packages/canvas-adapter/summaryPanel.d.ts +2 -0
- package/dist/packages/canvas-adapter/summaryPanel.js +3 -3
- package/dist/packages/canvas-adapter/userGuideHtml.d.ts +1 -1
- package/dist/packages/canvas-adapter/userGuideHtml.js +1 -1
- package/dist/packages/canvas-adapter/version.d.ts +2 -2
- package/dist/packages/canvas-adapter/version.js +1 -1
- package/dist/packages/canvas-adapter/warnings.d.ts +6 -1
- package/dist/packages/core/classify.d.ts +6 -2
- package/dist/packages/core/dies.d.ts +67 -7
- package/dist/packages/core/dies.js +1 -1
- package/dist/packages/core/probe.d.ts +5 -0
- package/dist/packages/core/probe.js +1 -1
- package/dist/packages/core/transforms.d.ts +4 -4
- package/dist/packages/core/transforms.js +1 -1
- package/dist/packages/renderer/buildView.d.ts +3 -3
- package/dist/packages/renderer/buildView.js +1 -1
- package/dist/packages/renderer/buildWaferMap.d.ts +25 -8
- package/dist/packages/renderer/buildWaferMap.js +1 -1
- package/dist/packages/stats/analyzeWaferMap.js +1 -1
- package/dist/packages/stats/clusterDetection.d.ts +2 -2
- package/dist/packages/stats/patternClassification.d.ts +2 -2
- package/dist/packages/stats/regions.d.ts +6 -6
- package/dist/packages/stats/regions.js +1 -1
- package/dist/packages/stats/renderSummaryReport.js +17 -17
- package/llms.txt +1 -1
- package/package.json +1 -1
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{isParametricTest as le}from"../renderer/buildWaferMap.js";import{buildRingRegions as G,buildQuadrantRegions as U,buildRegionYieldData as de}from"../stats/regions.js";import{computeFunctionalYield as pe}from"../stats/analyzeWaferMap.js";import{openHtmlReport as X}from"../stats/renderFindingsReport.js";import{renderSummaryReportHtml as ce,renderLotSummaryReportHtml as ue}from"../stats/renderSummaryReport.js";import{buildFindingsNarrative as fe}from"../stats/findingsNarrative.js";import{filterFindings as me}from"../stats/filterFindings.js";import{buildFacetTable as he,prettyKey as K}from"../stats/facets.js";import{getColorScheme as ge}from"../renderer/colorSchemes.js";import{buildWarningsBanner as O,collectWarnings as Z}from"./warnings.js";export{O as buildWarningsBanner};import{fmt as J,fmtAggregationMethod as xe,plainBinTerms as H}from"../renderer/fmt.js";import{getUniqueTestNumbers as be}from"../renderer/buildView.js";import{quantile as q}from"../stats/math.js";import{makeLabeledSelect as ee}from"./charts/chartShell.js";import{CLR as S,sevColor as _,openModal as ve,saveTextFile as te}from"./toolbar.js";import{medianOfSorted as ye}from"../core/utils.js";const Se=S.panelBg,M=`1px solid ${S.menuBorder}`,Ce="12px",F=S.label,W=S.value,ne="10px";function s(e,n,t){const i=document.createElement(e);return n&&Object.assign(i.style,n),t!==void 0&&(i.textContent=t),i}function I(e){return s("div",{fontSize:ne,fontWeight:"700",letterSpacing:"0.06em",textTransform:"uppercase",color:F,marginBottom:"6px"},e)}function ie(e,n=!0,t){const i=s("div"),r=document.createElement("button");r.type="button",Object.assign(r.style,{display:"flex",alignItems:"center",gap:"4px",width:"100%",background:"none",border:"none",cursor:"pointer",padding:"0 0 6px",textAlign:"left"});const d=s("span",{fontSize:"9px",color:F,transition:"transform 0.15s",transform:n?"rotate(90deg)":"rotate(0deg)",display:"inline-block",lineHeight:"1",marginRight:"1px"},"\u25B6"),c=s("span",{fontSize:ne,fontWeight:"700",letterSpacing:"0.06em",textTransform:"uppercase",color:F,flex:"1"},e);if(r.setAttribute("aria-expanded",n?"true":"false"),r.appendChild(d),r.appendChild(c),t){const l=s("span",{fontSize:"9px",fontWeight:"700",background:S.warnBg,color:S.warnText,borderRadius:"10px",padding:"1px 5px"},t);r.appendChild(l)}const p=s("div");p.style.display=n?"block":"none";let o=n;return r.addEventListener("click",()=>{o=!o,p.style.display=o?"block":"none",d.style.transform=o?"rotate(90deg)":"rotate(0deg)",r.setAttribute("aria-expanded",o?"true":"false")}),i.appendChild(r),i.appendChild(p),{outer:i,content:p}}function oe(){return s("div",{height:"1px",background:S.separator,margin:`${Ce} 0`,flexShrink:"0"})}function V(e,n,t="#2a6fc0",i,r,d){const c=s("div",{marginBottom:"5px"}),p=s("div",{display:"flex",justifyContent:"space-between",fontSize:"11px",color:W,marginBottom:"2px"}),o=s("span",{},e),l=s("span",{fontWeight:"600"},`${n.toFixed(1)}%`);p.appendChild(o),p.appendChild(l);const u=i!==void 0?i:Math.min(100,Math.max(0,n)),b=d?"#94a3b8":t,v=s("div",{position:"relative",height:"9px",background:S.bgActive,borderRadius:"4px",overflow:"hidden"}),L=s("div",{height:"100%",width:`${u}%`,background:b,borderRadius:"4px",transition:"width 0.3s ease"});if(v.appendChild(L),r!==void 0){const B=s("div",{position:"absolute",top:"0",bottom:"0",left:`${r}%`,width:"1px",background:S.infoText,opacity:"0.5"});v.appendChild(B)}return c.appendChild(p),c.appendChild(v),c}function P(e,n,t){const i=s("div",{background:S.menuBg,border:M,borderRadius:"6px",padding:"8px 10px",textAlign:"center",flex:"1"}),r=s("div",{fontSize:"20px",fontWeight:"700",color:W,lineHeight:"1.2"},e),d=s("div",{fontSize:"10px",color:F,marginTop:"2px"},n);return i.appendChild(r),i.appendChild(d),t&&i.appendChild(s("div",{fontSize:"9px",color:F,opacity:"0.85"},t)),i}function we(e,n){const t=s("div",{display:"flex",justifyContent:"space-between",fontSize:"11px",gap:"8px",marginBottom:"3px"}),i=s("span",{color:F,flexShrink:"0"},e),r=s("span",{color:W,textAlign:"right",fontWeight:"500",wordBreak:"break-all"},n);return t.appendChild(i),t.appendChild(r),t}function ke(e,n){const t=s("div",{display:"flex",fontSize:"11px",gap:"6px",marginBottom:"3px"}),i=s("span",{color:F,flexShrink:"0"},`${e}:`),r=s("span",{color:W,fontWeight:"500",wordBreak:"break-all"},n);return t.appendChild(i),t.appendChild(r),t}export function metadataEntries(e){return Object.entries(e).filter(([,n])=>n!=null&&n!=="").map(([n,t])=>[n,String(t)])}export function buildFacetSummaryChips(e,n=3){if(!e.length)return null;const t=s("div",{display:"flex",flexWrap:"wrap",alignItems:"baseline",gap:"4px 10px",fontSize:"11px"});for(const i of e){const r=s("span",{whiteSpace:"nowrap"}),d=s("span",{color:F},`${K(i.key)}: `);r.appendChild(d);const c=i.values.slice(0,n),p=i.values.length-c.length;let o=c.map(l=>l.value).join(", ");p>0&&(o+=` +${p} more`),r.appendChild(document.createTextNode(o)),t.appendChild(r)}return t}export function buildMetadataStripRow(e,n,t){const i=he(e,t),r=buildFacetSummaryChips(i);if(!r&&!n)return null;const d=s("div",{display:"flex",flexWrap:"wrap",alignItems:"baseline",gap:"4px 14px"});if(n){const c=s("span",{fontWeight:"500",whiteSpace:"nowrap"},n.aggrMethod?`${n.lotSize} wafers stacked \xB7 ${n.aggrMethod}`:`${n.lotSize} wafers stacked`);d.appendChild(c)}return r&&d.appendChild(r),d}const Be={display:"flex",flexDirection:"column",gap:"6px",background:S.menuBg,border:`1px solid ${S.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(e,n,t){const i=buildMetadataStripRow(e,n,t);if(!i)return null;const r=s("div",Be);return r.appendChild(i),r}export function buildCompactMetadataRows(e){const n=metadataEntries(e);if(!n.length)return null;const t=s("div");for(const[i,r]of n)t.appendChild(ke(K(i),r));return t}export function buildMetadataInfoSection(e,n){const t=buildMetadataStripRow(e,n,{facetableOnly:e.length>1});if(!t)return null;const i=s("div");return i.appendChild(I("Wafer Info")),i.appendChild(t),i}export function buildYieldSection(e,n,t=[1]){const i=s("div");i.appendChild(I("Summary"));const r=s("div",{display:"flex",gap:"6px",marginBottom:"8px"});if(r.appendChild(P(String(n.totalDies),"Total dies")),e.partialDies>0&&r.appendChild(P(String(e.partialDies),"Partial")),e.yieldPercent!==null){const d=t.length===1?`bin ${t[0]}`:`bins ${t.join(", ")}`;r.appendChild(P(`${e.yieldPercent.toFixed(1)}%`,"Yield",`pass: ${d}`))}return i.appendChild(r),e.edgeExcludedDies>0&&i.appendChild(we("Edge excluded (outer zone)",String(e.edgeExcludedDies))),i}export function buildBinSection(e,n,t,i,r){const d=new Map;if(r)for(const[u,b]of Object.entries(r))d.set(Number(u),b);else for(const u of e){if(u.partial||u.edgeExcluded)continue;const b=t==="hard"?u.hbin:u.sbin;b!=null&&d.set(b,(d.get(b)??0)+1)}if(!d.size)return null;const c=[...d.values()].reduce((u,b)=>u+b,0),p=n?new Map(n.map(u=>[u.bin,u])):null,o=[...d.entries()].sort((u,b)=>u[0]-b[0]),l=s("div");l.appendChild(I(t==="hard"?"Hard Bin Breakdown":"Soft Bin Breakdown"));for(const[u,b]of o){const v=p?.get(u),L=v?.name?`Bin ${u} \xB7 ${v.name}`:`Bin ${u}`,B=b/c*100,$=ge(i),R=(i==="custom"?v?.color:void 0)??$.forBin(u);l.appendChild(V(`${L} (${b})`,B,R))}return l}export function buildLotBinSection(e,n,t,i){return buildBinSection(e,n,t,i)}function Y(e,n,t,i,r,d){const c=de(e,n,t,i,r);if(!c.length)return null;const p=s("div");p.appendChild(I(d));for(const{label:o,n:l,yieldPercent:u}of c)p.appendChild(V(`${o} (N=${l})`,u));return p}export function buildRingSection(e,n,t,i){return Y([e],[n],t,i,G,"Ring Yield")}export function buildQuadrantSection(e,n,t,i){return Y([e],[n],t,i,U,"Quadrant Yield")}export function buildLotRingSection(e,n,t,i){return Y(e,n,t,i,G,"Ring Yield")}export function buildLotQuadrantSection(e,n,t,i){return Y(e,n,t,i,U,"Quadrant Yield")}export function buildLotOverviewSection(e){const n=s("div");n.appendChild(I("Lot Summary"));const t=s("div",{display:"flex",gap:"6px",marginBottom:"8px"});t.appendChild(P(String(e.stats.waferCount),"Wafers"));const i=e.perWafer.map(r=>r.summary.stats.yieldPercent).filter(r=>r!==null);if(i.length){const r=i.reduce((d,c)=>d+c,0)/i.length;t.appendChild(P(`${r.toFixed(1)}%`,"Mean wafer yield"))}return n.appendChild(t),n}export function buildPerWaferYieldSection(e,n,t){const i=e.perWafer.map(l=>({waferIndex:l.waferIndex,label:(n[l.waferIndex]?.label??`W${l.waferIndex+1}`).replace(/\s*·\s*\d+(\.\d+)?%$/,""),yieldPct:l.summary.stats.yieldPercent})).filter(l=>l.yieldPct!==null);if(!i.length)return null;const r=Math.min(...i.map(l=>l.yieldPct)),d=Math.max(...i.map(l=>l.yieldPct)),c=r===d?"":` (${r.toFixed(1)}\u2013${d.toFixed(1)}%)`,p=ye([...i.map(l=>l.yieldPct)].sort((l,u)=>l-u)),o=s("div");o.appendChild(I("Wafer Yield"+c));for(const{waferIndex:l,label:u,yieldPct:b}of i){const v=V(u,b,void 0,void 0,p,b<p);t&&(v.style.cursor="pointer",v.style.borderRadius="4px",v.style.padding="2px 3px",v.style.marginLeft="-3px",v.style.marginRight="-3px",v.setAttribute("role","button"),v.setAttribute("aria-label",`${u}, ${b.toFixed(1)}% yield \u2014 view wafer`),v.tabIndex=0,v.addEventListener("mouseenter",()=>{v.style.background=S.bgHover}),v.addEventListener("mouseleave",()=>{v.style.background=""}),v.addEventListener("focus",()=>{v.style.background=S.bgHover}),v.addEventListener("blur",()=>{v.style.background=""}),v.addEventListener("click",()=>t(l)),v.addEventListener("keydown",L=>{(L.key==="Enter"||L.key===" ")&&(L.preventDefault(),t(l))})),o.appendChild(v)}return o}function $e(e){const n=[...e].sort((r,d)=>r-d),t=e.reduce((r,d)=>r+d,0)/e.length,i=e.reduce((r,d)=>r+(d-t)**2,0)/e.length;return{min:n[0],max:n[n.length-1],mean:t,count:e.length,stddev:Math.sqrt(i),median:q(n,.5),q1:q(n,.25),q3:q(n,.75)}}function A(e){return/[",\n]/.test(e)?`"${e.replace(/"/g,'""')}"`:e}export function buildTestSection(e,n,t,i,r){const d=e.filter(a=>!a.partial&&!a.edgeExcluded),c=new Map((i?.perTestStats??[]).map(a=>[a.testNumber,a])),p=new Map((i?.testSpecYield??[]).map(a=>[a.testNumber,a]));let o;if(n?.length?o=n.filter(le).map(a=>({testNumber:a.testNumber,name:a.name,unit:a.unit,limitLow:a.limitLow,limitHigh:a.limitHigh})):o=be(d).map(h=>({testNumber:h,name:`Test ${h}`})),!o.length)return null;const l=o.filter(a=>d.some(h=>{const y=h.testValues?.[a.testNumber];return y!==void 0&&isFinite(y)}));if(!l.length)return null;const u=l.some(a=>a.limitLow!==void 0||a.limitHigh!==void 0),b=[];for(const a of l){const h=c.get(a.testNumber),y=h&&h.stddev!==void 0&&h.median!==void 0&&h.q1!==void 0&&h.q3!==void 0;let w;if(y){const g=h;w={testNumber:a.testNumber,min:g.min,max:g.max,mean:g.mean,count:g.count,stddev:g.stddev,median:g.median,q1:g.q1,q3:g.q3}}else{const g=d.map(D=>D.testValues?.[a.testNumber]).filter(D=>D!==void 0&&isFinite(D));if(!g.length)continue;w={testNumber:a.testNumber,...$e(g)}}let x=null,m=0;if(a.limitLow!==void 0||a.limitHigh!==void 0){const g=p.get(a.testNumber);if(g)({yieldPercent:x,totalDies:m}=g);else{const D=d.map(N=>N.testValues?.[a.testNumber]).filter(N=>N!==void 0&&isFinite(N)),j=D.filter(N=>a.limitLow!==void 0&&N<a.limitLow||a.limitHigh!==void 0&&N>a.limitHigh).length;m=D.length,x=D.length>0?(D.length-j)/D.length*100:null}}b.push({entry:a,stats:w,specYieldPct:x,specN:m})}if(!b.length)return null;const v=s("div"),L=s("div",{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:"6px"}),B=I(`Test Values (${b.length})`);B.style.marginBottom="0",L.appendChild(B);const $=document.createElement("button");$.type="button",$.textContent="Export CSV",Object.assign($.style,{background:"none",border:M,borderRadius:"4px",cursor:"pointer",fontSize:"10px",color:S.iconHover,padding:"2px 7px"}),$.addEventListener("click",()=>{const a=["Test","Unit","N","Min","Q1","Median","Mean","Q3","Max","StdDev"];u&&a.push("LSL","USL","Spec Yield %","Spec Yield N");const h=[a.map(A).join(",")],y=w=>J(w,void 0,"engineering");for(const{entry:w,stats:x,specYieldPct:m,specN:g}of b){const D=[w.name,w.unit??"",String(x.count),y(x.min),y(x.q1),y(x.median),y(x.mean),y(x.q3),y(x.max),y(x.stddev)];u&&D.push(w.limitLow!==void 0?y(w.limitLow):"",w.limitHigh!==void 0?y(w.limitHigh):"",m!==null?m.toFixed(1):"",w.limitLow!==void 0||w.limitHigh!==void 0?String(g):""),h.push(D.map(A).join(","))}te(h.join(`
|
|
2
|
-
`),"test-values.csv","text/csv",r)}),
|
|
3
|
-
`),"functional-tests.csv","text/csv",i)}),c.appendChild(o),d.appendChild(c);const l=s("table",{width:"100%",borderCollapse:"collapse",fontSize:"11px"}),u=document.createElement("thead"),b=document.createElement("tr");for(const B of["Test","N","Pass","Fail","Pass rate"])b.appendChild(s("th",{textAlign:B==="Test"?"left":"right",fontWeight:"700",fontSize:"10px",letterSpacing:"0.03em",textTransform:"uppercase",color:F,padding:"3px 8px 5px",borderBottom:`1px solid ${S.menuBorder}`,whiteSpace:"nowrap"},B));u.appendChild(b),l.appendChild(u);const v=document.createElement("tbody");for(const B of r){const $=document.createElement("tr"),R=(T,E="right")=>{$.appendChild(s("td",{textAlign:E,padding:"4px 8px",borderBottom:`1px solid ${S.menuBorder}`,color:W,whiteSpace:"nowrap"},T))};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"),v.appendChild($)}l.appendChild(v);const L=s("div",{overflowX:"auto"});return L.appendChild(l),d.appendChild(L),d}export function buildLotFunctionalSection(e,n,t,i){if(t?.length&&t.every(r=>r.stats.functionalYield!==void 0)){const r=new Map;for(const c of t)for(const p of c.stats.functionalYield??[]){const o=r.get(p.testNumber)??{label:p.label,passDies:0,failDies:0,totalDies:0};o.passDies+=p.passDies,o.failDies+=p.failDies,o.totalDies+=p.totalDies,r.set(p.testNumber,o)}const d=[...r.entries()].map(([c,p])=>({testNumber:c,...p,passRatePercent:p.totalDies>0?p.passDies/p.totalDies*100:null}));if(d.length)return buildFunctionalTestSection(e,n,d,i)}return buildFunctionalTestSection(e,n,void 0,i)}const z={unusual:0,notable:1,info:2};function Q(e){return s("span",{display:"inline-block",width:"7px",height:"7px",borderRadius:"50%",background:_(e),flexShrink:"0"})}function re(e,n){let t=e.summary;return n&&(t.startsWith(`${n} has `)?t=t.slice(n.length+5):t.startsWith(`${n} `)&&(t=t.slice(n.length+1))),t=H(t),t.length?t[0].toUpperCase()+t.slice(1):t}export function buildFindingsSection(e,n,t,i,r=!1){if(!e.length)return null;const d=e.some(f=>f.severity==="unusual"||f.severity==="notable"),c=d?e.filter(f=>f.severity!=="info").length.toString():void 0,{outer:p,content:o}=r?(()=>{const f=s("div");return{outer:f,content:f}})():ie(`Findings (${e.length})`,d,c);function l(f){return f.reduce((k,C)=>z[C.severity]<z[k]?C.severity:k,"info")}function u(f){const k=new Map;for(const a of f){const h=`${a.comparison.family}\0${a.comparison.left}`,y=k.get(h)??[];y.push(a),k.set(h,y)}const C=[...k.entries()].map(([a,h])=>{const y=[...h].sort((w,x)=>z[w.severity]-z[x.severity]);return{key:a,findings:y,worst:l(y)}});return C.sort((a,h)=>z[a.worst]-z[h.worst]),C}function b(f,k){const a={ring:"Ring",quadrant:"Quadrant",sector:"Sector","reticle-position":"Reticle","test-site":"Test site",cluster:"Cluster","edge-arc":"Edge arc",wafer:"Wafer"}[f]??f;return k.toLowerCase().startsWith(a.toLowerCase())?k:`${a}: ${k}`}const v=e.filter(f=>f.comparison.family==="spatial-pattern"),L=new Set([...v.flatMap(f=>f.relatedIds??[]),...e.flatMap(f=>f.absorbedIds??[])]),B=e.filter(f=>f.comparison.family!=="spatial-pattern"&&!L.has(f.id)),$=u(B);function R(f,k=!1,C){const a=i===f.id,h=document.createElement("button");return h.type="button",h.dataset.wmapFinding=f.id,h.textContent=re(f,C),h.title=f.summary,Object.assign(h.style,{border:`1px solid ${S.menuBorder}`,borderLeft:`3px solid ${_(f.severity)}`,background:a?S.bgActive:S.menuBg,borderRadius:"6px",padding:k?"6px 10px":"8px 10px",textAlign:"left",fontSize:k?"10px":"11px",fontWeight:a?"600":"400",color:S.iconHover,cursor:"pointer",width:"100%",marginBottom:"4px"}),h.addEventListener("click",()=>t(f,h)),h}const T=H(fe(e)??"");if(T){const f=s("div",{background:S.bgActive,borderRadius:"6px",padding:"8px 10px",marginBottom:"8px",display:"flex",gap:"8px",alignItems:"flex-start"}),k=s("span",{flex:"1",fontSize:"12px",lineHeight:"1.5",color:S.iconHover},T);f.appendChild(k);const C=s("button",{flexShrink:"0",border:"none",background:"none",fontSize:"10px",color:S.icon,cursor:"pointer",padding:"0",lineHeight:"1.5",whiteSpace:"nowrap"},"Detail \u25B8");C.type="button",C.addEventListener("click",()=>{const a=ve({title:"Findings Summary",onClose:()=>{},anchor:C}),h=s("p",{fontSize:"16px",lineHeight:"1.6",color:S.iconHover,padding:"20px 24px 16px",margin:"0",borderBottom:`1px solid ${S.menuBorder}`,flexShrink:"0"},T);a.contentWrap.appendChild(h);const y=s("div",{overflowY:"auto",padding:"16px 24px",flex:"1"}),w=(x,m)=>{const g=s("div",{display:"flex",alignItems:"center",gap:"7px",fontSize:"13px",fontWeight:"600",color:W,marginTop:"10px",marginBottom:"4px"});return g.appendChild(Q(x)),g.appendChild(s("span",{},m)),g};for(const x of v){y.appendChild(w(x.severity,x.comparison.left)),y.appendChild(s("div",{fontSize:"13px",color:S.iconHover,padding:"3px 0 3px 15px",marginBottom:"2px"},H(x.summary)));const m=e.filter(g=>x.relatedIds?.includes(g.id));for(const g of m)y.appendChild(s("div",{fontSize:"12px",color:S.icon,padding:"2px 0 2px 23px",marginBottom:"2px"},H(g.summary)))}for(const x of $){const[m,g]=x.key.split("\0");y.appendChild(w(x.worst,b(m,g)));for(const D of x.findings)y.appendChild(s("div",{fontSize:"13px",color:S.iconHover,padding:"3px 0 3px 15px",marginBottom:"2px"},re(D,g)))}a.contentWrap.appendChild(y),Object.assign(a.contentWrap.style,{flexDirection:"column",overflow:"hidden"})}),f.appendChild(C),o.appendChild(f)}let E=!0;for(const f of v){E||o.appendChild(s("div",{height:"1px",background:S.separator,margin:"4px 0"})),E=!1;const k=e.filter(w=>f.relatedIds?.includes(w.id)),C=k.length>0,a=s("div",{position:"relative",marginBottom:C?"2px":"4px"}),h=i===f.id,y=document.createElement("button");if(y.type="button",y.dataset.wmapFinding=f.id,Object.assign(y.style,{border:`1px solid ${S.menuBorder}`,borderLeft:`3px solid ${_(f.severity)}`,background:h?S.bgActive:S.menuBg,borderRadius:"6px",padding:"8px 32px 8px 10px",textAlign:"left",fontSize:"11px",fontWeight:h?"600":"500",color:S.iconHover,cursor:"pointer",width:"100%"}),y.textContent=H(f.summary),y.title=f.summary,y.addEventListener("click",()=>t(f,y)),a.appendChild(y),C){const w=s("div",{display:"none",paddingLeft:"12px",marginBottom:"4px"});for(const g of k)w.appendChild(R(g,!0));a.appendChild(w);let x=!1;const m=s("button",{position:"absolute",top:"50%",right:"8px",transform:"translateY(-50%)",border:"none",background:"none",fontSize:"10px",color:S.icon,cursor:"pointer",padding:"2px 4px",lineHeight:"1"},"\u25B8");m.type="button",m.title="Show supporting findings",m.addEventListener("click",g=>{g.stopPropagation(),x=!x,w.style.display=x?"block":"none",m.textContent=x?"\u25BE":"\u25B8",m.title=x?"Hide supporting findings":"Show supporting findings"}),a.appendChild(m)}o.appendChild(a)}for(const f of $){E||o.appendChild(s("div",{height:"1px",background:S.separator,margin:"4px 0"})),E=!1;const[k,C]=f.key.split("\0"),a=s("div",{display:"flex",alignItems:"center",gap:"6px",fontSize:"11px",fontWeight:"600",color:W,margin:"2px 0 4px"});a.appendChild(Q(f.worst)),a.appendChild(s("span",{},b(k,C))),o.appendChild(a);for(const h of f.findings)o.appendChild(R(h,!1,C))}return p}const Le=[{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"}],Re=[{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"}],De=["unusual","notable","info"],Ee={unusual:"Unusual",notable:"Notable",info:"Info"};function Te(e,n,t){const i=s("div",{display:"flex",flexWrap:"wrap",alignItems:"center",gap:"10px",marginBottom:"10px",paddingBottom:"10px",borderBottom:`1px solid ${S.separator}`}),r={unusual:0,notable:0,info:0};for(const o of e)r[o.severity]++;const d=De.filter(o=>r[o]>0),c=new Set(n.severity===void 0?d:Array.isArray(n.severity)?n.severity:[n.severity]),p=s("div",{display:"flex",gap:"4px",flexWrap:"wrap"});for(const o of d){const l=document.createElement("button");l.type="button";const u=()=>{const b=c.has(o);l.setAttribute("aria-pressed",b?"true":"false"),Object.assign(l.style,{display:"inline-flex",alignItems:"center",gap:"5px",border:`1px solid ${S.menuBorder}`,borderRadius:"10px",background:b?S.bgActive:"none",opacity:b?"1":"0.5",color:S.text,fontSize:"11px",padding:"2px 8px",cursor:"pointer"})};l.appendChild(Q(o)),l.appendChild(s("span",{},`${Ee[o]} ${r[o]}`)),l.title=c.has(o)?"Click to hide these findings":"Click to show these findings",u(),l.addEventListener("click",()=>{c.has(o)?c.delete(o):c.add(o),n.severity=c.size===d.length?void 0:[...c],t()}),p.appendChild(l)}return i.appendChild(p),i.appendChild(ee("Kind:",Le,n.kind??"",o=>{n.kind=o||void 0,t()},{maxWidth:"130px"})),i.appendChild(ee("Region:",Re,n.family??"",o=>{n.family=o||void 0,t()},{maxWidth:"150px"})),i}export function buildFindingsSectionWithFilter(e,n,t,i,r){if(!e.findings.length)return null;const d=e.findings.some(b=>b.severity==="unusual"||b.severity==="notable"),c=d?e.findings.filter(b=>b.severity!=="info").length.toString():void 0,{outer:p,content:o}=ie(`Findings (${e.findings.length})`,d,c);o.appendChild(Te(e.findings,i,r));const l=me(e,i);if(!l.length)return o.appendChild(s("div",{color:F,fontSize:"11px",textAlign:"center",padding:"16px 8px"},"No findings match the current filter.")),p;const u=buildFindingsSection(l,e,n,t,!0);return u&&o.appendChild(u),p}export function buildLotTestSection(e,n,t,i,r){let d;if(i?.length&&i.every(c=>c.stats.perTestStats!==void 0)){const c=new Map;for(const p of i)for(const o of p.stats.perTestStats??[]){const l=c.get(o.testNumber);l?(l.n+=o.count,l.sum+=o.mean*o.count,l.min=Math.min(l.min,o.min),l.max=Math.max(l.max,o.max)):c.set(o.testNumber,{n:o.count,sum:o.mean*o.count,min:o.min,max:o.max})}d={perTestStats:[...c.entries()].map(([p,o])=>({testNumber:p,count:o.n,min:o.min,max:o.max,mean:o.sum/o.n}))}}if(i?.length&&i.every(c=>c.stats.testSpecYield!==void 0)){const c=new Map;for(const p of i)for(const o of p.stats.testSpecYield??[]){const l=c.get(o.testNumber);l?(l.passDies+=o.passDies,l.totalDies+=o.totalDies):c.set(o.testNumber,{passDies:o.passDies,totalDies:o.totalDies})}d={...d,testSpecYield:[...c.entries()].map(([p,o])=>({testNumber:p,totalDies:o.totalDies,yieldPercent:o.totalDies>0?o.passDies/o.totalDies*100:null}))}}return buildTestSection(e,n,t,d,r)}export function createSummaryPanelEl(e){const n=e==="top"||e==="bottom",t=s("div",{background:Se,border:M,borderRadius:"8px",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)"});return n?(t.style.height="180px",t.style.width="100%"):(t.style.width="260px",t.style.maxHeight="100%"),t}export function wrapWithSummaryPanel(e,n,t){const i=t==="top"||t==="bottom",r=s("div",{display:"flex",flexDirection:i?"column":"row",gap:"8px",width:"100%",height:"100%",flex:"1 1 0",minHeight:"0",boxSizing:"border-box",alignItems:i?"flex-start":"stretch"});return e.style.flex="1 1 0",e.style.minWidth="0",e.style.minHeight="0",t==="right"||t==="bottom"?(r.appendChild(e),r.appendChild(n)):(r.appendChild(n),r.appendChild(e)),r}function ae(e){return s("div",{fontSize:"13px",fontWeight:"700",color:W,marginBottom:"10px"},e)}function se(e,n){const t=s("button",{background:"none",border:M,borderRadius:"4px",cursor:"pointer",fontSize:"10px",color:S.iconHover,padding:"2px 7px",marginBottom:"10px",display:"block"},e);return t.type="button",t.addEventListener("click",n),t}export function renderWaferSummaryContent(e,n){const t=e.scrollTop;e.innerHTML="";const{wafer:i,dies:r,yieldSummary:d,dataCoverage:c,hbinDefs:p,sbinDefs:o,testDefs:l,statsSummary:u,passBins:b=[1],ringCount:v=4,colorScheme:L,fallbackFormat:B,onFindingClick:$,activeFindingId:R=null,findingsFilter:T,onFindingsFilterChange:E,onSaveText:f}=n;e.appendChild(ae("Wafer Summary"));const k=n.warnings??Z({statsSummary:u});k.length&&e.appendChild(O(k)),d&&c&&e.appendChild(se("Summary report",()=>{X(ce({wafer:i,dies:r,yieldSummary:d,dataCoverage:c,hbinDefs:p,sbinDefs:o,testDefs:l,statsSummary:u,passBins:b,ringCount:v}))}));const C=[],a=u?.stats.isLotStack?u.stats:void 0,h=a?.lotSize!==void 0?{lotSize:a.lotSize,aggrMethod:xe(a.aggregationMethod)}:void 0;C.push(buildMetadataInfoSection([{metadata:i.metadata??void 0}],h)),d&&c&&C.push(buildYieldSection(d,c,b));const y=r.some(m=>m.hbin!=null),w=r.some(m=>m.sbin!=null);y?C.push(buildBinSection(r,p,"hard",L,u?.stats.hardBinCounts)):w&&C.push(buildBinSection(r,o,"soft",L,u?.stats.softBinCounts)),C.push(buildRingSection(r,i,v,b)),C.push(buildQuadrantSection(r,i,v,b)),C.push(buildTestSection(r,l,B,u?.stats,f)),C.push(buildFunctionalTestSection(r,l,u?.stats.functionalYield,f)),u&&$&&T&&E&&C.push(buildFindingsSectionWithFilter(u,$,R,T,E));let x=!0;for(const m of C)m&&(x||e.appendChild(oe()),x=!1,e.appendChild(m));e.appendChild(s("div",{height:"12px",flexShrink:"0"})),e.scrollTop=t}export function renderLotSummaryContent(e,n){const t=e.scrollTop;e.innerHTML="";const{lotSummary:i,items:r,hbinDefs:d,sbinDefs:c,testDefs:p,passBins:o=[1],ringCount:l=4,colorScheme:u,fallbackFormat:b,onFindingClick:v,activeFindingId:L=null,onWaferClick:B,findingsFilter:$,onFindingsFilterChange:R,onSaveText:T}=n;e.appendChild(ae(`Lot Summary \u2014 ${i.stats.waferCount} wafer${i.stats.waferCount===1?"":"s"}`));const E=n.warnings??Z({lotStatsSummary:i});E.length&&e.appendChild(O(E)),e.appendChild(se("Summary report",()=>{X(ue({items:r.map((m,g)=>({label:m?.label??`W${g+1}`,wafer:m?.wafer,dies:m?.dies,statsSummary:m?.statsSummary})),hbinDefs:d,sbinDefs:c,testDefs:p,passBins:o,ringCount:l}))}));const f=[],k=[],C=[];for(const m of r){if(!m){k.push([]);continue}m.wafer&&f.push(m.wafer);const g=m.dies??[];k.push(g),C.push(...g)}const a=C.some(m=>m.hbin!=null),h=C.some(m=>m.sbin!=null),y=r.map(m=>m?.statsSummary).filter(m=>!!m),w=[buildLotOverviewSection(i),buildMetadataInfoSection(r.filter(m=>m!==null).map(m=>({metadata:m.wafer?.metadata}))),buildPerWaferYieldSection(i,r,B),a?buildLotBinSection(C,d,"hard",u):h?buildLotBinSection(C,c,"soft",u):null,buildLotRingSection(k,f,l,o),buildLotQuadrantSection(k,f,l,o),p?.length?buildLotTestSection(C,p,b,y,T):null,p?.length?buildLotFunctionalSection(C,p,y,T):null];v&&$&&R&&w.push(buildFindingsSectionWithFilter(i,v,L,$,R));let x=!0;for(const m of w)m&&(x||e.appendChild(oe()),x=!1,e.appendChild(m));e.appendChild(s("div",{height:"12px",flexShrink:"0"})),e.scrollTop=t}
|
|
1
|
+
import{isParametricTest as se}from"../renderer/buildWaferMap.js";import{buildRingRegions as Q,buildQuadrantRegions as G,buildRegionYieldData as le}from"../stats/regions.js";import{computeFunctionalYield as de}from"../stats/analyzeWaferMap.js";import{openHtmlReport as U}from"../stats/renderFindingsReport.js";import{renderSummaryReportHtml as pe,renderLotSummaryReportHtml as ce}from"../stats/renderSummaryReport.js";import{buildFindingsNarrative as ue}from"../stats/findingsNarrative.js";import{filterFindings as fe}from"../stats/filterFindings.js";import{buildFacetTable as me,prettyKey as X}from"../stats/facets.js";import{getColorScheme as he}from"../renderer/colorSchemes.js";import{buildWarningsBanner as j,collectWarnings as K}from"./warnings.js";export{j as buildWarningsBanner};import{fmt as Z,fmtAggregationMethod as ge,plainBinTerms as H}from"../renderer/fmt.js";import{getUniqueTestNumbers as xe}from"../renderer/buildView.js";import{quantile as O}from"../stats/math.js";import{makeLabeledSelect as J}from"./charts/chartShell.js";import{CLR as y,sevColor as q,openModal as be,saveTextFile as ee}from"./toolbar.js";import{medianOfSorted as ve}from"../core/utils.js";const Se=y.panelBg,M=`1px solid ${y.menuBorder}`,ye="12px",F=y.label,W=y.value,te="10px";function s(e,n,t){const i=document.createElement(e);return n&&Object.assign(i.style,n),t!==void 0&&(i.textContent=t),i}function I(e){return s("div",{fontSize:te,fontWeight:"700",letterSpacing:"0.06em",textTransform:"uppercase",color:F,marginBottom:"6px"},e)}function ne(e,n=!0,t){const i=s("div"),r=document.createElement("button");r.type="button",Object.assign(r.style,{display:"flex",alignItems:"center",gap:"4px",width:"100%",background:"none",border:"none",cursor:"pointer",padding:"0 0 6px",textAlign:"left"});const d=s("span",{fontSize:"9px",color:F,transition:"transform 0.15s",transform:n?"rotate(90deg)":"rotate(0deg)",display:"inline-block",lineHeight:"1",marginRight:"1px"},"\u25B6"),c=s("span",{fontSize:te,fontWeight:"700",letterSpacing:"0.06em",textTransform:"uppercase",color:F,flex:"1"},e);if(r.setAttribute("aria-expanded",n?"true":"false"),r.appendChild(d),r.appendChild(c),t){const l=s("span",{fontSize:"9px",fontWeight:"700",background:y.warnBg,color:y.warnText,borderRadius:"10px",padding:"1px 5px"},t);r.appendChild(l)}const p=s("div");p.style.display=n?"block":"none";let o=n;return r.addEventListener("click",()=>{o=!o,p.style.display=o?"block":"none",d.style.transform=o?"rotate(90deg)":"rotate(0deg)",r.setAttribute("aria-expanded",o?"true":"false")}),i.appendChild(r),i.appendChild(p),{outer:i,content:p}}function ie(){return s("div",{height:"1px",background:y.separator,margin:`${ye} 0`,flexShrink:"0"})}function _(e,n,t="#2a6fc0",i,r,d){const c=s("div",{marginBottom:"5px"}),p=s("div",{display:"flex",justifyContent:"space-between",fontSize:"11px",color:W,marginBottom:"2px"}),o=s("span",{},e),l=s("span",{fontWeight:"600"},`${n.toFixed(1)}%`);p.appendChild(o),p.appendChild(l);const f=i!==void 0?i:Math.min(100,Math.max(0,n)),b=d?"#94a3b8":t,v=s("div",{position:"relative",height:"9px",background:y.bgActive,borderRadius:"4px",overflow:"hidden"}),R=s("div",{height:"100%",width:`${f}%`,background:b,borderRadius:"4px",transition:"width 0.3s ease"});if(v.appendChild(R),r!==void 0){const B=s("div",{position:"absolute",top:"0",bottom:"0",left:`${r}%`,width:"1px",background:y.infoText,opacity:"0.5"});v.appendChild(B)}return c.appendChild(p),c.appendChild(v),c}function A(e,n,t){const i=s("div",{background:y.menuBg,border:M,borderRadius:"6px",padding:"8px 10px",textAlign:"center",flex:"1"}),r=s("div",{fontSize:"20px",fontWeight:"700",color:W,lineHeight:"1.2"},e),d=s("div",{fontSize:"10px",color:F,marginTop:"2px"},n);return i.appendChild(r),i.appendChild(d),t&&i.appendChild(s("div",{fontSize:"9px",color:F,opacity:"0.85"},t)),i}function Ce(e,n){const t=s("div",{display:"flex",justifyContent:"space-between",fontSize:"11px",gap:"8px",marginBottom:"3px"}),i=s("span",{color:F,flexShrink:"0"},e),r=s("span",{color:W,textAlign:"right",fontWeight:"500",wordBreak:"break-all"},n);return t.appendChild(i),t.appendChild(r),t}function we(e,n){const t=s("div",{display:"flex",fontSize:"11px",gap:"6px",marginBottom:"3px"}),i=s("span",{color:F,flexShrink:"0"},`${e}:`),r=s("span",{color:W,fontWeight:"500",wordBreak:"break-all"},n);return t.appendChild(i),t.appendChild(r),t}export function metadataEntries(e){return Object.entries(e).filter(([,n])=>n!=null&&n!=="").map(([n,t])=>[n,String(t)])}export function buildFacetSummaryChips(e,n=3){if(!e.length)return null;const t=s("div",{display:"flex",flexWrap:"wrap",alignItems:"baseline",gap:"4px 10px",fontSize:"11px"});for(const i of e){const r=s("span",{whiteSpace:"nowrap"}),d=s("span",{color:F},`${X(i.key)}: `);r.appendChild(d);const c=i.values.slice(0,n),p=i.values.length-c.length;let o=c.map(l=>l.value).join(", ");p>0&&(o+=` +${p} more`),r.appendChild(document.createTextNode(o)),t.appendChild(r)}return t}export function buildMetadataStripRow(e,n,t){const i=me(e,t),r=buildFacetSummaryChips(i);if(!r&&!n)return null;const d=s("div",{display:"flex",flexWrap:"wrap",alignItems:"baseline",gap:"4px 14px"});if(n){const c=s("span",{fontWeight:"500",whiteSpace:"nowrap"},n.aggrMethod?`${n.lotSize} wafers stacked \xB7 ${n.aggrMethod}`:`${n.lotSize} wafers stacked`);d.appendChild(c)}return r&&d.appendChild(r),d}const ke={display:"flex",flexDirection:"column",gap:"6px",background:y.menuBg,border:`1px solid ${y.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(e,n,t){const i=buildMetadataStripRow(e,n,t);if(!i)return null;const r=s("div",ke);return r.appendChild(i),r}export function buildCompactMetadataRows(e){const n=metadataEntries(e);if(!n.length)return null;const t=s("div");for(const[i,r]of n)t.appendChild(we(X(i),r));return t}export function buildMetadataInfoSection(e,n){const t=buildMetadataStripRow(e,n,{facetableOnly:e.length>1});if(!t)return null;const i=s("div");return i.appendChild(I("Wafer Info")),i.appendChild(t),i}export function buildYieldSection(e,n,t=[1]){const i=s("div");i.appendChild(I("Summary"));const r=s("div",{display:"flex",gap:"6px",marginBottom:"8px"});if(r.appendChild(A(String(e.totalDies),"Total dies")),e.partialDies>0&&r.appendChild(A(String(e.partialDies),"Partial")),e.yieldPercent!==null){const d=t.length===1?`bin ${t[0]}`:`bins ${t.join(", ")}`;r.appendChild(A(`${e.yieldPercent.toFixed(1)}%`,"Yield",`pass: ${d}`))}return i.appendChild(r),e.edgeExcludedDies>0&&i.appendChild(Ce("Edge excluded (outer zone)",String(e.edgeExcludedDies))),i}export function buildBinSection(e,n,t,i,r){const d=new Map;if(r)for(const[f,b]of Object.entries(r))d.set(Number(f),b);else for(const f of e){if(f.partial||f.edgeExcluded)continue;const b=t==="hard"?f.hbin:f.sbin;b!=null&&d.set(b,(d.get(b)??0)+1)}if(!d.size)return null;const c=[...d.values()].reduce((f,b)=>f+b,0),p=n?new Map(n.map(f=>[f.bin,f])):null,o=[...d.entries()].sort((f,b)=>f[0]-b[0]),l=s("div");l.appendChild(I(t==="hard"?"Hard Bin Breakdown":"Soft Bin Breakdown"));for(const[f,b]of o){const v=p?.get(f),R=v?.name?`Bin ${f} \xB7 ${v.name}`:`Bin ${f}`,B=b/c*100,$=he(i),D=(i==="custom"?v?.color:void 0)??$.forBin(f);l.appendChild(_(`${R} (${b})`,B,D))}return l}export function buildLotBinSection(e,n,t,i){return buildBinSection(e,n,t,i)}function P(e,n,t,i,r,d){const c=le(e,n,t,i,r);if(!c.length)return null;const p=s("div");p.appendChild(I(d));for(const{label:o,n:l,yieldPercent:f}of c)p.appendChild(_(`${o} (N=${l})`,f));return p}export function buildRingSection(e,n,t,i){return P([e],[n],t,i,Q,"Ring Yield")}export function buildQuadrantSection(e,n,t,i){return P([e],[n],t,i,G,"Quadrant Yield")}export function buildLotRingSection(e,n,t,i){return P(e,n,t,i,Q,"Ring Yield")}export function buildLotQuadrantSection(e,n,t,i){return P(e,n,t,i,G,"Quadrant Yield")}export function buildLotOverviewSection(e){const n=s("div");n.appendChild(I("Lot Summary"));const t=s("div",{display:"flex",gap:"6px",marginBottom:"8px"});t.appendChild(A(String(e.stats.waferCount),"Wafers"));const i=e.perWafer.map(r=>r.summary.stats.yieldPercent).filter(r=>r!==null);if(i.length){const r=i.reduce((d,c)=>d+c,0)/i.length;t.appendChild(A(`${r.toFixed(1)}%`,"Mean wafer yield"))}return n.appendChild(t),n}export function buildPerWaferYieldSection(e,n,t){const i=e.perWafer.map(l=>({waferIndex:l.waferIndex,label:(n[l.waferIndex]?.label??`W${l.waferIndex+1}`).replace(/\s*·\s*\d+(\.\d+)?%$/,""),yieldPct:l.summary.stats.yieldPercent})).filter(l=>l.yieldPct!==null);if(!i.length)return null;const r=Math.min(...i.map(l=>l.yieldPct)),d=Math.max(...i.map(l=>l.yieldPct)),c=r===d?"":` (${r.toFixed(1)}\u2013${d.toFixed(1)}%)`,p=ve([...i.map(l=>l.yieldPct)].sort((l,f)=>l-f)),o=s("div");o.appendChild(I("Wafer Yield"+c));for(const{waferIndex:l,label:f,yieldPct:b}of i){const v=_(f,b,void 0,void 0,p,b<p);t&&(v.style.cursor="pointer",v.style.borderRadius="4px",v.style.padding="2px 3px",v.style.marginLeft="-3px",v.style.marginRight="-3px",v.setAttribute("role","button"),v.setAttribute("aria-label",`${f}, ${b.toFixed(1)}% yield \u2014 view wafer`),v.tabIndex=0,v.addEventListener("mouseenter",()=>{v.style.background=y.bgHover}),v.addEventListener("mouseleave",()=>{v.style.background=""}),v.addEventListener("focus",()=>{v.style.background=y.bgHover}),v.addEventListener("blur",()=>{v.style.background=""}),v.addEventListener("click",()=>t(l)),v.addEventListener("keydown",R=>{(R.key==="Enter"||R.key===" ")&&(R.preventDefault(),t(l))})),o.appendChild(v)}return o}function Be(e){const n=[...e].sort((r,d)=>r-d),t=e.reduce((r,d)=>r+d,0)/e.length,i=e.reduce((r,d)=>r+(d-t)**2,0)/e.length;return{min:n[0],max:n[n.length-1],mean:t,count:e.length,stddev:Math.sqrt(i),median:O(n,.5),q1:O(n,.25),q3:O(n,.75)}}export function csvField(e){return/[",\n]/.test(e)?`"${e.replace(/"/g,'""')}"`:e}export function buildTestSection(e,n,t,i,r){const d=e.filter(a=>!a.partial&&!a.edgeExcluded),c=new Map((i?.perTestStats??[]).map(a=>[a.testNumber,a])),p=new Map((i?.testSpecYield??[]).map(a=>[a.testNumber,a]));let o;if(n?.length?o=n.filter(se).map(a=>({testNumber:a.testNumber,name:a.name,unit:a.unit,limitLow:a.limitLow,limitHigh:a.limitHigh})):o=xe(d).map(h=>({testNumber:h,name:`Test ${h}`})),!o.length)return null;const l=o.filter(a=>d.some(h=>{const S=h.testValues?.[a.testNumber];return S!==void 0&&isFinite(S)}));if(!l.length)return null;const f=l.some(a=>a.limitLow!==void 0||a.limitHigh!==void 0),b=[];for(const a of l){const h=c.get(a.testNumber),S=h&&h.stddev!==void 0&&h.median!==void 0&&h.q1!==void 0&&h.q3!==void 0;let w;if(S){const g=h;w={testNumber:a.testNumber,min:g.min,max:g.max,mean:g.mean,count:g.count,stddev:g.stddev,median:g.median,q1:g.q1,q3:g.q3}}else{const g=d.map(L=>L.testValues?.[a.testNumber]).filter(L=>L!==void 0&&isFinite(L));if(!g.length)continue;w={testNumber:a.testNumber,...Be(g)}}let x=null,u=0;if(a.limitLow!==void 0||a.limitHigh!==void 0){const g=p.get(a.testNumber);if(g)({yieldPercent:x,totalDies:u}=g);else{const L=d.map(N=>N.testValues?.[a.testNumber]).filter(N=>N!==void 0&&isFinite(N)),Y=L.filter(N=>a.limitLow!==void 0&&N<a.limitLow||a.limitHigh!==void 0&&N>a.limitHigh).length;u=L.length,x=L.length>0?(L.length-Y)/L.length*100:null}}b.push({entry:a,stats:w,specYieldPct:x,specN:u})}if(!b.length)return null;const v=s("div"),R=s("div",{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:"6px"}),B=I(`Test Values (${b.length})`);B.style.marginBottom="0",R.appendChild(B);const $=document.createElement("button");$.type="button",$.textContent="Export CSV",Object.assign($.style,{background:"none",border:M,borderRadius:"4px",cursor:"pointer",fontSize:"10px",color:y.iconHover,padding:"2px 7px"}),$.addEventListener("click",()=>{const a=["Test","Unit","N","Min","Q1","Median","Mean","Q3","Max","StdDev"];f&&a.push("LSL","USL","Spec Yield %","Spec Yield N");const h=[a.map(csvField).join(",")],S=w=>Z(w,void 0,"engineering");for(const{entry:w,stats:x,specYieldPct:u,specN:g}of b){const L=[w.name,w.unit??"",String(x.count),S(x.min),S(x.q1),S(x.median),S(x.mean),S(x.q3),S(x.max),S(x.stddev)];f&&L.push(w.limitLow!==void 0?S(w.limitLow):"",w.limitHigh!==void 0?S(w.limitHigh):"",u!==null?u.toFixed(1):"",w.limitLow!==void 0||w.limitHigh!==void 0?String(g):""),h.push(L.map(csvField).join(","))}ee(h.join(`
|
|
2
|
+
`),"test-values.csv","text/csv",r)}),R.appendChild($),v.appendChild(R);const D=s("table",{width:"100%",borderCollapse:"collapse",fontSize:"11px"}),T=document.createElement("thead"),E=document.createElement("tr"),m=["Test","N","Min","Q1","Median","Mean","Q3","Max","StdDev"];f&&m.push("LSL","USL","Spec yield");for(const a of m){const h=s("th",{textAlign:a==="Test"?"left":"right",fontWeight:"700",fontSize:"10px",letterSpacing:"0.03em",textTransform:"uppercase",color:F,padding:"3px 8px 5px",borderBottom:`1px solid ${y.menuBorder}`,whiteSpace:"nowrap"},a);E.appendChild(h)}T.appendChild(E),D.appendChild(T);const k=document.createElement("tbody");for(const{entry:a,stats:h,specYieldPct:S,specN:w}of b){const x=L=>Z(L,a.unit,t),u=document.createElement("tr"),g=(L,Y="right")=>{const N=s("td",{textAlign:Y,padding:"4px 8px",borderBottom:`1px solid ${y.menuBorder}`,color:W,whiteSpace:"nowrap"},L);u.appendChild(N)};g(a.name,"left"),g(`${h.count}`),g(x(h.min)),g(x(h.q1)),g(x(h.median)),g(x(h.mean)),g(x(h.q3)),g(x(h.max)),g(x(h.stddev)),f&&(g(a.limitLow!==void 0?x(a.limitLow):"\u2014"),g(a.limitHigh!==void 0?x(a.limitHigh):"\u2014"),g(S!==null?`${S.toFixed(1)}% (N=${w})`:"\u2014")),k.appendChild(u)}D.appendChild(k);const C=s("div",{overflowX:"auto"});return C.appendChild(D),v.appendChild(C),v}export function buildFunctionalTestSection(e,n,t,i){const r=t??de(e,n);if(!r?.length)return null;const d=s("div"),c=s("div",{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:"6px"}),p=I(`Functional Tests (${r.length})`);p.style.marginBottom="0",c.appendChild(p);const o=document.createElement("button");o.type="button",o.textContent="Export CSV",Object.assign(o.style,{background:"none",border:M,borderRadius:"4px",cursor:"pointer",fontSize:"10px",color:y.iconHover,padding:"2px 7px"}),o.addEventListener("click",()=>{const B=[["Test","N","Pass","Fail","Pass Rate %"].map(csvField).join(",")];for(const $ of r)B.push([$.label,String($.totalDies),String($.passDies),String($.failDies),$.passRatePercent!==null?$.passRatePercent.toFixed(1):""].map(csvField).join(","));ee(B.join(`
|
|
3
|
+
`),"functional-tests.csv","text/csv",i)}),c.appendChild(o),d.appendChild(c);const l=s("table",{width:"100%",borderCollapse:"collapse",fontSize:"11px"}),f=document.createElement("thead"),b=document.createElement("tr");for(const B of["Test","N","Pass","Fail","Pass rate"])b.appendChild(s("th",{textAlign:B==="Test"?"left":"right",fontWeight:"700",fontSize:"10px",letterSpacing:"0.03em",textTransform:"uppercase",color:F,padding:"3px 8px 5px",borderBottom:`1px solid ${y.menuBorder}`,whiteSpace:"nowrap"},B));f.appendChild(b),l.appendChild(f);const v=document.createElement("tbody");for(const B of r){const $=document.createElement("tr"),D=(T,E="right")=>{$.appendChild(s("td",{textAlign:E,padding:"4px 8px",borderBottom:`1px solid ${y.menuBorder}`,color:W,whiteSpace:"nowrap"},T))};D(B.label,"left"),D(String(B.totalDies)),D(String(B.passDies)),D(String(B.failDies)),D(B.passRatePercent!==null?`${B.passRatePercent.toFixed(1)}% (N=${B.totalDies})`:"\u2014"),v.appendChild($)}l.appendChild(v);const R=s("div",{overflowX:"auto"});return R.appendChild(l),d.appendChild(R),d}export function buildLotFunctionalSection(e,n,t,i){if(t?.length&&t.every(r=>r.stats.functionalYield!==void 0)){const r=new Map;for(const c of t)for(const p of c.stats.functionalYield??[]){const o=r.get(p.testNumber)??{label:p.label,passDies:0,failDies:0,totalDies:0};o.passDies+=p.passDies,o.failDies+=p.failDies,o.totalDies+=p.totalDies,r.set(p.testNumber,o)}const d=[...r.entries()].map(([c,p])=>({testNumber:c,...p,passRatePercent:p.totalDies>0?p.passDies/p.totalDies*100:null}));if(d.length)return buildFunctionalTestSection(e,n,d,i)}return buildFunctionalTestSection(e,n,void 0,i)}const z={unusual:0,notable:1,info:2};function V(e){return s("span",{display:"inline-block",width:"7px",height:"7px",borderRadius:"50%",background:q(e),flexShrink:"0"})}function oe(e,n){let t=e.summary;return n&&(t.startsWith(`${n} has `)?t=t.slice(n.length+5):t.startsWith(`${n} `)&&(t=t.slice(n.length+1))),t=H(t),t.length?t[0].toUpperCase()+t.slice(1):t}export function buildFindingsSection(e,n,t,i,r=!1){if(!e.length)return null;const d=e.some(m=>m.severity==="unusual"||m.severity==="notable"),c=d?e.filter(m=>m.severity!=="info").length.toString():void 0,{outer:p,content:o}=r?(()=>{const m=s("div");return{outer:m,content:m}})():ne(`Findings (${e.length})`,d,c);function l(m){return m.reduce((k,C)=>z[C.severity]<z[k]?C.severity:k,"info")}function f(m){const k=new Map;for(const a of m){const h=`${a.comparison.family}\0${a.comparison.left}`,S=k.get(h)??[];S.push(a),k.set(h,S)}const C=[...k.entries()].map(([a,h])=>{const S=[...h].sort((w,x)=>z[w.severity]-z[x.severity]);return{key:a,findings:S,worst:l(S)}});return C.sort((a,h)=>z[a.worst]-z[h.worst]),C}function b(m,k){const a={ring:"Ring",quadrant:"Quadrant",sector:"Sector","reticle-position":"Reticle","test-site":"Test site",cluster:"Cluster","edge-arc":"Edge arc",wafer:"Wafer"}[m]??m;return k.toLowerCase().startsWith(a.toLowerCase())?k:`${a}: ${k}`}const v=e.filter(m=>m.comparison.family==="spatial-pattern"),R=new Set([...v.flatMap(m=>m.relatedIds??[]),...e.flatMap(m=>m.absorbedIds??[])]),B=e.filter(m=>m.comparison.family!=="spatial-pattern"&&!R.has(m.id)),$=f(B);function D(m,k=!1,C){const a=i===m.id,h=document.createElement("button");return h.type="button",h.dataset.wmapFinding=m.id,h.textContent=oe(m,C),h.title=m.summary,h.setAttribute("aria-current",a?"true":"false"),Object.assign(h.style,{border:`1px solid ${y.menuBorder}`,borderLeft:`3px solid ${q(m.severity)}`,background:a?y.bgActive:y.menuBg,borderRadius:"6px",padding:k?"6px 10px":"8px 10px",textAlign:"left",fontSize:k?"10px":"11px",fontWeight:a?"600":"400",color:y.iconHover,cursor:"pointer",width:"100%",marginBottom:"4px"}),h.addEventListener("click",()=>t(m,h)),h}const T=H(ue(e)??"");if(T){const m=s("div",{background:y.bgActive,borderRadius:"6px",padding:"8px 10px",marginBottom:"8px",display:"flex",gap:"8px",alignItems:"flex-start"}),k=s("span",{flex:"1",fontSize:"12px",lineHeight:"1.5",color:y.iconHover},T);m.appendChild(k);const C=s("button",{flexShrink:"0",border:"none",background:"none",fontSize:"10px",color:y.icon,cursor:"pointer",padding:"0",lineHeight:"1.5",whiteSpace:"nowrap"},"Detail \u25B8");C.type="button",C.addEventListener("click",()=>{const a=be({title:"Findings Summary",onClose:()=>{},anchor:C}),h=s("p",{fontSize:"16px",lineHeight:"1.6",color:y.iconHover,padding:"20px 24px 16px",margin:"0",borderBottom:`1px solid ${y.menuBorder}`,flexShrink:"0"},T);a.contentWrap.appendChild(h);const S=s("div",{overflowY:"auto",padding:"16px 24px",flex:"1"}),w=(x,u)=>{const g=s("div",{display:"flex",alignItems:"center",gap:"7px",fontSize:"13px",fontWeight:"600",color:W,marginTop:"10px",marginBottom:"4px"});return g.appendChild(V(x)),g.appendChild(s("span",{},u)),g};for(const x of v){S.appendChild(w(x.severity,x.comparison.left)),S.appendChild(s("div",{fontSize:"13px",color:y.iconHover,padding:"3px 0 3px 15px",marginBottom:"2px"},H(x.summary)));const u=e.filter(g=>x.relatedIds?.includes(g.id));for(const g of u)S.appendChild(s("div",{fontSize:"12px",color:y.icon,padding:"2px 0 2px 23px",marginBottom:"2px"},H(g.summary)))}for(const x of $){const[u,g]=x.key.split("\0");S.appendChild(w(x.worst,b(u,g)));for(const L of x.findings)S.appendChild(s("div",{fontSize:"13px",color:y.iconHover,padding:"3px 0 3px 15px",marginBottom:"2px"},oe(L,g)))}a.contentWrap.appendChild(S),Object.assign(a.contentWrap.style,{flexDirection:"column",overflow:"hidden"})}),m.appendChild(C),o.appendChild(m)}let E=!0;for(const m of v){E||o.appendChild(s("div",{height:"1px",background:y.separator,margin:"4px 0"})),E=!1;const k=e.filter(w=>m.relatedIds?.includes(w.id)),C=k.length>0,a=s("div",{position:"relative",marginBottom:C?"2px":"4px"}),h=i===m.id,S=document.createElement("button");if(S.type="button",S.dataset.wmapFinding=m.id,Object.assign(S.style,{border:`1px solid ${y.menuBorder}`,borderLeft:`3px solid ${q(m.severity)}`,background:h?y.bgActive:y.menuBg,borderRadius:"6px",padding:"8px 32px 8px 10px",textAlign:"left",fontSize:"11px",fontWeight:h?"600":"500",color:y.iconHover,cursor:"pointer",width:"100%"}),S.textContent=H(m.summary),S.title=m.summary,S.setAttribute("aria-current",h?"true":"false"),S.addEventListener("click",()=>t(m,S)),a.appendChild(S),C){const w=s("div",{display:"none",paddingLeft:"12px",marginBottom:"4px"});for(const g of k)w.appendChild(D(g,!0));a.appendChild(w);let x=!1;const u=s("button",{position:"absolute",top:"50%",right:"8px",transform:"translateY(-50%)",border:"none",background:"none",fontSize:"10px",color:y.icon,cursor:"pointer",padding:"2px 4px",lineHeight:"1"},"\u25B8");u.type="button",u.title="Show supporting findings",u.setAttribute("aria-label","Show supporting findings"),u.setAttribute("aria-expanded","false"),u.addEventListener("click",g=>{g.stopPropagation(),x=!x,w.style.display=x?"block":"none",u.textContent=x?"\u25BE":"\u25B8";const L=x?"Hide supporting findings":"Show supporting findings";u.title=L,u.setAttribute("aria-label",L),u.setAttribute("aria-expanded",String(x))}),a.appendChild(u)}o.appendChild(a)}for(const m of $){E||o.appendChild(s("div",{height:"1px",background:y.separator,margin:"4px 0"})),E=!1;const[k,C]=m.key.split("\0"),a=s("div",{display:"flex",alignItems:"center",gap:"6px",fontSize:"11px",fontWeight:"600",color:W,margin:"2px 0 4px"});a.appendChild(V(m.worst)),a.appendChild(s("span",{},b(k,C))),o.appendChild(a);for(const h of m.findings)o.appendChild(D(h,!1,C))}return p}const $e=[{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"}],Le=[{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"}],Re=["unusual","notable","info"],De={unusual:"Unusual",notable:"Notable",info:"Info"};function Ee(e,n,t){const i=s("div",{display:"flex",flexWrap:"wrap",alignItems:"center",gap:"10px",marginBottom:"10px",paddingBottom:"10px",borderBottom:`1px solid ${y.separator}`}),r={unusual:0,notable:0,info:0};for(const o of e)r[o.severity]++;const d=Re.filter(o=>r[o]>0),c=new Set(n.severity===void 0?d:Array.isArray(n.severity)?n.severity:[n.severity]),p=s("div",{display:"flex",gap:"4px",flexWrap:"wrap"});for(const o of d){const l=document.createElement("button");l.type="button";const f=()=>{const b=c.has(o);l.setAttribute("aria-pressed",b?"true":"false"),Object.assign(l.style,{display:"inline-flex",alignItems:"center",gap:"5px",border:`1px solid ${y.menuBorder}`,borderRadius:"10px",background:b?y.bgActive:"none",opacity:b?"1":"0.5",color:y.text,fontSize:"11px",padding:"2px 8px",cursor:"pointer"})};l.appendChild(V(o)),l.appendChild(s("span",{},`${De[o]} ${r[o]}`)),l.title=c.has(o)?"Click to hide these findings":"Click to show these findings",f(),l.addEventListener("click",()=>{c.has(o)?c.delete(o):c.add(o),n.severity=c.size===d.length?void 0:[...c],t()}),p.appendChild(l)}return i.appendChild(p),i.appendChild(J("Kind:",$e,n.kind??"",o=>{n.kind=o||void 0,t()},{maxWidth:"130px"})),i.appendChild(J("Region:",Le,n.family??"",o=>{n.family=o||void 0,t()},{maxWidth:"150px"})),i}export function buildFindingsSectionWithFilter(e,n,t,i,r){if(!e.findings.length)return null;const d=e.findings.some(b=>b.severity==="unusual"||b.severity==="notable"),c=d?e.findings.filter(b=>b.severity!=="info").length.toString():void 0,{outer:p,content:o}=ne(`Findings (${e.findings.length})`,d,c);o.appendChild(Ee(e.findings,i,r));const l=fe(e,i);if(!l.length)return o.appendChild(s("div",{color:F,fontSize:"11px",textAlign:"center",padding:"16px 8px"},"No findings match the current filter.")),p;const f=buildFindingsSection(l,e,n,t,!0);return f&&o.appendChild(f),p}export function buildLotTestSection(e,n,t,i,r){let d;if(i?.length&&i.every(c=>c.stats.perTestStats!==void 0)){const c=new Map;for(const p of i)for(const o of p.stats.perTestStats??[]){const l=c.get(o.testNumber);l?(l.n+=o.count,l.sum+=o.mean*o.count,l.min=Math.min(l.min,o.min),l.max=Math.max(l.max,o.max)):c.set(o.testNumber,{n:o.count,sum:o.mean*o.count,min:o.min,max:o.max})}d={perTestStats:[...c.entries()].map(([p,o])=>({testNumber:p,count:o.n,min:o.min,max:o.max,mean:o.sum/o.n}))}}if(i?.length&&i.every(c=>c.stats.testSpecYield!==void 0)){const c=new Map;for(const p of i)for(const o of p.stats.testSpecYield??[]){const l=c.get(o.testNumber);l?(l.passDies+=o.passDies,l.totalDies+=o.totalDies):c.set(o.testNumber,{passDies:o.passDies,totalDies:o.totalDies})}d={...d,testSpecYield:[...c.entries()].map(([p,o])=>({testNumber:p,totalDies:o.totalDies,yieldPercent:o.totalDies>0?o.passDies/o.totalDies*100:null}))}}return buildTestSection(e,n,t,d,r)}export function createSummaryPanelEl(e){const n=e==="top"||e==="bottom",t=s("div",{background:Se,border:M,borderRadius:"8px",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)"});return n?(t.style.height="180px",t.style.width="100%"):(t.style.width="260px",t.style.maxHeight="100%"),t}export function wrapWithSummaryPanel(e,n,t){const i=t==="top"||t==="bottom",r=s("div",{display:"flex",flexDirection:i?"column":"row",gap:"8px",width:"100%",height:"100%",flex:"1 1 0",minHeight:"0",boxSizing:"border-box",alignItems:i?"flex-start":"stretch"});return e.style.flex="1 1 0",e.style.minWidth="0",e.style.minHeight="0",t==="right"||t==="bottom"?(r.appendChild(e),r.appendChild(n)):(r.appendChild(n),r.appendChild(e)),r}function re(e){return s("div",{fontSize:"13px",fontWeight:"700",color:W,marginBottom:"10px"},e)}function ae(e,n){const t=s("button",{background:"none",border:M,borderRadius:"4px",cursor:"pointer",fontSize:"10px",color:y.iconHover,padding:"2px 7px",marginBottom:"10px",display:"block"},e);return t.type="button",t.addEventListener("click",n),t}export function renderWaferSummaryContent(e,n){const t=e.scrollTop;e.innerHTML="";const{wafer:i,dies:r,yieldSummary:d,dataCoverage:c,hbinDefs:p,sbinDefs:o,testDefs:l,statsSummary:f,passBins:b=[1],ringCount:v=4,colorScheme:R,fallbackFormat:B,onFindingClick:$,activeFindingId:D=null,findingsFilter:T,onFindingsFilterChange:E,onSaveText:m}=n;e.appendChild(re("Wafer Summary"));const k=n.warnings??K({statsSummary:f});k.length&&e.appendChild(j(k)),d&&c&&e.appendChild(ae("Summary report",()=>{U(pe({wafer:i,dies:r,yieldSummary:d,dataCoverage:c,hbinDefs:p,sbinDefs:o,testDefs:l,statsSummary:f,passBins:b,ringCount:v}))}));const C=[],a=f?.stats.isLotStack?f.stats:void 0,h=a?.lotSize!==void 0?{lotSize:a.lotSize,aggrMethod:ge(a.aggregationMethod)}:void 0;C.push(buildMetadataInfoSection([{metadata:i.metadata??void 0}],h)),d&&c&&C.push(buildYieldSection(d,c,b));const S=r.some(u=>u.hbin!=null),w=r.some(u=>u.sbin!=null);S?C.push(buildBinSection(r,p,"hard",R,f?.stats.hardBinCounts)):w&&C.push(buildBinSection(r,o,"soft",R,f?.stats.softBinCounts)),C.push(buildRingSection(r,i,v,b)),C.push(buildQuadrantSection(r,i,v,b)),C.push(buildTestSection(r,l,B,f?.stats,m)),C.push(buildFunctionalTestSection(r,l,f?.stats.functionalYield,m)),f&&$&&T&&E&&C.push(buildFindingsSectionWithFilter(f,$,D,T,E));let x=!0;for(const u of C)u&&(x||e.appendChild(ie()),x=!1,e.appendChild(u));e.appendChild(s("div",{height:"12px",flexShrink:"0"})),e.scrollTop=t}export function renderLotSummaryContent(e,n){const t=e.scrollTop;e.innerHTML="";const{lotSummary:i,items:r,hbinDefs:d,sbinDefs:c,testDefs:p,passBins:o=[1],ringCount:l=4,colorScheme:f,fallbackFormat:b,onFindingClick:v,activeFindingId:R=null,onWaferClick:B,findingsFilter:$,onFindingsFilterChange:D,onSaveText:T}=n;e.appendChild(re(`Lot Summary \u2014 ${i.stats.waferCount} wafer${i.stats.waferCount===1?"":"s"}`));const E=n.warnings??K({lotStatsSummary:i});E.length&&e.appendChild(j(E)),e.appendChild(ae("Summary report",()=>{U(ce({items:r.map((u,g)=>({label:u?.label??`W${g+1}`,wafer:u?.wafer,dies:u?.dies,statsSummary:u?.statsSummary})),hbinDefs:d,sbinDefs:c,testDefs:p,passBins:o,ringCount:l}))}));const m=[],k=[],C=[];for(const u of r){if(!u){k.push([]);continue}u.wafer&&m.push(u.wafer);const g=u.dies??[];k.push(g),C.push(...g)}const a=C.some(u=>u.hbin!=null),h=C.some(u=>u.sbin!=null),S=r.map(u=>u?.statsSummary).filter(u=>!!u),w=[buildLotOverviewSection(i),buildMetadataInfoSection(r.filter(u=>u!==null).map(u=>({metadata:u.wafer?.metadata}))),buildPerWaferYieldSection(i,r,B),a?buildLotBinSection(C,d,"hard",f):h?buildLotBinSection(C,c,"soft",f):null,buildLotRingSection(k,m,l,o),buildLotQuadrantSection(k,m,l,o),p?.length?buildLotTestSection(C,p,b,S,T):null,p?.length?buildLotFunctionalSection(C,p,S,T):null];v&&$&&D&&w.push(buildFindingsSectionWithFilter(i,v,R,$,D));let x=!0;for(const u of w)u&&(x||e.appendChild(ie()),x=!1,e.appendChild(u));e.appendChild(s("div",{height:"12px",flexShrink:"0"})),e.scrollTop=t}
|