@wafertools/wafermap 0.30.0 → 0.30.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +68 -9
- package/CHANGELOG.md +247 -0
- package/README.md +3 -3
- package/dist/packages/canvas-adapter/charts/barPanel.js +1 -1
- package/dist/packages/canvas-adapter/charts/binCluster.js +1 -1
- package/dist/packages/canvas-adapter/charts/boxplot.js +1 -1
- package/dist/packages/canvas-adapter/charts/capability.js +1 -1
- package/dist/packages/canvas-adapter/charts/chartShell.js +1 -1
- package/dist/packages/canvas-adapter/charts/correlation.js +2 -2
- package/dist/packages/canvas-adapter/charts/groupedBarPlot.d.ts +1 -0
- package/dist/packages/canvas-adapter/charts/histogram.js +1 -1
- package/dist/packages/canvas-adapter/charts/scatter.js +1 -1
- package/dist/packages/canvas-adapter/charts/testPassRate.js +1 -1
- package/dist/packages/canvas-adapter/charts/trend.js +1 -1
- package/dist/packages/canvas-adapter/chunked.d.ts +45 -0
- package/dist/packages/canvas-adapter/chunked.js +1 -0
- package/dist/packages/canvas-adapter/deprecated.d.ts +0 -3
- package/dist/packages/canvas-adapter/deprecated.js +1 -1
- package/dist/packages/canvas-adapter/dieList.js +1 -1
- package/dist/packages/canvas-adapter/exportName.d.ts +68 -0
- package/dist/packages/canvas-adapter/exportName.js +1 -0
- package/dist/packages/canvas-adapter/icons.js +2 -2
- package/dist/packages/canvas-adapter/index.d.ts +2 -1
- package/dist/packages/canvas-adapter/index.js +1 -1
- package/dist/packages/canvas-adapter/insightsTab.js +1 -1
- package/dist/packages/canvas-adapter/renderWaferGallery.d.ts +80 -3
- package/dist/packages/canvas-adapter/renderWaferGallery.js +1 -1
- package/dist/packages/canvas-adapter/renderWaferMap.d.ts +24 -2
- package/dist/packages/canvas-adapter/renderWaferMap.js +1 -1
- package/dist/packages/canvas-adapter/summaryPanel.d.ts +76 -15
- package/dist/packages/canvas-adapter/summaryPanel.js +3 -3
- package/dist/packages/canvas-adapter/toCanvas.js +1 -1
- package/dist/packages/canvas-adapter/toolbar.d.ts +6 -0
- package/dist/packages/canvas-adapter/toolbar.js +2 -2
- package/dist/packages/canvas-adapter/userGuideHtml.d.ts +1 -1
- package/dist/packages/canvas-adapter/userGuideHtml.js +15 -8
- package/dist/packages/canvas-adapter/version.d.ts +2 -2
- package/dist/packages/canvas-adapter/version.js +1 -1
- package/dist/packages/canvas-adapter/warnings.js +1 -1
- package/dist/packages/core/aggregates.js +1 -1
- package/dist/packages/core/deprecated.d.ts +8 -12
- package/dist/packages/core/deprecated.js +1 -1
- package/dist/packages/core/index.d.ts +1 -1
- package/dist/packages/core/index.js +1 -1
- package/dist/packages/core/utils.d.ts +67 -0
- package/dist/packages/core/utils.js +1 -1
- package/dist/packages/core/waferLabel.d.ts +12 -2
- package/dist/packages/core/waferLabel.js +1 -1
- package/dist/packages/renderer/binColors.d.ts +52 -0
- package/dist/packages/renderer/binColors.js +1 -1
- package/dist/packages/renderer/buildView.js +1 -1
- package/dist/packages/renderer/buildWaferMap.d.ts +30 -5
- package/dist/packages/renderer/buildWaferMap.js +1 -1
- package/dist/packages/renderer/deprecate.d.ts +7 -0
- package/dist/packages/renderer/deprecate.js +1 -1
- package/dist/packages/renderer/deprecated.d.ts +2 -2
- package/dist/packages/renderer/deprecated.js +1 -1
- package/dist/packages/renderer/index.d.ts +2 -1
- package/dist/packages/renderer/index.js +1 -1
- package/dist/packages/stats/analyzeWaferLot.js +1 -1
- package/dist/packages/stats/analyzeWaferMap.js +1 -1
- package/dist/packages/stats/capability.d.ts +72 -1
- package/dist/packages/stats/capability.js +1 -1
- package/dist/packages/stats/correlation.d.ts +30 -0
- package/dist/packages/stats/correlation.js +1 -1
- package/dist/packages/stats/deprecated.d.ts +30 -35
- package/dist/packages/stats/deprecated.js +1 -1
- package/dist/packages/stats/findingsNarrative.js +1 -1
- package/dist/packages/stats/index.d.ts +4 -2
- package/dist/packages/stats/index.js +1 -1
- package/dist/packages/stats/math.d.ts +27 -2
- package/dist/packages/stats/math.js +1 -1
- package/dist/packages/stats/normalizeInput.d.ts +10 -0
- package/dist/packages/stats/normalizeInput.js +1 -0
- package/dist/packages/stats/regions.d.ts +2 -0
- package/dist/packages/stats/regions.js +1 -1
- package/dist/packages/stats/renderFindingsReport.js +1 -1
- package/dist/packages/stats/renderSummaryReport.d.ts +39 -1
- package/dist/packages/stats/renderSummaryReport.js +27 -27
- package/dist/packages/stats/reportHtml.d.ts +0 -1
- package/dist/packages/stats/reportHtml.js +10 -10
- package/dist/packages/stats/summaryFigures.d.ts +47 -0
- package/dist/packages/stats/summaryFigures.js +1 -0
- package/dist/packages/stats/types.d.ts +118 -0
- package/llms.txt +12 -7
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
import{buildView as hi,buildHoverText as gi,findTestDef as rt,resolveTestNumber as Vt}from"../renderer/buildView.js";import{drawMapCanvas as mi,BIN_LEGEND_W as Pn,BIN_LEGEND_W_COMPACT as yi,BIN_LEGEND_ADAPT_COMPACT as bi,BIN_LEGEND_ADAPT_FLOATING as vi}from"./toCanvas.js";import{buildWaferMap as xi,getTestPassStatus as Ci,isParametricTest as zt}from"../renderer/buildWaferMap.js";import{analyzeWaferMap as wi}from"../stats/analyzeWaferMap.js";import{SHADOW as Si,LEADING as Rn,wireControlHover as In,SPACE as W,EDGE_GUTTER as Mi,RADIUS as Wn,FONT as dt,CLR as x,applyOverlayZ as Ei,getTooltip as Fn,hideTooltip as ct,positionTooltip as An,createToolbarHelpers as Di,buildModeMenuEl as Bi,openReparentedModal as ki,openUserGuideWindow as Li,makePaletteBtn as Ti,makeLogScaleBtn as Oi,makeLegendStyleBtn as Pi,makeOverlaysBtn as Ri,makeOrientationBtn as Ii,menuLayerFor as Hn,saveImageBlob as Wi,markMenuTrigger as _e,wireMenuA11y as Vn,wireExpandToggle as Fi,nextFrame as Yt,requestedPassFailDisplay as Ai,overlayMenuRows as Hi,anyOverlayActive as Vi,logWmapVersionOnce as zi,buildDataModeEntries as Yi,metadataKeyHasData as Ni,metadataModeEntry as Xi}from"./toolbar.js";import{waferDisplayLabel as ji}from"../core/waferLabel.js";import{createSummaryPanelEl as Nt,wrapWithSummaryPanel as Xt,renderWaferSummaryContent as _i}from"./summaryPanel.js";import{collectWarnings as Ki,buildWarningsMenuEl as $i,severityOf as Gi}from"./warnings.js";import{ICONS as zn}from"./icons.js";import{createIdentityHeader as Ui,collapsedLabel as jt}from"./identityHeader.js";import{getDieKey as Be,hasPosition as Yn,isPositionedDie as Zi}from"../core/dies.js";import{buildDieListSection as Qi}from"./dieList.js";import{buildMaplessSummary as qi}from"./maplessSummary.js";import{resolveBinColors as Ji,binColorWarning as eo}from"../renderer/binColors.js";import{INPUT_DEFAULT_PASS_BINS as to}from"../core/passBins.js";const Nn=new Set(["binColorScheme","valueColorScheme","reverseValueScheme","useDefinedBinColors","rotation","flipX","flipY","showDieLabels","showPartialDies","showRingBoundaries","showQuadrantBoundaries","showReticle","showXYIndicator","legendPosition","logScale","colorbarRangeMode","markFailingDies","fallbackFormat"]);export const COLOR_KEYS=["binColorScheme","valueColorScheme","reverseValueScheme","useDefinedBinColors","binColors"];export function classifyChanged(O){const g=O.some(f=>Nn.has(f)),v=O.some(f=>!Nn.has(f));return g&&v?"mixed":g?"preference":"state"}export function toPublicViewOptions(O){const{metadataValueOrder:g,binColors:v,lotSize:f,...B}=O;return B}export function renderWaferMap(O,g,v={}){return renderWaferMapCard(O,g,v)}export function renderWaferMapCard(O,g,v={}){zi();const f=O.ownerDocument,B=f.defaultView??window;B.getComputedStyle(O).position==="static"&&(O.style.position="relative");const Xn=O.clientHeight;v.height!=null&&(O.style.height=typeof v.height=="number"?`${v.height}px`:v.height);const pt=g.dataCoverage?g.dataCoverage.unpositionedDies:g.dies.filter(e=>!Yn(e)).length,Ke=(g.dataCoverage?g.dataCoverage.totalDies:g.dies.length-pt)===0&&pt>0,ke=f.createElement("div");Object.assign(ke.style,{display:"flex",flexDirection:"column",width:"100%",height:"100%"}),O.appendChild(ke);const me=f.createElement("div");Object.assign(me.style,{position:"relative",width:"100%",flex:"1 1 auto",minHeight:"0"});const de=v.chromeInset??Mi,j=f.createElement("div");Object.assign(j.style,{display:"flex",alignItems:"stretch",gap:W.sm,background:x.canvasBg,paddingBottom:W.lg,paddingTop:de,paddingLeft:de,paddingRight:de,flexShrink:"0",minWidth:"0"}),ke.appendChild(j),ke.appendChild(me);function Le(){const e=[...j.children].some(t=>t.style.display!=="none");j.style.display=e?"flex":"none"}const w=f.createElement("div");Object.assign(w.style,{position:"relative",width:"100%",height:"100%"});const s=f.createElement("canvas");Object.assign(s.style,{width:"100%",height:"100%",display:"block"}),w.appendChild(s),me.appendChild(w);let $e=null;if(pt>0){let n=function(){if(t){const p=Qi(e,g.testDefs,{...v.dieList,onSaveText:v.onSaveText,waferMetadata:_.metadata,metadataFields:pe,ownerDocument:f});if(p)return p}const o=rt(g.testDefs,d.activeTest??0),r=zt(o)?d.logScale??o?.logScale??!1:!1;return qi(e,g.testDefs,{plotMode:d.plotMode??"hardBin",activeTest:d.activeTest,hbinDefs:G,sbinDefs:U,binColors:y.binColors,valueColorScheme:d.valueColorScheme,reverseValueScheme:d.reverseValueScheme,logScale:r,colorbarRangeMode:d.colorbarRangeMode,valueRangeDies:g.dies})},i=function(o){const r=f.createElement("button");return r.type="button",In(r),Object.assign(r.style,{fontSize:dt.body,padding:`${W.xxs} ${W.sm}`,borderRadius:Wn.control,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",p=>{p.stopPropagation(),t=!t,r.textContent=t?"View chart":"View die list",o()}),r};const e=g.dies.filter(o=>!Yn(o));let t=!1;if(Ke){const o=f.createElement("div");Object.assign(o.style,{position:"absolute",inset:"0",background:x.panelBg,padding:W.xl,boxSizing:"border-box",overflow:"hidden",display:"flex",flexDirection:"column",gap:W.md,zIndex:"1"});const r=f.createElement("div");Object.assign(r.style,{display:"flex",justifyContent:"space-between",alignItems:"flex-start",gap:W.md});const p=f.createElement("span");Object.assign(p.style,{fontSize:dt.body,color:x.label,lineHeight:Rn.base}),p.textContent="No die position data for this wafer.",r.appendChild(p);const l=f.createElement("div");Object.assign(l.style,{flex:"1",minHeight:"0",overflow:"auto",display:"flex",flexDirection:"column"}),r.appendChild(i(()=>l.replaceChildren(n()))),o.appendChild(r),o.appendChild(l),w.appendChild(o),$e=()=>{t||l.replaceChildren(n())}}else{const o=f.createElement("div");Object.assign(o.style,{position:"absolute",left:"0",right:"0",bottom:"0",zIndex:"3",background:x.panelBg,borderTop:`1px solid ${x.menuBorder}`,fontSize:dt.body,color:x.text,cursor:"pointer",padding:`${W.xs} ${W.md}`,display:"flex",alignItems:"center",justifyContent:"space-between",gap:W.md}),In(o,"bare");const r=f.createElement("span");r.textContent=`+${e.length} ${e.length===1?"die":"dies"} without position data`,o.appendChild(r);const p=f.createElement("span");p.textContent="\u25BE",Object.assign(p.style,{fontSize:dt.body,lineHeight:Rn.none,color:x.label,flexShrink:"0"}),o.appendChild(p),o.setAttribute("aria-expanded","false"),o.setAttribute("aria-label",`${e.length} dies without position data. Click to view.`);let l=null,a=null;Fi(o,c=>{if(p.textContent=c?"\u25B4":"\u25BE",o.setAttribute("aria-expanded",String(c)),c){l=f.createElement("div");const h=o.getBoundingClientRect().height||28;Object.assign(l.style,{position:"absolute",left:"0",right:"0",bottom:`${h}px`,top:"20%",zIndex:"2",background:x.panelBg,borderTop:`1px solid ${x.menuBorder}`,padding:W.md,boxSizing:"border-box",display:"flex",flexDirection:"column",gap:W.md}),l.addEventListener("click",oe=>oe.stopPropagation());const m=f.createElement("div");Object.assign(m.style,{display:"flex",justifyContent:"flex-end"}),m.appendChild(i(()=>{a&&a.replaceChildren(n())})),l.appendChild(m),a=f.createElement("div"),Object.assign(a.style,{flex:"1",minHeight:"0",overflow:"auto",display:"flex",flexDirection:"column"}),a.appendChild(n()),l.appendChild(a),w.appendChild(l)}else l&&(l.remove(),l=null,a=null)}),w.appendChild(o),$e=()=>{a&&!t&&a.replaceChildren(n())}}}const{onHover:Ge,onClick:jn,onSelect:ce,onViewOptionsChange:_n,showTooltip:Kn=!0,showToolbar:Te=!0,showIdentity:_t=!0,summaryPanel:Oe,showHelpButton:Kt=!1,userGuideExtension:$n,onExpand:$t,showExpandButton:Gt=!0,zIndex:Gn,insights:ft,warnings:Ut,viewOptions:Un={},...ye}=v,Pe=ft?.enabled??!1,Zn=.4,Qn=20,Ue=[...g.passBins??to],Zt=Ut?.display??!0,qn=Ei(Gn);let se=v.statsSummary,le=[],Qt=!1,Ze=null,qt=!1;function ut(){const e=Ki({result:g,statsSummary:se,extra:Ze?[Ze]:[]}),t=e.length!==le.length||e.some((n,i)=>n.code!==le[i]?.code||n.message!==le[i]?.message);le=e,(t||!Qt)&&(Qt=!0,Ut?.onWarning?.(e))}ut();let be=g,_=g.wafer,ve=g.dies,M=new Set,G=g.hbinDefs,U=g.sbinDefs,ee=g.testDefs,pe=g.metadataFields,Jt=g.reticles?.length?g.reticles:void 0,en=g.reticleConfig,tn=g.view?.dataAxisFlip,ht=g.isLotStack??!1,gt=g.aggrMethod,mt=g.lotSize;const Jn=Te&&Pe;let V=null,Z=null,Q=null;_t&&(V=Ui(jt(_.metadata??{},Re())??"",_.metadata,{lotStack:Re(),ownerDocument:f}),w.appendChild(V.metaPanel),V.metaPanel.style.visibility="visible",V.isEmpty()||(Z=nn(V.wrap),j.insertBefore(Z,j.firstChild),Le()));function nn(e){const t=f.createElement("div");return Object.assign(t.style,{display:"flex",alignItems:"center",padding:`${W.sm} ${W.lg}`,flex:"1 1 auto",minWidth:"0",overflow:"hidden",gap:W.sm}),Object.assign(e.style,{flex:"1",minWidth:"0"}),t.appendChild(e),t}function Re(){return ht?{lotSize:mt??1,aggrMethod:gt}:void 0}function ei(){if(!V)return;V.update(jt(_.metadata??{},Re())??"",_.metadata,Re());const e=Z?.isConnected??!1,t=!V.isEmpty();!t&&e?(Z.remove(),Z=null):t&&!e&&(Z=nn(V.wrap),Z.style.display="",j.insertBefore(Z,j.firstChild),Le())}const ti=[...G??[],...U??[]].some(e=>e.color);let d={plotMode:"hardBin",showDieLabels:!1,showPartialDies:!0,showRingBoundaries:!1,showQuadrantBoundaries:!1,showReticle:!1,showXYIndicator:!1,rotation:0,flipX:!1,flipY:!1,legendPosition:"default",...Un},z=null,te=!1,on=null;function ni(){return Pe?z?Promise.resolve(z):(on??=import("./insightsTab.js").then(({createInsightsTab:e})=>(z=e({getItems:()=>[{wafer:_,dies:ve,hbinDefs:G,sbinDefs:U,testDefs:ee,label:ji({wafer:_},0),passBins:Ue,statsSummary:se}],getBinColors:()=>y.binColors,getRingCount:()=>be.ringCount??4,onSaveImage:v.onSaveImage,onSaveText:v.onSaveText,defaultView:ft?.defaultView,showMetadataStrip:!1,contentInset:de,backTab:Jn?void 0:{label:"Map",onBack:()=>Ie(!1)},onOpenGuide:Kt&&!Te?()=>It():void 0,focusTest:t=>{E({plotMode:"value",activeTest:t,highlightBin:void 0}),Ie(!1)},ownerDocument:f}),Object.assign(z.el.style,{position:"absolute",inset:"0",background:x.canvasBg,overflowY:"auto",paddingTop:"0"}),z.el.style.display="none",me.appendChild(z.el),z)),on):Promise.resolve(null)}let sn=0;const yt=["wheel","touchstart","pointerdown","keydown"];function ii(e,t){if(t<=0)return;let n=!1;const i=[],o=()=>{n=!0;for(const p of i)B.clearTimeout(p);i.length=0;for(const p of yt)e.removeEventListener(p,o)},r=()=>n||!te?!0:(e.scrollTop=t,e.scrollTop>=t);if(!r()){for(const p of yt)e.addEventListener(p,o,{passive:!0,once:!0});for(const p of[0,50,150,300,600])i.push(B.setTimeout(()=>{r()},p));i.push(B.setTimeout(()=>{for(const p of yt)e.removeEventListener(p,o)},700))}}function Ie(e){if(!Pe)return;const t=te;te=e,z&&!e&&t&&(sn=z.el.scrollTop),z&&(z.el.style.display=e?"flex":"none"),w.style.visibility=e?"hidden":"",A&&(A.style.display=e||Ke?"none":"flex"),T&&(T.style.display=e?"none":"flex"),Q&&(Q.style.display=he?"none":"flex"),ne&&(ne.style.display="flex"),Z&&(Z.style.display=""),Le(),V&&e&&V.collapse(),tt(),H&&(H.innerHTML=e?zn.wafer:zn.analysis,H.ariaLabel=e?"Back to wafer view":"Insights"),e&&ni().then(n=>{!n||!te||(n.el.style.display="flex",n.render(),ii(n.el,sn))})}Pe&&ft?.defaultOpen&&queueMicrotask(()=>Ie(!0));let y,ln,Y=null,k=null,bt=[],vt;function an(e){vt!==e&&(vt=e,C())}let We=null,xt=ye.legendOffset??{x:0,y:0},Fe=!1,xe=!1,Ae={x:0,y:0},Ct={x:0,y:0},fe=!1,Ce=!1,N="pan",we={x:0,y:0},Qe={x:0,y:0},P={x:0,y:0},R={x:0,y:0},He=!1,Se=!1;function wt(){const e=d;y=hi(_,ve.filter(Zi),{plotMode:e.plotMode,binColorScheme:e.binColorScheme,valueColorScheme:e.valueColorScheme,reverseValueScheme:e.reverseValueScheme,useDefinedBinColors:e.useDefinedBinColors,binColors:e.binColors??Ji(ve,{passBins:Ue,binColorScheme:e.binColorScheme,hbinDefs:G,sbinDefs:U,useDefinedBinColors:e.useDefinedBinColors}),passBins:Ue,showDieLabels:e.showDieLabels,showPartialDies:e.showPartialDies,showRingBoundaries:e.showRingBoundaries,showQuadrantBoundaries:e.showQuadrantBoundaries,showReticle:e.showReticle,showXYIndicator:e.showXYIndicator,reticles:Jt,ringCount:be.ringCount??4,highlightBin:e.highlightBin,highlightMetadataValue:e.highlightMetadataValue,activeTest:e.activeTest,activeMetadataKey:e.activeMetadataKey,testDefs:ee,valueRange:e.valueRange,metadataValueOrder:e.metadataValueOrder,logScale:e.logScale,isLotStack:ht,aggregationMethod:gt??e.aggregationMethod,lotSize:mt??e.lotSize,dataAxisFlip:tn,colorbarRangeMode:e.colorbarRangeMode,passFailDisplay:e.passFailDisplay,fallbackFormat:e.fallbackFormat,interactiveTransform:{rotation:e.rotation??0,flipX:e.flipX??!1,flipY:e.flipY??!1}},{hbinDefs:G,sbinDefs:U,metadataFields:pe}),ln=new Map(y.dies.map((n,i)=>[Be(n),i]));const t=e.binColors?null:eo(y.binColors,y.plotMode);t?.message!==Ze?.message&&(Ze=t,ut(),qt&&St())}wt();let q=null,Me=null,qe=null,rn=v.findingsNotice,oi={},F=null,ae=null;function si(e){const{kind:t,index:n}=e.variable;E(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"?(Lt(i.dieKeys),E({highlightBin:i.bin})):(i.kind==="region"||i.kind==="dies")&&Lt(i.dieKeys)}function dn(e){_i(e,{wafer:_,dies:ve,yieldSummary:be.yield,dataCoverage:be.dataCoverage,hbinDefs:G,sbinDefs:U,testDefs:ee,statsSummary:se,warnings:Zt?le:[],passBins:Ue,ringCount:be.ringCount??4,binColors:y.binColors,plotMode:d.plotMode??"hardBin",metadataShownElsewhere:_t,fallbackFormat:d.fallbackFormat,activeFindingId:qe,findingsFilter:oi,findingsNotice:rn,onFindingsFilterChange:ue,onSaveText:v.onSaveText,metadataFields:pe,dieListOptions:v.dieList,onFindingClick:(t,n)=>{qe===t.id?(qe=null,Lt([]),E({highlightBin:void 0})):(qe=t.id,si(t)),ue()}})}function ue(){q&&dn(q)}function Ve(){F&&dn(F)}if(Oe?.placement){const e=Oe.placement;q=Nt(e,de,f);const t=w.parentElement,n=w.nextSibling;Me=Xt(w,q,e),t?.insertBefore(Me,n),ue()}else if(se){const e=Oe?.defaultOpen??!Te;F=Nt("right",de,f),F.style.display=e?"block":"none";const t=w.parentElement,n=w.nextSibling;ae=Xt(w,F,"right"),t?.insertBefore(ae,n),Ve()}const I=Kn?Fn(f):null;let ne=null,L=null,A=null,T=null,Je=null,K=null,cn=null,H=null,ie=null,et=null;qt=!0;function St(){if(!ie||!et)return;const e=le.length,t=e>0;if(ie.style.display=t?"flex":"none",et.style.display=t?"":"none",!t)return;const n=Gi(le[0]),i=`${e} data ${e===1?"warning":"warnings"}`;ie.style.color=n==="error"?x.errText:x.warnText,ie.ariaLabel=n==="error"?`${i} \u2014 the map may be positionally wrong`:i}let Mt=null,pn=null,Et=null,Dt=null,Bt=null,kt=null;function Lt(e){M=new Set(e??[]),ce&&ce(Rt()),C()}function tt(){if(!K)return;const e=!!(q??F);K.style.display=se&&e&&!te?"flex":"none";const t=q??F,n=t?t.style.display!=="none":!1;se?.hasNotableFindings&&!n?K.style.color=x.findingIndicator:K.dataset.active||(K.style.color=x.icon)}if(Te){let h=function(D){N=D,i(oe,D==="zoom"),i(S,D==="pan"),Je&&i(Je,D==="select"),s.style.cursor=D==="pan"?"grab":"crosshair"};ne=f.createElement("div"),ne.dataset.wmapToolbar="single",Object.assign(ne.style,{marginLeft:"auto",flexShrink:"0",display:"flex",flexDirection:"row",alignItems:"center",flexWrap:"wrap-reverse",justifyContent:"flex-end",maxWidth:"100%",background:x.menuBg,border:`1px solid ${x.menuBorder}`,borderRadius:Wn.control,boxShadow:Si.panel,pointerEvents:"auto"});const e=Fn(f),t=Di(e),{makeBtn:n,setActive:i,makeSep:o,makeMenuRow:r,makeMenuSection:p,closeOpenMenu:l,getOpenMenu:a,setOpenMenu:c}=t;Mt=l,pn=a,f.addEventListener("click",l,!0),A=f.createElement("div"),Object.assign(A.style,{display:Ke?"none":"flex",alignItems:"center",gap:"0",flexWrap:"wrap",justifyContent:"flex-end"}),ne.appendChild(A);const m=n("download","Download PNG",ri);A.appendChild(m),A.appendChild(o());const oe=n("zoomMode","Zoom (drag to zoom region)",()=>h("zoom")),De=n("zoomIn","Zoom in",()=>Ee(s.clientWidth/2,s.clientHeight/2,1.2)),J=n("zoomOut","Zoom out",()=>Ee(s.clientWidth/2,s.clientHeight/2,1/1.2)),re=n("reset","Reset zoom (double-click)",()=>it());A.appendChild(oe),A.appendChild(De),A.appendChild(J),A.appendChild(re),A.appendChild(o());const S=n("pan","Pan (drag to move)",()=>h("pan"));A.appendChild(S),Je=n("boxSelect","Select (drag to select dies)",()=>h("select")),A.appendChild(Je),i(S,!0);{let D=function(u){return u.plotMode!==(d.plotMode??"hardBin")?!1:u.plotMode==="value"?(d.activeTest??0)===(u.activeTest??0):u.plotMode==="metadata"?d.activeMetadataKey===u.activeMetadataKey:!0},Wt=function(u,b){u.activeTest!==void 0?E({plotMode:u.plotMode,activeTest:u.activeTest,activeMetadataKey:void 0,logScale:u.logScale}):u.activeMetadataKey!==void 0?E({plotMode:u.plotMode,activeTest:void 0,activeMetadataKey:u.activeMetadataKey,passFailDisplay:"off"}):E({plotMode:u.plotMode,activeTest:void 0,activeMetadataKey:void 0,passFailDisplay:"off"}),b.remove(),c(null),_e($,!1)};L=f.createElement("div"),Object.assign(L.style,{display:"flex",alignItems:"center",gap:"0",flexWrap:"wrap",justifyContent:"flex-end"}),ne.appendChild(L),T=f.createElement("div"),Object.assign(T.style,{display:"flex",alignItems:"center",gap:"0"}),L.appendChild(T),T.appendChild(o());const ot=()=>{const u=a();u&&(u.remove(),c(null)),_e($,!1)},$=n("mode","Plot mode",()=>{if(a()){ot();return}const u=ve,b=y.testDefs,{testEntries:at,binEntries:ge,stackedEntries:Ne}=Yi(u,b,{includeStacked:y.isLotStack}),Ht=(pe??[]).filter(je=>Ni(u,je.key)).map(Xi),Xe=Bi($.getBoundingClientRect(),at,ge,Ne,D,Wt,{makeMenuRow:r,makeMenuSection:p},d.plotMode??"hardBin",$.ownerDocument.defaultView??window,Ht);Hn($).appendChild(Xe),c(Xe),_e($,!0),Vn(Xe,$,ot)});_e($,!1);const{btn:st,sync:Ye}=Ti(t,()=>({...d,plotMode:d.plotMode??"hardBin"}),()=>ti,E);Dt=Ye,Dt();const Ft=Ri(t,()=>{const u=!!y.hasReticle,b=(d.plotMode??"hardBin")==="value",{testNumber:at}=Vt(d.activeTest??0,y.testDefs),ge=rt(y.testDefs,at),Ne=b&&ge!==void 0&&!zt(ge),Ht=b&&!Ne&&(ge?.limitLow!==void 0||ge?.limitHigh!==void 0),Xe=b&&!Ne&&y.dies.some(je=>Ci(je,at,ge)!==void 0);return Hi(d,u,{functionalActive:Ne,hasLimits:Ht,hasRecorded:Xe,binMode:(d.plotMode??"hardBin")==="hardBin"||(d.plotMode??"hardBin")==="softBin"},je=>E(je))},()=>Vi(d)),{btn:At,sync:di}=Pi(t,()=>d,u=>E({legendPosition:u}));Et=di,Et();const On=()=>{const{testNumber:u}=Vt(d.activeTest??0,ee),b=rt(ee,u);return b!==void 0&&!zt(b)},{btn:ci,sync:pi}=Oi(t,()=>({...d,functionalActive:On()}),u=>E(u));Bt=pi,Bt();const fi=()=>{const{testNumber:u}=Vt(d.activeTest??0,ee),b=rt(ee,u);return b!==void 0&&(b.limitLow!==void 0||b.limitHigh!==void 0)},lt=n("specRange","Colorbar range: spec limits",()=>{const u=d.colorbarRangeMode==="data"?"spec":"data";E({colorbarRangeMode:u})});kt=()=>{const u=d.plotMode==="value"&&fi()&&Ai(d)==="off"&&!On();lt.style.display=u?"":"none";const b=(d.colorbarRangeMode??"spec")==="spec";i(lt,b),lt.ariaLabel=b?"Colorbar range: spec limits (click for data range)":"Colorbar range: data range (click for spec limits)"},kt();const ui=Ii(t,()=>d,u=>E(u));T.appendChild($),T.appendChild(st),T.appendChild(ci),T.appendChild(lt),Ke||(T.appendChild(o()),T.appendChild(Ft),T.appendChild(o()),T.appendChild(At),T.appendChild(o()),T.appendChild(ui)),se&&(K=n("findings","Summary panel",()=>{const u=q??F;if(!u)return;const b=u.style.display!=="none";u.style.display=b?"none":"block",i(K,!b),tt()}),L.appendChild(o()),L.appendChild(K),F?.style.display!=="none"&&i(K,!0),tt()),Zt&&(et=o(),ie=n("warning","Data warnings",()=>{const u=a();if(l(new MouseEvent("click")),u)return;const b=$i(ie.getBoundingClientRect(),le,B);Hn(me).appendChild(b),c(b),Vn(b,ie,()=>l(new MouseEvent("click")))}),_e(ie,!1),L.appendChild(et),L.appendChild(ie),St()),Pe&&(L.appendChild(o()),H=n("analysis","Insights",()=>{Ie(!te),i(H,te)}),H.dataset.wmapInsightsBtn="1",L.appendChild(H)),Gt&&(L.appendChild(o()),Q=n("expand","Expand (E)",$t??fn),L.appendChild(Q)),Kt&&(L.appendChild(o()),cn=n("help","User guide",()=>It()),L.appendChild(cn))}j.appendChild(ne),Le()}let he=null;function fn(){he&&(he.close(),he=null);const e=me;e.style.flex="1",e.style.minWidth="0",e.style.minHeight="0";const t=jt(_.metadata??{},Re()),n=j.childElementCount>0?[j,e]:[e],i=ki(n,{ownerDocument:f,boxSize:te?{width:"min(96vw, 1600px)",height:"min(92vh, 1000px)"}:void 0,onClosed:()=>{he=null,Q&&(Q.style.display="flex"),te||s.focus({preventScroll:!0})}});i&&(i.box.setAttribute("aria-label",t??"Expanded wafer map"),n.length>1&&(i.contentWrap.style.flexDirection="column"),he=i,Q&&(Q.style.display="none"))}function un(e){const t=d.plotMode;d={...d,...e},e.plotMode!==void 0&&e.plotMode,Object.keys(e).every(r=>r==="legendPosition"||r==="showLegend"||r==="markFailingDies")||wt(),Et?.(),Dt?.(),Bt?.(),kt?.(),C();const i=e.plotMode!==void 0&&e.plotMode!==t,o=COLOR_KEYS.some(r=>r in e);(o||i)&&(ue(),Ve()),(o||i||e.activeTest!==void 0||e.logScale!==void 0||e.colorbarRangeMode!==void 0)&&$e?.()}function E(e){un(e);const t=Object.keys(e);_n?.(d,t,classifyChanged(t))}let Tt=!1;function Ot(){Tt||(Tt=!0,Yt(()=>{Tt=!1,C()},B))}function C(){const e=k??void 0,t=y.dies[0],n=t?{x:t.width,y:t.height}:ye.diePitchMm,i=Math.floor(s.clientWidth||s.width),o=!!(G?.length||U?.length||y.dies.some(m=>m.hbin!=null||m.sbin!=null)),r=d.legendPosition??"default",p=d.showLegend??!0,l=r==="default"||r==="compact",a=(ye.colorbarWidth??16)+28,c=o&&l?r!=="default"?Math.max(Pn,a):i<vi?0:i<bi?Math.max(yi,a):Math.max(Pn,a):void 0,h=mi(s,y,{...ye,minRightReserve:p?c:0,showColorbar:p&&(ye.showColorbar??!0),markFailingDies:d.markFailingDies??!1,legendPosition:r,legendOffset:xt,diePitchMm:n,fallbackFormat:d.fallbackFormat,showAxes:ye.showAxes??k!==null,viewport:e,activeBin:d.plotMode==="metadata"?d.highlightMetadataValue:d.highlightBin,hoverBin:vt,hbinDefs:G,sbinDefs:U,metadataFields:pe});bt=h.binLegendRows,We=h.legendBox??null,k===null&&(Y=h.viewport),M.size>0&&li(),Ce&&ai()}function li(){const e=X();if(!e)return;const t=s.getContext("2d"),n=y.hoverPoints,i=y.rectangles[0],o=i?i.width/2*e.ppm:e.ppm*.5,r=i?i.height/2*e.ppm:e.ppm*.5,p=Math.max(1,Math.min(3,o*.08)),l=o-p,a=r-p,c=[];for(const h of M){const m=ln.get(h);m!==void 0&&c.push({sx:e.originX+n[m].x*e.ppm,sy:e.originY-n[m].y*e.ppm})}if(c.length){t.save(),t.setLineDash([]),t.fillStyle="rgba(0,0,0,0.12)",t.beginPath();for(const{sx:h,sy:m}of c)t.rect(h-l,m-a,l*2,a*2);t.fill(),t.strokeStyle="rgba(255,255,255,0.9)",t.lineWidth=3,t.beginPath();for(const{sx:h,sy:m}of c)t.rect(h-l,m-a,l*2,a*2);t.stroke(),t.strokeStyle="rgba(0,0,0,0.9)",t.lineWidth=1.5,t.beginPath();for(const{sx:h,sy:m}of c)t.rect(h-l,m-a,l*2,a*2);t.stroke(),t.restore()}}function ai(){const e=s.getContext("2d"),t=Math.min(P.x,R.x),n=Math.min(P.y,R.y),i=Math.abs(R.x-P.x),o=Math.abs(R.y-P.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 ri(){s.toBlob(e=>{e&&Wi(e,v.downloadFilename??"wafermap",v.onSaveImage)})}function hn(e){return Y?Math.max(Y.ppm*Zn,Math.min(Y.ppm*Qn,e)):e}function Ee(e,t,n){const i=k??Y;if(!i)return;const o=hn(i.ppm*n),r=o/i.ppm,p=e-(e-i.originX)*r,l=t-(t-i.originY)*r,a=(Y?.snapDist??1)/(o/(Y?.ppm??o));k={originX:p,originY:l,ppm:o,snapDist:a},C()}function X(){return k??Y}function gn(e){if(e.ctrlKey||e.metaKey){e.preventDefault();const t=s.getBoundingClientRect(),n=e.deltaY<0?1.12:1/1.12;Ee(e.clientX-t.left,e.clientY-t.top,n)}else if(k!==null){e.preventDefault();const t=X(),n=k.snapDist;k={originX:t.originX-e.deltaX,originY:t.originY-e.deltaY,ppm:t.ppm,snapDist:n},C()}}function mn(e,t,n){return e>=n.x&&e<n.x+n.w&&t>=n.y&&t<n.y+n.h}function yn(e){if(e.button!==0||!X())return;s.focus({preventScroll:!0}),s.setPointerCapture(e.pointerId);const t=s.getBoundingClientRect(),n=e.clientX-t.left,i=e.clientY-t.top;if(We&&d.legendPosition==="floating"&&mn(n,i,We)){xe=!0,Ae={x:n,y:i},Ct={...xt};return}if(He&&N!=="pan"){Se=!0,fe=!0,we={x:n,y:i},Qe={x:X().originX,y:X().originY},s.style.cursor="grabbing";return}if(N==="zoom"||N==="select"){Ce=!0,P=R={x:n,y:i};return}fe=!0,we={x:n,y:i},Qe={x:X().originX,y:X().originY},s.style.cursor="grabbing"}function bn(e){const t=s.getBoundingClientRect(),n=e.clientX-t.left,i=e.clientY-t.top;if(Ce){R={x:n,y:i},Ot();return}if(xe){const h=n-Ae.x,m=i-Ae.y;h*h+m*m>16&&(xe=!1,Fe=!0,s.style.cursor="grabbing")}if(Fe){xt={x:Ct.x+(n-Ae.x),y:Ct.y+(i-Ae.y)},Ot();return}if(fe){const h=X(),m=k?.snapDist??Y?.snapDist??1;k={originX:Qe.x+(n-we.x),originY:Qe.y+(i-we.y),ppm:h.ppm,snapDist:m},Ot();return}const o=X();if(!o)return;const r=(n-o.originX)/o.ppm,p=(o.originY-i)/o.ppm,a=wn(r,p,o.snapDist)?.die??null,c=bt.find(h=>n>=h.x&&n<h.x+h.w&&i>=h.y&&i<h.y+h.h);if(an(c?c.bin:void 0),c){s.style.cursor="pointer",I&&(I.innerHTML=c.label??`Bin ${c.bin}`,I.style.display="block",An(I,s,e.clientX,e.clientY)),Ge?.(null,e);return}N==="pan"&&(s.style.cursor=a?"crosshair":"grab"),I&&(a?(I.innerHTML=gi(a,y.plotMode,{testDefs:ee,hbinDefs:G,sbinDefs:U,fallbackFormat:d.fallbackFormat,aggrMethod:y.aggrMethod,lotSize:y.lotSize,metadataFields:pe,activeTest:y.activeTest,reticleConfig:en}),I.style.display="block",An(I,s,e.clientX,e.clientY)):I.style.display="none"),Ge?.(a,e)}function vn(e){const t=s.getBoundingClientRect(),n=e.clientX-t.left,i=e.clientY-t.top,o=e.ctrlKey||e.metaKey;if(I&&(n<0||i<0||n>t.width||i>t.height)&&(I.style.display="none"),Ce){Ce=!1,R={x:n,y:i};const l=n-P.x,a=i-P.y,c=X();if(N==="zoom"){if(l*l+a*a<25)Ee(n,i,2);else if(c){const h=Math.min(P.x,R.x),m=Math.max(P.x,R.x),oe=Math.min(P.y,R.y),De=Math.max(P.y,R.y),J=m-h,re=De-oe;if(J>4&&re>4){const S=s.clientWidth,D=s.clientHeight,Wt=S/J,ot=D/re,$=Math.min(Wt,ot),st=hn(c.ppm*$),Ye=st/c.ppm,Ft=(h+m)/2,At=(oe+De)/2;k={originX:S/2-(Ft-c.originX)*Ye,originY:D/2-(At-c.originY)*Ye,ppm:st,snapDist:c.snapDist/Ye}}}C(),s.style.cursor="crosshair";return}if(l*l+a*a<25)Pt(n,i,o,e);else if(c){const h=(Math.min(P.x,R.x)-c.originX)/c.ppm,m=(Math.max(P.x,R.x)-c.originX)/c.ppm,oe=(c.originY-Math.max(P.y,R.y))/c.ppm,De=(c.originY-Math.min(P.y,R.y))/c.ppm,J=y.hoverPoints,re=[];for(let S=0;S<J.length;S++)if(J[S].x>=h&&J[S].x<=m&&J[S].y>=oe&&J[S].y<=De){const D=y.dies[S];D&&re.push(D)}if(o)for(const S of re){const D=Be(S);M.has(D)?M.delete(D):M.add(D)}else M=new Set(re.map(S=>Be(S)));ce?.(Rt())}C(),s.style.cursor="crosshair";return}if(xe){xe=!1,Pt(n,i,o,e);return}if(Fe){Fe=!1,s.style.cursor="grab";return}if(!fe)return;if(fe=!1,Se){Se=!1,s.style.cursor=He||N==="pan"?"grab":"crosshair";return}s.style.cursor=N==="pan"?"grab":"crosshair";const r=n-we.x,p=i-we.y;r*r+p*p<25&&Pt(n,i,o,e)}function Pt(e,t,n,i){for(const l of bt)if(e>=l.x&&e<l.x+l.w&&t>=l.y&&t<l.y+l.h){if(typeof l.bin=="number"){const a=d.highlightBin===l.bin?void 0:l.bin;E({highlightBin:a})}else{const a=d.highlightMetadataValue===l.bin?void 0:l.bin;E({highlightMetadataValue:a})}return}if(We&&mn(e,t,We))return;const o=X();if(!o)return;const p=wn((e-o.originX)/o.ppm,(o.originY-t)/o.ppm,o.snapDist)?.die??null;if(p){jn?.(p,i);const l=Be(p);n?M.has(l)?M.delete(l):M.add(l):M=new Set([l]),ce?.(Rt()),C()}else n||(M=new Set,ce?.([]),C())}function Rt(){const e=[],t=y.hoverPoints;for(let n=0;n<t.length;n++){const i=y.dies[n];i&&M.has(Be(i))&&e.push(i)}return e}function xn(){an(void 0),I&&ct(f),Ge?.(null,new MouseEvent("mouseleave")),s.style.cursor=N==="pan"?"grab":"crosshair"}function Cn(){fe=!1,Se=!1,Ce=!1,xe=!1,Fe=!1,I&&ct(f),Ge?.(null,new MouseEvent("mouseleave")),s.style.cursor=N==="pan"?"grab":"crosshair",C()}function wn(e,t,n){const i=y.hoverPoints,o=y.rectangles;for(let a=0;a<o.length;a++){const c=o[a];if(Math.abs(e-c.x)<=c.width/2&&Math.abs(t-c.y)<=c.height/2){const h=y.dies[a];return h?{die:h,index:a}:null}}let r=null,p=-1,l=n*n;for(let a=0;a<i.length;a++){const c=i[a].x-e,h=i[a].y-t,m=c*c+h*h;m<l&&(l=m,r=y.dies[a]??null,p=a)}return r?{die:r,index:p}:null}const Sn=new B.ResizeObserver(()=>{Y=null,k=null,C()});Sn.observe(s),v.height==null&&Xn<=0&&Yt(()=>Yt(()=>{O.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 ze=B.matchMedia(`(resolution: ${B.devicePixelRatio}dppx)`);const nt=()=>{ze.removeEventListener("change",nt),ze=B.matchMedia(`(resolution: ${B.devicePixelRatio}dppx)`),ze.addEventListener("change",nt),C()};ze.addEventListener("change",nt);const Mn=B.matchMedia("(prefers-color-scheme: dark)"),En=()=>C();Mn.addEventListener("change",En);const Dn=()=>{I&&ct(f)};B.addEventListener("blur",Dn);function Bn(e){if(e.key==="Escape"&&M.size>0&&(M=new Set,ce?.([]),C()),(e.key==="e"||e.key==="E")&&Gt&&(e.stopPropagation(),($t??fn)()),(e.ctrlKey||e.metaKey)&&(e.key==="="||e.key==="+"?(e.preventDefault(),Ee(s.clientWidth/2,s.clientHeight/2,1.2)):e.key==="-"?(e.preventDefault(),Ee(s.clientWidth/2,s.clientHeight/2,1/1.2)):e.key==="0"&&(e.preventDefault(),it())),!e.ctrlKey&&!e.metaKey&&!e.shiftKey){const n=X();if(n){const i=k?.snapDist??Y?.snapDist??1;let o=0,r=0;e.key==="ArrowLeft"&&(o=20,e.preventDefault()),e.key==="ArrowRight"&&(o=-20,e.preventDefault()),e.key==="ArrowUp"&&(r=20,e.preventDefault()),e.key==="ArrowDown"&&(r=-20,e.preventDefault()),(o||r)&&(k={originX:n.originX+o,originY:n.originY+r,ppm:n.ppm,snapDist:i},C())}e.key===" "&&!He&&(e.preventDefault(),He=!0,N!=="pan"&&(s.style.cursor="grab"))}}function kn(e){e.key===" "&&(He=!1,Se&&(fe=!1,Se=!1),s.style.cursor=N==="pan"?"grab":"crosshair")}s.style.cursor="grab",s.setAttribute("tabindex","0"),s.addEventListener("wheel",gn,{passive:!1}),s.addEventListener("pointerdown",yn),s.addEventListener("pointermove",bn),s.addEventListener("pointerup",vn),s.addEventListener("pointerleave",xn),s.addEventListener("pointercancel",Cn);const Ln=()=>it();s.addEventListener("dblclick",Ln),s.addEventListener("keydown",Bn),s.addEventListener("keyup",kn);const Tn=e=>{e.stopPropagation()};s.addEventListener("click",Tn),s.clientWidth,C(),$e?.();function it(){Y=null,k=null,C()}function It(){import("./userGuideHtml.js").then(e=>Li({buildWaferMap:xi,renderWaferMap,renderWaferGallery:void 0,analyzeWaferMap:wi},e.USER_GUIDE_HTML,$n,O))}return Le(),{setResult(e){be=e,_=e.wafer,ve=e.dies,G=e.hbinDefs,U=e.sbinDefs,ee=e.testDefs,pe=e.metadataFields,Jt=e.reticles?.length?e.reticles:void 0,en=e.reticleConfig,tn=e.view?.dataAxisFlip,ht=e.isLotStack,gt=e.aggrMethod,mt=e.lotSize,ei(),wt(),C(),q&&ue()},setOptions(e){un(e)},getOptions(){return{...d}},resetZoom:it,setSelection(e){M=new Set(e.map(t=>Be(t))),C()},clearSelection(){M=new Set,ce?.([]),C()},setFindingsNotice(e){rn=e,q?ue():F&&Ve()},setStatsSummary(e){if(se=e,ut(),St(),q)ue();else if(F)Ve();else if(e&&!Oe?.placement){const t=Oe?.defaultOpen??!Te;F=Nt("right",de,f),F.style.display=t?"block":"none";const n=w.parentElement,i=w.nextSibling;ae=Xt(w,F,"right"),n?.insertBefore(ae,i),Ve()}tt()},setSummaryVisible(e){K&&(K.style.display=e?"flex":"none")},setViewControlsVisible(e){L&&(L.style.display=e?"flex":"none")},setExpandVisible(e){Q&&(Q.style.display=e?"flex":"none")},openUserGuide:It,setInsightsOpen(e){Ie(e),H&&(e?(H.dataset.active="1",H.style.background=x.bgActive,H.style.color=x.iconActive):(delete H.dataset.active,H.style.background="transparent",H.style.color=x.icon))},destroy(){he?.close(),pn?.()?.remove(),Mt&&f.removeEventListener("click",Mt,!0),s.removeEventListener("wheel",gn),s.removeEventListener("pointerdown",yn),s.removeEventListener("pointermove",bn),s.removeEventListener("pointerup",vn),s.removeEventListener("pointerleave",xn),s.removeEventListener("pointercancel",Cn),s.removeEventListener("dblclick",Ln),s.removeEventListener("keydown",Bn),s.removeEventListener("keyup",kn),s.removeEventListener("click",Tn),Sn.disconnect(),ze.removeEventListener("change",nt),Mn.removeEventListener("change",En),B.removeEventListener("blur",Dn),qn(),I&&ct(f),ne?.remove(),Me&&(Me.parentElement?.insertBefore(w,Me),Me.remove()),ae&&(ae.parentElement?.insertBefore(w,ae),ae.remove()),w.remove(),s.style.cursor="",z?.destroy(),V?.destroy(),ke.remove()}}}
|
|
1
|
+
import{buildView as xi,buildHoverText as Ci,findTestDef as ct,resolveTestNumber as Yt,buildMapTitle as wi}from"../renderer/buildView.js";import{drawMapCanvas as Si,BIN_LEGEND_W as An,BIN_LEGEND_W_COMPACT as Mi,BIN_LEGEND_ADAPT_COMPACT as Ei,BIN_LEGEND_ADAPT_FLOATING as Di}from"./toCanvas.js";import{buildWaferMap as Bi,getTestPassStatus as ki,isParametricTest as Nt}from"../renderer/buildWaferMap.js";import{analyzeWaferMap as Li}from"../stats/analyzeWaferMap.js";import{SHADOW as Ti,LEADING as Hn,wireControlHover as Vn,SPACE as F,EDGE_GUTTER as Pi,RADIUS as zn,FONT as ft,CLR as v,applyOverlayZ as Oi,getTooltip as Yn,hideTooltip as pt,positionTooltip as Nn,createToolbarHelpers as Ri,buildModeMenuEl as Ii,openReparentedModal as Wi,openUserGuideWindow as Fi,makePaletteBtn as Ai,makeLogScaleBtn as Hi,makeLegendStyleBtn as Vi,makeOverlaysBtn as zi,makeOrientationBtn as Yi,menuLayerFor as Xn,saveImageBlob as jn,markMenuTrigger as $e,wireMenuA11y as _n,wireExpandToggle as Ni,nextFrame as Xt,requestedPassFailDisplay as Xi,overlayMenuRows as ji,anyOverlayActive as _i,logWmapVersionOnce as Ki,buildDataModeEntries as $i,metadataKeyHasData as Gi,metadataModeEntry as Ui}from"./toolbar.js";import{waferDisplayLabel as Zi,waferIdentityLabel as Qi}from"../core/waferLabel.js";import{metadataDisplayValue as qi}from"../core/metadata.js";import{withExportContext as Ji,noticeDownloadFilenameChange as eo}from"./exportName.js";import{createSummaryPanelEl as jt,wrapWithSummaryPanel as _t,renderWaferSummaryContentSteps as to}from"./summaryPanel.js";import{runChunked as no}from"./chunked.js";import{collectWarnings as io,buildWarningsMenuEl as oo,severityOf as so}from"./warnings.js";import{ICONS as Kn}from"./icons.js";import{createIdentityHeader as lo,collapsedLabel as Kt}from"./identityHeader.js";import{getDieKey as Be,hasPosition as $n,isPositionedDie as ao}from"../core/dies.js";import{buildDieListSection as ro}from"./dieList.js";import{buildMaplessSummary as co}from"./maplessSummary.js";import{resolveBinColors as fo,binColorWarning as po}from"../renderer/binColors.js";import{INPUT_DEFAULT_PASS_BINS as uo}from"../core/passBins.js";const Gn=new Set(["binColorScheme","valueColorScheme","reverseValueScheme","useDefinedBinColors","rotation","flipX","flipY","showDieLabels","showPartialDies","showRingBoundaries","showQuadrantBoundaries","showReticle","showXYIndicator","legendPosition","logScale","colorbarRangeMode","markFailingDies","fallbackFormat"]);export const COLOR_KEYS=["binColorScheme","valueColorScheme","reverseValueScheme","useDefinedBinColors","binColors"];export function classifyChanged(P){const m=P.some(p=>Gn.has(p)),b=P.some(p=>!Gn.has(p));return m&&b?"mixed":m?"preference":"state"}export function toPublicViewOptions(P){const{metadataValueOrder:m,binColors:b,lotSize:p,...B}=P;return B}export function renderWaferMap(P,m,b={}){return renderWaferMapCard(P,m,b)}export function renderWaferMapCard(P,m,b={}){Ki();const p=P.ownerDocument,B=p.defaultView??window,ke=Ji(()=>{const e=qi(V.metadata?.lot);return{lots:e!==void 0?[e]:[],...ee.isLotStack?{stackedWafers:h?.lotSize??!0}:{wafer:Qi({label:ee.label,wafer:V})}}},b.onSaveImage,b.onSaveText);eo(b.downloadFilename);function $t(){const e=h.plotMode==="softBin"||h.plotMode==="stackedSoftBins"?G:$,{primary:t,secondary:n}=wi(h,d.fallbackFormat,e);return[t,ee.isLotStack?"":n].filter(Boolean).join(" ")||"wafer-map"}B.getComputedStyle(P).position==="static"&&(P.style.position="relative");const Un=P.clientHeight;b.height!=null&&(P.style.height=typeof b.height=="number"?`${b.height}px`:b.height);const ut=m.dataCoverage?m.dataCoverage.unpositionedDies:m.dies.filter(e=>!$n(e)).length,Ge=(m.dataCoverage?m.dataCoverage.totalDies:m.dies.length-ut)===0&&ut>0,Le=p.createElement("div");Object.assign(Le.style,{display:"flex",flexDirection:"column",width:"100%",height:"100%"}),P.appendChild(Le);const ye=p.createElement("div");Object.assign(ye.style,{position:"relative",width:"100%",flex:"1 1 auto",minHeight:"0"});const ce=b.chromeInset??Pi,K=p.createElement("div");Object.assign(K.style,{display:"flex",alignItems:"stretch",gap:F.sm,background:v.canvasBg,paddingBottom:F.lg,paddingTop:ce,paddingLeft:ce,paddingRight:ce,flexShrink:"0",minWidth:"0"}),Le.appendChild(K),Le.appendChild(ye);function Te(){const e=[...K.children].some(t=>t.style.display!=="none");K.style.display=e?"flex":"none"}const w=p.createElement("div");Object.assign(w.style,{position:"relative",width:"100%",height:"100%"});const s=p.createElement("canvas");Object.assign(s.style,{width:"100%",height:"100%",display:"block"}),w.appendChild(s),ye.appendChild(w);let Ue=null;if(ut>0){let n=function(){if(t){const f=ro(e,m.testDefs,{...b.dieList,onSaveText:ke.onSaveText,waferMetadata:V.metadata,metadataFields:pe,ownerDocument:p});if(f)return f}const o=ct(m.testDefs,d.activeTest??0),r=Nt(o)?d.logScale??o?.logScale??!1:!1;return co(e,m.testDefs,{plotMode:d.plotMode??"hardBin",activeTest:d.activeTest,hbinDefs:$,sbinDefs:G,binColors:h.binColors,valueColorScheme:d.valueColorScheme,reverseValueScheme:d.reverseValueScheme,logScale:r,colorbarRangeMode:d.colorbarRangeMode,valueRangeDies:m.dies})},i=function(o){const r=p.createElement("button");return r.type="button",Vn(r),Object.assign(r.style,{fontSize:ft.body,padding:`${F.xxs} ${F.sm}`,borderRadius:zn.control,flexShrink:"0",border:`1px solid ${v.menuBorder}`,background:v.menuBg,color:v.text,cursor:"pointer"}),r.textContent=t?"View chart":"View die list",r.addEventListener("click",f=>{f.stopPropagation(),t=!t,r.textContent=t?"View chart":"View die list",o()}),r};const e=m.dies.filter(o=>!$n(o));let t=!1;if(Ge){const o=p.createElement("div");Object.assign(o.style,{position:"absolute",inset:"0",background:v.panelBg,padding:F.xl,boxSizing:"border-box",overflow:"hidden",display:"flex",flexDirection:"column",gap:F.md,zIndex:"1"});const r=p.createElement("div");Object.assign(r.style,{display:"flex",justifyContent:"space-between",alignItems:"flex-start",gap:F.md});const f=p.createElement("span");Object.assign(f.style,{fontSize:ft.body,color:v.label,lineHeight:Hn.base}),f.textContent="No die position data for this wafer.",r.appendChild(f);const l=p.createElement("div");Object.assign(l.style,{flex:"1",minHeight:"0",overflow:"auto",display:"flex",flexDirection:"column"}),r.appendChild(i(()=>l.replaceChildren(n()))),o.appendChild(r),o.appendChild(l),w.appendChild(o),Ue=()=>{t||l.replaceChildren(n())}}else{const o=p.createElement("div");Object.assign(o.style,{position:"absolute",left:"0",right:"0",bottom:"0",zIndex:"3",background:v.panelBg,borderTop:`1px solid ${v.menuBorder}`,fontSize:ft.body,color:v.text,cursor:"pointer",padding:`${F.xs} ${F.md}`,display:"flex",alignItems:"center",justifyContent:"space-between",gap:F.md}),Vn(o,"bare");const r=p.createElement("span");r.textContent=`+${e.length} ${e.length===1?"die":"dies"} without position data`,o.appendChild(r);const f=p.createElement("span");f.textContent="\u25BE",Object.assign(f.style,{fontSize:ft.body,lineHeight:Hn.none,color:v.label,flexShrink:"0"}),o.appendChild(f),o.setAttribute("aria-expanded","false"),o.setAttribute("aria-label",`${e.length} dies without position data. Click to view.`);let l=null,a=null;Ni(o,c=>{if(f.textContent=c?"\u25B4":"\u25BE",o.setAttribute("aria-expanded",String(c)),c){l=p.createElement("div");const g=o.getBoundingClientRect().height||28;Object.assign(l.style,{position:"absolute",left:"0",right:"0",bottom:`${g}px`,top:"20%",zIndex:"2",background:v.panelBg,borderTop:`1px solid ${v.menuBorder}`,padding:F.md,boxSizing:"border-box",display:"flex",flexDirection:"column",gap:F.md}),l.addEventListener("click",se=>se.stopPropagation());const y=p.createElement("div");Object.assign(y.style,{display:"flex",justifyContent:"flex-end"}),y.appendChild(i(()=>{a&&a.replaceChildren(n())})),l.appendChild(y),a=p.createElement("div"),Object.assign(a.style,{flex:"1",minHeight:"0",overflow:"auto",display:"flex",flexDirection:"column"}),a.appendChild(n()),l.appendChild(a),w.appendChild(l)}else l&&(l.remove(),l=null,a=null)}),w.appendChild(o),Ue=()=>{a&&!t&&a.replaceChildren(n())}}}const{onHover:Ze,onClick:Zn,onSelect:fe,onViewOptionsChange:Qn,showTooltip:qn=!0,showToolbar:Pe=!0,showIdentity:Gt=!0,summaryPanel:Oe,showHelpButton:Ut=!1,userGuideExtension:Jn,onExpand:Zt,showExpandButton:Qt=!0,zIndex:ei,insights:gt,warnings:qt,viewOptions:ti={},...be}=b,Re=gt?.enabled??!1,ni=.4,ii=20,Qe=[...m.passBins??uo],Jt=qt?.display??!0,oi=Oi(ei);let le=b.statsSummary,ae=[],en=!1,qe=null,tn=!1;function ht(){const e=io({result:m,statsSummary:le,extra:qe?[qe]:[]}),t=e.length!==ae.length||e.some((n,i)=>n.code!==ae[i]?.code||n.message!==ae[i]?.message);ae=e,(t||!en)&&(en=!0,qt?.onWarning?.(e))}ht();let ee=m,V=m.wafer,ve=m.dies,M=new Set,$=m.hbinDefs,G=m.sbinDefs,te=m.testDefs,pe=m.metadataFields,nn=m.reticles?.length?m.reticles:void 0,on=m.reticleConfig,sn=m.view?.dataAxisFlip,mt=m.isLotStack??!1,yt=m.aggrMethod,bt=m.lotSize;const si=Pe&ℜlet z=null,Q=null,q=null;Gt&&(z=lo(Kt(V.metadata??{},Ie())??"",V.metadata,{lotStack:Ie(),ownerDocument:p}),w.appendChild(z.metaPanel),z.metaPanel.style.visibility="visible",z.isEmpty()||(Q=ln(z.wrap),K.insertBefore(Q,K.firstChild),Te()));function ln(e){const t=p.createElement("div");return Object.assign(t.style,{display:"flex",alignItems:"center",padding:`${F.sm} ${F.lg}`,flex:"1 1 auto",minWidth:"0",overflow:"hidden",gap:F.sm}),Object.assign(e.style,{flex:"1",minWidth:"0"}),t.appendChild(e),t}function Ie(){return mt?{lotSize:bt??1,aggrMethod:yt}:void 0}function li(){if(!z)return;z.update(Kt(V.metadata??{},Ie())??"",V.metadata,Ie());const e=Q?.isConnected??!1,t=!z.isEmpty();!t&&e?(Q.remove(),Q=null):t&&!e&&(Q=ln(z.wrap),Q.style.display="",K.insertBefore(Q,K.firstChild),Te())}const ai=[...$??[],...G??[]].some(e=>e.color);let d={plotMode:"hardBin",showDieLabels:!1,showPartialDies:!0,showRingBoundaries:!1,showQuadrantBoundaries:!1,showReticle:!1,showXYIndicator:!1,rotation:0,flipX:!1,flipY:!1,legendPosition:"default",...ti},Y=null,ne=!1,an=null;function ri(){return Re?Y?Promise.resolve(Y):(an??=import("./insightsTab.js").then(({createInsightsTab:e})=>(Y=e({getItems:()=>[{wafer:V,dies:ve,hbinDefs:$,sbinDefs:G,testDefs:te,label:Zi({wafer:V},0),passBins:Qe,statsSummary:le}],getBinColors:()=>h.binColors,getRingCount:()=>ee.ringCount??4,onSaveImage:ke.onSaveImage,onSaveText:ke.onSaveText,defaultView:gt?.defaultView,showMetadataStrip:!1,contentInset:ce,backTab:si?void 0:{label:"Map",onBack:()=>We(!1)},onOpenGuide:Ut&&!Pe?()=>Ft():void 0,focusTest:t=>{E({plotMode:"value",activeTest:t,highlightBin:void 0}),We(!1)},ownerDocument:p}),Object.assign(Y.el.style,{position:"absolute",inset:"0",background:v.canvasBg,overflowY:"auto",paddingTop:"0"}),Y.el.style.display="none",ye.appendChild(Y.el),Y)),an):Promise.resolve(null)}let rn=0;const vt=["wheel","touchstart","pointerdown","keydown"];function di(e,t){if(t<=0)return;let n=!1;const i=[],o=()=>{n=!0;for(const f of i)B.clearTimeout(f);i.length=0;for(const f of vt)e.removeEventListener(f,o)},r=()=>n||!ne?!0:(e.scrollTop=t,e.scrollTop>=t);if(!r()){for(const f of vt)e.addEventListener(f,o,{passive:!0,once:!0});for(const f of[0,50,150,300,600])i.push(B.setTimeout(()=>{r()},f));i.push(B.setTimeout(()=>{for(const f of vt)e.removeEventListener(f,o)},700))}}function We(e){if(!Re)return;const t=ne;ne=e,Y&&!e&&t&&(rn=Y.el.scrollTop),Y&&(Y.el.style.display=e?"flex":"none"),w.style.visibility=e?"hidden":"",A&&(A.style.display=e||Ge?"none":"flex"),T&&(T.style.display=e?"none":"flex"),q&&(q.style.display=he?"none":"flex"),ie&&(ie.style.display="flex"),Q&&(Q.style.display=""),Te(),z&&e&&z.collapse(),it(),H&&(H.innerHTML=e?Kn.wafer:Kn.analysis,H.ariaLabel=e?"Back to wafer view":"Insights"),e&&ri().then(n=>{!n||!ne||(n.el.style.display="flex",n.render(),di(n.el,rn))})}Re&>?.defaultOpen&&queueMicrotask(()=>We(!0));let h,dn,N=null,k=null,xt=[],Ct;function cn(e){Ct!==e&&(Ct=e,x())}let Fe=null,wt=be.legendOffset??{x:0,y:0},Ae=!1,xe=!1,He={x:0,y:0},St={x:0,y:0},ue=!1,Ce=!1,X="pan",we={x:0,y:0},Je={x:0,y:0},O={x:0,y:0},R={x:0,y:0},Ve=!1,Se=!1;function Mt(){const e=d;h=xi(V,ve.filter(ao),{plotMode:e.plotMode,binColorScheme:e.binColorScheme,valueColorScheme:e.valueColorScheme,reverseValueScheme:e.reverseValueScheme,useDefinedBinColors:e.useDefinedBinColors,binColors:e.binColors??fo(ve,{passBins:Qe,binColorScheme:e.binColorScheme,hbinDefs:$,sbinDefs:G,useDefinedBinColors:e.useDefinedBinColors}),passBins:Qe,showDieLabels:e.showDieLabels,showPartialDies:e.showPartialDies,showRingBoundaries:e.showRingBoundaries,showQuadrantBoundaries:e.showQuadrantBoundaries,showReticle:e.showReticle,showXYIndicator:e.showXYIndicator,reticles:nn,ringCount:ee.ringCount??4,highlightBin:e.highlightBin,highlightMetadataValue:e.highlightMetadataValue,activeTest:e.activeTest,activeMetadataKey:e.activeMetadataKey,testDefs:te,valueRange:e.valueRange,metadataValueOrder:e.metadataValueOrder,logScale:e.logScale,isLotStack:mt,aggregationMethod:yt??e.aggregationMethod,lotSize:bt??e.lotSize,dataAxisFlip:sn,colorbarRangeMode:e.colorbarRangeMode,passFailDisplay:e.passFailDisplay,fallbackFormat:e.fallbackFormat,interactiveTransform:{rotation:e.rotation??0,flipX:e.flipX??!1,flipY:e.flipY??!1}},{hbinDefs:$,sbinDefs:G,metadataFields:pe}),dn=new Map(h.dies.map((n,i)=>[Be(n),i]));const t=e.binColors?null:po(h.binColors,h.plotMode);t?.message!==qe?.message&&(qe=t,ht(),tn&&Et())}Mt();let U=null,Me=null,et=null,fn=b.findingsNotice,ci={},I=null,re=null;function fi(e){const{kind:t,index:n}=e.variable;E(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"?(Pt(i.dieKeys),E({highlightBin:i.bin})):(i.kind==="region"||i.kind==="dies")&&Pt(i.dieKeys)}const ze=new Map;function pn(e){ze.get(e)?.cancel(),ze.delete(e);const t=no(to(e,{wafer:V,dies:ve,yieldSummary:ee.yield,dataCoverage:ee.dataCoverage,hbinDefs:$,sbinDefs:G,testDefs:te,statsSummary:le,warnings:Jt?ae:[],passBins:Qe,ringCount:ee.ringCount??4,binColors:h.binColors,plotMode:d.plotMode??"hardBin",metadataShownElsewhere:Gt,fallbackFormat:d.fallbackFormat,activeFindingId:et,findingsFilter:ci,findingsNotice:fn,onFindingsFilterChange:ge,onSaveText:ke.onSaveText,metadataFields:pe,dieListOptions:b.dieList,onFindingClick:(n,i)=>{et===n.id?(et=null,Pt([]),E({highlightBin:void 0})):(et=n.id,fi(n)),ge()}}));t.done||ze.set(e,t)}function ge(){U&&pn(U)}function Ye(){I&&pn(I)}if(Oe?.placement){const e=Oe.placement;U=jt(e,ce,p);const t=w.parentElement,n=w.nextSibling;Me=_t(w,U,e),t?.insertBefore(Me,n),ge()}else if(le){const e=Oe?.defaultOpen??!Pe;I=jt("right",ce,p),I.style.display=e?"block":"none";const t=w.parentElement,n=w.nextSibling;re=_t(w,I,"right"),t?.insertBefore(re,n),Ye()}const W=qn?Yn(p):null;let ie=null,L=null,A=null,T=null,tt=null,j=null,un=null,H=null,oe=null,nt=null;tn=!0;function Et(){if(!oe||!nt)return;const e=ae.length,t=e>0;if(oe.style.display=t?"flex":"none",nt.style.display=t?"":"none",!t)return;const n=so(ae[0]),i=`${e} data ${e===1?"warning":"warnings"}`;oe.style.color=n==="error"?v.errText:v.warnText,oe.ariaLabel=n==="error"?`${i} \u2014 the map may be positionally wrong`:i}let Dt=null,gn=null,Bt=null,kt=null,Lt=null,Tt=null;function Pt(e){M=new Set(e??[]),fe&&fe(Wt()),x()}function it(){if(!j)return;const e=!!(U??I);j.style.display=le&&e&&!ne?"flex":"none";const t=U??I,n=t?t.style.display!=="none":!1;le?.hasNotableFindings&&!n?j.style.color=v.findingIndicator:j.dataset.active||(j.style.color=v.icon)}let hn=null;function mn(e){const t=U??I;t&&(t.style.display=e?"block":"none",j&&hn?.(j,e),it())}if(Pe){let g=function(D){X=D,i(se,D==="zoom"),i(S,D==="pan"),tt&&i(tt,D==="select"),s.style.cursor=D==="pan"?"grab":"crosshair"};ie=p.createElement("div"),ie.dataset.wmapToolbar="single",Object.assign(ie.style,{marginLeft:"auto",flexShrink:"0",display:"flex",flexDirection:"row",alignItems:"center",flexWrap:"wrap-reverse",justifyContent:"flex-end",maxWidth:"100%",background:v.menuBg,border:`1px solid ${v.menuBorder}`,borderRadius:zn.control,boxShadow:Ti.panel,pointerEvents:"auto"});const e=Yn(p),t=Ri(e),{makeBtn:n,setActive:i,makeSep:o,makeMenuRow:r,makeMenuSection:f,closeOpenMenu:l,getOpenMenu:a,setOpenMenu:c}=t;hn=i,Dt=l,gn=a,p.addEventListener("click",l,!0),A=p.createElement("div"),Object.assign(A.style,{display:Ge?"none":"flex",alignItems:"center",gap:"0",flexWrap:"wrap",justifyContent:"flex-end"}),ie.appendChild(A);const y=n("download","Download PNG",gi);A.appendChild(y),A.appendChild(o());const se=n("zoomMode","Zoom (drag to zoom region)",()=>g("zoom")),De=n("zoomIn","Zoom in",()=>Ee(s.clientWidth/2,s.clientHeight/2,1.2)),J=n("zoomOut","Zoom out",()=>Ee(s.clientWidth/2,s.clientHeight/2,1/1.2)),de=n("reset","Reset zoom (double-click)",()=>st());A.appendChild(se),A.appendChild(De),A.appendChild(J),A.appendChild(de),A.appendChild(o());const S=n("pan","Pan (drag to move)",()=>g("pan"));A.appendChild(S),tt=n("boxSelect","Select (drag to select dies)",()=>g("select")),A.appendChild(tt),i(S,!0);{let D=function(u){return u.plotMode!==(d.plotMode??"hardBin")?!1:u.plotMode==="value"?(d.activeTest??0)===(u.activeTest??0):u.plotMode==="metadata"?d.activeMetadataKey===u.activeMetadataKey:!0},At=function(u,C){u.activeTest!==void 0?E({plotMode:u.plotMode,activeTest:u.activeTest,activeMetadataKey:void 0,logScale:u.logScale}):u.activeMetadataKey!==void 0?E({plotMode:u.plotMode,activeTest:void 0,activeMetadataKey:u.activeMetadataKey,passFailDisplay:"off"}):E({plotMode:u.plotMode,activeTest:void 0,activeMetadataKey:void 0,passFailDisplay:"off"}),C.remove(),c(null),$e(Z,!1)};L=p.createElement("div"),Object.assign(L.style,{display:"flex",alignItems:"center",gap:"0",flexWrap:"wrap",justifyContent:"flex-end"}),ie.appendChild(L),T=p.createElement("div"),Object.assign(T.style,{display:"flex",alignItems:"center",gap:"0"}),L.appendChild(T),T.appendChild(o());const lt=()=>{const u=a();u&&(u.remove(),c(null)),$e(Z,!1)},Z=n("mode","Plot mode",()=>{if(a()){lt();return}const u=ve,C=h.testDefs,{testEntries:dt,binEntries:me,stackedEntries:je}=$i(u,C,{includeStacked:h.isLotStack}),zt=(pe??[]).filter(Ke=>Gi(u,Ke.key)).map(Ui),_e=Ii(Z.getBoundingClientRect(),dt,me,je,D,At,{makeMenuRow:r,makeMenuSection:f},d.plotMode??"hardBin",Z.ownerDocument.defaultView??window,zt);Xn(Z).appendChild(_e),c(_e),$e(Z,!0),_n(_e,Z,lt)});$e(Z,!1);const{btn:at,sync:Xe}=Ai(t,()=>({...d,plotMode:d.plotMode??"hardBin"}),()=>ai,E);kt=Xe,kt();const Ht=zi(t,()=>{const u=!!h.hasReticle,C=(d.plotMode??"hardBin")==="value",{testNumber:dt}=Yt(d.activeTest??0,h.testDefs),me=ct(h.testDefs,dt),je=C&&me!==void 0&&!Nt(me),zt=C&&!je&&(me?.limitLow!==void 0||me?.limitHigh!==void 0),_e=C&&!je&&h.dies.some(Ke=>ki(Ke,dt,me)!==void 0);return ji(d,u,{functionalActive:je,hasLimits:zt,hasRecorded:_e,binMode:(d.plotMode??"hardBin")==="hardBin"||(d.plotMode??"hardBin")==="softBin"},Ke=>E(Ke))},()=>_i(d)),{btn:Vt,sync:hi}=Vi(t,()=>d,u=>E({legendPosition:u}));Bt=hi,Bt();const Fn=()=>{const{testNumber:u}=Yt(d.activeTest??0,te),C=ct(te,u);return C!==void 0&&!Nt(C)},{btn:mi,sync:yi}=Hi(t,()=>({...d,functionalActive:Fn()}),u=>E(u));Lt=yi,Lt();const bi=()=>{const{testNumber:u}=Yt(d.activeTest??0,te),C=ct(te,u);return C!==void 0&&(C.limitLow!==void 0||C.limitHigh!==void 0)},rt=n("specRange","Colorbar range: spec limits",()=>{const u=d.colorbarRangeMode==="data"?"spec":"data";E({colorbarRangeMode:u})});Tt=()=>{const u=d.plotMode==="value"&&bi()&&Xi(d)==="off"&&!Fn();rt.style.display=u?"":"none";const C=(d.colorbarRangeMode??"spec")==="spec";i(rt,C),rt.ariaLabel=C?"Colorbar range: spec limits (click for data range)":"Colorbar range: data range (click for spec limits)"},Tt();const vi=Yi(t,()=>d,u=>E(u));T.appendChild(Z),T.appendChild(at),T.appendChild(mi),T.appendChild(rt),Ge||(T.appendChild(o()),T.appendChild(Ht),T.appendChild(o()),T.appendChild(Vt),T.appendChild(o()),T.appendChild(vi)),le&&(j=n("findings","Summary panel",()=>{const u=U??I;u&&mn(u.style.display==="none")}),L.appendChild(o()),L.appendChild(j),I?.style.display!=="none"&&i(j,!0),it()),Jt&&(nt=o(),oe=n("warning","Data warnings",()=>{const u=a();if(l(new MouseEvent("click")),u)return;const C=oo(oe.getBoundingClientRect(),ae,B);Xn(ye).appendChild(C),c(C),_n(C,oe,()=>l(new MouseEvent("click")))}),$e(oe,!1),L.appendChild(nt),L.appendChild(oe),Et()),Re&&(L.appendChild(o()),H=n("analysis","Insights",()=>{We(!ne),i(H,ne)}),H.dataset.wmapInsightsBtn="1",L.appendChild(H)),Qt&&(L.appendChild(o()),q=n("expand","Expand (E)",Zt??yn),L.appendChild(q)),Ut&&(L.appendChild(o()),un=n("help","User guide",()=>Ft()),L.appendChild(un))}K.appendChild(ie),Te()}let he=null;function yn(){he&&(he.close(),he=null);const e=ye;e.style.flex="1",e.style.minWidth="0",e.style.minHeight="0";const t=Kt(V.metadata??{},Ie()),n=K.childElementCount>0?[K,e]:[e],i=Wi(n,{ownerDocument:p,boxSize:ne?{width:"min(96vw, 1600px)",height:"min(92vh, 1000px)"}:void 0,onClosed:()=>{he=null,q&&(q.style.display="flex"),ne||s.focus({preventScroll:!0})}});i&&(i.box.setAttribute("aria-label",t??"Expanded wafer map"),n.length>1&&(i.contentWrap.style.flexDirection="column"),he=i,q&&(q.style.display="none"))}function bn(e){("binColorScheme"in e||"useDefinedBinColors"in e)&&!("binColors"in e)&&d.binColors!==void 0&&(e={...e,binColors:void 0});const t=d.plotMode;d={...d,...e},e.plotMode!==void 0&&e.plotMode,Object.keys(e).every(r=>r==="legendPosition"||r==="showLegend"||r==="markFailingDies")||Mt(),Bt?.(),kt?.(),Lt?.(),Tt?.(),x();const i=e.plotMode!==void 0&&e.plotMode!==t,o=COLOR_KEYS.some(r=>r in e);(o||i)&&(ge(),Ye()),(o||i||e.activeTest!==void 0||e.logScale!==void 0||e.colorbarRangeMode!==void 0)&&Ue?.()}function E(e){bn(e);const t=Object.keys(e);Qn?.(d,t,classifyChanged(t))}let Ot=!1;function Rt(){Ot||(Ot=!0,Xt(()=>{Ot=!1,x()},B))}function x(){const e=k??void 0,t=h.dies[0],n=t?{x:t.width,y:t.height}:be.diePitchMm,i=Math.floor(s.clientWidth||s.width),o=!!($?.length||G?.length||h.dies.some(y=>y.hbin!=null||y.sbin!=null)),r=d.legendPosition??"default",f=d.showLegend??!0,l=r==="default"||r==="compact",a=(be.colorbarWidth??16)+28,c=o&&l?r!=="default"?Math.max(An,a):i<Di?0:i<Ei?Math.max(Mi,a):Math.max(An,a):void 0,g=Si(s,h,{...be,minRightReserve:f?c:0,showColorbar:f&&(be.showColorbar??!0),markFailingDies:d.markFailingDies??!1,legendPosition:r,legendOffset:wt,diePitchMm:n,fallbackFormat:d.fallbackFormat,showAxes:be.showAxes??k!==null,viewport:e,activeBin:d.plotMode==="metadata"?d.highlightMetadataValue:d.highlightBin,hoverBin:Ct,hbinDefs:$,sbinDefs:G,metadataFields:pe});xt=g.binLegendRows,Fe=g.legendBox??null,k===null&&(N=g.viewport),M.size>0&&pi(),Ce&&ui()}function pi(){const e=_();if(!e)return;const t=s.getContext("2d"),n=h.hoverPoints,i=h.rectangles[0],o=i?i.width/2*e.ppm:e.ppm*.5,r=i?i.height/2*e.ppm:e.ppm*.5,f=Math.max(1,Math.min(3,o*.08)),l=o-f,a=r-f,c=[];for(const g of M){const y=dn.get(g);y!==void 0&&c.push({sx:e.originX+n[y].x*e.ppm,sy:e.originY-n[y].y*e.ppm})}if(c.length){t.save(),t.setLineDash([]),t.fillStyle="rgba(0,0,0,0.12)",t.beginPath();for(const{sx:g,sy:y}of c)t.rect(g-l,y-a,l*2,a*2);t.fill(),t.strokeStyle="rgba(255,255,255,0.9)",t.lineWidth=3,t.beginPath();for(const{sx:g,sy:y}of c)t.rect(g-l,y-a,l*2,a*2);t.stroke(),t.strokeStyle="rgba(0,0,0,0.9)",t.lineWidth=1.5,t.beginPath();for(const{sx:g,sy:y}of c)t.rect(g-l,y-a,l*2,a*2);t.stroke(),t.restore()}}function ui(){const e=s.getContext("2d"),t=Math.min(O.x,R.x),n=Math.min(O.y,R.y),i=Math.abs(R.x-O.x),o=Math.abs(R.y-O.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 gi(){s.toBlob(e=>{e&&(b.downloadFilename!=null?jn(e,b.downloadFilename,b.onSaveImage):jn(e,$t(),ke.onSaveImage))})}function vn(e){return N?Math.max(N.ppm*ni,Math.min(N.ppm*ii,e)):e}function Ee(e,t,n){const i=k??N;if(!i)return;const o=vn(i.ppm*n),r=o/i.ppm,f=e-(e-i.originX)*r,l=t-(t-i.originY)*r,a=(N?.snapDist??1)/(o/(N?.ppm??o));k={originX:f,originY:l,ppm:o,snapDist:a},x()}function _(){return k??N}function xn(e){if(e.ctrlKey||e.metaKey){e.preventDefault();const t=s.getBoundingClientRect(),n=e.deltaY<0?1.12:1/1.12;Ee(e.clientX-t.left,e.clientY-t.top,n)}else if(k!==null){e.preventDefault();const t=_(),n=k.snapDist;k={originX:t.originX-e.deltaX,originY:t.originY-e.deltaY,ppm:t.ppm,snapDist:n},x()}}function Cn(e,t,n){return e>=n.x&&e<n.x+n.w&&t>=n.y&&t<n.y+n.h}function wn(e){if(e.button!==0||!_())return;s.focus({preventScroll:!0}),s.setPointerCapture(e.pointerId);const t=s.getBoundingClientRect(),n=e.clientX-t.left,i=e.clientY-t.top;if(Fe&&d.legendPosition==="floating"&&Cn(n,i,Fe)){xe=!0,He={x:n,y:i},St={...wt};return}if(Ve&&X!=="pan"){Se=!0,ue=!0,we={x:n,y:i},Je={x:_().originX,y:_().originY},s.style.cursor="grabbing";return}if(X==="zoom"||X==="select"){Ce=!0,O=R={x:n,y:i};return}ue=!0,we={x:n,y:i},Je={x:_().originX,y:_().originY},s.style.cursor="grabbing"}function Sn(e){const t=s.getBoundingClientRect(),n=e.clientX-t.left,i=e.clientY-t.top;if(Ce){R={x:n,y:i},Rt();return}if(xe){const g=n-He.x,y=i-He.y;g*g+y*y>16&&(xe=!1,Ae=!0,s.style.cursor="grabbing")}if(Ae){wt={x:St.x+(n-He.x),y:St.y+(i-He.y)},Rt();return}if(ue){const g=_(),y=k?.snapDist??N?.snapDist??1;k={originX:Je.x+(n-we.x),originY:Je.y+(i-we.y),ppm:g.ppm,snapDist:y},Rt();return}const o=_();if(!o)return;const r=(n-o.originX)/o.ppm,f=(o.originY-i)/o.ppm,a=Bn(r,f,o.snapDist)?.die??null,c=xt.find(g=>n>=g.x&&n<g.x+g.w&&i>=g.y&&i<g.y+g.h);if(cn(c?c.bin:void 0),c){s.style.cursor="pointer",W&&(W.textContent=c.label??`Bin ${c.bin}`,W.style.display="block",Nn(W,s,e.clientX,e.clientY)),Ze?.(null,e);return}X==="pan"&&(s.style.cursor=a?"crosshair":"grab"),W&&(a?(W.innerHTML=Ci(a,h.plotMode,{testDefs:te,hbinDefs:$,sbinDefs:G,fallbackFormat:d.fallbackFormat,aggrMethod:h.aggrMethod,lotSize:h.lotSize,metadataFields:pe,activeTest:h.activeTest,reticleConfig:on}),W.style.display="block",Nn(W,s,e.clientX,e.clientY)):W.style.display="none"),Ze?.(a,e)}function Mn(e){const t=s.getBoundingClientRect(),n=e.clientX-t.left,i=e.clientY-t.top,o=e.ctrlKey||e.metaKey;if(W&&(n<0||i<0||n>t.width||i>t.height)&&(W.style.display="none"),Ce){Ce=!1,R={x:n,y:i};const l=n-O.x,a=i-O.y,c=_();if(X==="zoom"){if(l*l+a*a<25)Ee(n,i,2);else if(c){const g=Math.min(O.x,R.x),y=Math.max(O.x,R.x),se=Math.min(O.y,R.y),De=Math.max(O.y,R.y),J=y-g,de=De-se;if(J>4&&de>4){const S=s.clientWidth,D=s.clientHeight,At=S/J,lt=D/de,Z=Math.min(At,lt),at=vn(c.ppm*Z),Xe=at/c.ppm,Ht=(g+y)/2,Vt=(se+De)/2;k={originX:S/2-(Ht-c.originX)*Xe,originY:D/2-(Vt-c.originY)*Xe,ppm:at,snapDist:c.snapDist/Xe}}}x(),s.style.cursor="crosshair";return}if(l*l+a*a<25)It(n,i,o,e);else if(c){const g=(Math.min(O.x,R.x)-c.originX)/c.ppm,y=(Math.max(O.x,R.x)-c.originX)/c.ppm,se=(c.originY-Math.max(O.y,R.y))/c.ppm,De=(c.originY-Math.min(O.y,R.y))/c.ppm,J=h.hoverPoints,de=[];for(let S=0;S<J.length;S++)if(J[S].x>=g&&J[S].x<=y&&J[S].y>=se&&J[S].y<=De){const D=h.dies[S];D&&de.push(D)}if(o)for(const S of de){const D=Be(S);M.has(D)?M.delete(D):M.add(D)}else M=new Set(de.map(S=>Be(S)));fe?.(Wt())}x(),s.style.cursor="crosshair";return}if(xe){xe=!1,It(n,i,o,e);return}if(Ae){Ae=!1,s.style.cursor="grab";return}if(!ue)return;if(ue=!1,Se){Se=!1,s.style.cursor=Ve||X==="pan"?"grab":"crosshair";return}s.style.cursor=X==="pan"?"grab":"crosshair";const r=n-we.x,f=i-we.y;r*r+f*f<25&&It(n,i,o,e)}function It(e,t,n,i){for(const l of xt)if(e>=l.x&&e<l.x+l.w&&t>=l.y&&t<l.y+l.h){if(typeof l.bin=="number"){const a=d.highlightBin===l.bin?void 0:l.bin;E({highlightBin:a})}else{const a=d.highlightMetadataValue===l.bin?void 0:l.bin;E({highlightMetadataValue:a})}return}if(Fe&&Cn(e,t,Fe))return;const o=_();if(!o)return;const f=Bn((e-o.originX)/o.ppm,(o.originY-t)/o.ppm,o.snapDist)?.die??null;if(f){Zn?.(f,i);const l=Be(f);n?M.has(l)?M.delete(l):M.add(l):M=new Set([l]),fe?.(Wt()),x()}else n||(M=new Set,fe?.([]),x())}function Wt(){const e=[],t=h.hoverPoints;for(let n=0;n<t.length;n++){const i=h.dies[n];i&&M.has(Be(i))&&e.push(i)}return e}function En(){cn(void 0),W&&pt(p),Ze?.(null,new MouseEvent("mouseleave")),s.style.cursor=X==="pan"?"grab":"crosshair"}function Dn(){ue=!1,Se=!1,Ce=!1,xe=!1,Ae=!1,W&&pt(p),Ze?.(null,new MouseEvent("mouseleave")),s.style.cursor=X==="pan"?"grab":"crosshair",x()}function Bn(e,t,n){const i=h.hoverPoints,o=h.rectangles;for(let a=0;a<o.length;a++){const c=o[a];if(Math.abs(e-c.x)<=c.width/2&&Math.abs(t-c.y)<=c.height/2){const g=h.dies[a];return g?{die:g,index:a}:null}}let r=null,f=-1,l=n*n;for(let a=0;a<i.length;a++){const c=i[a].x-e,g=i[a].y-t,y=c*c+g*g;y<l&&(l=y,r=h.dies[a]??null,f=a)}return r?{die:r,index:f}:null}const kn=new B.ResizeObserver(()=>{N=null,k=null,x()});kn.observe(s),b.height==null&&Un<=0&&Xt(()=>Xt(()=>{P.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 Ne=B.matchMedia(`(resolution: ${B.devicePixelRatio}dppx)`);const ot=()=>{Ne.removeEventListener("change",ot),Ne=B.matchMedia(`(resolution: ${B.devicePixelRatio}dppx)`),Ne.addEventListener("change",ot),x()};Ne.addEventListener("change",ot);const Ln=B.matchMedia("(prefers-color-scheme: dark)"),Tn=()=>x();Ln.addEventListener("change",Tn);const Pn=()=>{W&&pt(p)};B.addEventListener("blur",Pn);function On(e){if(e.key==="Escape"&&M.size>0&&(M=new Set,fe?.([]),x()),(e.key==="e"||e.key==="E")&&Qt&&(e.stopPropagation(),(Zt??yn)()),(e.ctrlKey||e.metaKey)&&(e.key==="="||e.key==="+"?(e.preventDefault(),Ee(s.clientWidth/2,s.clientHeight/2,1.2)):e.key==="-"?(e.preventDefault(),Ee(s.clientWidth/2,s.clientHeight/2,1/1.2)):e.key==="0"&&(e.preventDefault(),st())),!e.ctrlKey&&!e.metaKey&&!e.shiftKey){const n=_();if(n){const i=k?.snapDist??N?.snapDist??1;let o=0,r=0;e.key==="ArrowLeft"&&(o=20,e.preventDefault()),e.key==="ArrowRight"&&(o=-20,e.preventDefault()),e.key==="ArrowUp"&&(r=20,e.preventDefault()),e.key==="ArrowDown"&&(r=-20,e.preventDefault()),(o||r)&&(k={originX:n.originX+o,originY:n.originY+r,ppm:n.ppm,snapDist:i},x())}e.key===" "&&!Ve&&(e.preventDefault(),Ve=!0,X!=="pan"&&(s.style.cursor="grab"))}}function Rn(e){e.key===" "&&(Ve=!1,Se&&(ue=!1,Se=!1),s.style.cursor=X==="pan"?"grab":"crosshair")}s.style.cursor="grab",s.setAttribute("tabindex","0"),s.addEventListener("wheel",xn,{passive:!1}),s.addEventListener("pointerdown",wn),s.addEventListener("pointermove",Sn),s.addEventListener("pointerup",Mn),s.addEventListener("pointerleave",En),s.addEventListener("pointercancel",Dn);const In=()=>st();s.addEventListener("dblclick",In),s.addEventListener("keydown",On),s.addEventListener("keyup",Rn);const Wn=e=>{e.stopPropagation()};s.addEventListener("click",Wn),s.clientWidth,x(),Ue?.();function st(){N=null,k=null,x()}function Ft(){import("./userGuideHtml.js").then(e=>Fi({buildWaferMap:Bi,renderWaferMap,renderWaferGallery:void 0,analyzeWaferMap:Li},e.USER_GUIDE_HTML,Jn,P))}return Te(),{setResult(e){ee=e,V=e.wafer,ve=e.dies,$=e.hbinDefs,G=e.sbinDefs,te=e.testDefs,pe=e.metadataFields,nn=e.reticles?.length?e.reticles:void 0,on=e.reticleConfig,sn=e.view?.dataAxisFlip,mt=e.isLotStack,yt=e.aggrMethod,bt=e.lotSize,li(),Mt(),x(),U&&ge()},setOptions(e){bn(e)},getOptions(){return{...d}},resetZoom:st,setSelection(e){M=new Set(e.map(t=>Be(t))),x()},clearSelection(){M=new Set,fe?.([]),x()},setFindingsNotice(e){fn=e,U?ge():I&&Ye()},setStatsSummary(e){if(le=e,ht(),Et(),U)ge();else if(I)Ye();else if(e&&!Oe?.placement){const t=Oe?.defaultOpen??!Pe;I=jt("right",ce,p),I.style.display=t?"block":"none";const n=w.parentElement,i=w.nextSibling;re=_t(w,I,"right"),n?.insertBefore(re,i),Ye()}it()},closeSummaryPanel(){mn(!1)},getExportTitle(){return $t()},getBinColors(){return h.binColors},setSummaryVisible(e){j&&(j.style.display=e?"flex":"none")},setViewControlsVisible(e){L&&(L.style.display=e?"flex":"none")},setExpandVisible(e){q&&(q.style.display=e?"flex":"none")},openUserGuide:Ft,setInsightsOpen(e){We(e),H&&(e?(H.dataset.active="1",H.style.background=v.bgActive,H.style.color=v.iconActive):(delete H.dataset.active,H.style.background="transparent",H.style.color=v.icon))},destroy(){for(const e of ze.values())e.cancel();ze.clear(),he?.close(),gn?.()?.remove(),Dt&&p.removeEventListener("click",Dt,!0),s.removeEventListener("wheel",xn),s.removeEventListener("pointerdown",wn),s.removeEventListener("pointermove",Sn),s.removeEventListener("pointerup",Mn),s.removeEventListener("pointerleave",En),s.removeEventListener("pointercancel",Dn),s.removeEventListener("dblclick",In),s.removeEventListener("keydown",On),s.removeEventListener("keyup",Rn),s.removeEventListener("click",Wn),kn.disconnect(),Ne.removeEventListener("change",ot),Ln.removeEventListener("change",Tn),B.removeEventListener("blur",Pn),oi(),W&&pt(p),ie?.remove(),Me&&(Me.parentElement?.insertBefore(w,Me),Me.remove()),re&&(re.parentElement?.insertBefore(w,re),re.remove()),w.remove(),s.style.cursor="",Y?.destroy(),z?.destroy(),Le.remove()}}}
|
|
@@ -2,6 +2,7 @@ import type { Wafer } from '../core/wafer.js';
|
|
|
2
2
|
import type { Die } from '../core/dies.js';
|
|
3
3
|
import { type BinDef, type TestDef, type YieldSummary, type MetadataFieldDef } from '../renderer/buildWaferMap.js';
|
|
4
4
|
import type { StatsFinding, StatsSummary, LotStatsSummary } from '../stats/types.js';
|
|
5
|
+
import { type ReportMap } from '../stats/renderSummaryReport.js';
|
|
5
6
|
import { type FindingsFilter } from '../stats/filterFindings.js';
|
|
6
7
|
import { type BinColors } from '../renderer/binColors.js';
|
|
7
8
|
import { buildWarningsBanner, type WaferWarning } from './warnings.js';
|
|
@@ -11,6 +12,7 @@ import { type CapabilityItem } from '../stats/capability.js';
|
|
|
11
12
|
import { type SaveTextHandler } from './toolbar.js';
|
|
12
13
|
import { type DieListDisplayOptions } from './dieList.js';
|
|
13
14
|
export { csvField } from '../core/utils.js';
|
|
15
|
+
import { type Chunked } from '../core/utils.js';
|
|
14
16
|
import type { WaferMetadata } from '../core/metadata.js';
|
|
15
17
|
export interface SummaryPanelOptions {
|
|
16
18
|
/** Which side of the content area to place the panel. Default 'right'. */
|
|
@@ -220,7 +222,20 @@ export interface CsvExportContext {
|
|
|
220
222
|
* section title and emitted as a `Population` CSV column. */
|
|
221
223
|
populationLabel?: string;
|
|
222
224
|
}
|
|
223
|
-
|
|
225
|
+
/**
|
|
226
|
+
* {@link buildTestSectionSteps}, run straight through — the entry for every
|
|
227
|
+
* caller that is not staging its render across tasks.
|
|
228
|
+
*/
|
|
229
|
+
export declare function buildTestSection(...args: Parameters<typeof buildTestSectionSteps>): HTMLDivElement | null;
|
|
230
|
+
/**
|
|
231
|
+
* @internal The Test Values table as a {@link Chunked} computation: one step per
|
|
232
|
+
* test for the descriptive statistics, plus the steps of the capability pass it
|
|
233
|
+
* delegates to. This is the single largest piece of work in either summary
|
|
234
|
+
* panel — at lot scale it scans the pooled dies once per test and sorts every
|
|
235
|
+
* test's values — so it is the one that has to be interruptible for the panel
|
|
236
|
+
* not to block the main thread for seconds at a time.
|
|
237
|
+
*/
|
|
238
|
+
export declare function buildTestSectionSteps(dies: Die[], testDefs: TestDef[] | undefined, fallbackFormat?: 'si' | 'engineering',
|
|
224
239
|
/**
|
|
225
240
|
* When supplied, each test's descriptive stats and spec-yield are read from
|
|
226
241
|
* `.perTestStats`/`.testSpecYield` (already computed once by
|
|
@@ -273,7 +288,7 @@ panel?: HTMLElement,
|
|
|
273
288
|
* information for no benefit. The CSV export always carries every column
|
|
274
289
|
* regardless.
|
|
275
290
|
*/
|
|
276
|
-
columns?: 'compact' | 'full'): HTMLDivElement | null
|
|
291
|
+
columns?: 'compact' | 'full'): Chunked<HTMLDivElement | null>;
|
|
277
292
|
/**
|
|
278
293
|
* "Functional Tests" section — one row per functional (`testType: 'F'`) test
|
|
279
294
|
* with pass/fail counts and pass rate. The functional counterpart of
|
|
@@ -367,7 +382,11 @@ notice?: FindingsNotice): HTMLDivElement | null;
|
|
|
367
382
|
* they aren't reconstructable from per-wafer quartiles alone — but
|
|
368
383
|
* `buildTestSection`'s display doesn't need them.)
|
|
369
384
|
*/
|
|
370
|
-
|
|
385
|
+
/** {@link buildLotTestSectionSteps}, run straight through. */
|
|
386
|
+
export declare function buildLotTestSection(...args: Parameters<typeof buildLotTestSectionSteps>): HTMLDivElement | null;
|
|
387
|
+
/** @internal {@link buildLotTestSection} as a {@link Chunked} computation —
|
|
388
|
+
* see {@link buildTestSectionSteps}, which does the work. */
|
|
389
|
+
export declare function buildLotTestSectionSteps(allDies: Die[], testDefs: TestDef[] | undefined, fallbackFormat?: 'si' | 'engineering', perWaferSummaries?: StatsSummary[],
|
|
371
390
|
/** Optional host hook for the "Export CSV" button — see `saveTextFile` (toolbar.ts). */
|
|
372
391
|
onSaveText?: SaveTextHandler,
|
|
373
392
|
/**
|
|
@@ -378,7 +397,7 @@ capabilityItems?: CapabilityItem[],
|
|
|
378
397
|
/** Panel element owning the collapsed state. Omit for a stateless render. */
|
|
379
398
|
panel?: HTMLElement,
|
|
380
399
|
/** See `buildTestSection`'s `columns`. Defaults to the full set. */
|
|
381
|
-
columns?: 'compact' | 'full'): HTMLDivElement | null
|
|
400
|
+
columns?: 'compact' | 'full'): Chunked<HTMLDivElement | null>;
|
|
382
401
|
export declare function createSummaryPanelEl(placement: 'right' | 'left' | 'top' | 'bottom',
|
|
383
402
|
/**
|
|
384
403
|
* Inset from the edge this panel docks against — stated by the caller,
|
|
@@ -402,8 +421,22 @@ export declare function createSummaryPanelEl(placement: 'right' | 'left' | 'top'
|
|
|
402
421
|
edgeInset: string, ownerDocument?: Document): HTMLDivElement;
|
|
403
422
|
/** Wrap the canvas + panel in a flex container according to placement. */
|
|
404
423
|
export declare function wrapWithSummaryPanel(content: HTMLElement, panel: HTMLDivElement, placement: 'right' | 'left' | 'top' | 'bottom'): HTMLDivElement;
|
|
405
|
-
/**
|
|
406
|
-
|
|
424
|
+
/**
|
|
425
|
+
* {@link renderWaferSummaryContentSteps}, run straight through — the entry for a
|
|
426
|
+
* caller that does not stage its render.
|
|
427
|
+
*/
|
|
428
|
+
export declare function renderWaferSummaryContent(...args: Parameters<typeof renderWaferSummaryContentSteps>): void;
|
|
429
|
+
/**
|
|
430
|
+
* @internal Render all wafer-level sections into a panel element, as a
|
|
431
|
+
* {@link Chunked} computation. Clears existing content.
|
|
432
|
+
*
|
|
433
|
+
* Chunked for the same reason the lot panel is: the Test Values table walks
|
|
434
|
+
* every die once per test, which on a single 400,000-die wafer is seconds of
|
|
435
|
+
* uninterruptible work on the main thread. Sections are appended as they are
|
|
436
|
+
* built, so the panel fills in. The synchronous entry above is this drained —
|
|
437
|
+
* one implementation, not a second progressive copy.
|
|
438
|
+
*/
|
|
439
|
+
export declare function renderWaferSummaryContentSteps(panel: HTMLDivElement, params: {
|
|
407
440
|
wafer: Wafer;
|
|
408
441
|
dies: Die[];
|
|
409
442
|
yieldSummary?: YieldSummary;
|
|
@@ -460,17 +493,45 @@ export declare function renderWaferSummaryContent(panel: HTMLDivElement, params:
|
|
|
460
493
|
* authoritative in neither place, is the thing being avoided in both cases.
|
|
461
494
|
*/
|
|
462
495
|
metadataShownElsewhere?: boolean;
|
|
463
|
-
}): void
|
|
496
|
+
}): Chunked<void>;
|
|
464
497
|
/** Render lot-level content into the panel. Clears existing content. */
|
|
465
|
-
|
|
498
|
+
/** A gallery item as the lot report reads it — every field optional, since a slot may not have loaded. */
|
|
499
|
+
type ReportItem = {
|
|
500
|
+
label?: string;
|
|
501
|
+
wafer?: Wafer;
|
|
502
|
+
dies?: Die[];
|
|
503
|
+
passBins?: readonly number[];
|
|
504
|
+
ringCount?: number;
|
|
505
|
+
hbinDefs?: BinDef[];
|
|
506
|
+
sbinDefs?: BinDef[];
|
|
507
|
+
testDefs?: TestDef[];
|
|
508
|
+
statsSummary?: StatsSummary;
|
|
509
|
+
};
|
|
510
|
+
/**
|
|
511
|
+
* @internal Gallery items as report maps — the one conversion for the gallery's
|
|
512
|
+
* and the lot panel's report buttons. A slot not yet loaded is skipped, but each
|
|
513
|
+
* wafer keeps the label its position gives it, so a report names wafers exactly
|
|
514
|
+
* as the cards do. `passBins`/`ringCount` fill in only for an item built without them.
|
|
515
|
+
*/
|
|
516
|
+
export declare function reportMapsFromItems(items: ReadonlyArray<ReportItem | null | undefined>, passBins: readonly number[], ringCount: number): ReportMap[];
|
|
517
|
+
/**
|
|
518
|
+
* {@link renderLotSummaryContentSteps}, run straight through — the entry for a
|
|
519
|
+
* caller that is not staging the render across tasks.
|
|
520
|
+
*/
|
|
521
|
+
export declare function renderLotSummaryContent(...args: Parameters<typeof renderLotSummaryContentSteps>): void;
|
|
522
|
+
/**
|
|
523
|
+
* @internal The lot summary panel as a {@link Chunked} computation: it pools
|
|
524
|
+
* every die of every wafer and derives bin, region and per-test sections from
|
|
525
|
+
* that pool, which at lot scale is the longest single piece of work anywhere in
|
|
526
|
+
* this library — 15.3 s on a 50-wafer lot of 4,000 dies x 100 tests, enough for
|
|
527
|
+
* the browser to offer to kill the page. Each step is one section, or one test
|
|
528
|
+
* within the Test Values table, and each section is appended as it is built, so
|
|
529
|
+
* the panel fills in rather than arriving at once.
|
|
530
|
+
*/
|
|
531
|
+
export declare function renderLotSummaryContentSteps(panel: HTMLDivElement, params: {
|
|
466
532
|
lotSummary: LotStatsSummary;
|
|
467
533
|
/** `passBins` on an item is that wafer's own (`WaferMapResult.passBins`) and wins over the top-level fallback. */
|
|
468
|
-
items: Array<{
|
|
469
|
-
label?: string;
|
|
470
|
-
wafer?: Wafer;
|
|
471
|
-
dies?: Die[];
|
|
472
|
-
passBins?: readonly number[];
|
|
473
|
-
statsSummary?: StatsSummary;
|
|
534
|
+
items: Array<ReportItem & {
|
|
474
535
|
metadataFields?: MetadataFieldDef[];
|
|
475
536
|
} | null>;
|
|
476
537
|
hbinDefs?: BinDef[];
|
|
@@ -502,5 +563,5 @@ export declare function renderLotSummaryContent(panel: HTMLDivElement, params: {
|
|
|
502
563
|
unusual: number;
|
|
503
564
|
notable: number;
|
|
504
565
|
} | undefined;
|
|
505
|
-
}): void
|
|
566
|
+
}): Chunked<void>;
|
|
506
567
|
//# sourceMappingURL=summaryPanel.d.ts.map
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{waferDisplayLabel as me}from"../core/waferLabel.js";import{itemPassBins as he,passBinsLabel as Ke}from"../core/passBins.js";import{isParametricTest as Ge}from"../renderer/buildWaferMap.js";import{buildRingRegions as Ue,buildQuadrantRegions as Qe,buildRegionYieldData as Xe}from"../stats/regions.js";import{computeFunctionalYield as Ze}from"../stats/analyzeWaferMap.js";import{renderSummaryReportHtml as Je,renderLotSummaryReportHtml as et}from"../stats/renderSummaryReport.js";import{buildFindingsNarrative as tt}from"../stats/findingsNarrative.js";import{filterFindings as nt}from"../stats/filterFindings.js";import{buildFacetTable as it,prettyKey as Ce}from"../stats/facets.js";import{commonMetadata as we}from"../stats/facets.js";import{resolveMetadataColumns as ot}from"../stats/metadataColumns.js";import{resolveBinColors as Se,resolveBinColorsByWafer as st}from"../renderer/binColors.js";import{NO_DATA_FILL as at}from"../renderer/colorMap.js";import{describeWaferPopulation as ve,populationLabel as rt}from"../stats/population.js";import{buildWarningsBanner as ge,collectWarnings as $e}from"./warnings.js";export{ge as buildWarningsBanner};import{fmt as ke,fmtAggregationMethod as lt,plainBinTerms as ne}from"../renderer/fmt.js";import{getUniqueTestNumbers as dt}from"../renderer/buildView.js";import{quantile as ie}from"../stats/math.js";import{buildCapabilityData as ct}from"../stats/capability.js";import{sortBinsForDisplay as pt}from"../stats/binPareto.js";import{poolFunctionalYield as ut}from"../stats/testPassRate.js";import{makeLabeledSelect as Be,makeSegmented as be}from"./charts/chartShell.js";import{SHADOW as Le,MOTION as Ne,LEADING as Q,TRACKING as re,wireControlHover as q,controlStyle as le,SPACE as y,RADIUS as _,FONT as E,CLR as L,sevColor as de,openModal as Fe,openReportModal as Ee,saveTextFile as De,wireTooltip as oe}from"./toolbar.js";import{buildDieListSection as ft}from"./dieList.js";export{csvField}from"../core/utils.js";import{medianOfSorted as mt,csvField as ce}from"../core/utils.js";import{metadataDisplayValue as ht}from"../core/metadata.js";const gt=L.panelBg,Re=`1px solid ${L.menuBorder}`,bt="12px",Y=L.label,K=L.value,Te="10px";function l(e,t,i,n=document){const o=n.createElement(e);return t&&Object.assign(o.style,t),i!==void 0&&(o.textContent=i),o}function J(e){return l("div",{fontSize:Te,fontWeight:"700",letterSpacing:re,textTransform:"uppercase",color:Y,marginBottom:y.sm},e)}const Me=new WeakMap,Ae=["regionYield","testValues","functionalTests"];function pe(e){if(!e)return{collapsed:new Set(Ae),regionMode:"ring",waferSort:"slot"};let t=Me.get(e);return t||(t={collapsed:new Set(Ae),regionMode:"ring",waferSort:"slot"},Me.set(e,t)),t}function X(e,t=!0,i,n){const o=l("div"),d=pe(n?.panel);n?.stateKey&&n.panel&&(t=!d.collapsed.has(n.stateKey));const s=document.createElement("button");s.type="button",Object.assign(s.style,{display:"flex",alignItems:"center",gap:y.xs,width:"100%",background:"none",border:"none",cursor:"pointer",padding:"0 0 6px",textAlign:"left"});const p=l("span",{fontSize:E.meta,color:Y,transition:`transform ${Ne.base}`,transform:t?"rotate(90deg)":"rotate(0deg)",display:"inline-block",lineHeight:Q.none,marginRight:"1px"},"\u25B6"),c=l("span",{fontSize:Te,fontWeight:"700",letterSpacing:re,textTransform:"uppercase",color:Y,flex:"1"},e);if(q(s,"bare"),s.setAttribute("aria-expanded",t?"true":"false"),s.appendChild(p),s.appendChild(c),i){const b=l("span",{fontSize:E.meta,fontWeight:"700",background:L.warnBg,color:L.warnText,borderRadius:_.pill,padding:"1px 5px"},i);s.appendChild(b)}const r=l("div");r.style.display=t?"block":"none";let a=t;if(s.addEventListener("click",()=>{a=!a,r.style.display=a?"block":"none",p.style.transform=a?"rotate(90deg)":"rotate(0deg)",s.setAttribute("aria-expanded",a?"true":"false"),n?.stateKey&&n.panel&&(a?d.collapsed.delete(n.stateKey):d.collapsed.add(n.stateKey))}),n?.control){const b=l("div",{display:"flex",alignItems:"center",gap:y.sm});s.style.width="auto",s.style.flex="1",b.appendChild(s);const u=()=>{r.innerHTML="",n.render?.(r)},S=n.control(u);S&&(S.style.marginBottom="6px",S.addEventListener("click",N=>N.stopPropagation()),b.appendChild(S)),o.appendChild(b)}else o.appendChild(s);return o.appendChild(r),n?.render?.(r),{outer:o,content:r}}function Ie(){return l("div",{height:"1px",background:L.separator,margin:`${bt} 0`,flexShrink:"0"})}function xe(e,t,i=L.barFill,n,o){const d=l("div",{marginBottom:"5px"}),s=l("div",{display:"flex",justifyContent:"space-between",fontSize:E.body,color:K,marginBottom:y.xxs}),p=l("span",{color:Y},e),c=l("span",{fontWeight:"600"},`${t.toFixed(1)}%`);s.appendChild(p),s.appendChild(c);const r=n!==void 0?n:Math.min(100,Math.max(0,t)),a=i,b=l("div",{position:"relative",height:"9px",background:L.bgActive,borderRadius:_.control,overflow:"hidden"}),u=l("div",{height:"100%",width:`${r}%`,background:a,borderRadius:_.control,transition:`width ${Ne.base}`});if(b.appendChild(u),o!==void 0){const S=l("div",{position:"absolute",top:"0",bottom:"0",left:`${o}%`,width:"2px",marginLeft:"-1px",background:L.value,opacity:"0.8"});b.appendChild(S)}return d.appendChild(s),d.appendChild(b),d}function We(){const e=l("div",{display:"flex",gap:y.sm,marginBottom:y.md});return e.finish=()=>{const t=e.lastElementChild;t&&Object.assign(t.style,{borderRight:"none",paddingRight:"0"})},e}function se(e,t,i){const n=l("div",{padding:`${y.xxs} ${y.md} ${y.xxs} 0`,borderRight:Re,textAlign:"center",flex:"1"}),o=l("div",{fontSize:E.heading,fontWeight:"700",color:K,lineHeight:Q.tight},e),d=l("div",{fontSize:E.body,color:Y,marginTop:y.xxs},t);return n.appendChild(o),n.appendChild(d),i&&n.appendChild(l("div",{fontSize:E.body,color:Y,opacity:"0.85"},i)),n}function Pe(e,t){const i=l("div",{display:"flex",justifyContent:"space-between",fontSize:E.body,gap:y.md,marginBottom:"3px"}),n=l("span",{color:Y,flexShrink:"0"},e),o=l("span",{color:K,textAlign:"right",fontWeight:"500",wordBreak:"break-all"},t);return i.appendChild(n),i.appendChild(o),i}function xt(e,t){const i=l("div",{display:"flex",fontSize:E.body,gap:y.sm,marginBottom:"3px"}),n=l("span",{color:Y,flexShrink:"0"},`${e}:`),o=l("span",{color:K,fontWeight:"500",wordBreak:"break-all"},t);return i.appendChild(n),i.appendChild(o),i}export function metadataEntries(e){const t=[];for(const[i,n]of Object.entries(e)){const o=ht(n);o!==void 0&&t.push([i,o])}return t}const yt=["lot","product","testprogram","split"],ue=e=>{const t=yt.indexOf(e.toLowerCase().replace(/[^a-z]/g,""));return t===-1?Number.MAX_SAFE_INTEGER:t};export function buildFacetSummaryChips(e,t=3){if(!e.length)return null;const i=l("div",{display:"flex",flexWrap:"wrap",alignItems:"baseline",gap:`${y.xs} ${y.lg}`}),n=[...e].sort((p,c)=>ue(p.key)-ue(c.key)),o=n.filter(p=>ue(p.key)!==Number.MAX_SAFE_INTEGER),d=n.filter(p=>ue(p.key)===Number.MAX_SAFE_INTEGER),s=p=>{const c=l("span",{whiteSpace:"nowrap"}),r=l("span",{color:Y},`${Ce(p.key)}: `);c.appendChild(r);const a=p.values.slice(0,t),b=p.values.length-a.length;let u=a.map(S=>S.value).join(", ");return b>0&&(u+=` +${b} more`),c.appendChild(document.createTextNode(u)),c};for(const p of o)i.appendChild(s(p));if(d.length){const p=l("span",{display:"none",flexWrap:"wrap",alignItems:"baseline",gap:`${y.xs} ${y.lg}`});for(const a of d)p.appendChild(s(a));const c=l("button",{background:"none",border:"none",padding:"0",cursor:"pointer",color:L.iconActive,fontSize:E.body,whiteSpace:"nowrap"});c.type="button",q(c,"bare");const r=a=>{p.style.display=a?"contents":"none",c.textContent=a?"less":`+${d.length} more`,c.setAttribute("aria-expanded",String(a))};r(!1),c.addEventListener("click",()=>r(c.getAttribute("aria-expanded")!=="true")),i.appendChild(p),i.appendChild(c)}return i}export function buildMetadataStripRow(e,t,i){const n=it(e,i),o=buildFacetSummaryChips(n);if(!o&&!t)return null;const d=l("div",{display:"flex",flexWrap:"wrap",alignItems:"baseline",gap:"4px 14px"});if(t){const s=l("span",{fontWeight:"500",whiteSpace:"nowrap"},t.aggrMethod?`${t.lotSize} wafers stacked \xB7 ${t.aggrMethod}`:`${t.lotSize} wafers stacked`);d.appendChild(s)}return o&&d.appendChild(o),d}const Ct={display:"flex",flexDirection:"column",gap:y.sm,background:L.menuBg,border:`1px solid ${L.menuBorder}`,borderRadius:_.container,padding:`${y.sm} ${y.lg}`,boxShadow:Le.panel,fontSize:E.body,lineHeight:Q.none,boxSizing:"border-box",width:"100%",minWidth:"0"};export function buildMetadataStripBox(e,t,i){const n=buildMetadataStripRow(e,t,i);if(!n)return null;const o=l("div",Ct);return o.appendChild(n),o}export function buildCompactMetadataRows(e){const t=metadataEntries(e);if(!t.length)return null;const i=l("div");for(const[n,o]of t)i.appendChild(xt(Ce(n),o));return i}export function buildMetadataInfoSection(e,t){const i=buildMetadataStripRow(e,t,{facetableOnly:e.length>1});if(!i)return null;const n=l("div");return n.appendChild(J("Wafer Info")),n.appendChild(i),n}export function buildYieldSection(e,t,i=[1]){const n=l("div");n.appendChild(J("Summary"));const o=We();if(o.appendChild(se(String(e.totalDies),"Total dies")),e.partialDies>0&&o.appendChild(se(String(e.partialDies),"Partial")),e.yieldPercent!==null){const d=Ke([i]);o.appendChild(se(`${e.yieldPercent.toFixed(1)}%`,"Yield",`pass: ${d}`))}return o.finish(),n.appendChild(o),e.edgeExcludedDies>0&&n.appendChild(Pe("Edge excluded (outer zone)",String(e.edgeExcludedDies))),n}export function buildBinSection(e,t,i,n,o,d){const s=new Map;if(o)for(const[r,a]of Object.entries(o))s.set(Number(r),a);else for(const r of e){if(r.partial||r.edgeExcluded)continue;const a=i==="hard"?r.hbin:r.sbin;a!=null&&s.set(a,(s.get(a)??0)+1)}if(!s.size)return null;const p=n??Se(e,{passBins:d,...i==="hard"?{hbinDefs:t}:{sbinDefs:t}}),c=l("div");c.appendChild(J(ze(i,[...s.values()].reduce((r,a)=>r+a,0))));for(const r of He(s,t,p[i],p.pass[i]))c.appendChild(r);return c}function ze(e,t){return`${e==="hard"?"Hard":"Soft"} Bin Breakdown \u2014 % of dies (N=${t})`}function He(e,t,i,n){const o=[...e.values()].reduce((p,c)=>p+c,0),d=t?new Map(t.map(p=>[p.bin,p])):null;return pt(e.entries(),n).map(([p,c])=>{const r=d?.get(p),a=r?.name?`Bin ${p} \xB7 ${r.name}`:`Bin ${p}`,b=c/o*100,u=i.get(p)??at;return xe(`${a} (${c})`,b,u)})}export function buildBinBreakdownSection(e){const{dies:t,hbinDefs:i,sbinDefs:n,hardCounts:o,softCounts:d,plotMode:s,passBins:p=[1],panel:c}=e,r=e.binColors??Se(t,{passBins:p,hbinDefs:i,sbinDefs:n}),a=m=>{const x=m==="hard"?o:d,C=new Map;if(x){for(const[v,k]of Object.entries(x))C.set(Number(v),k);return C}for(const v of t){if(v.partial||v.edgeExcluded)continue;const k=m==="hard"?v.hbin:v.sbin;k!=null&&C.set(k,(C.get(k)??0)+1)}return C},b=a("hard"),u=a("soft"),S=b.size>0,N=u.size>0;if(!S&&!N)return null;const I=pe(c),P=s==="softBin"||s==="stackedSoftBins"?"soft":s==="hardBin"||s==="stackedBins"?"hard":void 0;let R=I.binMode??P??(S?"hard":"soft");R==="hard"&&!S&&(R="soft"),R==="soft"&&!N&&(R="hard");const H=R==="hard"?b:u,h=R==="hard"?i:n,f=[...H.values()].reduce((m,x)=>m+x,0),{outer:w}=X(ze(R,f),!0,void 0,{stateKey:"bins",panel:c,render:m=>{const x=R==="hard"?r.hard:r.soft;for(const C of He(H,h,x,r.pass[R]))m.appendChild(C)},control:S&&N&&c?()=>be([["hard","Hard"],["soft","Soft"]],R,m=>{I.binMode=m;const x=buildBinBreakdownSection(e);x&&w.replaceWith(x)},c.ownerDocument,!0):void 0});return w}export function buildLotBinSection(e,t,i,n){return buildBinSection(e,t,i,n)}export function buildRegionYieldPanelSection(e){const{diesByWafer:t,allWafers:i,ringCount:n,passBins:o,panel:d}=e,s=pe(d),p=a=>Xe(t,i,n,o,a==="ring"?Ue:Qe);if(!p("ring").length&&!p("quadrant").length)return null;const c=s.regionMode,{outer:r}=X(c==="ring"?"Ring Yield":"Quadrant Yield",!0,void 0,{stateKey:"regionYield",panel:d,render:a=>{const b=p(c);if(!b.length){a.appendChild(l("div",{fontSize:E.body,color:Y},"No positioned dies for this breakdown."));return}for(const{label:u,n:S,yieldPercent:N}of b)a.appendChild(xe(`${u} (N=${S})`,N))},control:d?()=>be([["ring","Ring"],["quadrant","Quadrant"]],c,a=>{s.regionMode=a;const b=buildRegionYieldPanelSection(e);b&&r.replaceWith(b)},d.ownerDocument,!0):void 0});return r}export function buildLotOverviewSection(e,t=[]){const i=l("div"),n=ve(e.perWafer.map(s=>s.summary.wafer));i.appendChild(J(n.lotId!==void 0?"Lot Summary":"Summary"));const o=We();o.appendChild(se(String(e.stats.waferCount),"Wafers"));const d=e.perWafer.map(s=>s.summary.stats.yieldPercent).filter(s=>s!==null);if(d.length){const s=d.reduce((p,c)=>p+c,0)/d.length;o.appendChild(se(`${s.toFixed(1)}%`,"Mean per-wafer yield"))}if(o.finish(),i.appendChild(o),t.length){const s=t.reduce((c,r)=>c+r.stats.analyzedDies,0),p=t.reduce((c,r)=>c+r.stats.excludedDies,0);(s||p)&&i.appendChild(Pe("Dies analysed",p?`${s.toLocaleString()} (${p.toLocaleString()} excluded)`:s.toLocaleString()))}return i}export function buildPerWaferYieldSection(e,t,i,n,o){const d=e.perWafer.map(f=>({waferIndex:f.waferIndex,label:me(t[f.waferIndex],f.waferIndex).replace(/\s*·\s*\d+(\.\d+)?%$/,""),yieldPct:f.summary.stats.yieldPercent})).filter(f=>f.yieldPct!==null);if(!d.length)return null;const s=Math.min(...d.map(f=>f.yieldPct)),p=Math.max(...d.map(f=>f.yieldPct)),c=s===p?"":` (${s.toFixed(1)}\u2013${p.toFixed(1)}%)`,r=[...d.map(f=>f.yieldPct)].sort((f,w)=>f-w),a=mt(r),b=ie(r,.25),u=ie(r,.75),S=d.length>=5?b-1.5*(u-b):-1/0,N=pe(n),I=f=>{const w=N.waferSort==="yield"?[...d].sort((m,x)=>m.yieldPct-x.yieldPct):d;for(const{waferIndex:m,label:x,yieldPct:C}of w){const k=C<S?`${x} \xB7 low outlier`:x,T=xe(k,C,void 0,void 0,a),A=o?.(m);A?.total&&H(T,A),h(T,m,x,C,A),f.appendChild(T)}},P=` \xB7 median ${a.toFixed(1)}%`,{outer:R}=X("Wafer Yield"+c+P,!0,void 0,{stateKey:"waferYield",panel:n,render:I,control:n?f=>be([["slot","Slot"],["yield","Yield"]],N.waferSort,w=>{N.waferSort=w,f()},n.ownerDocument,!0):void 0});return R;function H(f,w){const m=w.unusual?"unusual":w.notable?"notable":"info",x=l("span",{marginLeft:y.sm,flexShrink:"0",background:de(m),color:"#fff",borderRadius:_.container,padding:"0 5px",fontSize:E.body,fontWeight:"600"},`${w.total}`);x.setAttribute("aria-hidden","true"),oe(x,`${w.total} finding${w.total===1?"":"s"}`+(w.unusual?`, ${w.unusual} unusual`:"")+(w.notable?`, ${w.notable} notable`:"")),f.firstElementChild?.firstElementChild?.appendChild(x)}function h(f,w,m,x,C){i&&(f.style.cursor="pointer",f.style.borderRadius="4px",f.style.padding="2px 3px",f.style.marginLeft="-3px",f.style.marginRight="-3px",f.setAttribute("role","button"),f.setAttribute("aria-label",`${m}, ${x.toFixed(1)}% yield`+(C?.total?`, ${C.total} finding${C.total===1?"":"s"}${C.unusual?`, ${C.unusual} unusual`:""}`:"")+" \u2014 open wafer"),f.tabIndex=0,f.addEventListener("mouseenter",()=>{f.style.background=L.bgHover}),f.addEventListener("mouseleave",()=>{f.style.background=""}),f.addEventListener("focus",()=>{f.style.background=L.bgHover}),f.addEventListener("blur",()=>{f.style.background=""}),f.addEventListener("click",()=>i(w)),f.addEventListener("keydown",v=>{(v.key==="Enter"||v.key===" ")&&(v.preventDefault(),i(w))}))}}function wt(e){const t=[...e].sort((o,d)=>o-d),i=e.reduce((o,d)=>o+d,0)/e.length,n=e.reduce((o,d)=>o+(d-i)**2,0)/e.length;return{min:t[0],max:t[t.length-1],mean:i,count:e.length,stddev:Math.sqrt(n),median:ie(t,.5),q1:ie(t,.25),q3:ie(t,.75)}}function Ye(e,t){if(!e)return[];const i=e.waferMetadata??(e.perWaferMetadata?we(e.perWaferMetadata.map(n=>({metadata:n}))):void 0);return!i||!Object.keys(i).length?[]:ot({waferMetadata:i,waferKeys:"identity",waferPlacement:"csv",reservedLabels:t}).columns}function Oe(e){return e?.populationLabel?[{key:"population",label:"Population",scope:"wafer",constant:e.populationLabel,get:()=>e.populationLabel,csvOnly:!0}]:[]}export function buildTestSection(e,t,i,n,o,d,s,p,c="full"){const r=e.filter(g=>!g.partial&&!g.edgeExcluded),a=new Map((n?.perTestStats??[]).map(g=>[g.testNumber,g])),b=new Map((n?.testSpecYield??[]).map(g=>[g.testNumber,g]));let u;if(t?.length?u=t.filter(Ge).map(g=>({testNumber:g.testNumber,name:g.name,unit:g.unit,limitLow:g.limitLow,limitHigh:g.limitHigh})):u=dt(r).map(F=>({testNumber:F,name:`Test ${F}`})),!u.length)return null;const S=u.filter(g=>r.some(F=>{const O=F.testValues?.[g.testNumber];return O!==void 0&&isFinite(O)}));if(!S.length)return null;const N=S.some(g=>g.limitLow!==void 0||g.limitHigh!==void 0),I=[];for(const g of S){const F=a.get(g.testNumber),O=F&&F.stddev!==void 0&&F.median!==void 0&&F.q1!==void 0&&F.q3!==void 0;let B;if(O){const $=F;B={testNumber:g.testNumber,min:$.min,max:$.max,mean:$.mean,count:$.count,stddev:$.stddev,median:$.median,q1:$.q1,q3:$.q3}}else{const $=r.map(D=>D.testValues?.[g.testNumber]).filter(D=>D!==void 0&&isFinite(D));if(!$.length)continue;B={testNumber:g.testNumber,...wt($)}}let M=null,z=0;if(g.limitLow!==void 0||g.limitHigh!==void 0){const $=b.get(g.testNumber);if($)({yieldPercent:M,totalDies:z}=$);else{const D=r.map(j=>j.testValues?.[g.testNumber]).filter(j=>j!==void 0&&isFinite(j)),Z=D.filter(j=>g.limitLow!==void 0&&j<g.limitLow||g.limitHigh!==void 0&&j>g.limitHigh).length;z=D.length,M=D.length>0?(D.length-Z)/D.length*100:null}}I.push({entry:g,stats:B,specYieldPct:M,specN:z})}if(!I.length)return null;const P=new Map;if(s?.length&&t?.length)for(const g of ct(s,t))g.hasSpec&&P.set(g.testNumber,g.ppk);const R=P.size>0,h=new Set(I.map(g=>g.stats.count)).size===1?I[0].stats.count:null,f=l("div"),w=l("div",{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:y.sm}),m=h!==null?` \xB7 N=${h.toLocaleString()}`:"",x=d?.populationLabel?`Test Values (${I.length}) \u2014 ${d.populationLabel}${m}`:`Test Values (${I.length})${m}`,C=J(x);C.style.marginBottom="0",w.appendChild(C);const v=document.createElement("button");v.type="button",v.textContent="Test values CSV",Object.assign(v.style,{...le("outlined")}),q(v),v.addEventListener("click",()=>{const g=["Test","Unit","N","Min","Q1","Median","Mean","Q3","Max","StdDev"];R&&g.push("Ppk");const F=I.some($=>$.specYieldPct!==null&&$.specN!==$.stats.count);N&&(g.push("LSL","USL","Spec Yield %"),F&&g.push("Spec Yield N"));const O=[...Ye(d,g),...Oe(d)],M=[[...O.map($=>$.label),...g].map(ce).join(",")],z=$=>ke($,void 0,"engineering");for(const{entry:$,stats:D,specYieldPct:Z,specN:j}of I){const ae=[...O.map(te=>te.constant??""),$.name,$.unit??"",String(D.count),z(D.min),z(D.q1),z(D.median),z(D.mean),z(D.q3),z(D.max),z(D.stddev)];if(R){const te=P.get($.testNumber);ae.push(te==null?"":te.toFixed(3))}N&&(ae.push($.limitLow!==void 0?z($.limitLow):"",$.limitHigh!==void 0?z($.limitHigh):"",Z!==null?Z.toFixed(1):""),F&&ae.push($.limitLow!==void 0||$.limitHigh!==void 0?String(j):"")),M.push(ae.map(ce).join(","))}De(M.join(`
|
|
2
|
-
`),"test-values.csv","text/csv",
|
|
3
|
-
`),"functional-tests.csv","text/csv",n)}),b.appendChild(N),a.appendChild(b);const I=l("table",{width:"100%",borderCollapse:"collapse",fontSize:E.body}),P=document.createElement("thead"),R=document.createElement("tr"),H=c===null?["Test","N","Pass","Fail","Pass rate"]:["Test","Pass","Fail","Pass rate"];for(const m of H)R.appendChild(l("th",{textAlign:m==="Test"?"left":"right",fontWeight:"700",fontSize:E.body,letterSpacing:re,textTransform:"uppercase",color:Y,padding:"3px 8px 5px",borderBottom:`1px solid ${L.menuBorder}`,whiteSpace:"nowrap"},m));P.appendChild(R),I.appendChild(P);const h=document.createElement("tbody");for(const m of s){const x=document.createElement("tr"),C=(v,k="right")=>{x.appendChild(l("td",{textAlign:k,padding:`${y.xs} ${y.md}`,borderBottom:`1px solid ${L.menuBorder}`,color:K,whiteSpace:"nowrap"},v))};C(m.label,"left"),c===null&&C(String(m.totalDies)),C(String(m.passDies)),C(String(m.failDies)),C(m.passRatePercent!==null?`${m.passRatePercent.toFixed(1)}%`:"\u2014"),h.appendChild(x)}I.appendChild(h);const f=l("div",{overflowX:"auto"});if(f.appendChild(I),!d)return a.appendChild(f),a;b.remove();const{outer:w}=X(u,!0,void 0,{stateKey:"functionalTests",panel:d,render:m=>m.appendChild(f),control:()=>N});return w}export function buildLotFunctionalSection(e,t,i,n,o){const d=i?.length?{perWaferMetadata:i.map(p=>p.wafer??{}),populationLabel:`${i.length} wafer${i.length===1?"":"s"} pooled`}:void 0,s=ut(i);return s?buildFunctionalTestSection(e,t,s,n,d,o):buildFunctionalTestSection(e,t,void 0,n,d,o)}const ee={unusual:0,notable:1,info:2};function ye(e){return l("span",{display:"inline-block",width:"7px",height:"7px",borderRadius:_.pill,background:de(e),flexShrink:"0"})}function _e(e,t){let i=e.summary;return t&&(i.startsWith(`${t} has `)?i=i.slice(t.length+5):i.startsWith(`${t} `)&&(i=i.slice(t.length+1))),i=ne(i),i.length?i[0].toUpperCase()+i.slice(1):i}export function buildFindingsSection(e,t,i,n,o=!1){if(!e.length)return null;const d=e.some(h=>h.severity==="unusual"||h.severity==="notable"),s=d?e.filter(h=>h.severity!=="info").length.toString():void 0,{outer:p,content:c}=o?(()=>{const h=l("div");return{outer:h,content:h}})():X(`Findings (${e.length})`,d,s);function r(h){return h.reduce((f,w)=>ee[w.severity]<ee[f]?w.severity:f,"info")}function a(h){const f=new Map;for(const m of h){const x=`${m.comparison.family}\0${m.comparison.left}`,C=f.get(x)??[];C.push(m),f.set(x,C)}const w=[...f.entries()].map(([m,x])=>{const C=[...x].sort((v,k)=>ee[v.severity]-ee[k.severity]);return{key:m,findings:C,worst:r(C)}});return w.sort((m,x)=>ee[m.worst]-ee[x.worst]),w}function b(h,f){const m={ring:"Ring",quadrant:"Quadrant",sector:"Sector","reticle-position":"Reticle","test-site":"Test site",cluster:"Cluster","edge-arc":"Edge arc",wafer:"Wafer"}[h]??h;return f.toLowerCase().startsWith(m.toLowerCase())?f:`${m}: ${f}`}const u=e.filter(h=>h.comparison.family==="spatial-pattern"),S=new Set([...u.flatMap(h=>h.relatedIds??[]),...e.flatMap(h=>h.absorbedIds??[])]),N=e.filter(h=>h.comparison.family!=="spatial-pattern"&&!S.has(h.id)),I=a(N);function P(h,f=!1,w){const m=n===h.id,x=document.createElement("button");return x.type="button",x.dataset.wmapFinding=h.id,x.textContent=_e(h,w),oe(x,h.summary),x.setAttribute("aria-current",m?"true":"false"),Object.assign(x.style,{border:`1px solid ${L.menuBorder}`,borderLeft:`3px solid ${de(h.severity)}`,background:m?L.bgActive:L.menuBg,borderRadius:_.container,padding:f?"6px 10px":"8px 10px",textAlign:"left",fontSize:f?"10px":"11px",fontWeight:m?"600":"400",color:L.text,cursor:"pointer",width:"100%",marginBottom:y.xs}),q(x,"bare"),x.addEventListener("click",()=>i(h,x)),x}const R=ne(tt(e)??"");if(R){const h=l("div",{background:L.bgActive,borderRadius:_.container,padding:`${y.md} ${y.lg}`,marginBottom:y.md,display:"flex",gap:y.md,alignItems:"flex-start"}),f=l("span",{flex:"1",fontSize:E.body,lineHeight:Q.base,color:L.text},R);h.appendChild(f);const w=l("button",{flexShrink:"0",border:"none",background:"none",fontSize:E.body,color:L.icon,cursor:"pointer",padding:"0",lineHeight:Q.base,whiteSpace:"nowrap"},"Detail \u25B8");w.type="button",q(w,"bare"),w.addEventListener("click",()=>{const m=Fe({title:"Findings Summary",onClose:()=>{},anchor:w}),x=l("p",{fontSize:"16px",lineHeight:Q.base,color:L.text,padding:`${y.xxl} ${y.xxxl} ${y.xxl}`,margin:"0",borderBottom:`1px solid ${L.menuBorder}`,flexShrink:"0"},R);m.contentWrap.appendChild(x);const C=l("div",{overflowY:"auto",padding:`${y.xxl} ${y.xxxl}`,flex:"1"}),v=(k,T)=>{const A=l("div",{display:"flex",alignItems:"center",gap:"7px",fontSize:E.sub,fontWeight:"600",color:K,marginTop:y.lg,marginBottom:y.xs});return A.appendChild(ye(k)),A.appendChild(l("span",{},T)),A};for(const k of u){C.appendChild(v(k.severity,k.comparison.left)),C.appendChild(l("div",{fontSize:E.body,color:L.text,padding:"4px 0 4px 15px",marginBottom:y.xxs},ne(k.summary)));const T=e.filter(A=>k.relatedIds?.includes(A.id));for(const A of T)C.appendChild(l("div",{fontSize:E.body,color:Y,padding:"2px 0 2px 23px",marginBottom:y.xxs},ne(A.summary)))}for(const k of I){const[T,A]=k.key.split("\0");C.appendChild(v(k.worst,b(T,A)));for(const W of k.findings)C.appendChild(l("div",{fontSize:E.body,color:L.text,padding:"4px 0 4px 15px",marginBottom:y.xxs},_e(W,A)))}m.contentWrap.appendChild(C),Object.assign(m.contentWrap.style,{flexDirection:"column",overflow:"hidden"})}),h.appendChild(w),c.appendChild(h)}let H=!0;for(const h of u){H||c.appendChild(l("div",{height:"1px",background:L.separator,margin:"4px 0"})),H=!1;const f=e.filter(v=>h.relatedIds?.includes(v.id)),w=f.length>0,m=l("div",{position:"relative",marginBottom:w?"2px":"4px"}),x=n===h.id,C=document.createElement("button");if(C.type="button",C.dataset.wmapFinding=h.id,Object.assign(C.style,{border:`1px solid ${L.menuBorder}`,borderLeft:`3px solid ${de(h.severity)}`,background:x?L.bgActive:L.menuBg,borderRadius:_.container,padding:"8px 32px 8px 10px",textAlign:"left",fontSize:E.body,fontWeight:x?"600":"500",color:L.text,cursor:"pointer",width:"100%"}),C.textContent=ne(h.summary),oe(C,h.summary),C.setAttribute("aria-current",x?"true":"false"),q(C,"bare"),C.addEventListener("click",()=>i(h,C)),m.appendChild(C),w){const v=l("div",{display:"none",paddingLeft:"12px",marginBottom:y.xs});for(const A of f)v.appendChild(P(A,!0));m.appendChild(v);let k=!1;const T=l("button",{position:"absolute",top:"50%",right:"8px",transform:"translateY(-50%)",border:"none",background:"none",fontSize:E.body,color:L.icon,cursor:"pointer",padding:`${y.xxs} ${y.xs}`,lineHeight:Q.none},"\u25B8");q(T,"bare"),T.type="button",oe(T),T.setAttribute("aria-label","Show supporting findings"),T.setAttribute("aria-expanded","false"),T.addEventListener("click",A=>{A.stopPropagation(),k=!k,v.style.display=k?"block":"none",T.textContent=k?"\u25BE":"\u25B8";const W=k?"Hide supporting findings":"Show supporting findings";T.setAttribute("aria-label",W),T.setAttribute("aria-expanded",String(k))}),m.appendChild(T)}c.appendChild(m)}for(const h of I){H||c.appendChild(l("div",{height:"1px",background:L.separator,margin:"4px 0"})),H=!1;const[f,w]=h.key.split("\0"),m=l("div",{display:"flex",alignItems:"center",gap:y.sm,fontSize:E.body,fontWeight:"600",color:K,margin:"2px 0 4px"});m.appendChild(ye(h.worst)),m.appendChild(l("span",{},b(f,w))),c.appendChild(m);for(const x of h.findings)c.appendChild(P(x,!1,w))}return p}const St=[{value:"",label:"All kinds"},{value:"yield",label:"Yield"},{value:"hardBin",label:"Hard bin"},{value:"softBin",label:"Soft bin"},{value:"test",label:"Test value"},{value:"functionalTest",label:"Functional test"},{value:"spatialPattern",label:"Spatial pattern"}],vt=[{value:"",label:"All regions"},{value:"ring",label:"Ring"},{value:"quadrant",label:"Quadrant"},{value:"reticle-position",label:"Reticle position"},{value:"test-site",label:"Test site"},{value:"wafer",label:"Wafer"},{value:"sector",label:"Sector"},{value:"cluster",label:"Cluster"},{value:"edge-arc",label:"Edge arc"},{value:"spatial-pattern",label:"Spatial pattern"}],$t=["unusual","notable","info"],kt={unusual:"Unusual",notable:"Notable",info:"Info"};function Bt(e,t,i){const n=l("div",{display:"flex",flexWrap:"wrap",alignItems:"center",gap:y.lg,marginBottom:y.lg,paddingBottom:"10px",borderBottom:`1px solid ${L.separator}`}),o={unusual:0,notable:0,info:0};for(const r of e)o[r.severity]++;const d=$t.filter(r=>o[r]>0),s=new Set(t.severity===void 0?d:Array.isArray(t.severity)?t.severity:[t.severity]),p=l("div",{display:"flex",gap:y.xs,flexWrap:"wrap"});for(const r of d){const a=document.createElement("button");a.type="button";const b=()=>{const u=s.has(r);a.setAttribute("aria-pressed",u?"true":"false"),Object.assign(a.style,{display:"inline-flex",alignItems:"center",gap:"5px",border:`1px solid ${L.menuBorder}`,borderRadius:_.pill,background:u?L.bgActive:"none",opacity:u?"1":"0.5",color:L.text,fontSize:E.body,padding:`${y.xxs} ${y.md}`,cursor:"pointer"}),a.dataset.on=u?"true":"false"};a.appendChild(ye(r)),a.appendChild(l("span",{},`${kt[r]} ${o[r]}`)),oe(a,()=>s.has(r)?"Click to hide these findings":"Click to show these findings"),b(),q(a,"bare"),a.addEventListener("click",()=>{s.has(r)?s.delete(r):s.add(r),t.severity=s.size===d.length?void 0:[...s],i()}),p.appendChild(a)}n.appendChild(p);const c=t.kind!==void 0||t.family!==void 0;return(e.length>=Lt||c)&&(n.appendChild(Be("Kind:",St,t.kind??"",r=>{t.kind=r||void 0,i()},{maxWidth:"130px"})),n.appendChild(Be("Region:",vt,t.family??"",r=>{t.family=r||void 0,i()},{maxWidth:"150px"}))),n}const Lt=8;function Nt(e,t){const i=l("div",{display:"flex",flexDirection:"column",gap:y.xs,padding:y.md,marginBottom:y.md,background:L.bgHover,borderRadius:_.control},void 0,t);if(i.appendChild(l("div",{fontSize:E.body,color:L.value},e.message,t)),e.detail&&i.appendChild(l("div",{fontSize:E.meta,color:Y},e.detail,t)),e.actionLabel&&e.onAction){const n=l("button",le("outlined"),e.actionLabel,t);n.type="button",n.style.alignSelf="flex-start",n.style.marginTop=y.xs,q(n),n.addEventListener("click",e.onAction),i.appendChild(n)}return i}export function buildFindingsSectionWithFilter(e,t,i,n,o,d,s){if(!e.findings.length&&!s)return null;const p=e.findings.some(N=>N.severity==="unusual"||N.severity==="notable"),c=p?e.findings.filter(N=>N.severity!=="info").length.toString():void 0,r=d?.ownerDocument??document,{outer:a,content:b}=X(`Findings (${e.findings.length})`,p||!!s,c,{stateKey:"findings",panel:d});if(s&&b.appendChild(Nt(s,r)),!e.findings.length)return a;b.appendChild(Bt(e.findings,n,o));const u=nt(e,n);if(!u.length)return b.appendChild(l("div",{color:Y,fontSize:E.body,textAlign:"center",padding:`${y.xxl} ${y.md}`},"No findings match the current filter.")),a;const S=buildFindingsSection(u,e,t,i,!0);return S&&b.appendChild(S),a}export function buildLotTestSection(e,t,i,n,o,d,s,p="full"){const c=n?.length?{perWaferMetadata:n.map(a=>a.wafer??{}),populationLabel:`${n.length} wafer${n.length===1?"":"s"} pooled`}:void 0;let r;if(n?.length&&n.every(a=>a.stats.perTestStats!==void 0)){const a=new Map;for(const b of n)for(const u of b.stats.perTestStats??[]){const S=a.get(u.testNumber);S?(S.n+=u.count,S.sum+=u.mean*u.count,S.min=Math.min(S.min,u.min),S.max=Math.max(S.max,u.max)):a.set(u.testNumber,{n:u.count,sum:u.mean*u.count,min:u.min,max:u.max})}r={perTestStats:[...a.entries()].map(([b,u])=>({testNumber:b,count:u.n,min:u.min,max:u.max,mean:u.sum/u.n}))}}if(n?.length&&n.every(a=>a.stats.testSpecYield!==void 0)){const a=new Map;for(const b of n)for(const u of b.stats.testSpecYield??[]){const S=a.get(u.testNumber);S?(S.passDies+=u.passDies,S.totalDies+=u.totalDies):a.set(u.testNumber,{passDies:u.passDies,totalDies:u.totalDies})}r={...r,testSpecYield:[...a.entries()].map(([b,u])=>({testNumber:b,totalDies:u.totalDies,yieldPercent:u.totalDies>0?u.passDies/u.totalDies*100:null}))}}return buildTestSection(e,t,i,r,o,c,d,s,p)}export function createSummaryPanelEl(e,t,i=document){const n=e==="top"||e==="bottom",o=l("div",{background:gt,color:L.text,fontVariantNumeric:"tabular-nums",border:Re,borderRadius:_.container,padding:y.xl,overflowY:"auto",overflowX:n?"auto":"hidden",flexShrink:"0",boxSizing:"border-box",fontFamily:E.family,fontSize:E.sub,boxShadow:Le.panel},void 0,i);return e==="right"&&(o.style.marginRight=t),e==="left"&&(o.style.marginLeft=t),e==="bottom"&&(o.style.marginBottom=t),n?(o.style.height="180px",o.style.width="100%"):(o.style.width="300px",o.style.maxHeight="100%"),o}export function wrapWithSummaryPanel(e,t,i){const n=i==="top"||i==="bottom",o=l("div",{display:"flex",flexDirection:n?"column":"row",gap:y.md,width:"100%",height:"100%",flex:"1 1 0",minHeight:"0",boxSizing:"border-box",alignItems:n?"flex-start":"stretch"});return e.style.flex="1 1 0",e.style.minWidth="0",e.style.minHeight="0",i==="right"||i==="bottom"?(o.appendChild(e),o.appendChild(t)):(o.appendChild(t),o.appendChild(e)),o}function je(e){return l("div",{fontSize:E.heading,fontWeight:"600",color:K,marginBottom:y.lg},e)}function fe(e,t){const i=l("button",le("outlined"),e);return i.type="button",q(i),i.addEventListener("click",t),i}function qe(...e){const t=e.filter(n=>!!n);if(!t.length)return null;const i=l("div",{display:"flex",flexWrap:"wrap",gap:y.sm,marginBottom:y.lg});for(const n of t)i.appendChild(n);return i}function Ve(e,t,i,n,o,d,s,p,c,r,a){const b=e.ownerDocument,u=Fe({title:"Die list",onClose:()=>{},anchor:e,ownerDocument:b});u.contentWrap.style.padding="14px 16px";const S=ft(t,i,{...s,title:n,onSaveText:p,waferMetadata:o,metadataFields:d,extraColumn:c,getWafer:r,ringCount:a,ownerDocument:b});S&&u.contentWrap.appendChild(S)}export function renderWaferSummaryContent(e,t){const i=e.scrollTop;e.innerHTML="";const{wafer:n,dies:o,yieldSummary:d,dataCoverage:s,hbinDefs:p,sbinDefs:c,testDefs:r,statsSummary:a,passBins:b=[1],ringCount:u=4,binColors:S,plotMode:N,fallbackFormat:I,onFindingClick:P,activeFindingId:R=null,findingsFilter:H,onFindingsFilterChange:h,findingsNotice:f,onSaveText:w,metadataFields:m,dieListOptions:x,metadataShownElsewhere:C}=t;e.appendChild(je("Wafer Summary"));const v=t.warnings??$e({statsSummary:a});v.length&&e.appendChild(ge(v,e.ownerDocument));const k=d&&s?fe("Summary report",()=>{Ee(Je({wafer:n,dies:o,yieldSummary:d,dataCoverage:s,hbinDefs:p,sbinDefs:c,testDefs:r,statsSummary:a,passBins:b,ringCount:u}),{anchor:e})}):null,T=(x?.enabled??!0)&&o.length?fe("View die list",()=>{Ve(e,o,r,`Die list \u2014 ${o.length} dies`,n.metadata,m,x,w,void 0,()=>n,u)}):null,A=qe(k,T);A&&e.appendChild(A);const W=[],V=a?.stats.isLotStack?a.stats:void 0,G=V?.lotSize!==void 0?{lotSize:V.lotSize,aggrMethod:lt(V.aggregationMethod)}:void 0;C||W.push(buildMetadataInfoSection([{metadata:n.metadata??void 0}],G)),d&&s&&W.push(buildYieldSection(d,s,b)),a&&P&&H&&h&&W.push(buildFindingsSectionWithFilter(a,P,R,H,h,e,f)),W.push(buildBinBreakdownSection({dies:o,hbinDefs:p,sbinDefs:c,binColors:S,hardCounts:a?.stats.hardBinCounts,softCounts:a?.stats.softBinCounts,plotMode:N,passBins:b,panel:e})),W.push(buildRegionYieldPanelSection({diesByWafer:[o],allWafers:[n],ringCount:u,passBins:b,panel:e}));const U=n.metadata?{waferMetadata:n.metadata}:void 0;W.push(buildTestSection(o,r,I,a?.stats,w,U,[{dies:o}],e,"compact")),W.push(buildFunctionalTestSection(o,r,a?.stats.functionalYield,w,U,e));let g=!0;for(const F of W)F&&(g||e.appendChild(Ie()),g=!1,e.appendChild(F));e.appendChild(l("div",{height:"12px",flexShrink:"0"})),e.scrollTop=i}export function renderLotSummaryContent(e,t){const i=e.scrollTop;e.innerHTML="";const{lotSummary:n,items:o,hbinDefs:d,sbinDefs:s,testDefs:p,passBins:c=[1],ringCount:r=4,binColors:a,plotMode:b,fallbackFormat:u,onFindingClick:S,activeFindingId:N=null,onWaferClick:I,findingsFilter:P,onFindingsFilterChange:R,findingsNotice:H,onSaveText:h,dieListOptions:f,findingsFor:w}=t;e.appendChild(je(`Summary \u2014 ${rt(ve(n.perWafer.map(B=>B.summary.wafer)))}`));const m=t.warnings??$e({lotStatsSummary:n});m.length&&e.appendChild(ge(m,e.ownerDocument));const x=fe("Summary report",()=>{Ee(et({items:o.map((B,M)=>({label:me(B,M),wafer:B?.wafer,dies:B?.dies,passBins:[...he(B,c)],statsSummary:B?.statsSummary})),hbinDefs:d,sbinDefs:s,testDefs:p,passBins:c,ringCount:r}),{anchor:e})}),C=[],v=[],k=[],T=[],A=[],W=new WeakMap,V=new WeakMap;for(let B=0;B<o.length;B++){const M=o[B];if(!M){v.push([]);continue}M.wafer&&(C.push(M.wafer),T.push(M.dies??[]),A.push(he(M,c)));const z=M.dies??[],$=me(M,B);for(const D of z)W.set(D,$),M.wafer&&V.set(D,M.wafer);v.push(z),k.push(...z)}const G=f?.enabled??!0?fe("View die list",()=>{k.length&&Ve(e,k,p,`Die list \u2014 ${k.length} dies across ${o.length} wafer${o.length===1?"":"s"}`,we(o.filter(B=>!!B).map(B=>({metadata:B.wafer?.metadata}))),o.find(B=>B?.metadataFields?.length)?.metadataFields,f,h,{label:"Wafer",get:B=>W.get(B)},B=>V.get(B),r)}):null,U=qe(x,G);U&&e.appendChild(U);const g=o.map(B=>B?.statsSummary).filter(B=>!!B),F=[buildLotOverviewSection(n,g)];S&&P&&R&&F.push(buildFindingsSectionWithFilter(n,S,N,P,R,e,H)),F.push(buildPerWaferYieldSection(n,o,I,e,w),buildBinBreakdownSection({dies:k,hbinDefs:d,sbinDefs:s,plotMode:b,passBins:c,panel:e,binColors:a??st(o.flatMap(B=>B?[{dies:B.dies??[],passBins:he(B,c)}]:[]),{hbinDefs:d,sbinDefs:s}).colors}),buildRegionYieldPanelSection({diesByWafer:T,allWafers:C,ringCount:r,passBins:B=>A[B],panel:e}),p?.length?buildLotTestSection(k,p,u,g,h,v.map(B=>({dies:B})),e,"compact"):null,p?.length?buildLotFunctionalSection(k,p,g,h,e):null);let O=!0;for(const B of F)B&&(O||e.appendChild(Ie()),O=!1,e.appendChild(B));e.appendChild(l("div",{height:"12px",flexShrink:"0"})),e.scrollTop=i}
|
|
1
|
+
import{waferDisplayLabel as ye}from"../core/waferLabel.js";import{itemPassBins as Ce,passBinsLabel as Je}from"../core/passBins.js";import{isParametricTest as et}from"../renderer/buildWaferMap.js";import{buildRingRegions as tt,buildQuadrantRegions as nt,buildRegionYieldData as ot}from"../stats/regions.js";import{computeFunctionalYield as it}from"../stats/analyzeWaferMap.js";import{renderWaferReportHtml as st,renderLotReportHtml as at}from"../stats/renderSummaryReport.js";import{buildFindingsNarrative as rt}from"../stats/findingsNarrative.js";import{filterFindings as lt}from"../stats/filterFindings.js";import{buildFacetTable as dt,prettyKey as ke}from"../stats/facets.js";import{commonMetadata as Le}from"../stats/facets.js";import{resolveMetadataColumns as ct}from"../stats/metadataColumns.js";import{resolveBinColors as Be,resolveBinColorsByWafer as pt}from"../renderer/binColors.js";import{NO_DATA_FILL as ut}from"../renderer/colorMap.js";import{describeWaferPopulation as Ne,populationLabel as ft}from"../stats/population.js";import{buildWarningsBanner as Se,collectWarnings as Te}from"./warnings.js";export{Se as buildWarningsBanner};import{fmt as Ee,fmtAggregationMethod as mt,plainBinTerms as le}from"../renderer/fmt.js";import{getUniqueTestNumbers as gt}from"../renderer/buildView.js";import{describeSorted as ht,quantile as Fe}from"../stats/math.js";import{pooledTestStatsSteps as bt}from"../stats/capability.js";import{sortBinsForDisplay as xt}from"../stats/binPareto.js";import{poolFunctionalYield as yt}from"../stats/testPassRate.js";import{makeLabeledSelect as De,makeSegmented as we}from"./charts/chartShell.js";import{SHADOW as Re,MOTION as Me,LEADING as oe,TRACKING as pe,wireControlHover as G,controlStyle as ue,SPACE as y,RADIUS as q,FONT as T,CLR as $,sevColor as fe,openModal as Ie,openReportModal as We,saveTextFile as Ae,wireTooltip as de}from"./toolbar.js";import{buildDieListSection as Ct}from"./dieList.js";export{csvField}from"../core/utils.js";import{csvField as me,drain as ge,maxOf as St,medianOfSorted as wt,minOf as vt}from"../core/utils.js";import{metadataDisplayValue as $t}from"../core/metadata.js";const kt=$.panelBg,Pe=`1px solid ${$.menuBorder}`,Lt="12px",_=$.label,ee=$.value,ze="10px";function l(e,t,o,n=document){const i=n.createElement(e);return t&&Object.assign(i.style,t),o!==void 0&&(i.textContent=o),i}function ae(e){return l("div",{fontSize:ze,fontWeight:"700",letterSpacing:pe,textTransform:"uppercase",color:_,marginBottom:y.sm},e)}const He=new WeakMap,Oe=["regionYield","testValues","functionalTests"];function he(e){if(!e)return{collapsed:new Set(Oe),regionMode:"ring",waferSort:"slot"};let t=He.get(e);return t||(t={collapsed:new Set(Oe),regionMode:"ring",waferSort:"slot"},He.set(e,t)),t}function ie(e,t=!0,o,n){const i=l("div"),c=he(n?.panel);n?.stateKey&&n.panel&&(t=!c.collapsed.has(n.stateKey));const s=document.createElement("button");s.type="button",Object.assign(s.style,{display:"flex",alignItems:"center",gap:y.xs,width:"100%",background:"none",border:"none",cursor:"pointer",padding:"0 0 6px",textAlign:"left"});const m=l("span",{fontSize:T.meta,color:_,transition:`transform ${Me.base}`,transform:t?"rotate(90deg)":"rotate(0deg)",display:"inline-block",lineHeight:oe.none,marginRight:"1px"},"\u25B6"),d=l("span",{fontSize:ze,fontWeight:"700",letterSpacing:pe,textTransform:"uppercase",color:_,flex:"1"},e);if(G(s,"bare"),s.setAttribute("aria-expanded",t?"true":"false"),s.appendChild(m),s.appendChild(d),o){const h=l("span",{fontSize:T.meta,fontWeight:"700",background:$.warnBg,color:$.warnText,borderRadius:q.pill,padding:"1px 5px"},o);s.appendChild(h)}const r=l("div");r.style.display=t?"block":"none";let a=t;if(s.addEventListener("click",()=>{a=!a,r.style.display=a?"block":"none",m.style.transform=a?"rotate(90deg)":"rotate(0deg)",s.setAttribute("aria-expanded",a?"true":"false"),n?.stateKey&&n.panel&&(a?c.collapsed.delete(n.stateKey):c.collapsed.add(n.stateKey))}),n?.control){const h=l("div",{display:"flex",alignItems:"center",gap:y.sm});s.style.width="auto",s.style.flex="1",h.appendChild(s);const u=()=>{r.innerHTML="",n.render?.(r)},w=n.control(u);w&&(w.style.marginBottom="6px",w.addEventListener("click",L=>L.stopPropagation()),h.appendChild(w)),i.appendChild(h)}else i.appendChild(s);return i.appendChild(r),n?.render?.(r),{outer:i,content:r}}function Ye(){return l("div",{height:"1px",background:$.separator,margin:`${Lt} 0`,flexShrink:"0"})}function ve(e,t,o=$.barFill,n,i){const c=l("div",{marginBottom:"5px"}),s=l("div",{display:"flex",justifyContent:"space-between",fontSize:T.body,color:ee,marginBottom:y.xxs}),m=l("span",{color:_},e),d=l("span",{fontWeight:"600"},`${t.toFixed(1)}%`);s.appendChild(m),s.appendChild(d);const r=n!==void 0?n:Math.min(100,Math.max(0,t)),a=o,h=l("div",{position:"relative",height:"9px",background:$.bgActive,borderRadius:q.control,overflow:"hidden"}),u=l("div",{height:"100%",width:`${r}%`,background:a,borderRadius:q.control,transition:`width ${Me.base}`});if(h.appendChild(u),i!==void 0){const w=l("div",{position:"absolute",top:"0",bottom:"0",left:`${i}%`,width:"2px",marginLeft:"-1px",background:$.value,opacity:"0.8"});h.appendChild(w)}return c.appendChild(s),c.appendChild(h),c}function _e(){const e=l("div",{display:"flex",gap:y.sm,marginBottom:y.md});return e.finish=()=>{const t=e.lastElementChild;t&&Object.assign(t.style,{borderRight:"none",paddingRight:"0"})},e}function ce(e,t,o){const n=l("div",{padding:`${y.xxs} ${y.md} ${y.xxs} 0`,borderRight:Pe,textAlign:"center",flex:"1"}),i=l("div",{fontSize:T.heading,fontWeight:"700",color:ee,lineHeight:oe.tight},e),c=l("div",{fontSize:T.body,color:_,marginTop:y.xxs},t);return n.appendChild(i),n.appendChild(c),o&&n.appendChild(l("div",{fontSize:T.body,color:_,opacity:"0.85"},o)),n}function je(e,t){const o=l("div",{display:"flex",justifyContent:"space-between",fontSize:T.body,gap:y.md,marginBottom:"3px"}),n=l("span",{color:_,flexShrink:"0"},e),i=l("span",{color:ee,textAlign:"right",fontWeight:"500",wordBreak:"break-all"},t);return o.appendChild(n),o.appendChild(i),o}function Bt(e,t){const o=l("div",{display:"flex",fontSize:T.body,gap:y.sm,marginBottom:"3px"}),n=l("span",{color:_,flexShrink:"0"},`${e}:`),i=l("span",{color:ee,fontWeight:"500",wordBreak:"break-all"},t);return o.appendChild(n),o.appendChild(i),o}export function metadataEntries(e){const t=[];for(const[o,n]of Object.entries(e)){const i=$t(n);i!==void 0&&t.push([o,i])}return t}const Nt=["lot","product","testprogram","split"],be=e=>{const t=Nt.indexOf(e.toLowerCase().replace(/[^a-z]/g,""));return t===-1?Number.MAX_SAFE_INTEGER:t};export function buildFacetSummaryChips(e,t=3){if(!e.length)return null;const o=l("div",{display:"flex",flexWrap:"wrap",alignItems:"baseline",gap:`${y.xs} ${y.lg}`}),n=[...e].sort((m,d)=>be(m.key)-be(d.key)),i=n.filter(m=>be(m.key)!==Number.MAX_SAFE_INTEGER),c=n.filter(m=>be(m.key)===Number.MAX_SAFE_INTEGER),s=m=>{const d=l("span",{whiteSpace:"nowrap"}),r=l("span",{color:_},`${ke(m.key)}: `);d.appendChild(r);const a=m.values.slice(0,t),h=m.values.length-a.length;let u=a.map(w=>w.value).join(", ");return h>0&&(u+=` +${h} more`),d.appendChild(document.createTextNode(u)),d};for(const m of i)o.appendChild(s(m));if(c.length){const m=l("span",{display:"none",flexWrap:"wrap",alignItems:"baseline",gap:`${y.xs} ${y.lg}`});for(const a of c)m.appendChild(s(a));const d=l("button",{background:"none",border:"none",padding:"0",cursor:"pointer",color:$.iconActive,fontSize:T.body,whiteSpace:"nowrap"});d.type="button",G(d,"bare");const r=a=>{m.style.display=a?"contents":"none",d.textContent=a?"less":`+${c.length} more`,d.setAttribute("aria-expanded",String(a))};r(!1),d.addEventListener("click",()=>r(d.getAttribute("aria-expanded")!=="true")),o.appendChild(m),o.appendChild(d)}return o}export function buildMetadataStripRow(e,t,o){const n=dt(e,o),i=buildFacetSummaryChips(n);if(!i&&!t)return null;const c=l("div",{display:"flex",flexWrap:"wrap",alignItems:"baseline",gap:"4px 14px"});if(t){const s=l("span",{fontWeight:"500",whiteSpace:"nowrap"},t.aggrMethod?`${t.lotSize} wafers stacked \xB7 ${t.aggrMethod}`:`${t.lotSize} wafers stacked`);c.appendChild(s)}return i&&c.appendChild(i),c}const Tt={display:"flex",flexDirection:"column",gap:y.sm,background:$.menuBg,border:`1px solid ${$.menuBorder}`,borderRadius:q.container,padding:`${y.sm} ${y.lg}`,boxShadow:Re.panel,fontSize:T.body,lineHeight:oe.none,boxSizing:"border-box",width:"100%",minWidth:"0"};export function buildMetadataStripBox(e,t,o){const n=buildMetadataStripRow(e,t,o);if(!n)return null;const i=l("div",Tt);return i.appendChild(n),i}export function buildCompactMetadataRows(e){const t=metadataEntries(e);if(!t.length)return null;const o=l("div");for(const[n,i]of t)o.appendChild(Bt(ke(n),i));return o}export function buildMetadataInfoSection(e,t){const o=buildMetadataStripRow(e,t,{facetableOnly:e.length>1});if(!o)return null;const n=l("div");return n.appendChild(ae("Wafer Info")),n.appendChild(o),n}export function buildYieldSection(e,t,o=[1]){const n=l("div");n.appendChild(ae("Summary"));const i=_e();if(i.appendChild(ce(String(e.totalDies),"Total dies")),e.partialDies>0&&i.appendChild(ce(String(e.partialDies),"Partial")),e.yieldPercent!==null){const c=Je([o]);i.appendChild(ce(`${e.yieldPercent.toFixed(1)}%`,"Yield",`pass: ${c}`))}return i.finish(),n.appendChild(i),e.edgeExcludedDies>0&&n.appendChild(je("Edge excluded (outer zone)",String(e.edgeExcludedDies))),n}export function buildBinSection(e,t,o,n,i,c){const s=new Map;if(i)for(const[r,a]of Object.entries(i))s.set(Number(r),a);else for(const r of e){if(r.partial||r.edgeExcluded)continue;const a=o==="hard"?r.hbin:r.sbin;a!=null&&s.set(a,(s.get(a)??0)+1)}if(!s.size)return null;const m=n??Be(e,{passBins:c,...o==="hard"?{hbinDefs:t}:{sbinDefs:t}}),d=l("div");d.appendChild(ae(Ve(o,[...s.values()].reduce((r,a)=>r+a,0))));for(const r of qe(s,t,m[o],m.pass[o]))d.appendChild(r);return d}function Ve(e,t){return`${e==="hard"?"Hard":"Soft"} Bin Breakdown \u2014 % of dies (N=${t})`}function qe(e,t,o,n){const i=[...e.values()].reduce((m,d)=>m+d,0),c=t?new Map(t.map(m=>[m.bin,m])):null;return xt(e.entries(),n).map(([m,d])=>{const r=c?.get(m),a=r?.name?`Bin ${m} \xB7 ${r.name}`:`Bin ${m}`,h=d/i*100,u=o.get(m)??ut;return ve(`${a} (${d})`,h,u)})}export function buildBinBreakdownSection(e){const{dies:t,hbinDefs:o,sbinDefs:n,hardCounts:i,softCounts:c,plotMode:s,passBins:m=[1],panel:d}=e,r=e.binColors??Be(t,{passBins:m,hbinDefs:o,sbinDefs:n}),a=g=>{const C=g==="hard"?i:c,b=new Map;if(C){for(const[k,v]of Object.entries(C))b.set(Number(k),v);return b}for(const k of t){if(k.partial||k.edgeExcluded)continue;const v=g==="hard"?k.hbin:k.sbin;v!=null&&b.set(v,(b.get(v)??0)+1)}return b},h=a("hard"),u=a("soft"),w=h.size>0,L=u.size>0;if(!w&&!L)return null;const R=he(d),P=s==="softBin"||s==="stackedSoftBins"?"soft":s==="hardBin"||s==="stackedBins"?"hard":void 0;let F=R.binMode??P??(w?"hard":"soft");F==="hard"&&!w&&(F="soft"),F==="soft"&&!L&&(F="hard");const A=F==="hard"?h:u,x=F==="hard"?o:n,f=[...A.values()].reduce((g,C)=>g+C,0),{outer:S}=ie(Ve(F,f),!0,void 0,{stateKey:"bins",panel:d,render:g=>{const C=F==="hard"?r.hard:r.soft;for(const b of qe(A,x,C,r.pass[F]))g.appendChild(b)},control:w&&L&&d?()=>we([["hard","Hard"],["soft","Soft"]],F,g=>{R.binMode=g;const C=buildBinBreakdownSection(e);C&&S.replaceWith(C)},d.ownerDocument,!0):void 0});return S}export function buildLotBinSection(e,t,o,n){return buildBinSection(e,t,o,n)}export function buildRegionYieldPanelSection(e){const{diesByWafer:t,allWafers:o,ringCount:n,passBins:i,panel:c}=e,s=he(c),m=a=>ot(t,o,n,i,a==="ring"?tt:nt);if(!m("ring").length&&!m("quadrant").length)return null;const d=s.regionMode,{outer:r}=ie(d==="ring"?"Ring Yield":"Quadrant Yield",!0,void 0,{stateKey:"regionYield",panel:c,render:a=>{const h=m(d);if(!h.length){a.appendChild(l("div",{fontSize:T.body,color:_},"No positioned dies for this breakdown."));return}for(const{label:u,n:w,yieldPercent:L}of h)a.appendChild(ve(`${u} (N=${w})`,L))},control:c?()=>we([["ring","Ring"],["quadrant","Quadrant"]],d,a=>{s.regionMode=a;const h=buildRegionYieldPanelSection(e);h&&r.replaceWith(h)},c.ownerDocument,!0):void 0});return r}export function buildLotOverviewSection(e,t=[]){const o=l("div"),n=Ne(e.perWafer.map(s=>s.summary.wafer));o.appendChild(ae(n.lotId!==void 0?"Lot Summary":"Summary"));const i=_e();i.appendChild(ce(String(e.stats.waferCount),"Wafers"));const c=e.perWafer.map(s=>s.summary.stats.yieldPercent).filter(s=>s!==null);if(c.length){const s=c.reduce((m,d)=>m+d,0)/c.length;i.appendChild(ce(`${s.toFixed(1)}%`,"Mean per-wafer yield"))}if(i.finish(),o.appendChild(i),t.length){const s=t.reduce((d,r)=>d+r.stats.analyzedDies,0),m=t.reduce((d,r)=>d+r.stats.excludedDies,0);(s||m)&&o.appendChild(je("Dies analysed",m?`${s.toLocaleString()} (${m.toLocaleString()} excluded)`:s.toLocaleString()))}return o}export function buildPerWaferYieldSection(e,t,o,n,i){const c=e.perWafer.map(f=>({waferIndex:f.waferIndex,label:ye(t[f.waferIndex],f.waferIndex).replace(/\s*·\s*\d+(\.\d+)?%$/,""),yieldPct:f.summary.stats.yieldPercent})).filter(f=>f.yieldPct!==null);if(!c.length)return null;const s=vt(c.map(f=>f.yieldPct)),m=St(c.map(f=>f.yieldPct)),d=s===m?"":` (${s.toFixed(1)}\u2013${m.toFixed(1)}%)`,r=[...c.map(f=>f.yieldPct)].sort((f,S)=>f-S),a=wt(r),h=Fe(r,.25),u=Fe(r,.75),w=c.length>=5?h-1.5*(u-h):-1/0,L=he(n),R=f=>{const S=L.waferSort==="yield"?[...c].sort((g,C)=>g.yieldPct-C.yieldPct):c;for(const{waferIndex:g,label:C,yieldPct:b}of S){const v=b<w?`${C} \xB7 low outlier`:C,E=ve(v,b,void 0,void 0,a),D=i?.(g);D?.total&&A(E,D),x(E,g,C,b,D),f.appendChild(E)}},P=` \xB7 median ${a.toFixed(1)}%`,{outer:F}=ie("Wafer Yield"+d+P,!0,void 0,{stateKey:"waferYield",panel:n,render:R,control:n?f=>we([["slot","Slot"],["yield","Yield"]],L.waferSort,S=>{L.waferSort=S,f()},n.ownerDocument,!0):void 0});return F;function A(f,S){const g=S.unusual?"unusual":S.notable?"notable":"info",C=l("span",{marginLeft:y.sm,flexShrink:"0",background:fe(g),color:"#fff",borderRadius:q.container,padding:"0 5px",fontSize:T.body,fontWeight:"600"},`${S.total}`);C.setAttribute("aria-hidden","true"),de(C,`${S.total} finding${S.total===1?"":"s"}`+(S.unusual?`, ${S.unusual} unusual`:"")+(S.notable?`, ${S.notable} notable`:"")),f.firstElementChild?.firstElementChild?.appendChild(C)}function x(f,S,g,C,b){o&&(f.style.cursor="pointer",f.style.borderRadius="4px",f.style.padding="2px 3px",f.style.marginLeft="-3px",f.style.marginRight="-3px",f.setAttribute("role","button"),f.setAttribute("aria-label",`${g}, ${C.toFixed(1)}% yield`+(b?.total?`, ${b.total} finding${b.total===1?"":"s"}${b.unusual?`, ${b.unusual} unusual`:""}`:"")+" \u2014 open wafer"),f.tabIndex=0,f.addEventListener("mouseenter",()=>{f.style.background=$.bgHover}),f.addEventListener("mouseleave",()=>{f.style.background=""}),f.addEventListener("focus",()=>{f.style.background=$.bgHover}),f.addEventListener("blur",()=>{f.style.background=""}),f.addEventListener("click",()=>o(S)),f.addEventListener("keydown",k=>{(k.key==="Enter"||k.key===" ")&&(k.preventDefault(),o(S))}))}}function Et(e){return ht([...e].sort((t,o)=>t-o))}function Ke(e,t){if(!e)return[];const o=e.waferMetadata??(e.perWaferMetadata?Le(e.perWaferMetadata.map(n=>({metadata:n}))):void 0);return!o||!Object.keys(o).length?[]:ct({waferMetadata:o,waferKeys:"identity",waferPlacement:"csv",reservedLabels:t}).columns}function Ge(e){return e?.populationLabel?[{key:"population",label:"Population",scope:"wafer",constant:e.populationLabel,get:()=>e.populationLabel,csvOnly:!0}]:[]}export function buildTestSection(...e){return ge(buildTestSectionSteps(...e))}export function*buildTestSectionSteps(e,t,o,n,i,c,s,m,d="full"){const r=e.filter(p=>!p.partial&&!p.edgeExcluded),a=new Map((n?.perTestStats??[]).map(p=>[p.testNumber,p])),h=new Map((n?.testSpecYield??[]).map(p=>[p.testNumber,p]));let u;if(t?.length?u=t.filter(et).map(p=>({testNumber:p.testNumber,name:p.name,unit:p.unit,limitLow:p.limitLow,limitHigh:p.limitHigh})):u=gt(r).map(W=>({testNumber:W,name:`Test ${W}`})),!u.length)return null;const w=u.filter(p=>r.some(W=>{const H=W.testValues?.[p.testNumber];return H!==void 0&&isFinite(H)}));if(!w.length)return null;const L=w.some(p=>p.limitLow!==void 0||p.limitHigh!==void 0),R=[],P=p=>!!p&&p.stddev!==void 0&&p.median!==void 0&&p.q1!==void 0&&p.q3!==void 0,F=p=>p.limitLow!==void 0||p.limitHigh!==void 0,A=!!(s?.length&&t?.length),f=(A||w.some(p=>!P(a.get(p.testNumber))||F(p)&&!h.has(p.testNumber)))&&t?.length?yield*bt(s??[{dies:e}],t):void 0;for(const p of w){yield;const W=a.get(p.testNumber),H=f?.specTally.get(p.testNumber),se=f?.stats.get(p.testNumber),Y=()=>r.map(I=>I.testValues?.[p.testNumber]).filter(I=>I!==void 0&&isFinite(I));let O;if(P(W)){const I=W;O={testNumber:p.testNumber,min:I.min,max:I.max,mean:I.mean,count:I.count,stddev:I.stddev,median:I.median,q1:I.q1,q3:I.q3}}else if(se)O={testNumber:p.testNumber,...se};else{const I=Y();if(!I.length)continue;O={testNumber:p.testNumber,...Et(I)}}let B=null,M=0;if(F(p)){const I=h.get(p.testNumber);if(I)({yieldPercent:B,totalDies:M}=I);else if(H)M=H.n,B=M>0?(M-H.fail)/M*100:null;else{const Z=Y();let ne=0;for(const J of Z)(p.limitLow!==void 0&&J<p.limitLow||p.limitHigh!==void 0&&J>p.limitHigh)&&ne++;M=Z.length,B=Z.length>0?(Z.length-ne)/Z.length*100:null}}R.push({entry:p,stats:O,specYieldPct:B,specN:M})}if(!R.length)return null;const S=new Map;for(const p of(A?f?.capability:void 0)??[])p.hasSpec&&S.set(p.testNumber,p.ppk);const g=S.size>0,b=new Set(R.map(p=>p.stats.count)).size===1?R[0].stats.count:null,k=l("div"),v=l("div",{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:y.sm}),E=b!==null?` \xB7 N=${b.toLocaleString()}`:"",D=c?.populationLabel?`Test Values (${R.length}) \u2014 ${c.populationLabel}${E}`:`Test Values (${R.length})${E}`,V=ae(D);V.style.marginBottom="0",v.appendChild(V);const z=document.createElement("button");z.type="button",z.textContent="Test values CSV",Object.assign(z.style,{...ue("outlined")}),G(z),z.addEventListener("click",()=>{const p=["Test","Unit","N","Min","Q1","Median","Mean","Q3","Max","StdDev"];g&&p.push("Ppk");const W=R.some(B=>B.specYieldPct!==null&&B.specN!==B.stats.count);L&&(p.push("LSL","USL","Spec Yield %"),W&&p.push("Spec Yield N"));const H=[...Ke(c,p),...Ge(c)],Y=[[...H.map(B=>B.label),...p].map(me).join(",")],O=B=>Ee(B,void 0,"engineering");for(const{entry:B,stats:M,specYieldPct:I,specN:Z}of R){const ne=[...H.map(J=>J.constant??""),B.name,B.unit??"",String(M.count),O(M.min),O(M.q1),O(M.median),O(M.mean),O(M.q3),O(M.max),O(M.stddev)];if(g){const J=S.get(B.testNumber);ne.push(J==null?"":J.toFixed(3))}L&&(ne.push(B.limitLow!==void 0?O(B.limitLow):"",B.limitHigh!==void 0?O(B.limitHigh):"",I!==null?I.toFixed(1):""),W&&ne.push(B.limitLow!==void 0||B.limitHigh!==void 0?String(Z):"")),Y.push(ne.map(me).join(","))}Ae(Y.join(`
|
|
2
|
+
`),"test-values.csv","text/csv",i)}),v.appendChild(z),k.appendChild(v);const Q=l("table",{width:"100%",borderCollapse:"collapse",fontSize:T.body}),te=document.createElement("thead"),X=document.createElement("tr"),j=["Test"];b===null&&j.push("N"),d==="full"&&j.push("Min","Q1","Median"),j.push("Mean"),d==="full"&&j.push("Q3","Max","StdDev"),g&&j.push("Ppk"),d==="full"&&L&&j.push("LSL","USL"),L&&j.push("Spec yield");for(const p of j){const W=l("th",{textAlign:p==="Test"?"left":"right",fontWeight:"600",fontSize:T.meta,letterSpacing:pe,textTransform:"uppercase",color:_,padding:"3px 8px 5px",borderBottom:`1px solid ${$.menuBorder}`,whiteSpace:"nowrap"},p);X.appendChild(W)}te.appendChild(X),Q.appendChild(te);const U=document.createElement("tbody");for(const{entry:p,stats:W,specYieldPct:H,specN:se}of R){const Y=M=>Ee(M,p.unit,o),O=document.createElement("tr"),B=(M,I="right")=>{const Z=l("td",{textAlign:I,padding:`${y.xs} ${y.md}`,borderBottom:`1px solid ${$.menuBorder}`,color:$.text,whiteSpace:"nowrap"},M);O.appendChild(Z)};if(B(p.name,"left"),b===null&&B(`${W.count}`),d==="full"&&(B(Y(W.min)),B(Y(W.q1)),B(Y(W.median))),B(Y(W.mean)),d==="full"&&(B(Y(W.q3)),B(Y(W.max)),B(Y(W.stddev))),g){const M=S.get(p.testNumber);B(M==null?"\u2014":M.toFixed(2))}d==="full"&&L&&(B(p.limitLow!==void 0?Y(p.limitLow):"\u2014"),B(p.limitHigh!==void 0?Y(p.limitHigh):"\u2014")),L&&B(H!==null?b!==null&&se===b?`${H.toFixed(1)}%`:`${H.toFixed(1)}% (N=${se})`:"\u2014"),U.appendChild(O)}Q.appendChild(U);const N=l("div",{overflowX:"auto"});if(N.appendChild(Q),!m)return k.appendChild(N),k;v.remove();const{outer:K}=ie(D,!0,void 0,{stateKey:"testValues",panel:m,render:p=>p.appendChild(N),control:()=>z});return K}export function buildFunctionalTestSection(e,t,o,n,i,c){const s=o??it(e,t);if(!s?.length)return null;const d=new Set(s.map(g=>g.totalDies)).size===1?s[0].totalDies:null,r=d!==null?` \xB7 N=${d.toLocaleString()}`:"",a=l("div"),h=l("div",{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:y.sm}),u=i?.populationLabel?`Functional Tests (${s.length}) \u2014 ${i.populationLabel}${r}`:`Functional Tests (${s.length})${r}`,w=ae(u);w.style.marginBottom="0",h.appendChild(w);const L=document.createElement("button");L.type="button",L.textContent="Functional CSV",Object.assign(L.style,{...ue("outlined")}),G(L),L.addEventListener("click",()=>{const g=["Test","N","Pass","Fail","Pass Rate %"],C=[...Ke(i,g),...Ge(i)],b=[[...C.map(k=>k.label),...g].map(me).join(",")];for(const k of s)b.push([...C.map(v=>v.constant??""),k.label,String(k.totalDies),String(k.passDies),String(k.failDies),k.passRatePercent!==null?k.passRatePercent.toFixed(1):""].map(me).join(","));Ae(b.join(`
|
|
3
|
+
`),"functional-tests.csv","text/csv",n)}),h.appendChild(L),a.appendChild(h);const R=l("table",{width:"100%",borderCollapse:"collapse",fontSize:T.body}),P=document.createElement("thead"),F=document.createElement("tr"),A=d===null?["Test","N","Pass","Fail","Pass rate"]:["Test","Pass","Fail","Pass rate"];for(const g of A)F.appendChild(l("th",{textAlign:g==="Test"?"left":"right",fontWeight:"700",fontSize:T.body,letterSpacing:pe,textTransform:"uppercase",color:_,padding:"3px 8px 5px",borderBottom:`1px solid ${$.menuBorder}`,whiteSpace:"nowrap"},g));P.appendChild(F),R.appendChild(P);const x=document.createElement("tbody");for(const g of s){const C=document.createElement("tr"),b=(k,v="right")=>{C.appendChild(l("td",{textAlign:v,padding:`${y.xs} ${y.md}`,borderBottom:`1px solid ${$.menuBorder}`,color:ee,whiteSpace:"nowrap"},k))};b(g.label,"left"),d===null&&b(String(g.totalDies)),b(String(g.passDies)),b(String(g.failDies)),b(g.passRatePercent!==null?`${g.passRatePercent.toFixed(1)}%`:"\u2014"),x.appendChild(C)}R.appendChild(x);const f=l("div",{overflowX:"auto"});if(f.appendChild(R),!c)return a.appendChild(f),a;h.remove();const{outer:S}=ie(u,!0,void 0,{stateKey:"functionalTests",panel:c,render:g=>g.appendChild(f),control:()=>L});return S}export function buildLotFunctionalSection(e,t,o,n,i){const c=o?.length?{perWaferMetadata:o.map(m=>m.wafer??{}),populationLabel:`${o.length} wafer${o.length===1?"":"s"} pooled`}:void 0,s=yt(o);return s?buildFunctionalTestSection(e,t,s,n,c,i):buildFunctionalTestSection(e,t,void 0,n,c,i)}const re={unusual:0,notable:1,info:2};function $e(e){return l("span",{display:"inline-block",width:"7px",height:"7px",borderRadius:q.pill,background:fe(e),flexShrink:"0"})}function Ue(e,t){let o=e.summary;return t&&(o.startsWith(`${t} has `)?o=o.slice(t.length+5):o.startsWith(`${t} `)&&(o=o.slice(t.length+1))),o=le(o),o.length?o[0].toUpperCase()+o.slice(1):o}export function buildFindingsSection(e,t,o,n,i=!1){if(!e.length)return null;const c=e.some(x=>x.severity==="unusual"||x.severity==="notable"),s=c?e.filter(x=>x.severity!=="info").length.toString():void 0,{outer:m,content:d}=i?(()=>{const x=l("div");return{outer:x,content:x}})():ie(`Findings (${e.length})`,c,s);function r(x){return x.reduce((f,S)=>re[S.severity]<re[f]?S.severity:f,"info")}function a(x){const f=new Map;for(const g of x){const C=`${g.comparison.family}\0${g.comparison.left}`,b=f.get(C)??[];b.push(g),f.set(C,b)}const S=[...f.entries()].map(([g,C])=>{const b=[...C].sort((k,v)=>re[k.severity]-re[v.severity]);return{key:g,findings:b,worst:r(b)}});return S.sort((g,C)=>re[g.worst]-re[C.worst]),S}function h(x,f){const g={ring:"Ring",quadrant:"Quadrant",sector:"Sector","reticle-position":"Reticle","test-site":"Test site",cluster:"Cluster","edge-arc":"Edge arc",wafer:"Wafer"}[x]??x;return f.toLowerCase().startsWith(g.toLowerCase())?f:`${g}: ${f}`}const u=e.filter(x=>x.comparison.family==="spatial-pattern"),w=new Set([...u.flatMap(x=>x.relatedIds??[]),...e.flatMap(x=>x.absorbedIds??[])]),L=e.filter(x=>x.comparison.family!=="spatial-pattern"&&!w.has(x.id)),R=a(L);function P(x,f=!1,S){const g=n===x.id,C=document.createElement("button");return C.type="button",C.dataset.wmapFinding=x.id,C.textContent=Ue(x,S),de(C,x.summary),C.setAttribute("aria-current",g?"true":"false"),Object.assign(C.style,{border:`1px solid ${$.menuBorder}`,borderLeft:`3px solid ${fe(x.severity)}`,background:g?$.bgActive:$.menuBg,borderRadius:q.container,padding:f?"6px 10px":"8px 10px",textAlign:"left",fontSize:f?"10px":"11px",fontWeight:g?"600":"400",color:$.text,cursor:"pointer",width:"100%",marginBottom:y.xs}),G(C,"bare"),C.addEventListener("click",()=>o(x,C)),C}const F=le(rt(e)??"");if(F){const x=l("div",{background:$.bgActive,borderRadius:q.container,padding:`${y.md} ${y.lg}`,marginBottom:y.md,display:"flex",gap:y.md,alignItems:"flex-start"}),f=l("span",{flex:"1",fontSize:T.body,lineHeight:oe.base,color:$.text},F);x.appendChild(f);const S=l("button",{flexShrink:"0",border:"none",background:"none",fontSize:T.body,color:$.icon,cursor:"pointer",padding:"0",lineHeight:oe.base,whiteSpace:"nowrap"},"Detail \u25B8");S.type="button",G(S,"bare"),S.addEventListener("click",()=>{const g=Ie({title:"Findings Summary",onClose:()=>{},anchor:S}),C=l("p",{fontSize:"16px",lineHeight:oe.base,color:$.text,padding:`${y.xxl} ${y.xxxl} ${y.xxl}`,margin:"0",borderBottom:`1px solid ${$.menuBorder}`,flexShrink:"0"},F);g.contentWrap.appendChild(C);const b=l("div",{overflowY:"auto",padding:`${y.xxl} ${y.xxxl}`,flex:"1"}),k=(v,E)=>{const D=l("div",{display:"flex",alignItems:"center",gap:"7px",fontSize:T.sub,fontWeight:"600",color:ee,marginTop:y.lg,marginBottom:y.xs});return D.appendChild($e(v)),D.appendChild(l("span",{},E)),D};for(const v of u){b.appendChild(k(v.severity,v.comparison.left)),b.appendChild(l("div",{fontSize:T.body,color:$.text,padding:"4px 0 4px 15px",marginBottom:y.xxs},le(v.summary)));const E=e.filter(D=>v.relatedIds?.includes(D.id));for(const D of E)b.appendChild(l("div",{fontSize:T.body,color:_,padding:"2px 0 2px 23px",marginBottom:y.xxs},le(D.summary)))}for(const v of R){const[E,D]=v.key.split("\0");b.appendChild(k(v.worst,h(E,D)));for(const V of v.findings)b.appendChild(l("div",{fontSize:T.body,color:$.text,padding:"4px 0 4px 15px",marginBottom:y.xxs},Ue(V,D)))}g.contentWrap.appendChild(b),Object.assign(g.contentWrap.style,{flexDirection:"column",overflow:"hidden"})}),x.appendChild(S),d.appendChild(x)}let A=!0;for(const x of u){A||d.appendChild(l("div",{height:"1px",background:$.separator,margin:"4px 0"})),A=!1;const f=e.filter(k=>x.relatedIds?.includes(k.id)),S=f.length>0,g=l("div",{position:"relative",marginBottom:S?"2px":"4px"}),C=n===x.id,b=document.createElement("button");if(b.type="button",b.dataset.wmapFinding=x.id,Object.assign(b.style,{border:`1px solid ${$.menuBorder}`,borderLeft:`3px solid ${fe(x.severity)}`,background:C?$.bgActive:$.menuBg,borderRadius:q.container,padding:"8px 32px 8px 10px",textAlign:"left",fontSize:T.body,fontWeight:C?"600":"500",color:$.text,cursor:"pointer",width:"100%"}),b.textContent=le(x.summary),de(b,x.summary),b.setAttribute("aria-current",C?"true":"false"),G(b,"bare"),b.addEventListener("click",()=>o(x,b)),g.appendChild(b),S){const k=l("div",{display:"none",paddingLeft:"12px",marginBottom:y.xs});for(const D of f)k.appendChild(P(D,!0));g.appendChild(k);let v=!1;const E=l("button",{position:"absolute",top:"50%",right:"8px",transform:"translateY(-50%)",border:"none",background:"none",fontSize:T.body,color:$.icon,cursor:"pointer",padding:`${y.xxs} ${y.xs}`,lineHeight:oe.none},"\u25B8");G(E,"bare"),E.type="button",de(E),E.setAttribute("aria-label","Show supporting findings"),E.setAttribute("aria-expanded","false"),E.addEventListener("click",D=>{D.stopPropagation(),v=!v,k.style.display=v?"block":"none",E.textContent=v?"\u25BE":"\u25B8";const V=v?"Hide supporting findings":"Show supporting findings";E.setAttribute("aria-label",V),E.setAttribute("aria-expanded",String(v))}),g.appendChild(E)}d.appendChild(g)}for(const x of R){A||d.appendChild(l("div",{height:"1px",background:$.separator,margin:"4px 0"})),A=!1;const[f,S]=x.key.split("\0"),g=l("div",{display:"flex",alignItems:"center",gap:y.sm,fontSize:T.body,fontWeight:"600",color:ee,margin:"2px 0 4px"});g.appendChild($e(x.worst)),g.appendChild(l("span",{},h(f,S))),d.appendChild(g);for(const C of x.findings)d.appendChild(P(C,!1,S))}return m}const Ft=[{value:"",label:"All kinds"},{value:"yield",label:"Yield"},{value:"hardBin",label:"Hard bin"},{value:"softBin",label:"Soft bin"},{value:"test",label:"Test value"},{value:"functionalTest",label:"Functional test"},{value:"spatialPattern",label:"Spatial pattern"}],Dt=[{value:"",label:"All regions"},{value:"ring",label:"Ring"},{value:"quadrant",label:"Quadrant"},{value:"reticle-position",label:"Reticle position"},{value:"test-site",label:"Test site"},{value:"wafer",label:"Wafer"},{value:"sector",label:"Sector"},{value:"cluster",label:"Cluster"},{value:"edge-arc",label:"Edge arc"},{value:"spatial-pattern",label:"Spatial pattern"}],Rt=["unusual","notable","info"],Mt={unusual:"Unusual",notable:"Notable",info:"Info"};function It(e,t,o){const n=l("div",{display:"flex",flexWrap:"wrap",alignItems:"center",gap:y.lg,marginBottom:y.lg,paddingBottom:"10px",borderBottom:`1px solid ${$.separator}`}),i={unusual:0,notable:0,info:0};for(const r of e)i[r.severity]++;const c=Rt.filter(r=>i[r]>0),s=new Set(t.severity===void 0?c:Array.isArray(t.severity)?t.severity:[t.severity]),m=l("div",{display:"flex",gap:y.xs,flexWrap:"wrap"});for(const r of c){const a=document.createElement("button");a.type="button";const h=()=>{const u=s.has(r);a.setAttribute("aria-pressed",u?"true":"false"),Object.assign(a.style,{display:"inline-flex",alignItems:"center",gap:"5px",border:`1px solid ${$.menuBorder}`,borderRadius:q.pill,background:u?$.bgActive:"none",opacity:u?"1":"0.5",color:$.text,fontSize:T.body,padding:`${y.xxs} ${y.md}`,cursor:"pointer"}),a.dataset.on=u?"true":"false"};a.appendChild($e(r)),a.appendChild(l("span",{},`${Mt[r]} ${i[r]}`)),de(a,()=>s.has(r)?"Click to hide these findings":"Click to show these findings"),h(),G(a,"bare"),a.addEventListener("click",()=>{s.has(r)?s.delete(r):s.add(r),t.severity=s.size===c.length?void 0:[...s],o()}),m.appendChild(a)}n.appendChild(m);const d=t.kind!==void 0||t.family!==void 0;return(e.length>=Wt||d)&&(n.appendChild(De("Kind:",Ft,t.kind??"",r=>{t.kind=r||void 0,o()},{maxWidth:"130px"})),n.appendChild(De("Region:",Dt,t.family??"",r=>{t.family=r||void 0,o()},{maxWidth:"150px"}))),n}const Wt=8;function At(e,t){const o=l("div",{display:"flex",flexDirection:"column",gap:y.xs,padding:y.md,marginBottom:y.md,background:$.bgHover,borderRadius:q.control},void 0,t);if(o.appendChild(l("div",{fontSize:T.body,color:$.value},e.message,t)),e.detail&&o.appendChild(l("div",{fontSize:T.meta,color:_},e.detail,t)),e.actionLabel&&e.onAction){const n=l("button",ue("outlined"),e.actionLabel,t);n.type="button",n.style.alignSelf="flex-start",n.style.marginTop=y.xs,G(n),n.addEventListener("click",e.onAction),o.appendChild(n)}return o}export function buildFindingsSectionWithFilter(e,t,o,n,i,c,s){if(!e.findings.length&&!s)return null;const m=e.findings.some(L=>L.severity==="unusual"||L.severity==="notable"),d=m?e.findings.filter(L=>L.severity!=="info").length.toString():void 0,r=c?.ownerDocument??document,{outer:a,content:h}=ie(`Findings (${e.findings.length})`,m||!!s,d,{stateKey:"findings",panel:c});if(s&&h.appendChild(At(s,r)),!e.findings.length)return a;h.appendChild(It(e.findings,n,i));const u=lt(e,n);if(!u.length)return h.appendChild(l("div",{color:_,fontSize:T.body,textAlign:"center",padding:`${y.xxl} ${y.md}`},"No findings match the current filter.")),a;const w=buildFindingsSection(u,e,t,o,!0);return w&&h.appendChild(w),a}export function buildLotTestSection(...e){return ge(buildLotTestSectionSteps(...e))}export function*buildLotTestSectionSteps(e,t,o,n,i,c,s,m="full"){const d=n?.length?{perWaferMetadata:n.map(a=>a.wafer??{}),populationLabel:`${n.length} wafer${n.length===1?"":"s"} pooled`}:void 0;let r;if(n?.length&&n.every(a=>a.stats.perTestStats!==void 0)){const a=new Map;for(const h of n)for(const u of h.stats.perTestStats??[]){const w=a.get(u.testNumber);w?(w.n+=u.count,w.sum+=u.mean*u.count,w.min=Math.min(w.min,u.min),w.max=Math.max(w.max,u.max)):a.set(u.testNumber,{n:u.count,sum:u.mean*u.count,min:u.min,max:u.max})}r={perTestStats:[...a.entries()].map(([h,u])=>({testNumber:h,count:u.n,min:u.min,max:u.max,mean:u.sum/u.n}))}}if(n?.length&&n.every(a=>a.stats.testSpecYield!==void 0)){const a=new Map;for(const h of n)for(const u of h.stats.testSpecYield??[]){const w=a.get(u.testNumber);w?(w.passDies+=u.passDies,w.totalDies+=u.totalDies):a.set(u.testNumber,{passDies:u.passDies,totalDies:u.totalDies})}r={...r,testSpecYield:[...a.entries()].map(([h,u])=>({testNumber:h,totalDies:u.totalDies,yieldPercent:u.totalDies>0?u.passDies/u.totalDies*100:null}))}}return yield*buildTestSectionSteps(e,t,o,r,i,d,c,s,m)}export function createSummaryPanelEl(e,t,o=document){const n=e==="top"||e==="bottom",i=l("div",{background:kt,color:$.text,fontVariantNumeric:"tabular-nums",border:Pe,borderRadius:q.container,padding:y.xl,overflowY:"auto",overflowX:n?"auto":"hidden",flexShrink:"0",boxSizing:"border-box",fontFamily:T.family,fontSize:T.sub,boxShadow:Re.panel},void 0,o);return e==="right"&&(i.style.marginRight=t),e==="left"&&(i.style.marginLeft=t),e==="bottom"&&(i.style.marginBottom=t),n?(i.style.height="180px",i.style.width="100%"):(i.style.width="300px",i.style.maxHeight="100%"),i}export function wrapWithSummaryPanel(e,t,o){const n=o==="top"||o==="bottom",i=l("div",{display:"flex",flexDirection:n?"column":"row",gap:y.md,width:"100%",height:"100%",flex:"1 1 0",minHeight:"0",boxSizing:"border-box",alignItems:n?"flex-start":"stretch"});return e.style.flex="1 1 0",e.style.minWidth="0",e.style.minHeight="0",o==="right"||o==="bottom"?(i.appendChild(e),i.appendChild(t)):(i.appendChild(t),i.appendChild(e)),i}function Qe(e){return l("div",{fontSize:T.heading,fontWeight:"600",color:ee,marginBottom:y.lg},e)}function xe(e,t){const o=l("button",ue("outlined"),e);return o.type="button",G(o),o.addEventListener("click",t),o}function Xe(...e){const t=e.filter(n=>!!n);if(!t.length)return null;const o=l("div",{display:"flex",flexWrap:"wrap",gap:y.sm,marginBottom:y.lg});for(const n of t)o.appendChild(n);return o}function Ze(e,t,o,n,i,c,s,m,d,r,a){const h=e.ownerDocument,u=Ie({title:"Die list",onClose:()=>{},anchor:e,ownerDocument:h});u.contentWrap.style.padding="14px 16px";const w=Ct(t,o,{...s,title:n,onSaveText:m,waferMetadata:i,metadataFields:c,extraColumn:d,getWafer:r,ringCount:a,ownerDocument:h});w&&u.contentWrap.appendChild(w)}export function renderWaferSummaryContent(...e){ge(renderWaferSummaryContentSteps(...e))}export function*renderWaferSummaryContentSteps(e,t){const o=e.scrollTop;e.innerHTML="";const{wafer:n,dies:i,yieldSummary:c,dataCoverage:s,hbinDefs:m,sbinDefs:d,testDefs:r,statsSummary:a,passBins:h=[1],ringCount:u=4,binColors:w,plotMode:L,fallbackFormat:R,onFindingClick:P,activeFindingId:F=null,findingsFilter:A,onFindingsFilterChange:x,findingsNotice:f,onSaveText:S,metadataFields:g,dieListOptions:C,metadataShownElsewhere:b}=t;e.appendChild(Qe("Wafer Summary"));const k=t.warnings??Te({statsSummary:a});k.length&&e.appendChild(Se(k,e.ownerDocument));const v=c&&s?xe("Summary report",()=>{We(st({wafer:n,dies:i,yield:c,dataCoverage:s,hbinDefs:m,sbinDefs:d,testDefs:r,passBins:h,ringCount:u},a),{anchor:e})}):null,E=(C?.enabled??!0)&&i.length?xe("View die list",()=>{Ze(e,i,r,`Die list \u2014 ${i.length} dies`,n.metadata,g,C,S,void 0,()=>n,u)}):null,D=Xe(v,E);D&&e.appendChild(D);let V=!0;const z=j=>{j&&(V||e.appendChild(Ye()),V=!1,e.appendChild(j))},Q=a?.stats.isLotStack?a.stats:void 0,te=Q?.lotSize!==void 0?{lotSize:Q.lotSize,aggrMethod:mt(Q.aggregationMethod)}:void 0;b||z(buildMetadataInfoSection([{metadata:n.metadata??void 0}],te)),c&&s&&z(buildYieldSection(c,s,h)),yield,a&&P&&A&&x&&(z(buildFindingsSectionWithFilter(a,P,F,A,x,e,f)),yield),z(buildBinBreakdownSection({dies:i,hbinDefs:m,sbinDefs:d,binColors:w,hardCounts:a?.stats.hardBinCounts,softCounts:a?.stats.softBinCounts,plotMode:L,passBins:h,panel:e})),yield,z(buildRegionYieldPanelSection({diesByWafer:[i],allWafers:[n],ringCount:u,passBins:h,panel:e})),yield;const X=n.metadata?{waferMetadata:n.metadata}:void 0;z(yield*buildTestSectionSteps(i,r,R,a?.stats,S,X,[{dies:i}],e,"compact")),yield,z(buildFunctionalTestSection(i,r,a?.stats.functionalYield,S,X,e)),e.appendChild(l("div",{height:"12px",flexShrink:"0"})),e.scrollTop=o}export function reportMapsFromItems(e,t,o){const n=[];return e.forEach((i,c)=>{!i?.wafer||!i.dies||n.push({...i,wafer:i.wafer,dies:i.dies,label:ye(i,c),passBins:[...Ce(i,t)],ringCount:i.ringCount??o})}),n}export function renderLotSummaryContent(...e){ge(renderLotSummaryContentSteps(...e))}export function*renderLotSummaryContentSteps(e,t){const o=e.scrollTop;e.innerHTML="";const{lotSummary:n,items:i,hbinDefs:c,sbinDefs:s,testDefs:m,passBins:d=[1],ringCount:r=4,binColors:a,plotMode:h,fallbackFormat:u,onFindingClick:w,activeFindingId:L=null,onWaferClick:R,findingsFilter:P,onFindingsFilterChange:F,findingsNotice:A,onSaveText:x,dieListOptions:f,findingsFor:S}=t;e.appendChild(Qe(`Summary \u2014 ${ft(Ne(n.perWafer.map(N=>N.summary.wafer)))}`));const g=t.warnings??Te({lotStatsSummary:n});g.length&&e.appendChild(Se(g,e.ownerDocument));const C=xe("Summary report",()=>{We(at(reportMapsFromItems(i,d,r)),{anchor:e})}),b=[],k=[],v=[],E=[],D=[],V=new WeakMap,z=new WeakMap;for(let N=0;N<i.length;N++){yield;const K=i[N];if(!K){k.push([]);continue}K.wafer&&(b.push(K.wafer),E.push(K.dies??[]),D.push(Ce(K,d)));const p=K.dies??[],W=ye(K,N);for(const H of p)V.set(H,W),K.wafer&&z.set(H,K.wafer);k.push(p);for(const H of p)v.push(H)}const Q=f?.enabled??!0?xe("View die list",()=>{v.length&&Ze(e,v,m,`Die list \u2014 ${v.length} dies across ${i.length} wafer${i.length===1?"":"s"}`,Le(i.filter(N=>!!N).map(N=>({metadata:N.wafer?.metadata}))),i.find(N=>N?.metadataFields?.length)?.metadataFields,f,x,{label:"Wafer",get:N=>V.get(N)},N=>z.get(N),r)}):null,te=Xe(C,Q);te&&e.appendChild(te);const X=i.map(N=>N?.statsSummary).filter(N=>!!N);let j=!0;const U=N=>{N&&(j||e.appendChild(Ye()),j=!1,e.appendChild(N))};U(buildLotOverviewSection(n,X)),yield,w&&P&&F&&(U(buildFindingsSectionWithFilter(n,w,L,P,F,e,A)),yield),U(buildPerWaferYieldSection(n,i,R,e,S)),yield,U(buildBinBreakdownSection({dies:v,hbinDefs:c,sbinDefs:s,plotMode:h,passBins:d,panel:e,binColors:a??pt(i.flatMap(N=>N?[{dies:N.dies??[],passBins:Ce(N,d)}]:[]),{hbinDefs:c,sbinDefs:s}).colors})),yield,U(buildRegionYieldPanelSection({diesByWafer:E,allWafers:b,ringCount:r,passBins:N=>D[N],panel:e})),yield,m?.length&&(U(yield*buildLotTestSectionSteps(v,m,u,X,x,k.map(N=>({dies:N})),e,"compact")),yield,U(buildLotFunctionalSection(v,m,X,x,e))),e.appendChild(l("div",{height:"12px",flexShrink:"0"})),e.scrollTop=o}
|