@wafertools/wafermap 0.29.0 → 0.30.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +26 -17
- package/CHANGELOG.md +410 -0
- package/README.md +6 -6
- package/dist/packages/canvas-adapter/charts/barPanel.js +1 -1
- package/dist/packages/canvas-adapter/charts/binCluster.js +1 -1
- package/dist/packages/canvas-adapter/charts/boxplot.js +1 -1
- package/dist/packages/canvas-adapter/charts/capability.js +1 -1
- package/dist/packages/canvas-adapter/charts/correlation.js +2 -2
- package/dist/packages/canvas-adapter/charts/groupedBarPlot.d.ts +1 -0
- package/dist/packages/canvas-adapter/charts/histogram.js +1 -1
- package/dist/packages/canvas-adapter/charts/testPassRate.js +1 -1
- package/dist/packages/canvas-adapter/charts/trend.js +1 -1
- package/dist/packages/canvas-adapter/deprecated.d.ts +7 -0
- package/dist/packages/canvas-adapter/deprecated.js +1 -0
- package/dist/packages/canvas-adapter/dieList.d.ts +1 -3
- package/dist/packages/canvas-adapter/dieList.js +7 -7
- package/dist/packages/canvas-adapter/exportName.d.ts +68 -0
- package/dist/packages/canvas-adapter/exportName.js +1 -0
- package/dist/packages/canvas-adapter/icons.js +2 -2
- package/dist/packages/canvas-adapter/index.d.ts +2 -3
- package/dist/packages/canvas-adapter/index.js +1 -1
- package/dist/packages/canvas-adapter/insightsTab.d.ts +0 -1
- package/dist/packages/canvas-adapter/insightsTab.js +1 -1
- package/dist/packages/canvas-adapter/maplessSummary.js +1 -1
- package/dist/packages/canvas-adapter/renderWaferGallery.d.ts +23 -40
- package/dist/packages/canvas-adapter/renderWaferGallery.js +1 -1
- package/dist/packages/canvas-adapter/renderWaferMap.d.ts +96 -104
- package/dist/packages/canvas-adapter/renderWaferMap.js +1 -1
- package/dist/packages/canvas-adapter/summaryPanel.d.ts +31 -13
- package/dist/packages/canvas-adapter/summaryPanel.js +3 -3
- package/dist/packages/canvas-adapter/toCanvas.d.ts +20 -12
- package/dist/packages/canvas-adapter/toCanvas.js +1 -1
- package/dist/packages/canvas-adapter/toolbar.d.ts +6 -0
- package/dist/packages/canvas-adapter/toolbar.js +2 -2
- package/dist/packages/canvas-adapter/userGuideHtml.d.ts +1 -1
- package/dist/packages/canvas-adapter/userGuideHtml.js +26 -15
- package/dist/packages/canvas-adapter/version.d.ts +2 -2
- package/dist/packages/canvas-adapter/version.js +1 -1
- package/dist/packages/canvas-adapter/warnings.js +1 -1
- package/dist/packages/core/deprecated.d.ts +60 -0
- package/dist/packages/core/deprecated.js +1 -0
- package/dist/packages/core/index.d.ts +1 -3
- package/dist/packages/core/index.js +1 -1
- package/dist/packages/core/passBins.d.ts +33 -0
- package/dist/packages/core/passBins.js +1 -0
- package/dist/packages/core/utils.d.ts +12 -0
- package/dist/packages/core/utils.js +1 -1
- package/dist/packages/core/waferLabel.d.ts +35 -0
- package/dist/packages/core/waferLabel.js +1 -0
- package/dist/packages/renderer/binColors.d.ts +105 -13
- package/dist/packages/renderer/binColors.js +1 -1
- package/dist/packages/renderer/buildView.d.ts +8 -9
- package/dist/packages/renderer/buildView.js +1 -1
- package/dist/packages/renderer/buildWaferMap.d.ts +76 -17
- package/dist/packages/renderer/buildWaferMap.js +1 -1
- package/dist/packages/renderer/colorMap.d.ts +4 -3
- package/dist/packages/renderer/colorSchemes.d.ts +8 -6
- package/dist/packages/renderer/deprecate.d.ts +31 -0
- package/dist/packages/renderer/deprecate.js +1 -0
- package/dist/packages/renderer/deprecated.d.ts +45 -0
- package/dist/packages/renderer/deprecated.js +1 -0
- package/dist/packages/renderer/index.d.ts +4 -4
- 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/binPareto.d.ts +6 -1
- package/dist/packages/stats/capability.d.ts +16 -1
- package/dist/packages/stats/capability.js +1 -1
- package/dist/packages/stats/clusterDetection.d.ts +0 -2
- package/dist/packages/stats/deprecated.d.ts +82 -0
- package/dist/packages/stats/deprecated.js +1 -0
- package/dist/packages/stats/index.d.ts +5 -14
- package/dist/packages/stats/index.js +1 -1
- package/dist/packages/stats/normalizeInput.d.ts +10 -0
- package/dist/packages/stats/normalizeInput.js +1 -0
- package/dist/packages/stats/regions.d.ts +9 -2
- package/dist/packages/stats/regions.js +1 -1
- package/dist/packages/stats/renderFindingsReport.js +1 -1
- package/dist/packages/stats/renderSummaryReport.d.ts +42 -1
- package/dist/packages/stats/renderSummaryReport.js +34 -34
- package/dist/packages/stats/reportHtml.d.ts +0 -1
- package/dist/packages/stats/reportHtml.js +10 -10
- package/dist/packages/stats/summaryFigures.d.ts +47 -0
- package/dist/packages/stats/summaryFigures.js +1 -0
- package/dist/packages/stats/types.d.ts +118 -43
- package/dist/packages/stats/yield.d.ts +12 -6
- package/dist/packages/stats/yield.js +1 -1
- package/package.json +1 -1
|
@@ -72,7 +72,7 @@ export const USER_GUIDE_HTML=`<div class="wmap-guide">
|
|
|
72
72
|
.wmap-guide-toc{display:none!important}
|
|
73
73
|
}
|
|
74
74
|
</style>
|
|
75
|
-
<h1 id="wafer-map-user-guide">Wafer Map \u2014 User Guide<span class="wmap-guide-version" title="Built 2026-09-
|
|
75
|
+
<h1 id="wafer-map-user-guide">Wafer Map \u2014 User Guide<span class="wmap-guide-version" title="Built 2026-09-17T07:11:09.912Z">v0.30.1</span></h1>
|
|
76
76
|
<p class="wmap-guide-online-link">This is a quick reference. <a href="https://wafertools.github.io/wafermap/user-guide/" target="_blank" rel="noopener">View the full illustrated guide online \u2197</a></p>
|
|
77
77
|
<p>This guide describes the display and analysis features of the wafer map viewer.
|
|
78
78
|
It is written for users who may be semiconductor test engineers, device engineers, and yield engineers
|
|
@@ -129,7 +129,9 @@ fail; it simply has no result recorded. Edge-excluded dies are shown dimmed and
|
|
|
129
129
|
not counted in yield calculations.</p>
|
|
130
130
|
<h3 id="14-legend-and-colorbar">1.4 Legend and colorbar</h3>
|
|
131
131
|
<p><strong>Bin modes</strong> show a discrete colour legend: one swatch per bin, with bin number
|
|
132
|
-
and name if the application has supplied bin names
|
|
132
|
+
and name if the application has supplied bin names. Passing bins are listed first,
|
|
133
|
+
then failing bins from the most dies to the fewest \u2014 the same order as the Summary
|
|
134
|
+
panel and reports.</p>
|
|
133
135
|
<p><strong>Value mode</strong> shows a continuous colorbar: the colour scale runs from the minimum
|
|
134
136
|
to maximum value, with units when available. The colorbar is informational only \u2014
|
|
135
137
|
clicking it has no effect. To switch to a pass/fail view, use the <strong>Spec pass/fail</strong>
|
|
@@ -358,20 +360,23 @@ shows die tooltips \u2014 a separate thing from the toolbar, which is always pre
|
|
|
358
360
|
</tbody></table>
|
|
359
361
|
<p><strong>This guide's own window</strong> (and a gallery card detached into its own window,
|
|
360
362
|
see <a href="#gallery" onclick="(function(e){e.preventDefault();var g=e.target.closest('.wmap-guide');var el=g&&g.querySelector('[id=\\'gallery\\']');if(el)el.scrollIntoView({behavior:'smooth'});})(event)">Section 3 \u2014 Gallery</a> below) is a floating window, not a modal \u2014
|
|
361
|
-
its header shows
|
|
362
|
-
and resized by its corner grip.
|
|
363
|
-
without closing it; click
|
|
363
|
+
its header shows collapse, maximize, and close buttons, and it can be dragged
|
|
364
|
+
and resized by its corner grip. Collapse shrinks it to a small title strip
|
|
365
|
+
without closing it; click the same button (now <strong>Show contents</strong>) to restore it.
|
|
366
|
+
While the window is maximized only restore and close are shown.</p>
|
|
364
367
|
<p><strong>Highlight bin</strong> \u2014 in bin modes, click any bin swatch in the legend to highlight
|
|
365
368
|
that bin and dim all others. Click again to clear. Useful for isolating a specific
|
|
366
369
|
failure category across the wafer.</p>
|
|
367
370
|
<div data-wmap-demo="bin-highlight" class="wmap-demo"></div><p><em>Bin 2 (Fail) highlighted \u2014 all other bins are dimmed.</em></p>
|
|
368
371
|
<p><strong>Bin colours</strong> \u2014 a bin's colour tells you whether it passed before you read the legend:
|
|
369
372
|
passing bins are always shades of green and failing bins never are, whichever bin numbers
|
|
370
|
-
your test program uses.
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
373
|
+
your test program uses. Each bin number keeps its colour: bin 7 is the same colour in every
|
|
374
|
+
lot, every gallery and every screenshot, however many dies it holds, so you can learn your
|
|
375
|
+
program's colours. Hard and soft bins are coloured separately, so hard bin 3 and soft bin 3
|
|
376
|
+
are different colours. A colour scheme has a limited number of colours, so bins far enough
|
|
377
|
+
apart in number repeat one \u2014 when two of them are on screen together a <strong>Data warnings</strong>
|
|
378
|
+
entry names them, and you can tell them apart with the legend, the tooltip, or by
|
|
379
|
+
highlighting one bin at a time.</p>
|
|
375
380
|
<h3 id="overlays">Overlays</h3>
|
|
376
381
|
<p>Use the <strong>Overlays</strong> menu to toggle optional display layers on and off:</p>
|
|
377
382
|
<ul>
|
|
@@ -462,7 +467,7 @@ the legend, the tooltip, or by highlighting one bin at a time.</p>
|
|
|
462
467
|
<tr>
|
|
463
468
|
<td><img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjE2IiBoZWlnaHQ9IjE2IiBmaWxsPSJub25lIiBzdHJva2U9IiMzNzQxNTEiIHN0cm9rZS13aWR0aD0iMS44IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPgogIDxyZWN0IHg9IjMiIHk9IjMiIHdpZHRoPSI0IiBoZWlnaHQ9IjE4IiByeD0iMSIvPgogIDxyZWN0IHg9IjEwIiB5PSIzIiB3aWR0aD0iNCIgaGVpZ2h0PSIxOCIgcng9IjEiLz4KICA8cmVjdCB4PSIxNyIgeT0iMyIgd2lkdGg9IjQiIGhlaWdodD0iMTgiIHJ4PSIxIi8+Cjwvc3ZnPgo=" width="20" height="20"></td>
|
|
464
469
|
<td>Columns</td>
|
|
465
|
-
<td>Sets the number of columns
|
|
470
|
+
<td>Sets the number of columns. <strong>Auto</strong> fits as many cards as stay readable; a number divides the full width between that many columns.</td>
|
|
466
471
|
</tr>
|
|
467
472
|
<tr>
|
|
468
473
|
<td><img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjE2IiBoZWlnaHQ9IjE2IiBmaWxsPSJub25lIiBzdHJva2U9IiMzNzQxNTEiIHN0cm9rZS13aWR0aD0iMS44IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGQ9Ik0xMy45OTcgNGEyIDIgMCAwIDEgMS43NiAxLjA1bC40ODYuOUEyIDIgMCAwIDAgMTguMDAzIDdIMjBhMiAyIDAgMCAxIDIgMnY5YTIgMiAwIDAgMS0yIDJINGEyIDIgMCAwIDEtMi0yVjlhMiAyIDAgMCAxIDItMmgxLjk5N2EyIDIgMCAwIDAgMS43NTktMS4wNDhsLjQ4OS0uOTA0QTIgMiAwIDAgMSAxMC4wMDQgNHoiLz48Y2lyY2xlIGN4PSIxMiIgY3k9IjEzIiByPSIzIi8+PGNpcmNsZSBjeD0iNS41IiBjeT0iNC41IiByPSIwLjgiIGZpbGw9IiMzNzQxNTEiIHN0cm9rZT0ibm9uZSIvPjxjaXJjbGUgY3g9IjgiIGN5PSI0LjUiIHI9IjAuOCIgZmlsbD0iIzM3NDE1MSIgc3Ryb2tlPSJub25lIi8+PGNpcmNsZSBjeD0iNS41IiBjeT0iNyIgcj0iMC44IiBmaWxsPSIjMzc0MTUxIiBzdHJva2U9Im5vbmUiLz48Y2lyY2xlIGN4PSI4IiBjeT0iNyIgcj0iMC44IiBmaWxsPSIjMzc0MTUxIiBzdHJva2U9Im5vbmUiLz48L3N2Zz4K" width="20" height="20"></td>
|
|
@@ -482,7 +487,7 @@ the legend, the tooltip, or by highlighting one bin at a time.</p>
|
|
|
482
487
|
<tr>
|
|
483
488
|
<td><img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjE2IiBoZWlnaHQ9IjE2IiBmaWxsPSJub25lIiBzdHJva2U9IiMzNzQxNTEiIHN0cm9rZS13aWR0aD0iMS44IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjciIHg9IjMiIHk9IjMiIHJ4PSIxIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iNyIgeD0iMyIgeT0iMTQiIHJ4PSIxIi8+PHBhdGggZD0iTTE0IDRoNyIvPjxwYXRoIGQ9Ik0xNCA5aDciLz48cGF0aCBkPSJNMTQgMTVoNyIvPjxwYXRoIGQ9Ik0xNCAyMGg3Ii8+PC9zdmc+Cg==" width="20" height="20"></td>
|
|
484
489
|
<td>Legend style</td>
|
|
485
|
-
<td>
|
|
490
|
+
<td><strong>Legend on each map</strong> adds a legend to every card as well as the shared one above the grid (off by default). While it is on, bin modes also let you choose where that legend sits on each card.</td>
|
|
486
491
|
</tr>
|
|
487
492
|
<tr>
|
|
488
493
|
<td><img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjE2IiBoZWlnaHQ9IjE2IiBmaWxsPSJub25lIiBzdHJva2U9IiMzNzQxNTEiIHN0cm9rZS13aWR0aD0iMS44IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGQ9Ik01IDQgTDUgMjAiLz48cGF0aCBkPSJNNSA0IEw4IDQiLz48cGF0aCBkPSJNNSAyMCBMOCAyMCIvPjxwYXRoIGQ9Ik0xOSA0IEwxOSAyMCIvPjxwYXRoIGQ9Ik0xOSA0IEwxNiA0Ii8+PHBhdGggZD0iTTE5IDIwIEwxNiAyMCIvPjxwYXRoIGQ9Ik01IDEyIEwxOSAxMiIgc3Ryb2tlLWRhc2hhcnJheT0iMyAyIi8+PC9zdmc+Cg==" width="20" height="20"></td>
|
|
@@ -829,9 +834,15 @@ onto that pair.</em></p>
|
|
|
829
834
|
<p>Every chart panel has a <strong>camera</strong> button that saves the current view as a PNG at the displayed
|
|
830
835
|
resolution. To get a clean full-resolution render, use the panel's expand (corner-arrows)
|
|
831
836
|
button first to open it in the fullscreen modal, then click the camera button.</p>
|
|
832
|
-
<p>
|
|
833
|
-
|
|
834
|
-
|
|
837
|
+
<p>The saved image is the chart as shown, on a white background. It carries no title or
|
|
838
|
+
context of its own, but its file name identifies the lot, wafers and chart (see below).</p>
|
|
839
|
+
<h3 id="names-of-saved-files">Names of saved files</h3>
|
|
840
|
+
<p>Every image and CSV you save is named for what it shows: the lot, then the wafer (or how many
|
|
841
|
+
wafers), then the content. For example, <code>LOT123_W05_hard-bin.png</code>, <code>LOT123_W05_die-list.csv</code> or
|
|
842
|
+
<code>LOT123_25-wafers_yield-by-wafer.png</code>. Saving the same export from different wafers gives
|
|
843
|
+
different names, so files don't overwrite each other or need renaming. A part is left out when
|
|
844
|
+
the data doesn't have it, for example a wafer with no ID. Your application may choose its own
|
|
845
|
+
name for map images instead.</p>
|
|
835
846
|
<hr>
|
|
836
847
|
<h2 id="9-reticle-overlay">9. Reticle overlay</h2>
|
|
837
848
|
<p>When reticle (stepper field) geometry is configured, the <strong>Reticle grid</strong> overlay
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export declare const WMAP_VERSION = "0.
|
|
2
|
-
export declare const WMAP_BUILD_TIME = "2026-09-
|
|
1
|
+
export declare const WMAP_VERSION = "0.30.1";
|
|
2
|
+
export declare const WMAP_BUILD_TIME = "2026-09-17T07:12:45.499Z";
|
|
3
3
|
//# sourceMappingURL=version.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export const WMAP_VERSION="0.
|
|
1
|
+
export const WMAP_VERSION="0.30.1",WMAP_BUILD_TIME="2026-09-17T07:12:45.499Z";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{SHADOW as
|
|
1
|
+
import{SHADOW as S,TRACKING as O,SPACE as s,RADIUS as v,FONT as y,CLR as d,Z_BASE as B}from"./toolbar.js";const E={error:0,warning:1,info:2};export function severityOf(t){return t.severity??"warning"}export function collectWarnings(t){const o=[],i=new Set,n=e=>{if(!e?.message)return;const r=`${e.code}\0${e.message}`;i.has(r)||(i.add(r),o.push(e))};for(const e of t.result?.warnings??[])n(e);for(const e of t.statsSummary?.stats.warnings??[])n(e);for(const e of t.lotStatsSummary?.perWafer??[])for(const r of e.summary.stats.warnings??[])n(r);for(const e of t.extra??[])n(e);return o.sort((e,r)=>E[severityOf(e)]-E[severityOf(r)])}function $(t){return t==="error"?{bg:d.errBg,border:d.errBorder,text:d.errText}:{bg:d.warnBg,border:d.warnBorder,text:d.warnText}}function w(t){return t==="error"?"\u26D4":t==="info"?"\u2139":"\u26A0"}export const SHORT_LABEL={"partial-coverage":"Partial wafer coverage","geometry-conflict":"Geometry conflict","non-standard-diameter":"Non-standard wafer diameter","diameter-exceeds-die-extent":"Diameter exceeds die extent","edge-exclusion-exceeds-radius":"Edge exclusion exceeds radius","test-count-capped":"Test analysis skipped","test-def-collision":"Test definitions disagree","analysis-option-corrected":"Analysis option corrected","bin-colors-shared":"Bins share a colour","pass-bins-mixed":"Pass bins differ by wafer","ring-count-mixed":"Ring counts differ by wafer","input-field-removed":"Removed input name ignored","input-values-not-numbers":"Bins or test values are text"};function C(t){const o=t.code?SHORT_LABEL[t.code]:void 0;if(o)return o;const i=t.message.split(/(?<=\.)\s/)[0]??t.message;return i.length>60?`${i.slice(0,57)}\u2026`:i}export function buildWarningsBanner(t,o=document){const i=o.createElement("div");Object.assign(i.style,{marginBottom:s.lg});for(const n of t){const e=severityOf(n),r=$(e),m=o.createElement("div");Object.assign(m.style,{background:r.bg,border:`1px solid ${r.border}`,borderRadius:v.control,marginBottom:s.sm,fontSize:y.body,color:r.text,lineHeight:"1.5"}),m.setAttribute("role","status");const a=o.createElement("button");a.type="button",Object.assign(a.style,{display:"flex",alignItems:"center",gap:s.sm,width:"100%",background:"none",border:"none",font:"inherit",color:"inherit",textAlign:"left",padding:`${s.sm} ${s.lg}`,cursor:"pointer"});const g=o.createElement("span");Object.assign(g.style,{flex:"1",minWidth:"0"}),g.textContent=`${w(e)} ${C(n)}`;const l=o.createElement("span");Object.assign(l.style,{flexShrink:"0"}),a.append(g,l);const p=o.createElement("div");Object.assign(p.style,{padding:`0 ${s.lg} ${s.sm}`}),p.textContent=n.message;let c=!1;const f=()=>{l.textContent=c?"\u25B4":"\u25BE",p.style.display=c?"block":"none",a.setAttribute("aria-expanded",String(c)),a.setAttribute("aria-label",`${C(n)}. ${c?"Click to collapse.":"Click to expand for detail."}`)};f(),a.addEventListener("click",()=>{c=!c,f()}),a.addEventListener("mouseenter",()=>{l.style.opacity="0.65"}),a.addEventListener("mouseleave",()=>{l.style.opacity="1"}),m.append(a,p),i.appendChild(m)}return i}export function buildWarningsMenuEl(t,o,i=window){const n=i.document,e=n.createElement("div"),r=280,a=t.left+r<=(i.innerWidth??1/0)?t.left:Math.max(4,t.right-r);Object.assign(e.style,{position:"fixed",top:`${t.bottom+4}px`,left:`${a}px`,background:d.menuBg,border:`1px solid ${d.menuBorder}`,borderRadius:v.control,boxShadow:S.menu,zIndex:B,width:`${r}px`,maxHeight:"320px",overflowY:"auto",padding:"4px 0",pointerEvents:"auto"}),e.setAttribute("role","dialog"),e.setAttribute("aria-label","Data warnings");const g=n.createElement("div");Object.assign(g.style,{padding:`${s.sm} ${s.xl} ${s.xs}`,fontSize:y.body,fontWeight:"700",letterSpacing:O,textTransform:"uppercase",color:d.label}),g.textContent=o.length===1?"1 warning":`${o.length} warnings`,e.appendChild(g);for(const l of o){const p=severityOf(l),c=$(p),f=n.createElement("div");Object.assign(f.style,{display:"flex",gap:s.md,padding:`${s.md} ${s.xl}`,fontSize:y.body,lineHeight:"1.5",color:d.text,borderTop:`1px solid ${d.menuBorder}`,alignItems:"flex-start"});const x=n.createElement("span");Object.assign(x.style,{color:c.text,flexShrink:"0"}),x.textContent=w(p),f.appendChild(x);const u=n.createElement("div"),b=n.createElement("div");Object.assign(b.style,{fontWeight:"700",color:c.text,marginBottom:s.xxs}),b.textContent=l.code,u.appendChild(b);const h=n.createElement("div");h.textContent=l.message,u.appendChild(h),f.appendChild(u),e.appendChild(f)}return e}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { createWafer as createWaferImpl } from './wafer.js';
|
|
2
|
+
import { generateDies as generateDiesImpl, isPositionedDie as isPositionedDieImpl } from './dies.js';
|
|
3
|
+
import { clipDiesToWafer as clipDiesToWaferImpl, applyOrientation as applyOrientationImpl, transformDies as transformDiesImpl, mapDataToDies as mapDataToDiesImpl, isInsideWafer as isInsideWaferImpl, affineIdentity as affineIdentityImpl, affineRotation as affineRotationImpl, affineMirror as affineMirrorImpl, affineCompose as affineComposeImpl, affineInvert as affineInvertImpl, affinePoint as affinePointImpl, affineVector as affineVectorImpl, affineSwapsAxes as affineSwapsAxesImpl } from './transforms.js';
|
|
4
|
+
import { applyProbeSequence as applyProbeSequenceImpl } from './probe.js';
|
|
5
|
+
import { generateReticleGrid as generateReticleGridImpl } from './reticle.js';
|
|
6
|
+
import { classifyDie as classifyDieImpl, getRingLabel as getRingLabelImpl } from './classify.js';
|
|
7
|
+
import { aggregateValues as aggregateValuesImpl, aggregateBinCounts as aggregateBinCountsImpl, getUniqueBins as getUniqueBinsImpl } from './aggregates.js';
|
|
8
|
+
import { metadataCategoricalValue as metadataCategoricalValueImpl } from './metadata.js';
|
|
9
|
+
import { resolveGridPitch as resolveGridPitchImpl } from './inference/pitch.js';
|
|
10
|
+
/** @deprecated Removed in 0.31.0. For a die layout with no test data use `buildWaferMap({ layout: true, waferConfig, dieConfig })`; otherwise build with `buildWaferMap` and draw with `renderWaferMap` or `renderWaferGallery`. */
|
|
11
|
+
export declare const createWafer: typeof createWaferImpl;
|
|
12
|
+
/** @deprecated Removed in 0.31.0. For a die layout with no test data use `buildWaferMap({ layout: true, waferConfig, dieConfig })`, which keeps every site fully on the wafer. */
|
|
13
|
+
export declare const generateDies: typeof generateDiesImpl;
|
|
14
|
+
/** @deprecated Removed in 0.31.0. Use `hasPosition` to test whether a die has a position. */
|
|
15
|
+
export declare const isPositionedDie: typeof isPositionedDieImpl;
|
|
16
|
+
/** @deprecated Removed in 0.31.0. For a die layout with no test data use `buildWaferMap({ layout: true, waferConfig, dieConfig })`, which keeps every site fully on the wafer. */
|
|
17
|
+
export declare const clipDiesToWafer: typeof clipDiesToWaferImpl;
|
|
18
|
+
/** @deprecated Removed in 0.31.0. It belongs to the low-level drawing pipeline, which is being withdrawn: build with `buildWaferMap` and draw with `renderWaferMap` or `renderWaferGallery`. */
|
|
19
|
+
export declare const applyOrientation: typeof applyOrientationImpl;
|
|
20
|
+
/** @deprecated Removed in 0.31.0. It belongs to the low-level drawing pipeline, which is being withdrawn: build with `buildWaferMap` and draw with `renderWaferMap` or `renderWaferGallery`. */
|
|
21
|
+
export declare const transformDies: typeof transformDiesImpl;
|
|
22
|
+
/** @deprecated Removed in 0.31.0. `buildWaferMap` maps results onto dies. */
|
|
23
|
+
export declare const mapDataToDies: typeof mapDataToDiesImpl;
|
|
24
|
+
/** @deprecated Removed in 0.31.0. It belongs to the low-level drawing pipeline, which is being withdrawn: build with `buildWaferMap` and draw with `renderWaferMap` or `renderWaferGallery`. */
|
|
25
|
+
export declare const isInsideWafer: typeof isInsideWaferImpl;
|
|
26
|
+
/** @deprecated Removed in 0.31.0. It belongs to the low-level drawing pipeline, which is being withdrawn: build with `buildWaferMap` and draw with `renderWaferMap` or `renderWaferGallery`. */
|
|
27
|
+
export declare const affineIdentity: typeof affineIdentityImpl;
|
|
28
|
+
/** @deprecated Removed in 0.31.0. It belongs to the low-level drawing pipeline, which is being withdrawn: build with `buildWaferMap` and draw with `renderWaferMap` or `renderWaferGallery`. */
|
|
29
|
+
export declare const affineRotation: typeof affineRotationImpl;
|
|
30
|
+
/** @deprecated Removed in 0.31.0. It belongs to the low-level drawing pipeline, which is being withdrawn: build with `buildWaferMap` and draw with `renderWaferMap` or `renderWaferGallery`. */
|
|
31
|
+
export declare const affineMirror: typeof affineMirrorImpl;
|
|
32
|
+
/** @deprecated Removed in 0.31.0. It belongs to the low-level drawing pipeline, which is being withdrawn: build with `buildWaferMap` and draw with `renderWaferMap` or `renderWaferGallery`. */
|
|
33
|
+
export declare const affineCompose: typeof affineComposeImpl;
|
|
34
|
+
/** @deprecated Removed in 0.31.0. It belongs to the low-level drawing pipeline, which is being withdrawn: build with `buildWaferMap` and draw with `renderWaferMap` or `renderWaferGallery`. */
|
|
35
|
+
export declare const affineInvert: typeof affineInvertImpl;
|
|
36
|
+
/** @deprecated Removed in 0.31.0. It belongs to the low-level drawing pipeline, which is being withdrawn: build with `buildWaferMap` and draw with `renderWaferMap` or `renderWaferGallery`. */
|
|
37
|
+
export declare const affinePoint: typeof affinePointImpl;
|
|
38
|
+
/** @deprecated Removed in 0.31.0. It belongs to the low-level drawing pipeline, which is being withdrawn: build with `buildWaferMap` and draw with `renderWaferMap` or `renderWaferGallery`. */
|
|
39
|
+
export declare const affineVector: typeof affineVectorImpl;
|
|
40
|
+
/** @deprecated Removed in 0.31.0. It belongs to the low-level drawing pipeline, which is being withdrawn: build with `buildWaferMap` and draw with `renderWaferMap` or `renderWaferGallery`. */
|
|
41
|
+
export declare const affineSwapsAxes: typeof affineSwapsAxesImpl;
|
|
42
|
+
/** @deprecated Removed in 0.31.0. It belongs to the low-level drawing pipeline, which is being withdrawn: build with `buildWaferMap` and draw with `renderWaferMap` or `renderWaferGallery`. */
|
|
43
|
+
export declare const applyProbeSequence: typeof applyProbeSequenceImpl;
|
|
44
|
+
/** @deprecated Removed in 0.31.0. It belongs to the low-level drawing pipeline, which is being withdrawn: build with `buildWaferMap` and draw with `renderWaferMap` or `renderWaferGallery`. */
|
|
45
|
+
export declare const generateReticleGrid: typeof generateReticleGridImpl;
|
|
46
|
+
/** @deprecated Removed in 0.31.0. A die's ring and quadrant are in the die list's CSV export (Ring and Quadrant columns); ring and quadrant yield is `stats.regionYield.` */
|
|
47
|
+
export declare const classifyDie: typeof classifyDieImpl;
|
|
48
|
+
/** @deprecated Removed in 0.31.0. Ring labels come with ring yield (`stats.regionYield.ring[].label`) and ring findings (`comparison.left`). */
|
|
49
|
+
export declare const getRingLabel: typeof getRingLabelImpl;
|
|
50
|
+
/** @deprecated Removed in 0.31.0. Stack wafers with `buildWaferMap`'s `lotStack` option. */
|
|
51
|
+
export declare const aggregateValues: typeof aggregateValuesImpl;
|
|
52
|
+
/** @deprecated Removed in 0.31.0. Stack wafers with `buildWaferMap`'s `lotStack` option. */
|
|
53
|
+
export declare const aggregateBinCounts: typeof aggregateBinCountsImpl;
|
|
54
|
+
/** @deprecated Removed in 0.31.0. Stack wafers with `buildWaferMap`'s `lotStack` option. */
|
|
55
|
+
export declare const getUniqueBins: typeof getUniqueBinsImpl;
|
|
56
|
+
/** @deprecated Removed in 0.31.0. Use `metadataDisplayValue` for a metadata value's text. */
|
|
57
|
+
export declare const metadataCategoricalValue: typeof metadataCategoricalValueImpl;
|
|
58
|
+
/** @deprecated Removed in 0.31.0. `buildWaferMap` resolves the die pitch itself; each built die's width and height carry it. */
|
|
59
|
+
export declare const resolveGridPitch: typeof resolveGridPitchImpl;
|
|
60
|
+
//# sourceMappingURL=deprecated.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{deprecated as e}from"../renderer/deprecate.js";import{createWafer as o}from"./wafer.js";import{generateDies as r,isPositionedDie as n}from"./dies.js";import{clipDiesToWafer as s,applyOrientation as f,transformDies as p,mapDataToDies as l,isInsideWafer as d,affineIdentity as c,affineRotation as g,affineMirror as m,affineCompose as u,affineInvert as I,affinePoint as $,affineVector as h,affineSwapsAxes as D}from"./transforms.js";import{applyProbeSequence as y}from"./probe.js";import{generateReticleGrid as w}from"./reticle.js";import{classifyDie as x,getRingLabel as C}from"./classify.js";import{aggregateValues as b,aggregateBinCounts as W,getUniqueBins as P}from"./aggregates.js";import{metadataCategoricalValue as V}from"./metadata.js";import{resolveGridPitch as S}from"./inference/pitch.js";const a="If you depend on it, say so at https://github.com/wafertools/wafermap/issues.",t="It belongs to the low-level drawing pipeline, which is being withdrawn: build with buildWaferMap and draw with renderWaferMap or renderWaferGallery.",A="Use hasPosition to test whether a die has a position.",M="buildWaferMap maps results onto dies.",i="Stack wafers with buildWaferMap's lotStack option.",R="buildWaferMap resolves the die pitch itself; each built die's width and height carry it.";export const createWafer=e(o,"createWafer",`For a die layout with no test data use buildWaferMap({ layout: true, waferConfig, dieConfig }); otherwise build with buildWaferMap and draw with renderWaferMap or renderWaferGallery. ${a}`),generateDies=e(r,"generateDies",`For a die layout with no test data use buildWaferMap({ layout: true, waferConfig, dieConfig }), which keeps every site fully on the wafer. ${a}`),isPositionedDie=e(n,"isPositionedDie",`${A} ${a}`),clipDiesToWafer=e(s,"clipDiesToWafer",`For a die layout with no test data use buildWaferMap({ layout: true, waferConfig, dieConfig }), which keeps every site fully on the wafer. ${a}`),applyOrientation=e(f,"applyOrientation",`${t} ${a}`),transformDies=e(p,"transformDies",`${t} ${a}`),mapDataToDies=e(l,"mapDataToDies",`${M} ${a}`),isInsideWafer=e(d,"isInsideWafer",`${t} ${a}`),affineIdentity=e(c,"affineIdentity",`${t} ${a}`),affineRotation=e(g,"affineRotation",`${t} ${a}`),affineMirror=e(m,"affineMirror",`${t} ${a}`),affineCompose=e(u,"affineCompose",`${t} ${a}`),affineInvert=e(I,"affineInvert",`${t} ${a}`),affinePoint=e($,"affinePoint",`${t} ${a}`),affineVector=e(h,"affineVector",`${t} ${a}`),affineSwapsAxes=e(D,"affineSwapsAxes",`${t} ${a}`),applyProbeSequence=e(y,"applyProbeSequence",`${t} ${a}`),generateReticleGrid=e(w,"generateReticleGrid",`${t} ${a}`),classifyDie=e(x,"classifyDie",`A die's ring and quadrant are in the die list's CSV export (Ring and Quadrant columns); ring and quadrant yield is stats.regionYield. ${a}`),getRingLabel=e(C,"getRingLabel",`Ring labels come with ring yield (stats.regionYield.ring[].label) and ring findings (comparison.left). ${a}`),aggregateValues=e(b,"aggregateValues",`${i} ${a}`),aggregateBinCounts=e(W,"aggregateBinCounts",`${i} ${a}`),getUniqueBins=e(P,"getUniqueBins",`${i} ${a}`),metadataCategoricalValue=e(V,"metadataCategoricalValue",`Use metadataDisplayValue for a metadata value's text. ${a}`),resolveGridPitch=e(S,"resolveGridPitch",`${R} ${a}`);
|
|
@@ -5,9 +5,7 @@ export * from './metadata.js';
|
|
|
5
5
|
export * from './probe.js';
|
|
6
6
|
export * from './reticle.js';
|
|
7
7
|
export type { DataRow, MapOptions, TransformOptions, Affine, CoordFrame } from './transforms.js';
|
|
8
|
-
export { isInsideWafer, clipDiesToWafer, applyOrientation, transformDies, mapDataToDies } from './transforms.js';
|
|
9
|
-
export { affineIdentity, affineRotation, affineMirror, affineCompose, affineInvert, affinePoint, affineVector, affineSwapsAxes, } from './transforms.js';
|
|
10
8
|
export * from './wafer.js';
|
|
11
9
|
export type { PitchResult } from './inference/pitch.js';
|
|
12
|
-
export { resolveGridPitch } from './
|
|
10
|
+
export { createWafer, generateDies, isPositionedDie, clipDiesToWafer, applyOrientation, transformDies, mapDataToDies, isInsideWafer, affineIdentity, affineRotation, affineMirror, affineCompose, affineInvert, affinePoint, affineVector, affineSwapsAxes, applyProbeSequence, generateReticleGrid, classifyDie, getRingLabel, aggregateValues, aggregateBinCounts, getUniqueBins, metadataCategoricalValue, resolveGridPitch, } from './deprecated.js';
|
|
13
11
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export*from"./aggregates.js";export*from"./classify.js";export*from"./dies.js";export*from"./metadata.js";export*from"./probe.js";export*from"./reticle.js";export{
|
|
1
|
+
export*from"./aggregates.js";export*from"./classify.js";export*from"./dies.js";export*from"./metadata.js";export*from"./probe.js";export*from"./reticle.js";export*from"./wafer.js";export{createWafer,generateDies,isPositionedDie,clipDiesToWafer,applyOrientation,transformDies,mapDataToDies,isInsideWafer,affineIdentity,affineRotation,affineMirror,affineCompose,affineInvert,affinePoint,affineVector,affineSwapsAxes,applyProbeSequence,generateReticleGrid,classifyDie,getRingLabel,aggregateValues,aggregateBinCounts,getUniqueBins,metadataCategoricalValue,resolveGridPitch}from"./deprecated.js";
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which bins pass, per wafer — and how to name a set of them.
|
|
3
|
+
*
|
|
4
|
+
* The rule this file exists for: `[1]` is a default only where data ENTERS the
|
|
5
|
+
* library (`buildWaferMap`'s input). From there the value travels on the result
|
|
6
|
+
* (`WaferMapResult.passBins`), and every display, analysis and report reads it —
|
|
7
|
+
* per wafer, because a gallery can hold wafers from programs with different pass
|
|
8
|
+
* bins. Every downstream surface used to default `passBins` to `[1]` on its own
|
|
9
|
+
* unless the caller repeated it, so a host that told `buildWaferMap` bins 1 and 2
|
|
10
|
+
* pass saw bin 2 drawn, sorted and totalled as a failure everywhere else — with
|
|
11
|
+
* `result.yield`, the one figure that did use them, disagreeing beside it.
|
|
12
|
+
*
|
|
13
|
+
* Deliberately internal (not re-exported from `core/index.ts`).
|
|
14
|
+
*/
|
|
15
|
+
/** The industry convention, applied ONLY to input that states no pass bins. */
|
|
16
|
+
export declare const INPUT_DEFAULT_PASS_BINS: readonly number[];
|
|
17
|
+
/**
|
|
18
|
+
* One wafer's pass bins: its own (carried from `buildWaferMap`), else the
|
|
19
|
+
* caller's default for items built without any, else the input convention.
|
|
20
|
+
*/
|
|
21
|
+
export declare function itemPassBins(item: {
|
|
22
|
+
passBins?: readonly number[];
|
|
23
|
+
} | null | undefined, fallback?: readonly number[]): readonly number[];
|
|
24
|
+
/** Same bins, in any order. */
|
|
25
|
+
export declare function sameBins(a: readonly number[], b: readonly number[]): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Names the pass bins in use, for a yield label: "bin 1", "bins 1, 2", or —
|
|
28
|
+
* when the wafers shown disagree — "per wafer: bin 1 · bins 1, 2". A label that
|
|
29
|
+
* named one wafer's set while the figure pooled wafers judged differently would
|
|
30
|
+
* be the exact mislabelled population the library must never show.
|
|
31
|
+
*/
|
|
32
|
+
export declare function passBinsLabel(sets: Iterable<readonly number[]>): string;
|
|
33
|
+
//# sourceMappingURL=passBins.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const INPUT_DEFAULT_PASS_BINS=[1];export function itemPassBins(s,e=INPUT_DEFAULT_PASS_BINS){return s?.passBins??e}export function sameBins(s,e){const t=new Set(s),n=new Set(e);return t.size===n.size&&[...t].every(i=>n.has(i))}export function passBinsLabel(s){const e=[];for(const n of s)e.some(i=>sameBins(i,n))||e.push(n);const t=n=>n.length===0?"no bins":n.length===1?`bin ${n[0]}`:`bins ${n.join(", ")}`;return e.length<=1?t(e[0]??INPUT_DEFAULT_PASS_BINS):`per wafer: ${e.map(t).join(" \xB7 ")}`}
|
|
@@ -68,4 +68,16 @@ export declare function modeOf(values: number[]): number | null;
|
|
|
68
68
|
* obvious. Every CSV this library writes must go through it.
|
|
69
69
|
*/
|
|
70
70
|
export declare function csvField(value: string): string;
|
|
71
|
+
/**
|
|
72
|
+
* Escape text for insertion into HTML — the one copy for the whole library.
|
|
73
|
+
*
|
|
74
|
+
* Every string the library puts into `innerHTML` that did not come from its own
|
|
75
|
+
* literals must go through this: test names, units, bin names, wafer labels and
|
|
76
|
+
* metadata values all arrive from input files (STDF/ATDF/CSV headers, MES
|
|
77
|
+
* fields, operator free text), and a name like `<img src=x onerror=…>` would
|
|
78
|
+
* otherwise run as script when a tooltip showed it — in a Tauri or Electron
|
|
79
|
+
* host, inside the app's own webview. It used to live in stats/reportHtml.ts,
|
|
80
|
+
* where only the reports used it, while every tooltip interpolated raw names.
|
|
81
|
+
*/
|
|
82
|
+
export declare function escHtml(value: string): string;
|
|
71
83
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export function compareNatural(t,
|
|
1
|
+
export function compareNatural(t,e){return t.localeCompare(e,"en",{numeric:!0})}export function prettyKey(t){return t.replace(/([A-Z])/g," $1").replace(/_/g," ").trim().replace(/^./,e=>e.toUpperCase())}export function clamp01(t){return Math.max(0,Math.min(1,t))}export function mean(t){if(t.length===0)return NaN;let e=0;for(const n of t)e+=n;return e/t.length}export function medianOfSorted(t){const e=t.length;if(e===0)return 0;const n=Math.floor(e/2);return e%2===1?t[n]:(t[n-1]+t[n])/2}export function median(t){return medianOfSorted([...t].sort((e,n)=>e-n))}export function percentile98(t){if(t.length===0)return 0;const e=[...t].sort((o,r)=>o-r),n=Math.floor(e.length*.98);return e[Math.min(n,e.length-1)]}export function modeOf(t){if(!t.length)return null;const e=new Map;for(const r of t)e.set(r,(e.get(r)??0)+1);let n=0,o=t[0];for(const[r,c]of e)c>n&&(n=c,o=r);return o}const p=/^[=+\-@]/;export function csvField(t){const e=p.test(t)&&Number.isNaN(Number(t))?`'${t}`:t;return/[",\n\r]/.test(e)?`"${e.replace(/"/g,'""')}"`:e}export function escHtml(t){return t.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type WaferMetadata } from './metadata.js';
|
|
2
|
+
/**
|
|
3
|
+
* The name to show for one wafer among several — a gallery card's header, a
|
|
4
|
+
* findings or yield list row, a report's Wafer column, a die list's Wafer
|
|
5
|
+
* column, a detached window's title.
|
|
6
|
+
*
|
|
7
|
+
* Deliberately internal (not re-exported from `core/index.ts`): it is the one
|
|
8
|
+
* rule for every surface that names a wafer, not an API a host needs.
|
|
9
|
+
*
|
|
10
|
+
* Every one of those surfaces used to supply its own fallback for an item with
|
|
11
|
+
* no `label`, and they disagreed: the gallery card header was blank, the
|
|
12
|
+
* findings list and reports said `W3` (a position, which reads as a wafer ID
|
|
13
|
+
* and need not match one), a detached window said "Wafer map", and the
|
|
14
|
+
* Insights tab used the wafer ID. The wafer ID was on the item the whole time.
|
|
15
|
+
*
|
|
16
|
+
* Order: the caller's `label` (a blank one counts as absent), then the wafer's
|
|
17
|
+
* own `metadata.waferId`, then a position that says plainly it is not an ID.
|
|
18
|
+
*/
|
|
19
|
+
export declare function waferDisplayLabel(item: WaferLabelSource, index: number): string;
|
|
20
|
+
type WaferLabelSource = {
|
|
21
|
+
label?: string;
|
|
22
|
+
wafer?: {
|
|
23
|
+
metadata?: WaferMetadata | null;
|
|
24
|
+
} | null;
|
|
25
|
+
} | null | undefined;
|
|
26
|
+
/**
|
|
27
|
+
* The wafer's real identity — the caller's `label`, else `metadata.waferId` —
|
|
28
|
+
* or `undefined` when it has none. `waferDisplayLabel` without its positional
|
|
29
|
+
* fallback, for places where a position must not stand in for an identity: a
|
|
30
|
+
* saved file's name (see canvas-adapter/exportName.ts), where "Wafer 3 (no ID)"
|
|
31
|
+
* would be written into every export of a lot and read back later as an ID.
|
|
32
|
+
*/
|
|
33
|
+
export declare function waferIdentityLabel(item: WaferLabelSource): string | undefined;
|
|
34
|
+
export {};
|
|
35
|
+
//# sourceMappingURL=waferLabel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{metadataDisplayValue as r}from"./metadata.js";export function waferDisplayLabel(a,e){return waferIdentityLabel(a)??`Wafer ${e+1} (no ID)`}export function waferIdentityLabel(a){return(a?.label?.trim()||void 0)??r(a?.wafer?.metadata?.waferId)}
|
|
@@ -12,15 +12,26 @@ export interface BinColors {
|
|
|
12
12
|
hard: Map<number, string>;
|
|
13
13
|
soft: Map<number, string>;
|
|
14
14
|
/**
|
|
15
|
-
* Bins drawn in a colour that another bin of the same type also has —
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* colour alone. Ascending bin number.
|
|
15
|
+
* Bins drawn in a colour that another bin of the same type also has — two
|
|
16
|
+
* bins present whose numbers land on the same palette slot (they differ by a
|
|
17
|
+
* multiple of the palette's length), or a defined colour that duplicates one.
|
|
18
|
+
* Empty when every bin is distinguishable by colour alone. Ascending bin number.
|
|
19
19
|
*/
|
|
20
20
|
shared: {
|
|
21
21
|
hard: number[];
|
|
22
22
|
soft: number[];
|
|
23
23
|
};
|
|
24
|
+
/**
|
|
25
|
+
* Bins that pass, per type — the verdict the colours were chosen with. Hard:
|
|
26
|
+
* the bins in `passBins`. Soft: bins whose every die passes. Read this, never
|
|
27
|
+
* `passBins`, to order, total or judge SOFT bins: `passBins` holds hard-bin
|
|
28
|
+
* numbers, so testing a soft bin against it treats soft bin 1 as a pass and
|
|
29
|
+
* soft bin 100 as a fail whatever their dies did.
|
|
30
|
+
*/
|
|
31
|
+
pass: {
|
|
32
|
+
hard: Set<number>;
|
|
33
|
+
soft: Set<number>;
|
|
34
|
+
};
|
|
24
35
|
}
|
|
25
36
|
export interface BinColorOptions {
|
|
26
37
|
/** Which bins pass. Default `[1]`. Must match the `passBins` behind the yield figure. */
|
|
@@ -40,26 +51,107 @@ export interface BinColorOptions {
|
|
|
40
51
|
* Assign every bin present in `dies` a colour — the ONE rule for bin colour,
|
|
41
52
|
* shared by the map, its legends, the summary panels and the Insights charts.
|
|
42
53
|
*
|
|
43
|
-
* Why not a function of the bin number, as it used to be:
|
|
44
54
|
* - **Pass/fail comes from `passBins`, never the number.** Passing bins take
|
|
45
55
|
* the palette's pass colours (greens) and failing bins its fail colours, so
|
|
46
|
-
* with `passBins: [1, 3]` bin 3 is green and a failing bin
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* the most distinct
|
|
51
|
-
*
|
|
52
|
-
*
|
|
56
|
+
* with `passBins: [1, 3]` bin 3 is green and a failing bin 1 is not.
|
|
57
|
+
* - **Which colour is keyed by bin number, never by die count.** A pass bin
|
|
58
|
+
* takes `pass[(bin − 1) mod n]` and a fail bin `fail[(bin − 2) mod n]`: bin 1
|
|
59
|
+
* (the conventional pass bin) and bin 2 (the conventional first fail bin)
|
|
60
|
+
* land on the front, most distinct colour of each list, and the low bin
|
|
61
|
+
* numbers most programs use get the clearest colours. So bin 7 is the same
|
|
62
|
+
* colour in every lot, gallery subset and screenshot of a program, which is
|
|
63
|
+
* how engineers learn to read a bin map. This used to rank bins by die count,
|
|
64
|
+
* which gave "the biggest fail bin" a colour rather than any bin — two lots of
|
|
65
|
+
* one program drew the same bin in different colours. Before that it hashed
|
|
66
|
+
* the number, which collided two of the first sixteen soft bins; a modular
|
|
67
|
+
* index collides only at a palette's length apart, and `shared` names those.
|
|
68
|
+
* - **The slot counts from the bin number alone**, not its position among the
|
|
69
|
+
* pass or fail bins, so changing `passBins` recolours only the bins whose
|
|
70
|
+
* verdict changed.
|
|
53
71
|
* - **Soft bins are pass-aware too.** A soft bin passes when every die
|
|
54
72
|
* carrying it passes (by the same per-die rule yield uses); otherwise, or
|
|
55
73
|
* when no die says, it takes a fail colour. The library has the data to
|
|
56
74
|
* decide, so the caller never supplies it.
|
|
75
|
+
* - **Soft bins read the palette shifted by half its length**, so hard bin n
|
|
76
|
+
* and soft bin n are different colours by default. They are separate number
|
|
77
|
+
* spaces and are never on screen together, but a shared colour invites
|
|
78
|
+
* reading one as the other.
|
|
57
79
|
*
|
|
58
80
|
* A gallery resolves ONCE over every wafer it shows and hands the result to every
|
|
59
|
-
* card (`ViewOptions.binColors`)
|
|
81
|
+
* card (`ViewOptions.binColors`): a `BinDef.color` supplied by one item then
|
|
82
|
+
* colours that bin on every card, and `shared` describes the whole gallery.
|
|
60
83
|
* A lone map resolves over its own dies.
|
|
61
84
|
*/
|
|
62
85
|
export declare function resolveBinColors(dies: Iterable<Die>, options?: BinColorOptions): BinColors;
|
|
86
|
+
/** The inputs a built map carries for its bin colours. A `WaferMapResult` is one. */
|
|
87
|
+
export interface BinColorSource {
|
|
88
|
+
dies: Iterable<Die>;
|
|
89
|
+
/** The pass bins the map was built with (`WaferMapResult.passBins`). */
|
|
90
|
+
passBins?: readonly number[];
|
|
91
|
+
hbinDefs?: readonly BinDef[];
|
|
92
|
+
sbinDefs?: readonly BinDef[];
|
|
93
|
+
}
|
|
94
|
+
/** Display choices for `binColorsForMaps` — the palette and whether defined colours win. */
|
|
95
|
+
export interface MapBinColorOptions {
|
|
96
|
+
/** Registered bin palette name (`registerBinColorScheme`). Default `'default'`. */
|
|
97
|
+
binColorScheme?: string;
|
|
98
|
+
/** Honour `BinDef.color`. Default true. */
|
|
99
|
+
useDefinedBinColors?: boolean;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* The bin colours for one or more built maps — exactly the colours
|
|
103
|
+
* `renderWaferMap` and `renderWaferGallery` draw them in, for a host surface of
|
|
104
|
+
* its own: a table swatch, a PDF, a chart in another library.
|
|
105
|
+
*
|
|
106
|
+
* Takes the maps rather than dies and a `passBins` list, so pass/fail cannot be
|
|
107
|
+
* judged by the wrong bins: each map's dies are judged by that map's own
|
|
108
|
+
* `passBins`, and bin definitions (with any `BinDef.color`) are merged across the
|
|
109
|
+
* maps, first definition of a bin winning — the gallery's own rule. For a live
|
|
110
|
+
* map with the user's palette choice, read `WaferMapController.getBinColors()` or
|
|
111
|
+
* `GalleryController.getBinColors()` instead.
|
|
112
|
+
*/
|
|
113
|
+
export declare function binColorsForMaps(maps: BinColorSource | readonly BinColorSource[], options?: MapBinColorOptions): BinColors;
|
|
114
|
+
/** @internal `binColorsForMaps` plus the hard bins that pass on some maps and fail on others. */
|
|
115
|
+
export declare function resolveBinColorsForMaps(maps: readonly BinColorSource[], options?: MapBinColorOptions): {
|
|
116
|
+
colors: BinColors;
|
|
117
|
+
mixedHardBins: number[];
|
|
118
|
+
};
|
|
119
|
+
/**
|
|
120
|
+
* @internal Bin definitions merged across maps: one per bin, the first map's
|
|
121
|
+
* definition winning. The one rule for a multi-map legend, report or colouring.
|
|
122
|
+
*/
|
|
123
|
+
export declare function mergeBinDefs(lists: Iterable<readonly BinDef[] | undefined>): BinDef[];
|
|
124
|
+
/** One wafer's dies and the pass bins that wafer was built with. */
|
|
125
|
+
export interface BinPassGroup {
|
|
126
|
+
dies: Iterable<Die>;
|
|
127
|
+
/** Omitted ⇒ the input convention `[1]` — pass `WaferMapResult.passBins`. */
|
|
128
|
+
passBins?: readonly number[];
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* `resolveBinColors` over several wafers that may carry DIFFERENT pass bins — a
|
|
132
|
+
* gallery of wafers from more than one test program. Each die is judged by its
|
|
133
|
+
* own wafer's `passBins`, and a bin passes only when every die carrying it
|
|
134
|
+
* passes (for one wafer that is exactly "the bin is in `passBins`").
|
|
135
|
+
*
|
|
136
|
+
* `mixedHardBins` names hard bins that pass on some wafers and fail on others.
|
|
137
|
+
* One colour and one legend row cannot be right for both, so the gallery states
|
|
138
|
+
* it (`mixedPassBinsWarning`) rather than letting either wafer's verdict
|
|
139
|
+
* silently stand for all of them.
|
|
140
|
+
*/
|
|
141
|
+
export declare function resolveBinColorsByWafer(groups: Iterable<BinPassGroup>, options?: Omit<BinColorOptions, 'passBins'>): {
|
|
142
|
+
colors: BinColors;
|
|
143
|
+
mixedHardBins: number[];
|
|
144
|
+
};
|
|
145
|
+
/**
|
|
146
|
+
* Which hard and soft bins pass — `BinColors.pass` without the colours, for a
|
|
147
|
+
* caller that has dies but no resolved assignment (the summary report). The same
|
|
148
|
+
* tally `resolveBinColors` uses, so the two cannot disagree about a verdict.
|
|
149
|
+
*/
|
|
150
|
+
export declare function binPassSets(dies: Iterable<Die>, passBins?: readonly number[]): BinColors['pass'];
|
|
151
|
+
/** `binPassSets` over wafers that each carry their own pass bins. */
|
|
152
|
+
export declare function binPassSetsByWafer(groups: Iterable<BinPassGroup>): BinColors['pass'];
|
|
153
|
+
/** The `pass-bins-mixed` advisory for `resolveBinColorsByWafer`'s `mixedHardBins`, or null. */
|
|
154
|
+
export declare function mixedPassBinsWarning(bins: readonly number[]): WaferWarning | null;
|
|
63
155
|
/**
|
|
64
156
|
* True when `colors` has an entry for every bin on these dies — i.e. it was
|
|
65
157
|
* resolved over a population that includes them. `buildView` checks this
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{diePassStatus as
|
|
1
|
+
import{diePassStatus as g}from"../core/dies.js";import{INPUT_DEFAULT_PASS_BINS as B,itemPassBins as m}from"../core/passBins.js";import{getBinColorScheme as w}from"./colorSchemes.js";export function resolveBinColors(s,n={}){return resolveBinColorsByWafer([{dies:s,passBins:n.passBins}],n).colors}export function binColorsForMaps(s,n={}){return resolveBinColorsForMaps(Array.isArray(s)?s:[s],n).colors}export function resolveBinColorsForMaps(s,n={}){return resolveBinColorsByWafer(s.map(e=>({dies:e.dies,passBins:m(e)})),{...n,hbinDefs:mergeBinDefs(s.map(e=>e.hbinDefs)),sbinDefs:mergeBinDefs(s.map(e=>e.sbinDefs))})}export function mergeBinDefs(s){const n=new Set,e=[];for(const a of s)for(const o of a??[])n.has(o.bin)||(n.add(o.bin),e.push(o));return e}export function resolveBinColorsByWafer(s,n={}){const e=w(n.binColorScheme),a=n.useDefinedBinColors??!0,o=h(s),f=b(o.hardBins,i=>o.pass.hard.has(i),e,a?n.hbinDefs:void 0,!1),t=b(o.softBins,i=>o.pass.soft.has(i),e,a?n.sbinDefs:void 0,!0);return{colors:{hard:f.colors,soft:t.colors,shared:{hard:f.shared,soft:t.shared},pass:o.pass},mixedHardBins:o.mixedHardBins}}export function binPassSets(s,n){return h([{dies:s,passBins:n}]).pass}export function binPassSetsByWafer(s){return h(s).pass}function h(s){const n=new Map,e=new Map,a=new Set;for(const t of s){const i=new Set(t.passBins??B);for(const l of t.dies){const r=g(l,i)===!0;l.hbin!=null&&(n.set(l.hbin,(n.get(l.hbin)??!0)&&r),r&&a.add(l.hbin)),l.sbin!=null&&e.set(l.sbin,(e.get(l.sbin)??!0)&&r)}}const o=t=>new Set([...t].filter(([,i])=>i).map(([i])=>i)),f={hard:o(n),soft:o(e)};return{hardBins:[...n.keys()],softBins:[...e.keys()],pass:f,mixedHardBins:[...a].filter(t=>!f.hard.has(t)).sort((t,i)=>t-i)}}function u(s){return s.length>8?`${s.slice(0,8).join(", ")} and ${s.length-8} more`:s.join(", ")}export function mixedPassBinsWarning(s){if(!s.length)return null;const n=s.length===1;return{code:"pass-bins-mixed",severity:"warning",message:`Hard ${n?"bin":"bins"} ${u(s)} ${n?"passes":"pass"} on some wafers and ${n?"fails":"fail"} on others: these wafers were built with different pass bins. Each wafer's own yield and die verdicts are correct, but a bin has one colour and one legend row, so ${n?"it is":"they are"} shown as failing there.`}}export function binColorsCover(s,n){if(!s.pass)return!1;for(const e of n)if(e.hbin!=null&&!s.hard.has(e.hbin)||e.sbin!=null&&!s.soft.has(e.sbin))return!1;return!0}export function binColorWarning(s,n){const e=n==="softBin"?"soft":n==="hardBin"?"hard":null;if(!e)return null;const a=s.shared[e];if(!a.length)return null;const o=u(a);return{code:"bin-colors-shared",severity:"warning",message:`${e==="hard"?"Hard":"Soft"} bins ${o} are drawn in a colour another bin also has, so colour alone cannot tell them apart. There are more bins than the colour scheme has distinct colours (or a bin definition repeats one). Use the legend, the tooltip, or highlight one bin at a time.`}}const S=1,x=2;function p(s,n,e,a){const o=s.length,f=a?Math.floor(o/2):0;return s[((n-e+f)%o+o)%o]}function b(s,n,e,a,o){const f=new Map;for(const r of a??[])r.color&&f.set(r.bin,r.color);const t=new Map;for(const r of s)t.set(r,f.get(r)??(n(r)?p(e.pass,r,S,o):p(e.fail,r,x,o)));const i=new Map;for(const[r,c]of t){const d=c.toLowerCase();i.set(d,[...i.get(d)??[],r])}const l=[...i.values()].filter(r=>r.length>1).flat().sort((r,c)=>r-c);return{colors:t,shared:l}}
|
|
@@ -155,7 +155,7 @@ export interface View {
|
|
|
155
155
|
allIntegerValues?: boolean;
|
|
156
156
|
/** Named test definitions — populated when `testDefs` is passed to `buildWaferMap`. */
|
|
157
157
|
testDefs?: TestDef[];
|
|
158
|
-
/**
|
|
158
|
+
/** The test number being displayed in `value` plot mode — a `die.testValues` key, not a position. */
|
|
159
159
|
activeTest: number;
|
|
160
160
|
/** True when log₁₀ scale is both requested and valid (vMin > 0). */
|
|
161
161
|
logScale: boolean;
|
|
@@ -217,8 +217,6 @@ export interface View {
|
|
|
217
217
|
* - `'off'` — continuous value gradient (or a non-value plot mode).
|
|
218
218
|
*/
|
|
219
219
|
passFailDisplay: 'off' | 'spec' | 'test';
|
|
220
|
-
/** True when `passFailDisplay === 'spec'` — kept for back-compat with existing consumers. */
|
|
221
|
-
colorBySpec: boolean;
|
|
222
220
|
/** Whether the colorbar range is anchored to spec limits ('spec') or data extents ('data'). */
|
|
223
221
|
colorbarRangeMode: 'spec' | 'data';
|
|
224
222
|
/** Wafer centre in scene/display mm coordinates (the rotation pivot). */
|
|
@@ -284,7 +282,6 @@ export interface ViewOptions {
|
|
|
284
282
|
showRingBoundaries?: boolean;
|
|
285
283
|
showQuadrantBoundaries?: boolean;
|
|
286
284
|
showXYIndicator?: boolean;
|
|
287
|
-
dieGap?: number;
|
|
288
285
|
/** Bin palette for `hardBin`/`softBin` — any name registered via `registerBinColorScheme()`. Default `'default'`. */
|
|
289
286
|
binColorScheme?: string;
|
|
290
287
|
/** Value gradient for `value` and the stacked modes — any name registered via `registerValueColorScheme()`. Default `'default'`. */
|
|
@@ -364,9 +361,10 @@ export interface ViewOptions {
|
|
|
364
361
|
* Which bins count as passing. Default `[1]`.
|
|
365
362
|
*
|
|
366
363
|
* Sets `ViewRect.binFail` and decides which bins take the palette's pass
|
|
367
|
-
* colours (see `resolveBinColors`) — never the bin number.
|
|
368
|
-
*
|
|
369
|
-
*
|
|
364
|
+
* colours (see `resolveBinColors`) — never the bin number. `buildWaferMap` and
|
|
365
|
+
* the renderers set this from `WaferMapResult.passBins`, so a map agrees with
|
|
366
|
+
* its own yield figure; only a hand-rolled pipeline calling `buildView`
|
|
367
|
+
* directly supplies it.
|
|
370
368
|
*/
|
|
371
369
|
passBins?: number[];
|
|
372
370
|
/**
|
|
@@ -374,10 +372,11 @@ export interface ViewOptions {
|
|
|
374
372
|
* Generated by `generateReticleGrid` or the `reticle` option on `buildWaferMap`.
|
|
375
373
|
*/
|
|
376
374
|
reticles?: Reticle[];
|
|
377
|
-
/** Named test definitions — one per `
|
|
375
|
+
/** Named test definitions — one per test number in `die.testValues`. */
|
|
378
376
|
testDefs?: TestDef[];
|
|
379
377
|
/**
|
|
380
|
-
*
|
|
378
|
+
* The test number to display in `value` plot mode — a `die.testValues` key
|
|
379
|
+
* (`TestDef.testNumber`), not a position. Default `0`.
|
|
381
380
|
* When `testDefs` is provided, the toolbar mode dropdown offers one item per test.
|
|
382
381
|
*/
|
|
383
382
|
activeTest?: number;
|