@wafertools/wafermap 0.22.0 → 0.23.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +16 -5
- package/CHANGELOG.md +130 -1
- package/dist/packages/canvas-adapter/charts/chartShell.d.ts +1 -0
- package/dist/packages/canvas-adapter/charts/chartShell.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/dieList.d.ts +41 -0
- package/dist/packages/canvas-adapter/dieList.js +2 -0
- package/dist/packages/canvas-adapter/index.d.ts +2 -0
- package/dist/packages/canvas-adapter/index.js +1 -1
- package/dist/packages/canvas-adapter/insightsTab.js +1 -1
- package/dist/packages/canvas-adapter/maplessSummary.d.ts +34 -0
- package/dist/packages/canvas-adapter/maplessSummary.js +1 -0
- package/dist/packages/canvas-adapter/renderWaferGallery.d.ts +2 -18
- package/dist/packages/canvas-adapter/renderWaferGallery.js +8 -8
- package/dist/packages/canvas-adapter/renderWaferMap.d.ts +17 -1
- package/dist/packages/canvas-adapter/renderWaferMap.js +1 -1
- package/dist/packages/canvas-adapter/summaryPanel.d.ts +2 -0
- package/dist/packages/canvas-adapter/summaryPanel.js +3 -3
- package/dist/packages/canvas-adapter/userGuideHtml.d.ts +1 -1
- package/dist/packages/canvas-adapter/userGuideHtml.js +1 -1
- package/dist/packages/canvas-adapter/version.d.ts +2 -2
- package/dist/packages/canvas-adapter/version.js +1 -1
- package/dist/packages/canvas-adapter/warnings.d.ts +6 -1
- package/dist/packages/core/classify.d.ts +6 -2
- package/dist/packages/core/dies.d.ts +67 -7
- package/dist/packages/core/dies.js +1 -1
- package/dist/packages/core/inference/pitch.js +1 -1
- package/dist/packages/core/probe.d.ts +5 -0
- package/dist/packages/core/probe.js +1 -1
- package/dist/packages/core/transforms.d.ts +4 -4
- package/dist/packages/core/transforms.js +1 -1
- package/dist/packages/renderer/buildView.d.ts +3 -3
- package/dist/packages/renderer/buildView.js +1 -1
- package/dist/packages/renderer/buildWaferMap.d.ts +25 -8
- package/dist/packages/renderer/buildWaferMap.js +1 -1
- package/dist/packages/stats/analyzeWaferMap.js +1 -1
- package/dist/packages/stats/clusterDetection.d.ts +2 -2
- package/dist/packages/stats/patternClassification.d.ts +2 -2
- package/dist/packages/stats/regions.d.ts +6 -6
- package/dist/packages/stats/regions.js +1 -1
- package/dist/packages/stats/renderSummaryReport.js +17 -17
- package/llms.txt +1 -1
- package/package.json +1 -1
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import{getUniqueTestNumbers as yn,resolveTestNumber as xn,findTestDef as wn}from"../renderer/buildView.js";import{getColorScheme as vn}from"../renderer/colorSchemes.js";import{metadataValueColor as Cn}from"../renderer/colorMap.js";import{resolveCanvasTheme as Sn}from"./canvasTheme.js";import{ICONS as pe}from"./icons.js";import{CLR as
|
|
2
|
-
`),
|
|
1
|
+
import{getUniqueTestNumbers as yn,resolveTestNumber as xn,findTestDef as wn}from"../renderer/buildView.js";import{getColorScheme as vn}from"../renderer/colorSchemes.js";import{metadataValueColor as Cn}from"../renderer/colorMap.js";import{resolveCanvasTheme as Sn}from"./canvasTheme.js";import{ICONS as pe}from"./icons.js";import{CLR as m,sevColor as Mt,BIN_LEGEND_MODES as Mn,STACKED_MODES as ue,Z_ABOVE as kt,applyOverlayZ as kn,getTooltip as Bn,hideTooltip as Bt,createToolbarHelpers as En,buildModeMenuEl as On,openDetachWindow as Dn,openFloatingWindow as Tn,openModal as Wn,copyWmapThemeTokens as Ln,syncWmapPopupTheme as In,openUserGuideWindow as Rn,makePaletteBtn as Pn,makeLogScaleBtn as An,makeLegendStyleBtn as Fn,makeOverlaysBtn as Hn,makeOrientationBtn as $n,overlayRootFor as Et,saveImageBlob as jn,markMenuTrigger as me,wireMenuA11y as Ot,wireExpandToggle as Dt,passFailMenuRows as zn,requestedPassFailDisplay as Ge,logWmapVersionOnce as Nn,buildDataModeEntries as Vn,metadataKeyHasData as _n,metadataModeEntry as Gn}from"./toolbar.js";import{aggregateValues as Kn,aggregateBinCounts as Tt}from"../core/aggregates.js";import{renderWaferMap as Ke}from"./renderWaferMap.js";import{classifyChanged as qn}from"./renderWaferMap.js";import{buildWaferMap as Xn,getTestPassStatus as Un,isParametricTest as Wt}from"../renderer/buildWaferMap.js";import{analyzeWaferMap as Ee}from"../stats/analyzeWaferMap.js";import{collectWarnings as Yn,buildWarningsMenuEl as Qn,severityOf as Zn}from"./warnings.js";import{compareNatural as Jn}from"../core/utils.js";import{createSummaryPanelEl as qe,buildMetadataStripRow as ei,buildCompactMetadataRows as Lt,metadataEntries as It,renderLotSummaryContent as ti}from"./summaryPanel.js";import"../stats/facets.js";import{openHtmlReport as ni}from"../stats/renderFindingsReport.js";import{escHtml as ge,renderSection as ii,renderSeverityBadge as ai,reportStyles as oi}from"../stats/reportHtml.js";import{createInsightsTab as li}from"./insightsTab.js";import{getDieKey as si,hasPosition as ri}from"../core/dies.js";function Oe(S){const B=new Set;return S.filter(u=>B.has(u.bin)?!1:(B.add(u.bin),!0))}function Rt(S,B){const u=document.createElement("div");Object.assign(u.style,{display:"flex",alignItems:"center",gap:"5px",cursor:"pointer",userSelect:"none",padding:"2px 4px",borderRadius:"3px"});const Y=document.createElement("span");Object.assign(Y.style,{display:"inline-block",width:"13px",height:"13px",flexShrink:"0",background:B.color,border:B.isActive?`2px solid ${m.iconActive}`:`1px solid ${m.menuBorder}`,borderRadius:"2px",boxSizing:"border-box"});const te=document.createElement("span");te.textContent=B.label,Object.assign(te.style,{fontWeight:B.isActive?"700":"400",color:B.isActive?m.iconActive:m.text,whiteSpace:"nowrap"}),u.appendChild(Y),u.appendChild(te),u.setAttribute("role","button"),u.setAttribute("aria-pressed",B.isActive?"true":"false"),u.tabIndex=0,u.addEventListener("mouseenter",()=>{u.style.background=m.bgHover}),u.addEventListener("mouseleave",()=>{u.style.background="transparent"}),u.addEventListener("focus",()=>{u.style.background=m.bgHover}),u.addEventListener("blur",()=>{u.style.background="transparent"}),u.addEventListener("click",B.onClick),u.addEventListener("keydown",L=>{(L.key==="Enter"||L.key===" ")&&(L.preventDefault(),B.onClick())}),S.appendChild(u)}export function renderWaferGallery(S,B,u={}){Nn();const Y=u.cardPadding??6,te=u.downloadFilename??"wafer-gallery";let L=u.columns;const Pt=u.showPlotModeSelector??!0,At=u.showHelpButton??!1,Ft=u.userGuideExtension,Xe=u.insights?.enabled??!1,Ht=kn(u.zIndex),Q=u.summaryPanel,Ue=u.passBins??[1];let he=u.fallbackFormat,D=u.lotStatsSummary,ne=u.legendPosition??"default",d={plotMode:"hardBin",colorScheme:"default",showDieLabels:!1,showRingBoundaries:!1,showQuadrantBoundaries:!1,ringCount:4,rotation:0,flipX:!1,flipY:!1,...u.viewOptions},w=[],q=[],Z=[],M=[],y=B.map(e=>typeof e=="function"?null:e),De=0,be=0;const R=new Map;let $t=0,T=null,ie=null,Ye=new Set,p=null,ae="lot",jt={};function Qe(e){return y[e]?.statsSummary??D?.perWafer.find(t=>t.waferIndex===e)?.summary}function ye(){return!!(y.some(e=>e?.statsSummary?.findings.length)||D?.perWafer.some(e=>e.summary.findings.length))}const zt=Bn(),J=En(zt),{makeBtn:V,setActive:oe,makeSep:P,makeMenuRow:Nt,makeMenuSection:Vt,makeDropdown:Ze,makeCheckMenuBtn:di,closeOpenMenu:xe,getOpenMenu:le,setOpenMenu:se}=J;S.ownerDocument.addEventListener("click",xe,!0);const Je=()=>Bt();window.addEventListener("blur",Je);function Te(e){Ye=new Set(e);const t=[...O.querySelectorAll(".wmap-gallery-card")];let n;t.forEach((i,s)=>{const c=Ye.has(s);i.style.outline=c?`3px solid ${m.findingHighlight}`:"",i.style.outlineOffset=c?"-3px":"",c&&n===void 0&&(n=i)}),n?.scrollIntoView?.({behavior:"smooth",block:"nearest"})}function We(){Te([])}function Le(){for(const e of w)e&&e.clearSelection()}function Ie(e,t){const n=new Set(e),i=t??w.map((s,c)=>c);for(const s of i){const c=M[s],a=w[s];if(!c||!a)continue;const r=c.dies.filter(o=>n.has(si(o)));a.setSelection(r)}}function et(){const e=document.createElement("div");Object.assign(e.style,{display:"flex",gap:"4px",marginBottom:"10px",borderBottom:`1px solid ${m.menuBorder}`,paddingBottom:"8px"});for(const t of["lot","wafers"]){const n=document.createElement("button");n.type="button",n.textContent=t==="lot"?"Lot":"Wafers";const i=ae===t;Object.assign(n.style,{border:"none",borderRadius:"4px",padding:"2px 8px",fontSize:"11px",cursor:"pointer",fontWeight:i?"600":"400",background:i?m.bgActive:"transparent",color:i?m.iconHover:m.icon}),n.addEventListener("click",()=>{ae=t,We(),Le(),I()}),e.appendChild(n)}return e}function _t(){if(!p)return;p.innerHTML="",D&&p.appendChild(et());const e=[];for(let n=0;n<y.length;n++){const i=y[n];if(!i)continue;const s=Qe(n)?.findings??[];if(!s.length)continue;const c=s.filter(r=>r.severity==="unusual").length,a=s.filter(r=>r.severity==="notable").length;e.push({index:n,item:i,unusualCount:c,notableCount:a,totalCount:s.length})}if(e.length>0){const n=document.createElement("button");n.type="button",n.textContent="Findings report",Object.assign(n.style,{border:`1px solid ${m.menuBorder}`,borderRadius:"4px",padding:"3px 8px",marginBottom:"10px",fontSize:"10px",color:m.iconHover,background:"none",cursor:"pointer",display:"block",width:"100%",textAlign:"left"}),n.addEventListener("click",()=>{const i=`Findings report \u2014 ${e.length} wafer${e.length>1?"s":""}`,s=new Date().toLocaleString(),c=e.map(({item:r,index:o})=>{const l=Qe(o),f=r.label??`W${o+1}`,h=l.findings.map(g=>`<li>${ai(g.severity)} ${ge(g.summary)}</li>`).join("");return ii(ge(f),`<ul style="margin:0;padding-left:18px;list-style:none">${h}</ul>`)}).join(`
|
|
2
|
+
`),a=`<!DOCTYPE html>
|
|
3
3
|
<html lang="en">
|
|
4
4
|
<head>
|
|
5
5
|
<meta charset="UTF-8">
|
|
6
|
-
<title>${ge(
|
|
6
|
+
<title>${ge(i)}</title>
|
|
7
7
|
<style>
|
|
8
|
-
${
|
|
8
|
+
${oi()}
|
|
9
9
|
</style>
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
|
12
12
|
<main class="report">
|
|
13
13
|
<header class="report-header">
|
|
14
|
-
<h1>${ge(
|
|
15
|
-
<p class="report-subtitle">Generated ${ge(
|
|
14
|
+
<h1>${ge(i)}</h1>
|
|
15
|
+
<p class="report-subtitle">Generated ${ge(s)}</p>
|
|
16
16
|
</header>
|
|
17
|
-
${
|
|
17
|
+
${c}
|
|
18
18
|
</main>
|
|
19
19
|
</body>
|
|
20
|
-
</html>`;na(s)}),p.appendChild(n)}if(e.length===0){const n=document.createElement("div");Object.assign(n.style,{color:g.icon,fontSize:"11px",padding:"4px 0"}),n.textContent="No findings on any wafer.",p.appendChild(n)}else for(const{index:n,item:a,unusualCount:l,notableCount:o,totalCount:s}of e){const r=l?"unusual":o?"notable":"info",i=l+o||s,d=document.createElement("button");d.type="button",Object.assign(d.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"}),d.addEventListener("mouseover",()=>{d.style.background=g.bgActive}),d.addEventListener("mouseout",()=>{d.style.background=g.bgHover});const f=document.createElement("span");f.textContent=a.label??`W${n+1}`,Object.assign(f.style,{color:g.iconHover,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"});const h=document.createElement("span");h.textContent=String(i),Object.assign(h.style,{marginLeft:"6px",flexShrink:"0",background:Mt(r),color:"#fff",borderRadius:"8px",padding:"1px 5px",fontSize:"10px",fontWeight:"600"}),d.appendChild(f),d.appendChild(h),d.addEventListener("click",()=>ke(n,a)),p.appendChild(d)}const t=document.createElement("div");t.style.height="12px",p.appendChild(t)}function I(){if(p)if(ae==="lot"&&O){const e=Oe(y.flatMap(n=>n?.hbinDefs??[])),t=Oe(y.flatMap(n=>n?.sbinDefs??[]));ta(p,{lotSummary:O,items:y,hbinDefs:e.length?e:void 0,sbinDefs:t.length?t:void 0,testDefs:y.find(n=>n?.testDefs?.length)?.testDefs,passBins:Ue,ringCount:c.ringCount,colorScheme:c.colorScheme,fallbackFormat:he,activeFindingId:ne,warnings:u.warnings?.display??!0?_:[],findingsFilter:jt,onFindingsFilterChange:I,onSaveText:u.onSaveText,onFindingClick:(n,a)=>{ne===n.id?Re():Gt(n,a),I()},onWaferClick:n=>{Te([n])}}),ye()&&p.insertBefore(et(),p.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(){ne=null,We(),Le(),w({highlightBin:void 0},{fireCallback:!1})}function Gt(e,t){if(ne===e.id){Re();return}ne=e.id,t.style.background=g.bgActive,t.style.fontWeight="600";const{kind:n,index:a}=e.variable;n==="test"?w({plotMode:"value",activeTest:a??0,highlightBin:void 0},{fireCallback:!1}):n==="softBin"?w({plotMode:"softBin",highlightBin:void 0},{fireCallback:!1}):w({plotMode:"hardBin",highlightBin:void 0},{fireCallback:!1}),We(),Le();const l=e.highlight;if(l.kind==="wafer"){Te(l.waferIndices);const o=tt(e);for(const s of l.waferIndices){const d=M[s]?.statsSummary?.findings.find(f=>tt(f)===o)?.highlight?.dieKeys;d?.length&&Ie(d,[s])}}else l.kind==="bin"?l.dieKeys?.length&&Ie(l.dieKeys):(l.kind==="region"||l.kind==="dies")&&l.dieKeys?.length&&Ie(l.dieKeys)}function q(){if(!D)return;const e=!!p;D.style.display=(O||ye())&&e&&!Ae?"flex":"none";const t=p?p.style.display!=="none":!1;(O?.hasNotableFindings||y.some(a=>a?.statsSummary?.hasNotableFindings))&&!t?D.style.color=g.findingIndicator:D.dataset.active||(D.style.color=g.icon)}const B=document.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=oe();e&&(e.remove(),le(null)),me(H,!1)},H=V("mode","Plot mode",()=>{if(oe()){nt();return}const e=y.flatMap(m=>m?.dies??[]),t=y.find(m=>m?.testDefs?.length)?.testDefs,{testEntries:n,binEntries:a,stackedEntries:l}=Vn(e,t,{includeStacked:!0}),o=c.plotMode??"hardBin",s=c.activeTest??0;function r(m){return m.plotMode!==o?!1:m.plotMode==="value"?s===(m.activeTest??0):m.plotMode==="metadata"?c.activeMetadataKey===m.activeMetadataKey:!0}function i(m,T){m.activeTest!==void 0?w({plotMode:"value",activeTest:m.activeTest,activeMetadataKey:void 0,logScale:m.logScale}):m.activeMetadataKey!==void 0?w({plotMode:m.plotMode,activeTest:void 0,activeMetadataKey:m.activeMetadataKey,passFailDisplay:"off"}):w({plotMode:m.plotMode,activeTest:void 0,activeMetadataKey:void 0,passFailDisplay:"off"}),T.remove(),le(null),me(H,!1)}const d=new Set,f=y.flatMap(m=>m?.metadataFields??[]).filter(m=>!d.has(m.key)&&d.add(m.key)).filter(m=>_n(e,m.key)).map(Gn),h=On(H.getBoundingClientRect(),n,a,l,r,i,{makeMenuRow:Nt,makeMenuSection:Vt},o,H.ownerDocument.defaultView??window,f);Et(H).appendChild(h),le(h),me(H,!0),Ot(h,H,nt)});me(H,!1);const Kt=()=>M.flatMap(e=>e?[...e.hbinDefs??[],...e.sbinDefs??[]]:[]).some(e=>e.color),{btn:qt,sync:at}=Pn(Q,()=>c.plotMode??"hardBin",()=>c.colorScheme??"default",Kt,e=>w({colorScheme:e}));at();const Xt=k.some(e=>typeof e!="function"&&(e.reticles?.length??0)>0);function Pe(){const e=y.find(n=>n?.testDefs?.length)?.testDefs,{testNumber:t}=xn(c.activeTest??0,e);return{testNumber:t,td:wn(e,t)}}function it(){if((c.plotMode??"hardBin")!=="value")return!1;const{td:e}=Pe();return e!==void 0&&(e.limitLow!==void 0||e.limitHigh!==void 0)}function se(){if((c.plotMode??"hardBin")!=="value")return!1;const{td:e}=Pe();return e!==void 0&&!Wt(e)}function Ut(){if((c.plotMode??"hardBin")!=="value")return!1;const{testNumber:e,td:t}=Pe();return y.some(n=>n?.dies?.some(a=>Un(a,e,t)!==void 0))}const Yt=Hn(Q,()=>[{label:"Ring boundaries",active:!!c.showRingBoundaries,onClick:()=>w({showRingBoundaries:!c.showRingBoundaries})},{label:"Quadrant lines",active:!!c.showQuadrantBoundaries,onClick:()=>w({showQuadrantBoundaries:!c.showQuadrantBoundaries})},{label:"Die labels",active:!!c.showDieLabels,onClick:()=>w({showDieLabels:!c.showDieLabels})},{label:"Reticle grid",active:!!c.showReticle,enabled:Xt,onClick:()=>w({showReticle:!c.showReticle})},{label:"XY indicator",active:!!c.showXYIndicator,onClick:()=>w({showXYIndicator:!c.showXYIndicator})},...zn({functionalActive:se(),hasLimits:it()&&!se(),hasRecorded:Ut()&&!se(),display:Ge(c)},e=>w({passFailDisplay:e}))],()=>!!(c.showRingBoundaries||c.showQuadrantBoundaries||c.showDieLabels||c.showReticle||c.showXYIndicator||Ge(c)!=="off")),{btn:Qt,sync:ot}=Fn(Q,()=>({plotMode:c.plotMode,legendPosition:te}),e=>{te=e;for(const t of v)t&&t.setOptions({legendPosition:te})});ot();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,()=>c.aggregationMethod??"mean",e=>w({aggregationMethod:e}));function st(){const e=c.plotMode==="stackedValues";lt.style.display=e?"":"none"}st();const{btn:Jt,sync:rt}=An(Q,()=>({...c,functionalActive:se()}),e=>w(e));rt();const we=V("specRange","Colorbar range: spec limits",()=>{const e=c.colorbarRangeMode==="data"?"spec":"data";w({colorbarRangeMode:e})});function dt(){const e=(c.plotMode??"hardBin")==="value"&&it()&&Ge(c)==="off"&&!se();we.style.display=e?"":"none";const t=(c.colorbarRangeMode??"spec")==="spec";ie(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(Q,()=>c,e=>w(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))),C=document.createElement("div");Object.assign(C.style,{display:"inline-flex",alignItems:"center",gap:"0"}),B.appendChild(C),Pt&&C.appendChild(H),C.appendChild(qt),C.appendChild(lt),C.appendChild(Jt),C.appendChild(we),C.appendChild(A()),C.appendChild(Yt),C.appendChild(A()),C.appendChild(Qt),C.appendChild(A()),C.appendChild(en),C.appendChild(A()),C.appendChild(nn),C.appendChild(A()),C.appendChild(tn),(O||ye())&&(D=V("findings","Summary panel",()=>{if(!p)return;const e=p.style.display!=="none";e||I(),p.style.display=e?"none":"flex",ie(D,!e),q()}),B.appendChild(A()),B.appendChild(D));let $=null,ve=null,_=[],ct=!1;function ft(){const e=Yn({lotStatsSummary:O,result:{warnings:y.flatMap(n=>n?.warnings??[])}}),t=e.length!==_.length||e.some((n,a)=>n.code!==_[a]?.code||n.message!==_[a]?.message);_=e,(t||!ct)&&(ct=!0,u.warnings?.onWarning?.(e)),an()}function an(){if(!$||!ve)return;const e=_.length,t=e>0;if($.style.display=t?"flex":"none",ve.style.display=t?"":"none",!t)return;const n=Zn(_[0]),a=`${e} data ${e===1?"warning":"warnings"}`;$.style.color=n==="error"?g.errText:g.warnText,$.ariaLabel=n==="error"?`${a} \u2014 wafers in this lot may be positionally wrong`:a}(u.warnings?.display??!0)&&(ve=A(),$=V("warning","Data warnings",()=>{const e=oe();if(xe(new MouseEvent("click")),e)return;const t=Qn($.getBoundingClientRect(),_);Et(S).appendChild(t),le(t),Ot(t,$,()=>xe(new MouseEvent("click")))}),me($,!1),B.appendChild(ve),B.appendChild($)),ft();let Z=null;Xe&&(Z=V("analysis","Insights",()=>{const e=J?.style.display!=="none";ut(!e)}),B.appendChild(A()),B.appendChild(Z));function pt(){import("./userGuideHtml.js").then(e=>Rn({buildWaferMap:Xn,renderWaferMap:Ke,renderWaferGallery,analyzeWaferMap:Ee},e.USER_GUIDE_HTML,Ft,S))}At&&(B.appendChild(A()),B.appendChild(V("help","User guide",()=>pt())));const G=document.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=document.createElement("div");Object.assign(F.style,{display:"flex",flexDirection:"row",gap:"12px",alignItems:"flex-start"});let re=null,J=null;Xe&&(re=la({getItems:()=>y,getLotStats:()=>O,getColorSchemeName:()=>c.colorScheme??"default",passBins:Ue,getRingCount:()=>c.ringCount??4,defaultView:u.insights?.defaultView,backTab:{label:"Gallery",onBack:()=>ut(!1)},showMetadataStrip:!1,onSaveImage:u.onSaveImage,onSaveText:u.onSaveText,openWafer:(e,t,n)=>{const a=y[e];if(!a)return;let l=null;const o=Wn({title:t,onClose:()=>l?.destroy(),anchor:S});vt(o,t,a.wafer.metadata??void 0),l=ze(o.contentWrap,a,n)}}),J=re.el);let Ae=!1;function ut(e){!re||!J||(Ae=e,J.style.display=e?"flex":"none",F.style.display=e?"none":"flex",C.style.display=e?"none":"inline-flex",Z&&(ie(Z,e),Z.innerHTML=e?pe.wafer:pe.analysis,Z.ariaLabel=e?"Back to gallery view":"Insights"),q(),Me(),e&&re.render())}const on=4,Fe=240,mt=480,ln=720,sn=1.25,gt=u.maxSize;let j=gt??mt;function ht(e){const t=X*2+110+2;let n=null;for(const a of e){if(a==null||!a.dies?.length)continue;const l=a.dies[0].width;if(!(l>0))continue;const o=a.wafer.radius*2*(on/l),s=Math.ceil(o+t);(n==null||s>n)&&(n=s)}return n}function rn(e){const t=ht(e);return t==null?Fe:Math.min(j,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<=j?!1:(j=n,!0)}function cn(){for(const e of Array.from(E.children))e.classList.contains("wmap-gallery-card")&&(e.style.maxWidth=`${j}px`,e.style.maxHeight=`${j}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, ${j}px))`}function Se(){if(L!=null){E.style.gridTemplateColumns=He(L);return}const e=Math.max(1,bt),t=12,n=E.clientWidth||0,a=o=>(n-t*(o-1))/o;let l=Math.max(1,Math.ceil(Math.sqrt(e)));if(n>0){for(;l>1&&a(l)<Ce;)l--;const o=Math.min(j,Ce*sn);for(;l<e&&a(l+1)>=o;)l++}E.style.gridTemplateColumns=He(l)}const E=document.createElement("div");if(Object.assign(E.style,{flex:"1 1 0",minWidth:"0",display:"grid",gridTemplateColumns:He(1),gap:"12px",justifyContent:"start",alignContent:"start"}),ae=O?"lot":"wafers",U?.placement){const e=U.placement;p=qe(e),p.style.maxHeight="calc(100vh - 80px)",p.style.position="sticky",p.style.top="8px",p.style.display="flex",p.style.flexDirection="column"}else if(O||ye()){const e=!!U?.defaultOpen;p=qe("right"),p.style.maxHeight="calc(100vh - 80px)",p.style.position="sticky",p.style.top="8px",p.style.flexDirection="column",p.style.display=e?"flex":"none",I()}q(),p?.style.display!=="none"&&D&&ie(D,!0),(U?.placement??"right")==="left"?(p&&F.appendChild(p),F.appendChild(E)):(F.appendChild(E),p&&F.appendChild(p)),S.appendChild(B),S.appendChild(G),S.appendChild(F),J&&S.appendChild(J);function Me(){G.innerHTML="";const e=c.plotMode??"hardBin",t=!Ae&&Mn.has(e),n=M.filter(b=>b!=null),a=n.find(b=>b.isLotStack),l=ea(n.map(b=>({metadata:b.wafer.metadata??void 0})),a?{lotSize:a.lotSize??n.length,aggrMethod:a.aggrMethod}:void 0),o=e==="metadata",s=c.activeMetadataKey,r=new Set;if(t&&!o)for(const b of n)for(const W of b.dies){if(W.partial)continue;const x=e==="softBin"?W.sbin:W.hbin;x!=null&&r.add(x)}const i=t&&!o?[...r].sort((b,W)=>b-W):[],d=new Set;if(t&&o&&s)for(const b of n)for(const W of b.dies){if(W.partial)continue;const x=W.metadata?.[s];x!=null&&(typeof x=="string"||typeof x=="number"||typeof x=="boolean")&&d.add(String(x))}const f=t&&o?[...d].sort(Jn):[];if(!l&&!i.length&&!f.length){G.style.display="none";return}if(G.style.display="flex",l&&G.appendChild(l),!i.length&&!f.length)return;const h=document.createElement("div");Object.assign(h.style,{display:"flex",flexWrap:"wrap",alignItems:"center",gap:"6px 14px"}),l&&Object.assign(h.style,{borderTop:`1px solid ${g.separator}`,paddingTop:"6px"}),G.appendChild(h);const m=vn(c.colorScheme),T=c.highlightBin;if(o){const b=c.highlightMetadataValue,W=M.flatMap(x=>x?.metadataFields??[]).find(x=>x.key===s);f.forEach((x,Ne)=>{const Ve=b===x,St=W?.values?.find(_e=>_e.value===x),bn=St?.color??Cn(Ne);Rt(h,{color:bn,isActive:Ve,label:St?.label??x,onClick:()=>{const _e=c.highlightMetadataValue===x?void 0:x;w({highlightMetadataValue:_e})}})});return}const N=e==="softBin"?M.flatMap(b=>b?.sbinDefs??[]):M.flatMap(b=>b?.hbinDefs??[]),R=new Set,ce=[];for(const b of N)R.has(b.bin)||(R.add(b.bin),ce.push(b));const fe=ce.length>0?new Map(ce.map(b=>[b.bin,b])):null;for(const b of i){const W=T===b,x=fe?.get(b),Ne=(c.colorScheme==="custom"?x?.color:void 0)??m.forBin(b);Rt(h,{color:Ne,isActive:W,label:x?.name?`${b} \xB7 ${x.name}`:`Bin ${b}`,onClick:()=>{const Ve=c.highlightBin===b?void 0:b;w({highlightBin:Ve})}})}}function de(e){const t=y.filter(r=>r!==null);if(!t.length)return[];const n=t.map(r=>r.dies),a=t[0].wafer,l=t.length,o=a.metadata?{...a,metadata:(({wafer:r,waferId:i,...d})=>d)(a.metadata)}:a;function s(r,i){return{...r,stats:{...r.stats,isLotStack:!0,aggregationMethod:i,lotSize:l}}}if(e==="stackedValues"){const r=t.find(f=>f.testDefs?.length)?.testDefs;let i=r?.filter(Wt);if(r?.length||(i=yn(t.flatMap(h=>h.dies)).map(h=>({testNumber:h,name:`Test ${h}`}))),!i?.length)return[];const d=c.aggregationMethod??"mean";return i.map(f=>{const h=Kn(n,d,f.testNumber),m={testNumber:0,name:f.name,unit:f.unit};return{wafer:o,dies:h,testDefs:[m],label:`${f.name} \xB7 ${d}`,isLotStack:!0,aggrMethod:d,lotSize:l,statsSummary:s(Ee({wafer:o,dies:h,testDefs:[m]},{testNumbers:[0]}),d)}})}if(e==="stackedBins"){let r=Oe(t.flatMap(i=>i.hbinDefs??[]));return(!r||r.length===0)&&(r=[...new Set(t.flatMap(d=>d.dies.map(f=>f.hbin).filter(f=>f!=null)))].sort((d,f)=>d-f).map(d=>({bin:d,name:`Bin ${d}`}))),r.map(i=>{const d=Tt(n,i.bin,"hard"),f=[{bin:i.bin,name:i.name}];return{wafer:o,dies:d,hbinDefs:f,label:`${i.bin} \xB7 ${i.name}`,isLotStack:!0,aggrMethod:"countBin",lotSize:l,statsSummary:s(Ee({wafer:o,dies:d,hbinDefs:f}),"countBin")}})}if(e==="stackedSoftBins"){let r=Oe(t.flatMap(i=>i.sbinDefs??[]));return(!r||r.length===0)&&(r=[...new Set(t.flatMap(d=>d.dies.map(f=>f.sbin).filter(f=>f!=null)))].sort((d,f)=>d-f).map(d=>({bin:d,name:`Bin ${d}`}))),r.map(i=>{const d=Tt(n,i.bin,"soft"),f=[{bin:i.bin,name:i.name}];return{wafer:o,dies:d,sbinDefs:f,label:`${i.bin} \xB7 ${i.name}`,isLotStack:!0,aggrMethod:"countBin",lotSize:l,statsSummary:s(Ee({wafer:o,dies:d,sbinDefs:f}),"countBin")}})}return t}function $e(e){const t=y.length;return e==="stackedBins"||e==="stackedSoftBins"?{valueRange:[0,t],lotSize:t}:e==="stackedValues"?{aggregationMethod:c.aggregationMethod??"mean",valueRange:void 0,lotSize:void 0}:{}}const fn=new Set(["default","accessible","custom"]);function w(e,{fireCallback:t=!0}={}){const n=c.plotMode;c={...c,...e};const a=c.plotMode,l=ue.has(a),o=n!==void 0&&ue.has(n),s=be>0;if(e.plotMode!==void 0&&e.plotMode!==n&&(a==="hardBin"||a==="softBin")&&!fn.has(c.colorScheme??"")&&(c={...c,colorScheme:"default"}),e.plotMode!==void 0)if(l){const i=$e(a);if(c={...c,...i},s)for(const d of v)d&&d.setOptions(e);else z(de(a))}else if(o){const{valueRange:i,lotSize:d,aggregationMethod:f,...h}=c;if(c=h,s)for(const m of v)m&&m.setOptions(e);else z(y.filter(m=>m!==null))}else for(const i of v)i&&i.setOptions(e);else if(e.aggregationMethod!==void 0&&a==="stackedValues")if(s)for(const i of v)i&&i.setOptions(e);else z(de("stackedValues"));else for(const i of v)i&&i.setOptions(e);Me(),st(),ot(),at();const r=e.plotMode!==void 0&&e.plotMode!==n;if((e.colorScheme!==void 0||r)&&I(),rt(),dt(),t){const i=Object.keys(e);u.onViewOptionsChange?.(c,i,qn(i))}}function wt(e,t,n){const a=e.createElement("div");Object.assign(a.style,{display:"flex",alignItems:"center",gap:"4px",flex:"1",minWidth:"0"});const l=e.createElement("span");l.textContent=t,Object.assign(l.style,{fontWeight:"700",fontSize:"13px",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}),a.appendChild(l);const o=It(n??{});let s=null;if(o.length>0){const r=e.createElement("span");Object.assign(r.style,{fontSize:"12px",lineHeight:"1",color:g.label,flexShrink:"0"}),r.textContent="\u25BE",a.appendChild(r),Object.assign(a.style,{cursor:"pointer"}),s=e.createElement("div"),s.dataset.wmapCardMetaPanel="1",Object.assign(s.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 i=Lt(n??{});i&&s.appendChild(i),a.setAttribute("aria-expanded","false"),a.setAttribute("aria-label",`Wafer info for ${t||"this card"}. Click to expand.`),Dt(a,d=>{r.textContent=d?"\u25B4":"\u25BE",a.setAttribute("aria-expanded",String(d)),s&&(s.style.display=d?"block":"none")})}return{wrap:a,metaPanel:s}}function vt(e,t,n){const a=e.box.querySelector("[data-wmap-window-title]"),l=It(n??{});if(!a||l.length===0)return;const o=a.parentElement,s=document.createElement("div");Object.assign(s.style,{display:"flex",alignItems:"center",gap:"4px",flex:"1",minWidth:"0",cursor:"pointer"}),o?.insertBefore(s,a),s.appendChild(a);const r=document.createElement("span");Object.assign(r.style,{fontSize:"12px",lineHeight:"1",color:g.label,flexShrink:"0"}),r.textContent="\u25BE",s.appendChild(r);const i=document.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 d=Lt(n??{});d&&i.appendChild(d),e.contentWrap.style.position="relative",e.contentWrap.appendChild(i),s.setAttribute("aria-expanded","false"),s.setAttribute("aria-label",`Wafer info for ${t}. Click to expand.`),Dt(s,f=>{r.textContent=f?"\u25B4":"\u25BE",s.setAttribute("aria-expanded",String(f)),i.style.display=f?"block":"none"})}function je(e,t,n){const a=document.createElement("div");a.className="wmap-gallery-card",Object.assign(a.style,{background:g.menuBg,border:`1px solid ${g.menuBorder}`,borderRadius:"10px",overflow:"hidden",display:"flex",flexDirection:"column",position:"relative",aspectRatio:"1",maxWidth:`${j}px`,maxHeight:`${j}px`});const l=document.createElement("div");Object.assign(l.style,{display:"flex",alignItems:"center",padding:"8px 10px 6px",borderBottom:`1px solid ${g.menuBorder}`,flexShrink:"0",gap:"6px"});const{wrap:o,metaPanel:s}=wt(document,e.label??"",e.wafer.metadata??void 0);l.appendChild(o);const r=document.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"}),l.appendChild(r),a.appendChild(l);const i=document.createElement("div");Object.assign(i.style,{position:"relative",flex:"1",minHeight:"0",overflow:"hidden",display:"flex",flexDirection:"column"}),a.appendChild(i),s&&i.appendChild(s),E.appendChild(a);const d=Ke(i,e,{viewOptions:e.viewOptions?{...c,...e.viewOptions}:c,toolbarControls:"full",showTooltip:!0,padding:X,legendPosition:te,fallbackFormat:he,statsSummary:e.statsSummary,onSaveImage:u.onSaveImage,onSaveText:u.onSaveText,onClick:e.onClick,onSelect:e.onSelect,onExpand:()=>ke(t,e),showMetadataBadge:!1});return d.setViewControlsVisible(!1),d.setSummaryVisible(!1),r.onclick=()=>ke(t,e),{card:a,ctrl:d,canvasWrapper:i,expandBtn:r}}function pn(e){const t=Y[e];if(!t)return;const n=[...P.values()].find(a=>a.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 z(e){gn(),oe()?.remove(),le(null),Re(),M=[];for(const s of v)s&&s.destroy();v=[],K=[],Y=[],be=0,E.innerHTML="",bt=e.length,yt(e.map(s=>typeof s=="function"?null:s));const t=[];for(let s=0;s<e.length;s++){const r=e[s];if(typeof r=="function"){const i=document.createElement("div");i.className="wmap-gallery-card",Object.assign(i.style,{background:g.menuBg,border:`1px solid ${g.menuBorder}`,borderRadius:"10px",aspectRatio:"1",display:"flex",alignItems:"center",justifyContent:"center"});const d=document.createElement("span");d.textContent="\u2026",Object.assign(d.style,{color:g.label,fontSize:"18px"}),i.appendChild(d),E.appendChild(i),M.push(null),v.push(null),K.push(null),Y.push(null),t.push({index:s,factory:r,placeholder:i}),be++}else{const{ctrl:i,canvasWrapper:d,expandBtn:f}=je(r,s,e.length);M.push(r),v.push(i),K.push(d),Y.push(f)}}M.flatMap(s=>s?[...s.hbinDefs??[],...s.sbinDefs??[]]:[]).some(s=>s.color)&&!u.viewOptions?.colorScheme&&(c={...c,colorScheme:"custom"}),Me();const a=++De;let l=0;function o(){if(a!==De)return;if(l>=t.length){if(ue.has(c.plotMode)){const N=c.plotMode;z(de(N))}return}const{index:s,factory:r,placeholder:i}=t[l++],d=r();M[s]=d,y[s]=d,yt([d]);const{card:f,ctrl:h,canvasWrapper:m,expandBtn:T}=je(d,s,e.length);v[s]=h,K[s]=m,Y[s]=T,be--,i.replaceWith(f),Me(),!p&&!U?.placement&&d.statsSummary?.findings.length?(O||(ae="wafers"),p=qe("right"),p.style.maxHeight="calc(100vh - 80px)",p.style.position="sticky",p.style.top="8px",p.style.flexDirection="column",p.style.display="none",(U?.placement??"right")==="left"?F.insertBefore(p,E):F.appendChild(p),I(),D||(D=V("findings","Summary panel",()=>{if(!p)return;const R=p.style.display!=="none";R||I(),p.style.display=R?"none":"flex",ie(D,!R),q()}),B.appendChild(A()),B.appendChild(D)),q()):p&&p.style.display!=="none"&&I(),q(),setTimeout(o,0)}t.length>0&&setTimeout(o,0)}if(ue.has(c.plotMode)&&y.length>0){const e=$e(c.plotMode);c={...c,...e},z(de(c.plotMode))}else z(k);const Ct=new ResizeObserver(()=>{L==null&&Se()});Ct.observe(E),p&&I();function un(e){const t=K[e];if(!t)return;t.innerHTML="",Object.assign(t.style,{alignItems:"center",justifyContent:"center"});const n=document.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 o of P.values())if(o.cardIndex===e)return;const n=t.label??"Wafer map",a=$t++,l=Dn(n);if(l){const o=l.document;o.title=n,Object.assign(o.documentElement.style,{height:"100%"}),Object.assign(o.body.style,{margin:"0",height:"100vh",overflow:"hidden",display:"flex",flexDirection:"column",fontFamily:'system-ui, -apple-system, "Segoe UI", sans-serif'}),Ln(S,o.documentElement);const s=In(S,o.documentElement,()=>T.setOptions({})),r=o.createElement("div");r.dataset.wmapWindowBanner="1",r.textContent=n,Object.assign(r.style,{display:"none",padding:"6px 12px",fontSize:"12px",fontWeight:"700",background:g.warnBg,color:g.warnText,borderBottom:`1px solid ${g.warnBorder}`,flexShrink:"0"}),o.body.appendChild(r);const i=o.createElement("div");Object.assign(i.style,{flex:"1",minHeight:"0",display:"flex",flexDirection:"column"}),o.body.appendChild(i);const{wrap:d,metaPanel:f}=wt(o,n,t.wafer.metadata??void 0),h=o.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(d),i.appendChild(h);const m=o.createElement("div");Object.assign(m.style,{position:"relative",flex:"1",minHeight:"0",overflow:"hidden",display:"flex",flexDirection:"column"}),f&&m.appendChild(f),i.appendChild(m);const T=ze(m,t),N=setInterval(()=>{l.closed&&Be(a)},400);l.addEventListener("pagehide",()=>Be(a)),P.set(a,{id:a,ctrl:T,cardIndex:e,label:n,closePollId:N,stopThemeSync:s,close:()=>{l.closed||l.close()},setTitle:R=>{o.title=R,r.textContent=R,r.style.display="block"}})}else{const o=Tn({title:n,onClose:()=>Be(a),anchor:S});o.contentWrap.style.flexDirection="column",vt(o,n,t.wafer.metadata??void 0);const s=ze(o.contentWrap,t);P.set(a,{id:a,ctrl:s,cardIndex:e,label:n,closePollId:null,close:()=>o.close(),setTitle:r=>{const i=o.box.querySelector("[data-wmap-window-title]");i&&(i.textContent=r,i.title=r)}})}v[e]?.destroy(),v[e]=null,un(e),pn(e)}function ze(e,t,n){const a=t.viewOptions?{...c,...t.viewOptions}:c,l=n!==void 0?{...a,plotMode:"value",activeTest:n}:a,o=Ke(e,t,{viewOptions:l,toolbarControls:"full",showTooltip:!0,padding:X,legendPosition:te,fallbackFormat:he,statsSummary:t.statsSummary,onSaveImage:u.onSaveImage,onSaveText:u.onSaveText,onClick:t.onClick,onSelect:t.onSelect,showExpandButton:!1,showMetadataBadge:!1});return o.setViewControlsVisible(!0),o.setSummaryVisible(!0),o.setExpandVisible(!1),o}function Be(e){const t=P.get(e);if(!t)return;P.delete(e),t.closePollId!=null&&clearInterval(t.closePollId),t.stopThemeSync?.();const n=t.ctrl.getOptions();if(t.ctrl.destroy(),t.cardIndex===null)return;const a=t.cardIndex,l=M[a];if(!l)return;const o={...l,viewOptions:n};M[a]=o;const{card:s,ctrl:r,canvasWrapper:i,expandBtn:d}=je(o,a,M.length);K[a]?.parentElement?.replaceWith(s),v[a]=r,K[a]=i,Y[a]=d}function mn(e){const t=P.get(e);t&&(t.close(),Be(e))}function gn(){for(const e of P.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)),a=Math.ceil(t/n),l=e[0].width,o=e[0].height,s=8,r=window.devicePixelRatio||1,i=Math.round(26*r),d=Math.round(12*r),f=document.createElement("canvas");f.width=n*l+(n-1)*s,f.height=a*(o+i)+(a-1)*s;const h=f.getContext("2d"),m=Sn(E);h.fillStyle=m.background,h.fillRect(0,0,f.width,f.height),e.forEach((T,N)=>{const R=N%n,ce=Math.floor(N/n),fe=R*(l+s),b=ce*(o+i+s),W=T.closest(".wmap-gallery-card")?.querySelector("span")?.textContent??"";h.fillStyle=m.surface,h.fillRect(fe,b,l,i),h.fillStyle=m.text,h.font=`700 ${d}px system-ui, sans-serif`,h.textAlign="left",h.textBaseline="middle",h.fillText(W,fe+Math.round(10*r),b+i/2,l-Math.round(20*r)),h.drawImage(T,fe,b+i)}),f.toBlob(T=>{T&&jn(T,ee,u.onSaveImage)})}return{setItems(e){y=e.map(n=>typeof n=="function"?null:n);const t=c.plotMode;if(ue.has(t))if(e.some(a=>typeof a=="function"))z(e);else{const a=$e(t);c={...c,...a},z(de(t))}else z(e)},setOptions(e){w(e,{fireCallback:!1})},getOptions(){return{...c}},setFallbackFormat(e){he=e;for(const t of v)t&&t.setFallbackFormat(e)},setLotStatsSummary(e){O=e,ft(),p&&I(),q()},setColumns(e){xt(e)},openUserGuide:pt,destroy(){De++;for(const e of[...P.values()])e.closePollId!=null&&clearInterval(e.closePollId),e.close(),e.ctrl.destroy();P.clear();for(const e of v)e&&e.destroy();v=[],oe()?.remove(),Ct.disconnect(),S.ownerDocument.removeEventListener("click",xe,!0),window.removeEventListener("blur",Je),Ht(),Bt(),B.remove(),G.remove(),F.remove(),p?.remove(),re?.destroy()}}}
|
|
20
|
+
</html>`;ni(a)}),p.appendChild(n)}if(e.length===0){const n=document.createElement("div");Object.assign(n.style,{color:m.icon,fontSize:"11px",padding:"4px 0"}),n.textContent="No findings on any wafer.",p.appendChild(n)}else for(const{index:n,item:i,unusualCount:s,notableCount:c,totalCount:a}of e){const r=s?"unusual":c?"notable":"info",o=s+c||a,l=document.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:m.bgHover,cursor:"pointer",fontSize:"11px",textAlign:"left",boxSizing:"border-box"}),l.addEventListener("mouseover",()=>{l.style.background=m.bgActive}),l.addEventListener("mouseout",()=>{l.style.background=m.bgHover});const f=document.createElement("span");f.textContent=i.label??`W${n+1}`,Object.assign(f.style,{color:m.iconHover,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"});const h=document.createElement("span");h.textContent=String(o),Object.assign(h.style,{marginLeft:"6px",flexShrink:"0",background:Mt(r),color:"#fff",borderRadius:"8px",padding:"1px 5px",fontSize:"10px",fontWeight:"600"}),l.appendChild(f),l.appendChild(h),l.addEventListener("click",()=>ke(n,i)),p.appendChild(l)}const t=document.createElement("div");t.style.height="12px",p.appendChild(t)}function I(){if(p)if(ae==="lot"&&D){const e=Oe(y.flatMap(n=>n?.hbinDefs??[])),t=Oe(y.flatMap(n=>n?.sbinDefs??[]));ti(p,{lotSummary:D,items:y,hbinDefs:e.length?e:void 0,sbinDefs:t.length?t:void 0,testDefs:y.find(n=>n?.testDefs?.length)?.testDefs,passBins:Ue,ringCount:d.ringCount,colorScheme:d.colorScheme,fallbackFormat:he,activeFindingId:ie,warnings:u.warnings?.display??!0?_:[],findingsFilter:jt,onFindingsFilterChange:I,onSaveText:u.onSaveText,onFindingClick:(n,i)=>{ie===n.id?Re():Gt(n,i),I()},onWaferClick:n=>{Te([n])}}),ye()&&p.insertBefore(et(),p.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(){ie=null,We(),Le(),v({highlightBin:void 0},{fireCallback:!1})}function Gt(e,t){if(ie===e.id){Re();return}ie=e.id,t.style.background=m.bgActive,t.style.fontWeight="600";const{kind:n,index:i}=e.variable;n==="test"?v({plotMode:"value",activeTest:i??0,highlightBin:void 0},{fireCallback:!1}):n==="softBin"?v({plotMode:"softBin",highlightBin:void 0},{fireCallback:!1}):v({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 a of s.waferIndices){const l=M[a]?.statsSummary?.findings.find(f=>tt(f)===c)?.highlight?.dieKeys;l?.length&&Ie(l,[a])}}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=!!p;T.style.display=(D||ye())&&e&&!Ae?"flex":"none";const t=p?p.style.display!=="none":!1;(D?.hasNotableFindings||y.some(i=>i?.statsSummary?.hasNotableFindings))&&!t?T.style.color=m.findingIndicator:T.dataset.active||(T.style.color=m.icon)}const E=document.createElement("div");E.dataset.wmapToolbar="gallery",Object.assign(E.style,{display:"inline-flex",flexDirection:"row",alignItems:"center",gap:"0",background:m.menuBg,border:`1px solid ${m.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($,!1)},$=V("mode","Plot mode",()=>{if(le()){nt();return}const e=y.flatMap(g=>g?.dies??[]),t=y.find(g=>g?.testDefs?.length)?.testDefs,{testEntries:n,binEntries:i,stackedEntries:s}=Vn(e,t,{includeStacked:!0}),c=d.plotMode??"hardBin",a=d.activeTest??0;function r(g){return g.plotMode!==c?!1:g.plotMode==="value"?a===(g.activeTest??0):g.plotMode==="metadata"?d.activeMetadataKey===g.activeMetadataKey:!0}function o(g,k){g.activeTest!==void 0?v({plotMode:"value",activeTest:g.activeTest,activeMetadataKey:void 0,logScale:g.logScale}):g.activeMetadataKey!==void 0?v({plotMode:g.plotMode,activeTest:void 0,activeMetadataKey:g.activeMetadataKey,passFailDisplay:"off"}):v({plotMode:g.plotMode,activeTest:void 0,activeMetadataKey:void 0,passFailDisplay:"off"}),k.remove(),se(null),me($,!1)}const l=new Set,f=y.flatMap(g=>g?.metadataFields??[]).filter(g=>!l.has(g.key)&&l.add(g.key)).filter(g=>_n(e,g.key)).map(Gn),h=On($.getBoundingClientRect(),n,i,s,r,o,{makeMenuRow:Nt,makeMenuSection:Vt},c,$.ownerDocument.defaultView??window,f);Et($).appendChild(h),se(h),me($,!0),Ot(h,$,nt)});me($,!1);const Kt=()=>M.flatMap(e=>e?[...e.hbinDefs??[],...e.sbinDefs??[]]:[]).some(e=>e.color),{btn:qt,sync:it}=Pn(J,()=>d.plotMode??"hardBin",()=>d.colorScheme??"default",Kt,e=>v({colorScheme:e}));it();const Xt=B.some(e=>typeof e!="function"&&(e.reticles?.length??0)>0);function Pe(){const e=y.find(n=>n?.testDefs?.length)?.testDefs,{testNumber:t}=xn(d.activeTest??0,e);return{testNumber:t,td:wn(e,t)}}function at(){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 y.some(n=>n?.dies?.some(i=>Un(i,e,t)!==void 0))}const Yt=Hn(J,()=>[{label:"Ring boundaries",active:!!d.showRingBoundaries,onClick:()=>v({showRingBoundaries:!d.showRingBoundaries})},{label:"Quadrant lines",active:!!d.showQuadrantBoundaries,onClick:()=>v({showQuadrantBoundaries:!d.showQuadrantBoundaries})},{label:"Die labels",active:!!d.showDieLabels,onClick:()=>v({showDieLabels:!d.showDieLabels})},{label:"Reticle grid",active:!!d.showReticle,enabled:Xt,onClick:()=>v({showReticle:!d.showReticle})},{label:"XY indicator",active:!!d.showXYIndicator,onClick:()=>v({showXYIndicator:!d.showXYIndicator})},...zn({functionalActive:re(),hasLimits:at()&&!re(),hasRecorded:Ut()&&!re(),display:Ge(d)},e=>v({passFailDisplay:e}))],()=>!!(d.showRingBoundaries||d.showQuadrantBoundaries||d.showDieLabels||d.showReticle||d.showXYIndicator||Ge(d)!=="off")),{btn:Qt,sync:ot}=Fn(J,()=>({plotMode:d.plotMode,legendPosition:ne}),e=>{ne=e;for(const t of w)t&&t.setOptions({legendPosition:ne})});ot();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=>v({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=>v(e));rt();const we=V("specRange","Colorbar range: spec limits",()=>{const e=d.colorbarRangeMode==="data"?"spec":"data";v({colorbarRangeMode:e})});function dt(){const e=(d.plotMode??"hardBin")==="value"&&at()&&Ge(d)==="off"&&!re();we.style.display=e?"":"none";const t=(d.colorbarRangeMode??"spec")==="spec";oe(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=>v(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))),C=document.createElement("div");Object.assign(C.style,{display:"inline-flex",alignItems:"center",gap:"0"}),E.appendChild(C),Pt&&C.appendChild($),C.appendChild(qt),C.appendChild(lt),C.appendChild(Jt),C.appendChild(we),C.appendChild(P()),C.appendChild(Yt),C.appendChild(P()),C.appendChild(Qt),C.appendChild(P()),C.appendChild(en),C.appendChild(P()),C.appendChild(nn),C.appendChild(P()),C.appendChild(tn),(D||ye())&&(T=V("findings","Summary panel",()=>{if(!p)return;const e=p.style.display!=="none";e||I(),p.style.display=e?"none":"flex",oe(T,!e),X()}),E.appendChild(P()),E.appendChild(T));let j=null,ve=null,_=[],ct=!1;function ft(){const e=Yn({lotStatsSummary:D,result:{warnings:y.flatMap(n=>n?.warnings??[])}}),t=e.length!==_.length||e.some((n,i)=>n.code!==_[i]?.code||n.message!==_[i]?.message);_=e,(t||!ct)&&(ct=!0,u.warnings?.onWarning?.(e)),an()}function an(){if(!j||!ve)return;const e=_.length,t=e>0;if(j.style.display=t?"flex":"none",ve.style.display=t?"":"none",!t)return;const n=Zn(_[0]),i=`${e} data ${e===1?"warning":"warnings"}`;j.style.color=n==="error"?m.errText:m.warnText,j.ariaLabel=n==="error"?`${i} \u2014 wafers in this lot may be positionally wrong`:i}(u.warnings?.display??!0)&&(ve=P(),j=V("warning","Data warnings",()=>{const e=le();if(xe(new MouseEvent("click")),e)return;const t=Qn(j.getBoundingClientRect(),_);Et(S).appendChild(t),se(t),Ot(t,j,()=>xe(new MouseEvent("click")))}),me(j,!1),E.appendChild(ve),E.appendChild(j)),ft();let U=null;Xe&&(U=V("analysis","Insights",()=>{const e=ee?.style.display!=="none";ut(!e)}),U.dataset.wmapInsightsBtn="1",E.appendChild(P()),E.appendChild(U));function pt(){import("./userGuideHtml.js").then(e=>Rn({buildWaferMap:Xn,renderWaferMap:Ke,renderWaferGallery,analyzeWaferMap:Ee},e.USER_GUIDE_HTML,Ft,S))}At&&(E.appendChild(P()),E.appendChild(V("help","User guide",()=>pt())));const G=document.createElement("div");Object.assign(G.style,{display:"flex",flexDirection:"column",gap:"6px",background:m.menuBg,border:`1px solid ${m.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 A=document.createElement("div");Object.assign(A.style,{display:"flex",flexDirection:"row",gap:"12px",alignItems:"flex-start"});let de=null,ee=null;Xe&&(de=li({getItems:()=>y,getLotStats:()=>D,getColorSchemeName:()=>d.colorScheme??"default",passBins:Ue,getRingCount:()=>d.ringCount??4,defaultView:u.insights?.defaultView,backTab:{label:"Gallery",onBack:()=>ut(!1)},showMetadataStrip:!1,onSaveImage:u.onSaveImage,onSaveText:u.onSaveText,openWafer:(e,t,n)=>{const i=y[e];if(!i)return;let s=null;const c=Wn({title:t,onClose:()=>s?.destroy(),anchor:S});vt(c,t,i.wafer.metadata??void 0),s=ze(c.contentWrap,i,n)}}),ee=de.el);let Ae=!1;function ut(e){!de||!ee||(Ae=e,ee.style.display=e?"flex":"none",A.style.display=e?"none":"flex",C.style.display=e?"none":"inline-flex",U&&(oe(U,e),U.innerHTML=e?pe.wafer:pe.analysis,U.ariaLabel=e?"Back to gallery view":"Insights"),X(),Me(),e&&de.render())}const on=4,Fe=240,mt=480,ln=720,sn=1.25,gt=u.maxSize;let z=gt??mt;function ht(e){const t=Y*2+110+2;let n=null;for(const i of e){if(i==null||!i.dies?.length)continue;const s=i.dies[0].width;if(!(s>0))continue;const c=i.wafer.radius*2*(on/s),a=Math.ceil(c+t);(n==null||a>n)&&(n=a)}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(O.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){O.style.gridTemplateColumns=He(L);return}const e=Math.max(1,bt),t=12,n=O.clientWidth||0,i=c=>(n-t*(c-1))/c;let s=Math.max(1,Math.ceil(Math.sqrt(e)));if(n>0){for(;s>1&&i(s)<Ce;)s--;const c=Math.min(z,Ce*sn);for(;s<e&&i(s+1)>=c;)s++}O.style.gridTemplateColumns=He(s)}const O=document.createElement("div");if(Object.assign(O.style,{flex:"1 1 0",minWidth:"0",display:"grid",gridTemplateColumns:He(1),gap:"12px",justifyContent:"start",alignContent:"start"}),ae=D?"lot":"wafers",Q?.placement){const e=Q.placement;p=qe(e),p.style.maxHeight="calc(100vh - 80px)",p.style.position="sticky",p.style.top="8px",p.style.display="flex",p.style.flexDirection="column"}else if(D||ye()){const e=!!Q?.defaultOpen;p=qe("right"),p.style.maxHeight="calc(100vh - 80px)",p.style.position="sticky",p.style.top="8px",p.style.flexDirection="column",p.style.display=e?"flex":"none",I()}X(),p?.style.display!=="none"&&T&&oe(T,!0),(Q?.placement??"right")==="left"?(p&&A.appendChild(p),A.appendChild(O)):(A.appendChild(O),p&&A.appendChild(p)),S.appendChild(E),S.appendChild(G),S.appendChild(A),ee&&S.appendChild(ee);function Me(){G.innerHTML="";const e=d.plotMode??"hardBin",t=!Ae&&Mn.has(e),n=M.filter(b=>b!=null),i=n.find(b=>b.isLotStack),s=ei(n.map(b=>({metadata:b.wafer.metadata??void 0})),i?{lotSize:i.lotSize??n.length,aggrMethod:i.aggrMethod}:void 0),c=e==="metadata",a=d.activeMetadataKey,r=new Set;if(t&&!c)for(const b of n)for(const W of b.dies){if(W.partial)continue;const x=e==="softBin"?W.sbin:W.hbin;x!=null&&r.add(x)}const o=t&&!c?[...r].sort((b,W)=>b-W):[],l=new Set;if(t&&c&&a)for(const b of n)for(const W of b.dies){if(W.partial)continue;const x=W.metadata?.[a];x!=null&&(typeof x=="string"||typeof x=="number"||typeof x=="boolean")&&l.add(String(x))}const f=t&&c?[...l].sort(Jn):[];if(!s&&!o.length&&!f.length){G.style.display="none";return}if(G.style.display="flex",s&&G.appendChild(s),!o.length&&!f.length)return;const h=document.createElement("div");Object.assign(h.style,{display:"flex",flexWrap:"wrap",alignItems:"center",gap:"6px 14px"}),s&&Object.assign(h.style,{borderTop:`1px solid ${m.separator}`,paddingTop:"6px"}),G.appendChild(h);const g=vn(d.colorScheme),k=d.highlightBin;if(c){const b=d.highlightMetadataValue,W=M.flatMap(x=>x?.metadataFields??[]).find(x=>x.key===a);f.forEach((x,Ne)=>{const Ve=b===x,St=W?.values?.find(_e=>_e.value===x),bn=St?.color??Cn(Ne);Rt(h,{color:bn,isActive:Ve,label:St?.label??x,onClick:()=>{const _e=d.highlightMetadataValue===x?void 0:x;v({highlightMetadataValue:_e})}})});return}const F=e==="softBin"?M.flatMap(b=>b?.sbinDefs??[]):M.flatMap(b=>b?.hbinDefs??[]),H=new Set,K=[];for(const b of F)H.has(b.bin)||(H.add(b.bin),K.push(b));const fe=K.length>0?new Map(K.map(b=>[b.bin,b])):null;for(const b of o){const W=k===b,x=fe?.get(b),Ne=(d.colorScheme==="custom"?x?.color:void 0)??g.forBin(b);Rt(h,{color:Ne,isActive:W,label:x?.name?`${b} \xB7 ${x.name}`:`Bin ${b}`,onClick:()=>{const Ve=d.highlightBin===b?void 0:b;v({highlightBin:Ve})}})}}function ce(e){const t=y.filter(r=>r!==null);if(!t.length)return[];const n=t.map(r=>r.dies.filter(ri)),i=t[0].wafer,s=t.length,c=i.metadata?{...i,metadata:(({wafer:r,waferId:o,...l})=>l)(i.metadata)}:i;function a(r,o){return{...r,stats:{...r.stats,isLotStack:!0,aggregationMethod:o,lotSize:s}}}if(e==="stackedValues"){const r=t.find(f=>f.testDefs?.length)?.testDefs;let o=r?.filter(Wt);if(r?.length||(o=yn(t.flatMap(h=>h.dies)).map(h=>({testNumber:h,name:`Test ${h}`}))),!o?.length)return[];const l=d.aggregationMethod??"mean";return o.map(f=>{const h=Kn(n,l,f.testNumber),g={testNumber:0,name:f.name,unit:f.unit};return{wafer:c,dies:h,testDefs:[g],label:`${f.name} \xB7 ${l}`,isLotStack:!0,aggrMethod:l,lotSize:s,statsSummary:a(Ee({wafer:c,dies:h,testDefs:[g]},{testNumbers:[0]}),l)}})}if(e==="stackedBins"){let r=Oe(t.flatMap(o=>o.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(o=>{const l=Tt(n,o.bin,"hard"),f=[{bin:o.bin,name:o.name}];return{wafer:c,dies:l,hbinDefs:f,label:`${o.bin} \xB7 ${o.name}`,isLotStack:!0,aggrMethod:"countBin",lotSize:s,statsSummary:a(Ee({wafer:c,dies:l,hbinDefs:f}),"countBin")}})}if(e==="stackedSoftBins"){let r=Oe(t.flatMap(o=>o.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(o=>{const l=Tt(n,o.bin,"soft"),f=[{bin:o.bin,name:o.name}];return{wafer:c,dies:l,sbinDefs:f,label:`${o.bin} \xB7 ${o.name}`,isLotStack:!0,aggrMethod:"countBin",lotSize:s,statsSummary:a(Ee({wafer:c,dies:l,sbinDefs:f}),"countBin")}})}return t}function $e(e){const t=y.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 v(e,{fireCallback:t=!0}={}){const n=d.plotMode;d={...d,...e};const i=d.plotMode,s=ue.has(i),c=n!==void 0&&ue.has(n),a=be>0;if(e.plotMode!==void 0&&e.plotMode!==n&&(i==="hardBin"||i==="softBin")&&!fn.has(d.colorScheme??"")&&(d={...d,colorScheme:"default"}),e.plotMode!==void 0)if(s){const o=$e(i);if(d={...d,...o},a)for(const l of w)l&&l.setOptions(e);else N(ce(i))}else if(c){const{valueRange:o,lotSize:l,aggregationMethod:f,...h}=d;if(d=h,a)for(const g of w)g&&g.setOptions(e);else N(y.filter(g=>g!==null))}else for(const o of w)o&&o.setOptions(e);else if(e.aggregationMethod!==void 0&&i==="stackedValues")if(a)for(const o of w)o&&o.setOptions(e);else N(ce("stackedValues"));else for(const o of w)o&&o.setOptions(e);Me(),st(),ot(),it();const r=e.plotMode!==void 0&&e.plotMode!==n;if((e.colorScheme!==void 0||r)&&I(),rt(),dt(),t){const o=Object.keys(e);u.onViewOptionsChange?.(d,o,qn(o))}}function wt(e,t,n){const i=e.createElement("div");Object.assign(i.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"}),i.appendChild(s);const c=It(n??{});let a=null;if(c.length>0){const r=e.createElement("span");Object.assign(r.style,{fontSize:"12px",lineHeight:"1",color:m.label,flexShrink:"0"}),r.textContent="\u25BE",i.appendChild(r),Object.assign(i.style,{cursor:"pointer"}),a=e.createElement("div"),a.dataset.wmapCardMetaPanel="1",Object.assign(a.style,{position:"absolute",top:"0",left:"0",right:"0",zIndex:kt,background:m.menuBg,borderBottom:`1px solid ${m.menuBorder}`,boxShadow:"0 2px 6px rgba(0,0,0,0.15)",padding:"8px 10px",fontSize:"11px",display:"none"});const o=Lt(n??{});o&&a.appendChild(o),i.setAttribute("aria-expanded","false"),i.setAttribute("aria-label",`Wafer info for ${t||"this card"}. Click to expand.`),Dt(i,l=>{r.textContent=l?"\u25B4":"\u25BE",i.setAttribute("aria-expanded",String(l)),a&&(a.style.display=l?"block":"none")})}return{wrap:i,metaPanel:a}}function vt(e,t,n){const i=e.box.querySelector("[data-wmap-window-title]"),s=It(n??{});if(!i||s.length===0)return;const c=i.parentElement,a=document.createElement("div");Object.assign(a.style,{display:"flex",alignItems:"center",gap:"4px",flex:"1",minWidth:"0",cursor:"pointer"}),c?.insertBefore(a,i),a.appendChild(i);const r=document.createElement("span");Object.assign(r.style,{fontSize:"12px",lineHeight:"1",color:m.label,flexShrink:"0"}),r.textContent="\u25BE",a.appendChild(r);const o=document.createElement("div");o.dataset.wmapCardMetaPanel="1",Object.assign(o.style,{position:"absolute",top:"0",left:"0",right:"0",zIndex:kt,background:m.menuBg,borderBottom:`1px solid ${m.menuBorder}`,boxShadow:"0 2px 6px rgba(0,0,0,0.15)",padding:"8px 10px",fontSize:"11px",display:"none"});const l=Lt(n??{});l&&o.appendChild(l),e.contentWrap.style.position="relative",e.contentWrap.appendChild(o),a.setAttribute("aria-expanded","false"),a.setAttribute("aria-label",`Wafer info for ${t}. Click to expand.`),Dt(a,f=>{r.textContent=f?"\u25B4":"\u25BE",a.setAttribute("aria-expanded",String(f)),o.style.display=f?"block":"none"})}function je(e,t,n){const i=document.createElement("div");i.className="wmap-gallery-card",Object.assign(i.style,{background:m.menuBg,border:`1px solid ${m.menuBorder}`,borderRadius:"10px",overflow:"hidden",display:"flex",flexDirection:"column",position:"relative",aspectRatio:"1",maxWidth:`${z}px`,maxHeight:`${z}px`});const s=document.createElement("div");Object.assign(s.style,{display:"flex",alignItems:"center",padding:"8px 10px 6px",borderBottom:`1px solid ${m.menuBorder}`,flexShrink:"0",gap:"6px"});const{wrap:c,metaPanel:a}=wt(document,e.label??"",e.wafer.metadata??void 0);s.appendChild(c);const r=document.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 ${m.menuBorder}`,borderRadius:"4px",background:m.panelBg,color:m.label,padding:"2px",cursor:"pointer",flexShrink:"0",width:"22px",height:"22px"}),s.appendChild(r),i.appendChild(s);const o=document.createElement("div");Object.assign(o.style,{position:"relative",flex:"1",minHeight:"0",overflow:"hidden",display:"flex",flexDirection:"column"}),i.appendChild(o),a&&o.appendChild(a),O.appendChild(i);const l=Ke(o,e,{viewOptions:e.viewOptions?{...d,...e.viewOptions}:d,toolbarControls:"full",showTooltip:!0,padding:Y,legendPosition:ne,fallbackFormat:he,statsSummary:e.statsSummary,onSaveImage:u.onSaveImage,onSaveText:u.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:i,ctrl:l,canvasWrapper:o,expandBtn:r}}function pn(e){const t=Z[e];if(!t)return;const n=[...R.values()].find(i=>i.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 a of w)a&&a.destroy();w=[],q=[],Z=[],be=0,O.innerHTML="",bt=e.length,yt(e.map(a=>typeof a=="function"?null:a));const t=[];for(let a=0;a<e.length;a++){const r=e[a];if(typeof r=="function"){const o=document.createElement("div");o.className="wmap-gallery-card",Object.assign(o.style,{background:m.menuBg,border:`1px solid ${m.menuBorder}`,borderRadius:"10px",aspectRatio:"1",display:"flex",alignItems:"center",justifyContent:"center"});const l=document.createElement("span");l.textContent="\u2026",Object.assign(l.style,{color:m.label,fontSize:"18px"}),o.appendChild(l),O.appendChild(o),M.push(null),w.push(null),q.push(null),Z.push(null),t.push({index:a,factory:r,placeholder:o}),be++}else{const{ctrl:o,canvasWrapper:l,expandBtn:f}=je(r,a,e.length);M.push(r),w.push(o),q.push(l),Z.push(f)}}M.flatMap(a=>a?[...a.hbinDefs??[],...a.sbinDefs??[]]:[]).some(a=>a.color)&&!u.viewOptions?.colorScheme&&(d={...d,colorScheme:"custom"}),Me();const i=++De;let s=0;function c(){if(i!==De)return;if(s>=t.length){if(ue.has(d.plotMode)){const F=d.plotMode;N(ce(F))}return}const{index:a,factory:r,placeholder:o}=t[s++],l=r();M[a]=l,y[a]=l,yt([l]);const{card:f,ctrl:h,canvasWrapper:g,expandBtn:k}=je(l,a,e.length);w[a]=h,q[a]=g,Z[a]=k,be--,o.replaceWith(f),Me(),!p&&!Q?.placement&&l.statsSummary?.findings.length?(D||(ae="wafers"),p=qe("right"),p.style.maxHeight="calc(100vh - 80px)",p.style.position="sticky",p.style.top="8px",p.style.flexDirection="column",p.style.display="none",(Q?.placement??"right")==="left"?A.insertBefore(p,O):A.appendChild(p),I(),T||(T=V("findings","Summary panel",()=>{if(!p)return;const H=p.style.display!=="none";H||I(),p.style.display=H?"none":"flex",oe(T,!H),X()}),E.appendChild(P()),E.appendChild(T)),X()):p&&p.style.display!=="none"&&I(),X(),setTimeout(c,0)}t.length>0&&setTimeout(c,0)}if(ue.has(d.plotMode)&&y.length>0){const e=$e(d.plotMode);d={...d,...e},N(ce(d.plotMode))}else N(B);const Ct=new ResizeObserver(()=>{L==null&&Se()});Ct.observe(O),p&&I();function un(e){const t=q[e];if(!t)return;t.innerHTML="",Object.assign(t.style,{alignItems:"center",justifyContent:"center"});const n=document.createElement("span");n.textContent="Detached \u2014 open in its own window",Object.assign(n.style,{color:m.label,fontSize:"12px",textAlign:"center",padding:"0 12px"}),t.appendChild(n)}function ke(e,t){for(const a of R.values())if(a.cardIndex===e)return;const n=t.label??"Wafer map",i=$t++,s=w[e]?.getOptions(),c=Dn(n);if(c){const a=c.document;a.title=n,Object.assign(a.documentElement.style,{height:"100%"}),Object.assign(a.body.style,{margin:"0",height:"100vh",overflow:"hidden",display:"flex",flexDirection:"column",fontFamily:'system-ui, -apple-system, "Segoe UI", sans-serif'}),Ln(S,a.documentElement);const r=In(S,a.documentElement,()=>F.setOptions({})),o=a.createElement("div");o.dataset.wmapWindowBanner="1",o.textContent=n,Object.assign(o.style,{display:"none",padding:"6px 12px",fontSize:"12px",fontWeight:"700",background:m.warnBg,color:m.warnText,borderBottom:`1px solid ${m.warnBorder}`,flexShrink:"0"}),a.body.appendChild(o);const l=a.createElement("div");Object.assign(l.style,{flex:"1",minHeight:"0",display:"flex",flexDirection:"column"}),a.body.appendChild(l);const{wrap:f,metaPanel:h}=wt(a,n,t.wafer.metadata??void 0),g=a.createElement("div");Object.assign(g.style,{display:"flex",alignItems:"center",padding:"8px 10px 6px",borderBottom:`1px solid ${m.menuBorder}`,flexShrink:"0",gap:"6px"}),g.appendChild(f),l.appendChild(g);const k=a.createElement("div");Object.assign(k.style,{position:"relative",flex:"1",minHeight:"0",overflow:"hidden",display:"flex",flexDirection:"column"}),h&&k.appendChild(h),l.appendChild(k);const F=ze(k,t,void 0,s),H=setInterval(()=>{c.closed&&Be(i)},400);c.addEventListener("pagehide",()=>Be(i)),R.set(i,{id:i,ctrl:F,cardIndex:e,label:n,closePollId:H,stopThemeSync:r,close:()=>{c.closed||c.close()},setTitle:K=>{a.title=K,o.textContent=K,o.style.display="block"}})}else{const a=Tn({title:n,onClose:()=>Be(i),anchor:S});a.contentWrap.style.flexDirection="column",vt(a,n,t.wafer.metadata??void 0);const r=ze(a.contentWrap,t,void 0,s);R.set(i,{id:i,ctrl:r,cardIndex:e,label:n,closePollId:null,close:()=>a.close(),setTitle:o=>{const l=a.box.querySelector("[data-wmap-window-title]");l&&(l.textContent=o,l.title=o)}})}w[e]?.destroy(),w[e]=null,un(e),pn(e)}function ze(e,t,n,i){const s=t.viewOptions?{...d,...t.viewOptions}:d,c=i?{...s,...i}:s,a=n!==void 0?{...c,plotMode:"value",activeTest:n}:c,r=Ke(e,t,{viewOptions:a,toolbarControls:"full",showTooltip:!0,padding:Y,legendPosition:ne,fallbackFormat:he,statsSummary:t.statsSummary,onSaveImage:u.onSaveImage,onSaveText:u.onSaveText,onClick:t.onClick,onSelect:t.onSelect,showExpandButton:!1,showMetadataBadge:!1});return r.setViewControlsVisible(!0),r.setSummaryVisible(!0),r.setExpandVisible(!1),r}function Be(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 i=t.cardIndex,s=M[i];if(!s)return;const c={...s,viewOptions:n};M[i]=c;const{card:a,ctrl:r,canvasWrapper:o,expandBtn:l}=je(c,i,M.length);q[i]?.parentElement?.replaceWith(a),w[i]=r,q[i]=o,Z[i]=l}function mn(e){const t=R.get(e);t&&(t.close(),Be(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=[...O.querySelectorAll("canvas")];if(!e.length)return;const t=e.length,n=Math.ceil(Math.sqrt(t)),i=Math.ceil(t/n),s=e[0].width,c=e[0].height,a=8,r=window.devicePixelRatio||1,o=Math.round(26*r),l=Math.round(12*r),f=document.createElement("canvas");f.width=n*s+(n-1)*a,f.height=i*(c+o)+(i-1)*a;const h=f.getContext("2d"),g=Sn(O);h.fillStyle=g.background,h.fillRect(0,0,f.width,f.height),e.forEach((k,F)=>{const H=F%n,K=Math.floor(F/n),fe=H*(s+a),b=K*(c+o+a),W=k.closest(".wmap-gallery-card")?.querySelector("span")?.textContent??"";h.fillStyle=g.surface,h.fillRect(fe,b,s,o),h.fillStyle=g.text,h.font=`700 ${l}px system-ui, sans-serif`,h.textAlign="left",h.textBaseline="middle",h.fillText(W,fe+Math.round(10*r),b+o/2,s-Math.round(20*r)),h.drawImage(k,fe,b+o)}),f.toBlob(k=>{k&&jn(k,te,u.onSaveImage)})}return{setItems(e){y=e.map(n=>typeof n=="function"?null:n);const t=d.plotMode;if(ue.has(t))if(e.some(i=>typeof i=="function"))N(e);else{const i=$e(t);d={...d,...i},N(ce(t))}else N(e)},setOptions(e){v(e,{fireCallback:!1})},getOptions(){return{...d}},setFallbackFormat(e){he=e;for(const t of w)t&&t.setFallbackFormat(e)},setLotStatsSummary(e){D=e,ft(),p&&I(),X()},setColumns(e){xt(e)},openUserGuide:pt,destroy(){De++;for(const e of[...R.values()])e.closePollId!=null&&clearInterval(e.closePollId),e.close(),e.ctrl.destroy();R.clear();for(const e of w)e&&e.destroy();w=[],le()?.remove(),Ct.disconnect(),S.ownerDocument.removeEventListener("click",xe,!0),window.removeEventListener("blur",Je),Ht(),Bt(),E.remove(),G.remove(),A.remove(),p?.remove(),de?.destroy()}}}
|
|
@@ -326,5 +326,21 @@ export interface WaferMapController {
|
|
|
326
326
|
destroy(): void;
|
|
327
327
|
}
|
|
328
328
|
export declare function classifyChanged(keys: (keyof WaferViewOptions)[]): 'preference' | 'state' | 'mixed';
|
|
329
|
-
|
|
329
|
+
/**
|
|
330
|
+
* What `renderWaferMap` actually needs: a wafer and its dies, plus anything
|
|
331
|
+
* else `buildWaferMap` would have produced *if* the caller went through it.
|
|
332
|
+
*
|
|
333
|
+
* A `WaferMapResult` satisfies this, so nothing changes for the ordinary
|
|
334
|
+
* `buildWaferMap` → `renderWaferMap` path. The reason it isn't simply
|
|
335
|
+
* `WaferMapResult` is `renderWaferGallery`: it renders every card through this
|
|
336
|
+
* same function, but a card is a `WaferMapDisplayItem` — a hand-built or
|
|
337
|
+
* gallery-synthesised shape carrying no `dataCoverage`, `viewport`,
|
|
338
|
+
* `legendBox`, `binLegendRows` or `reticleConfig`. Those cards used to arrive
|
|
339
|
+
* as `item as WaferMapResult`, which told the type checker the fields were
|
|
340
|
+
* there when at runtime they were simply absent; reading one unguarded threw,
|
|
341
|
+
* and each such read had to be found the hard way. Declaring them optional
|
|
342
|
+
* hands that job back to the compiler.
|
|
343
|
+
*/
|
|
344
|
+
export type RenderableWaferMap = Pick<WaferMapResult, 'wafer' | 'dies'> & Partial<Omit<WaferMapResult, 'wafer' | 'dies'>>;
|
|
345
|
+
export declare function renderWaferMap(container: HTMLElement, result: RenderableWaferMap, options?: RenderOptions): WaferMapController;
|
|
330
346
|
//# sourceMappingURL=renderWaferMap.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{buildView as ei,buildHoverText as ti,findTestDef as wt,resolveTestNumber as Mt}from"../renderer/buildView.js";import{toCanvas as ni,BIN_LEGEND_W as yn,BIN_LEGEND_W_COMPACT as ii,BIN_LEGEND_ADAPT_COMPACT as oi,BIN_LEGEND_ADAPT_FLOATING as ai}from"./toCanvas.js";import{buildWaferMap as si,getTestPassStatus as li,isParametricTest as vn}from"../renderer/buildWaferMap.js";import{analyzeWaferMap as ri}from"../stats/analyzeWaferMap.js";import{CLR as _,Z_BASE as ci,applyOverlayZ as di,getTooltip as bn,hideTooltip as tt,reparentTooltip as pi,positionTooltip as St,createToolbarHelpers as fi,buildModeMenuEl as ui,openReparentedModal as hi,openUserGuideWindow as gi,makePaletteBtn as mi,makeLogScaleBtn as yi,makeLegendStyleBtn as vi,makeOverlaysBtn as bi,makeOrientationBtn as xi,overlayRootFor as xn,saveImageBlob as wi,markMenuTrigger as He,wireMenuA11y as wn,nextFrame as Ct,passFailMenuRows as Mi,requestedPassFailDisplay as Et,logWmapVersionOnce as Si,buildDataModeEntries as Ci,metadataKeyHasData as Ei,metadataModeEntry as Bi}from"./toolbar.js";import{createSummaryPanelEl as Bt,wrapWithSummaryPanel as kt,renderWaferSummaryContent as ki}from"./summaryPanel.js";import{collectWarnings as Di,buildWarningsMenuEl as Li,severityOf as Ti}from"./warnings.js";import"../stats/facets.js";import{ICONS as Mn}from"./icons.js";import{hardBinColor as Pi,softBinColor as Oi,metadataValueColor as Ri}from"../renderer/colorMap.js";import{createInsightsTab as Ii}from"./insightsTab.js";import{createMetadataBadge as Wi}from"./metadataBadge.js";import{getDieKey as Ce}from"../core/dies.js";const Sn=new Set(["colorScheme","rotation","flipX","flipY","showDieLabels","showPartialDies","showRingBoundaries","showQuadrantBoundaries","showReticle","showXYIndicator","ringCount","legendPosition","logScale","colorbarRangeMode"]);export function classifyChanged(z){const x=z.some(I=>Sn.has(I)),M=z.some(I=>!Sn.has(I));return x&&M?"mixed":x?"preference":"state"}export function renderWaferMap(z,x,M={}){Si();const I=z.ownerDocument,j=I.defaultView??window;j.getComputedStyle(z).position==="static"&&(z.style.position="relative");const Cn=z.clientHeight;M.height!=null&&(z.style.height=typeof M.height=="number"?`${M.height}px`:M.height);const Q=document.createElement("div");Object.assign(Q.style,{position:"relative",width:"100%",height:"100%"}),M.maxSize!=null&&(Q.style.maxWidth=`${M.maxSize}px`,Q.style.maxHeight=`${M.maxSize}px`),z.appendChild(Q);const w=document.createElement("div");Object.assign(w.style,{position:"relative",width:"100%",height:"100%"});const a=document.createElement("canvas");Object.assign(a.style,{width:"100%",height:"100%",display:"block"}),w.appendChild(a),Q.appendChild(w);const{onHover:Xe,onClick:En,onSelect:le,onViewOptionsChange:Bn,showTooltip:kn=!0,showToolbar:he=!0,showMetadataBadge:Dn=!0,toolbarControls:Dt="full",showPlotModeSelector:Ln=!0,minZoom:Tn=.4,maxZoom:Pn=20,summaryPanel:Ee,renderTooltip:Lt,passBins:Tt=[1],showHelpButton:On=!1,userGuideExtension:Rn,onExpand:Pt,showExpandButton:Ot=!0,zIndex:In,insights:Rt,warnings:It,viewOptions:Wn={},...re}=M,An=Rt?.enabled??!1,Wt=It?.display??!0,Fn=di(In);let Be=re.fallbackFormat,te=M.statsSummary,ne=[],At=!1;function Ft(){const e=Di({result:x,statsSummary:te}),t=e.length!==ne.length||e.some((n,i)=>n.code!==ne[i]?.code||n.message!==ne[i]?.message);ne=e,(t||!At)&&(At=!0,It?.onWarning?.(e))}Ft();let nt=x,ie=x.wafer,ce=x.dies,S=new Set,$=x.hbinDefs,U=x.sbinDefs,q=x.testDefs,ke=x.metadataFields,Yt=x.reticles?.length?x.reticles:void 0,Ht=x.reticleConfig,Xt=x.view?.dataAxisFlip,it=x.isLotStack,ot=x.aggrMethod,at=x.lotSize,zt=!1,D=null;Dn&&(D=Wi(ie.metadata,{lotStack:Kt()}),D.isEmpty()||w.appendChild(D.el));function Kt(){return it?{lotSize:at??1,aggrMethod:ot}:void 0}function Yn(){if(!D)return;D.update(ie.metadata,Kt());const e=D.el.isConnected;D.isEmpty()&&e?D.el.remove():!D.isEmpty()&&!e&&w.appendChild(D.el)}const Nt=[...$??[],...U??[]].some(e=>e.color);let s={plotMode:"hardBin",colorScheme:Nt?"custom":"default",showDieLabels:!1,showPartialDies:!0,showRingBoundaries:!1,showQuadrantBoundaries:!1,showReticle:!1,showXYIndicator:!1,ringCount:4,rotation:0,flipX:!1,flipY:!1,legendPosition:re.legendPosition??"default",...Wn},oe=null,ge=!1;An&&(oe=Ii({getItems:()=>[{wafer:ie,dies:ce,hbinDefs:$,sbinDefs:U,testDefs:q,label:String(ie.metadata?.waferId??""),statsSummary:te}],getColorSchemeName:()=>s.colorScheme??"default",passBins:Tt,getRingCount:()=>s.ringCount??4,onSaveImage:M.onSaveImage,onSaveText:M.onSaveText,defaultView:Rt?.defaultView,backTab:{label:"Map",onBack:()=>st(!1)}}),Object.assign(oe.el.style,{position:"absolute",inset:"0",background:_.panelBg,overflowY:"auto",paddingTop:he?"44px":"0"}),Q.appendChild(oe.el));function st(e){oe&&(ge=e,oe.el.style.display=e?"flex":"none",A&&(A.style.display=e?"none":"flex"),B&&(B.style.display=e?"none":"flex"),G&&(G.style.display=e?"none":"flex"),D&&(D.el.style.display=e||zt?"none":""),Ge(),F&&(F.innerHTML=e?Mn.wafer:Mn.analysis,F.ariaLabel=e?"Back to wafer view":"Insights"),e&&oe.render())}let h,Vt,W=null,L=null,lt=[],De=null,rt=re.legendOffset??{x:0,y:0},Le=!1,me=!1,Te={x:0,y:0},ct={x:0,y:0},de=!1,ye=!1,Y="pan",ve={x:0,y:0},ze={x:0,y:0},T={x:0,y:0},P={x:0,y:0},Pe=!1,be=!1;function Oe(){const e=s;h=ei(ie,ce,{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:Yt,ringCount:e.ringCount,highlightBin:e.highlightBin,highlightMetadataValue:e.highlightMetadataValue,activeTest:e.activeTest,activeMetadataKey:e.activeMetadataKey,testDefs:q,valueRange:e.valueRange,logScale:e.logScale,isLotStack:it,aggregationMethod:ot??e.aggregationMethod,lotSize:at??e.lotSize,dataAxisFlip:Xt,colorbarRangeMode:e.colorbarRangeMode,passFailDisplay:e.passFailDisplay,fallbackFormat:Be,interactiveTransform:{rotation:e.rotation??0,flipX:e.flipX??!1,flipY:e.flipY??!1}},{hbinDefs:$,sbinDefs:U,metadataFields:ke}),Vt=new Map(h.dies.map((t,n)=>[Ce(t),n]))}Oe();let H=null,pe=null,Ke=null,Hn={},O=null,J=null;function Xn(e){const{kind:t,index:n}=e.variable;b(t==="test"?{plotMode:"value",activeTest:n??0,highlightBin:void 0}:t==="softBin"?{plotMode:"softBin",highlightBin:void 0}:{plotMode:"hardBin",highlightBin:void 0});const i=e.highlight;i.kind==="bin"?(gt(i.dieKeys),b({highlightBin:i.bin})):(i.kind==="region"||i.kind==="dies")&>(i.dieKeys)}function _t(e){ki(e,{wafer:ie,dies:ce,yieldSummary:nt.yield,dataCoverage:nt.dataCoverage,hbinDefs:$,sbinDefs:U,testDefs:q,statsSummary:te,warnings:Wt?ne:[],passBins:Tt,ringCount:s.ringCount??4,colorScheme:s.colorScheme,fallbackFormat:Be,activeFindingId:Ke,findingsFilter:Hn,onFindingsFilterChange:fe,onSaveText:M.onSaveText,onFindingClick:(t,n)=>{Ke===t.id?(Ke=null,gt([]),b({highlightBin:void 0})):(Ke=t.id,Xn(t)),fe()}})}function fe(){H&&_t(H)}function Ne(){O&&_t(O)}function jt(e,t){he&&(t==="right"||t==="top")&&(e.style.paddingTop="44px")}if(Ee?.placement){const e=Ee.placement;H=Bt(e),jt(H,e);const t=w.parentElement,n=w.nextSibling;pe=kt(w,H,e),t?.insertBefore(pe,n),fe()}else if(te){const e=Ee?.defaultOpen??!he;O=Bt("right"),jt(O,"right"),O.style.display=e?"block":"none";const t=w.parentElement,n=w.nextSibling;J=kt(w,O,"right"),t?.insertBefore(J,n),Ne()}const y=kn?bn(I):null;let C=null,E=null,A=null,B=null,Ve=null,R=null,G=null,_e=null,F=null,ee=null,je=null;function Gt(){if(!ee||!je)return;const e=ne.length,t=e>0;if(ee.style.display=t?"flex":"none",je.style.display=t?"":"none",!t)return;const n=Ti(ne[0]),i=`${e} data ${e===1?"warning":"warnings"}`;ee.style.color=n==="error"?_.errText:_.warnText,ee.ariaLabel=n==="error"?`${i} \u2014 the map may be positionally wrong`:i}const zn=24;let xe=null,dt=null,Zt=null,pt=null,ft=null,ut=null,ht=null;function gt(e){S=new Set(e??[]),le&&le(bt()),v()}function Ge(){if(!R)return;const e=!!(H??O);R.style.display=te&&e&&!ge?"flex":"none";const t=H??O,n=t?t.style.display!=="none":!1;te?.hasNotableFindings&&!n?R.style.color=_.findingIndicator:R.dataset.active||(R.style.color=_.icon)}if(he){let ae=function(Z){Y=Z,i(K,Z==="zoom"),i(Ie,Z==="pan"),Ve&&i(Ve,Z==="select"),a.style.cursor=Z==="pan"?"grab":"crosshair"},$e=function(){xe&&(clearTimeout(xe),xe=null),C&&(C.style.opacity="1")},Ue=function(){xe=setTimeout(()=>{C&&(C.style.opacity="0.35")},600)};C=document.createElement("div"),C.dataset.wmapToolbar="single",Object.assign(C.style,{position:"absolute",top:"4px",right:"4px",display:"flex",flexDirection:"row",alignItems:"center",flexWrap:"wrap-reverse",justifyContent:"flex-end",maxWidth:"calc(100% - 8px)",background:_.menuBg,border:`1px solid ${_.menuBorder}`,borderRadius:"4px",boxShadow:"0 1px 4px rgba(0,0,0,0.12)",zIndex:ci,opacity:"0.35",transition:"opacity 0.2s ease",pointerEvents:"auto"});const e=bn(I),t=fi(e),{makeBtn:n,setActive:i,makeSep:o,makeMenuRow:f,makeMenuSection:g,makeDropdown:l,makeCheckMenuBtn:p,closeOpenMenu:r,getOpenMenu:c,setOpenMenu:u}=t;dt=r,Zt=c,I.addEventListener("click",r,!0),A=document.createElement("div"),Object.assign(A.style,{display:"flex",alignItems:"center",gap:"0",flexWrap:"wrap",justifyContent:"flex-end"}),C.appendChild(A);const Se=n("download","Download PNG",Vn);A.appendChild(Se),A.appendChild(o());const K=n("zoomMode","Zoom (drag to zoom region)",()=>ae("zoom")),se=n("zoomIn","Zoom in",()=>Me(a.clientWidth/2,a.clientHeight/2,1.2)),k=n("zoomOut","Zoom out",()=>Me(a.clientWidth/2,a.clientHeight/2,1/1.2)),N=n("reset","Reset zoom (double-click)",()=>Qe());A.appendChild(K),A.appendChild(se),A.appendChild(k),A.appendChild(N),A.appendChild(o());const Ie=n("pan","Pan (drag to move)",()=>ae("pan"));if(A.appendChild(Ie),Ve=n("boxSelect","Select (drag to select dies)",()=>ae("select")),A.appendChild(Ve),i(Ie,!0),Dt!=="view-only"){let Z=function(d){return d.plotMode!==(s.plotMode??"hardBin")?!1:d.plotMode==="value"?(s.activeTest??0)===(d.activeTest??0):d.plotMode==="metadata"?s.activeMetadataKey===d.activeMetadataKey:!0},We=function(d,m){d.activeTest!==void 0?b({plotMode:d.plotMode,activeTest:d.activeTest,activeMetadataKey:void 0,logScale:d.logScale}):d.activeMetadataKey!==void 0?b({plotMode:d.plotMode,activeTest:void 0,activeMetadataKey:d.activeMetadataKey,passFailDisplay:"off"}):b({plotMode:d.plotMode,activeTest:void 0,activeMetadataKey:void 0,passFailDisplay:"off"}),m.remove(),u(null),He(V,!1)};E=document.createElement("div"),Object.assign(E.style,{display:"flex",alignItems:"center",gap:"0",flexWrap:"wrap",justifyContent:"flex-end"}),C.appendChild(E),B=document.createElement("div"),Object.assign(B.style,{display:"flex",alignItems:"center",gap:"0"}),E.appendChild(B),B.appendChild(o());const qe=()=>{const d=c();d&&(d.remove(),u(null)),He(V,!1)},V=n("mode","Plot mode",()=>{if(c()){qe();return}const d=h.dies,m=h.testDefs,{testEntries:et,binEntries:ue,stackedEntries:Ae}=Ci(d,m,{includeStacked:h.isLotStack}),xt=(ke??[]).filter(Ye=>Ei(d,Ye.key)).map(Bi),Fe=ui(V.getBoundingClientRect(),et,ue,Ae,Z,We,{makeMenuRow:f,makeMenuSection:g},s.plotMode??"hardBin",V.ownerDocument.defaultView??window,xt);xn(V).appendChild(Fe),u(Fe),He(V,!0),wn(Fe,V,qe)});He(V,!1);const{btn:_n,sync:jn}=mi(t,()=>s.plotMode??"hardBin",()=>s.colorScheme??"default",()=>Nt,d=>b({colorScheme:d}));ft=jn,ft();const Gn=bi(t,()=>{const d=!!h.hasReticle,m=(s.plotMode??"hardBin")==="value",{testNumber:et}=Mt(s.activeTest??0,h.testDefs),ue=wt(h.testDefs,et),Ae=m&&ue!==void 0&&!vn(ue),xt=m&&!Ae&&(ue?.limitLow!==void 0||ue?.limitHigh!==void 0),Fe=m&&!Ae&&h.dies.some(Ye=>li(Ye,et,ue)!==void 0);return[{label:"Ring boundaries",active:!!s.showRingBoundaries,onClick:()=>b({showRingBoundaries:!s.showRingBoundaries})},{label:"Quadrant lines",active:!!s.showQuadrantBoundaries,onClick:()=>b({showQuadrantBoundaries:!s.showQuadrantBoundaries})},{label:"Die labels",active:!!s.showDieLabels,onClick:()=>b({showDieLabels:!s.showDieLabels})},{label:"Reticle grid",active:!!s.showReticle,enabled:d,onClick:()=>b({showReticle:!s.showReticle})},{label:"XY indicator",active:!!s.showXYIndicator,onClick:()=>b({showXYIndicator:!s.showXYIndicator})},...Mi({functionalActive:Ae,hasLimits:xt,hasRecorded:Fe,display:Et(s)},Ye=>b({passFailDisplay:Ye}))]},()=>!!(s.showRingBoundaries||s.showQuadrantBoundaries||s.showDieLabels||s.showReticle||s.showXYIndicator||Et(s)!=="off")),{btn:Zn,sync:Qn}=vi(t,()=>s,d=>b({legendPosition:d}));pt=Qn,pt();const mn=()=>{const{testNumber:d}=Mt(s.activeTest??0,q),m=wt(q,d);return m!==void 0&&!vn(m)},{btn:$n,sync:Un}=yi(t,()=>({...s,functionalActive:mn()}),d=>b(d));ut=Un,ut();const qn=()=>{const{testNumber:d}=Mt(s.activeTest??0,q),m=wt(q,d);return m!==void 0&&(m.limitLow!==void 0||m.limitHigh!==void 0)},Je=n("specRange","Colorbar range: spec limits",()=>{const d=s.colorbarRangeMode==="data"?"spec":"data";b({colorbarRangeMode:d})});ht=()=>{const d=s.plotMode==="value"&&qn()&&Et(s)==="off"&&!mn();Je.style.display=d?"":"none";const m=(s.colorbarRangeMode??"spec")==="spec";i(Je,m),Je.ariaLabel=m?"Colorbar range: spec limits (click for data range)":"Colorbar range: data range (click for spec limits)"},ht();const Jn=xi(t,()=>s,d=>b(d));Ln&&B.appendChild(V),B.appendChild(_n),B.appendChild($n),B.appendChild(Je),B.appendChild(o()),B.appendChild(Gn),B.appendChild(o()),B.appendChild(Zn),B.appendChild(o()),B.appendChild(Jn),te&&(R=n("findings","Summary panel",()=>{const d=H??O;if(!d)return;const m=d.style.display!=="none";d.style.display=m?"none":"block",i(R,!m),Ge()}),E.appendChild(o()),E.appendChild(R),O?.style.display!=="none"&&i(R,!0),Ge()),Wt&&(je=o(),ee=n("warning","Data warnings",()=>{const d=c();if(r(new MouseEvent("click")),d)return;const m=Li(ee.getBoundingClientRect(),ne);xn(Q).appendChild(m),u(m),wn(m,ee,()=>r(new MouseEvent("click")))}),He(ee,!1),E.appendChild(je),E.appendChild(ee),Gt()),Ot&&(E.appendChild(o()),G=n("expand","Expand (E)",Pt??Qt),E.appendChild(G)),oe&&(E.appendChild(o()),F=n("analysis","Insights",()=>{st(!ge),i(F,ge)}),E.appendChild(F)),On&&(E.appendChild(o()),_e=n("help","User guide",()=>gn()),E.appendChild(_e))}Q.appendChild(C),a.addEventListener("mouseenter",$e),a.addEventListener("mouseleave",Ue),C.addEventListener("mouseenter",$e),C.addEventListener("mouseleave",Ue)}let we=null;function Qt(){we&&(we.close(),we=null);const e=pe??J??w;e.style.flex="1",e.style.minWidth="0",e.style.minHeight="0";const t=hi(C?[e,C]:[e],{ownerDocument:I,onClosed:()=>{we=null,G&&(G.style.display="flex"),a.focus({preventScroll:!0})}});t&&(C&&(t.contentWrap.style.position="relative"),we=t,G&&(G.style.display="none"))}function $t(e){const t=s.plotMode;if(s={...s,...e},e.plotMode!==void 0&&e.plotMode!==t){W=null;const o=s.plotMode;(o==="hardBin"||o==="softBin")&&!new Set(["default","accessible","custom"]).has(s.colorScheme??"")&&(s={...s,colorScheme:"default"})}Object.keys(e).every(o=>o==="legendPosition")||Oe(),pt?.(),ft?.(),ut?.(),ht?.(),v();const i=e.plotMode!==void 0&&e.plotMode!==t;(e.colorScheme!==void 0||i)&&(fe(),Ne())}function b(e){$t(e);const t=Object.keys(e);Bn?.(s,t,classifyChanged(t))}let mt=!1;function yt(){mt||(mt=!0,Ct(()=>{mt=!1,v()},j))}function v(){const e=L??void 0,t=h.dies[0],n=t?{x:t.width,y:t.height}:re.diePitchMm,i=Math.floor(a.clientWidth||a.width),o=!!($?.length||U?.length||h.dies.some(c=>c.hbin!=null||c.sbin!=null)),f=s.legendPosition??"default",g=f==="default"||f==="compact",l=(re.colorbarWidth??16)+28,p=o&&g?f!=="default"?Math.max(yn,l):i<ai?0:i<oi?Math.max(ii,l):Math.max(yn,l):void 0,r=ni(a,h,{...re,topClearance:he?zn:0,minRightReserve:p,legendPosition:f,legendOffset:rt,diePitchMm:n,fallbackFormat:Be,showAxes:re.showAxes??L!==null,viewport:e,activeBin:s.plotMode==="metadata"?s.highlightMetadataValue:s.highlightBin,hbinDefs:$,sbinDefs:U,metadataFields:ke});lt=r.binLegendRows,De=r.legendBox??null,W||(W=r.viewport),S.size>0&&Kn(),ye&&Nn()}function Kn(){const e=X();if(!e)return;const t=a.getContext("2d"),n=h.hoverPoints,i=h.rectangles[0],o=i?i.width/2*e.ppm:e.ppm*.5,f=i?i.height/2*e.ppm:e.ppm*.5,g=Math.max(1,Math.min(3,o*.08)),l=o-g,p=f-g,r=[];for(const c of S){const u=Vt.get(c);u!==void 0&&r.push({sx:e.originX+n[u].x*e.ppm,sy:e.originY-n[u].y*e.ppm})}if(r.length){t.save(),t.setLineDash([]),t.fillStyle="rgba(0,0,0,0.12)",t.beginPath();for(const{sx:c,sy:u}of r)t.rect(c-l,u-p,l*2,p*2);t.fill(),t.strokeStyle="rgba(255,255,255,0.9)",t.lineWidth=3,t.beginPath();for(const{sx:c,sy:u}of r)t.rect(c-l,u-p,l*2,p*2);t.stroke(),t.strokeStyle="rgba(0,0,0,0.9)",t.lineWidth=1.5,t.beginPath();for(const{sx:c,sy:u}of r)t.rect(c-l,u-p,l*2,p*2);t.stroke(),t.restore()}}function Nn(){const e=a.getContext("2d"),t=Math.min(T.x,P.x),n=Math.min(T.y,P.y),i=Math.abs(P.x-T.x),o=Math.abs(P.y-T.y);e.save(),e.fillStyle="rgba(0,0,0,0.08)",e.fillRect(t,n,i,o),e.setLineDash([5,3]),e.strokeStyle="rgba(255,255,255,0.9)",e.lineWidth=3,e.strokeRect(t,n,i,o),e.strokeStyle="rgba(0,0,0,0.9)",e.lineWidth=1.5,e.strokeRect(t,n,i,o),e.restore()}function Vn(){a.toBlob(e=>{e&&wi(e,M.downloadFilename??"wafermap",M.onSaveImage)})}function Ut(e){return W?Math.max(W.ppm*Tn,Math.min(W.ppm*Pn,e)):e}function Me(e,t,n){const i=L??W;if(!i)return;const o=Ut(i.ppm*n),f=o/i.ppm,g=e-(e-i.originX)*f,l=t-(t-i.originY)*f,p=(W?.snapDist??1)/(o/(W?.ppm??o));L={originX:g,originY:l,ppm:o,snapDist:p},v()}function X(){return L??W}function qt(e){if(e.ctrlKey||e.metaKey){e.preventDefault();const t=a.getBoundingClientRect(),n=e.deltaY<0?1.12:1/1.12;Me(e.clientX-t.left,e.clientY-t.top,n)}else if(L!==null){e.preventDefault();const t=X(),n=L.snapDist;L={originX:t.originX-e.deltaX,originY:t.originY-e.deltaY,ppm:t.ppm,snapDist:n},v()}}function Jt(e,t,n){return e>=n.x&&e<n.x+n.w&&t>=n.y&&t<n.y+n.h}function en(e){if(e.button!==0||!X())return;a.focus({preventScroll:!0}),a.setPointerCapture(e.pointerId);const t=a.getBoundingClientRect(),n=e.clientX-t.left,i=e.clientY-t.top;if(De&&s.legendPosition==="floating"&&Jt(n,i,De)){me=!0,Te={x:n,y:i},ct={...rt};return}if(Pe&&Y!=="pan"){be=!0,de=!0,ve={x:n,y:i},ze={x:X().originX,y:X().originY},a.style.cursor="grabbing";return}if(Y==="zoom"||Y==="select"){ye=!0,T=P={x:n,y:i};return}de=!0,ve={x:n,y:i},ze={x:X().originX,y:X().originY},a.style.cursor="grabbing"}function tn(e){const t=a.getBoundingClientRect(),n=e.clientX-t.left,i=e.clientY-t.top;if(ye){P={x:n,y:i},yt();return}if(me){const c=n-Te.x,u=i-Te.y;c*c+u*u>16&&(me=!1,Le=!0,a.style.cursor="grabbing")}if(Le){rt={x:ct.x+(n-Te.x),y:ct.y+(i-Te.y)},yt();return}if(de){const c=X(),u=L?.snapDist??W?.snapDist??1;L={originX:ze.x+(n-ve.x),originY:ze.y+(i-ve.y),ppm:c.ppm,snapDist:u},yt();return}const o=X();if(!o)return;const f=(n-o.originX)/o.ppm,g=(o.originY-i)/o.ppm,p=sn(f,g,o.snapDist)?.die??null,r=lt.find(c=>n>=c.x&&n<c.x+c.w&&i>=c.y&&i<c.y+c.h);if(r){a.style.cursor="pointer",y&&(y.innerHTML=r.label??`Bin ${r.bin}`,y.style.display="block",St(y,a,e.clientX,e.clientY)),Xe?.(null,e);return}if(Y==="pan"&&(a.style.cursor=p?"crosshair":"grab"),y)if(p)if(Lt){const c=Lt(p);c===null?y.style.display="none":(typeof c=="string"?y.innerHTML=c:(y.innerHTML="",y.appendChild(c)),y.style.display="block",St(y,a,e.clientX,e.clientY))}else y.innerHTML=ti(p,h.plotMode,{testDefs:q,hbinDefs:$,sbinDefs:U,fallbackFormat:Be,aggrMethod:h.aggrMethod,lotSize:h.lotSize,waferMeta:ie.metadata,activeTest:h.activeTest,reticleConfig:Ht}),y.style.display="block",St(y,a,e.clientX,e.clientY);else y.style.display="none";Xe?.(p,e)}function nn(e){const t=a.getBoundingClientRect(),n=e.clientX-t.left,i=e.clientY-t.top,o=e.ctrlKey||e.metaKey;if(y&&(n<0||i<0||n>t.width||i>t.height)&&(y.style.display="none"),ye){ye=!1,P={x:n,y:i};const l=n-T.x,p=i-T.y,r=X();if(Y==="zoom"){if(l*l+p*p<25)Me(n,i,2);else if(r){const c=Math.min(T.x,P.x),u=Math.max(T.x,P.x),ae=Math.min(T.y,P.y),Se=Math.max(T.y,P.y),K=u-c,se=Se-ae;if(K>4&&se>4){const k=a.clientWidth,N=a.clientHeight,Ie=k/K,$e=N/se,Ue=Math.min(Ie,$e),Z=Ut(r.ppm*Ue),We=Z/r.ppm,qe=(c+u)/2,V=(ae+Se)/2;L={originX:k/2-(qe-r.originX)*We,originY:N/2-(V-r.originY)*We,ppm:Z,snapDist:r.snapDist/We}}}v(),a.style.cursor="crosshair";return}if(l*l+p*p<25)vt(n,i,o,e);else if(r){const c=(Math.min(T.x,P.x)-r.originX)/r.ppm,u=(Math.max(T.x,P.x)-r.originX)/r.ppm,ae=(r.originY-Math.max(T.y,P.y))/r.ppm,Se=(r.originY-Math.min(T.y,P.y))/r.ppm,K=h.hoverPoints,se=[];for(let k=0;k<K.length;k++)if(K[k].x>=c&&K[k].x<=u&&K[k].y>=ae&&K[k].y<=Se){const N=h.dies[k];N&&se.push(N)}if(o)for(const k of se){const N=Ce(k);S.has(N)?S.delete(N):S.add(N)}else S=new Set(se.map(k=>Ce(k)));le?.(bt())}v(),a.style.cursor="crosshair";return}if(me){me=!1,vt(n,i,o,e);return}if(Le){Le=!1,a.style.cursor="grab";return}if(!de)return;if(de=!1,be){be=!1,a.style.cursor=Pe||Y==="pan"?"grab":"crosshair";return}a.style.cursor=Y==="pan"?"grab":"crosshair";const f=n-ve.x,g=i-ve.y;f*f+g*g<25&&vt(n,i,o,e)}function vt(e,t,n,i){for(const l of lt)if(e>=l.x&&e<l.x+l.w&&t>=l.y&&t<l.y+l.h){if(typeof l.bin=="number"){const p=s.highlightBin===l.bin?void 0:l.bin;b({highlightBin:p})}else{const p=s.highlightMetadataValue===l.bin?void 0:l.bin;b({highlightMetadataValue:p})}return}if(De&&Jt(e,t,De))return;const o=X();if(!o)return;const g=sn((e-o.originX)/o.ppm,(o.originY-t)/o.ppm,o.snapDist)?.die??null;if(g){En?.(g,i);const l=Ce(g);n?S.has(l)?S.delete(l):S.add(l):S=new Set([l]),le?.(bt()),v()}else n||(S=new Set,le?.([]),v())}function bt(){const e=[],t=h.hoverPoints;for(let n=0;n<t.length;n++){const i=h.dies[n];i&&S.has(Ce(i))&&e.push(i)}return e}function on(){y&&tt(I),Xe?.(null,new MouseEvent("mouseleave")),a.style.cursor=Y==="pan"?"grab":"crosshair"}function an(){de=!1,be=!1,ye=!1,me=!1,Le=!1,y&&tt(I),Xe?.(null,new MouseEvent("mouseleave")),a.style.cursor=Y==="pan"?"grab":"crosshair",v()}function sn(e,t,n){const i=h.hoverPoints,o=h.rectangles;for(let p=0;p<o.length;p++){const r=o[p];if(Math.abs(e-r.x)<=r.width/2&&Math.abs(t-r.y)<=r.height/2){const c=h.dies[p];return c?{die:c,index:p}:null}}let f=null,g=-1,l=n*n;for(let p=0;p<i.length;p++){const r=i[p].x-e,c=i[p].y-t,u=r*r+c*c;u<l&&(l=u,f=h.dies[p]??null,g=p)}return f?{die:f,index:g}:null}const ln=new j.ResizeObserver(()=>{W=null,L=null,v()});ln.observe(a),M.height==null&&Cn<=0&&Ct(()=>Ct(()=>{z.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=j.matchMedia(`(resolution: ${j.devicePixelRatio}dppx)`);const Ze=()=>{Re.removeEventListener("change",Ze),Re=j.matchMedia(`(resolution: ${j.devicePixelRatio}dppx)`),Re.addEventListener("change",Ze),v()};Re.addEventListener("change",Ze);const rn=j.matchMedia("(prefers-color-scheme: dark)"),cn=()=>v();rn.addEventListener("change",cn);const dn=()=>{y&&tt(I)};j.addEventListener("blur",dn);function pn(e){if(e.key==="Escape"&&S.size>0&&(S=new Set,le?.([]),v()),(e.key==="e"||e.key==="E")&&Dt!=="view-only"&&Ot&&!ge&&(e.stopPropagation(),(Pt??Qt)()),(e.ctrlKey||e.metaKey)&&(e.key==="="||e.key==="+"?(e.preventDefault(),Me(a.clientWidth/2,a.clientHeight/2,1.2)):e.key==="-"?(e.preventDefault(),Me(a.clientWidth/2,a.clientHeight/2,1/1.2)):e.key==="0"&&(e.preventDefault(),Qe())),!e.ctrlKey&&!e.metaKey&&!e.shiftKey){const n=X();if(n){const i=L?.snapDist??W?.snapDist??1;let o=0,f=0;e.key==="ArrowLeft"&&(o=20,e.preventDefault()),e.key==="ArrowRight"&&(o=-20,e.preventDefault()),e.key==="ArrowUp"&&(f=20,e.preventDefault()),e.key==="ArrowDown"&&(f=-20,e.preventDefault()),(o||f)&&(L={originX:n.originX+o,originY:n.originY+f,ppm:n.ppm,snapDist:i},v())}e.key===" "&&!Pe&&(e.preventDefault(),Pe=!0,Y!=="pan"&&(a.style.cursor="grab"))}}function fn(e){e.key===" "&&(Pe=!1,be&&(de=!1,be=!1),a.style.cursor=Y==="pan"?"grab":"crosshair")}a.style.cursor="grab",a.setAttribute("tabindex","0"),a.addEventListener("wheel",qt,{passive:!1}),a.addEventListener("pointerdown",en),a.addEventListener("pointermove",tn),a.addEventListener("pointerup",nn),a.addEventListener("pointerleave",on),a.addEventListener("pointercancel",an);const un=()=>Qe();a.addEventListener("dblclick",un),a.addEventListener("keydown",pn),a.addEventListener("keyup",fn);const hn=e=>{e.stopPropagation()};a.addEventListener("click",hn),a.clientWidth,v();function Qe(){W=null,L=null,v()}function gn(){import("./userGuideHtml.js").then(e=>gi({buildWaferMap:si,renderWaferMap,renderWaferGallery:void 0,analyzeWaferMap:ri},e.USER_GUIDE_HTML,Rn,z))}return{setDies(e){ce=e,Oe(),v(),H&&fe()},setResult(e){nt=e,ie=e.wafer,ce=e.dies,$=e.hbinDefs,U=e.sbinDefs,q=e.testDefs,ke=e.metadataFields,Yt=e.reticles?.length?e.reticles:void 0,Ht=e.reticleConfig,Xt=e.view?.dataAxisFlip,it=e.isLotStack,ot=e.aggrMethod,at=e.lotSize,Yn(),Oe(),v(),H&&fe()},setOptions(e){$t(e)},getOptions(){return{...s}},resetZoom:Qe,setSelection(e){S=new Set(e.map(t=>Ce(t))),v()},clearSelection(){S=new Set,le?.([]),v()},setFallbackFormat(e){Be=e,Oe(),v()},setStatsSummary(e){if(te=e,Ft(),Gt(),H)fe();else if(O)Ne();else if(e&&!Ee?.placement){const t=Ee?.defaultOpen??!he;O=Bt("right"),O.style.display=t?"block":"none";const n=w.parentElement,i=w.nextSibling;J=kt(w,O,"right"),n?.insertBefore(J,i),Ne()}Ge()},setSummaryVisible(e){R&&(R.style.display=e?"flex":"none")},setViewControlsVisible(e){E&&(E.style.display=e?"flex":"none")},setExpandVisible(e){G&&(G.style.display=e?"flex":"none")},setHelpButtonVisible(e){_e&&(_e.style.display=e?"flex":"none")},setMetadataBadgeVisible(e){zt=!e,D&&(D.el.style.display=e&&!ge?"":"none")},openUserGuide:gn,setInsightsOpen(e){st(e),F&&(e?(F.dataset.active="1",F.style.background=_.bgActive,F.style.color=_.iconActive):(delete F.dataset.active,F.style.background="transparent",F.style.color=_.icon))},closeSummaryPanel(){const e=H??O;!e||e.style.display==="none"||(e.style.display="none",R&&(delete R.dataset.active,R.style.background="transparent",R.style.color=_.icon))},setTooltipParent(e){y&&pi(e)},getActiveLegend(){const e=s.plotMode;if(e==="metadata"){const o=s.activeMetadataKey;if(!o)return null;const f=ke?.find(l=>l.key===o),g=[...new Set(ce.map(l=>l.metadata?.[o]).filter(l=>l!=null&&(typeof l=="string"||typeof l=="number"||typeof l=="boolean")).map(String))].sort();return g.length?g.map((l,p)=>{const r=f?.values?.find(u=>u.value===l),c=r?.color??Ri(p);return{bin:l,name:r?.label??l,color:c}}):null}if(e!=="hardBin"&&e!=="softBin")return null;const t=e==="hardBin",n=t?$:U,i=[...new Set(ce.map(o=>t?o.hbin:o.sbin).filter(o=>o!==void 0))].sort((o,f)=>o-f);return i.length?i.map(o=>{const f=n?.find(l=>l.bin===o),g=f?.color??(t?Pi(o):Oi(o));return{bin:o,name:f?.name??`Bin ${o}`,color:g}}):null},destroy(){we?.close(),xe&&clearTimeout(xe),Zt?.()?.remove(),dt&&I.removeEventListener("click",dt,!0),a.removeEventListener("wheel",qt),a.removeEventListener("pointerdown",en),a.removeEventListener("pointermove",tn),a.removeEventListener("pointerup",nn),a.removeEventListener("pointerleave",on),a.removeEventListener("pointercancel",an),a.removeEventListener("dblclick",un),a.removeEventListener("keydown",pn),a.removeEventListener("keyup",fn),a.removeEventListener("click",hn),ln.disconnect(),Re.removeEventListener("change",Ze),rn.removeEventListener("change",cn),j.removeEventListener("blur",dn),Fn(),y&&tt(I),C?.remove(),pe&&(pe.parentElement?.insertBefore(w,pe),pe.remove()),J&&(J.parentElement?.insertBefore(w,J),J.remove()),w.remove(),a.style.cursor="",oe?.destroy(),D?.destroy(),Q.remove()}}}
|
|
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 x,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 Me,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 h=N.some(W=>Dn.has(W)),C=N.some(W=>!Dn.has(W));return h&&C?"mixed":h?"preference":"state"}export function renderWaferMap(N,h,C={}){ki();const W=N.ownerDocument,_=W.defaultView??window;_.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=h.dataCoverage?h.dataCoverage.unpositionedDies:h.dies.filter(e=>!Bn(e)).length,ze=(h.dataCoverage?h.dataCoverage.totalDies:h.dies.length-at)===0&&at>0,q=document.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 w=document.createElement("div");Object.assign(w.style,{position:"relative",width:"100%",height:"100%"});const a=document.createElement("canvas");Object.assign(a.style,{width:"100%",height:"100%",display:"block"}),w.appendChild(a),q.appendChild(w);let Xe=null;if(at>0){let n=function(){if(t){const u=Ni(e,h.testDefs,{onSaveText:C.onSaveText});if(u)return u}const i=it(h.testDefs,l.activeTest??0),r=Bt(i)?l.logScale??i?.logScale??!1:!1;return Ki(e,h.testDefs,{plotMode:l.plotMode??"hardBin",activeTest:l.activeTest,hbinDefs:$,sbinDefs:G,colorScheme:l.colorScheme,logScale:r,colorbarRangeMode:l.colorbarRangeMode,valueRangeDies:h.dies})},o=function(i){const r=document.createElement("button");return r.type="button",Object.assign(r.style,{fontSize:"10px",padding:"2px 6px",borderRadius:"4px",flexShrink:"0",border:`1px solid ${x.menuBorder}`,background:x.menuBg,color:x.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=h.dies.filter(i=>!Bn(i));let t=!1;if(ze){const i=document.createElement("div");Object.assign(i.style,{position:"absolute",inset:"0",background:x.panelBg,padding:"12px",paddingTop:C.showToolbar??!0?"44px":"12px",boxSizing:"border-box",overflow:"hidden",display:"flex",flexDirection:"column",gap:"8px",zIndex:"1"});const r=document.createElement("div");Object.assign(r.style,{display:"flex",justifyContent:"space-between",alignItems:"flex-start",gap:"8px"});const u=document.createElement("span");Object.assign(u.style,{fontSize:"11px",color:x.label,lineHeight:"1.4"}),u.textContent="No die position data for this wafer.",r.appendChild(u);const s=document.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),w.appendChild(i),Xe=()=>{t||s.replaceChildren(n())}}else{const i=document.createElement("div");Object.assign(i.style,{position:"absolute",left:"0",right:"0",bottom:"0",zIndex:"3",background:x.panelBg,borderTop:`1px solid ${x.menuBorder}`,fontSize:"11px",color:x.text,cursor:"pointer",padding:"4px 8px",display:"flex",alignItems:"center",justifyContent:"space-between",gap:"8px"});const r=document.createElement("span");r.textContent=`+${e.length} ${e.length===1?"die":"dies"} without position data`,i.appendChild(r);const u=document.createElement("span");u.textContent="\u25BE",Object.assign(u.style,{fontSize:"12px",lineHeight:"1",color:x.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=document.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:x.panelBg,borderTop:`1px solid ${x.menuBorder}`,padding:"8px",boxSizing:"border-box",display:"flex",flexDirection:"column",gap:"8px"}),s.addEventListener("click",Q=>Q.stopPropagation());const g=document.createElement("div");Object.assign(g.style,{display:"flex",justifyContent:"flex-end"}),g.appendChild(o(()=>{d&&d.replaceChildren(n())})),s.appendChild(g),d=document.createElement("div"),Object.assign(d.style,{flex:"1",minHeight:"0",overflow:"auto",display:"flex",flexDirection:"column"}),d.appendChild(n()),s.appendChild(d),w.appendChild(s)}else s&&(s.remove(),s=null,d=null)}),w.appendChild(i),Xe=()=>{d&&!t&&d.replaceChildren(n())}}}const{onHover:Ne,onClick:Ln,onSelect:re,onViewOptionsChange:Tn,showTooltip:Pn=!0,showToolbar:ge=!0,showMetadataBadge:On=!0,toolbarControls:Ot="full",showPlotModeSelector:Rn=!0,minZoom:In=.4,maxZoom:Wn=20,summaryPanel:Ee,renderTooltip:Rt,passBins:It=[1],showHelpButton:Hn=!1,userGuideExtension:An,onExpand:Wt,showExpandButton:Ht=!0,zIndex:Fn,insights:At,warnings:Ft,viewOptions:Yn={},...de}=C,zn=At?.enabled??!1,Yt=Ft?.display??!0,Xn=gi(Fn);let Be=de.fallbackFormat,ne=C.statsSummary,ie=[],zt=!1;function Xt(){const e=Ri({result:h,statsSummary:ne}),t=e.length!==ie.length||e.some((n,o)=>n.code!==ie[o]?.code||n.message!==ie[o]?.message);ie=e,(t||!zt)&&(zt=!0,Ft?.onWarning?.(e))}Xt();let st=h,oe=h.wafer,ae=h.dies,M=new Set,$=h.hbinDefs,G=h.sbinDefs,J=h.testDefs,De=h.metadataFields,Nt=h.reticles?.length?h.reticles:void 0,Kt=h.reticleConfig,Vt=h.view?.dataAxisFlip,lt=h.isLotStack??!1,rt=h.aggrMethod,dt=h.lotSize,jt=!1,L=null;On&&(L=zi(oe.metadata,{lotStack:_t()}),L.isEmpty()||w.appendChild(L.el));function _t(){return lt?{lotSize:dt??1,aggrMethod:rt}:void 0}function Nn(){if(!L)return;L.update(oe.metadata,_t());const e=L.el.isConnected;L.isEmpty()&&e?L.el.remove():!L.isEmpty()&&!e&&w.appendChild(L.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:de.legendPosition??"default",...Yn},se=null,he=!1;zn&&(se=Yi({getItems:()=>[{wafer:oe,dies:ae,hbinDefs:$,sbinDefs:G,testDefs:J,label:String(oe.metadata?.waferId??""),statsSummary:ne}],getColorSchemeName:()=>l.colorScheme??"default",passBins:It,getRingCount:()=>l.ringCount??4,onSaveImage:C.onSaveImage,onSaveText:C.onSaveText,defaultView:At?.defaultView,backTab:{label:"Map",onBack:()=>ct(!1)}}),Object.assign(se.el.style,{position:"absolute",inset:"0",background:x.panelBg,overflowY:"auto",paddingTop:ge?"44px":"0"}),q.appendChild(se.el));function ct(e){se&&(he=e,se.el.style.display=e?"flex":"none",A&&(A.style.display=e||ze?"none":"flex"),D&&(D.style.display=e?"none":"flex"),Z&&(Z.style.display=e?"none":"flex"),L&&(L.el.style.display=e||jt?"none":""),Ze(),F&&(F.innerHTML=e?En.wafer:En.analysis,F.ariaLabel=e?"Back to wafer view":"Insights"),e&&se.render())}let m,Gt,H=null,T=null,pt=[],ke=null,ft=de.legendOffset??{x:0,y:0},Le=!1,me=!1,Te={x:0,y:0},ut={x:0,y:0},ce=!1,ye=!1,Y="pan",be={x:0,y:0},Ke={x:0,y:0},P={x:0,y:0},O={x:0,y:0},Pe=!1,ve=!1;function Oe(){const e=l;m=oi(oe,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:J,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:Be,interactiveTransform:{rotation:e.rotation??0,flipX:e.flipX??!1,flipY:e.flipY??!1}},{hbinDefs:$,sbinDefs:G,metadataFields:De}),Gt=new Map(m.dies.map((t,n)=>[Me(t),n]))}Oe();let z=null,pe=null,Ve=null,Kn={},R=null,ee=null;function Vn(e){const{kind:t,index:n}=e.variable;S(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),S({highlightBin:o.bin})):(o.kind==="region"||o.kind==="dies")&&vt(o.dieKeys)}function Zt(e){Oi(e,{wafer:oe,dies:ae,yieldSummary:st.yield,dataCoverage:st.dataCoverage,hbinDefs:$,sbinDefs:G,testDefs:J,statsSummary:ne,warnings:Yt?ie:[],passBins:It,ringCount:l.ringCount??4,colorScheme:l.colorScheme,fallbackFormat:Be,activeFindingId:Ve,findingsFilter:Kn,onFindingsFilterChange:fe,onSaveText:C.onSaveText,onFindingClick:(t,n)=>{Ve===t.id?(Ve=null,vt([]),S({highlightBin:void 0})):(Ve=t.id,Vn(t)),fe()}})}function fe(){z&&Zt(z)}function je(){R&&Zt(R)}function Qt(e,t){ge&&(t==="right"||t==="top")&&(e.style.paddingTop="44px")}if(Ee?.placement){const e=Ee.placement;z=Tt(e),Qt(z,e);const t=w.parentElement,n=w.nextSibling;pe=Pt(w,z,e),t?.insertBefore(pe,n),fe()}else if(ne){const e=Ee?.defaultOpen??!ge;R=Tt("right"),Qt(R,"right"),R.style.display=e?"block":"none";const t=w.parentElement,n=w.nextSibling;ee=Pt(w,R,"right"),t?.insertBefore(ee,n),je()}const b=Pn?Sn(W):null;let E=null,B=null,A=null,D=null,_e=null,I=null,Z=null,$e=null,F=null,te=null,Ge=null;function Ut(){if(!te||!Ge)return;const e=ie.length,t=e>0;if(te.style.display=t?"flex":"none",Ge.style.display=t?"":"none",!t)return;const n=Wi(ie[0]),o=`${e} data ${e===1?"warning":"warnings"}`;te.style.color=n==="error"?x.errText:x.warnText,te.ariaLabel=n==="error"?`${o} \u2014 the map may be positionally wrong`:o}const jn=24;let xe=null,gt=null,qt=null,ht=null,mt=null,yt=null,bt=null;function vt(e){M=new Set(e??[]),re&&re(Ct()),v()}function Ze(){if(!I)return;const e=!!(z??R);I.style.display=ne&&e&&!he?"flex":"none";const t=z??R,n=t?t.style.display!=="none":!1;ne?.hasNotableFindings&&!n?I.style.color=x.findingIndicator:I.dataset.active||(I.style.color=x.icon)}if(ge){let Q=function(U){Y=U,o(K,U==="zoom"),o(Ie,U==="pan"),_e&&o(_e,U==="select"),a.style.cursor=U==="pan"?"grab":"crosshair"},qe=function(){xe&&(clearTimeout(xe),xe=null),E&&(E.style.opacity="1")},Je=function(){xe=setTimeout(()=>{E&&(E.style.opacity="0.35")},600)};E=document.createElement("div"),E.dataset.wmapToolbar="single",Object.assign(E.style,{position:"absolute",top:"4px",right:"4px",display:"flex",flexDirection:"row",alignItems:"center",flexWrap:"wrap-reverse",justifyContent:"flex-end",maxWidth:"calc(100% - 8px)",background:x.menuBg,border:`1px solid ${x.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(W),t=mi(e),{makeBtn:n,setActive:o,makeSep:i,makeMenuRow:r,makeMenuSection:u,makeDropdown:s,makeCheckMenuBtn:d,closeOpenMenu:c,getOpenMenu:p,setOpenMenu:g}=t;gt=c,qt=p,W.addEventListener("click",c,!0),A=document.createElement("div"),Object.assign(A.style,{display:ze?"none":"flex",alignItems:"center",gap:"0",flexWrap:"wrap",justifyContent:"flex-end"}),E.appendChild(A);const Ce=n("download","Download PNG",Gn);A.appendChild(Ce),A.appendChild(i());const K=n("zoomMode","Zoom (drag to zoom region)",()=>Q("zoom")),le=n("zoomIn","Zoom in",()=>Se(a.clientWidth/2,a.clientHeight/2,1.2)),k=n("zoomOut","Zoom out",()=>Se(a.clientWidth/2,a.clientHeight/2,1/1.2)),V=n("reset","Reset zoom (double-click)",()=>Ue());A.appendChild(K),A.appendChild(le),A.appendChild(k),A.appendChild(V),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,y){f.activeTest!==void 0?S({plotMode:f.plotMode,activeTest:f.activeTest,activeMetadataKey:void 0,logScale:f.logScale}):f.activeMetadataKey!==void 0?S({plotMode:f.plotMode,activeTest:void 0,activeMetadataKey:f.activeMetadataKey,passFailDisplay:"off"}):S({plotMode:f.plotMode,activeTest:void 0,activeMetadataKey:void 0,passFailDisplay:"off"}),y.remove(),g(null),Ye(j,!1)};B=document.createElement("div"),Object.assign(B.style,{display:"flex",alignItems:"center",gap:"0",flexWrap:"wrap",justifyContent:"flex-end"}),E.appendChild(B),D=document.createElement("div"),Object.assign(D.style,{display:"flex",alignItems:"center",gap:"0"}),B.appendChild(D),D.appendChild(i());const et=()=>{const f=p();f&&(f.remove(),g(null)),Ye(j,!1)},j=n("mode","Plot mode",()=>{if(p()){et();return}const f=ae,y=m.testDefs,{testEntries:nt,binEntries:ue,stackedEntries:He}=Li(f,y,{includeStacked:m.isLotStack}),Mt=(De??[]).filter(Fe=>Ti(f,Fe.key)).map(Pi),Ae=yi(j.getBoundingClientRect(),nt,ue,He,U,We,{makeMenuRow:r,makeMenuSection:u},l.plotMode??"hardBin",j.ownerDocument.defaultView??window,Mt);Cn(j).appendChild(Ae),g(Ae),Ye(j,!0),Mn(Ae,j,et)});Ye(j,!1);const{btn:Zn,sync:Qn}=xi(t,()=>l.plotMode??"hardBin",()=>l.colorScheme??"default",()=>$t,f=>S({colorScheme:f}));mt=Qn,mt();const Un=Ci(t,()=>{const f=!!m.hasReticle,y=(l.plotMode??"hardBin")==="value",{testNumber:nt}=Et(l.activeTest??0,m.testDefs),ue=it(m.testDefs,nt),He=y&&ue!==void 0&&!Bt(ue),Mt=y&&!He&&(ue?.limitLow!==void 0||ue?.limitHigh!==void 0),Ae=y&&!He&&m.dies.some(Fe=>pi(Fe,nt,ue)!==void 0);return[{label:"Ring boundaries",active:!!l.showRingBoundaries,onClick:()=>S({showRingBoundaries:!l.showRingBoundaries})},{label:"Quadrant lines",active:!!l.showQuadrantBoundaries,onClick:()=>S({showQuadrantBoundaries:!l.showQuadrantBoundaries})},{label:"Die labels",active:!!l.showDieLabels,onClick:()=>S({showDieLabels:!l.showDieLabels})},{label:"Reticle grid",active:!!l.showReticle,enabled:f,onClick:()=>S({showReticle:!l.showReticle})},{label:"XY indicator",active:!!l.showXYIndicator,onClick:()=>S({showXYIndicator:!l.showXYIndicator})},...Di({functionalActive:He,hasLimits:Mt,hasRecorded:Ae,display:Lt(l)},Fe=>S({passFailDisplay:Fe}))]},()=>!!(l.showRingBoundaries||l.showQuadrantBoundaries||l.showDieLabels||l.showReticle||l.showXYIndicator||Lt(l)!=="off")),{btn:qn,sync:Jn}=Si(t,()=>l,f=>S({legendPosition:f}));ht=Jn,ht();const xn=()=>{const{testNumber:f}=Et(l.activeTest??0,J),y=it(J,f);return y!==void 0&&!Bt(y)},{btn:ei,sync:ti}=wi(t,()=>({...l,functionalActive:xn()}),f=>S(f));yt=ti,yt();const ni=()=>{const{testNumber:f}=Et(l.activeTest??0,J),y=it(J,f);return y!==void 0&&(y.limitLow!==void 0||y.limitHigh!==void 0)},tt=n("specRange","Colorbar range: spec limits",()=>{const f=l.colorbarRangeMode==="data"?"spec":"data";S({colorbarRangeMode:f})});bt=()=>{const f=l.plotMode==="value"&&ni()&&Lt(l)==="off"&&!xn();tt.style.display=f?"":"none";const y=(l.colorbarRangeMode??"spec")==="spec";o(tt,y),tt.ariaLabel=y?"Colorbar range: spec limits (click for data range)":"Colorbar range: data range (click for spec limits)"},bt();const ii=Mi(t,()=>l,f=>S(f));Rn&&D.appendChild(j),D.appendChild(Zn),D.appendChild(ei),D.appendChild(tt),ze||(D.appendChild(i()),D.appendChild(Un),D.appendChild(i()),D.appendChild(qn),D.appendChild(i()),D.appendChild(ii)),ne&&(I=n("findings","Summary panel",()=>{const f=z??R;if(!f)return;const y=f.style.display!=="none";f.style.display=y?"none":"block",o(I,!y),Ze()}),B.appendChild(i()),B.appendChild(I),R?.style.display!=="none"&&o(I,!0),Ze()),Yt&&(Ge=i(),te=n("warning","Data warnings",()=>{const f=p();if(c(new MouseEvent("click")),f)return;const y=Ii(te.getBoundingClientRect(),ie);Cn(q).appendChild(y),g(y),Mn(y,te,()=>c(new MouseEvent("click")))}),Ye(te,!1),B.appendChild(Ge),B.appendChild(te),Ut()),Ht&&(B.appendChild(i()),Z=n("expand","Expand (E)",Wt??Jt),B.appendChild(Z)),se&&(B.appendChild(i()),F=n("analysis","Insights",()=>{ct(!he),o(F,he)}),F.dataset.wmapInsightsBtn="1",B.appendChild(F)),Hn&&(B.appendChild(i()),$e=n("help","User guide",()=>vn()),B.appendChild($e))}q.appendChild(E),a.addEventListener("mouseenter",qe),a.addEventListener("mouseleave",Je),E.addEventListener("mouseenter",qe),E.addEventListener("mouseleave",Je)}let we=null;function Jt(){we&&(we.close(),we=null);const e=pe??ee??w;e.style.flex="1",e.style.minWidth="0",e.style.minHeight="0";const t=bi(E?[e,E]:[e],{ownerDocument:W,onClosed:()=>{we=null,Z&&(Z.style.display="flex"),a.focus({preventScroll:!0})}});t&&(E&&(t.contentWrap.style.position="relative"),we=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?.(),v();const o=e.plotMode!==void 0&&e.plotMode!==t;(e.colorScheme!==void 0||o)&&(fe(),je()),(e.colorScheme!==void 0||o||e.activeTest!==void 0||e.logScale!==void 0||e.colorbarRangeMode!==void 0)&&Xe?.()}function S(e){en(e);const t=Object.keys(e);Tn?.(l,t,classifyChanged(t))}let xt=!1;function wt(){xt||(xt=!0,kt(()=>{xt=!1,v()},_))}function v(){const e=T??void 0,t=m.dies[0],n=t?{x:t.width,y:t.height}:de.diePitchMm,o=Math.floor(a.clientWidth||a.width),i=!!($?.length||G?.length||m.dies.some(p=>p.hbin!=null||p.sbin!=null)),r=l.legendPosition??"default",u=r==="default"||r==="compact",s=(de.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,m,{...de,topClearance:ge?jn:0,minRightReserve:d,legendPosition:r,legendOffset:ft,diePitchMm:n,fallbackFormat:Be,showAxes:de.showAxes??T!==null,viewport:e,activeBin:l.plotMode==="metadata"?l.highlightMetadataValue:l.highlightBin,hbinDefs:$,sbinDefs:G,metadataFields:De});pt=c.binLegendRows,ke=c.legendBox??null,H||(H=c.viewport),M.size>0&&_n(),ye&&$n()}function _n(){const e=X();if(!e)return;const t=a.getContext("2d"),n=m.hoverPoints,o=m.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 M){const g=Gt.get(p);g!==void 0&&c.push({sx:e.originX+n[g].x*e.ppm,sy:e.originY-n[g].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:g}of c)t.rect(p-s,g-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:g}of c)t.rect(p-s,g-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:g}of c)t.rect(p-s,g-d,s*2,d*2);t.stroke(),t.restore()}}function $n(){const e=a.getContext("2d"),t=Math.min(P.x,O.x),n=Math.min(P.y,O.y),o=Math.abs(O.x-P.x),i=Math.abs(O.y-P.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 H?Math.max(H.ppm*In,Math.min(H.ppm*Wn,e)):e}function Se(e,t,n){const o=T??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));T={originX:u,originY:s,ppm:i,snapDist:d},v()}function X(){return T??H}function nn(e){if(e.ctrlKey||e.metaKey){e.preventDefault();const t=a.getBoundingClientRect(),n=e.deltaY<0?1.12:1/1.12;Se(e.clientX-t.left,e.clientY-t.top,n)}else if(T!==null){e.preventDefault();const t=X(),n=T.snapDist;T={originX:t.originX-e.deltaX,originY:t.originY-e.deltaY,ppm:t.ppm,snapDist:n},v()}}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)){me=!0,Te={x:n,y:o},ut={...ft};return}if(Pe&&Y!=="pan"){ve=!0,ce=!0,be={x:n,y:o},Ke={x:X().originX,y:X().originY},a.style.cursor="grabbing";return}if(Y==="zoom"||Y==="select"){ye=!0,P=O={x:n,y:o};return}ce=!0,be={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(ye){O={x:n,y:o},wt();return}if(me){const p=n-Te.x,g=o-Te.y;p*p+g*g>16&&(me=!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(ce){const p=X(),g=T?.snapDist??H?.snapDist??1;T={originX:Ke.x+(n-be.x),originY:Ke.y+(o-be.y),ppm:p.ppm,snapDist:g},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",b&&(b.innerHTML=c.label??`Bin ${c.bin}`,b.style.display="block",Dt(b,a,e.clientX,e.clientY)),Ne?.(null,e);return}if(Y==="pan"&&(a.style.cursor=d?"crosshair":"grab"),b)if(d)if(Rt){const p=Rt(d);p===null?b.style.display="none":(typeof p=="string"?b.innerHTML=p:(b.innerHTML="",b.appendChild(p)),b.style.display="block",Dt(b,a,e.clientX,e.clientY))}else b.innerHTML=ai(d,m.plotMode,{testDefs:J,hbinDefs:$,sbinDefs:G,fallbackFormat:Be,aggrMethod:m.aggrMethod,lotSize:m.lotSize,waferMeta:oe.metadata,activeTest:m.activeTest,reticleConfig:Kt}),b.style.display="block",Dt(b,a,e.clientX,e.clientY);else b.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(b&&(n<0||o<0||n>t.width||o>t.height)&&(b.style.display="none"),ye){ye=!1,O={x:n,y:o};const s=n-P.x,d=o-P.y,c=X();if(Y==="zoom"){if(s*s+d*d<25)Se(n,o,2);else if(c){const p=Math.min(P.x,O.x),g=Math.max(P.x,O.x),Q=Math.min(P.y,O.y),Ce=Math.max(P.y,O.y),K=g-p,le=Ce-Q;if(K>4&&le>4){const k=a.clientWidth,V=a.clientHeight,Ie=k/K,qe=V/le,Je=Math.min(Ie,qe),U=tn(c.ppm*Je),We=U/c.ppm,et=(p+g)/2,j=(Q+Ce)/2;T={originX:k/2-(et-c.originX)*We,originY:V/2-(j-c.originY)*We,ppm:U,snapDist:c.snapDist/We}}}v(),a.style.cursor="crosshair";return}if(s*s+d*d<25)St(n,o,i,e);else if(c){const p=(Math.min(P.x,O.x)-c.originX)/c.ppm,g=(Math.max(P.x,O.x)-c.originX)/c.ppm,Q=(c.originY-Math.max(P.y,O.y))/c.ppm,Ce=(c.originY-Math.min(P.y,O.y))/c.ppm,K=m.hoverPoints,le=[];for(let k=0;k<K.length;k++)if(K[k].x>=p&&K[k].x<=g&&K[k].y>=Q&&K[k].y<=Ce){const V=m.dies[k];V&&le.push(V)}if(i)for(const k of le){const V=Me(k);M.has(V)?M.delete(V):M.add(V)}else M=new Set(le.map(k=>Me(k)));re?.(Ct())}v(),a.style.cursor="crosshair";return}if(me){me=!1,St(n,o,i,e);return}if(Le){Le=!1,a.style.cursor="grab";return}if(!ce)return;if(ce=!1,ve){ve=!1,a.style.cursor=Pe||Y==="pan"?"grab":"crosshair";return}a.style.cursor=Y==="pan"?"grab":"crosshair";const r=n-be.x,u=o-be.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;S({highlightBin:d})}else{const d=l.highlightMetadataValue===s.bin?void 0:s.bin;S({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=Me(u);n?M.has(s)?M.delete(s):M.add(s):M=new Set([s]),re?.(Ct()),v()}else n||(M=new Set,re?.([]),v())}function Ct(){const e=[],t=m.hoverPoints;for(let n=0;n<t.length;n++){const o=m.dies[n];o&&M.has(Me(o))&&e.push(o)}return e}function rn(){b&&ot(W),Ne?.(null,new MouseEvent("mouseleave")),a.style.cursor=Y==="pan"?"grab":"crosshair"}function dn(){ce=!1,ve=!1,ye=!1,me=!1,Le=!1,b&&ot(W),Ne?.(null,new MouseEvent("mouseleave")),a.style.cursor=Y==="pan"?"grab":"crosshair",v()}function cn(e,t,n){const o=m.hoverPoints,i=m.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=m.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,g=c*c+p*p;g<s&&(s=g,r=m.dies[d]??null,u=d)}return r?{die:r,index:u}:null}const pn=new _.ResizeObserver(()=>{H=null,T=null,v()});pn.observe(a),C.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=_.matchMedia(`(resolution: ${_.devicePixelRatio}dppx)`);const Qe=()=>{Re.removeEventListener("change",Qe),Re=_.matchMedia(`(resolution: ${_.devicePixelRatio}dppx)`),Re.addEventListener("change",Qe),v()};Re.addEventListener("change",Qe);const fn=_.matchMedia("(prefers-color-scheme: dark)"),un=()=>v();fn.addEventListener("change",un);const gn=()=>{b&&ot(W)};_.addEventListener("blur",gn);function hn(e){if(e.key==="Escape"&&M.size>0&&(M=new Set,re?.([]),v()),(e.key==="e"||e.key==="E")&&Ot!=="view-only"&&Ht&&!he&&(e.stopPropagation(),(Wt??Jt)()),(e.ctrlKey||e.metaKey)&&(e.key==="="||e.key==="+"?(e.preventDefault(),Se(a.clientWidth/2,a.clientHeight/2,1.2)):e.key==="-"?(e.preventDefault(),Se(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=T?.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)&&(T={originX:n.originX+i,originY:n.originY+r,ppm:n.ppm,snapDist:o},v())}e.key===" "&&!Pe&&(e.preventDefault(),Pe=!0,Y!=="pan"&&(a.style.cursor="grab"))}}function mn(e){e.key===" "&&(Pe=!1,ve&&(ce=!1,ve=!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,v(),Xe?.();function Ue(){H=null,T=null,v()}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(),v(),z&&fe()},setResult(e){st=e,oe=e.wafer,ae=e.dies,$=e.hbinDefs,G=e.sbinDefs,J=e.testDefs,De=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(),v(),z&&fe()},setOptions(e){en(e)},getOptions(){return{...l}},resetZoom:Ue,setSelection(e){M=new Set(e.map(t=>Me(t))),v()},clearSelection(){M=new Set,re?.([]),v()},setFallbackFormat(e){Be=e,Oe(),v()},setStatsSummary(e){if(ne=e,Xt(),Ut(),z)fe();else if(R)je();else if(e&&!Ee?.placement){const t=Ee?.defaultOpen??!ge;R=Tt("right"),R.style.display=t?"block":"none";const n=w.parentElement,o=w.nextSibling;ee=Pt(w,R,"right"),n?.insertBefore(ee,o),je()}Ze()},setSummaryVisible(e){I&&(I.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,L&&(L.el.style.display=e&&!he?"":"none")},openUserGuide:vn,setInsightsOpen(e){ct(e),F&&(e?(F.dataset.active="1",F.style.background=x.bgActive,F.style.color=x.iconActive):(delete F.dataset.active,F.style.background="transparent",F.style.color=x.icon))},closeSummaryPanel(){const e=z??R;!e||e.style.display==="none"||(e.style.display="none",I&&(delete I.dataset.active,I.style.background="transparent",I.style.color=x.icon))},setTooltipParent(e){b&&hi(e)},getActiveLegend(){const e=l.plotMode;if(e==="metadata"){const i=l.activeMetadataKey;if(!i)return null;const r=De?.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(g=>g.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(){we?.close(),xe&&clearTimeout(xe),qt?.()?.remove(),gt&&W.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),_.removeEventListener("blur",gn),Xn(),b&&ot(W),E?.remove(),pe&&(pe.parentElement?.insertBefore(w,pe),pe.remove()),ee&&(ee.parentElement?.insertBefore(w,ee),ee.remove()),w.remove(),a.style.cursor="",se?.destroy(),L?.destroy(),q.remove()}}}
|
|
@@ -125,6 +125,8 @@ export declare function buildLotOverviewSection(lotSummary: LotStatsSummary): HT
|
|
|
125
125
|
export declare function buildPerWaferYieldSection(lotSummary: LotStatsSummary, items: Array<{
|
|
126
126
|
label?: string;
|
|
127
127
|
} | null>, onWaferClick?: (waferIndex: number) => void): HTMLDivElement | null;
|
|
128
|
+
/** CSV field escaper — exported so `dieList.ts` shares it rather than a second copy. */
|
|
129
|
+
export declare function csvField(value: string): string;
|
|
128
130
|
export declare function buildTestSection(dies: Die[], testDefs: TestDef[] | undefined, fallbackFormat?: 'si' | 'engineering',
|
|
129
131
|
/**
|
|
130
132
|
* When supplied, each test's descriptive stats and spec-yield are read from
|