@wafertools/wafermap 0.24.3 → 0.25.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/CHANGELOG.md +34 -0
- package/dist/packages/canvas-adapter/charts/capability.js +1 -1
- package/dist/packages/canvas-adapter/charts/chartShell.d.ts +16 -0
- package/dist/packages/canvas-adapter/charts/chartShell.js +1 -1
- package/dist/packages/canvas-adapter/charts/correlation.js +1 -1
- 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/renderWaferGallery.d.ts +14 -1
- package/dist/packages/canvas-adapter/renderWaferGallery.js +6 -6
- package/dist/packages/canvas-adapter/renderWaferMap.d.ts +22 -0
- package/dist/packages/canvas-adapter/renderWaferMap.js +1 -1
- package/dist/packages/canvas-adapter/summaryPanel.js +3 -3
- package/dist/packages/canvas-adapter/toCanvas.d.ts +11 -0
- package/dist/packages/canvas-adapter/toCanvas.js +1 -1
- package/dist/packages/canvas-adapter/toolbar.d.ts +53 -6
- package/dist/packages/canvas-adapter/toolbar.js +2 -2
- package/dist/packages/canvas-adapter/userGuideHtml.d.ts +1 -1
- package/dist/packages/canvas-adapter/userGuideHtml.js +1 -1
- package/dist/packages/canvas-adapter/version.d.ts +2 -2
- package/dist/packages/canvas-adapter/version.js +1 -1
- package/dist/packages/renderer/buildView.d.ts +22 -0
- package/dist/packages/renderer/buildView.js +1 -1
- package/dist/packages/stats/renderSummaryReport.js +1 -1
- package/package.json +4 -4
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import{getUniqueTestNumbers as
|
|
1
|
+
import{getUniqueTestNumbers as kn,resolveTestNumber as Dn,findTestDef as Bn}from"../renderer/buildView.js";import{getColorScheme as En}from"../renderer/colorSchemes.js";import{metadataValueColor as On}from"../renderer/colorMap.js";import{resolveCanvasTheme as Tn}from"./canvasTheme.js";import{ICONS as ge}from"./icons.js";import{CLR as g,sevColor as Tt,BIN_LEGEND_MODES as Lt,STACKED_MODES as he,Z_ABOVE as Wt,applyOverlayZ as Ln,getTooltip as Wn,hideTooltip as Rt,createToolbarHelpers as Rn,buildModeMenuEl as In,openDetachWindow as $n,openFloatingWindow as Pn,openModal as Fn,copyWmapThemeTokens as An,syncWmapPopupTheme as Hn,openUserGuideWindow as jn,makePaletteBtn as zn,makeLogScaleBtn as Vn,makeLegendStyleBtn as Nn,makeOverlaysBtn as _n,makeOrientationBtn as Gn,menuLayerFor as It,saveImageBlob as Kn,markMenuTrigger as be,wireMenuA11y as $t,wireExpandToggle as Pt,passFailMenuRows as qn,requestedPassFailDisplay as Ue,logWmapVersionOnce as Xn,buildDataModeEntries as Un,metadataKeyHasData as Qn,metadataModeEntry as Yn}from"./toolbar.js";import{aggregateValues as Zn,aggregateBinCounts as Ft}from"../core/aggregates.js";import{renderWaferMap as Qe}from"./renderWaferMap.js";import{classifyChanged as Jn}from"./renderWaferMap.js";import{buildWaferMap as eo,getTestPassStatus as to,isParametricTest as At}from"../renderer/buildWaferMap.js";import{analyzeWaferMap as Le}from"../stats/analyzeWaferMap.js";import{collectWarnings as no,buildWarningsMenuEl as oo,severityOf as io}from"./warnings.js";import{compareNatural as ao}from"../core/utils.js";import{createSummaryPanelEl as Ye,buildMetadataStripRow as lo,buildCompactMetadataRows as Ht,metadataEntries as jt,renderLotSummaryContent as so}from"./summaryPanel.js";import"../stats/facets.js";import{openHtmlReport as ro}from"../stats/renderFindingsReport.js";import{escHtml as ye,renderSection as co,renderSeverityBadge as uo,reportStyles as fo}from"../stats/reportHtml.js";import{createInsightsTab as po}from"./insightsTab.js";import{getDieKey as mo,hasPosition as go}from"../core/dies.js";function We(f){const D=new Set;return f.filter(p=>D.has(p.bin)?!1:(D.add(p.bin),!0))}function zt(f,D){const p=f.ownerDocument.createElement("div");Object.assign(p.style,{display:"flex",alignItems:"center",gap:"5px",cursor:"pointer",userSelect:"none",padding:"2px 4px",borderRadius:"3px"});const Q=f.ownerDocument.createElement("span");Object.assign(Q.style,{display:"inline-block",width:"13px",height:"13px",flexShrink:"0",background:D.color,border:D.isActive?`2px solid ${g.iconActive}`:`1px solid ${g.menuBorder}`,borderRadius:"2px",boxSizing:"border-box"});const ne=f.ownerDocument.createElement("span");ne.textContent=D.label,Object.assign(ne.style,{fontWeight:D.isActive?"700":"400",color:D.isActive?g.iconActive:g.text,whiteSpace:"nowrap"}),p.appendChild(Q),p.appendChild(ne),p.setAttribute("role","button"),p.setAttribute("aria-pressed",D.isActive?"true":"false"),p.tabIndex=0,p.addEventListener("mouseenter",()=>{p.style.background=g.bgHover}),p.addEventListener("mouseleave",()=>{p.style.background="transparent"}),p.addEventListener("focus",()=>{p.style.background=g.bgHover}),p.addEventListener("blur",()=>{p.style.background="transparent"}),p.addEventListener("click",D.onClick),p.addEventListener("keydown",W=>{(W.key==="Enter"||W.key===" ")&&(W.preventDefault(),D.onClick())}),f.appendChild(p)}export function renderWaferGallery(f,D,p={}){Xn();const Q=p.cardPadding??6,ne=p.downloadFilename??"wafer-gallery";let W=p.columns;const Vt=p.showPlotModeSelector??!0,Nt=p.showHelpButton??!1,_t=p.userGuideExtension,Ze=p.insights?.enabled??!1,Gt=Ln(p.zIndex),Y=p.summaryPanel,Je=p.passBins??[1];let we=p.fallbackFormat,E=p.lotStatsSummary,oe=p.legendPosition??"default",xe=p.perCardLegend??!1;function ie(){const e=r.plotMode??"hardBin";return Lt.has(e)?null:r.colorbarRangeMode==="data"?"Each map has its own value range, so it keeps its own colour bar":"This lot has no shared colour bar for value mode, so each map keeps its own"}function et(){const e=xe||ie()!==null;for(const t of v)t&&t.setOptions({showLegend:e})}let r={plotMode:"hardBin",colorScheme:"default",showDieLabels:!1,showRingBoundaries:!1,showQuadrantBoundaries:!1,ringCount:4,rotation:0,flipX:!1,flipY:!1,...p.viewOptions},v=[],q=[],Z=[],k=[],w=D.map(e=>typeof e=="function"?null:e),Re=0,ve=0;const I=new Map;let Kt=0,O=null,ae=null,tt=new Set,m=null,le="lot",qt={};function nt(e){return w[e]?.statsSummary??E?.perWafer.find(t=>t.waferIndex===e)?.summary}function Ce(){return!!(w.some(e=>e?.statsSummary?.findings.length)||E?.perWafer.some(e=>e.summary.findings.length))}const Xt=Wn(),J=Rn(Xt),{makeBtn:N,setActive:se,makeSep:$,makeMenuRow:Ut,makeMenuSection:Qt,makeDropdown:ot,makeCheckMenuBtn:ho,closeOpenMenu:Se,getOpenMenu:re,setOpenMenu:de}=J;f.ownerDocument.addEventListener("click",Se,!0);const it=()=>Rt();window.addEventListener("blur",it);function Ie(e){tt=new Set(e);const t=[...B.querySelectorAll(".wmap-gallery-card")];let n;t.forEach((o,s)=>{const c=tt.has(s);o.style.outline=c?`3px solid ${g.findingHighlight}`:"",o.style.outlineOffset=c?"-3px":"",c&&n===void 0&&(n=o)}),n?.scrollIntoView?.({behavior:"smooth",block:"nearest"})}function $e(){Ie([])}function Pe(){for(const e of v)e&&e.clearSelection()}function Fe(e,t){const n=new Set(e),o=t??v.map((s,c)=>c);for(const s of o){const c=k[s],i=v[s];if(!c||!i)continue;const d=c.dies.filter(l=>n.has(mo(l)));i.setSelection(d)}}function at(){const e=f.ownerDocument.createElement("div");Object.assign(e.style,{display:"flex",gap:"4px",marginBottom:"10px",borderBottom:`1px solid ${g.menuBorder}`,paddingBottom:"8px"});for(const t of["lot","wafers"]){const n=f.ownerDocument.createElement("button");n.type="button",n.textContent=t==="lot"?"Lot":"Findings";const o=le===t;Object.assign(n.style,{border:"none",borderRadius:"4px",padding:"2px 8px",fontSize:"11px",cursor:"pointer",fontWeight:o?"600":"400",background:o?g.bgActive:"transparent",color:o?g.iconHover:g.icon}),n.addEventListener("click",()=>{le=t,$e(),Pe(),R()}),e.appendChild(n)}return e}function Yt(){if(!m)return;m.innerHTML="",E&&m.appendChild(at());const e=[];for(let n=0;n<w.length;n++){const o=w[n];if(!o)continue;const s=nt(n)?.findings??[];if(!s.length)continue;const c=s.filter(d=>d.severity==="unusual").length,i=s.filter(d=>d.severity==="notable").length;e.push({index:n,item:o,unusualCount:c,notableCount:i,totalCount:s.length})}if(w.length>0){const n=f.ownerDocument.createElement("div"),o=e.length,s=w.filter(Boolean).length;n.textContent=o===0?`No findings on any of the ${s} wafers`:`${o} of ${s} wafer${s===1?"":"s"} with findings`,Object.assign(n.style,{fontSize:"11px",color:g.label,marginBottom:"8px"}),m.appendChild(n)}if(e.length>0){const n=f.ownerDocument.createElement("button");n.type="button",n.textContent="Findings report",Object.assign(n.style,{border:`1px solid ${g.menuBorder}`,borderRadius:"4px",padding:"3px 8px",marginBottom:"10px",fontSize:"10px",color:g.iconHover,background:"none",cursor:"pointer",display:"block",width:"100%",textAlign:"left"}),n.addEventListener("click",()=>{const o=`Findings report \u2014 ${e.length} wafer${e.length>1?"s":""}`,s=new Date().toLocaleString(),c=e.map(({item:d,index:l})=>{const a=nt(l),u=d.label??`W${l+1}`,h=a.findings.map(b=>`<li>${uo(b.severity)} ${ye(b.summary)}</li>`).join("");return co(ye(u),`<ul style="margin:0;padding-left:18px;list-style:none">${h}</ul>`)}).join(`
|
|
2
2
|
`),i=`<!DOCTYPE html>
|
|
3
3
|
<html lang="en">
|
|
4
4
|
<head>
|
|
5
5
|
<meta charset="UTF-8">
|
|
6
|
-
<title>${
|
|
6
|
+
<title>${ye(o)}</title>
|
|
7
7
|
<style>
|
|
8
|
-
${
|
|
8
|
+
${fo()}
|
|
9
9
|
</style>
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
|
12
12
|
<main class="report">
|
|
13
13
|
<header class="report-header">
|
|
14
|
-
<h1>${
|
|
15
|
-
<p class="report-subtitle">Generated ${
|
|
14
|
+
<h1>${ye(o)}</h1>
|
|
15
|
+
<p class="report-subtitle">Generated ${ye(s)}</p>
|
|
16
16
|
</header>
|
|
17
17
|
${c}
|
|
18
18
|
</main>
|
|
19
19
|
</body>
|
|
20
|
-
</html>`;no(i)}),u.appendChild(n)}if(e.length===0){const n=m.ownerDocument.createElement("div");Object.assign(n.style,{color:g.icon,fontSize:"11px",padding:"4px 0"}),n.textContent="No findings on any wafer.",u.appendChild(n)}else for(const{index:n,item:o,unusualCount:s,notableCount:c,totalCount:i}of e){const r=s?"unusual":c?"notable":"info",a=s+c||i,l=m.ownerDocument.createElement("button");l.type="button",Object.assign(l.style,{display:"flex",alignItems:"center",justifyContent:"space-between",width:"100%",padding:"5px 8px",marginBottom:"4px",border:"none",borderLeft:`3px solid ${Mt(r)}`,borderRadius:"3px",background:g.bgHover,cursor:"pointer",fontSize:"11px",textAlign:"left",boxSizing:"border-box"}),l.addEventListener("mouseover",()=>{l.style.background=g.bgActive}),l.addEventListener("mouseout",()=>{l.style.background=g.bgHover});const f=m.ownerDocument.createElement("span");f.textContent=o.label??`W${n+1}`,Object.assign(f.style,{color:g.iconHover,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"});const b=m.ownerDocument.createElement("span");b.textContent=String(a),Object.assign(b.style,{marginLeft:"6px",flexShrink:"0",background:Mt(r),color:"#fff",borderRadius:"8px",padding:"1px 5px",fontSize:"10px",fontWeight:"600"}),l.appendChild(f),l.appendChild(b),l.addEventListener("click",()=>ke(n,o)),u.appendChild(l)}const t=m.ownerDocument.createElement("div");t.style.height="12px",u.appendChild(t)}function I(){if(u)if(ie==="lot"&&O){const e=Ee(x.flatMap(n=>n?.hbinDefs??[])),t=Ee(x.flatMap(n=>n?.sbinDefs??[]));to(u,{lotSummary:O,items:x,hbinDefs:e.length?e:void 0,sbinDefs:t.length?t:void 0,testDefs:x.find(n=>n?.testDefs?.length)?.testDefs,passBins:Ue,ringCount:d.ringCount,colorScheme:d.colorScheme,fallbackFormat:he,activeFindingId:oe,warnings:p.warnings?.display??!0?_:[],findingsFilter:jt,onFindingsFilterChange:I,onSaveText:p.onSaveText,onFindingClick:(n,o)=>{oe===n.id?Re():Gt(n,o),I()},onWaferClick:n=>{Te([n])},dieListOptions:p.dieList}),ye()&&u.insertBefore(et(),u.firstChild)}else _t()}function tt(e){return[e.variable.kind,e.variable.index??"",e.variable.bin??"",e.comparison.family,e.comparison.left,e.effect.direction].join("|")}function Re(){oe=null,We(),Le(),C({highlightBin:void 0},{fireCallback:!1})}function Gt(e,t){if(oe===e.id){Re();return}oe=e.id,t.style.background=g.bgActive,t.style.fontWeight="600";const{kind:n,index:o}=e.variable;n==="test"?C({plotMode:"value",activeTest:o??0,highlightBin:void 0},{fireCallback:!1}):n==="softBin"?C({plotMode:"softBin",highlightBin:void 0},{fireCallback:!1}):C({plotMode:"hardBin",highlightBin:void 0},{fireCallback:!1}),We(),Le();const s=e.highlight;if(s.kind==="wafer"){Te(s.waferIndices);const c=tt(e);for(const i of s.waferIndices){const l=M[i]?.statsSummary?.findings.find(f=>tt(f)===c)?.highlight?.dieKeys;l?.length&&Ie(l,[i])}}else s.kind==="bin"?s.dieKeys?.length&&Ie(s.dieKeys):(s.kind==="region"||s.kind==="dies")&&s.dieKeys?.length&&Ie(s.dieKeys)}function X(){if(!T)return;const e=!!u;T.style.display=(O||ye())&&e&&!Ae?"flex":"none";const t=u?u.style.display!=="none":!1;(O?.hasNotableFindings||x.some(o=>o?.statsSummary?.hasNotableFindings))&&!t?T.style.color=g.findingIndicator:T.dataset.active||(T.style.color=g.icon)}const B=m.ownerDocument.createElement("div");B.dataset.wmapToolbar="gallery",Object.assign(B.style,{display:"inline-flex",flexDirection:"row",alignItems:"center",gap:"0",background:g.menuBg,border:`1px solid ${g.menuBorder}`,borderRadius:"6px",padding:"3px 4px",marginBottom:"10px",boxShadow:"0 1px 4px rgba(0,0,0,0.10)",flexWrap:"wrap",minWidth:"0",overflowX:"auto"});const nt=()=>{const e=le();e&&(e.remove(),se(null)),me(j,!1)},j=V("mode","Plot mode",()=>{if(le()){nt();return}const e=x.flatMap(h=>h?.dies??[]),t=x.find(h=>h?.testDefs?.length)?.testDefs,{testEntries:n,binEntries:o,stackedEntries:s}=Vn(e,t,{includeStacked:!0}),c=d.plotMode??"hardBin",i=d.activeTest??0;function r(h){return h.plotMode!==c?!1:h.plotMode==="value"?i===(h.activeTest??0):h.plotMode==="metadata"?d.activeMetadataKey===h.activeMetadataKey:!0}function a(h,k){h.activeTest!==void 0?C({plotMode:"value",activeTest:h.activeTest,activeMetadataKey:void 0,logScale:h.logScale}):h.activeMetadataKey!==void 0?C({plotMode:h.plotMode,activeTest:void 0,activeMetadataKey:h.activeMetadataKey,passFailDisplay:"off"}):C({plotMode:h.plotMode,activeTest:void 0,activeMetadataKey:void 0,passFailDisplay:"off"}),k.remove(),se(null),me(j,!1)}const l=new Set,f=x.flatMap(h=>h?.metadataFields??[]).filter(h=>!l.has(h.key)&&l.add(h.key)).filter(h=>_n(e,h.key)).map(Gn),b=En(j.getBoundingClientRect(),n,o,s,r,a,{makeMenuRow:Nt,makeMenuSection:Vt},c,j.ownerDocument.defaultView??window,f);Bt(j).appendChild(b),se(b),me(j,!0),Et(b,j,nt)});me(j,!1);const Kt=()=>M.flatMap(e=>e?[...e.hbinDefs??[],...e.sbinDefs??[]]:[]).some(e=>e.color),{btn:qt,sync:ot}=Pn(J,()=>d.plotMode??"hardBin",()=>d.colorScheme??"default",Kt,e=>C({colorScheme:e}));ot();const Xt=D.some(e=>typeof e!="function"&&(e.reticles?.length??0)>0);function Pe(){const e=x.find(n=>n?.testDefs?.length)?.testDefs,{testNumber:t}=xn(d.activeTest??0,e);return{testNumber:t,td:wn(e,t)}}function it(){if((d.plotMode??"hardBin")!=="value")return!1;const{td:e}=Pe();return e!==void 0&&(e.limitLow!==void 0||e.limitHigh!==void 0)}function re(){if((d.plotMode??"hardBin")!=="value")return!1;const{td:e}=Pe();return e!==void 0&&!Wt(e)}function Ut(){if((d.plotMode??"hardBin")!=="value")return!1;const{testNumber:e,td:t}=Pe();return x.some(n=>n?.dies?.some(o=>Un(o,e,t)!==void 0))}const Yt=Hn(J,()=>[{label:"Ring boundaries",active:!!d.showRingBoundaries,onClick:()=>C({showRingBoundaries:!d.showRingBoundaries})},{label:"Quadrant lines",active:!!d.showQuadrantBoundaries,onClick:()=>C({showQuadrantBoundaries:!d.showQuadrantBoundaries})},{label:"Die labels",active:!!d.showDieLabels,onClick:()=>C({showDieLabels:!d.showDieLabels})},{label:"Reticle grid",active:!!d.showReticle,enabled:Xt,onClick:()=>C({showReticle:!d.showReticle})},{label:"XY indicator",active:!!d.showXYIndicator,onClick:()=>C({showXYIndicator:!d.showXYIndicator})},...zn({functionalActive:re(),hasLimits:it()&&!re(),hasRecorded:Ut()&&!re(),display:Ge(d)},e=>C({passFailDisplay:e}))],()=>!!(d.showRingBoundaries||d.showQuadrantBoundaries||d.showDieLabels||d.showReticle||d.showXYIndicator||Ge(d)!=="off")),{btn:Qt,sync:at}=Fn(J,()=>({plotMode:d.plotMode,legendPosition:ne}),e=>{ne=e;for(const t of v)t&&t.setOptions({legendPosition:ne})});at();const Zt=[{value:"mean",label:"Mean"},{value:"median",label:"Median"},{value:"stddev",label:"Std Dev"},{value:"min",label:"Min"},{value:"max",label:"Max"},{value:"count",label:"Count"}],lt=Ze("aggr","Aggregation method",()=>Zt,()=>d.aggregationMethod??"mean",e=>C({aggregationMethod:e}));function st(){const e=d.plotMode==="stackedValues";lt.style.display=e?"":"none"}st();const{btn:Jt,sync:rt}=An(J,()=>({...d,functionalActive:re()}),e=>C(e));rt();const we=V("specRange","Colorbar range: spec limits",()=>{const e=d.colorbarRangeMode==="data"?"spec":"data";C({colorbarRangeMode:e})});function dt(){const e=(d.plotMode??"hardBin")==="value"&&it()&&Ge(d)==="off"&&!re();we.style.display=e?"":"none";const t=(d.colorbarRangeMode??"spec")==="spec";ae(we,t),we.ariaLabel=t?"Colorbar range: spec limits (click for data range)":"Colorbar range: data range (click for spec limits)"}dt();const en=$n(J,()=>d,e=>C(e)),tn=V("downloadAll","Download gallery PNG",hn),nn=Ze("columns","Columns",()=>[{value:"auto",label:"Auto"},{value:"1",label:"1 column"},{value:"2",label:"2 columns"},{value:"3",label:"3 columns"},{value:"4",label:"4 columns"},{value:"5",label:"5 columns"}],()=>L!=null?String(L):"auto",e=>xt(e==="auto"?void 0:Number(e))),S=m.ownerDocument.createElement("div");Object.assign(S.style,{display:"inline-flex",alignItems:"center",gap:"0"}),B.appendChild(S),Pt&&S.appendChild(j),S.appendChild(qt),S.appendChild(lt),S.appendChild(Jt),S.appendChild(we),S.appendChild(P()),S.appendChild(Yt),S.appendChild(P()),S.appendChild(Qt),S.appendChild(P()),S.appendChild(en),S.appendChild(P()),S.appendChild(nn),S.appendChild(P()),S.appendChild(tn),(O||ye())&&(T=V("findings","Summary panel",()=>{if(!u)return;const e=u.style.display!=="none";e||I(),u.style.display=e?"none":"flex",ae(T,!e),X()}),B.appendChild(P()),B.appendChild(T));let A=null,ve=null,_=[],ct=!1;function ft(){const e=Yn({lotStatsSummary:O,result:{warnings:x.flatMap(n=>n?.warnings??[])}}),t=e.length!==_.length||e.some((n,o)=>n.code!==_[o]?.code||n.message!==_[o]?.message);_=e,(t||!ct)&&(ct=!0,p.warnings?.onWarning?.(e)),on()}function on(){if(!A||!ve)return;const e=_.length,t=e>0;if(A.style.display=t?"flex":"none",ve.style.display=t?"":"none",!t)return;const n=Zn(_[0]),o=`${e} data ${e===1?"warning":"warnings"}`;A.style.color=n==="error"?g.errText:g.warnText,A.ariaLabel=n==="error"?`${o} \u2014 wafers in this lot may be positionally wrong`:o}(p.warnings?.display??!0)&&(ve=P(),A=V("warning","Data warnings",()=>{const e=le();if(xe(new MouseEvent("click")),e)return;const t=Qn(A.getBoundingClientRect(),_,A.ownerDocument.defaultView??window);Bt(m).appendChild(t),se(t),Et(t,A,()=>xe(new MouseEvent("click")))}),me(A,!1),B.appendChild(ve),B.appendChild(A)),ft();let U=null;Xe&&(U=V("analysis","Insights",()=>{const e=ee?.style.display!=="none";ut(!e)}),U.dataset.wmapInsightsBtn="1",B.appendChild(P()),B.appendChild(U));function pt(){import("./userGuideHtml.js").then(e=>Rn({buildWaferMap:Xn,renderWaferMap:Ke,renderWaferGallery,analyzeWaferMap:Be},e.USER_GUIDE_HTML,Ft,m))}At&&(B.appendChild(P()),B.appendChild(V("help","User guide",()=>pt())));const G=m.ownerDocument.createElement("div");Object.assign(G.style,{display:"flex",flexDirection:"column",gap:"6px",background:g.menuBg,border:`1px solid ${g.menuBorder}`,borderRadius:"6px",padding:"6px 10px",marginBottom:"10px",boxShadow:"0 1px 4px rgba(0,0,0,0.10)",fontSize:"12px",lineHeight:"1",boxSizing:"border-box",width:"100%",minWidth:"0"});const F=m.ownerDocument.createElement("div");Object.assign(F.style,{display:"flex",flexDirection:"row",gap:"12px",alignItems:"flex-start"});let de=null,ee=null;Xe&&(de=lo({getItems:()=>x,getLotStats:()=>O,getColorSchemeName:()=>d.colorScheme??"default",passBins:Ue,getRingCount:()=>d.ringCount??4,defaultView:p.insights?.defaultView,backTab:{label:"Gallery",onBack:()=>ut(!1)},showMetadataStrip:!1,onSaveImage:p.onSaveImage,onSaveText:p.onSaveText,ownerDocument:m.ownerDocument,openWafer:(e,t,n)=>{const o=x[e];if(!o)return;let s=null;const c=Wn({title:t,onClose:()=>s?.destroy(),anchor:m});vt(c,t,o.wafer.metadata??void 0),s=ze(c.contentWrap,o,n)}}),ee=de.el);let Ae=!1;function ut(e){!de||!ee||(Ae=e,ee.style.display=e?"flex":"none",F.style.display=e?"none":"flex",S.style.display=e?"none":"inline-flex",U&&(ae(U,e),U.innerHTML=e?pe.wafer:pe.analysis,U.ariaLabel=e?"Back to gallery view":"Insights"),X(),Me(),e&&de.render())}const an=4,Fe=240,mt=480,ln=720,sn=1.25,gt=p.maxSize;let z=gt??mt;function ht(e){const t=Y*2+110+2;let n=null;for(const o of e){if(o==null||!o.dies?.length)continue;const s=o.dies[0].width;if(!(s>0))continue;const c=o.wafer.radius*2*(an/s),i=Math.ceil(c+t);(n==null||i>n)&&(n=i)}return n}function rn(e){const t=ht(e);return t==null?Fe:Math.min(z,Math.max(Fe,t))}function dn(e){if(gt!=null)return!1;const t=ht(e);if(t==null)return!1;const n=Math.min(ln,Math.max(mt,t));return n<=z?!1:(z=n,!0)}function cn(){for(const e of Array.from(E.children))e.classList.contains("wmap-gallery-card")&&(e.style.maxWidth=`${z}px`,e.style.maxHeight=`${z}px`)}let Ce=Fe,bt=0;function yt(e){const t=dn(e);if(t&&cn(),L!=null){t&&Se();return}const n=rn(e);n>Ce&&(Ce=n),Se()}function xt(e){L=e,Se()}function He(e){return`repeat(${e}, minmax(0, ${z}px))`}function Se(){if(L!=null){E.style.gridTemplateColumns=He(L);return}const e=Math.max(1,bt),t=12,n=E.clientWidth||0,o=c=>(n-t*(c-1))/c;let s=Math.max(1,Math.ceil(Math.sqrt(e)));if(n>0){for(;s>1&&o(s)<Ce;)s--;const c=Math.min(z,Ce*sn);for(;s<e&&o(s+1)>=c;)s++}E.style.gridTemplateColumns=He(s)}const E=m.ownerDocument.createElement("div");if(Object.assign(E.style,{flex:"1 1 0",minWidth:"0",display:"grid",gridTemplateColumns:He(1),gap:"12px",justifyContent:"start",alignContent:"start"}),ie=O?"lot":"wafers",Q?.placement){const e=Q.placement;u=qe(e,m.ownerDocument),u.style.maxHeight="calc(100vh - 80px)",u.style.position="sticky",u.style.top="8px",u.style.display="flex",u.style.flexDirection="column"}else if(O||ye()){const e=!!Q?.defaultOpen;u=qe("right",m.ownerDocument),u.style.maxHeight="calc(100vh - 80px)",u.style.position="sticky",u.style.top="8px",u.style.flexDirection="column",u.style.display=e?"flex":"none",I()}X(),u?.style.display!=="none"&&T&&ae(T,!0),(Q?.placement??"right")==="left"?(u&&F.appendChild(u),F.appendChild(E)):(F.appendChild(E),u&&F.appendChild(u)),m.appendChild(B),m.appendChild(G),m.appendChild(F),ee&&m.appendChild(ee);function Me(){G.innerHTML="";const e=d.plotMode??"hardBin",t=!Ae&&Mn.has(e),n=M.filter(y=>y!=null),o=n.find(y=>y.isLotStack),s=eo(n.map(y=>({metadata:y.wafer.metadata??void 0})),o?{lotSize:o.lotSize??n.length,aggrMethod:o.aggrMethod}:void 0),c=e==="metadata",i=d.activeMetadataKey,r=new Set;if(t&&!c)for(const y of n)for(const W of y.dies){if(W.partial)continue;const w=e==="softBin"?W.sbin:W.hbin;w!=null&&r.add(w)}const a=t&&!c?[...r].sort((y,W)=>y-W):[],l=new Set;if(t&&c&&i)for(const y of n)for(const W of y.dies){if(W.partial)continue;const w=W.metadata?.[i];w!=null&&(typeof w=="string"||typeof w=="number"||typeof w=="boolean")&&l.add(String(w))}const f=t&&c?[...l].sort(Jn):[];if(!s&&!a.length&&!f.length){G.style.display="none";return}if(G.style.display="flex",s&&G.appendChild(s),!a.length&&!f.length)return;const b=m.ownerDocument.createElement("div");Object.assign(b.style,{display:"flex",flexWrap:"wrap",alignItems:"center",gap:"6px 14px"}),s&&Object.assign(b.style,{borderTop:`1px solid ${g.separator}`,paddingTop:"6px"}),G.appendChild(b);const h=vn(d.colorScheme),k=d.highlightBin;if(c){const y=d.highlightMetadataValue,W=M.flatMap(w=>w?.metadataFields??[]).find(w=>w.key===i);f.forEach((w,Ne)=>{const Ve=y===w,St=W?.values?.find(_e=>_e.value===w),bn=St?.color??Cn(Ne);Rt(b,{color:bn,isActive:Ve,label:St?.label??w,onClick:()=>{const _e=d.highlightMetadataValue===w?void 0:w;C({highlightMetadataValue:_e})}})});return}const H=e==="softBin"?M.flatMap(y=>y?.sbinDefs??[]):M.flatMap(y=>y?.hbinDefs??[]),$=new Set,K=[];for(const y of H)$.has(y.bin)||($.add(y.bin),K.push(y));const fe=K.length>0?new Map(K.map(y=>[y.bin,y])):null;for(const y of a){const W=k===y,w=fe?.get(y),Ne=(d.colorScheme==="custom"?w?.color:void 0)??h.forBin(y);Rt(b,{color:Ne,isActive:W,label:w?.name?`${y} \xB7 ${w.name}`:`Bin ${y}`,onClick:()=>{const Ve=d.highlightBin===y?void 0:y;C({highlightBin:Ve})}})}}function ce(e){const t=x.filter(r=>r!==null);if(!t.length)return[];const n=t.map(r=>r.dies.filter(ro)),o=t[0].wafer,s=t.length,c=o.metadata?{...o,metadata:(({wafer:r,waferId:a,...l})=>l)(o.metadata)}:o;function i(r,a){return{...r,stats:{...r.stats,isLotStack:!0,aggregationMethod:a,lotSize:s}}}if(e==="stackedValues"){const r=t.find(f=>f.testDefs?.length)?.testDefs;let a=r?.filter(Wt);if(r?.length||(a=yn(t.flatMap(b=>b.dies)).map(b=>({testNumber:b,name:`Test ${b}`}))),!a?.length)return[];const l=d.aggregationMethod??"mean";return a.map(f=>{const b=Kn(n,l,f.testNumber),h={testNumber:0,name:f.name,unit:f.unit};return{wafer:c,dies:b,testDefs:[h],label:`${f.name} \xB7 ${l}`,isLotStack:!0,aggrMethod:l,lotSize:s,statsSummary:i(Be({wafer:c,dies:b,testDefs:[h]},{testNumbers:[0]}),l)}})}if(e==="stackedBins"){let r=Ee(t.flatMap(a=>a.hbinDefs??[]));return(!r||r.length===0)&&(r=[...new Set(t.flatMap(l=>l.dies.map(f=>f.hbin).filter(f=>f!=null)))].sort((l,f)=>l-f).map(l=>({bin:l,name:`Bin ${l}`}))),r.map(a=>{const l=Tt(n,a.bin,"hard"),f=[{bin:a.bin,name:a.name}];return{wafer:c,dies:l,hbinDefs:f,label:`${a.bin} \xB7 ${a.name}`,isLotStack:!0,aggrMethod:"countBin",lotSize:s,statsSummary:i(Be({wafer:c,dies:l,hbinDefs:f}),"countBin")}})}if(e==="stackedSoftBins"){let r=Ee(t.flatMap(a=>a.sbinDefs??[]));return(!r||r.length===0)&&(r=[...new Set(t.flatMap(l=>l.dies.map(f=>f.sbin).filter(f=>f!=null)))].sort((l,f)=>l-f).map(l=>({bin:l,name:`Bin ${l}`}))),r.map(a=>{const l=Tt(n,a.bin,"soft"),f=[{bin:a.bin,name:a.name}];return{wafer:c,dies:l,sbinDefs:f,label:`${a.bin} \xB7 ${a.name}`,isLotStack:!0,aggrMethod:"countBin",lotSize:s,statsSummary:i(Be({wafer:c,dies:l,sbinDefs:f}),"countBin")}})}return t}function $e(e){const t=x.length;return e==="stackedBins"||e==="stackedSoftBins"?{valueRange:[0,t],lotSize:t}:e==="stackedValues"?{aggregationMethod:d.aggregationMethod??"mean",valueRange:void 0,lotSize:void 0}:{}}const fn=new Set(["default","accessible","custom"]);function C(e,{fireCallback:t=!0}={}){const n=d.plotMode;d={...d,...e};const o=d.plotMode,s=ue.has(o),c=n!==void 0&&ue.has(n),i=be>0;if(e.plotMode!==void 0&&e.plotMode!==n&&(o==="hardBin"||o==="softBin")&&!fn.has(d.colorScheme??"")&&(d={...d,colorScheme:"default"}),e.plotMode!==void 0)if(s){const a=$e(o);if(d={...d,...a},i)for(const l of v)l&&l.setOptions(e);else N(ce(o))}else if(c){const{valueRange:a,lotSize:l,aggregationMethod:f,...b}=d;if(d=b,i)for(const h of v)h&&h.setOptions(e);else N(x.filter(h=>h!==null))}else for(const a of v)a&&a.setOptions(e);else if(e.aggregationMethod!==void 0&&o==="stackedValues")if(i)for(const a of v)a&&a.setOptions(e);else N(ce("stackedValues"));else for(const a of v)a&&a.setOptions(e);Me(),st(),at(),ot();const r=e.plotMode!==void 0&&e.plotMode!==n;if((e.colorScheme!==void 0||r)&&I(),rt(),dt(),t){const a=Object.keys(e);p.onViewOptionsChange?.(d,a,qn(a))}}function wt(e,t,n){const o=e.createElement("div");Object.assign(o.style,{display:"flex",alignItems:"center",gap:"4px",flex:"1",minWidth:"0"});const s=e.createElement("span");s.textContent=t,Object.assign(s.style,{fontWeight:"700",fontSize:"13px",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}),o.appendChild(s);const c=It(n??{});let i=null;if(c.length>0){const r=e.createElement("span");Object.assign(r.style,{fontSize:"12px",lineHeight:"1",color:g.label,flexShrink:"0"}),r.textContent="\u25BE",o.appendChild(r),Object.assign(o.style,{cursor:"pointer"}),i=e.createElement("div"),i.dataset.wmapCardMetaPanel="1",Object.assign(i.style,{position:"absolute",top:"0",left:"0",right:"0",zIndex:kt,background:g.menuBg,borderBottom:`1px solid ${g.menuBorder}`,boxShadow:"0 2px 6px rgba(0,0,0,0.15)",padding:"8px 10px",fontSize:"11px",display:"none"});const a=Lt(n??{});a&&i.appendChild(a),o.setAttribute("aria-expanded","false"),o.setAttribute("aria-label",`Wafer info for ${t||"this card"}. Click to expand.`),Ot(o,l=>{r.textContent=l?"\u25B4":"\u25BE",o.setAttribute("aria-expanded",String(l)),i&&(i.style.display=l?"block":"none")})}return{wrap:o,metaPanel:i}}function vt(e,t,n){const o=e.box.querySelector("[data-wmap-window-title]"),s=It(n??{});if(!o||s.length===0)return;const c=o.parentElement,i=m.ownerDocument.createElement("div");Object.assign(i.style,{display:"flex",alignItems:"center",gap:"4px",flex:"1",minWidth:"0",cursor:"pointer"}),c?.insertBefore(i,o),i.appendChild(o);const r=m.ownerDocument.createElement("span");Object.assign(r.style,{fontSize:"12px",lineHeight:"1",color:g.label,flexShrink:"0"}),r.textContent="\u25BE",i.appendChild(r);const a=m.ownerDocument.createElement("div");a.dataset.wmapCardMetaPanel="1",Object.assign(a.style,{position:"absolute",top:"0",left:"0",right:"0",zIndex:kt,background:g.menuBg,borderBottom:`1px solid ${g.menuBorder}`,boxShadow:"0 2px 6px rgba(0,0,0,0.15)",padding:"8px 10px",fontSize:"11px",display:"none"});const l=Lt(n??{});l&&a.appendChild(l),e.contentWrap.style.position="relative",e.contentWrap.appendChild(a),i.setAttribute("aria-expanded","false"),i.setAttribute("aria-label",`Wafer info for ${t}. Click to expand.`),Ot(i,f=>{r.textContent=f?"\u25B4":"\u25BE",i.setAttribute("aria-expanded",String(f)),a.style.display=f?"block":"none"})}function je(e,t,n){const o=m.ownerDocument.createElement("div");o.className="wmap-gallery-card",Object.assign(o.style,{background:g.menuBg,border:`1px solid ${g.menuBorder}`,borderRadius:"10px",overflow:"hidden",display:"flex",flexDirection:"column",position:"relative",aspectRatio:"1",maxWidth:`${z}px`,maxHeight:`${z}px`});const s=m.ownerDocument.createElement("div");Object.assign(s.style,{display:"flex",alignItems:"center",padding:"8px 10px 6px",borderBottom:`1px solid ${g.menuBorder}`,flexShrink:"0",gap:"6px"});const{wrap:c,metaPanel:i}=wt(document,e.label??"",e.wafer.metadata??void 0);s.appendChild(c);const r=m.ownerDocument.createElement("button");r.dataset.wmapExpandBtn="1",r.title="Open full view",r.innerHTML=pe.expand,Object.assign(r.style,{display:"flex",alignItems:"center",justifyContent:"center",border:`1px solid ${g.menuBorder}`,borderRadius:"4px",background:g.panelBg,color:g.label,padding:"2px",cursor:"pointer",flexShrink:"0",width:"22px",height:"22px"}),s.appendChild(r),o.appendChild(s);const a=m.ownerDocument.createElement("div");Object.assign(a.style,{position:"relative",flex:"1",minHeight:"0",overflow:"hidden",display:"flex",flexDirection:"column"}),o.appendChild(a),i&&a.appendChild(i),E.appendChild(o);const l=Ke(a,e,{viewOptions:e.viewOptions?{...d,...e.viewOptions}:d,toolbarControls:"full",showTooltip:!0,padding:Y,legendPosition:ne,fallbackFormat:he,statsSummary:e.statsSummary,onSaveImage:p.onSaveImage,onSaveText:p.onSaveText,onClick:e.onClick,onSelect:e.onSelect,onExpand:()=>ke(t,e),showMetadataBadge:!1});return l.setViewControlsVisible(!1),l.setSummaryVisible(!1),r.onclick=()=>ke(t,e),{card:o,ctrl:l,canvasWrapper:a,expandBtn:r}}function pn(e){const t=Z[e];if(!t)return;const n=[...R.values()].find(o=>o.cardIndex===e);n?(t.innerHTML=pe.minimize,t.title="Reattach to gallery",t.setAttribute("aria-label","Reattach to gallery"),t.onclick=()=>mn(n.id)):(t.innerHTML=pe.expand,t.title="Open full view",t.setAttribute("aria-label","Open full view"),t.onclick=()=>ke(e,M[e]))}function N(e){gn(),le()?.remove(),se(null),Re(),M=[];for(const i of v)i&&i.destroy();v=[],q=[],Z=[],be=0,E.innerHTML="",bt=e.length,yt(e.map(i=>typeof i=="function"?null:i));const t=[];for(let i=0;i<e.length;i++){const r=e[i];if(typeof r=="function"){const a=m.ownerDocument.createElement("div");a.className="wmap-gallery-card",Object.assign(a.style,{background:g.menuBg,border:`1px solid ${g.menuBorder}`,borderRadius:"10px",aspectRatio:"1",display:"flex",alignItems:"center",justifyContent:"center"});const l=m.ownerDocument.createElement("span");l.textContent="\u2026",Object.assign(l.style,{color:g.label,fontSize:"18px"}),a.appendChild(l),E.appendChild(a),M.push(null),v.push(null),q.push(null),Z.push(null),t.push({index:i,factory:r,placeholder:a}),be++}else{const{ctrl:a,canvasWrapper:l,expandBtn:f}=je(r,i,e.length);M.push(r),v.push(a),q.push(l),Z.push(f)}}M.flatMap(i=>i?[...i.hbinDefs??[],...i.sbinDefs??[]]:[]).some(i=>i.color)&&!p.viewOptions?.colorScheme&&(d={...d,colorScheme:"custom"}),Me();const o=++Oe;let s=0;function c(){if(o!==Oe)return;if(s>=t.length){if(ue.has(d.plotMode)){const H=d.plotMode;N(ce(H))}return}const{index:i,factory:r,placeholder:a}=t[s++],l=r();M[i]=l,x[i]=l,yt([l]);const{card:f,ctrl:b,canvasWrapper:h,expandBtn:k}=je(l,i,e.length);v[i]=b,q[i]=h,Z[i]=k,be--,a.replaceWith(f),Me(),!u&&!Q?.placement&&l.statsSummary?.findings.length?(O||(ie="wafers"),u=qe("right",m.ownerDocument),u.style.maxHeight="calc(100vh - 80px)",u.style.position="sticky",u.style.top="8px",u.style.flexDirection="column",u.style.display="none",(Q?.placement??"right")==="left"?F.insertBefore(u,E):F.appendChild(u),I(),T||(T=V("findings","Summary panel",()=>{if(!u)return;const $=u.style.display!=="none";$||I(),u.style.display=$?"none":"flex",ae(T,!$),X()}),B.appendChild(P()),B.appendChild(T)),X()):u&&u.style.display!=="none"&&I(),X(),setTimeout(c,0)}t.length>0&&setTimeout(c,0)}if(ue.has(d.plotMode)&&x.length>0){const e=$e(d.plotMode);d={...d,...e},N(ce(d.plotMode))}else N(D);const Ct=new ResizeObserver(()=>{L==null&&Se()});Ct.observe(E),u&&I();function un(e){const t=q[e];if(!t)return;t.innerHTML="",Object.assign(t.style,{alignItems:"center",justifyContent:"center"});const n=m.ownerDocument.createElement("span");n.textContent="Detached \u2014 open in its own window",Object.assign(n.style,{color:g.label,fontSize:"12px",textAlign:"center",padding:"0 12px"}),t.appendChild(n)}function ke(e,t){for(const i of R.values())if(i.cardIndex===e)return;const n=t.label??"Wafer map",o=$t++,s=v[e]?.getOptions(),c=On(n);if(c){const i=c.document;i.title=n,Object.assign(i.documentElement.style,{height:"100%"}),Object.assign(i.body.style,{margin:"0",height:"100vh",overflow:"hidden",display:"flex",flexDirection:"column",fontFamily:'system-ui, -apple-system, "Segoe UI", sans-serif'}),Ln(m,i.documentElement);const r=In(m,i.documentElement,()=>H.setOptions({})),a=i.createElement("div");a.dataset.wmapWindowBanner="1",a.textContent=n,Object.assign(a.style,{display:"none",padding:"6px 12px",fontSize:"12px",fontWeight:"700",background:g.warnBg,color:g.warnText,borderBottom:`1px solid ${g.warnBorder}`,flexShrink:"0"}),i.body.appendChild(a);const l=i.createElement("div");Object.assign(l.style,{flex:"1",minHeight:"0",display:"flex",flexDirection:"column"}),i.body.appendChild(l);const{wrap:f,metaPanel:b}=wt(i,n,t.wafer.metadata??void 0),h=i.createElement("div");Object.assign(h.style,{display:"flex",alignItems:"center",padding:"8px 10px 6px",borderBottom:`1px solid ${g.menuBorder}`,flexShrink:"0",gap:"6px"}),h.appendChild(f),l.appendChild(h);const k=i.createElement("div");Object.assign(k.style,{position:"relative",flex:"1",minHeight:"0",overflow:"hidden",display:"flex",flexDirection:"column"}),b&&k.appendChild(b),l.appendChild(k);const H=ze(k,t,void 0,s),$=setInterval(()=>{c.closed&&De(o)},400);c.addEventListener("pagehide",()=>De(o)),R.set(o,{id:o,ctrl:H,cardIndex:e,label:n,closePollId:$,stopThemeSync:r,close:()=>{c.closed||c.close()},setTitle:K=>{i.title=K,a.textContent=K,a.style.display="block"}})}else{const i=Tn({title:n,onClose:()=>De(o),anchor:m});i.contentWrap.style.flexDirection="column",vt(i,n,t.wafer.metadata??void 0);const r=ze(i.contentWrap,t,void 0,s);R.set(o,{id:o,ctrl:r,cardIndex:e,label:n,closePollId:null,close:()=>i.close(),setTitle:a=>{const l=i.box.querySelector("[data-wmap-window-title]");l&&(l.textContent=a,l.title=a)}})}v[e]?.destroy(),v[e]=null,un(e),pn(e)}function ze(e,t,n,o){const s=t.viewOptions?{...d,...t.viewOptions}:d,c=o?{...s,...o}:s,i=n!==void 0?{...c,plotMode:"value",activeTest:n}:c,r=Ke(e,t,{viewOptions:i,toolbarControls:"full",showTooltip:!0,padding:Y,legendPosition:ne,fallbackFormat:he,statsSummary:t.statsSummary,onSaveImage:p.onSaveImage,onSaveText:p.onSaveText,onClick:t.onClick,onSelect:t.onSelect,showExpandButton:!1,showMetadataBadge:!1});return r.setViewControlsVisible(!0),r.setSummaryVisible(!0),r.setExpandVisible(!1),r}function De(e){const t=R.get(e);if(!t)return;R.delete(e),t.closePollId!=null&&clearInterval(t.closePollId),t.stopThemeSync?.();const n=t.ctrl.getOptions();if(t.ctrl.destroy(),t.cardIndex===null)return;const o=t.cardIndex,s=M[o];if(!s)return;const c={...s,viewOptions:n};M[o]=c;const{card:i,ctrl:r,canvasWrapper:a,expandBtn:l}=je(c,o,M.length);q[o]?.parentElement?.replaceWith(i),v[o]=r,q[o]=a,Z[o]=l}function mn(e){const t=R.get(e);t&&(t.close(),De(e))}function gn(){for(const e of R.values())e.cardIndex!==null&&(e.cardIndex=null,e.setTitle(`${e.label} \u2014 unlinked from gallery`))}function hn(){const e=[...E.querySelectorAll("canvas")];if(!e.length)return;const t=e.length,n=Math.ceil(Math.sqrt(t)),o=Math.ceil(t/n),s=e[0].width,c=e[0].height,i=8,r=window.devicePixelRatio||1,a=Math.round(26*r),l=Math.round(12*r),f=m.ownerDocument.createElement("canvas");f.width=n*s+(n-1)*i,f.height=o*(c+a)+(o-1)*i;const b=f.getContext("2d"),h=Sn(E);b.fillStyle=h.background,b.fillRect(0,0,f.width,f.height),e.forEach((k,H)=>{const $=H%n,K=Math.floor(H/n),fe=$*(s+i),y=K*(c+a+i),W=k.closest(".wmap-gallery-card")?.querySelector("span")?.textContent??"";b.fillStyle=h.surface,b.fillRect(fe,y,s,a),b.fillStyle=h.text,b.font=`700 ${l}px system-ui, sans-serif`,b.textAlign="left",b.textBaseline="middle",b.fillText(W,fe+Math.round(10*r),y+a/2,s-Math.round(20*r)),b.drawImage(k,fe,y+a)}),f.toBlob(k=>{k&&jn(k,te,p.onSaveImage)})}return{setItems(e){x=e.map(n=>typeof n=="function"?null:n);const t=d.plotMode;if(ue.has(t))if(e.some(o=>typeof o=="function"))N(e);else{const o=$e(t);d={...d,...o},N(ce(t))}else N(e)},setOptions(e){C(e,{fireCallback:!1})},getOptions(){return{...d}},setFallbackFormat(e){he=e;for(const t of v)t&&t.setFallbackFormat(e)},setLotStatsSummary(e){O=e,ft(),u&&I(),X()},setColumns(e){xt(e)},openUserGuide:pt,destroy(){Oe++;for(const e of[...R.values()])e.closePollId!=null&&clearInterval(e.closePollId),e.close(),e.ctrl.destroy();R.clear();for(const e of v)e&&e.destroy();v=[],le()?.remove(),Ct.disconnect(),m.ownerDocument.removeEventListener("click",xe,!0),window.removeEventListener("blur",Je),Ht(),Dt(),B.remove(),G.remove(),F.remove(),u?.remove(),de?.destroy()}}}
|
|
20
|
+
</html>`;ro(i)}),m.appendChild(n)}if(e.length===0){const n=f.ownerDocument.createElement("div");Object.assign(n.style,{color:g.icon,fontSize:"11px",padding:"4px 0"}),n.textContent="No findings on any wafer.",m.appendChild(n)}else for(const{index:n,item:o,unusualCount:s,notableCount:c,totalCount:i}of e){const d=s?"unusual":c?"notable":"info",l=s+c||i,a=f.ownerDocument.createElement("button");a.type="button",Object.assign(a.style,{display:"flex",alignItems:"center",justifyContent:"space-between",width:"100%",padding:"5px 8px",marginBottom:"4px",border:"none",borderLeft:`3px solid ${Tt(d)}`,borderRadius:"3px",background:g.bgHover,cursor:"pointer",fontSize:"11px",textAlign:"left",boxSizing:"border-box"}),a.addEventListener("mouseover",()=>{a.style.background=g.bgActive}),a.addEventListener("mouseout",()=>{a.style.background=g.bgHover});const u=f.ownerDocument.createElement("span");u.textContent=o.label??`W${n+1}`,Object.assign(u.style,{color:g.iconHover,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"});const h=f.ownerDocument.createElement("span");h.textContent=String(l),a.setAttribute("aria-label",`${o.label??`W${n+1}`} \u2014 ${l} finding${l===1?"":"s"}${s?`, ${s} unusual`:""} \u2014 view wafer`),Object.assign(h.style,{marginLeft:"6px",flexShrink:"0",background:Tt(d),color:"#fff",borderRadius:"8px",padding:"1px 5px",fontSize:"10px",fontWeight:"600"}),a.appendChild(u),a.appendChild(h),a.addEventListener("click",()=>Oe(n,o)),m.appendChild(a)}const t=f.ownerDocument.createElement("div");t.style.height="12px",m.appendChild(t)}function R(){if(m)if(le==="lot"&&E){const e=We(w.flatMap(n=>n?.hbinDefs??[])),t=We(w.flatMap(n=>n?.sbinDefs??[]));so(m,{lotSummary:E,items:w,hbinDefs:e.length?e:void 0,sbinDefs:t.length?t:void 0,testDefs:w.find(n=>n?.testDefs?.length)?.testDefs,passBins:Je,ringCount:r.ringCount,colorScheme:r.colorScheme,fallbackFormat:we,activeFindingId:ae,warnings:p.warnings?.display??!0?_:[],findingsFilter:qt,onFindingsFilterChange:R,onSaveText:p.onSaveText,onFindingClick:(n,o)=>{ae===n.id?Ae():Zt(n,o),R()},onWaferClick:n=>{Ie([n])},dieListOptions:p.dieList}),Ce()&&m.insertBefore(at(),m.firstChild)}else Yt()}function lt(e){return[e.variable.kind,e.variable.index??"",e.variable.bin??"",e.comparison.family,e.comparison.left,e.effect.direction].join("|")}function Ae(){ae=null,$e(),Pe(),C({highlightBin:void 0},{fireCallback:!1})}function Zt(e,t){if(ae===e.id){Ae();return}ae=e.id,t.style.background=g.bgActive,t.style.fontWeight="600";const{kind:n,index:o}=e.variable;n==="test"?C({plotMode:"value",activeTest:o??0,highlightBin:void 0},{fireCallback:!1}):n==="softBin"?C({plotMode:"softBin",highlightBin:void 0},{fireCallback:!1}):C({plotMode:"hardBin",highlightBin:void 0},{fireCallback:!1}),$e(),Pe();const s=e.highlight;if(s.kind==="wafer"){Ie(s.waferIndices);const c=lt(e);for(const i of s.waferIndices){const a=k[i]?.statsSummary?.findings.find(u=>lt(u)===c)?.highlight?.dieKeys;a?.length&&Fe(a,[i])}}else s.kind==="bin"?s.dieKeys?.length&&Fe(s.dieKeys):(s.kind==="region"||s.kind==="dies")&&s.dieKeys?.length&&Fe(s.dieKeys)}function X(){if(!O)return;const e=!!m;O.style.display=(E||Ce())&&e&&!je?"flex":"none";const t=m?m.style.display!=="none":!1;(E?.hasNotableFindings||w.some(o=>o?.statsSummary?.hasNotableFindings))&&!t?O.style.color=g.findingIndicator:O.dataset.active||(O.style.color=g.icon)}const T=f.ownerDocument.createElement("div");T.dataset.wmapToolbar="gallery",Object.assign(T.style,{display:"inline-flex",flexDirection:"row",alignItems:"center",gap:"0",background:g.menuBg,border:`1px solid ${g.menuBorder}`,borderRadius:"6px",padding:"3px 4px",marginBottom:"10px",boxShadow:"0 1px 4px rgba(0,0,0,0.10)",flexWrap:"wrap",minWidth:"0",overflowX:"auto"});const st=()=>{const e=re();e&&(e.remove(),de(null)),be(j,!1)},j=N("mode","Plot mode",()=>{if(re()){st();return}const e=w.flatMap(b=>b?.dies??[]),t=w.find(b=>b?.testDefs?.length)?.testDefs,{testEntries:n,binEntries:o,stackedEntries:s}=Un(e,t,{includeStacked:!0}),c=r.plotMode??"hardBin",i=r.activeTest??0;function d(b){return b.plotMode!==c?!1:b.plotMode==="value"?i===(b.activeTest??0):b.plotMode==="metadata"?r.activeMetadataKey===b.activeMetadataKey:!0}function l(b,S){b.activeTest!==void 0?C({plotMode:"value",activeTest:b.activeTest,activeMetadataKey:void 0,logScale:b.logScale}):b.activeMetadataKey!==void 0?C({plotMode:b.plotMode,activeTest:void 0,activeMetadataKey:b.activeMetadataKey,passFailDisplay:"off"}):C({plotMode:b.plotMode,activeTest:void 0,activeMetadataKey:void 0,passFailDisplay:"off"}),S.remove(),de(null),be(j,!1)}const a=new Set,u=w.flatMap(b=>b?.metadataFields??[]).filter(b=>!a.has(b.key)&&a.add(b.key)).filter(b=>Qn(e,b.key)).map(Yn),h=In(j.getBoundingClientRect(),n,o,s,d,l,{makeMenuRow:Ut,makeMenuSection:Qt},c,j.ownerDocument.defaultView??window,u);It(j).appendChild(h),de(h),be(j,!0),$t(h,j,st)});be(j,!1);const Jt=()=>k.flatMap(e=>e?[...e.hbinDefs??[],...e.sbinDefs??[]]:[]).some(e=>e.color),{btn:en,sync:rt}=zn(J,()=>r.plotMode??"hardBin",()=>r.colorScheme??"default",Jt,e=>C({colorScheme:e}),{get:()=>r.markFailingDies??!1,set:e=>C({markFailingDies:e})});rt();const tn=D.some(e=>typeof e!="function"&&(e.reticles?.length??0)>0);function He(){const e=w.find(n=>n?.testDefs?.length)?.testDefs,{testNumber:t}=Dn(r.activeTest??0,e);return{testNumber:t,td:Bn(e,t)}}function dt(){if((r.plotMode??"hardBin")!=="value")return!1;const{td:e}=He();return e!==void 0&&(e.limitLow!==void 0||e.limitHigh!==void 0)}function ce(){if((r.plotMode??"hardBin")!=="value")return!1;const{td:e}=He();return e!==void 0&&!At(e)}function nn(){if((r.plotMode??"hardBin")!=="value")return!1;const{testNumber:e,td:t}=He();return w.some(n=>n?.dies?.some(o=>to(o,e,t)!==void 0))}const on=_n(J,()=>[{label:"Ring boundaries",active:!!r.showRingBoundaries,onClick:()=>C({showRingBoundaries:!r.showRingBoundaries})},{label:"Quadrant lines",active:!!r.showQuadrantBoundaries,onClick:()=>C({showQuadrantBoundaries:!r.showQuadrantBoundaries})},{label:"Die labels",active:!!r.showDieLabels,onClick:()=>C({showDieLabels:!r.showDieLabels})},{label:"Reticle grid",active:!!r.showReticle,enabled:tn,onClick:()=>C({showReticle:!r.showReticle})},{label:"XY indicator",active:!!r.showXYIndicator,onClick:()=>C({showXYIndicator:!r.showXYIndicator})},...qn({functionalActive:ce(),hasLimits:dt()&&!ce(),hasRecorded:nn()&&!ce(),display:Ue(r)},e=>C({passFailDisplay:e}))],()=>!!(r.showRingBoundaries||r.showQuadrantBoundaries||r.showDieLabels||r.showReticle||r.showXYIndicator||Ue(r)!=="off")),{btn:an,sync:ct}=Nn(J,()=>({plotMode:r.plotMode,legendPosition:oe}),e=>{oe=e;for(const t of v)t&&t.setOptions({legendPosition:oe})},{get:()=>xe,set:e=>{xe=e,et()},blockedReason:ie});ct();const ln=[{value:"mean",label:"Mean"},{value:"median",label:"Median"},{value:"stddev",label:"Std Dev"},{value:"min",label:"Min"},{value:"max",label:"Max"},{value:"count",label:"Count"}],ut=ot("aggr","Aggregation method",()=>ln,()=>r.aggregationMethod??"mean",e=>C({aggregationMethod:e}));function ft(){const e=r.plotMode==="stackedValues";ut.style.display=e?"":"none"}ft();const{btn:sn,sync:pt}=Vn(J,()=>({...r,functionalActive:ce()}),e=>C(e));pt();const Me=N("specRange","Colorbar range: spec limits",()=>{const e=r.colorbarRangeMode==="data"?"spec":"data";C({colorbarRangeMode:e})});function mt(){const e=(r.plotMode??"hardBin")==="value"&&dt()&&Ue(r)==="off"&&!ce();Me.style.display=e?"":"none";const t=(r.colorbarRangeMode??"spec")==="spec";se(Me,t),Me.ariaLabel=t?"Colorbar range: spec limits (click for data range)":"Colorbar range: data range (click for spec limits)"}mt();const rn=Gn(J,()=>r,e=>C(e)),dn=N("downloadAll","Download gallery PNG",Sn),cn=ot("columns","Columns",()=>[{value:"auto",label:"Auto"},{value:"1",label:"1 column"},{value:"2",label:"2 columns"},{value:"3",label:"3 columns"},{value:"4",label:"4 columns"},{value:"5",label:"5 columns"}],()=>W!=null?String(W):"auto",e=>Mt(e==="auto"?void 0:Number(e))),M=f.ownerDocument.createElement("div");Object.assign(M.style,{display:"inline-flex",alignItems:"center",gap:"0"}),T.appendChild(M),Vt&&M.appendChild(j),M.appendChild(en),M.appendChild(ut),M.appendChild(sn),M.appendChild(Me),M.appendChild($()),M.appendChild(on),M.appendChild($()),M.appendChild(an),M.appendChild($()),M.appendChild(rn),M.appendChild($()),M.appendChild(cn),M.appendChild($()),M.appendChild(dn),(E||Ce())&&(O=N("findings","Summary panel",()=>{if(!m)return;const e=m.style.display!=="none";e||R(),m.style.display=e?"none":"flex",se(O,!e),X()}),T.appendChild($()),T.appendChild(O));let P=null,ke=null,_=[],gt=!1;function ht(){const e=no({lotStatsSummary:E,result:{warnings:w.flatMap(n=>n?.warnings??[])}}),t=e.length!==_.length||e.some((n,o)=>n.code!==_[o]?.code||n.message!==_[o]?.message);_=e,(t||!gt)&&(gt=!0,p.warnings?.onWarning?.(e)),un()}function un(){if(!P||!ke)return;const e=_.length,t=e>0;if(P.style.display=t?"flex":"none",ke.style.display=t?"":"none",!t)return;const n=io(_[0]),o=`${e} data ${e===1?"warning":"warnings"}`;P.style.color=n==="error"?g.errText:g.warnText,P.ariaLabel=n==="error"?`${o} \u2014 wafers in this lot may be positionally wrong`:o}(p.warnings?.display??!0)&&(ke=$(),P=N("warning","Data warnings",()=>{const e=re();if(Se(new MouseEvent("click")),e)return;const t=oo(P.getBoundingClientRect(),_,P.ownerDocument.defaultView??window);It(f).appendChild(t),de(t),$t(t,P,()=>Se(new MouseEvent("click")))}),be(P,!1),T.appendChild(ke),T.appendChild(P)),ht();let U=null;Ze&&(U=N("analysis","Insights",()=>{const e=ee?.style.display!=="none";yt(!e)}),U.dataset.wmapInsightsBtn="1",T.appendChild($()),T.appendChild(U));function bt(){import("./userGuideHtml.js").then(e=>jn({buildWaferMap:eo,renderWaferMap:Qe,renderWaferGallery,analyzeWaferMap:Le},e.USER_GUIDE_HTML,_t,f))}Nt&&(T.appendChild($()),T.appendChild(N("help","User guide",()=>bt())));const G=f.ownerDocument.createElement("div");G.dataset.wmapGalleryLegend="1",Object.assign(G.style,{display:"flex",flexDirection:"column",gap:"6px",background:g.menuBg,border:`1px solid ${g.menuBorder}`,borderRadius:"6px",padding:"6px 10px",marginBottom:"10px",boxShadow:"0 1px 4px rgba(0,0,0,0.10)",fontSize:"12px",lineHeight:"1",boxSizing:"border-box",width:"100%",minWidth:"0"});const F=f.ownerDocument.createElement("div");Object.assign(F.style,{display:"flex",flexDirection:"row",gap:"12px",alignItems:"flex-start"});let ue=null,ee=null;Ze&&(ue=po({getItems:()=>w,getLotStats:()=>E,getColorSchemeName:()=>r.colorScheme??"default",passBins:Je,getRingCount:()=>r.ringCount??4,defaultView:p.insights?.defaultView,backTab:{label:"Gallery",onBack:()=>yt(!1)},showMetadataStrip:!1,onSaveImage:p.onSaveImage,onSaveText:p.onSaveText,ownerDocument:f.ownerDocument,openWafer:(e,t,n)=>{const o=w[e];if(!o)return;let s=null;const c=Fn({title:t,onClose:()=>s?.destroy(),anchor:f});Bt(c,t,o.wafer.metadata??void 0),s=Ge(c.contentWrap,o,n)}}),ee=ue.el);let je=!1;function yt(e){!ue||!ee||(je=e,ee.style.display=e?"flex":"none",F.style.display=e?"none":"flex",M.style.display=e?"none":"inline-flex",U&&(se(U,e),U.innerHTML=e?ge.wafer:ge.analysis,U.ariaLabel=e?"Back to gallery view":"Insights"),X(),Ee(),e&&ue.render())}const fn=4,ze=240,wt=480,pn=720,mn=1.25,xt=p.maxSize;let z=xt??wt;function vt(e){const t=Q*2+110+2;let n=null;for(const o of e){if(o==null||!o.dies?.length)continue;const s=o.dies[0].width;if(!(s>0))continue;const c=o.wafer.radius*2*(fn/s),i=Math.ceil(c+t);(n==null||i>n)&&(n=i)}return n}function gn(e){const t=vt(e);return t==null?ze:Math.min(z,Math.max(ze,t))}function hn(e){if(xt!=null)return!1;const t=vt(e);if(t==null)return!1;const n=Math.min(pn,Math.max(wt,t));return n<=z?!1:(z=n,!0)}function bn(){for(const e of Array.from(B.children))e.classList.contains("wmap-gallery-card")&&(e.style.maxWidth=`${z}px`,e.style.maxHeight=`${z}px`)}let De=ze,Ct=0;function St(e){const t=hn(e);if(t&&bn(),W!=null){t&&Be();return}const n=gn(e);n>De&&(De=n),Be()}function Mt(e){W=e,Be()}function Ve(e){return`repeat(${e}, minmax(0, ${z}px))`}function kt(e){B.style.gridTemplateColumns!==e&&(B.style.gridTemplateColumns=e)}function Be(){if(W!=null){kt(Ve(W));return}const e=Math.max(1,Ct),t=12,n=B.clientWidth||0,o=c=>(n-t*(c-1))/c;let s=Math.max(1,Math.ceil(Math.sqrt(e)));if(n>0){const c=Math.min(z,De*mn),i=d=>{let l=0;for(;l<e&&o(l+1)>=d;)l++;return l};s=i(c)||i(De)||1}kt(Ve(s))}const B=f.ownerDocument.createElement("div");if(Object.assign(B.style,{flex:"1 1 0",minWidth:"0",display:"grid",gridTemplateColumns:Ve(1),gap:"12px",justifyContent:"start",alignContent:"start",isolation:"isolate"}),le=E?"lot":"wafers",Y?.placement){const e=Y.placement;m=Ye(e,f.ownerDocument),m.style.maxHeight="calc(100vh - 80px)",m.style.position="sticky",m.style.top="8px",m.style.display="flex",m.style.flexDirection="column"}else if(E||Ce()){const e=!!Y?.defaultOpen;m=Ye("right",f.ownerDocument),m.style.maxHeight="calc(100vh - 80px)",m.style.position="sticky",m.style.top="8px",m.style.flexDirection="column",m.style.display=e?"flex":"none",R()}X(),m?.style.display!=="none"&&O&&se(O,!0),(Y?.placement??"right")==="left"?(m&&F.appendChild(m),F.appendChild(B)):(F.appendChild(B),m&&F.appendChild(m));const fe=f.ownerDocument.createElement("div");Object.assign(fe.style,{position:"sticky",top:"0",zIndex:"1",background:g.menuBg}),fe.appendChild(T),fe.appendChild(G),f.appendChild(fe),f.appendChild(F),ee&&f.appendChild(ee);function Ee(){G.innerHTML="";const e=r.plotMode??"hardBin",t=!je&&Lt.has(e),n=k.filter(y=>y!=null),o=n.find(y=>y.isLotStack),s=lo(n.map(y=>({metadata:y.wafer.metadata??void 0})),o?{lotSize:o.lotSize??n.length,aggrMethod:o.aggrMethod}:void 0),c=e==="metadata",i=r.activeMetadataKey,d=new Set;if(t&&!c)for(const y of n)for(const L of y.dies){if(L.partial)continue;const x=e==="softBin"?L.sbin:L.hbin;x!=null&&d.add(x)}const l=t&&!c?[...d].sort((y,L)=>y-L):[],a=new Set;if(t&&c&&i)for(const y of n)for(const L of y.dies){if(L.partial)continue;const x=L.metadata?.[i];x!=null&&(typeof x=="string"||typeof x=="number"||typeof x=="boolean")&&a.add(String(x))}const u=t&&c?[...a].sort(ao):[];if(!s&&!l.length&&!u.length){G.style.display="none";return}if(G.style.display="flex",s&&G.appendChild(s),!l.length&&!u.length)return;const h=f.ownerDocument.createElement("div");Object.assign(h.style,{display:"flex",flexWrap:"wrap",alignItems:"center",gap:"6px 14px"}),s&&Object.assign(h.style,{borderTop:`1px solid ${g.separator}`,paddingTop:"6px"}),G.appendChild(h);const b=En(r.colorScheme),S=r.highlightBin;if(c){const y=r.highlightMetadataValue,L=k.flatMap(x=>x?.metadataFields??[]).find(x=>x.key===i);u.forEach((x,Ke)=>{const qe=y===x,Ot=L?.values?.find(Xe=>Xe.value===x),Mn=Ot?.color??On(Ke);zt(h,{color:Mn,isActive:qe,label:Ot?.label??x,onClick:()=>{const Xe=r.highlightMetadataValue===x?void 0:x;C({highlightMetadataValue:Xe})}})});return}const A=e==="softBin"?k.flatMap(y=>y?.sbinDefs??[]):k.flatMap(y=>y?.hbinDefs??[]),H=new Set,K=[];for(const y of A)H.has(y.bin)||(H.add(y.bin),K.push(y));const me=K.length>0?new Map(K.map(y=>[y.bin,y])):null;for(const y of l){const L=S===y,x=me?.get(y),Ke=(r.colorScheme==="custom"?x?.color:void 0)??b.forBin(y);zt(h,{color:Ke,isActive:L,label:x?.name?`${y} \xB7 ${x.name}`:`Bin ${y}`,onClick:()=>{const qe=r.highlightBin===y?void 0:y;C({highlightBin:qe})}})}}function pe(e){const t=w.filter(d=>d!==null);if(!t.length)return[];const n=t.map(d=>d.dies.filter(go)),o=t[0].wafer,s=t.length,c=o.metadata?{...o,metadata:(({wafer:d,waferId:l,...a})=>a)(o.metadata)}:o;function i(d,l){return{...d,stats:{...d.stats,isLotStack:!0,aggregationMethod:l,lotSize:s}}}if(e==="stackedValues"){const d=t.find(u=>u.testDefs?.length)?.testDefs;let l=d?.filter(At);if(d?.length||(l=kn(t.flatMap(h=>h.dies)).map(h=>({testNumber:h,name:`Test ${h}`}))),!l?.length)return[];const a=r.aggregationMethod??"mean";return l.map(u=>{const h=Zn(n,a,u.testNumber),b={testNumber:0,name:u.name,unit:u.unit};return{wafer:c,dies:h,testDefs:[b],label:`${u.name} \xB7 ${a}`,isLotStack:!0,aggrMethod:a,lotSize:s,statsSummary:i(Le({wafer:c,dies:h,testDefs:[b]},{testNumbers:[0]}),a)}})}if(e==="stackedBins"){let d=We(t.flatMap(l=>l.hbinDefs??[]));return(!d||d.length===0)&&(d=[...new Set(t.flatMap(a=>a.dies.map(u=>u.hbin).filter(u=>u!=null)))].sort((a,u)=>a-u).map(a=>({bin:a,name:`Bin ${a}`}))),d.map(l=>{const a=Ft(n,l.bin,"hard"),u=[{bin:l.bin,name:l.name}];return{wafer:c,dies:a,hbinDefs:u,label:`${l.bin} \xB7 ${l.name}`,isLotStack:!0,aggrMethod:"countBin",lotSize:s,statsSummary:i(Le({wafer:c,dies:a,hbinDefs:u}),"countBin")}})}if(e==="stackedSoftBins"){let d=We(t.flatMap(l=>l.sbinDefs??[]));return(!d||d.length===0)&&(d=[...new Set(t.flatMap(a=>a.dies.map(u=>u.sbin).filter(u=>u!=null)))].sort((a,u)=>a-u).map(a=>({bin:a,name:`Bin ${a}`}))),d.map(l=>{const a=Ft(n,l.bin,"soft"),u=[{bin:l.bin,name:l.name}];return{wafer:c,dies:a,sbinDefs:u,label:`${l.bin} \xB7 ${l.name}`,isLotStack:!0,aggrMethod:"countBin",lotSize:s,statsSummary:i(Le({wafer:c,dies:a,sbinDefs:u}),"countBin")}})}return t}function Ne(e){const t=w.length;return e==="stackedBins"||e==="stackedSoftBins"?{valueRange:[0,t],lotSize:t}:e==="stackedValues"?{aggregationMethod:r.aggregationMethod??"mean",valueRange:void 0,lotSize:void 0}:{}}const yn=new Set(["default","accessible","custom"]);function C(e,{fireCallback:t=!0}={}){const n=r.plotMode,o=ie()!==null;r={...r,...e};const s=r.plotMode,c=he.has(s),i=n!==void 0&&he.has(n),d=ve>0;if(e.plotMode!==void 0&&e.plotMode!==n&&(s==="hardBin"||s==="softBin")&&!yn.has(r.colorScheme??"")&&(r={...r,colorScheme:"default"}),e.plotMode!==void 0)if(c){const a=Ne(s);if(r={...r,...a},d)for(const u of v)u&&u.setOptions(e);else V(pe(s))}else if(i){const{valueRange:a,lotSize:u,aggregationMethod:h,...b}=r;if(r=b,d)for(const S of v)S&&S.setOptions(e);else V(w.filter(S=>S!==null))}else for(const a of v)a&&a.setOptions(e);else if(e.aggregationMethod!==void 0&&s==="stackedValues")if(d)for(const a of v)a&&a.setOptions(e);else V(pe("stackedValues"));else for(const a of v)a&&a.setOptions(e);ie()!==null!==o&&et(),Ee(),ft(),ct(),rt();const l=e.plotMode!==void 0&&e.plotMode!==n;if((e.colorScheme!==void 0||l)&&R(),pt(),mt(),t){const a=Object.keys(e);p.onViewOptionsChange?.(r,a,Jn(a))}}function Dt(e,t,n){const o=e.createElement("div");Object.assign(o.style,{display:"flex",alignItems:"center",gap:"4px",flex:"1",minWidth:"0"});const s=e.createElement("span");s.textContent=t,Object.assign(s.style,{fontWeight:"700",fontSize:"13px",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}),o.appendChild(s);const c=jt(n??{});let i=null;if(c.length>0){const d=e.createElement("span");Object.assign(d.style,{fontSize:"12px",lineHeight:"1",color:g.label,flexShrink:"0"}),d.textContent="\u25BE",o.appendChild(d),Object.assign(o.style,{cursor:"pointer"}),i=e.createElement("div"),i.dataset.wmapCardMetaPanel="1",Object.assign(i.style,{position:"absolute",top:"0",left:"0",right:"0",zIndex:Wt,background:g.menuBg,borderBottom:`1px solid ${g.menuBorder}`,boxShadow:"0 2px 6px rgba(0,0,0,0.15)",padding:"8px 10px",fontSize:"11px",display:"none"});const l=Ht(n??{});l&&i.appendChild(l),o.setAttribute("aria-expanded","false"),o.setAttribute("aria-label",`Wafer info for ${t||"this card"}. Click to expand.`),Pt(o,a=>{d.textContent=a?"\u25B4":"\u25BE",o.setAttribute("aria-expanded",String(a)),i&&(i.style.display=a?"block":"none")})}return{wrap:o,metaPanel:i}}function Bt(e,t,n){const o=e.box.querySelector("[data-wmap-window-title]"),s=jt(n??{});if(!o||s.length===0)return;const c=o.parentElement,i=f.ownerDocument.createElement("div");Object.assign(i.style,{display:"flex",alignItems:"center",gap:"4px",flex:"1",minWidth:"0",cursor:"pointer"}),c?.insertBefore(i,o),i.appendChild(o);const d=f.ownerDocument.createElement("span");Object.assign(d.style,{fontSize:"12px",lineHeight:"1",color:g.label,flexShrink:"0"}),d.textContent="\u25BE",i.appendChild(d);const l=f.ownerDocument.createElement("div");l.dataset.wmapCardMetaPanel="1",Object.assign(l.style,{position:"absolute",top:"0",left:"0",right:"0",zIndex:Wt,background:g.menuBg,borderBottom:`1px solid ${g.menuBorder}`,boxShadow:"0 2px 6px rgba(0,0,0,0.15)",padding:"8px 10px",fontSize:"11px",display:"none"});const a=Ht(n??{});a&&l.appendChild(a),e.contentWrap.style.position="relative",e.contentWrap.appendChild(l),i.setAttribute("aria-expanded","false"),i.setAttribute("aria-label",`Wafer info for ${t}. Click to expand.`),Pt(i,u=>{d.textContent=u?"\u25B4":"\u25BE",i.setAttribute("aria-expanded",String(u)),l.style.display=u?"block":"none"})}function _e(e,t,n){const o=f.ownerDocument.createElement("div");o.className="wmap-gallery-card",Object.assign(o.style,{background:g.menuBg,border:`1px solid ${g.menuBorder}`,borderRadius:"10px",overflow:"hidden",display:"flex",flexDirection:"column",position:"relative",aspectRatio:"1",maxWidth:`${z}px`,maxHeight:`${z}px`});const s=f.ownerDocument.createElement("div");Object.assign(s.style,{display:"flex",alignItems:"center",padding:"8px 10px 6px",borderBottom:`1px solid ${g.menuBorder}`,flexShrink:"0",gap:"6px"});const{wrap:c,metaPanel:i}=Dt(document,e.label??"",e.wafer.metadata??void 0);s.appendChild(c);const d=f.ownerDocument.createElement("button");d.dataset.wmapExpandBtn="1",d.title="Open full view",d.innerHTML=ge.expand,Object.assign(d.style,{display:"flex",alignItems:"center",justifyContent:"center",border:`1px solid ${g.menuBorder}`,borderRadius:"4px",background:g.panelBg,color:g.label,padding:"2px",cursor:"pointer",flexShrink:"0",width:"22px",height:"22px"}),s.appendChild(d),o.appendChild(s);const l=f.ownerDocument.createElement("div");Object.assign(l.style,{position:"relative",flex:"1",minHeight:"0",overflow:"hidden",display:"flex",flexDirection:"column"}),o.appendChild(l),i&&l.appendChild(i),B.appendChild(o);const a=xe||ie()!==null,u=e.viewOptions?{...r,...e.viewOptions}:r,h=Qe(l,e,{viewOptions:{...u,showLegend:a},toolbarControls:"full",showTooltip:!0,padding:Q,legendPosition:oe,fallbackFormat:we,statsSummary:e.statsSummary,onSaveImage:p.onSaveImage,onSaveText:p.onSaveText,onClick:e.onClick,onSelect:e.onSelect,onExpand:()=>Oe(t,e),showMetadataBadge:!1});return h.setViewControlsVisible(!1),h.setSummaryVisible(!1),d.onclick=()=>Oe(t,e),{card:o,ctrl:h,canvasWrapper:l,expandBtn:d}}function wn(e){const t=Z[e];if(!t)return;const n=[...I.values()].find(o=>o.cardIndex===e);n?(t.innerHTML=ge.minimize,t.title="Reattach to gallery",t.setAttribute("aria-label","Reattach to gallery"),t.onclick=()=>vn(n.id)):(t.innerHTML=ge.expand,t.title="Open full view",t.setAttribute("aria-label","Open full view"),t.onclick=()=>Oe(e,k[e]))}function V(e){Cn(),re()?.remove(),de(null),Ae(),k=[];for(const i of v)i&&i.destroy();v=[],q=[],Z=[],ve=0,B.innerHTML="",Ct=e.length,St(e.map(i=>typeof i=="function"?null:i));const t=[];for(let i=0;i<e.length;i++){const d=e[i];if(typeof d=="function"){const l=f.ownerDocument.createElement("div");l.className="wmap-gallery-card",Object.assign(l.style,{background:g.menuBg,border:`1px solid ${g.menuBorder}`,borderRadius:"10px",aspectRatio:"1",display:"flex",alignItems:"center",justifyContent:"center"});const a=f.ownerDocument.createElement("span");a.textContent="\u2026",Object.assign(a.style,{color:g.label,fontSize:"18px"}),l.appendChild(a),B.appendChild(l),k.push(null),v.push(null),q.push(null),Z.push(null),t.push({index:i,factory:d,placeholder:l}),ve++}else{const{ctrl:l,canvasWrapper:a,expandBtn:u}=_e(d,i,e.length);k.push(d),v.push(l),q.push(a),Z.push(u)}}k.flatMap(i=>i?[...i.hbinDefs??[],...i.sbinDefs??[]]:[]).some(i=>i.color)&&!p.viewOptions?.colorScheme&&(r={...r,colorScheme:"custom"}),Ee();const o=++Re;let s=0;function c(){if(o!==Re)return;if(s>=t.length){if(he.has(r.plotMode)){const A=r.plotMode;V(pe(A))}return}const{index:i,factory:d,placeholder:l}=t[s++],a=d();k[i]=a,w[i]=a,St([a]);const{card:u,ctrl:h,canvasWrapper:b,expandBtn:S}=_e(a,i,e.length);v[i]=h,q[i]=b,Z[i]=S,ve--,l.replaceWith(u),Ee(),!m&&!Y?.placement&&a.statsSummary?.findings.length?(E||(le="wafers"),m=Ye("right",f.ownerDocument),m.style.maxHeight="calc(100vh - 80px)",m.style.position="sticky",m.style.top="8px",m.style.flexDirection="column",m.style.display="none",(Y?.placement??"right")==="left"?F.insertBefore(m,B):F.appendChild(m),R(),O||(O=N("findings","Summary panel",()=>{if(!m)return;const H=m.style.display!=="none";H||R(),m.style.display=H?"none":"flex",se(O,!H),X()}),T.appendChild($()),T.appendChild(O)),X()):m&&m.style.display!=="none"&&R(),X(),setTimeout(c,0)}t.length>0&&setTimeout(c,0)}if(he.has(r.plotMode)&&w.length>0){const e=Ne(r.plotMode);r={...r,...e},V(pe(r.plotMode))}else V(D);let te=0;const Et=new(f.ownerDocument.defaultView??window).ResizeObserver(()=>{if(te)return;te=(f.ownerDocument.defaultView??window).requestAnimationFrame(()=>{te=0,W==null&&Be()})});Et.observe(B),m&&R();function xn(e,t){const n=q[e];if(!n)return;n.innerHTML="",Object.assign(n.style,{alignItems:"center",justifyContent:"center"});const o=f.ownerDocument.createElement("span");o.textContent=t?"Opened in its own window":"Opened in the wafer viewer",Object.assign(o.style,{color:g.label,fontSize:"12px",textAlign:"center",padding:"0 12px"}),n.appendChild(o)}function Oe(e,t){for(const i of I.values())if(i.cardIndex===e)return;const n=t.label??"Wafer map",o=Kt++,s=v[e]?.getOptions(),c=$n(n);if(c){const i=c.document;i.title=n,Object.assign(i.documentElement.style,{height:"100%"}),Object.assign(i.body.style,{margin:"0",height:"100vh",overflow:"hidden",display:"flex",flexDirection:"column",fontFamily:'system-ui, -apple-system, "Segoe UI", sans-serif'}),An(f,i.documentElement);const d=Hn(f,i.documentElement,()=>A.setOptions({})),l=i.createElement("div");l.dataset.wmapWindowBanner="1",l.textContent=n,Object.assign(l.style,{display:"none",padding:"6px 12px",fontSize:"12px",fontWeight:"700",background:g.warnBg,color:g.warnText,borderBottom:`1px solid ${g.warnBorder}`,flexShrink:"0"}),i.body.appendChild(l);const a=i.createElement("div");Object.assign(a.style,{flex:"1",minHeight:"0",display:"flex",flexDirection:"column"}),i.body.appendChild(a);const{wrap:u,metaPanel:h}=Dt(i,n,t.wafer.metadata??void 0),b=i.createElement("div");Object.assign(b.style,{display:"flex",alignItems:"center",padding:"8px 10px 6px",borderBottom:`1px solid ${g.menuBorder}`,flexShrink:"0",gap:"6px"}),b.appendChild(u),a.appendChild(b);const S=i.createElement("div");Object.assign(S.style,{position:"relative",flex:"1",minHeight:"0",overflow:"hidden",display:"flex",flexDirection:"column"}),h&&S.appendChild(h),a.appendChild(S);const A=Ge(S,t,void 0,s),H=setInterval(()=>{c.closed&&Te(o)},400);c.addEventListener("pagehide",()=>Te(o)),I.set(o,{id:o,ctrl:A,cardIndex:e,label:n,closePollId:H,stopThemeSync:d,close:()=>{c.closed||c.close()},setTitle:K=>{i.title=K,l.textContent=K,l.style.display="block"}})}else{const i=Pn({title:n,onClose:()=>Te(o),anchor:f});i.contentWrap.style.flexDirection="column",Bt(i,n,t.wafer.metadata??void 0);const d=Ge(i.contentWrap,t,void 0,s);I.set(o,{id:o,ctrl:d,cardIndex:e,label:n,closePollId:null,close:()=>i.close(),setTitle:l=>{const a=i.box.querySelector("[data-wmap-window-title]");a&&(a.textContent=l,a.title=l)}})}v[e]?.destroy(),v[e]=null,xn(e,c!==null),wn(e)}function Ge(e,t,n,o){const s=t.viewOptions?{...r,...t.viewOptions}:r,c=o?{...s,...o}:s,d={...n!==void 0?{...c,plotMode:"value",activeTest:n}:c,showLegend:!0},l=Qe(e,t,{viewOptions:d,toolbarControls:"full",showTooltip:!0,padding:Q,legendPosition:oe,fallbackFormat:we,statsSummary:t.statsSummary,onSaveImage:p.onSaveImage,onSaveText:p.onSaveText,onClick:t.onClick,onSelect:t.onSelect,showExpandButton:!1,showMetadataBadge:!1});return l.setViewControlsVisible(!0),l.setSummaryVisible(!0),l.setExpandVisible(!1),l}function Te(e){const t=I.get(e);if(!t)return;I.delete(e),t.closePollId!=null&&clearInterval(t.closePollId),t.stopThemeSync?.();const n=t.ctrl.getOptions();if(t.ctrl.destroy(),t.cardIndex===null)return;const o=t.cardIndex,s=k[o];if(!s)return;const c={...s,viewOptions:n};k[o]=c;const{card:i,ctrl:d,canvasWrapper:l,expandBtn:a}=_e(c,o,k.length);q[o]?.parentElement?.replaceWith(i),v[o]=d,q[o]=l,Z[o]=a}function vn(e){const t=I.get(e);t&&(t.close(),Te(e))}function Cn(){for(const e of I.values())e.cardIndex!==null&&(e.cardIndex=null,e.setTitle(`${e.label} \u2014 unlinked from gallery`))}function Sn(){const e=[...B.querySelectorAll("canvas")];if(!e.length)return;const t=e.length,n=Math.ceil(Math.sqrt(t)),o=Math.ceil(t/n),s=e[0].width,c=e[0].height,i=8,d=window.devicePixelRatio||1,l=Math.round(26*d),a=Math.round(12*d),u=f.ownerDocument.createElement("canvas");u.width=n*s+(n-1)*i,u.height=o*(c+l)+(o-1)*i;const h=u.getContext("2d"),b=Tn(B);h.fillStyle=b.background,h.fillRect(0,0,u.width,u.height),e.forEach((S,A)=>{const H=A%n,K=Math.floor(A/n),me=H*(s+i),y=K*(c+l+i),L=S.closest(".wmap-gallery-card")?.querySelector("span")?.textContent??"";h.fillStyle=b.surface,h.fillRect(me,y,s,l),h.fillStyle=b.text,h.font=`700 ${a}px system-ui, sans-serif`,h.textAlign="left",h.textBaseline="middle",h.fillText(L,me+Math.round(10*d),y+l/2,s-Math.round(20*d)),h.drawImage(S,me,y+l)}),u.toBlob(S=>{S&&Kn(S,ne,p.onSaveImage)})}return{setItems(e){w=e.map(n=>typeof n=="function"?null:n);const t=r.plotMode;if(he.has(t))if(e.some(o=>typeof o=="function"))V(e);else{const o=Ne(t);r={...r,...o},V(pe(t))}else V(e)},setOptions(e){C(e,{fireCallback:!1})},getOptions(){return{...r}},setFallbackFormat(e){we=e;for(const t of v)t&&t.setFallbackFormat(e)},setLotStatsSummary(e){E=e,ht(),m&&R(),X()},setColumns(e){Mt(e)},openUserGuide:bt,destroy(){Re++;for(const e of[...I.values()])e.closePollId!=null&&clearInterval(e.closePollId),e.close(),e.ctrl.destroy();I.clear();for(const e of v)e&&e.destroy();v=[],re()?.remove(),Et.disconnect(),te&&((f.ownerDocument.defaultView??window).cancelAnimationFrame(te),te=0),f.ownerDocument.removeEventListener("click",Se,!0),window.removeEventListener("blur",it),Gt(),Rt(),fe.remove(),F.remove(),m?.remove(),ue?.destroy()}}}
|
|
@@ -26,6 +26,28 @@ export interface WaferPreferences {
|
|
|
26
26
|
ringCount?: number;
|
|
27
27
|
/** Legend position for bin modes. Default 'default'. */
|
|
28
28
|
legendPosition?: 'default' | 'compact' | 'bottom' | 'top' | 'left' | 'floating';
|
|
29
|
+
/**
|
|
30
|
+
* Draw this map's own legend block — the categorical bin legend, the spec/
|
|
31
|
+
* pass-fail legend, or the value colorbar, whichever the plot mode calls for.
|
|
32
|
+
* Default true.
|
|
33
|
+
*
|
|
34
|
+
* Exists for the gallery, where one lot-level legend can stand in for every
|
|
35
|
+
* card's, so the cards can spend that width on the wafer instead. It is a
|
|
36
|
+
* view option rather than a render-time flag because the gallery toggles it
|
|
37
|
+
* live via `setOptions`.
|
|
38
|
+
*
|
|
39
|
+
* Suppressing a legend also suppresses a *control* — legend rows are click
|
|
40
|
+
* targets that toggle `highlightBin` for this map — so only turn it off where
|
|
41
|
+
* an equivalent control is still reachable, and never where the map's scale
|
|
42
|
+
* is its own (a data-ranged colorbar). `renderWaferGallery` owns that rule.
|
|
43
|
+
*/
|
|
44
|
+
showLegend?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Hatch dies whose bin is not a pass bin, giving pass/fail a channel that is
|
|
47
|
+
* not hue. Default false. Bin modes only — in value mode the spec markers
|
|
48
|
+
* already serve this role.
|
|
49
|
+
*/
|
|
50
|
+
markFailingDies?: boolean;
|
|
29
51
|
/**
|
|
30
52
|
* When true, apply log₁₀ scale to value normalization and the colorbar.
|
|
31
53
|
* Overrides the per-test TestDef.logScale default.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{buildView as oi,buildHoverText as ai,findTestDef as it,resolveTestNumber as Et}from"../renderer/buildView.js";import{toCanvas as si,BIN_LEGEND_W as wn,BIN_LEGEND_W_COMPACT as li,BIN_LEGEND_ADAPT_COMPACT as ri,BIN_LEGEND_ADAPT_FLOATING as di}from"./toCanvas.js";import{buildWaferMap as ci,getTestPassStatus as pi,isParametricTest as Bt}from"../renderer/buildWaferMap.js";import{analyzeWaferMap as fi}from"../stats/analyzeWaferMap.js";import{CLR as w,Z_BASE as ui,applyOverlayZ as gi,getTooltip as Sn,hideTooltip as ot,reparentTooltip as hi,positionTooltip as Dt,createToolbarHelpers as mi,buildModeMenuEl as yi,openReparentedModal as bi,openUserGuideWindow as vi,makePaletteBtn as xi,makeLogScaleBtn as wi,makeLegendStyleBtn as Si,makeOverlaysBtn as Ci,makeOrientationBtn as Mi,overlayRootFor as Cn,saveImageBlob as Ei,markMenuTrigger as Ye,wireMenuA11y as Mn,wireExpandToggle as Bi,nextFrame as kt,passFailMenuRows as Di,requestedPassFailDisplay as Lt,logWmapVersionOnce as ki,buildDataModeEntries as Li,metadataKeyHasData as Ti,metadataModeEntry as Pi}from"./toolbar.js";import{createSummaryPanelEl as Tt,wrapWithSummaryPanel as Pt,renderWaferSummaryContent as Oi}from"./summaryPanel.js";import{collectWarnings as Ri,buildWarningsMenuEl as Ii,severityOf as Wi}from"./warnings.js";import"../stats/facets.js";import{ICONS as En}from"./icons.js";import{hardBinColor as Hi,softBinColor as Ai,metadataValueColor as Fi}from"../renderer/colorMap.js";import{createInsightsTab as Yi}from"./insightsTab.js";import{createMetadataBadge as zi}from"./metadataBadge.js";import{getDieKey as Ee,hasPosition as Bn,isPositionedDie as Xi}from"../core/dies.js";import{buildDieListSection as Ni}from"./dieList.js";import{buildMaplessSummary as Ki}from"./maplessSummary.js";const Dn=new Set(["colorScheme","rotation","flipX","flipY","showDieLabels","showPartialDies","showRingBoundaries","showQuadrantBoundaries","showReticle","showXYIndicator","ringCount","legendPosition","logScale","colorbarRangeMode"]);export function classifyChanged(N){const m=N.some(g=>Dn.has(g)),S=N.some(g=>!Dn.has(g));return m&&S?"mixed":m?"preference":"state"}export function renderWaferMap(N,m,S={}){ki();const g=N.ownerDocument,K=g.defaultView??window;K.getComputedStyle(N).position==="static"&&(N.style.position="relative");const kn=N.clientHeight;S.height!=null&&(N.style.height=typeof S.height=="number"?`${S.height}px`:S.height);const at=m.dataCoverage?m.dataCoverage.unpositionedDies:m.dies.filter(e=>!Bn(e)).length,ze=(m.dataCoverage?m.dataCoverage.totalDies:m.dies.length-at)===0&&at>0,q=g.createElement("div");Object.assign(q.style,{position:"relative",width:"100%",height:"100%"}),S.maxSize!=null&&(q.style.maxWidth=`${S.maxSize}px`,q.style.maxHeight=`${S.maxSize}px`),N.appendChild(q);const C=g.createElement("div");Object.assign(C.style,{position:"relative",width:"100%",height:"100%"});const a=g.createElement("canvas");Object.assign(a.style,{width:"100%",height:"100%",display:"block"}),C.appendChild(a),q.appendChild(C);let Xe=null;if(at>0){let n=function(){if(t){const u=Ni(e,m.testDefs,{...S.dieList,onSaveText:S.onSaveText,waferMetadata:J.metadata,metadataFields:se,ownerDocument:g});if(u)return u}const i=it(m.testDefs,l.activeTest??0),r=Bt(i)?l.logScale??i?.logScale??!1:!1;return Ki(e,m.testDefs,{plotMode:l.plotMode??"hardBin",activeTest:l.activeTest,hbinDefs:$,sbinDefs:G,colorScheme:l.colorScheme,logScale:r,colorbarRangeMode:l.colorbarRangeMode,valueRangeDies:m.dies})},o=function(i){const r=g.createElement("button");return r.type="button",Object.assign(r.style,{fontSize:"10px",padding:"2px 6px",borderRadius:"4px",flexShrink:"0",border:`1px solid ${w.menuBorder}`,background:w.menuBg,color:w.text,cursor:"pointer"}),r.textContent=t?"View chart":"View die list",r.addEventListener("click",u=>{u.stopPropagation(),t=!t,r.textContent=t?"View chart":"View die list",i()}),r};const e=m.dies.filter(i=>!Bn(i));let t=!1;if(ze){const i=g.createElement("div");Object.assign(i.style,{position:"absolute",inset:"0",background:w.panelBg,padding:"12px",paddingTop:S.showToolbar??!0?"44px":"12px",boxSizing:"border-box",overflow:"hidden",display:"flex",flexDirection:"column",gap:"8px",zIndex:"1"});const r=g.createElement("div");Object.assign(r.style,{display:"flex",justifyContent:"space-between",alignItems:"flex-start",gap:"8px"});const u=g.createElement("span");Object.assign(u.style,{fontSize:"11px",color:w.label,lineHeight:"1.4"}),u.textContent="No die position data for this wafer.",r.appendChild(u);const s=g.createElement("div");Object.assign(s.style,{flex:"1",minHeight:"0",overflow:"auto",display:"flex",flexDirection:"column"}),r.appendChild(o(()=>s.replaceChildren(n()))),i.appendChild(r),i.appendChild(s),C.appendChild(i),Xe=()=>{t||s.replaceChildren(n())}}else{const i=g.createElement("div");Object.assign(i.style,{position:"absolute",left:"0",right:"0",bottom:"0",zIndex:"3",background:w.panelBg,borderTop:`1px solid ${w.menuBorder}`,fontSize:"11px",color:w.text,cursor:"pointer",padding:"4px 8px",display:"flex",alignItems:"center",justifyContent:"space-between",gap:"8px"});const r=g.createElement("span");r.textContent=`+${e.length} ${e.length===1?"die":"dies"} without position data`,i.appendChild(r);const u=g.createElement("span");u.textContent="\u25BE",Object.assign(u.style,{fontSize:"12px",lineHeight:"1",color:w.label,flexShrink:"0"}),i.appendChild(u),i.setAttribute("aria-expanded","false"),i.setAttribute("aria-label",`${e.length} dies without position data. Click to view.`);let s=null,d=null;Bi(i,c=>{if(u.textContent=c?"\u25B4":"\u25BE",i.setAttribute("aria-expanded",String(c)),c){s=g.createElement("div");const p=i.getBoundingClientRect().height||28;Object.assign(s.style,{position:"absolute",left:"0",right:"0",bottom:`${p}px`,top:"20%",zIndex:"2",background:w.panelBg,borderTop:`1px solid ${w.menuBorder}`,padding:"8px",boxSizing:"border-box",display:"flex",flexDirection:"column",gap:"8px"}),s.addEventListener("click",Q=>Q.stopPropagation());const h=g.createElement("div");Object.assign(h.style,{display:"flex",justifyContent:"flex-end"}),h.appendChild(o(()=>{d&&d.replaceChildren(n())})),s.appendChild(h),d=g.createElement("div"),Object.assign(d.style,{flex:"1",minHeight:"0",overflow:"auto",display:"flex",flexDirection:"column"}),d.appendChild(n()),s.appendChild(d),C.appendChild(s)}else s&&(s.remove(),s=null,d=null)}),C.appendChild(i),Xe=()=>{d&&!t&&d.replaceChildren(n())}}}const{onHover:Ne,onClick:Ln,onSelect:de,onViewOptionsChange:Tn,showTooltip:Pn=!0,showToolbar:he=!0,showMetadataBadge:On=!0,toolbarControls:Ot="full",showPlotModeSelector:Rn=!0,minZoom:In=.4,maxZoom:Wn=20,summaryPanel:Be,renderTooltip:Rt,passBins:It=[1],showHelpButton:Hn=!1,userGuideExtension:An,onExpand:Wt,showExpandButton:Ht=!0,zIndex:Fn,insights:At,warnings:Ft,viewOptions:Yn={},...ce}=S,zn=At?.enabled??!1,Yt=Ft?.display??!0,Xn=gi(Fn);let De=ce.fallbackFormat,ie=S.statsSummary,oe=[],zt=!1;function Xt(){const e=Ri({result:m,statsSummary:ie}),t=e.length!==oe.length||e.some((n,o)=>n.code!==oe[o]?.code||n.message!==oe[o]?.message);oe=e,(t||!zt)&&(zt=!0,Ft?.onWarning?.(e))}Xt();let st=m,J=m.wafer,ae=m.dies,E=new Set,$=m.hbinDefs,G=m.sbinDefs,ee=m.testDefs,se=m.metadataFields,Nt=m.reticles?.length?m.reticles:void 0,Kt=m.reticleConfig,Vt=m.view?.dataAxisFlip,lt=m.isLotStack??!1,rt=m.aggrMethod,dt=m.lotSize,jt=!1,T=null;On&&(T=zi(J.metadata,{lotStack:_t(),ownerDocument:g}),T.isEmpty()||C.appendChild(T.el));function _t(){return lt?{lotSize:dt??1,aggrMethod:rt}:void 0}function Nn(){if(!T)return;T.update(J.metadata,_t());const e=T.el.isConnected;T.isEmpty()&&e?T.el.remove():!T.isEmpty()&&!e&&C.appendChild(T.el)}const $t=[...$??[],...G??[]].some(e=>e.color);let l={plotMode:"hardBin",colorScheme:$t?"custom":"default",showDieLabels:!1,showPartialDies:!0,showRingBoundaries:!1,showQuadrantBoundaries:!1,showReticle:!1,showXYIndicator:!1,ringCount:4,rotation:0,flipX:!1,flipY:!1,legendPosition:ce.legendPosition??"default",...Yn},le=null,me=!1;zn&&(le=Yi({getItems:()=>[{wafer:J,dies:ae,hbinDefs:$,sbinDefs:G,testDefs:ee,label:String(J.metadata?.waferId??""),statsSummary:ie}],getColorSchemeName:()=>l.colorScheme??"default",passBins:It,getRingCount:()=>l.ringCount??4,onSaveImage:S.onSaveImage,onSaveText:S.onSaveText,defaultView:At?.defaultView,backTab:{label:"Map",onBack:()=>ct(!1)},ownerDocument:g}),Object.assign(le.el.style,{position:"absolute",inset:"0",background:w.panelBg,overflowY:"auto",paddingTop:he?"44px":"0"}),q.appendChild(le.el));function ct(e){le&&(me=e,le.el.style.display=e?"flex":"none",A&&(A.style.display=e||ze?"none":"flex"),k&&(k.style.display=e?"none":"flex"),Z&&(Z.style.display=e?"none":"flex"),T&&(T.el.style.display=e||jt?"none":""),Ze(),F&&(F.innerHTML=e?En.wafer:En.analysis,F.ariaLabel=e?"Back to wafer view":"Insights"),e&&le.render())}let y,Gt,H=null,P=null,pt=[],ke=null,ft=ce.legendOffset??{x:0,y:0},Le=!1,ye=!1,Te={x:0,y:0},ut={x:0,y:0},pe=!1,be=!1,Y="pan",ve={x:0,y:0},Ke={x:0,y:0},O={x:0,y:0},R={x:0,y:0},Pe=!1,xe=!1;function Oe(){const e=l;y=oi(J,ae.filter(Xi),{plotMode:e.plotMode,colorScheme:e.colorScheme,showDieLabels:e.showDieLabels,showPartialDies:e.showPartialDies,showRingBoundaries:e.showRingBoundaries,showQuadrantBoundaries:e.showQuadrantBoundaries,showReticle:e.showReticle,showXYIndicator:e.showXYIndicator,reticles:Nt,ringCount:e.ringCount,highlightBin:e.highlightBin,highlightMetadataValue:e.highlightMetadataValue,activeTest:e.activeTest,activeMetadataKey:e.activeMetadataKey,testDefs:ee,valueRange:e.valueRange,logScale:e.logScale,isLotStack:lt,aggregationMethod:rt??e.aggregationMethod,lotSize:dt??e.lotSize,dataAxisFlip:Vt,colorbarRangeMode:e.colorbarRangeMode,passFailDisplay:e.passFailDisplay,fallbackFormat:De,interactiveTransform:{rotation:e.rotation??0,flipX:e.flipX??!1,flipY:e.flipY??!1}},{hbinDefs:$,sbinDefs:G,metadataFields:se}),Gt=new Map(y.dies.map((t,n)=>[Ee(t),n]))}Oe();let z=null,fe=null,Ve=null,Kn={},I=null,te=null;function Vn(e){const{kind:t,index:n}=e.variable;M(t==="test"?{plotMode:"value",activeTest:n??0,highlightBin:void 0}:t==="softBin"?{plotMode:"softBin",highlightBin:void 0}:{plotMode:"hardBin",highlightBin:void 0});const o=e.highlight;o.kind==="bin"?(vt(o.dieKeys),M({highlightBin:o.bin})):(o.kind==="region"||o.kind==="dies")&&vt(o.dieKeys)}function Zt(e){Oi(e,{wafer:J,dies:ae,yieldSummary:st.yield,dataCoverage:st.dataCoverage,hbinDefs:$,sbinDefs:G,testDefs:ee,statsSummary:ie,warnings:Yt?oe:[],passBins:It,ringCount:l.ringCount??4,colorScheme:l.colorScheme,fallbackFormat:De,activeFindingId:Ve,findingsFilter:Kn,onFindingsFilterChange:ue,onSaveText:S.onSaveText,metadataFields:se,dieListOptions:S.dieList,onFindingClick:(t,n)=>{Ve===t.id?(Ve=null,vt([]),M({highlightBin:void 0})):(Ve=t.id,Vn(t)),ue()}})}function ue(){z&&Zt(z)}function je(){I&&Zt(I)}function Qt(e,t){he&&(t==="right"||t==="top")&&(e.style.paddingTop="44px")}if(Be?.placement){const e=Be.placement;z=Tt(e,g),Qt(z,e);const t=C.parentElement,n=C.nextSibling;fe=Pt(C,z,e),t?.insertBefore(fe,n),ue()}else if(ie){const e=Be?.defaultOpen??!he;I=Tt("right",g),Qt(I,"right"),I.style.display=e?"block":"none";const t=C.parentElement,n=C.nextSibling;te=Pt(C,I,"right"),t?.insertBefore(te,n),je()}const v=Pn?Sn(g):null;let B=null,D=null,A=null,k=null,_e=null,W=null,Z=null,$e=null,F=null,ne=null,Ge=null;function Ut(){if(!ne||!Ge)return;const e=oe.length,t=e>0;if(ne.style.display=t?"flex":"none",Ge.style.display=t?"":"none",!t)return;const n=Wi(oe[0]),o=`${e} data ${e===1?"warning":"warnings"}`;ne.style.color=n==="error"?w.errText:w.warnText,ne.ariaLabel=n==="error"?`${o} \u2014 the map may be positionally wrong`:o}const jn=24;let we=null,gt=null,qt=null,ht=null,mt=null,yt=null,bt=null;function vt(e){E=new Set(e??[]),de&&de(Ct()),x()}function Ze(){if(!W)return;const e=!!(z??I);W.style.display=ie&&e&&!me?"flex":"none";const t=z??I,n=t?t.style.display!=="none":!1;ie?.hasNotableFindings&&!n?W.style.color=w.findingIndicator:W.dataset.active||(W.style.color=w.icon)}if(he){let Q=function(U){Y=U,o(V,U==="zoom"),o(Ie,U==="pan"),_e&&o(_e,U==="select"),a.style.cursor=U==="pan"?"grab":"crosshair"},qe=function(){we&&(clearTimeout(we),we=null),B&&(B.style.opacity="1")},Je=function(){we=setTimeout(()=>{B&&(B.style.opacity="0.35")},600)};B=g.createElement("div"),B.dataset.wmapToolbar="single",Object.assign(B.style,{position:"absolute",top:"4px",right:"4px",display:"flex",flexDirection:"row",alignItems:"center",flexWrap:"wrap-reverse",justifyContent:"flex-end",maxWidth:"calc(100% - 8px)",background:w.menuBg,border:`1px solid ${w.menuBorder}`,borderRadius:"4px",boxShadow:"0 1px 4px rgba(0,0,0,0.12)",zIndex:ui,opacity:"0.35",transition:"opacity 0.2s ease",pointerEvents:"auto"});const e=Sn(g),t=mi(e),{makeBtn:n,setActive:o,makeSep:i,makeMenuRow:r,makeMenuSection:u,makeDropdown:s,makeCheckMenuBtn:d,closeOpenMenu:c,getOpenMenu:p,setOpenMenu:h}=t;gt=c,qt=p,g.addEventListener("click",c,!0),A=g.createElement("div"),Object.assign(A.style,{display:ze?"none":"flex",alignItems:"center",gap:"0",flexWrap:"wrap",justifyContent:"flex-end"}),B.appendChild(A);const Me=n("download","Download PNG",Gn);A.appendChild(Me),A.appendChild(i());const V=n("zoomMode","Zoom (drag to zoom region)",()=>Q("zoom")),re=n("zoomIn","Zoom in",()=>Ce(a.clientWidth/2,a.clientHeight/2,1.2)),L=n("zoomOut","Zoom out",()=>Ce(a.clientWidth/2,a.clientHeight/2,1/1.2)),j=n("reset","Reset zoom (double-click)",()=>Ue());A.appendChild(V),A.appendChild(re),A.appendChild(L),A.appendChild(j),A.appendChild(i());const Ie=n("pan","Pan (drag to move)",()=>Q("pan"));if(A.appendChild(Ie),_e=n("boxSelect","Select (drag to select dies)",()=>Q("select")),A.appendChild(_e),o(Ie,!0),Ot!=="view-only"){let U=function(f){return f.plotMode!==(l.plotMode??"hardBin")?!1:f.plotMode==="value"?(l.activeTest??0)===(f.activeTest??0):f.plotMode==="metadata"?l.activeMetadataKey===f.activeMetadataKey:!0},We=function(f,b){f.activeTest!==void 0?M({plotMode:f.plotMode,activeTest:f.activeTest,activeMetadataKey:void 0,logScale:f.logScale}):f.activeMetadataKey!==void 0?M({plotMode:f.plotMode,activeTest:void 0,activeMetadataKey:f.activeMetadataKey,passFailDisplay:"off"}):M({plotMode:f.plotMode,activeTest:void 0,activeMetadataKey:void 0,passFailDisplay:"off"}),b.remove(),h(null),Ye(_,!1)};D=g.createElement("div"),Object.assign(D.style,{display:"flex",alignItems:"center",gap:"0",flexWrap:"wrap",justifyContent:"flex-end"}),B.appendChild(D),k=g.createElement("div"),Object.assign(k.style,{display:"flex",alignItems:"center",gap:"0"}),D.appendChild(k),k.appendChild(i());const et=()=>{const f=p();f&&(f.remove(),h(null)),Ye(_,!1)},_=n("mode","Plot mode",()=>{if(p()){et();return}const f=ae,b=y.testDefs,{testEntries:nt,binEntries:ge,stackedEntries:He}=Li(f,b,{includeStacked:y.isLotStack}),Mt=(se??[]).filter(Fe=>Ti(f,Fe.key)).map(Pi),Ae=yi(_.getBoundingClientRect(),nt,ge,He,U,We,{makeMenuRow:r,makeMenuSection:u},l.plotMode??"hardBin",_.ownerDocument.defaultView??window,Mt);Cn(_).appendChild(Ae),h(Ae),Ye(_,!0),Mn(Ae,_,et)});Ye(_,!1);const{btn:Zn,sync:Qn}=xi(t,()=>l.plotMode??"hardBin",()=>l.colorScheme??"default",()=>$t,f=>M({colorScheme:f}));mt=Qn,mt();const Un=Ci(t,()=>{const f=!!y.hasReticle,b=(l.plotMode??"hardBin")==="value",{testNumber:nt}=Et(l.activeTest??0,y.testDefs),ge=it(y.testDefs,nt),He=b&&ge!==void 0&&!Bt(ge),Mt=b&&!He&&(ge?.limitLow!==void 0||ge?.limitHigh!==void 0),Ae=b&&!He&&y.dies.some(Fe=>pi(Fe,nt,ge)!==void 0);return[{label:"Ring boundaries",active:!!l.showRingBoundaries,onClick:()=>M({showRingBoundaries:!l.showRingBoundaries})},{label:"Quadrant lines",active:!!l.showQuadrantBoundaries,onClick:()=>M({showQuadrantBoundaries:!l.showQuadrantBoundaries})},{label:"Die labels",active:!!l.showDieLabels,onClick:()=>M({showDieLabels:!l.showDieLabels})},{label:"Reticle grid",active:!!l.showReticle,enabled:f,onClick:()=>M({showReticle:!l.showReticle})},{label:"XY indicator",active:!!l.showXYIndicator,onClick:()=>M({showXYIndicator:!l.showXYIndicator})},...Di({functionalActive:He,hasLimits:Mt,hasRecorded:Ae,display:Lt(l)},Fe=>M({passFailDisplay:Fe}))]},()=>!!(l.showRingBoundaries||l.showQuadrantBoundaries||l.showDieLabels||l.showReticle||l.showXYIndicator||Lt(l)!=="off")),{btn:qn,sync:Jn}=Si(t,()=>l,f=>M({legendPosition:f}));ht=Jn,ht();const xn=()=>{const{testNumber:f}=Et(l.activeTest??0,ee),b=it(ee,f);return b!==void 0&&!Bt(b)},{btn:ei,sync:ti}=wi(t,()=>({...l,functionalActive:xn()}),f=>M(f));yt=ti,yt();const ni=()=>{const{testNumber:f}=Et(l.activeTest??0,ee),b=it(ee,f);return b!==void 0&&(b.limitLow!==void 0||b.limitHigh!==void 0)},tt=n("specRange","Colorbar range: spec limits",()=>{const f=l.colorbarRangeMode==="data"?"spec":"data";M({colorbarRangeMode:f})});bt=()=>{const f=l.plotMode==="value"&&ni()&&Lt(l)==="off"&&!xn();tt.style.display=f?"":"none";const b=(l.colorbarRangeMode??"spec")==="spec";o(tt,b),tt.ariaLabel=b?"Colorbar range: spec limits (click for data range)":"Colorbar range: data range (click for spec limits)"},bt();const ii=Mi(t,()=>l,f=>M(f));Rn&&k.appendChild(_),k.appendChild(Zn),k.appendChild(ei),k.appendChild(tt),ze||(k.appendChild(i()),k.appendChild(Un),k.appendChild(i()),k.appendChild(qn),k.appendChild(i()),k.appendChild(ii)),ie&&(W=n("findings","Summary panel",()=>{const f=z??I;if(!f)return;const b=f.style.display!=="none";f.style.display=b?"none":"block",o(W,!b),Ze()}),D.appendChild(i()),D.appendChild(W),I?.style.display!=="none"&&o(W,!0),Ze()),Yt&&(Ge=i(),ne=n("warning","Data warnings",()=>{const f=p();if(c(new MouseEvent("click")),f)return;const b=Ii(ne.getBoundingClientRect(),oe,K);Cn(q).appendChild(b),h(b),Mn(b,ne,()=>c(new MouseEvent("click")))}),Ye(ne,!1),D.appendChild(Ge),D.appendChild(ne),Ut()),Ht&&(D.appendChild(i()),Z=n("expand","Expand (E)",Wt??Jt),D.appendChild(Z)),le&&(D.appendChild(i()),F=n("analysis","Insights",()=>{ct(!me),o(F,me)}),F.dataset.wmapInsightsBtn="1",D.appendChild(F)),Hn&&(D.appendChild(i()),$e=n("help","User guide",()=>vn()),D.appendChild($e))}q.appendChild(B),a.addEventListener("mouseenter",qe),a.addEventListener("mouseleave",Je),B.addEventListener("mouseenter",qe),B.addEventListener("mouseleave",Je)}let Se=null;function Jt(){Se&&(Se.close(),Se=null);const e=fe??te??C;e.style.flex="1",e.style.minWidth="0",e.style.minHeight="0";const t=bi(B?[e,B]:[e],{ownerDocument:g,onClosed:()=>{Se=null,Z&&(Z.style.display="flex"),a.focus({preventScroll:!0})}});t&&(B&&(t.contentWrap.style.position="relative"),Se=t,Z&&(Z.style.display="none"))}function en(e){const t=l.plotMode;if(l={...l,...e},e.plotMode!==void 0&&e.plotMode!==t){H=null;const i=l.plotMode;(i==="hardBin"||i==="softBin")&&!new Set(["default","accessible","custom"]).has(l.colorScheme??"")&&(l={...l,colorScheme:"default"})}Object.keys(e).every(i=>i==="legendPosition")||Oe(),ht?.(),mt?.(),yt?.(),bt?.(),x();const o=e.plotMode!==void 0&&e.plotMode!==t;(e.colorScheme!==void 0||o)&&(ue(),je()),(e.colorScheme!==void 0||o||e.activeTest!==void 0||e.logScale!==void 0||e.colorbarRangeMode!==void 0)&&Xe?.()}function M(e){en(e);const t=Object.keys(e);Tn?.(l,t,classifyChanged(t))}let xt=!1;function wt(){xt||(xt=!0,kt(()=>{xt=!1,x()},K))}function x(){const e=P??void 0,t=y.dies[0],n=t?{x:t.width,y:t.height}:ce.diePitchMm,o=Math.floor(a.clientWidth||a.width),i=!!($?.length||G?.length||y.dies.some(p=>p.hbin!=null||p.sbin!=null)),r=l.legendPosition??"default",u=r==="default"||r==="compact",s=(ce.colorbarWidth??16)+28,d=i&&u?r!=="default"?Math.max(wn,s):o<di?0:o<ri?Math.max(li,s):Math.max(wn,s):void 0,c=si(a,y,{...ce,topClearance:he?jn:0,minRightReserve:d,legendPosition:r,legendOffset:ft,diePitchMm:n,fallbackFormat:De,showAxes:ce.showAxes??P!==null,viewport:e,activeBin:l.plotMode==="metadata"?l.highlightMetadataValue:l.highlightBin,hbinDefs:$,sbinDefs:G,metadataFields:se});pt=c.binLegendRows,ke=c.legendBox??null,H||(H=c.viewport),E.size>0&&_n(),be&&$n()}function _n(){const e=X();if(!e)return;const t=a.getContext("2d"),n=y.hoverPoints,o=y.rectangles[0],i=o?o.width/2*e.ppm:e.ppm*.5,r=o?o.height/2*e.ppm:e.ppm*.5,u=Math.max(1,Math.min(3,i*.08)),s=i-u,d=r-u,c=[];for(const p of E){const h=Gt.get(p);h!==void 0&&c.push({sx:e.originX+n[h].x*e.ppm,sy:e.originY-n[h].y*e.ppm})}if(c.length){t.save(),t.setLineDash([]),t.fillStyle="rgba(0,0,0,0.12)",t.beginPath();for(const{sx:p,sy:h}of c)t.rect(p-s,h-d,s*2,d*2);t.fill(),t.strokeStyle="rgba(255,255,255,0.9)",t.lineWidth=3,t.beginPath();for(const{sx:p,sy:h}of c)t.rect(p-s,h-d,s*2,d*2);t.stroke(),t.strokeStyle="rgba(0,0,0,0.9)",t.lineWidth=1.5,t.beginPath();for(const{sx:p,sy:h}of c)t.rect(p-s,h-d,s*2,d*2);t.stroke(),t.restore()}}function $n(){const e=a.getContext("2d"),t=Math.min(O.x,R.x),n=Math.min(O.y,R.y),o=Math.abs(R.x-O.x),i=Math.abs(R.y-O.y);e.save(),e.fillStyle="rgba(0,0,0,0.08)",e.fillRect(t,n,o,i),e.setLineDash([5,3]),e.strokeStyle="rgba(255,255,255,0.9)",e.lineWidth=3,e.strokeRect(t,n,o,i),e.strokeStyle="rgba(0,0,0,0.9)",e.lineWidth=1.5,e.strokeRect(t,n,o,i),e.restore()}function Gn(){a.toBlob(e=>{e&&Ei(e,S.downloadFilename??"wafermap",S.onSaveImage)})}function tn(e){return H?Math.max(H.ppm*In,Math.min(H.ppm*Wn,e)):e}function Ce(e,t,n){const o=P??H;if(!o)return;const i=tn(o.ppm*n),r=i/o.ppm,u=e-(e-o.originX)*r,s=t-(t-o.originY)*r,d=(H?.snapDist??1)/(i/(H?.ppm??i));P={originX:u,originY:s,ppm:i,snapDist:d},x()}function X(){return P??H}function nn(e){if(e.ctrlKey||e.metaKey){e.preventDefault();const t=a.getBoundingClientRect(),n=e.deltaY<0?1.12:1/1.12;Ce(e.clientX-t.left,e.clientY-t.top,n)}else if(P!==null){e.preventDefault();const t=X(),n=P.snapDist;P={originX:t.originX-e.deltaX,originY:t.originY-e.deltaY,ppm:t.ppm,snapDist:n},x()}}function on(e,t,n){return e>=n.x&&e<n.x+n.w&&t>=n.y&&t<n.y+n.h}function an(e){if(e.button!==0||!X())return;a.focus({preventScroll:!0}),a.setPointerCapture(e.pointerId);const t=a.getBoundingClientRect(),n=e.clientX-t.left,o=e.clientY-t.top;if(ke&&l.legendPosition==="floating"&&on(n,o,ke)){ye=!0,Te={x:n,y:o},ut={...ft};return}if(Pe&&Y!=="pan"){xe=!0,pe=!0,ve={x:n,y:o},Ke={x:X().originX,y:X().originY},a.style.cursor="grabbing";return}if(Y==="zoom"||Y==="select"){be=!0,O=R={x:n,y:o};return}pe=!0,ve={x:n,y:o},Ke={x:X().originX,y:X().originY},a.style.cursor="grabbing"}function sn(e){const t=a.getBoundingClientRect(),n=e.clientX-t.left,o=e.clientY-t.top;if(be){R={x:n,y:o},wt();return}if(ye){const p=n-Te.x,h=o-Te.y;p*p+h*h>16&&(ye=!1,Le=!0,a.style.cursor="grabbing")}if(Le){ft={x:ut.x+(n-Te.x),y:ut.y+(o-Te.y)},wt();return}if(pe){const p=X(),h=P?.snapDist??H?.snapDist??1;P={originX:Ke.x+(n-ve.x),originY:Ke.y+(o-ve.y),ppm:p.ppm,snapDist:h},wt();return}const i=X();if(!i)return;const r=(n-i.originX)/i.ppm,u=(i.originY-o)/i.ppm,d=cn(r,u,i.snapDist)?.die??null,c=pt.find(p=>n>=p.x&&n<p.x+p.w&&o>=p.y&&o<p.y+p.h);if(c){a.style.cursor="pointer",v&&(v.innerHTML=c.label??`Bin ${c.bin}`,v.style.display="block",Dt(v,a,e.clientX,e.clientY)),Ne?.(null,e);return}if(Y==="pan"&&(a.style.cursor=d?"crosshair":"grab"),v)if(d)if(Rt){const p=Rt(d);p===null?v.style.display="none":(typeof p=="string"?v.innerHTML=p:(v.innerHTML="",v.appendChild(p)),v.style.display="block",Dt(v,a,e.clientX,e.clientY))}else v.innerHTML=ai(d,y.plotMode,{testDefs:ee,hbinDefs:$,sbinDefs:G,fallbackFormat:De,aggrMethod:y.aggrMethod,lotSize:y.lotSize,waferMeta:J.metadata,metadataFields:se,activeTest:y.activeTest,reticleConfig:Kt}),v.style.display="block",Dt(v,a,e.clientX,e.clientY);else v.style.display="none";Ne?.(d,e)}function ln(e){const t=a.getBoundingClientRect(),n=e.clientX-t.left,o=e.clientY-t.top,i=e.ctrlKey||e.metaKey;if(v&&(n<0||o<0||n>t.width||o>t.height)&&(v.style.display="none"),be){be=!1,R={x:n,y:o};const s=n-O.x,d=o-O.y,c=X();if(Y==="zoom"){if(s*s+d*d<25)Ce(n,o,2);else if(c){const p=Math.min(O.x,R.x),h=Math.max(O.x,R.x),Q=Math.min(O.y,R.y),Me=Math.max(O.y,R.y),V=h-p,re=Me-Q;if(V>4&&re>4){const L=a.clientWidth,j=a.clientHeight,Ie=L/V,qe=j/re,Je=Math.min(Ie,qe),U=tn(c.ppm*Je),We=U/c.ppm,et=(p+h)/2,_=(Q+Me)/2;P={originX:L/2-(et-c.originX)*We,originY:j/2-(_-c.originY)*We,ppm:U,snapDist:c.snapDist/We}}}x(),a.style.cursor="crosshair";return}if(s*s+d*d<25)St(n,o,i,e);else if(c){const p=(Math.min(O.x,R.x)-c.originX)/c.ppm,h=(Math.max(O.x,R.x)-c.originX)/c.ppm,Q=(c.originY-Math.max(O.y,R.y))/c.ppm,Me=(c.originY-Math.min(O.y,R.y))/c.ppm,V=y.hoverPoints,re=[];for(let L=0;L<V.length;L++)if(V[L].x>=p&&V[L].x<=h&&V[L].y>=Q&&V[L].y<=Me){const j=y.dies[L];j&&re.push(j)}if(i)for(const L of re){const j=Ee(L);E.has(j)?E.delete(j):E.add(j)}else E=new Set(re.map(L=>Ee(L)));de?.(Ct())}x(),a.style.cursor="crosshair";return}if(ye){ye=!1,St(n,o,i,e);return}if(Le){Le=!1,a.style.cursor="grab";return}if(!pe)return;if(pe=!1,xe){xe=!1,a.style.cursor=Pe||Y==="pan"?"grab":"crosshair";return}a.style.cursor=Y==="pan"?"grab":"crosshair";const r=n-ve.x,u=o-ve.y;r*r+u*u<25&&St(n,o,i,e)}function St(e,t,n,o){for(const s of pt)if(e>=s.x&&e<s.x+s.w&&t>=s.y&&t<s.y+s.h){if(typeof s.bin=="number"){const d=l.highlightBin===s.bin?void 0:s.bin;M({highlightBin:d})}else{const d=l.highlightMetadataValue===s.bin?void 0:s.bin;M({highlightMetadataValue:d})}return}if(ke&&on(e,t,ke))return;const i=X();if(!i)return;const u=cn((e-i.originX)/i.ppm,(i.originY-t)/i.ppm,i.snapDist)?.die??null;if(u){Ln?.(u,o);const s=Ee(u);n?E.has(s)?E.delete(s):E.add(s):E=new Set([s]),de?.(Ct()),x()}else n||(E=new Set,de?.([]),x())}function Ct(){const e=[],t=y.hoverPoints;for(let n=0;n<t.length;n++){const o=y.dies[n];o&&E.has(Ee(o))&&e.push(o)}return e}function rn(){v&&ot(g),Ne?.(null,new MouseEvent("mouseleave")),a.style.cursor=Y==="pan"?"grab":"crosshair"}function dn(){pe=!1,xe=!1,be=!1,ye=!1,Le=!1,v&&ot(g),Ne?.(null,new MouseEvent("mouseleave")),a.style.cursor=Y==="pan"?"grab":"crosshair",x()}function cn(e,t,n){const o=y.hoverPoints,i=y.rectangles;for(let d=0;d<i.length;d++){const c=i[d];if(Math.abs(e-c.x)<=c.width/2&&Math.abs(t-c.y)<=c.height/2){const p=y.dies[d];return p?{die:p,index:d}:null}}let r=null,u=-1,s=n*n;for(let d=0;d<o.length;d++){const c=o[d].x-e,p=o[d].y-t,h=c*c+p*p;h<s&&(s=h,r=y.dies[d]??null,u=d)}return r?{die:r,index:u}:null}const pn=new K.ResizeObserver(()=>{H=null,P=null,x()});pn.observe(a),S.height==null&&kn<=0&&kt(()=>kt(()=>{N.clientHeight>0||console.warn("[wafermap] The map container has zero height, so the map cannot render. renderWaferMap fills its container \u2014 give the container a resolved height: an explicit CSS `height` (e.g. 600px), a height-resolved flex/grid parent, or `position:absolute; inset:0`. Alternatively pass `{ height: 600 }` in the render options and the library will size it for you.")}));let Re=K.matchMedia(`(resolution: ${K.devicePixelRatio}dppx)`);const Qe=()=>{Re.removeEventListener("change",Qe),Re=K.matchMedia(`(resolution: ${K.devicePixelRatio}dppx)`),Re.addEventListener("change",Qe),x()};Re.addEventListener("change",Qe);const fn=K.matchMedia("(prefers-color-scheme: dark)"),un=()=>x();fn.addEventListener("change",un);const gn=()=>{v&&ot(g)};K.addEventListener("blur",gn);function hn(e){if(e.key==="Escape"&&E.size>0&&(E=new Set,de?.([]),x()),(e.key==="e"||e.key==="E")&&Ot!=="view-only"&&Ht&&!me&&(e.stopPropagation(),(Wt??Jt)()),(e.ctrlKey||e.metaKey)&&(e.key==="="||e.key==="+"?(e.preventDefault(),Ce(a.clientWidth/2,a.clientHeight/2,1.2)):e.key==="-"?(e.preventDefault(),Ce(a.clientWidth/2,a.clientHeight/2,1/1.2)):e.key==="0"&&(e.preventDefault(),Ue())),!e.ctrlKey&&!e.metaKey&&!e.shiftKey){const n=X();if(n){const o=P?.snapDist??H?.snapDist??1;let i=0,r=0;e.key==="ArrowLeft"&&(i=20,e.preventDefault()),e.key==="ArrowRight"&&(i=-20,e.preventDefault()),e.key==="ArrowUp"&&(r=20,e.preventDefault()),e.key==="ArrowDown"&&(r=-20,e.preventDefault()),(i||r)&&(P={originX:n.originX+i,originY:n.originY+r,ppm:n.ppm,snapDist:o},x())}e.key===" "&&!Pe&&(e.preventDefault(),Pe=!0,Y!=="pan"&&(a.style.cursor="grab"))}}function mn(e){e.key===" "&&(Pe=!1,xe&&(pe=!1,xe=!1),a.style.cursor=Y==="pan"?"grab":"crosshair")}a.style.cursor="grab",a.setAttribute("tabindex","0"),a.addEventListener("wheel",nn,{passive:!1}),a.addEventListener("pointerdown",an),a.addEventListener("pointermove",sn),a.addEventListener("pointerup",ln),a.addEventListener("pointerleave",rn),a.addEventListener("pointercancel",dn);const yn=()=>Ue();a.addEventListener("dblclick",yn),a.addEventListener("keydown",hn),a.addEventListener("keyup",mn);const bn=e=>{e.stopPropagation()};a.addEventListener("click",bn),a.clientWidth,x(),Xe?.();function Ue(){H=null,P=null,x()}function vn(){import("./userGuideHtml.js").then(e=>vi({buildWaferMap:ci,renderWaferMap,renderWaferGallery:void 0,analyzeWaferMap:fi},e.USER_GUIDE_HTML,An,N))}return{setDies(e){ae=e,Oe(),x(),z&&ue()},setResult(e){st=e,J=e.wafer,ae=e.dies,$=e.hbinDefs,G=e.sbinDefs,ee=e.testDefs,se=e.metadataFields,Nt=e.reticles?.length?e.reticles:void 0,Kt=e.reticleConfig,Vt=e.view?.dataAxisFlip,lt=e.isLotStack,rt=e.aggrMethod,dt=e.lotSize,Nn(),Oe(),x(),z&&ue()},setOptions(e){en(e)},getOptions(){return{...l}},resetZoom:Ue,setSelection(e){E=new Set(e.map(t=>Ee(t))),x()},clearSelection(){E=new Set,de?.([]),x()},setFallbackFormat(e){De=e,Oe(),x()},setStatsSummary(e){if(ie=e,Xt(),Ut(),z)ue();else if(I)je();else if(e&&!Be?.placement){const t=Be?.defaultOpen??!he;I=Tt("right",g),I.style.display=t?"block":"none";const n=C.parentElement,o=C.nextSibling;te=Pt(C,I,"right"),n?.insertBefore(te,o),je()}Ze()},setSummaryVisible(e){W&&(W.style.display=e?"flex":"none")},setViewControlsVisible(e){D&&(D.style.display=e?"flex":"none")},setExpandVisible(e){Z&&(Z.style.display=e?"flex":"none")},setHelpButtonVisible(e){$e&&($e.style.display=e?"flex":"none")},setMetadataBadgeVisible(e){jt=!e,T&&(T.el.style.display=e&&!me?"":"none")},openUserGuide:vn,setInsightsOpen(e){ct(e),F&&(e?(F.dataset.active="1",F.style.background=w.bgActive,F.style.color=w.iconActive):(delete F.dataset.active,F.style.background="transparent",F.style.color=w.icon))},closeSummaryPanel(){const e=z??I;!e||e.style.display==="none"||(e.style.display="none",W&&(delete W.dataset.active,W.style.background="transparent",W.style.color=w.icon))},setTooltipParent(e){v&&hi(e)},getActiveLegend(){const e=l.plotMode;if(e==="metadata"){const i=l.activeMetadataKey;if(!i)return null;const r=se?.find(s=>s.key===i),u=[...new Set(ae.map(s=>s.metadata?.[i]).filter(s=>s!=null&&(typeof s=="string"||typeof s=="number"||typeof s=="boolean")).map(String))].sort();return u.length?u.map((s,d)=>{const c=r?.values?.find(h=>h.value===s),p=c?.color??Fi(d);return{bin:s,name:c?.label??s,color:p}}):null}if(e!=="hardBin"&&e!=="softBin")return null;const t=e==="hardBin",n=t?$:G,o=[...new Set(ae.map(i=>t?i.hbin:i.sbin).filter(i=>i!==void 0))].sort((i,r)=>i-r);return o.length?o.map(i=>{const r=n?.find(s=>s.bin===i),u=r?.color??(t?Hi(i):Ai(i));return{bin:i,name:r?.name??`Bin ${i}`,color:u}}):null},destroy(){Se?.close(),we&&clearTimeout(we),qt?.()?.remove(),gt&&g.removeEventListener("click",gt,!0),a.removeEventListener("wheel",nn),a.removeEventListener("pointerdown",an),a.removeEventListener("pointermove",sn),a.removeEventListener("pointerup",ln),a.removeEventListener("pointerleave",rn),a.removeEventListener("pointercancel",dn),a.removeEventListener("dblclick",yn),a.removeEventListener("keydown",hn),a.removeEventListener("keyup",mn),a.removeEventListener("click",bn),pn.disconnect(),Re.removeEventListener("change",Qe),fn.removeEventListener("change",un),K.removeEventListener("blur",gn),Xn(),v&&ot(g),B?.remove(),fe&&(fe.parentElement?.insertBefore(C,fe),fe.remove()),te&&(te.parentElement?.insertBefore(C,te),te.remove()),C.remove(),a.style.cursor="",le?.destroy(),T?.destroy(),q.remove()}}}
|
|
1
|
+
import{buildView as oi,buildHoverText as ai,findTestDef as it,resolveTestNumber as Dt}from"../renderer/buildView.js";import{toCanvas as si,BIN_LEGEND_W as wn,BIN_LEGEND_W_COMPACT as li,BIN_LEGEND_ADAPT_COMPACT as ri,BIN_LEGEND_ADAPT_FLOATING as di}from"./toCanvas.js";import{buildWaferMap as ci,getTestPassStatus as pi,isParametricTest as Bt}from"../renderer/buildWaferMap.js";import{analyzeWaferMap as fi}from"../stats/analyzeWaferMap.js";import{CLR as S,Z_BASE as ui,applyOverlayZ as gi,getTooltip as Sn,hideTooltip as ot,reparentTooltip as hi,positionTooltip as kt,createToolbarHelpers as mi,buildModeMenuEl as yi,openReparentedModal as bi,openUserGuideWindow as vi,makePaletteBtn as xi,makeLogScaleBtn as wi,makeLegendStyleBtn as Si,makeOverlaysBtn as Ci,makeOrientationBtn as Mi,menuLayerFor as Cn,saveImageBlob as Ei,markMenuTrigger as Ye,wireMenuA11y as Mn,wireExpandToggle as Di,nextFrame as Lt,passFailMenuRows as Bi,requestedPassFailDisplay as Tt,logWmapVersionOnce as ki,buildDataModeEntries as Li,metadataKeyHasData as Ti,metadataModeEntry as Pi}from"./toolbar.js";import{createSummaryPanelEl as Pt,wrapWithSummaryPanel as Ot,renderWaferSummaryContent as Oi}from"./summaryPanel.js";import{collectWarnings as Ri,buildWarningsMenuEl as Ii,severityOf as Fi}from"./warnings.js";import"../stats/facets.js";import{ICONS as En}from"./icons.js";import{hardBinColor as Wi,softBinColor as Hi,metadataValueColor as Ai}from"../renderer/colorMap.js";import{createInsightsTab as Yi}from"./insightsTab.js";import{createMetadataBadge as zi}from"./metadataBadge.js";import{getDieKey as Ee,hasPosition as Dn,isPositionedDie as Xi}from"../core/dies.js";import{buildDieListSection as Ni}from"./dieList.js";import{buildMaplessSummary as Ki}from"./maplessSummary.js";const Bn=new Set(["colorScheme","rotation","flipX","flipY","showDieLabels","showPartialDies","showRingBoundaries","showQuadrantBoundaries","showReticle","showXYIndicator","ringCount","legendPosition","logScale","colorbarRangeMode","markFailingDies"]);export function classifyChanged(N){const m=N.some(g=>Bn.has(g)),C=N.some(g=>!Bn.has(g));return m&&C?"mixed":m?"preference":"state"}export function renderWaferMap(N,m,C={}){ki();const g=N.ownerDocument,K=g.defaultView??window;K.getComputedStyle(N).position==="static"&&(N.style.position="relative");const kn=N.clientHeight;C.height!=null&&(N.style.height=typeof C.height=="number"?`${C.height}px`:C.height);const at=m.dataCoverage?m.dataCoverage.unpositionedDies:m.dies.filter(e=>!Dn(e)).length,ze=(m.dataCoverage?m.dataCoverage.totalDies:m.dies.length-at)===0&&at>0,q=g.createElement("div");Object.assign(q.style,{position:"relative",width:"100%",height:"100%"}),C.maxSize!=null&&(q.style.maxWidth=`${C.maxSize}px`,q.style.maxHeight=`${C.maxSize}px`),N.appendChild(q);const M=g.createElement("div");Object.assign(M.style,{position:"relative",width:"100%",height:"100%"});const a=g.createElement("canvas");Object.assign(a.style,{width:"100%",height:"100%",display:"block"}),M.appendChild(a),q.appendChild(M);let Xe=null;if(at>0){let n=function(){if(t){const u=Ni(e,m.testDefs,{...C.dieList,onSaveText:C.onSaveText,waferMetadata:J.metadata,metadataFields:le,ownerDocument:g});if(u)return u}const i=it(m.testDefs,l.activeTest??0),d=Bt(i)?l.logScale??i?.logScale??!1:!1;return Ki(e,m.testDefs,{plotMode:l.plotMode??"hardBin",activeTest:l.activeTest,hbinDefs:$,sbinDefs:G,colorScheme:l.colorScheme,logScale:d,colorbarRangeMode:l.colorbarRangeMode,valueRangeDies:m.dies})},o=function(i){const d=g.createElement("button");return d.type="button",Object.assign(d.style,{fontSize:"10px",padding:"2px 6px",borderRadius:"4px",flexShrink:"0",border:`1px solid ${S.menuBorder}`,background:S.menuBg,color:S.text,cursor:"pointer"}),d.textContent=t?"View chart":"View die list",d.addEventListener("click",u=>{u.stopPropagation(),t=!t,d.textContent=t?"View chart":"View die list",i()}),d};const e=m.dies.filter(i=>!Dn(i));let t=!1;if(ze){const i=g.createElement("div");Object.assign(i.style,{position:"absolute",inset:"0",background:S.panelBg,padding:"12px",paddingTop:C.showToolbar??!0?"44px":"12px",boxSizing:"border-box",overflow:"hidden",display:"flex",flexDirection:"column",gap:"8px",zIndex:"1"});const d=g.createElement("div");Object.assign(d.style,{display:"flex",justifyContent:"space-between",alignItems:"flex-start",gap:"8px"});const u=g.createElement("span");Object.assign(u.style,{fontSize:"11px",color:S.label,lineHeight:"1.4"}),u.textContent="No die position data for this wafer.",d.appendChild(u);const s=g.createElement("div");Object.assign(s.style,{flex:"1",minHeight:"0",overflow:"auto",display:"flex",flexDirection:"column"}),d.appendChild(o(()=>s.replaceChildren(n()))),i.appendChild(d),i.appendChild(s),M.appendChild(i),Xe=()=>{t||s.replaceChildren(n())}}else{const i=g.createElement("div");Object.assign(i.style,{position:"absolute",left:"0",right:"0",bottom:"0",zIndex:"3",background:S.panelBg,borderTop:`1px solid ${S.menuBorder}`,fontSize:"11px",color:S.text,cursor:"pointer",padding:"4px 8px",display:"flex",alignItems:"center",justifyContent:"space-between",gap:"8px"});const d=g.createElement("span");d.textContent=`+${e.length} ${e.length===1?"die":"dies"} without position data`,i.appendChild(d);const u=g.createElement("span");u.textContent="\u25BE",Object.assign(u.style,{fontSize:"12px",lineHeight:"1",color:S.label,flexShrink:"0"}),i.appendChild(u),i.setAttribute("aria-expanded","false"),i.setAttribute("aria-label",`${e.length} dies without position data. Click to view.`);let s=null,r=null;Di(i,p=>{if(u.textContent=p?"\u25B4":"\u25BE",i.setAttribute("aria-expanded",String(p)),p){s=g.createElement("div");const c=i.getBoundingClientRect().height||28;Object.assign(s.style,{position:"absolute",left:"0",right:"0",bottom:`${c}px`,top:"20%",zIndex:"2",background:S.panelBg,borderTop:`1px solid ${S.menuBorder}`,padding:"8px",boxSizing:"border-box",display:"flex",flexDirection:"column",gap:"8px"}),s.addEventListener("click",Q=>Q.stopPropagation());const h=g.createElement("div");Object.assign(h.style,{display:"flex",justifyContent:"flex-end"}),h.appendChild(o(()=>{r&&r.replaceChildren(n())})),s.appendChild(h),r=g.createElement("div"),Object.assign(r.style,{flex:"1",minHeight:"0",overflow:"auto",display:"flex",flexDirection:"column"}),r.appendChild(n()),s.appendChild(r),M.appendChild(s)}else s&&(s.remove(),s=null,r=null)}),M.appendChild(i),Xe=()=>{r&&!t&&r.replaceChildren(n())}}}const{onHover:Ne,onClick:Ln,onSelect:ce,onViewOptionsChange:Tn,showTooltip:Pn=!0,showToolbar:he=!0,showMetadataBadge:On=!0,toolbarControls:Rt="full",showPlotModeSelector:Rn=!0,minZoom:In=.4,maxZoom:Fn=20,summaryPanel:De,renderTooltip:It,passBins:st=[1],showHelpButton:Wn=!1,userGuideExtension:Hn,onExpand:Ft,showExpandButton:Wt=!0,zIndex:An,insights:Ht,warnings:At,viewOptions:Yn={},...ie}=C,zn=Ht?.enabled??!1,Yt=At?.display??!0,Xn=gi(An);let Be=ie.fallbackFormat,oe=C.statsSummary,ae=[],zt=!1;function Xt(){const e=Ri({result:m,statsSummary:oe}),t=e.length!==ae.length||e.some((n,o)=>n.code!==ae[o]?.code||n.message!==ae[o]?.message);ae=e,(t||!zt)&&(zt=!0,At?.onWarning?.(e))}Xt();let lt=m,J=m.wafer,se=m.dies,E=new Set,$=m.hbinDefs,G=m.sbinDefs,ee=m.testDefs,le=m.metadataFields,Nt=m.reticles?.length?m.reticles:void 0,Kt=m.reticleConfig,Vt=m.view?.dataAxisFlip,rt=m.isLotStack??!1,dt=m.aggrMethod,ct=m.lotSize,jt=!1,T=null;On&&(T=zi(J.metadata,{lotStack:_t(),ownerDocument:g}),T.isEmpty()||M.appendChild(T.el));function _t(){return rt?{lotSize:ct??1,aggrMethod:dt}:void 0}function Nn(){if(!T)return;T.update(J.metadata,_t());const e=T.el.isConnected;T.isEmpty()&&e?T.el.remove():!T.isEmpty()&&!e&&M.appendChild(T.el)}const $t=[...$??[],...G??[]].some(e=>e.color);let l={plotMode:"hardBin",colorScheme:$t?"custom":"default",showDieLabels:!1,showPartialDies:!0,showRingBoundaries:!1,showQuadrantBoundaries:!1,showReticle:!1,showXYIndicator:!1,ringCount:4,rotation:0,flipX:!1,flipY:!1,legendPosition:ie.legendPosition??"default",...Yn},re=null,me=!1;zn&&(re=Yi({getItems:()=>[{wafer:J,dies:se,hbinDefs:$,sbinDefs:G,testDefs:ee,label:String(J.metadata?.waferId??""),statsSummary:oe}],getColorSchemeName:()=>l.colorScheme??"default",passBins:st,getRingCount:()=>l.ringCount??4,onSaveImage:C.onSaveImage,onSaveText:C.onSaveText,defaultView:Ht?.defaultView,backTab:{label:"Map",onBack:()=>pt(!1)},ownerDocument:g}),Object.assign(re.el.style,{position:"absolute",inset:"0",background:S.panelBg,overflowY:"auto",paddingTop:he?"44px":"0"}),q.appendChild(re.el));function pt(e){re&&(me=e,re.el.style.display=e?"flex":"none",H&&(H.style.display=e||ze?"none":"flex"),k&&(k.style.display=e?"none":"flex"),Z&&(Z.style.display=e?"none":"flex"),T&&(T.el.style.display=e||jt?"none":""),Ze(),A&&(A.innerHTML=e?En.wafer:En.analysis,A.ariaLabel=e?"Back to wafer view":"Insights"),e&&re.render())}let y,Gt,W=null,P=null,ft=[],ke=null,ut=ie.legendOffset??{x:0,y:0},Le=!1,ye=!1,Te={x:0,y:0},gt={x:0,y:0},pe=!1,be=!1,Y="pan",ve={x:0,y:0},Ke={x:0,y:0},O={x:0,y:0},R={x:0,y:0},Pe=!1,xe=!1;function Oe(){const e=l;y=oi(J,se.filter(Xi),{plotMode:e.plotMode,colorScheme:e.colorScheme,passBins:st,showDieLabels:e.showDieLabels,showPartialDies:e.showPartialDies,showRingBoundaries:e.showRingBoundaries,showQuadrantBoundaries:e.showQuadrantBoundaries,showReticle:e.showReticle,showXYIndicator:e.showXYIndicator,reticles:Nt,ringCount:e.ringCount,highlightBin:e.highlightBin,highlightMetadataValue:e.highlightMetadataValue,activeTest:e.activeTest,activeMetadataKey:e.activeMetadataKey,testDefs:ee,valueRange:e.valueRange,logScale:e.logScale,isLotStack:rt,aggregationMethod:dt??e.aggregationMethod,lotSize:ct??e.lotSize,dataAxisFlip:Vt,colorbarRangeMode:e.colorbarRangeMode,passFailDisplay:e.passFailDisplay,fallbackFormat:Be,interactiveTransform:{rotation:e.rotation??0,flipX:e.flipX??!1,flipY:e.flipY??!1}},{hbinDefs:$,sbinDefs:G,metadataFields:le}),Gt=new Map(y.dies.map((t,n)=>[Ee(t),n]))}Oe();let z=null,fe=null,Ve=null,Kn={},I=null,te=null;function Vn(e){const{kind:t,index:n}=e.variable;x(t==="test"?{plotMode:"value",activeTest:n??0,highlightBin:void 0}:t==="softBin"?{plotMode:"softBin",highlightBin:void 0}:{plotMode:"hardBin",highlightBin:void 0});const o=e.highlight;o.kind==="bin"?(xt(o.dieKeys),x({highlightBin:o.bin})):(o.kind==="region"||o.kind==="dies")&&xt(o.dieKeys)}function Zt(e){Oi(e,{wafer:J,dies:se,yieldSummary:lt.yield,dataCoverage:lt.dataCoverage,hbinDefs:$,sbinDefs:G,testDefs:ee,statsSummary:oe,warnings:Yt?ae:[],passBins:st,ringCount:l.ringCount??4,colorScheme:l.colorScheme,fallbackFormat:Be,activeFindingId:Ve,findingsFilter:Kn,onFindingsFilterChange:ue,onSaveText:C.onSaveText,metadataFields:le,dieListOptions:C.dieList,onFindingClick:(t,n)=>{Ve===t.id?(Ve=null,xt([]),x({highlightBin:void 0})):(Ve=t.id,Vn(t)),ue()}})}function ue(){z&&Zt(z)}function je(){I&&Zt(I)}function Qt(e,t){he&&(t==="right"||t==="top")&&(e.style.paddingTop="44px")}if(De?.placement){const e=De.placement;z=Pt(e,g),Qt(z,e);const t=M.parentElement,n=M.nextSibling;fe=Ot(M,z,e),t?.insertBefore(fe,n),ue()}else if(oe){const e=De?.defaultOpen??!he;I=Pt("right",g),Qt(I,"right"),I.style.display=e?"block":"none";const t=M.parentElement,n=M.nextSibling;te=Ot(M,I,"right"),t?.insertBefore(te,n),je()}const v=Pn?Sn(g):null;let D=null,B=null,H=null,k=null,_e=null,F=null,Z=null,$e=null,A=null,ne=null,Ge=null;function Ut(){if(!ne||!Ge)return;const e=ae.length,t=e>0;if(ne.style.display=t?"flex":"none",Ge.style.display=t?"":"none",!t)return;const n=Fi(ae[0]),o=`${e} data ${e===1?"warning":"warnings"}`;ne.style.color=n==="error"?S.errText:S.warnText,ne.ariaLabel=n==="error"?`${o} \u2014 the map may be positionally wrong`:o}const jn=24;let we=null,ht=null,qt=null,mt=null,yt=null,bt=null,vt=null;function xt(e){E=new Set(e??[]),ce&&ce(Mt()),w()}function Ze(){if(!F)return;const e=!!(z??I);F.style.display=oe&&e&&!me?"flex":"none";const t=z??I,n=t?t.style.display!=="none":!1;oe?.hasNotableFindings&&!n?F.style.color=S.findingIndicator:F.dataset.active||(F.style.color=S.icon)}if(he){let Q=function(U){Y=U,o(V,U==="zoom"),o(Ie,U==="pan"),_e&&o(_e,U==="select"),a.style.cursor=U==="pan"?"grab":"crosshair"},qe=function(){we&&(clearTimeout(we),we=null),D&&(D.style.opacity="1")},Je=function(){we=setTimeout(()=>{D&&(D.style.opacity="0.35")},600)};D=g.createElement("div"),D.dataset.wmapToolbar="single",Object.assign(D.style,{position:"absolute",top:"4px",right:"4px",display:"flex",flexDirection:"row",alignItems:"center",flexWrap:"wrap-reverse",justifyContent:"flex-end",maxWidth:"calc(100% - 8px)",background:S.menuBg,border:`1px solid ${S.menuBorder}`,borderRadius:"4px",boxShadow:"0 1px 4px rgba(0,0,0,0.12)",zIndex:ui,opacity:"0.35",transition:"opacity 0.2s ease",pointerEvents:"auto"});const e=Sn(g),t=mi(e),{makeBtn:n,setActive:o,makeSep:i,makeMenuRow:d,makeMenuSection:u,makeDropdown:s,makeCheckMenuBtn:r,closeOpenMenu:p,getOpenMenu:c,setOpenMenu:h}=t;ht=p,qt=c,g.addEventListener("click",p,!0),H=g.createElement("div"),Object.assign(H.style,{display:ze?"none":"flex",alignItems:"center",gap:"0",flexWrap:"wrap",justifyContent:"flex-end"}),D.appendChild(H);const Me=n("download","Download PNG",Gn);H.appendChild(Me),H.appendChild(i());const V=n("zoomMode","Zoom (drag to zoom region)",()=>Q("zoom")),de=n("zoomIn","Zoom in",()=>Ce(a.clientWidth/2,a.clientHeight/2,1.2)),L=n("zoomOut","Zoom out",()=>Ce(a.clientWidth/2,a.clientHeight/2,1/1.2)),j=n("reset","Reset zoom (double-click)",()=>Ue());H.appendChild(V),H.appendChild(de),H.appendChild(L),H.appendChild(j),H.appendChild(i());const Ie=n("pan","Pan (drag to move)",()=>Q("pan"));if(H.appendChild(Ie),_e=n("boxSelect","Select (drag to select dies)",()=>Q("select")),H.appendChild(_e),o(Ie,!0),Rt!=="view-only"){let U=function(f){return f.plotMode!==(l.plotMode??"hardBin")?!1:f.plotMode==="value"?(l.activeTest??0)===(f.activeTest??0):f.plotMode==="metadata"?l.activeMetadataKey===f.activeMetadataKey:!0},Fe=function(f,b){f.activeTest!==void 0?x({plotMode:f.plotMode,activeTest:f.activeTest,activeMetadataKey:void 0,logScale:f.logScale}):f.activeMetadataKey!==void 0?x({plotMode:f.plotMode,activeTest:void 0,activeMetadataKey:f.activeMetadataKey,passFailDisplay:"off"}):x({plotMode:f.plotMode,activeTest:void 0,activeMetadataKey:void 0,passFailDisplay:"off"}),b.remove(),h(null),Ye(_,!1)};B=g.createElement("div"),Object.assign(B.style,{display:"flex",alignItems:"center",gap:"0",flexWrap:"wrap",justifyContent:"flex-end"}),D.appendChild(B),k=g.createElement("div"),Object.assign(k.style,{display:"flex",alignItems:"center",gap:"0"}),B.appendChild(k),k.appendChild(i());const et=()=>{const f=c();f&&(f.remove(),h(null)),Ye(_,!1)},_=n("mode","Plot mode",()=>{if(c()){et();return}const f=se,b=y.testDefs,{testEntries:nt,binEntries:ge,stackedEntries:We}=Li(f,b,{includeStacked:y.isLotStack}),Et=(le??[]).filter(Ae=>Ti(f,Ae.key)).map(Pi),He=yi(_.getBoundingClientRect(),nt,ge,We,U,Fe,{makeMenuRow:d,makeMenuSection:u},l.plotMode??"hardBin",_.ownerDocument.defaultView??window,Et);Cn(_).appendChild(He),h(He),Ye(_,!0),Mn(He,_,et)});Ye(_,!1);const{btn:Zn,sync:Qn}=xi(t,()=>l.plotMode??"hardBin",()=>l.colorScheme??"default",()=>$t,f=>x({colorScheme:f}),{get:()=>l.markFailingDies??!1,set:f=>x({markFailingDies:f})});yt=Qn,yt();const Un=Ci(t,()=>{const f=!!y.hasReticle,b=(l.plotMode??"hardBin")==="value",{testNumber:nt}=Dt(l.activeTest??0,y.testDefs),ge=it(y.testDefs,nt),We=b&&ge!==void 0&&!Bt(ge),Et=b&&!We&&(ge?.limitLow!==void 0||ge?.limitHigh!==void 0),He=b&&!We&&y.dies.some(Ae=>pi(Ae,nt,ge)!==void 0);return[{label:"Ring boundaries",active:!!l.showRingBoundaries,onClick:()=>x({showRingBoundaries:!l.showRingBoundaries})},{label:"Quadrant lines",active:!!l.showQuadrantBoundaries,onClick:()=>x({showQuadrantBoundaries:!l.showQuadrantBoundaries})},{label:"Die labels",active:!!l.showDieLabels,onClick:()=>x({showDieLabels:!l.showDieLabels})},{label:"Reticle grid",active:!!l.showReticle,enabled:f,onClick:()=>x({showReticle:!l.showReticle})},{label:"XY indicator",active:!!l.showXYIndicator,onClick:()=>x({showXYIndicator:!l.showXYIndicator})},...Bi({functionalActive:We,hasLimits:Et,hasRecorded:He,display:Tt(l)},Ae=>x({passFailDisplay:Ae}))]},()=>!!(l.showRingBoundaries||l.showQuadrantBoundaries||l.showDieLabels||l.showReticle||l.showXYIndicator||Tt(l)!=="off")),{btn:qn,sync:Jn}=Si(t,()=>l,f=>x({legendPosition:f}));mt=Jn,mt();const xn=()=>{const{testNumber:f}=Dt(l.activeTest??0,ee),b=it(ee,f);return b!==void 0&&!Bt(b)},{btn:ei,sync:ti}=wi(t,()=>({...l,functionalActive:xn()}),f=>x(f));bt=ti,bt();const ni=()=>{const{testNumber:f}=Dt(l.activeTest??0,ee),b=it(ee,f);return b!==void 0&&(b.limitLow!==void 0||b.limitHigh!==void 0)},tt=n("specRange","Colorbar range: spec limits",()=>{const f=l.colorbarRangeMode==="data"?"spec":"data";x({colorbarRangeMode:f})});vt=()=>{const f=l.plotMode==="value"&&ni()&&Tt(l)==="off"&&!xn();tt.style.display=f?"":"none";const b=(l.colorbarRangeMode??"spec")==="spec";o(tt,b),tt.ariaLabel=b?"Colorbar range: spec limits (click for data range)":"Colorbar range: data range (click for spec limits)"},vt();const ii=Mi(t,()=>l,f=>x(f));Rn&&k.appendChild(_),k.appendChild(Zn),k.appendChild(ei),k.appendChild(tt),ze||(k.appendChild(i()),k.appendChild(Un),k.appendChild(i()),k.appendChild(qn),k.appendChild(i()),k.appendChild(ii)),oe&&(F=n("findings","Summary panel",()=>{const f=z??I;if(!f)return;const b=f.style.display!=="none";f.style.display=b?"none":"block",o(F,!b),Ze()}),B.appendChild(i()),B.appendChild(F),I?.style.display!=="none"&&o(F,!0),Ze()),Yt&&(Ge=i(),ne=n("warning","Data warnings",()=>{const f=c();if(p(new MouseEvent("click")),f)return;const b=Ii(ne.getBoundingClientRect(),ae,K);Cn(q).appendChild(b),h(b),Mn(b,ne,()=>p(new MouseEvent("click")))}),Ye(ne,!1),B.appendChild(Ge),B.appendChild(ne),Ut()),Wt&&(B.appendChild(i()),Z=n("expand","Expand (E)",Ft??Jt),B.appendChild(Z)),re&&(B.appendChild(i()),A=n("analysis","Insights",()=>{pt(!me),o(A,me)}),A.dataset.wmapInsightsBtn="1",B.appendChild(A)),Wn&&(B.appendChild(i()),$e=n("help","User guide",()=>vn()),B.appendChild($e))}q.appendChild(D),a.addEventListener("mouseenter",qe),a.addEventListener("mouseleave",Je),D.addEventListener("mouseenter",qe),D.addEventListener("mouseleave",Je)}let Se=null;function Jt(){Se&&(Se.close(),Se=null);const e=fe??te??M;e.style.flex="1",e.style.minWidth="0",e.style.minHeight="0";const t=bi(D?[e,D]:[e],{ownerDocument:g,onClosed:()=>{Se=null,Z&&(Z.style.display="flex"),a.focus({preventScroll:!0})}});t&&(D&&(t.contentWrap.style.position="relative"),Se=t,Z&&(Z.style.display="none"))}function en(e){const t=l.plotMode;if(l={...l,...e},e.plotMode!==void 0&&e.plotMode!==t){W=null;const i=l.plotMode;(i==="hardBin"||i==="softBin")&&!new Set(["default","accessible","custom"]).has(l.colorScheme??"")&&(l={...l,colorScheme:"default"})}Object.keys(e).every(i=>i==="legendPosition"||i==="showLegend"||i==="markFailingDies")||Oe(),mt?.(),yt?.(),bt?.(),vt?.(),w();const o=e.plotMode!==void 0&&e.plotMode!==t;(e.colorScheme!==void 0||o)&&(ue(),je()),(e.colorScheme!==void 0||o||e.activeTest!==void 0||e.logScale!==void 0||e.colorbarRangeMode!==void 0)&&Xe?.()}function x(e){en(e);const t=Object.keys(e);Tn?.(l,t,classifyChanged(t))}let wt=!1;function St(){wt||(wt=!0,Lt(()=>{wt=!1,w()},K))}function w(){const e=P??void 0,t=y.dies[0],n=t?{x:t.width,y:t.height}:ie.diePitchMm,o=Math.floor(a.clientWidth||a.width),i=!!($?.length||G?.length||y.dies.some(h=>h.hbin!=null||h.sbin!=null)),d=l.legendPosition??"default",u=l.showLegend??!0,s=d==="default"||d==="compact",r=(ie.colorbarWidth??16)+28,p=i&&s?d!=="default"?Math.max(wn,r):o<di?0:o<ri?Math.max(li,r):Math.max(wn,r):void 0,c=si(a,y,{...ie,topClearance:he?jn:0,minRightReserve:u?p:0,showColorbar:u&&(ie.showColorbar??!0),markFailingDies:l.markFailingDies??!1,legendPosition:d,legendOffset:ut,diePitchMm:n,fallbackFormat:Be,showAxes:ie.showAxes??P!==null,viewport:e,activeBin:l.plotMode==="metadata"?l.highlightMetadataValue:l.highlightBin,hbinDefs:$,sbinDefs:G,metadataFields:le});ft=c.binLegendRows,ke=c.legendBox??null,W||(W=c.viewport),E.size>0&&_n(),be&&$n()}function _n(){const e=X();if(!e)return;const t=a.getContext("2d"),n=y.hoverPoints,o=y.rectangles[0],i=o?o.width/2*e.ppm:e.ppm*.5,d=o?o.height/2*e.ppm:e.ppm*.5,u=Math.max(1,Math.min(3,i*.08)),s=i-u,r=d-u,p=[];for(const c of E){const h=Gt.get(c);h!==void 0&&p.push({sx:e.originX+n[h].x*e.ppm,sy:e.originY-n[h].y*e.ppm})}if(p.length){t.save(),t.setLineDash([]),t.fillStyle="rgba(0,0,0,0.12)",t.beginPath();for(const{sx:c,sy:h}of p)t.rect(c-s,h-r,s*2,r*2);t.fill(),t.strokeStyle="rgba(255,255,255,0.9)",t.lineWidth=3,t.beginPath();for(const{sx:c,sy:h}of p)t.rect(c-s,h-r,s*2,r*2);t.stroke(),t.strokeStyle="rgba(0,0,0,0.9)",t.lineWidth=1.5,t.beginPath();for(const{sx:c,sy:h}of p)t.rect(c-s,h-r,s*2,r*2);t.stroke(),t.restore()}}function $n(){const e=a.getContext("2d"),t=Math.min(O.x,R.x),n=Math.min(O.y,R.y),o=Math.abs(R.x-O.x),i=Math.abs(R.y-O.y);e.save(),e.fillStyle="rgba(0,0,0,0.08)",e.fillRect(t,n,o,i),e.setLineDash([5,3]),e.strokeStyle="rgba(255,255,255,0.9)",e.lineWidth=3,e.strokeRect(t,n,o,i),e.strokeStyle="rgba(0,0,0,0.9)",e.lineWidth=1.5,e.strokeRect(t,n,o,i),e.restore()}function Gn(){a.toBlob(e=>{e&&Ei(e,C.downloadFilename??"wafermap",C.onSaveImage)})}function tn(e){return W?Math.max(W.ppm*In,Math.min(W.ppm*Fn,e)):e}function Ce(e,t,n){const o=P??W;if(!o)return;const i=tn(o.ppm*n),d=i/o.ppm,u=e-(e-o.originX)*d,s=t-(t-o.originY)*d,r=(W?.snapDist??1)/(i/(W?.ppm??i));P={originX:u,originY:s,ppm:i,snapDist:r},w()}function X(){return P??W}function nn(e){if(e.ctrlKey||e.metaKey){e.preventDefault();const t=a.getBoundingClientRect(),n=e.deltaY<0?1.12:1/1.12;Ce(e.clientX-t.left,e.clientY-t.top,n)}else if(P!==null){e.preventDefault();const t=X(),n=P.snapDist;P={originX:t.originX-e.deltaX,originY:t.originY-e.deltaY,ppm:t.ppm,snapDist:n},w()}}function on(e,t,n){return e>=n.x&&e<n.x+n.w&&t>=n.y&&t<n.y+n.h}function an(e){if(e.button!==0||!X())return;a.focus({preventScroll:!0}),a.setPointerCapture(e.pointerId);const t=a.getBoundingClientRect(),n=e.clientX-t.left,o=e.clientY-t.top;if(ke&&l.legendPosition==="floating"&&on(n,o,ke)){ye=!0,Te={x:n,y:o},gt={...ut};return}if(Pe&&Y!=="pan"){xe=!0,pe=!0,ve={x:n,y:o},Ke={x:X().originX,y:X().originY},a.style.cursor="grabbing";return}if(Y==="zoom"||Y==="select"){be=!0,O=R={x:n,y:o};return}pe=!0,ve={x:n,y:o},Ke={x:X().originX,y:X().originY},a.style.cursor="grabbing"}function sn(e){const t=a.getBoundingClientRect(),n=e.clientX-t.left,o=e.clientY-t.top;if(be){R={x:n,y:o},St();return}if(ye){const c=n-Te.x,h=o-Te.y;c*c+h*h>16&&(ye=!1,Le=!0,a.style.cursor="grabbing")}if(Le){ut={x:gt.x+(n-Te.x),y:gt.y+(o-Te.y)},St();return}if(pe){const c=X(),h=P?.snapDist??W?.snapDist??1;P={originX:Ke.x+(n-ve.x),originY:Ke.y+(o-ve.y),ppm:c.ppm,snapDist:h},St();return}const i=X();if(!i)return;const d=(n-i.originX)/i.ppm,u=(i.originY-o)/i.ppm,r=cn(d,u,i.snapDist)?.die??null,p=ft.find(c=>n>=c.x&&n<c.x+c.w&&o>=c.y&&o<c.y+c.h);if(p){a.style.cursor="pointer",v&&(v.innerHTML=p.label??`Bin ${p.bin}`,v.style.display="block",kt(v,a,e.clientX,e.clientY)),Ne?.(null,e);return}if(Y==="pan"&&(a.style.cursor=r?"crosshair":"grab"),v)if(r)if(It){const c=It(r);c===null?v.style.display="none":(typeof c=="string"?v.innerHTML=c:(v.innerHTML="",v.appendChild(c)),v.style.display="block",kt(v,a,e.clientX,e.clientY))}else v.innerHTML=ai(r,y.plotMode,{testDefs:ee,hbinDefs:$,sbinDefs:G,fallbackFormat:Be,aggrMethod:y.aggrMethod,lotSize:y.lotSize,waferMeta:J.metadata,metadataFields:le,activeTest:y.activeTest,reticleConfig:Kt}),v.style.display="block",kt(v,a,e.clientX,e.clientY);else v.style.display="none";Ne?.(r,e)}function ln(e){const t=a.getBoundingClientRect(),n=e.clientX-t.left,o=e.clientY-t.top,i=e.ctrlKey||e.metaKey;if(v&&(n<0||o<0||n>t.width||o>t.height)&&(v.style.display="none"),be){be=!1,R={x:n,y:o};const s=n-O.x,r=o-O.y,p=X();if(Y==="zoom"){if(s*s+r*r<25)Ce(n,o,2);else if(p){const c=Math.min(O.x,R.x),h=Math.max(O.x,R.x),Q=Math.min(O.y,R.y),Me=Math.max(O.y,R.y),V=h-c,de=Me-Q;if(V>4&&de>4){const L=a.clientWidth,j=a.clientHeight,Ie=L/V,qe=j/de,Je=Math.min(Ie,qe),U=tn(p.ppm*Je),Fe=U/p.ppm,et=(c+h)/2,_=(Q+Me)/2;P={originX:L/2-(et-p.originX)*Fe,originY:j/2-(_-p.originY)*Fe,ppm:U,snapDist:p.snapDist/Fe}}}w(),a.style.cursor="crosshair";return}if(s*s+r*r<25)Ct(n,o,i,e);else if(p){const c=(Math.min(O.x,R.x)-p.originX)/p.ppm,h=(Math.max(O.x,R.x)-p.originX)/p.ppm,Q=(p.originY-Math.max(O.y,R.y))/p.ppm,Me=(p.originY-Math.min(O.y,R.y))/p.ppm,V=y.hoverPoints,de=[];for(let L=0;L<V.length;L++)if(V[L].x>=c&&V[L].x<=h&&V[L].y>=Q&&V[L].y<=Me){const j=y.dies[L];j&&de.push(j)}if(i)for(const L of de){const j=Ee(L);E.has(j)?E.delete(j):E.add(j)}else E=new Set(de.map(L=>Ee(L)));ce?.(Mt())}w(),a.style.cursor="crosshair";return}if(ye){ye=!1,Ct(n,o,i,e);return}if(Le){Le=!1,a.style.cursor="grab";return}if(!pe)return;if(pe=!1,xe){xe=!1,a.style.cursor=Pe||Y==="pan"?"grab":"crosshair";return}a.style.cursor=Y==="pan"?"grab":"crosshair";const d=n-ve.x,u=o-ve.y;d*d+u*u<25&&Ct(n,o,i,e)}function Ct(e,t,n,o){for(const s of ft)if(e>=s.x&&e<s.x+s.w&&t>=s.y&&t<s.y+s.h){if(typeof s.bin=="number"){const r=l.highlightBin===s.bin?void 0:s.bin;x({highlightBin:r})}else{const r=l.highlightMetadataValue===s.bin?void 0:s.bin;x({highlightMetadataValue:r})}return}if(ke&&on(e,t,ke))return;const i=X();if(!i)return;const u=cn((e-i.originX)/i.ppm,(i.originY-t)/i.ppm,i.snapDist)?.die??null;if(u){Ln?.(u,o);const s=Ee(u);n?E.has(s)?E.delete(s):E.add(s):E=new Set([s]),ce?.(Mt()),w()}else n||(E=new Set,ce?.([]),w())}function Mt(){const e=[],t=y.hoverPoints;for(let n=0;n<t.length;n++){const o=y.dies[n];o&&E.has(Ee(o))&&e.push(o)}return e}function rn(){v&&ot(g),Ne?.(null,new MouseEvent("mouseleave")),a.style.cursor=Y==="pan"?"grab":"crosshair"}function dn(){pe=!1,xe=!1,be=!1,ye=!1,Le=!1,v&&ot(g),Ne?.(null,new MouseEvent("mouseleave")),a.style.cursor=Y==="pan"?"grab":"crosshair",w()}function cn(e,t,n){const o=y.hoverPoints,i=y.rectangles;for(let r=0;r<i.length;r++){const p=i[r];if(Math.abs(e-p.x)<=p.width/2&&Math.abs(t-p.y)<=p.height/2){const c=y.dies[r];return c?{die:c,index:r}:null}}let d=null,u=-1,s=n*n;for(let r=0;r<o.length;r++){const p=o[r].x-e,c=o[r].y-t,h=p*p+c*c;h<s&&(s=h,d=y.dies[r]??null,u=r)}return d?{die:d,index:u}:null}const pn=new K.ResizeObserver(()=>{W=null,P=null,w()});pn.observe(a),C.height==null&&kn<=0&&Lt(()=>Lt(()=>{N.clientHeight>0||console.warn("[wafermap] The map container has zero height, so the map cannot render. renderWaferMap fills its container \u2014 give the container a resolved height: an explicit CSS `height` (e.g. 600px), a height-resolved flex/grid parent, or `position:absolute; inset:0`. Alternatively pass `{ height: 600 }` in the render options and the library will size it for you.")}));let Re=K.matchMedia(`(resolution: ${K.devicePixelRatio}dppx)`);const Qe=()=>{Re.removeEventListener("change",Qe),Re=K.matchMedia(`(resolution: ${K.devicePixelRatio}dppx)`),Re.addEventListener("change",Qe),w()};Re.addEventListener("change",Qe);const fn=K.matchMedia("(prefers-color-scheme: dark)"),un=()=>w();fn.addEventListener("change",un);const gn=()=>{v&&ot(g)};K.addEventListener("blur",gn);function hn(e){if(e.key==="Escape"&&E.size>0&&(E=new Set,ce?.([]),w()),(e.key==="e"||e.key==="E")&&Rt!=="view-only"&&Wt&&!me&&(e.stopPropagation(),(Ft??Jt)()),(e.ctrlKey||e.metaKey)&&(e.key==="="||e.key==="+"?(e.preventDefault(),Ce(a.clientWidth/2,a.clientHeight/2,1.2)):e.key==="-"?(e.preventDefault(),Ce(a.clientWidth/2,a.clientHeight/2,1/1.2)):e.key==="0"&&(e.preventDefault(),Ue())),!e.ctrlKey&&!e.metaKey&&!e.shiftKey){const n=X();if(n){const o=P?.snapDist??W?.snapDist??1;let i=0,d=0;e.key==="ArrowLeft"&&(i=20,e.preventDefault()),e.key==="ArrowRight"&&(i=-20,e.preventDefault()),e.key==="ArrowUp"&&(d=20,e.preventDefault()),e.key==="ArrowDown"&&(d=-20,e.preventDefault()),(i||d)&&(P={originX:n.originX+i,originY:n.originY+d,ppm:n.ppm,snapDist:o},w())}e.key===" "&&!Pe&&(e.preventDefault(),Pe=!0,Y!=="pan"&&(a.style.cursor="grab"))}}function mn(e){e.key===" "&&(Pe=!1,xe&&(pe=!1,xe=!1),a.style.cursor=Y==="pan"?"grab":"crosshair")}a.style.cursor="grab",a.setAttribute("tabindex","0"),a.addEventListener("wheel",nn,{passive:!1}),a.addEventListener("pointerdown",an),a.addEventListener("pointermove",sn),a.addEventListener("pointerup",ln),a.addEventListener("pointerleave",rn),a.addEventListener("pointercancel",dn);const yn=()=>Ue();a.addEventListener("dblclick",yn),a.addEventListener("keydown",hn),a.addEventListener("keyup",mn);const bn=e=>{e.stopPropagation()};a.addEventListener("click",bn),a.clientWidth,w(),Xe?.();function Ue(){W=null,P=null,w()}function vn(){import("./userGuideHtml.js").then(e=>vi({buildWaferMap:ci,renderWaferMap,renderWaferGallery:void 0,analyzeWaferMap:fi},e.USER_GUIDE_HTML,Hn,N))}return{setDies(e){se=e,Oe(),w(),z&&ue()},setResult(e){lt=e,J=e.wafer,se=e.dies,$=e.hbinDefs,G=e.sbinDefs,ee=e.testDefs,le=e.metadataFields,Nt=e.reticles?.length?e.reticles:void 0,Kt=e.reticleConfig,Vt=e.view?.dataAxisFlip,rt=e.isLotStack,dt=e.aggrMethod,ct=e.lotSize,Nn(),Oe(),w(),z&&ue()},setOptions(e){en(e)},getOptions(){return{...l}},resetZoom:Ue,setSelection(e){E=new Set(e.map(t=>Ee(t))),w()},clearSelection(){E=new Set,ce?.([]),w()},setFallbackFormat(e){Be=e,Oe(),w()},setStatsSummary(e){if(oe=e,Xt(),Ut(),z)ue();else if(I)je();else if(e&&!De?.placement){const t=De?.defaultOpen??!he;I=Pt("right",g),I.style.display=t?"block":"none";const n=M.parentElement,o=M.nextSibling;te=Ot(M,I,"right"),n?.insertBefore(te,o),je()}Ze()},setSummaryVisible(e){F&&(F.style.display=e?"flex":"none")},setViewControlsVisible(e){B&&(B.style.display=e?"flex":"none")},setExpandVisible(e){Z&&(Z.style.display=e?"flex":"none")},setHelpButtonVisible(e){$e&&($e.style.display=e?"flex":"none")},setMetadataBadgeVisible(e){jt=!e,T&&(T.el.style.display=e&&!me?"":"none")},openUserGuide:vn,setInsightsOpen(e){pt(e),A&&(e?(A.dataset.active="1",A.style.background=S.bgActive,A.style.color=S.iconActive):(delete A.dataset.active,A.style.background="transparent",A.style.color=S.icon))},closeSummaryPanel(){const e=z??I;!e||e.style.display==="none"||(e.style.display="none",F&&(delete F.dataset.active,F.style.background="transparent",F.style.color=S.icon))},setTooltipParent(e){v&&hi(e)},getActiveLegend(){const e=l.plotMode;if(e==="metadata"){const i=l.activeMetadataKey;if(!i)return null;const d=le?.find(s=>s.key===i),u=[...new Set(se.map(s=>s.metadata?.[i]).filter(s=>s!=null&&(typeof s=="string"||typeof s=="number"||typeof s=="boolean")).map(String))].sort();return u.length?u.map((s,r)=>{const p=d?.values?.find(h=>h.value===s),c=p?.color??Ai(r);return{bin:s,name:p?.label??s,color:c}}):null}if(e!=="hardBin"&&e!=="softBin")return null;const t=e==="hardBin",n=t?$:G,o=[...new Set(se.map(i=>t?i.hbin:i.sbin).filter(i=>i!==void 0))].sort((i,d)=>i-d);return o.length?o.map(i=>{const d=n?.find(s=>s.bin===i),u=d?.color??(t?Wi(i):Hi(i));return{bin:i,name:d?.name??`Bin ${i}`,color:u}}):null},destroy(){Se?.close(),we&&clearTimeout(we),qt?.()?.remove(),ht&&g.removeEventListener("click",ht,!0),a.removeEventListener("wheel",nn),a.removeEventListener("pointerdown",an),a.removeEventListener("pointermove",sn),a.removeEventListener("pointerup",ln),a.removeEventListener("pointerleave",rn),a.removeEventListener("pointercancel",dn),a.removeEventListener("dblclick",yn),a.removeEventListener("keydown",hn),a.removeEventListener("keyup",mn),a.removeEventListener("click",bn),pn.disconnect(),Re.removeEventListener("change",Qe),fn.removeEventListener("change",un),K.removeEventListener("blur",gn),Xn(),v&&ot(g),D?.remove(),fe&&(fe.parentElement?.insertBefore(M,fe),fe.remove()),te&&(te.parentElement?.insertBefore(M,te),te.remove()),M.remove(),a.style.cursor="",re?.destroy(),T?.destroy(),q.remove()}}}
|