@jax-data-science/sci-image-visualizer 0.16.0 → 0.18.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 (127) hide show
  1. package/esm2022/lib/contracts/display-types.mjs +4 -2
  2. package/esm2022/lib/contracts/image.contract.mjs +1 -1
  3. package/esm2022/lib/contracts/ports/spatial-data.port.mjs +1 -1
  4. package/esm2022/lib/contracts/region-editor-api.contract.mjs +1 -1
  5. package/esm2022/lib/contracts/region-store.contract.mjs +1 -1
  6. package/esm2022/lib/contracts/spatial-dataset.contract.mjs +1 -1
  7. package/esm2022/lib/contracts/visualizer.contract.mjs +1 -1
  8. package/esm2022/lib/geometry/cell-meshes.mjs +37 -0
  9. package/esm2022/lib/geometry/place.mjs +47 -0
  10. package/esm2022/lib/implementations/napari-js/napari-camera-depth.mjs +93 -0
  11. package/esm2022/lib/implementations/napari-js/napari-loading-state.mjs +1 -1
  12. package/esm2022/lib/implementations/napari-js/napari-region-overlay.mjs +2 -2
  13. package/esm2022/lib/implementations/napari-js/napari-scene.mjs +1 -1
  14. package/esm2022/lib/implementations/napari-js/napari-spatial-2d-scene.mjs +86 -18
  15. package/esm2022/lib/implementations/napari-js/napari-spatial-3d-cells.mjs +746 -0
  16. package/esm2022/lib/implementations/napari-js/napari-spatial-3d-scene.mjs +343 -18
  17. package/esm2022/lib/implementations/napari-js/napari-spatial-3d-transcripts.mjs +427 -0
  18. package/esm2022/lib/implementations/napari-js/napari-spatial-encoding.mjs +11 -4
  19. package/esm2022/lib/implementations/napari-js/napari-spatial-hover.mjs +95 -5
  20. package/esm2022/lib/implementations/napari-js/napari-spatial-scene.mjs +15 -1
  21. package/esm2022/lib/implementations/napari-js/napari-spatial-tiles.mjs +35 -8
  22. package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +40 -1
  23. package/esm2022/lib/implementations/napari-js/napari-volume-region-meshes.mjs +136 -28
  24. package/esm2022/lib/implementations/napari-js/napari-volume-scene.mjs +19 -3
  25. package/esm2022/lib/implementations/napari-js/spatial-tiles/cell-layers.mjs +188 -52
  26. package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-layers.mjs +35 -11
  27. package/esm2022/lib/implementations/osd/osd-region-overlay.mjs +2 -2
  28. package/esm2022/lib/implementations/spatial-data-http/spatial-data-http.service.mjs +10 -1
  29. package/esm2022/lib/region-editor/class-tree/class-tree.component.mjs +30 -3
  30. package/esm2022/lib/region-editor/classes-panel/classes-panel.component.mjs +15 -3
  31. package/esm2022/lib/region-editor/region-editor.component.mjs +24 -4
  32. package/esm2022/lib/region-source/region-source-ops.mjs +7 -1
  33. package/esm2022/lib/region-source/region-tiles.mjs +1 -1
  34. package/esm2022/lib/region-source/worker-region-source.mjs +24 -1
  35. package/esm2022/lib/routing-visualizer.service.mjs +404 -7
  36. package/esm2022/lib/spatial/observations-in-selection.mjs +83 -0
  37. package/esm2022/lib/spatial/plane-cells.mjs +119 -0
  38. package/esm2022/lib/spatial/spatial-controls.facade.mjs +304 -8
  39. package/esm2022/lib/spatial/spatial-encoding.mjs +52 -3
  40. package/esm2022/lib/spatial/spatial-hover.mjs +34 -1
  41. package/esm2022/lib/spatial/spatial-planes.mjs +49 -0
  42. package/esm2022/lib/spatial/spatial-selection.mjs +2 -2
  43. package/esm2022/lib/spatial/spatial-tile-merge.mjs +38 -1
  44. package/esm2022/lib/spatial/transcripts-in-selection.mjs +208 -0
  45. package/esm2022/lib/spatial-controls/spatial-cells-panel/spatial-cells-panel.component.mjs +42 -65
  46. package/esm2022/lib/spatial-controls/spatial-charts/spatial-charts.component.mjs +6 -2
  47. package/esm2022/lib/spatial-controls/spatial-color-by/spatial-color-by.component.mjs +187 -0
  48. package/esm2022/lib/spatial-controls/spatial-controls.component.mjs +51 -12
  49. package/esm2022/lib/spatial-controls/spatial-gene-style/spatial-gene-style.component.mjs +7 -3
  50. package/esm2022/lib/spatial-controls/spatial-gene-tree/spatial-gene-tree.component.mjs +21 -6
  51. package/esm2022/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.mjs +94 -13
  52. package/esm2022/lib/spatial-controls/spatial-key/spatial-key.component.mjs +3 -3
  53. package/esm2022/lib/spatial-controls/spatial-marker-genes-form/spatial-marker-genes-form.component.mjs +3 -3
  54. package/esm2022/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.mjs +79 -57
  55. package/esm2022/lib/spatial-controls/spatial-selection-observations/spatial-selection-observations.component.mjs +101 -0
  56. package/esm2022/lib/spatial-controls/spatial-selection-transcripts/spatial-selection-transcripts.component.mjs +94 -0
  57. package/esm2022/lib/spatial-controls/spatial-transcripts-panel/spatial-transcripts-panel.component.mjs +9 -3
  58. package/esm2022/lib/store/region-source-scope.mjs +10 -1
  59. package/esm2022/lib/store/region-store.service.mjs +33 -2
  60. package/esm2022/lib/toolbar/toolbar.component.mjs +10 -3
  61. package/esm2022/lib/visualizer/spatial-region-set.mjs +95 -0
  62. package/esm2022/lib/visualizer.component.mjs +40 -4
  63. package/fesm2022/{jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-CYsPzX3J.mjs → jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-CBiLcnE6.mjs} +4838 -656
  64. package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-CBiLcnE6.mjs.map +1 -0
  65. package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-DaZVXq1s.mjs → jax-data-science-sci-image-visualizer-onnx-sam-session-BXHjv4PE.mjs} +2 -2
  66. package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-DaZVXq1s.mjs.map → jax-data-science-sci-image-visualizer-onnx-sam-session-BXHjv4PE.mjs.map} +1 -1
  67. package/fesm2022/jax-data-science-sci-image-visualizer.mjs +1 -1
  68. package/fesm2022/region-source.worker.js +84 -2
  69. package/lib/contracts/display-types.d.ts +99 -6
  70. package/lib/contracts/image.contract.d.ts +6 -0
  71. package/lib/contracts/ports/spatial-data.port.d.ts +7 -0
  72. package/lib/contracts/region-editor-api.contract.d.ts +9 -0
  73. package/lib/contracts/region-store.contract.d.ts +6 -0
  74. package/lib/contracts/spatial-dataset.contract.d.ts +7 -1
  75. package/lib/contracts/visualizer.contract.d.ts +43 -1
  76. package/lib/geometry/cell-meshes.d.ts +27 -0
  77. package/lib/geometry/place.d.ts +45 -0
  78. package/lib/implementations/napari-js/napari-camera-depth.d.ts +23 -0
  79. package/lib/implementations/napari-js/napari-loading-state.d.ts +1 -1
  80. package/lib/implementations/napari-js/napari-scene.d.ts +12 -0
  81. package/lib/implementations/napari-js/napari-spatial-2d-scene.d.ts +19 -3
  82. package/lib/implementations/napari-js/napari-spatial-3d-cells.d.ts +141 -0
  83. package/lib/implementations/napari-js/napari-spatial-3d-scene.d.ts +89 -0
  84. package/lib/implementations/napari-js/napari-spatial-3d-transcripts.d.ts +103 -0
  85. package/lib/implementations/napari-js/napari-spatial-encoding.d.ts +9 -2
  86. package/lib/implementations/napari-js/napari-spatial-hover.d.ts +22 -0
  87. package/lib/implementations/napari-js/napari-spatial-scene.d.ts +12 -0
  88. package/lib/implementations/napari-js/napari-spatial-tiles.d.ts +20 -6
  89. package/lib/implementations/napari-js/napari-visualizer.service.d.ts +27 -1
  90. package/lib/implementations/napari-js/napari-volume-region-meshes.d.ts +48 -16
  91. package/lib/implementations/napari-js/napari-volume-scene.d.ts +2 -0
  92. package/lib/implementations/napari-js/spatial-tiles/cell-layers.d.ts +54 -1
  93. package/lib/implementations/napari-js/spatial-tiles/transcript-layers.d.ts +11 -2
  94. package/lib/implementations/spatial-data-http/spatial-data-http.service.d.ts +7 -0
  95. package/lib/region-editor/class-tree/class-tree.component.d.ts +16 -1
  96. package/lib/region-editor/classes-panel/classes-panel.component.d.ts +10 -1
  97. package/lib/region-editor/region-editor.component.d.ts +4 -0
  98. package/lib/region-source/region-source-ops.d.ts +12 -0
  99. package/lib/region-source/region-tiles.d.ts +8 -0
  100. package/lib/region-source/worker-region-source.d.ts +18 -0
  101. package/lib/routing-visualizer.service.d.ts +140 -1
  102. package/lib/spatial/observations-in-selection.d.ts +43 -0
  103. package/lib/spatial/plane-cells.d.ts +37 -0
  104. package/lib/spatial/spatial-controls.facade.d.ts +59 -0
  105. package/lib/spatial/spatial-encoding.d.ts +24 -1
  106. package/lib/spatial/spatial-hover.d.ts +23 -0
  107. package/lib/spatial/spatial-planes.d.ts +22 -0
  108. package/lib/spatial/spatial-selection.d.ts +2 -1
  109. package/lib/spatial/spatial-tile-merge.d.ts +9 -0
  110. package/lib/spatial/transcripts-in-selection.d.ts +95 -0
  111. package/lib/spatial-controls/spatial-cells-panel/spatial-cells-panel.component.d.ts +19 -28
  112. package/lib/spatial-controls/spatial-color-by/spatial-color-by.component.d.ts +64 -0
  113. package/lib/spatial-controls/spatial-controls.component.d.ts +19 -2
  114. package/lib/spatial-controls/spatial-gene-style/spatial-gene-style.component.d.ts +3 -1
  115. package/lib/spatial-controls/spatial-gene-tree/spatial-gene-tree.component.d.ts +7 -0
  116. package/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.d.ts +28 -7
  117. package/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.d.ts +26 -23
  118. package/lib/spatial-controls/spatial-selection-observations/spatial-selection-observations.component.d.ts +48 -0
  119. package/lib/spatial-controls/spatial-selection-transcripts/spatial-selection-transcripts.component.d.ts +43 -0
  120. package/lib/spatial-controls/spatial-transcripts-panel/spatial-transcripts-panel.component.d.ts +3 -1
  121. package/lib/store/region-source-scope.d.ts +4 -0
  122. package/lib/store/region-store.service.d.ts +21 -0
  123. package/lib/toolbar/toolbar.component.d.ts +6 -1
  124. package/lib/visualizer/spatial-region-set.d.ts +55 -0
  125. package/lib/visualizer.component.d.ts +14 -0
  126. package/package.json +2 -2
  127. package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-CYsPzX3J.mjs.map +0 -1
@@ -1,11 +1,14 @@
1
- import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, NgZone, } from '@angular/core';
1
+ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, NgZone, Output, } from '@angular/core';
2
2
  import { CommonModule } from '@angular/common';
3
3
  import { FormsModule } from '@angular/forms';
4
4
  import { SharedModule } from 'primeng/api';
5
5
  import { CheckboxModule } from 'primeng/checkbox';
6
6
  import { DropdownModule } from 'primeng/dropdown';
7
+ import { OverlayPanelModule } from 'primeng/overlaypanel';
7
8
  import { DEFAULT_SPATIAL_VIEW } from '../../contracts/display-types';
8
9
  import { cellTypeColumnFor } from '../../spatial/spatial-tiles';
10
+ import { groupColorsKey } from '../../spatial/spatial-encoding';
11
+ import { SpatialGeneStyleComponent } from '../spatial-gene-style/spatial-gene-style.component';
9
12
  import { FAMILY_PREFIX, countGroupRows, familyMembers, groupEntryFor, groupOptions, groupVariantOptions, toggleHidden, } from '../../spatial/spatial-panel-model';
10
13
  import { Supersede } from '../../util/supersede';
11
14
  import * as i0 from "@angular/core";
@@ -14,13 +17,16 @@ import * as i2 from "@angular/forms";
14
17
  import * as i3 from "primeng/api";
15
18
  import * as i4 from "primeng/checkbox";
16
19
  import * as i5 from "primeng/dropdown";
20
+ import * as i6 from "primeng/overlaypanel";
17
21
  /**
18
- * The cells' grouping, as Xenium Explorer's Groups section: the group picker (columns under
19
- * their section heading, a k-means family once, with its k beside it), CSV import of a new
20
- * grouping, and the grouping's categories with their colours, cell counts and show/hide
21
- * switches.
22
+ * The observations' grouping, as Xenium Explorer's Groups section: the group picker (columns
23
+ * under their section heading, a k-means family once, with its k beside it), CSV import of a new
24
+ * grouping, and the grouping's categories with their colours (each one's swatch opens a colour
25
+ * picker), cell counts and show/hide switches. A group's name selects its observations.
22
26
  *
23
- * Writes only through `controls.setViewState` (`cellTypeColumn`, `hiddenGroups`).
27
+ * The Observations section's "Colour by" in Group mode: the grouping colours the markers and the
28
+ * cells alike. Writes only through `controls.setViewState` (`cellTypeColumn` with `colorBy` and
29
+ * `cellColorMode`, `hiddenGroups`, `groupColors`).
24
30
  */
25
31
  export class SpatialGroupsPanelComponent {
26
32
  constructor(zone, cdr) {
@@ -32,6 +38,10 @@ export class SpatialGroupsPanelComponent {
32
38
  this.dataset = null;
33
39
  /** The current spatial view state: what is drawn, and how. */
34
40
  this.view = DEFAULT_SPATIAL_VIEW;
41
+ /** The category selected (its code in the grouping), for highlighting its row. */
42
+ this.selectedCategory = null;
43
+ /** A group's name was clicked: its category's code in the grouping, to select its observations. */
44
+ this.categoryClicked = new EventEmitter();
35
45
  /**
36
46
  * The group picker: categorical columns under their section heading, a family of
37
47
  * variants (k-means at k = 2…10) listed once. Values are a column name, or
@@ -53,6 +63,8 @@ export class SpatialGroupsPanelComponent {
53
63
  this.groupRowsLoad = new Supersede();
54
64
  this.groupImportError = null;
55
65
  this.groupImporting = false;
66
+ /** The group the open colour picker edits. */
67
+ this.styleGroup = null;
56
68
  /** {@link SpatialViewState.hiddenGroups} as a set, for the per-row checks. */
57
69
  this.hiddenGroups = new Set();
58
70
  this.trackByLabel = (_i, row) => row.label;
@@ -92,8 +104,26 @@ export class SpatialGroupsPanelComponent {
92
104
  this.onCellTypeColumn(name);
93
105
  }
94
106
  onCellTypeColumn(name) {
95
- // Switched-off groups belong to the grouping they were switched off in.
96
- this.controls?.setViewState({ cellTypeColumn: name, hiddenGroups: [] });
107
+ // Switched-off groups belong to the grouping they were switched off in. The grouping colours
108
+ // the markers (colorBy) and the cells (cellColorMode) alike.
109
+ this.controls?.setViewState({
110
+ cellTypeColumn: name,
111
+ hiddenGroups: [],
112
+ cellColorMode: 'group',
113
+ ...(name ? { colorBy: { kind: 'column', name } } : {}),
114
+ });
115
+ }
116
+ /** Group `label`'s category code in the active grouping, or -1. */
117
+ codeOf(label) {
118
+ const name = this.activeCellTypeColumn;
119
+ const meta = this.dataset?.columns.find((c) => c.name === name);
120
+ return meta?.kind === 'categorical' ? meta.categories.indexOf(label) : -1;
121
+ }
122
+ /** Select (or, selected already, clear) group `label`'s observations. */
123
+ onGroupClicked(label) {
124
+ const code = this.codeOf(label);
125
+ if (code >= 0)
126
+ this.categoryClicked.emit(code);
97
127
  }
98
128
  isGroupShown(label) {
99
129
  return !this.hiddenGroups.has(label);
@@ -107,6 +137,43 @@ export class SpatialGroupsPanelComponent {
107
137
  onAllGroupsShown(on) {
108
138
  this.controls?.setViewState({ hiddenGroups: on ? [] : this.groupRows.map((r) => r.label) });
109
139
  }
140
+ // ── per-group colour picker ──────────────────────────────────────────────
141
+ openGroupStyle(event, label, panel) {
142
+ if (this.styleGroup === label) {
143
+ panel.toggle(event);
144
+ return;
145
+ }
146
+ this.styleGroup = label;
147
+ panel.hide();
148
+ // Re-open anchored on the row that was clicked, once the panel has closed.
149
+ setTimeout(() => panel.toggle(event));
150
+ }
151
+ /** The colour group `label` is drawn in now (the user's, else the column's or the palette's). */
152
+ groupColorOf(label) {
153
+ return this.groupRows.find((r) => r.label === label)?.color ?? '#999999';
154
+ }
155
+ onGroupColor(label, hex) {
156
+ const column = this.activeCellTypeColumn;
157
+ if (!column)
158
+ return;
159
+ const all = this.view.groupColors ?? {};
160
+ this.controls?.setViewState({ groupColors: { ...all, [column]: { ...all[column], [label]: hex } } });
161
+ }
162
+ /** Back to the group's own colour (the column's, else the palette's). */
163
+ resetGroupColor(label) {
164
+ const column = this.activeCellTypeColumn;
165
+ const own = column ? this.view.groupColors?.[column] : undefined;
166
+ if (!column || !own || !(label in own))
167
+ return;
168
+ const rest = { ...own };
169
+ delete rest[label];
170
+ const all = { ...this.view.groupColors };
171
+ if (Object.keys(rest).length)
172
+ all[column] = rest;
173
+ else
174
+ delete all[column];
175
+ this.controls?.setViewState({ groupColors: all });
176
+ }
110
177
  get canImportGroups() {
111
178
  return !!this.controls?.importGroups;
112
179
  }
@@ -149,9 +216,11 @@ export class SpatialGroupsPanelComponent {
149
216
  this.groupRowsFor = null;
150
217
  return;
151
218
  }
152
- if (name === this.groupRowsFor)
219
+ // The user's colours for the grouping are part of what the rows show.
220
+ const key = `${name}\u0001${groupColorsKey(name, this.view.groupColors)}`;
221
+ if (key === this.groupRowsFor)
153
222
  return;
154
- this.groupRowsFor = name;
223
+ this.groupRowsFor = key;
155
224
  const task = this.groupRowsLoad.next();
156
225
  try {
157
226
  const v = await this.controls.categoricalView(name);
@@ -178,16 +247,28 @@ export class SpatialGroupsPanelComponent {
178
247
  });
179
248
  }
180
249
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: SpatialGroupsPanelComponent, deps: [{ token: i0.NgZone }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
181
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.9", type: SpatialGroupsPanelComponent, isStandalone: true, selector: "spatial-groups-panel", inputs: { controls: "controls", dataset: "dataset", view: "view" }, usesOnChanges: true, ngImport: i0, template: "<ng-container *ngIf=\"groupOptions.length\">\n <div class=\"sc-subhead\">Groups</div>\n <div class=\"sc-row sc-row-picker\">\n <p-dropdown\n [options]=\"groupOptions\"\n [group]=\"true\"\n optionLabel=\"label\"\n optionValue=\"value\"\n optionGroupLabel=\"label\"\n optionGroupChildren=\"items\"\n [ngModel]=\"activeGroupEntry\"\n (ngModelChange)=\"onGroupEntry($event)\"\n appendTo=\"body\"\n styleClass=\"sc-full\"\n >\n <ng-template let-group pTemplate=\"group\">\n <span class=\"sc-group-heading\">{{ group.label }}</span>\n </ng-template>\n </p-dropdown>\n <p-dropdown\n *ngIf=\"groupVariantOptions.length\"\n [options]=\"groupVariantOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n styleClass=\"sc-variant\"\n [ngModel]=\"activeCellTypeColumn\"\n (ngModelChange)=\"onGroupVariant($event)\"\n appendTo=\"body\"\n ></p-dropdown>\n <button\n *ngIf=\"canImportGroups\"\n type=\"button\"\n class=\"sc-icon-btn\"\n [disabled]=\"groupImporting\"\n (click)=\"groupFile.click()\"\n title=\"Import cell groups (CSV of cell_id, group)\"\n >\n <i\n class=\"pi\"\n [class.pi-plus-circle]=\"!groupImporting\"\n [class.pi-spin]=\"groupImporting\"\n [class.pi-spinner]=\"groupImporting\"\n ></i>\n </button>\n <input #groupFile type=\"file\" accept=\".csv,.tsv,.txt\" hidden (change)=\"onImportGroupsFile(groupFile)\" />\n </div>\n <small class=\"sc-hint sc-error\" *ngIf=\"groupImportError\">{{ groupImportError }}</small>\n\n <div class=\"sc-group-list\" *ngIf=\"groupRows.length\">\n <div class=\"sc-group-row sc-group-all\">\n <p-checkbox\n [binary]=\"true\"\n [ngModel]=\"allGroupsShown\"\n (onChange)=\"onAllGroupsShown($event.checked)\"\n ></p-checkbox>\n <span class=\"sc-group-label\">All groups</span>\n <span class=\"sc-count\">({{ groupTotal | number }})</span>\n <button type=\"button\" class=\"sc-icon-btn\" (click)=\"groupsExpanded = !groupsExpanded\">\n <i class=\"pi\" [class.pi-chevron-down]=\"groupsExpanded\" [class.pi-chevron-right]=\"!groupsExpanded\"></i>\n </button>\n </div>\n <ng-container *ngIf=\"groupsExpanded\">\n <div class=\"sc-group-row\" *ngFor=\"let row of groupRows; trackBy: trackByLabel\">\n <p-checkbox\n [binary]=\"true\"\n [ngModel]=\"isGroupShown(row.label)\"\n (onChange)=\"onGroupShown(row.label, $event.checked)\"\n ></p-checkbox>\n <span class=\"sc-dot\" [style.background]=\"row.color\"></span>\n <span class=\"sc-group-label\" [title]=\"row.label\">{{ row.label }}</span>\n <span class=\"sc-count\">({{ row.count | number }})</span>\n </div>\n </ng-container>\n </div>\n</ng-container>\n", styles: [".sc-hint{font-size:.75rem;color:var(--text-color-secondary, #6c757d)}.sc-error{color:var(--red-600, #c62828)}.sc-section{display:flex;flex-direction:column;gap:.35rem}.sc-lbl{font-size:.78rem;color:var(--text-color-secondary, #6c757d);white-space:nowrap}.sc-row{display:flex;align-items:center;gap:.6rem}.sc-row p-slider,.sc-row p-dropdown,.sc-row p-treeSelect{flex:1 1 0;min-width:0}:host ::ng-deep .sc-row p-slider .p-slider{width:100%}:host ::ng-deep .sc-row p-dropdown .p-dropdown,:host ::ng-deep .sc-row p-treeSelect .p-treeselect{width:100%}.sc-row .sc-lbl{flex:0 0 calc(50% - .6rem);min-width:0;overflow:hidden;text-overflow:ellipsis}.sc-cmap-option{display:inline-flex;align-items:center;gap:.4rem}.sc-cmap-swatch{width:3.5rem;height:.7rem;border-radius:2px;display:block}.sc-val{flex:0 0 4rem;text-align:right;font-size:.78rem;font-variant-numeric:tabular-nums;white-space:nowrap}:host ::ng-deep .sc-full,:host ::ng-deep .sc-full .p-dropdown,:host ::ng-deep .sc-full .p-autocomplete,:host ::ng-deep .sc-full input{width:100%}.sc-colorbar{height:.75rem;border-radius:2px;border:1px solid rgba(0,0,0,.2)}.sc-colorbar-ends{display:flex;justify-content:space-between;font-size:.7rem;color:var(--text-color-secondary, #6c757d);margin-top:.2rem}.sc-panel{border:1px solid var(--surface-border, #dee2e6);border-radius:6px;margin-bottom:.5rem;overflow:hidden}.sc-panel-head{display:flex;align-items:center;gap:.6rem;padding:.5rem .7rem;cursor:pointer;-webkit-user-select:none;user-select:none;background:var(--surface-100, #f5f6f7)}.sc-panel-head .sc-panel-title{flex:1;font-weight:600}.sc-panel.open>.sc-panel-head{background:var(--primary-color, #2196f3);color:var(--primary-color-text, #fff)}.sc-panel-body{display:flex;flex-direction:column;gap:.45rem;padding:.6rem .75rem .75rem}.sc-subhead{display:flex;align-items:center;gap:.5rem;margin-top:.4rem;font-size:.72rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--text-color-secondary, #6c757d)}.sc-subhead:after{content:\"\";flex:1;border-top:1px solid var(--surface-border, #dee2e6)}:host ::ng-deep .sc-buttons .p-button{padding:.35rem .75rem;font-size:.85rem}.sc-row-picker p-dropdown,.sc-row-picker p-multiSelect,.sc-row-picker p-treeSelect{flex:1 1 0;min-width:0}:host ::ng-deep .sc-row-picker .sc-variant{width:6.5rem}:host ::ng-deep .sc-row-picker p-multiselect .p-multiselect{width:100%}:host ::ng-deep .sc-row-picker p-dropdown:has(.sc-variant){flex:0 0 6.5rem}:host ::ng-deep .sc-row-picker p-treeselect:has(.sc-palette){flex:0 0 3rem}:host ::ng-deep .sc-palette .p-treeselect-label{width:0;padding:0}.sc-icon-btn{flex:0 0 auto;border:0;background:transparent;cursor:pointer;padding:.25rem .35rem;font:inherit;font-size:1.05rem;color:var(--text-color, #333);border-radius:4px}.sc-icon-btn:hover{background:var(--surface-200, #e9ecef)}.sc-icon-btn.active{color:var(--primary-color, #2196f3);font-weight:700}.sc-icon-btn:disabled{opacity:.5;cursor:default}.sc-small-btn{margin-left:auto;border:1px solid var(--surface-border, #ced4da);background:var(--surface-0, #fff);border-radius:4px;padding:.2rem .6rem;font:inherit;font-size:.8rem;cursor:pointer}:host ::ng-deep .sc-group-heading{font-size:.7rem;font-weight:700;letter-spacing:.05em;text-transform:uppercase;opacity:.7}.sc-group-list,.sc-gene-tree{max-height:16rem;overflow-y:auto;border:1px solid var(--surface-border, #dee2e6);border-radius:4px;padding:.25rem .4rem}.sc-group-row,.sc-gene-row{display:flex;align-items:center;gap:.45rem;padding:.15rem 0;font-size:.88rem}.sc-group-row .sc-group-label,.sc-gene-row .sc-group-label{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sc-group-all,.sc-gene-root,.sc-gene-group{font-weight:600}.sc-group-all .sc-icon-btn,.sc-gene-root .sc-icon-btn,.sc-gene-group .sc-icon-btn{margin-left:auto;font-size:.85rem}.sc-count{flex:0 0 auto;font-size:.78rem;color:var(--text-color-secondary, #6c757d)}.sc-glyph-option{display:inline-flex;align-items:center;gap:.4rem}.sc-glyph-svg{width:1rem;height:1rem;fill:currentColor}:host ::ng-deep .sc-glyph-pick .p-dropdown-label{padding:.2rem .4rem}.sc-color-input{width:2.5rem;height:1.8rem;border:1px solid var(--surface-border, #ced4da);border-radius:4px;padding:0;background:none}.sc-row-number p-slider,.sc-row-range p-slider{flex:1 1 0;min-width:0}:host ::ng-deep .sc-num{width:4.5rem;padding:.3rem .4rem;text-align:center}:host ::ng-deep .sc-row-number p-inputnumber,:host ::ng-deep .sc-row-range p-inputnumber{flex:0 0 auto}.sc-gene-icon{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:1.4rem;height:1.4rem;padding:0;border:1px solid transparent;border-radius:4px;background:transparent;cursor:pointer}.sc-gene-icon:hover,.sc-gene-icon:focus-visible{border-color:var(--surface-border, rgba(0, 0, 0, .2))}:host{display:contents}.sc-dot{flex:0 0 auto;width:.7rem;height:.7rem;border-radius:50%;border:1px solid rgba(0,0,0,.2)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i1.DecimalPipe, name: "number" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: SharedModule }, { kind: "directive", type: i3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: CheckboxModule }, { kind: "component", type: i4.Checkbox, selector: "p-checkbox", inputs: ["value", "name", "disabled", "binary", "label", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "style", "styleClass", "labelStyleClass", "formControl", "checkboxIcon", "readonly", "required", "autofocus", "trueValue", "falseValue", "variant"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "ngmodule", type: DropdownModule }, { kind: "component", type: i5.Dropdown, selector: "p-dropdown", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "autoShowPanelOnPrintableCharacterKeyDown", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
250
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.9", type: SpatialGroupsPanelComponent, isStandalone: true, selector: "spatial-groups-panel", inputs: { controls: "controls", dataset: "dataset", view: "view", selectedCategory: "selectedCategory" }, outputs: { categoryClicked: "categoryClicked" }, usesOnChanges: true, ngImport: i0, template: "<ng-container *ngIf=\"groupOptions.length\">\n <div class=\"sc-subhead\">Groups</div>\n <div class=\"sc-row sc-row-picker\">\n <p-dropdown\n [options]=\"groupOptions\"\n [group]=\"true\"\n optionLabel=\"label\"\n optionValue=\"value\"\n optionGroupLabel=\"label\"\n optionGroupChildren=\"items\"\n [ngModel]=\"activeGroupEntry\"\n (ngModelChange)=\"onGroupEntry($event)\"\n appendTo=\"body\"\n styleClass=\"sc-full\"\n >\n <ng-template let-group pTemplate=\"group\">\n <span class=\"sc-group-heading\">{{ group.label }}</span>\n </ng-template>\n </p-dropdown>\n <p-dropdown\n *ngIf=\"groupVariantOptions.length\"\n [options]=\"groupVariantOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n styleClass=\"sc-variant\"\n [ngModel]=\"activeCellTypeColumn\"\n (ngModelChange)=\"onGroupVariant($event)\"\n appendTo=\"body\"\n ></p-dropdown>\n <button\n *ngIf=\"canImportGroups\"\n type=\"button\"\n class=\"sc-icon-btn\"\n [disabled]=\"groupImporting\"\n (click)=\"groupFile.click()\"\n title=\"Import cell groups (CSV of cell_id, group)\"\n >\n <i\n class=\"pi\"\n [class.pi-plus-circle]=\"!groupImporting\"\n [class.pi-spin]=\"groupImporting\"\n [class.pi-spinner]=\"groupImporting\"\n ></i>\n </button>\n <input #groupFile type=\"file\" accept=\".csv,.tsv,.txt\" hidden (change)=\"onImportGroupsFile(groupFile)\" />\n </div>\n <small class=\"sc-hint sc-error\" *ngIf=\"groupImportError\">{{ groupImportError }}</small>\n\n <div class=\"sc-group-list\" *ngIf=\"groupRows.length\">\n <div class=\"sc-group-row sc-group-all\">\n <p-checkbox\n [binary]=\"true\"\n [ngModel]=\"allGroupsShown\"\n (onChange)=\"onAllGroupsShown($event.checked)\"\n ></p-checkbox>\n <span class=\"sc-group-label\">All groups</span>\n <span class=\"sc-count\">({{ groupTotal | number }})</span>\n <button type=\"button\" class=\"sc-icon-btn\" (click)=\"groupsExpanded = !groupsExpanded\">\n <i class=\"pi\" [class.pi-chevron-down]=\"groupsExpanded\" [class.pi-chevron-right]=\"!groupsExpanded\"></i>\n </button>\n </div>\n <ng-container *ngIf=\"groupsExpanded\">\n <div class=\"sc-group-row\" *ngFor=\"let row of groupRows; trackBy: trackByLabel\">\n <p-checkbox\n [binary]=\"true\"\n [ngModel]=\"isGroupShown(row.label)\"\n (onChange)=\"onGroupShown(row.label, $event.checked)\"\n ></p-checkbox>\n <!-- The group's colour; clicking it opens the colour picker. -->\n <button\n type=\"button\"\n class=\"sc-dot sc-dot-btn\"\n [style.background]=\"row.color\"\n [attr.aria-label]=\"'Colour for ' + row.label\"\n title=\"Colour\"\n (click)=\"openGroupStyle($event, row.label, groupPop)\"\n ></button>\n <!-- The name selects the group's observations; again, clears. -->\n <button\n type=\"button\"\n class=\"sc-group-label sc-group-select\"\n [class.selected]=\"selectedCategory !== null && selectedCategory === codeOf(row.label)\"\n [title]=\"'Select ' + row.label\"\n (click)=\"onGroupClicked(row.label)\"\n >\n {{ row.label }}\n </button>\n <span class=\"sc-count\">({{ row.count | number }})</span>\n </div>\n </ng-container>\n </div>\n <!-- One picker for every group row, filled for the group that opened it. -->\n <p-overlayPanel #groupPop styleClass=\"sc-gene-style\" appendTo=\"body\">\n <ng-template pTemplate=\"content\">\n <spatial-gene-style\n *ngIf=\"styleGroup as group\"\n [gene]=\"group\"\n what=\"Group\"\n [color]=\"groupColorOf(group)\"\n [showIcons]=\"false\"\n (colorChange)=\"onGroupColor(group, $event)\"\n (resetStyle)=\"resetGroupColor(group)\"\n ></spatial-gene-style>\n </ng-template>\n </p-overlayPanel>\n</ng-container>\n", styles: [".sc-hint{font-size:.75rem;color:var(--text-color-secondary, #6c757d)}.sc-error{color:var(--red-600, #c62828)}.sc-section{display:flex;flex-direction:column;gap:.35rem}.sc-lbl{font-size:.78rem;color:var(--text-color-secondary, #6c757d);white-space:nowrap}.sc-row{display:flex;align-items:center;gap:.6rem}.sc-row p-slider,.sc-row p-dropdown,.sc-row p-treeSelect{flex:1 1 0;min-width:0}:host ::ng-deep .sc-row p-slider .p-slider{width:100%}:host ::ng-deep .sc-row p-dropdown .p-dropdown,:host ::ng-deep .sc-row p-treeSelect .p-treeselect{width:100%}.sc-row .sc-lbl{flex:0 0 calc(50% - .6rem);min-width:0;overflow:hidden;text-overflow:ellipsis}.sc-cmap-option{display:inline-flex;align-items:center;gap:.4rem}.sc-cmap-swatch{width:3.5rem;height:.7rem;border-radius:2px;display:block}.sc-val{flex:0 0 4rem;text-align:right;font-size:.78rem;font-variant-numeric:tabular-nums;white-space:nowrap}:host ::ng-deep .sc-full,:host ::ng-deep .sc-full .p-dropdown,:host ::ng-deep .sc-full .p-autocomplete,:host ::ng-deep .sc-full input{width:100%}.sc-colorbar{height:.75rem;border-radius:2px;border:1px solid rgba(0,0,0,.2)}.sc-colorbar-ends{display:flex;justify-content:space-between;font-size:.7rem;color:var(--text-color-secondary, #6c757d);margin-top:.2rem}.sc-panel{border:1px solid var(--surface-border, #dee2e6);border-radius:6px;margin-bottom:.5rem;overflow:hidden}.sc-panel-head{display:flex;align-items:center;gap:.6rem;padding:.5rem .7rem;cursor:pointer;-webkit-user-select:none;user-select:none;background:var(--surface-100, #f5f6f7)}.sc-panel-head .sc-panel-title{flex:1;font-weight:600}.sc-panel.open>.sc-panel-head{background:var(--primary-color, #2196f3);color:var(--primary-color-text, #fff)}.sc-panel-body{display:flex;flex-direction:column;gap:.45rem;padding:.6rem .75rem .75rem}.sc-subhead{display:flex;align-items:center;gap:.5rem;margin-top:.4rem;font-size:.72rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--text-color-secondary, #6c757d)}.sc-subhead:after{content:\"\";flex:1;border-top:1px solid var(--surface-border, #dee2e6)}.sc-subsection{display:flex;flex-direction:column;gap:.45rem}.sc-subsection-head{cursor:pointer;-webkit-user-select:none;user-select:none}.sc-subsection-head i{font-size:.65rem}.sc-subsection-head:hover .sc-subsection-title{color:var(--primary-color, #3b82f6)}.sc-subsection-body{display:flex;flex-direction:column;gap:.45rem;padding-left:.6rem;border-left:2px solid var(--surface-border, #dee2e6)}:host ::ng-deep .sc-buttons .p-button{padding:.35rem .75rem;font-size:.85rem}.sc-row-picker p-dropdown,.sc-row-picker p-multiSelect,.sc-row-picker p-treeSelect{flex:1 1 0;min-width:0}:host ::ng-deep .sc-row-picker .sc-variant{width:6.5rem}:host ::ng-deep .sc-row-picker p-multiselect .p-multiselect{width:100%}:host ::ng-deep .sc-row-picker p-dropdown:has(.sc-variant){flex:0 0 6.5rem}:host ::ng-deep .sc-row-picker p-treeselect:has(.sc-palette){flex:0 0 3rem}:host ::ng-deep .sc-palette .p-treeselect-label{width:0;padding:0}.sc-icon-btn{flex:0 0 auto;border:0;background:transparent;cursor:pointer;padding:.25rem .35rem;font:inherit;font-size:1.05rem;color:var(--text-color, #333);border-radius:4px}.sc-icon-btn:hover{background:var(--surface-200, #e9ecef)}.sc-icon-btn.active{color:var(--primary-color, #2196f3);font-weight:700}.sc-icon-btn:disabled{opacity:.5;cursor:default}.sc-small-btn{margin-left:auto;border:1px solid var(--surface-border, #ced4da);background:var(--surface-0, #fff);border-radius:4px;padding:.2rem .6rem;font:inherit;font-size:.8rem;cursor:pointer}:host ::ng-deep .sc-group-heading{font-size:.7rem;font-weight:700;letter-spacing:.05em;text-transform:uppercase;opacity:.7}.sc-group-list,.sc-gene-tree{max-height:16rem;overflow-y:auto;border:1px solid var(--surface-border, #dee2e6);border-radius:4px;padding:.25rem .4rem}.sc-group-row,.sc-gene-row{display:flex;align-items:center;gap:.45rem;padding:.15rem 0;font-size:.88rem}.sc-group-row .sc-group-label,.sc-gene-row .sc-group-label{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sc-group-all,.sc-gene-root,.sc-gene-group{font-weight:600}.sc-group-all .sc-icon-btn,.sc-gene-root .sc-icon-btn,.sc-gene-group .sc-icon-btn{margin-left:auto;font-size:.85rem}.sc-count{flex:0 0 auto;font-size:.78rem;color:var(--text-color-secondary, #6c757d)}.sc-glyph-option{display:inline-flex;align-items:center;gap:.4rem}.sc-glyph-svg{width:1rem;height:1rem;fill:currentColor}:host ::ng-deep .sc-glyph-pick .p-dropdown-label{padding:.2rem .4rem}.sc-color-input{width:2.5rem;height:1.8rem;border:1px solid var(--surface-border, #ced4da);border-radius:4px;padding:0;background:none}.sc-row-number p-slider,.sc-row-range p-slider{flex:1 1 0;min-width:0}:host ::ng-deep .sc-num{width:4.5rem;padding:.3rem .4rem;text-align:center}:host ::ng-deep .sc-row-number p-inputnumber,:host ::ng-deep .sc-row-range p-inputnumber{flex:0 0 auto}.sc-gene-icon{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:1.4rem;height:1.4rem;padding:0;border:1px solid transparent;border-radius:4px;background:transparent;cursor:pointer}.sc-gene-icon:hover,.sc-gene-icon:focus-visible{border-color:var(--surface-border, rgba(0, 0, 0, .2))}.sc-seltx-toggle{width:100%;padding:0;background:none;border:0;cursor:pointer;font-family:inherit;text-align:left}.sc-seltx-toggle i{font-size:.65rem}.sc-seltx-toggle:hover{color:var(--primary-color, #3b82f6)}.sc-seltx{display:flex;flex-direction:column;gap:.35rem}.sc-seltx-head{display:flex;align-items:baseline;gap:.5rem;min-width:0}.sc-seltx-label{font-size:.82rem;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sc-seltx-summary{display:flex;align-items:center;justify-content:space-between;font-size:.78rem}.sc-seltx-list{list-style:none;margin:0;padding:0;max-height:16rem;overflow-y:auto;font-size:.78rem}.sc-seltx-list.stale{opacity:.55}.sc-seltx-list li{display:grid;grid-template-columns:minmax(4rem,7rem) 1fr auto;align-items:center;gap:.5rem;padding:.1rem 0}.sc-seltx-gene{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sc-seltx-bar{height:.45rem;border-radius:2px;background:var(--surface-200, #e9ecef);overflow:hidden}.sc-seltx-bar span{display:block;height:100%;background:var(--primary-color, #3b82f6)}.sc-seltx-count{font-variant-numeric:tabular-nums;text-align:right;min-width:3rem}.sc-seltx-swatch{display:inline-block;width:.6rem;height:.6rem;margin-right:.35rem;border-radius:2px;vertical-align:baseline}.sc-seltx-measures{display:grid;grid-template-columns:minmax(4rem,1fr) auto;gap:.1rem .75rem;margin:0;font-size:.78rem}.sc-seltx-measures dt{color:var(--text-color-secondary, #6c757d);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sc-seltx-measures dd{margin:0;text-align:right;font-variant-numeric:tabular-nums}:host{display:contents}.sc-dot{flex:0 0 auto;width:.7rem;height:.7rem;border-radius:50%;border:1px solid rgba(0,0,0,.2)}.sc-dot-btn{padding:0;cursor:pointer}.sc-dot-btn:hover,.sc-dot-btn:focus-visible{outline:2px solid var(--surface-border, rgba(0, 0, 0, .35));outline-offset:1px}.sc-group-select{padding:0 .2rem;border:0;border-radius:3px;background:none;color:inherit;font:inherit;text-align:left;cursor:pointer}.sc-group-select:hover{background:var(--surface-hover, rgba(0, 0, 0, .05))}.sc-group-select.selected{background:var(--highlight-bg, rgba(33, 150, 243, .15));font-weight:600}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i1.DecimalPipe, name: "number" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: SharedModule }, { kind: "directive", type: i3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: CheckboxModule }, { kind: "component", type: i4.Checkbox, selector: "p-checkbox", inputs: ["value", "name", "disabled", "binary", "label", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "style", "styleClass", "labelStyleClass", "formControl", "checkboxIcon", "readonly", "required", "autofocus", "trueValue", "falseValue", "variant"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "ngmodule", type: DropdownModule }, { kind: "component", type: i5.Dropdown, selector: "p-dropdown", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "autoShowPanelOnPrintableCharacterKeyDown", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: OverlayPanelModule }, { kind: "component", type: i6.OverlayPanel, selector: "p-overlayPanel", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "showCloseIcon", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions"], outputs: ["onShow", "onHide"] }, { kind: "component", type: SpatialGeneStyleComponent, selector: "spatial-gene-style", inputs: ["gene", "what", "color", "glyph", "iconHint", "showIcons"], outputs: ["colorChange", "glyphChange", "resetStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
182
251
  }
183
252
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: SpatialGroupsPanelComponent, decorators: [{
184
253
  type: Component,
185
- args: [{ selector: 'spatial-groups-panel', standalone: true, imports: [CommonModule, FormsModule, SharedModule, CheckboxModule, DropdownModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *ngIf=\"groupOptions.length\">\n <div class=\"sc-subhead\">Groups</div>\n <div class=\"sc-row sc-row-picker\">\n <p-dropdown\n [options]=\"groupOptions\"\n [group]=\"true\"\n optionLabel=\"label\"\n optionValue=\"value\"\n optionGroupLabel=\"label\"\n optionGroupChildren=\"items\"\n [ngModel]=\"activeGroupEntry\"\n (ngModelChange)=\"onGroupEntry($event)\"\n appendTo=\"body\"\n styleClass=\"sc-full\"\n >\n <ng-template let-group pTemplate=\"group\">\n <span class=\"sc-group-heading\">{{ group.label }}</span>\n </ng-template>\n </p-dropdown>\n <p-dropdown\n *ngIf=\"groupVariantOptions.length\"\n [options]=\"groupVariantOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n styleClass=\"sc-variant\"\n [ngModel]=\"activeCellTypeColumn\"\n (ngModelChange)=\"onGroupVariant($event)\"\n appendTo=\"body\"\n ></p-dropdown>\n <button\n *ngIf=\"canImportGroups\"\n type=\"button\"\n class=\"sc-icon-btn\"\n [disabled]=\"groupImporting\"\n (click)=\"groupFile.click()\"\n title=\"Import cell groups (CSV of cell_id, group)\"\n >\n <i\n class=\"pi\"\n [class.pi-plus-circle]=\"!groupImporting\"\n [class.pi-spin]=\"groupImporting\"\n [class.pi-spinner]=\"groupImporting\"\n ></i>\n </button>\n <input #groupFile type=\"file\" accept=\".csv,.tsv,.txt\" hidden (change)=\"onImportGroupsFile(groupFile)\" />\n </div>\n <small class=\"sc-hint sc-error\" *ngIf=\"groupImportError\">{{ groupImportError }}</small>\n\n <div class=\"sc-group-list\" *ngIf=\"groupRows.length\">\n <div class=\"sc-group-row sc-group-all\">\n <p-checkbox\n [binary]=\"true\"\n [ngModel]=\"allGroupsShown\"\n (onChange)=\"onAllGroupsShown($event.checked)\"\n ></p-checkbox>\n <span class=\"sc-group-label\">All groups</span>\n <span class=\"sc-count\">({{ groupTotal | number }})</span>\n <button type=\"button\" class=\"sc-icon-btn\" (click)=\"groupsExpanded = !groupsExpanded\">\n <i class=\"pi\" [class.pi-chevron-down]=\"groupsExpanded\" [class.pi-chevron-right]=\"!groupsExpanded\"></i>\n </button>\n </div>\n <ng-container *ngIf=\"groupsExpanded\">\n <div class=\"sc-group-row\" *ngFor=\"let row of groupRows; trackBy: trackByLabel\">\n <p-checkbox\n [binary]=\"true\"\n [ngModel]=\"isGroupShown(row.label)\"\n (onChange)=\"onGroupShown(row.label, $event.checked)\"\n ></p-checkbox>\n <span class=\"sc-dot\" [style.background]=\"row.color\"></span>\n <span class=\"sc-group-label\" [title]=\"row.label\">{{ row.label }}</span>\n <span class=\"sc-count\">({{ row.count | number }})</span>\n </div>\n </ng-container>\n </div>\n</ng-container>\n", styles: [".sc-hint{font-size:.75rem;color:var(--text-color-secondary, #6c757d)}.sc-error{color:var(--red-600, #c62828)}.sc-section{display:flex;flex-direction:column;gap:.35rem}.sc-lbl{font-size:.78rem;color:var(--text-color-secondary, #6c757d);white-space:nowrap}.sc-row{display:flex;align-items:center;gap:.6rem}.sc-row p-slider,.sc-row p-dropdown,.sc-row p-treeSelect{flex:1 1 0;min-width:0}:host ::ng-deep .sc-row p-slider .p-slider{width:100%}:host ::ng-deep .sc-row p-dropdown .p-dropdown,:host ::ng-deep .sc-row p-treeSelect .p-treeselect{width:100%}.sc-row .sc-lbl{flex:0 0 calc(50% - .6rem);min-width:0;overflow:hidden;text-overflow:ellipsis}.sc-cmap-option{display:inline-flex;align-items:center;gap:.4rem}.sc-cmap-swatch{width:3.5rem;height:.7rem;border-radius:2px;display:block}.sc-val{flex:0 0 4rem;text-align:right;font-size:.78rem;font-variant-numeric:tabular-nums;white-space:nowrap}:host ::ng-deep .sc-full,:host ::ng-deep .sc-full .p-dropdown,:host ::ng-deep .sc-full .p-autocomplete,:host ::ng-deep .sc-full input{width:100%}.sc-colorbar{height:.75rem;border-radius:2px;border:1px solid rgba(0,0,0,.2)}.sc-colorbar-ends{display:flex;justify-content:space-between;font-size:.7rem;color:var(--text-color-secondary, #6c757d);margin-top:.2rem}.sc-panel{border:1px solid var(--surface-border, #dee2e6);border-radius:6px;margin-bottom:.5rem;overflow:hidden}.sc-panel-head{display:flex;align-items:center;gap:.6rem;padding:.5rem .7rem;cursor:pointer;-webkit-user-select:none;user-select:none;background:var(--surface-100, #f5f6f7)}.sc-panel-head .sc-panel-title{flex:1;font-weight:600}.sc-panel.open>.sc-panel-head{background:var(--primary-color, #2196f3);color:var(--primary-color-text, #fff)}.sc-panel-body{display:flex;flex-direction:column;gap:.45rem;padding:.6rem .75rem .75rem}.sc-subhead{display:flex;align-items:center;gap:.5rem;margin-top:.4rem;font-size:.72rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--text-color-secondary, #6c757d)}.sc-subhead:after{content:\"\";flex:1;border-top:1px solid var(--surface-border, #dee2e6)}:host ::ng-deep .sc-buttons .p-button{padding:.35rem .75rem;font-size:.85rem}.sc-row-picker p-dropdown,.sc-row-picker p-multiSelect,.sc-row-picker p-treeSelect{flex:1 1 0;min-width:0}:host ::ng-deep .sc-row-picker .sc-variant{width:6.5rem}:host ::ng-deep .sc-row-picker p-multiselect .p-multiselect{width:100%}:host ::ng-deep .sc-row-picker p-dropdown:has(.sc-variant){flex:0 0 6.5rem}:host ::ng-deep .sc-row-picker p-treeselect:has(.sc-palette){flex:0 0 3rem}:host ::ng-deep .sc-palette .p-treeselect-label{width:0;padding:0}.sc-icon-btn{flex:0 0 auto;border:0;background:transparent;cursor:pointer;padding:.25rem .35rem;font:inherit;font-size:1.05rem;color:var(--text-color, #333);border-radius:4px}.sc-icon-btn:hover{background:var(--surface-200, #e9ecef)}.sc-icon-btn.active{color:var(--primary-color, #2196f3);font-weight:700}.sc-icon-btn:disabled{opacity:.5;cursor:default}.sc-small-btn{margin-left:auto;border:1px solid var(--surface-border, #ced4da);background:var(--surface-0, #fff);border-radius:4px;padding:.2rem .6rem;font:inherit;font-size:.8rem;cursor:pointer}:host ::ng-deep .sc-group-heading{font-size:.7rem;font-weight:700;letter-spacing:.05em;text-transform:uppercase;opacity:.7}.sc-group-list,.sc-gene-tree{max-height:16rem;overflow-y:auto;border:1px solid var(--surface-border, #dee2e6);border-radius:4px;padding:.25rem .4rem}.sc-group-row,.sc-gene-row{display:flex;align-items:center;gap:.45rem;padding:.15rem 0;font-size:.88rem}.sc-group-row .sc-group-label,.sc-gene-row .sc-group-label{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sc-group-all,.sc-gene-root,.sc-gene-group{font-weight:600}.sc-group-all .sc-icon-btn,.sc-gene-root .sc-icon-btn,.sc-gene-group .sc-icon-btn{margin-left:auto;font-size:.85rem}.sc-count{flex:0 0 auto;font-size:.78rem;color:var(--text-color-secondary, #6c757d)}.sc-glyph-option{display:inline-flex;align-items:center;gap:.4rem}.sc-glyph-svg{width:1rem;height:1rem;fill:currentColor}:host ::ng-deep .sc-glyph-pick .p-dropdown-label{padding:.2rem .4rem}.sc-color-input{width:2.5rem;height:1.8rem;border:1px solid var(--surface-border, #ced4da);border-radius:4px;padding:0;background:none}.sc-row-number p-slider,.sc-row-range p-slider{flex:1 1 0;min-width:0}:host ::ng-deep .sc-num{width:4.5rem;padding:.3rem .4rem;text-align:center}:host ::ng-deep .sc-row-number p-inputnumber,:host ::ng-deep .sc-row-range p-inputnumber{flex:0 0 auto}.sc-gene-icon{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:1.4rem;height:1.4rem;padding:0;border:1px solid transparent;border-radius:4px;background:transparent;cursor:pointer}.sc-gene-icon:hover,.sc-gene-icon:focus-visible{border-color:var(--surface-border, rgba(0, 0, 0, .2))}:host{display:contents}.sc-dot{flex:0 0 auto;width:.7rem;height:.7rem;border-radius:50%;border:1px solid rgba(0,0,0,.2)}\n"] }]
254
+ args: [{ selector: 'spatial-groups-panel', standalone: true, imports: [
255
+ CommonModule,
256
+ FormsModule,
257
+ SharedModule,
258
+ CheckboxModule,
259
+ DropdownModule,
260
+ OverlayPanelModule,
261
+ SpatialGeneStyleComponent,
262
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *ngIf=\"groupOptions.length\">\n <div class=\"sc-subhead\">Groups</div>\n <div class=\"sc-row sc-row-picker\">\n <p-dropdown\n [options]=\"groupOptions\"\n [group]=\"true\"\n optionLabel=\"label\"\n optionValue=\"value\"\n optionGroupLabel=\"label\"\n optionGroupChildren=\"items\"\n [ngModel]=\"activeGroupEntry\"\n (ngModelChange)=\"onGroupEntry($event)\"\n appendTo=\"body\"\n styleClass=\"sc-full\"\n >\n <ng-template let-group pTemplate=\"group\">\n <span class=\"sc-group-heading\">{{ group.label }}</span>\n </ng-template>\n </p-dropdown>\n <p-dropdown\n *ngIf=\"groupVariantOptions.length\"\n [options]=\"groupVariantOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n styleClass=\"sc-variant\"\n [ngModel]=\"activeCellTypeColumn\"\n (ngModelChange)=\"onGroupVariant($event)\"\n appendTo=\"body\"\n ></p-dropdown>\n <button\n *ngIf=\"canImportGroups\"\n type=\"button\"\n class=\"sc-icon-btn\"\n [disabled]=\"groupImporting\"\n (click)=\"groupFile.click()\"\n title=\"Import cell groups (CSV of cell_id, group)\"\n >\n <i\n class=\"pi\"\n [class.pi-plus-circle]=\"!groupImporting\"\n [class.pi-spin]=\"groupImporting\"\n [class.pi-spinner]=\"groupImporting\"\n ></i>\n </button>\n <input #groupFile type=\"file\" accept=\".csv,.tsv,.txt\" hidden (change)=\"onImportGroupsFile(groupFile)\" />\n </div>\n <small class=\"sc-hint sc-error\" *ngIf=\"groupImportError\">{{ groupImportError }}</small>\n\n <div class=\"sc-group-list\" *ngIf=\"groupRows.length\">\n <div class=\"sc-group-row sc-group-all\">\n <p-checkbox\n [binary]=\"true\"\n [ngModel]=\"allGroupsShown\"\n (onChange)=\"onAllGroupsShown($event.checked)\"\n ></p-checkbox>\n <span class=\"sc-group-label\">All groups</span>\n <span class=\"sc-count\">({{ groupTotal | number }})</span>\n <button type=\"button\" class=\"sc-icon-btn\" (click)=\"groupsExpanded = !groupsExpanded\">\n <i class=\"pi\" [class.pi-chevron-down]=\"groupsExpanded\" [class.pi-chevron-right]=\"!groupsExpanded\"></i>\n </button>\n </div>\n <ng-container *ngIf=\"groupsExpanded\">\n <div class=\"sc-group-row\" *ngFor=\"let row of groupRows; trackBy: trackByLabel\">\n <p-checkbox\n [binary]=\"true\"\n [ngModel]=\"isGroupShown(row.label)\"\n (onChange)=\"onGroupShown(row.label, $event.checked)\"\n ></p-checkbox>\n <!-- The group's colour; clicking it opens the colour picker. -->\n <button\n type=\"button\"\n class=\"sc-dot sc-dot-btn\"\n [style.background]=\"row.color\"\n [attr.aria-label]=\"'Colour for ' + row.label\"\n title=\"Colour\"\n (click)=\"openGroupStyle($event, row.label, groupPop)\"\n ></button>\n <!-- The name selects the group's observations; again, clears. -->\n <button\n type=\"button\"\n class=\"sc-group-label sc-group-select\"\n [class.selected]=\"selectedCategory !== null && selectedCategory === codeOf(row.label)\"\n [title]=\"'Select ' + row.label\"\n (click)=\"onGroupClicked(row.label)\"\n >\n {{ row.label }}\n </button>\n <span class=\"sc-count\">({{ row.count | number }})</span>\n </div>\n </ng-container>\n </div>\n <!-- One picker for every group row, filled for the group that opened it. -->\n <p-overlayPanel #groupPop styleClass=\"sc-gene-style\" appendTo=\"body\">\n <ng-template pTemplate=\"content\">\n <spatial-gene-style\n *ngIf=\"styleGroup as group\"\n [gene]=\"group\"\n what=\"Group\"\n [color]=\"groupColorOf(group)\"\n [showIcons]=\"false\"\n (colorChange)=\"onGroupColor(group, $event)\"\n (resetStyle)=\"resetGroupColor(group)\"\n ></spatial-gene-style>\n </ng-template>\n </p-overlayPanel>\n</ng-container>\n", styles: [".sc-hint{font-size:.75rem;color:var(--text-color-secondary, #6c757d)}.sc-error{color:var(--red-600, #c62828)}.sc-section{display:flex;flex-direction:column;gap:.35rem}.sc-lbl{font-size:.78rem;color:var(--text-color-secondary, #6c757d);white-space:nowrap}.sc-row{display:flex;align-items:center;gap:.6rem}.sc-row p-slider,.sc-row p-dropdown,.sc-row p-treeSelect{flex:1 1 0;min-width:0}:host ::ng-deep .sc-row p-slider .p-slider{width:100%}:host ::ng-deep .sc-row p-dropdown .p-dropdown,:host ::ng-deep .sc-row p-treeSelect .p-treeselect{width:100%}.sc-row .sc-lbl{flex:0 0 calc(50% - .6rem);min-width:0;overflow:hidden;text-overflow:ellipsis}.sc-cmap-option{display:inline-flex;align-items:center;gap:.4rem}.sc-cmap-swatch{width:3.5rem;height:.7rem;border-radius:2px;display:block}.sc-val{flex:0 0 4rem;text-align:right;font-size:.78rem;font-variant-numeric:tabular-nums;white-space:nowrap}:host ::ng-deep .sc-full,:host ::ng-deep .sc-full .p-dropdown,:host ::ng-deep .sc-full .p-autocomplete,:host ::ng-deep .sc-full input{width:100%}.sc-colorbar{height:.75rem;border-radius:2px;border:1px solid rgba(0,0,0,.2)}.sc-colorbar-ends{display:flex;justify-content:space-between;font-size:.7rem;color:var(--text-color-secondary, #6c757d);margin-top:.2rem}.sc-panel{border:1px solid var(--surface-border, #dee2e6);border-radius:6px;margin-bottom:.5rem;overflow:hidden}.sc-panel-head{display:flex;align-items:center;gap:.6rem;padding:.5rem .7rem;cursor:pointer;-webkit-user-select:none;user-select:none;background:var(--surface-100, #f5f6f7)}.sc-panel-head .sc-panel-title{flex:1;font-weight:600}.sc-panel.open>.sc-panel-head{background:var(--primary-color, #2196f3);color:var(--primary-color-text, #fff)}.sc-panel-body{display:flex;flex-direction:column;gap:.45rem;padding:.6rem .75rem .75rem}.sc-subhead{display:flex;align-items:center;gap:.5rem;margin-top:.4rem;font-size:.72rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--text-color-secondary, #6c757d)}.sc-subhead:after{content:\"\";flex:1;border-top:1px solid var(--surface-border, #dee2e6)}.sc-subsection{display:flex;flex-direction:column;gap:.45rem}.sc-subsection-head{cursor:pointer;-webkit-user-select:none;user-select:none}.sc-subsection-head i{font-size:.65rem}.sc-subsection-head:hover .sc-subsection-title{color:var(--primary-color, #3b82f6)}.sc-subsection-body{display:flex;flex-direction:column;gap:.45rem;padding-left:.6rem;border-left:2px solid var(--surface-border, #dee2e6)}:host ::ng-deep .sc-buttons .p-button{padding:.35rem .75rem;font-size:.85rem}.sc-row-picker p-dropdown,.sc-row-picker p-multiSelect,.sc-row-picker p-treeSelect{flex:1 1 0;min-width:0}:host ::ng-deep .sc-row-picker .sc-variant{width:6.5rem}:host ::ng-deep .sc-row-picker p-multiselect .p-multiselect{width:100%}:host ::ng-deep .sc-row-picker p-dropdown:has(.sc-variant){flex:0 0 6.5rem}:host ::ng-deep .sc-row-picker p-treeselect:has(.sc-palette){flex:0 0 3rem}:host ::ng-deep .sc-palette .p-treeselect-label{width:0;padding:0}.sc-icon-btn{flex:0 0 auto;border:0;background:transparent;cursor:pointer;padding:.25rem .35rem;font:inherit;font-size:1.05rem;color:var(--text-color, #333);border-radius:4px}.sc-icon-btn:hover{background:var(--surface-200, #e9ecef)}.sc-icon-btn.active{color:var(--primary-color, #2196f3);font-weight:700}.sc-icon-btn:disabled{opacity:.5;cursor:default}.sc-small-btn{margin-left:auto;border:1px solid var(--surface-border, #ced4da);background:var(--surface-0, #fff);border-radius:4px;padding:.2rem .6rem;font:inherit;font-size:.8rem;cursor:pointer}:host ::ng-deep .sc-group-heading{font-size:.7rem;font-weight:700;letter-spacing:.05em;text-transform:uppercase;opacity:.7}.sc-group-list,.sc-gene-tree{max-height:16rem;overflow-y:auto;border:1px solid var(--surface-border, #dee2e6);border-radius:4px;padding:.25rem .4rem}.sc-group-row,.sc-gene-row{display:flex;align-items:center;gap:.45rem;padding:.15rem 0;font-size:.88rem}.sc-group-row .sc-group-label,.sc-gene-row .sc-group-label{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sc-group-all,.sc-gene-root,.sc-gene-group{font-weight:600}.sc-group-all .sc-icon-btn,.sc-gene-root .sc-icon-btn,.sc-gene-group .sc-icon-btn{margin-left:auto;font-size:.85rem}.sc-count{flex:0 0 auto;font-size:.78rem;color:var(--text-color-secondary, #6c757d)}.sc-glyph-option{display:inline-flex;align-items:center;gap:.4rem}.sc-glyph-svg{width:1rem;height:1rem;fill:currentColor}:host ::ng-deep .sc-glyph-pick .p-dropdown-label{padding:.2rem .4rem}.sc-color-input{width:2.5rem;height:1.8rem;border:1px solid var(--surface-border, #ced4da);border-radius:4px;padding:0;background:none}.sc-row-number p-slider,.sc-row-range p-slider{flex:1 1 0;min-width:0}:host ::ng-deep .sc-num{width:4.5rem;padding:.3rem .4rem;text-align:center}:host ::ng-deep .sc-row-number p-inputnumber,:host ::ng-deep .sc-row-range p-inputnumber{flex:0 0 auto}.sc-gene-icon{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:1.4rem;height:1.4rem;padding:0;border:1px solid transparent;border-radius:4px;background:transparent;cursor:pointer}.sc-gene-icon:hover,.sc-gene-icon:focus-visible{border-color:var(--surface-border, rgba(0, 0, 0, .2))}.sc-seltx-toggle{width:100%;padding:0;background:none;border:0;cursor:pointer;font-family:inherit;text-align:left}.sc-seltx-toggle i{font-size:.65rem}.sc-seltx-toggle:hover{color:var(--primary-color, #3b82f6)}.sc-seltx{display:flex;flex-direction:column;gap:.35rem}.sc-seltx-head{display:flex;align-items:baseline;gap:.5rem;min-width:0}.sc-seltx-label{font-size:.82rem;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sc-seltx-summary{display:flex;align-items:center;justify-content:space-between;font-size:.78rem}.sc-seltx-list{list-style:none;margin:0;padding:0;max-height:16rem;overflow-y:auto;font-size:.78rem}.sc-seltx-list.stale{opacity:.55}.sc-seltx-list li{display:grid;grid-template-columns:minmax(4rem,7rem) 1fr auto;align-items:center;gap:.5rem;padding:.1rem 0}.sc-seltx-gene{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sc-seltx-bar{height:.45rem;border-radius:2px;background:var(--surface-200, #e9ecef);overflow:hidden}.sc-seltx-bar span{display:block;height:100%;background:var(--primary-color, #3b82f6)}.sc-seltx-count{font-variant-numeric:tabular-nums;text-align:right;min-width:3rem}.sc-seltx-swatch{display:inline-block;width:.6rem;height:.6rem;margin-right:.35rem;border-radius:2px;vertical-align:baseline}.sc-seltx-measures{display:grid;grid-template-columns:minmax(4rem,1fr) auto;gap:.1rem .75rem;margin:0;font-size:.78rem}.sc-seltx-measures dt{color:var(--text-color-secondary, #6c757d);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sc-seltx-measures dd{margin:0;text-align:right;font-variant-numeric:tabular-nums}:host{display:contents}.sc-dot{flex:0 0 auto;width:.7rem;height:.7rem;border-radius:50%;border:1px solid rgba(0,0,0,.2)}.sc-dot-btn{padding:0;cursor:pointer}.sc-dot-btn:hover,.sc-dot-btn:focus-visible{outline:2px solid var(--surface-border, rgba(0, 0, 0, .35));outline-offset:1px}.sc-group-select{padding:0 .2rem;border:0;border-radius:3px;background:none;color:inherit;font:inherit;text-align:left;cursor:pointer}.sc-group-select:hover{background:var(--surface-hover, rgba(0, 0, 0, .05))}.sc-group-select.selected{background:var(--highlight-bg, rgba(33, 150, 243, .15));font-weight:600}\n"] }]
186
263
  }], ctorParameters: () => [{ type: i0.NgZone }, { type: i0.ChangeDetectorRef }], propDecorators: { controls: [{
187
264
  type: Input
188
265
  }], dataset: [{
189
266
  type: Input
190
267
  }], view: [{
191
268
  type: Input
269
+ }], selectedCategory: [{
270
+ type: Input
271
+ }], categoryClicked: [{
272
+ type: Output
192
273
  }] } });
193
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BhdGlhbC1ncm91cHMtcGFuZWwuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9zcGF0aWFsLWNvbnRyb2xzL3NwYXRpYWwtZ3JvdXBzLXBhbmVsL3NwYXRpYWwtZ3JvdXBzLXBhbmVsLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3NyYy9saWIvc3BhdGlhbC1jb250cm9scy9zcGF0aWFsLWdyb3Vwcy1wYW5lbC9zcGF0aWFsLWdyb3Vwcy1wYW5lbC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsS0FBSyxFQUNMLE1BQU0sR0FHUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzdDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDM0MsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUlsRCxPQUFPLEVBQUUsb0JBQW9CLEVBQW9CLE1BQU0sK0JBQStCLENBQUM7QUFDdkYsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDaEUsT0FBTyxFQUNMLGFBQWEsRUFJYixjQUFjLEVBQ2QsYUFBYSxFQUNiLGFBQWEsRUFDYixZQUFZLEVBQ1osbUJBQW1CLEVBQ25CLFlBQVksR0FDYixNQUFNLG1DQUFtQyxDQUFDO0FBQzNDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQzs7Ozs7OztBQUVqRDs7Ozs7OztHQU9HO0FBU0gsTUFBTSxPQUFPLDJCQUEyQjtJQStCdEMsWUFDbUIsSUFBWSxFQUNaLEdBQXNCO1FBRHRCLFNBQUksR0FBSixJQUFJLENBQVE7UUFDWixRQUFHLEdBQUgsR0FBRyxDQUFtQjtRQWhDekMsb0dBQW9HO1FBQzNGLGFBQVEsR0FBNEIsSUFBSSxDQUFDO1FBQ2xELHFDQUFxQztRQUM1QixZQUFPLEdBQTBCLElBQUksQ0FBQztRQUMvQyw4REFBOEQ7UUFDckQsU0FBSSxHQUFxQixvQkFBb0IsQ0FBQztRQUV2RDs7OztXQUlHO1FBQ08saUJBQVksR0FBeUIsRUFBRSxDQUFDO1FBQ2xELHlFQUF5RTtRQUMvRCx3QkFBbUIsR0FBMEIsRUFBRSxDQUFDO1FBQzFELDhFQUE4RTtRQUM3RCxpQkFBWSxHQUFHLElBQUksR0FBRyxFQUFrQixDQUFDO1FBRTFELG9GQUFvRjtRQUMxRSxjQUFTLEdBQWUsRUFBRSxDQUFDO1FBQzNCLGVBQVUsR0FBRyxDQUFDLENBQUM7UUFDZixtQkFBYyxHQUFHLElBQUksQ0FBQztRQUNoQywrRkFBK0Y7UUFDdkYsaUJBQVksR0FBa0IsSUFBSSxDQUFDO1FBQzNDOzRGQUNvRjtRQUNuRSxrQkFBYSxHQUFHLElBQUksU0FBUyxFQUFFLENBQUM7UUFDdkMscUJBQWdCLEdBQWtCLElBQUksQ0FBQztRQUN2QyxtQkFBYyxHQUFHLEtBQUssQ0FBQztRQWdEakMsOEVBQThFO1FBQ3RFLGlCQUFZLEdBQUcsSUFBSSxHQUFHLEVBQVUsQ0FBQztRQTRDL0IsaUJBQVksR0FBRyxDQUFDLEVBQVUsRUFBRSxHQUFzQixFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDO0lBeEZ4RSxDQUFDO0lBRUosV0FBVyxDQUFDLE9BQXNCO1FBQ2hDLElBQUksT0FBTyxDQUFDLE1BQU0sQ0FBQztZQUFFLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUN6RSxJQUFJLE9BQU8sQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1lBQ3ZCLElBQUksQ0FBQyxZQUFZLEdBQUcsWUFBWSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUMvQyw2REFBNkQ7WUFDN0QsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7UUFDM0IsQ0FBQztRQUNELEtBQUssSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO0lBQzVCLENBQUM7SUFFRCx1REFBdUQ7SUFDdkQsSUFBYyxvQkFBb0I7UUFDaEMsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO0lBQzFFLENBQUM7SUFFRCxzREFBc0Q7SUFDdEQsSUFBYyxnQkFBZ0I7UUFDNUIsT0FBTyxhQUFhLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsb0JBQW9CLENBQUMsQ0FBQztJQUNoRSxDQUFDO0lBRVMsWUFBWSxDQUFDLEtBQWE7UUFDbEMsSUFBSSxLQUFLLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxFQUFFLENBQUM7WUFDcEMsTUFBTSxFQUFFLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDN0MsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksYUFBYSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDO1lBQ25GLElBQUksSUFBSTtnQkFBRSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDdEMsT0FBTztRQUNULENBQUM7UUFDRCxJQUFJLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDL0IsQ0FBQztJQUVTLGNBQWMsQ0FBQyxJQUFZO1FBQ25DLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxJQUFJLENBQUMsQ0FBQztRQUNoRSxJQUFJLElBQUksRUFBRSxJQUFJLEtBQUssYUFBYSxJQUFJLElBQUksQ0FBQyxNQUFNO1lBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDN0YsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzlCLENBQUM7SUFFRCxnQkFBZ0IsQ0FBQyxJQUFtQjtRQUNsQyx3RUFBd0U7UUFDeEUsSUFBSSxDQUFDLFFBQVEsRUFBRSxZQUFZLENBQUMsRUFBRSxjQUFjLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQzFFLENBQUM7SUFLUyxZQUFZLENBQUMsS0FBYTtRQUNsQyxPQUFPLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUVELElBQWMsY0FBYztRQUMxQixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQUM7SUFDN0MsQ0FBQztJQUVTLFlBQVksQ0FBQyxLQUFhLEVBQUUsRUFBVztRQUMvQyxJQUFJLENBQUMsUUFBUSxFQUFFLFlBQVksQ0FBQyxFQUFFLFlBQVksRUFBRSxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQyxLQUFLLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDbkcsQ0FBQztJQUVTLGdCQUFnQixDQUFDLEVBQVc7UUFDcEMsSUFBSSxDQUFDLFFBQVEsRUFBRSxZQUFZLENBQUMsRUFBRSxZQUFZLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQzlGLENBQUM7SUFFRCxJQUFjLGVBQWU7UUFDM0IsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxZQUFZLENBQUM7SUFDdkMsQ0FBQztJQUVELG1FQUFtRTtJQUN6RCxLQUFLLENBQUMsa0JBQWtCLENBQUMsS0FBdUI7UUFDeEQsTUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzlCLEtBQUssQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDO1FBQ2pCLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLFlBQVk7WUFBRSxPQUFPO1FBQ2xELElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUM7UUFDN0IsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUM7UUFDM0IsSUFBSSxDQUFDO1lBQ0gsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsbUJBQW1CLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDekQsTUFBTSxFQUFFLE1BQU0sRUFBRSxHQUFHLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLE1BQU0sSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7WUFDOUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDdkQsQ0FBQztRQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7WUFDYixJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRTtnQkFDZCxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsTUFBTSxDQUFFLEdBQWEsRUFBRSxPQUFPLElBQUksR0FBRyxDQUFDLENBQUM7WUFDakUsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDO2dCQUFTLENBQUM7WUFDVCxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRTtnQkFDZCxJQUFJLENBQUMsY0FBYyxHQUFHLEtBQUssQ0FBQztZQUM5QixDQUFDLENBQUMsQ0FBQztRQUNMLENBQUM7SUFDSCxDQUFDO0lBSU8sZUFBZTtRQUNyQixNQUFNLElBQUksR0FBRyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1FBQzFFLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsS0FBSyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQztZQUFFLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxJQUFJLENBQUM7SUFDekcsQ0FBQztJQUVPLEtBQUssQ0FBQyxhQUFhO1FBQ3pCLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUN2QixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUM7UUFDdkMsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUM1QixJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQzVCLElBQUksQ0FBQyxTQUFTLEdBQUcsRUFBRSxDQUFDO1lBQ3BCLElBQUksQ0FBQyxVQUFVLEdBQUcsQ0FBQyxDQUFDO1lBQ3BCLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDO1lBQ3pCLE9BQU87UUFDVCxDQUFDO1FBQ0QsSUFBSSxJQUFJLEtBQUssSUFBSSxDQUFDLFlBQVk7WUFBRSxPQUFPO1FBQ3ZDLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDO1FBQ3pCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDdkMsSUFBSSxDQUFDO1lBQ0gsTUFBTSxDQUFDLEdBQUcsTUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNwRCxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRTtnQkFBRSxPQUFPO1lBQzlCLE1BQU0sRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLEdBQUcsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzFDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFO2dCQUNkLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDO2dCQUN0QixJQUFJLENBQUMsVUFBVSxHQUFHLEtBQUssQ0FBQztZQUMxQixDQUFDLENBQUMsQ0FBQztRQUNMLENBQUM7UUFBQyxNQUFNLENBQUM7WUFDUCxpRkFBaUY7WUFDakYsZ0VBQWdFO1lBQ2hFLElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRTtnQkFBRSxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztRQUNqRCxDQUFDO0lBQ0gsQ0FBQztJQUVELDZFQUE2RTtJQUNyRSxLQUFLLENBQUMsRUFBYztRQUMxQixJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUU7WUFDakIsRUFBRSxFQUFFLENBQUM7WUFDTCxJQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQzFCLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQzs4R0FuS1UsMkJBQTJCO2tHQUEzQiwyQkFBMkIseUtDakR4Qyx3MEZBMkVBLDAzSkQvQlksWUFBWSx1VEFBRSxXQUFXLDhWQUFFLFlBQVkscUlBQUUsY0FBYyxnWkFBRSxjQUFjOzsyRkFLdEUsMkJBQTJCO2tCQVJ2QyxTQUFTOytCQUNFLHNCQUFzQixjQUNwQixJQUFJLFdBQ1AsQ0FBQyxZQUFZLEVBQUUsV0FBVyxFQUFFLFlBQVksRUFBRSxjQUFjLEVBQUUsY0FBYyxDQUFDLG1CQUdqRSx1QkFBdUIsQ0FBQyxNQUFNOzJHQUl0QyxRQUFRO3NCQUFoQixLQUFLO2dCQUVHLE9BQU87c0JBQWYsS0FBSztnQkFFRyxJQUFJO3NCQUFaLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgSW5wdXQsXG4gIE5nWm9uZSxcbiAgT25DaGFuZ2VzLFxuICBTaW1wbGVDaGFuZ2VzLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBGb3Jtc01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IFNoYXJlZE1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvYXBpJztcbmltcG9ydCB7IENoZWNrYm94TW9kdWxlIH0gZnJvbSAncHJpbWVuZy9jaGVja2JveCc7XG5pbXBvcnQgeyBEcm9wZG93bk1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvZHJvcGRvd24nO1xuXG5pbXBvcnQgdHlwZSB7IElTcGF0aWFsQ29udHJvbHMgfSBmcm9tICcuLi8uLi9jb250cmFjdHMvdmlzdWFsaXplci5jb250cmFjdCc7XG5pbXBvcnQgdHlwZSB7IFNwYXRpYWxEYXRhc2V0IH0gZnJvbSAnLi4vLi4vY29udHJhY3RzL3NwYXRpYWwtZGF0YXNldC5jb250cmFjdCc7XG5pbXBvcnQgeyBERUZBVUxUX1NQQVRJQUxfVklFVywgU3BhdGlhbFZpZXdTdGF0ZSB9IGZyb20gJy4uLy4uL2NvbnRyYWN0cy9kaXNwbGF5LXR5cGVzJztcbmltcG9ydCB7IGNlbGxUeXBlQ29sdW1uRm9yIH0gZnJvbSAnLi4vLi4vc3BhdGlhbC9zcGF0aWFsLXRpbGVzJztcbmltcG9ydCB7XG4gIEZBTUlMWV9QUkVGSVgsXG4gIEdyb3VwT3B0aW9uU2VjdGlvbixcbiAgR3JvdXBSb3csXG4gIFBhbmVsT3B0aW9uLFxuICBjb3VudEdyb3VwUm93cyxcbiAgZmFtaWx5TWVtYmVycyxcbiAgZ3JvdXBFbnRyeUZvcixcbiAgZ3JvdXBPcHRpb25zLFxuICBncm91cFZhcmlhbnRPcHRpb25zLFxuICB0b2dnbGVIaWRkZW4sXG59IGZyb20gJy4uLy4uL3NwYXRpYWwvc3BhdGlhbC1wYW5lbC1tb2RlbCc7XG5pbXBvcnQgeyBTdXBlcnNlZGUgfSBmcm9tICcuLi8uLi91dGlsL3N1cGVyc2VkZSc7XG5cbi8qKlxuICogVGhlIGNlbGxzJyBncm91cGluZywgYXMgWGVuaXVtIEV4cGxvcmVyJ3MgR3JvdXBzIHNlY3Rpb246IHRoZSBncm91cCBwaWNrZXIgKGNvbHVtbnMgdW5kZXJcbiAqIHRoZWlyIHNlY3Rpb24gaGVhZGluZywgYSBrLW1lYW5zIGZhbWlseSBvbmNlLCB3aXRoIGl0cyBrIGJlc2lkZSBpdCksIENTViBpbXBvcnQgb2YgYSBuZXdcbiAqIGdyb3VwaW5nLCBhbmQgdGhlIGdyb3VwaW5nJ3MgY2F0ZWdvcmllcyB3aXRoIHRoZWlyIGNvbG91cnMsIGNlbGwgY291bnRzIGFuZCBzaG93L2hpZGVcbiAqIHN3aXRjaGVzLlxuICpcbiAqIFdyaXRlcyBvbmx5IHRocm91Z2ggYGNvbnRyb2xzLnNldFZpZXdTdGF0ZWAgKGBjZWxsVHlwZUNvbHVtbmAsIGBoaWRkZW5Hcm91cHNgKS5cbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnc3BhdGlhbC1ncm91cHMtcGFuZWwnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlLCBGb3Jtc01vZHVsZSwgU2hhcmVkTW9kdWxlLCBDaGVja2JveE1vZHVsZSwgRHJvcGRvd25Nb2R1bGVdLFxuICB0ZW1wbGF0ZVVybDogJy4vc3BhdGlhbC1ncm91cHMtcGFuZWwuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9zcGF0aWFsLWdyb3Vwcy1wYW5lbC5jb21wb25lbnQuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgU3BhdGlhbEdyb3Vwc1BhbmVsQ29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzIHtcbiAgLyoqIFRoZSBzcGF0aWFsIGNvbnRyb2xzIHRoaXMgcGFuZWwgcmVhZHMgYW5kIHdyaXRlcyB0aHJvdWdoOyBudWxsIHdpdGhvdXQgYSBgU1BBVElBTF9EQVRBX1BPUlRgLiAqL1xuICBASW5wdXQoKSBjb250cm9sczogSVNwYXRpYWxDb250cm9scyB8IG51bGwgPSBudWxsO1xuICAvKiogVGhlIGRhdGFzZXQgb24gb2ZmZXIsIG9yIG51bGwuICovXG4gIEBJbnB1dCgpIGRhdGFzZXQ6IFNwYXRpYWxEYXRhc2V0IHwgbnVsbCA9IG51bGw7XG4gIC8qKiBUaGUgY3VycmVudCBzcGF0aWFsIHZpZXcgc3RhdGU6IHdoYXQgaXMgZHJhd24sIGFuZCBob3cuICovXG4gIEBJbnB1dCgpIHZpZXc6IFNwYXRpYWxWaWV3U3RhdGUgPSBERUZBVUxUX1NQQVRJQUxfVklFVztcblxuICAvKipcbiAgICogVGhlIGdyb3VwIHBpY2tlcjogY2F0ZWdvcmljYWwgY29sdW1ucyB1bmRlciB0aGVpciBzZWN0aW9uIGhlYWRpbmcsIGEgZmFtaWx5IG9mXG4gICAqIHZhcmlhbnRzIChrLW1lYW5zIGF0IGsgPSAy4oCmMTApIGxpc3RlZCBvbmNlLiBWYWx1ZXMgYXJlIGEgY29sdW1uIG5hbWUsIG9yXG4gICAqIGBmYW1pbHk6PGlkPmAgZm9yIGEgZmFtaWx5LlxuICAgKi9cbiAgcHJvdGVjdGVkIGdyb3VwT3B0aW9uczogR3JvdXBPcHRpb25TZWN0aW9uW10gPSBbXTtcbiAgLyoqIFZhcmlhbnRzIG9mIHRoZSBhY3RpdmUgZmFtaWx5IChrID0gMuKApjEwKSwgd2hlbiBhIGZhbWlseSBpcyBhY3RpdmUuICovXG4gIHByb3RlY3RlZCBncm91cFZhcmlhbnRPcHRpb25zOiBQYW5lbE9wdGlvbjxzdHJpbmc+W10gPSBbXTtcbiAgLyoqIFRoZSBsYXN0IHZhcmlhbnQgY2hvc2VuIHBlciBmYW1pbHksIHNvIHN3aXRjaGluZyBhd2F5IGFuZCBiYWNrIGtlZXBzIGsuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgZmFtaWx5Q2hvaWNlID0gbmV3IE1hcDxzdHJpbmcsIHN0cmluZz4oKTtcblxuICAvKiogVGhlIGFjdGl2ZSBncm91cGluZydzIGNhdGVnb3JpZXMgd2l0aCBjb2xvdXJzIGFuZCBjZWxsIGNvdW50cywgbGFyZ2VzdCBmaXJzdC4gKi9cbiAgcHJvdGVjdGVkIGdyb3VwUm93czogR3JvdXBSb3dbXSA9IFtdO1xuICBwcm90ZWN0ZWQgZ3JvdXBUb3RhbCA9IDA7XG4gIHByb3RlY3RlZCBncm91cHNFeHBhbmRlZCA9IHRydWU7XG4gIC8qKiBUaGUgZ3JvdXBpbmcge0BsaW5rIGdyb3VwUm93c30gc2hvd3Mgb3IgaXMgbG9hZGluZyDigJQgYSByZXBlYXQgcmVxdWVzdCBmb3IgaXQgaXMgYSBuby1vcC4gKi9cbiAgcHJpdmF0ZSBncm91cFJvd3NGb3I6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICAvKiogTGF0ZXN0IHdpbnMgYW1vbmcgZ3JvdXAtcm93IGxvYWRzLCBzbyBhIHNsb3cgb25lIGZvciBhbiBlYXJsaWVyIGdyb3VwaW5nIChvciB0aGVcbiAgICogIHByZXZpb3VzIGRhdGFzZXQncyBjb2x1bW4gb2YgdGhlIHNhbWUgbmFtZSkgY2Fubm90IGxhbmQgb3ZlciB0aGUgY3VycmVudCBvbmUuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgZ3JvdXBSb3dzTG9hZCA9IG5ldyBTdXBlcnNlZGUoKTtcbiAgcHJvdGVjdGVkIGdyb3VwSW1wb3J0RXJyb3I6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICBwcm90ZWN0ZWQgZ3JvdXBJbXBvcnRpbmcgPSBmYWxzZTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IHpvbmU6IE5nWm9uZSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICkge31cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgaWYgKGNoYW5nZXNbJ3ZpZXcnXSkgdGhpcy5oaWRkZW5Hcm91cHMgPSBuZXcgU2V0KHRoaXMudmlldy5oaWRkZW5Hcm91cHMpO1xuICAgIGlmIChjaGFuZ2VzWydkYXRhc2V0J10pIHtcbiAgICAgIHRoaXMuZ3JvdXBPcHRpb25zID0gZ3JvdXBPcHRpb25zKHRoaXMuZGF0YXNldCk7XG4gICAgICAvLyBBIHNhbWUtbmFtZWQgZ3JvdXBpbmcgb2YgYSBuZXcgZGF0YXNldCBpcyBub3QgdGhlIG9sZCBvbmUuXG4gICAgICB0aGlzLmdyb3VwUm93c0ZvciA9IG51bGw7XG4gICAgfVxuICAgIHZvaWQgdGhpcy5yZWZyZXNoR3JvdXBzKCk7XG4gIH1cblxuICAvKiogVGhlIGNhdGVnb3JpY2FsIGNvbHVtbiB0aGUgY2VsbHMgYXJlIGdyb3VwZWQgYnkuICovXG4gIHByb3RlY3RlZCBnZXQgYWN0aXZlQ2VsbFR5cGVDb2x1bW4oKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuZGF0YXNldCA/IGNlbGxUeXBlQ29sdW1uRm9yKHRoaXMuZGF0YXNldCwgdGhpcy52aWV3KSA6IG51bGw7XG4gIH1cblxuICAvKiogVGhlIHBpY2tlcidzIHZhbHVlIGZvciB0aGUgYWN0aXZlIGdyb3VwIGNvbHVtbi4gKi9cbiAgcHJvdGVjdGVkIGdldCBhY3RpdmVHcm91cEVudHJ5KCk6IHN0cmluZyB8IG51bGwge1xuICAgIHJldHVybiBncm91cEVudHJ5Rm9yKHRoaXMuZGF0YXNldCwgdGhpcy5hY3RpdmVDZWxsVHlwZUNvbHVtbik7XG4gIH1cblxuICBwcm90ZWN0ZWQgb25Hcm91cEVudHJ5KHZhbHVlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAodmFsdWUuc3RhcnRzV2l0aChGQU1JTFlfUFJFRklYKSkge1xuICAgICAgY29uc3QgaWQgPSB2YWx1ZS5zbGljZShGQU1JTFlfUFJFRklYLmxlbmd0aCk7XG4gICAgICBjb25zdCBuYW1lID0gdGhpcy5mYW1pbHlDaG9pY2UuZ2V0KGlkKSA/PyBmYW1pbHlNZW1iZXJzKHRoaXMuZGF0YXNldCwgaWQpWzBdPy5uYW1lO1xuICAgICAgaWYgKG5hbWUpIHRoaXMub25DZWxsVHlwZUNvbHVtbihuYW1lKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5vbkNlbGxUeXBlQ29sdW1uKHZhbHVlKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvbkdyb3VwVmFyaWFudChuYW1lOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBtZXRhID0gdGhpcy5kYXRhc2V0Py5jb2x1bW5zLmZpbmQoKGMpID0+IGMubmFtZSA9PT0gbmFtZSk7XG4gICAgaWYgKG1ldGE/LmtpbmQgPT09ICdjYXRlZ29yaWNhbCcgJiYgbWV0YS5mYW1pbHkpIHRoaXMuZmFtaWx5Q2hvaWNlLnNldChtZXRhLmZhbWlseS5pZCwgbmFtZSk7XG4gICAgdGhpcy5vbkNlbGxUeXBlQ29sdW1uKG5hbWUpO1xuICB9XG5cbiAgb25DZWxsVHlwZUNvbHVtbihuYW1lOiBzdHJpbmcgfCBudWxsKTogdm9pZCB7XG4gICAgLy8gU3dpdGNoZWQtb2ZmIGdyb3VwcyBiZWxvbmcgdG8gdGhlIGdyb3VwaW5nIHRoZXkgd2VyZSBzd2l0Y2hlZCBvZmYgaW4uXG4gICAgdGhpcy5jb250cm9scz8uc2V0Vmlld1N0YXRlKHsgY2VsbFR5cGVDb2x1bW46IG5hbWUsIGhpZGRlbkdyb3VwczogW10gfSk7XG4gIH1cblxuICAvKioge0BsaW5rIFNwYXRpYWxWaWV3U3RhdGUuaGlkZGVuR3JvdXBzfSBhcyBhIHNldCwgZm9yIHRoZSBwZXItcm93IGNoZWNrcy4gKi9cbiAgcHJpdmF0ZSBoaWRkZW5Hcm91cHMgPSBuZXcgU2V0PHN0cmluZz4oKTtcblxuICBwcm90ZWN0ZWQgaXNHcm91cFNob3duKGxhYmVsOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gIXRoaXMuaGlkZGVuR3JvdXBzLmhhcyhsYWJlbCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0IGFsbEdyb3Vwc1Nob3duKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnZpZXcuaGlkZGVuR3JvdXBzLmxlbmd0aCA9PT0gMDtcbiAgfVxuXG4gIHByb3RlY3RlZCBvbkdyb3VwU2hvd24obGFiZWw6IHN0cmluZywgb246IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLmNvbnRyb2xzPy5zZXRWaWV3U3RhdGUoeyBoaWRkZW5Hcm91cHM6IHRvZ2dsZUhpZGRlbih0aGlzLnZpZXcuaGlkZGVuR3JvdXBzLCBbbGFiZWxdLCBvbikgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgb25BbGxHcm91cHNTaG93bihvbjogYm9vbGVhbik6IHZvaWQge1xuICAgIHRoaXMuY29udHJvbHM/LnNldFZpZXdTdGF0ZSh7IGhpZGRlbkdyb3Vwczogb24gPyBbXSA6IHRoaXMuZ3JvdXBSb3dzLm1hcCgocikgPT4gci5sYWJlbCkgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0IGNhbkltcG9ydEdyb3VwcygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISF0aGlzLmNvbnRyb2xzPy5pbXBvcnRHcm91cHM7XG4gIH1cblxuICAvKiogJysnOiBhIENTVi9UU1Ygb2YgYGNlbGxfaWRgIGFuZCBncm91cCwgbmFtZWQgYWZ0ZXIgdGhlIGZpbGUuICovXG4gIHByb3RlY3RlZCBhc3luYyBvbkltcG9ydEdyb3Vwc0ZpbGUoaW5wdXQ6IEhUTUxJbnB1dEVsZW1lbnQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBmaWxlID0gaW5wdXQuZmlsZXM/LlswXTtcbiAgICBpbnB1dC52YWx1ZSA9ICcnO1xuICAgIGlmICghZmlsZSB8fCAhdGhpcy5jb250cm9scz8uaW1wb3J0R3JvdXBzKSByZXR1cm47XG4gICAgdGhpcy5ncm91cEltcG9ydEVycm9yID0gbnVsbDtcbiAgICB0aGlzLmdyb3VwSW1wb3J0aW5nID0gdHJ1ZTtcbiAgICB0cnkge1xuICAgICAgY29uc3QgbGFiZWwgPSBmaWxlLm5hbWUucmVwbGFjZSgvXFwuKGNzdnx0c3Z8dHh0KSQvaSwgJycpO1xuICAgICAgY29uc3QgeyBjb2x1bW4gfSA9IGF3YWl0IHRoaXMuY29udHJvbHMuaW1wb3J0R3JvdXBzKGxhYmVsLCBhd2FpdCBmaWxlLnRleHQoKSk7XG4gICAgICB0aGlzLmFwcGx5KCgpID0+IHRoaXMub25DZWxsVHlwZUNvbHVtbihjb2x1bW4ubmFtZSkpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgdGhpcy5hcHBseSgoKSA9PiB7XG4gICAgICAgIHRoaXMuZ3JvdXBJbXBvcnRFcnJvciA9IFN0cmluZygoZXJyIGFzIEVycm9yKT8ubWVzc2FnZSA/PyBlcnIpO1xuICAgICAgfSk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRoaXMuYXBwbHkoKCkgPT4ge1xuICAgICAgICB0aGlzLmdyb3VwSW1wb3J0aW5nID0gZmFsc2U7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgdHJhY2tCeUxhYmVsID0gKF9pOiBudW1iZXIsIHJvdzogeyBsYWJlbDogc3RyaW5nIH0pID0+IHJvdy5sYWJlbDtcblxuICBwcml2YXRlIHJlZnJlc2hWYXJpYW50cygpOiB2b2lkIHtcbiAgICBjb25zdCBuZXh0ID0gZ3JvdXBWYXJpYW50T3B0aW9ucyh0aGlzLmRhdGFzZXQsIHRoaXMuYWN0aXZlQ2VsbFR5cGVDb2x1bW4pO1xuICAgIGlmIChKU09OLnN0cmluZ2lmeShuZXh0KSAhPT0gSlNPTi5zdHJpbmdpZnkodGhpcy5ncm91cFZhcmlhbnRPcHRpb25zKSkgdGhpcy5ncm91cFZhcmlhbnRPcHRpb25zID0gbmV4dDtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcmVmcmVzaEdyb3VwcygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLnJlZnJlc2hWYXJpYW50cygpO1xuICAgIGNvbnN0IG5hbWUgPSB0aGlzLmFjdGl2ZUNlbGxUeXBlQ29sdW1uO1xuICAgIGlmICghbmFtZSB8fCAhdGhpcy5jb250cm9scykge1xuICAgICAgdGhpcy5ncm91cFJvd3NMb2FkLmNhbmNlbCgpO1xuICAgICAgdGhpcy5ncm91cFJvd3MgPSBbXTtcbiAgICAgIHRoaXMuZ3JvdXBUb3RhbCA9IDA7XG4gICAgICB0aGlzLmdyb3VwUm93c0ZvciA9IG51bGw7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChuYW1lID09PSB0aGlzLmdyb3VwUm93c0ZvcikgcmV0dXJuO1xuICAgIHRoaXMuZ3JvdXBSb3dzRm9yID0gbmFtZTtcbiAgICBjb25zdCB0YXNrID0gdGhpcy5ncm91cFJvd3NMb2FkLm5leHQoKTtcbiAgICB0cnkge1xuICAgICAgY29uc3QgdiA9IGF3YWl0IHRoaXMuY29udHJvbHMuY2F0ZWdvcmljYWxWaWV3KG5hbWUpO1xuICAgICAgaWYgKCF0YXNrLmlzQ3VycmVudCgpKSByZXR1cm47XG4gICAgICBjb25zdCB7IHJvd3MsIHRvdGFsIH0gPSBjb3VudEdyb3VwUm93cyh2KTtcbiAgICAgIHRoaXMuYXBwbHkoKCkgPT4ge1xuICAgICAgICB0aGlzLmdyb3VwUm93cyA9IHJvd3M7XG4gICAgICAgIHRoaXMuZ3JvdXBUb3RhbCA9IHRvdGFsO1xuICAgICAgfSk7XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBPbmx5IHRoZSBjdXJyZW50IGxvYWQncyBmYWlsdXJlIHJlLW9wZW5zIHRoZSBrZXk6IGEgc3VwZXJzZWRlZCBvbmUgY2xlYXJpbmcgaXRcbiAgICAgIC8vIHdvdWxkIG1ha2UgdGhlIG5ld2VyIGxvYWQncyByZXN1bHQgbG9vayBzdGFsZSBhbmQgYmUgZHJvcHBlZC5cbiAgICAgIGlmICh0YXNrLmlzQ3VycmVudCgpKSB0aGlzLmdyb3VwUm93c0ZvciA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgLyoqIEFwcGx5IGFuIGFzeW5jIHJlc3VsdCBpbnNpZGUgdGhlIHpvbmUgYW5kIHJlLXJlbmRlciB0aGlzIE9uUHVzaCBwYW5lbC4gKi9cbiAgcHJpdmF0ZSBhcHBseShmbjogKCkgPT4gdm9pZCk6IHZvaWQge1xuICAgIHRoaXMuem9uZS5ydW4oKCkgPT4ge1xuICAgICAgZm4oKTtcbiAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgIH0pO1xuICB9XG59XG4iLCI8bmctY29udGFpbmVyICpuZ0lmPVwiZ3JvdXBPcHRpb25zLmxlbmd0aFwiPlxuICA8ZGl2IGNsYXNzPVwic2Mtc3ViaGVhZFwiPkdyb3VwczwvZGl2PlxuICA8ZGl2IGNsYXNzPVwic2Mtcm93IHNjLXJvdy1waWNrZXJcIj5cbiAgICA8cC1kcm9wZG93blxuICAgICAgW29wdGlvbnNdPVwiZ3JvdXBPcHRpb25zXCJcbiAgICAgIFtncm91cF09XCJ0cnVlXCJcbiAgICAgIG9wdGlvbkxhYmVsPVwibGFiZWxcIlxuICAgICAgb3B0aW9uVmFsdWU9XCJ2YWx1ZVwiXG4gICAgICBvcHRpb25Hcm91cExhYmVsPVwibGFiZWxcIlxuICAgICAgb3B0aW9uR3JvdXBDaGlsZHJlbj1cIml0ZW1zXCJcbiAgICAgIFtuZ01vZGVsXT1cImFjdGl2ZUdyb3VwRW50cnlcIlxuICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwib25Hcm91cEVudHJ5KCRldmVudClcIlxuICAgICAgYXBwZW5kVG89XCJib2R5XCJcbiAgICAgIHN0eWxlQ2xhc3M9XCJzYy1mdWxsXCJcbiAgICA+XG4gICAgICA8bmctdGVtcGxhdGUgbGV0LWdyb3VwIHBUZW1wbGF0ZT1cImdyb3VwXCI+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwic2MtZ3JvdXAtaGVhZGluZ1wiPnt7IGdyb3VwLmxhYmVsIH19PC9zcGFuPlxuICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICA8L3AtZHJvcGRvd24+XG4gICAgPHAtZHJvcGRvd25cbiAgICAgICpuZ0lmPVwiZ3JvdXBWYXJpYW50T3B0aW9ucy5sZW5ndGhcIlxuICAgICAgW29wdGlvbnNdPVwiZ3JvdXBWYXJpYW50T3B0aW9uc1wiXG4gICAgICBvcHRpb25MYWJlbD1cImxhYmVsXCJcbiAgICAgIG9wdGlvblZhbHVlPVwidmFsdWVcIlxuICAgICAgc3R5bGVDbGFzcz1cInNjLXZhcmlhbnRcIlxuICAgICAgW25nTW9kZWxdPVwiYWN0aXZlQ2VsbFR5cGVDb2x1bW5cIlxuICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwib25Hcm91cFZhcmlhbnQoJGV2ZW50KVwiXG4gICAgICBhcHBlbmRUbz1cImJvZHlcIlxuICAgID48L3AtZHJvcGRvd24+XG4gICAgPGJ1dHRvblxuICAgICAgKm5nSWY9XCJjYW5JbXBvcnRHcm91cHNcIlxuICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICBjbGFzcz1cInNjLWljb24tYnRuXCJcbiAgICAgIFtkaXNhYmxlZF09XCJncm91cEltcG9ydGluZ1wiXG4gICAgICAoY2xpY2spPVwiZ3JvdXBGaWxlLmNsaWNrKClcIlxuICAgICAgdGl0bGU9XCJJbXBvcnQgY2VsbCBncm91cHMgKENTViBvZiBjZWxsX2lkLCBncm91cClcIlxuICAgID5cbiAgICAgIDxpXG4gICAgICAgIGNsYXNzPVwicGlcIlxuICAgICAgICBbY2xhc3MucGktcGx1cy1jaXJjbGVdPVwiIWdyb3VwSW1wb3J0aW5nXCJcbiAgICAgICAgW2NsYXNzLnBpLXNwaW5dPVwiZ3JvdXBJbXBvcnRpbmdcIlxuICAgICAgICBbY2xhc3MucGktc3Bpbm5lcl09XCJncm91cEltcG9ydGluZ1wiXG4gICAgICA+PC9pPlxuICAgIDwvYnV0dG9uPlxuICAgIDxpbnB1dCAjZ3JvdXBGaWxlIHR5cGU9XCJmaWxlXCIgYWNjZXB0PVwiLmNzdiwudHN2LC50eHRcIiBoaWRkZW4gKGNoYW5nZSk9XCJvbkltcG9ydEdyb3Vwc0ZpbGUoZ3JvdXBGaWxlKVwiIC8+XG4gIDwvZGl2PlxuICA8c21hbGwgY2xhc3M9XCJzYy1oaW50IHNjLWVycm9yXCIgKm5nSWY9XCJncm91cEltcG9ydEVycm9yXCI+e3sgZ3JvdXBJbXBvcnRFcnJvciB9fTwvc21hbGw+XG5cbiAgPGRpdiBjbGFzcz1cInNjLWdyb3VwLWxpc3RcIiAqbmdJZj1cImdyb3VwUm93cy5sZW5ndGhcIj5cbiAgICA8ZGl2IGNsYXNzPVwic2MtZ3JvdXAtcm93IHNjLWdyb3VwLWFsbFwiPlxuICAgICAgPHAtY2hlY2tib3hcbiAgICAgICAgW2JpbmFyeV09XCJ0cnVlXCJcbiAgICAgICAgW25nTW9kZWxdPVwiYWxsR3JvdXBzU2hvd25cIlxuICAgICAgICAob25DaGFuZ2UpPVwib25BbGxHcm91cHNTaG93bigkZXZlbnQuY2hlY2tlZClcIlxuICAgICAgPjwvcC1jaGVja2JveD5cbiAgICAgIDxzcGFuIGNsYXNzPVwic2MtZ3JvdXAtbGFiZWxcIj5BbGwgZ3JvdXBzPC9zcGFuPlxuICAgICAgPHNwYW4gY2xhc3M9XCJzYy1jb3VudFwiPih7eyBncm91cFRvdGFsIHwgbnVtYmVyIH19KTwvc3Bhbj5cbiAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwic2MtaWNvbi1idG5cIiAoY2xpY2spPVwiZ3JvdXBzRXhwYW5kZWQgPSAhZ3JvdXBzRXhwYW5kZWRcIj5cbiAgICAgICAgPGkgY2xhc3M9XCJwaVwiIFtjbGFzcy5waS1jaGV2cm9uLWRvd25dPVwiZ3JvdXBzRXhwYW5kZWRcIiBbY2xhc3MucGktY2hldnJvbi1yaWdodF09XCIhZ3JvdXBzRXhwYW5kZWRcIj48L2k+XG4gICAgICA8L2J1dHRvbj5cbiAgICA8L2Rpdj5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZ3JvdXBzRXhwYW5kZWRcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJzYy1ncm91cC1yb3dcIiAqbmdGb3I9XCJsZXQgcm93IG9mIGdyb3VwUm93czsgdHJhY2tCeTogdHJhY2tCeUxhYmVsXCI+XG4gICAgICAgIDxwLWNoZWNrYm94XG4gICAgICAgICAgW2JpbmFyeV09XCJ0cnVlXCJcbiAgICAgICAgICBbbmdNb2RlbF09XCJpc0dyb3VwU2hvd24ocm93LmxhYmVsKVwiXG4gICAgICAgICAgKG9uQ2hhbmdlKT1cIm9uR3JvdXBTaG93bihyb3cubGFiZWwsICRldmVudC5jaGVja2VkKVwiXG4gICAgICAgID48L3AtY2hlY2tib3g+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwic2MtZG90XCIgW3N0eWxlLmJhY2tncm91bmRdPVwicm93LmNvbG9yXCI+PC9zcGFuPlxuICAgICAgICA8c3BhbiBjbGFzcz1cInNjLWdyb3VwLWxhYmVsXCIgW3RpdGxlXT1cInJvdy5sYWJlbFwiPnt7IHJvdy5sYWJlbCB9fTwvc3Bhbj5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJzYy1jb3VudFwiPih7eyByb3cuY291bnQgfCBudW1iZXIgfX0pPC9zcGFuPlxuICAgICAgPC9kaXY+XG4gICAgPC9uZy1jb250YWluZXI+XG4gIDwvZGl2PlxuPC9uZy1jb250YWluZXI+XG4iXX0=
274
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BhdGlhbC1ncm91cHMtcGFuZWwuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9zcGF0aWFsLWNvbnRyb2xzL3NwYXRpYWwtZ3JvdXBzLXBhbmVsL3NwYXRpYWwtZ3JvdXBzLXBhbmVsLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3NyYy9saWIvc3BhdGlhbC1jb250cm9scy9zcGF0aWFsLWdyb3Vwcy1wYW5lbC9zcGF0aWFsLWdyb3Vwcy1wYW5lbC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsWUFBWSxFQUNaLEtBQUssRUFDTCxNQUFNLEVBRU4sTUFBTSxHQUVQLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0MsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUMzQyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDbEQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBSTFELE9BQU8sRUFBRSxvQkFBb0IsRUFBb0IsTUFBTSwrQkFBK0IsQ0FBQztBQUN2RixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDaEUsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sb0RBQW9ELENBQUM7QUFDL0YsT0FBTyxFQUNMLGFBQWEsRUFJYixjQUFjLEVBQ2QsYUFBYSxFQUNiLGFBQWEsRUFD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QUFHLEtBQUssQ0FBQztZQUMxQixDQUFDLENBQUMsQ0FBQztRQUNMLENBQUM7UUFBQyxNQUFNLENBQUM7WUFDUCxpRkFBaUY7WUFDakYsZ0VBQWdFO1lBQ2hFLElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRTtnQkFBRSxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztRQUNqRCxDQUFDO0lBQ0gsQ0FBQztJQUVELDZFQUE2RTtJQUNyRSxLQUFLLENBQUMsRUFBYztRQUMxQixJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUU7WUFDakIsRUFBRSxFQUFFLENBQUM7WUFDTCxJQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQzFCLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQzs4R0FwT1UsMkJBQTJCO2tHQUEzQiwyQkFBMkIsZ1FDaEV4QywyL0hBMEdBLGd4T0R0REksWUFBWSx1VEFDWixXQUFXLDhWQUNYLFlBQVkscUlBQ1osY0FBYyxnWkFDZCxjQUFjLHV0Q0FDZCxrQkFBa0IsbVdBQ2xCLHlCQUF5Qjs7MkZBTWhCLDJCQUEyQjtrQkFoQnZDLFNBQVM7K0JBQ0Usc0JBQXNCLGNBQ3BCLElBQUksV0FDUDt3QkFDUCxZQUFZO3dCQUNaLFdBQVc7d0JBQ1gsWUFBWTt3QkFDWixjQUFjO3dCQUNkLGNBQWM7d0JBQ2Qsa0JBQWtCO3dCQUNsQix5QkFBeUI7cUJBQzFCLG1CQUdnQix1QkFBdUIsQ0FBQyxNQUFNOzJHQUl0QyxRQUFRO3NCQUFoQixLQUFLO2dCQUVHLE9BQU87c0JBQWYsS0FBSztnQkFFRyxJQUFJO3NCQUFaLEtBQUs7Z0JBRUcsZ0JBQWdCO3NCQUF4QixLQUFLO2dCQUVhLGVBQWU7c0JBQWpDLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgRXZlbnRFbWl0dGVyLFxuICBJbnB1dCxcbiAgTmdab25lLFxuICBPbkNoYW5nZXMsXG4gIE91dHB1dCxcbiAgU2ltcGxlQ2hhbmdlcyxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBTaGFyZWRNb2R1bGUgfSBmcm9tICdwcmltZW5nL2FwaSc7XG5pbXBvcnQgeyBDaGVja2JveE1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvY2hlY2tib3gnO1xuaW1wb3J0IHsgRHJvcGRvd25Nb2R1bGUgfSBmcm9tICdwcmltZW5nL2Ryb3Bkb3duJztcbmltcG9ydCB7IE92ZXJsYXlQYW5lbE1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvb3ZlcmxheXBhbmVsJztcblxuaW1wb3J0IHR5cGUgeyBJU3BhdGlhbENvbnRyb2xzIH0gZnJvbSAnLi4vLi4vY29udHJhY3RzL3Zpc3VhbGl6ZXIuY29udHJhY3QnO1xuaW1wb3J0IHR5cGUgeyBTcGF0aWFsRGF0YXNldCB9IGZyb20gJy4uLy4uL2NvbnRyYWN0cy9zcGF0aWFsLWRhdGFzZXQuY29udHJhY3QnO1xuaW1wb3J0IHsgREVGQVVMVF9TUEFUSUFMX1ZJRVcsIFNwYXRpYWxWaWV3U3RhdGUgfSBmcm9tICcuLi8uLi9jb250cmFjdHMvZGlzcGxheS10eXBlcyc7XG5pbXBvcnQgeyBjZWxsVHlwZUNvbHVtbkZvciB9IGZyb20gJy4uLy4uL3NwYXRpYWwvc3BhdGlhbC10aWxlcyc7XG5pbXBvcnQgeyBncm91cENvbG9yc0tleSB9IGZyb20gJy4uLy4uL3NwYXRpYWwvc3BhdGlhbC1lbmNvZGluZyc7XG5pbXBvcnQgeyBTcGF0aWFsR2VuZVN0eWxlQ29tcG9uZW50IH0gZnJvbSAnLi4vc3BhdGlhbC1nZW5lLXN0eWxlL3NwYXRpYWwtZ2VuZS1zdHlsZS5jb21wb25lbnQnO1xuaW1wb3J0IHtcbiAgRkFNSUxZX1BSRUZJWCxcbiAgR3JvdXBPcHRpb25TZWN0aW9uLFxuICBHcm91cFJvdyxcbiAgUGFuZWxPcHRpb24sXG4gIGNvdW50R3JvdXBSb3dzLFxuICBmYW1pbHlNZW1iZXJzLFxuICBncm91cEVudHJ5Rm9yLFxuICBncm91cE9wdGlvbnMsXG4gIGdyb3VwVmFyaWFudE9wdGlvbnMsXG4gIHRvZ2dsZUhpZGRlbixcbn0gZnJvbSAnLi4vLi4vc3BhdGlhbC9zcGF0aWFsLXBhbmVsLW1vZGVsJztcbmltcG9ydCB7IFN1cGVyc2VkZSB9IGZyb20gJy4uLy4uL3V0aWwvc3VwZXJzZWRlJztcblxuLyoqXG4gKiBUaGUgb2JzZXJ2YXRpb25zJyBncm91cGluZywgYXMgWGVuaXVtIEV4cGxvcmVyJ3MgR3JvdXBzIHNlY3Rpb246IHRoZSBncm91cCBwaWNrZXIgKGNvbHVtbnNcbiAqIHVuZGVyIHRoZWlyIHNlY3Rpb24gaGVhZGluZywgYSBrLW1lYW5zIGZhbWlseSBvbmNlLCB3aXRoIGl0cyBrIGJlc2lkZSBpdCksIENTViBpbXBvcnQgb2YgYSBuZXdcbiAqIGdyb3VwaW5nLCBhbmQgdGhlIGdyb3VwaW5nJ3MgY2F0ZWdvcmllcyB3aXRoIHRoZWlyIGNvbG91cnMgKGVhY2ggb25lJ3Mgc3dhdGNoIG9wZW5zIGEgY29sb3VyXG4gKiBwaWNrZXIpLCBjZWxsIGNvdW50cyBhbmQgc2hvdy9oaWRlIHN3aXRjaGVzLiBBIGdyb3VwJ3MgbmFtZSBzZWxlY3RzIGl0cyBvYnNlcnZhdGlvbnMuXG4gKlxuICogVGhlIE9ic2VydmF0aW9ucyBzZWN0aW9uJ3MgXCJDb2xvdXIgYnlcIiBpbiBHcm91cCBtb2RlOiB0aGUgZ3JvdXBpbmcgY29sb3VycyB0aGUgbWFya2VycyBhbmQgdGhlXG4gKiBjZWxscyBhbGlrZS4gV3JpdGVzIG9ubHkgdGhyb3VnaCBgY29udHJvbHMuc2V0Vmlld1N0YXRlYCAoYGNlbGxUeXBlQ29sdW1uYCB3aXRoIGBjb2xvckJ5YCBhbmRcbiAqIGBjZWxsQ29sb3JNb2RlYCwgYGhpZGRlbkdyb3Vwc2AsIGBncm91cENvbG9yc2ApLlxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdzcGF0aWFsLWdyb3Vwcy1wYW5lbCcsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtcbiAgICBDb21tb25Nb2R1bGUsXG4gICAgRm9ybXNNb2R1bGUsXG4gICAgU2hhcmVkTW9kdWxlLFxuICAgIENoZWNrYm94TW9kdWxlLFxuICAgIERyb3Bkb3duTW9kdWxlLFxuICAgIE92ZXJsYXlQYW5lbE1vZHVsZSxcbiAgICBTcGF0aWFsR2VuZVN0eWxlQ29tcG9uZW50LFxuICBdLFxuICB0ZW1wbGF0ZVVybDogJy4vc3BhdGlhbC1ncm91cHMtcGFuZWwuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9zcGF0aWFsLWdyb3Vwcy1wYW5lbC5jb21wb25lbnQuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgU3BhdGlhbEdyb3Vwc1BhbmVsQ29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzIHtcbiAgLyoqIFRoZSBzcGF0aWFsIGNvbnRyb2xzIHRoaXMgcGFuZWwgcmVhZHMgYW5kIHdyaXRlcyB0aHJvdWdoOyBudWxsIHdpdGhvdXQgYSBgU1BBVElBTF9EQVRBX1BPUlRgLiAqL1xuICBASW5wdXQoKSBjb250cm9sczogSVNwYXRpYWxDb250cm9scyB8IG51bGwgPSBudWxsO1xuICAvKiogVGhlIGRhdGFzZXQgb24gb2ZmZXIsIG9yIG51bGwuICovXG4gIEBJbnB1dCgpIGRhdGFzZXQ6IFNwYXRpYWxEYXRhc2V0IHwgbnVsbCA9IG51bGw7XG4gIC8qKiBUaGUgY3VycmVudCBzcGF0aWFsIHZpZXcgc3RhdGU6IHdoYXQgaXMgZHJhd24sIGFuZCBob3cuICovXG4gIEBJbnB1dCgpIHZpZXc6IFNwYXRpYWxWaWV3U3RhdGUgPSBERUZBVUxUX1NQQVRJQUxfVklFVztcbiAgLyoqIFRoZSBjYXRlZ29yeSBzZWxlY3RlZCAoaXRzIGNvZGUgaW4gdGhlIGdyb3VwaW5nKSwgZm9yIGhpZ2hsaWdodGluZyBpdHMgcm93LiAqL1xuICBASW5wdXQoKSBzZWxlY3RlZENhdGVnb3J5OiBudW1iZXIgfCBudWxsID0gbnVsbDtcbiAgLyoqIEEgZ3JvdXAncyBuYW1lIHdhcyBjbGlja2VkOiBpdHMgY2F0ZWdvcnkncyBjb2RlIGluIHRoZSBncm91cGluZywgdG8gc2VsZWN0IGl0cyBvYnNlcnZhdGlvbnMuICovXG4gIEBPdXRwdXQoKSByZWFkb25seSBjYXRlZ29yeUNsaWNrZWQgPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlcj4oKTtcblxuICAvKipcbiAgICogVGhlIGdyb3VwIHBpY2tlcjogY2F0ZWdvcmljYWwgY29sdW1ucyB1bmRlciB0aGVpciBzZWN0aW9uIGhlYWRpbmcsIGEgZmFtaWx5IG9mXG4gICAqIHZhcmlhbnRzIChrLW1lYW5zIGF0IGsgPSAy4oCmMTApIGxpc3RlZCBvbmNlLiBWYWx1ZXMgYXJlIGEgY29sdW1uIG5hbWUsIG9yXG4gICAqIGBmYW1pbHk6PGlkPmAgZm9yIGEgZmFtaWx5LlxuICAgKi9cbiAgcHJvdGVjdGVkIGdyb3VwT3B0aW9uczogR3JvdXBPcHRpb25TZWN0aW9uW10gPSBbXTtcbiAgLyoqIFZhcmlhbnRzIG9mIHRoZSBhY3RpdmUgZmFtaWx5IChrID0gMuKApjEwKSwgd2hlbiBhIGZhbWlseSBpcyBhY3RpdmUuICovXG4gIHByb3RlY3RlZCBncm91cFZhcmlhbnRPcHRpb25zOiBQYW5lbE9wdGlvbjxzdHJpbmc+W10gPSBbXTtcbiAgLyoqIFRoZSBsYXN0IHZhcmlhbnQgY2hvc2VuIHBlciBmYW1pbHksIHNvIHN3aXRjaGluZyBhd2F5IGFuZCBiYWNrIGtlZXBzIGsuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgZmFtaWx5Q2hvaWNlID0gbmV3IE1hcDxzdHJpbmcsIHN0cmluZz4oKTtcblxuICAvKiogVGhlIGFjdGl2ZSBncm91cGluZydzIGNhdGVnb3JpZXMgd2l0aCBjb2xvdXJzIGFuZCBjZWxsIGNvdW50cywgbGFyZ2VzdCBmaXJzdC4gKi9cbiAgcHJvdGVjdGVkIGdyb3VwUm93czogR3JvdXBSb3dbXSA9IFtdO1xuICBwcm90ZWN0ZWQgZ3JvdXBUb3RhbCA9IDA7XG4gIHByb3RlY3RlZCBncm91cHNFeHBhbmRlZCA9IHRydWU7XG4gIC8qKiBUaGUgZ3JvdXBpbmcge0BsaW5rIGdyb3VwUm93c30gc2hvd3Mgb3IgaXMgbG9hZGluZyDigJQgYSByZXBlYXQgcmVxdWVzdCBmb3IgaXQgaXMgYSBuby1vcC4gKi9cbiAgcHJpdmF0ZSBncm91cFJvd3NGb3I6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICAvKiogTGF0ZXN0IHdpbnMgYW1vbmcgZ3JvdXAtcm93IGxvYWRzLCBzbyBhIHNsb3cgb25lIGZvciBhbiBlYXJsaWVyIGdyb3VwaW5nIChvciB0aGVcbiAgICogIHByZXZpb3VzIGRhdGFzZXQncyBjb2x1bW4gb2YgdGhlIHNhbWUgbmFtZSkgY2Fubm90IGxhbmQgb3ZlciB0aGUgY3VycmVudCBvbmUuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgZ3JvdXBSb3dzTG9hZCA9IG5ldyBTdXBlcnNlZGUoKTtcbiAgcHJvdGVjdGVkIGdyb3VwSW1wb3J0RXJyb3I6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICBwcm90ZWN0ZWQgZ3JvdXBJbXBvcnRpbmcgPSBmYWxzZTtcbiAgLyoqIFRoZSBncm91cCB0aGUgb3BlbiBjb2xvdXIgcGlja2VyIGVkaXRzLiAqL1xuICBwcm90ZWN0ZWQgc3R5bGVHcm91cDogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSB6b25lOiBOZ1pvbmUsXG4gICAgcHJpdmF0ZSByZWFkb25seSBjZHI6IENoYW5nZURldGVjdG9yUmVmLFxuICApIHt9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGlmIChjaGFuZ2VzWyd2aWV3J10pIHRoaXMuaGlkZGVuR3JvdXBzID0gbmV3IFNldCh0aGlzLnZpZXcuaGlkZGVuR3JvdXBzKTtcbiAgICBpZiAoY2hhbmdlc1snZGF0YXNldCddKSB7XG4gICAgICB0aGlzLmdyb3VwT3B0aW9ucyA9IGdyb3VwT3B0aW9ucyh0aGlzLmRhdGFzZXQpO1xuICAgICAgLy8gQSBzYW1lLW5hbWVkIGdyb3VwaW5nIG9mIGEgbmV3IGRhdGFzZXQgaXMgbm90IHRoZSBvbGQgb25lLlxuICAgICAgdGhpcy5ncm91cFJvd3NGb3IgPSBudWxsO1xuICAgIH1cbiAgICB2b2lkIHRoaXMucmVmcmVzaEdyb3VwcygpO1xuICB9XG5cbiAgLyoqIFRoZSBjYXRlZ29yaWNhbCBjb2x1bW4gdGhlIGNlbGxzIGFyZSBncm91cGVkIGJ5LiAqL1xuICBwcm90ZWN0ZWQgZ2V0IGFjdGl2ZUNlbGxUeXBlQ29sdW1uKCk6IHN0cmluZyB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLmRhdGFzZXQgPyBjZWxsVHlwZUNvbHVtbkZvcih0aGlzLmRhdGFzZXQsIHRoaXMudmlldykgOiBudWxsO1xuICB9XG5cbiAgLyoqIFRoZSBwaWNrZXIncyB2YWx1ZSBmb3IgdGhlIGFjdGl2ZSBncm91cCBjb2x1bW4uICovXG4gIHByb3RlY3RlZCBnZXQgYWN0aXZlR3JvdXBFbnRyeSgpOiBzdHJpbmcgfCBudWxsIHtcbiAgICByZXR1cm4gZ3JvdXBFbnRyeUZvcih0aGlzLmRhdGFzZXQsIHRoaXMuYWN0aXZlQ2VsbFR5cGVDb2x1bW4pO1xuICB9XG5cbiAgcHJvdGVjdGVkIG9uR3JvdXBFbnRyeSh2YWx1ZTogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKHZhbHVlLnN0YXJ0c1dpdGgoRkFNSUxZX1BSRUZJWCkpIHtcbiAgICAgIGNvbnN0IGlkID0gdmFsdWUuc2xpY2UoRkFNSUxZX1BSRUZJWC5sZW5ndGgpO1xuICAgICAgY29uc3QgbmFtZSA9IHRoaXMuZmFtaWx5Q2hvaWNlLmdldChpZCkgPz8gZmFtaWx5TWVtYmVycyh0aGlzLmRhdGFzZXQsIGlkKVswXT8ubmFtZTtcbiAgICAgIGlmIChuYW1lKSB0aGlzLm9uQ2VsbFR5cGVDb2x1bW4obmFtZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMub25DZWxsVHlwZUNvbHVtbih2YWx1ZSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgb25Hcm91cFZhcmlhbnQobmFtZTogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgbWV0YSA9IHRoaXMuZGF0YXNldD8uY29sdW1ucy5maW5kKChjKSA9PiBjLm5hbWUgPT09IG5hbWUpO1xuICAgIGlmIChtZXRhPy5raW5kID09PSAnY2F0ZWdvcmljYWwnICYmIG1ldGEuZmFtaWx5KSB0aGlzLmZhbWlseUNob2ljZS5zZXQobWV0YS5mYW1pbHkuaWQsIG5hbWUpO1xuICAgIHRoaXMub25DZWxsVHlwZUNvbHVtbihuYW1lKTtcbiAgfVxuXG4gIG9uQ2VsbFR5cGVDb2x1bW4obmFtZTogc3RyaW5nIHwgbnVsbCk6IHZvaWQge1xuICAgIC8vIFN3aXRjaGVkLW9mZiBncm91cHMgYmVsb25nIHRvIHRoZSBncm91cGluZyB0aGV5IHdlcmUgc3dpdGNoZWQgb2ZmIGluLiBUaGUgZ3JvdXBpbmcgY29sb3Vyc1xuICAgIC8vIHRoZSBtYXJrZXJzIChjb2xvckJ5KSBhbmQgdGhlIGNlbGxzIChjZWxsQ29sb3JNb2RlKSBhbGlrZS5cbiAgICB0aGlzLmNvbnRyb2xzPy5zZXRWaWV3U3RhdGUoe1xuICAgICAgY2VsbFR5cGVDb2x1bW46IG5hbWUsXG4gICAgICBoaWRkZW5Hcm91cHM6IFtdLFxuICAgICAgY2VsbENvbG9yTW9kZTogJ2dyb3VwJyxcbiAgICAgIC4uLihuYW1lID8geyBjb2xvckJ5OiB7IGtpbmQ6ICdjb2x1bW4nLCBuYW1lIH0gfSA6IHt9KSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKiBHcm91cCBgbGFiZWxgJ3MgY2F0ZWdvcnkgY29kZSBpbiB0aGUgYWN0aXZlIGdyb3VwaW5nLCBvciAtMS4gKi9cbiAgcHJvdGVjdGVkIGNvZGVPZihsYWJlbDogc3RyaW5nKTogbnVtYmVyIHtcbiAgICBjb25zdCBuYW1lID0gdGhpcy5hY3RpdmVDZWxsVHlwZUNvbHVtbjtcbiAgICBjb25zdCBtZXRhID0gdGhpcy5kYXRhc2V0Py5jb2x1bW5zLmZpbmQoKGMpID0+IGMubmFtZSA9PT0gbmFtZSk7XG4gICAgcmV0dXJuIG1ldGE/LmtpbmQgPT09ICdjYXRlZ29yaWNhbCcgPyBtZXRhLmNhdGVnb3JpZXMuaW5kZXhPZihsYWJlbCkgOiAtMTtcbiAgfVxuXG4gIC8qKiBTZWxlY3QgKG9yLCBzZWxlY3RlZCBhbHJlYWR5LCBjbGVhcikgZ3JvdXAgYGxhYmVsYCdzIG9ic2VydmF0aW9ucy4gKi9cbiAgcHJvdGVjdGVkIG9uR3JvdXBDbGlja2VkKGxhYmVsOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBjb2RlID0gdGhpcy5jb2RlT2YobGFiZWwpO1xuICAgIGlmIChjb2RlID49IDApIHRoaXMuY2F0ZWdvcnlDbGlja2VkLmVtaXQoY29kZSk7XG4gIH1cblxuICAvKioge0BsaW5rIFNwYXRpYWxWaWV3U3RhdGUuaGlkZGVuR3JvdXBzfSBhcyBhIHNldCwgZm9yIHRoZSBwZXItcm93IGNoZWNrcy4gKi9cbiAgcHJpdmF0ZSBoaWRkZW5Hcm91cHMgPSBuZXcgU2V0PHN0cmluZz4oKTtcblxuICBwcm90ZWN0ZWQgaXNHcm91cFNob3duKGxhYmVsOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gIXRoaXMuaGlkZGVuR3JvdXBzLmhhcyhsYWJlbCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0IGFsbEdyb3Vwc1Nob3duKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnZpZXcuaGlkZGVuR3JvdXBzLmxlbmd0aCA9PT0gMDtcbiAgfVxuXG4gIHByb3RlY3RlZCBvbkdyb3VwU2hvd24obGFiZWw6IHN0cmluZywgb246IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLmNvbnRyb2xzPy5zZXRWaWV3U3RhdGUoeyBoaWRkZW5Hcm91cHM6IHRvZ2dsZUhpZGRlbih0aGlzLnZpZXcuaGlkZGVuR3JvdXBzLCBbbGFiZWxdLCBvbikgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgb25BbGxHcm91cHNTaG93bihvbjogYm9vbGVhbik6IHZvaWQge1xuICAgIHRoaXMuY29udHJvbHM/LnNldFZpZXdTdGF0ZSh7IGhpZGRlbkdyb3Vwczogb24gPyBbXSA6IHRoaXMuZ3JvdXBSb3dzLm1hcCgocikgPT4gci5sYWJlbCkgfSk7XG4gIH1cblxuICAvLyDilIDilIAgcGVyLWdyb3VwIGNvbG91ciBwaWNrZXIg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgcHJvdGVjdGVkIG9wZW5Hcm91cFN0eWxlKGV2ZW50OiBFdmVudCwgbGFiZWw6IHN0cmluZywgcGFuZWw6IHsgdG9nZ2xlKGU6IEV2ZW50KTogdm9pZDsgaGlkZSgpOiB2b2lkIH0pOiB2b2lkIHtcbiAgICBpZiAodGhpcy5zdHlsZUdyb3VwID09PSBsYWJlbCkge1xuICAgICAgcGFuZWwudG9nZ2xlKGV2ZW50KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5zdHlsZUdyb3VwID0gbGFiZWw7XG4gICAgcGFuZWwuaGlkZSgpO1xuICAgIC8vIFJlLW9wZW4gYW5jaG9yZWQgb24gdGhlIHJvdyB0aGF0IHdhcyBjbGlja2VkLCBvbmNlIHRoZSBwYW5lbCBoYXMgY2xvc2VkLlxuICAgIHNldFRpbWVvdXQoKCkgPT4gcGFuZWwudG9nZ2xlKGV2ZW50KSk7XG4gIH1cblxuICAvKiogVGhlIGNvbG91ciBncm91cCBgbGFiZWxgIGlzIGRyYXduIGluIG5vdyAodGhlIHVzZXIncywgZWxzZSB0aGUgY29sdW1uJ3Mgb3IgdGhlIHBhbGV0dGUncykuICovXG4gIHByb3RlY3RlZCBncm91cENvbG9yT2YobGFiZWw6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuZ3JvdXBSb3dzLmZpbmQoKHIpID0+IHIubGFiZWwgPT09IGxhYmVsKT8uY29sb3IgPz8gJyM5OTk5OTknO1xuICB9XG5cbiAgcHJvdGVjdGVkIG9uR3JvdXBDb2xvcihsYWJlbDogc3RyaW5nLCBoZXg6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IGNvbHVtbiA9IHRoaXMuYWN0aXZlQ2VsbFR5cGVDb2x1bW47XG4gICAgaWYgKCFjb2x1bW4pIHJldHVybjtcbiAgICBjb25zdCBhbGwgPSB0aGlzLnZpZXcuZ3JvdXBDb2xvcnMgPz8ge307XG4gICAgdGhpcy5jb250cm9scz8uc2V0Vmlld1N0YXRlKHsgZ3JvdXBDb2xvcnM6IHsgLi4uYWxsLCBbY29sdW1uXTogeyAuLi5hbGxbY29sdW1uXSwgW2xhYmVsXTogaGV4IH0gfSB9KTtcbiAgfVxuXG4gIC8qKiBCYWNrIHRvIHRoZSBncm91cCdzIG93biBjb2xvdXIgKHRoZSBjb2x1bW4ncywgZWxzZSB0aGUgcGFsZXR0ZSdzKS4gKi9cbiAgcHJvdGVjdGVkIHJlc2V0R3JvdXBDb2xvcihsYWJlbDogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgY29sdW1uID0gdGhpcy5hY3RpdmVDZWxsVHlwZUNvbHVtbjtcbiAgICBjb25zdCBvd24gPSBjb2x1bW4gPyB0aGlzLnZpZXcuZ3JvdXBDb2xvcnM/Lltjb2x1bW5dIDogdW5kZWZpbmVkO1xuICAgIGlmICghY29sdW1uIHx8ICFvd24gfHwgIShsYWJlbCBpbiBvd24pKSByZXR1cm47XG4gICAgY29uc3QgcmVzdCA9IHsgLi4ub3duIH07XG4gICAgZGVsZXRlIHJlc3RbbGFiZWxdO1xuICAgIGNvbnN0IGFsbCA9IHsgLi4udGhpcy52aWV3Lmdyb3VwQ29sb3JzIH07XG4gICAgaWYgKE9iamVjdC5rZXlzKHJlc3QpLmxlbmd0aCkgYWxsW2NvbHVtbl0gPSByZXN0O1xuICAgIGVsc2UgZGVsZXRlIGFsbFtjb2x1bW5dO1xuICAgIHRoaXMuY29udHJvbHM/LnNldFZpZXdTdGF0ZSh7IGdyb3VwQ29sb3JzOiBhbGwgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0IGNhbkltcG9ydEdyb3VwcygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISF0aGlzLmNvbnRyb2xzPy5pbXBvcnRHcm91cHM7XG4gIH1cblxuICAvKiogJysnOiBhIENTVi9UU1Ygb2YgYGNlbGxfaWRgIGFuZCBncm91cCwgbmFtZWQgYWZ0ZXIgdGhlIGZpbGUuICovXG4gIHByb3RlY3RlZCBhc3luYyBvbkltcG9ydEdyb3Vwc0ZpbGUoaW5wdXQ6IEhUTUxJbnB1dEVsZW1lbnQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBmaWxlID0gaW5wdXQuZmlsZXM/LlswXTtcbiAgICBpbnB1dC52YWx1ZSA9ICcnO1xuICAgIGlmICghZmlsZSB8fCAhdGhpcy5jb250cm9scz8uaW1wb3J0R3JvdXBzKSByZXR1cm47XG4gICAgdGhpcy5ncm91cEltcG9ydEVycm9yID0gbnVsbDtcbiAgICB0aGlzLmdyb3VwSW1wb3J0aW5nID0gdHJ1ZTtcbiAgICB0cnkge1xuICAgICAgY29uc3QgbGFiZWwgPSBmaWxlLm5hbWUucmVwbGFjZSgvXFwuKGNzdnx0c3Z8dHh0KSQvaSwgJycpO1xuICAgICAgY29uc3QgeyBjb2x1bW4gfSA9IGF3YWl0IHRoaXMuY29udHJvbHMuaW1wb3J0R3JvdXBzKGxhYmVsLCBhd2FpdCBmaWxlLnRleHQoKSk7XG4gICAgICB0aGlzLmFwcGx5KCgpID0+IHRoaXMub25DZWxsVHlwZUNvbHVtbihjb2x1bW4ubmFtZSkpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgdGhpcy5hcHBseSgoKSA9PiB7XG4gICAgICAgIHRoaXMuZ3JvdXBJbXBvcnRFcnJvciA9IFN0cmluZygoZXJyIGFzIEVycm9yKT8ubWVzc2FnZSA/PyBlcnIpO1xuICAgICAgfSk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRoaXMuYXBwbHkoKCkgPT4ge1xuICAgICAgICB0aGlzLmdyb3VwSW1wb3J0aW5nID0gZmFsc2U7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgdHJhY2tCeUxhYmVsID0gKF9pOiBudW1iZXIsIHJvdzogeyBsYWJlbDogc3RyaW5nIH0pID0+IHJvdy5sYWJlbDtcblxuICBwcml2YXRlIHJlZnJlc2hWYXJpYW50cygpOiB2b2lkIHtcbiAgICBjb25zdCBuZXh0ID0gZ3JvdXBWYXJpYW50T3B0aW9ucyh0aGlzLmRhdGFzZXQsIHRoaXMuYWN0aXZlQ2VsbFR5cGVDb2x1bW4pO1xuICAgIGlmIChKU09OLnN0cmluZ2lmeShuZXh0KSAhPT0gSlNPTi5zdHJpbmdpZnkodGhpcy5ncm91cFZhcmlhbnRPcHRpb25zKSkgdGhpcy5ncm91cFZhcmlhbnRPcHRpb25zID0gbmV4dDtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcmVmcmVzaEdyb3VwcygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLnJlZnJlc2hWYXJpYW50cygpO1xuICAgIGNvbnN0IG5hbWUgPSB0aGlzLmFjdGl2ZUNlbGxUeXBlQ29sdW1uO1xuICAgIGlmICghbmFtZSB8fCAhdGhpcy5jb250cm9scykge1xuICAgICAgdGhpcy5ncm91cFJvd3NMb2FkLmNhbmNlbCgpO1xuICAgICAgdGhpcy5ncm91cFJvd3MgPSBbXTtcbiAgICAgIHRoaXMuZ3JvdXBUb3RhbCA9IDA7XG4gICAgICB0aGlzLmdyb3VwUm93c0ZvciA9IG51bGw7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIFRoZSB1c2VyJ3MgY29sb3VycyBmb3IgdGhlIGdyb3VwaW5nIGFyZSBwYXJ0IG9mIHdoYXQgdGhlIHJvd3Mgc2hvdy5cbiAgICBjb25zdCBrZXkgPSBgJHtuYW1lfVxcdTAwMDEke2dyb3VwQ29sb3JzS2V5KG5hbWUsIHRoaXMudmlldy5ncm91cENvbG9ycyl9YDtcbiAgICBpZiAoa2V5ID09PSB0aGlzLmdyb3VwUm93c0ZvcikgcmV0dXJuO1xuICAgIHRoaXMuZ3JvdXBSb3dzRm9yID0ga2V5O1xuICAgIGNvbnN0IHRhc2sgPSB0aGlzLmdyb3VwUm93c0xvYWQubmV4dCgpO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCB2ID0gYXdhaXQgdGhpcy5jb250cm9scy5jYXRlZ29yaWNhbFZpZXcobmFtZSk7XG4gICAgICBpZiAoIXRhc2suaXNDdXJyZW50KCkpIHJldHVybjtcbiAgICAgIGNvbnN0IHsgcm93cywgdG90YWwgfSA9IGNvdW50R3JvdXBSb3dzKHYpO1xuICAgICAgdGhpcy5hcHBseSgoKSA9PiB7XG4gICAgICAgIHRoaXMuZ3JvdXBSb3dzID0gcm93cztcbiAgICAgICAgdGhpcy5ncm91cFRvdGFsID0gdG90YWw7XG4gICAgICB9KTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIE9ubHkgdGhlIGN1cnJlbnQgbG9hZCdzIGZhaWx1cmUgcmUtb3BlbnMgdGhlIGtleTogYSBzdXBlcnNlZGVkIG9uZSBjbGVhcmluZyBpdFxuICAgICAgLy8gd291bGQgbWFrZSB0aGUgbmV3ZXIgbG9hZCdzIHJlc3VsdCBsb29rIHN0YWxlIGFuZCBiZSBkcm9wcGVkLlxuICAgICAgaWYgKHRhc2suaXNDdXJyZW50KCkpIHRoaXMuZ3JvdXBSb3dzRm9yID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICAvKiogQXBwbHkgYW4gYXN5bmMgcmVzdWx0IGluc2lkZSB0aGUgem9uZSBhbmQgcmUtcmVuZGVyIHRoaXMgT25QdXNoIHBhbmVsLiAqL1xuICBwcml2YXRlIGFwcGx5KGZuOiAoKSA9PiB2b2lkKTogdm9pZCB7XG4gICAgdGhpcy56b25lLnJ1bigoKSA9PiB7XG4gICAgICBmbigpO1xuICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfSk7XG4gIH1cbn1cbiIsIjxuZy1jb250YWluZXIgKm5nSWY9XCJncm91cE9wdGlvbnMubGVuZ3RoXCI+XG4gIDxkaXYgY2xhc3M9XCJzYy1zdWJoZWFkXCI+R3JvdXBzPC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJzYy1yb3cgc2Mtcm93LXBpY2tlclwiPlxuICAgIDxwLWRyb3Bkb3duXG4gICAgICBbb3B0aW9uc109XCJncm91cE9wdGlvbnNcIlxuICAgICAgW2dyb3VwXT1cInRydWVcIlxuICAgICAgb3B0aW9uTGFiZWw9XCJsYWJlbFwiXG4gICAgICBvcHRpb25WYWx1ZT1cInZhbHVlXCJcbiAgICAgIG9wdGlvbkdyb3VwTGFiZWw9XCJsYWJlbFwiXG4gICAgICBvcHRpb25Hcm91cENoaWxkcmVuPVwiaXRlbXNcIlxuICAgICAgW25nTW9kZWxdPVwiYWN0aXZlR3JvdXBFbnRyeVwiXG4gICAgICAobmdNb2RlbENoYW5nZSk9XCJvbkdyb3VwRW50cnkoJGV2ZW50KVwiXG4gICAgICBhcHBlbmRUbz1cImJvZHlcIlxuICAgICAgc3R5bGVDbGFzcz1cInNjLWZ1bGxcIlxuICAgID5cbiAgICAgIDxuZy10ZW1wbGF0ZSBsZXQtZ3JvdXAgcFRlbXBsYXRlPVwiZ3JvdXBcIj5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJzYy1ncm91cC1oZWFkaW5nXCI+e3sgZ3JvdXAubGFiZWwgfX08L3NwYW4+XG4gICAgICA8L25nLXRlbXBsYXRlPlxuICAgIDwvcC1kcm9wZG93bj5cbiAgICA8cC1kcm9wZG93blxuICAgICAgKm5nSWY9XCJncm91cFZhcmlhbnRPcHRpb25zLmxlbmd0aFwiXG4gICAgICBbb3B0aW9uc109XCJncm91cFZhcmlhbnRPcHRpb25zXCJcbiAgICAgIG9wdGlvbkxhYmVsPVwibGFiZWxcIlxuICAgICAgb3B0aW9uVmFsdWU9XCJ2YWx1ZVwiXG4gICAgICBzdHlsZUNsYXNzPVwic2MtdmFyaWFudFwiXG4gICAgICBbbmdNb2RlbF09XCJhY3RpdmVDZWxsVHlwZUNvbHVtblwiXG4gICAgICAobmdNb2RlbENoYW5nZSk9XCJvbkdyb3VwVmFyaWFudCgkZXZlbnQpXCJcbiAgICAgIGFwcGVuZFRvPVwiYm9keVwiXG4gICAgPjwvcC1kcm9wZG93bj5cbiAgICA8YnV0dG9uXG4gICAgICAqbmdJZj1cImNhbkltcG9ydEdyb3Vwc1wiXG4gICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgIGNsYXNzPVwic2MtaWNvbi1idG5cIlxuICAgICAgW2Rpc2FibGVkXT1cImdyb3VwSW1wb3J0aW5nXCJcbiAgICAgIChjbGljayk9XCJncm91cEZpbGUuY2xpY2soKVwiXG4gICAgICB0aXRsZT1cIkltcG9ydCBjZWxsIGdyb3VwcyAoQ1NWIG9mIGNlbGxfaWQsIGdyb3VwKVwiXG4gICAgPlxuICAgICAgPGlcbiAgICAgICAgY2xhc3M9XCJwaVwiXG4gICAgICAgIFtjbGFzcy5waS1wbHVzLWNpcmNsZV09XCIhZ3JvdXBJbXBvcnRpbmdcIlxuICAgICAgICBbY2xhc3MucGktc3Bpbl09XCJncm91cEltcG9ydGluZ1wiXG4gICAgICAgIFtjbGFzcy5waS1zcGlubmVyXT1cImdyb3VwSW1wb3J0aW5nXCJcbiAgICAgID48L2k+XG4gICAgPC9idXR0b24+XG4gICAgPGlucHV0ICNncm91cEZpbGUgdHlwZT1cImZpbGVcIiBhY2NlcHQ9XCIuY3N2LC50c3YsLnR4dFwiIGhpZGRlbiAoY2hhbmdlKT1cIm9uSW1wb3J0R3JvdXBzRmlsZShncm91cEZpbGUpXCIgLz5cbiAgPC9kaXY+XG4gIDxzbWFsbCBjbGFzcz1cInNjLWhpbnQgc2MtZXJyb3JcIiAqbmdJZj1cImdyb3VwSW1wb3J0RXJyb3JcIj57eyBncm91cEltcG9ydEVycm9yIH19PC9zbWFsbD5cblxuICA8ZGl2IGNsYXNzPVwic2MtZ3JvdXAtbGlzdFwiICpuZ0lmPVwiZ3JvdXBSb3dzLmxlbmd0aFwiPlxuICAgIDxkaXYgY2xhc3M9XCJzYy1ncm91cC1yb3cgc2MtZ3JvdXAtYWxsXCI+XG4gICAgICA8cC1jaGVja2JveFxuICAgICAgICBbYmluYXJ5XT1cInRydWVcIlxuICAgICAgICBbbmdNb2RlbF09XCJhbGxHcm91cHNTaG93blwiXG4gICAgICAgIChvbkNoYW5nZSk9XCJvbkFsbEdyb3Vwc1Nob3duKCRldmVudC5jaGVja2VkKVwiXG4gICAgICA+PC9wLWNoZWNrYm94PlxuICAgICAgPHNwYW4gY2xhc3M9XCJzYy1ncm91cC1sYWJlbFwiPkFsbCBncm91cHM8L3NwYW4+XG4gICAgICA8c3BhbiBjbGFzcz1cInNjLWNvdW50XCI+KHt7IGdyb3VwVG90YWwgfCBudW1iZXIgfX0pPC9zcGFuPlxuICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJzYy1pY29uLWJ0blwiIChjbGljayk9XCJncm91cHNFeHBhbmRlZCA9ICFncm91cHNFeHBhbmRlZFwiPlxuICAgICAgICA8aSBjbGFzcz1cInBpXCIgW2NsYXNzLnBpLWNoZXZyb24tZG93bl09XCJncm91cHNFeHBhbmRlZFwiIFtjbGFzcy5waS1jaGV2cm9uLXJpZ2h0XT1cIiFncm91cHNFeHBhbmRlZFwiPjwvaT5cbiAgICAgIDwvYnV0dG9uPlxuICAgIDwvZGl2PlxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJncm91cHNFeHBhbmRlZFwiPlxuICAgICAgPGRpdiBjbGFzcz1cInNjLWdyb3VwLXJvd1wiICpuZ0Zvcj1cImxldCByb3cgb2YgZ3JvdXBSb3dzOyB0cmFja0J5OiB0cmFja0J5TGFiZWxcIj5cbiAgICAgICAgPHAtY2hlY2tib3hcbiAgICAgICAgICBbYmluYXJ5XT1cInRydWVcIlxuICAgICAgICAgIFtuZ01vZGVsXT1cImlzR3JvdXBTaG93bihyb3cubGFiZWwpXCJcbiAgICAgICAgICAob25DaGFuZ2UpPVwib25Hcm91cFNob3duKHJvdy5sYWJlbCwgJGV2ZW50LmNoZWNrZWQpXCJcbiAgICAgICAgPjwvcC1jaGVja2JveD5cbiAgICAgICAgPCEtLSBUaGUgZ3JvdXAncyBjb2xvdXI7IGNsaWNraW5nIGl0IG9wZW5zIHRoZSBjb2xvdXIgcGlja2VyLiAtLT5cbiAgICAgICAgPGJ1dHRvblxuICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgIGNsYXNzPVwic2MtZG90IHNjLWRvdC1idG5cIlxuICAgICAgICAgIFtzdHlsZS5iYWNrZ3JvdW5kXT1cInJvdy5jb2xvclwiXG4gICAgICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCInQ29sb3VyIGZvciAnICsgcm93LmxhYmVsXCJcbiAgICAgICAgICB0aXRsZT1cIkNvbG91clwiXG4gICAgICAgICAgKGNsaWNrKT1cIm9wZW5Hcm91cFN0eWxlKCRldmVudCwgcm93LmxhYmVsLCBncm91cFBvcClcIlxuICAgICAgICA+PC9idXR0b24+XG4gICAgICAgIDwhLS0gVGhlIG5hbWUgc2VsZWN0cyB0aGUgZ3JvdXAncyBvYnNlcnZhdGlvbnM7IGFnYWluLCBjbGVhcnMuIC0tPlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgY2xhc3M9XCJzYy1ncm91cC1sYWJlbCBzYy1ncm91cC1zZWxlY3RcIlxuICAgICAgICAgIFtjbGFzcy5zZWxlY3RlZF09XCJzZWxlY3RlZENhdGVnb3J5ICE9PSBudWxsICYmIHNlbGVjdGVkQ2F0ZWdvcnkgPT09IGNvZGVPZihyb3cubGFiZWwpXCJcbiAgICAgICAgICBbdGl0bGVdPVwiJ1NlbGVjdCAnICsgcm93LmxhYmVsXCJcbiAgICAgICAgICAoY2xpY2spPVwib25Hcm91cENsaWNrZWQocm93LmxhYmVsKVwiXG4gICAgICAgID5cbiAgICAgICAgICB7eyByb3cubGFiZWwgfX1cbiAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwic2MtY291bnRcIj4oe3sgcm93LmNvdW50IHwgbnVtYmVyIH19KTwvc3Bhbj5cbiAgICAgIDwvZGl2PlxuICAgIDwvbmctY29udGFpbmVyPlxuICA8L2Rpdj5cbiAgPCEtLSBPbmUgcGlja2VyIGZvciBldmVyeSBncm91cCByb3csIGZpbGxlZCBmb3IgdGhlIGdyb3VwIHRoYXQgb3BlbmVkIGl0LiAtLT5cbiAgPHAtb3ZlcmxheVBhbmVsICNncm91cFBvcCBzdHlsZUNsYXNzPVwic2MtZ2VuZS1zdHlsZVwiIGFwcGVuZFRvPVwiYm9keVwiPlxuICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJjb250ZW50XCI+XG4gICAgICA8c3BhdGlhbC1nZW5lLXN0eWxlXG4gICAgICAgICpuZ0lmPVwic3R5bGVHcm91cCBhcyBncm91cFwiXG4gICAgICAgIFtnZW5lXT1cImdyb3VwXCJcbiAgICAgICAgd2hhdD1cIkdyb3VwXCJcbiAgICAgICAgW2NvbG9yXT1cImdyb3VwQ29sb3JPZihncm91cClcIlxuICAgICAgICBbc2hvd0ljb25zXT1cImZhbHNlXCJcbiAgICAgICAgKGNvbG9yQ2hhbmdlKT1cIm9uR3JvdXBDb2xvcihncm91cCwgJGV2ZW50KVwiXG4gICAgICAgIChyZXNldFN0eWxlKT1cInJlc2V0R3JvdXBDb2xvcihncm91cClcIlxuICAgICAgPjwvc3BhdGlhbC1nZW5lLXN0eWxlPlxuICAgIDwvbmctdGVtcGxhdGU+XG4gIDwvcC1vdmVybGF5UGFuZWw+XG48L25nLWNvbnRhaW5lcj5cbiJdfQ==