@wafertools/wafermap 0.27.0 → 0.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +10 -2
- package/CHANGELOG.md +366 -0
- package/README.md +1 -1
- package/dist/packages/canvas-adapter/charts/binCluster.d.ts +0 -1
- package/dist/packages/canvas-adapter/charts/boxplot.d.ts +8 -1
- package/dist/packages/canvas-adapter/charts/boxplot.js +1 -1
- package/dist/packages/canvas-adapter/charts/capability.d.ts +0 -1
- package/dist/packages/canvas-adapter/charts/correlation.d.ts +0 -1
- package/dist/packages/canvas-adapter/charts/histogram.d.ts +0 -1
- package/dist/packages/canvas-adapter/charts/histogram.js +1 -1
- package/dist/packages/canvas-adapter/charts/regionYieldDiagram.d.ts +0 -1
- package/dist/packages/canvas-adapter/charts/scatter.d.ts +6 -1
- package/dist/packages/canvas-adapter/charts/scatter.js +1 -1
- package/dist/packages/canvas-adapter/charts/trend.d.ts +7 -0
- package/dist/packages/canvas-adapter/charts/trend.js +1 -1
- package/dist/packages/canvas-adapter/hitGrid.d.ts +22 -0
- package/dist/packages/canvas-adapter/hitGrid.js +1 -0
- package/dist/packages/canvas-adapter/index.d.ts +1 -0
- package/dist/packages/canvas-adapter/index.js +1 -1
- package/dist/packages/canvas-adapter/insightsTab.d.ts +24 -2
- package/dist/packages/canvas-adapter/insightsTab.js +1 -1
- package/dist/packages/canvas-adapter/maplessSummary.d.ts +8 -1
- package/dist/packages/canvas-adapter/maplessSummary.js +1 -1
- package/dist/packages/canvas-adapter/renderWaferGallery.js +1 -1
- package/dist/packages/canvas-adapter/renderWaferMap.d.ts +45 -1
- package/dist/packages/canvas-adapter/renderWaferMap.js +1 -1
- package/dist/packages/canvas-adapter/summaryPanel.d.ts +15 -5
- package/dist/packages/canvas-adapter/summaryPanel.js +3 -3
- package/dist/packages/canvas-adapter/toCanvas.js +1 -1
- package/dist/packages/canvas-adapter/toolbar.d.ts +46 -11
- package/dist/packages/canvas-adapter/toolbar.js +2 -2
- package/dist/packages/canvas-adapter/userGuideHtml.d.ts +1 -1
- package/dist/packages/canvas-adapter/userGuideHtml.js +27 -16
- package/dist/packages/canvas-adapter/version.d.ts +2 -2
- package/dist/packages/canvas-adapter/version.js +1 -1
- package/dist/packages/canvas-adapter/warnings.d.ts +25 -0
- package/dist/packages/canvas-adapter/warnings.js +1 -1
- package/dist/packages/core/dies.d.ts +11 -0
- package/dist/packages/core/dies.js +1 -1
- package/dist/packages/renderer/binColors.d.ts +80 -0
- package/dist/packages/renderer/binColors.js +1 -0
- package/dist/packages/renderer/buildView.d.ts +82 -6
- package/dist/packages/renderer/buildView.js +1 -1
- package/dist/packages/renderer/buildWaferMap.d.ts +8 -2
- package/dist/packages/renderer/buildWaferMap.js +1 -1
- package/dist/packages/renderer/colorMap.d.ts +16 -15
- package/dist/packages/renderer/colorMap.js +1 -1
- package/dist/packages/renderer/colorSchemes.d.ts +57 -25
- package/dist/packages/renderer/colorSchemes.js +1 -1
- package/dist/packages/renderer/index.d.ts +3 -1
- package/dist/packages/renderer/index.js +1 -1
- package/dist/packages/stats/analyzeWaferLot.js +1 -1
- package/dist/packages/stats/analyzeWaferMap.js +1 -1
- package/dist/packages/stats/histogram.d.ts +28 -1
- package/dist/packages/stats/histogram.js +1 -1
- package/dist/packages/stats/population.d.ts +23 -0
- package/dist/packages/stats/population.js +1 -0
- package/dist/packages/stats/renderFindingsReport.js +10 -10
- package/dist/packages/stats/renderSummaryReport.js +22 -22
- package/dist/packages/stats/yield.js +1 -1
- package/package.json +5 -3
|
@@ -8,12 +8,35 @@ import type { SummaryPanelOptions, FindingsNotice } from './summaryPanel.js';
|
|
|
8
8
|
import { type WarningsOptions } from './warnings.js';
|
|
9
9
|
import type { InsightsOptions } from './insightsTab.js';
|
|
10
10
|
import { type DieListDisplayOptions } from './dieList.js';
|
|
11
|
+
import { type BinColors } from '../renderer/binColors.js';
|
|
11
12
|
/**
|
|
12
13
|
* Stable display preferences — worth persisting to localStorage or a user profile.
|
|
13
14
|
* These describe how the user wants to view wafer maps in general.
|
|
14
15
|
*/
|
|
15
16
|
export interface WaferPreferences {
|
|
16
|
-
|
|
17
|
+
/**
|
|
18
|
+
* Bin palette for hard/soft-bin maps — a name from `listBinColorSchemes()`.
|
|
19
|
+
* Default `'default'`. Independent of `valueColorScheme`: each mode keeps
|
|
20
|
+
* its own choice, and switching modes never resets either.
|
|
21
|
+
*/
|
|
22
|
+
binColorScheme?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Value gradient for value and stacked maps — a name from
|
|
25
|
+
* `listValueColorSchemes()`. Default `'default'`.
|
|
26
|
+
*/
|
|
27
|
+
valueColorScheme?: string;
|
|
28
|
+
/**
|
|
29
|
+
* Flip the value gradient so high values take its low-end colour. Default
|
|
30
|
+
* false — every built-in gradient reads low = dark, high = light. Offered in
|
|
31
|
+
* the Colour scheme menu as "Reverse gradient"; applies to the dies, the
|
|
32
|
+
* colorbar and the mapless summary together.
|
|
33
|
+
*/
|
|
34
|
+
reverseValueScheme?: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Honour `BinDef.color` where a bin definition supplies one. Default true.
|
|
37
|
+
* The toolbar offers the toggle only when some definition carries a colour.
|
|
38
|
+
*/
|
|
39
|
+
useDefinedBinColors?: boolean;
|
|
17
40
|
/** Interactive rotation in degrees (0 | 90 | 180 | 270). */
|
|
18
41
|
rotation?: 0 | 90 | 180 | 270;
|
|
19
42
|
flipX?: boolean;
|
|
@@ -110,6 +133,24 @@ export interface WaferDisplayState {
|
|
|
110
133
|
test: number;
|
|
111
134
|
range: [number, number];
|
|
112
135
|
};
|
|
136
|
+
/**
|
|
137
|
+
* The full, ordered list of metadata values to assign colours from in
|
|
138
|
+
* `metadata` plot mode — applied only when `key` matches `activeMetadataKey`.
|
|
139
|
+
* Set by a host rendering several wafers together (`renderWaferGallery` does
|
|
140
|
+
* it for you) so every map indexes into ONE list; without it each map derives
|
|
141
|
+
* the order from its own dies, and a wafer missing a value the others have
|
|
142
|
+
* paints every later value in the next map's colour. See `ViewOptions`.
|
|
143
|
+
*/
|
|
144
|
+
metadataValueOrder?: {
|
|
145
|
+
key: string;
|
|
146
|
+
values: string[];
|
|
147
|
+
};
|
|
148
|
+
/**
|
|
149
|
+
* Bin colours resolved over the whole population being shown together —
|
|
150
|
+
* set by `renderWaferGallery` so a bin is one colour on every card. A lone
|
|
151
|
+
* map leaves it unset and resolves over its own dies. See `ViewOptions.binColors`.
|
|
152
|
+
*/
|
|
153
|
+
binColors?: BinColors;
|
|
113
154
|
/**
|
|
114
155
|
* Aggregation method for `stackedValues` mode.
|
|
115
156
|
* Drives both the per-die aggregation and the hover tooltip label.
|
|
@@ -414,6 +455,9 @@ export interface WaferMapController {
|
|
|
414
455
|
/** Remove all event listeners and DOM elements. */
|
|
415
456
|
destroy(): void;
|
|
416
457
|
}
|
|
458
|
+
/** Options that change die colours without changing what the view contains —
|
|
459
|
+
* any of them means every colour-bearing surface (panels, footer) redraws. */
|
|
460
|
+
export declare const COLOR_KEYS: readonly (keyof WaferViewOptions)[];
|
|
417
461
|
export declare function classifyChanged(keys: (keyof WaferViewOptions)[]): 'preference' | 'state' | 'mixed';
|
|
418
462
|
/**
|
|
419
463
|
* What `renderWaferMap` actually needs: a wafer and its dies, plus anything
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{buildView as ui,buildHoverText as gi,findTestDef as st,resolveTestNumber as At}from"../renderer/buildView.js";import{toCanvas as hi,BIN_LEGEND_W as Rn,BIN_LEGEND_W_COMPACT as mi,BIN_LEGEND_ADAPT_COMPACT as yi,BIN_LEGEND_ADAPT_FLOATING as bi}from"./toCanvas.js";import{buildWaferMap as vi,getTestPassStatus as xi,isParametricTest as zt}from"../renderer/buildWaferMap.js";import{analyzeWaferMap as wi}from"../stats/analyzeWaferMap.js";import{SHADOW as Si,LEADING as In,wireControlHover as Hn,SPACE as H,EDGE_GUTTER as Mi,RADIUS as Wn,FONT as rt,CLR as x,applyOverlayZ as Ci,getTooltip as Fn,hideTooltip as dt,reparentTooltip as Ei,positionTooltip as Yt,createToolbarHelpers as Di,buildModeMenuEl as ki,openReparentedModal as Bi,openUserGuideWindow as Li,makePaletteBtn as Pi,makeLogScaleBtn as Ti,makeLegendStyleBtn as Oi,makeOverlaysBtn as Ri,makeOrientationBtn as Ii,menuLayerFor as An,saveImageBlob as Hi,markMenuTrigger as Ve,wireMenuA11y as zn,wireExpandToggle as Wi,nextFrame as Nt,requestedPassFailDisplay as Fi,overlayMenuRows as Ai,anyOverlayActive as zi,logWmapVersionOnce as Yi,buildDataModeEntries as Ni,metadataKeyHasData as Xi,metadataModeEntry as ji}from"./toolbar.js";import{createSummaryPanelEl as Xt,wrapWithSummaryPanel as jt,renderWaferSummaryContent as Vi}from"./summaryPanel.js";import{collectWarnings as Ki,buildWarningsMenuEl as $i,severityOf as _i}from"./warnings.js";import{ICONS as Yn}from"./icons.js";import{hardBinColor as Gi,softBinColor as Zi,metadataValueColor as Ui}from"../renderer/colorMap.js";import{createIdentityHeader as Qi,collapsedLabel as Vt}from"./identityHeader.js";import{getDieKey as De,hasPosition as Nn,isPositionedDie as qi}from"../core/dies.js";import{buildDieListSection as Ji}from"./dieList.js";import{buildMaplessSummary as eo}from"./maplessSummary.js";const Xn=new Set(["colorScheme","rotation","flipX","flipY","showDieLabels","showPartialDies","showRingBoundaries","showQuadrantBoundaries","showReticle","showXYIndicator","ringCount","legendPosition","logScale","colorbarRangeMode","markFailingDies"]);export function classifyChanged(j){const m=j.some(u=>Xn.has(u)),w=j.some(u=>!Xn.has(u));return m&&w?"mixed":m?"preference":"state"}export function renderWaferMap(j,m,w={}){Yi();const u=j.ownerDocument,V=u.defaultView??window;V.getComputedStyle(j).position==="static"&&(j.style.position="relative");const jn=j.clientHeight;w.height!=null&&(j.style.height=typeof w.height=="number"?`${w.height}px`:w.height);const ct=m.dataCoverage?m.dataCoverage.unpositionedDies:m.dies.filter(e=>!Nn(e)).length,Ke=(m.dataCoverage?m.dataCoverage.totalDies:m.dies.length-ct)===0&&ct>0,ke=u.createElement("div");Object.assign(ke.style,{display:"flex",flexDirection:"column",width:"100%",height:"100%"}),j.appendChild(ke);const oe=u.createElement("div");Object.assign(oe.style,{position:"relative",width:"100%",flex:"1 1 auto",minHeight:"0"}),w.maxSize!=null&&(oe.style.maxWidth=`${w.maxSize}px`,oe.style.maxHeight=`${w.maxSize}px`);const ue=w.chromeInset??Mi,J=u.createElement("div");Object.assign(J.style,{display:"flex",alignItems:"stretch",gap:H.sm,background:x.canvasBg,paddingBottom:H.lg,paddingTop:ue,paddingLeft:ue,paddingRight:ue,flexShrink:"0",minWidth:"0"}),ke.appendChild(J),ke.appendChild(oe);const M=u.createElement("div");Object.assign(M.style,{position:"relative",width:"100%",height:"100%"});const a=u.createElement("canvas");Object.assign(a.style,{width:"100%",height:"100%",display:"block"}),M.appendChild(a),oe.appendChild(M);let $e=null;if(ct>0){let n=function(){if(t){const g=Ji(e,m.testDefs,{...w.dieList,onSaveText:w.onSaveText,waferMetadata:K.metadata,metadataFields:de,ownerDocument:u});if(g)return g}const i=st(m.testDefs,d.activeTest??0),s=zt(i)?d.logScale??i?.logScale??!1:!1;return eo(e,m.testDefs,{plotMode:d.plotMode??"hardBin",activeTest:d.activeTest,hbinDefs:G,sbinDefs:Z,colorScheme:d.colorScheme,logScale:s,colorbarRangeMode:d.colorbarRangeMode,valueRangeDies:m.dies})},o=function(i){const s=u.createElement("button");return s.type="button",Hn(s),Object.assign(s.style,{fontSize:rt.body,padding:`${H.xxs} ${H.sm}`,borderRadius:Wn.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",g=>{g.stopPropagation(),t=!t,s.textContent=t?"View chart":"View die list",i()}),s};const e=m.dies.filter(i=>!Nn(i));let t=!1;if(Ke){const i=u.createElement("div");Object.assign(i.style,{position:"absolute",inset:"0",background:x.panelBg,padding:H.xl,boxSizing:"border-box",overflow:"hidden",display:"flex",flexDirection:"column",gap:H.md,zIndex:"1"});const s=u.createElement("div");Object.assign(s.style,{display:"flex",justifyContent:"space-between",alignItems:"flex-start",gap:H.md});const g=u.createElement("span");Object.assign(g.style,{fontSize:rt.body,color:x.label,lineHeight:In.base}),g.textContent="No die position data for this wafer.",s.appendChild(g);const l=u.createElement("div");Object.assign(l.style,{flex:"1",minHeight:"0",overflow:"auto",display:"flex",flexDirection:"column"}),s.appendChild(o(()=>l.replaceChildren(n()))),i.appendChild(s),i.appendChild(l),M.appendChild(i),$e=()=>{t||l.replaceChildren(n())}}else{const i=u.createElement("div");Object.assign(i.style,{position:"absolute",left:"0",right:"0",bottom:"0",zIndex:"3",background:x.panelBg,borderTop:`1px solid ${x.menuBorder}`,fontSize:rt.body,color:x.text,cursor:"pointer",padding:`${H.xs} ${H.md}`,display:"flex",alignItems:"center",justifyContent:"space-between",gap:H.md}),Hn(i,"bare");const s=u.createElement("span");s.textContent=`+${e.length} ${e.length===1?"die":"dies"} without position data`,i.appendChild(s);const g=u.createElement("span");g.textContent="\u25BE",Object.assign(g.style,{fontSize:rt.body,lineHeight:In.none,color:x.label,flexShrink:"0"}),i.appendChild(g),i.setAttribute("aria-expanded","false"),i.setAttribute("aria-label",`${e.length} dies without position data. Click to view.`);let l=null,r=null;Wi(i,c=>{if(g.textContent=c?"\u25B4":"\u25BE",i.setAttribute("aria-expanded",String(c)),c){l=u.createElement("div");const p=i.getBoundingClientRect().height||28;Object.assign(l.style,{position:"absolute",left:"0",right:"0",bottom:`${p}px`,top:"20%",zIndex:"2",background:x.panelBg,borderTop:`1px solid ${x.menuBorder}`,padding:H.md,boxSizing:"border-box",display:"flex",flexDirection:"column",gap:H.md}),l.addEventListener("click",ie=>ie.stopPropagation());const h=u.createElement("div");Object.assign(h.style,{display:"flex",justifyContent:"flex-end"}),h.appendChild(o(()=>{r&&r.replaceChildren(n())})),l.appendChild(h),r=u.createElement("div"),Object.assign(r.style,{flex:"1",minHeight:"0",overflow:"auto",display:"flex",flexDirection:"column"}),r.appendChild(n()),l.appendChild(r),M.appendChild(l)}else l&&(l.remove(),l=null,r=null)}),M.appendChild(i),$e=()=>{r&&!t&&r.replaceChildren(n())}}}const{onHover:_e,onClick:Vn,onSelect:ge,onViewOptionsChange:Kn,showTooltip:$n=!0,showToolbar:Be=!0,showIdentity:Kt=!0,toolbarControls:pt="full",showPlotModeSelector:_n=!0,minZoom:Gn=.4,maxZoom:Zn=20,summaryPanel:Le,renderTooltip:$t,passBins:ft=[1],showHelpButton:_t=!1,userGuideExtension:Un,onExpand:Gt,showExpandButton:Zt=!0,zIndex:Qn,insights:ut,warnings:Ut,viewOptions:qn={},...le}=w,Pe=ut?.enabled??!1,Qt=Ut?.display??!0,Jn=Ci(Qn);let Te=le.fallbackFormat,ae=w.statsSummary,se=[],qt=!1;function Jt(){const e=Ki({result:m,statsSummary:ae}),t=e.length!==se.length||e.some((n,o)=>n.code!==se[o]?.code||n.message!==se[o]?.message);se=e,(t||!qt)&&(qt=!0,Ut?.onWarning?.(e))}Jt();let gt=m,K=m.wafer,re=m.dies,E=new Set,G=m.hbinDefs,Z=m.sbinDefs,ee=m.testDefs,de=m.metadataFields,en=m.reticles?.length?m.reticles:void 0,tn=m.reticleConfig,nn=m.view?.dataAxisFlip,ht=m.isLotStack??!1,mt=m.aggrMethod,yt=m.lotSize;const ei=Be&&pt!=="view-only"&&Pe;let bt=!1,$=null,A=null,U=null;Kt&&($=Qi(Vt(K.metadata??{},Oe())??"",K.metadata,{lotStack:Oe(),ownerDocument:u}),M.appendChild($.metaPanel),$.isEmpty()||(A=on($.wrap),J.insertBefore(A,J.firstChild)));function on(e){const t=u.createElement("div");return Object.assign(t.style,{display:"flex",alignItems:"center",padding:`${H.sm} ${H.lg}`,flex:"1 1 auto",minWidth:"0",overflow:"hidden",gap:H.sm}),Object.assign(e.style,{flex:"1",minWidth:"0"}),t.appendChild(e),t}function Oe(){return ht?{lotSize:yt??1,aggrMethod:mt}:void 0}function ti(){if(!$)return;$.update(Vt(K.metadata??{},Oe())??"",K.metadata,Oe());const e=A?.isConnected??!1,t=!$.isEmpty();!t&&e?(A.remove(),A=null):t&&!e&&(A=on($.wrap),A.style.display=bt?"none":"",J.insertBefore(A,J.firstChild))}const ln=[...G??[],...Z??[]].some(e=>e.color);let d={plotMode:"hardBin",colorScheme:ln?"custom":"default",showDieLabels:!1,showPartialDies:!0,showRingBoundaries:!1,showQuadrantBoundaries:!1,showReticle:!1,showXYIndicator:!1,ringCount:4,rotation:0,flipX:!1,flipY:!1,legendPosition:le.legendPosition??"default",...qn},Q=null,he=!1,an=null;function ni(){return Pe?Q?Promise.resolve(Q):(an??=import("./insightsTab.js").then(({createInsightsTab:e})=>(Q=e({getItems:()=>[{wafer:K,dies:re,hbinDefs:G,sbinDefs:Z,testDefs:ee,label:String(K.metadata?.waferId??""),statsSummary:ae}],getColorSchemeName:()=>d.colorScheme??"default",passBins:ft,getRingCount:()=>d.ringCount??4,onSaveImage:w.onSaveImage,onSaveText:w.onSaveText,defaultView:ut?.defaultView,showMetadataStrip:!1,contentInset:ue,backTab:ei?void 0:{label:"Map",onBack:()=>Ge(!1)},onOpenGuide:_t&&!Be?()=>Rt():void 0,ownerDocument:u}),Object.assign(Q.el.style,{position:"absolute",inset:"0",background:x.canvasBg,overflowY:"auto",paddingTop:"0"}),Q.el.style.display="none",oe.appendChild(Q.el),Q)),an):Promise.resolve(null)}function Ge(e){Pe&&(he=e,Q&&(Q.el.style.display=e?"flex":"none"),W&&(W.style.display=e||Ke?"none":"flex"),P&&(P.style.display=e?"none":"flex"),U&&(U.style.display=ye?"none":"flex"),te&&(te.style.display="flex"),A&&(A.style.display=bt?"none":""),$&&e&&$.collapse(),et(),F&&(F.innerHTML=e?Yn.wafer:Yn.analysis,F.ariaLabel=e?"Back to wafer view":"Insights"),e&&ni().then(t=>{!t||!he||(t.el.style.display="flex",t.render())}))}Pe&&ut?.defaultOpen&&queueMicrotask(()=>Ge(!0));let y,sn,z=null,B=null,vt=[],xt;function rn(e){xt!==e&&(xt=e,v())}let Re=null,wt=le.legendOffset??{x:0,y:0},Ie=!1,ve=!1,He={x:0,y:0},St={x:0,y:0},me=!1,xe=!1,Y="pan",we={x:0,y:0},Ze={x:0,y:0},T={x:0,y:0},O={x:0,y:0},We=!1,Se=!1;function Fe(){const e=d;y=ui(K,re.filter(qi),{plotMode:e.plotMode,colorScheme:e.colorScheme,passBins:ft,showDieLabels:e.showDieLabels,showPartialDies:e.showPartialDies,showRingBoundaries:e.showRingBoundaries,showQuadrantBoundaries:e.showQuadrantBoundaries,showReticle:e.showReticle,showXYIndicator:e.showXYIndicator,reticles:en,ringCount:e.ringCount,highlightBin:e.highlightBin,highlightMetadataValue:e.highlightMetadataValue,activeTest:e.activeTest,activeMetadataKey:e.activeMetadataKey,testDefs:ee,valueRange:e.valueRange,logScale:e.logScale,isLotStack:ht,aggregationMethod:mt??e.aggregationMethod,lotSize:yt??e.lotSize,dataAxisFlip:nn,colorbarRangeMode:e.colorbarRangeMode,passFailDisplay:e.passFailDisplay,fallbackFormat:Te,interactiveTransform:{rotation:e.rotation??0,flipX:e.flipX??!1,flipY:e.flipY??!1}},{hbinDefs:G,sbinDefs:Z,metadataFields:de}),sn=new Map(y.dies.map((t,n)=>[De(t),n]))}Fe();let N=null,Me=null,Ue=null,dn=w.findingsNotice,ii={},R=null,ce=null;function oi(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 o=e.highlight;o.kind==="bin"?(Bt(o.dieKeys),D({highlightBin:o.bin})):(o.kind==="region"||o.kind==="dies")&&Bt(o.dieKeys)}function cn(e){Vi(e,{wafer:K,dies:re,yieldSummary:gt.yield,dataCoverage:gt.dataCoverage,hbinDefs:G,sbinDefs:Z,testDefs:ee,statsSummary:ae,warnings:Qt?se:[],passBins:ft,ringCount:d.ringCount??4,colorScheme:d.colorScheme,plotMode:d.plotMode??"hardBin",metadataShownElsewhere:Kt,fallbackFormat:Te,activeFindingId:Ue,findingsFilter:ii,findingsNotice:dn,onFindingsFilterChange:pe,onSaveText:w.onSaveText,metadataFields:de,dieListOptions:w.dieList,onFindingClick:(t,n)=>{Ue===t.id?(Ue=null,Bt([]),D({highlightBin:void 0})):(Ue=t.id,oi(t)),pe()}})}function pe(){N&&cn(N)}function Ae(){R&&cn(R)}if(Le?.placement){const e=Le.placement;N=Xt(e,ue,u);const t=M.parentElement,n=M.nextSibling;Me=jt(M,N,e),t?.insertBefore(Me,n),pe()}else if(ae){const e=Le?.defaultOpen??!Be;R=Xt("right",ue,u),R.style.display=e?"block":"none";const t=M.parentElement,n=M.nextSibling;ce=jt(M,R,"right"),t?.insertBefore(ce,n),Ae()}const S=$n?Fn(u):null;let te=null,L=null,W=null,P=null,Qe=null,I=null,qe=null,F=null,ne=null,Je=null;function pn(){if(!ne||!Je)return;const e=se.length,t=e>0;if(ne.style.display=t?"flex":"none",Je.style.display=t?"":"none",!t)return;const n=_i(se[0]),o=`${e} data ${e===1?"warning":"warnings"}`;ne.style.color=n==="error"?x.errText:x.warnText,ne.ariaLabel=n==="error"?`${o} \u2014 the map may be positionally wrong`:o}let Mt=null,fn=null,Ct=null,Et=null,Dt=null,kt=null;function Bt(e){E=new Set(e??[]),ge&&ge(Ot()),v()}function et(){if(!I)return;const e=!!(N??R);I.style.display=ae&&e&&!he?"flex":"none";const t=N??R,n=t?t.style.display!=="none":!1;ae?.hasNotableFindings&&!n?I.style.color=x.findingIndicator:I.dataset.active||(I.style.color=x.icon)}if(Be){let p=function(k){Y=k,o(ie,k==="zoom"),o(C,k==="pan"),Qe&&o(Qe,k==="select"),a.style.cursor=k==="pan"?"grab":"crosshair"};te=u.createElement("div"),te.dataset.wmapToolbar="single",Object.assign(te.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(u),t=Di(e),{makeBtn:n,setActive:o,makeSep:i,makeMenuRow:s,makeMenuSection:g,closeOpenMenu:l,getOpenMenu:r,setOpenMenu:c}=t;Mt=l,fn=r,u.addEventListener("click",l,!0),W=u.createElement("div"),Object.assign(W.style,{display:Ke?"none":"flex",alignItems:"center",gap:"0",flexWrap:"wrap",justifyContent:"flex-end"}),te.appendChild(W);const h=n("download","Download PNG",si);W.appendChild(h),W.appendChild(i());const ie=n("zoomMode","Zoom (drag to zoom region)",()=>p("zoom")),Ee=n("zoomIn","Zoom in",()=>Ce(a.clientWidth/2,a.clientHeight/2,1.2)),q=n("zoomOut","Zoom out",()=>Ce(a.clientWidth/2,a.clientHeight/2,1/1.2)),fe=n("reset","Reset zoom (double-click)",()=>nt());W.appendChild(ie),W.appendChild(Ee),W.appendChild(q),W.appendChild(fe),W.appendChild(i());const C=n("pan","Pan (drag to move)",()=>p("pan"));if(W.appendChild(C),Qe=n("boxSelect","Select (drag to select dies)",()=>p("select")),W.appendChild(Qe),o(C,!0),pt!=="view-only"){let k=function(f){return f.plotMode!==(d.plotMode??"hardBin")?!1:f.plotMode==="value"?(d.activeTest??0)===(f.activeTest??0):f.plotMode==="metadata"?d.activeMetadataKey===f.activeMetadataKey:!0},It=function(f,b){f.activeTest!==void 0?D({plotMode:f.plotMode,activeTest:f.activeTest,activeMetadataKey:void 0,logScale:f.logScale}):f.activeMetadataKey!==void 0?D({plotMode:f.plotMode,activeTest:void 0,activeMetadataKey:f.activeMetadataKey,passFailDisplay:"off"}):D({plotMode:f.plotMode,activeTest:void 0,activeMetadataKey:void 0,passFailDisplay:"off"}),b.remove(),c(null),Ve(_,!1)};L=u.createElement("div"),Object.assign(L.style,{display:"flex",alignItems:"center",gap:"0",flexWrap:"wrap",justifyContent:"flex-end"}),te.appendChild(L),P=u.createElement("div"),Object.assign(P.style,{display:"flex",alignItems:"center",gap:"0"}),L.appendChild(P),P.appendChild(i());const it=()=>{const f=r();f&&(f.remove(),c(null)),Ve(_,!1)},_=n("mode","Plot mode",()=>{if(r()){it();return}const f=re,b=y.testDefs,{testEntries:at,binEntries:be,stackedEntries:Ne}=Ni(f,b,{includeStacked:y.isLotStack}),Ft=(de??[]).filter(je=>Xi(f,je.key)).map(ji),Xe=ki(_.getBoundingClientRect(),at,be,Ne,k,It,{makeMenuRow:s,makeMenuSection:g},d.plotMode??"hardBin",_.ownerDocument.defaultView??window,Ft);An(_).appendChild(Xe),c(Xe),Ve(_,!0),zn(Xe,_,it)});Ve(_,!1);const{btn:ot,sync:Ye}=Pi(t,()=>d.plotMode??"hardBin",()=>d.colorScheme??"default",()=>ln,f=>D({colorScheme:f}),{get:()=>d.markFailingDies??!1,set:f=>D({markFailingDies:f})});Et=Ye,Et();const Ht=Ri(t,()=>{const f=!!y.hasReticle,b=(d.plotMode??"hardBin")==="value",{testNumber:at}=At(d.activeTest??0,y.testDefs),be=st(y.testDefs,at),Ne=b&&be!==void 0&&!zt(be),Ft=b&&!Ne&&(be?.limitLow!==void 0||be?.limitHigh!==void 0),Xe=b&&!Ne&&y.dies.some(je=>xi(je,at,be)!==void 0);return Ai(d,f,{functionalActive:Ne,hasLimits:Ft,hasRecorded:Xe},je=>D(je))},()=>zi(d)),{btn:Wt,sync:ri}=Oi(t,()=>d,f=>D({legendPosition:f}));Ct=ri,Ct();const On=()=>{const{testNumber:f}=At(d.activeTest??0,ee),b=st(ee,f);return b!==void 0&&!zt(b)},{btn:di,sync:ci}=Ti(t,()=>({...d,functionalActive:On()}),f=>D(f));Dt=ci,Dt();const pi=()=>{const{testNumber:f}=At(d.activeTest??0,ee),b=st(ee,f);return b!==void 0&&(b.limitLow!==void 0||b.limitHigh!==void 0)},lt=n("specRange","Colorbar range: spec limits",()=>{const f=d.colorbarRangeMode==="data"?"spec":"data";D({colorbarRangeMode:f})});kt=()=>{const f=d.plotMode==="value"&&pi()&&Fi(d)==="off"&&!On();lt.style.display=f?"":"none";const b=(d.colorbarRangeMode??"spec")==="spec";o(lt,b),lt.ariaLabel=b?"Colorbar range: spec limits (click for data range)":"Colorbar range: data range (click for spec limits)"},kt();const fi=Ii(t,()=>d,f=>D(f));_n&&P.appendChild(_),P.appendChild(ot),P.appendChild(di),P.appendChild(lt),Ke||(P.appendChild(i()),P.appendChild(Ht),P.appendChild(i()),P.appendChild(Wt),P.appendChild(i()),P.appendChild(fi)),ae&&(I=n("findings","Summary panel",()=>{const f=N??R;if(!f)return;const b=f.style.display!=="none";f.style.display=b?"none":"block",o(I,!b),et()}),L.appendChild(i()),L.appendChild(I),R?.style.display!=="none"&&o(I,!0),et()),Qt&&(Je=i(),ne=n("warning","Data warnings",()=>{const f=r();if(l(new MouseEvent("click")),f)return;const b=$i(ne.getBoundingClientRect(),se,V);An(oe).appendChild(b),c(b),zn(b,ne,()=>l(new MouseEvent("click")))}),Ve(ne,!1),L.appendChild(Je),L.appendChild(ne),pn()),Pe&&(L.appendChild(i()),F=n("analysis","Insights",()=>{Ge(!he),o(F,he)}),F.dataset.wmapInsightsBtn="1",L.appendChild(F)),Zt&&(L.appendChild(i()),U=n("expand","Expand (E)",Gt??un),L.appendChild(U)),_t&&(L.appendChild(i()),qe=n("help","User guide",()=>Rt()),L.appendChild(qe))}J.appendChild(te)}let ye=null;function un(){ye&&(ye.close(),ye=null);const e=oe;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 o=Vt(K.metadata??{},Oe()),i=J.childElementCount>0?[J,e]:[e],s=Bi(i,{ownerDocument:u,boxSize:he?{width:"min(96vw, 1600px)",height:"min(92vh, 1000px)"}:void 0,onClosed:()=>{ye=null,e.style.maxWidth=t,e.style.maxHeight=n,U&&(U.style.display="flex"),he||a.focus({preventScroll:!0})}});s&&(s.box.setAttribute("aria-label",o??"Expanded wafer map"),i.length>1&&(s.contentWrap.style.flexDirection="column"),ye=s,U&&(U.style.display="none"))}function gn(e){const t=d.plotMode;if(d={...d,...e},e.plotMode!==void 0&&e.plotMode!==t){const i=d.plotMode;(i==="hardBin"||i==="softBin")&&!new Set(["default","accessible","custom"]).has(d.colorScheme??"")&&(d={...d,colorScheme:"default"})}Object.keys(e).every(i=>i==="legendPosition"||i==="showLegend"||i==="markFailingDies")||Fe(),Ct?.(),Et?.(),Dt?.(),kt?.(),v();const o=e.plotMode!==void 0&&e.plotMode!==t;(e.colorScheme!==void 0||o)&&(pe(),Ae()),(e.colorScheme!==void 0||o||e.activeTest!==void 0||e.logScale!==void 0||e.colorbarRangeMode!==void 0)&&$e?.()}function D(e){gn(e);const t=Object.keys(e);Kn?.(d,t,classifyChanged(t))}let Lt=!1;function Pt(){Lt||(Lt=!0,Nt(()=>{Lt=!1,v()},V))}function v(){const e=B??void 0,t=y.dies[0],n=t?{x:t.width,y:t.height}:le.diePitchMm,o=Math.floor(a.clientWidth||a.width),i=!!(G?.length||Z?.length||y.dies.some(h=>h.hbin!=null||h.sbin!=null)),s=d.legendPosition??"default",g=d.showLegend??!0,l=s==="default"||s==="compact",r=(le.colorbarWidth??16)+28,c=i&&l?s!=="default"?Math.max(Rn,r):o<bi?0:o<yi?Math.max(mi,r):Math.max(Rn,r):void 0,p=hi(a,y,{...le,topClearance:0,minRightReserve:g?c:0,showColorbar:g&&(le.showColorbar??!0),markFailingDies:d.markFailingDies??!1,legendPosition:s,legendOffset:wt,diePitchMm:n,fallbackFormat:Te,showAxes:le.showAxes??B!==null,viewport:e,activeBin:d.plotMode==="metadata"?d.highlightMetadataValue:d.highlightBin,hoverBin:xt,hbinDefs:G,sbinDefs:Z,metadataFields:de});vt=p.binLegendRows,Re=p.legendBox??null,B===null&&(z=p.viewport),E.size>0&&li(),xe&&ai()}function li(){const e=X();if(!e)return;const t=a.getContext("2d"),n=y.hoverPoints,o=y.rectangles[0],i=o?o.width/2*e.ppm:e.ppm*.5,s=o?o.height/2*e.ppm:e.ppm*.5,g=Math.max(1,Math.min(3,i*.08)),l=i-g,r=s-g,c=[];for(const p of E){const h=sn.get(p);h!==void 0&&c.push({sx:e.originX+n[h].x*e.ppm,sy:e.originY-n[h].y*e.ppm})}if(c.length){t.save(),t.setLineDash([]),t.fillStyle="rgba(0,0,0,0.12)",t.beginPath();for(const{sx:p,sy:h}of c)t.rect(p-l,h-r,l*2,r*2);t.fill(),t.strokeStyle="rgba(255,255,255,0.9)",t.lineWidth=3,t.beginPath();for(const{sx:p,sy:h}of c)t.rect(p-l,h-r,l*2,r*2);t.stroke(),t.strokeStyle="rgba(0,0,0,0.9)",t.lineWidth=1.5,t.beginPath();for(const{sx:p,sy:h}of c)t.rect(p-l,h-r,l*2,r*2);t.stroke(),t.restore()}}function ai(){const e=a.getContext("2d"),t=Math.min(T.x,O.x),n=Math.min(T.y,O.y),o=Math.abs(O.x-T.x),i=Math.abs(O.y-T.y);e.save(),e.fillStyle="rgba(0,0,0,0.08)",e.fillRect(t,n,o,i),e.setLineDash([5,3]),e.strokeStyle="rgba(255,255,255,0.9)",e.lineWidth=3,e.strokeRect(t,n,o,i),e.strokeStyle="rgba(0,0,0,0.9)",e.lineWidth=1.5,e.strokeRect(t,n,o,i),e.restore()}function si(){a.toBlob(e=>{e&&Hi(e,w.downloadFilename??"wafermap",w.onSaveImage)})}function hn(e){return z?Math.max(z.ppm*Gn,Math.min(z.ppm*Zn,e)):e}function Ce(e,t,n){const o=B??z;if(!o)return;const i=hn(o.ppm*n),s=i/o.ppm,g=e-(e-o.originX)*s,l=t-(t-o.originY)*s,r=(z?.snapDist??1)/(i/(z?.ppm??i));B={originX:g,originY:l,ppm:i,snapDist:r},v()}function X(){return B??z}function mn(e){if(e.ctrlKey||e.metaKey){e.preventDefault();const t=a.getBoundingClientRect(),n=e.deltaY<0?1.12:1/1.12;Ce(e.clientX-t.left,e.clientY-t.top,n)}else if(B!==null){e.preventDefault();const t=X(),n=B.snapDist;B={originX:t.originX-e.deltaX,originY:t.originY-e.deltaY,ppm:t.ppm,snapDist:n},v()}}function yn(e,t,n){return e>=n.x&&e<n.x+n.w&&t>=n.y&&t<n.y+n.h}function bn(e){if(e.button!==0||!X())return;a.focus({preventScroll:!0}),a.setPointerCapture(e.pointerId);const t=a.getBoundingClientRect(),n=e.clientX-t.left,o=e.clientY-t.top;if(Re&&d.legendPosition==="floating"&&yn(n,o,Re)){ve=!0,He={x:n,y:o},St={...wt};return}if(We&&Y!=="pan"){Se=!0,me=!0,we={x:n,y:o},Ze={x:X().originX,y:X().originY},a.style.cursor="grabbing";return}if(Y==="zoom"||Y==="select"){xe=!0,T=O={x:n,y:o};return}me=!0,we={x:n,y:o},Ze={x:X().originX,y:X().originY},a.style.cursor="grabbing"}function vn(e){const t=a.getBoundingClientRect(),n=e.clientX-t.left,o=e.clientY-t.top;if(xe){O={x:n,y:o},Pt();return}if(ve){const p=n-He.x,h=o-He.y;p*p+h*h>16&&(ve=!1,Ie=!0,a.style.cursor="grabbing")}if(Ie){wt={x:St.x+(n-He.x),y:St.y+(o-He.y)},Pt();return}if(me){const p=X(),h=B?.snapDist??z?.snapDist??1;B={originX:Ze.x+(n-we.x),originY:Ze.y+(o-we.y),ppm:p.ppm,snapDist:h},Pt();return}const i=X();if(!i)return;const s=(n-i.originX)/i.ppm,g=(i.originY-o)/i.ppm,r=Mn(s,g,i.snapDist)?.die??null,c=vt.find(p=>n>=p.x&&n<p.x+p.w&&o>=p.y&&o<p.y+p.h);if(rn(c?c.bin:void 0),c){a.style.cursor="pointer",S&&(S.innerHTML=c.label??`Bin ${c.bin}`,S.style.display="block",Yt(S,a,e.clientX,e.clientY)),_e?.(null,e);return}if(Y==="pan"&&(a.style.cursor=r?"crosshair":"grab"),S)if(r)if($t){const p=$t(r);p===null?S.style.display="none":(typeof p=="string"?S.innerHTML=p:(S.innerHTML="",S.appendChild(p)),S.style.display="block",Yt(S,a,e.clientX,e.clientY))}else S.innerHTML=gi(r,y.plotMode,{testDefs:ee,hbinDefs:G,sbinDefs:Z,fallbackFormat:Te,aggrMethod:y.aggrMethod,lotSize:y.lotSize,metadataFields:de,activeTest:y.activeTest,reticleConfig:tn}),S.style.display="block",Yt(S,a,e.clientX,e.clientY);else S.style.display="none";_e?.(r,e)}function xn(e){const t=a.getBoundingClientRect(),n=e.clientX-t.left,o=e.clientY-t.top,i=e.ctrlKey||e.metaKey;if(S&&(n<0||o<0||n>t.width||o>t.height)&&(S.style.display="none"),xe){xe=!1,O={x:n,y:o};const l=n-T.x,r=o-T.y,c=X();if(Y==="zoom"){if(l*l+r*r<25)Ce(n,o,2);else if(c){const p=Math.min(T.x,O.x),h=Math.max(T.x,O.x),ie=Math.min(T.y,O.y),Ee=Math.max(T.y,O.y),q=h-p,fe=Ee-ie;if(q>4&&fe>4){const C=a.clientWidth,k=a.clientHeight,It=C/q,it=k/fe,_=Math.min(It,it),ot=hn(c.ppm*_),Ye=ot/c.ppm,Ht=(p+h)/2,Wt=(ie+Ee)/2;B={originX:C/2-(Ht-c.originX)*Ye,originY:k/2-(Wt-c.originY)*Ye,ppm:ot,snapDist:c.snapDist/Ye}}}v(),a.style.cursor="crosshair";return}if(l*l+r*r<25)Tt(n,o,i,e);else if(c){const p=(Math.min(T.x,O.x)-c.originX)/c.ppm,h=(Math.max(T.x,O.x)-c.originX)/c.ppm,ie=(c.originY-Math.max(T.y,O.y))/c.ppm,Ee=(c.originY-Math.min(T.y,O.y))/c.ppm,q=y.hoverPoints,fe=[];for(let C=0;C<q.length;C++)if(q[C].x>=p&&q[C].x<=h&&q[C].y>=ie&&q[C].y<=Ee){const k=y.dies[C];k&&fe.push(k)}if(i)for(const C of fe){const k=De(C);E.has(k)?E.delete(k):E.add(k)}else E=new Set(fe.map(C=>De(C)));ge?.(Ot())}v(),a.style.cursor="crosshair";return}if(ve){ve=!1,Tt(n,o,i,e);return}if(Ie){Ie=!1,a.style.cursor="grab";return}if(!me)return;if(me=!1,Se){Se=!1,a.style.cursor=We||Y==="pan"?"grab":"crosshair";return}a.style.cursor=Y==="pan"?"grab":"crosshair";const s=n-we.x,g=o-we.y;s*s+g*g<25&&Tt(n,o,i,e)}function Tt(e,t,n,o){for(const l of vt)if(e>=l.x&&e<l.x+l.w&&t>=l.y&&t<l.y+l.h){if(typeof l.bin=="number"){const r=d.highlightBin===l.bin?void 0:l.bin;D({highlightBin:r})}else{const r=d.highlightMetadataValue===l.bin?void 0:l.bin;D({highlightMetadataValue:r})}return}if(Re&&yn(e,t,Re))return;const i=X();if(!i)return;const g=Mn((e-i.originX)/i.ppm,(i.originY-t)/i.ppm,i.snapDist)?.die??null;if(g){Vn?.(g,o);const l=De(g);n?E.has(l)?E.delete(l):E.add(l):E=new Set([l]),ge?.(Ot()),v()}else n||(E=new Set,ge?.([]),v())}function Ot(){const e=[],t=y.hoverPoints;for(let n=0;n<t.length;n++){const o=y.dies[n];o&&E.has(De(o))&&e.push(o)}return e}function wn(){rn(void 0),S&&dt(u),_e?.(null,new MouseEvent("mouseleave")),a.style.cursor=Y==="pan"?"grab":"crosshair"}function Sn(){me=!1,Se=!1,xe=!1,ve=!1,Ie=!1,S&&dt(u),_e?.(null,new MouseEvent("mouseleave")),a.style.cursor=Y==="pan"?"grab":"crosshair",v()}function Mn(e,t,n){const o=y.hoverPoints,i=y.rectangles;for(let r=0;r<i.length;r++){const c=i[r];if(Math.abs(e-c.x)<=c.width/2&&Math.abs(t-c.y)<=c.height/2){const p=y.dies[r];return p?{die:p,index:r}:null}}let s=null,g=-1,l=n*n;for(let r=0;r<o.length;r++){const c=o[r].x-e,p=o[r].y-t,h=c*c+p*p;h<l&&(l=h,s=y.dies[r]??null,g=r)}return s?{die:s,index:g}:null}const Cn=new V.ResizeObserver(()=>{z=null,B=null,v()});Cn.observe(a),w.height==null&&jn<=0&&Nt(()=>Nt(()=>{j.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=V.matchMedia(`(resolution: ${V.devicePixelRatio}dppx)`);const tt=()=>{ze.removeEventListener("change",tt),ze=V.matchMedia(`(resolution: ${V.devicePixelRatio}dppx)`),ze.addEventListener("change",tt),v()};ze.addEventListener("change",tt);const En=V.matchMedia("(prefers-color-scheme: dark)"),Dn=()=>v();En.addEventListener("change",Dn);const kn=()=>{S&&dt(u)};V.addEventListener("blur",kn);function Bn(e){if(e.key==="Escape"&&E.size>0&&(E=new Set,ge?.([]),v()),(e.key==="e"||e.key==="E")&&pt!=="view-only"&&Zt&&(e.stopPropagation(),(Gt??un)()),(e.ctrlKey||e.metaKey)&&(e.key==="="||e.key==="+"?(e.preventDefault(),Ce(a.clientWidth/2,a.clientHeight/2,1.2)):e.key==="-"?(e.preventDefault(),Ce(a.clientWidth/2,a.clientHeight/2,1/1.2)):e.key==="0"&&(e.preventDefault(),nt())),!e.ctrlKey&&!e.metaKey&&!e.shiftKey){const n=X();if(n){const o=B?.snapDist??z?.snapDist??1;let i=0,s=0;e.key==="ArrowLeft"&&(i=20,e.preventDefault()),e.key==="ArrowRight"&&(i=-20,e.preventDefault()),e.key==="ArrowUp"&&(s=20,e.preventDefault()),e.key==="ArrowDown"&&(s=-20,e.preventDefault()),(i||s)&&(B={originX:n.originX+i,originY:n.originY+s,ppm:n.ppm,snapDist:o},v())}e.key===" "&&!We&&(e.preventDefault(),We=!0,Y!=="pan"&&(a.style.cursor="grab"))}}function Ln(e){e.key===" "&&(We=!1,Se&&(me=!1,Se=!1),a.style.cursor=Y==="pan"?"grab":"crosshair")}a.style.cursor="grab",a.setAttribute("tabindex","0"),a.addEventListener("wheel",mn,{passive:!1}),a.addEventListener("pointerdown",bn),a.addEventListener("pointermove",vn),a.addEventListener("pointerup",xn),a.addEventListener("pointerleave",wn),a.addEventListener("pointercancel",Sn);const Pn=()=>nt();a.addEventListener("dblclick",Pn),a.addEventListener("keydown",Bn),a.addEventListener("keyup",Ln);const Tn=e=>{e.stopPropagation()};a.addEventListener("click",Tn),a.clientWidth,v(),$e?.();function nt(){z=null,B=null,v()}function Rt(){import("./userGuideHtml.js").then(e=>Li({buildWaferMap:vi,renderWaferMap,renderWaferGallery:void 0,analyzeWaferMap:wi},e.USER_GUIDE_HTML,Un,j))}return{setDies(e){re=e,Fe(),v(),N&&pe()},setResult(e){gt=e,K=e.wafer,re=e.dies,G=e.hbinDefs,Z=e.sbinDefs,ee=e.testDefs,de=e.metadataFields,en=e.reticles?.length?e.reticles:void 0,tn=e.reticleConfig,nn=e.view?.dataAxisFlip,ht=e.isLotStack,mt=e.aggrMethod,yt=e.lotSize,ti(),Fe(),v(),N&&pe()},setOptions(e){gn(e)},getOptions(){return{...d}},resetZoom:nt,setSelection(e){E=new Set(e.map(t=>De(t))),v()},clearSelection(){E=new Set,ge?.([]),v()},setFallbackFormat(e){Te=e,Fe(),v()},setFindingsNotice(e){dn=e,N?pe():R&&Ae()},setStatsSummary(e){if(ae=e,Jt(),pn(),N)pe();else if(R)Ae();else if(e&&!Le?.placement){const t=Le?.defaultOpen??!Be;R=Xt("right",ue,u),R.style.display=t?"block":"none";const n=M.parentElement,o=M.nextSibling;ce=jt(M,R,"right"),n?.insertBefore(ce,o),Ae()}et()},setSummaryVisible(e){I&&(I.style.display=e?"flex":"none")},setViewControlsVisible(e){L&&(L.style.display=e?"flex":"none")},setExpandVisible(e){U&&(U.style.display=e?"flex":"none")},setHelpButtonVisible(e){qe&&(qe.style.display=e?"flex":"none")},setIdentityVisible(e){bt=!e,A&&(A.style.display=e?"":"none")},openUserGuide:Rt,setInsightsOpen(e){Ge(e),F&&(e?(F.dataset.active="1",F.style.background=x.bgActive,F.style.color=x.iconActive):(delete F.dataset.active,F.style.background="transparent",F.style.color=x.icon))},closeSummaryPanel(){const e=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){S&&Ei(e)},getActiveLegend(){const e=d.plotMode;if(e==="metadata"){const i=d.activeMetadataKey;if(!i)return null;const s=de?.find(l=>l.key===i),g=[...new Set(re.map(l=>l.metadata?.[i]).filter(l=>l!=null&&(typeof l=="string"||typeof l=="number"||typeof l=="boolean")).map(String))].sort();return g.length?g.map((l,r)=>{const c=s?.values?.find(h=>h.value===l),p=c?.color??Ui(r);return{bin:l,name:c?.label??l,color:p}}):null}if(e!=="hardBin"&&e!=="softBin")return null;const t=e==="hardBin",n=t?G:Z,o=[...new Set(re.map(i=>t?i.hbin:i.sbin).filter(i=>i!==void 0))].sort((i,s)=>i-s);return o.length?o.map(i=>{const s=n?.find(l=>l.bin===i),g=s?.color??(t?Gi(i):Zi(i));return{bin:i,name:s?.name??`Bin ${i}`,color:g}}):null},destroy(){ye?.close(),fn?.()?.remove(),Mt&&u.removeEventListener("click",Mt,!0),a.removeEventListener("wheel",mn),a.removeEventListener("pointerdown",bn),a.removeEventListener("pointermove",vn),a.removeEventListener("pointerup",xn),a.removeEventListener("pointerleave",wn),a.removeEventListener("pointercancel",Sn),a.removeEventListener("dblclick",Pn),a.removeEventListener("keydown",Bn),a.removeEventListener("keyup",Ln),a.removeEventListener("click",Tn),Cn.disconnect(),ze.removeEventListener("change",tt),En.removeEventListener("change",Dn),V.removeEventListener("blur",kn),Jn(),S&&dt(u),te?.remove(),Me&&(Me.parentElement?.insertBefore(M,Me),Me.remove()),ce&&(ce.parentElement?.insertBefore(M,ce),ce.remove()),M.remove(),a.style.cursor="",Q?.destroy(),$?.destroy(),ke.remove()}}}
|
|
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&>!=="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")&>!=="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()}}}
|
|
@@ -3,6 +3,7 @@ import type { Die } from '../core/dies.js';
|
|
|
3
3
|
import { type BinDef, type TestDef, type YieldSummary, type MetadataFieldDef } from '../renderer/buildWaferMap.js';
|
|
4
4
|
import type { StatsFinding, StatsSummary, LotStatsSummary } from '../stats/types.js';
|
|
5
5
|
import { type FindingsFilter } from '../stats/filterFindings.js';
|
|
6
|
+
import { type BinColors } from '../renderer/binColors.js';
|
|
6
7
|
import { buildWarningsBanner, type WaferWarning } from './warnings.js';
|
|
7
8
|
export { buildWarningsBanner };
|
|
8
9
|
import type { PlotMode } from '../renderer/buildView.js';
|
|
@@ -87,7 +88,13 @@ export declare function buildYieldSection(yieldSummary: YieldSummary, dataCovera
|
|
|
87
88
|
edgeExcludedDies: number;
|
|
88
89
|
ratio: number;
|
|
89
90
|
}, passBins?: number[]): HTMLDivElement;
|
|
90
|
-
export declare function buildBinSection(dies: Die[], binDefs: BinDef[] | undefined, mode: 'hard' | 'soft',
|
|
91
|
+
export declare function buildBinSection(dies: Die[], binDefs: BinDef[] | undefined, mode: 'hard' | 'soft',
|
|
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.
|
|
96
|
+
*/
|
|
97
|
+
binColors?: ReadonlyMap<number, string>,
|
|
91
98
|
/**
|
|
92
99
|
* Precomputed counts (e.g. `StatsSummary.stats.hardBinCounts`/`.softBinCounts`,
|
|
93
100
|
* already scoped to the yield-eligible population) — used directly instead
|
|
@@ -114,7 +121,8 @@ export declare function buildBinBreakdownSection(params: {
|
|
|
114
121
|
dies: Die[];
|
|
115
122
|
hbinDefs?: BinDef[];
|
|
116
123
|
sbinDefs?: BinDef[];
|
|
117
|
-
|
|
124
|
+
/** The map's resolved bin colours (`View.binColors`). Omitted ⇒ resolved from `dies`. */
|
|
125
|
+
binColors?: BinColors;
|
|
118
126
|
hardCounts?: Record<number, number>;
|
|
119
127
|
softCounts?: Record<number, number>;
|
|
120
128
|
/** The map's active plot mode. `hardBin`/`softBin` pick the matching bin type. */
|
|
@@ -126,7 +134,7 @@ export declare function buildBinBreakdownSection(params: {
|
|
|
126
134
|
* precomputed bin counts exist (`hardBinCounts`/`softBinCounts` are
|
|
127
135
|
* per-wafer only), so this scans the pooled `Die[]` directly, same as
|
|
128
136
|
* `buildBinSection` does when it has no `precomputedCounts`. */
|
|
129
|
-
export declare function buildLotBinSection(allDies: Die[], binDefs: BinDef[] | undefined, mode: 'hard' | 'soft',
|
|
137
|
+
export declare function buildLotBinSection(allDies: Die[], binDefs: BinDef[] | undefined, mode: 'hard' | 'soft', binColors?: ReadonlyMap<number, string>): HTMLDivElement | null;
|
|
130
138
|
/**
|
|
131
139
|
* Region yield as ONE section with a Ring/Quadrant selector, replacing the two
|
|
132
140
|
* always-on stacked sections (`Ring Yield` + `Quadrant Yield`) this used to render.
|
|
@@ -417,7 +425,8 @@ export declare function renderWaferSummaryContent(panel: HTMLDivElement, params:
|
|
|
417
425
|
warnings?: WaferWarning[];
|
|
418
426
|
passBins?: number[];
|
|
419
427
|
ringCount?: number;
|
|
420
|
-
|
|
428
|
+
/** The map's resolved bin colours (`View.binColors`), so bars match die fills. */
|
|
429
|
+
binColors?: BinColors;
|
|
421
430
|
/**
|
|
422
431
|
* The map's active plot mode. Selects which bin type the bin breakdown opens
|
|
423
432
|
* on, so the panel describes the population actually on screen — see
|
|
@@ -466,7 +475,8 @@ export declare function renderLotSummaryContent(panel: HTMLDivElement, params: {
|
|
|
466
475
|
testDefs?: TestDef[];
|
|
467
476
|
passBins?: number[];
|
|
468
477
|
ringCount?: number;
|
|
469
|
-
|
|
478
|
+
/** The gallery-wide bin colours, so bars match every card. */
|
|
479
|
+
binColors?: BinColors;
|
|
470
480
|
/** The gallery's active plot mode — see the wafer panel's `plotMode`. */
|
|
471
481
|
plotMode?: PlotMode;
|
|
472
482
|
fallbackFormat?: 'si' | 'engineering';
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{isParametricTest as _t}from"../renderer/buildWaferMap.js";import{buildRingRegions as jt,buildQuadrantRegions as qt,buildRegionYieldData as Vt}from"../stats/regions.js";import{computeFunctionalYield as Kt}from"../stats/analyzeWaferMap.js";import{renderSummaryReportHtml as Gt,renderLotSummaryReportHtml as Ut}from"../stats/renderSummaryReport.js";import{buildFindingsNarrative as Qt}from"../stats/findingsNarrative.js";import{filterFindings as Xt}from"../stats/filterFindings.js";import{buildFacetTable as Zt,prettyKey as xt}from"../stats/facets.js";import{commonMetadata as yt}from"../stats/facets.js";import{resolveMetadataColumns as Jt}from"../stats/metadataColumns.js";import{getColorScheme as te}from"../renderer/colorSchemes.js";import{buildWarningsBanner as mt,collectWarnings as Ct}from"./warnings.js";export{mt as buildWarningsBanner};import{fmt as St,fmtAggregationMethod as ee,plainBinTerms as nt}from"../renderer/fmt.js";import{getUniqueTestNumbers as ne}from"../renderer/buildView.js";import{quantile as it}from"../stats/math.js";import{buildCapabilityData as ie}from"../stats/capability.js";import{sortBinsForDisplay as oe}from"../stats/binPareto.js";import{poolFunctionalYield as ae}from"../stats/testPassRate.js";import{makeLabeledSelect as wt,makeSegmented as ht}from"./charts/chartShell.js";import{SHADOW as vt,MOTION as $t,LEADING as Q,TRACKING as rt,wireControlHover as O,controlStyle as lt,SPACE as y,RADIUS as _,FONT as E,CLR as B,sevColor as dt,openModal as kt,openReportModal as Lt,saveTextFile as Bt,wireTooltip as ot}from"./toolbar.js";import{buildDieListSection as se}from"./dieList.js";export{csvField}from"../core/utils.js";import{medianOfSorted as re,csvField as ct}from"../core/utils.js";import{metadataDisplayValue as le}from"../core/metadata.js";const de=B.panelBg,Nt=`1px solid ${B.menuBorder}`,ce="12px",Y=B.label,U=B.value,Et="10px";function s(t,n,i,e=document){const o=e.createElement(t);return n&&Object.assign(o.style,n),i!==void 0&&(o.textContent=i),o}function J(t){return s("div",{fontSize:Et,fontWeight:"700",letterSpacing:rt,textTransform:"uppercase",color:Y,marginBottom:y.sm},t)}const Ft=new WeakMap,Rt=["regionYield","testValues","functionalTests"];function pt(t){if(!t)return{collapsed:new Set(Rt),regionMode:"ring",waferSort:"slot"};let n=Ft.get(t);return n||(n={collapsed:new Set(Rt),regionMode:"ring",waferSort:"slot"},Ft.set(t,n)),n}function X(t,n=!0,i,e){const o=s("div"),a=pt(e?.panel);e?.stateKey&&e.panel&&(n=!a.collapsed.has(e.stateKey));const r=document.createElement("button");r.type="button",Object.assign(r.style,{display:"flex",alignItems:"center",gap:y.xs,width:"100%",background:"none",border:"none",cursor:"pointer",padding:"0 0 6px",textAlign:"left"});const f=s("span",{fontSize:E.meta,color:Y,transition:`transform ${$t.base}`,transform:n?"rotate(90deg)":"rotate(0deg)",display:"inline-block",lineHeight:Q.none,marginRight:"1px"},"\u25B6"),c=s("span",{fontSize:Et,fontWeight:"700",letterSpacing:rt,textTransform:"uppercase",color:Y,flex:"1"},t);if(O(r,"bare"),r.setAttribute("aria-expanded",n?"true":"false"),r.appendChild(f),r.appendChild(c),i){const b=s("span",{fontSize:E.meta,fontWeight:"700",background:B.warnBg,color:B.warnText,borderRadius:_.pill,padding:"1px 5px"},i);r.appendChild(b)}const l=s("div");l.style.display=n?"block":"none";let d=n;if(r.addEventListener("click",()=>{d=!d,l.style.display=d?"block":"none",f.style.transform=d?"rotate(90deg)":"rotate(0deg)",r.setAttribute("aria-expanded",d?"true":"false"),e?.stateKey&&e.panel&&(d?a.collapsed.delete(e.stateKey):a.collapsed.add(e.stateKey))}),e?.control){const b=s("div",{display:"flex",alignItems:"center",gap:y.sm});r.style.width="auto",r.style.flex="1",b.appendChild(r);const p=()=>{l.innerHTML="",e.render?.(l)},v=e.control(p);v&&(v.style.marginBottom="6px",v.addEventListener("click",N=>N.stopPropagation()),b.appendChild(v)),o.appendChild(b)}else o.appendChild(r);return o.appendChild(l),e?.render?.(l),{outer:o,content:l}}function Tt(){return s("div",{height:"1px",background:B.separator,margin:`${ce} 0`,flexShrink:"0"})}function gt(t,n,i=B.barFill,e,o){const a=s("div",{marginBottom:"5px"}),r=s("div",{display:"flex",justifyContent:"space-between",fontSize:E.body,color:U,marginBottom:y.xxs}),f=s("span",{color:Y},t),c=s("span",{fontWeight:"600"},`${n.toFixed(1)}%`);r.appendChild(f),r.appendChild(c);const l=e!==void 0?e:Math.min(100,Math.max(0,n)),d=i,b=s("div",{position:"relative",height:"9px",background:B.bgActive,borderRadius:_.control,overflow:"hidden"}),p=s("div",{height:"100%",width:`${l}%`,background:d,borderRadius:_.control,transition:`width ${$t.base}`});if(b.appendChild(p),o!==void 0){const v=s("div",{position:"absolute",top:"0",bottom:"0",left:`${o}%`,width:"2px",marginLeft:"-1px",background:B.value,opacity:"0.8"});b.appendChild(v)}return a.appendChild(r),a.appendChild(b),a}function Dt(){const t=s("div",{display:"flex",gap:y.sm,marginBottom:y.md});return t.finish=()=>{const n=t.lastElementChild;n&&Object.assign(n.style,{borderRight:"none",paddingRight:"0"})},t}function at(t,n,i){const e=s("div",{padding:`${y.xxs} ${y.md} ${y.xxs} 0`,borderRight:Nt,textAlign:"center",flex:"1"}),o=s("div",{fontSize:E.heading,fontWeight:"700",color:U,lineHeight:Q.tight},t),a=s("div",{fontSize:E.body,color:Y,marginTop:y.xxs},n);return e.appendChild(o),e.appendChild(a),i&&e.appendChild(s("div",{fontSize:E.body,color:Y,opacity:"0.85"},i)),e}function Mt(t,n){const i=s("div",{display:"flex",justifyContent:"space-between",fontSize:E.body,gap:y.md,marginBottom:"3px"}),e=s("span",{color:Y,flexShrink:"0"},t),o=s("span",{color:U,textAlign:"right",fontWeight:"500",wordBreak:"break-all"},n);return i.appendChild(e),i.appendChild(o),i}function pe(t,n){const i=s("div",{display:"flex",fontSize:E.body,gap:y.sm,marginBottom:"3px"}),e=s("span",{color:Y,flexShrink:"0"},`${t}:`),o=s("span",{color:U,fontWeight:"500",wordBreak:"break-all"},n);return i.appendChild(e),i.appendChild(o),i}export function metadataEntries(t){const n=[];for(const[i,e]of Object.entries(t)){const o=le(e);o!==void 0&&n.push([i,o])}return n}const ue=["lot","product","testprogram","split"],ut=t=>{const n=ue.indexOf(t.toLowerCase().replace(/[^a-z]/g,""));return n===-1?Number.MAX_SAFE_INTEGER:n};export function buildFacetSummaryChips(t,n=3){if(!t.length)return null;const i=s("div",{display:"flex",flexWrap:"wrap",alignItems:"baseline",gap:`${y.xs} ${y.lg}`}),e=[...t].sort((f,c)=>ut(f.key)-ut(c.key)),o=e.filter(f=>ut(f.key)!==Number.MAX_SAFE_INTEGER),a=e.filter(f=>ut(f.key)===Number.MAX_SAFE_INTEGER),r=f=>{const c=s("span",{whiteSpace:"nowrap"}),l=s("span",{color:Y},`${xt(f.key)}: `);c.appendChild(l);const d=f.values.slice(0,n),b=f.values.length-d.length;let p=d.map(v=>v.value).join(", ");return b>0&&(p+=` +${b} more`),c.appendChild(document.createTextNode(p)),c};for(const f of o)i.appendChild(r(f));if(a.length){const f=s("span",{display:"none",flexWrap:"wrap",alignItems:"baseline",gap:`${y.xs} ${y.lg}`});for(const d of a)f.appendChild(r(d));const c=s("button",{background:"none",border:"none",padding:"0",cursor:"pointer",color:B.iconActive,fontSize:E.body,whiteSpace:"nowrap"});c.type="button",O(c,"bare");const l=d=>{f.style.display=d?"contents":"none",c.textContent=d?"less":`+${a.length} more`,c.setAttribute("aria-expanded",String(d))};l(!1),c.addEventListener("click",()=>l(c.getAttribute("aria-expanded")!=="true")),i.appendChild(f),i.appendChild(c)}return i}export function buildMetadataStripRow(t,n,i){const e=Zt(t,i),o=buildFacetSummaryChips(e);if(!o&&!n)return null;const a=s("div",{display:"flex",flexWrap:"wrap",alignItems:"baseline",gap:"4px 14px"});if(n){const r=s("span",{fontWeight:"500",whiteSpace:"nowrap"},n.aggrMethod?`${n.lotSize} wafers stacked \xB7 ${n.aggrMethod}`:`${n.lotSize} wafers stacked`);a.appendChild(r)}return o&&a.appendChild(o),a}const fe={display:"flex",flexDirection:"column",gap:y.sm,background:B.menuBg,border:`1px solid ${B.menuBorder}`,borderRadius:_.container,padding:`${y.sm} ${y.lg}`,boxShadow:vt.panel,fontSize:E.body,lineHeight:Q.none,boxSizing:"border-box",width:"100%",minWidth:"0"};export function buildMetadataStripBox(t,n,i){const e=buildMetadataStripRow(t,n,i);if(!e)return null;const o=s("div",fe);return o.appendChild(e),o}export function buildCompactMetadataRows(t){const n=metadataEntries(t);if(!n.length)return null;const i=s("div");for(const[e,o]of n)i.appendChild(pe(xt(e),o));return i}export function buildMetadataInfoSection(t,n){const i=buildMetadataStripRow(t,n,{facetableOnly:t.length>1});if(!i)return null;const e=s("div");return e.appendChild(J("Wafer Info")),e.appendChild(i),e}export function buildYieldSection(t,n,i=[1]){const e=s("div");e.appendChild(J("Summary"));const o=Dt();if(o.appendChild(at(String(t.totalDies),"Total dies")),t.partialDies>0&&o.appendChild(at(String(t.partialDies),"Partial")),t.yieldPercent!==null){const a=i.length===1?`bin ${i[0]}`:`bins ${i.join(", ")}`;o.appendChild(at(`${t.yieldPercent.toFixed(1)}%`,"Yield",`pass: ${a}`))}return o.finish(),e.appendChild(o),t.edgeExcludedDies>0&&e.appendChild(Mt("Edge excluded (outer zone)",String(t.edgeExcludedDies))),e}export function buildBinSection(t,n,i,e,o,a){const r=new Map;if(o)for(const[c,l]of Object.entries(o))r.set(Number(c),l);else for(const c of t){if(c.partial||c.edgeExcluded)continue;const l=i==="hard"?c.hbin:c.sbin;l!=null&&r.set(l,(r.get(l)??0)+1)}if(!r.size)return null;const f=s("div");f.appendChild(J(At(i,[...r.values()].reduce((c,l)=>c+l,0))));for(const c of It(r,n,e,a))f.appendChild(c);return f}function At(t,n){return`${t==="hard"?"Hard":"Soft"} Bin Breakdown \u2014 % of dies (N=${n})`}function It(t,n,i,e=[1]){const o=[...t.values()].reduce((c,l)=>c+l,0),a=n?new Map(n.map(c=>[c.bin,c])):null,r=oe(t.entries(),e),f=te(i);return r.map(([c,l])=>{const d=a?.get(c),b=d?.name?`Bin ${c} \xB7 ${d.name}`:`Bin ${c}`,p=l/o*100,v=(i==="custom"?d?.color:void 0)??f.forBin(c);return gt(`${b} (${l})`,p,v)})}export function buildBinBreakdownSection(t){const{dies:n,hbinDefs:i,sbinDefs:e,colorScheme:o,hardCounts:a,softCounts:r,plotMode:f,passBins:c=[1],panel:l}=t,d=m=>{const x=m==="hard"?a:r,S=new Map;if(x){for(const[$,L]of Object.entries(x))S.set(Number($),L);return S}for(const $ of n){if($.partial||$.edgeExcluded)continue;const L=m==="hard"?$.hbin:$.sbin;L!=null&&S.set(L,(S.get(L)??0)+1)}return S},b=d("hard"),p=d("soft"),v=b.size>0,N=p.size>0;if(!v&&!N)return null;const M=pt(l),W=f==="softBin"||f==="stackedSoftBins"?"soft":f==="hardBin"||f==="stackedBins"?"hard":void 0;let R=M.binMode??W??(v?"hard":"soft");R==="hard"&&!v&&(R="soft"),R==="soft"&&!N&&(R="hard");const H=R==="hard"?b:p,h=R==="hard"?i:e,u=[...H.values()].reduce((m,x)=>m+x,0),{outer:w}=X(At(R,u),!0,void 0,{stateKey:"bins",panel:l,render:m=>{for(const x of It(H,h,o,c))m.appendChild(x)},control:v&&N&&l?()=>ht([["hard","Hard"],["soft","Soft"]],R,m=>{M.binMode=m;const x=buildBinBreakdownSection(t);x&&w.replaceWith(x)},l.ownerDocument,!0):void 0});return w}export function buildLotBinSection(t,n,i,e){return buildBinSection(t,n,i,e)}export function buildRegionYieldPanelSection(t){const{diesByWafer:n,allWafers:i,ringCount:e,passBins:o,panel:a}=t,r=pt(a),f=d=>Vt(n,i,e,o,d==="ring"?jt:qt);if(!f("ring").length&&!f("quadrant").length)return null;const c=r.regionMode,{outer:l}=X(c==="ring"?"Ring Yield":"Quadrant Yield",!0,void 0,{stateKey:"regionYield",panel:a,render:d=>{const b=f(c);if(!b.length){d.appendChild(s("div",{fontSize:E.body,color:Y},"No positioned dies for this breakdown."));return}for(const{label:p,n:v,yieldPercent:N}of b)d.appendChild(gt(`${p} (N=${v})`,N))},control:a?()=>ht([["ring","Ring"],["quadrant","Quadrant"]],c,d=>{r.regionMode=d;const b=buildRegionYieldPanelSection(t);b&&l.replaceWith(b)},a.ownerDocument,!0):void 0});return l}export function buildLotOverviewSection(t,n=[]){const i=s("div");i.appendChild(J("Lot Summary"));const e=Dt();e.appendChild(at(String(t.stats.waferCount),"Wafers"));const o=t.perWafer.map(a=>a.summary.stats.yieldPercent).filter(a=>a!==null);if(o.length){const a=o.reduce((r,f)=>r+f,0)/o.length;e.appendChild(at(`${a.toFixed(1)}%`,"Mean per-wafer yield"))}if(e.finish(),i.appendChild(e),n.length){const a=n.reduce((f,c)=>f+c.stats.analyzedDies,0),r=n.reduce((f,c)=>f+c.stats.excludedDies,0);(a||r)&&i.appendChild(Mt("Dies analysed",r?`${a.toLocaleString()} (${r.toLocaleString()} excluded)`:a.toLocaleString()))}return i}export function buildPerWaferYieldSection(t,n,i,e,o){const a=t.perWafer.map(u=>({waferIndex:u.waferIndex,label:(n[u.waferIndex]?.label??`W${u.waferIndex+1}`).replace(/\s*·\s*\d+(\.\d+)?%$/,""),yieldPct:u.summary.stats.yieldPercent})).filter(u=>u.yieldPct!==null);if(!a.length)return null;const r=Math.min(...a.map(u=>u.yieldPct)),f=Math.max(...a.map(u=>u.yieldPct)),c=r===f?"":` (${r.toFixed(1)}\u2013${f.toFixed(1)}%)`,l=[...a.map(u=>u.yieldPct)].sort((u,w)=>u-w),d=re(l),b=it(l,.25),p=it(l,.75),v=a.length>=5?b-1.5*(p-b):-1/0,N=pt(e),M=u=>{const w=N.waferSort==="yield"?[...a].sort((m,x)=>m.yieldPct-x.yieldPct):a;for(const{waferIndex:m,label:x,yieldPct:S}of w){const L=S<v?`${x} \xB7 low outlier`:x,F=gt(L,S,void 0,void 0,d),T=o?.(m);T?.total&&H(F,T),h(F,m,x,S,T),u.appendChild(F)}},W=` \xB7 median ${d.toFixed(1)}%`,{outer:R}=X("Wafer Yield"+c+W,!0,void 0,{stateKey:"waferYield",panel:e,render:M,control:e?u=>ht([["slot","Slot"],["yield","Yield"]],N.waferSort,w=>{N.waferSort=w,u()},e.ownerDocument,!0):void 0});return R;function H(u,w){const m=w.unusual?"unusual":w.notable?"notable":"info",x=s("span",{marginLeft:y.sm,flexShrink:"0",background:dt(m),color:"#fff",borderRadius:_.container,padding:"0 5px",fontSize:E.body,fontWeight:"600"},`${w.total}`);x.setAttribute("aria-hidden","true"),ot(x,`${w.total} finding${w.total===1?"":"s"}`+(w.unusual?`, ${w.unusual} unusual`:"")+(w.notable?`, ${w.notable} notable`:"")),u.firstElementChild?.firstElementChild?.appendChild(x)}function h(u,w,m,x,S){i&&(u.style.cursor="pointer",u.style.borderRadius="4px",u.style.padding="2px 3px",u.style.marginLeft="-3px",u.style.marginRight="-3px",u.setAttribute("role","button"),u.setAttribute("aria-label",`${m}, ${x.toFixed(1)}% yield`+(S?.total?`, ${S.total} finding${S.total===1?"":"s"}${S.unusual?`, ${S.unusual} unusual`:""}`:"")+" \u2014 open wafer"),u.tabIndex=0,u.addEventListener("mouseenter",()=>{u.style.background=B.bgHover}),u.addEventListener("mouseleave",()=>{u.style.background=""}),u.addEventListener("focus",()=>{u.style.background=B.bgHover}),u.addEventListener("blur",()=>{u.style.background=""}),u.addEventListener("click",()=>i(w)),u.addEventListener("keydown",$=>{($.key==="Enter"||$.key===" ")&&($.preventDefault(),i(w))}))}}function me(t){const n=[...t].sort((o,a)=>o-a),i=t.reduce((o,a)=>o+a,0)/t.length,e=t.reduce((o,a)=>o+(a-i)**2,0)/t.length;return{min:n[0],max:n[n.length-1],mean:i,count:t.length,stddev:Math.sqrt(e),median:it(n,.5),q1:it(n,.25),q3:it(n,.75)}}function Wt(t,n){if(!t)return[];const i=t.waferMetadata??(t.perWaferMetadata?yt(t.perWaferMetadata.map(e=>({metadata:e}))):void 0);return!i||!Object.keys(i).length?[]:Jt({waferMetadata:i,waferKeys:"identity",waferPlacement:"csv",reservedLabels:n}).columns}function Pt(t){return t?.populationLabel?[{key:"population",label:"Population",scope:"wafer",constant:t.populationLabel,get:()=>t.populationLabel,csvOnly:!0}]:[]}export function buildTestSection(t,n,i,e,o,a,r,f,c="full"){const l=t.filter(g=>!g.partial&&!g.edgeExcluded),d=new Map((e?.perTestStats??[]).map(g=>[g.testNumber,g])),b=new Map((e?.testSpecYield??[]).map(g=>[g.testNumber,g]));let p;if(n?.length?p=n.filter(_t).map(g=>({testNumber:g.testNumber,name:g.name,unit:g.unit,limitLow:g.limitLow,limitHigh:g.limitHigh})):p=ne(l).map(C=>({testNumber:C,name:`Test ${C}`})),!p.length)return null;const v=p.filter(g=>l.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=d.get(g.testNumber),I=C&&C.stddev!==void 0&&C.median!==void 0&&C.q1!==void 0&&C.q3!==void 0;let j;if(I){const k=C;j={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=l.map(D=>D.testValues?.[g.testNumber]).filter(D=>D!==void 0&&isFinite(D));if(!k.length)continue;j={testNumber:g.testNumber,...me(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=l.map(q=>q.testValues?.[g.testNumber]).filter(q=>q!==void 0&&isFinite(q)),Z=D.filter(q=>g.limitLow!==void 0&&q<g.limitLow||g.limitHigh!==void 0&&q>g.limitHigh).length;P=D.length,z=D.length>0?(D.length-Z)/D.length*100:null}}M.push({entry:g,stats:j,specYieldPct:z,specN:P})}if(!M.length)return null;const W=new Map;if(r?.length&&n?.length)for(const g of ie(r,n))g.hasSpec&&W.set(g.testNumber,g.ppk);const R=W.size>0,h=new Set(M.map(g=>g.stats.count)).size===1?M[0].stats.count:null,u=s("div"),w=s("div",{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:y.sm}),m=h!==null?` \xB7 N=${h.toLocaleString()}`:"",x=a?.populationLabel?`Test Values (${M.length}) \u2014 ${a.populationLabel}${m}`:`Test Values (${M.length})${m}`,S=J(x);S.style.marginBottom="0",w.appendChild(S);const $=document.createElement("button");$.type="button",$.textContent="Test values CSV",Object.assign($.style,{...lt("outlined")}),O($),$.addEventListener("click",()=>{const g=["Test","Unit","N","Min","Q1","Median","Mean","Q3","Max","StdDev"];R&&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=[...Wt(a,g),...Pt(a)],z=[[...I.map(k=>k.label),...g].map(ct).join(",")],P=k=>St(k,void 0,"engineering");for(const{entry:k,stats:D,specYieldPct:Z,specN:q}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(R){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(q):"")),z.push(st.map(ct).join(","))}Bt(z.join(`
|
|
2
|
-
`),"test-values.csv","text/csv",
|
|
3
|
-
`),"functional-tests.csv","text/csv",e)}),b.appendChild(N),d.appendChild(b);const M=s("table",{width:"100%",borderCollapse:"collapse",fontSize:E.body}),W=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(s("th",{textAlign:m==="Test"?"left":"right",fontWeight:"700",fontSize:E.body,letterSpacing:rt,textTransform:"uppercase",color:Y,padding:"3px 8px 5px",borderBottom:`1px solid ${B.menuBorder}`,whiteSpace:"nowrap"},m));W.appendChild(R),M.appendChild(W);const h=document.createElement("tbody");for(const m of r){const x=document.createElement("tr"),S=($,L="right")=>{x.appendChild(s("td",{textAlign:L,padding:`${y.xs} ${y.md}`,borderBottom:`1px solid ${B.menuBorder}`,color:U,whiteSpace:"nowrap"},$))};S(m.label,"left"),c===null&&S(String(m.totalDies)),S(String(m.passDies)),S(String(m.failDies)),S(m.passRatePercent!==null?`${m.passRatePercent.toFixed(1)}%`:"\u2014"),h.appendChild(x)}M.appendChild(h);const u=s("div",{overflowX:"auto"});if(u.appendChild(M),!a)return d.appendChild(u),d;b.remove();const{outer:w}=X(p,!0,void 0,{stateKey:"functionalTests",panel:a,render:m=>m.appendChild(u),control:()=>N});return w}export function buildLotFunctionalSection(t,n,i,e,o){const a=i?.length?{perWaferMetadata:i.map(f=>f.wafer??{}),populationLabel:`${i.length} wafer${i.length===1?"":"s"} pooled`}:void 0,r=ae(i);return r?buildFunctionalTestSection(t,n,r,e,a,o):buildFunctionalTestSection(t,n,void 0,e,a,o)}const tt={unusual:0,notable:1,info:2};function bt(t){return s("span",{display:"inline-block",width:"7px",height:"7px",borderRadius:_.pill,background:dt(t),flexShrink:"0"})}function zt(t,n){let i=t.summary;return n&&(i.startsWith(`${n} has `)?i=i.slice(n.length+5):i.startsWith(`${n} `)&&(i=i.slice(n.length+1))),i=nt(i),i.length?i[0].toUpperCase()+i.slice(1):i}export function buildFindingsSection(t,n,i,e,o=!1){if(!t.length)return null;const a=t.some(h=>h.severity==="unusual"||h.severity==="notable"),r=a?t.filter(h=>h.severity!=="info").length.toString():void 0,{outer:f,content:c}=o?(()=>{const h=s("div");return{outer:h,content:h}})():X(`Findings (${t.length})`,a,r);function l(h){return h.reduce((u,w)=>tt[w.severity]<tt[u]?w.severity:u,"info")}function d(h){const u=new Map;for(const m of h){const x=`${m.comparison.family}\0${m.comparison.left}`,S=u.get(x)??[];S.push(m),u.set(x,S)}const w=[...u.entries()].map(([m,x])=>{const S=[...x].sort(($,L)=>tt[$.severity]-tt[L.severity]);return{key:m,findings:S,worst:l(S)}});return w.sort((m,x)=>tt[m.worst]-tt[x.worst]),w}function b(h,u){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 u.toLowerCase().startsWith(m.toLowerCase())?u:`${m}: ${u}`}const p=t.filter(h=>h.comparison.family==="spatial-pattern"),v=new Set([...p.flatMap(h=>h.relatedIds??[]),...t.flatMap(h=>h.absorbedIds??[])]),N=t.filter(h=>h.comparison.family!=="spatial-pattern"&&!v.has(h.id)),M=d(N);function W(h,u=!1,w){const m=e===h.id,x=document.createElement("button");return x.type="button",x.dataset.wmapFinding=h.id,x.textContent=zt(h,w),ot(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:_.container,padding:u?"6px 10px":"8px 10px",textAlign:"left",fontSize:u?"10px":"11px",fontWeight:m?"600":"400",color:B.text,cursor:"pointer",width:"100%",marginBottom:y.xs}),O(x,"bare"),x.addEventListener("click",()=>i(h,x)),x}const R=nt(Qt(t)??"");if(R){const h=s("div",{background:B.bgActive,borderRadius:_.container,padding:`${y.md} ${y.lg}`,marginBottom:y.md,display:"flex",gap:y.md,alignItems:"flex-start"}),u=s("span",{flex:"1",fontSize:E.body,lineHeight:Q.base,color:B.text},R);h.appendChild(u);const w=s("button",{flexShrink:"0",border:"none",background:"none",fontSize:E.body,color:B.icon,cursor:"pointer",padding:"0",lineHeight:Q.base,whiteSpace:"nowrap"},"Detail \u25B8");w.type="button",O(w,"bare"),w.addEventListener("click",()=>{const m=kt({title:"Findings Summary",onClose:()=>{},anchor:w}),x=s("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"},R);m.contentWrap.appendChild(x);const S=s("div",{overflowY:"auto",padding:`${y.xxl} ${y.xxxl}`,flex:"1"}),$=(L,F)=>{const T=s("div",{display:"flex",alignItems:"center",gap:"7px",fontSize:E.sub,fontWeight:"600",color:U,marginTop:y.lg,marginBottom:y.xs});return T.appendChild(bt(L)),T.appendChild(s("span",{},F)),T};for(const L of p){S.appendChild($(L.severity,L.comparison.left)),S.appendChild(s("div",{fontSize:E.body,color:B.text,padding:"4px 0 4px 15px",marginBottom:y.xxs},nt(L.summary)));const F=t.filter(T=>L.relatedIds?.includes(T.id));for(const T of F)S.appendChild(s("div",{fontSize:E.body,color:Y,padding:"2px 0 2px 23px",marginBottom:y.xxs},nt(T.summary)))}for(const L of M){const[F,T]=L.key.split("\0");S.appendChild($(L.worst,b(F,T)));for(const A of L.findings)S.appendChild(s("div",{fontSize:E.body,color:B.text,padding:"4px 0 4px 15px",marginBottom:y.xxs},zt(A,T)))}m.contentWrap.appendChild(S),Object.assign(m.contentWrap.style,{flexDirection:"column",overflow:"hidden"})}),h.appendChild(w),c.appendChild(h)}let H=!0;for(const h of p){H||c.appendChild(s("div",{height:"1px",background:B.separator,margin:"4px 0"})),H=!1;const u=t.filter($=>h.relatedIds?.includes($.id)),w=u.length>0,m=s("div",{position:"relative",marginBottom:w?"2px":"4px"}),x=e===h.id,S=document.createElement("button");if(S.type="button",S.dataset.wmapFinding=h.id,Object.assign(S.style,{border:`1px solid ${B.menuBorder}`,borderLeft:`3px solid ${dt(h.severity)}`,background:x?B.bgActive:B.menuBg,borderRadius:_.container,padding:"8px 32px 8px 10px",textAlign:"left",fontSize:E.body,fontWeight:x?"600":"500",color:B.text,cursor:"pointer",width:"100%"}),S.textContent=nt(h.summary),ot(S,h.summary),S.setAttribute("aria-current",x?"true":"false"),O(S,"bare"),S.addEventListener("click",()=>i(h,S)),m.appendChild(S),w){const $=s("div",{display:"none",paddingLeft:"12px",marginBottom:y.xs});for(const T of u)$.appendChild(W(T,!0));m.appendChild($);let L=!1;const F=s("button",{position:"absolute",top:"50%",right:"8px",transform:"translateY(-50%)",border:"none",background:"none",fontSize:E.body,color:B.icon,cursor:"pointer",padding:`${y.xxs} ${y.xs}`,lineHeight:Q.none},"\u25B8");O(F,"bare"),F.type="button",ot(F),O(F,"bare"),F.setAttribute("aria-label","Show supporting findings"),F.setAttribute("aria-expanded","false"),F.addEventListener("click",T=>{T.stopPropagation(),L=!L,$.style.display=L?"block":"none",F.textContent=L?"\u25BE":"\u25B8";const A=L?"Hide supporting findings":"Show supporting findings";F.setAttribute("aria-label",A),F.setAttribute("aria-expanded",String(L))}),m.appendChild(F)}c.appendChild(m)}for(const h of M){H||c.appendChild(s("div",{height:"1px",background:B.separator,margin:"4px 0"})),H=!1;const[u,w]=h.key.split("\0"),m=s("div",{display:"flex",alignItems:"center",gap:y.sm,fontSize:E.body,fontWeight:"600",color:U,margin:"2px 0 4px"});m.appendChild(bt(h.worst)),m.appendChild(s("span",{},b(u,w))),c.appendChild(m);for(const x of h.findings)c.appendChild(W(x,!1,w))}return f}const he=[{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"}],ge=[{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"}],be=["unusual","notable","info"],xe={unusual:"Unusual",notable:"Notable",info:"Info"};function ye(t,n,i){const e=s("div",{display:"flex",flexWrap:"wrap",alignItems:"center",gap:y.lg,marginBottom:y.lg,paddingBottom:"10px",borderBottom:`1px solid ${B.separator}`}),o={unusual:0,notable:0,info:0};for(const l of t)o[l.severity]++;const a=be.filter(l=>o[l]>0),r=new Set(n.severity===void 0?a:Array.isArray(n.severity)?n.severity:[n.severity]),f=s("div",{display:"flex",gap:y.xs,flexWrap:"wrap"});for(const l of a){const d=document.createElement("button");d.type="button";const b=()=>{const p=r.has(l);d.setAttribute("aria-pressed",p?"true":"false"),Object.assign(d.style,{display:"inline-flex",alignItems:"center",gap:"5px",border:`1px solid ${B.menuBorder}`,borderRadius:_.pill,background:p?B.bgActive:"none",opacity:p?"1":"0.5",color:B.text,fontSize:E.body,padding:`${y.xxs} ${y.md}`,cursor:"pointer"}),d.dataset.on=p?"true":"false"};d.appendChild(bt(l)),d.appendChild(s("span",{},`${xe[l]} ${o[l]}`)),ot(d,()=>r.has(l)?"Click to hide these findings":"Click to show these findings"),b(),O(d,"bare"),d.addEventListener("click",()=>{r.has(l)?r.delete(l):r.add(l),n.severity=r.size===a.length?void 0:[...r],i()}),f.appendChild(d)}e.appendChild(f);const c=n.kind!==void 0||n.family!==void 0;return(t.length>=Ce||c)&&(e.appendChild(wt("Kind:",he,n.kind??"",l=>{n.kind=l||void 0,i()},{maxWidth:"130px"})),e.appendChild(wt("Region:",ge,n.family??"",l=>{n.family=l||void 0,i()},{maxWidth:"150px"}))),e}const Ce=8;function Se(t,n){const i=s("div",{display:"flex",flexDirection:"column",gap:y.xs,padding:y.md,marginBottom:y.md,background:B.bgHover,borderRadius:_.control},void 0,n);if(i.appendChild(s("div",{fontSize:E.body,color:B.value},t.message,n)),t.detail&&i.appendChild(s("div",{fontSize:E.meta,color:Y},t.detail,n)),t.actionLabel&&t.onAction){const e=s("button",lt("outlined"),t.actionLabel,n);e.type="button",e.style.alignSelf="flex-start",e.style.marginTop=y.xs,O(e),e.addEventListener("click",t.onAction),i.appendChild(e)}return i}export function buildFindingsSectionWithFilter(t,n,i,e,o,a,r){if(!t.findings.length&&!r)return null;const f=t.findings.some(N=>N.severity==="unusual"||N.severity==="notable"),c=f?t.findings.filter(N=>N.severity!=="info").length.toString():void 0,l=a?.ownerDocument??document,{outer:d,content:b}=X(`Findings (${t.findings.length})`,f||!!r,c,{stateKey:"findings",panel:a});if(r&&b.appendChild(Se(r,l)),!t.findings.length)return d;b.appendChild(ye(t.findings,e,o));const p=Xt(t,e);if(!p.length)return b.appendChild(s("div",{color:Y,fontSize:E.body,textAlign:"center",padding:`${y.xxl} ${y.md}`},"No findings match the current filter.")),d;const v=buildFindingsSection(p,t,n,i,!0);return v&&b.appendChild(v),d}export function buildLotTestSection(t,n,i,e,o,a,r,f="full"){const c=e?.length?{perWaferMetadata:e.map(d=>d.wafer??{}),populationLabel:`${e.length} wafer${e.length===1?"":"s"} pooled`}:void 0;let l;if(e?.length&&e.every(d=>d.stats.perTestStats!==void 0)){const d=new Map;for(const b of e)for(const p of b.stats.perTestStats??[]){const v=d.get(p.testNumber);v?(v.n+=p.count,v.sum+=p.mean*p.count,v.min=Math.min(v.min,p.min),v.max=Math.max(v.max,p.max)):d.set(p.testNumber,{n:p.count,sum:p.mean*p.count,min:p.min,max:p.max})}l={perTestStats:[...d.entries()].map(([b,p])=>({testNumber:b,count:p.n,min:p.min,max:p.max,mean:p.sum/p.n}))}}if(e?.length&&e.every(d=>d.stats.testSpecYield!==void 0)){const d=new Map;for(const b of e)for(const p of b.stats.testSpecYield??[]){const v=d.get(p.testNumber);v?(v.passDies+=p.passDies,v.totalDies+=p.totalDies):d.set(p.testNumber,{passDies:p.passDies,totalDies:p.totalDies})}l={...l,testSpecYield:[...d.entries()].map(([b,p])=>({testNumber:b,totalDies:p.totalDies,yieldPercent:p.totalDies>0?p.passDies/p.totalDies*100:null}))}}return buildTestSection(t,n,i,l,o,c,a,r,f)}export function createSummaryPanelEl(t,n,i=document){const e=t==="top"||t==="bottom",o=s("div",{background:de,color:B.text,fontVariantNumeric:"tabular-nums",border:Nt,borderRadius:_.container,padding:y.xl,overflowY:e?"hidden":"auto",overflowX:e?"auto":"hidden",flexShrink:"0",boxSizing:"border-box",fontFamily:E.family,fontSize:E.sub,boxShadow:vt.panel},void 0,i);return t==="right"&&(o.style.marginRight=n),t==="left"&&(o.style.marginLeft=n),t==="bottom"&&(o.style.marginBottom=n),e?(o.style.height="180px",o.style.width="100%"):(o.style.width="300px",o.style.maxHeight="100%"),o}export function wrapWithSummaryPanel(t,n,i){const e=i==="top"||i==="bottom",o=s("div",{display:"flex",flexDirection:e?"column":"row",gap:y.md,width:"100%",height:"100%",flex:"1 1 0",minHeight:"0",boxSizing:"border-box",alignItems:e?"flex-start":"stretch"});return t.style.flex="1 1 0",t.style.minWidth="0",t.style.minHeight="0",i==="right"||i==="bottom"?(o.appendChild(t),o.appendChild(n)):(o.appendChild(n),o.appendChild(t)),o}function Ht(t){return s("div",{fontSize:E.heading,fontWeight:"600",color:U,marginBottom:y.lg},t)}function ft(t,n){const i=s("button",lt("outlined"),t);return i.type="button",O(i),i.addEventListener("click",n),i}function Yt(...t){const n=t.filter(e=>!!e);if(!n.length)return null;const i=s("div",{display:"flex",flexWrap:"wrap",gap:y.sm,marginBottom:y.lg});for(const e of n)i.appendChild(e);return i}function Ot(t,n,i,e,o,a,r,f,c,l,d){const b=t.ownerDocument,p=kt({title:"Die list",onClose:()=>{},anchor:t,ownerDocument:b});p.contentWrap.style.padding="14px 16px";const v=se(n,i,{...r,title:e,onSaveText:f,waferMetadata:o,metadataFields:a,extraColumn:c,getWafer:l,ringCount:d,ownerDocument:b});v&&p.contentWrap.appendChild(v)}export function renderWaferSummaryContent(t,n){const i=t.scrollTop;t.innerHTML="";const{wafer:e,dies:o,yieldSummary:a,dataCoverage:r,hbinDefs:f,sbinDefs:c,testDefs:l,statsSummary:d,passBins:b=[1],ringCount:p=4,colorScheme:v,plotMode:N,fallbackFormat:M,onFindingClick:W,activeFindingId:R=null,findingsFilter:H,onFindingsFilterChange:h,findingsNotice:u,onSaveText:w,metadataFields:m,dieListOptions:x,metadataShownElsewhere:S}=n;t.appendChild(Ht("Wafer Summary"));const $=n.warnings??Ct({statsSummary:d});$.length&&t.appendChild(mt($,t.ownerDocument));const L=a&&r?ft("Summary report",()=>{Lt(Gt({wafer:e,dies:o,yieldSummary:a,dataCoverage:r,hbinDefs:f,sbinDefs:c,testDefs:l,statsSummary:d,passBins:b,ringCount:p}),{anchor:t})}):null,F=(x?.enabled??!0)&&o.length?ft("View die list",()=>{Ot(t,o,l,`Die list \u2014 ${o.length} dies`,e.metadata,m,x,w,void 0,()=>e,p)}):null,T=Yt(L,F);T&&t.appendChild(T);const A=[],V=d?.stats.isLotStack?d.stats:void 0,K=V?.lotSize!==void 0?{lotSize:V.lotSize,aggrMethod:ee(V.aggregationMethod)}:void 0;S||A.push(buildMetadataInfoSection([{metadata:e.metadata??void 0}],K)),a&&r&&A.push(buildYieldSection(a,r,b)),d&&W&&H&&h&&A.push(buildFindingsSectionWithFilter(d,W,R,H,h,t,u)),A.push(buildBinBreakdownSection({dies:o,hbinDefs:f,sbinDefs:c,colorScheme:v,hardCounts:d?.stats.hardBinCounts,softCounts:d?.stats.softBinCounts,plotMode:N,passBins:b,panel:t})),A.push(buildRegionYieldPanelSection({diesByWafer:[o],allWafers:[e],ringCount:p,passBins:b,panel:t}));const G=e.metadata?{waferMetadata:e.metadata}:void 0;A.push(buildTestSection(o,l,M,d?.stats,w,G,[{dies:o}],t,"compact")),A.push(buildFunctionalTestSection(o,l,d?.stats.functionalYield,w,G,t));let g=!0;for(const C of A)C&&(g||t.appendChild(Tt()),g=!1,t.appendChild(C));t.appendChild(s("div",{height:"12px",flexShrink:"0"})),t.scrollTop=i}export function renderLotSummaryContent(t,n){const i=t.scrollTop;t.innerHTML="";const{lotSummary:e,items:o,hbinDefs:a,sbinDefs:r,testDefs:f,passBins:c=[1],ringCount:l=4,colorScheme:d,plotMode:b,fallbackFormat:p,onFindingClick:v,activeFindingId:N=null,onWaferClick:M,findingsFilter:W,onFindingsFilterChange:R,findingsNotice:H,onSaveText:h,dieListOptions:u,findingsFor:w}=n;t.appendChild(Ht(`Lot Summary \u2014 ${e.stats.waferCount} wafer${e.stats.waferCount===1?"":"s"}`));const m=n.warnings??Ct({lotStatsSummary:e});m.length&&t.appendChild(mt(m,t.ownerDocument));const x=ft("Summary report",()=>{Lt(Ut({items:o.map((C,I)=>({label:C?.label??`W${I+1}`,wafer:C?.wafer,dies:C?.dies,statsSummary:C?.statsSummary})),hbinDefs:a,sbinDefs:r,testDefs:f,passBins:c,ringCount:l}),{anchor:t})}),S=[],$=[],L=[],F=new WeakMap,T=new WeakMap;for(let C=0;C<o.length;C++){const I=o[C];if(!I){$.push([]);continue}I.wafer&&S.push(I.wafer);const j=I.dies??[],z=I.label??`W${C+1}`;for(const P of j)F.set(P,z),I.wafer&&T.set(P,I.wafer);$.push(j),L.push(...j)}const A=u?.enabled??!0?ft("View die list",()=>{L.length&&Ot(t,L,f,`Die list \u2014 ${L.length} dies across ${o.length} wafer${o.length===1?"":"s"}`,yt(o.filter(C=>!!C).map(C=>({metadata:C.wafer?.metadata}))),o.find(C=>C?.metadataFields?.length)?.metadataFields,u,h,{label:"Wafer",get:C=>F.get(C)},C=>T.get(C),l)}):null,V=Yt(x,A);V&&t.appendChild(V);const K=o.map(C=>C?.statsSummary).filter(C=>!!C),G=[buildLotOverviewSection(e,K)];v&&W&&R&&G.push(buildFindingsSectionWithFilter(e,v,N,W,R,t,H)),G.push(buildPerWaferYieldSection(e,o,M,t,w),buildBinBreakdownSection({dies:L,hbinDefs:a,sbinDefs:r,colorScheme:d,plotMode:b,passBins:c,panel:t}),buildRegionYieldPanelSection({diesByWafer:$,allWafers:S,ringCount:l,passBins:c,panel:t}),f?.length?buildLotTestSection(L,f,p,K,h,$.map(C=>({dies:C})),t,"compact"):null,f?.length?buildLotFunctionalSection(L,f,K,h,t):null);let g=!0;for(const C of G)C&&(g||t.appendChild(Tt()),g=!1,t.appendChild(C));t.appendChild(s("div",{height:"12px",flexShrink:"0"})),t.scrollTop=i}
|
|
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}
|