@ni/nimble-components 29.1.7 → 29.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/dist/all-components-bundle.js +861 -470
  2. package/dist/all-components-bundle.js.map +1 -1
  3. package/dist/all-components-bundle.min.js +2873 -2758
  4. package/dist/all-components-bundle.min.js.map +1 -1
  5. package/dist/esm/all-components.d.ts +1 -0
  6. package/dist/esm/all-components.js +1 -0
  7. package/dist/esm/all-components.js.map +1 -1
  8. package/dist/esm/combobox/template.js +1 -1
  9. package/dist/esm/combobox/template.js.map +1 -1
  10. package/dist/esm/list-option/template.js +1 -0
  11. package/dist/esm/list-option/template.js.map +1 -1
  12. package/dist/esm/list-option-group/index.d.ts +65 -0
  13. package/dist/esm/list-option-group/index.js +130 -0
  14. package/dist/esm/list-option-group/index.js.map +1 -0
  15. package/dist/esm/list-option-group/styles.d.ts +1 -0
  16. package/dist/esm/list-option-group/styles.js +62 -0
  17. package/dist/esm/list-option-group/styles.js.map +1 -0
  18. package/dist/esm/list-option-group/template.d.ts +2 -0
  19. package/dist/esm/list-option-group/template.js +37 -0
  20. package/dist/esm/list-option-group/template.js.map +1 -0
  21. package/dist/esm/rich-text/mention-listbox/template.js +3 -3
  22. package/dist/esm/rich-text/mention-listbox/template.js.map +1 -1
  23. package/dist/esm/select/index.d.ts +11 -2
  24. package/dist/esm/select/index.js +149 -36
  25. package/dist/esm/select/index.js.map +1 -1
  26. package/dist/esm/select/template.d.ts +4 -0
  27. package/dist/esm/select/template.js +11 -2
  28. package/dist/esm/select/template.js.map +1 -1
  29. package/dist/esm/select/testing/select.pageobject.d.ts +4 -1
  30. package/dist/esm/select/testing/select.pageobject.js +15 -0
  31. package/dist/esm/select/testing/select.pageobject.js.map +1 -1
  32. package/dist/esm/wafer-map/{modules/experimental → experimental}/computations.d.ts +25 -8
  33. package/dist/esm/wafer-map/{modules/experimental → experimental}/computations.js +87 -8
  34. package/dist/esm/wafer-map/experimental/computations.js.map +1 -0
  35. package/dist/esm/wafer-map/{modules/experimental → experimental}/hover-handler.d.ts +1 -1
  36. package/dist/esm/wafer-map/{modules/experimental → experimental}/hover-handler.js +3 -5
  37. package/dist/esm/wafer-map/experimental/hover-handler.js.map +1 -0
  38. package/dist/esm/wafer-map/experimental/worker-renderer.d.ts +24 -0
  39. package/dist/esm/wafer-map/experimental/worker-renderer.js +75 -0
  40. package/dist/esm/wafer-map/experimental/worker-renderer.js.map +1 -0
  41. package/dist/esm/wafer-map/index.d.ts +4 -3
  42. package/dist/esm/wafer-map/index.js +54 -18
  43. package/dist/esm/wafer-map/index.js.map +1 -1
  44. package/dist/esm/wafer-map/modules/computations.d.ts +1 -1
  45. package/dist/esm/wafer-map/modules/computations.js.map +1 -1
  46. package/dist/esm/wafer-map/modules/data-manager.d.ts +2 -1
  47. package/dist/esm/wafer-map/modules/data-manager.js.map +1 -1
  48. package/dist/esm/wafer-map/modules/prerendering.js.map +1 -1
  49. package/dist/esm/wafer-map/modules/wafer-map-update-tracker.d.ts +4 -0
  50. package/dist/esm/wafer-map/modules/wafer-map-update-tracker.js +37 -2
  51. package/dist/esm/wafer-map/modules/wafer-map-update-tracker.js.map +1 -1
  52. package/dist/esm/wafer-map/types.d.ts +0 -16
  53. package/dist/esm/wafer-map/types.js.map +1 -1
  54. package/dist/esm/wafer-map/workers/matrix-renderer.d.ts +1 -1
  55. package/dist/esm/wafer-map/workers/matrix-renderer.js +1 -1
  56. package/dist/esm/wafer-map/workers/matrix-renderer.js.map +1 -1
  57. package/dist/esm/wafer-map/workers/types.d.ts +39 -0
  58. package/dist/esm/wafer-map/workers/types.js +2 -0
  59. package/dist/esm/wafer-map/workers/types.js.map +1 -0
  60. package/package.json +1 -1
  61. package/dist/esm/wafer-map/modules/experimental/computations.js.map +0 -1
  62. package/dist/esm/wafer-map/modules/experimental/data-manager.d.ts +0 -21
  63. package/dist/esm/wafer-map/modules/experimental/data-manager.js +0 -41
  64. package/dist/esm/wafer-map/modules/experimental/data-manager.js.map +0 -1
  65. package/dist/esm/wafer-map/modules/experimental/hover-handler.js.map +0 -1
  66. package/dist/esm/wafer-map/modules/experimental/prerendering.d.ts +0 -18
  67. package/dist/esm/wafer-map/modules/experimental/prerendering.js +0 -63
  68. package/dist/esm/wafer-map/modules/experimental/prerendering.js.map +0 -1
  69. package/dist/esm/wafer-map/modules/experimental/worker-renderer.d.ts +0 -13
  70. package/dist/esm/wafer-map/modules/experimental/worker-renderer.js +0 -96
  71. package/dist/esm/wafer-map/modules/experimental/worker-renderer.js.map +0 -1
@@ -16278,7 +16278,7 @@
16278
16278
 
16279
16279
  /**
16280
16280
  * Do not edit directly
16281
- * Generated on Fri, 31 May 2024 15:10:22 GMT
16281
+ * Generated on Tue, 04 Jun 2024 01:53:57 GMT
16282
16282
  */
16283
16283
 
16284
16284
  const Information100DarkUi = "#a46eff";
@@ -16709,9 +16709,9 @@
16709
16709
  return `${prefix}${uniqueIdCounter++}`;
16710
16710
  }
16711
16711
 
16712
- const template$H = html `<slot></slot>`;
16712
+ const template$I = html `<slot></slot>`;
16713
16713
 
16714
- const styles$_ = css `
16714
+ const styles$$ = css `
16715
16715
  ${display('contents')}
16716
16716
  `;
16717
16717
 
@@ -16826,8 +16826,8 @@
16826
16826
  ], ThemeProvider.prototype, "theme", void 0);
16827
16827
  const nimbleDesignSystemProvider = ThemeProvider.compose({
16828
16828
  baseName: 'theme-provider',
16829
- styles: styles$_,
16830
- template: template$H
16829
+ styles: styles$$,
16830
+ template: template$I
16831
16831
  });
16832
16832
  DesignSystem.getOrCreate()
16833
16833
  .withPrefix('nimble')
@@ -17012,7 +17012,7 @@
17012
17012
  }
17013
17013
  }
17014
17014
 
17015
- const styles$Z = css `
17015
+ const styles$_ = css `
17016
17016
  @layer base, hover, focusVisible, active, disabled;
17017
17017
 
17018
17018
  @layer base {
@@ -17092,7 +17092,7 @@
17092
17092
  `;
17093
17093
 
17094
17094
  // prettier-ignore
17095
- const template$G = (_context, definition) => html `${
17095
+ const template$H = (_context, definition) => html `${
17096
17096
  /* top-container div is necessary because setting contenteditable directly on the native anchor instead
17097
17097
  leaves it focusable, unlike the behavior you get when the anchor is _within_ a contenteditable element.
17098
17098
  */ ''}<div
@@ -17195,8 +17195,8 @@
17195
17195
  const nimbleAnchor = Anchor.compose({
17196
17196
  baseName: 'anchor',
17197
17197
  baseClass: Anchor$1,
17198
- template: template$G,
17199
- styles: styles$Z,
17198
+ template: template$H,
17199
+ styles: styles$_,
17200
17200
  shadowOptions: {
17201
17201
  delegatesFocus: true
17202
17202
  }
@@ -17308,7 +17308,7 @@
17308
17308
  padding: 0;
17309
17309
  `;
17310
17310
 
17311
- const styles$Y = css `
17311
+ const styles$Z = css `
17312
17312
  @layer base, checked, hover, focusVisible, active, disabled, top;
17313
17313
 
17314
17314
  @layer base {
@@ -17586,8 +17586,8 @@
17586
17586
  }
17587
17587
  `));
17588
17588
 
17589
- const styles$X = css `
17590
- ${styles$Y}
17589
+ const styles$Y = css `
17590
+ ${styles$Z}
17591
17591
  ${buttonAppearanceVariantStyles}
17592
17592
 
17593
17593
  .control {
@@ -17607,7 +17607,7 @@
17607
17607
  }
17608
17608
  `;
17609
17609
 
17610
- const template$F = (context, definition) => html `
17610
+ const template$G = (context, definition) => html `
17611
17611
  <a
17612
17612
  class="control"
17613
17613
  part="control"
@@ -17689,8 +17689,8 @@
17689
17689
  ], AnchorButton.prototype, "disabled", void 0);
17690
17690
  const nimbleAnchorButton = AnchorButton.compose({
17691
17691
  baseName: 'anchor-button',
17692
- template: template$F,
17693
- styles: styles$X,
17692
+ template: template$G,
17693
+ styles: styles$Y,
17694
17694
  shadowOptions: {
17695
17695
  delegatesFocus: true
17696
17696
  }
@@ -17698,7 +17698,7 @@
17698
17698
  DesignSystem.getOrCreate().withPrefix('nimble').register(nimbleAnchorButton());
17699
17699
  const anchorButtonTag = 'nimble-anchor-button';
17700
17700
 
17701
- const styles$W = css `
17701
+ const styles$X = css `
17702
17702
  ${display('grid')}
17703
17703
 
17704
17704
  :host {
@@ -17782,7 +17782,7 @@
17782
17782
  }
17783
17783
  `;
17784
17784
 
17785
- const template$E = (context, definition) => html `
17785
+ const template$F = (context, definition) => html `
17786
17786
  <template
17787
17787
  role="menuitem"
17788
17788
  class="${x => (typeof x.startColumnCount === 'number'
@@ -17883,8 +17883,8 @@
17883
17883
  // FoundationAnchor already applies the StartEnd mixin, so we don't need to do it here.
17884
17884
  const nimbleAnchorMenuItem = AnchorMenuItem.compose({
17885
17885
  baseName: 'anchor-menu-item',
17886
- template: template$E,
17887
- styles: styles$W,
17886
+ template: template$F,
17887
+ styles: styles$X,
17888
17888
  shadowOptions: {
17889
17889
  delegatesFocus: true
17890
17890
  }
@@ -17894,7 +17894,7 @@
17894
17894
  .register(nimbleAnchorMenuItem());
17895
17895
  const anchorMenuItemTag = 'nimble-anchor-menu-item';
17896
17896
 
17897
- const styles$V = css `
17897
+ const styles$W = css `
17898
17898
  ${display('inline-flex')}
17899
17899
 
17900
17900
  :host {
@@ -18011,7 +18011,7 @@
18011
18011
  }
18012
18012
  `;
18013
18013
 
18014
- const template$D = (context, definition) => html `
18014
+ const template$E = (context, definition) => html `
18015
18015
  <template slot="anchortab" role="tab" aria-disabled="${x => x.disabled}">
18016
18016
  <a
18017
18017
  download="${x => x.download}"
@@ -18063,15 +18063,15 @@
18063
18063
  // FoundationAnchor already applies the StartEnd mixin, so we don't need to do it here.
18064
18064
  const nimbleAnchorTab = AnchorTab.compose({
18065
18065
  baseName: 'anchor-tab',
18066
- template: template$D,
18067
- styles: styles$V,
18066
+ template: template$E,
18067
+ styles: styles$W,
18068
18068
  shadowOptions: {
18069
18069
  delegatesFocus: true
18070
18070
  }
18071
18071
  });
18072
18072
  DesignSystem.getOrCreate().withPrefix('nimble').register(nimbleAnchorTab());
18073
18073
 
18074
- const styles$U = css `
18074
+ const styles$V = css `
18075
18075
  ${display('grid')}
18076
18076
 
18077
18077
  :host {
@@ -18093,7 +18093,7 @@
18093
18093
  }
18094
18094
  `;
18095
18095
 
18096
- const template$C = (context, definition) => html `
18096
+ const template$D = (context, definition) => html `
18097
18097
  ${startSlotTemplate(context, definition)}
18098
18098
  <div ${ref('tablist')} class="tablist" part="tablist" role="tablist">
18099
18099
  <slot name="anchortab" ${slotted('tabs')}></slot>
@@ -18299,8 +18299,8 @@
18299
18299
  applyMixins(AnchorTabs, StartEnd);
18300
18300
  const nimbleAnchorTabs = AnchorTabs.compose({
18301
18301
  baseName: 'anchor-tabs',
18302
- template: template$C,
18303
- styles: styles$U,
18302
+ template: template$D,
18303
+ styles: styles$V,
18304
18304
  shadowOptions: {
18305
18305
  delegatesFocus: false
18306
18306
  }
@@ -18316,7 +18316,7 @@
18316
18316
  -webkit-user-select: none;
18317
18317
  `;
18318
18318
 
18319
- const styles$T = css `
18319
+ const styles$U = css `
18320
18320
  ${display('block')}
18321
18321
 
18322
18322
  :host {
@@ -18422,7 +18422,7 @@
18422
18422
  }
18423
18423
  `;
18424
18424
 
18425
- const template$B = (context, definition) => html `
18425
+ const template$C = (context, definition) => html `
18426
18426
  <template
18427
18427
  role="treeitem"
18428
18428
  slot="${x => (x.isNestedItem() ? 'item' : null)}"
@@ -18559,8 +18559,8 @@
18559
18559
  // FoundationAnchor already applies the StartEnd mixin, so we don't need to do it here.
18560
18560
  const nimbleAnchorTreeItem = AnchorTreeItem.compose({
18561
18561
  baseName: 'anchor-tree-item',
18562
- template: template$B,
18563
- styles: styles$T,
18562
+ template: template$C,
18563
+ styles: styles$U,
18564
18564
  shadowOptions: {
18565
18565
  delegatesFocus: true
18566
18566
  }
@@ -18576,7 +18576,7 @@
18576
18576
  zIndex1000: '1000'
18577
18577
  };
18578
18578
 
18579
- const styles$S = css `
18579
+ const styles$T = css `
18580
18580
  ${display('block')}
18581
18581
 
18582
18582
  :host {
@@ -18607,7 +18607,7 @@
18607
18607
  baseName: 'anchored-region',
18608
18608
  baseClass: AnchoredRegion$1,
18609
18609
  template: anchoredRegionTemplate,
18610
- styles: styles$S
18610
+ styles: styles$T
18611
18611
  });
18612
18612
  DesignSystem.getOrCreate()
18613
18613
  .withPrefix('nimble')
@@ -18687,7 +18687,7 @@
18687
18687
  */
18688
18688
  const themeBehavior = (theme, styles) => new ThemeStyleSheetBehavior(theme, styles);
18689
18689
 
18690
- const styles$R = css `
18690
+ const styles$S = css `
18691
18691
  ${display('flex')}
18692
18692
 
18693
18693
  :host {
@@ -18802,12 +18802,12 @@
18802
18802
  }
18803
18803
  `));
18804
18804
 
18805
- const styles$Q = css `
18806
- ${styles$Y}
18805
+ const styles$R = css `
18806
+ ${styles$Z}
18807
18807
  ${buttonAppearanceVariantStyles}
18808
18808
  `;
18809
18809
 
18810
- const template$A = (context, definition) => html `
18810
+ const template$B = (context, definition) => html `
18811
18811
  <button
18812
18812
  class="control"
18813
18813
  part="control"
@@ -18898,8 +18898,8 @@
18898
18898
  const nimbleButton = Button.compose({
18899
18899
  baseName: 'button',
18900
18900
  baseClass: Button$1,
18901
- template: template$A,
18902
- styles: styles$Q,
18901
+ template: template$B,
18902
+ styles: styles$R,
18903
18903
  shadowOptions: {
18904
18904
  delegatesFocus: true
18905
18905
  }
@@ -19650,13 +19650,13 @@
19650
19650
  };
19651
19651
 
19652
19652
  // Avoiding any whitespace in the template because this is an inline element
19653
- const template$z = html `<div
19653
+ const template$A = html `<div
19654
19654
  class="icon"
19655
19655
  aria-hidden="true"
19656
19656
  :innerHTML=${x => x.icon.data}
19657
19657
  ></div>`;
19658
19658
 
19659
- const styles$P = css `
19659
+ const styles$Q = css `
19660
19660
  ${display('inline-flex')}
19661
19661
 
19662
19662
  :host {
@@ -19709,8 +19709,8 @@
19709
19709
  const registerIcon = (baseName, iconClass) => {
19710
19710
  const composedIcon = iconClass.compose({
19711
19711
  baseName,
19712
- template: template$z,
19713
- styles: styles$P
19712
+ template: template$A,
19713
+ styles: styles$Q
19714
19714
  });
19715
19715
  DesignSystem.getOrCreate().withPrefix('nimble').register(composedIcon());
19716
19716
  };
@@ -19823,7 +19823,7 @@
19823
19823
  }).withDefault(coreLabelDefaults.filterNoResultsLabel);
19824
19824
 
19825
19825
  // prettier-ignore
19826
- const template$y = html `
19826
+ const template$z = html `
19827
19827
  <${themeProviderTag} theme="${Theme.color}">
19828
19828
  <div class="container"
19829
19829
  role="status"
@@ -19941,12 +19941,12 @@
19941
19941
  applyMixins(Banner, ARIAGlobalStatesAndProperties);
19942
19942
  const nimbleBanner = Banner.compose({
19943
19943
  baseName: 'banner',
19944
- template: template$y,
19945
- styles: styles$R
19944
+ template: template$z,
19945
+ styles: styles$S
19946
19946
  });
19947
19947
  DesignSystem.getOrCreate().withPrefix('nimble').register(nimbleBanner());
19948
19948
 
19949
- const styles$O = css `
19949
+ const styles$P = css `
19950
19950
  ${display('inline-block')}
19951
19951
 
19952
19952
  :host {
@@ -19987,11 +19987,11 @@
19987
19987
  baseName: 'breadcrumb',
19988
19988
  baseClass: Breadcrumb$1,
19989
19989
  template: breadcrumbTemplate,
19990
- styles: styles$O
19990
+ styles: styles$P
19991
19991
  });
19992
19992
  DesignSystem.getOrCreate().withPrefix('nimble').register(nimbleBreadcrumb());
19993
19993
 
19994
- const styles$N = css `
19994
+ const styles$O = css `
19995
19995
  ${display('inline-flex')}
19996
19996
 
19997
19997
  :host {
@@ -20069,14 +20069,14 @@
20069
20069
  baseName: 'breadcrumb-item',
20070
20070
  baseClass: BreadcrumbItem$1,
20071
20071
  template: breadcrumbItemTemplate,
20072
- styles: styles$N,
20072
+ styles: styles$O,
20073
20073
  separator: forwardSlash16X16.data
20074
20074
  });
20075
20075
  DesignSystem.getOrCreate()
20076
20076
  .withPrefix('nimble')
20077
20077
  .register(nimbleBreadcrumbItem());
20078
20078
 
20079
- const styles$M = css `
20079
+ const styles$N = css `
20080
20080
  ${display('flex')}
20081
20081
 
20082
20082
  :host {
@@ -20100,7 +20100,7 @@
20100
20100
  }
20101
20101
  `;
20102
20102
 
20103
- const template$x = html `
20103
+ const template$y = html `
20104
20104
  <section aria-labelledby="title-slot">
20105
20105
  <span id="title-slot"><slot name="title"></slot></span>
20106
20106
  <slot></slot>
@@ -20115,12 +20115,12 @@
20115
20115
  const nimbleCard = Card.compose({
20116
20116
  baseName: 'card',
20117
20117
  baseClass: Card$1,
20118
- template: template$x,
20119
- styles: styles$M
20118
+ template: template$y,
20119
+ styles: styles$N
20120
20120
  });
20121
20121
  DesignSystem.getOrCreate().withPrefix('nimble').register(nimbleCard());
20122
20122
 
20123
- const styles$L = css `
20123
+ const styles$M = css `
20124
20124
  ${display('inline-flex')}
20125
20125
 
20126
20126
  :host {
@@ -20279,14 +20279,14 @@
20279
20279
  const nimbleCardButton = CardButton.compose({
20280
20280
  baseName: 'card-button',
20281
20281
  template: buttonTemplate,
20282
- styles: styles$L,
20282
+ styles: styles$M,
20283
20283
  shadowOptions: {
20284
20284
  delegatesFocus: true
20285
20285
  }
20286
20286
  });
20287
20287
  DesignSystem.getOrCreate().withPrefix('nimble').register(nimbleCardButton());
20288
20288
 
20289
- const styles$K = css `
20289
+ const styles$L = css `
20290
20290
  ${display('inline-flex')}
20291
20291
 
20292
20292
  :host {
@@ -20395,7 +20395,7 @@
20395
20395
  }
20396
20396
  `;
20397
20397
 
20398
- const template$w = (_context, definition) => html `
20398
+ const template$x = (_context, definition) => html `
20399
20399
  <template
20400
20400
  role="checkbox"
20401
20401
  aria-checked="${x => x.checked}"
@@ -20444,16 +20444,16 @@
20444
20444
  const nimbleCheckbox = Checkbox.compose({
20445
20445
  baseName: 'checkbox',
20446
20446
  baseClass: Checkbox$1,
20447
- template: template$w,
20448
- styles: styles$K,
20447
+ template: template$x,
20448
+ styles: styles$L,
20449
20449
  checkedIndicator: check16X16.data,
20450
20450
  indeterminateIndicator: minus16X16.data
20451
20451
  });
20452
20452
  DesignSystem.getOrCreate().withPrefix('nimble').register(nimbleCheckbox());
20453
20453
  const checkboxTag = 'nimble-checkbox';
20454
20454
 
20455
- const styles$J = css `
20456
- ${styles$Y}
20455
+ const styles$K = css `
20456
+ ${styles$Z}
20457
20457
  ${buttonAppearanceVariantStyles}
20458
20458
 
20459
20459
  @layer checked {
@@ -20502,7 +20502,7 @@
20502
20502
 
20503
20503
  /* eslint-disable @typescript-eslint/indent */
20504
20504
  // prettier-ignore
20505
- const template$v = (context, definition) => html `
20505
+ const template$w = (context, definition) => html `
20506
20506
  <div
20507
20507
  role="button"
20508
20508
  part="control"
@@ -20598,8 +20598,8 @@
20598
20598
  applyMixins(ToggleButton, StartEnd, DelegatesARIAButton);
20599
20599
  const nimbleToggleButton = ToggleButton.compose({
20600
20600
  baseName: 'toggle-button',
20601
- template: template$v,
20602
- styles: styles$J,
20601
+ template: template$w,
20602
+ styles: styles$K,
20603
20603
  shadowOptions: {
20604
20604
  delegatesFocus: true
20605
20605
  }
@@ -20636,7 +20636,7 @@
20636
20636
  block: 'block'
20637
20637
  };
20638
20638
 
20639
- const styles$I = css `
20639
+ const styles$J = css `
20640
20640
  ${display('inline-flex')}
20641
20641
 
20642
20642
  :host {
@@ -20856,7 +20856,7 @@
20856
20856
  }
20857
20857
  `));
20858
20858
 
20859
- const styles$H = css `
20859
+ const styles$I = css `
20860
20860
  .error-icon {
20861
20861
  display: none;
20862
20862
  }
@@ -20903,9 +20903,9 @@
20903
20903
  standard: 'standard'
20904
20904
  };
20905
20905
 
20906
- const styles$G = css `
20906
+ const styles$H = css `
20907
+ ${styles$J}
20907
20908
  ${styles$I}
20908
- ${styles$H}
20909
20909
 
20910
20910
  :host {
20911
20911
  --ni-private-hover-bottom-border-width: 2px;
@@ -21041,7 +21041,7 @@
21041
21041
  }
21042
21042
 
21043
21043
  // prettier-ignore
21044
- const template$u = (context, definition) => html `
21044
+ const template$v = (context, definition) => html `
21045
21045
  <template
21046
21046
  aria-disabled="${x => x.ariaDisabled}"
21047
21047
  autocomplete="${x => x.autocomplete}"
@@ -21102,7 +21102,7 @@
21102
21102
  ?disabled="${x => x.disabled}"
21103
21103
  ${ref('listbox')}
21104
21104
  >
21105
- <slot
21105
+ <slot name="option"
21106
21106
  ${slotted({
21107
21107
  filter: (n) => n instanceof HTMLElement && Listbox.slottedOptionFilter(n),
21108
21108
  flatten: true,
@@ -21746,8 +21746,8 @@
21746
21746
  const nimbleCombobox = Combobox.compose({
21747
21747
  baseName: 'combobox',
21748
21748
  baseClass: FormAssociatedCombobox,
21749
- template: template$u,
21750
- styles: styles$G,
21749
+ template: template$v,
21750
+ styles: styles$H,
21751
21751
  shadowOptions: {
21752
21752
  delegatesFocus: true
21753
21753
  },
@@ -21792,7 +21792,7 @@
21792
21792
  */
21793
21793
  const UserDismissed = Symbol('user dismissed');
21794
21794
 
21795
- const styles$F = css `
21795
+ const styles$G = css `
21796
21796
  ${display('grid')}
21797
21797
 
21798
21798
  dialog {
@@ -21898,7 +21898,7 @@
21898
21898
  }
21899
21899
  `));
21900
21900
 
21901
- const template$t = html `
21901
+ const template$u = html `
21902
21902
  <template>
21903
21903
  <dialog
21904
21904
  ${ref('dialogElement')}
@@ -22046,13 +22046,13 @@
22046
22046
  applyMixins(Dialog, ARIAGlobalStatesAndProperties);
22047
22047
  const nimbleDialog = Dialog.compose({
22048
22048
  baseName: 'dialog',
22049
- template: template$t,
22050
- styles: styles$F,
22049
+ template: template$u,
22050
+ styles: styles$G,
22051
22051
  baseClass: Dialog
22052
22052
  });
22053
22053
  DesignSystem.getOrCreate().withPrefix('nimble').register(nimbleDialog());
22054
22054
 
22055
- const styles$E = css `
22055
+ const styles$F = css `
22056
22056
  ${display('block')}
22057
22057
 
22058
22058
  :host {
@@ -22205,7 +22205,7 @@
22205
22205
  }
22206
22206
  `));
22207
22207
 
22208
- const template$s = html `
22208
+ const template$t = html `
22209
22209
  <dialog
22210
22210
  ${ref('dialog')}
22211
22211
  aria-label="${x => x.ariaLabel}"
@@ -22348,8 +22348,8 @@
22348
22348
  applyMixins(Drawer, ARIAGlobalStatesAndProperties);
22349
22349
  const nimbleDrawer = Drawer.compose({
22350
22350
  baseName: 'drawer',
22351
- template: template$s,
22352
- styles: styles$E
22351
+ template: template$t,
22352
+ styles: styles$F
22353
22353
  });
22354
22354
  DesignSystem.getOrCreate().withPrefix('nimble').register(nimbleDrawer());
22355
22355
 
@@ -24579,7 +24579,7 @@
24579
24579
  }
24580
24580
  }
24581
24581
 
24582
- const styles$D = css `
24582
+ const styles$E = css `
24583
24583
  ${display('none')}
24584
24584
  `;
24585
24585
 
@@ -24628,7 +24628,7 @@
24628
24628
  ], LabelProviderCore.prototype, "filterNoResults", void 0);
24629
24629
  const nimbleLabelProviderCore = LabelProviderCore.compose({
24630
24630
  baseName: 'label-provider-core',
24631
- styles: styles$D
24631
+ styles: styles$E
24632
24632
  });
24633
24633
  DesignSystem.getOrCreate()
24634
24634
  .withPrefix('nimble')
@@ -24795,13 +24795,13 @@
24795
24795
  ], LabelProviderTable.prototype, "groupRowPlaceholderEmpty", void 0);
24796
24796
  const nimbleLabelProviderTable = LabelProviderTable.compose({
24797
24797
  baseName: 'label-provider-table',
24798
- styles: styles$D
24798
+ styles: styles$E
24799
24799
  });
24800
24800
  DesignSystem.getOrCreate()
24801
24801
  .withPrefix('nimble')
24802
24802
  .register(nimbleLabelProviderTable());
24803
24803
 
24804
- const styles$C = css `
24804
+ const styles$D = css `
24805
24805
  ${display('flex')}
24806
24806
 
24807
24807
  :host {
@@ -24878,7 +24878,7 @@
24878
24878
  * @public
24879
24879
  */
24880
24880
  // prettier-ignore
24881
- const template$r = (context, definition) => html `
24881
+ const template$s = (context, definition) => html `
24882
24882
  <template
24883
24883
  aria-checked="${x => x.ariaChecked}"
24884
24884
  aria-disabled="${x => x.ariaDisabled}"
@@ -24889,6 +24889,7 @@
24889
24889
  .filter(Boolean)
24890
24890
  .join(' ')}"
24891
24891
  role="option"
24892
+ slot="option"
24892
24893
  >
24893
24894
  ${startSlotTemplate(context, definition)}
24894
24895
  <span
@@ -24973,12 +24974,228 @@
24973
24974
  const nimbleListOption = ListOption.compose({
24974
24975
  baseName: 'list-option',
24975
24976
  baseClass: ListboxOption,
24976
- template: template$r,
24977
- styles: styles$C
24977
+ template: template$s,
24978
+ styles: styles$D
24978
24979
  });
24979
24980
  DesignSystem.getOrCreate().withPrefix('nimble').register(nimbleListOption());
24980
24981
  const listOptionTag = 'nimble-list-option';
24981
24982
 
24983
+ const styles$C = css `
24984
+ ${display('flex')}
24985
+
24986
+ :host {
24987
+ cursor: default;
24988
+ flex-direction: column;
24989
+ }
24990
+
24991
+ :host([visually-hidden]) {
24992
+ display: none;
24993
+ }
24994
+
24995
+ :host::after,
24996
+ :host::before {
24997
+ content: ' ';
24998
+ margin-top: ${smallPadding};
24999
+ margin-bottom: ${smallPadding};
25000
+ border-bottom: ${borderColor} 2px solid;
25001
+ opacity: 0.1;
25002
+ display: none;
25003
+ }
25004
+
25005
+ :host([top-separator-visible])::before,
25006
+ :host([bottom-separator-visible])::after {
25007
+ display: block;
25008
+ }
25009
+
25010
+ slot[name='option']::slotted([role='option']) {
25011
+ background-color: transparent;
25012
+ }
25013
+
25014
+ slot[name='option']::slotted([role='option']:hover) {
25015
+ background-color: ${fillHoverColor};
25016
+ }
25017
+
25018
+ slot[name='option']::slotted([role='option'][active-option]) {
25019
+ background-color: ${fillSelectedColor};
25020
+ }
25021
+
25022
+ slot[name='option']::slotted([role='option'][active-option]:hover) {
25023
+ background-color: ${fillHoverSelectedColor};
25024
+ }
25025
+
25026
+ .label-display {
25027
+ font: ${groupHeaderFont};
25028
+ text-transform: ${groupHeaderTextTransform};
25029
+ color: ${groupHeaderFontColor};
25030
+ white-space: nowrap;
25031
+ overflow: hidden;
25032
+ text-overflow: ellipsis;
25033
+ margin-left: ${smallPadding};
25034
+ margin-bottom: ${smallPadding};
25035
+ }
25036
+
25037
+ .label-slot.hidden {
25038
+ display: none;
25039
+ }
25040
+ `;
25041
+
25042
+ const isListOption$1 = (n) => {
25043
+ return n instanceof ListOption;
25044
+ };
25045
+ // prettier-ignore
25046
+ const template$r = html `
25047
+ <template
25048
+ role="group"
25049
+ aria-label="${x => x.labelContent}"
25050
+ slot="option"
25051
+ >
25052
+ <span ${overflow('hasOverflow')}
25053
+ class="label-display"
25054
+ aria-hidden="true"
25055
+ title=${x => (x.hasOverflow && x.labelContent ? x.labelContent : null)}
25056
+ @click="${(x, c) => x.clickHandler(c.event)}"
25057
+ >
25058
+ ${when(x => (typeof x.label === 'string'), html `${x => x.label}`)}
25059
+ <slot ${ref('labelSlot')}
25060
+ class="label-slot ${x => (typeof x.label === 'string' ? 'hidden' : '')}"
25061
+ >
25062
+ </slot>
25063
+ </span>
25064
+ <span class="content" part="content" role="none">
25065
+ <slot name="option"
25066
+ ${slotted({
25067
+ flatten: true,
25068
+ filter: (n) => isListOption$1(n),
25069
+ property: 'listOptions'
25070
+ })}
25071
+ ></slot>
25072
+ </span>
25073
+ </template>
25074
+ `;
25075
+
25076
+ /**
25077
+ * A nimble-styled HTML listbox option group
25078
+ */
25079
+ class ListOptionGroup extends FoundationElement {
25080
+ constructor() {
25081
+ super(...arguments);
25082
+ /**
25083
+ * The hidden state of the element.
25084
+ *
25085
+ * @public
25086
+ * @defaultValue - false
25087
+ * @remarks
25088
+ * HTML Attribute: hidden
25089
+ */
25090
+ this.hidden = false;
25091
+ /**
25092
+ * @internal
25093
+ * This attribute is required to allow use-cases that offer dynamic filtering
25094
+ * (like the Select) to visually hide groups that are filtered out, but still
25095
+ * allow users to use the native 'hidden' attribute without it being affected
25096
+ * by the filtering process.
25097
+ */
25098
+ this.visuallyHidden = false;
25099
+ /**
25100
+ * @internal
25101
+ */
25102
+ this.topSeparatorVisible = false;
25103
+ /**
25104
+ * @internal
25105
+ */
25106
+ this.bottomSeparatorVisible = false;
25107
+ /** @internal */
25108
+ this.hasOverflow = false;
25109
+ this.hiddenOptions = new Set();
25110
+ }
25111
+ /** @internal */
25112
+ get labelContent() {
25113
+ if (this.label) {
25114
+ return this.label;
25115
+ }
25116
+ if (!this.$fastController.isConnected) {
25117
+ return '';
25118
+ }
25119
+ const nodes = this.labelSlot.assignedNodes();
25120
+ return nodes
25121
+ .filter(node => node.textContent?.trim() !== '')
25122
+ .map(node => node.textContent?.trim())
25123
+ .join(' ');
25124
+ }
25125
+ /**
25126
+ * @internal
25127
+ */
25128
+ clickHandler(e) {
25129
+ e.preventDefault();
25130
+ e.stopImmediatePropagation();
25131
+ }
25132
+ /**
25133
+ * @internal
25134
+ */
25135
+ handleChange(source, propertyName) {
25136
+ if (source instanceof ListOption
25137
+ && (propertyName === 'hidden' || propertyName === 'visuallyHidden')) {
25138
+ if (source.hidden || source.visuallyHidden) {
25139
+ this.hiddenOptions.add(source);
25140
+ }
25141
+ else {
25142
+ this.hiddenOptions.delete(source);
25143
+ }
25144
+ this.visuallyHidden = this.hiddenOptions.size === this.listOptions.length;
25145
+ }
25146
+ }
25147
+ listOptionsChanged(prev, next) {
25148
+ this.hiddenOptions.clear();
25149
+ next.filter(o => o.hidden || o.visuallyHidden).forEach(o => this.hiddenOptions.add(o));
25150
+ prev?.forEach(o => {
25151
+ const notifier = Observable.getNotifier(o);
25152
+ notifier.unsubscribe(this, 'hidden');
25153
+ notifier.unsubscribe(this, 'visuallyHidden');
25154
+ });
25155
+ let allOptionsHidden = true;
25156
+ next?.forEach(o => {
25157
+ const notifier = Observable.getNotifier(o);
25158
+ notifier.subscribe(this, 'hidden');
25159
+ notifier.subscribe(this, 'visuallyHidden');
25160
+ allOptionsHidden = allOptionsHidden && (o.hidden || o.visuallyHidden);
25161
+ });
25162
+ this.visuallyHidden = next.length === 0 || allOptionsHidden;
25163
+ }
25164
+ }
25165
+ __decorate$1([
25166
+ attr
25167
+ ], ListOptionGroup.prototype, "label", void 0);
25168
+ __decorate$1([
25169
+ attr({ mode: 'boolean' })
25170
+ ], ListOptionGroup.prototype, "hidden", void 0);
25171
+ __decorate$1([
25172
+ attr({ attribute: 'visually-hidden', mode: 'boolean' })
25173
+ ], ListOptionGroup.prototype, "visuallyHidden", void 0);
25174
+ __decorate$1([
25175
+ attr({ attribute: 'top-separator-visible', mode: 'boolean' })
25176
+ ], ListOptionGroup.prototype, "topSeparatorVisible", void 0);
25177
+ __decorate$1([
25178
+ attr({ attribute: 'bottom-separator-visible', mode: 'boolean' })
25179
+ ], ListOptionGroup.prototype, "bottomSeparatorVisible", void 0);
25180
+ __decorate$1([
25181
+ observable
25182
+ ], ListOptionGroup.prototype, "hasOverflow", void 0);
25183
+ __decorate$1([
25184
+ observable
25185
+ ], ListOptionGroup.prototype, "listOptions", void 0);
25186
+ __decorate$1([
25187
+ volatile
25188
+ ], ListOptionGroup.prototype, "labelContent", null);
25189
+ const nimbleListOptionGroup = ListOptionGroup.compose({
25190
+ baseName: 'list-option-group',
25191
+ baseClass: FoundationElement,
25192
+ template: template$r,
25193
+ styles: styles$C
25194
+ });
25195
+ DesignSystem.getOrCreate()
25196
+ .withPrefix('nimble')
25197
+ .register(nimbleListOptionGroup());
25198
+
24982
25199
  /**
24983
25200
  * Base class for mapping configuration elements
24984
25201
  */
@@ -25604,7 +25821,7 @@
25604
25821
 
25605
25822
  const styles$x = css `
25606
25823
  ${display('inline-block')}
25607
- ${styles$H}
25824
+ ${styles$I}
25608
25825
 
25609
25826
  :host {
25610
25827
  font: ${bodyFont};
@@ -43737,7 +43954,7 @@ img.ProseMirror-separator {
43737
43954
  }).withDefault(richTextLabelDefaults.richTextToggleNumberedListLabel);
43738
43955
 
43739
43956
  const styles$t = css `
43740
- ${styles$I}
43957
+ ${styles$J}
43741
43958
 
43742
43959
  :host {
43743
43960
  height: auto;
@@ -43775,8 +43992,8 @@ img.ProseMirror-separator {
43775
43992
  @click="${(x, c) => x.clickHandler(c.event)}"
43776
43993
  ?disabled="${x => x.disabled}"
43777
43994
  >
43778
- <slot
43779
- ${slotted({ filter: (n) => n instanceof HTMLElement && ListboxElement.slottedOptionFilter(n), flatten: true, property: 'slottedOptions' })}
43995
+ <slot name="option"
43996
+ ${slotted({ filter: (n) => n instanceof HTMLElement && Listbox.slottedOptionFilter(n), flatten: true, property: 'slottedOptions' })}
43780
43997
  >
43781
43998
  </slot>
43782
43999
  </div>
@@ -44129,7 +44346,7 @@ img.ProseMirror-separator {
44129
44346
 
44130
44347
  const styles$s = css `
44131
44348
  ${display('inline-flex')}
44132
- ${styles$H}
44349
+ ${styles$I}
44133
44350
 
44134
44351
  :host {
44135
44352
  font: ${bodyFont};
@@ -52912,9 +53129,9 @@ img.ProseMirror-separator {
52912
53129
  strong: {
52913
53130
  parseDOM: [
52914
53131
  { tag: "strong" },
52915
- { tag: "b", getAttrs: (node) => node.style.fontWeight != "normal" && null },
53132
+ { tag: "b", getAttrs: node => node.style.fontWeight != "normal" && null },
52916
53133
  { style: "font-weight=400", clearMark: m => m.type.name == "strong" },
52917
- { style: "font-weight", getAttrs: (value) => /^(bold(er)?|[5-9]\d{2,})$/.test(value) && null }
53134
+ { style: "font-weight", getAttrs: value => /^(bold(er)?|[5-9]\d{2,})$/.test(value) && null }
52918
53135
  ],
52919
53136
  toDOM() { return ["strong"]; }
52920
53137
  },
@@ -53168,6 +53385,7 @@ img.ProseMirror-separator {
53168
53385
  code_inline: { mark: "code", noCloseToken: true }
53169
53386
  });
53170
53387
 
53388
+ const blankMark = { open: "", close: "", mixable: true };
53171
53389
  /**
53172
53390
  A specification for serializing a ProseMirror document as
53173
53391
  Markdown/CommonMark text.
@@ -53375,6 +53593,18 @@ img.ProseMirror-separator {
53375
53593
  }
53376
53594
  }
53377
53595
  /**
53596
+ @internal
53597
+ */
53598
+ getMark(name) {
53599
+ let info = this.marks[name];
53600
+ if (!info) {
53601
+ if (this.options.strict !== false)
53602
+ throw new Error(`Mark type \`${name}\` not supported by Markdown renderer`);
53603
+ info = blankMark;
53604
+ }
53605
+ return info;
53606
+ }
53607
+ /**
53378
53608
  Render a block, prefixing each line with `delim`, and the first
53379
53609
  line in `firstDelim`. `node` should be the node that is closed at
53380
53610
  the end of the block, and `f` is a function that renders the
@@ -53439,9 +53669,22 @@ img.ProseMirror-separator {
53439
53669
  Render the given node as a block.
53440
53670
  */
53441
53671
  render(node, parent, index) {
53442
- if (!this.nodes[node.type.name])
53443
- throw new Error("Token type `" + node.type.name + "` not supported by Markdown renderer");
53444
- this.nodes[node.type.name](this, node, parent, index);
53672
+ if (this.nodes[node.type.name]) {
53673
+ this.nodes[node.type.name](this, node, parent, index);
53674
+ }
53675
+ else {
53676
+ if (this.options.strict !== false) {
53677
+ throw new Error("Token type `" + node.type.name + "` not supported by Markdown renderer");
53678
+ }
53679
+ else if (!node.type.isLeaf) {
53680
+ if (node.type.inlineContent)
53681
+ this.renderInline(node);
53682
+ else
53683
+ this.renderContent(node);
53684
+ if (node.isBlock)
53685
+ this.closeBlock(node);
53686
+ }
53687
+ }
53445
53688
  }
53446
53689
  /**
53447
53690
  Render the contents of `parent` as block nodes.
@@ -53472,7 +53715,7 @@ img.ProseMirror-separator {
53472
53715
  // If whitespace has to be expelled from the node, adjust
53473
53716
  // leading and trailing accordingly.
53474
53717
  if (node && node.isText && marks.some(mark => {
53475
- let info = this.marks[mark.type.name];
53718
+ let info = this.getMark(mark.type.name);
53476
53719
  return info && info.expelEnclosingWhitespace && !mark.isInSet(active);
53477
53720
  })) {
53478
53721
  let [_, lead, rest] = /^(\s*)(.*)$/m.exec(node.text);
@@ -53484,7 +53727,7 @@ img.ProseMirror-separator {
53484
53727
  }
53485
53728
  }
53486
53729
  if (node && node.isText && marks.some(mark => {
53487
- let info = this.marks[mark.type.name];
53730
+ let info = this.getMark(mark.type.name);
53488
53731
  return info && info.expelEnclosingWhitespace &&
53489
53732
  (index == parent.childCount - 1 || !mark.isInSet(parent.child(index + 1).marks));
53490
53733
  })) {
@@ -53497,7 +53740,7 @@ img.ProseMirror-separator {
53497
53740
  }
53498
53741
  }
53499
53742
  let inner = marks.length ? marks[marks.length - 1] : null;
53500
- let noEsc = inner && this.marks[inner.type.name].escape === false;
53743
+ let noEsc = inner && this.getMark(inner.type.name).escape === false;
53501
53744
  let len = marks.length - (noEsc ? 1 : 0);
53502
53745
  // Try to reorder 'mixable' marks, such as em and strong, which
53503
53746
  // in Markdown may be opened and closed in different order, so
@@ -53505,11 +53748,11 @@ img.ProseMirror-separator {
53505
53748
  // active.
53506
53749
  outer: for (let i = 0; i < len; i++) {
53507
53750
  let mark = marks[i];
53508
- if (!this.marks[mark.type.name].mixable)
53751
+ if (!this.getMark(mark.type.name).mixable)
53509
53752
  break;
53510
53753
  for (let j = 0; j < active.length; j++) {
53511
53754
  let other = active[j];
53512
- if (!this.marks[other.type.name].mixable)
53755
+ if (!this.getMark(other.type.name).mixable)
53513
53756
  break;
53514
53757
  if (mark.eq(other)) {
53515
53758
  if (i > j)
@@ -53615,7 +53858,7 @@ img.ProseMirror-separator {
53615
53858
  Get the markdown string for a given opening or closing mark.
53616
53859
  */
53617
53860
  markString(mark, open, parent, index) {
53618
- let info = this.marks[mark.type.name];
53861
+ let info = this.getMark(mark.type.name);
53619
53862
  let value = open ? info.open : info.close;
53620
53863
  return typeof value == "string" ? value : value(this, mark, parent, index);
53621
53864
  }
@@ -59006,8 +59249,8 @@ img.ProseMirror-separator {
59006
59249
  .register(nimbleRichTextViewer());
59007
59250
 
59008
59251
  const styles$q = css `
59252
+ ${styles$J}
59009
59253
  ${styles$I}
59010
- ${styles$H}
59011
59254
 
59012
59255
  ${
59013
59256
  /* We are using flex `order` to define the visual ordering of the selected value,
@@ -59145,6 +59388,12 @@ img.ProseMirror-separator {
59145
59388
  }
59146
59389
  `));
59147
59390
 
59391
+ const isListOption = (el) => {
59392
+ return el instanceof ListOption;
59393
+ };
59394
+ const isListOptionGroup = (n) => {
59395
+ return n instanceof ListOptionGroup;
59396
+ };
59148
59397
  /* eslint-disable @typescript-eslint/indent */
59149
59398
  // prettier-ignore
59150
59399
  const template$l = (context, definition) => html `
@@ -59246,8 +59495,9 @@ img.ProseMirror-separator {
59246
59495
  <div ${ref('scrollableRegion')}
59247
59496
  class="scrollable-region">
59248
59497
  <slot
59498
+ name="option"
59249
59499
  ${slotted({
59250
- filter: (n) => n instanceof HTMLElement && isListboxOption(n),
59500
+ filter: (n) => n instanceof HTMLElement && (isListOption(n) || isListOptionGroup(n)),
59251
59501
  flatten: true,
59252
59502
  property: 'slottedOptions',
59253
59503
  })}
@@ -59282,15 +59532,15 @@ img.ProseMirror-separator {
59282
59532
  }
59283
59533
  }
59284
59534
 
59285
- const isNimbleListOption = (el) => {
59286
- return el instanceof ListOption;
59287
- };
59288
59535
  const isOptionSelectable = (el) => {
59289
59536
  return !el.visuallyHidden && !el.disabled && !el.hidden;
59290
59537
  };
59291
59538
  const isOptionPlaceholder = (el) => {
59292
59539
  return el.disabled && el.hidden;
59293
59540
  };
59541
+ const isOptionOrGroupVisible = (el) => {
59542
+ return !el.visuallyHidden && !el.hidden;
59543
+ };
59294
59544
  /**
59295
59545
  * A nimble-styled HTML select.
59296
59546
  */
@@ -59411,13 +59661,25 @@ img.ProseMirror-separator {
59411
59661
  notifier.unsubscribe(this, 'hidden');
59412
59662
  notifier.unsubscribe(this, 'disabled');
59413
59663
  });
59414
- super.slottedOptionsChanged(prev, next);
59415
- this.options.forEach(o => {
59664
+ prev?.filter(isListOptionGroup).forEach(el => {
59665
+ const notifier = Observable.getNotifier(el);
59666
+ notifier.unsubscribe(this, 'hidden');
59667
+ notifier.unsubscribe(this, 'visuallyHidden');
59668
+ });
59669
+ const options = this.getSlottedOptions(next);
59670
+ super.slottedOptionsChanged(prev, options);
59671
+ options.forEach(o => {
59416
59672
  const notifier = Observable.getNotifier(o);
59417
59673
  notifier.subscribe(this, 'value');
59418
59674
  notifier.subscribe(this, 'hidden');
59419
59675
  notifier.subscribe(this, 'disabled');
59420
59676
  });
59677
+ next?.filter(isListOptionGroup).forEach(el => {
59678
+ this.updateAdjacentSeparatorState(el);
59679
+ const notifier = Observable.getNotifier(el);
59680
+ notifier.subscribe(this, 'hidden');
59681
+ notifier.subscribe(this, 'visuallyHidden');
59682
+ });
59421
59683
  this.setProxyOptions();
59422
59684
  this.updateValue();
59423
59685
  // We need to force an update to the filteredOptions observable
@@ -59470,8 +59732,7 @@ img.ProseMirror-separator {
59470
59732
  break;
59471
59733
  }
59472
59734
  case 'selected': {
59473
- if (isNimbleListOption(sourceElement)
59474
- && sourceElement.selected) {
59735
+ if (isListOption(sourceElement) && sourceElement.selected) {
59475
59736
  this.selectedIndex = this.options.indexOf(sourceElement);
59476
59737
  }
59477
59738
  else {
@@ -59480,12 +59741,27 @@ img.ProseMirror-separator {
59480
59741
  break;
59481
59742
  }
59482
59743
  case 'hidden': {
59483
- if (isNimbleListOption(sourceElement)) {
59744
+ if (isListOption(sourceElement)) {
59484
59745
  sourceElement.visuallyHidden = sourceElement.hidden;
59746
+ this.updateAdjacentSeparatorState(sourceElement);
59747
+ }
59748
+ else if (isListOptionGroup(sourceElement)) {
59749
+ sourceElement.listOptions.forEach(e => {
59750
+ e.visuallyHidden = sourceElement.hidden;
59751
+ });
59752
+ this.updateAdjacentSeparatorState(sourceElement);
59485
59753
  }
59754
+ this.filterOptions();
59486
59755
  this.updateDisplayValue();
59487
59756
  break;
59488
59757
  }
59758
+ case 'visuallyHidden': {
59759
+ if (isListOptionGroup(sourceElement)
59760
+ || isListOption(sourceElement)) {
59761
+ this.updateAdjacentSeparatorState(sourceElement);
59762
+ }
59763
+ break;
59764
+ }
59489
59765
  case 'disabled': {
59490
59766
  this.updateDisplayValue();
59491
59767
  break;
@@ -59738,8 +60014,7 @@ img.ProseMirror-separator {
59738
60014
  const startIndex = this.openActiveIndex ?? this.selectedIndex;
59739
60015
  for (let i = startIndex + 1; i < this.options.length; i++) {
59740
60016
  const listOption = this.options[i];
59741
- if (isNimbleListOption(listOption)
59742
- && isOptionSelectable(listOption)) {
60017
+ if (isListOption(listOption) && isOptionSelectable(listOption)) {
59743
60018
  this.setActiveOption(i);
59744
60019
  break;
59745
60020
  }
@@ -59754,8 +60029,7 @@ img.ProseMirror-separator {
59754
60029
  const startIndex = this.openActiveIndex ?? this.selectedIndex;
59755
60030
  for (let i = startIndex - 1; i >= 0; i--) {
59756
60031
  const listOption = this.options[i];
59757
- if (isNimbleListOption(listOption)
59758
- && isOptionSelectable(listOption)) {
60032
+ if (isListOption(listOption) && isOptionSelectable(listOption)) {
59759
60033
  this.setActiveOption(i);
59760
60034
  break;
59761
60035
  }
@@ -59765,14 +60039,14 @@ img.ProseMirror-separator {
59765
60039
  * @internal
59766
60040
  */
59767
60041
  selectFirstOption() {
59768
- const newActiveOptionIndex = this.options.findIndex(o => isNimbleListOption(o) && isOptionSelectable(o));
60042
+ const newActiveOptionIndex = this.options.findIndex(o => isListOption(o) && isOptionSelectable(o));
59769
60043
  this.setActiveOption(newActiveOptionIndex);
59770
60044
  }
59771
60045
  /**
59772
60046
  * @internal
59773
60047
  */
59774
60048
  selectLastOption() {
59775
- const newActiveOptionIndex = findLastIndex(this.options, o => isNimbleListOption(o) && isOptionSelectable(o));
60049
+ const newActiveOptionIndex = findLastIndex(this.options, o => isListOption(o) && isOptionSelectable(o));
59776
60050
  this.setActiveOption(newActiveOptionIndex);
59777
60051
  }
59778
60052
  /**
@@ -59840,7 +60114,7 @@ img.ProseMirror-separator {
59840
60114
  return;
59841
60115
  }
59842
60116
  const activeOption = this.options[this.openActiveIndex ?? this.selectedIndex];
59843
- if (isNimbleListOption(activeOption)) {
60117
+ if (isListOption(activeOption)) {
59844
60118
  activeOption.activeOption = false;
59845
60119
  }
59846
60120
  this.openActiveIndex = undefined;
@@ -59883,7 +60157,7 @@ img.ProseMirror-separator {
59883
60157
  */
59884
60158
  setDefaultSelectedOption() {
59885
60159
  const options = this.options
59886
- ?? Array.from(this.children).filter(o => isNimbleListOption(o));
60160
+ ?? Array.from(this.children).filter(o => isListOption(o));
59887
60161
  const optionIsSelected = (option) => {
59888
60162
  return option.hasAttribute('selected') || option.selected;
59889
60163
  };
@@ -59917,16 +60191,28 @@ img.ProseMirror-separator {
59917
60191
  this.selectedIndex = 0;
59918
60192
  }
59919
60193
  }
60194
+ getSlottedOptions(slottedElements) {
60195
+ const options = [];
60196
+ slottedElements?.forEach(el => {
60197
+ if (isListOption(el)) {
60198
+ options.push(el);
60199
+ }
60200
+ else if (isListOptionGroup(el)) {
60201
+ options.push(...this.getGroupOptions(el));
60202
+ }
60203
+ });
60204
+ return options;
60205
+ }
59920
60206
  setActiveOption(newActiveIndex) {
59921
60207
  const activeOption = this.options[newActiveIndex];
59922
60208
  if (this.open) {
59923
- if (isNimbleListOption(activeOption)) {
60209
+ if (isListOption(activeOption)) {
59924
60210
  activeOption.activeOption = true;
59925
60211
  }
59926
60212
  const previousActiveIndex = this.openActiveIndex ?? this.selectedIndex;
59927
60213
  const previousActiveOption = this.options[previousActiveIndex];
59928
60214
  if (previousActiveIndex !== newActiveIndex
59929
- && isNimbleListOption(previousActiveOption)) {
60215
+ && isListOption(previousActiveOption)) {
59930
60216
  previousActiveOption.activeOption = false;
59931
60217
  }
59932
60218
  this.openActiveIndex = newActiveIndex;
@@ -59980,32 +60266,110 @@ img.ProseMirror-separator {
59980
60266
  : Math.trunc(availableBottom);
59981
60267
  this.updateListboxMaxHeightCssVariable();
59982
60268
  }
60269
+ updateAdjacentSeparatorState(element) {
60270
+ const previousElement = this.getPreviousVisibleOptionOrGroup(element);
60271
+ const nextElement = this.getNextVisibleOptionOrGroup(element);
60272
+ if (isOptionOrGroupVisible(element)) {
60273
+ const topSeparatorVisible = isListOption(previousElement);
60274
+ this.setTopSeparatorState(element, topSeparatorVisible);
60275
+ const bottomSeparatorVisible = nextElement !== null;
60276
+ this.setBottomSeparatorState(element, bottomSeparatorVisible);
60277
+ this.setBottomSeparatorState(previousElement, true);
60278
+ }
60279
+ else {
60280
+ const nextTopSeparatorVisible = isListOption(previousElement);
60281
+ this.setTopSeparatorState(nextElement, nextTopSeparatorVisible);
60282
+ const previousBottomSeparatorVisible = nextElement !== null;
60283
+ this.setBottomSeparatorState(previousElement, previousBottomSeparatorVisible);
60284
+ }
60285
+ }
60286
+ setTopSeparatorState(element, visible) {
60287
+ if (isListOptionGroup(element)) {
60288
+ element.topSeparatorVisible = visible;
60289
+ }
60290
+ }
60291
+ setBottomSeparatorState(element, visible) {
60292
+ if (isListOptionGroup(element)) {
60293
+ element.bottomSeparatorVisible = visible;
60294
+ }
60295
+ }
60296
+ getPreviousVisibleOptionOrGroup(element) {
60297
+ let previousElement = element.previousElementSibling;
60298
+ while (previousElement) {
60299
+ if ((isListOption(previousElement)
60300
+ || isListOptionGroup(previousElement))
60301
+ && isOptionOrGroupVisible(previousElement)) {
60302
+ return previousElement;
60303
+ }
60304
+ previousElement = previousElement.previousElementSibling;
60305
+ }
60306
+ return null;
60307
+ }
60308
+ getNextVisibleOptionOrGroup(element) {
60309
+ let nextElement = element.nextElementSibling;
60310
+ while (nextElement) {
60311
+ if ((isListOption(nextElement) || isListOptionGroup(nextElement))
60312
+ && isOptionOrGroupVisible(nextElement)) {
60313
+ return nextElement;
60314
+ }
60315
+ nextElement = nextElement.nextElementSibling;
60316
+ }
60317
+ return null;
60318
+ }
60319
+ isOptionHiddenOrFilteredOut(option) {
60320
+ if (option.hidden) {
60321
+ return true;
60322
+ }
60323
+ return !this.filterMatchesText(option.text);
60324
+ }
60325
+ filterMatchesText(text) {
60326
+ const filter = this.filter.toLowerCase();
60327
+ const normalizedFilter = diacriticInsensitiveStringNormalizer(filter);
60328
+ return diacriticInsensitiveStringNormalizer(text).includes(normalizedFilter);
60329
+ }
59983
60330
  /**
59984
60331
  * Filter available options by text value.
59985
60332
  *
59986
60333
  * @public
59987
60334
  */
59988
60335
  filterOptions() {
59989
- const filter = this.filter.toLowerCase();
59990
- if (filter) {
59991
- this.filteredOptions = this.options.filter(option => {
59992
- const normalizedFilter = diacriticInsensitiveStringNormalizer(filter);
59993
- return (!option.hidden
59994
- && diacriticInsensitiveStringNormalizer(option.text).includes(normalizedFilter));
59995
- });
59996
- }
59997
- else {
59998
- this.filteredOptions = this.options.filter(option => !option.hidden);
60336
+ if (!this.$fastController.isConnected) {
60337
+ return;
59999
60338
  }
60000
- this.options.forEach(o => {
60001
- if (isNimbleListOption(o)) {
60002
- if (!this.filteredOptions.includes(o)) {
60003
- o.visuallyHidden = true;
60339
+ const filteredOptions = [];
60340
+ for (const element of this.slottedOptions) {
60341
+ if (isListOptionGroup(element)) {
60342
+ if (element.hidden) {
60343
+ continue; // no need to process hidden groups
60004
60344
  }
60005
- else {
60006
- o.visuallyHidden = false;
60345
+ const groupOptions = this.getGroupOptions(element);
60346
+ const groupMatchesFilter = this.filterMatchesText(element.labelContent);
60347
+ groupOptions.forEach(option => {
60348
+ option.visuallyHidden = groupMatchesFilter
60349
+ ? false
60350
+ : this.isOptionHiddenOrFilteredOut(option);
60351
+ if (!option.visuallyHidden) {
60352
+ filteredOptions.push(option);
60353
+ }
60354
+ });
60355
+ }
60356
+ else if (isListOption(element)) {
60357
+ element.visuallyHidden = this.isOptionHiddenOrFilteredOut(element);
60358
+ if (!element.visuallyHidden) {
60359
+ filteredOptions.push(element);
60007
60360
  }
60008
60361
  }
60362
+ }
60363
+ this.filteredOptions = filteredOptions;
60364
+ }
60365
+ getGroupOptions(group) {
60366
+ return Array.from(group.children)
60367
+ .filter(el => isListOption(el))
60368
+ .map(el => {
60369
+ if (group.hidden && isListOption(el)) {
60370
+ el.visuallyHidden = true;
60371
+ }
60372
+ return el;
60009
60373
  });
60010
60374
  }
60011
60375
  /**
@@ -70710,7 +71074,7 @@ img.ProseMirror-separator {
70710
71074
 
70711
71075
  const styles$6 = css `
70712
71076
  ${display('inline-flex')}
70713
- ${styles$H}
71077
+ ${styles$I}
70714
71078
 
70715
71079
  :host {
70716
71080
  font: ${bodyFont};
@@ -71056,7 +71420,7 @@ img.ProseMirror-separator {
71056
71420
 
71057
71421
  const styles$5 = css `
71058
71422
  ${display('inline-block')}
71059
- ${styles$H}
71423
+ ${styles$I}
71060
71424
 
71061
71425
  :host {
71062
71426
  font: ${bodyFont};
@@ -76724,7 +77088,7 @@ img.ProseMirror-separator {
76724
77088
  /**
76725
77089
  * Prerendering prepares render-ready dies data to be used by the rendering module
76726
77090
  */
76727
- let Prerendering$1 = class Prerendering {
77091
+ class Prerendering {
76728
77092
  get labelsFontSize() {
76729
77093
  return this._labelsFontSize;
76730
77094
  }
@@ -76831,12 +77195,12 @@ img.ProseMirror-separator {
76831
77195
  rgbColor = new ColorRGBA64(rgbColor.r, rgbColor.g, rgbColor.b, this.calculateOpacity(dieTags, highlightedTags));
76832
77196
  return rgbColor.toStringWebRGBA();
76833
77197
  }
76834
- };
77198
+ }
76835
77199
 
76836
77200
  /**
76837
77201
  * Data Manager uses Computations and Prerendering modules in order and exposes the results
76838
77202
  */
76839
- let DataManager$1 = class DataManager {
77203
+ class DataManager {
76840
77204
  get containerDimensions() {
76841
77205
  return this.computations.containerDimensions;
76842
77206
  }
@@ -76873,7 +77237,7 @@ img.ProseMirror-separator {
76873
77237
  constructor(wafermap) {
76874
77238
  this.wafermap = wafermap;
76875
77239
  this.computations = new Computations$1(wafermap);
76876
- this.prerendering = new Prerendering$1(wafermap);
77240
+ this.prerendering = new Prerendering(wafermap);
76877
77241
  }
76878
77242
  updateContainerDimensions() {
76879
77243
  this.computations.updateContainerDimensions();
@@ -76897,258 +77261,6 @@ img.ProseMirror-separator {
76897
77261
  updateDataMap() {
76898
77262
  this.dataMap = new Map(this.wafermap.dies.map(die => [`${die.x}_${die.y}`, die]));
76899
77263
  }
76900
- };
76901
-
76902
- /**
76903
- * Computations calculates and stores different measures which are used in the Wafermap
76904
- */
76905
- class Computations {
76906
- get containerDimensions() {
76907
- return this._containerDimensions;
76908
- }
76909
- get dieDimensions() {
76910
- return this._dieDimensions;
76911
- }
76912
- get margin() {
76913
- return this._margin;
76914
- }
76915
- get horizontalScale() {
76916
- return this._horizontalScale;
76917
- }
76918
- get verticalScale() {
76919
- return this._verticalScale;
76920
- }
76921
- constructor(wafermap) {
76922
- this.wafermap = wafermap;
76923
- this.defaultPadding = 0;
76924
- this.baseMarginPercentage = 0.04;
76925
- }
76926
- update() {
76927
- const canvasDimensions = {
76928
- width: this.wafermap.canvasWidth,
76929
- height: this.wafermap.canvasHeight
76930
- };
76931
- const canvasDiameter = Math.min(canvasDimensions.width, canvasDimensions.height);
76932
- const canvasMargin = {
76933
- top: (canvasDimensions.height - canvasDiameter) / 2,
76934
- right: (canvasDimensions.width - canvasDiameter) / 2,
76935
- bottom: (canvasDimensions.height - canvasDiameter) / 2,
76936
- left: (canvasDimensions.width - canvasDiameter) / 2
76937
- };
76938
- const baseMargin = {
76939
- top: canvasDiameter * this.baseMarginPercentage,
76940
- right: canvasDiameter * this.baseMarginPercentage,
76941
- bottom: canvasDiameter * this.baseMarginPercentage,
76942
- left: canvasDiameter * this.baseMarginPercentage
76943
- };
76944
- this._margin = this.calculateMarginAddition(baseMargin, canvasMargin);
76945
- this._containerDimensions = this.calculateContainerDimensions(canvasDimensions, this._margin);
76946
- const containerDiameter = Math.min(this._containerDimensions.width, this._containerDimensions.height);
76947
- const gridDimensions = this.gridDimensionsValidAndDefined()
76948
- ? this.calculateGridDimensionsFromBoundingBox()
76949
- : this.calculateGridDimensionsFromDies();
76950
- // this scale is used for positioning the dies on the canvas
76951
- const originLocation = this.wafermap.originLocation;
76952
- this._horizontalScale = this.createHorizontalScale(originLocation, gridDimensions, containerDiameter);
76953
- // this scale is used for positioning the dies on the canvas
76954
- this._verticalScale = this.createVerticalScale(originLocation, gridDimensions, containerDiameter);
76955
- this._dieDimensions = {
76956
- width: Math.abs(this._horizontalScale(0) - this._horizontalScale(1)),
76957
- height: Math.abs(this._verticalScale(0) - this._verticalScale(1))
76958
- };
76959
- }
76960
- gridDimensionsValidAndDefined() {
76961
- return (!this.wafermap.validity.invalidGridDimensions
76962
- && typeof this.wafermap.gridMinX === 'number'
76963
- && typeof this.wafermap.gridMinY === 'number'
76964
- && typeof this.wafermap.gridMaxX === 'number'
76965
- && typeof this.wafermap.gridMinX === 'number');
76966
- }
76967
- calculateGridDimensionsFromBoundingBox() {
76968
- const gridDimensions = { origin: { x: 0, y: 0 }, rows: 0, cols: 0 };
76969
- if (typeof this.wafermap.gridMaxY === 'number'
76970
- && typeof this.wafermap.gridMinY === 'number'
76971
- && typeof this.wafermap.gridMaxX === 'number'
76972
- && typeof this.wafermap.gridMinX === 'number') {
76973
- gridDimensions.origin.x = this.wafermap.gridMinX;
76974
- gridDimensions.origin.y = this.wafermap.gridMinY;
76975
- gridDimensions.rows = this.wafermap.gridMaxY - this.wafermap.gridMinY + 1;
76976
- gridDimensions.cols = this.wafermap.gridMaxX - this.wafermap.gridMinX + 1;
76977
- }
76978
- return gridDimensions;
76979
- }
76980
- calculateGridDimensionsFromDies() {
76981
- if (this.wafermap.diesTable === undefined) {
76982
- return { origin: { x: 0, y: 0 }, rows: 0, cols: 0 };
76983
- }
76984
- const colIndex = this.wafermap.diesTable
76985
- .getChild('colIndex')
76986
- .toArray();
76987
- const rowIndex = this.wafermap.diesTable
76988
- .getChild('rowIndex')
76989
- .toArray();
76990
- const minPoint = { x: colIndex[0], y: rowIndex[0] };
76991
- const maxPoint = { x: colIndex[0], y: rowIndex[0] };
76992
- // will replace iterating with arquero after fixing issues: https://github.com/uwdata/arquero/pull/346
76993
- for (let i = 0; i < colIndex.length; i++) {
76994
- if (colIndex[i] < minPoint.x) {
76995
- minPoint.x = colIndex[i];
76996
- }
76997
- if (colIndex[i] > maxPoint.x) {
76998
- maxPoint.x = colIndex[i];
76999
- }
77000
- if (rowIndex[i] < minPoint.y) {
77001
- minPoint.y = rowIndex[i];
77002
- }
77003
- if (rowIndex[i] > maxPoint.y) {
77004
- maxPoint.y = rowIndex[i];
77005
- }
77006
- }
77007
- return {
77008
- origin: minPoint,
77009
- rows: maxPoint.y - minPoint.y + 1,
77010
- cols: maxPoint.x - minPoint.x + 1
77011
- };
77012
- }
77013
- calculateContainerDimensions(canvasDimensions, margin) {
77014
- return {
77015
- width: canvasDimensions.width - margin.left - margin.right,
77016
- height: canvasDimensions.height - margin.top - margin.bottom
77017
- };
77018
- }
77019
- createHorizontalScale(originLocation, grid, containerWidth) {
77020
- const scale = linear();
77021
- if (originLocation === WaferMapOriginLocation.bottomLeft
77022
- || originLocation === WaferMapOriginLocation.topLeft) {
77023
- return scale
77024
- .domain([grid.origin.x, grid.origin.x + grid.cols])
77025
- .range([0, containerWidth]);
77026
- }
77027
- return scale
77028
- .domain([grid.origin.x - 1, grid.origin.x + grid.cols - 1])
77029
- .range([containerWidth, 0]);
77030
- }
77031
- createVerticalScale(originLocation, grid, containerHeight) {
77032
- const scale = linear();
77033
- // html canvas has top-left origin https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes#the_grid
77034
- // we need to flip the vertical scale
77035
- if (originLocation === WaferMapOriginLocation.bottomLeft
77036
- || originLocation === WaferMapOriginLocation.bottomRight) {
77037
- return scale
77038
- .domain([grid.origin.y - 1, grid.origin.y + grid.rows - 1])
77039
- .range([containerHeight, 0]);
77040
- }
77041
- return scale
77042
- .domain([grid.origin.y, grid.origin.y + grid.rows])
77043
- .range([0, containerHeight]);
77044
- }
77045
- calculateMarginAddition(baseMargin, addedMargin) {
77046
- return {
77047
- top: baseMargin.top + addedMargin.top,
77048
- right: baseMargin.right + addedMargin.right,
77049
- bottom: baseMargin.bottom + addedMargin.bottom,
77050
- left: baseMargin.left + addedMargin.left
77051
- };
77052
- }
77053
- }
77054
-
77055
- /**
77056
- * Prerendering prepares render-ready dies data to be used by the rendering module
77057
- */
77058
- class Prerendering {
77059
- get labelsFontSize() {
77060
- return this._labelsFontSize;
77061
- }
77062
- get colorScale() {
77063
- return this._colorScale;
77064
- }
77065
- constructor(wafermap) {
77066
- this.wafermap = wafermap;
77067
- this.fontSizeFactor = 0.8;
77068
- this.colorScaleResolution = 10;
77069
- }
77070
- update() {
77071
- this._labelsFontSize = this.calculateLabelsFontSize(this.wafermap.experimentalDataManager.dieDimensions, this.wafermap.maxCharacters);
77072
- this._colorScale = this.calculateColorScale();
77073
- }
77074
- calculateColorScale() {
77075
- if (this.wafermap.colorScaleMode === WaferMapColorScaleMode.linear) {
77076
- const values = this.wafermap.colorScale.values.map(item => +item);
77077
- const d3ColorScale = linear()
77078
- .domain(values)
77079
- .range(this.wafermap.colorScale.colors);
77080
- let min = values[0];
77081
- let max = values[0];
77082
- values.forEach(value => {
77083
- if (value < min) {
77084
- min = value;
77085
- }
77086
- if (value > max) {
77087
- max = value;
77088
- }
77089
- });
77090
- // the linear color scale will not be infinite but will be limited by the color scale resolution
77091
- const valueSamples = ticks(min, max, values.length * this.colorScaleResolution);
77092
- return valueSamples.map(value => {
77093
- return {
77094
- color: d3ColorScale(value),
77095
- value
77096
- };
77097
- });
77098
- }
77099
- // ordinal color categories have to be sorted by value
77100
- return this.wafermap.colorScale.colors
77101
- .map((color, index) => {
77102
- return {
77103
- color,
77104
- value: +this.wafermap.colorScale.values[index]
77105
- };
77106
- })
77107
- .sort((a, b) => a.value - b.value);
77108
- }
77109
- calculateLabelsFontSize(dieDimensions, maxCharacters) {
77110
- return Math.min(dieDimensions.height, (dieDimensions.width / (Math.max(2, maxCharacters) * 0.5))
77111
- * this.fontSizeFactor);
77112
- }
77113
- }
77114
-
77115
- /**
77116
- * Data Manager uses Computations and Prerendering modules in order and exposes the results
77117
- */
77118
- class DataManager {
77119
- get containerDimensions() {
77120
- return this.computations.containerDimensions;
77121
- }
77122
- get dieDimensions() {
77123
- return this.computations.dieDimensions;
77124
- }
77125
- get margin() {
77126
- return this.computations.margin;
77127
- }
77128
- get horizontalScale() {
77129
- return this.computations.horizontalScale;
77130
- }
77131
- get verticalScale() {
77132
- return this.computations.verticalScale;
77133
- }
77134
- get labelsFontSize() {
77135
- return this.prerendering.labelsFontSize;
77136
- }
77137
- get colorScale() {
77138
- return this.prerendering.colorScale;
77139
- }
77140
- constructor(wafermap) {
77141
- this.wafermap = wafermap;
77142
- this.computations = new Computations(wafermap);
77143
- this.prerendering = new Prerendering(wafermap);
77144
- }
77145
- updateComputations() {
77146
- this.computations.update();
77147
- this.prerendering.update();
77148
- }
77149
- updatePrerendering() {
77150
- this.prerendering.update();
77151
- }
77152
77264
  }
77153
77265
 
77154
77266
  /**
@@ -77307,8 +77419,7 @@ img.ProseMirror-separator {
77307
77419
  this.updateQueued = false;
77308
77420
  }
77309
77421
  get requiresEventsUpdate() {
77310
- return (this.isTracked('highlightedTags')
77311
- || this.isTracked('canvasWidth')
77422
+ return (this.isTracked('canvasWidth')
77312
77423
  || this.isTracked('canvasHeight')
77313
77424
  || this.isTracked('originLocation')
77314
77425
  || this.isTracked('gridMinX')
@@ -77317,15 +77428,35 @@ img.ProseMirror-separator {
77317
77428
  || this.isTracked('gridMaxY')
77318
77429
  || this.isTracked('dies')
77319
77430
  || this.isTracked('maxCharacters')
77431
+ || this.isTracked('highlightedTags')
77320
77432
  || this.isTracked('colorScale')
77321
77433
  || this.isTracked('colorScaleMode')
77322
77434
  || this.isTracked('dieLabelsHidden')
77323
77435
  || this.isTracked('dieLabelsSuffix')
77324
77436
  || this.isTracked('transform'));
77325
77437
  }
77438
+ get requiresWorkerWaferSetup() {
77439
+ return (this.isTracked('canvasWidth')
77440
+ || this.isTracked('canvasHeight')
77441
+ || this.isTracked('originLocation')
77442
+ || this.isTracked('gridMinX')
77443
+ || this.isTracked('gridMaxX')
77444
+ || this.isTracked('gridMinY')
77445
+ || this.isTracked('gridMaxY')
77446
+ || this.isTracked('dies')
77447
+ || this.isTracked('maxCharacters')
77448
+ || this.isTracked('highlightedTags')
77449
+ || this.isTracked('colorScale')
77450
+ || this.isTracked('colorScaleMode')
77451
+ || this.isTracked('dieLabelsHidden')
77452
+ || this.isTracked('dieLabelsSuffix'));
77453
+ }
77326
77454
  get requiresContainerDimensionsUpdate() {
77327
77455
  return this.isTracked('canvasWidth') || this.isTracked('canvasHeight');
77328
77456
  }
77457
+ get requiresComponentResizeUpdate() {
77458
+ return this.isTracked('canvasWidth') || this.isTracked('canvasHeight');
77459
+ }
77329
77460
  get requiresScalesUpdate() {
77330
77461
  return (this.isTracked('originLocation')
77331
77462
  || this.isTracked('gridMinX')
@@ -77334,6 +77465,14 @@ img.ProseMirror-separator {
77334
77465
  || this.isTracked('gridMaxY')
77335
77466
  || this.isTracked('dies'));
77336
77467
  }
77468
+ get requiresInputDataUpdate() {
77469
+ return (this.isTracked('originLocation')
77470
+ || this.isTracked('gridMinX')
77471
+ || this.isTracked('gridMaxX')
77472
+ || this.isTracked('gridMinY')
77473
+ || this.isTracked('gridMaxY')
77474
+ || this.isTracked('dies'));
77475
+ }
77337
77476
  get requiresLabelsFontSizeUpdate() {
77338
77477
  return this.isTracked('maxCharacters');
77339
77478
  }
@@ -77344,6 +77483,14 @@ img.ProseMirror-separator {
77344
77483
  || this.isTracked('dieLabelsHidden')
77345
77484
  || this.isTracked('dieLabelsSuffix'));
77346
77485
  }
77486
+ get requiresColorAndTextUpdate() {
77487
+ return (this.isTracked('maxCharacters')
77488
+ || this.isTracked('highlightedTags')
77489
+ || this.isTracked('colorScale')
77490
+ || this.isTracked('colorScaleMode')
77491
+ || this.isTracked('dieLabelsHidden')
77492
+ || this.isTracked('dieLabelsSuffix'));
77493
+ }
77347
77494
  get requiresDrawnWaferUpdate() {
77348
77495
  return this.isTracked('transform');
77349
77496
  }
@@ -78374,7 +78521,7 @@ img.ProseMirror-separator {
78374
78521
  }
78375
78522
 
78376
78523
  // eslint-disable-next-line no-template-curly-in-string
78377
- const workerCode = "var MatrixRenderer = (function (exports) {\n 'use strict';\n\n /**\n * @license\n * Copyright 2019 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n const proxyMarker = Symbol(\"Comlink.proxy\");\n const createEndpoint = Symbol(\"Comlink.endpoint\");\n const releaseProxy = Symbol(\"Comlink.releaseProxy\");\n const finalizer = Symbol(\"Comlink.finalizer\");\n const throwMarker = Symbol(\"Comlink.thrown\");\n const isObject = (val) => (typeof val === \"object\" && val !== null) || typeof val === \"function\";\n /**\n * Internal transfer handle to handle objects marked to proxy.\n */\n const proxyTransferHandler = {\n canHandle: (val) => isObject(val) && val[proxyMarker],\n serialize(obj) {\n const { port1, port2 } = new MessageChannel();\n expose(obj, port1);\n return [port2, [port2]];\n },\n deserialize(port) {\n port.start();\n return wrap(port);\n },\n };\n /**\n * Internal transfer handler to handle thrown exceptions.\n */\n const throwTransferHandler = {\n canHandle: (value) => isObject(value) && throwMarker in value,\n serialize({ value }) {\n let serialized;\n if (value instanceof Error) {\n serialized = {\n isError: true,\n value: {\n message: value.message,\n name: value.name,\n stack: value.stack,\n },\n };\n }\n else {\n serialized = { isError: false, value };\n }\n return [serialized, []];\n },\n deserialize(serialized) {\n if (serialized.isError) {\n throw Object.assign(new Error(serialized.value.message), serialized.value);\n }\n throw serialized.value;\n },\n };\n /**\n * Allows customizing the serialization of certain values.\n */\n const transferHandlers = new Map([\n [\"proxy\", proxyTransferHandler],\n [\"throw\", throwTransferHandler],\n ]);\n function isAllowedOrigin(allowedOrigins, origin) {\n for (const allowedOrigin of allowedOrigins) {\n if (origin === allowedOrigin || allowedOrigin === \"*\") {\n return true;\n }\n if (allowedOrigin instanceof RegExp && allowedOrigin.test(origin)) {\n return true;\n }\n }\n return false;\n }\n function expose(obj, ep = globalThis, allowedOrigins = [\"*\"]) {\n ep.addEventListener(\"message\", function callback(ev) {\n if (!ev || !ev.data) {\n return;\n }\n if (!isAllowedOrigin(allowedOrigins, ev.origin)) {\n console.warn(`Invalid origin '${ev.origin}' for comlink proxy`);\n return;\n }\n const { id, type, path } = Object.assign({ path: [] }, ev.data);\n const argumentList = (ev.data.argumentList || []).map(fromWireValue);\n let returnValue;\n try {\n const parent = path.slice(0, -1).reduce((obj, prop) => obj[prop], obj);\n const rawValue = path.reduce((obj, prop) => obj[prop], obj);\n switch (type) {\n case \"GET\" /* MessageType.GET */:\n {\n returnValue = rawValue;\n }\n break;\n case \"SET\" /* MessageType.SET */:\n {\n parent[path.slice(-1)[0]] = fromWireValue(ev.data.value);\n returnValue = true;\n }\n break;\n case \"APPLY\" /* MessageType.APPLY */:\n {\n returnValue = rawValue.apply(parent, argumentList);\n }\n break;\n case \"CONSTRUCT\" /* MessageType.CONSTRUCT */:\n {\n const value = new rawValue(...argumentList);\n returnValue = proxy(value);\n }\n break;\n case \"ENDPOINT\" /* MessageType.ENDPOINT */:\n {\n const { port1, port2 } = new MessageChannel();\n expose(obj, port2);\n returnValue = transfer(port1, [port1]);\n }\n break;\n case \"RELEASE\" /* MessageType.RELEASE */:\n {\n returnValue = undefined;\n }\n break;\n default:\n return;\n }\n }\n catch (value) {\n returnValue = { value, [throwMarker]: 0 };\n }\n Promise.resolve(returnValue)\n .catch((value) => {\n return { value, [throwMarker]: 0 };\n })\n .then((returnValue) => {\n const [wireValue, transferables] = toWireValue(returnValue);\n ep.postMessage(Object.assign(Object.assign({}, wireValue), { id }), transferables);\n if (type === \"RELEASE\" /* MessageType.RELEASE */) {\n // detach and deactive after sending release response above.\n ep.removeEventListener(\"message\", callback);\n closeEndPoint(ep);\n if (finalizer in obj && typeof obj[finalizer] === \"function\") {\n obj[finalizer]();\n }\n }\n })\n .catch((error) => {\n // Send Serialization Error To Caller\n const [wireValue, transferables] = toWireValue({\n value: new TypeError(\"Unserializable return value\"),\n [throwMarker]: 0,\n });\n ep.postMessage(Object.assign(Object.assign({}, wireValue), { id }), transferables);\n });\n });\n if (ep.start) {\n ep.start();\n }\n }\n function isMessagePort(endpoint) {\n return endpoint.constructor.name === \"MessagePort\";\n }\n function closeEndPoint(endpoint) {\n if (isMessagePort(endpoint))\n endpoint.close();\n }\n function wrap(ep, target) {\n return createProxy(ep, [], target);\n }\n function throwIfProxyReleased(isReleased) {\n if (isReleased) {\n throw new Error(\"Proxy has been released and is not useable\");\n }\n }\n function releaseEndpoint(ep) {\n return requestResponseMessage(ep, {\n type: \"RELEASE\" /* MessageType.RELEASE */,\n }).then(() => {\n closeEndPoint(ep);\n });\n }\n const proxyCounter = new WeakMap();\n const proxyFinalizers = \"FinalizationRegistry\" in globalThis &&\n new FinalizationRegistry((ep) => {\n const newCount = (proxyCounter.get(ep) || 0) - 1;\n proxyCounter.set(ep, newCount);\n if (newCount === 0) {\n releaseEndpoint(ep);\n }\n });\n function registerProxy(proxy, ep) {\n const newCount = (proxyCounter.get(ep) || 0) + 1;\n proxyCounter.set(ep, newCount);\n if (proxyFinalizers) {\n proxyFinalizers.register(proxy, ep, proxy);\n }\n }\n function unregisterProxy(proxy) {\n if (proxyFinalizers) {\n proxyFinalizers.unregister(proxy);\n }\n }\n function createProxy(ep, path = [], target = function () { }) {\n let isProxyReleased = false;\n const proxy = new Proxy(target, {\n get(_target, prop) {\n throwIfProxyReleased(isProxyReleased);\n if (prop === releaseProxy) {\n return () => {\n unregisterProxy(proxy);\n releaseEndpoint(ep);\n isProxyReleased = true;\n };\n }\n if (prop === \"then\") {\n if (path.length === 0) {\n return { then: () => proxy };\n }\n const r = requestResponseMessage(ep, {\n type: \"GET\" /* MessageType.GET */,\n path: path.map((p) => p.toString()),\n }).then(fromWireValue);\n return r.then.bind(r);\n }\n return createProxy(ep, [...path, prop]);\n },\n set(_target, prop, rawValue) {\n throwIfProxyReleased(isProxyReleased);\n // FIXME: ES6 Proxy Handler `set` methods are supposed to return a\n // boolean. To show good will, we return true asynchronously ¯\\_(ツ)_/¯\n const [value, transferables] = toWireValue(rawValue);\n return requestResponseMessage(ep, {\n type: \"SET\" /* MessageType.SET */,\n path: [...path, prop].map((p) => p.toString()),\n value,\n }, transferables).then(fromWireValue);\n },\n apply(_target, _thisArg, rawArgumentList) {\n throwIfProxyReleased(isProxyReleased);\n const last = path[path.length - 1];\n if (last === createEndpoint) {\n return requestResponseMessage(ep, {\n type: \"ENDPOINT\" /* MessageType.ENDPOINT */,\n }).then(fromWireValue);\n }\n // We just pretend that `bind()` didn’t happen.\n if (last === \"bind\") {\n return createProxy(ep, path.slice(0, -1));\n }\n const [argumentList, transferables] = processArguments(rawArgumentList);\n return requestResponseMessage(ep, {\n type: \"APPLY\" /* MessageType.APPLY */,\n path: path.map((p) => p.toString()),\n argumentList,\n }, transferables).then(fromWireValue);\n },\n construct(_target, rawArgumentList) {\n throwIfProxyReleased(isProxyReleased);\n const [argumentList, transferables] = processArguments(rawArgumentList);\n return requestResponseMessage(ep, {\n type: \"CONSTRUCT\" /* MessageType.CONSTRUCT */,\n path: path.map((p) => p.toString()),\n argumentList,\n }, transferables).then(fromWireValue);\n },\n });\n registerProxy(proxy, ep);\n return proxy;\n }\n function myFlat(arr) {\n return Array.prototype.concat.apply([], arr);\n }\n function processArguments(argumentList) {\n const processed = argumentList.map(toWireValue);\n return [processed.map((v) => v[0]), myFlat(processed.map((v) => v[1]))];\n }\n const transferCache = new WeakMap();\n function transfer(obj, transfers) {\n transferCache.set(obj, transfers);\n return obj;\n }\n function proxy(obj) {\n return Object.assign(obj, { [proxyMarker]: true });\n }\n function toWireValue(value) {\n for (const [name, handler] of transferHandlers) {\n if (handler.canHandle(value)) {\n const [serializedValue, transferables] = handler.serialize(value);\n return [\n {\n type: \"HANDLER\" /* WireValueType.HANDLER */,\n name,\n value: serializedValue,\n },\n transferables,\n ];\n }\n }\n return [\n {\n type: \"RAW\" /* WireValueType.RAW */,\n value,\n },\n transferCache.get(value) || [],\n ];\n }\n function fromWireValue(value) {\n switch (value.type) {\n case \"HANDLER\" /* WireValueType.HANDLER */:\n return transferHandlers.get(value.name).deserialize(value.value);\n case \"RAW\" /* WireValueType.RAW */:\n return value.value;\n }\n }\n function requestResponseMessage(ep, msg, transfers) {\n return new Promise((resolve) => {\n const id = generateUUID();\n ep.addEventListener(\"message\", function l(ev) {\n if (!ev.data || !ev.data.id || ev.data.id !== id) {\n return;\n }\n ep.removeEventListener(\"message\", l);\n resolve(ev.data);\n });\n if (ep.start) {\n ep.start();\n }\n ep.postMessage(Object.assign({ id }, msg), transfers);\n });\n }\n function generateUUID() {\n return new Array(4)\n .fill(0)\n .map(() => Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(16))\n .join(\"-\");\n }\n\n /**\n * MatrixRenderer class is meant to be used within a Web Worker context,\n * using Comlink to facilitate communication between the main thread and the worker.\n * The MatrixRenderer class manages a matrix of dies, once an instance of MatrixRenderer is created,\n * it is exposed to the main thread using Comlink's `expose` method.\n * This setup is used in the wafer-map component to perform heavy computational duties\n */\n class MatrixRenderer {\n constructor() {\n this.columnIndexes = Int32Array.from([]);\n this.rowIndexes = Int32Array.from([]);\n this.values = Float64Array.from([]);\n this.scaledColumnIndex = Float64Array.from([]);\n this.scaledRowIndex = Float64Array.from([]);\n this.columnIndexPositions = Int32Array.from([]);\n this.scaleX = 1;\n this.scaleY = 1;\n this.baseX = 1;\n this.baseY = 1;\n this.dieDimensions = { width: 1, height: 1 };\n this.transform = { k: 1, x: 0, y: 0 };\n this.smallestMarginPossible = 20;\n this.margin = {\n top: this.smallestMarginPossible,\n right: this.smallestMarginPossible,\n bottom: this.smallestMarginPossible,\n left: this.smallestMarginPossible\n };\n }\n calculateXScaledIndex(columnIndex) {\n return this.scaleX * columnIndex + this.baseX + this.margin.left;\n }\n calculateYScaledIndex(rowIndex) {\n return this.scaleY * rowIndex + this.baseY + this.margin.top;\n }\n setColumnIndexes(columnIndexes) {\n this.columnIndexes = columnIndexes;\n if (columnIndexes.length === 0 || this.columnIndexes[0] === undefined) {\n return;\n }\n const scaledColumnIndex = [\n this.calculateXScaledIndex(this.columnIndexes[0])\n ];\n const columnPositions = [0];\n let prev = this.columnIndexes[0];\n for (let i = 1; i < this.columnIndexes.length; i++) {\n const xIndex = this.columnIndexes[i];\n if (xIndex && xIndex !== prev) {\n const scaledX = this.calculateXScaledIndex(this.columnIndexes[i]);\n scaledColumnIndex.push(scaledX);\n columnPositions.push(i);\n prev = xIndex;\n }\n }\n this.scaledColumnIndex = Float64Array.from(scaledColumnIndex);\n this.columnIndexPositions = Int32Array.from(columnPositions);\n }\n setRowIndexes(rowIndexesBuffer) {\n this.rowIndexes = rowIndexesBuffer;\n this.scaledRowIndex = new Float64Array(this.rowIndexes.length);\n for (let i = 0; i < this.rowIndexes.length; i++) {\n this.scaledRowIndex[i] = this.calculateYScaledIndex(this.rowIndexes[i]);\n }\n }\n setMargin(margin) {\n this.margin = margin;\n }\n setCanvasCorners(topLeft, bottomRight) {\n this.topLeftCanvasCorner = topLeft;\n this.bottomRightCanvasCorner = bottomRight;\n }\n setDiesDimensions(data) {\n this.dieDimensions = { width: data.width, height: data.height };\n }\n setScaling(scaleX, scaleY) {\n this.scaleX = scaleX;\n this.scaleY = scaleY;\n }\n setBases(baseX, baseY) {\n this.baseX = baseX;\n this.baseY = baseY;\n }\n setTransform(transform) {\n this.transform = transform;\n }\n setCanvas(canvas) {\n this.canvas = canvas;\n this.context = canvas.getContext('2d');\n }\n getMatrix() {\n return {\n columnIndexes: this.columnIndexes,\n rowIndexes: this.rowIndexes,\n values: this.values\n };\n }\n emptyMatrix() {\n this.columnIndexes = Int32Array.from([]);\n this.rowIndexes = Int32Array.from([]);\n this.values = Float64Array.from([]);\n }\n scaleCanvas() {\n this.context.translate(this.transform.x, this.transform.y);\n this.context.scale(this.transform.k, this.transform.k);\n }\n updateMatrix(data) {\n this.columnIndexes = Int32Array.from(data.columnIndexes);\n this.rowIndexes = Int32Array.from(data.rowIndexes);\n this.values = Float64Array.from(data.values);\n }\n setCanvasDimensions(data) {\n this.canvas.width = data.width;\n this.canvas.height = data.height;\n }\n getCanvasDimensions() {\n return {\n width: this.canvas.width,\n height: this.canvas.height\n };\n }\n clearCanvas() {\n this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);\n }\n drawWafer() {\n this.context.restore();\n this.context.save();\n this.clearCanvas();\n this.scaleCanvas();\n if (this.topLeftCanvasCorner === undefined\n || this.bottomRightCanvasCorner === undefined) {\n throw new Error('Canvas corners are not set');\n }\n for (let i = 0; i < this.scaledColumnIndex.length; i++) {\n const scaledX = this.scaledColumnIndex[i];\n if (!(scaledX >= this.topLeftCanvasCorner.x\n && scaledX < this.bottomRightCanvasCorner.x)) {\n continue;\n }\n // columnIndexPositions is used to get chunks to determine the start and end index of the column, it looks something like [0, 1, 4, 9, 12]\n // This means that the first column has a start index of 0 and an end index of 1, the second column has a start index of 1 and an end index of 4, and so on\n // scaledRowIndex is used when we reach the end of the columnIndexPositions, when columnIndexPositions is [0, 1, 4, 9, 12], scaledRowIndex is 13\n const columnEndIndex = this.columnIndexPositions[i + 1] !== undefined\n ? this.columnIndexPositions[i + 1]\n : this.scaledRowIndex.length;\n for (let columnStartIndex = this.columnIndexPositions[i]; columnStartIndex < columnEndIndex; columnStartIndex++) {\n const scaledY = this.scaledRowIndex[columnStartIndex];\n if (!(scaledY >= this.topLeftCanvasCorner.y\n && scaledY < this.bottomRightCanvasCorner.y)) {\n continue;\n }\n // Fill style is temporary green for all dies, will be replaced with a color based on the value of the die in a future implementation\n this.context.fillStyle = 'Green';\n this.context.fillRect(scaledX, scaledY, this.dieDimensions.width, this.dieDimensions.height);\n }\n }\n }\n }\n expose(MatrixRenderer);\n\n exports.MatrixRenderer = MatrixRenderer;\n\n return exports;\n\n})({});\n";
78524
+ const workerCode = "var MatrixRenderer = (function (exports) {\n 'use strict';\n\n /**\n * @license\n * Copyright 2019 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n const proxyMarker = Symbol(\"Comlink.proxy\");\n const createEndpoint = Symbol(\"Comlink.endpoint\");\n const releaseProxy = Symbol(\"Comlink.releaseProxy\");\n const finalizer = Symbol(\"Comlink.finalizer\");\n const throwMarker = Symbol(\"Comlink.thrown\");\n const isObject = (val) => (typeof val === \"object\" && val !== null) || typeof val === \"function\";\n /**\n * Internal transfer handle to handle objects marked to proxy.\n */\n const proxyTransferHandler = {\n canHandle: (val) => isObject(val) && val[proxyMarker],\n serialize(obj) {\n const { port1, port2 } = new MessageChannel();\n expose(obj, port1);\n return [port2, [port2]];\n },\n deserialize(port) {\n port.start();\n return wrap(port);\n },\n };\n /**\n * Internal transfer handler to handle thrown exceptions.\n */\n const throwTransferHandler = {\n canHandle: (value) => isObject(value) && throwMarker in value,\n serialize({ value }) {\n let serialized;\n if (value instanceof Error) {\n serialized = {\n isError: true,\n value: {\n message: value.message,\n name: value.name,\n stack: value.stack,\n },\n };\n }\n else {\n serialized = { isError: false, value };\n }\n return [serialized, []];\n },\n deserialize(serialized) {\n if (serialized.isError) {\n throw Object.assign(new Error(serialized.value.message), serialized.value);\n }\n throw serialized.value;\n },\n };\n /**\n * Allows customizing the serialization of certain values.\n */\n const transferHandlers = new Map([\n [\"proxy\", proxyTransferHandler],\n [\"throw\", throwTransferHandler],\n ]);\n function isAllowedOrigin(allowedOrigins, origin) {\n for (const allowedOrigin of allowedOrigins) {\n if (origin === allowedOrigin || allowedOrigin === \"*\") {\n return true;\n }\n if (allowedOrigin instanceof RegExp && allowedOrigin.test(origin)) {\n return true;\n }\n }\n return false;\n }\n function expose(obj, ep = globalThis, allowedOrigins = [\"*\"]) {\n ep.addEventListener(\"message\", function callback(ev) {\n if (!ev || !ev.data) {\n return;\n }\n if (!isAllowedOrigin(allowedOrigins, ev.origin)) {\n console.warn(`Invalid origin '${ev.origin}' for comlink proxy`);\n return;\n }\n const { id, type, path } = Object.assign({ path: [] }, ev.data);\n const argumentList = (ev.data.argumentList || []).map(fromWireValue);\n let returnValue;\n try {\n const parent = path.slice(0, -1).reduce((obj, prop) => obj[prop], obj);\n const rawValue = path.reduce((obj, prop) => obj[prop], obj);\n switch (type) {\n case \"GET\" /* MessageType.GET */:\n {\n returnValue = rawValue;\n }\n break;\n case \"SET\" /* MessageType.SET */:\n {\n parent[path.slice(-1)[0]] = fromWireValue(ev.data.value);\n returnValue = true;\n }\n break;\n case \"APPLY\" /* MessageType.APPLY */:\n {\n returnValue = rawValue.apply(parent, argumentList);\n }\n break;\n case \"CONSTRUCT\" /* MessageType.CONSTRUCT */:\n {\n const value = new rawValue(...argumentList);\n returnValue = proxy(value);\n }\n break;\n case \"ENDPOINT\" /* MessageType.ENDPOINT */:\n {\n const { port1, port2 } = new MessageChannel();\n expose(obj, port2);\n returnValue = transfer(port1, [port1]);\n }\n break;\n case \"RELEASE\" /* MessageType.RELEASE */:\n {\n returnValue = undefined;\n }\n break;\n default:\n return;\n }\n }\n catch (value) {\n returnValue = { value, [throwMarker]: 0 };\n }\n Promise.resolve(returnValue)\n .catch((value) => {\n return { value, [throwMarker]: 0 };\n })\n .then((returnValue) => {\n const [wireValue, transferables] = toWireValue(returnValue);\n ep.postMessage(Object.assign(Object.assign({}, wireValue), { id }), transferables);\n if (type === \"RELEASE\" /* MessageType.RELEASE */) {\n // detach and deactive after sending release response above.\n ep.removeEventListener(\"message\", callback);\n closeEndPoint(ep);\n if (finalizer in obj && typeof obj[finalizer] === \"function\") {\n obj[finalizer]();\n }\n }\n })\n .catch((error) => {\n // Send Serialization Error To Caller\n const [wireValue, transferables] = toWireValue({\n value: new TypeError(\"Unserializable return value\"),\n [throwMarker]: 0,\n });\n ep.postMessage(Object.assign(Object.assign({}, wireValue), { id }), transferables);\n });\n });\n if (ep.start) {\n ep.start();\n }\n }\n function isMessagePort(endpoint) {\n return endpoint.constructor.name === \"MessagePort\";\n }\n function closeEndPoint(endpoint) {\n if (isMessagePort(endpoint))\n endpoint.close();\n }\n function wrap(ep, target) {\n return createProxy(ep, [], target);\n }\n function throwIfProxyReleased(isReleased) {\n if (isReleased) {\n throw new Error(\"Proxy has been released and is not useable\");\n }\n }\n function releaseEndpoint(ep) {\n return requestResponseMessage(ep, {\n type: \"RELEASE\" /* MessageType.RELEASE */,\n }).then(() => {\n closeEndPoint(ep);\n });\n }\n const proxyCounter = new WeakMap();\n const proxyFinalizers = \"FinalizationRegistry\" in globalThis &&\n new FinalizationRegistry((ep) => {\n const newCount = (proxyCounter.get(ep) || 0) - 1;\n proxyCounter.set(ep, newCount);\n if (newCount === 0) {\n releaseEndpoint(ep);\n }\n });\n function registerProxy(proxy, ep) {\n const newCount = (proxyCounter.get(ep) || 0) + 1;\n proxyCounter.set(ep, newCount);\n if (proxyFinalizers) {\n proxyFinalizers.register(proxy, ep, proxy);\n }\n }\n function unregisterProxy(proxy) {\n if (proxyFinalizers) {\n proxyFinalizers.unregister(proxy);\n }\n }\n function createProxy(ep, path = [], target = function () { }) {\n let isProxyReleased = false;\n const proxy = new Proxy(target, {\n get(_target, prop) {\n throwIfProxyReleased(isProxyReleased);\n if (prop === releaseProxy) {\n return () => {\n unregisterProxy(proxy);\n releaseEndpoint(ep);\n isProxyReleased = true;\n };\n }\n if (prop === \"then\") {\n if (path.length === 0) {\n return { then: () => proxy };\n }\n const r = requestResponseMessage(ep, {\n type: \"GET\" /* MessageType.GET */,\n path: path.map((p) => p.toString()),\n }).then(fromWireValue);\n return r.then.bind(r);\n }\n return createProxy(ep, [...path, prop]);\n },\n set(_target, prop, rawValue) {\n throwIfProxyReleased(isProxyReleased);\n // FIXME: ES6 Proxy Handler `set` methods are supposed to return a\n // boolean. To show good will, we return true asynchronously ¯\\_(ツ)_/¯\n const [value, transferables] = toWireValue(rawValue);\n return requestResponseMessage(ep, {\n type: \"SET\" /* MessageType.SET */,\n path: [...path, prop].map((p) => p.toString()),\n value,\n }, transferables).then(fromWireValue);\n },\n apply(_target, _thisArg, rawArgumentList) {\n throwIfProxyReleased(isProxyReleased);\n const last = path[path.length - 1];\n if (last === createEndpoint) {\n return requestResponseMessage(ep, {\n type: \"ENDPOINT\" /* MessageType.ENDPOINT */,\n }).then(fromWireValue);\n }\n // We just pretend that `bind()` didn’t happen.\n if (last === \"bind\") {\n return createProxy(ep, path.slice(0, -1));\n }\n const [argumentList, transferables] = processArguments(rawArgumentList);\n return requestResponseMessage(ep, {\n type: \"APPLY\" /* MessageType.APPLY */,\n path: path.map((p) => p.toString()),\n argumentList,\n }, transferables).then(fromWireValue);\n },\n construct(_target, rawArgumentList) {\n throwIfProxyReleased(isProxyReleased);\n const [argumentList, transferables] = processArguments(rawArgumentList);\n return requestResponseMessage(ep, {\n type: \"CONSTRUCT\" /* MessageType.CONSTRUCT */,\n path: path.map((p) => p.toString()),\n argumentList,\n }, transferables).then(fromWireValue);\n },\n });\n registerProxy(proxy, ep);\n return proxy;\n }\n function myFlat(arr) {\n return Array.prototype.concat.apply([], arr);\n }\n function processArguments(argumentList) {\n const processed = argumentList.map(toWireValue);\n return [processed.map((v) => v[0]), myFlat(processed.map((v) => v[1]))];\n }\n const transferCache = new WeakMap();\n function transfer(obj, transfers) {\n transferCache.set(obj, transfers);\n return obj;\n }\n function proxy(obj) {\n return Object.assign(obj, { [proxyMarker]: true });\n }\n function toWireValue(value) {\n for (const [name, handler] of transferHandlers) {\n if (handler.canHandle(value)) {\n const [serializedValue, transferables] = handler.serialize(value);\n return [\n {\n type: \"HANDLER\" /* WireValueType.HANDLER */,\n name,\n value: serializedValue,\n },\n transferables,\n ];\n }\n }\n return [\n {\n type: \"RAW\" /* WireValueType.RAW */,\n value,\n },\n transferCache.get(value) || [],\n ];\n }\n function fromWireValue(value) {\n switch (value.type) {\n case \"HANDLER\" /* WireValueType.HANDLER */:\n return transferHandlers.get(value.name).deserialize(value.value);\n case \"RAW\" /* WireValueType.RAW */:\n return value.value;\n }\n }\n function requestResponseMessage(ep, msg, transfers) {\n return new Promise((resolve) => {\n const id = generateUUID();\n ep.addEventListener(\"message\", function l(ev) {\n if (!ev.data || !ev.data.id || ev.data.id !== id) {\n return;\n }\n ep.removeEventListener(\"message\", l);\n resolve(ev.data);\n });\n if (ep.start) {\n ep.start();\n }\n ep.postMessage(Object.assign({ id }, msg), transfers);\n });\n }\n function generateUUID() {\n return new Array(4)\n .fill(0)\n .map(() => Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(16))\n .join(\"-\");\n }\n\n /**\n * MatrixRenderer class is meant to be used within a Web Worker context,\n * using Comlink to facilitate communication between the main thread and the worker.\n * The MatrixRenderer class manages a matrix of dies, once an instance of MatrixRenderer is created,\n * it is exposed to the main thread using Comlink's `expose` method.\n * This setup is used in the wafer-map component to perform heavy computational duties\n */\n class MatrixRenderer {\n constructor() {\n this.values = Float64Array.from([]);\n this.scaledColumnIndices = Float64Array.from([]);\n this.scaledRowIndices = Float64Array.from([]);\n this.columnIndicesPositions = Int32Array.from([]);\n this.renderConfig = {\n dieDimensions: {\n width: 0,\n height: 0\n },\n margin: {\n top: 0,\n right: 0,\n bottom: 0,\n left: 0\n },\n verticalCoefficient: 1,\n horizontalCoefficient: 1,\n horizontalConstant: 0,\n verticalConstant: 0,\n labelsFontSize: 0,\n colorScale: []\n };\n this.transformConfig = {\n transform: {\n k: 1,\n x: 0,\n y: 0\n },\n topLeftCanvasCorner: {\n x: 0,\n y: 0\n },\n bottomRightCanvasCorner: {\n x: 0,\n y: 0\n }\n };\n }\n calculateHorizontalScaledIndices(columnIndex) {\n return (this.renderConfig.horizontalCoefficient * columnIndex\n + this.renderConfig.horizontalConstant\n + this.renderConfig.margin.left);\n }\n calculateVerticalScaledIndices(rowIndex) {\n return (this.renderConfig.verticalCoefficient * rowIndex\n + this.renderConfig.verticalConstant\n + this.renderConfig.margin.top);\n }\n setColumnIndices(columnIndices) {\n if (columnIndices.length === 0 || columnIndices[0] === undefined) {\n return;\n }\n const scaledColumnIndex = [\n this.calculateHorizontalScaledIndices(columnIndices[0])\n ];\n const columnPositions = [0];\n let prev = columnIndices[0];\n for (let i = 1; i < columnIndices.length; i++) {\n const xIndex = columnIndices[i];\n if (xIndex && xIndex !== prev) {\n const scaledX = this.calculateHorizontalScaledIndices(columnIndices[i]);\n scaledColumnIndex.push(scaledX);\n columnPositions.push(i);\n prev = xIndex;\n }\n }\n this.scaledColumnIndices = Float64Array.from(scaledColumnIndex);\n this.columnIndicesPositions = Int32Array.from(columnPositions);\n }\n setRowIndices(rowIndices) {\n this.scaledRowIndices = new Float64Array(rowIndices.length);\n for (let i = 0; i < rowIndices.length; i++) {\n this.scaledRowIndices[i] = this.calculateVerticalScaledIndices(rowIndices[i]);\n }\n }\n setRenderConfig(renderConfig) {\n this.renderConfig = renderConfig;\n }\n setTransformConfig(transformData) {\n this.transformConfig = transformData;\n }\n setCanvas(canvas) {\n this.canvas = canvas;\n this.context = canvas.getContext('2d');\n }\n scaleCanvas() {\n this.context.translate(this.transformConfig.transform.x, this.transformConfig.transform.y);\n this.context.scale(this.transformConfig.transform.k, this.transformConfig.transform.k);\n }\n setCanvasDimensions(data) {\n this.canvas.width = data.width;\n this.canvas.height = data.height;\n }\n getCanvasDimensions() {\n return {\n width: this.canvas.width,\n height: this.canvas.height\n };\n }\n clearCanvas() {\n this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);\n }\n drawWafer() {\n this.context.restore();\n this.context.save();\n this.clearCanvas();\n this.scaleCanvas();\n for (let i = 0; i < this.scaledColumnIndices.length; i++) {\n const scaledX = this.scaledColumnIndices[i];\n if (!(scaledX >= this.transformConfig.topLeftCanvasCorner.x\n && scaledX < this.transformConfig.bottomRightCanvasCorner.x)) {\n continue;\n }\n // columnIndexPositions is used to get chunks to determine the start and end index of the column, it looks something like [0, 1, 4, 9, 12]\n // This means that the first column has a start index of 0 and an end index of 1, the second column has a start index of 1 and an end index of 4, and so on\n // scaledRowIndices is used when we reach the end of the columnIndexPositions, when columnIndexPositions is [0, 1, 4, 9, 12], scaledRowIndices is 13\n const columnEndIndex = this.columnIndicesPositions[i + 1] !== undefined\n ? this.columnIndicesPositions[i + 1]\n : this.scaledRowIndices.length;\n for (let columnStartIndex = this.columnIndicesPositions[i]; columnStartIndex < columnEndIndex; columnStartIndex++) {\n const scaledY = this.scaledRowIndices[columnStartIndex];\n if (!(scaledY >= this.transformConfig.topLeftCanvasCorner.y\n && scaledY < this.transformConfig.bottomRightCanvasCorner.y)) {\n continue;\n }\n // Fill style is temporary green for all dies, will be replaced with a color based on the value of the die in a future implementation\n this.context.fillStyle = 'Green';\n this.context.fillRect(scaledX, scaledY, this.renderConfig.dieDimensions.width, this.renderConfig.dieDimensions.height);\n }\n }\n }\n }\n expose(MatrixRenderer);\n\n exports.MatrixRenderer = MatrixRenderer;\n\n return exports;\n\n})({});\n";
78378
78525
 
78379
78526
  let url;
78380
78527
  /**
@@ -78404,66 +78551,45 @@ img.ProseMirror-separator {
78404
78551
  constructor(wafermap) {
78405
78552
  this.wafermap = wafermap;
78406
78553
  }
78407
- async setupWafer() {
78554
+ async setupWafer(snapshot) {
78408
78555
  if (this.matrixRenderer === undefined) {
78409
78556
  const { matrixRenderer } = await createMatrixRenderer();
78410
78557
  this.matrixRenderer = matrixRenderer;
78411
78558
  const offscreenCanvas = this.wafermap.workerCanvas.transferControlToOffscreen();
78412
78559
  await this.matrixRenderer.setCanvas(transfer(offscreenCanvas, [offscreenCanvas]));
78413
78560
  }
78414
- await this.matrixRenderer.setCanvasDimensions({
78415
- width: this.wafermap.canvasWidth ?? 0,
78416
- height: this.wafermap.canvasHeight ?? 0
78417
- });
78418
- await this.matrixRenderer.setDiesDimensions(this.wafermap.experimentalDataManager.dieDimensions);
78419
- const scaleX = this.wafermap.experimentalDataManager.horizontalScale(1)
78420
- - this.wafermap.experimentalDataManager.horizontalScale(0);
78421
- const scaleY = this.wafermap.experimentalDataManager.verticalScale(1)
78422
- - this.wafermap.experimentalDataManager.verticalScale(0);
78423
- await this.matrixRenderer.setScaling(scaleX, scaleY);
78424
- await this.matrixRenderer.setBases(this.wafermap.experimentalDataManager.horizontalScale(0), this.wafermap.experimentalDataManager.verticalScale(0));
78425
- await this.matrixRenderer.setMargin(this.wafermap.experimentalDataManager.margin);
78426
- if (this.wafermap.diesTable === undefined) {
78427
- await this.matrixRenderer.setColumnIndexes(Int32Array.from([]));
78428
- await this.matrixRenderer.setRowIndexes(Int32Array.from([]));
78429
- return;
78430
- }
78431
- const columnIndexes = this.wafermap.diesTable
78432
- .getChild('colIndex')
78433
- .toArray();
78434
- await this.matrixRenderer.setColumnIndexes(columnIndexes);
78435
- const rowIndexes = this.wafermap.diesTable
78436
- .getChild('rowIndex')
78437
- .toArray();
78438
- await this.matrixRenderer.setRowIndexes(rowIndexes);
78439
- }
78440
- async drawWafer() {
78441
- await this.matrixRenderer.setTransform(this.wafermap.transform);
78442
- const topLeftCanvasCorner = this.wafermap.transform.invert([0, 0]);
78443
- const bottomRightCanvasCorner = this.wafermap.transform.invert([
78444
- this.wafermap.canvasWidth,
78445
- this.wafermap.canvasHeight
78561
+ await this.matrixRenderer.setCanvasDimensions(snapshot.canvasDimensions);
78562
+ await this.matrixRenderer.setRenderConfig(snapshot.renderConfig);
78563
+ await this.matrixRenderer.setColumnIndices(snapshot.columnIndices);
78564
+ await this.matrixRenderer.setRowIndices(snapshot.rowIndices);
78565
+ }
78566
+ async drawWafer(snapshot) {
78567
+ const topLeftCanvasCorner = snapshot.transform.invert([0, 0]);
78568
+ const bottomRightCanvasCorner = snapshot.transform.invert([
78569
+ snapshot.canvasDimensions.width,
78570
+ snapshot.canvasDimensions.height
78446
78571
  ]);
78447
- await this.matrixRenderer.setCanvasCorners({
78448
- x: topLeftCanvasCorner[0]
78449
- - this.wafermap.experimentalDataManager.dieDimensions.width,
78450
- y: topLeftCanvasCorner[1]
78451
- - this.wafermap.experimentalDataManager.dieDimensions.height
78452
- }, {
78453
- x: bottomRightCanvasCorner[0],
78454
- y: bottomRightCanvasCorner[1]
78572
+ await this.matrixRenderer.setTransformConfig({
78573
+ transform: snapshot.transform,
78574
+ topLeftCanvasCorner: {
78575
+ x: topLeftCanvasCorner[0] - snapshot.dieDimensions.width,
78576
+ y: topLeftCanvasCorner[1] - snapshot.dieDimensions.height
78577
+ },
78578
+ bottomRightCanvasCorner: {
78579
+ x: bottomRightCanvasCorner[0],
78580
+ y: bottomRightCanvasCorner[1]
78581
+ }
78455
78582
  });
78456
78583
  await this.matrixRenderer.drawWafer();
78457
- this.renderHover();
78458
78584
  }
78459
78585
  renderHover() {
78460
- if (this.wafermap.experimentalDataManager.dieDimensions === undefined
78586
+ if (this.wafermap.computations.dieDimensions === undefined
78461
78587
  || this.wafermap.transform === undefined) {
78462
78588
  return;
78463
78589
  }
78464
- this.wafermap.hoverWidth = this.wafermap.experimentalDataManager.dieDimensions.width
78590
+ this.wafermap.hoverWidth = this.wafermap.computations.dieDimensions.width
78465
78591
  * this.wafermap.transform.k;
78466
- this.wafermap.hoverHeight = this.wafermap.experimentalDataManager.dieDimensions.height
78592
+ this.wafermap.hoverHeight = this.wafermap.computations.dieDimensions.height
78467
78593
  * this.wafermap.transform.k;
78468
78594
  this.wafermap.hoverOpacity = this.wafermap.hoverDie === undefined
78469
78595
  ? HoverDieOpacity.hide
@@ -78472,17 +78598,17 @@ img.ProseMirror-separator {
78472
78598
  }
78473
78599
  calculateHoverTransform() {
78474
78600
  if (this.wafermap.hoverDie !== undefined) {
78475
- const scaledX = this.wafermap.experimentalDataManager.horizontalScale(this.wafermap.hoverDie.x);
78601
+ const scaledX = this.wafermap.computations.horizontalScale(this.wafermap.hoverDie.x);
78476
78602
  if (scaledX === undefined) {
78477
78603
  return '';
78478
78604
  }
78479
- const scaledY = this.wafermap.experimentalDataManager.verticalScale(this.wafermap.hoverDie.y);
78605
+ const scaledY = this.wafermap.computations.verticalScale(this.wafermap.hoverDie.y);
78480
78606
  if (scaledY === undefined) {
78481
78607
  return '';
78482
78608
  }
78483
78609
  const transformedPoint = this.wafermap.transform.apply([
78484
- scaledX + this.wafermap.experimentalDataManager.margin.left,
78485
- scaledY + this.wafermap.experimentalDataManager.margin.top
78610
+ scaledX + this.wafermap.computations.margin.left,
78611
+ scaledY + this.wafermap.computations.margin.top
78486
78612
  ]);
78487
78613
  return `translate(${transformedPoint[0]}, ${transformedPoint[1]})`;
78488
78614
  }
@@ -78642,10 +78768,8 @@ img.ProseMirror-separator {
78642
78768
  ? Math.ceil
78643
78769
  : Math.floor;
78644
78770
  // go to x and y scale to get the x,y values of the die.
78645
- const x = xRoundFunction(this.wafermap.experimentalDataManager.horizontalScale.invert(mousePosition.x
78646
- - this.wafermap.experimentalDataManager.margin.left));
78647
- const y = yRoundFunction(this.wafermap.experimentalDataManager.verticalScale.invert(mousePosition.y
78648
- - this.wafermap.experimentalDataManager.margin.top));
78771
+ const x = xRoundFunction(this.wafermap.computations.horizontalScale.invert(mousePosition.x - this.wafermap.computations.margin.left));
78772
+ const y = yRoundFunction(this.wafermap.computations.verticalScale.invert(mousePosition.y - this.wafermap.computations.margin.top));
78649
78773
  return { x, y };
78650
78774
  }
78651
78775
  return undefined;
@@ -78704,6 +78828,237 @@ img.ProseMirror-separator {
78704
78828
  }
78705
78829
  }
78706
78830
 
78831
+ /**
78832
+ * Computations calculates and stores different measures which are used in the Wafermap
78833
+ */
78834
+ class Computations {
78835
+ get horizontalScale() {
78836
+ return this._horizontalScale;
78837
+ }
78838
+ get verticalScale() {
78839
+ return this._verticalScale;
78840
+ }
78841
+ get containerDimensions() {
78842
+ return this._containerDimensions;
78843
+ }
78844
+ get dieDimensions() {
78845
+ return this._dieDimensions;
78846
+ }
78847
+ get margin() {
78848
+ return this._margin;
78849
+ }
78850
+ get verticalCoefficient() {
78851
+ return this._verticalCoefficient;
78852
+ }
78853
+ get horizontalCoefficient() {
78854
+ return this._horizontalCoefficient;
78855
+ }
78856
+ get horizontalConstant() {
78857
+ return this._horizontalConstant;
78858
+ }
78859
+ get verticalConstant() {
78860
+ return this._verticalConstant;
78861
+ }
78862
+ get labelsFontSize() {
78863
+ return this._labelsFontSize;
78864
+ }
78865
+ get colorScale() {
78866
+ return this._colorScale;
78867
+ }
78868
+ constructor(wafermap) {
78869
+ this.wafermap = wafermap;
78870
+ this.baseMarginPercentage = 0.04;
78871
+ this.fontSizeFactor = 0.8;
78872
+ this.colorScaleResolution = 10;
78873
+ }
78874
+ componentResizeUpdate() {
78875
+ const canvasDimensions = {
78876
+ width: this.wafermap.canvasWidth,
78877
+ height: this.wafermap.canvasHeight
78878
+ };
78879
+ const canvasDiameter = Math.min(canvasDimensions.width, canvasDimensions.height);
78880
+ const canvasMargin = {
78881
+ top: (canvasDimensions.height - canvasDiameter) / 2,
78882
+ right: (canvasDimensions.width - canvasDiameter) / 2,
78883
+ bottom: (canvasDimensions.height - canvasDiameter) / 2,
78884
+ left: (canvasDimensions.width - canvasDiameter) / 2
78885
+ };
78886
+ const baseMargin = {
78887
+ top: canvasDiameter * this.baseMarginPercentage,
78888
+ right: canvasDiameter * this.baseMarginPercentage,
78889
+ bottom: canvasDiameter * this.baseMarginPercentage,
78890
+ left: canvasDiameter * this.baseMarginPercentage
78891
+ };
78892
+ this._margin = this.calculateMarginAddition(baseMargin, canvasMargin);
78893
+ this._containerDimensions = this.calculateContainerDimensions(canvasDimensions, this.margin);
78894
+ this.inputDataUpdate();
78895
+ }
78896
+ inputDataUpdate() {
78897
+ if (this._containerDimensions === undefined) {
78898
+ this.componentResizeUpdate();
78899
+ return;
78900
+ }
78901
+ const containerDiameter = Math.min(this._containerDimensions.width, this._containerDimensions.height);
78902
+ const gridDimensions = this.gridDimensionsValidAndDefined()
78903
+ ? this.calculateGridDimensionsFromBoundingBox()
78904
+ : this.calculateGridDimensionsFromDies();
78905
+ // this scale is used for positioning the dies on the canvas
78906
+ const originLocation = this.wafermap.originLocation;
78907
+ this._horizontalScale = this.createHorizontalScale(originLocation, gridDimensions, containerDiameter);
78908
+ // this scale is used for positioning the dies on the canvas
78909
+ this._verticalScale = this.createVerticalScale(originLocation, gridDimensions, containerDiameter);
78910
+ this._horizontalCoefficient = this._horizontalScale(1) - this._horizontalScale(0);
78911
+ this._verticalCoefficient = this._verticalScale(1) - this._verticalScale(0);
78912
+ this._horizontalConstant = this._horizontalScale(0);
78913
+ this._verticalConstant = this._verticalScale(0);
78914
+ this._dieDimensions = {
78915
+ width: Math.abs(this._horizontalScale(0) - this._horizontalScale(1)),
78916
+ height: Math.abs(this._verticalScale(0) - this._verticalScale(1))
78917
+ };
78918
+ this.colorAndTextUpdate();
78919
+ }
78920
+ colorAndTextUpdate() {
78921
+ if (this._dieDimensions === undefined) {
78922
+ this.inputDataUpdate();
78923
+ return;
78924
+ }
78925
+ this._labelsFontSize = this.calculateLabelsFontSize(this._dieDimensions, this.wafermap.maxCharacters);
78926
+ this._colorScale = this.calculateColorScale();
78927
+ }
78928
+ gridDimensionsValidAndDefined() {
78929
+ return (!this.wafermap.validity.invalidGridDimensions
78930
+ && typeof this.wafermap.gridMinX === 'number'
78931
+ && typeof this.wafermap.gridMinY === 'number'
78932
+ && typeof this.wafermap.gridMaxX === 'number'
78933
+ && typeof this.wafermap.gridMinX === 'number');
78934
+ }
78935
+ calculateGridDimensionsFromBoundingBox() {
78936
+ const gridDimensions = { origin: { x: 0, y: 0 }, rows: 0, cols: 0 };
78937
+ if (typeof this.wafermap.gridMaxY === 'number'
78938
+ && typeof this.wafermap.gridMinY === 'number'
78939
+ && typeof this.wafermap.gridMaxX === 'number'
78940
+ && typeof this.wafermap.gridMinX === 'number') {
78941
+ gridDimensions.origin.x = this.wafermap.gridMinX;
78942
+ gridDimensions.origin.y = this.wafermap.gridMinY;
78943
+ gridDimensions.rows = this.wafermap.gridMaxY - this.wafermap.gridMinY + 1;
78944
+ gridDimensions.cols = this.wafermap.gridMaxX - this.wafermap.gridMinX + 1;
78945
+ }
78946
+ return gridDimensions;
78947
+ }
78948
+ calculateGridDimensionsFromDies() {
78949
+ if (this.wafermap.diesTable === undefined) {
78950
+ return { origin: { x: 0, y: 0 }, rows: 0, cols: 0 };
78951
+ }
78952
+ const colIndex = this.wafermap.diesTable
78953
+ .getChild('colIndex')
78954
+ .toArray();
78955
+ const rowIndex = this.wafermap.diesTable
78956
+ .getChild('rowIndex')
78957
+ .toArray();
78958
+ const minPoint = { x: colIndex[0], y: rowIndex[0] };
78959
+ const maxPoint = { x: colIndex[0], y: rowIndex[0] };
78960
+ // will replace iterating with arquero after fixing issues: https://github.com/uwdata/arquero/pull/346
78961
+ for (let i = 0; i < colIndex.length; i++) {
78962
+ if (colIndex[i] < minPoint.x) {
78963
+ minPoint.x = colIndex[i];
78964
+ }
78965
+ if (colIndex[i] > maxPoint.x) {
78966
+ maxPoint.x = colIndex[i];
78967
+ }
78968
+ if (rowIndex[i] < minPoint.y) {
78969
+ minPoint.y = rowIndex[i];
78970
+ }
78971
+ if (rowIndex[i] > maxPoint.y) {
78972
+ maxPoint.y = rowIndex[i];
78973
+ }
78974
+ }
78975
+ return {
78976
+ origin: minPoint,
78977
+ rows: maxPoint.y - minPoint.y + 1,
78978
+ cols: maxPoint.x - minPoint.x + 1
78979
+ };
78980
+ }
78981
+ calculateContainerDimensions(canvasDimensions, margin) {
78982
+ return {
78983
+ width: canvasDimensions.width - margin.left - margin.right,
78984
+ height: canvasDimensions.height - margin.top - margin.bottom
78985
+ };
78986
+ }
78987
+ createHorizontalScale(originLocation, grid, containerWidth) {
78988
+ const scale = linear();
78989
+ if (originLocation === WaferMapOriginLocation.bottomLeft
78990
+ || originLocation === WaferMapOriginLocation.topLeft) {
78991
+ return scale
78992
+ .domain([grid.origin.x, grid.origin.x + grid.cols])
78993
+ .range([0, containerWidth]);
78994
+ }
78995
+ return scale
78996
+ .domain([grid.origin.x - 1, grid.origin.x + grid.cols - 1])
78997
+ .range([containerWidth, 0]);
78998
+ }
78999
+ createVerticalScale(originLocation, grid, containerHeight) {
79000
+ const scale = linear();
79001
+ // html canvas has top-left origin https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes#the_grid
79002
+ // we need to flip the vertical scale
79003
+ if (originLocation === WaferMapOriginLocation.bottomLeft
79004
+ || originLocation === WaferMapOriginLocation.bottomRight) {
79005
+ return scale
79006
+ .domain([grid.origin.y - 1, grid.origin.y + grid.rows - 1])
79007
+ .range([containerHeight, 0]);
79008
+ }
79009
+ return scale
79010
+ .domain([grid.origin.y, grid.origin.y + grid.rows])
79011
+ .range([0, containerHeight]);
79012
+ }
79013
+ calculateMarginAddition(baseMargin, addedMargin) {
79014
+ return {
79015
+ top: baseMargin.top + addedMargin.top,
79016
+ right: baseMargin.right + addedMargin.right,
79017
+ bottom: baseMargin.bottom + addedMargin.bottom,
79018
+ left: baseMargin.left + addedMargin.left
79019
+ };
79020
+ }
79021
+ calculateColorScale() {
79022
+ if (this.wafermap.colorScaleMode === WaferMapColorScaleMode.linear) {
79023
+ const values = this.wafermap.colorScale.values.map(item => +item);
79024
+ const d3ColorScale = linear()
79025
+ .domain(values)
79026
+ .range(this.wafermap.colorScale.colors);
79027
+ let min = values[0];
79028
+ let max = values[0];
79029
+ values.forEach(value => {
79030
+ if (value < min) {
79031
+ min = value;
79032
+ }
79033
+ if (value > max) {
79034
+ max = value;
79035
+ }
79036
+ });
79037
+ // the linear color scale will not be infinite but will be limited by the color scale resolution
79038
+ const valueSamples = ticks(min, max, values.length * this.colorScaleResolution);
79039
+ return valueSamples.map(value => {
79040
+ return {
79041
+ color: d3ColorScale(value),
79042
+ value
79043
+ };
79044
+ });
79045
+ }
79046
+ // ordinal color categories have to be sorted by value
79047
+ return this.wafermap.colorScale.colors
79048
+ .map((color, index) => {
79049
+ return {
79050
+ color,
79051
+ value: +this.wafermap.colorScale.values[index]
79052
+ };
79053
+ })
79054
+ .sort((a, b) => a.value - b.value);
79055
+ }
79056
+ calculateLabelsFontSize(dieDimensions, maxCharacters) {
79057
+ return Math.min(dieDimensions.height, (dieDimensions.width / (Math.max(2, maxCharacters) * 0.5))
79058
+ * this.fontSizeFactor);
79059
+ }
79060
+ }
79061
+
78707
79062
  /**
78708
79063
  * A nimble-styled WaferMap
78709
79064
  */
@@ -78725,8 +79080,8 @@ img.ProseMirror-separator {
78725
79080
  this.dieLabelsHidden = false;
78726
79081
  this.dieLabelsSuffix = '';
78727
79082
  this.colorScaleMode = WaferMapColorScaleMode.linear;
78728
- this.experimentalDataManager = new DataManager(this.asRequiredFieldsWaferMap);
78729
- this.dataManager = new DataManager$1(this.asRequiredFieldsWaferMap);
79083
+ this.computations = new Computations(this.asRequiredFieldsWaferMap);
79084
+ this.dataManager = new DataManager(this.asRequiredFieldsWaferMap);
78730
79085
  this.workerRenderer = new WorkerRenderer(this.asRequiredFieldsWaferMap);
78731
79086
  this.renderer = new RenderingModule(this.asRequiredFieldsWaferMap);
78732
79087
  /**
@@ -78795,24 +79150,22 @@ img.ProseMirror-separator {
78795
79150
  return;
78796
79151
  }
78797
79152
  if (this.waferMapUpdateTracker.requiresEventsUpdate) {
78798
- if (this.waferMapUpdateTracker.requiresContainerDimensionsUpdate
78799
- || this.waferMapUpdateTracker.requiresScalesUpdate) {
78800
- this.experimentalDataManager.updateComputations();
78801
- await this.workerRenderer.setupWafer();
78802
- await this.workerRenderer.drawWafer();
79153
+ if (this.waferMapUpdateTracker.requiresComponentResizeUpdate) {
79154
+ this.computations.componentResizeUpdate();
78803
79155
  }
78804
- else if (this.waferMapUpdateTracker.requiresLabelsFontSizeUpdate
78805
- || this.waferMapUpdateTracker.requiresDiesRenderInfoUpdate) {
78806
- this.experimentalDataManager.updatePrerendering();
78807
- await this.workerRenderer.drawWafer();
79156
+ else if (this.waferMapUpdateTracker.requiresInputDataUpdate) {
79157
+ this.computations.inputDataUpdate();
78808
79158
  }
78809
- else if (this.waferMapUpdateTracker.requiresDrawnWaferUpdate) {
78810
- await this.workerRenderer.drawWafer();
79159
+ else if (this.waferMapUpdateTracker.requiresColorAndTextUpdate) {
79160
+ this.computations.colorAndTextUpdate();
78811
79161
  }
79162
+ const snapshot = this.createSnapshot();
79163
+ if (this.waferMapUpdateTracker.requiresWorkerWaferSetup) {
79164
+ await this.workerRenderer.setupWafer(snapshot);
79165
+ }
79166
+ await this.workerRenderer.drawWafer(snapshot);
78812
79167
  }
78813
- else if (this.waferMapUpdateTracker.requiresRenderHoverUpdate) {
78814
- this.workerRenderer.renderHover();
78815
- }
79168
+ this.workerRenderer.renderHover();
78816
79169
  }
78817
79170
  /**
78818
79171
  * @internal
@@ -78859,6 +79212,44 @@ img.ProseMirror-separator {
78859
79212
  isExperimentalUpdate() {
78860
79213
  return this.diesTable !== undefined;
78861
79214
  }
79215
+ createSnapshot() {
79216
+ const canvasDimensions = {
79217
+ width: this.canvasWidth ?? 0,
79218
+ height: this.canvasHeight ?? 0
79219
+ };
79220
+ const renderConfig = {
79221
+ dieDimensions: this.computations.dieDimensions,
79222
+ margin: this.computations.margin,
79223
+ verticalCoefficient: this.computations.verticalCoefficient,
79224
+ horizontalCoefficient: this.computations.horizontalCoefficient,
79225
+ horizontalConstant: this.computations.horizontalConstant,
79226
+ verticalConstant: this.computations.verticalConstant,
79227
+ labelsFontSize: this.computations.labelsFontSize,
79228
+ colorScale: this.computations.colorScale
79229
+ };
79230
+ const dieDimensions = this.computations.dieDimensions;
79231
+ const transform = this.transform;
79232
+ if (this.diesTable === undefined) {
79233
+ return {
79234
+ canvasDimensions,
79235
+ renderConfig,
79236
+ dieDimensions,
79237
+ transform,
79238
+ columnIndices: Int32Array.from([]),
79239
+ rowIndices: Int32Array.from([])
79240
+ };
79241
+ }
79242
+ const columnIndices = this.diesTable.getChild('colIndex').toArray();
79243
+ const rowIndices = this.diesTable.getChild('rowIndex').toArray();
79244
+ return {
79245
+ canvasDimensions,
79246
+ renderConfig,
79247
+ columnIndices,
79248
+ rowIndices,
79249
+ dieDimensions,
79250
+ transform
79251
+ };
79252
+ }
78862
79253
  validate() {
78863
79254
  this.waferMapValidator.validateGridDimensions();
78864
79255
  this.waferMapValidator.validateDiesTableSchema();