@jax-data-science/sci-image-visualizer 0.17.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 (121) hide show
  1. package/esm2022/lib/contracts/display-types.mjs +3 -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 +81 -15
  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 +325 -18
  17. package/esm2022/lib/implementations/napari-js/napari-spatial-3d-transcripts.mjs +182 -24
  18. package/esm2022/lib/implementations/napari-js/napari-spatial-hover.mjs +95 -5
  19. package/esm2022/lib/implementations/napari-js/napari-spatial-scene.mjs +15 -1
  20. package/esm2022/lib/implementations/napari-js/napari-spatial-tiles.mjs +30 -2
  21. package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +40 -1
  22. package/esm2022/lib/implementations/napari-js/napari-volume-region-meshes.mjs +111 -28
  23. package/esm2022/lib/implementations/napari-js/napari-volume-scene.mjs +14 -2
  24. package/esm2022/lib/implementations/napari-js/spatial-tiles/cell-layers.mjs +180 -48
  25. package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-layers.mjs +28 -8
  26. package/esm2022/lib/implementations/osd/osd-region-overlay.mjs +2 -2
  27. package/esm2022/lib/implementations/spatial-data-http/spatial-data-http.service.mjs +10 -1
  28. package/esm2022/lib/region-editor/class-tree/class-tree.component.mjs +30 -3
  29. package/esm2022/lib/region-editor/classes-panel/classes-panel.component.mjs +15 -3
  30. package/esm2022/lib/region-editor/region-editor.component.mjs +24 -4
  31. package/esm2022/lib/region-source/region-source-ops.mjs +7 -1
  32. package/esm2022/lib/region-source/region-tiles.mjs +1 -1
  33. package/esm2022/lib/region-source/worker-region-source.mjs +24 -1
  34. package/esm2022/lib/routing-visualizer.service.mjs +404 -7
  35. package/esm2022/lib/spatial/observations-in-selection.mjs +83 -0
  36. package/esm2022/lib/spatial/plane-cells.mjs +119 -0
  37. package/esm2022/lib/spatial/spatial-controls.facade.mjs +298 -5
  38. package/esm2022/lib/spatial/spatial-encoding.mjs +35 -3
  39. package/esm2022/lib/spatial/spatial-hover.mjs +34 -1
  40. package/esm2022/lib/spatial/spatial-planes.mjs +49 -0
  41. package/esm2022/lib/spatial/spatial-selection.mjs +2 -2
  42. package/esm2022/lib/spatial/spatial-tile-merge.mjs +38 -1
  43. package/esm2022/lib/spatial/transcripts-in-selection.mjs +208 -0
  44. package/esm2022/lib/spatial-controls/spatial-cells-panel/spatial-cells-panel.component.mjs +42 -65
  45. package/esm2022/lib/spatial-controls/spatial-color-by/spatial-color-by.component.mjs +187 -0
  46. package/esm2022/lib/spatial-controls/spatial-controls.component.mjs +47 -12
  47. package/esm2022/lib/spatial-controls/spatial-gene-tree/spatial-gene-tree.component.mjs +3 -3
  48. package/esm2022/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.mjs +38 -10
  49. package/esm2022/lib/spatial-controls/spatial-key/spatial-key.component.mjs +3 -3
  50. package/esm2022/lib/spatial-controls/spatial-marker-genes-form/spatial-marker-genes-form.component.mjs +3 -3
  51. package/esm2022/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.mjs +79 -57
  52. package/esm2022/lib/spatial-controls/spatial-selection-observations/spatial-selection-observations.component.mjs +101 -0
  53. package/esm2022/lib/spatial-controls/spatial-selection-transcripts/spatial-selection-transcripts.component.mjs +94 -0
  54. package/esm2022/lib/spatial-controls/spatial-transcripts-panel/spatial-transcripts-panel.component.mjs +9 -3
  55. package/esm2022/lib/store/region-source-scope.mjs +10 -1
  56. package/esm2022/lib/store/region-store.service.mjs +33 -2
  57. package/esm2022/lib/toolbar/toolbar.component.mjs +10 -3
  58. package/esm2022/lib/visualizer/spatial-region-set.mjs +95 -0
  59. package/esm2022/lib/visualizer.component.mjs +40 -4
  60. package/fesm2022/{jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-DHrHO2ay.mjs → jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-CBiLcnE6.mjs} +4521 -759
  61. package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-CBiLcnE6.mjs.map +1 -0
  62. package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-CKEUwNta.mjs → jax-data-science-sci-image-visualizer-onnx-sam-session-BXHjv4PE.mjs} +2 -2
  63. package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-CKEUwNta.mjs.map → jax-data-science-sci-image-visualizer-onnx-sam-session-BXHjv4PE.mjs.map} +1 -1
  64. package/fesm2022/jax-data-science-sci-image-visualizer.mjs +1 -1
  65. package/fesm2022/region-source.worker.js +84 -2
  66. package/lib/contracts/display-types.d.ts +90 -4
  67. package/lib/contracts/image.contract.d.ts +6 -0
  68. package/lib/contracts/ports/spatial-data.port.d.ts +7 -0
  69. package/lib/contracts/region-editor-api.contract.d.ts +9 -0
  70. package/lib/contracts/region-store.contract.d.ts +6 -0
  71. package/lib/contracts/spatial-dataset.contract.d.ts +7 -1
  72. package/lib/contracts/visualizer.contract.d.ts +43 -1
  73. package/lib/geometry/cell-meshes.d.ts +27 -0
  74. package/lib/geometry/place.d.ts +45 -0
  75. package/lib/implementations/napari-js/napari-camera-depth.d.ts +23 -0
  76. package/lib/implementations/napari-js/napari-loading-state.d.ts +1 -1
  77. package/lib/implementations/napari-js/napari-scene.d.ts +12 -0
  78. package/lib/implementations/napari-js/napari-spatial-2d-scene.d.ts +19 -3
  79. package/lib/implementations/napari-js/napari-spatial-3d-cells.d.ts +141 -0
  80. package/lib/implementations/napari-js/napari-spatial-3d-scene.d.ts +87 -0
  81. package/lib/implementations/napari-js/napari-spatial-3d-transcripts.d.ts +49 -8
  82. package/lib/implementations/napari-js/napari-spatial-hover.d.ts +22 -0
  83. package/lib/implementations/napari-js/napari-spatial-scene.d.ts +12 -0
  84. package/lib/implementations/napari-js/napari-spatial-tiles.d.ts +15 -0
  85. package/lib/implementations/napari-js/napari-visualizer.service.d.ts +27 -1
  86. package/lib/implementations/napari-js/napari-volume-region-meshes.d.ts +38 -19
  87. package/lib/implementations/napari-js/napari-volume-scene.d.ts +2 -0
  88. package/lib/implementations/napari-js/spatial-tiles/cell-layers.d.ts +53 -0
  89. package/lib/implementations/napari-js/spatial-tiles/transcript-layers.d.ts +11 -2
  90. package/lib/implementations/spatial-data-http/spatial-data-http.service.d.ts +7 -0
  91. package/lib/region-editor/class-tree/class-tree.component.d.ts +16 -1
  92. package/lib/region-editor/classes-panel/classes-panel.component.d.ts +10 -1
  93. package/lib/region-editor/region-editor.component.d.ts +4 -0
  94. package/lib/region-source/region-source-ops.d.ts +12 -0
  95. package/lib/region-source/region-tiles.d.ts +8 -0
  96. package/lib/region-source/worker-region-source.d.ts +18 -0
  97. package/lib/routing-visualizer.service.d.ts +140 -1
  98. package/lib/spatial/observations-in-selection.d.ts +43 -0
  99. package/lib/spatial/plane-cells.d.ts +37 -0
  100. package/lib/spatial/spatial-controls.facade.d.ts +59 -0
  101. package/lib/spatial/spatial-encoding.d.ts +14 -1
  102. package/lib/spatial/spatial-hover.d.ts +23 -0
  103. package/lib/spatial/spatial-planes.d.ts +22 -0
  104. package/lib/spatial/spatial-selection.d.ts +2 -1
  105. package/lib/spatial/spatial-tile-merge.d.ts +9 -0
  106. package/lib/spatial/transcripts-in-selection.d.ts +95 -0
  107. package/lib/spatial-controls/spatial-cells-panel/spatial-cells-panel.component.d.ts +19 -28
  108. package/lib/spatial-controls/spatial-color-by/spatial-color-by.component.d.ts +64 -0
  109. package/lib/spatial-controls/spatial-controls.component.d.ts +17 -2
  110. package/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.d.ts +16 -6
  111. package/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.d.ts +26 -23
  112. package/lib/spatial-controls/spatial-selection-observations/spatial-selection-observations.component.d.ts +48 -0
  113. package/lib/spatial-controls/spatial-selection-transcripts/spatial-selection-transcripts.component.d.ts +43 -0
  114. package/lib/spatial-controls/spatial-transcripts-panel/spatial-transcripts-panel.component.d.ts +3 -1
  115. package/lib/store/region-source-scope.d.ts +4 -0
  116. package/lib/store/region-store.service.d.ts +21 -0
  117. package/lib/toolbar/toolbar.component.d.ts +6 -1
  118. package/lib/visualizer/spatial-region-set.d.ts +55 -0
  119. package/lib/visualizer.component.d.ts +14 -0
  120. package/package.json +1 -1
  121. package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-DHrHO2ay.mjs.map +0 -1
@@ -4,12 +4,14 @@ import { CommonModule } from '@angular/common';
4
4
  import { FormsModule } from '@angular/forms';
5
5
  import { ButtonModule } from 'primeng/button';
6
6
  import { CheckboxModule } from 'primeng/checkbox';
7
+ import { SliderModule } from 'primeng/slider';
7
8
  import { DialogModule } from 'primeng/dialog';
8
9
  import { TooltipModule } from 'primeng/tooltip';
9
10
  import { combineLatest } from 'rxjs';
10
11
  import { VISUALIZER } from '../contracts/visualizer.contract';
11
12
  import { SpatialChartsComponent } from './spatial-charts/spatial-charts.component';
12
13
  import { DEFAULT_SPATIAL_VIEW } from '../contracts/display-types';
14
+ import { datasetRegionSet } from '../visualizer/spatial-region-set';
13
15
  import { parseGeneGroups } from '../spatial/spatial-panel-model';
14
16
  import { emptySelection } from '../spatial/spatial-selection';
15
17
  import { GenePickerModel } from './spatial-gene-picker';
@@ -23,8 +25,9 @@ import * as i1 from "@angular/common";
23
25
  import * as i2 from "@angular/forms";
24
26
  import * as i3 from "primeng/button";
25
27
  import * as i4 from "primeng/checkbox";
26
- import * as i5 from "primeng/dialog";
27
- import * as i6 from "primeng/tooltip";
28
+ import * as i5 from "primeng/slider";
29
+ import * as i6 from "primeng/dialog";
30
+ import * as i7 from "primeng/tooltip";
28
31
  /** @deprecated Moved to `spatial/spatial-panel-model`; re-exported for one release. */
29
32
  export { parseGeneGroups };
30
33
  /** Per-instance id source — see {@link SpatialControlsComponent.chartsBodyId}. */
@@ -136,10 +139,17 @@ export class SpatialControlsComponent {
136
139
  this.reverse = false;
137
140
  this.destroyRef = inject(DestroyRef);
138
141
  this.cdr = inject(ChangeDetectorRef);
142
+ /** The 3D view's individual cells as they stand (null: none drawn). */
143
+ this.cells3dStatus = null;
144
+ /**
145
+ * Whether the router has the dataset's region set attached and placed (null: it does not say).
146
+ * See {@link hasCells3d}.
147
+ */
148
+ this.cells3dAvailable = null;
139
149
  /** Which collapsible sections are open. Per dialog instance, not persisted. */
140
150
  this.open = {
141
151
  images: false,
142
- cells: true,
152
+ volume: false,
143
153
  transcripts: false,
144
154
  annotations: false,
145
155
  observations: false,
@@ -164,12 +174,8 @@ export class SpatialControlsComponent {
164
174
  .subscribe((dataset) => {
165
175
  this.dataset = dataset;
166
176
  this.genes.setDataset(dataset);
167
- // A dataset with no cells to outline leads with its observations.
168
- this.open = {
169
- ...this.open,
170
- cells: !!(dataset?.polygonTiles || dataset?.polygons),
171
- observations: !(dataset?.polygonTiles || dataset?.polygons),
172
- };
177
+ // The Observations section leads.
178
+ this.open = { ...this.open, observations: !!dataset };
173
179
  void this.refreshKey();
174
180
  this.cdr.markForCheck();
175
181
  });
@@ -183,6 +189,18 @@ export class SpatialControlsComponent {
183
189
  });
184
190
  // The renderer's own streams may emit outside the zone: re-entered here, once, for
185
191
  // every panel they feed.
192
+ this.controls
193
+ .getCells3dStatus$?.()
194
+ ?.pipe(untilDestroyed())
195
+ .subscribe((s) => this.runAndMark(() => {
196
+ this.cells3dStatus = s;
197
+ }));
198
+ this.controls
199
+ .getCells3dAvailable$?.()
200
+ ?.pipe(untilDestroyed())
201
+ .subscribe((a) => this.runAndMark(() => {
202
+ this.cells3dAvailable = a;
203
+ }));
186
204
  const estimate$ = this.controls.getTranscriptEstimate$?.();
187
205
  estimate$?.pipe(untilDestroyed()).subscribe((e) => this.runAndMark(() => {
188
206
  this.estimate = e;
@@ -327,6 +345,13 @@ export class SpatialControlsComponent {
327
345
  get hasCells() {
328
346
  return !!(this.dataset?.polygonTiles || this.dataset?.polygons);
329
347
  }
348
+ /**
349
+ * The dataset's cells can be drawn in 3D: its boundaries name a 3D segmentation's region set, and
350
+ * it is attached with its planes (else the 3D view draws no cells, and the markers stay).
351
+ */
352
+ get hasCells3d() {
353
+ return !!datasetRegionSet(this.dataset) && this.cells3dAvailable !== false;
354
+ }
330
355
  /** Transcripts on offer: tiles to draw, or a density map. */
331
356
  get hasTranscripts() {
332
357
  return !!this.dataset?.transcriptTiles || !!this.dataset?.density;
@@ -338,6 +363,15 @@ export class SpatialControlsComponent {
338
363
  onShowImage(on) {
339
364
  this.controls?.setViewState({ showImage: on });
340
365
  }
366
+ /** The reference volume, in 3D (the Volume section's switch). */
367
+ onShowVolume(on) {
368
+ this.controls?.setViewState({ showVolume: on });
369
+ }
370
+ onVolumeOpacity(value) {
371
+ if (value === undefined)
372
+ return;
373
+ this.controls?.setViewState({ volumeOpacity: value });
374
+ }
341
375
  onShowAnnotations(on) {
342
376
  this.controls?.setViewState({ showAnnotations: on });
343
377
  }
@@ -370,7 +404,7 @@ export class SpatialControlsComponent {
370
404
  return this.key.refresh(this.controls, this.dataset, this.view, this.colormap, this.reverse);
371
405
  }
372
406
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: SpatialControlsComponent, deps: [{ token: VISUALIZER }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); }
373
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.9", type: SpatialControlsComponent, isStandalone: true, selector: "spatial-controls", inputs: { visible: "visible", is3d: "is3d" }, outputs: { visibleChange: "visibleChange" }, viewQueries: [{ propertyName: "charts", first: true, predicate: SpatialChartsComponent, descendants: true }], ngImport: i0, template: "<p-dialog\n header=\"Spatial omics\"\n [visible]=\"visible\"\n (visibleChange)=\"onVisibleChange($event)\"\n [modal]=\"false\"\n [resizable]=\"true\"\n [draggable]=\"true\"\n position=\"left\"\n (onResizeEnd)=\"onResizeEnd()\"\n [style]=\"{ width: '30rem' }\"\n [breakpoints]=\"{ '960px': '90vw' }\"\n styleClass=\"spatial-controls-dialog\"\n>\n <!-- No port bound: say why rather than showing controls that do nothing. -->\n <div class=\"sc-empty\" *ngIf=\"!controls\">\n No spatial-omics data source is configured. A host provides one by binding\n <code>SPATIAL_DATA_PORT</code>.\n </div>\n\n <div class=\"sc-empty\" *ngIf=\"controls && !dataset\">No dataset is loaded.</div>\n\n <div class=\"sc-body\" *ngIf=\"controls && dataset as ds\">\n <div class=\"sc-dataset\">\n <span class=\"sc-dataset-name\">{{ ds.name }}</span>\n <span class=\"sc-dataset-count\">{{ ds.observations.count | number }} observations</span>\n </div>\n\n <!-- Organised as Xenium Explorer's side panel: one collapsible section per layer,\n each with its own on/off switch in the header. -->\n\n <!-- Images -->\n <div class=\"sc-panel\" *ngIf=\"ds.imageRef && !is3d\" [class.open]=\"open.images\">\n <div class=\"sc-panel-head\" (click)=\"toggleSection('images')\">\n <p-checkbox\n [binary]=\"true\"\n [ngModel]=\"view.showImage\"\n (click)=\"$event.stopPropagation()\"\n (onChange)=\"onShowImage($event.checked)\"\n ></p-checkbox>\n <span class=\"sc-panel-title\">Images</span>\n <i class=\"pi\" [class.pi-chevron-down]=\"open.images\" [class.pi-chevron-right]=\"!open.images\"></i>\n </div>\n <div class=\"sc-panel-body\" *ngIf=\"open.images\">\n <small class=\"sc-hint\"> Channels, colours and contrast are in the Channels &amp; Histogram dialog. </small>\n </div>\n </div>\n\n <!-- Cells -->\n <spatial-cells-panel\n *ngIf=\"hasCells && !is3d\"\n [controls]=\"controls\"\n [dataset]=\"ds\"\n [view]=\"view\"\n [genes]=\"genes\"\n [colorBarCss]=\"colorBarCss\"\n [open]=\"open.cells\"\n (openChange)=\"setOpen('cells', $event)\"\n ></spatial-cells-panel>\n\n <!-- Transcripts -->\n <spatial-transcripts-panel\n *ngIf=\"hasTranscripts && (!is3d || hasTranscripts3d)\"\n [controls]=\"controls\"\n [dataset]=\"ds\"\n [view]=\"view\"\n [genes]=\"genes\"\n [estimate]=\"estimate\"\n [densityStats]=\"densityStats\"\n [geneCounts]=\"geneCounts\"\n [colormapOptions]=\"colormapOptions\"\n [open]=\"open.transcripts\"\n (openChange)=\"setOpen('transcripts', $event)\"\n >\n </spatial-transcripts-panel>\n\n <!-- Annotations: the drawn regions, and selecting what they enclose. -->\n <div class=\"sc-panel\" [class.open]=\"open.annotations\">\n <div class=\"sc-panel-head\" (click)=\"toggleSection('annotations')\">\n <p-checkbox\n [binary]=\"true\"\n [ngModel]=\"view.showAnnotations !== false\"\n (click)=\"$event.stopPropagation()\"\n (onChange)=\"onShowAnnotations($event.checked)\"\n pTooltip=\"Show the drawn regions\"\n tooltipPosition=\"top\"\n ></p-checkbox>\n <span class=\"sc-panel-title\">Annotations</span>\n <i class=\"pi\" [class.pi-chevron-down]=\"open.annotations\" [class.pi-chevron-right]=\"!open.annotations\"></i>\n </div>\n <div class=\"sc-panel-body\" *ngIf=\"open.annotations\">\n <div class=\"sc-row\">\n <p-button\n label=\"Select from ROIs\"\n icon=\"pi pi-object-group\"\n size=\"small\"\n [outlined]=\"true\"\n [loading]=\"selectingFromRegions\"\n (onClick)=\"selectFromRegions()\"\n [pTooltip]=\"\n selectsClassVolumes\n ? 'Select every observation inside the volumes of the classes picked in the Region Editor'\n : 'Select every observation inside the drawn regions'\n \"\n tooltipPosition=\"top\"\n ></p-button>\n <p-button\n *ngIf=\"hasSelection\"\n label=\"Clear\"\n size=\"small\"\n [text]=\"true\"\n (onClick)=\"clearSelection()\"\n ></p-button>\n </div>\n <small class=\"sc-hint\" *ngIf=\"hasSelection\">\n {{ selection.count | number }} of {{ ds.observations.count | number }} selected \u2014 the rest are muted.\n </small>\n <small class=\"sc-hint\" *ngIf=\"selectionMissed\">\n No observations fell inside the\n {{ missedMode === 'class-volumes' ? 'picked classes' : 'drawn regions' }}.\n </small>\n <small class=\"sc-hint\" *ngIf=\"selectsClassVolumes\">\n Selects inside the volume of {{ pickedClasses[0]\n }}{{ pickedClasses.length > 1 ? ' and ' + (pickedClasses.length - 1 | number) + ' more classes' : '' }},\n picked in the Region Editor. Draw a region to select by it instead.\n </small>\n <small class=\"sc-hint\" *ngIf=\"is3d && !selectsClassVolumes && pickedClasses.length\">\n The classes picked in the Region Editor are not on the reference volume shown here, so this selects by\n the regions drawn over the cloud instead.\n </small>\n <small class=\"sc-hint\" *ngIf=\"is3d && !selectsClassVolumes\">\n In 3D a region cuts through the cloud's full depth. Orbit and draw again to cut from another angle.\n <ng-container *ngIf=\"!pickedClasses.length\">\n Pick classes in the Region Editor's class tree to select inside their volumes.\n </ng-container>\n </small>\n </div>\n </div>\n\n <!-- Observations, then what else draws them: the gene map, the 3D scene, and the\n continuous-only knobs. -->\n <spatial-observations-panel\n [controls]=\"controls\"\n [dataset]=\"ds\"\n [view]=\"view\"\n [genes]=\"genes\"\n [legend]=\"legend\"\n [colorBarCss]=\"colorBarCss\"\n [selection]=\"selection\"\n [selectedCategory]=\"selectedCategory\"\n [colormapOptions]=\"colormapOptions\"\n [is3d]=\"is3d\"\n [open]=\"open.observations\"\n (openChange)=\"setOpen('observations', $event)\"\n (categoryClicked)=\"selectCategory($event)\"\n ></spatial-observations-panel>\n\n <!-- Distributions of whatever the map is coloured by. In the SAME dialog as\n the colour controls on purpose: changing the gene and watching the\n distribution move is one action, and two floating windows made that\n harder to see rather than easier. -->\n <div class=\"sc-section sc-charts\">\n <button\n type=\"button\"\n class=\"sc-disclosure\"\n (click)=\"toggleCharts()\"\n [attr.aria-expanded]=\"chartsOpen\"\n [attr.aria-controls]=\"chartsBodyId\"\n >\n <i class=\"pi\" [class.pi-chevron-right]=\"!chartsOpen\" [class.pi-chevron-down]=\"chartsOpen\"></i>\n <span>Distribution</span>\n <small *ngIf=\"!chartsOpen && view.colorBy\">of {{ colorByLabel }}</small>\n </button>\n <!-- Kept MOUNTED when collapsed, only hidden: destroying it would throw\n away the chart kind and grouping the user picked. `active` is what\n stops it drawing while it has no size. -->\n <div [id]=\"chartsBodyId\" [hidden]=\"!chartsOpen\">\n <spatial-charts [active]=\"visible && chartsOpen\"></spatial-charts>\n </div>\n </div>\n\n <div class=\"sc-btns\">\n <p-button label=\"Reset\" size=\"small\" [text]=\"true\" (onClick)=\"reset()\"></p-button>\n </div>\n </div>\n</p-dialog>\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 ::ng-deep .spatial-controls-dialog .p-dialog-content{padding:.75rem 1rem 1rem}.sc-empty{padding:.5rem 0;font-size:.85rem;color:var(--text-color-secondary, #6c757d);line-height:1.4}.sc-empty code{font-size:.8rem}.sc-body{display:flex;flex-direction:column;gap:.85rem}.sc-dataset{display:flex;flex-direction:column;gap:.1rem;padding-bottom:.5rem;border-bottom:1px solid var(--surface-border, #dee2e6)}.sc-dataset-name{font-weight:600;font-size:.9rem}.sc-dataset-count{font-size:.75rem;color:var(--text-color-secondary, #6c757d)}.sc-btns{display:flex;justify-content:flex-end}.sc-charts{padding-top:.5rem;border-top:1px solid var(--surface-border, #dee2e6);gap:0}.sc-disclosure{display:flex;align-items:center;gap:.4rem;width:100%;padding:.2rem 0;font:inherit;font-size:.82rem;font-weight:600;text-align:left;background:none;border:0;cursor:pointer;color:inherit}.sc-disclosure i{font-size:.7rem;color:var(--text-color-secondary, #6c757d)}.sc-disclosure small{font-weight:400;color:var(--text-color-secondary, #6c757d);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sc-disclosure:hover{color:var(--primary-color, #3b82f6)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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: ButtonModule }, { kind: "component", type: i3.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "style", "styleClass", "badgeClass", "ariaLabel", "autofocus"], outputs: ["onClick", "onFocus", "onBlur"] }, { 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: DialogModule }, { kind: "component", type: i5.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "visible", "style", "position"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i6.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "component", type: SpatialCellsPanelComponent, selector: "spatial-cells-panel", inputs: ["controls", "dataset", "view", "genes", "colorBarCss", "open"], outputs: ["openChange"] }, { kind: "component", type: SpatialTranscriptsPanelComponent, selector: "spatial-transcripts-panel", inputs: ["controls", "dataset", "view", "genes", "estimate", "densityStats", "geneCounts", "colormapOptions", "open"], outputs: ["openChange"] }, { kind: "component", type: SpatialObservationsPanelComponent, selector: "spatial-observations-panel", inputs: ["controls", "dataset", "view", "genes", "legend", "colorBarCss", "selection", "selectedCategory", "colormapOptions", "is3d", "open"], outputs: ["openChange", "categoryClicked"] }, { kind: "component", type: SpatialChartsComponent, selector: "spatial-charts", inputs: ["active"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
407
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.9", type: SpatialControlsComponent, isStandalone: true, selector: "spatial-controls", inputs: { visible: "visible", is3d: "is3d" }, outputs: { visibleChange: "visibleChange" }, viewQueries: [{ propertyName: "charts", first: true, predicate: SpatialChartsComponent, descendants: true }], ngImport: i0, template: "<p-dialog\n header=\"Spatial omics\"\n [visible]=\"visible\"\n (visibleChange)=\"onVisibleChange($event)\"\n [modal]=\"false\"\n [resizable]=\"true\"\n [draggable]=\"true\"\n position=\"left\"\n (onResizeEnd)=\"onResizeEnd()\"\n [style]=\"{ width: '30rem' }\"\n [breakpoints]=\"{ '960px': '90vw' }\"\n styleClass=\"spatial-controls-dialog\"\n>\n <!-- No port bound: say why rather than showing controls that do nothing. -->\n <div class=\"sc-empty\" *ngIf=\"!controls\">\n No spatial-omics data source is configured. A host provides one by binding\n <code>SPATIAL_DATA_PORT</code>.\n </div>\n\n <div class=\"sc-empty\" *ngIf=\"controls && !dataset\">No dataset is loaded.</div>\n\n <div class=\"sc-body\" *ngIf=\"controls && dataset as ds\">\n <div class=\"sc-dataset\">\n <span class=\"sc-dataset-name\">{{ ds.name }}</span>\n <span class=\"sc-dataset-count\">{{ ds.observations.count | number }} observations</span>\n </div>\n\n <!-- Organised as Xenium Explorer's side panel: one collapsible section per layer,\n each with its own on/off switch in the header. -->\n\n <!-- Images -->\n <div class=\"sc-panel\" *ngIf=\"ds.imageRef && !is3d\" [class.open]=\"open.images\">\n <div class=\"sc-panel-head\" (click)=\"toggleSection('images')\">\n <p-checkbox\n [binary]=\"true\"\n [ngModel]=\"view.showImage\"\n (click)=\"$event.stopPropagation()\"\n (onChange)=\"onShowImage($event.checked)\"\n ></p-checkbox>\n <span class=\"sc-panel-title\">Images</span>\n <i class=\"pi\" [class.pi-chevron-down]=\"open.images\" [class.pi-chevron-right]=\"!open.images\"></i>\n </div>\n <div class=\"sc-panel-body\" *ngIf=\"open.images\">\n <small class=\"sc-hint\"> Channels, colours and contrast are in the Channels &amp; Histogram dialog. </small>\n </div>\n </div>\n\n <!-- Volume: in 3D, the Images section's place: the reference volume the observations sit in. -->\n <div class=\"sc-panel\" *ngIf=\"ds.volume && is3d\" [class.open]=\"open.volume\">\n <div class=\"sc-panel-head\" (click)=\"toggleSection('volume')\">\n <p-checkbox\n [binary]=\"true\"\n [ngModel]=\"view.showVolume\"\n (click)=\"$event.stopPropagation()\"\n (onChange)=\"onShowVolume($event.checked)\"\n ></p-checkbox>\n <span class=\"sc-panel-title\">Volume</span>\n <i class=\"pi\" [class.pi-chevron-down]=\"open.volume\" [class.pi-chevron-right]=\"!open.volume\"></i>\n </div>\n <div class=\"sc-panel-body\" *ngIf=\"open.volume\">\n <!-- Its own opacity: reading the cloud or a density field through the anatomy means turning\n the anatomy down, not the data. -->\n <div class=\"sc-row\">\n <span class=\"sc-lbl\">Opacity</span>\n <p-slider\n [ngModel]=\"view.volumeOpacity\"\n [min]=\"0.05\"\n [max]=\"1\"\n [step]=\"0.05\"\n [disabled]=\"!view.showVolume\"\n (onChange)=\"onVolumeOpacity($event.value)\"\n ></p-slider>\n <span class=\"sc-val\">{{ view.volumeOpacity }}</span>\n </div>\n <small class=\"sc-hint\">The registered anatomy the observations sit in.</small>\n </div>\n </div>\n\n <!-- Transcripts -->\n <spatial-transcripts-panel\n *ngIf=\"hasTranscripts && (!is3d || hasTranscripts3d)\"\n [controls]=\"controls\"\n [dataset]=\"ds\"\n [view]=\"view\"\n [genes]=\"genes\"\n [estimate]=\"estimate\"\n [densityStats]=\"densityStats\"\n [geneCounts]=\"geneCounts\"\n [colormapOptions]=\"colormapOptions\"\n [is3d]=\"is3d\"\n [open]=\"open.transcripts\"\n (openChange)=\"setOpen('transcripts', $event)\"\n >\n </spatial-transcripts-panel>\n\n <!-- Observations, then what else draws them: the gene map, the 3D scene, and the\n continuous-only knobs. -->\n <spatial-observations-panel\n [controls]=\"controls\"\n [dataset]=\"ds\"\n [view]=\"view\"\n [genes]=\"genes\"\n [legend]=\"legend\"\n [colorBarCss]=\"colorBarCss\"\n [selection]=\"selection\"\n [selectedCategory]=\"selectedCategory\"\n [colormapOptions]=\"colormapOptions\"\n [is3d]=\"is3d\"\n [cellsAvailable]=\"hasCells && (!is3d || hasCells3d)\"\n [open]=\"open.observations\"\n (openChange)=\"setOpen('observations', $event)\"\n (categoryClicked)=\"selectCategory($event)\"\n >\n <!-- Cell segmentations: with a cell segmentation (in 3D, a 3D one), how the cells are drawn\n while the Observations are shown as them. -->\n <spatial-cells-panel\n *ngIf=\"hasCells && (!is3d || hasCells3d)\"\n [controls]=\"controls\"\n [dataset]=\"ds\"\n [view]=\"view\"\n [is3d]=\"is3d\"\n [cells3dStatus]=\"cells3dStatus\"\n ></spatial-cells-panel>\n </spatial-observations-panel>\n\n <!-- Regions, under the Observations: the drawn regions, and selecting what they enclose. Off by\n default; the dataset's own region set is the Cell segmentations'. -->\n <div class=\"sc-panel\" [class.open]=\"open.annotations\">\n <div class=\"sc-panel-head\" (click)=\"toggleSection('annotations')\">\n <p-checkbox\n [binary]=\"true\"\n [ngModel]=\"view.showAnnotations !== false\"\n (click)=\"$event.stopPropagation()\"\n (onChange)=\"onShowAnnotations($event.checked)\"\n pTooltip=\"Show the regions\"\n tooltipPosition=\"top\"\n ></p-checkbox>\n <span class=\"sc-panel-title\">Regions</span>\n <i class=\"pi\" [class.pi-chevron-down]=\"open.annotations\" [class.pi-chevron-right]=\"!open.annotations\"></i>\n </div>\n <div class=\"sc-panel-body\" *ngIf=\"open.annotations\">\n <div class=\"sc-row\">\n <p-button\n label=\"Select from ROIs\"\n icon=\"pi pi-object-group\"\n size=\"small\"\n [outlined]=\"true\"\n [loading]=\"selectingFromRegions\"\n (onClick)=\"selectFromRegions()\"\n [pTooltip]=\"\n selectsClassVolumes\n ? 'Select every observation inside the volumes of the classes picked in the Region Editor'\n : 'Select every observation inside the drawn regions'\n \"\n tooltipPosition=\"top\"\n ></p-button>\n <p-button\n *ngIf=\"hasSelection\"\n label=\"Clear\"\n size=\"small\"\n [text]=\"true\"\n (onClick)=\"clearSelection()\"\n ></p-button>\n </div>\n <small class=\"sc-hint\" *ngIf=\"hasSelection\">\n {{ selection.count | number }} of {{ ds.observations.count | number }} selected \u2014 the rest are muted.\n </small>\n <small class=\"sc-hint\" *ngIf=\"selectionMissed\">\n No observations fell inside the\n {{ missedMode === 'class-volumes' ? 'picked classes' : 'drawn regions' }}.\n </small>\n <small class=\"sc-hint\" *ngIf=\"selectsClassVolumes\">\n Selects inside the volume of {{ pickedClasses[0]\n }}{{ pickedClasses.length > 1 ? ' and ' + (pickedClasses.length - 1 | number) + ' more classes' : '' }},\n picked in the Region Editor. Draw a region to select by it instead.\n </small>\n <small class=\"sc-hint\" *ngIf=\"is3d && !selectsClassVolumes && pickedClasses.length\">\n The classes picked in the Region Editor are not on the reference volume shown here, so this selects by\n the regions drawn over the cloud instead.\n </small>\n <small class=\"sc-hint\" *ngIf=\"is3d && !selectsClassVolumes\">\n In 3D a region cuts through the cloud's full depth. Orbit and draw again to cut from another angle.\n <ng-container *ngIf=\"!pickedClasses.length\">\n Pick classes in the Region Editor's class tree to select inside their volumes.\n </ng-container>\n </small>\n </div>\n </div>\n\n <!-- Distributions of whatever the map is coloured by. In the SAME dialog as\n the colour controls on purpose: changing the gene and watching the\n distribution move is one action, and two floating windows made that\n harder to see rather than easier. -->\n <div class=\"sc-section sc-charts\">\n <button\n type=\"button\"\n class=\"sc-disclosure\"\n (click)=\"toggleCharts()\"\n [attr.aria-expanded]=\"chartsOpen\"\n [attr.aria-controls]=\"chartsBodyId\"\n >\n <i class=\"pi\" [class.pi-chevron-right]=\"!chartsOpen\" [class.pi-chevron-down]=\"chartsOpen\"></i>\n <span>Distribution</span>\n <small *ngIf=\"!chartsOpen && view.colorBy\">of {{ colorByLabel }}</small>\n </button>\n <!-- Kept MOUNTED when collapsed, only hidden: destroying it would throw\n away the chart kind and grouping the user picked. `active` is what\n stops it drawing while it has no size. -->\n <div [id]=\"chartsBodyId\" [hidden]=\"!chartsOpen\">\n <spatial-charts [active]=\"visible && chartsOpen\"></spatial-charts>\n </div>\n </div>\n\n <div class=\"sc-btns\">\n <p-button label=\"Reset\" size=\"small\" [text]=\"true\" (onClick)=\"reset()\"></p-button>\n </div>\n </div>\n</p-dialog>\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 ::ng-deep .spatial-controls-dialog .p-dialog-content{padding:.75rem 1rem 1rem}.sc-empty{padding:.5rem 0;font-size:.85rem;color:var(--text-color-secondary, #6c757d);line-height:1.4}.sc-empty code{font-size:.8rem}.sc-body{display:flex;flex-direction:column;gap:.85rem}.sc-dataset{display:flex;flex-direction:column;gap:.1rem;padding-bottom:.5rem;border-bottom:1px solid var(--surface-border, #dee2e6)}.sc-dataset-name{font-weight:600;font-size:.9rem}.sc-dataset-count{font-size:.75rem;color:var(--text-color-secondary, #6c757d)}.sc-btns{display:flex;justify-content:flex-end}.sc-charts{padding-top:.5rem;border-top:1px solid var(--surface-border, #dee2e6);gap:0}.sc-disclosure{display:flex;align-items:center;gap:.4rem;width:100%;padding:.2rem 0;font:inherit;font-size:.82rem;font-weight:600;text-align:left;background:none;border:0;cursor:pointer;color:inherit}.sc-disclosure i{font-size:.7rem;color:var(--text-color-secondary, #6c757d)}.sc-disclosure small{font-weight:400;color:var(--text-color-secondary, #6c757d);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sc-disclosure:hover{color:var(--primary-color, #3b82f6)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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: ButtonModule }, { kind: "component", type: i3.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "style", "styleClass", "badgeClass", "ariaLabel", "autofocus"], outputs: ["onClick", "onFocus", "onBlur"] }, { 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: SliderModule }, { kind: "component", type: i5.Slider, selector: "p-slider", inputs: ["animate", "disabled", "min", "max", "orientation", "step", "range", "style", "styleClass", "ariaLabel", "ariaLabelledBy", "tabindex", "autofocus"], outputs: ["onChange", "onSlideEnd"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i6.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "visible", "style", "position"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i7.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "component", type: SpatialCellsPanelComponent, selector: "spatial-cells-panel", inputs: ["controls", "dataset", "view", "is3d", "cells3dStatus"] }, { kind: "component", type: SpatialTranscriptsPanelComponent, selector: "spatial-transcripts-panel", inputs: ["controls", "dataset", "is3d", "view", "genes", "estimate", "densityStats", "geneCounts", "colormapOptions", "open"], outputs: ["openChange"] }, { kind: "component", type: SpatialObservationsPanelComponent, selector: "spatial-observations-panel", inputs: ["controls", "dataset", "view", "genes", "legend", "colorBarCss", "selection", "selectedCategory", "colormapOptions", "is3d", "open", "cellsAvailable"], outputs: ["openChange", "categoryClicked"] }, { kind: "component", type: SpatialChartsComponent, selector: "spatial-charts", inputs: ["active"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
374
408
  }
375
409
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: SpatialControlsComponent, decorators: [{
376
410
  type: Component,
@@ -379,13 +413,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImpor
379
413
  FormsModule,
380
414
  ButtonModule,
381
415
  CheckboxModule,
416
+ SliderModule,
382
417
  DialogModule,
383
418
  TooltipModule,
384
419
  SpatialCellsPanelComponent,
385
420
  SpatialTranscriptsPanelComponent,
386
421
  SpatialObservationsPanelComponent,
387
422
  SpatialChartsComponent,
388
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<p-dialog\n header=\"Spatial omics\"\n [visible]=\"visible\"\n (visibleChange)=\"onVisibleChange($event)\"\n [modal]=\"false\"\n [resizable]=\"true\"\n [draggable]=\"true\"\n position=\"left\"\n (onResizeEnd)=\"onResizeEnd()\"\n [style]=\"{ width: '30rem' }\"\n [breakpoints]=\"{ '960px': '90vw' }\"\n styleClass=\"spatial-controls-dialog\"\n>\n <!-- No port bound: say why rather than showing controls that do nothing. -->\n <div class=\"sc-empty\" *ngIf=\"!controls\">\n No spatial-omics data source is configured. A host provides one by binding\n <code>SPATIAL_DATA_PORT</code>.\n </div>\n\n <div class=\"sc-empty\" *ngIf=\"controls && !dataset\">No dataset is loaded.</div>\n\n <div class=\"sc-body\" *ngIf=\"controls && dataset as ds\">\n <div class=\"sc-dataset\">\n <span class=\"sc-dataset-name\">{{ ds.name }}</span>\n <span class=\"sc-dataset-count\">{{ ds.observations.count | number }} observations</span>\n </div>\n\n <!-- Organised as Xenium Explorer's side panel: one collapsible section per layer,\n each with its own on/off switch in the header. -->\n\n <!-- Images -->\n <div class=\"sc-panel\" *ngIf=\"ds.imageRef && !is3d\" [class.open]=\"open.images\">\n <div class=\"sc-panel-head\" (click)=\"toggleSection('images')\">\n <p-checkbox\n [binary]=\"true\"\n [ngModel]=\"view.showImage\"\n (click)=\"$event.stopPropagation()\"\n (onChange)=\"onShowImage($event.checked)\"\n ></p-checkbox>\n <span class=\"sc-panel-title\">Images</span>\n <i class=\"pi\" [class.pi-chevron-down]=\"open.images\" [class.pi-chevron-right]=\"!open.images\"></i>\n </div>\n <div class=\"sc-panel-body\" *ngIf=\"open.images\">\n <small class=\"sc-hint\"> Channels, colours and contrast are in the Channels &amp; Histogram dialog. </small>\n </div>\n </div>\n\n <!-- Cells -->\n <spatial-cells-panel\n *ngIf=\"hasCells && !is3d\"\n [controls]=\"controls\"\n [dataset]=\"ds\"\n [view]=\"view\"\n [genes]=\"genes\"\n [colorBarCss]=\"colorBarCss\"\n [open]=\"open.cells\"\n (openChange)=\"setOpen('cells', $event)\"\n ></spatial-cells-panel>\n\n <!-- Transcripts -->\n <spatial-transcripts-panel\n *ngIf=\"hasTranscripts && (!is3d || hasTranscripts3d)\"\n [controls]=\"controls\"\n [dataset]=\"ds\"\n [view]=\"view\"\n [genes]=\"genes\"\n [estimate]=\"estimate\"\n [densityStats]=\"densityStats\"\n [geneCounts]=\"geneCounts\"\n [colormapOptions]=\"colormapOptions\"\n [open]=\"open.transcripts\"\n (openChange)=\"setOpen('transcripts', $event)\"\n >\n </spatial-transcripts-panel>\n\n <!-- Annotations: the drawn regions, and selecting what they enclose. -->\n <div class=\"sc-panel\" [class.open]=\"open.annotations\">\n <div class=\"sc-panel-head\" (click)=\"toggleSection('annotations')\">\n <p-checkbox\n [binary]=\"true\"\n [ngModel]=\"view.showAnnotations !== false\"\n (click)=\"$event.stopPropagation()\"\n (onChange)=\"onShowAnnotations($event.checked)\"\n pTooltip=\"Show the drawn regions\"\n tooltipPosition=\"top\"\n ></p-checkbox>\n <span class=\"sc-panel-title\">Annotations</span>\n <i class=\"pi\" [class.pi-chevron-down]=\"open.annotations\" [class.pi-chevron-right]=\"!open.annotations\"></i>\n </div>\n <div class=\"sc-panel-body\" *ngIf=\"open.annotations\">\n <div class=\"sc-row\">\n <p-button\n label=\"Select from ROIs\"\n icon=\"pi pi-object-group\"\n size=\"small\"\n [outlined]=\"true\"\n [loading]=\"selectingFromRegions\"\n (onClick)=\"selectFromRegions()\"\n [pTooltip]=\"\n selectsClassVolumes\n ? 'Select every observation inside the volumes of the classes picked in the Region Editor'\n : 'Select every observation inside the drawn regions'\n \"\n tooltipPosition=\"top\"\n ></p-button>\n <p-button\n *ngIf=\"hasSelection\"\n label=\"Clear\"\n size=\"small\"\n [text]=\"true\"\n (onClick)=\"clearSelection()\"\n ></p-button>\n </div>\n <small class=\"sc-hint\" *ngIf=\"hasSelection\">\n {{ selection.count | number }} of {{ ds.observations.count | number }} selected \u2014 the rest are muted.\n </small>\n <small class=\"sc-hint\" *ngIf=\"selectionMissed\">\n No observations fell inside the\n {{ missedMode === 'class-volumes' ? 'picked classes' : 'drawn regions' }}.\n </small>\n <small class=\"sc-hint\" *ngIf=\"selectsClassVolumes\">\n Selects inside the volume of {{ pickedClasses[0]\n }}{{ pickedClasses.length > 1 ? ' and ' + (pickedClasses.length - 1 | number) + ' more classes' : '' }},\n picked in the Region Editor. Draw a region to select by it instead.\n </small>\n <small class=\"sc-hint\" *ngIf=\"is3d && !selectsClassVolumes && pickedClasses.length\">\n The classes picked in the Region Editor are not on the reference volume shown here, so this selects by\n the regions drawn over the cloud instead.\n </small>\n <small class=\"sc-hint\" *ngIf=\"is3d && !selectsClassVolumes\">\n In 3D a region cuts through the cloud's full depth. Orbit and draw again to cut from another angle.\n <ng-container *ngIf=\"!pickedClasses.length\">\n Pick classes in the Region Editor's class tree to select inside their volumes.\n </ng-container>\n </small>\n </div>\n </div>\n\n <!-- Observations, then what else draws them: the gene map, the 3D scene, and the\n continuous-only knobs. -->\n <spatial-observations-panel\n [controls]=\"controls\"\n [dataset]=\"ds\"\n [view]=\"view\"\n [genes]=\"genes\"\n [legend]=\"legend\"\n [colorBarCss]=\"colorBarCss\"\n [selection]=\"selection\"\n [selectedCategory]=\"selectedCategory\"\n [colormapOptions]=\"colormapOptions\"\n [is3d]=\"is3d\"\n [open]=\"open.observations\"\n (openChange)=\"setOpen('observations', $event)\"\n (categoryClicked)=\"selectCategory($event)\"\n ></spatial-observations-panel>\n\n <!-- Distributions of whatever the map is coloured by. In the SAME dialog as\n the colour controls on purpose: changing the gene and watching the\n distribution move is one action, and two floating windows made that\n harder to see rather than easier. -->\n <div class=\"sc-section sc-charts\">\n <button\n type=\"button\"\n class=\"sc-disclosure\"\n (click)=\"toggleCharts()\"\n [attr.aria-expanded]=\"chartsOpen\"\n [attr.aria-controls]=\"chartsBodyId\"\n >\n <i class=\"pi\" [class.pi-chevron-right]=\"!chartsOpen\" [class.pi-chevron-down]=\"chartsOpen\"></i>\n <span>Distribution</span>\n <small *ngIf=\"!chartsOpen && view.colorBy\">of {{ colorByLabel }}</small>\n </button>\n <!-- Kept MOUNTED when collapsed, only hidden: destroying it would throw\n away the chart kind and grouping the user picked. `active` is what\n stops it drawing while it has no size. -->\n <div [id]=\"chartsBodyId\" [hidden]=\"!chartsOpen\">\n <spatial-charts [active]=\"visible && chartsOpen\"></spatial-charts>\n </div>\n </div>\n\n <div class=\"sc-btns\">\n <p-button label=\"Reset\" size=\"small\" [text]=\"true\" (onClick)=\"reset()\"></p-button>\n </div>\n </div>\n</p-dialog>\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 ::ng-deep .spatial-controls-dialog .p-dialog-content{padding:.75rem 1rem 1rem}.sc-empty{padding:.5rem 0;font-size:.85rem;color:var(--text-color-secondary, #6c757d);line-height:1.4}.sc-empty code{font-size:.8rem}.sc-body{display:flex;flex-direction:column;gap:.85rem}.sc-dataset{display:flex;flex-direction:column;gap:.1rem;padding-bottom:.5rem;border-bottom:1px solid var(--surface-border, #dee2e6)}.sc-dataset-name{font-weight:600;font-size:.9rem}.sc-dataset-count{font-size:.75rem;color:var(--text-color-secondary, #6c757d)}.sc-btns{display:flex;justify-content:flex-end}.sc-charts{padding-top:.5rem;border-top:1px solid var(--surface-border, #dee2e6);gap:0}.sc-disclosure{display:flex;align-items:center;gap:.4rem;width:100%;padding:.2rem 0;font:inherit;font-size:.82rem;font-weight:600;text-align:left;background:none;border:0;cursor:pointer;color:inherit}.sc-disclosure i{font-size:.7rem;color:var(--text-color-secondary, #6c757d)}.sc-disclosure small{font-weight:400;color:var(--text-color-secondary, #6c757d);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sc-disclosure:hover{color:var(--primary-color, #3b82f6)}\n"] }]
423
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<p-dialog\n header=\"Spatial omics\"\n [visible]=\"visible\"\n (visibleChange)=\"onVisibleChange($event)\"\n [modal]=\"false\"\n [resizable]=\"true\"\n [draggable]=\"true\"\n position=\"left\"\n (onResizeEnd)=\"onResizeEnd()\"\n [style]=\"{ width: '30rem' }\"\n [breakpoints]=\"{ '960px': '90vw' }\"\n styleClass=\"spatial-controls-dialog\"\n>\n <!-- No port bound: say why rather than showing controls that do nothing. -->\n <div class=\"sc-empty\" *ngIf=\"!controls\">\n No spatial-omics data source is configured. A host provides one by binding\n <code>SPATIAL_DATA_PORT</code>.\n </div>\n\n <div class=\"sc-empty\" *ngIf=\"controls && !dataset\">No dataset is loaded.</div>\n\n <div class=\"sc-body\" *ngIf=\"controls && dataset as ds\">\n <div class=\"sc-dataset\">\n <span class=\"sc-dataset-name\">{{ ds.name }}</span>\n <span class=\"sc-dataset-count\">{{ ds.observations.count | number }} observations</span>\n </div>\n\n <!-- Organised as Xenium Explorer's side panel: one collapsible section per layer,\n each with its own on/off switch in the header. -->\n\n <!-- Images -->\n <div class=\"sc-panel\" *ngIf=\"ds.imageRef && !is3d\" [class.open]=\"open.images\">\n <div class=\"sc-panel-head\" (click)=\"toggleSection('images')\">\n <p-checkbox\n [binary]=\"true\"\n [ngModel]=\"view.showImage\"\n (click)=\"$event.stopPropagation()\"\n (onChange)=\"onShowImage($event.checked)\"\n ></p-checkbox>\n <span class=\"sc-panel-title\">Images</span>\n <i class=\"pi\" [class.pi-chevron-down]=\"open.images\" [class.pi-chevron-right]=\"!open.images\"></i>\n </div>\n <div class=\"sc-panel-body\" *ngIf=\"open.images\">\n <small class=\"sc-hint\"> Channels, colours and contrast are in the Channels &amp; Histogram dialog. </small>\n </div>\n </div>\n\n <!-- Volume: in 3D, the Images section's place: the reference volume the observations sit in. -->\n <div class=\"sc-panel\" *ngIf=\"ds.volume && is3d\" [class.open]=\"open.volume\">\n <div class=\"sc-panel-head\" (click)=\"toggleSection('volume')\">\n <p-checkbox\n [binary]=\"true\"\n [ngModel]=\"view.showVolume\"\n (click)=\"$event.stopPropagation()\"\n (onChange)=\"onShowVolume($event.checked)\"\n ></p-checkbox>\n <span class=\"sc-panel-title\">Volume</span>\n <i class=\"pi\" [class.pi-chevron-down]=\"open.volume\" [class.pi-chevron-right]=\"!open.volume\"></i>\n </div>\n <div class=\"sc-panel-body\" *ngIf=\"open.volume\">\n <!-- Its own opacity: reading the cloud or a density field through the anatomy means turning\n the anatomy down, not the data. -->\n <div class=\"sc-row\">\n <span class=\"sc-lbl\">Opacity</span>\n <p-slider\n [ngModel]=\"view.volumeOpacity\"\n [min]=\"0.05\"\n [max]=\"1\"\n [step]=\"0.05\"\n [disabled]=\"!view.showVolume\"\n (onChange)=\"onVolumeOpacity($event.value)\"\n ></p-slider>\n <span class=\"sc-val\">{{ view.volumeOpacity }}</span>\n </div>\n <small class=\"sc-hint\">The registered anatomy the observations sit in.</small>\n </div>\n </div>\n\n <!-- Transcripts -->\n <spatial-transcripts-panel\n *ngIf=\"hasTranscripts && (!is3d || hasTranscripts3d)\"\n [controls]=\"controls\"\n [dataset]=\"ds\"\n [view]=\"view\"\n [genes]=\"genes\"\n [estimate]=\"estimate\"\n [densityStats]=\"densityStats\"\n [geneCounts]=\"geneCounts\"\n [colormapOptions]=\"colormapOptions\"\n [is3d]=\"is3d\"\n [open]=\"open.transcripts\"\n (openChange)=\"setOpen('transcripts', $event)\"\n >\n </spatial-transcripts-panel>\n\n <!-- Observations, then what else draws them: the gene map, the 3D scene, and the\n continuous-only knobs. -->\n <spatial-observations-panel\n [controls]=\"controls\"\n [dataset]=\"ds\"\n [view]=\"view\"\n [genes]=\"genes\"\n [legend]=\"legend\"\n [colorBarCss]=\"colorBarCss\"\n [selection]=\"selection\"\n [selectedCategory]=\"selectedCategory\"\n [colormapOptions]=\"colormapOptions\"\n [is3d]=\"is3d\"\n [cellsAvailable]=\"hasCells && (!is3d || hasCells3d)\"\n [open]=\"open.observations\"\n (openChange)=\"setOpen('observations', $event)\"\n (categoryClicked)=\"selectCategory($event)\"\n >\n <!-- Cell segmentations: with a cell segmentation (in 3D, a 3D one), how the cells are drawn\n while the Observations are shown as them. -->\n <spatial-cells-panel\n *ngIf=\"hasCells && (!is3d || hasCells3d)\"\n [controls]=\"controls\"\n [dataset]=\"ds\"\n [view]=\"view\"\n [is3d]=\"is3d\"\n [cells3dStatus]=\"cells3dStatus\"\n ></spatial-cells-panel>\n </spatial-observations-panel>\n\n <!-- Regions, under the Observations: the drawn regions, and selecting what they enclose. Off by\n default; the dataset's own region set is the Cell segmentations'. -->\n <div class=\"sc-panel\" [class.open]=\"open.annotations\">\n <div class=\"sc-panel-head\" (click)=\"toggleSection('annotations')\">\n <p-checkbox\n [binary]=\"true\"\n [ngModel]=\"view.showAnnotations !== false\"\n (click)=\"$event.stopPropagation()\"\n (onChange)=\"onShowAnnotations($event.checked)\"\n pTooltip=\"Show the regions\"\n tooltipPosition=\"top\"\n ></p-checkbox>\n <span class=\"sc-panel-title\">Regions</span>\n <i class=\"pi\" [class.pi-chevron-down]=\"open.annotations\" [class.pi-chevron-right]=\"!open.annotations\"></i>\n </div>\n <div class=\"sc-panel-body\" *ngIf=\"open.annotations\">\n <div class=\"sc-row\">\n <p-button\n label=\"Select from ROIs\"\n icon=\"pi pi-object-group\"\n size=\"small\"\n [outlined]=\"true\"\n [loading]=\"selectingFromRegions\"\n (onClick)=\"selectFromRegions()\"\n [pTooltip]=\"\n selectsClassVolumes\n ? 'Select every observation inside the volumes of the classes picked in the Region Editor'\n : 'Select every observation inside the drawn regions'\n \"\n tooltipPosition=\"top\"\n ></p-button>\n <p-button\n *ngIf=\"hasSelection\"\n label=\"Clear\"\n size=\"small\"\n [text]=\"true\"\n (onClick)=\"clearSelection()\"\n ></p-button>\n </div>\n <small class=\"sc-hint\" *ngIf=\"hasSelection\">\n {{ selection.count | number }} of {{ ds.observations.count | number }} selected \u2014 the rest are muted.\n </small>\n <small class=\"sc-hint\" *ngIf=\"selectionMissed\">\n No observations fell inside the\n {{ missedMode === 'class-volumes' ? 'picked classes' : 'drawn regions' }}.\n </small>\n <small class=\"sc-hint\" *ngIf=\"selectsClassVolumes\">\n Selects inside the volume of {{ pickedClasses[0]\n }}{{ pickedClasses.length > 1 ? ' and ' + (pickedClasses.length - 1 | number) + ' more classes' : '' }},\n picked in the Region Editor. Draw a region to select by it instead.\n </small>\n <small class=\"sc-hint\" *ngIf=\"is3d && !selectsClassVolumes && pickedClasses.length\">\n The classes picked in the Region Editor are not on the reference volume shown here, so this selects by\n the regions drawn over the cloud instead.\n </small>\n <small class=\"sc-hint\" *ngIf=\"is3d && !selectsClassVolumes\">\n In 3D a region cuts through the cloud's full depth. Orbit and draw again to cut from another angle.\n <ng-container *ngIf=\"!pickedClasses.length\">\n Pick classes in the Region Editor's class tree to select inside their volumes.\n </ng-container>\n </small>\n </div>\n </div>\n\n <!-- Distributions of whatever the map is coloured by. In the SAME dialog as\n the colour controls on purpose: changing the gene and watching the\n distribution move is one action, and two floating windows made that\n harder to see rather than easier. -->\n <div class=\"sc-section sc-charts\">\n <button\n type=\"button\"\n class=\"sc-disclosure\"\n (click)=\"toggleCharts()\"\n [attr.aria-expanded]=\"chartsOpen\"\n [attr.aria-controls]=\"chartsBodyId\"\n >\n <i class=\"pi\" [class.pi-chevron-right]=\"!chartsOpen\" [class.pi-chevron-down]=\"chartsOpen\"></i>\n <span>Distribution</span>\n <small *ngIf=\"!chartsOpen && view.colorBy\">of {{ colorByLabel }}</small>\n </button>\n <!-- Kept MOUNTED when collapsed, only hidden: destroying it would throw\n away the chart kind and grouping the user picked. `active` is what\n stops it drawing while it has no size. -->\n <div [id]=\"chartsBodyId\" [hidden]=\"!chartsOpen\">\n <spatial-charts [active]=\"visible && chartsOpen\"></spatial-charts>\n </div>\n </div>\n\n <div class=\"sc-btns\">\n <p-button label=\"Reset\" size=\"small\" [text]=\"true\" (onClick)=\"reset()\"></p-button>\n </div>\n </div>\n</p-dialog>\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 ::ng-deep .spatial-controls-dialog .p-dialog-content{padding:.75rem 1rem 1rem}.sc-empty{padding:.5rem 0;font-size:.85rem;color:var(--text-color-secondary, #6c757d);line-height:1.4}.sc-empty code{font-size:.8rem}.sc-body{display:flex;flex-direction:column;gap:.85rem}.sc-dataset{display:flex;flex-direction:column;gap:.1rem;padding-bottom:.5rem;border-bottom:1px solid var(--surface-border, #dee2e6)}.sc-dataset-name{font-weight:600;font-size:.9rem}.sc-dataset-count{font-size:.75rem;color:var(--text-color-secondary, #6c757d)}.sc-btns{display:flex;justify-content:flex-end}.sc-charts{padding-top:.5rem;border-top:1px solid var(--surface-border, #dee2e6);gap:0}.sc-disclosure{display:flex;align-items:center;gap:.4rem;width:100%;padding:.2rem 0;font:inherit;font-size:.82rem;font-weight:600;text-align:left;background:none;border:0;cursor:pointer;color:inherit}.sc-disclosure i{font-size:.7rem;color:var(--text-color-secondary, #6c757d)}.sc-disclosure small{font-weight:400;color:var(--text-color-secondary, #6c757d);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sc-disclosure:hover{color:var(--primary-color, #3b82f6)}\n"] }]
389
424
  }], ctorParameters: () => [{ type: undefined, decorators: [{
390
425
  type: Inject,
391
426
  args: [VISUALIZER]
@@ -399,4 +434,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImpor
399
434
  }], visibleChange: [{
400
435
  type: Output
401
436
  }] } });
402
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BhdGlhbC1jb250cm9scy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3NwYXRpYWwtY29udHJvbHMvc3BhdGlhbC1jb250cm9scy5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9zcmMvbGliL3NwYXRpYWwtY29udHJvbHMvc3BhdGlhbC1jb250cm9scy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsVUFBVSxFQUNWLFlBQVksRUFDWixNQUFNLEVBQ04sS0FBSyxFQUNMLE1BQU0sRUFFTixNQUFNLEVBQ04sU0FBUyxFQUNULE1BQU0sR0FDUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzdDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM5QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDbEQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNoRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRXJDLE9BQU8sRUFBRSxVQUFVLEVBQW1ELE1BQU0sa0NBQWtDLENBQUM7QUFDL0csT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sMkNBQTJDLENBQUM7QUFFbkYsT0FBTyxFQUFrQyxvQkFBb0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ2xHLE9BQU8sRUFBZSxlQUFlLEVBQUUsTUFBTSxn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R0FBRyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUMvRixDQUFDOzhHQXhYVSx3QkFBd0Isa0JBd0d6QixVQUFVO2tHQXhHVCx3QkFBd0IsK01BRXhCLHNCQUFzQixnRENuRm5DLDZtUEF5TEEsbTNMRHZISSxZQUFZLDBMQUNaLFdBQVcsOFZBQ1gsWUFBWSw2WEFDWixjQUFjLGdaQUNkLFlBQVksdXVCQUNaLGFBQWEsc1hBQ2IsMEJBQTBCLGtLQUMxQixnQ0FBZ0Msc05BQ2hDLGlDQUFpQyxrUUFDakMsc0JBQXNCOzsyRkFNYix3QkFBd0I7a0JBbkJwQyxTQUFTOytCQUNFLGtCQUFrQixjQUNoQixJQUFJLFdBQ1A7d0JBQ1AsWUFBWTt3QkFDWixXQUFXO3dCQUNYLFlBQVk7d0JBQ1osY0FBYzt3QkFDZCxZQUFZO3dCQUNaLGFBQWE7d0JBQ2IsMEJBQTBCO3dCQUMxQixnQ0FBZ0M7d0JBQ2hDLGlDQUFpQzt3QkFDakMsc0JBQXNCO3FCQUN2QixtQkFHZ0IsdUJBQXVCLENBQUMsTUFBTTs7MEJBMEc1QyxNQUFNOzJCQUFDLFVBQVU7OERBdEd1QixNQUFNO3NCQUFoRCxTQUFTO3VCQUFDLHNCQUFzQjtnQkFnQnhCLE9BQU87c0JBQWYsS0FBSztnQkFJRyxJQUFJO3NCQUFaLEtBQUs7Z0JBRUksYUFBYTtzQkFBdEIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBEZXN0cm95UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIEluamVjdCxcbiAgSW5wdXQsXG4gIE5nWm9uZSxcbiAgT25Jbml0LFxuICBPdXRwdXQsXG4gIFZpZXdDaGlsZCxcbiAgaW5qZWN0LFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IHRha2VVbnRpbERlc3Ryb3llZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUvcnhqcy1pbnRlcm9wJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBGb3Jtc01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IEJ1dHRvbk1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvYnV0dG9uJztcbmltcG9ydCB7IENoZWNrYm94TW9kdWxlIH0gZnJvbSAncHJpbWVuZy9jaGVja2JveCc7XG5pbXBvcnQgeyBEaWFsb2dNb2R1bGUgfSBmcm9tICdwcmltZW5nL2RpYWxvZyc7XG5pbXBvcnQgeyBUb29sdGlwTW9kdWxlIH0gZnJvbSAncHJpbWVuZy90b29sdGlwJztcbmltcG9ydCB7IGNvbWJpbmVMYXRlc3QgfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgVklTVUFMSVpFUiwgSVZpc3VhbGl6ZXIsIElTcGF0aWFsQ29udHJvbHMsIFJvaVNlbGVjdGlvbk1vZGUgfSBmcm9tICcuLi9jb250cmFjdHMvdmlzdWFsaXplci5jb250cmFjdCc7XG5pbXBvcnQgeyBTcGF0aWFsQ2hhcnRzQ29tcG9uZW50IH0gZnJvbSAnLi9zcGF0aWFsLWNoYXJ0cy9zcGF0aWFsLWNoYXJ0cy5jb21wb25lbnQnO1xuaW1wb3J0IHsgU3BhdGlhbERhdGFzZXQgfSBmcm9tICcuLi9jb250cmFjdHMvc3BhdGlhbC1kYXRhc2V0LmNvbnRyYWN0JztcbmltcG9ydCB7IENvbG9ybWFwTm9kZSwgU3BhdGlhbFZpZXdTdGF0ZSwgREVGQVVMVF9TUEFUSUFMX1ZJRVcgfSBmcm9tICcuLi9jb250cmFjdHMvZGlzcGxheS10eXBlcyc7XG5pbXBvcnQgeyBQYW5lbE9wdGlvbiwgcGFyc2VHZW5lR3JvdXBzIH0gZnJvbSAnLi4vc3BhdGlhbC9zcGF0aWFsLXBhbmVsLW1vZGVsJztcbmltcG9ydCB7IFNwYXRpYWxTZWxlY3Rpb25NYXNrLCBlbXB0eVNlbGVjdGlvbiB9IGZyb20gJy4uL3NwYXRpYWwvc3BhdGlhbC1zZWxlY3Rpb24nO1xuaW1wb3J0IHsgR2VuZVBpY2tlck1vZGVsIH0gZnJvbSAnLi9zcGF0aWFsLWdlbmUtcGlja2VyJztcbmltcG9ydCB7IFNwYXRpYWxLZXlNb2RlbCwgU3BhdGlhbExlZ2VuZEVudHJ5IH0gZnJvbSAnLi9zcGF0aWFsLWtleS9zcGF0aWFsLWtleS5tb2RlbCc7XG5pbXBvcnQgeyBjb2xvckJ5TGFiZWwgfSBmcm9tICcuL3NwYXRpYWwta2V5L3NwYXRpYWwta2V5LmNvbXBvbmVudCc7XG5pbXBvcnQgeyBTcGF0aWFsQ2VsbHNQYW5lbENvbXBvbmVudCB9IGZyb20gJy4vc3BhdGlhbC1jZWxscy1wYW5lbC9zcGF0aWFsLWNlbGxzLXBhbmVsLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBTcGF0aWFsVHJhbnNjcmlwdHNQYW5lbENvbXBvbmVudCB9IGZyb20gJy4vc3BhdGlhbC10cmFuc2NyaXB0cy1wYW5lbC9zcGF0aWFsLXRyYW5zY3JpcHRzLXBhbmVsLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBTcGF0aWFsT2JzZXJ2YXRpb25zUGFuZWxDb21wb25lbnQgfSBmcm9tICcuL3NwYXRpYWwtb2JzZXJ2YXRpb25zLXBhbmVsL3NwYXRpYWwtb2JzZXJ2YXRpb25zLXBhbmVsLmNvbXBvbmVudCc7XG5cbi8qKiBAZGVwcmVjYXRlZCBNb3ZlZCB0byBgc3BhdGlhbC1rZXkvc3BhdGlhbC1rZXkubW9kZWxgOyByZS1leHBvcnRlZCBmb3Igb25lIHJlbGVhc2UuICovXG5leHBvcnQgdHlwZSB7IFNwYXRpYWxMZWdlbmRFbnRyeSB9O1xuXG4vKiogQGRlcHJlY2F0ZWQgTW92ZWQgdG8gYHNwYXRpYWwvc3BhdGlhbC1wYW5lbC1tb2RlbGA7IHJlLWV4cG9ydGVkIGZvciBvbmUgcmVsZWFzZS4gKi9cbmV4cG9ydCB7IHBhcnNlR2VuZUdyb3VwcyB9O1xuXG4vKiogUGVyLWluc3RhbmNlIGlkIHNvdXJjZSDigJQgc2VlIHtAbGluayBTcGF0aWFsQ29udHJvbHNDb21wb25lbnQuY2hhcnRzQm9keUlkfS4gKi9cbmxldCBjb250cm9sc0luc3RhbmNlU2VxID0gMDtcblxuLyoqXG4gKiBTcGF0aWFsLW9taWNzIGNvbnRyb2xzOiBhIG5vbi1tb2RhbCwgcmVzaXphYmxlLCBkcmFnZ2FibGUgZGlhbG9nIGZvciBjaG9vc2luZ1xuICogd2hhdCB0aGUgb2JzZXJ2YXRpb24gbWFya2VycyBhcmUgY29sb3VyZWQgYnksIGFuZCBob3cgdGhleSBhcmUgZHJhd24uXG4gKlxuICogRGVwZW5kcyBvbmx5IG9uIHtAbGluayBJU3BhdGlhbENvbnRyb2xzfSwgcmVhY2hlZCB0aHJvdWdoIHRoZSBgVklTVUFMSVpFUmBcbiAqIGNvbnRyYWN0IHRva2VuIOKAlCBuZXZlciBhIGNvbmNyZXRlIGJhY2tlbmQg4oCUIG1pcnJvcmluZyBob3dcbiAqIGBDaGFubmVsSGlzdG9ncmFtQ29tcG9uZW50YCBkZXBlbmRzIG9ubHkgb24gYENIQU5ORUxfSElTVE9HUkFNX0FQSWAuIFdoZW4gbm9cbiAqIGhvc3QgaGFzIGJvdW5kIGBTUEFUSUFMX0RBVEFfUE9SVGAsIGBnZXRTcGF0aWFsQ29udHJvbHMoKWAgcmV0dXJucyBudWxsIGFuZFxuICogdGhlIGRpYWxvZyByZW5kZXJzIGFuIGV4cGxhbmF0b3J5IGVtcHR5IHN0YXRlIHJhdGhlciB0aGFuIGRlYWQgY29udHJvbHMuXG4gKlxuICogVGhlIGxlZ2VuZCBzd2F0Y2hlcyBhbmQgdGhlIGNvbnRpbnVvdXMgY29sb3VyIGJhciBhcmUgYnVpbHQgd2l0aCB0aGUgU0FNRVxuICogZnVuY3Rpb25zIHRoZSByZW5kZXJlciB1c2VzIChgY2F0ZWdvcnlDb2xvcnNgIOKGkiBgcmVzb2x2ZUNhdGVnb3J5Q29sb3JzYCxcbiAqIGBzcGF0aWFsQ29udGludW91c0x1dGApLCBzbyB0aGUga2V5IGNhbm5vdCBkcmlmdCBmcm9tIHdoYXQgaXMgb24gc2NyZWVuLlxuICpcbiAqIE9uUHVzaDogdGhlIGNvbnRyb2xzJyBzdHJlYW1zLCB0aGUga2V5IGFuZCBnZW5lLWxpc3QgbW9kZWxzICh3aGljaCByZS1lbnRlciB0aGUgem9uZVxuICogd2hlbiB0aGVpciBhc3luYyB3b3JrIGxhbmRzKSBhbmQgYW4gYXdhaXRlZCBjYXRlZ29yeSBzZWxlY3Rpb24gbWFyayBpdCBmb3IgY2hlY2suXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3NwYXRpYWwtY29udHJvbHMnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXG4gICAgQ29tbW9uTW9kdWxlLFxuICAgIEZvcm1zTW9kdWxlLFxuICAgIEJ1dHRvbk1vZHVsZSxcbiAgICBDaGVja2JveE1vZHVsZSxcbiAgICBEaWFsb2dNb2R1bGUsXG4gICAgVG9vbHRpcE1vZHVsZSxcbiAgICBTcGF0aWFsQ2VsbHNQYW5lbENvbXBvbmVudCxcbiAgICBTcGF0aWFsVHJhbnNjcmlwdHNQYW5lbENvbXBvbmVudCxcbiAgICBTcGF0aWFsT2JzZXJ2YXRpb25zUGFuZWxDb21wb25lbnQsXG4gICAgU3BhdGlhbENoYXJ0c0NvbXBvbmVudCxcbiAgXSxcbiAgdGVtcGxhdGVVcmw6ICcuL3NwYXRpYWwtY29udHJvbHMuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9zcGF0aWFsLWNvbnRyb2xzLmNvbXBvbmVudC5zY3NzJ10sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxufSlcbmV4cG9ydCBjbGFzcyBTcGF0aWFsQ29udHJvbHNDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICAvKiogVGhlIGVtYmVkZGVkIGNoYXJ0LCBzbyBhIGRpYWxvZyByZXNpemUgY2FuIHJlLWZpdCBpdC4gKi9cbiAgQFZpZXdDaGlsZChTcGF0aWFsQ2hhcnRzQ29tcG9uZW50KSBwcml2YXRlIGNoYXJ0cz86IFNwYXRpYWxDaGFydHNDb21wb25lbnQ7XG5cbiAgLyoqXG4gICAqIFJlLWZpdCB0aGUgY2hhcnQgYWZ0ZXIgdGhlIGRpYWxvZyBpcyByZXNpemVkLlxuICAgKlxuICAgKiBQbG90bHkgZG9lcyBub3QgZm9sbG93IGEgY29udGFpbmVyIHJlc2l6ZSBvbiBpdHMgb3duIOKAlCBpdHMgYHJlc3BvbnNpdmVgXG4gICAqIG9wdGlvbiBsaXN0ZW5zIGZvciBXSU5ET1cgcmVzaXplcyBvbmx5LCBzbyBkcmFnZ2luZyB0aGUgZGlhbG9nJ3MgaGFuZGxlXG4gICAqIHJlYWNoZXMgaXQgdGhyb3VnaCBub3RoaW5nLiBQcmltZU5HIHRlbGxzIHVzIHdoZW4gdGhlIGRyYWcgZW5kcywgd2hpY2ggaXMgYVxuICAgKiBmYXIgbW9yZSBkaXJlY3Qgc2lnbmFsIHRoYW4gd2F0Y2hpbmcgYm94ZXMsIGFuZCBmaXJpbmcgb25jZSBvbiByZWxlYXNlIG1lYW5zXG4gICAqIG5vIHJlbGF5b3V0IGNodXJuIGR1cmluZyB0aGUgZHJhZy5cbiAgICovXG4gIHByb3RlY3RlZCBvblJlc2l6ZUVuZCgpOiB2b2lkIHtcbiAgICB0aGlzLmNoYXJ0cz8ucmVzaXplKCk7XG4gIH1cblxuICAvKiogRGlhbG9nIHZpc2liaWxpdHksIHR3by13YXkgYm91bmQgc28gYSB0b29sYmFyIGJ1dHRvbiBjYW4gb3BlbiBpdC4gKi9cbiAgQElucHV0KCkgdmlzaWJsZSA9IGZhbHNlO1xuICAvKiogU2V0IHdoaWxlIHRoZSAzRCBjbG91ZCBpcyB0aGUgYWN0aXZlIG1vZGUuIENoYW5nZXMgd2hhdCB0aGUgUk9JIHNlbGVjdGlvblxuICAgKiAgTUVBTlMg4oCUIGEgc2NyZWVuLXNwYWNlIGxhc3NvIGN1dHRpbmcgdGhyb3VnaCB0aGUgY2xvdWQncyBmdWxsIGRlcHRoIHJhdGhlclxuICAgKiAgdGhhbiBhIHNoYXBlIGluIHRpc3N1ZSBjb29yZGluYXRlcyDigJQgc28gdGhlIGhpbnQgYmVsb3cgaXQgc2F5cyBzby4gKi9cbiAgQElucHV0KCkgaXMzZCA9IGZhbHNlO1xuICAvKiogVGhlIGRpYWxvZyB3YXMgb3BlbmVkIG9yIGNsb3NlZDsgdHdvLXdheSB3aXRoIHtAbGluayB2aXNpYmxlfS4gKi9cbiAgQE91dHB1dCgpIHZpc2libGVDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPGJvb2xlYW4+KCk7XG5cbiAgLyoqIE51bGwgd2hlbiB0aGUgaG9zdCBib3VuZCBubyBgU1BBVElBTF9EQVRBX1BPUlRgLiAqL1xuICBwcm90ZWN0ZWQgY29udHJvbHM6IElTcGF0aWFsQ29udHJvbHMgfCBudWxsID0gbnVsbDtcbiAgcHJvdGVjdGVkIGRhdGFzZXQ6IFNwYXRpYWxEYXRhc2V0IHwgbnVsbCA9IG51bGw7XG4gIHByb3RlY3RlZCB2aWV3OiBTcGF0aWFsVmlld1N0YXRlID0geyAuLi5ERUZBVUxUX1NQQVRJQUxfVklFVyB9O1xuXG4gIC8qKlxuICAgKiBHZW5lIHBpY2tlcjogYSBmaWx0ZXJhYmxlIGRyb3Bkb3duIHJhdGhlciB0aGFuIGEgZnJlZS10ZXh0IHR5cGVhaGVhZCwgc28gdGhlXG4gICAqIG9wdGlvbnMgYXJlIHZpc2libGUgYmVmb3JlIGFueXRoaW5nIGlzIHR5cGVkIGFuZCBlYWNoIGtleXN0cm9rZSBuYXJyb3dzIGEgbGlzdFxuICAgKiB0aGUgdXNlciBjYW4gc2VlLiBPbmUgbW9kZWwgZmVlZHMgZXZlcnkgZ2VuZSBkcm9wZG93biBvZiB0aGUgcGFuZWwuXG4gICAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgZ2VuZXMgPSBuZXcgR2VuZVBpY2tlck1vZGVsKFxuICAgICgpID0+IHRoaXMuY29udHJvbHMsXG4gICAgKCkgPT4gW1xuICAgICAgLi4uKHRoaXMudmlldz8udHJhbnNjcmlwdEdlbmVzID8/IFtdKSxcbiAgICAgIC4uLih0aGlzLnZpZXc/Lm9ic2VydmF0aW9uR2VuZXMgPz8gW10pLFxuICAgICAgLi4uKHRoaXMudmlldz8uY29sb3JCeT8ua2luZCA9PT0gJ2ZlYXR1cmUnID8gW3RoaXMudmlldy5jb2xvckJ5Lm5hbWVdIDogW10pLFxuICAgIF0sXG4gICAgKGZuKSA9PiB0aGlzLnJ1bkFuZE1hcmsoZm4pLFxuICApO1xuICAvKiogVGhlIGdlbmUgZHJvcGRvd25zJyBvcHRpb25zLiAqL1xuICBnZXQgZ2VuZU9wdGlvbnMoKTogUGFuZWxPcHRpb248c3RyaW5nPltdIHtcbiAgICByZXR1cm4gdGhpcy5nZW5lcy5vcHRpb25zO1xuICB9XG4gIC8qKiBUcnVlIHdoZW4gdGhlIG9wdGlvbnMgY29tZSBmcm9tIHRoZSBwb3J0IHBlciBrZXlzdHJva2UgcmF0aGVyIHRoYW4gYSByZXNpZGVudCBsaXN0LiAqL1xuICBnZXQgZ2VuZXNBcmVSZW1vdGUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZ2VuZXMucmVtb3RlO1xuICB9XG4gIGdldCBnZW5lU2VhcmNoRmFpbGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmdlbmVzLmZhaWxlZDtcbiAgfVxuXG4gIC8qKiBUaGUga2V5IOKAlCBsZWdlbmQgb3IgY29sb3VyIGJhciDigJQgZm9yIHRoZSBhY3RpdmUgY29sb3VyaW5nLiBLZXB0IGhlcmUsIG5vdCBpblxuICAgKiAgYDxzcGF0aWFsLWtleT5gOiB3aGV0aGVyIHRoZSBjb2xvdXJpbmcgaXMgY2F0ZWdvcmljYWwgZGVjaWRlcyB3aGljaCBrbm9icyB0aGUgcmVzdCBvZlxuICAgKiAgdGhlIHBhbmVsIG9mZmVycywgd2hldGhlciBvciBub3QgdGhlIGtleSBpcyBvbiBzY3JlZW4uICovXG4gIHJlYWRvbmx5IGtleSA9IG5ldyBTcGF0aWFsS2V5TW9kZWwoKGZuKSA9PiB0aGlzLnJ1bkFuZE1hcmsoZm4pKTtcbiAgLyoqIENhdGVnb3JpY2FsIGtleSwgb3IgbnVsbCB3aGVuIHRoZSBhY3RpdmUgY29sb3VyaW5nIGlzIGNvbnRpbnVvdXMuICovXG4gIHByb3RlY3RlZCBnZXQgbGVnZW5kKCk6IFNwYXRpYWxMZWdlbmRFbnRyeVtdIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMua2V5LmxlZ2VuZDtcbiAgfVxuICAvKiogQ1NTIGdyYWRpZW50IGZvciBhIGNvbnRpbnVvdXMgY29sb3VyaW5nLCBvciBudWxsIHdoZW4gY2F0ZWdvcmljYWwuICovXG4gIHByb3RlY3RlZCBnZXQgY29sb3JCYXJDc3MoKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMua2V5LmNvbG9yQmFyQ3NzO1xuICB9XG5cbiAgLyoqIEN1cnJlbnQgc2VsZWN0aW9uIOKAlCBkcml2ZXMgdGhlIGNvdW50LCB0aGUgQ2xlYXIgYnV0dG9uIGFuZCB0aGUgbXV0aW5nLiAqL1xuICBwcm90ZWN0ZWQgc2VsZWN0aW9uOiBTcGF0aWFsU2VsZWN0aW9uTWFzayA9IGVtcHR5U2VsZWN0aW9uKCk7XG4gIC8qKiBUaGUgbGVnZW5kIHJvdyB3aG9zZSBjYXRlZ29yeSBpcyBjdXJyZW50bHkgc2VsZWN0ZWQsIGZvciBoaWdobGlnaHRpbmcuICovXG4gIHByb3RlY3RlZCBzZWxlY3RlZENhdGVnb3J5OiBudW1iZXIgfCBudWxsID0gbnVsbDtcbiAgLyoqIEFuIFJPSSBzZWxlY3Rpb24gdGhhdCBtYXRjaGVkIG5vdGhpbmcsIHNvIHRoZSBVSSBjYW4gc2F5IHNvIHJhdGhlciB0aGFuXG4gICAqICBsb29raW5nIGxpa2UgdGhlIGJ1dHRvbiBkaWQgbm90aGluZy4gKi9cbiAgcHJvdGVjdGVkIHNlbGVjdGlvbk1pc3NlZCA9IGZhbHNlO1xuICAvKiogVGhlIG1vZGUgb2YgdGhlIHNlbGVjdGlvbiB0aGF0IHtAbGluayBzZWxlY3Rpb25NaXNzZWR9OiB3aGF0IGl0IGZvdW5kIG5vdGhpbmcgaW5zaWRlLiAqL1xuICBwcm90ZWN0ZWQgbWlzc2VkTW9kZTogUm9pU2VsZWN0aW9uTW9kZSA9ICdyZWdpb25zJztcbiAgLyoqIFRoZSByZWdpb24gY2xhc3NlcyBwaWNrZWQgaW4gdGhlIFJlZ2lvbiBFZGl0b3I6IGluIDNELCBcIlNlbGVjdCBmcm9tIFJPSXNcIiBzZWxlY3RzIGluc2lkZSB0aGVtLiAqL1xuICBwcm90ZWN0ZWQgcGlja2VkQ2xhc3NlczogcmVhZG9ubHkgc3RyaW5nW10gPSBbXTtcbiAgLyoqIFdoaWxlIFwiU2VsZWN0IGZyb20gUk9Jc1wiIHJlYWRzIHRoZSBwaWNrZWQgY2xhc3Nlcycgb3V0bGluZXMuICovXG4gIHByb3RlY3RlZCBzZWxlY3RpbmdGcm9tUmVnaW9ucyA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBEaXN0cmlidXRpb24gc2VjdGlvbiBpcyBleHBhbmRlZC4gQ29sbGFwc2VkIGJ5IGRlZmF1bHQ6IHRoZVxuICAgKiBwYW5lbCdzIHByaW1hcnkgam9iIGlzIHRoZSBjb2xvdXIgY29udHJvbHMsIGFuZCB0aGUgY2hhcnQgcm91Z2hseSBkb3VibGVzXG4gICAqIGl0cyBoZWlnaHQuXG4gICAqL1xuICBwcm90ZWN0ZWQgY2hhcnRzT3BlbiA9IGZhbHNlO1xuICAvKiogUGVyLWluc3RhbmNlIGlkIGZvciB0aGUgY29sbGFwc2libGUgYm9keSwgc28gYGFyaWEtY29udHJvbHNgIHBvaW50cyBhdCBvbmVcbiAgICogIGVsZW1lbnQgYW5kIGV4cGFuZGluZyB0aGUgc2Vjb25kIHBhbmVsIGNhbm5vdCBzY3JvbGwgdGhlIGZpcnN0IG9uZSdzIGNoYXJ0LiAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgY2hhcnRzQm9keUlkID0gYHNjLWNoYXJ0cy1ib2R5LSR7Kytjb250cm9sc0luc3RhbmNlU2VxfWA7XG5cbiAgLyoqIENvbG9ybWFwIHRyZWUgZm9yIHRoZSBjb250aW51b3VzIGNvbG91ciBzY2FsZSBhbmQgdGhlIGRlbnNpdHkgbWFwOiB0aGUgbGlicmFyeSdzXG4gICAqICBvd24gYENPTE9STUFQX09QVElPTlNgLiAqL1xuICBwcm90ZWN0ZWQgY29sb3JtYXBPcHRpb25zOiBDb2xvcm1hcE5vZGVbXSA9IFtdO1xuXG4gIHByaXZhdGUgY29sb3JtYXA6IENvbG9ybWFwTm9kZSB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHJldmVyc2UgPSBmYWxzZTtcbiAgcHJpdmF0ZSByZWFkb25seSBkZXN0cm95UmVmID0gaW5qZWN0KERlc3Ryb3lSZWYpO1xuICBwcml2YXRlIHJlYWRvbmx5IGNkciA9IGluamVjdChDaGFuZ2VEZXRlY3RvclJlZik7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgQEluamVjdChWSVNVQUxJWkVSKSBwcml2YXRlIHJlYWRvbmx5IHZpejogSVZpc3VhbGl6ZXIsXG4gICAgcHJpdmF0ZSByZWFkb25seSB6b25lOiBOZ1pvbmUsXG4gICkge31cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmNvbnRyb2xzID0gdGhpcy52aXouZ2V0U3BhdGlhbENvbnRyb2xzPy4oKSA/PyBudWxsO1xuICAgIHRoaXMuY29sb3JtYXBPcHRpb25zID0gdGhpcy52aXouZ2V0Q29sb3JtYXBPcHRpb25zPy4oKSA/PyBbXTtcbiAgICBpZiAoIXRoaXMuY29udHJvbHMpIHJldHVybjtcblxuICAgIGNvbnN0IHVudGlsRGVzdHJveWVkID0gPFQ+KCkgPT4gdGFrZVVudGlsRGVzdHJveWVkPFQ+KHRoaXMuZGVzdHJveVJlZik7XG4gICAgdGhpcy5jb250cm9sc1xuICAgICAgLmdldERhdGFzZXQkKClcbiAgICAgIC5waXBlKHVudGlsRGVzdHJveWVkKCkpXG4gICAgICAuc3Vic2NyaWJlKChkYXRhc2V0KSA9PiB7XG4gICAgICAgIHRoaXMuZGF0YXNldCA9IGRhdGFzZXQ7XG4gICAgICAgIHRoaXMuZ2VuZXMuc2V0RGF0YXNldChkYXRhc2V0KTtcbiAgICAgICAgLy8gQSBkYXRhc2V0IHdpdGggbm8gY2VsbHMgdG8gb3V0bGluZSBsZWFkcyB3aXRoIGl0cyBvYnNlcnZhdGlvbnMuXG4gICAgICAgIHRoaXMub3BlbiA9IHtcbiAgICAgICAgICAuLi50aGlzLm9wZW4sXG4gICAgICAgICAgY2VsbHM6ICEhKGRhdGFzZXQ/LnBvbHlnb25UaWxlcyB8fCBkYXRhc2V0Py5wb2x5Z29ucyksXG4gICAgICAgICAgb2JzZXJ2YXRpb25zOiAhKGRhdGFzZXQ/LnBvbHlnb25UaWxlcyB8fCBkYXRhc2V0Py5wb2x5Z29ucyksXG4gICAgICAgIH07XG4gICAgICAgIHZvaWQgdGhpcy5yZWZyZXNoS2V5KCk7XG4gICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgICAgfSk7XG5cbiAgICB0aGlzLmNvbnRyb2xzXG4gICAgICAuZ2V0Vmlld1N0YXRlJCgpXG4gICAgICAucGlwZSh1bnRpbERlc3Ryb3llZCgpKVxuICAgICAgLnN1YnNjcmliZSgodmlldykgPT4ge1xuICAgICAgICB0aGlzLnZpZXcgPSB2aWV3O1xuICAgICAgICB2b2lkIHRoaXMucmVmcmVzaEtleSgpO1xuICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICAgIH0pO1xuXG4gICAgLy8gVGhlIHJlbmRlcmVyJ3Mgb3duIHN0cmVhbXMgbWF5IGVtaXQgb3V0c2lkZSB0aGUgem9uZTogcmUtZW50ZXJlZCBoZXJlLCBvbmNlLCBmb3JcbiAgICAvLyBldmVyeSBwYW5lbCB0aGV5IGZlZWQuXG4gICAgY29uc3QgZXN0aW1hdGUkID0gdGhpcy5jb250cm9scy5nZXRUcmFuc2NyaXB0RXN0aW1hdGUkPy4oKTtcbiAgICBlc3RpbWF0ZSQ/LnBpcGUodW50aWxEZXN0cm95ZWQoKSkuc3Vic2NyaWJlKChlKSA9PlxuICAgICAgdGhpcy5ydW5BbmRNYXJrKCgpID0+IHtcbiAgICAgICAgdGhpcy5lc3RpbWF0ZSA9IGU7XG4gICAgICB9KSxcbiAgICApO1xuICAgIGNvbnN0IGNvdW50cyQgPSB0aGlzLmNvbnRyb2xzLmdldEdlbmVDb3VudHNJblZpZXckPy4oKTtcbiAgICBjb3VudHMkPy5waXBlKHVudGlsRGVzdHJveWVkKCkpLnN1YnNjcmliZSgoYykgPT5cbiAgICAgIHRoaXMucnVuQW5kTWFyaygoKSA9PiB7XG4gICAgICAgIHRoaXMuZ2VuZUNvdW50cyA9IGM7XG4gICAgICB9KSxcbiAgICApO1xuICAgIGNvbnN0IGRlbnNpdHkkID0gdGhpcy5jb250cm9scy5nZXREZW5zaXR5U3RhdHMkPy4oKTtcbiAgICBkZW5zaXR5JD8ucGlwZSh1bnRpbERlc3Ryb3llZCgpKS5zdWJzY3JpYmUoKGQpID0+XG4gICAgICB0aGlzLnJ1bkFuZE1hcmsoKCkgPT4ge1xuICAgICAgICB0aGlzLmRlbnNpdHlTdGF0cyA9IGQ7XG4gICAgICB9KSxcbiAgICApO1xuXG4gICAgdGhpcy5jb250cm9sc1xuICAgICAgLmdldFNlbGVjdGlvbiQoKVxuICAgICAgLnBpcGUodW50aWxEZXN0cm95ZWQoKSlcbiAgICAgIC5zdWJzY3JpYmUoKHNlbGVjdGlvbikgPT5cbiAgICAgICAgLy8gU2V0IGZyb20gb3V0c2lkZSB0aGUgem9uZSB0b286IGEgc2VsZWN0aW9uIGZyb20gdGhlIHJlZ2lvbiBjbGFzc2VzJyB2b2x1bWVzLlxuICAgICAgICB0aGlzLnJ1bkFuZE1hcmsoKCkgPT4ge1xuICAgICAgICAgIHRoaXMuc2VsZWN0aW9uID0gc2VsZWN0aW9uO1xuICAgICAgICAgIGlmIChzZWxlY3Rpb24uY291bnQgPT09IDApIHRoaXMuc2VsZWN0ZWRDYXRlZ29yeSA9IG51bGw7XG4gICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgIHRoaXMuY29udHJvbHNcbiAgICAgIC5nZXRQaWNrZWRSZWdpb25DbGFzc2VzJD8uKClcbiAgICAgID8ucGlwZSh1bnRpbERlc3Ryb3llZCgpKVxuICAgICAgLnN1YnNjcmliZSgoY2xhc3NlcykgPT5cbiAgICAgICAgdGhpcy5ydW5BbmRNYXJrKCgpID0+IHtcbiAgICAgICAgICB0aGlzLnBpY2tlZENsYXNzZXMgPSBjbGFzc2VzO1xuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAvLyBUaGUgY29sb3VyIGJhciBtdXN0IHVzZSB0aGUgY29sb3JtYXAgdGhlIHJlbmRlcmVyIGlzIHVzaW5nLlxuICAgIGNvbWJpbmVMYXRlc3QoW3RoaXMudml6LmdldENvbG9ybWFwKCksIHRoaXMudml6LmdldFJldmVyc2VTY2FsZSgpXSlcbiAgICAgIC5waXBlKHVudGlsRGVzdHJveWVkKCkpXG4gICAgICAuc3Vic2NyaWJlKChbY29sb3JtYXAsIHJldmVyc2VdKSA9PiB7XG4gICAgICAgIHRoaXMuY29sb3JtYXAgPSAoY29sb3JtYXAgYXMgQ29sb3JtYXBOb2RlKSA/PyBudWxsO1xuICAgICAgICB0aGlzLnJldmVyc2UgPSAhIXJldmVyc2U7XG4gICAgICAgIHZvaWQgdGhpcy5yZWZyZXNoS2V5KCk7XG4gICAgICB9KTtcbiAgfVxuXG4gIC8qKiBBcHBseSBhbiBhc3luYyByZXN1bHQgaW5zaWRlIHRoZSB6b25lIGFuZCByZS1yZW5kZXIgdGhpcyBPblB1c2ggZGlhbG9nLiAqL1xuICBwcml2YXRlIHJ1bkFuZE1hcmsoZm46ICgpID0+IHZvaWQpOiB2b2lkIHtcbiAgICB0aGlzLnpvbmUucnVuKCgpID0+IHtcbiAgICAgIGZuKCk7XG4gICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvblZpc2libGVDaGFuZ2UodmFsdWU6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLnZpc2libGUgPSB2YWx1ZTtcbiAgICB0aGlzLnZpc2libGVDaGFuZ2UuZW1pdCh2YWx1ZSk7XG4gIH1cblxuICAvLyDilIDilIAgdGhlIHNoYXJlZCBnZW5lIGxpc3Qg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgLyoqIEEga2V5c3Ryb2tlIGluIGEgZ2VuZSBkcm9wZG93bidzIGZpbHRlciBib3gg4oCUIHNlZSB7QGxpbmsgR2VuZVBpY2tlck1vZGVsLm9uRmlsdGVyfS4gKi9cbiAgb25HZW5lRmlsdGVyKHF1ZXJ5OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gdGhpcy5nZW5lcy5vbkZpbHRlcihxdWVyeSk7XG4gIH1cblxuICAvKiogQSBnZW5lIGRyb3Bkb3duIG9wZW5lZCDigJQgc2VlIHtAbGluayBHZW5lUGlja2VyTW9kZWwuZW5zdXJlTGlzdH0uICovXG4gIGVuc3VyZUdlbmVMaXN0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiB0aGlzLmdlbmVzLmVuc3VyZUxpc3QoKTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBzZWxlY3Rpb24g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgLyoqIFNlbGVjdCBldmVyeSBvYnNlcnZhdGlvbiBpbnNpZGUgdGhlIGRyYXduIHJlZ2lvbnMgKHRoZWlyIHVuaW9uKSDigJQgaW4gM0QsIGluc2lkZSB0aGVcbiAgICogIHBpY2tlZCBjbGFzc2VzJyB2b2x1bWVzLiAqL1xuICBwcm90ZWN0ZWQgYXN5bmMgc2VsZWN0RnJvbVJlZ2lvbnMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKCF0aGlzLmNvbnRyb2xzIHx8IHRoaXMuc2VsZWN0aW5nRnJvbVJlZ2lvbnMpIHJldHVybjtcbiAgICB0aGlzLnNlbGVjdGluZ0Zyb21SZWdpb25zID0gdHJ1ZTtcbiAgICAvLyBUaGUgbW9kZSB0aGUgc2VsZWN0aW9uIHJ1bnMgaW4gKGRlY2lkZWQgYXMgaXQgc3RhcnRzKSwgZm9yIHdoYXQgYSBtaXNzIHNheXMgaXQgbWlzc2VkLlxuICAgIGNvbnN0IG1vZGUgPSB0aGlzLnJvaVNlbGVjdGlvbk1vZGU7XG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgbGV0IGNvdW50OiBudW1iZXIgfCBudWxsID0gMDtcbiAgICB0cnkge1xuICAgICAgY291bnQgPSBhd2FpdCB0aGlzLmNvbnRyb2xzLnNlbGVjdEZyb21SZWdpb25zKCk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBjb25zb2xlLndhcm4oJ1tzcGF0aWFsXSBjb3VsZCBub3Qgc2VsZWN0IGZyb20gdGhlIHJlZ2lvbnMnLCBlcnIpO1xuICAgIH1cbiAgICAvLyBUaGUgY2xhc3Nlcycgb3V0bGluZXMgYXJlIHJlYWQgaW4gYSB3b3JrZXIsIHdob3NlIGFuc3dlciBsYW5kcyBvdXRzaWRlIHRoZSB6b25lLlxuICAgIHRoaXMucnVuQW5kTWFyaygoKSA9PiB7XG4gICAgICB0aGlzLnNlbGVjdGluZ0Zyb21SZWdpb25zID0gZmFsc2U7XG4gICAgICAvLyBTdXBlcnNlZGVkIChudWxsKTogYSBuZXdlciBzZWxlY3Rpb24gc3RhbmRzLCBhbmQgc2F5cyB3aGF0IGl0IGlzIGl0c2VsZi5cbiAgICAgIGlmIChjb3VudCA9PT0gbnVsbCkgcmV0dXJuO1xuICAgICAgdGhpcy5zZWxlY3RlZENhdGVnb3J5ID0gbnVsbDtcbiAgICAgIHRoaXMuc2VsZWN0aW9uTWlzc2VkID0gY291bnQgPT09IDA7XG4gICAgICB0aGlzLm1pc3NlZE1vZGUgPSBtb2RlO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqIEluIDNEIHdpdGggY2xhc3NlcyBwaWNrZWQsIFwiU2VsZWN0IGZyb20gUk9Jc1wiIHNlbGVjdHMgaW5zaWRlIHRoZWlyIHZvbHVtZXMuICovXG4gIHByb3RlY3RlZCBnZXQgc2VsZWN0c0NsYXNzVm9sdW1lcygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5yb2lTZWxlY3Rpb25Nb2RlID09PSAnY2xhc3Mtdm9sdW1lcyc7XG4gIH1cblxuICAvKiogSG93IFwiU2VsZWN0IGZyb20gUk9Jc1wiIHNlbGVjdHMgbm93OiB0aGUgY29udHJvbHMnIG93biBydWxlLCB0aGUgb25lIHRoZSBzZWxlY3Rpb24gcnVucyBieS4gKi9cbiAgcHJpdmF0ZSBnZXQgcm9pU2VsZWN0aW9uTW9kZSgpOiBSb2lTZWxlY3Rpb25Nb2RlIHtcbiAgICByZXR1cm4gdGhpcy5jb250cm9scz8ucm9pU2VsZWN0aW9uTW9kZT8uKCkgPz8gJ3JlZ2lvbnMnO1xuICB9XG5cbiAgLyoqIExlZ2VuZCBjbGljazogc2VsZWN0IG9uZSBjYXRlZ29yeS4gQ2xpY2tpbmcgdGhlIGFjdGl2ZSByb3cgY2xlYXJzIGl0LCBzbyBhXG4gICAqICBzZWNvbmQgY2xpY2sgaXMgYW4gdW5kbyByYXRoZXIgdGhhbiBhIG5vLW9wLiAqL1xuICBwcm90ZWN0ZWQgYXN5bmMgc2VsZWN0Q2F0ZWdvcnkoaW5kZXg6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGJ5ID0gdGhpcy52aWV3LmNvbG9yQnk7XG4gICAgaWYgKCF0aGlzLmNvbnRyb2xzIHx8IGJ5Py5raW5kICE9PSAnY29sdW1uJykgcmV0dXJuO1xuICAgIGlmICh0aGlzLnNlbGVjdGVkQ2F0ZWdvcnkgPT09IGluZGV4KSB7XG4gICAgICB0aGlzLmNsZWFyU2VsZWN0aW9uKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLmNvbnRyb2xzLnNlbGVjdENhdGVnb3J5KGJ5Lm5hbWUsIGluZGV4KTtcbiAgICAgIHRoaXMuc2VsZWN0ZWRDYXRlZ29yeSA9IGluZGV4O1xuICAgICAgdGhpcy5zZWxlY3Rpb25NaXNzZWQgPSBmYWxzZTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWRDYXRlZ29yeSA9IG51bGw7XG4gICAgfVxuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4cGFuZCBvciBjb2xsYXBzZSB0aGUgZGlzdHJpYnV0aW9uIHNlY3Rpb24uXG4gICAqXG4gICAqIEV4cGFuZGluZyBTQ1JPTExTIGl0IGludG8gdmlldywgYmVjYXVzZSB0aGUgcGFuZWwgaXMgdGFsbGVyIHRoYW4gdGhlIHZpZXdwb3J0XG4gICAqIG9uY2UgdGhpcyBzZWN0aW9uIGlzIG9wZW4gYW5kIHRoZSBjaGFydCBpcyBpdHMgbGFzdCByb3c6IGV4cGFuZGluZyBpdCBkcmV3IGFcbiAgICogY2hhcnQgfjMwMCBweCBiZWxvdyB0aGUgZm9sZCwgd2hpY2ggcmVhZHMgYXMgdGhlIHNlY3Rpb24gYmVpbmcgZW1wdHkuIFRoZVxuICAgKiBzY3JvbGwgaXMgZGVmZXJyZWQgYSB0YXNrIHNvIHRoZSBjaGFydCdzIG93biBkZWZlcnJlZCBmaXJzdCBkcmF3IGhhcyBnaXZlbiB0aGVcbiAgICogYm9keSBpdHMgaGVpZ2h0LlxuICAgKi9cbiAgcHJvdGVjdGVkIHRvZ2dsZUNoYXJ0cygpOiB2b2lkIHtcbiAgICB0aGlzLmNoYXJ0c09wZW4gPSAhdGhpcy5jaGFydHNPcGVuO1xuICAgIGlmICghdGhpcy5jaGFydHNPcGVuKSByZXR1cm47XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLmNoYXJ0c0JvZHlJZCk/LnNjcm9sbEludG9WaWV3KHsgYmxvY2s6ICdlbmQnLCBiZWhhdmlvcjogJ3Ntb290aCcgfSk7XG4gICAgfSwgMCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgY2xlYXJTZWxlY3Rpb24oKTogdm9pZCB7XG4gICAgdGhpcy5jb250cm9scz8uY2xlYXJTZWxlY3Rpb24oKTtcbiAgICB0aGlzLnNlbGVjdGVkQ2F0ZWdvcnkgPSBudWxsO1xuICAgIHRoaXMuc2VsZWN0aW9uTWlzc2VkID0gZmFsc2U7XG4gIH1cblxuICAvKiogVHJ1ZSB3aGlsZSBhIHNlbGVjdGlvbiBpcyBhY3RpdmUg4oCUIGV2ZXJ5dGhpbmcgZWxzZSByZW5kZXJzIG11dGVkLiAqL1xuICBwcm90ZWN0ZWQgZ2V0IGhhc1NlbGVjdGlvbigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5zZWxlY3Rpb24uY291bnQgPiAwO1xuICB9XG5cbiAgLy8g4pSA4pSAIHNlY3Rpb25zIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIC8qKiBCb3VuZGFyaWVzIG9uIG9mZmVyOiB0aWxlZCAobGV2ZWwtb2YtZGV0YWlsKSBvciB3aG9sZS1kYXRhc2V0IHJpbmdzLiAqL1xuICBwcm90ZWN0ZWQgZ2V0IGhhc0NlbGxzKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhISh0aGlzLmRhdGFzZXQ/LnBvbHlnb25UaWxlcyB8fCB0aGlzLmRhdGFzZXQ/LnBvbHlnb25zKTtcbiAgfVxuXG4gIC8qKiBUcmFuc2NyaXB0cyBvbiBvZmZlcjogdGlsZXMgdG8gZHJhdywgb3IgYSBkZW5zaXR5IG1hcC4gKi9cbiAgcHJvdGVjdGVkIGdldCBoYXNUcmFuc2NyaXB0cygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISF0aGlzLmRhdGFzZXQ/LnRyYW5zY3JpcHRUaWxlcyB8fCAhIXRoaXMuZGF0YXNldD8uZGVuc2l0eTtcbiAgfVxuXG4gIC8qKiBXaGV0aGVyIHRoZSAzRCBjbG91ZCBjYW4gZHJhdyB0aGUgdHJhbnNjcmlwdHMgdG9vOiB0aGV5IGNhcnJ5IHogKGEgTUVSRklTSCB2b2x1bWUncyBkbykuICovXG4gIHByb3RlY3RlZCBnZXQgaGFzVHJhbnNjcmlwdHMzZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISF0aGlzLmRhdGFzZXQ/LnRyYW5zY3JpcHRUaWxlcz8uaGFzWjtcbiAgfVxuXG4gIHByb3RlY3RlZCBvblNob3dJbWFnZShvbjogYm9vbGVhbik6IHZvaWQge1xuICAgIHRoaXMuY29udHJvbHM/LnNldFZpZXdTdGF0ZSh7IHNob3dJbWFnZTogb24gfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgb25TaG93QW5ub3RhdGlvbnMob246IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLmNvbnRyb2xzPy5zZXRWaWV3U3RhdGUoeyBzaG93QW5ub3RhdGlvbnM6IG9uIH0pO1xuICB9XG5cbiAgLyoqIFdoaWNoIGNvbGxhcHNpYmxlIHNlY3Rpb25zIGFyZSBvcGVuLiBQZXIgZGlhbG9nIGluc3RhbmNlLCBub3QgcGVyc2lzdGVkLiAqL1xuICBwcm90ZWN0ZWQgb3BlbjogUmVjb3JkPCdpbWFnZXMnIHwgJ2NlbGxzJyB8ICd0cmFuc2NyaXB0cycgfCAnYW5ub3RhdGlvbnMnIHwgJ29ic2VydmF0aW9ucycsIGJvb2xlYW4+ID0ge1xuICAgIGltYWdlczogZmFsc2UsXG4gICAgY2VsbHM6IHRydWUsXG4gICAgdHJhbnNjcmlwdHM6IGZhbHNlLFxuICAgIGFubm90YXRpb25zOiBmYWxzZSxcbiAgICBvYnNlcnZhdGlvbnM6IGZhbHNlLFxuICB9O1xuXG4gIHByb3RlY3RlZCB0b2dnbGVTZWN0aW9uKG5hbWU6IGtleW9mIFNwYXRpYWxDb250cm9sc0NvbXBvbmVudFsnb3BlbiddKTogdm9pZCB7XG4gICAgdGhpcy5zZXRPcGVuKG5hbWUsICF0aGlzLm9wZW5bbmFtZV0pO1xuICB9XG5cbiAgLyoqIEV4cGFuZCBvciBjb2xsYXBzZSBhIHNlY3Rpb24g4oCUIHdoYXQgYSBwYW5lbCdzIGhlYWRlciBhc2tzIGZvci4gKi9cbiAgcHJvdGVjdGVkIHNldE9wZW4obmFtZToga2V5b2YgU3BhdGlhbENvbnRyb2xzQ29tcG9uZW50WydvcGVuJ10sIG9uOiBib29sZWFuKTogdm9pZCB7XG4gICAgdGhpcy5vcGVuID0geyAuLi50aGlzLm9wZW4sIFtuYW1lXTogb24gfTtcbiAgfVxuXG4gIC8vIOKUgOKUgCByZW5kZXJlciByZWFkb3V0cywgZm9yIHRoZSBUcmFuc2NyaXB0cyBzZWN0aW9uIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIC8qKiBFc3RpbWF0ZWQgdHJhbnNjcmlwdHMgaW4gdmlldywgYWdhaW5zdCB0aGUgYnVkZ2V0IOKAlCBFeHBsb3JlcidzIHBvaW50cyBiYXIuICovXG4gIHByb3RlY3RlZCBlc3RpbWF0ZTogeyBwb2ludHM6IG51bWJlcjsgbWF4OiBudW1iZXIgfSB8IG51bGwgPSBudWxsO1xuICAvKiogVGhlIGRlbnNpdHkgd2luZG93IGluIHVzZSBhbmQgaXRzIGRlbnNlc3QgYmluLCBmb3IgdGhlIHRocmVzaG9sZCBjb250cm9sLiAqL1xuICBwcm90ZWN0ZWQgZGVuc2l0eVN0YXRzOiB7IGxvOiBudW1iZXI7IGhpOiBudW1iZXI7IG1heDogbnVtYmVyIH0gfCBudWxsID0gbnVsbDtcbiAgLyoqIFRyYW5zY3JpcHRzIG9mIGVhY2ggc2VsZWN0ZWQgZ2VuZSBpbiB0aGUgY3VycmVudCB2aWV3LCBmcm9tIHRoZSByZW5kZXJlci4gKi9cbiAgcHJvdGVjdGVkIGdlbmVDb3VudHM6IFJlY29yZDxzdHJpbmcsIG51bWJlcj4gfCBudWxsID0gbnVsbDtcblxuICBwcm90ZWN0ZWQgcmVzZXQoKTogdm9pZCB7XG4gICAgdGhpcy5jb250cm9scz8uc2V0Vmlld1N0YXRlKHsgLi4uREVGQVVMVF9TUEFUSUFMX1ZJRVcgfSk7XG4gICAgdGhpcy5jbGVhclNlbGVjdGlvbigpO1xuICB9XG5cbiAgLyoqIExhYmVsIGZvciB0aGUgY3VycmVudCBjb2xvdXJpbmcsIGZvciB0aGUgRGlzdHJpYnV0aW9uIGhlYWRpbmcuICovXG4gIHByb3RlY3RlZCBnZXQgY29sb3JCeUxhYmVsKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGNvbG9yQnlMYWJlbCh0aGlzLnZpZXcpO1xuICB9XG5cbiAgLyoqIFRydWUgd2hlbiB0aGUgYWN0aXZlIGNvbG91cmluZyBpcyBhIGNhdGVnb3JpY2FsIGNvbHVtbiAoZHJpdmVzIHRoZSBrZXkpLiAqL1xuICBnZXQgaXNDYXRlZ29yaWNhbCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5sZWdlbmQgIT09IG51bGw7XG4gIH1cblxuICAvKiogV2hldGhlciBsb2cvY2xpcCBhcHBseSDigJQgdGhleSBhcmUgY29udGludW91cy1vbmx5IGtub2JzLiAqL1xuICBnZXQgaXNDb250aW51b3VzKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhIXRoaXMudmlldy5jb2xvckJ5ICYmIHRoaXMubGVnZW5kID09PSBudWxsO1xuICB9XG5cbiAgLy8g4pSA4pSAIGludGVybmFscyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICAvKiogUmVidWlsZCB0aGUgbGVnZW5kIG9yIGNvbG91ciBiYXIgZm9yIHRoZSBjdXJyZW50IGNvbG91cmluZy4gKi9cbiAgcHJpdmF0ZSByZWZyZXNoS2V5KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiB0aGlzLmtleS5yZWZyZXNoKHRoaXMuY29udHJvbHMsIHRoaXMuZGF0YXNldCwgdGhpcy52aWV3LCB0aGlzLmNvbG9ybWFwLCB0aGlzLnJldmVyc2UpO1xuICB9XG59XG4iLCI8cC1kaWFsb2dcbiAgaGVhZGVyPVwiU3BhdGlhbCBvbWljc1wiXG4gIFt2aXNpYmxlXT1cInZpc2libGVcIlxuICAodmlzaWJsZUNoYW5nZSk9XCJvblZpc2libGVDaGFuZ2UoJGV2ZW50KVwiXG4gIFttb2RhbF09XCJmYWxzZVwiXG4gIFtyZXNpemFibGVdPVwidHJ1ZVwiXG4gIFtkcmFnZ2FibGVdPVwidHJ1ZVwiXG4gIHBvc2l0aW9uPVwibGVmdFwiXG4gIChvblJlc2l6ZUVuZCk9XCJvblJlc2l6ZUVuZCgpXCJcbiAgW3N0eWxlXT1cInsgd2lkdGg6ICczMHJlbScgfVwiXG4gIFticmVha3BvaW50c109XCJ7ICc5NjBweCc6ICc5MHZ3JyB9XCJcbiAgc3R5bGVDbGFzcz1cInNwYXRpYWwtY29udHJvbHMtZGlhbG9nXCJcbj5cbiAgPCEtLSBObyBwb3J0IGJvdW5kOiBzYXkgd2h5IHJhdGhlciB0aGFuIHNob3dpbmcgY29udHJvbHMgdGhhdCBkbyBub3RoaW5nLiAtLT5cbiAgPGRpdiBjbGFzcz1cInNjLWVtcHR5XCIgKm5nSWY9XCIhY29udHJvbHNcIj5cbiAgICBObyBzcGF0aWFsLW9taWNzIGRhdGEgc291cmNlIGlzIGNvbmZpZ3VyZWQuIEEgaG9zdCBwcm92aWRlcyBvbmUgYnkgYmluZGluZ1xuICAgIDxjb2RlPlNQQVRJQUxfREFUQV9QT1JUPC9jb2RlPi5cbiAgPC9kaXY+XG5cbiAgPGRpdiBjbGFzcz1cInNjLWVtcHR5XCIgKm5nSWY9XCJjb250cm9scyAmJiAhZGF0YXNldFwiPk5vIGRhdGFzZXQgaXMgbG9hZGVkLjwvZGl2PlxuXG4gIDxkaXYgY2xhc3M9XCJzYy1ib2R5XCIgKm5nSWY9XCJjb250cm9scyAmJiBkYXRhc2V0IGFzIGRzXCI+XG4gICAgPGRpdiBjbGFzcz1cInNjLWRhdGFzZXRcIj5cbiAgICAgIDxzcGFuIGNsYXNzPVwic2MtZGF0YXNldC1uYW1lXCI+e3sgZHMubmFtZSB9fTwvc3Bhbj5cbiAgICAgIDxzcGFuIGNsYXNzPVwic2MtZGF0YXNldC1jb3VudFwiPnt7IGRzLm9ic2VydmF0aW9ucy5jb3VudCB8IG51bWJlciB9fSBvYnNlcnZhdGlvbnM8L3NwYW4+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tIE9yZ2FuaXNlZCBhcyBYZW5pdW0gRXhwbG9yZXIncyBzaWRlIHBhbmVsOiBvbmUgY29sbGFwc2libGUgc2VjdGlvbiBwZXIgbGF5ZXIsXG4gICAgICAgICBlYWNoIHdpdGggaXRzIG93biBvbi9vZmYgc3dpdGNoIGluIHRoZSBoZWFkZXIuIC0tPlxuXG4gICAgPCEtLSBJbWFnZXMgLS0+XG4gICAgPGRpdiBjbGFzcz1cInNjLXBhbmVsXCIgKm5nSWY9XCJkcy5pbWFnZVJlZiAmJiAhaXMzZFwiIFtjbGFzcy5vcGVuXT1cIm9wZW4uaW1hZ2VzXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwic2MtcGFuZWwtaGVhZFwiIChjbGljayk9XCJ0b2dnbGVTZWN0aW9uKCdpbWFnZXMnKVwiPlxuICAgICAgICA8cC1jaGVja2JveFxuICAgICAgICAgIFtiaW5hcnldPVwidHJ1ZVwiXG4gICAgICAgICAgW25nTW9kZWxdPVwidmlldy5zaG93SW1hZ2VcIlxuICAgICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxuICAgICAgICAgIChvbkNoYW5nZSk9XCJvblNob3dJbWFnZSgkZXZlbnQuY2hlY2tlZClcIlxuICAgICAgICA+PC9wLWNoZWNrYm94PlxuICAgICAgICA8c3BhbiBjbGFzcz1cInNjLXBhbmVsLXRpdGxlXCI+SW1hZ2VzPC9zcGFuPlxuICAgICAgICA8aSBjbGFzcz1cInBpXCIgW2NsYXNzLnBpLWNoZXZyb24tZG93bl09XCJvcGVuLmltYWdlc1wiIFtjbGFzcy5waS1jaGV2cm9uLXJpZ2h0XT1cIiFvcGVuLmltYWdlc1wiPjwvaT5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cInNjLXBhbmVsLWJvZHlcIiAqbmdJZj1cIm9wZW4uaW1hZ2VzXCI+XG4gICAgICAgIDxzbWFsbCBjbGFzcz1cInNjLWhpbnRcIj4gQ2hhbm5lbHMsIGNvbG91cnMgYW5kIGNvbnRyYXN0IGFyZSBpbiB0aGUgQ2hhbm5lbHMgJmFtcDsgSGlzdG9ncmFtIGRpYWxvZy4gPC9zbWFsbD5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSBDZWxscyAtLT5cbiAgICA8c3BhdGlhbC1jZWxscy1wYW5lbFxuICAgICAgKm5nSWY9XCJoYXNDZWxscyAmJiAhaXMzZFwiXG4gICAgICBbY29udHJvbHNdPVwiY29udHJvbHNcIlxuICAgICAgW2RhdGFzZXRdPVwiZHNcIlxuICAgICAgW3ZpZXddPVwidmlld1wiXG4gICAgICBbZ2VuZXNdPVwiZ2VuZXNcIlxuICAgICAgW2NvbG9yQmFyQ3NzXT1cImNvbG9yQmFyQ3NzXCJcbiAgICAgIFtvcGVuXT1cIm9wZW4uY2VsbHNcIlxuICAgICAgKG9wZW5DaGFuZ2UpPVwic2V0T3BlbignY2VsbHMnLCAkZXZlbnQpXCJcbiAgICA+PC9zcGF0aWFsLWNlbGxzLXBhbmVsPlxuXG4gICAgPCEtLSBUcmFuc2NyaXB0cyAtLT5cbiAgICA8c3BhdGlhbC10cmFuc2NyaXB0cy1wYW5lbFxuICAgICAgKm5nSWY9XCJoYXNUcmFuc2NyaXB0cyAmJiAoIWlzM2QgfHwgaGFzVHJhbnNjcmlwdHMzZClcIlxuICAgICAgW2NvbnRyb2xzXT1cImNvbnRyb2xzXCJcbiAgICAgIFtkYXRhc2V0XT1cImRzXCJcbiAgICAgIFt2aWV3XT1cInZpZXdcIlxuICAgICAgW2dlbmVzXT1cImdlbmVzXCJcbiAgICAgIFtlc3RpbWF0ZV09XCJlc3RpbWF0ZVwiXG4gICAgICBbZGVuc2l0eVN0YXRzXT1cImRlbnNpdHlTdGF0c1wiXG4gICAgICBbZ2VuZUNvdW50c109XCJnZW5lQ291bnRzXCJcbiAgICAgIFtjb2xvcm1hcE9wdGlvbnNdPVwiY29sb3JtYXBPcHRpb25zXCJcbiAgICAgIFtvcGVuXT1cIm9wZW4udHJhbnNjcmlwdHNcIlxuICAgICAgKG9wZW5DaGFuZ2UpPVwic2V0T3BlbigndHJhbnNjcmlwdHMnLCAkZXZlbnQpXCJcbiAgICA+XG4gICAgPC9zcGF0aWFsLXRyYW5zY3JpcHRzLXBhbmVsPlxuXG4gICAgPCEtLSBBbm5vdGF0aW9uczogdGhlIGRyYXduIHJlZ2lvbnMsIGFuZCBzZWxlY3Rpbmcgd2hhdCB0aGV5IGVuY2xvc2UuIC0tPlxuICAgIDxkaXYgY2xhc3M9XCJzYy1wYW5lbFwiIFtjbGFzcy5vcGVuXT1cIm9wZW4uYW5ub3RhdGlvbnNcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJzYy1wYW5lbC1oZWFkXCIgKGNsaWNrKT1cInRvZ2dsZVNlY3Rpb24oJ2Fubm90YXRpb25zJylcIj5cbiAgICAgICAgPHAtY2hlY2tib3hcbiAgICAgICAgICBbYmluYXJ5XT1cInRydWVcIlxuICAgICAgICAgIFtuZ01vZGVsXT1cInZpZXcuc2hvd0Fubm90YXRpb25zICE9PSBmYWxzZVwiXG4gICAgICAgICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXG4gICAgICAgICAgKG9uQ2hhbmdlKT1cIm9uU2hvd0Fubm90YXRpb25zKCRldmVudC5jaGVja2VkKVwiXG4gICAgICAgICAgcFRvb2x0aXA9XCJTaG93IHRoZSBkcmF3biByZWdpb25zXCJcbiAgICAgICAgICB0b29sdGlwUG9zaXRpb249XCJ0b3BcIlxuICAgICAgICA+PC9wLWNoZWNrYm94PlxuICAgICAgICA8c3BhbiBjbGFzcz1cInNjLXBhbmVsLXRpdGxlXCI+QW5ub3RhdGlvbnM8L3NwYW4+XG4gICAgICAgIDxpIGNsYXNzPVwicGlcIiBbY2xhc3MucGktY2hldnJvbi1kb3duXT1cIm9wZW4uYW5ub3RhdGlvbnNcIiBbY2xhc3MucGktY2hldnJvbi1yaWdodF09XCIhb3Blbi5hbm5vdGF0aW9uc1wiPjwvaT5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cInNjLXBhbmVsLWJvZHlcIiAqbmdJZj1cIm9wZW4uYW5ub3RhdGlvbnNcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInNjLXJvd1wiPlxuICAgICAgICAgIDxwLWJ1dHRvblxuICAgICAgICAgICAgbGFiZWw9XCJTZWxlY3QgZnJvbSBST0lzXCJcbiAgICAgICAgICAgIGljb249XCJwaSBwaS1vYmplY3QtZ3JvdXBcIlxuICAgICAgICAgICAgc2l6ZT1cInNtYWxsXCJcbiAgICAgICAgICAgIFtvdXRsaW5lZF09XCJ0cnVlXCJcbiAgICAgICAgICAgIFtsb2FkaW5nXT1cInNlbGVjdGluZ0Zyb21SZWdpb25zXCJcbiAgICAgICAgICAgIChvbkNsaWNrKT1cInNlbGVjdEZyb21SZWdpb25zKClcIlxuICAgICAgICAgICAgW3BUb29sdGlwXT1cIlxuICAgICAgICAgICAgICBzZWxlY3RzQ2xhc3NWb2x1bWVzXG4gICAgICAgICAgICAgICAgPyAnU2VsZWN0IGV2ZXJ5IG9ic2VydmF0aW9uIGluc2lkZSB0aGUgdm9sdW1lcyBvZiB0aGUgY2xhc3NlcyBwaWNrZWQgaW4gdGhlIFJlZ2lvbiBFZGl0b3InXG4gICAgICAgICAgICAgICAgOiAnU2VsZWN0IGV2ZXJ5IG9ic2VydmF0aW9uIGluc2lkZSB0aGUgZHJhd24gcmVnaW9ucydcbiAgICAgICAgICAgIFwiXG4gICAgICAgICAgICB0b29sdGlwUG9zaXRpb249XCJ0b3BcIlxuICAgICAgICAgID48L3AtYnV0dG9uPlxuICAgICAgICAgIDxwLWJ1dHRvblxuICAgICAgICAgICAgKm5nSWY9XCJoYXNTZWxlY3Rpb25cIlxuICAgICAgICAgICAgbGFiZWw9XCJDbGVhclwiXG4gICAgICAgICAgICBzaXplPVwic21hbGxcIlxuICAgICAgICAgICAgW3RleHRdPVwidHJ1ZVwiXG4gICAgICAgICAgICAob25DbGljayk9XCJjbGVhclNlbGVjdGlvbigpXCJcbiAgICAgICAgICA+PC9wLWJ1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxzbWFsbCBjbGFzcz1cInNjLWhpbnRcIiAqbmdJZj1cImhhc1NlbGVjdGlvblwiPlxuICAgICAgICAgIHt7IHNlbGVjdGlvbi5jb3VudCB8IG51bWJlciB9fSBvZiB7eyBkcy5vYnNlcnZhdGlvbnMuY291bnQgfCBudW1iZXIgfX0gc2VsZWN0ZWQg4oCUIHRoZSByZXN0IGFyZSBtdXRlZC5cbiAgICAgICAgPC9zbWFsbD5cbiAgICAgICAgPHNtYWxsIGNsYXNzPVwic2MtaGludFwiICpuZ0lmPVwic2VsZWN0aW9uTWlzc2VkXCI+XG4gICAgICAgICAgTm8gb2JzZXJ2YXRpb25zIGZlbGwgaW5zaWRlIHRoZVxuICAgICAgICAgIHt7IG1pc3NlZE1vZGUgPT09ICdjbGFzcy12b2x1bWVzJyA/ICdwaWNrZWQgY2xhc3NlcycgOiAnZHJhd24gcmVnaW9ucycgfX0uXG4gICAgICAgIDwvc21hbGw+XG4gICAgICAgIDxzbWFsbCBjbGFzcz1cInNjLWhpbnRcIiAqbmdJZj1cInNlbGVjdHNDbGFzc1ZvbHVtZXNcIj5cbiAgICAgICAgICBTZWxlY3RzIGluc2lkZSB0aGUgdm9sdW1lIG9mIHt7IHBpY2tlZENsYXNzZXNbMF1cbiAgICAgICAgICB9fXt7IHBpY2tlZENsYXNzZXMubGVuZ3RoID4gMSA/ICcgYW5kICcgKyAocGlja2VkQ2xhc3Nlcy5sZW5ndGggLSAxIHwgbnVtYmVyKSArICcgbW9yZSBjbGFzc2VzJyA6ICcnIH19LFxuICAgICAgICAgIHBpY2tlZCBpbiB0aGUgUmVnaW9uIEVkaXRvci4gRHJhdyBhIHJlZ2lvbiB0byBzZWxlY3QgYnkgaXQgaW5zdGVhZC5cbiAgICAgICAgPC9zbWFsbD5cbiAgICAgICAgPHNtYWxsIGNsYXNzPVwic2MtaGludFwiICpuZ0lmPVwiaXMzZCAmJiAhc2VsZWN0c0NsYXNzVm9sdW1lcyAmJiBwaWNrZWRDbGFzc2VzLmxlbmd0aFwiPlxuICAgICAgICAgIFRoZSBjbGFzc2VzIHBpY2tlZCBpbiB0aGUgUmVnaW9uIEVkaXRvciBhcmUgbm90IG9uIHRoZSByZWZlcmVuY2Ugdm9sdW1lIHNob3duIGhlcmUsIHNvIHRoaXMgc2VsZWN0cyBieVxuICAgICAgICAgIHRoZSByZWdpb25zIGRyYXduIG92ZXIgdGhlIGNsb3VkIGluc3RlYWQuXG4gICAgICAgIDwvc21hbGw+XG4gICAgICAgIDxzbWFsbCBjbGFzcz1cInNjLWhpbnRcIiAqbmdJZj1cImlzM2QgJiYgIXNlbGVjdHNDbGFzc1ZvbHVtZXNcIj5cbiAgICAgICAgICBJbiAzRCBhIHJlZ2lvbiBjdXRzIHRocm91Z2ggdGhlIGNsb3VkJ3MgZnVsbCBkZXB0aC4gT3JiaXQgYW5kIGRyYXcgYWdhaW4gdG8gY3V0IGZyb20gYW5vdGhlciBhbmdsZS5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIXBpY2tlZENsYXNzZXMubGVuZ3RoXCI+XG4gICAgICAgICAgICBQaWNrIGNsYXNzZXMgaW4gdGhlIFJlZ2lvbiBFZGl0b3IncyBjbGFzcyB0cmVlIHRvIHNlbGVjdCBpbnNpZGUgdGhlaXIgdm9sdW1lcy5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9zbWFsbD5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSBPYnNlcnZhdGlvbnMsIHRoZW4gd2hhdCBlbHNlIGRyYXdzIHRoZW06IHRoZSBnZW5lIG1hcCwgdGhlIDNEIHNjZW5lLCBhbmQgdGhlXG4gICAgICAgICBjb250aW51b3VzLW9ubHkga25vYnMuIC0tPlxuICAgIDxzcGF0aWFsLW9ic2VydmF0aW9ucy1wYW5lbFxuICAgICAgW2NvbnRyb2xzXT1cImNvbnRyb2xzXCJcbiAgICAgIFtkYXRhc2V0XT1cImRzXCJcbiAgICAgIFt2aWV3XT1cInZpZXdcIlxuICAgICAgW2dlbmVzXT1cImdlbmVzXCJcbiAgICAgIFtsZWdlbmRdPVwibGVnZW5kXCJcbiAgICAgIFtjb2xvckJhckNzc109XCJjb2xvckJhckNzc1wiXG4gICAgICBbc2VsZWN0aW9uXT1cInNlbGVjdGlvblwiXG4gICAgICBbc2VsZWN0ZWRDYXRlZ29yeV09XCJzZWxlY3RlZENhdGVnb3J5XCJcbiAgICAgIFtjb2xvcm1hcE9wdGlvbnNdPVwiY29sb3JtYXBPcHRpb25zXCJcbiAgICAgIFtpczNkXT1cImlzM2RcIlxuICAgICAgW29wZW5dPVwib3Blbi5vYnNlcnZhdGlvbnNcIlxuICAgICAgKG9wZW5DaGFuZ2UpPVwic2V0T3Blbignb2JzZXJ2YXRpb25zJywgJGV2ZW50KVwiXG4gICAgICAoY2F0ZWdvcnlDbGlja2VkKT1cInNlbGVjdENhdGVnb3J5KCRldmVudClcIlxuICAgID48L3NwYXRpYWwtb2JzZXJ2YXRpb25zLXBhbmVsPlxuXG4gICAgPCEtLSBEaXN0cmlidXRpb25zIG9mIHdoYXRldmVyIHRoZSBtYXAgaXMgY29sb3VyZWQgYnkuIEluIHRoZSBTQU1FIGRpYWxvZyBhc1xuICAgICAgICAgdGhlIGNvbG91ciBjb250cm9scyBvbiBwdXJwb3NlOiBjaGFuZ2luZyB0aGUgZ2VuZSBhbmQgd2F0Y2hpbmcgdGhlXG4gICAgICAgICBkaXN0cmlidXRpb24gbW92ZSBpcyBvbmUgYWN0aW9uLCBhbmQgdHdvIGZsb2F0aW5nIHdpbmRvd3MgbWFkZSB0aGF0XG4gICAgICAgICBoYXJkZXIgdG8gc2VlIHJhdGhlciB0aGFuIGVhc2llci4gLS0+XG4gICAgPGRpdiBjbGFzcz1cInNjLXNlY3Rpb24gc2MtY2hhcnRzXCI+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICBjbGFzcz1cInNjLWRpc2Nsb3N1cmVcIlxuICAgICAgICAoY2xpY2spPVwidG9nZ2xlQ2hhcnRzKClcIlxuICAgICAgICBbYXR0ci5hcmlhLWV4cGFuZGVkXT1cImNoYXJ0c09wZW5cIlxuICAgICAgICBbYXR0ci5hcmlhLWNvbnRyb2xzXT1cImNoYXJ0c0JvZHlJZFwiXG4gICAgICA+XG4gICAgICAgIDxpIGNsYXNzPVwicGlcIiBbY2xhc3MucGktY2hldnJvbi1yaWdodF09XCIhY2hhcnRzT3BlblwiIFtjbGFzcy5waS1jaGV2cm9uLWRvd25dPVwiY2hhcnRzT3BlblwiPjwvaT5cbiAgICAgICAgPHNwYW4+RGlzdHJpYnV0aW9uPC9zcGFuPlxuICAgICAgICA8c21hbGwgKm5nSWY9XCIhY2hhcnRzT3BlbiAmJiB2aWV3LmNvbG9yQnlcIj5vZiB7eyBjb2xvckJ5TGFiZWwgfX08L3NtYWxsPlxuICAgICAgPC9idXR0b24+XG4gICAgICA8IS0tIEtlcHQgTU9VTlRFRCB3aGVuIGNvbGxhcHNlZCwgb25seSBoaWRkZW46IGRlc3Ryb3lpbmcgaXQgd291bGQgdGhyb3dcbiAgICAgICAgICAgYXdheSB0aGUgY2hhcnQga2luZCBhbmQgZ3JvdXBpbmcgdGhlIHVzZXIgcGlja2VkLiBgYWN0aXZlYCBpcyB3aGF0XG4gICAgICAgICAgIHN0b3BzIGl0IGRyYXdpbmcgd2hpbGUgaXQgaGFzIG5vIHNpemUuIC0tPlxuICAgICAgPGRpdiBbaWRdPVwiY2hhcnRzQm9keUlkXCIgW2hpZGRlbl09XCIhY2hhcnRzT3BlblwiPlxuICAgICAgICA8c3BhdGlhbC1jaGFydHMgW2FjdGl2ZV09XCJ2aXNpYmxlICYmIGNoYXJ0c09wZW5cIj48L3NwYXRpYWwtY2hhcnRzPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwic2MtYnRuc1wiPlxuICAgICAgPHAtYnV0dG9uIGxhYmVsPVwiUmVzZXRcIiBzaXplPVwic21hbGxcIiBbdGV4dF09XCJ0cnVlXCIgKG9uQ2xpY2spPVwicmVzZXQoKVwiPjwvcC1idXR0b24+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9wLWRpYWxvZz5cbiJdfQ==
437
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BhdGlhbC1jb250cm9scy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3NwYXRpYWwtY29udHJvbHMvc3BhdGlhbC1jb250cm9scy5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9zcmMvbGliL3NwYXRpYWwtY29udHJvbHMvc3BhdGlhbC1jb250cm9scy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsVUFBVSxFQUNWLFlBQVksRUFDWixNQUFNLEVBQ04sS0FBSyxFQUNMLE1BQU0sRUFFTixNQUFNLEVBQ04sU0FBUyxFQUNULE1BQU0sR0FDUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzdDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM5QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDbEQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM5QyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDaEQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUVyQyxPQUFPLEVBQUUsVUFBVSxFQUFtRCxNQUFNLGtDQUFrQyxDQUFDO0FBQy9HLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLDJDQUEyQyxDQUFDO0FBRW5GLE9BQU8sRUFBaUQsb0JBQW9CLEVBQUUsTUFBTSw0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QUFRLEVBQUUsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQy9GLENBQUM7OEdBL1pVLHdCQUF3QixrQkF3R3pCLFVBQVU7a0dBeEdULHdCQUF3QiwrTUFFeEIsc0JBQXNCLGdEQ3RGbkMsb3hTQTBOQSxzelBEdEpJLFlBQVksMExBQ1osV0FBVyw4VkFDWCxZQUFZLDZYQUNaLGNBQWMsZ1pBQ2QsWUFBWSwrUkFDWixZQUFZLHV1QkFDWixhQUFhLHNYQUNiLDBCQUEwQixrSUFDMUIsZ0NBQWdDLDhOQUNoQyxpQ0FBaUMsb1JBQ2pDLHNCQUFzQjs7MkZBTWIsd0JBQXdCO2tCQXBCcEMsU0FBUzsrQkFDRSxrQkFBa0IsY0FDaEIsSUFBSSxXQUNQO3dCQUNQLFlBQVk7d0JBQ1osV0FBVzt3QkFDWCxZQUFZO3dCQUNaLGNBQWM7d0JBQ2QsWUFBWTt3QkFDWixZQUFZO3dCQUNaLGFBQWE7d0JBQ2IsMEJBQTBCO3dCQUMxQixnQ0FBZ0M7d0JBQ2hDLGlDQUFpQzt3QkFDakMsc0JBQXNCO3FCQUN2QixtQkFHZ0IsdUJBQXVCLENBQUMsTUFBTTs7MEJBMEc1QyxNQUFNOzJCQUFDLFVBQVU7OERBdEd1QixNQUFNO3NCQUFoRCxTQUFTO3VCQUFDLHNCQUFzQjtnQkFnQnhCLE9BQU87c0JBQWYsS0FBSztnQkFJRyxJQUFJO3NCQUFaLEtBQUs7Z0JBRUksYUFBYTtzQkFBdEIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBEZXN0cm95UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIEluamVjdCxcbiAgSW5wdXQsXG4gIE5nWm9uZSxcbiAgT25Jbml0LFxuICBPdXRwdXQsXG4gIFZpZXdDaGlsZCxcbiAgaW5qZWN0LFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IHRha2VVbnRpbERlc3Ryb3llZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUvcnhqcy1pbnRlcm9wJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBGb3Jtc01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IEJ1dHRvbk1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvYnV0dG9uJztcbmltcG9ydCB7IENoZWNrYm94TW9kdWxlIH0gZnJvbSAncHJpbWVuZy9jaGVja2JveCc7XG5pbXBvcnQgeyBTbGlkZXJNb2R1bGUgfSBmcm9tICdwcmltZW5nL3NsaWRlcic7XG5pbXBvcnQgeyBEaWFsb2dNb2R1bGUgfSBmcm9tICdwcmltZW5nL2RpYWxvZyc7XG5pbXBvcnQgeyBUb29sdGlwTW9kdWxlIH0gZnJvbSAncHJpbWVuZy90b29sdGlwJztcbmltcG9ydCB7IGNvbWJpbmVMYXRlc3QgfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgVklTVUFMSVpFUiwgSVZpc3VhbGl6ZXIsIElTcGF0aWFsQ29udHJvbHMsIFJvaVNlbGVjdGlvbk1vZGUgfSBmcm9tICcuLi9jb250cmFjdHMvdmlzdWFsaXplci5jb250cmFjdCc7XG5pbXBvcnQgeyBTcGF0aWFsQ2hhcnRzQ29tcG9uZW50IH0gZnJvbSAnLi9zcGF0aWFsLWNoYXJ0cy9zcGF0aWFsLWNoYXJ0cy5jb21wb25lbnQnO1xuaW1wb3J0IHsgU3BhdGlhbERhdGFzZXQgfSBmcm9tICcuLi9jb250cmFjdHMvc3BhdGlhbC1kYXRhc2V0LmNvbnRyYWN0JztcbmltcG9ydCB7IENlbGxzM2RTdGF0dXMsIENvbG9ybWFwTm9kZSwgU3BhdGlhbFZpZXdTdGF0ZSwgREVGQVVMVF9TUEFUSUFMX1ZJRVcgfSBmcm9tICcuLi9jb250cmFjdHMvZGlzcGxheS10eXBlcyc7XG5pbXBvcnQgeyBkYXRhc2V0UmVnaW9uU2V0IH0gZnJvbSAnLi4vdmlzdWFsaXplci9zcGF0aWFsLXJlZ2lvbi1zZXQnO1xuaW1wb3J0IHsgUGFuZWxPcHRpb24sIHBhcnNlR2VuZUdyb3VwcyB9IGZyb20gJy4uL3NwYXRpYWwvc3BhdGlhbC1wYW5lbC1tb2RlbCc7XG5pbXBvcnQgeyBTcGF0aWFsU2VsZWN0aW9uTWFzaywgZW1wdHlTZWxlY3Rpb24gfSBmcm9tICcuLi9zcGF0aWFsL3NwYXRpYWwtc2VsZWN0aW9uJztcbmltcG9ydCB7IEdlbmVQaWNrZXJNb2RlbCB9IGZyb20gJy4vc3BhdGlhbC1nZW5lLXBpY2tlcic7XG5pbXBvcnQgeyBTcGF0aWFsS2V5TW9kZWwsIFNwYXRpYWxMZWdlbmRFbnRyeSB9IGZyb20gJy4vc3BhdGlhbC1rZXkvc3BhdGlhbC1rZXkubW9kZWwnO1xuaW1wb3J0IHsgY29sb3JCeUxhYmVsIH0gZnJvbSAnLi9zcGF0aWFsLWtleS9zcGF0aWFsLWtleS5jb21wb25lbnQnO1xuaW1wb3J0IHsgU3BhdGlhbENlbGxzUGFuZWxDb21wb25lbnQgfSBmcm9tICcuL3NwYXRpYWwtY2VsbHMtcGFuZWwvc3BhdGlhbC1jZWxscy1wYW5lbC5jb21wb25lbnQnO1xuaW1wb3J0IHsgU3BhdGlhbFRyYW5zY3JpcHRzUGFuZWxDb21wb25lbnQgfSBmcm9tICcuL3NwYXRpYWwtdHJhbnNjcmlwdHMtcGFuZWwvc3BhdGlhbC10cmFuc2NyaXB0cy1wYW5lbC5jb21wb25lbnQnO1xuaW1wb3J0IHsgU3BhdGlhbE9ic2VydmF0aW9uc1BhbmVsQ29tcG9uZW50IH0gZnJvbSAnLi9zcGF0aWFsLW9ic2VydmF0aW9ucy1wYW5lbC9zcGF0aWFsLW9ic2VydmF0aW9ucy1wYW5lbC5jb21wb25lbnQnO1xuXG4vKiogQGRlcHJlY2F0ZWQgTW92ZWQgdG8gYHNwYXRpYWwta2V5L3NwYXRpYWwta2V5Lm1vZGVsYDsgcmUtZXhwb3J0ZWQgZm9yIG9uZSByZWxlYXNlLiAqL1xuZXhwb3J0IHR5cGUgeyBTcGF0aWFsTGVnZW5kRW50cnkgfTtcblxuLyoqIEBkZXByZWNhdGVkIE1vdmVkIHRvIGBzcGF0aWFsL3NwYXRpYWwtcGFuZWwtbW9kZWxgOyByZS1leHBvcnRlZCBmb3Igb25lIHJlbGVhc2UuICovXG5leHBvcnQgeyBwYXJzZUdlbmVHcm91cHMgfTtcblxuLyoqIFBlci1pbnN0YW5jZSBpZCBzb3VyY2Ug4oCUIHNlZSB7QGxpbmsgU3BhdGlhbENvbnRyb2xzQ29tcG9uZW50LmNoYXJ0c0JvZHlJZH0uICovXG5sZXQgY29udHJvbHNJbnN0YW5jZVNlcSA9IDA7XG5cbi8qKlxuICogU3BhdGlhbC1vbWljcyBjb250cm9sczogYSBub24tbW9kYWwsIHJlc2l6YWJsZSwgZHJhZ2dhYmxlIGRpYWxvZyBmb3IgY2hvb3NpbmdcbiAqIHdoYXQgdGhlIG9ic2VydmF0aW9uIG1hcmtlcnMgYXJlIGNvbG91cmVkIGJ5LCBhbmQgaG93IHRoZXkgYXJlIGRyYXduLlxuICpcbiAqIERlcGVuZHMgb25seSBvbiB7QGxpbmsgSVNwYXRpYWxDb250cm9sc30sIHJlYWNoZWQgdGhyb3VnaCB0aGUgYFZJU1VBTElaRVJgXG4gKiBjb250cmFjdCB0b2tlbiDigJQgbmV2ZXIgYSBjb25jcmV0ZSBiYWNrZW5kIOKAlCBtaXJyb3JpbmcgaG93XG4gKiBgQ2hhbm5lbEhpc3RvZ3JhbUNvbXBvbmVudGAgZGVwZW5kcyBvbmx5IG9uIGBDSEFOTkVMX0hJU1RPR1JBTV9BUElgLiBXaGVuIG5vXG4gKiBob3N0IGhhcyBib3VuZCBgU1BBVElBTF9EQVRBX1BPUlRgLCBgZ2V0U3BhdGlhbENvbnRyb2xzKClgIHJldHVybnMgbnVsbCBhbmRcbiAqIHRoZSBkaWFsb2cgcmVuZGVycyBhbiBleHBsYW5hdG9yeSBlbXB0eSBzdGF0ZSByYXRoZXIgdGhhbiBkZWFkIGNvbnRyb2xzLlxuICpcbiAqIFRoZSBsZWdlbmQgc3dhdGNoZXMgYW5kIHRoZSBjb250aW51b3VzIGNvbG91ciBiYXIgYXJlIGJ1aWx0IHdpdGggdGhlIFNBTUVcbiAqIGZ1bmN0aW9ucyB0aGUgcmVuZGVyZXIgdXNlcyAoYGNhdGVnb3J5Q29sb3JzYCDihpIgYHJlc29sdmVDYXRlZ29yeUNvbG9yc2AsXG4gKiBgc3BhdGlhbENvbnRpbnVvdXNMdXRgKSwgc28gdGhlIGtleSBjYW5ub3QgZHJpZnQgZnJvbSB3aGF0IGlzIG9uIHNjcmVlbi5cbiAqXG4gKiBPblB1c2g6IHRoZSBjb250cm9scycgc3RyZWFtcywgdGhlIGtleSBhbmQgZ2VuZS1saXN0IG1vZGVscyAod2hpY2ggcmUtZW50ZXIgdGhlIHpvbmVcbiAqIHdoZW4gdGhlaXIgYXN5bmMgd29yayBsYW5kcykgYW5kIGFuIGF3YWl0ZWQgY2F0ZWdvcnkgc2VsZWN0aW9uIG1hcmsgaXQgZm9yIGNoZWNrLlxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdzcGF0aWFsLWNvbnRyb2xzJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIENvbW1vbk1vZHVsZSxcbiAgICBGb3Jtc01vZHVsZSxcbiAgICBCdXR0b25Nb2R1bGUsXG4gICAgQ2hlY2tib3hNb2R1bGUsXG4gICAgU2xpZGVyTW9kdWxlLFxuICAgIERpYWxvZ01vZHVsZSxcbiAgICBUb29sdGlwTW9kdWxlLFxuICAgIFNwYXRpYWxDZWxsc1BhbmVsQ29tcG9uZW50LFxuICAgIFNwYXRpYWxUcmFuc2NyaXB0c1BhbmVsQ29tcG9uZW50LFxuICAgIFNwYXRpYWxPYnNlcnZhdGlvbnNQYW5lbENvbXBvbmVudCxcbiAgICBTcGF0aWFsQ2hhcnRzQ29tcG9uZW50LFxuICBdLFxuICB0ZW1wbGF0ZVVybDogJy4vc3BhdGlhbC1jb250cm9scy5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3NwYXRpYWwtY29udHJvbHMuY29tcG9uZW50LnNjc3MnXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG59KVxuZXhwb3J0IGNsYXNzIFNwYXRpYWxDb250cm9sc0NvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIC8qKiBUaGUgZW1iZWRkZWQgY2hhcnQsIHNvIGEgZGlhbG9nIHJlc2l6ZSBjYW4gcmUtZml0IGl0LiAqL1xuICBAVmlld0NoaWxkKFNwYXRpYWxDaGFydHNDb21wb25lbnQpIHByaXZhdGUgY2hhcnRzPzogU3BhdGlhbENoYXJ0c0NvbXBvbmVudDtcblxuICAvKipcbiAgICogUmUtZml0IHRoZSBjaGFydCBhZnRlciB0aGUgZGlhbG9nIGlzIHJlc2l6ZWQuXG4gICAqXG4gICAqIFBsb3RseSBkb2VzIG5vdCBmb2xsb3cgYSBjb250YWluZXIgcmVzaXplIG9uIGl0cyBvd24g4oCUIGl0cyBgcmVzcG9uc2l2ZWBcbiAgICogb3B0aW9uIGxpc3RlbnMgZm9yIFdJTkRPVyByZXNpemVzIG9ubHksIHNvIGRyYWdnaW5nIHRoZSBkaWFsb2cncyBoYW5kbGVcbiAgICogcmVhY2hlcyBpdCB0aHJvdWdoIG5vdGhpbmcuIFByaW1lTkcgdGVsbHMgdXMgd2hlbiB0aGUgZHJhZyBlbmRzLCB3aGljaCBpcyBhXG4gICAqIGZhciBtb3JlIGRpcmVjdCBzaWduYWwgdGhhbiB3YXRjaGluZyBib3hlcywgYW5kIGZpcmluZyBvbmNlIG9uIHJlbGVhc2UgbWVhbnNcbiAgICogbm8gcmVsYXlvdXQgY2h1cm4gZHVyaW5nIHRoZSBkcmFnLlxuICAgKi9cbiAgcHJvdGVjdGVkIG9uUmVzaXplRW5kKCk6IHZvaWQge1xuICAgIHRoaXMuY2hhcnRzPy5yZXNpemUoKTtcbiAgfVxuXG4gIC8qKiBEaWFsb2cgdmlzaWJpbGl0eSwgdHdvLXdheSBib3VuZCBzbyBhIHRvb2xiYXIgYnV0dG9uIGNhbiBvcGVuIGl0LiAqL1xuICBASW5wdXQoKSB2aXNpYmxlID0gZmFsc2U7XG4gIC8qKiBTZXQgd2hpbGUgdGhlIDNEIGNsb3VkIGlzIHRoZSBhY3RpdmUgbW9kZS4gQ2hhbmdlcyB3aGF0IHRoZSBST0kgc2VsZWN0aW9uXG4gICAqICBNRUFOUyDigJQgYSBzY3JlZW4tc3BhY2UgbGFzc28gY3V0dGluZyB0aHJvdWdoIHRoZSBjbG91ZCdzIGZ1bGwgZGVwdGggcmF0aGVyXG4gICAqICB0aGFuIGEgc2hhcGUgaW4gdGlzc3VlIGNvb3JkaW5hdGVzIOKAlCBzbyB0aGUgaGludCBiZWxvdyBpdCBzYXlzIHNvLiAqL1xuICBASW5wdXQoKSBpczNkID0gZmFsc2U7XG4gIC8qKiBUaGUgZGlhbG9nIHdhcyBvcGVuZWQgb3IgY2xvc2VkOyB0d28td2F5IHdpdGgge0BsaW5rIHZpc2libGV9LiAqL1xuICBAT3V0cHV0KCkgdmlzaWJsZUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4oKTtcblxuICAvKiogTnVsbCB3aGVuIHRoZSBob3N0IGJvdW5kIG5vIGBTUEFUSUFMX0RBVEFfUE9SVGAuICovXG4gIHByb3RlY3RlZCBjb250cm9sczogSVNwYXRpYWxDb250cm9scyB8IG51bGwgPSBudWxsO1xuICBwcm90ZWN0ZWQgZGF0YXNldDogU3BhdGlhbERhdGFzZXQgfCBudWxsID0gbnVsbDtcbiAgcHJvdGVjdGVkIHZpZXc6IFNwYXRpYWxWaWV3U3RhdGUgPSB7IC4uLkRFRkFVTFRfU1BBVElBTF9WSUVXIH07XG5cbiAgLyoqXG4gICAqIEdlbmUgcGlja2VyOiBhIGZpbHRlcmFibGUgZHJvcGRvd24gcmF0aGVyIHRoYW4gYSBmcmVlLXRleHQgdHlwZWFoZWFkLCBzbyB0aGVcbiAgICogb3B0aW9ucyBhcmUgdmlzaWJsZSBiZWZvcmUgYW55dGhpbmcgaXMgdHlwZWQgYW5kIGVhY2gga2V5c3Ryb2tlIG5hcnJvd3MgYSBsaXN0XG4gICAqIHRoZSB1c2VyIGNhbiBzZWUuIE9uZSBtb2RlbCBmZWVkcyBldmVyeSBnZW5lIGRyb3Bkb3duIG9mIHRoZSBwYW5lbC5cbiAgICovXG4gIHByb3RlY3RlZCByZWFkb25seSBnZW5lcyA9IG5ldyBHZW5lUGlja2VyTW9kZWwoXG4gICAgKCkgPT4gdGhpcy5jb250cm9scyxcbiAgICAoKSA9PiBbXG4gICAgICAuLi4odGhpcy52aWV3Py50cmFuc2NyaXB0R2VuZXMgPz8gW10pLFxuICAgICAgLi4uKHRoaXMudmlldz8ub2JzZXJ2YXRpb25HZW5lcyA/PyBbXSksXG4gICAgICAuLi4odGhpcy52aWV3Py5jb2xvckJ5Py5raW5kID09PSAnZmVhdHVyZScgPyBbdGhpcy52aWV3LmNvbG9yQnkubmFtZV0gOiBbXSksXG4gICAgXSxcbiAgICAoZm4pID0+IHRoaXMucnVuQW5kTWFyayhmbiksXG4gICk7XG4gIC8qKiBUaGUgZ2VuZSBkcm9wZG93bnMnIG9wdGlvbnMuICovXG4gIGdldCBnZW5lT3B0aW9ucygpOiBQYW5lbE9wdGlvbjxzdHJpbmc+W10ge1xuICAgIHJldHVybiB0aGlzLmdlbmVzLm9wdGlvbnM7XG4gIH1cbiAgLyoqIFRydWUgd2hlbiB0aGUgb3B0aW9ucyBjb21lIGZyb20gdGhlIHBvcnQgcGVyIGtleXN0cm9rZSByYXRoZXIgdGhhbiBhIHJlc2lkZW50IGxpc3QuICovXG4gIGdldCBnZW5lc0FyZVJlbW90ZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5nZW5lcy5yZW1vdGU7XG4gIH1cbiAgZ2V0IGdlbmVTZWFyY2hGYWlsZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZ2VuZXMuZmFpbGVkO1xuICB9XG5cbiAgLyoqIFRoZSBrZXkg4oCUIGxlZ2VuZCBvciBjb2xvdXIgYmFyIOKAlCBmb3IgdGhlIGFjdGl2ZSBjb2xvdXJpbmcuIEtlcHQgaGVyZSwgbm90IGluXG4gICAqICBgPHNwYXRpYWwta2V5PmA6IHdoZXRoZXIgdGhlIGNvbG91cmluZyBpcyBjYXRlZ29yaWNhbCBkZWNpZGVzIHdoaWNoIGtub2JzIHRoZSByZXN0IG9mXG4gICAqICB0aGUgcGFuZWwgb2ZmZXJzLCB3aGV0aGVyIG9yIG5vdCB0aGUga2V5IGlzIG9uIHNjcmVlbi4gKi9cbiAgcmVhZG9ubHkga2V5ID0gbmV3IFNwYXRpYWxLZXlNb2RlbCgoZm4pID0+IHRoaXMucnVuQW5kTWFyayhmbikpO1xuICAvKiogQ2F0ZWdvcmljYWwga2V5LCBvciBudWxsIHdoZW4gdGhlIGFjdGl2ZSBjb2xvdXJpbmcgaXMgY29udGludW91cy4gKi9cbiAgcHJvdGVjdGVkIGdldCBsZWdlbmQoKTogU3BhdGlhbExlZ2VuZEVudHJ5W10gfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy5rZXkubGVnZW5kO1xuICB9XG4gIC8qKiBDU1MgZ3JhZGllbnQgZm9yIGEgY29udGludW91cyBjb2xvdXJpbmcsIG9yIG51bGwgd2hlbiBjYXRlZ29yaWNhbC4gKi9cbiAgcHJvdGVjdGVkIGdldCBjb2xvckJhckNzcygpOiBzdHJpbmcgfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy5rZXkuY29sb3JCYXJDc3M7XG4gIH1cblxuICAvKiogQ3VycmVudCBzZWxlY3Rpb24g4oCUIGRyaXZlcyB0aGUgY291bnQsIHRoZSBDbGVhciBidXR0b24gYW5kIHRoZSBtdXRpbmcuICovXG4gIHByb3RlY3RlZCBzZWxlY3Rpb246IFNwYXRpYWxTZWxlY3Rpb25NYXNrID0gZW1wdHlTZWxlY3Rpb24oKTtcbiAgLyoqIFRoZSBsZWdlbmQgcm93IHdob3NlIGNhdGVnb3J5IGlzIGN1cnJlbnRseSBzZWxlY3RlZCwgZm9yIGhpZ2hsaWdodGluZy4gKi9cbiAgcHJvdGVjdGVkIHNlbGVjdGVkQ2F0ZWdvcnk6IG51bWJlciB8IG51bGwgPSBudWxsO1xuICAvKiogQW4gUk9JIHNlbGVjdGlvbiB0aGF0IG1hdGNoZWQgbm90aGluZywgc28gdGhlIFVJIGNhbiBzYXkgc28gcmF0aGVyIHRoYW5cbiAgICogIGxvb2tpbmcgbGlrZSB0aGUgYnV0dG9uIGRpZCBub3RoaW5nLiAqL1xuICBwcm90ZWN0ZWQgc2VsZWN0aW9uTWlzc2VkID0gZmFsc2U7XG4gIC8qKiBUaGUgbW9kZSBvZiB0aGUgc2VsZWN0aW9uIHRoYXQge0BsaW5rIHNlbGVjdGlvbk1pc3NlZH06IHdoYXQgaXQgZm91bmQgbm90aGluZyBpbnNpZGUuICovXG4gIHByb3RlY3RlZCBtaXNzZWRNb2RlOiBSb2lTZWxlY3Rpb25Nb2RlID0gJ3JlZ2lvbnMnO1xuICAvKiogVGhlIHJlZ2lvbiBjbGFzc2VzIHBpY2tlZCBpbiB0aGUgUmVnaW9uIEVkaXRvcjogaW4gM0QsIFwiU2VsZWN0IGZyb20gUk9Jc1wiIHNlbGVjdHMgaW5zaWRlIHRoZW0uICovXG4gIHByb3RlY3RlZCBwaWNrZWRDbGFzc2VzOiByZWFkb25seSBzdHJpbmdbXSA9IFtdO1xuICAvKiogV2hpbGUgXCJTZWxlY3QgZnJvbSBST0lzXCIgcmVhZHMgdGhlIHBpY2tlZCBjbGFzc2VzJyBvdXRsaW5lcy4gKi9cbiAgcHJvdGVjdGVkIHNlbGVjdGluZ0Zyb21SZWdpb25zID0gZmFsc2U7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIERpc3RyaWJ1dGlvbiBzZWN0aW9uIGlzIGV4cGFuZGVkLiBDb2xsYXBzZWQgYnkgZGVmYXVsdDogdGhlXG4gICAqIHBhbmVsJ3MgcHJpbWFyeSBqb2IgaXMgdGhlIGNvbG91ciBjb250cm9scywgYW5kIHRoZSBjaGFydCByb3VnaGx5IGRvdWJsZXNcbiAgICogaXRzIGhlaWdodC5cbiAgICovXG4gIHByb3RlY3RlZCBjaGFydHNPcGVuID0gZmFsc2U7XG4gIC8qKiBQZXItaW5zdGFuY2UgaWQgZm9yIHRoZSBjb2xsYXBzaWJsZSBib2R5LCBzbyBgYXJpYS1jb250cm9sc2AgcG9pbnRzIGF0IG9uZVxuICAgKiAgZWxlbWVudCBhbmQgZXhwYW5kaW5nIHRoZSBzZWNvbmQgcGFuZWwgY2Fubm90IHNjcm9sbCB0aGUgZmlyc3Qgb25lJ3MgY2hhcnQuICovXG4gIHByb3RlY3RlZCByZWFkb25seSBjaGFydHNCb2R5SWQgPSBgc2MtY2hhcnRzLWJvZHktJHsrK2NvbnRyb2xzSW5zdGFuY2VTZXF9YDtcblxuICAvKiogQ29sb3JtYXAgdHJlZSBmb3IgdGhlIGNvbnRpbnVvdXMgY29sb3VyIHNjYWxlIGFuZCB0aGUgZGVuc2l0eSBtYXA6IHRoZSBsaWJyYXJ5J3NcbiAgICogIG93biBgQ09MT1JNQVBfT1BUSU9OU2AuICovXG4gIHByb3RlY3RlZCBjb2xvcm1hcE9wdGlvbnM6IENvbG9ybWFwTm9kZVtdID0gW107XG5cbiAgcHJpdmF0ZSBjb2xvcm1hcDogQ29sb3JtYXBOb2RlIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgcmV2ZXJzZSA9IGZhbHNlO1xuICBwcml2YXRlIHJlYWRvbmx5IGRlc3Ryb3lSZWYgPSBpbmplY3QoRGVzdHJveVJlZik7XG4gIHByaXZhdGUgcmVhZG9ubHkgY2RyID0gaW5qZWN0KENoYW5nZURldGVjdG9yUmVmKTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBASW5qZWN0KFZJU1VBTElaRVIpIHByaXZhdGUgcmVhZG9ubHkgdml6OiBJVmlzdWFsaXplcixcbiAgICBwcml2YXRlIHJlYWRvbmx5IHpvbmU6IE5nWm9uZSxcbiAgKSB7fVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMuY29udHJvbHMgPSB0aGlzLnZpei5nZXRTcGF0aWFsQ29udHJvbHM/LigpID8/IG51bGw7XG4gICAgdGhpcy5jb2xvcm1hcE9wdGlvbnMgPSB0aGlzLnZpei5nZXRDb2xvcm1hcE9wdGlvbnM/LigpID8/IFtdO1xuICAgIGlmICghdGhpcy5jb250cm9scykgcmV0dXJuO1xuXG4gICAgY29uc3QgdW50aWxEZXN0cm95ZWQgPSA8VD4oKSA9PiB0YWtlVW50aWxEZXN0cm95ZWQ8VD4odGhpcy5kZXN0cm95UmVmKTtcbiAgICB0aGlzLmNvbnRyb2xzXG4gICAgICAuZ2V0RGF0YXNldCQoKVxuICAgICAgLnBpcGUodW50aWxEZXN0cm95ZWQoKSlcbiAgICAgIC5zdWJzY3JpYmUoKGRhdGFzZXQpID0+IHtcbiAgICAgICAgdGhpcy5kYXRhc2V0ID0gZGF0YXNldDtcbiAgICAgICAgdGhpcy5nZW5lcy5zZXREYXRhc2V0KGRhdGFzZXQpO1xuICAgICAgICAvLyBUaGUgT2JzZXJ2YXRpb25zIHNlY3Rpb24gbGVhZHMuXG4gICAgICAgIHRoaXMub3BlbiA9IHsgLi4udGhpcy5vcGVuLCBvYnNlcnZhdGlvbnM6ICEhZGF0YXNldCB9O1xuICAgICAgICB2b2lkIHRoaXMucmVmcmVzaEtleSgpO1xuICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICAgIH0pO1xuXG4gICAgdGhpcy5jb250cm9sc1xuICAgICAgLmdldFZpZXdTdGF0ZSQoKVxuICAgICAgLnBpcGUodW50aWxEZXN0cm95ZWQoKSlcbiAgICAgIC5zdWJzY3JpYmUoKHZpZXcpID0+IHtcbiAgICAgICAgdGhpcy52aWV3ID0gdmlldztcbiAgICAgICAgdm9pZCB0aGlzLnJlZnJlc2hLZXkoKTtcbiAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgICB9KTtcblxuICAgIC8vIFRoZSByZW5kZXJlcidzIG93biBzdHJlYW1zIG1heSBlbWl0IG91dHNpZGUgdGhlIHpvbmU6IHJlLWVudGVyZWQgaGVyZSwgb25jZSwgZm9yXG4gICAgLy8gZXZlcnkgcGFuZWwgdGhleSBmZWVkLlxuICAgIHRoaXMuY29udHJvbHNcbiAgICAgIC5nZXRDZWxsczNkU3RhdHVzJD8uKClcbiAgICAgID8ucGlwZSh1bnRpbERlc3Ryb3llZCgpKVxuICAgICAgLnN1YnNjcmliZSgocykgPT5cbiAgICAgICAgdGhpcy5ydW5BbmRNYXJrKCgpID0+IHtcbiAgICAgICAgICB0aGlzLmNlbGxzM2RTdGF0dXMgPSBzO1xuICAgICAgICB9KSxcbiAgICAgICk7XG4gICAgdGhpcy5jb250cm9sc1xuICAgICAgLmdldENlbGxzM2RBdmFpbGFibGUkPy4oKVxuICAgICAgPy5waXBlKHVudGlsRGVzdHJveWVkKCkpXG4gICAgICAuc3Vic2NyaWJlKChhKSA9PlxuICAgICAgICB0aGlzLnJ1bkFuZE1hcmsoKCkgPT4ge1xuICAgICAgICAgIHRoaXMuY2VsbHMzZEF2YWlsYWJsZSA9IGE7XG4gICAgICAgIH0pLFxuICAgICAgKTtcbiAgICBjb25zdCBlc3RpbWF0ZSQgPSB0aGlzLmNvbnRyb2xzLmdldFRyYW5zY3JpcHRFc3RpbWF0ZSQ/LigpO1xuICAgIGVzdGltYXRlJD8ucGlwZSh1bnRpbERlc3Ryb3llZCgpKS5zdWJzY3JpYmUoKGUpID0+XG4gICAgICB0aGlzLnJ1bkFuZE1hcmsoKCkgPT4ge1xuICAgICAgICB0aGlzLmVzdGltYXRlID0gZTtcbiAgICAgIH0pLFxuICAgICk7XG4gICAgY29uc3QgY291bnRzJCA9IHRoaXMuY29udHJvbHMuZ2V0R2VuZUNvdW50c0luVmlldyQ/LigpO1xuICAgIGNvdW50cyQ/LnBpcGUodW50aWxEZXN0cm95ZWQoKSkuc3Vic2NyaWJlKChjKSA9PlxuICAgICAgdGhpcy5ydW5BbmRNYXJrKCgpID0+IHtcbiAgICAgICAgdGhpcy5nZW5lQ291bnRzID0gYztcbiAgICAgIH0pLFxuICAgICk7XG4gICAgY29uc3QgZGVuc2l0eSQgPSB0aGlzLmNvbnRyb2xzLmdldERlbnNpdHlTdGF0cyQ/LigpO1xuICAgIGRlbnNpdHkkPy5waXBlKHVudGlsRGVzdHJveWVkKCkpLnN1YnNjcmliZSgoZCkgPT5cbiAgICAgIHRoaXMucnVuQW5kTWFyaygoKSA9PiB7XG4gICAgICAgIHRoaXMuZGVuc2l0eVN0YXRzID0gZDtcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICB0aGlzLmNvbnRyb2xzXG4gICAgICAuZ2V0U2VsZWN0aW9uJCgpXG4gICAgICAucGlwZSh1bnRpbERlc3Ryb3llZCgpKVxuICAgICAgLnN1YnNjcmliZSgoc2VsZWN0aW9uKSA9PlxuICAgICAgICAvLyBTZXQgZnJvbSBvdXRzaWRlIHRoZSB6b25lIHRvbzogYSBzZWxlY3Rpb24gZnJvbSB0aGUgcmVnaW9uIGNsYXNzZXMnIHZvbHVtZXMuXG4gICAgICAgIHRoaXMucnVuQW5kTWFyaygoKSA9PiB7XG4gICAgICAgICAgdGhpcy5zZWxlY3Rpb24gPSBzZWxlY3Rpb247XG4gICAgICAgICAgaWYgKHNlbGVjdGlvbi5jb3VudCA9PT0gMCkgdGhpcy5zZWxlY3RlZENhdGVnb3J5ID0gbnVsbDtcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgdGhpcy5jb250cm9sc1xuICAgICAgLmdldFBpY2tlZFJlZ2lvbkNsYXNzZXMkPy4oKVxuICAgICAgPy5waXBlKHVudGlsRGVzdHJveWVkKCkpXG4gICAgICAuc3Vic2NyaWJlKChjbGFzc2VzKSA9PlxuICAgICAgICB0aGlzLnJ1bkFuZE1hcmsoKCkgPT4ge1xuICAgICAgICAgIHRoaXMucGlja2VkQ2xhc3NlcyA9IGNsYXNzZXM7XG4gICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgIC8vIFRoZSBjb2xvdXIgYmFyIG11c3QgdXNlIHRoZSBjb2xvcm1hcCB0aGUgcmVuZGVyZXIgaXMgdXNpbmcuXG4gICAgY29tYmluZUxhdGVzdChbdGhpcy52aXouZ2V0Q29sb3JtYXAoKSwgdGhpcy52aXouZ2V0UmV2ZXJzZVNjYWxlKCldKVxuICAgICAgLnBpcGUodW50aWxEZXN0cm95ZWQoKSlcbiAgICAgIC5zdWJzY3JpYmUoKFtjb2xvcm1hcCwgcmV2ZXJzZV0pID0+IHtcbiAgICAgICAgdGhpcy5jb2xvcm1hcCA9IChjb2xvcm1hcCBhcyBDb2xvcm1hcE5vZGUpID8/IG51bGw7XG4gICAgICAgIHRoaXMucmV2ZXJzZSA9ICEhcmV2ZXJzZTtcbiAgICAgICAgdm9pZCB0aGlzLnJlZnJlc2hLZXkoKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgLyoqIEFwcGx5IGFuIGFzeW5jIHJlc3VsdCBpbnNpZGUgdGhlIHpvbmUgYW5kIHJlLXJlbmRlciB0aGlzIE9uUHVzaCBkaWFsb2cuICovXG4gIHByaXZhdGUgcnVuQW5kTWFyayhmbjogKCkgPT4gdm9pZCk6IHZvaWQge1xuICAgIHRoaXMuem9uZS5ydW4oKCkgPT4ge1xuICAgICAgZm4oKTtcbiAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIG9uVmlzaWJsZUNoYW5nZSh2YWx1ZTogYm9vbGVhbik6IHZvaWQge1xuICAgIHRoaXMudmlzaWJsZSA9IHZhbHVlO1xuICAgIHRoaXMudmlzaWJsZUNoYW5nZS5lbWl0KHZhbHVlKTtcbiAgfVxuXG4gIC8vIOKUgOKUgCB0aGUgc2hhcmVkIGdlbmUgbGlzdCDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICAvKiogQSBrZXlzdHJva2UgaW4gYSBnZW5lIGRyb3Bkb3duJ3MgZmlsdGVyIGJveCDigJQgc2VlIHtAbGluayBHZW5lUGlja2VyTW9kZWwub25GaWx0ZXJ9LiAqL1xuICBvbkdlbmVGaWx0ZXIocXVlcnk6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiB0aGlzLmdlbmVzLm9uRmlsdGVyKHF1ZXJ5KTtcbiAgfVxuXG4gIC8qKiBBIGdlbmUgZHJvcGRvd24gb3BlbmVkIOKAlCBzZWUge0BsaW5rIEdlbmVQaWNrZXJNb2RlbC5lbnN1cmVMaXN0fS4gKi9cbiAgZW5zdXJlR2VuZUxpc3QoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIHRoaXMuZ2VuZXMuZW5zdXJlTGlzdCgpO1xuICB9XG5cbiAgLy8g4pSA4pSAIHNlbGVjdGlvbiDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICAvKiogU2VsZWN0IGV2ZXJ5IG9ic2VydmF0aW9uIGluc2lkZSB0aGUgZHJhd24gcmVnaW9ucyAodGhlaXIgdW5pb24pIOKAlCBpbiAzRCwgaW5zaWRlIHRoZVxuICAgKiAgcGlja2VkIGNsYXNzZXMnIHZvbHVtZXMuICovXG4gIHByb3RlY3RlZCBhc3luYyBzZWxlY3RGcm9tUmVnaW9ucygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIXRoaXMuY29udHJvbHMgfHwgdGhpcy5zZWxlY3RpbmdGcm9tUmVnaW9ucykgcmV0dXJuO1xuICAgIHRoaXMuc2VsZWN0aW5nRnJvbVJlZ2lvbnMgPSB0cnVlO1xuICAgIC8vIFRoZSBtb2RlIHRoZSBzZWxlY3Rpb24gcnVucyBpbiAoZGVjaWRlZCBhcyBpdCBzdGFydHMpLCBmb3Igd2hhdCBhIG1pc3Mgc2F5cyBpdCBtaXNzZWQuXG4gICAgY29uc3QgbW9kZSA9IHRoaXMucm9pU2VsZWN0aW9uTW9kZTtcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICBsZXQgY291bnQ6IG51bWJlciB8IG51bGwgPSAwO1xuICAgIHRyeSB7XG4gICAgICBjb3VudCA9IGF3YWl0IHRoaXMuY29udHJvbHMuc2VsZWN0RnJvbVJlZ2lvbnMoKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGNvbnNvbGUud2FybignW3NwYXRpYWxdIGNvdWxkIG5vdCBzZWxlY3QgZnJvbSB0aGUgcmVnaW9ucycsIGVycik7XG4gICAgfVxuICAgIC8vIFRoZSBjbGFzc2VzJyBvdXRsaW5lcyBhcmUgcmVhZCBpbiBhIHdvcmtlciwgd2hvc2UgYW5zd2VyIGxhbmRzIG91dHNpZGUgdGhlIHpvbmUuXG4gICAgdGhpcy5ydW5BbmRNYXJrKCgpID0+IHtcbiAgICAgIHRoaXMuc2VsZWN0aW5nRnJvbVJlZ2lvbnMgPSBmYWxzZTtcbiAgICAgIC8vIFN1cGVyc2VkZWQgKG51bGwpOiBhIG5ld2VyIHNlbGVjdGlvbiBzdGFuZHMsIGFuZCBzYXlzIHdoYXQgaXQgaXMgaXRzZWxmLlxuICAgICAgaWYgKGNvdW50ID09PSBudWxsKSByZXR1cm47XG4gICAgICB0aGlzLnNlbGVjdGVkQ2F0ZWdvcnkgPSBudWxsO1xuICAgICAgdGhpcy5zZWxlY3Rpb25NaXNzZWQgPSBjb3VudCA9PT0gMDtcbiAgICAgIHRoaXMubWlzc2VkTW9kZSA9IG1vZGU7XG4gICAgfSk7XG4gIH1cblxuICAvKiogSW4gM0Qgd2l0aCBjbGFzc2VzIHBpY2tlZCwgXCJTZWxlY3QgZnJvbSBST0lzXCIgc2VsZWN0cyBpbnNpZGUgdGhlaXIgdm9sdW1lcy4gKi9cbiAgcHJvdGVjdGVkIGdldCBzZWxlY3RzQ2xhc3NWb2x1bWVzKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnJvaVNlbGVjdGlvbk1vZGUgPT09ICdjbGFzcy12b2x1bWVzJztcbiAgfVxuXG4gIC8qKiBIb3cgXCJTZWxlY3QgZnJvbSBST0lzXCIgc2VsZWN0cyBub3c6IHRoZSBjb250cm9scycgb3duIHJ1bGUsIHRoZSBvbmUgdGhlIHNlbGVjdGlvbiBydW5zIGJ5LiAqL1xuICBwcml2YXRlIGdldCByb2lTZWxlY3Rpb25Nb2RlKCk6IFJvaVNlbGVjdGlvbk1vZGUge1xuICAgIHJldHVybiB0aGlzLmNvbnRyb2xzPy5yb2lTZWxlY3Rpb25Nb2RlPy4oKSA/PyAncmVnaW9ucyc7XG4gIH1cblxuICAvKiogTGVnZW5kIGNsaWNrOiBzZWxlY3Qgb25lIGNhdGVnb3J5LiBDbGlja2luZyB0aGUgYWN0aXZlIHJvdyBjbGVhcnMgaXQsIHNvIGFcbiAgICogIHNlY29uZCBjbGljayBpcyBhbiB1bmRvIHJhdGhlciB0aGFuIGEgbm8tb3AuICovXG4gIHByb3RlY3RlZCBhc3luYyBzZWxlY3RDYXRlZ29yeShpbmRleDogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgYnkgPSB0aGlzLnZpZXcuY29sb3JCeTtcbiAgICBpZiAoIXRoaXMuY29udHJvbHMgfHwgYnk/LmtpbmQgIT09ICdjb2x1bW4nKSByZXR1cm47XG4gICAgaWYgKHRoaXMuc2VsZWN0ZWRDYXRlZ29yeSA9PT0gaW5kZXgpIHtcbiAgICAgIHRoaXMuY2xlYXJTZWxlY3Rpb24oKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuY29udHJvbHMuc2VsZWN0Q2F0ZWdvcnkoYnkubmFtZSwgaW5kZXgpO1xuICAgICAgdGhpcy5zZWxlY3RlZENhdGVnb3J5ID0gaW5kZXg7XG4gICAgICB0aGlzLnNlbGVjdGlvbk1pc3NlZCA9IGZhbHNlO1xuICAgIH0gY2F0Y2gge1xuICAgICAgdGhpcy5zZWxlY3RlZENhdGVnb3J5ID0gbnVsbDtcbiAgICB9XG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICAvKipcbiAgICogRXhwYW5kIG9yIGNvbGxhcHNlIHRoZSBkaXN0cmlidXRpb24gc2VjdGlvbi5cbiAgICpcbiAgICogRXhwYW5kaW5nIFNDUk9MTFMgaXQgaW50byB2aWV3LCBiZWNhdXNlIHRoZSBwYW5lbCBpcyB0YWxsZXIgdGhhbiB0aGUgdmlld3BvcnRcbiAgICogb25jZSB0aGlzIHNlY3Rpb24gaXMgb3BlbiBhbmQgdGhlIGNoYXJ0IGlzIGl0cyBsYXN0IHJvdzogZXhwYW5kaW5nIGl0IGRyZXcgYVxuICAgKiBjaGFydCB+MzAwIHB4IGJlbG93IHRoZSBmb2xkLCB3aGljaCByZWFkcyBhcyB0aGUgc2VjdGlvbiBiZWluZyBlbXB0eS4gVGhlXG4gICAqIHNjcm9sbCBpcyBkZWZlcnJlZCBhIHRhc2sgc28gdGhlIGNoYXJ0J3Mgb3duIGRlZmVycmVkIGZpcnN0IGRyYXcgaGFzIGdpdmVuIHRoZVxuICAgKiBib2R5IGl0cyBoZWlnaHQuXG4gICAqL1xuICBwcm90ZWN0ZWQgdG9nZ2xlQ2hhcnRzKCk6IHZvaWQge1xuICAgIHRoaXMuY2hhcnRzT3BlbiA9ICF0aGlzLmNoYXJ0c09wZW47XG4gICAgaWYgKCF0aGlzLmNoYXJ0c09wZW4pIHJldHVybjtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRoaXMuY2hhcnRzQm9keUlkKT8uc2Nyb2xsSW50b1ZpZXcoeyBibG9jazogJ2VuZCcsIGJlaGF2aW9yOiAnc21vb3RoJyB9KTtcbiAgICB9LCAwKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBjbGVhclNlbGVjdGlvbigpOiB2b2lkIHtcbiAgICB0aGlzLmNvbnRyb2xzPy5jbGVhclNlbGVjdGlvbigpO1xuICAgIHRoaXMuc2VsZWN0ZWRDYXRlZ29yeSA9IG51bGw7XG4gICAgdGhpcy5zZWxlY3Rpb25NaXNzZWQgPSBmYWxzZTtcbiAgfVxuXG4gIC8qKiBUcnVlIHdoaWxlIGEgc2VsZWN0aW9uIGlzIGFjdGl2ZSDigJQgZXZlcnl0aGluZyBlbHNlIHJlbmRlcnMgbXV0ZWQuICovXG4gIHByb3RlY3RlZCBnZXQgaGFzU2VsZWN0aW9uKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnNlbGVjdGlvbi5jb3VudCA+IDA7XG4gIH1cblxuICAvLyDilIDilIAgc2VjdGlvbnMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgLyoqIEJvdW5kYXJpZXMgb24gb2ZmZXI6IHRpbGVkIChsZXZlbC1vZi1kZXRhaWwpIG9yIHdob2xlLWRhdGFzZXQgcmluZ3MuICovXG4gIHByb3RlY3RlZCBnZXQgaGFzQ2VsbHMoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICEhKHRoaXMuZGF0YXNldD8ucG9seWdvblRpbGVzIHx8IHRoaXMuZGF0YXNldD8ucG9seWdvbnMpO1xuICB9XG5cbiAgLyoqIFRoZSAzRCB2aWV3J3MgaW5kaXZpZHVhbCBjZWxscyBhcyB0aGV5IHN0YW5kIChudWxsOiBub25lIGRyYXduKS4gKi9cbiAgcHJvdGVjdGVkIGNlbGxzM2RTdGF0dXM6IENlbGxzM2RTdGF0dXMgfCBudWxsID0gbnVsbDtcblxuICAvKipcbiAgICogV2hldGhlciB0aGUgcm91dGVyIGhhcyB0aGUgZGF0YXNldCdzIHJlZ2lvbiBzZXQgYXR0YWNoZWQgYW5kIHBsYWNlZCAobnVsbDogaXQgZG9lcyBub3Qgc2F5KS5cbiAgICogU2VlIHtAbGluayBoYXNDZWxsczNkfS5cbiAgICovXG4gIHByb3RlY3RlZCBjZWxsczNkQXZhaWxhYmxlOiBib29sZWFuIHwgbnVsbCA9IG51bGw7XG5cbiAgLyoqXG4gICAqIFRoZSBkYXRhc2V0J3MgY2VsbHMgY2FuIGJlIGRyYXduIGluIDNEOiBpdHMgYm91bmRhcmllcyBuYW1lIGEgM0Qgc2VnbWVudGF0aW9uJ3MgcmVnaW9uIHNldCwgYW5kXG4gICAqIGl0IGlzIGF0dGFjaGVkIHdpdGggaXRzIHBsYW5lcyAoZWxzZSB0aGUgM0QgdmlldyBkcmF3cyBubyBjZWxscywgYW5kIHRoZSBtYXJrZXJzIHN0YXkpLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldCBoYXNDZWxsczNkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhIWRhdGFzZXRSZWdpb25TZXQodGhpcy5kYXRhc2V0KSAmJiB0aGlzLmNlbGxzM2RBdmFpbGFibGUgIT09IGZhbHNlO1xuICB9XG5cbiAgLyoqIFRyYW5zY3JpcHRzIG9uIG9mZmVyOiB0aWxlcyB0byBkcmF3LCBvciBhIGRlbnNpdHkgbWFwLiAqL1xuICBwcm90ZWN0ZWQgZ2V0IGhhc1RyYW5zY3JpcHRzKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhIXRoaXMuZGF0YXNldD8udHJhbnNjcmlwdFRpbGVzIHx8ICEhdGhpcy5kYXRhc2V0Py5kZW5zaXR5O1xuICB9XG5cbiAgLyoqIFdoZXRoZXIgdGhlIDNEIGNsb3VkIGNhbiBkcmF3IHRoZSB0cmFuc2NyaXB0cyB0b286IHRoZXkgY2FycnkgeiAoYSBNRVJGSVNIIHZvbHVtZSdzIGRvKS4gKi9cbiAgcHJvdGVjdGVkIGdldCBoYXNUcmFuc2NyaXB0czNkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhIXRoaXMuZGF0YXNldD8udHJhbnNjcmlwdFRpbGVzPy5oYXNaO1xuICB9XG5cbiAgcHJvdGVjdGVkIG9uU2hvd0ltYWdlKG9uOiBib29sZWFuKTogdm9pZCB7XG4gICAgdGhpcy5jb250cm9scz8uc2V0Vmlld1N0YXRlKHsgc2hvd0ltYWdlOiBvbiB9KTtcbiAgfVxuXG4gIC8qKiBUaGUgcmVmZXJlbmNlIHZvbHVtZSwgaW4gM0QgKHRoZSBWb2x1bWUgc2VjdGlvbidzIHN3aXRjaCkuICovXG4gIHByb3RlY3RlZCBvblNob3dWb2x1bWUob246IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLmNvbnRyb2xzPy5zZXRWaWV3U3RhdGUoeyBzaG93Vm9sdW1lOiBvbiB9KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvblZvbHVtZU9wYWNpdHkodmFsdWU6IG51bWJlciB8IHVuZGVmaW5lZCk6IHZvaWQge1xuICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSByZXR1cm47XG4gICAgdGhpcy5jb250cm9scz8uc2V0Vmlld1N0YXRlKHsgdm9sdW1lT3BhY2l0eTogdmFsdWUgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgb25TaG93QW5ub3RhdGlvbnMob246IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLmNvbnRyb2xzPy5zZXRWaWV3U3RhdGUoeyBzaG93QW5ub3RhdGlvbnM6IG9uIH0pO1xuICB9XG5cbiAgLyoqIFdoaWNoIGNvbGxhcHNpYmxlIHNlY3Rpb25zIGFyZSBvcGVuLiBQZXIgZGlhbG9nIGluc3RhbmNlLCBub3QgcGVyc2lzdGVkLiAqL1xuICBwcm90ZWN0ZWQgb3BlbjogUmVjb3JkPCdpbWFnZXMnIHwgJ3ZvbHVtZScgfCAndHJhbnNjcmlwdHMnIHwgJ2Fubm90YXRpb25zJyB8ICdvYnNlcnZhdGlvbnMnLCBib29sZWFuPiA9IHtcbiAgICBpbWFnZXM6IGZhbHNlLFxuICAgIHZvbHVtZTogZmFsc2UsXG4gICAgdHJhbnNjcmlwdHM6IGZhbHNlLFxuICAgIGFubm90YXRpb25zOiBmYWxzZSxcbiAgICBvYnNlcnZhdGlvbnM6IGZhbHNlLFxuICB9O1xuXG4gIHByb3RlY3RlZCB0b2dnbGVTZWN0aW9uKG5hbWU6IGtleW9mIFNwYXRpYWxDb250cm9sc0NvbXBvbmVudFsnb3BlbiddKTogdm9pZCB7XG4gICAgdGhpcy5zZXRPcGVuKG5hbWUsICF0aGlzLm9wZW5bbmFtZV0pO1xuICB9XG5cbiAgLyoqIEV4cGFuZCBvciBjb2xsYXBzZSBhIHNlY3Rpb24g4oCUIHdoYXQgYSBwYW5lbCdzIGhlYWRlciBhc2tzIGZvci4gKi9cbiAgcHJvdGVjdGVkIHNldE9wZW4obmFtZToga2V5b2YgU3BhdGlhbENvbnRyb2xzQ29tcG9uZW50WydvcGVuJ10sIG9uOiBib29sZWFuKTogdm9pZCB7XG4gICAgdGhpcy5vcGVuID0geyAuLi50aGlzLm9wZW4sIFtuYW1lXTogb24gfTtcbiAgfVxuXG4gIC8vIOKUgOKUgCByZW5kZXJlciByZWFkb3V0cywgZm9yIHRoZSBUcmFuc2NyaXB0cyBzZWN0aW9uIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIC8qKiBFc3RpbWF0ZWQgdHJhbnNjcmlwdHMgaW4gdmlldywgYWdhaW5zdCB0aGUgYnVkZ2V0IOKAlCBFeHBsb3JlcidzIHBvaW50cyBiYXIuICovXG4gIHByb3RlY3RlZCBlc3RpbWF0ZTogeyBwb2ludHM6IG51bWJlcjsgbWF4OiBudW1iZXIgfSB8IG51bGwgPSBudWxsO1xuICAvKiogVGhlIGRlbnNpdHkgd2luZG93IGluIHVzZSBhbmQgaXRzIGRlbnNlc3QgYmluLCBmb3IgdGhlIHRocmVzaG9sZCBjb250cm9sLiAqL1xuICBwcm90ZWN0ZWQgZGVuc2l0eVN0YXRzOiB7IGxvOiBudW1iZXI7IGhpOiBudW1iZXI7IG1heDogbnVtYmVyIH0gfCBudWxsID0gbnVsbDtcbiAgLyoqIFRyYW5zY3JpcHRzIG9mIGVhY2ggc2VsZWN0ZWQgZ2VuZSBpbiB0aGUgY3VycmVudCB2aWV3LCBmcm9tIHRoZSByZW5kZXJlci4gKi9cbiAgcHJvdGVjdGVkIGdlbmVDb3VudHM6IFJlY29yZDxzdHJpbmcsIG51bWJlcj4gfCBudWxsID0gbnVsbDtcblxuICBwcm90ZWN0ZWQgcmVzZXQoKTogdm9pZCB7XG4gICAgdGhpcy5jb250cm9scz8uc2V0Vmlld1N0YXRlKHsgLi4uREVGQVVMVF9TUEFUSUFMX1ZJRVcgfSk7XG4gICAgdGhpcy5jbGVhclNlbGVjdGlvbigpO1xuICB9XG5cbiAgLyoqIExhYmVsIGZvciB0aGUgY3VycmVudCBjb2xvdXJpbmcsIGZvciB0aGUgRGlzdHJpYnV0aW9uIGhlYWRpbmcuICovXG4gIHByb3RlY3RlZCBnZXQgY29sb3JCeUxhYmVsKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGNvbG9yQnlMYWJlbCh0aGlzLnZpZXcpO1xuICB9XG5cbiAgLyoqIFRydWUgd2hlbiB0aGUgYWN0aXZlIGNvbG91cmluZyBpcyBhIGNhdGVnb3JpY2FsIGNvbHVtbiAoZHJpdmVzIHRoZSBrZXkpLiAqL1xuICBnZXQgaXNDYXRlZ29yaWNhbCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5sZWdlbmQgIT09IG51bGw7XG4gIH1cblxuICAvKiogV2hldGhlciBsb2cvY2xpcCBhcHBseSDigJQgdGhleSBhcmUgY29udGludW91cy1vbmx5IGtub2JzLiAqL1xuICBnZXQgaXNDb250aW51b3VzKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhIXRoaXMudmlldy5jb2xvckJ5ICYmIHRoaXMubGVnZW5kID09PSBudWxsO1xuICB9XG5cbiAgLy8g4pSA4pSAIGludGVybmFscyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICAvKiogUmVidWlsZCB0aGUgbGVnZW5kIG9yIGNvbG91ciBiYXIgZm9yIHRoZSBjdXJyZW50IGNvbG91cmluZy4gKi9cbiAgcHJpdmF0ZSByZWZyZXNoS2V5KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiB0aGlzLmtleS5yZWZyZXNoKHRoaXMuY29udHJvbHMsIHRoaXMuZGF0YXNldCwgdGhpcy52aWV3LCB0aGlzLmNvbG9ybWFwLCB0aGlzLnJldmVyc2UpO1xuICB9XG59XG4iLCI8cC1kaWFsb2dcbiAgaGVhZGVyPVwiU3BhdGlhbCBvbWljc1wiXG4gIFt2aXNpYmxlXT1cInZpc2libGVcIlxuICAodmlzaWJsZUNoYW5nZSk9XCJvblZpc2libGVDaGFuZ2UoJGV2ZW50KVwiXG4gIFttb2RhbF09XCJmYWxzZVwiXG4gIFtyZXNpemFibGVdPVwidHJ1ZVwiXG4gIFtkcmFnZ2FibGVdPVwidHJ1ZVwiXG4gIHBvc2l0aW9uPVwibGVmdFwiXG4gIChvblJlc2l6ZUVuZCk9XCJvblJlc2l6ZUVuZCgpXCJcbiAgW3N0eWxlXT1cInsgd2lkdGg6ICczMHJlbScgfVwiXG4gIFticmVha3BvaW50c109XCJ7ICc5NjBweCc6ICc5MHZ3JyB9XCJcbiAgc3R5bGVDbGFzcz1cInNwYXRpYWwtY29udHJvbHMtZGlhbG9nXCJcbj5cbiAgPCEtLSBObyBwb3J0IGJvdW5kOiBzYXkgd2h5IHJhdGhlciB0aGFuIHNob3dpbmcgY29udHJvbHMgdGhhdCBkbyBub3RoaW5nLiAtLT5cbiAgPGRpdiBjbGFzcz1cInNjLWVtcHR5XCIgKm5nSWY9XCIhY29udHJvbHNcIj5cbiAgICBObyBzcGF0aWFsLW9taWNzIGRhdGEgc291cmNlIGlzIGNvbmZpZ3VyZWQuIEEgaG9zdCBwcm92aWRlcyBvbmUgYnkgYmluZGluZ1xuICAgIDxjb2RlPlNQQVRJQUxfREFUQV9QT1JUPC9jb2RlPi5cbiAgPC9kaXY+XG5cbiAgPGRpdiBjbGFzcz1cInNjLWVtcHR5XCIgKm5nSWY9XCJjb250cm9scyAmJiAhZGF0YXNldFwiPk5vIGRhdGFzZXQgaXMgbG9hZGVkLjwvZGl2PlxuXG4gIDxkaXYgY2xhc3M9XCJzYy1ib2R5XCIgKm5nSWY9XCJjb250cm9scyAmJiBkYXRhc2V0IGFzIGRzXCI+XG4gICAgPGRpdiBjbGFzcz1cInNjLWRhdGFzZXRcIj5cbiAgICAgIDxzcGFuIGNsYXNzPVwic2MtZGF0YXNldC1uYW1lXCI+e3sgZHMubmFtZSB9fTwvc3Bhbj5cbiAgICAgIDxzcGFuIGNsYXNzPVwic2MtZGF0YXNldC1jb3VudFwiPnt7IGRzLm9ic2VydmF0aW9ucy5jb3VudCB8IG51bWJlciB9fSBvYnNlcnZhdGlvbnM8L3NwYW4+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tIE9yZ2FuaXNlZCBhcyBYZW5pdW0gRXhwbG9yZXIncyBzaWRlIHBhbmVsOiBvbmUgY29sbGFwc2libGUgc2VjdGlvbiBwZXIgbGF5ZXIsXG4gICAgICAgICBlYWNoIHdpdGggaXRzIG93biBvbi9vZmYgc3dpdGNoIGluIHRoZSBoZWFkZXIuIC0tPlxuXG4gICAgPCEtLSBJbWFnZXMgLS0+XG4gICAgPGRpdiBjbGFzcz1cInNjLXBhbmVsXCIgKm5nSWY9XCJkcy5pbWFnZVJlZiAmJiAhaXMzZFwiIFtjbGFzcy5vcGVuXT1cIm9wZW4uaW1hZ2VzXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwic2MtcGFuZWwtaGVhZFwiIChjbGljayk9XCJ0b2dnbGVTZWN0aW9uKCdpbWFnZXMnKVwiPlxuICAgICAgICA8cC1jaGVja2JveFxuICAgICAgICAgIFtiaW5hcnldPVwidHJ1ZVwiXG4gICAgICAgICAgW25nTW9kZWxdPVwidmlldy5zaG93SW1hZ2VcIlxuICAgICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxuICAgICAgICAgIChvbkNoYW5nZSk9XCJvblNob3dJbWFnZSgkZXZlbnQuY2hlY2tlZClcIlxuICAgICAgICA+PC9wLWNoZWNrYm94PlxuICAgICAgICA8c3BhbiBjbGFzcz1cInNjLXBhbmVsLXRpdGxlXCI+SW1hZ2VzPC9zcGFuPlxuICAgICAgICA8aSBjbGFzcz1cInBpXCIgW2NsYXNzLnBpLWNoZXZyb24tZG93bl09XCJvcGVuLmltYWdlc1wiIFtjbGFzcy5waS1jaGV2cm9uLXJpZ2h0XT1cIiFvcGVuLmltYWdlc1wiPjwvaT5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cInNjLXBhbmVsLWJvZHlcIiAqbmdJZj1cIm9wZW4uaW1hZ2VzXCI+XG4gICAgICAgIDxzbWFsbCBjbGFzcz1cInNjLWhpbnRcIj4gQ2hhbm5lbHMsIGNvbG91cnMgYW5kIGNvbnRyYXN0IGFyZSBpbiB0aGUgQ2hhbm5lbHMgJmFtcDsgSGlzdG9ncmFtIGRpYWxvZy4gPC9zbWFsbD5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSBWb2x1bWU6IGluIDNELCB0aGUgSW1hZ2VzIHNlY3Rpb24ncyBwbGFjZTogdGhlIHJlZmVyZW5jZSB2b2x1bWUgdGhlIG9ic2VydmF0aW9ucyBzaXQgaW4uIC0tPlxuICAgIDxkaXYgY2xhc3M9XCJzYy1wYW5lbFwiICpuZ0lmPVwiZHMudm9sdW1lICYmIGlzM2RcIiBbY2xhc3Mub3Blbl09XCJvcGVuLnZvbHVtZVwiPlxuICAgICAgPGRpdiBjbGFzcz1cInNjLXBhbmVsLWhlYWRcIiAoY2xpY2spPVwidG9nZ2xlU2VjdGlvbigndm9sdW1lJylcIj5cbiAgICAgICAgPHAtY2hlY2tib3hcbiAgICAgICAgICBbYmluYXJ5XT1cInRydWVcIlxuICAgICAgICAgIFtuZ01vZGVsXT1cInZpZXcuc2hvd1ZvbHVtZVwiXG4gICAgICAgICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXG4gICAgICAgICAgKG9uQ2hhbmdlKT1cIm9uU2hvd1ZvbHVtZSgkZXZlbnQuY2hlY2tlZClcIlxuICAgICAgICA+PC9wLWNoZWNrYm94PlxuICAgICAgICA8c3BhbiBjbGFzcz1cInNjLXBhbmVsLXRpdGxlXCI+Vm9sdW1lPC9zcGFuPlxuICAgICAgICA8aSBjbGFzcz1cInBpXCIgW2NsYXNzLnBpLWNoZXZyb24tZG93bl09XCJvcGVuLnZvbHVtZVwiIFtjbGFzcy5waS1jaGV2cm9uLXJpZ2h0XT1cIiFvcGVuLnZvbHVtZVwiPjwvaT5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cInNjLXBhbmVsLWJvZHlcIiAqbmdJZj1cIm9wZW4udm9sdW1lXCI+XG4gICAgICAgIDwhLS0gSXRzIG93biBvcGFjaXR5OiByZWFkaW5nIHRoZSBjbG91ZCBvciBhIGRlbnNpdHkgZmllbGQgdGhyb3VnaCB0aGUgYW5hdG9teSBtZWFucyB0dXJuaW5nXG4gICAgICAgICAgIHRoZSBhbmF0b215IGRvd24sIG5vdCB0aGUgZGF0YS4gLS0+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJzYy1yb3dcIj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cInNjLWxibFwiPk9wYWNpdHk8L3NwYW4+XG4gICAgICAgICAgPHAtc2xpZGVyXG4gICAgICAgICAgICBbbmdNb2RlbF09XCJ2aWV3LnZvbHVtZU9wYWNpdHlcIlxuICAgICAgICAgICAgW21pbl09XCIwLjA1XCJcbiAgICAgICAgICAgIFttYXhdPVwiMVwiXG4gICAgICAgICAgICBbc3RlcF09XCIwLjA1XCJcbiAgICAgICAgICAgIFtkaXNhYmxlZF09XCIhdmlldy5zaG93Vm9sdW1lXCJcbiAgICAgICAgICAgIChvbkNoYW5nZSk9XCJvblZvbHVtZU9wYWNpdHkoJGV2ZW50LnZhbHVlKVwiXG4gICAgICAgICAgPjwvcC1zbGlkZXI+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYy12YWxcIj57eyB2aWV3LnZvbHVtZU9wYWNpdHkgfX08L3NwYW4+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8c21hbGwgY2xhc3M9XCJzYy1oaW50XCI+VGhlIHJlZ2lzdGVyZWQgYW5hdG9teSB0aGUgb2JzZXJ2YXRpb25zIHNpdCBpbi48L3NtYWxsPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tIFRyYW5zY3JpcHRzIC0tPlxuICAgIDxzcGF0aWFsLXRyYW5zY3JpcHRzLXBhbmVsXG4gICAgICAqbmdJZj1cImhhc1RyYW5zY3JpcHRzICYmICghaXMzZCB8fCBoYXNUcmFuc2NyaXB0czNkKVwiXG4gICAgICBbY29udHJvbHNdPVwiY29udHJvbHNcIlxuICAgICAgW2RhdGFzZXRdPVwiZHNcIlxuICAgICAgW3ZpZXddPVwidmlld1wiXG4gICAgICBbZ2VuZXNdPVwiZ2VuZXNcIlxuICAgICAgW2VzdGltYXRlXT1cImVzdGltYXRlXCJcbiAgICAgIFtkZW5zaXR5U3RhdHNdPVwiZGVuc2l0eVN0YXRzXCJcbiAgICAgIFtnZW5lQ291bnRzXT1cImdlbmVDb3VudHNcIlxuICAgICAgW2NvbG9ybWFwT3B0aW9uc109XCJjb2xvcm1hcE9wdGlvbnNcIlxuICAgICAgW2lzM2RdPVwiaXMzZFwiXG4gICAgICBbb3Blbl09XCJvcGVuLnRyYW5zY3JpcHRzXCJcbiAgICAgIChvcGVuQ2hhbmdlKT1cInNldE9wZW4oJ3RyYW5zY3JpcHRzJywgJGV2ZW50KVwiXG4gICAgPlxuICAgIDwvc3BhdGlhbC10cmFuc2NyaXB0cy1wYW5lbD5cblxuICAgIDwhLS0gT2JzZXJ2YXRpb25zLCB0aGVuIHdoYXQgZWxzZSBkcmF3cyB0aGVtOiB0aGUgZ2VuZSBtYXAsIHRoZSAzRCBzY2VuZSwgYW5kIHRoZVxuICAgICAgICAgY29udGludW91cy1vbmx5IGtub2JzLiAtLT5cbiAgICA8c3BhdGlhbC1vYnNlcnZhdGlvbnMtcGFuZWxcbiAgICAgIFtjb250cm9sc109XCJjb250cm9sc1wiXG4gICAgICBbZGF0YXNldF09XCJkc1wiXG4gICAgICBbdmlld109XCJ2aWV3XCJcbiAgICAgIFtnZW5lc109XCJnZW5lc1wiXG4gICAgICBbbGVnZW5kXT1cImxlZ2VuZFwiXG4gICAgICBbY29sb3JCYXJDc3NdPVwiY29sb3JCYXJDc3NcIlxuICAgICAgW3NlbGVjdGlvbl09XCJzZWxlY3Rpb25cIlxuICAgICAgW3NlbGVjdGVkQ2F0ZWdvcnldPVwic2VsZWN0ZWRDYXRlZ29yeVwiXG4gICAgICBbY29sb3JtYXBPcHRpb25zXT1cImNvbG9ybWFwT3B0aW9uc1wiXG4gICAgICBbaXMzZF09XCJpczNkXCJcbiAgICAgIFtjZWxsc0F2YWlsYWJsZV09XCJoYXNDZWxscyAmJiAoIWlzM2QgfHwgaGFzQ2VsbHMzZClcIlxuICAgICAgW29wZW5dPVwib3Blbi5vYnNlcnZhdGlvbnNcIlxuICAgICAgKG9wZW5DaGFuZ2UpPVwic2V0T3Blbignb2JzZXJ2YXRpb25zJywgJGV2ZW50KVwiXG4gICAgICAoY2F0ZWdvcnlDbGlja2VkKT1cInNlbGVjdENhdGVnb3J5KCRldmVudClcIlxuICAgID5cbiAgICAgIDwhLS0gQ2VsbCBzZWdtZW50YXRpb25zOiB3aXRoIGEgY2VsbCBzZWdtZW50YXRpb24gKGluIDNELCBhIDNEIG9uZSksIGhvdyB0aGUgY2VsbHMgYXJlIGRyYXduXG4gICAgICAgICAgIHdoaWxlIHRoZSBPYnNlcnZhdGlvbnMgYXJlIHNob3duIGFzIHRoZW0uIC0tPlxuICAgICAgPHNwYXRpYWwtY2VsbHMtcGFuZWxcbiAgICAgICAgKm5nSWY9XCJoYXNDZWxscyAmJiAoIWlzM2QgfHwgaGFzQ2VsbHMzZClcIlxuICAgICAgICBbY29udHJvbHNdPVwiY29udHJvbHNcIlxuICAgICAgICBbZGF0YXNldF09XCJkc1wiXG4gICAgICAgIFt2aWV3XT1cInZpZXdcIlxuICAgICAgICBbaXMzZF09XCJpczNkXCJcbiAgICAgICAgW2NlbGxzM2RTdGF0dXNdPVwiY2VsbHMzZFN0YXR1c1wiXG4gICAgICA+PC9zcGF0aWFsLWNlbGxzLXBhbmVsPlxuICAgIDwvc3BhdGlhbC1vYnNlcnZhdGlvbnMtcGFuZWw+XG5cbiAgICA8IS0tIFJlZ2lvbnMsIHVuZGVyIHRoZSBPYnNlcnZhdGlvbnM6IHRoZSBkcmF3biByZWdpb25zLCBhbmQgc2VsZWN0aW5nIHdoYXQgdGhleSBlbmNsb3NlLiBPZmYgYnlcbiAgICAgICAgIGRlZmF1bHQ7IHRoZSBkYXRhc2V0J3Mgb3duIHJlZ2lvbiBzZXQgaXMgdGhlIENlbGwgc2VnbWVudGF0aW9ucycuIC0tPlxuICAgIDxkaXYgY2xhc3M9XCJzYy1wYW5lbFwiIFtjbGFzcy5vcGVuXT1cIm9wZW4uYW5ub3RhdGlvbnNcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJzYy1wYW5lbC1oZWFkXCIgKGNsaWNrKT1cInRvZ2dsZVNlY3Rpb24oJ2Fubm90YXRpb25zJylcIj5cbiAgICAgICAgPHAtY2hlY2tib3hcbiAgICAgICAgICBbYmluYXJ5XT1cInRydWVcIlxuICAgICAgICAgIFtuZ01vZGVsXT1cInZpZXcuc2hvd0Fubm90YXRpb25zICE9PSBmYWxzZVwiXG4gICAgICAgICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXG4gICAgICAgICAgKG9uQ2hhbmdlKT1cIm9uU2hvd0Fubm90YXRpb25zKCRldmVudC5jaGVja2VkKVwiXG4gICAgICAgICAgcFRvb2x0aXA9XCJTaG93IHRoZSByZWdpb25zXCJcbiAgICAgICAgICB0b29sdGlwUG9zaXRpb249XCJ0b3BcIlxuICAgICAgICA+PC9wLWNoZWNrYm94PlxuICAgICAgICA8c3BhbiBjbGFzcz1cInNjLXBhbmVsLXRpdGxlXCI+UmVnaW9uczwvc3Bhbj5cbiAgICAgICAgPGkgY2xhc3M9XCJwaVwiIFtjbGFzcy5waS1jaGV2cm9uLWRvd25dPVwib3Blbi5hbm5vdGF0aW9uc1wiIFtjbGFzcy5waS1jaGV2cm9uLXJpZ2h0XT1cIiFvcGVuLmFubm90YXRpb25zXCI+PC9pPlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwic2MtcGFuZWwtYm9keVwiICpuZ0lmPVwib3Blbi5hbm5vdGF0aW9uc1wiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwic2Mtcm93XCI+XG4gICAgICAgICAgPHAtYnV0dG9uXG4gICAgICAgICAgICBsYWJlbD1cIlNlbGVjdCBmcm9tIFJPSXNcIlxuICAgICAgICAgICAgaWNvbj1cInBpIHBpLW9iamVjdC1ncm91cFwiXG4gICAgICAgICAgICBzaXplPVwic21hbGxcIlxuICAgICAgICAgICAgW291dGxpbmVkXT1cInRydWVcIlxuICAgICAgICAgICAgW2xvYWRpbmddPVwic2VsZWN0aW5nRnJvbVJlZ2lvbnNcIlxuICAgICAgICAgICAgKG9uQ2xpY2spPVwic2VsZWN0RnJvbVJlZ2lvbnMoKVwiXG4gICAgICAgICAgICBbcFRvb2x0aXBdPVwiXG4gICAgICAgICAgICAgIHNlbGVjdHNDbGFzc1ZvbHVtZXNcbiAgICAgICAgICAgICAgICA/ICdTZWxlY3QgZXZlcnkgb2JzZXJ2YXRpb24gaW5zaWRlIHRoZSB2b2x1bWVzIG9mIHRoZSBjbGFzc2VzIHBpY2tlZCBpbiB0aGUgUmVnaW9uIEVkaXRvcidcbiAgICAgICAgICAgICAgICA6ICdTZWxlY3QgZXZlcnkgb2JzZXJ2YXRpb24gaW5zaWRlIHRoZSBkcmF3biByZWdpb25zJ1xuICAgICAgICAgICAgXCJcbiAgICAgICAgICAgIHRvb2x0aXBQb3NpdGlvbj1cInRvcFwiXG4gICAgICAgICAgPjwvcC1idXR0b24+XG4gICAgICAgICAgPHAtYnV0dG9uXG4gICAgICAgICAgICAqbmdJZj1cImhhc1NlbGVjdGlvblwiXG4gICAgICAgICAgICBsYWJlbD1cIkNsZWFyXCJcbiAgICAgICAgICAgIHNpemU9XCJzbWFsbFwiXG4gICAgICAgICAgICBbdGV4dF09XCJ0cnVlXCJcbiAgICAgICAgICAgIChvbkNsaWNrKT1cImNsZWFyU2VsZWN0aW9uKClcIlxuICAgICAgICAgID48L3AtYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPHNtYWxsIGNsYXNzPVwic2MtaGludFwiICpuZ0lmPVwiaGFzU2VsZWN0aW9uXCI+XG4gICAgICAgICAge3sgc2VsZWN0aW9uLmNvdW50IHwgbnVtYmVyIH19IG9mIHt7IGRzLm9ic2VydmF0aW9ucy5jb3VudCB8IG51bWJlciB9fSBzZWxlY3RlZCDigJQgdGhlIHJlc3QgYXJlIG11dGVkLlxuICAgICAgICA8L3NtYWxsPlxuICAgICAgICA8c21hbGwgY2xhc3M9XCJzYy1oaW50XCIgKm5nSWY9XCJzZWxlY3Rpb25NaXNzZWRcIj5cbiAgICAgICAgICBObyBvYnNlcnZhdGlvbnMgZmVsbCBpbnNpZGUgdGhlXG4gICAgICAgICAge3sgbWlzc2VkTW9kZSA9PT0gJ2NsYXNzLXZvbHVtZXMnID8gJ3BpY2tlZCBjbGFzc2VzJyA6ICdkcmF3biByZWdpb25zJyB9fS5cbiAgICAgICAgPC9zbWFsbD5cbiAgICAgICAgPHNtYWxsIGNsYXNzPVwic2MtaGludFwiICpuZ0lmPVwic2VsZWN0c0NsYXNzVm9sdW1lc1wiPlxuICAgICAgICAgIFNlbGVjdHMgaW5zaWRlIHRoZSB2b2x1bWUgb2Yge3sgcGlja2VkQ2xhc3Nlc1swXVxuICAgICAgICAgIH19e3sgcGlja2VkQ2xhc3Nlcy5sZW5ndGggPiAxID8gJyBhbmQgJyArIChwaWNrZWRDbGFzc2VzLmxlbmd0aCAtIDEgfCBudW1iZXIpICsgJyBtb3JlIGNsYXNzZXMnIDogJycgfX0sXG4gICAgICAgICAgcGlja2VkIGluIHRoZSBSZWdpb24gRWRpdG9yLiBEcmF3IGEgcmVnaW9uIHRvIHNlbGVjdCBieSBpdCBpbnN0ZWFkLlxuICAgICAgICA8L3NtYWxsPlxuICAgICAgICA8c21hbGwgY2xhc3M9XCJzYy1oaW50XCIgKm5nSWY9XCJpczNkICYmICFzZWxlY3RzQ2xhc3NWb2x1bWVzICYmIHBpY2tlZENsYXNzZXMubGVuZ3RoXCI+XG4gICAgICAgICAgVGhlIGNsYXNzZXMgcGlja2VkIGluIHRoZSBSZWdpb24gRWRpdG9yIGFyZSBub3Qgb24gdGhlIHJlZmVyZW5jZSB2b2x1bWUgc2hvd24gaGVyZSwgc28gdGhpcyBzZWxlY3RzIGJ5XG4gICAgICAgICAgdGhlIHJlZ2lvbnMgZHJhd24gb3ZlciB0aGUgY2xvdWQgaW5zdGVhZC5cbiAgICAgICAgPC9zbWFsbD5cbiAgICAgICAgPHNtYWxsIGNsYXNzPVwic2MtaGludFwiICpuZ0lmPVwiaXMzZCAmJiAhc2VsZWN0c0NsYXNzVm9sdW1lc1wiPlxuICAgICAgICAgIEluIDNEIGEgcmVnaW9uIGN1dHMgdGhyb3VnaCB0aGUgY2xvdWQncyBmdWxsIGRlcHRoLiBPcmJpdCBhbmQgZHJhdyBhZ2FpbiB0byBjdXQgZnJvbSBhbm90aGVyIGFuZ2xlLlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhcGlja2VkQ2xhc3Nlcy5sZW5ndGhcIj5cbiAgICAgICAgICAgIFBpY2sgY2xhc3NlcyBpbiB0aGUgUmVnaW9uIEVkaXRvcidzIGNsYXNzIHRyZWUgdG8gc2VsZWN0IGluc2lkZSB0aGVpciB2b2x1bWVzLlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8L3NtYWxsPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tIERpc3RyaWJ1dGlvbnMgb2Ygd2hhdGV2ZXIgdGhlIG1hcCBpcyBjb2xvdXJlZCBieS4gSW4gdGhlIFNBTUUgZGlhbG9nIGFzXG4gICAgICAgICB0aGUgY29sb3VyIGNvbnRyb2xzIG9uIHB1cnBvc2U6IGNoYW5naW5nIHRoZSBnZW5lIGFuZCB3YXRjaGluZyB0aGVcbiAgICAgICAgIGRpc3RyaWJ1dGlvbiBtb3ZlIGlzIG9uZSBhY3Rpb24sIGFuZCB0d28gZmxvYXRpbmcgd2luZG93cyBtYWRlIHRoYXRcbiAgICAgICAgIGhhcmRlciB0byBzZWUgcmF0aGVyIHRoYW4gZWFzaWVyLiAtLT5cbiAgICA8ZGl2IGNsYXNzPVwic2Mtc2VjdGlvbiBzYy1jaGFydHNcIj5cbiAgICAgIDxidXR0b25cbiAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgIGNsYXNzPVwic2MtZGlzY2xvc3VyZVwiXG4gICAgICAgIChjbGljayk9XCJ0b2dnbGVDaGFydHMoKVwiXG4gICAgICAgIFthdHRyLmFyaWEtZXhwYW5kZWRdPVwiY2hhcnRzT3BlblwiXG4gICAgICAgIFthdHRyLmFyaWEtY29udHJvbHNdPVwiY2hhcnRzQm9keUlkXCJcbiAgICAgID5cbiAgICAgICAgPGkgY2xhc3M9XCJwaVwiIFtjbGFzcy5waS1jaGV2cm9uLXJpZ2h0XT1cIiFjaGFydHNPcGVuXCIgW2NsYXNzLnBpLWNoZXZyb24tZG93bl09XCJjaGFydHNPcGVuXCI+PC9pPlxuICAgICAgICA8c3Bhbj5EaXN0cmlidXRpb248L3NwYW4+XG4gICAgICAgIDxzbWFsbCAqbmdJZj1cIiFjaGFydHNPcGVuICYmIHZpZXcuY29sb3JCeVwiPm9mIHt7IGNvbG9yQnlMYWJlbCB9fTwvc21hbGw+XG4gICAgICA8L2J1dHRvbj5cbiAgICAgIDwhLS0gS2VwdCBNT1VOVEVEIHdoZW4gY29sbGFwc2VkLCBvbmx5IGhpZGRlbjogZGVzdHJveWluZyBpdCB3b3VsZCB0aHJvd1xuICAgICAgICAgICBhd2F5IHRoZSBjaGFydCBraW5kIGFuZCBncm91cGluZyB0aGUgdXNlciBwaWNrZWQuIGBhY3RpdmVgIGlzIHdoYXRcbiAgICAgICAgICAgc3RvcHMgaXQgZHJhd2luZyB3aGlsZSBpdCBoYXMgbm8gc2l6ZS4gLS0+XG4gICAgICA8ZGl2IFtpZF09XCJjaGFydHNCb2R5SWRcIiBbaGlkZGVuXT1cIiFjaGFydHNPcGVuXCI+XG4gICAgICAgIDxzcGF0aWFsLWNoYXJ0cyBbYWN0aXZlXT1cInZpc2libGUgJiYgY2hhcnRzT3BlblwiPjwvc3BhdGlhbC1jaGFydHM+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cblxuICAgIDxkaXYgY2xhc3M9XCJzYy1idG5zXCI+XG4gICAgICA8cC1idXR0b24gbGFiZWw9XCJSZXNldFwiIHNpemU9XCJzbWFsbFwiIFt0ZXh0XT1cInRydWVcIiAob25DbGljayk9XCJyZXNldCgpXCI+PC9wLWJ1dHRvbj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L3AtZGlhbG9nPlxuIl19