@wafertools/wafermap 0.29.0 → 0.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/AGENTS.md +13 -14
  2. package/CHANGELOG.md +235 -0
  3. package/README.md +5 -5
  4. package/dist/packages/canvas-adapter/deprecated.d.ts +10 -0
  5. package/dist/packages/canvas-adapter/deprecated.js +1 -0
  6. package/dist/packages/canvas-adapter/dieList.d.ts +1 -3
  7. package/dist/packages/canvas-adapter/dieList.js +7 -7
  8. package/dist/packages/canvas-adapter/index.d.ts +1 -3
  9. package/dist/packages/canvas-adapter/index.js +1 -1
  10. package/dist/packages/canvas-adapter/insightsTab.d.ts +0 -1
  11. package/dist/packages/canvas-adapter/insightsTab.js +1 -1
  12. package/dist/packages/canvas-adapter/maplessSummary.js +1 -1
  13. package/dist/packages/canvas-adapter/renderWaferGallery.d.ts +1 -40
  14. package/dist/packages/canvas-adapter/renderWaferGallery.js +1 -1
  15. package/dist/packages/canvas-adapter/renderWaferMap.d.ts +74 -104
  16. package/dist/packages/canvas-adapter/renderWaferMap.js +1 -1
  17. package/dist/packages/canvas-adapter/summaryPanel.d.ts +11 -8
  18. package/dist/packages/canvas-adapter/summaryPanel.js +3 -3
  19. package/dist/packages/canvas-adapter/toCanvas.d.ts +20 -12
  20. package/dist/packages/canvas-adapter/toCanvas.js +1 -1
  21. package/dist/packages/canvas-adapter/toolbar.js +2 -2
  22. package/dist/packages/canvas-adapter/userGuideHtml.d.ts +1 -1
  23. package/dist/packages/canvas-adapter/userGuideHtml.js +12 -8
  24. package/dist/packages/canvas-adapter/version.d.ts +2 -2
  25. package/dist/packages/canvas-adapter/version.js +1 -1
  26. package/dist/packages/canvas-adapter/warnings.js +1 -1
  27. package/dist/packages/core/deprecated.d.ts +64 -0
  28. package/dist/packages/core/deprecated.js +1 -0
  29. package/dist/packages/core/index.d.ts +1 -3
  30. package/dist/packages/core/index.js +1 -1
  31. package/dist/packages/core/passBins.d.ts +33 -0
  32. package/dist/packages/core/passBins.js +1 -0
  33. package/dist/packages/core/waferLabel.d.ts +25 -0
  34. package/dist/packages/core/waferLabel.js +1 -0
  35. package/dist/packages/renderer/binColors.d.ts +67 -13
  36. package/dist/packages/renderer/binColors.js +1 -1
  37. package/dist/packages/renderer/buildView.d.ts +8 -9
  38. package/dist/packages/renderer/buildView.js +1 -1
  39. package/dist/packages/renderer/buildWaferMap.d.ts +47 -13
  40. package/dist/packages/renderer/buildWaferMap.js +1 -1
  41. package/dist/packages/renderer/colorMap.d.ts +4 -3
  42. package/dist/packages/renderer/colorSchemes.d.ts +8 -6
  43. package/dist/packages/renderer/deprecate.d.ts +24 -0
  44. package/dist/packages/renderer/deprecate.js +1 -0
  45. package/dist/packages/renderer/deprecated.d.ts +45 -0
  46. package/dist/packages/renderer/deprecated.js +1 -0
  47. package/dist/packages/renderer/index.d.ts +2 -3
  48. package/dist/packages/renderer/index.js +1 -1
  49. package/dist/packages/stats/analyzeWaferMap.js +1 -1
  50. package/dist/packages/stats/binPareto.d.ts +6 -1
  51. package/dist/packages/stats/clusterDetection.d.ts +0 -2
  52. package/dist/packages/stats/deprecated.d.ts +87 -0
  53. package/dist/packages/stats/deprecated.js +1 -0
  54. package/dist/packages/stats/index.d.ts +3 -14
  55. package/dist/packages/stats/index.js +1 -1
  56. package/dist/packages/stats/regions.d.ts +7 -2
  57. package/dist/packages/stats/regions.js +1 -1
  58. package/dist/packages/stats/renderSummaryReport.d.ts +3 -0
  59. package/dist/packages/stats/renderSummaryReport.js +34 -34
  60. package/dist/packages/stats/types.d.ts +0 -43
  61. package/dist/packages/stats/yield.d.ts +12 -6
  62. package/dist/packages/stats/yield.js +1 -1
  63. package/package.json +1 -1
@@ -1 +1 @@
1
- import{buildView as vi,buildHoverText as xi,findTestDef as ct,resolveTestNumber as Nt}from"../renderer/buildView.js";import{toCanvas as Ci,BIN_LEGEND_W as Fn,BIN_LEGEND_W_COMPACT as wi,BIN_LEGEND_ADAPT_COMPACT as Si,BIN_LEGEND_ADAPT_FLOATING as Mi}from"./toCanvas.js";import{buildWaferMap as Ei,getTestPassStatus as Di,isParametricTest as jt}from"../renderer/buildWaferMap.js";import{analyzeWaferMap as Bi}from"../stats/analyzeWaferMap.js";import{SHADOW as ki,LEADING as An,wireControlHover as Vn,SPACE as W,EDGE_GUTTER as Li,RADIUS as zn,FONT as ft,CLR as x,applyOverlayZ as Ti,getTooltip as Yn,hideTooltip as pt,reparentTooltip as Oi,positionTooltip as Kt,createToolbarHelpers as Pi,buildModeMenuEl as Ri,openReparentedModal as Ii,openUserGuideWindow as Wi,makePaletteBtn as Hi,makeLogScaleBtn as Fi,makeLegendStyleBtn as Ai,makeOverlaysBtn as Vi,makeOrientationBtn as zi,menuLayerFor as Xn,saveImageBlob as Yi,markMenuTrigger as _e,wireMenuA11y as Nn,wireExpandToggle as Xi,nextFrame as _t,requestedPassFailDisplay as Ni,overlayMenuRows as ji,anyOverlayActive as Ki,logWmapVersionOnce as _i,buildDataModeEntries as $i,metadataKeyHasData as Gi,metadataModeEntry as Ui}from"./toolbar.js";import{createSummaryPanelEl as $t,wrapWithSummaryPanel as Gt,renderWaferSummaryContent as Zi}from"./summaryPanel.js";import{collectWarnings as Qi,buildWarningsMenuEl as qi,severityOf as Ji}from"./warnings.js";import{ICONS as jn}from"./icons.js";import{metadataValueColor as eo,NO_DATA_FILL as to}from"../renderer/colorMap.js";import{createIdentityHeader as no,collapsedLabel as Ut}from"./identityHeader.js";import{getDieKey as Be,hasPosition as Kn,isPositionedDie as io}from"../core/dies.js";import{buildDieListSection as oo}from"./dieList.js";import{buildMaplessSummary as so}from"./maplessSummary.js";import{resolveBinColors as lo,binColorWarning as ao}from"../renderer/binColors.js";const _n=new Set(["binColorScheme","valueColorScheme","reverseValueScheme","useDefinedBinColors","rotation","flipX","flipY","showDieLabels","showPartialDies","showRingBoundaries","showQuadrantBoundaries","showReticle","showXYIndicator","ringCount","legendPosition","logScale","colorbarRangeMode","markFailingDies"]);export const COLOR_KEYS=["binColorScheme","valueColorScheme","reverseValueScheme","useDefinedBinColors","binColors"];export function classifyChanged(K){const y=K.some(g=>_n.has(g)),C=K.some(g=>!_n.has(g));return y&&C?"mixed":y?"preference":"state"}export function renderWaferMap(K,y,C={}){_i();const g=K.ownerDocument,H=g.defaultView??window;H.getComputedStyle(K).position==="static"&&(K.style.position="relative");const $n=K.clientHeight;C.height!=null&&(K.style.height=typeof C.height=="number"?`${C.height}px`:C.height);const ut=y.dataCoverage?y.dataCoverage.unpositionedDies:y.dies.filter(e=>!Kn(e)).length,$e=(y.dataCoverage?y.dataCoverage.totalDies:y.dies.length-ut)===0&&ut>0,ke=g.createElement("div");Object.assign(ke.style,{display:"flex",flexDirection:"column",width:"100%",height:"100%"}),K.appendChild(ke);const le=g.createElement("div");Object.assign(le.style,{position:"relative",width:"100%",flex:"1 1 auto",minHeight:"0"}),C.maxSize!=null&&(le.style.maxWidth=`${C.maxSize}px`,le.style.maxHeight=`${C.maxSize}px`);const ge=C.chromeInset??Li,_=g.createElement("div");Object.assign(_.style,{display:"flex",alignItems:"stretch",gap:W.sm,background:x.canvasBg,paddingBottom:W.lg,paddingTop:ge,paddingLeft:ge,paddingRight:ge,flexShrink:"0",minWidth:"0"}),ke.appendChild(_),ke.appendChild(le);function ve(){const e=[..._.children].some(t=>t.style.display!=="none");_.style.display=e?"flex":"none"}const S=g.createElement("div");Object.assign(S.style,{position:"relative",width:"100%",height:"100%"});const a=g.createElement("canvas");Object.assign(a.style,{width:"100%",height:"100%",display:"block"}),S.appendChild(a),le.appendChild(S);let Ge=null;if(ut>0){let n=function(){if(t){const d=oo(e,y.testDefs,{...C.dieList,onSaveText:C.onSaveText,waferMetadata:$.metadata,metadataFields:ce,ownerDocument:g});if(d)return d}const o=ct(y.testDefs,c.activeTest??0),s=jt(o)?c.logScale??o?.logScale??!1:!1;return so(e,y.testDefs,{plotMode:c.plotMode??"hardBin",activeTest:c.activeTest,hbinDefs:G,sbinDefs:U,binColors:m.binColors,valueColorScheme:c.valueColorScheme,reverseValueScheme:c.reverseValueScheme,logScale:s,colorbarRangeMode:c.colorbarRangeMode,valueRangeDies:y.dies})},i=function(o){const s=g.createElement("button");return s.type="button",Vn(s),Object.assign(s.style,{fontSize:ft.body,padding:`${W.xxs} ${W.sm}`,borderRadius:zn.control,flexShrink:"0",border:`1px solid ${x.menuBorder}`,background:x.menuBg,color:x.text,cursor:"pointer"}),s.textContent=t?"View chart":"View die list",s.addEventListener("click",d=>{d.stopPropagation(),t=!t,s.textContent=t?"View chart":"View die list",o()}),s};const e=y.dies.filter(o=>!Kn(o));let t=!1;if($e){const o=g.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 s=g.createElement("div");Object.assign(s.style,{display:"flex",justifyContent:"space-between",alignItems:"flex-start",gap:W.md});const d=g.createElement("span");Object.assign(d.style,{fontSize:ft.body,color:x.label,lineHeight:An.base}),d.textContent="No die position data for this wafer.",s.appendChild(d);const r=g.createElement("div");Object.assign(r.style,{flex:"1",minHeight:"0",overflow:"auto",display:"flex",flexDirection:"column"}),s.appendChild(i(()=>r.replaceChildren(n()))),o.appendChild(s),o.appendChild(r),S.appendChild(o),Ge=()=>{t||r.replaceChildren(n())}}else{const o=g.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:ft.body,color:x.text,cursor:"pointer",padding:`${W.xs} ${W.md}`,display:"flex",alignItems:"center",justifyContent:"space-between",gap:W.md}),Vn(o,"bare");const s=g.createElement("span");s.textContent=`+${e.length} ${e.length===1?"die":"dies"} without position data`,o.appendChild(s);const d=g.createElement("span");d.textContent="\u25BE",Object.assign(d.style,{fontSize:ft.body,lineHeight:An.none,color:x.label,flexShrink:"0"}),o.appendChild(d),o.setAttribute("aria-expanded","false"),o.setAttribute("aria-label",`${e.length} dies without position data. Click to view.`);let r=null,l=null;Xi(o,f=>{if(d.textContent=f?"\u25B4":"\u25BE",o.setAttribute("aria-expanded",String(f)),f){r=g.createElement("div");const p=o.getBoundingClientRect().height||28;Object.assign(r.style,{position:"absolute",left:"0",right:"0",bottom:`${p}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}),r.addEventListener("click",Q=>Q.stopPropagation());const h=g.createElement("div");Object.assign(h.style,{display:"flex",justifyContent:"flex-end"}),h.appendChild(i(()=>{l&&l.replaceChildren(n())})),r.appendChild(h),l=g.createElement("div"),Object.assign(l.style,{flex:"1",minHeight:"0",overflow:"auto",display:"flex",flexDirection:"column"}),l.appendChild(n()),r.appendChild(l),S.appendChild(r)}else r&&(r.remove(),r=null,l=null)}),S.appendChild(o),Ge=()=>{l&&!t&&l.replaceChildren(n())}}}const{onHover:Ue,onClick:Gn,onSelect:he,onViewOptionsChange:Un,showTooltip:Zn=!0,showToolbar:Le=!0,showIdentity:Zt=!0,toolbarControls:gt="full",showPlotModeSelector:Qn=!0,minZoom:qn=.4,maxZoom:Jn=20,summaryPanel:Te,renderTooltip:Qt,passBins:Ze=[1],showHelpButton:qt=!1,userGuideExtension:ei,onExpand:Jt,showExpandButton:en=!0,zIndex:ti,insights:ht,warnings:tn,viewOptions:ni={},...ae}=C,Oe=ht?.enabled??!1,nn=tn?.display??!0,ii=Ti(ti);let Pe=ae.fallbackFormat,re=C.statsSummary,de=[],on=!1,Qe=null,sn=!1;function mt(){const e=Qi({result:y,statsSummary:re,extra:Qe?[Qe]:[]}),t=e.length!==de.length||e.some((n,i)=>n.code!==de[i]?.code||n.message!==de[i]?.message);de=e,(t||!on)&&(on=!0,tn?.onWarning?.(e))}mt();let yt=y,$=y.wafer,te=y.dies,E=new Set,G=y.hbinDefs,U=y.sbinDefs,ne=y.testDefs,ce=y.metadataFields,ln=y.reticles?.length?y.reticles:void 0,an=y.reticleConfig,rn=y.view?.dataAxisFlip,bt=y.isLotStack??!1,vt=y.aggrMethod,xt=y.lotSize;const oi=Le&&gt!=="view-only"&&Oe;let Ct=!1,Z=null,V=null,J=null;Zt&&(Z=no(Ut($.metadata??{},Re())??"",$.metadata,{lotStack:Re(),ownerDocument:g}),S.appendChild(Z.metaPanel),Z.isEmpty()||(V=dn(Z.wrap),_.insertBefore(V,_.firstChild),ve()));function dn(e){const t=g.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 bt?{lotSize:xt??1,aggrMethod:vt}:void 0}function si(){if(!Z)return;Z.update(Ut($.metadata??{},Re())??"",$.metadata,Re());const e=V?.isConnected??!1,t=!Z.isEmpty();!t&&e?(V.remove(),V=null):t&&!e&&(V=dn(Z.wrap),V.style.display=Ct?"none":"",_.insertBefore(V,_.firstChild),ve())}const li=[...G??[],...U??[]].some(e=>e.color);let c={plotMode:"hardBin",showDieLabels:!1,showPartialDies:!0,showRingBoundaries:!1,showQuadrantBoundaries:!1,showReticle:!1,showXYIndicator:!1,ringCount:4,rotation:0,flipX:!1,flipY:!1,legendPosition:ae.legendPosition??"default",...ni},z=null,ie=!1,cn=null;function ai(){return Oe?z?Promise.resolve(z):(cn??=import("./insightsTab.js").then(({createInsightsTab:e})=>(z=e({getItems:()=>[{wafer:$,dies:te,hbinDefs:G,sbinDefs:U,testDefs:ne,label:String($.metadata?.waferId??""),statsSummary:re}],getBinColors:()=>m.binColors,passBins:Ze,getRingCount:()=>c.ringCount??4,onSaveImage:C.onSaveImage,onSaveText:C.onSaveText,defaultView:ht?.defaultView,showMetadataStrip:!1,contentInset:ge,backTab:oi?void 0:{label:"Map",onBack:()=>Ie(!1)},onOpenGuide:qt&&!Le?()=>At():void 0,focusTest:t=>{D({plotMode:"value",activeTest:t,highlightBin:void 0}),Ie(!1)},ownerDocument:g}),Object.assign(z.el.style,{position:"absolute",inset:"0",background:x.canvasBg,overflowY:"auto",paddingTop:"0"}),z.el.style.display="none",le.appendChild(z.el),z)),cn):Promise.resolve(null)}let fn=0;const wt=["wheel","touchstart","pointerdown","keydown"];function ri(e,t){if(t<=0)return;let n=!1;const i=[],o=()=>{n=!0;for(const d of i)H.clearTimeout(d);i.length=0;for(const d of wt)e.removeEventListener(d,o)},s=()=>n||!ie?!0:(e.scrollTop=t,e.scrollTop>=t);if(!s()){for(const d of wt)e.addEventListener(d,o,{passive:!0,once:!0});for(const d of[0,50,150,300,600])i.push(H.setTimeout(()=>{s()},d));i.push(H.setTimeout(()=>{for(const d of wt)e.removeEventListener(d,o)},700))}}function Ie(e){if(!Oe)return;const t=ie;ie=e,z&&!e&&t&&(fn=z.el.scrollTop),z&&(z.el.style.display=e?"flex":"none"),F&&(F.style.display=e||$e?"none":"flex"),T&&(T.style.display=e?"none":"flex"),J&&(J.style.display=ye?"none":"flex"),oe&&(oe.style.display="flex"),V&&(V.style.display=Ct?"none":""),ve(),Z&&e&&Z.collapse(),it(),A&&(A.innerHTML=e?jn.wafer:jn.analysis,A.ariaLabel=e?"Back to wafer view":"Insights"),e&&ai().then(n=>{!n||!ie||(n.el.style.display="flex",n.render(),ri(n.el,fn))})}Oe&&ht?.defaultOpen&&queueMicrotask(()=>Ie(!0));let m,pn,Y=null,k=null,St=[],Mt;function un(e){Mt!==e&&(Mt=e,v())}let We=null,Et=ae.legendOffset??{x:0,y:0},He=!1,xe=!1,Fe={x:0,y:0},Dt={x:0,y:0},me=!1,Ce=!1,X="pan",we={x:0,y:0},qe={x:0,y:0},O={x:0,y:0},P={x:0,y:0},Ae=!1,Se=!1;function Ve(){const e=c;m=vi($,te.filter(io),{plotMode:e.plotMode,binColorScheme:e.binColorScheme,valueColorScheme:e.valueColorScheme,reverseValueScheme:e.reverseValueScheme,useDefinedBinColors:e.useDefinedBinColors,binColors:e.binColors??lo(te,{passBins:Ze,binColorScheme:e.binColorScheme,hbinDefs:G,sbinDefs:U,useDefinedBinColors:e.useDefinedBinColors}),passBins:Ze,showDieLabels:e.showDieLabels,showPartialDies:e.showPartialDies,showRingBoundaries:e.showRingBoundaries,showQuadrantBoundaries:e.showQuadrantBoundaries,showReticle:e.showReticle,showXYIndicator:e.showXYIndicator,reticles:ln,ringCount:e.ringCount,highlightBin:e.highlightBin,highlightMetadataValue:e.highlightMetadataValue,activeTest:e.activeTest,activeMetadataKey:e.activeMetadataKey,testDefs:ne,valueRange:e.valueRange,metadataValueOrder:e.metadataValueOrder,logScale:e.logScale,isLotStack:bt,aggregationMethod:vt??e.aggregationMethod,lotSize:xt??e.lotSize,dataAxisFlip:rn,colorbarRangeMode:e.colorbarRangeMode,passFailDisplay:e.passFailDisplay,fallbackFormat:Pe,interactiveTransform:{rotation:e.rotation??0,flipX:e.flipX??!1,flipY:e.flipY??!1}},{hbinDefs:G,sbinDefs:U,metadataFields:ce}),pn=new Map(m.dies.map((n,i)=>[Be(n),i]));const t=e.binColors?null:ao(m.binColors,m.plotMode);t?.message!==Qe?.message&&(Qe=t,mt(),sn&&Bt())}Ve();let N=null,Me=null,Je=null,gn=C.findingsNotice,di={},R=null,fe=null;function ci(e){const{kind:t,index:n}=e.variable;D(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"?(Rt(i.dieKeys),D({highlightBin:i.bin})):(i.kind==="region"||i.kind==="dies")&&Rt(i.dieKeys)}function hn(e){Zi(e,{wafer:$,dies:te,yieldSummary:yt.yield,dataCoverage:yt.dataCoverage,hbinDefs:G,sbinDefs:U,testDefs:ne,statsSummary:re,warnings:nn?de:[],passBins:Ze,ringCount:c.ringCount??4,binColors:m.binColors,plotMode:c.plotMode??"hardBin",metadataShownElsewhere:Zt,fallbackFormat:Pe,activeFindingId:Je,findingsFilter:di,findingsNotice:gn,onFindingsFilterChange:pe,onSaveText:C.onSaveText,metadataFields:ce,dieListOptions:C.dieList,onFindingClick:(t,n)=>{Je===t.id?(Je=null,Rt([]),D({highlightBin:void 0})):(Je=t.id,ci(t)),pe()}})}function pe(){N&&hn(N)}function ze(){R&&hn(R)}if(Te?.placement){const e=Te.placement;N=$t(e,ge,g);const t=S.parentElement,n=S.nextSibling;Me=Gt(S,N,e),t?.insertBefore(Me,n),pe()}else if(re){const e=Te?.defaultOpen??!Le;R=$t("right",ge,g),R.style.display=e?"block":"none";const t=S.parentElement,n=S.nextSibling;fe=Gt(S,R,"right"),t?.insertBefore(fe,n),ze()}const w=Zn?Yn(g):null;let oe=null,L=null,F=null,T=null,et=null,I=null,tt=null,A=null,se=null,nt=null;sn=!0;function Bt(){if(!se||!nt)return;const e=de.length,t=e>0;if(se.style.display=t?"flex":"none",nt.style.display=t?"":"none",!t)return;const n=Ji(de[0]),i=`${e} data ${e===1?"warning":"warnings"}`;se.style.color=n==="error"?x.errText:x.warnText,se.ariaLabel=n==="error"?`${i} \u2014 the map may be positionally wrong`:i}let kt=null,mn=null,Lt=null,Tt=null,Ot=null,Pt=null;function Rt(e){E=new Set(e??[]),he&&he(Ft()),v()}function it(){if(!I)return;const e=!!(N??R);I.style.display=re&&e&&!ie?"flex":"none";const t=N??R,n=t?t.style.display!=="none":!1;re?.hasNotableFindings&&!n?I.style.color=x.findingIndicator:I.dataset.active||(I.style.color=x.icon)}if(Le){let p=function(B){X=B,i(Q,B==="zoom"),i(M,B==="pan"),et&&i(et,B==="select"),a.style.cursor=B==="pan"?"grab":"crosshair"};oe=g.createElement("div"),oe.dataset.wmapToolbar="single",Object.assign(oe.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:zn.control,boxShadow:ki.panel,pointerEvents:"auto"});const e=Yn(g),t=Pi(e),{makeBtn:n,setActive:i,makeSep:o,makeMenuRow:s,makeMenuSection:d,closeOpenMenu:r,getOpenMenu:l,setOpenMenu:f}=t;kt=r,mn=l,g.addEventListener("click",r,!0),F=g.createElement("div"),Object.assign(F.style,{display:$e?"none":"flex",alignItems:"center",gap:"0",flexWrap:"wrap",justifyContent:"flex-end"}),oe.appendChild(F);const h=n("download","Download PNG",ui);F.appendChild(h),F.appendChild(o());const Q=n("zoomMode","Zoom (drag to zoom region)",()=>p("zoom")),De=n("zoomIn","Zoom in",()=>Ee(a.clientWidth/2,a.clientHeight/2,1.2)),ee=n("zoomOut","Zoom out",()=>Ee(a.clientWidth/2,a.clientHeight/2,1/1.2)),ue=n("reset","Reset zoom (double-click)",()=>st());F.appendChild(Q),F.appendChild(De),F.appendChild(ee),F.appendChild(ue),F.appendChild(o());const M=n("pan","Pan (drag to move)",()=>p("pan"));if(F.appendChild(M),et=n("boxSelect","Select (drag to select dies)",()=>p("select")),F.appendChild(et),i(M,!0),gt!=="view-only"){let B=function(u){return u.plotMode!==(c.plotMode??"hardBin")?!1:u.plotMode==="value"?(c.activeTest??0)===(u.activeTest??0):u.plotMode==="metadata"?c.activeMetadataKey===u.activeMetadataKey:!0},Vt=function(u,b){u.activeTest!==void 0?D({plotMode:u.plotMode,activeTest:u.activeTest,activeMetadataKey:void 0,logScale:u.logScale}):u.activeMetadataKey!==void 0?D({plotMode:u.plotMode,activeTest:void 0,activeMetadataKey:u.activeMetadataKey,passFailDisplay:"off"}):D({plotMode:u.plotMode,activeTest:void 0,activeMetadataKey:void 0,passFailDisplay:"off"}),b.remove(),f(null),_e(q,!1)};L=g.createElement("div"),Object.assign(L.style,{display:"flex",alignItems:"center",gap:"0",flexWrap:"wrap",justifyContent:"flex-end"}),oe.appendChild(L),T=g.createElement("div"),Object.assign(T.style,{display:"flex",alignItems:"center",gap:"0"}),L.appendChild(T),T.appendChild(o());const lt=()=>{const u=l();u&&(u.remove(),f(null)),_e(q,!1)},q=n("mode","Plot mode",()=>{if(l()){lt();return}const u=te,b=m.testDefs,{testEntries:dt,binEntries:be,stackedEntries:Ne}=$i(u,b,{includeStacked:m.isLotStack}),Xt=(ce??[]).filter(Ke=>Gi(u,Ke.key)).map(Ui),je=Ri(q.getBoundingClientRect(),dt,be,Ne,B,Vt,{makeMenuRow:s,makeMenuSection:d},c.plotMode??"hardBin",q.ownerDocument.defaultView??window,Xt);Xn(q).appendChild(je),f(je),_e(q,!0),Nn(je,q,lt)});_e(q,!1);const{btn:at,sync:Xe}=Hi(t,()=>({...c,plotMode:c.plotMode??"hardBin"}),()=>li,D);Tt=Xe,Tt();const zt=Vi(t,()=>{const u=!!m.hasReticle,b=(c.plotMode??"hardBin")==="value",{testNumber:dt}=Nt(c.activeTest??0,m.testDefs),be=ct(m.testDefs,dt),Ne=b&&be!==void 0&&!jt(be),Xt=b&&!Ne&&(be?.limitLow!==void 0||be?.limitHigh!==void 0),je=b&&!Ne&&m.dies.some(Ke=>Di(Ke,dt,be)!==void 0);return ji(c,u,{functionalActive:Ne,hasLimits:Xt,hasRecorded:je,binMode:(c.plotMode??"hardBin")==="hardBin"||(c.plotMode??"hardBin")==="softBin"},Ke=>D(Ke))},()=>Ki(c)),{btn:Yt,sync:gi}=Ai(t,()=>c,u=>D({legendPosition:u}));Lt=gi,Lt();const Hn=()=>{const{testNumber:u}=Nt(c.activeTest??0,ne),b=ct(ne,u);return b!==void 0&&!jt(b)},{btn:hi,sync:mi}=Fi(t,()=>({...c,functionalActive:Hn()}),u=>D(u));Ot=mi,Ot();const yi=()=>{const{testNumber:u}=Nt(c.activeTest??0,ne),b=ct(ne,u);return b!==void 0&&(b.limitLow!==void 0||b.limitHigh!==void 0)},rt=n("specRange","Colorbar range: spec limits",()=>{const u=c.colorbarRangeMode==="data"?"spec":"data";D({colorbarRangeMode:u})});Pt=()=>{const u=c.plotMode==="value"&&yi()&&Ni(c)==="off"&&!Hn();rt.style.display=u?"":"none";const b=(c.colorbarRangeMode??"spec")==="spec";i(rt,b),rt.ariaLabel=b?"Colorbar range: spec limits (click for data range)":"Colorbar range: data range (click for spec limits)"},Pt();const bi=zi(t,()=>c,u=>D(u));Qn&&T.appendChild(q),T.appendChild(at),T.appendChild(hi),T.appendChild(rt),$e||(T.appendChild(o()),T.appendChild(zt),T.appendChild(o()),T.appendChild(Yt),T.appendChild(o()),T.appendChild(bi)),re&&(I=n("findings","Summary panel",()=>{const u=N??R;if(!u)return;const b=u.style.display!=="none";u.style.display=b?"none":"block",i(I,!b),it()}),L.appendChild(o()),L.appendChild(I),R?.style.display!=="none"&&i(I,!0),it()),nn&&(nt=o(),se=n("warning","Data warnings",()=>{const u=l();if(r(new MouseEvent("click")),u)return;const b=qi(se.getBoundingClientRect(),de,H);Xn(le).appendChild(b),f(b),Nn(b,se,()=>r(new MouseEvent("click")))}),_e(se,!1),L.appendChild(nt),L.appendChild(se),Bt()),Oe&&(L.appendChild(o()),A=n("analysis","Insights",()=>{Ie(!ie),i(A,ie)}),A.dataset.wmapInsightsBtn="1",L.appendChild(A)),en&&(L.appendChild(o()),J=n("expand","Expand (E)",Jt??yn),L.appendChild(J)),qt&&(L.appendChild(o()),tt=n("help","User guide",()=>At()),L.appendChild(tt))}_.appendChild(oe),ve()}let ye=null;function yn(){ye&&(ye.close(),ye=null);const e=le;e.style.flex="1",e.style.minWidth="0",e.style.minHeight="0";const t=e.style.maxWidth,n=e.style.maxHeight;e.style.maxWidth="none",e.style.maxHeight="none";const i=Ut($.metadata??{},Re()),o=_.childElementCount>0?[_,e]:[e],s=Ii(o,{ownerDocument:g,boxSize:ie?{width:"min(96vw, 1600px)",height:"min(92vh, 1000px)"}:void 0,onClosed:()=>{ye=null,e.style.maxWidth=t,e.style.maxHeight=n,J&&(J.style.display="flex"),ie||a.focus({preventScroll:!0})}});s&&(s.box.setAttribute("aria-label",i??"Expanded wafer map"),o.length>1&&(s.contentWrap.style.flexDirection="column"),ye=s,J&&(J.style.display="none"))}function bn(e){const t=c.plotMode;c={...c,...e},e.plotMode!==void 0&&e.plotMode,Object.keys(e).every(s=>s==="legendPosition"||s==="showLegend"||s==="markFailingDies")||Ve(),Lt?.(),Tt?.(),Ot?.(),Pt?.(),v();const i=e.plotMode!==void 0&&e.plotMode!==t,o=COLOR_KEYS.some(s=>s in e);(o||i)&&(pe(),ze()),(o||i||e.activeTest!==void 0||e.logScale!==void 0||e.colorbarRangeMode!==void 0)&&Ge?.()}function D(e){bn(e);const t=Object.keys(e);Un?.(c,t,classifyChanged(t))}let It=!1;function Wt(){It||(It=!0,_t(()=>{It=!1,v()},H))}function v(){const e=k??void 0,t=m.dies[0],n=t?{x:t.width,y:t.height}:ae.diePitchMm,i=Math.floor(a.clientWidth||a.width),o=!!(G?.length||U?.length||m.dies.some(h=>h.hbin!=null||h.sbin!=null)),s=c.legendPosition??"default",d=c.showLegend??!0,r=s==="default"||s==="compact",l=(ae.colorbarWidth??16)+28,f=o&&r?s!=="default"?Math.max(Fn,l):i<Mi?0:i<Si?Math.max(wi,l):Math.max(Fn,l):void 0,p=Ci(a,m,{...ae,topClearance:0,minRightReserve:d?f:0,showColorbar:d&&(ae.showColorbar??!0),markFailingDies:c.markFailingDies??!1,legendPosition:s,legendOffset:Et,diePitchMm:n,fallbackFormat:Pe,showAxes:ae.showAxes??k!==null,viewport:e,activeBin:c.plotMode==="metadata"?c.highlightMetadataValue:c.highlightBin,hoverBin:Mt,hbinDefs:G,sbinDefs:U,metadataFields:ce});St=p.binLegendRows,We=p.legendBox??null,k===null&&(Y=p.viewport),E.size>0&&fi(),Ce&&pi()}function fi(){const e=j();if(!e)return;const t=a.getContext("2d"),n=m.hoverPoints,i=m.rectangles[0],o=i?i.width/2*e.ppm:e.ppm*.5,s=i?i.height/2*e.ppm:e.ppm*.5,d=Math.max(1,Math.min(3,o*.08)),r=o-d,l=s-d,f=[];for(const p of E){const h=pn.get(p);h!==void 0&&f.push({sx:e.originX+n[h].x*e.ppm,sy:e.originY-n[h].y*e.ppm})}if(f.length){t.save(),t.setLineDash([]),t.fillStyle="rgba(0,0,0,0.12)",t.beginPath();for(const{sx:p,sy:h}of f)t.rect(p-r,h-l,r*2,l*2);t.fill(),t.strokeStyle="rgba(255,255,255,0.9)",t.lineWidth=3,t.beginPath();for(const{sx:p,sy:h}of f)t.rect(p-r,h-l,r*2,l*2);t.stroke(),t.strokeStyle="rgba(0,0,0,0.9)",t.lineWidth=1.5,t.beginPath();for(const{sx:p,sy:h}of f)t.rect(p-r,h-l,r*2,l*2);t.stroke(),t.restore()}}function pi(){const e=a.getContext("2d"),t=Math.min(O.x,P.x),n=Math.min(O.y,P.y),i=Math.abs(P.x-O.x),o=Math.abs(P.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 ui(){a.toBlob(e=>{e&&Yi(e,C.downloadFilename??"wafermap",C.onSaveImage)})}function vn(e){return Y?Math.max(Y.ppm*qn,Math.min(Y.ppm*Jn,e)):e}function Ee(e,t,n){const i=k??Y;if(!i)return;const o=vn(i.ppm*n),s=o/i.ppm,d=e-(e-i.originX)*s,r=t-(t-i.originY)*s,l=(Y?.snapDist??1)/(o/(Y?.ppm??o));k={originX:d,originY:r,ppm:o,snapDist:l},v()}function j(){return k??Y}function xn(e){if(e.ctrlKey||e.metaKey){e.preventDefault();const t=a.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=j(),n=k.snapDist;k={originX:t.originX-e.deltaX,originY:t.originY-e.deltaY,ppm:t.ppm,snapDist:n},v()}}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||!j())return;a.focus({preventScroll:!0}),a.setPointerCapture(e.pointerId);const t=a.getBoundingClientRect(),n=e.clientX-t.left,i=e.clientY-t.top;if(We&&c.legendPosition==="floating"&&Cn(n,i,We)){xe=!0,Fe={x:n,y:i},Dt={...Et};return}if(Ae&&X!=="pan"){Se=!0,me=!0,we={x:n,y:i},qe={x:j().originX,y:j().originY},a.style.cursor="grabbing";return}if(X==="zoom"||X==="select"){Ce=!0,O=P={x:n,y:i};return}me=!0,we={x:n,y:i},qe={x:j().originX,y:j().originY},a.style.cursor="grabbing"}function Sn(e){const t=a.getBoundingClientRect(),n=e.clientX-t.left,i=e.clientY-t.top;if(Ce){P={x:n,y:i},Wt();return}if(xe){const p=n-Fe.x,h=i-Fe.y;p*p+h*h>16&&(xe=!1,He=!0,a.style.cursor="grabbing")}if(He){Et={x:Dt.x+(n-Fe.x),y:Dt.y+(i-Fe.y)},Wt();return}if(me){const p=j(),h=k?.snapDist??Y?.snapDist??1;k={originX:qe.x+(n-we.x),originY:qe.y+(i-we.y),ppm:p.ppm,snapDist:h},Wt();return}const o=j();if(!o)return;const s=(n-o.originX)/o.ppm,d=(o.originY-i)/o.ppm,l=Bn(s,d,o.snapDist)?.die??null,f=St.find(p=>n>=p.x&&n<p.x+p.w&&i>=p.y&&i<p.y+p.h);if(un(f?f.bin:void 0),f){a.style.cursor="pointer",w&&(w.innerHTML=f.label??`Bin ${f.bin}`,w.style.display="block",Kt(w,a,e.clientX,e.clientY)),Ue?.(null,e);return}if(X==="pan"&&(a.style.cursor=l?"crosshair":"grab"),w)if(l)if(Qt){const p=Qt(l);p===null?w.style.display="none":(typeof p=="string"?w.innerHTML=p:(w.innerHTML="",w.appendChild(p)),w.style.display="block",Kt(w,a,e.clientX,e.clientY))}else w.innerHTML=xi(l,m.plotMode,{testDefs:ne,hbinDefs:G,sbinDefs:U,fallbackFormat:Pe,aggrMethod:m.aggrMethod,lotSize:m.lotSize,metadataFields:ce,activeTest:m.activeTest,reticleConfig:an}),w.style.display="block",Kt(w,a,e.clientX,e.clientY);else w.style.display="none";Ue?.(l,e)}function Mn(e){const t=a.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,P={x:n,y:i};const r=n-O.x,l=i-O.y,f=j();if(X==="zoom"){if(r*r+l*l<25)Ee(n,i,2);else if(f){const p=Math.min(O.x,P.x),h=Math.max(O.x,P.x),Q=Math.min(O.y,P.y),De=Math.max(O.y,P.y),ee=h-p,ue=De-Q;if(ee>4&&ue>4){const M=a.clientWidth,B=a.clientHeight,Vt=M/ee,lt=B/ue,q=Math.min(Vt,lt),at=vn(f.ppm*q),Xe=at/f.ppm,zt=(p+h)/2,Yt=(Q+De)/2;k={originX:M/2-(zt-f.originX)*Xe,originY:B/2-(Yt-f.originY)*Xe,ppm:at,snapDist:f.snapDist/Xe}}}v(),a.style.cursor="crosshair";return}if(r*r+l*l<25)Ht(n,i,o,e);else if(f){const p=(Math.min(O.x,P.x)-f.originX)/f.ppm,h=(Math.max(O.x,P.x)-f.originX)/f.ppm,Q=(f.originY-Math.max(O.y,P.y))/f.ppm,De=(f.originY-Math.min(O.y,P.y))/f.ppm,ee=m.hoverPoints,ue=[];for(let M=0;M<ee.length;M++)if(ee[M].x>=p&&ee[M].x<=h&&ee[M].y>=Q&&ee[M].y<=De){const B=m.dies[M];B&&ue.push(B)}if(o)for(const M of ue){const B=Be(M);E.has(B)?E.delete(B):E.add(B)}else E=new Set(ue.map(M=>Be(M)));he?.(Ft())}v(),a.style.cursor="crosshair";return}if(xe){xe=!1,Ht(n,i,o,e);return}if(He){He=!1,a.style.cursor="grab";return}if(!me)return;if(me=!1,Se){Se=!1,a.style.cursor=Ae||X==="pan"?"grab":"crosshair";return}a.style.cursor=X==="pan"?"grab":"crosshair";const s=n-we.x,d=i-we.y;s*s+d*d<25&&Ht(n,i,o,e)}function Ht(e,t,n,i){for(const r of St)if(e>=r.x&&e<r.x+r.w&&t>=r.y&&t<r.y+r.h){if(typeof r.bin=="number"){const l=c.highlightBin===r.bin?void 0:r.bin;D({highlightBin:l})}else{const l=c.highlightMetadataValue===r.bin?void 0:r.bin;D({highlightMetadataValue:l})}return}if(We&&Cn(e,t,We))return;const o=j();if(!o)return;const d=Bn((e-o.originX)/o.ppm,(o.originY-t)/o.ppm,o.snapDist)?.die??null;if(d){Gn?.(d,i);const r=Be(d);n?E.has(r)?E.delete(r):E.add(r):E=new Set([r]),he?.(Ft()),v()}else n||(E=new Set,he?.([]),v())}function Ft(){const e=[],t=m.hoverPoints;for(let n=0;n<t.length;n++){const i=m.dies[n];i&&E.has(Be(i))&&e.push(i)}return e}function En(){un(void 0),w&&pt(g),Ue?.(null,new MouseEvent("mouseleave")),a.style.cursor=X==="pan"?"grab":"crosshair"}function Dn(){me=!1,Se=!1,Ce=!1,xe=!1,He=!1,w&&pt(g),Ue?.(null,new MouseEvent("mouseleave")),a.style.cursor=X==="pan"?"grab":"crosshair",v()}function Bn(e,t,n){const i=m.hoverPoints,o=m.rectangles;for(let l=0;l<o.length;l++){const f=o[l];if(Math.abs(e-f.x)<=f.width/2&&Math.abs(t-f.y)<=f.height/2){const p=m.dies[l];return p?{die:p,index:l}:null}}let s=null,d=-1,r=n*n;for(let l=0;l<i.length;l++){const f=i[l].x-e,p=i[l].y-t,h=f*f+p*p;h<r&&(r=h,s=m.dies[l]??null,d=l)}return s?{die:s,index:d}:null}const kn=new H.ResizeObserver(()=>{Y=null,k=null,v()});kn.observe(a),C.height==null&&$n<=0&&_t(()=>_t(()=>{K.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 Ye=H.matchMedia(`(resolution: ${H.devicePixelRatio}dppx)`);const ot=()=>{Ye.removeEventListener("change",ot),Ye=H.matchMedia(`(resolution: ${H.devicePixelRatio}dppx)`),Ye.addEventListener("change",ot),v()};Ye.addEventListener("change",ot);const Ln=H.matchMedia("(prefers-color-scheme: dark)"),Tn=()=>v();Ln.addEventListener("change",Tn);const On=()=>{w&&pt(g)};H.addEventListener("blur",On);function Pn(e){if(e.key==="Escape"&&E.size>0&&(E=new Set,he?.([]),v()),(e.key==="e"||e.key==="E")&&gt!=="view-only"&&en&&(e.stopPropagation(),(Jt??yn)()),(e.ctrlKey||e.metaKey)&&(e.key==="="||e.key==="+"?(e.preventDefault(),Ee(a.clientWidth/2,a.clientHeight/2,1.2)):e.key==="-"?(e.preventDefault(),Ee(a.clientWidth/2,a.clientHeight/2,1/1.2)):e.key==="0"&&(e.preventDefault(),st())),!e.ctrlKey&&!e.metaKey&&!e.shiftKey){const n=j();if(n){const i=k?.snapDist??Y?.snapDist??1;let o=0,s=0;e.key==="ArrowLeft"&&(o=20,e.preventDefault()),e.key==="ArrowRight"&&(o=-20,e.preventDefault()),e.key==="ArrowUp"&&(s=20,e.preventDefault()),e.key==="ArrowDown"&&(s=-20,e.preventDefault()),(o||s)&&(k={originX:n.originX+o,originY:n.originY+s,ppm:n.ppm,snapDist:i},v())}e.key===" "&&!Ae&&(e.preventDefault(),Ae=!0,X!=="pan"&&(a.style.cursor="grab"))}}function Rn(e){e.key===" "&&(Ae=!1,Se&&(me=!1,Se=!1),a.style.cursor=X==="pan"?"grab":"crosshair")}a.style.cursor="grab",a.setAttribute("tabindex","0"),a.addEventListener("wheel",xn,{passive:!1}),a.addEventListener("pointerdown",wn),a.addEventListener("pointermove",Sn),a.addEventListener("pointerup",Mn),a.addEventListener("pointerleave",En),a.addEventListener("pointercancel",Dn);const In=()=>st();a.addEventListener("dblclick",In),a.addEventListener("keydown",Pn),a.addEventListener("keyup",Rn);const Wn=e=>{e.stopPropagation()};a.addEventListener("click",Wn),a.clientWidth,v(),Ge?.();function st(){Y=null,k=null,v()}function At(){import("./userGuideHtml.js").then(e=>Wi({buildWaferMap:Ei,renderWaferMap,renderWaferGallery:void 0,analyzeWaferMap:Bi},e.USER_GUIDE_HTML,ei,K))}return ve(),{setDies(e){te=e,Ve(),v(),N&&pe()},setResult(e){yt=e,$=e.wafer,te=e.dies,G=e.hbinDefs,U=e.sbinDefs,ne=e.testDefs,ce=e.metadataFields,ln=e.reticles?.length?e.reticles:void 0,an=e.reticleConfig,rn=e.view?.dataAxisFlip,bt=e.isLotStack,vt=e.aggrMethod,xt=e.lotSize,si(),Ve(),v(),N&&pe()},setOptions(e){bn(e)},getOptions(){return{...c}},resetZoom:st,setSelection(e){E=new Set(e.map(t=>Be(t))),v()},clearSelection(){E=new Set,he?.([]),v()},setFallbackFormat(e){Pe=e,Ve(),v()},setFindingsNotice(e){gn=e,N?pe():R&&ze()},setStatsSummary(e){if(re=e,mt(),Bt(),N)pe();else if(R)ze();else if(e&&!Te?.placement){const t=Te?.defaultOpen??!Le;R=$t("right",ge,g),R.style.display=t?"block":"none";const n=S.parentElement,i=S.nextSibling;fe=Gt(S,R,"right"),n?.insertBefore(fe,i),ze()}it()},setSummaryVisible(e){I&&(I.style.display=e?"flex":"none")},setViewControlsVisible(e){L&&(L.style.display=e?"flex":"none")},setExpandVisible(e){J&&(J.style.display=e?"flex":"none")},setHelpButtonVisible(e){tt&&(tt.style.display=e?"flex":"none")},setIdentityVisible(e){Ct=!e,V&&(V.style.display=e?"":"none"),ve()},openUserGuide:At,setInsightsOpen(e){Ie(e),A&&(e?(A.dataset.active="1",A.style.background=x.bgActive,A.style.color=x.iconActive):(delete A.dataset.active,A.style.background="transparent",A.style.color=x.icon))},closeSummaryPanel(){const e=N??R;!e||e.style.display==="none"||(e.style.display="none",I&&(delete I.dataset.active,I.style.background="transparent",I.style.color=x.icon))},setTooltipParent(e){w&&Oi(e)},getActiveLegend(){const e=c.plotMode;if(e==="metadata"){const s=c.activeMetadataKey;if(!s)return null;const d=ce?.find(l=>l.key===s),r=[...new Set(te.map(l=>l.metadata?.[s]).filter(l=>l!=null&&(typeof l=="string"||typeof l=="number"||typeof l=="boolean")).map(String))].sort();return r.length?r.map((l,f)=>{const p=d?.values?.find(Q=>Q.value===l),h=p?.color??eo(f);return{bin:l,name:p?.label??l,color:h}}):null}if(e!=="hardBin"&&e!=="softBin")return null;const t=e==="hardBin",n=t?G:U,i=[...new Set(te.map(s=>t?s.hbin:s.sbin).filter(s=>s!==void 0))].sort((s,d)=>s-d);if(!i.length)return null;const o=t?m.binColors.hard:m.binColors.soft;return i.map(s=>{const d=n?.find(r=>r.bin===s);return{bin:s,name:d?.name??`Bin ${s}`,color:o.get(s)??to}})},destroy(){ye?.close(),mn?.()?.remove(),kt&&g.removeEventListener("click",kt,!0),a.removeEventListener("wheel",xn),a.removeEventListener("pointerdown",wn),a.removeEventListener("pointermove",Sn),a.removeEventListener("pointerup",Mn),a.removeEventListener("pointerleave",En),a.removeEventListener("pointercancel",Dn),a.removeEventListener("dblclick",In),a.removeEventListener("keydown",Pn),a.removeEventListener("keyup",Rn),a.removeEventListener("click",Wn),kn.disconnect(),Ye.removeEventListener("change",ot),Ln.removeEventListener("change",Tn),H.removeEventListener("blur",On),ii(),w&&pt(g),oe?.remove(),Me&&(Me.parentElement?.insertBefore(S,Me),Me.remove()),fe&&(fe.parentElement?.insertBefore(S,fe),fe.remove()),S.remove(),a.style.cursor="",z?.destroy(),Z?.destroy(),ke.remove()}}}
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()}}}
@@ -90,19 +90,19 @@ export declare function buildYieldSection(yieldSummary: YieldSummary, dataCovera
90
90
  }, passBins?: number[]): HTMLDivElement;
91
91
  export declare function buildBinSection(dies: Die[], binDefs: BinDef[] | undefined, mode: 'hard' | 'soft',
92
92
  /**
93
- * The map's resolved colours for this bin type (`View.binColors.hard`/`.soft`),
94
- * so bars match die fills. Omitted ⇒ resolved here from `dies` with the
95
- * default palette — never a second colour rule.
93
+ * The map's resolved bin colours (`View.binColors`) — colours AND pass
94
+ * verdicts, so bars match die fills and pass rows sit where the map's legend
95
+ * puts them. Omitted ⇒ resolved here from `dies` — never a second rule.
96
96
  */
97
- binColors?: ReadonlyMap<number, string>,
97
+ binColors?: BinColors,
98
98
  /**
99
99
  * Precomputed counts (e.g. `StatsSummary.stats.hardBinCounts`/`.softBinCounts`,
100
100
  * already scoped to the yield-eligible population) — used directly instead
101
101
  * of re-walking `dies` when supplied.
102
102
  */
103
103
  precomputedCounts?: Record<number, number>,
104
- /** Pass bins, pinned to the top of the pareto ordering. See `binRows`. */
105
- passBins?: number[]): HTMLDivElement | null;
104
+ /** Used only to resolve colours and verdicts when `binColors` is omitted. */
105
+ passBins?: readonly number[]): HTMLDivElement | null;
106
106
  /**
107
107
  * The panels' bin section: identical bars to `buildBinSection`, wrapped in a
108
108
  * collapsible shell with a Hard/Soft selector.
@@ -134,7 +134,7 @@ export declare function buildBinBreakdownSection(params: {
134
134
  * precomputed bin counts exist (`hardBinCounts`/`softBinCounts` are
135
135
  * per-wafer only), so this scans the pooled `Die[]` directly, same as
136
136
  * `buildBinSection` does when it has no `precomputedCounts`. */
137
- export declare function buildLotBinSection(allDies: Die[], binDefs: BinDef[] | undefined, mode: 'hard' | 'soft', binColors?: ReadonlyMap<number, string>): HTMLDivElement | null;
137
+ export declare function buildLotBinSection(allDies: Die[], binDefs: BinDef[] | undefined, mode: 'hard' | 'soft', binColors?: BinColors): HTMLDivElement | null;
138
138
  /**
139
139
  * Region yield as ONE section with a Ring/Quadrant selector, replacing the two
140
140
  * always-on stacked sections (`Ring Yield` + `Quadrant Yield`) this used to render.
@@ -155,7 +155,8 @@ export declare function buildRegionYieldPanelSection(params: {
155
155
  diesByWafer: Die[][];
156
156
  allWafers: Wafer[];
157
157
  ringCount: number;
158
- passBins: number[];
158
+ /** One set for every wafer, or a lookup by index into `allWafers` — see `buildRegionYieldData`. */
159
+ passBins: readonly number[] | ((waferIndex: number) => readonly number[]);
159
160
  panel?: HTMLElement;
160
161
  }): HTMLDivElement | null;
161
162
  /** Lot overview — wafer count and mean (unweighted arithmetic mean of each
@@ -463,10 +464,12 @@ export declare function renderWaferSummaryContent(panel: HTMLDivElement, params:
463
464
  /** Render lot-level content into the panel. Clears existing content. */
464
465
  export declare function renderLotSummaryContent(panel: HTMLDivElement, params: {
465
466
  lotSummary: LotStatsSummary;
467
+ /** `passBins` on an item is that wafer's own (`WaferMapResult.passBins`) and wins over the top-level fallback. */
466
468
  items: Array<{
467
469
  label?: string;
468
470
  wafer?: Wafer;
469
471
  dies?: Die[];
472
+ passBins?: readonly number[];
470
473
  statsSummary?: StatsSummary;
471
474
  metadataFields?: MetadataFieldDef[];
472
475
  } | null>;
@@ -1,3 +1,3 @@
1
- import{isParametricTest as qt}from"../renderer/buildWaferMap.js";import{buildRingRegions as Vt,buildQuadrantRegions as Kt,buildRegionYieldData as Gt}from"../stats/regions.js";import{computeFunctionalYield as Ut}from"../stats/analyzeWaferMap.js";import{renderSummaryReportHtml as Qt,renderLotSummaryReportHtml as Xt}from"../stats/renderSummaryReport.js";import{buildFindingsNarrative as Zt}from"../stats/findingsNarrative.js";import{filterFindings as Jt}from"../stats/filterFindings.js";import{buildFacetTable as te,prettyKey as xt}from"../stats/facets.js";import{commonMetadata as yt}from"../stats/facets.js";import{resolveMetadataColumns as ee}from"../stats/metadataColumns.js";import{resolveBinColors as Ct}from"../renderer/binColors.js";import{NO_DATA_FILL as ne}from"../renderer/colorMap.js";import{describeWaferPopulation as wt,populationLabel as oe}from"../stats/population.js";import{buildWarningsBanner as mt,collectWarnings as St}from"./warnings.js";export{mt as buildWarningsBanner};import{fmt as vt,fmtAggregationMethod as ie,plainBinTerms as nt}from"../renderer/fmt.js";import{getUniqueTestNumbers as ae}from"../renderer/buildView.js";import{quantile as ot}from"../stats/math.js";import{buildCapabilityData as se}from"../stats/capability.js";import{sortBinsForDisplay as re}from"../stats/binPareto.js";import{poolFunctionalYield as le}from"../stats/testPassRate.js";import{makeLabeledSelect as $t,makeSegmented as ht}from"./charts/chartShell.js";import{SHADOW as kt,MOTION as Lt,LEADING as Q,TRACKING as rt,wireControlHover as q,controlStyle as lt,SPACE as y,RADIUS as O,FONT as F,CLR as B,sevColor as dt,openModal as Bt,openReportModal as Nt,saveTextFile as Ft,wireTooltip as it}from"./toolbar.js";import{buildDieListSection as de}from"./dieList.js";export{csvField}from"../core/utils.js";import{medianOfSorted as ce,csvField as ct}from"../core/utils.js";import{metadataDisplayValue as pe}from"../core/metadata.js";const ue=B.panelBg,Et=`1px solid ${B.menuBorder}`,fe="12px",Y=B.label,U=B.value,Rt="10px";function l(t,e,o,n=document){const i=n.createElement(t);return e&&Object.assign(i.style,e),o!==void 0&&(i.textContent=o),i}function J(t){return l("div",{fontSize:Rt,fontWeight:"700",letterSpacing:rt,textTransform:"uppercase",color:Y,marginBottom:y.sm},t)}const Tt=new WeakMap,Dt=["regionYield","testValues","functionalTests"];function pt(t){if(!t)return{collapsed:new Set(Dt),regionMode:"ring",waferSort:"slot"};let e=Tt.get(t);return e||(e={collapsed:new Set(Dt),regionMode:"ring",waferSort:"slot"},Tt.set(t,e)),e}function X(t,e=!0,o,n){const i=l("div"),d=pt(n?.panel);n?.stateKey&&n.panel&&(e=!d.collapsed.has(n.stateKey));const a=document.createElement("button");a.type="button",Object.assign(a.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:F.meta,color:Y,transition:`transform ${Lt.base}`,transform:e?"rotate(90deg)":"rotate(0deg)",display:"inline-block",lineHeight:Q.none,marginRight:"1px"},"\u25B6"),c=l("span",{fontSize:Rt,fontWeight:"700",letterSpacing:rt,textTransform:"uppercase",color:Y,flex:"1"},t);if(q(a,"bare"),a.setAttribute("aria-expanded",e?"true":"false"),a.appendChild(p),a.appendChild(c),o){const b=l("span",{fontSize:F.meta,fontWeight:"700",background:B.warnBg,color:B.warnText,borderRadius:O.pill,padding:"1px 5px"},o);a.appendChild(b)}const r=l("div");r.style.display=e?"block":"none";let s=e;if(a.addEventListener("click",()=>{s=!s,r.style.display=s?"block":"none",p.style.transform=s?"rotate(90deg)":"rotate(0deg)",a.setAttribute("aria-expanded",s?"true":"false"),n?.stateKey&&n.panel&&(s?d.collapsed.delete(n.stateKey):d.collapsed.add(n.stateKey))}),n?.control){const b=l("div",{display:"flex",alignItems:"center",gap:y.sm});a.style.width="auto",a.style.flex="1",b.appendChild(a);const u=()=>{r.innerHTML="",n.render?.(r)},v=n.control(u);v&&(v.style.marginBottom="6px",v.addEventListener("click",N=>N.stopPropagation()),b.appendChild(v)),i.appendChild(b)}else i.appendChild(a);return i.appendChild(r),n?.render?.(r),{outer:i,content:r}}function Mt(){return l("div",{height:"1px",background:B.separator,margin:`${fe} 0`,flexShrink:"0"})}function gt(t,e,o=B.barFill,n,i){const d=l("div",{marginBottom:"5px"}),a=l("div",{display:"flex",justifyContent:"space-between",fontSize:F.body,color:U,marginBottom:y.xxs}),p=l("span",{color:Y},t),c=l("span",{fontWeight:"600"},`${e.toFixed(1)}%`);a.appendChild(p),a.appendChild(c);const r=n!==void 0?n:Math.min(100,Math.max(0,e)),s=o,b=l("div",{position:"relative",height:"9px",background:B.bgActive,borderRadius:O.control,overflow:"hidden"}),u=l("div",{height:"100%",width:`${r}%`,background:s,borderRadius:O.control,transition:`width ${Lt.base}`});if(b.appendChild(u),i!==void 0){const v=l("div",{position:"absolute",top:"0",bottom:"0",left:`${i}%`,width:"2px",marginLeft:"-1px",background:B.value,opacity:"0.8"});b.appendChild(v)}return d.appendChild(a),d.appendChild(b),d}function At(){const t=l("div",{display:"flex",gap:y.sm,marginBottom:y.md});return t.finish=()=>{const e=t.lastElementChild;e&&Object.assign(e.style,{borderRight:"none",paddingRight:"0"})},t}function at(t,e,o){const n=l("div",{padding:`${y.xxs} ${y.md} ${y.xxs} 0`,borderRight:Et,textAlign:"center",flex:"1"}),i=l("div",{fontSize:F.heading,fontWeight:"700",color:U,lineHeight:Q.tight},t),d=l("div",{fontSize:F.body,color:Y,marginTop:y.xxs},e);return n.appendChild(i),n.appendChild(d),o&&n.appendChild(l("div",{fontSize:F.body,color:Y,opacity:"0.85"},o)),n}function It(t,e){const o=l("div",{display:"flex",justifyContent:"space-between",fontSize:F.body,gap:y.md,marginBottom:"3px"}),n=l("span",{color:Y,flexShrink:"0"},t),i=l("span",{color:U,textAlign:"right",fontWeight:"500",wordBreak:"break-all"},e);return o.appendChild(n),o.appendChild(i),o}function me(t,e){const o=l("div",{display:"flex",fontSize:F.body,gap:y.sm,marginBottom:"3px"}),n=l("span",{color:Y,flexShrink:"0"},`${t}:`),i=l("span",{color:U,fontWeight:"500",wordBreak:"break-all"},e);return o.appendChild(n),o.appendChild(i),o}export function metadataEntries(t){const e=[];for(const[o,n]of Object.entries(t)){const i=pe(n);i!==void 0&&e.push([o,i])}return e}const he=["lot","product","testprogram","split"],ut=t=>{const e=he.indexOf(t.toLowerCase().replace(/[^a-z]/g,""));return e===-1?Number.MAX_SAFE_INTEGER:e};export function buildFacetSummaryChips(t,e=3){if(!t.length)return null;const o=l("div",{display:"flex",flexWrap:"wrap",alignItems:"baseline",gap:`${y.xs} ${y.lg}`}),n=[...t].sort((p,c)=>ut(p.key)-ut(c.key)),i=n.filter(p=>ut(p.key)!==Number.MAX_SAFE_INTEGER),d=n.filter(p=>ut(p.key)===Number.MAX_SAFE_INTEGER),a=p=>{const c=l("span",{whiteSpace:"nowrap"}),r=l("span",{color:Y},`${xt(p.key)}: `);c.appendChild(r);const s=p.values.slice(0,e),b=p.values.length-s.length;let u=s.map(v=>v.value).join(", ");return b>0&&(u+=` +${b} more`),c.appendChild(document.createTextNode(u)),c};for(const p of i)o.appendChild(a(p));if(d.length){const p=l("span",{display:"none",flexWrap:"wrap",alignItems:"baseline",gap:`${y.xs} ${y.lg}`});for(const s of d)p.appendChild(a(s));const c=l("button",{background:"none",border:"none",padding:"0",cursor:"pointer",color:B.iconActive,fontSize:F.body,whiteSpace:"nowrap"});c.type="button",q(c,"bare");const r=s=>{p.style.display=s?"contents":"none",c.textContent=s?"less":`+${d.length} more`,c.setAttribute("aria-expanded",String(s))};r(!1),c.addEventListener("click",()=>r(c.getAttribute("aria-expanded")!=="true")),o.appendChild(p),o.appendChild(c)}return o}export function buildMetadataStripRow(t,e,o){const n=te(t,o),i=buildFacetSummaryChips(n);if(!i&&!e)return null;const d=l("div",{display:"flex",flexWrap:"wrap",alignItems:"baseline",gap:"4px 14px"});if(e){const a=l("span",{fontWeight:"500",whiteSpace:"nowrap"},e.aggrMethod?`${e.lotSize} wafers stacked \xB7 ${e.aggrMethod}`:`${e.lotSize} wafers stacked`);d.appendChild(a)}return i&&d.appendChild(i),d}const ge={display:"flex",flexDirection:"column",gap:y.sm,background:B.menuBg,border:`1px solid ${B.menuBorder}`,borderRadius:O.container,padding:`${y.sm} ${y.lg}`,boxShadow:kt.panel,fontSize:F.body,lineHeight:Q.none,boxSizing:"border-box",width:"100%",minWidth:"0"};export function buildMetadataStripBox(t,e,o){const n=buildMetadataStripRow(t,e,o);if(!n)return null;const i=l("div",ge);return i.appendChild(n),i}export function buildCompactMetadataRows(t){const e=metadataEntries(t);if(!e.length)return null;const o=l("div");for(const[n,i]of e)o.appendChild(me(xt(n),i));return o}export function buildMetadataInfoSection(t,e){const o=buildMetadataStripRow(t,e,{facetableOnly:t.length>1});if(!o)return null;const n=l("div");return n.appendChild(J("Wafer Info")),n.appendChild(o),n}export function buildYieldSection(t,e,o=[1]){const n=l("div");n.appendChild(J("Summary"));const i=At();if(i.appendChild(at(String(t.totalDies),"Total dies")),t.partialDies>0&&i.appendChild(at(String(t.partialDies),"Partial")),t.yieldPercent!==null){const d=o.length===1?`bin ${o[0]}`:`bins ${o.join(", ")}`;i.appendChild(at(`${t.yieldPercent.toFixed(1)}%`,"Yield",`pass: ${d}`))}return i.finish(),n.appendChild(i),t.edgeExcludedDies>0&&n.appendChild(It("Edge excluded (outer zone)",String(t.edgeExcludedDies))),n}export function buildBinSection(t,e,o,n,i,d){const a=new Map;if(i)for(const[r,s]of Object.entries(i))a.set(Number(r),s);else for(const r of t){if(r.partial||r.edgeExcluded)continue;const s=o==="hard"?r.hbin:r.sbin;s!=null&&a.set(s,(a.get(s)??0)+1)}if(!a.size)return null;const p=n??be(t,o,e,d),c=l("div");c.appendChild(J(Wt(o,[...a.values()].reduce((r,s)=>r+s,0))));for(const r of Pt(a,e,p,d))c.appendChild(r);return c}function be(t,e,o,n){const i=Ct(t,{passBins:n,...e==="hard"?{hbinDefs:o}:{sbinDefs:o}});return e==="hard"?i.hard:i.soft}function Wt(t,e){return`${t==="hard"?"Hard":"Soft"} Bin Breakdown \u2014 % of dies (N=${e})`}function Pt(t,e,o,n=[1]){const i=[...t.values()].reduce((p,c)=>p+c,0),d=e?new Map(e.map(p=>[p.bin,p])):null;return re(t.entries(),n).map(([p,c])=>{const r=d?.get(p),s=r?.name?`Bin ${p} \xB7 ${r.name}`:`Bin ${p}`,b=c/i*100,u=o.get(p)??ne;return gt(`${s} (${c})`,b,u)})}export function buildBinBreakdownSection(t){const{dies:e,hbinDefs:o,sbinDefs:n,hardCounts:i,softCounts:d,plotMode:a,passBins:p=[1],panel:c}=t,r=t.binColors??Ct(e,{passBins:p,hbinDefs:o,sbinDefs:n}),s=m=>{const x=m==="hard"?i:d,w=new Map;if(x){for(const[$,L]of Object.entries(x))w.set(Number($),L);return w}for(const $ of e){if($.partial||$.edgeExcluded)continue;const L=m==="hard"?$.hbin:$.sbin;L!=null&&w.set(L,(w.get(L)??0)+1)}return w},b=s("hard"),u=s("soft"),v=b.size>0,N=u.size>0;if(!v&&!N)return null;const M=pt(c),W=a==="softBin"||a==="stackedSoftBins"?"soft":a==="hardBin"||a==="stackedBins"?"hard":void 0;let E=M.binMode??W??(v?"hard":"soft");E==="hard"&&!v&&(E="soft"),E==="soft"&&!N&&(E="hard");const H=E==="hard"?b:u,h=E==="hard"?o:n,f=[...H.values()].reduce((m,x)=>m+x,0),{outer:S}=X(Wt(E,f),!0,void 0,{stateKey:"bins",panel:c,render:m=>{const x=E==="hard"?r.hard:r.soft;for(const w of Pt(H,h,x,p))m.appendChild(w)},control:v&&N&&c?()=>ht([["hard","Hard"],["soft","Soft"]],E,m=>{M.binMode=m;const x=buildBinBreakdownSection(t);x&&S.replaceWith(x)},c.ownerDocument,!0):void 0});return S}export function buildLotBinSection(t,e,o,n){return buildBinSection(t,e,o,n)}export function buildRegionYieldPanelSection(t){const{diesByWafer:e,allWafers:o,ringCount:n,passBins:i,panel:d}=t,a=pt(d),p=s=>Gt(e,o,n,i,s==="ring"?Vt:Kt);if(!p("ring").length&&!p("quadrant").length)return null;const c=a.regionMode,{outer:r}=X(c==="ring"?"Ring Yield":"Quadrant Yield",!0,void 0,{stateKey:"regionYield",panel:d,render:s=>{const b=p(c);if(!b.length){s.appendChild(l("div",{fontSize:F.body,color:Y},"No positioned dies for this breakdown."));return}for(const{label:u,n:v,yieldPercent:N}of b)s.appendChild(gt(`${u} (N=${v})`,N))},control:d?()=>ht([["ring","Ring"],["quadrant","Quadrant"]],c,s=>{a.regionMode=s;const b=buildRegionYieldPanelSection(t);b&&r.replaceWith(b)},d.ownerDocument,!0):void 0});return r}export function buildLotOverviewSection(t,e=[]){const o=l("div"),n=wt(t.perWafer.map(a=>a.summary.wafer));o.appendChild(J(n.lotId!==void 0?"Lot Summary":"Summary"));const i=At();i.appendChild(at(String(t.stats.waferCount),"Wafers"));const d=t.perWafer.map(a=>a.summary.stats.yieldPercent).filter(a=>a!==null);if(d.length){const a=d.reduce((p,c)=>p+c,0)/d.length;i.appendChild(at(`${a.toFixed(1)}%`,"Mean per-wafer yield"))}if(i.finish(),o.appendChild(i),e.length){const a=e.reduce((c,r)=>c+r.stats.analyzedDies,0),p=e.reduce((c,r)=>c+r.stats.excludedDies,0);(a||p)&&o.appendChild(It("Dies analysed",p?`${a.toLocaleString()} (${p.toLocaleString()} excluded)`:a.toLocaleString()))}return o}export function buildPerWaferYieldSection(t,e,o,n,i){const d=t.perWafer.map(f=>({waferIndex:f.waferIndex,label:(e[f.waferIndex]?.label??`W${f.waferIndex+1}`).replace(/\s*·\s*\d+(\.\d+)?%$/,""),yieldPct:f.summary.stats.yieldPercent})).filter(f=>f.yieldPct!==null);if(!d.length)return null;const a=Math.min(...d.map(f=>f.yieldPct)),p=Math.max(...d.map(f=>f.yieldPct)),c=a===p?"":` (${a.toFixed(1)}\u2013${p.toFixed(1)}%)`,r=[...d.map(f=>f.yieldPct)].sort((f,S)=>f-S),s=ce(r),b=ot(r,.25),u=ot(r,.75),v=d.length>=5?b-1.5*(u-b):-1/0,N=pt(n),M=f=>{const S=N.waferSort==="yield"?[...d].sort((m,x)=>m.yieldPct-x.yieldPct):d;for(const{waferIndex:m,label:x,yieldPct:w}of S){const L=w<v?`${x} \xB7 low outlier`:x,R=gt(L,w,void 0,void 0,s),T=i?.(m);T?.total&&H(R,T),h(R,m,x,w,T),f.appendChild(R)}},W=` \xB7 median ${s.toFixed(1)}%`,{outer:E}=X("Wafer Yield"+c+W,!0,void 0,{stateKey:"waferYield",panel:n,render:M,control:n?f=>ht([["slot","Slot"],["yield","Yield"]],N.waferSort,S=>{N.waferSort=S,f()},n.ownerDocument,!0):void 0});return E;function H(f,S){const m=S.unusual?"unusual":S.notable?"notable":"info",x=l("span",{marginLeft:y.sm,flexShrink:"0",background:dt(m),color:"#fff",borderRadius:O.container,padding:"0 5px",fontSize:F.body,fontWeight:"600"},`${S.total}`);x.setAttribute("aria-hidden","true"),it(x,`${S.total} finding${S.total===1?"":"s"}`+(S.unusual?`, ${S.unusual} unusual`:"")+(S.notable?`, ${S.notable} notable`:"")),f.firstElementChild?.firstElementChild?.appendChild(x)}function h(f,S,m,x,w){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",`${m}, ${x.toFixed(1)}% yield`+(w?.total?`, ${w.total} finding${w.total===1?"":"s"}${w.unusual?`, ${w.unusual} unusual`:""}`:"")+" \u2014 open wafer"),f.tabIndex=0,f.addEventListener("mouseenter",()=>{f.style.background=B.bgHover}),f.addEventListener("mouseleave",()=>{f.style.background=""}),f.addEventListener("focus",()=>{f.style.background=B.bgHover}),f.addEventListener("blur",()=>{f.style.background=""}),f.addEventListener("click",()=>o(S)),f.addEventListener("keydown",$=>{($.key==="Enter"||$.key===" ")&&($.preventDefault(),o(S))}))}}function xe(t){const e=[...t].sort((i,d)=>i-d),o=t.reduce((i,d)=>i+d,0)/t.length,n=t.reduce((i,d)=>i+(d-o)**2,0)/t.length;return{min:e[0],max:e[e.length-1],mean:o,count:t.length,stddev:Math.sqrt(n),median:ot(e,.5),q1:ot(e,.25),q3:ot(e,.75)}}function zt(t,e){if(!t)return[];const o=t.waferMetadata??(t.perWaferMetadata?yt(t.perWaferMetadata.map(n=>({metadata:n}))):void 0);return!o||!Object.keys(o).length?[]:ee({waferMetadata:o,waferKeys:"identity",waferPlacement:"csv",reservedLabels:e}).columns}function Ht(t){return t?.populationLabel?[{key:"population",label:"Population",scope:"wafer",constant:t.populationLabel,get:()=>t.populationLabel,csvOnly:!0}]:[]}export function buildTestSection(t,e,o,n,i,d,a,p,c="full"){const r=t.filter(g=>!g.partial&&!g.edgeExcluded),s=new Map((n?.perTestStats??[]).map(g=>[g.testNumber,g])),b=new Map((n?.testSpecYield??[]).map(g=>[g.testNumber,g]));let u;if(e?.length?u=e.filter(qt).map(g=>({testNumber:g.testNumber,name:g.name,unit:g.unit,limitLow:g.limitLow,limitHigh:g.limitHigh})):u=ae(r).map(C=>({testNumber:C,name:`Test ${C}`})),!u.length)return null;const v=u.filter(g=>r.some(C=>{const I=C.testValues?.[g.testNumber];return I!==void 0&&isFinite(I)}));if(!v.length)return null;const N=v.some(g=>g.limitLow!==void 0||g.limitHigh!==void 0),M=[];for(const g of v){const C=s.get(g.testNumber),I=C&&C.stddev!==void 0&&C.median!==void 0&&C.q1!==void 0&&C.q3!==void 0;let _;if(I){const k=C;_={testNumber:g.testNumber,min:k.min,max:k.max,mean:k.mean,count:k.count,stddev:k.stddev,median:k.median,q1:k.q1,q3:k.q3}}else{const k=r.map(D=>D.testValues?.[g.testNumber]).filter(D=>D!==void 0&&isFinite(D));if(!k.length)continue;_={testNumber:g.testNumber,...xe(k)}}let z=null,P=0;if(g.limitLow!==void 0||g.limitHigh!==void 0){const k=b.get(g.testNumber);if(k)({yieldPercent:z,totalDies:P}=k);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;P=D.length,z=D.length>0?(D.length-Z)/D.length*100:null}}M.push({entry:g,stats:_,specYieldPct:z,specN:P})}if(!M.length)return null;const W=new Map;if(a?.length&&e?.length)for(const g of se(a,e))g.hasSpec&&W.set(g.testNumber,g.ppk);const E=W.size>0,h=new Set(M.map(g=>g.stats.count)).size===1?M[0].stats.count:null,f=l("div"),S=l("div",{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:y.sm}),m=h!==null?` \xB7 N=${h.toLocaleString()}`:"",x=d?.populationLabel?`Test Values (${M.length}) \u2014 ${d.populationLabel}${m}`:`Test Values (${M.length})${m}`,w=J(x);w.style.marginBottom="0",S.appendChild(w);const $=document.createElement("button");$.type="button",$.textContent="Test values CSV",Object.assign($.style,{...lt("outlined")}),q($),$.addEventListener("click",()=>{const g=["Test","Unit","N","Min","Q1","Median","Mean","Q3","Max","StdDev"];E&&g.push("Ppk");const C=M.some(k=>k.specYieldPct!==null&&k.specN!==k.stats.count);N&&(g.push("LSL","USL","Spec Yield %"),C&&g.push("Spec Yield N"));const I=[...zt(d,g),...Ht(d)],z=[[...I.map(k=>k.label),...g].map(ct).join(",")],P=k=>vt(k,void 0,"engineering");for(const{entry:k,stats:D,specYieldPct:Z,specN:j}of M){const st=[...I.map(et=>et.constant??""),k.name,k.unit??"",String(D.count),P(D.min),P(D.q1),P(D.median),P(D.mean),P(D.q3),P(D.max),P(D.stddev)];if(E){const et=W.get(k.testNumber);st.push(et==null?"":et.toFixed(3))}N&&(st.push(k.limitLow!==void 0?P(k.limitLow):"",k.limitHigh!==void 0?P(k.limitHigh):"",Z!==null?Z.toFixed(1):""),C&&st.push(k.limitLow!==void 0||k.limitHigh!==void 0?String(j):"")),z.push(st.map(ct).join(","))}Ft(z.join(`
2
- `),"test-values.csv","text/csv",i)}),S.appendChild($),f.appendChild(S);const L=l("table",{width:"100%",borderCollapse:"collapse",fontSize:F.body}),R=document.createElement("thead"),T=document.createElement("tr"),A=["Test"];h===null&&A.push("N"),c==="full"&&A.push("Min","Q1","Median"),A.push("Mean"),c==="full"&&A.push("Q3","Max","StdDev"),E&&A.push("Ppk"),c==="full"&&N&&A.push("LSL","USL"),N&&A.push("Spec yield");for(const g of A){const C=l("th",{textAlign:g==="Test"?"left":"right",fontWeight:"600",fontSize:F.meta,letterSpacing:rt,textTransform:"uppercase",color:Y,padding:"3px 8px 5px",borderBottom:`1px solid ${B.menuBorder}`,whiteSpace:"nowrap"},g);T.appendChild(C)}R.appendChild(T),L.appendChild(R);const V=document.createElement("tbody");for(const{entry:g,stats:C,specYieldPct:I,specN:_}of M){const z=D=>vt(D,g.unit,o),P=document.createElement("tr"),k=(D,Z="right")=>{const j=l("td",{textAlign:Z,padding:`${y.xs} ${y.md}`,borderBottom:`1px solid ${B.menuBorder}`,color:B.text,whiteSpace:"nowrap"},D);P.appendChild(j)};if(k(g.name,"left"),h===null&&k(`${C.count}`),c==="full"&&(k(z(C.min)),k(z(C.q1)),k(z(C.median))),k(z(C.mean)),c==="full"&&(k(z(C.q3)),k(z(C.max)),k(z(C.stddev))),E){const D=W.get(g.testNumber);k(D==null?"\u2014":D.toFixed(2))}c==="full"&&N&&(k(g.limitLow!==void 0?z(g.limitLow):"\u2014"),k(g.limitHigh!==void 0?z(g.limitHigh):"\u2014")),N&&k(I!==null?h!==null&&_===h?`${I.toFixed(1)}%`:`${I.toFixed(1)}% (N=${_})`:"\u2014"),V.appendChild(P)}L.appendChild(V);const K=l("div",{overflowX:"auto"});if(K.appendChild(L),!p)return f.appendChild(K),f;S.remove();const{outer:G}=X(x,!0,void 0,{stateKey:"testValues",panel:p,render:g=>g.appendChild(K),control:()=>$});return G}export function buildFunctionalTestSection(t,e,o,n,i,d){const a=o??Ut(t,e);if(!a?.length)return null;const c=new Set(a.map(m=>m.totalDies)).size===1?a[0].totalDies:null,r=c!==null?` \xB7 N=${c.toLocaleString()}`:"",s=l("div"),b=l("div",{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:y.sm}),u=i?.populationLabel?`Functional Tests (${a.length}) \u2014 ${i.populationLabel}${r}`:`Functional Tests (${a.length})${r}`,v=J(u);v.style.marginBottom="0",b.appendChild(v);const N=document.createElement("button");N.type="button",N.textContent="Functional CSV",Object.assign(N.style,{...lt("outlined")}),q(N),N.addEventListener("click",()=>{const m=["Test","N","Pass","Fail","Pass Rate %"],x=[...zt(i,m),...Ht(i)],w=[[...x.map($=>$.label),...m].map(ct).join(",")];for(const $ of a)w.push([...x.map(L=>L.constant??""),$.label,String($.totalDies),String($.passDies),String($.failDies),$.passRatePercent!==null?$.passRatePercent.toFixed(1):""].map(ct).join(","));Ft(w.join(`
3
- `),"functional-tests.csv","text/csv",n)}),b.appendChild(N),s.appendChild(b);const M=l("table",{width:"100%",borderCollapse:"collapse",fontSize:F.body}),W=document.createElement("thead"),E=document.createElement("tr"),H=c===null?["Test","N","Pass","Fail","Pass rate"]:["Test","Pass","Fail","Pass rate"];for(const m of H)E.appendChild(l("th",{textAlign:m==="Test"?"left":"right",fontWeight:"700",fontSize:F.body,letterSpacing:rt,textTransform:"uppercase",color:Y,padding:"3px 8px 5px",borderBottom:`1px solid ${B.menuBorder}`,whiteSpace:"nowrap"},m));W.appendChild(E),M.appendChild(W);const h=document.createElement("tbody");for(const m of a){const x=document.createElement("tr"),w=($,L="right")=>{x.appendChild(l("td",{textAlign:L,padding:`${y.xs} ${y.md}`,borderBottom:`1px solid ${B.menuBorder}`,color:U,whiteSpace:"nowrap"},$))};w(m.label,"left"),c===null&&w(String(m.totalDies)),w(String(m.passDies)),w(String(m.failDies)),w(m.passRatePercent!==null?`${m.passRatePercent.toFixed(1)}%`:"\u2014"),h.appendChild(x)}M.appendChild(h);const f=l("div",{overflowX:"auto"});if(f.appendChild(M),!d)return s.appendChild(f),s;b.remove();const{outer:S}=X(u,!0,void 0,{stateKey:"functionalTests",panel:d,render:m=>m.appendChild(f),control:()=>N});return S}export function buildLotFunctionalSection(t,e,o,n,i){const d=o?.length?{perWaferMetadata:o.map(p=>p.wafer??{}),populationLabel:`${o.length} wafer${o.length===1?"":"s"} pooled`}:void 0,a=le(o);return a?buildFunctionalTestSection(t,e,a,n,d,i):buildFunctionalTestSection(t,e,void 0,n,d,i)}const tt={unusual:0,notable:1,info:2};function bt(t){return l("span",{display:"inline-block",width:"7px",height:"7px",borderRadius:O.pill,background:dt(t),flexShrink:"0"})}function Yt(t,e){let o=t.summary;return e&&(o.startsWith(`${e} has `)?o=o.slice(e.length+5):o.startsWith(`${e} `)&&(o=o.slice(e.length+1))),o=nt(o),o.length?o[0].toUpperCase()+o.slice(1):o}export function buildFindingsSection(t,e,o,n,i=!1){if(!t.length)return null;const d=t.some(h=>h.severity==="unusual"||h.severity==="notable"),a=d?t.filter(h=>h.severity!=="info").length.toString():void 0,{outer:p,content:c}=i?(()=>{const h=l("div");return{outer:h,content:h}})():X(`Findings (${t.length})`,d,a);function r(h){return h.reduce((f,S)=>tt[S.severity]<tt[f]?S.severity:f,"info")}function s(h){const f=new Map;for(const m of h){const x=`${m.comparison.family}\0${m.comparison.left}`,w=f.get(x)??[];w.push(m),f.set(x,w)}const S=[...f.entries()].map(([m,x])=>{const w=[...x].sort(($,L)=>tt[$.severity]-tt[L.severity]);return{key:m,findings:w,worst:r(w)}});return S.sort((m,x)=>tt[m.worst]-tt[x.worst]),S}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=t.filter(h=>h.comparison.family==="spatial-pattern"),v=new Set([...u.flatMap(h=>h.relatedIds??[]),...t.flatMap(h=>h.absorbedIds??[])]),N=t.filter(h=>h.comparison.family!=="spatial-pattern"&&!v.has(h.id)),M=s(N);function W(h,f=!1,S){const m=n===h.id,x=document.createElement("button");return x.type="button",x.dataset.wmapFinding=h.id,x.textContent=Yt(h,S),it(x,h.summary),x.setAttribute("aria-current",m?"true":"false"),Object.assign(x.style,{border:`1px solid ${B.menuBorder}`,borderLeft:`3px solid ${dt(h.severity)}`,background:m?B.bgActive:B.menuBg,borderRadius:O.container,padding:f?"6px 10px":"8px 10px",textAlign:"left",fontSize:f?"10px":"11px",fontWeight:m?"600":"400",color:B.text,cursor:"pointer",width:"100%",marginBottom:y.xs}),q(x,"bare"),x.addEventListener("click",()=>o(h,x)),x}const E=nt(Zt(t)??"");if(E){const h=l("div",{background:B.bgActive,borderRadius:O.container,padding:`${y.md} ${y.lg}`,marginBottom:y.md,display:"flex",gap:y.md,alignItems:"flex-start"}),f=l("span",{flex:"1",fontSize:F.body,lineHeight:Q.base,color:B.text},E);h.appendChild(f);const S=l("button",{flexShrink:"0",border:"none",background:"none",fontSize:F.body,color:B.icon,cursor:"pointer",padding:"0",lineHeight:Q.base,whiteSpace:"nowrap"},"Detail \u25B8");S.type="button",q(S,"bare"),S.addEventListener("click",()=>{const m=Bt({title:"Findings Summary",onClose:()=>{},anchor:S}),x=l("p",{fontSize:"16px",lineHeight:Q.base,color:B.text,padding:`${y.xxl} ${y.xxxl} ${y.xxl}`,margin:"0",borderBottom:`1px solid ${B.menuBorder}`,flexShrink:"0"},E);m.contentWrap.appendChild(x);const w=l("div",{overflowY:"auto",padding:`${y.xxl} ${y.xxxl}`,flex:"1"}),$=(L,R)=>{const T=l("div",{display:"flex",alignItems:"center",gap:"7px",fontSize:F.sub,fontWeight:"600",color:U,marginTop:y.lg,marginBottom:y.xs});return T.appendChild(bt(L)),T.appendChild(l("span",{},R)),T};for(const L of u){w.appendChild($(L.severity,L.comparison.left)),w.appendChild(l("div",{fontSize:F.body,color:B.text,padding:"4px 0 4px 15px",marginBottom:y.xxs},nt(L.summary)));const R=t.filter(T=>L.relatedIds?.includes(T.id));for(const T of R)w.appendChild(l("div",{fontSize:F.body,color:Y,padding:"2px 0 2px 23px",marginBottom:y.xxs},nt(T.summary)))}for(const L of M){const[R,T]=L.key.split("\0");w.appendChild($(L.worst,b(R,T)));for(const A of L.findings)w.appendChild(l("div",{fontSize:F.body,color:B.text,padding:"4px 0 4px 15px",marginBottom:y.xxs},Yt(A,T)))}m.contentWrap.appendChild(w),Object.assign(m.contentWrap.style,{flexDirection:"column",overflow:"hidden"})}),h.appendChild(S),c.appendChild(h)}let H=!0;for(const h of u){H||c.appendChild(l("div",{height:"1px",background:B.separator,margin:"4px 0"})),H=!1;const f=t.filter($=>h.relatedIds?.includes($.id)),S=f.length>0,m=l("div",{position:"relative",marginBottom:S?"2px":"4px"}),x=n===h.id,w=document.createElement("button");if(w.type="button",w.dataset.wmapFinding=h.id,Object.assign(w.style,{border:`1px solid ${B.menuBorder}`,borderLeft:`3px solid ${dt(h.severity)}`,background:x?B.bgActive:B.menuBg,borderRadius:O.container,padding:"8px 32px 8px 10px",textAlign:"left",fontSize:F.body,fontWeight:x?"600":"500",color:B.text,cursor:"pointer",width:"100%"}),w.textContent=nt(h.summary),it(w,h.summary),w.setAttribute("aria-current",x?"true":"false"),q(w,"bare"),w.addEventListener("click",()=>o(h,w)),m.appendChild(w),S){const $=l("div",{display:"none",paddingLeft:"12px",marginBottom:y.xs});for(const T of f)$.appendChild(W(T,!0));m.appendChild($);let L=!1;const R=l("button",{position:"absolute",top:"50%",right:"8px",transform:"translateY(-50%)",border:"none",background:"none",fontSize:F.body,color:B.icon,cursor:"pointer",padding:`${y.xxs} ${y.xs}`,lineHeight:Q.none},"\u25B8");q(R,"bare"),R.type="button",it(R),R.setAttribute("aria-label","Show supporting findings"),R.setAttribute("aria-expanded","false"),R.addEventListener("click",T=>{T.stopPropagation(),L=!L,$.style.display=L?"block":"none",R.textContent=L?"\u25BE":"\u25B8";const A=L?"Hide supporting findings":"Show supporting findings";R.setAttribute("aria-label",A),R.setAttribute("aria-expanded",String(L))}),m.appendChild(R)}c.appendChild(m)}for(const h of M){H||c.appendChild(l("div",{height:"1px",background:B.separator,margin:"4px 0"})),H=!1;const[f,S]=h.key.split("\0"),m=l("div",{display:"flex",alignItems:"center",gap:y.sm,fontSize:F.body,fontWeight:"600",color:U,margin:"2px 0 4px"});m.appendChild(bt(h.worst)),m.appendChild(l("span",{},b(f,S))),c.appendChild(m);for(const x of h.findings)c.appendChild(W(x,!1,S))}return p}const ye=[{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"}],Ce=[{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"}],we=["unusual","notable","info"],Se={unusual:"Unusual",notable:"Notable",info:"Info"};function ve(t,e,o){const n=l("div",{display:"flex",flexWrap:"wrap",alignItems:"center",gap:y.lg,marginBottom:y.lg,paddingBottom:"10px",borderBottom:`1px solid ${B.separator}`}),i={unusual:0,notable:0,info:0};for(const r of t)i[r.severity]++;const d=we.filter(r=>i[r]>0),a=new Set(e.severity===void 0?d:Array.isArray(e.severity)?e.severity:[e.severity]),p=l("div",{display:"flex",gap:y.xs,flexWrap:"wrap"});for(const r of d){const s=document.createElement("button");s.type="button";const b=()=>{const u=a.has(r);s.setAttribute("aria-pressed",u?"true":"false"),Object.assign(s.style,{display:"inline-flex",alignItems:"center",gap:"5px",border:`1px solid ${B.menuBorder}`,borderRadius:O.pill,background:u?B.bgActive:"none",opacity:u?"1":"0.5",color:B.text,fontSize:F.body,padding:`${y.xxs} ${y.md}`,cursor:"pointer"}),s.dataset.on=u?"true":"false"};s.appendChild(bt(r)),s.appendChild(l("span",{},`${Se[r]} ${i[r]}`)),it(s,()=>a.has(r)?"Click to hide these findings":"Click to show these findings"),b(),q(s,"bare"),s.addEventListener("click",()=>{a.has(r)?a.delete(r):a.add(r),e.severity=a.size===d.length?void 0:[...a],o()}),p.appendChild(s)}n.appendChild(p);const c=e.kind!==void 0||e.family!==void 0;return(t.length>=$e||c)&&(n.appendChild($t("Kind:",ye,e.kind??"",r=>{e.kind=r||void 0,o()},{maxWidth:"130px"})),n.appendChild($t("Region:",Ce,e.family??"",r=>{e.family=r||void 0,o()},{maxWidth:"150px"}))),n}const $e=8;function ke(t,e){const o=l("div",{display:"flex",flexDirection:"column",gap:y.xs,padding:y.md,marginBottom:y.md,background:B.bgHover,borderRadius:O.control},void 0,e);if(o.appendChild(l("div",{fontSize:F.body,color:B.value},t.message,e)),t.detail&&o.appendChild(l("div",{fontSize:F.meta,color:Y},t.detail,e)),t.actionLabel&&t.onAction){const n=l("button",lt("outlined"),t.actionLabel,e);n.type="button",n.style.alignSelf="flex-start",n.style.marginTop=y.xs,q(n),n.addEventListener("click",t.onAction),o.appendChild(n)}return o}export function buildFindingsSectionWithFilter(t,e,o,n,i,d,a){if(!t.findings.length&&!a)return null;const p=t.findings.some(N=>N.severity==="unusual"||N.severity==="notable"),c=p?t.findings.filter(N=>N.severity!=="info").length.toString():void 0,r=d?.ownerDocument??document,{outer:s,content:b}=X(`Findings (${t.findings.length})`,p||!!a,c,{stateKey:"findings",panel:d});if(a&&b.appendChild(ke(a,r)),!t.findings.length)return s;b.appendChild(ve(t.findings,n,i));const u=Jt(t,n);if(!u.length)return b.appendChild(l("div",{color:Y,fontSize:F.body,textAlign:"center",padding:`${y.xxl} ${y.md}`},"No findings match the current filter.")),s;const v=buildFindingsSection(u,t,e,o,!0);return v&&b.appendChild(v),s}export function buildLotTestSection(t,e,o,n,i,d,a,p="full"){const c=n?.length?{perWaferMetadata:n.map(s=>s.wafer??{}),populationLabel:`${n.length} wafer${n.length===1?"":"s"} pooled`}:void 0;let r;if(n?.length&&n.every(s=>s.stats.perTestStats!==void 0)){const s=new Map;for(const b of n)for(const u of b.stats.perTestStats??[]){const v=s.get(u.testNumber);v?(v.n+=u.count,v.sum+=u.mean*u.count,v.min=Math.min(v.min,u.min),v.max=Math.max(v.max,u.max)):s.set(u.testNumber,{n:u.count,sum:u.mean*u.count,min:u.min,max:u.max})}r={perTestStats:[...s.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(s=>s.stats.testSpecYield!==void 0)){const s=new Map;for(const b of n)for(const u of b.stats.testSpecYield??[]){const v=s.get(u.testNumber);v?(v.passDies+=u.passDies,v.totalDies+=u.totalDies):s.set(u.testNumber,{passDies:u.passDies,totalDies:u.totalDies})}r={...r,testSpecYield:[...s.entries()].map(([b,u])=>({testNumber:b,totalDies:u.totalDies,yieldPercent:u.totalDies>0?u.passDies/u.totalDies*100:null}))}}return buildTestSection(t,e,o,r,i,c,d,a,p)}export function createSummaryPanelEl(t,e,o=document){const n=t==="top"||t==="bottom",i=l("div",{background:ue,color:B.text,fontVariantNumeric:"tabular-nums",border:Et,borderRadius:O.container,padding:y.xl,overflowY:"auto",overflowX:n?"auto":"hidden",flexShrink:"0",boxSizing:"border-box",fontFamily:F.family,fontSize:F.sub,boxShadow:kt.panel},void 0,o);return t==="right"&&(i.style.marginRight=e),t==="left"&&(i.style.marginLeft=e),t==="bottom"&&(i.style.marginBottom=e),n?(i.style.height="180px",i.style.width="100%"):(i.style.width="300px",i.style.maxHeight="100%"),i}export function wrapWithSummaryPanel(t,e,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 t.style.flex="1 1 0",t.style.minWidth="0",t.style.minHeight="0",o==="right"||o==="bottom"?(i.appendChild(t),i.appendChild(e)):(i.appendChild(e),i.appendChild(t)),i}function Ot(t){return l("div",{fontSize:F.heading,fontWeight:"600",color:U,marginBottom:y.lg},t)}function ft(t,e){const o=l("button",lt("outlined"),t);return o.type="button",q(o),o.addEventListener("click",e),o}function _t(...t){const e=t.filter(n=>!!n);if(!e.length)return null;const o=l("div",{display:"flex",flexWrap:"wrap",gap:y.sm,marginBottom:y.lg});for(const n of e)o.appendChild(n);return o}function jt(t,e,o,n,i,d,a,p,c,r,s){const b=t.ownerDocument,u=Bt({title:"Die list",onClose:()=>{},anchor:t,ownerDocument:b});u.contentWrap.style.padding="14px 16px";const v=de(e,o,{...a,title:n,onSaveText:p,waferMetadata:i,metadataFields:d,extraColumn:c,getWafer:r,ringCount:s,ownerDocument:b});v&&u.contentWrap.appendChild(v)}export function renderWaferSummaryContent(t,e){const o=t.scrollTop;t.innerHTML="";const{wafer:n,dies:i,yieldSummary:d,dataCoverage:a,hbinDefs:p,sbinDefs:c,testDefs:r,statsSummary:s,passBins:b=[1],ringCount:u=4,binColors:v,plotMode:N,fallbackFormat:M,onFindingClick:W,activeFindingId:E=null,findingsFilter:H,onFindingsFilterChange:h,findingsNotice:f,onSaveText:S,metadataFields:m,dieListOptions:x,metadataShownElsewhere:w}=e;t.appendChild(Ot("Wafer Summary"));const $=e.warnings??St({statsSummary:s});$.length&&t.appendChild(mt($,t.ownerDocument));const L=d&&a?ft("Summary report",()=>{Nt(Qt({wafer:n,dies:i,yieldSummary:d,dataCoverage:a,hbinDefs:p,sbinDefs:c,testDefs:r,statsSummary:s,passBins:b,ringCount:u}),{anchor:t})}):null,R=(x?.enabled??!0)&&i.length?ft("View die list",()=>{jt(t,i,r,`Die list \u2014 ${i.length} dies`,n.metadata,m,x,S,void 0,()=>n,u)}):null,T=_t(L,R);T&&t.appendChild(T);const A=[],V=s?.stats.isLotStack?s.stats:void 0,K=V?.lotSize!==void 0?{lotSize:V.lotSize,aggrMethod:ie(V.aggregationMethod)}:void 0;w||A.push(buildMetadataInfoSection([{metadata:n.metadata??void 0}],K)),d&&a&&A.push(buildYieldSection(d,a,b)),s&&W&&H&&h&&A.push(buildFindingsSectionWithFilter(s,W,E,H,h,t,f)),A.push(buildBinBreakdownSection({dies:i,hbinDefs:p,sbinDefs:c,binColors:v,hardCounts:s?.stats.hardBinCounts,softCounts:s?.stats.softBinCounts,plotMode:N,passBins:b,panel:t})),A.push(buildRegionYieldPanelSection({diesByWafer:[i],allWafers:[n],ringCount:u,passBins:b,panel:t}));const G=n.metadata?{waferMetadata:n.metadata}:void 0;A.push(buildTestSection(i,r,M,s?.stats,S,G,[{dies:i}],t,"compact")),A.push(buildFunctionalTestSection(i,r,s?.stats.functionalYield,S,G,t));let g=!0;for(const C of A)C&&(g||t.appendChild(Mt()),g=!1,t.appendChild(C));t.appendChild(l("div",{height:"12px",flexShrink:"0"})),t.scrollTop=o}export function renderLotSummaryContent(t,e){const o=t.scrollTop;t.innerHTML="";const{lotSummary:n,items:i,hbinDefs:d,sbinDefs:a,testDefs:p,passBins:c=[1],ringCount:r=4,binColors:s,plotMode:b,fallbackFormat:u,onFindingClick:v,activeFindingId:N=null,onWaferClick:M,findingsFilter:W,onFindingsFilterChange:E,findingsNotice:H,onSaveText:h,dieListOptions:f,findingsFor:S}=e;t.appendChild(Ot(`Summary \u2014 ${oe(wt(n.perWafer.map(C=>C.summary.wafer)))}`));const m=e.warnings??St({lotStatsSummary:n});m.length&&t.appendChild(mt(m,t.ownerDocument));const x=ft("Summary report",()=>{Nt(Xt({items:i.map((C,I)=>({label:C?.label??`W${I+1}`,wafer:C?.wafer,dies:C?.dies,statsSummary:C?.statsSummary})),hbinDefs:d,sbinDefs:a,testDefs:p,passBins:c,ringCount:r}),{anchor:t})}),w=[],$=[],L=[],R=new WeakMap,T=new WeakMap;for(let C=0;C<i.length;C++){const I=i[C];if(!I){$.push([]);continue}I.wafer&&w.push(I.wafer);const _=I.dies??[],z=I.label??`W${C+1}`;for(const P of _)R.set(P,z),I.wafer&&T.set(P,I.wafer);$.push(_),L.push(..._)}const A=f?.enabled??!0?ft("View die list",()=>{L.length&&jt(t,L,p,`Die list \u2014 ${L.length} dies across ${i.length} wafer${i.length===1?"":"s"}`,yt(i.filter(C=>!!C).map(C=>({metadata:C.wafer?.metadata}))),i.find(C=>C?.metadataFields?.length)?.metadataFields,f,h,{label:"Wafer",get:C=>R.get(C)},C=>T.get(C),r)}):null,V=_t(x,A);V&&t.appendChild(V);const K=i.map(C=>C?.statsSummary).filter(C=>!!C),G=[buildLotOverviewSection(n,K)];v&&W&&E&&G.push(buildFindingsSectionWithFilter(n,v,N,W,E,t,H)),G.push(buildPerWaferYieldSection(n,i,M,t,S),buildBinBreakdownSection({dies:L,hbinDefs:d,sbinDefs:a,binColors:s,plotMode:b,passBins:c,panel:t}),buildRegionYieldPanelSection({diesByWafer:$,allWafers:w,ringCount:r,passBins:c,panel:t}),p?.length?buildLotTestSection(L,p,u,K,h,$.map(C=>({dies:C})),t,"compact"):null,p?.length?buildLotFunctionalSection(L,p,K,h,t):null);let g=!0;for(const C of G)C&&(g||t.appendChild(Mt()),g=!1,t.appendChild(C));t.appendChild(l("div",{height:"12px",flexShrink:"0"})),t.scrollTop=o}
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",o)}),w.appendChild(v),f.appendChild(w);const k=l("table",{width:"100%",borderCollapse:"collapse",fontSize:E.body}),T=document.createElement("thead"),A=document.createElement("tr"),W=["Test"];h===null&&W.push("N"),c==="full"&&W.push("Min","Q1","Median"),W.push("Mean"),c==="full"&&W.push("Q3","Max","StdDev"),R&&W.push("Ppk"),c==="full"&&N&&W.push("LSL","USL"),N&&W.push("Spec yield");for(const g of W){const F=l("th",{textAlign:g==="Test"?"left":"right",fontWeight:"600",fontSize:E.meta,letterSpacing:re,textTransform:"uppercase",color:Y,padding:"3px 8px 5px",borderBottom:`1px solid ${L.menuBorder}`,whiteSpace:"nowrap"},g);A.appendChild(F)}T.appendChild(A),k.appendChild(T);const V=document.createElement("tbody");for(const{entry:g,stats:F,specYieldPct:O,specN:B}of I){const M=D=>ke(D,g.unit,i),z=document.createElement("tr"),$=(D,Z="right")=>{const j=l("td",{textAlign:Z,padding:`${y.xs} ${y.md}`,borderBottom:`1px solid ${L.menuBorder}`,color:L.text,whiteSpace:"nowrap"},D);z.appendChild(j)};if($(g.name,"left"),h===null&&$(`${F.count}`),c==="full"&&($(M(F.min)),$(M(F.q1)),$(M(F.median))),$(M(F.mean)),c==="full"&&($(M(F.q3)),$(M(F.max)),$(M(F.stddev))),R){const D=P.get(g.testNumber);$(D==null?"\u2014":D.toFixed(2))}c==="full"&&N&&($(g.limitLow!==void 0?M(g.limitLow):"\u2014"),$(g.limitHigh!==void 0?M(g.limitHigh):"\u2014")),N&&$(O!==null?h!==null&&B===h?`${O.toFixed(1)}%`:`${O.toFixed(1)}% (N=${B})`:"\u2014"),V.appendChild(z)}k.appendChild(V);const G=l("div",{overflowX:"auto"});if(G.appendChild(k),!p)return f.appendChild(G),f;w.remove();const{outer:U}=X(x,!0,void 0,{stateKey:"testValues",panel:p,render:g=>g.appendChild(G),control:()=>v});return U}export function buildFunctionalTestSection(e,t,i,n,o,d){const s=i??Ze(e,t);if(!s?.length)return null;const c=new Set(s.map(m=>m.totalDies)).size===1?s[0].totalDies:null,r=c!==null?` \xB7 N=${c.toLocaleString()}`:"",a=l("div"),b=l("div",{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:y.sm}),u=o?.populationLabel?`Functional Tests (${s.length}) \u2014 ${o.populationLabel}${r}`:`Functional Tests (${s.length})${r}`,S=J(u);S.style.marginBottom="0",b.appendChild(S);const N=document.createElement("button");N.type="button",N.textContent="Functional CSV",Object.assign(N.style,{...le("outlined")}),q(N),N.addEventListener("click",()=>{const m=["Test","N","Pass","Fail","Pass Rate %"],x=[...Ye(o,m),...Oe(o)],C=[[...x.map(v=>v.label),...m].map(ce).join(",")];for(const v of s)C.push([...x.map(k=>k.constant??""),v.label,String(v.totalDies),String(v.passDies),String(v.failDies),v.passRatePercent!==null?v.passRatePercent.toFixed(1):""].map(ce).join(","));De(C.join(`
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}
@@ -42,14 +42,6 @@ export interface ToCanvasOptions {
42
42
  * zoom/pan. Also accepts a zoom-adjusted `snapDist` for hit testing.
43
43
  */
44
44
  viewport?: ViewportTransform;
45
- /** Currently highlighted bin (or metadata value) — drawn with an active indicator in the bin legend. */
46
- activeBin?: number | string;
47
- /** Bin legend row under the pointer — drawn with a background fill, which is
48
- * deliberately a different channel from `activeBin`'s accent border and bold
49
- * label so "selected" and "pointed at" never look the same. The legend is
50
- * canvas-drawn, so this is the only way it can answer the pointer at all;
51
- * a DOM `:hover` cannot reach it. */
52
- hoverBin?: number | string;
53
45
  /**
54
46
  * Format to use for unitless values outside the normal display range [0.1, 9999].
55
47
  * `'engineering'` (default): multiples-of-3 exponent notation (e.g. `12E-6`).
@@ -57,10 +49,6 @@ export interface ToCanvasOptions {
57
49
  * Values with a unit always use SI prefix regardless of this setting.
58
50
  */
59
51
  fallbackFormat?: 'si' | 'engineering';
60
- /** Extra space reserved at the top of the canvas in CSS pixels. Default 0. Used by renderWaferMap to prevent the floating toolbar from obscuring the wafer. */
61
- topClearance?: number;
62
- /** Minimum right-side reserve in CSS pixels. Ensures the wafer draw width stays stable across plot mode switches. */
63
- minRightReserve?: number;
64
52
  /** Named hard bin definitions — used to label the bin legend. */
65
53
  hbinDefs?: import('../renderer/buildWaferMap.js').BinDef[];
66
54
  /** Named soft bin definitions — used to label the bin legend. */
@@ -74,6 +62,24 @@ export interface ToCanvasOptions {
74
62
  */
75
63
  showTitle?: boolean;
76
64
  }
65
+ /**
66
+ * @internal What only `renderWaferMap` knows while it draws: the legend row it
67
+ * highlights, the one under the pointer, and the right-hand reserve that keeps the
68
+ * wafer the same size across plot modes. A direct `toCanvas` caller has no pointer
69
+ * or mode-switch state to pass, so these are not on `ToCanvasOptions`.
70
+ */
71
+ export interface MapCanvasOptions extends ToCanvasOptions {
72
+ /** Currently highlighted bin (or metadata value) — drawn with an active indicator in the bin legend. */
73
+ activeBin?: number | string;
74
+ /** Bin legend row under the pointer — drawn with a background fill, which is
75
+ * deliberately a different channel from `activeBin`'s accent border and bold
76
+ * label so "selected" and "pointed at" never look the same. The legend is
77
+ * canvas-drawn, so this is the only way it can answer the pointer at all;
78
+ * a DOM `:hover` cannot reach it. */
79
+ hoverBin?: number | string;
80
+ /** Minimum right-side reserve in CSS pixels. Ensures the wafer draw width stays stable across plot mode switches. */
81
+ minRightReserve?: number;
82
+ }
77
83
  /** Internal viewport state shared between toCanvas and renderWaferMap. */
78
84
  export interface ViewportTransform {
79
85
  originX: number;
@@ -119,5 +125,7 @@ export declare const BIN_LEGEND_ADAPT_FLOATING = 180;
119
125
  export declare const BIN_LEGEND_MIN_CANVAS_W = 150;
120
126
  export declare const BIN_LEGEND_MIN_CANVAS_H = 120;
121
127
  export declare function toCanvas(canvas: HTMLCanvasElement, view: View, options?: ToCanvasOptions): ToCanvasResult;
128
+ /** @internal `toCanvas` plus the interaction state `renderWaferMap` draws with. */
129
+ export declare function drawMapCanvas(canvas: HTMLCanvasElement, view: View, options?: MapCanvasOptions): ToCanvasResult;
122
130
  export { fmt, fmtColorbarAxis } from '../renderer/fmt.js';
123
131
  //# sourceMappingURL=toCanvas.d.ts.map