@jax-data-science/sci-image-visualizer 0.17.0 → 0.18.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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-YrNqv8wH.mjs} +4521 -759
  61. package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-YrNqv8wH.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-Dph35S7m.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-Dph35S7m.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
@@ -343,7 +343,7 @@ export class SpatialGeneTreeComponent {
343
343
  });
344
344
  }
345
345
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: SpatialGeneTreeComponent, deps: [{ token: i0.NgZone }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
346
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.9", type: SpatialGeneTreeComponent, isStandalone: true, selector: "spatial-gene-tree", inputs: { controls: "controls", dataset: "dataset", view: "view", geneCounts: "geneCounts", geneTotal: "geneTotal" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"sc-subhead\">Selected genes</div>\n<div class=\"sc-gene-sort\" *ngIf=\"sortShown\" role=\"group\" aria-label=\"Sort genes\">\n <span class=\"sc-lbl\">Sort by</span>\n <button\n type=\"button\"\n class=\"sc-sort-btn\"\n [class.active]=\"!byCount\"\n [attr.aria-pressed]=\"!byCount\"\n (click)=\"onGeneSort('name')\"\n >\n Name\n </button>\n <button\n type=\"button\"\n class=\"sc-sort-btn\"\n [class.active]=\"byCount\"\n [attr.aria-pressed]=\"byCount\"\n title=\"Transcripts in view, most first\"\n (click)=\"onGeneSort('count')\"\n >\n Count\n </button>\n</div>\n<div class=\"sc-gene-tree\">\n <div class=\"sc-gene-row sc-gene-root\">\n <button\n type=\"button\"\n class=\"sc-eye\"\n (click)=\"\n view.transcriptAllGenes ? onAllGenesShown(!rootShown) : onGenesShown(view.transcriptGenes, !rootShown)\n \"\n >\n <i class=\"pi\" [class.pi-eye]=\"rootShown\" [class.pi-eye-slash]=\"!rootShown\"></i>\n </button>\n <span class=\"sc-group-label\">Genes</span>\n <span class=\"sc-count\"\n >({{ (view.transcriptAllGenes ? geneTotal : view.transcriptGenes.length) | number }}/{{\n geneTotal | number\n }})</span\n >\n <button\n type=\"button\"\n class=\"sc-icon-btn\"\n (click)=\"geneTreeOpen = !geneTreeOpen\"\n *ngIf=\"!view.transcriptAllGenes && view.transcriptGenes.length\"\n >\n <i class=\"pi\" [class.pi-chevron-down]=\"geneTreeOpen\" [class.pi-chevron-right]=\"!geneTreeOpen\"></i>\n </button>\n <button\n type=\"button\"\n class=\"sc-icon-btn\"\n (click)=\"toggleAllGenesOpen()\"\n *ngIf=\"view.transcriptAllGenes && allGeneList?.length\"\n [attr.aria-label]=\"allGenesOpen ? 'Hide the gene list' : 'Show every gene'\"\n >\n <i class=\"pi\" [class.pi-chevron-down]=\"allGenesOpen\" [class.pi-chevron-right]=\"!allGenesOpen\"></i>\n </button>\n </div>\n <!-- \"All genes\": every gene of the dataset, each with its eye when the dataset says which\n transcripts are whose (its gene list in code order). -->\n <ng-container *ngIf=\"allGenesOpen && view.transcriptAllGenes && allGeneList?.length\">\n <input\n pInputText\n class=\"sc-gene-filter\"\n placeholder=\"Filter genes\u2026\"\n aria-label=\"Filter genes\"\n [value]=\"allGenesFilter\"\n (input)=\"onAllGenesFilter($any($event.target).value)\"\n />\n <small class=\"sc-hint\" *ngIf=\"!canHideAllGenes\">\n This dataset does not say which transcripts are whose, so its genes cannot be hidden one by one.\n </small>\n <small class=\"sc-hint\" *ngIf=\"canHideAllGenes && view.transcriptMode === 'density'\">\n The density map draws every gene as one raster: genes are hidden one by one as circles or icons.\n </small>\n <div class=\"sc-gene-row sc-gene-leaf nested\" *ngFor=\"let row of allRows; trackBy: trackByAllRow\">\n <button\n type=\"button\"\n class=\"sc-eye\"\n [disabled]=\"!canHideAllGenes || view.transcriptMode === 'density'\"\n (click)=\"onAllGeneShown(row.gene, !row.shown)\"\n >\n <i class=\"pi\" [class.pi-eye]=\"row.shown\" [class.pi-eye-slash]=\"!row.shown\"></i>\n </button>\n <!-- The gene's colour among every gene; clicking it opens the colour picker. -->\n <button\n type=\"button\"\n class=\"sc-gene-icon\"\n *ngIf=\"row.swatch\"\n [style.color]=\"row.swatch\"\n [attr.aria-label]=\"'Colour for ' + row.gene\"\n pTooltip=\"Colour\"\n tooltipPosition=\"top\"\n (click)=\"openGeneStyle($event, row.gene, genePop)\"\n >\n <svg viewBox=\"-1.2 -1.2 2.4 2.4\" class=\"sc-glyph-svg\"><circle r=\"0.75\"></circle></svg>\n </button>\n <span class=\"sc-group-label\" [title]=\"row.gene\">{{ row.gene }}</span>\n <span class=\"sc-gene-count\" *ngIf=\"row.count !== null\" title=\"Transcripts in view\">{{\n row.count | number\n }}</span>\n </div>\n <small class=\"sc-hint\" *ngIf=\"allGenesMatched > allRows.length\">\n Showing {{ allRows.length | number }} of {{ allGenesMatched | number }} genes: filter to find the others.\n </small>\n <small class=\"sc-hint\" *ngIf=\"allGenesMatched === 0\">No gene matches.</small>\n </ng-container>\n <ng-container *ngIf=\"geneTreeOpen && !view.transcriptAllGenes\">\n <ng-container *ngFor=\"let node of sortedTree; trackBy: trackByNode\">\n <div class=\"sc-gene-row sc-gene-group\" *ngIf=\"node.name\">\n <button type=\"button\" class=\"sc-eye\" (click)=\"onGenesShown(node.genes, !groupShown.get(node.name))\">\n <i\n class=\"pi\"\n [class.pi-eye]=\"groupShown.get(node.name)\"\n [class.pi-eye-slash]=\"!groupShown.get(node.name)\"\n ></i>\n </button>\n <span class=\"sc-group-label\" [title]=\"node.name\">{{ node.name }}</span>\n <span class=\"sc-count\">({{ node.genes.length }})</span>\n <button type=\"button\" class=\"sc-icon-btn\" (click)=\"toggleGeneGroup(node.name)\">\n <i\n class=\"pi\"\n [class.pi-chevron-down]=\"!collapsedGeneGroups.has(node.name)\"\n [class.pi-chevron-right]=\"collapsedGeneGroups.has(node.name)\"\n ></i>\n </button>\n </div>\n <ng-container *ngIf=\"!node.name || !collapsedGeneGroups.has(node.name)\">\n <div\n class=\"sc-gene-row sc-gene-leaf\"\n [class.nested]=\"!!node.name\"\n *ngFor=\"let gene of node.genes; trackBy: trackByLabelString\"\n >\n <button type=\"button\" class=\"sc-eye\" (click)=\"onGenesShown([gene], !rows.get(gene)?.shown)\">\n <i class=\"pi\" [class.pi-eye]=\"rows.get(gene)?.shown\" [class.pi-eye-slash]=\"!rows.get(gene)?.shown\"></i>\n </button>\n <!-- The gene's marker, in its colour: its icon in Icons mode, a dot for circles.\n Clicking it opens the icon and colour picker (as Xenium Explorer does). -->\n <button\n type=\"button\"\n class=\"sc-gene-icon\"\n [style.color]=\"rows.get(gene)?.swatch\"\n [attr.aria-label]=\"'Icon and colour for ' + gene\"\n pTooltip=\"Icon and colour\"\n tooltipPosition=\"top\"\n (click)=\"openGeneStyle($event, gene, genePop)\"\n >\n <svg viewBox=\"-1.2 -1.2 2.4 2.4\" class=\"sc-glyph-svg\">\n <polygon\n *ngIf=\"view.transcriptMode === 'glyphs'; else dotIcon\"\n [attr.points]=\"rows.get(gene)?.points\"\n ></polygon>\n <ng-template #dotIcon><circle r=\"0.75\"></circle></ng-template>\n </svg>\n </button>\n <span class=\"sc-group-label\">{{ gene }}</span>\n <span\n class=\"sc-gene-count\"\n *ngIf=\"rows.get(gene)?.count as n; else zeroCount\"\n title=\"Transcripts in view\"\n >{{ n | number }}</span\n >\n <ng-template #zeroCount>\n <span class=\"sc-gene-count\" *ngIf=\"geneCounts\" title=\"Transcripts in view\">0</span>\n </ng-template>\n </div>\n </ng-container>\n </ng-container>\n </ng-container>\n <!-- One picker for every gene row, filled for the gene that opened it. -->\n <p-overlayPanel #genePop styleClass=\"sc-gene-style\" appendTo=\"body\">\n <ng-template pTemplate=\"content\">\n <spatial-gene-style\n *ngIf=\"styleGene as gene\"\n [gene]=\"gene\"\n what=\"Transcript\"\n [color]=\"styleColorOf(gene)\"\n [glyph]=\"styleGlyph ?? 'circle'\"\n [showIcons]=\"!view.transcriptAllGenes\"\n [iconHint]=\"\n view.transcriptMode !== 'glyphs' ? 'Icons show when the transcript point style is Icons.' : null\n \"\n (colorChange)=\"onGeneColor(gene, $event)\"\n (glyphChange)=\"onGlyph(gene, $event)\"\n (resetStyle)=\"resetGeneStyle(gene)\"\n ></spatial-gene-style>\n </ng-template>\n </p-overlayPanel>\n <div class=\"sc-gene-footer\">\n {{ (view.transcriptAllGenes ? geneTotal : view.transcriptGenes.length) | number }}/{{ geneTotal | number }}\n genes selected\n </div>\n</div>\n", styles: [".sc-hint{font-size:.75rem;color:var(--text-color-secondary, #6c757d)}.sc-error{color:var(--red-600, #c62828)}.sc-section{display:flex;flex-direction:column;gap:.35rem}.sc-lbl{font-size:.78rem;color:var(--text-color-secondary, #6c757d);white-space:nowrap}.sc-row{display:flex;align-items:center;gap:.6rem}.sc-row p-slider,.sc-row p-dropdown,.sc-row p-treeSelect{flex:1 1 0;min-width:0}:host ::ng-deep .sc-row p-slider .p-slider{width:100%}:host ::ng-deep .sc-row p-dropdown .p-dropdown,:host ::ng-deep .sc-row p-treeSelect .p-treeselect{width:100%}.sc-row .sc-lbl{flex:0 0 calc(50% - .6rem);min-width:0;overflow:hidden;text-overflow:ellipsis}.sc-cmap-option{display:inline-flex;align-items:center;gap:.4rem}.sc-cmap-swatch{width:3.5rem;height:.7rem;border-radius:2px;display:block}.sc-val{flex:0 0 4rem;text-align:right;font-size:.78rem;font-variant-numeric:tabular-nums;white-space:nowrap}:host ::ng-deep .sc-full,:host ::ng-deep .sc-full .p-dropdown,:host ::ng-deep .sc-full .p-autocomplete,:host ::ng-deep .sc-full input{width:100%}.sc-colorbar{height:.75rem;border-radius:2px;border:1px solid rgba(0,0,0,.2)}.sc-colorbar-ends{display:flex;justify-content:space-between;font-size:.7rem;color:var(--text-color-secondary, #6c757d);margin-top:.2rem}.sc-panel{border:1px solid var(--surface-border, #dee2e6);border-radius:6px;margin-bottom:.5rem;overflow:hidden}.sc-panel-head{display:flex;align-items:center;gap:.6rem;padding:.5rem .7rem;cursor:pointer;-webkit-user-select:none;user-select:none;background:var(--surface-100, #f5f6f7)}.sc-panel-head .sc-panel-title{flex:1;font-weight:600}.sc-panel.open>.sc-panel-head{background:var(--primary-color, #2196f3);color:var(--primary-color-text, #fff)}.sc-panel-body{display:flex;flex-direction:column;gap:.45rem;padding:.6rem .75rem .75rem}.sc-subhead{display:flex;align-items:center;gap:.5rem;margin-top:.4rem;font-size:.72rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--text-color-secondary, #6c757d)}.sc-subhead:after{content:\"\";flex:1;border-top:1px solid var(--surface-border, #dee2e6)}:host ::ng-deep .sc-buttons .p-button{padding:.35rem .75rem;font-size:.85rem}.sc-row-picker p-dropdown,.sc-row-picker p-multiSelect,.sc-row-picker p-treeSelect{flex:1 1 0;min-width:0}:host ::ng-deep .sc-row-picker .sc-variant{width:6.5rem}:host ::ng-deep .sc-row-picker p-multiselect .p-multiselect{width:100%}:host ::ng-deep .sc-row-picker p-dropdown:has(.sc-variant){flex:0 0 6.5rem}:host ::ng-deep .sc-row-picker p-treeselect:has(.sc-palette){flex:0 0 3rem}:host ::ng-deep .sc-palette .p-treeselect-label{width:0;padding:0}.sc-icon-btn{flex:0 0 auto;border:0;background:transparent;cursor:pointer;padding:.25rem .35rem;font:inherit;font-size:1.05rem;color:var(--text-color, #333);border-radius:4px}.sc-icon-btn:hover{background:var(--surface-200, #e9ecef)}.sc-icon-btn.active{color:var(--primary-color, #2196f3);font-weight:700}.sc-icon-btn:disabled{opacity:.5;cursor:default}.sc-small-btn{margin-left:auto;border:1px solid var(--surface-border, #ced4da);background:var(--surface-0, #fff);border-radius:4px;padding:.2rem .6rem;font:inherit;font-size:.8rem;cursor:pointer}:host ::ng-deep .sc-group-heading{font-size:.7rem;font-weight:700;letter-spacing:.05em;text-transform:uppercase;opacity:.7}.sc-group-list,.sc-gene-tree{max-height:16rem;overflow-y:auto;border:1px solid var(--surface-border, #dee2e6);border-radius:4px;padding:.25rem .4rem}.sc-group-row,.sc-gene-row{display:flex;align-items:center;gap:.45rem;padding:.15rem 0;font-size:.88rem}.sc-group-row .sc-group-label,.sc-gene-row .sc-group-label{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sc-group-all,.sc-gene-root,.sc-gene-group{font-weight:600}.sc-group-all .sc-icon-btn,.sc-gene-root .sc-icon-btn,.sc-gene-group .sc-icon-btn{margin-left:auto;font-size:.85rem}.sc-count{flex:0 0 auto;font-size:.78rem;color:var(--text-color-secondary, #6c757d)}.sc-glyph-option{display:inline-flex;align-items:center;gap:.4rem}.sc-glyph-svg{width:1rem;height:1rem;fill:currentColor}:host ::ng-deep .sc-glyph-pick .p-dropdown-label{padding:.2rem .4rem}.sc-color-input{width:2.5rem;height:1.8rem;border:1px solid var(--surface-border, #ced4da);border-radius:4px;padding:0;background:none}.sc-row-number p-slider,.sc-row-range p-slider{flex:1 1 0;min-width:0}:host ::ng-deep .sc-num{width:4.5rem;padding:.3rem .4rem;text-align:center}:host ::ng-deep .sc-row-number p-inputnumber,:host ::ng-deep .sc-row-range p-inputnumber{flex:0 0 auto}.sc-gene-icon{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:1.4rem;height:1.4rem;padding:0;border:1px solid transparent;border-radius:4px;background:transparent;cursor:pointer}.sc-gene-icon:hover,.sc-gene-icon:focus-visible{border-color:var(--surface-border, rgba(0, 0, 0, .2))}:host{display:contents}.sc-gene-group,.sc-gene-leaf{padding-left:1rem}.sc-gene-leaf.nested{padding-left:2rem}.sc-eye{flex:0 0 auto;border:0;background:transparent;cursor:pointer;padding:0;color:var(--text-color-secondary, #6c757d)}.sc-eye .pi-eye{color:var(--text-color, #333)}.sc-eye:disabled{cursor:default;opacity:.5}.sc-gene-sort{display:flex;align-items:center;gap:.25rem;font-size:.8rem}.sc-gene-sort .sc-lbl{margin-right:auto}.sc-sort-btn{border:1px solid var(--surface-border, #ced4da);background:var(--surface-0, #fff);color:var(--text-color, #333);border-radius:4px;padding:.1rem .5rem;font:inherit;cursor:pointer}.sc-sort-btn.active{border-color:var(--primary-color, #2196f3);color:var(--primary-color, #2196f3);font-weight:600}.sc-gene-filter{width:calc(100% - 1rem);margin:.2rem 0 .2rem 1rem;font-size:.8rem;padding:.2rem .4rem}.sc-gene-footer{text-align:right;font-size:.78rem;padding:.2rem 0;color:var(--text-color-secondary, #6c757d)}.sc-gene-count{margin-left:auto;font-variant-numeric:tabular-nums;opacity:.8;padding-left:.5rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i1.DecimalPipe, name: "number" }, { kind: "ngmodule", type: SharedModule }, { kind: "directive", type: i2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3.InputText, selector: "[pInputText]", inputs: ["variant"] }, { kind: "ngmodule", type: OverlayPanelModule }, { kind: "component", type: i4.OverlayPanel, selector: "p-overlayPanel", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "showCloseIcon", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions"], outputs: ["onShow", "onHide"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5.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: SpatialGeneStyleComponent, selector: "spatial-gene-style", inputs: ["gene", "what", "color", "glyph", "iconHint", "showIcons"], outputs: ["colorChange", "glyphChange", "resetStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
346
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.9", type: SpatialGeneTreeComponent, isStandalone: true, selector: "spatial-gene-tree", inputs: { controls: "controls", dataset: "dataset", view: "view", geneCounts: "geneCounts", geneTotal: "geneTotal" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"sc-subhead\">Selected genes</div>\n<div class=\"sc-gene-sort\" *ngIf=\"sortShown\" role=\"group\" aria-label=\"Sort genes\">\n <span class=\"sc-lbl\">Sort by</span>\n <button\n type=\"button\"\n class=\"sc-sort-btn\"\n [class.active]=\"!byCount\"\n [attr.aria-pressed]=\"!byCount\"\n (click)=\"onGeneSort('name')\"\n >\n Name\n </button>\n <button\n type=\"button\"\n class=\"sc-sort-btn\"\n [class.active]=\"byCount\"\n [attr.aria-pressed]=\"byCount\"\n title=\"Transcripts in view, most first\"\n (click)=\"onGeneSort('count')\"\n >\n Count\n </button>\n</div>\n<div class=\"sc-gene-tree\">\n <div class=\"sc-gene-row sc-gene-root\">\n <button\n type=\"button\"\n class=\"sc-eye\"\n (click)=\"\n view.transcriptAllGenes ? onAllGenesShown(!rootShown) : onGenesShown(view.transcriptGenes, !rootShown)\n \"\n >\n <i class=\"pi\" [class.pi-eye]=\"rootShown\" [class.pi-eye-slash]=\"!rootShown\"></i>\n </button>\n <span class=\"sc-group-label\">Genes</span>\n <span class=\"sc-count\"\n >({{ (view.transcriptAllGenes ? geneTotal : view.transcriptGenes.length) | number }}/{{\n geneTotal | number\n }})</span\n >\n <button\n type=\"button\"\n class=\"sc-icon-btn\"\n (click)=\"geneTreeOpen = !geneTreeOpen\"\n *ngIf=\"!view.transcriptAllGenes && view.transcriptGenes.length\"\n >\n <i class=\"pi\" [class.pi-chevron-down]=\"geneTreeOpen\" [class.pi-chevron-right]=\"!geneTreeOpen\"></i>\n </button>\n <button\n type=\"button\"\n class=\"sc-icon-btn\"\n (click)=\"toggleAllGenesOpen()\"\n *ngIf=\"view.transcriptAllGenes && allGeneList?.length\"\n [attr.aria-label]=\"allGenesOpen ? 'Hide the gene list' : 'Show every gene'\"\n >\n <i class=\"pi\" [class.pi-chevron-down]=\"allGenesOpen\" [class.pi-chevron-right]=\"!allGenesOpen\"></i>\n </button>\n </div>\n <!-- \"All genes\": every gene of the dataset, each with its eye when the dataset says which\n transcripts are whose (its gene list in code order). -->\n <ng-container *ngIf=\"allGenesOpen && view.transcriptAllGenes && allGeneList?.length\">\n <input\n pInputText\n class=\"sc-gene-filter\"\n placeholder=\"Filter genes\u2026\"\n aria-label=\"Filter genes\"\n [value]=\"allGenesFilter\"\n (input)=\"onAllGenesFilter($any($event.target).value)\"\n />\n <small class=\"sc-hint\" *ngIf=\"!canHideAllGenes\">\n This dataset does not say which transcripts are whose, so its genes cannot be hidden one by one.\n </small>\n <small class=\"sc-hint\" *ngIf=\"canHideAllGenes && view.transcriptMode === 'density'\">\n The density map draws every gene as one raster: genes are hidden one by one as circles or icons.\n </small>\n <div class=\"sc-gene-row sc-gene-leaf nested\" *ngFor=\"let row of allRows; trackBy: trackByAllRow\">\n <button\n type=\"button\"\n class=\"sc-eye\"\n [disabled]=\"!canHideAllGenes || view.transcriptMode === 'density'\"\n (click)=\"onAllGeneShown(row.gene, !row.shown)\"\n >\n <i class=\"pi\" [class.pi-eye]=\"row.shown\" [class.pi-eye-slash]=\"!row.shown\"></i>\n </button>\n <!-- The gene's colour among every gene; clicking it opens the colour picker. -->\n <button\n type=\"button\"\n class=\"sc-gene-icon\"\n *ngIf=\"row.swatch\"\n [style.color]=\"row.swatch\"\n [attr.aria-label]=\"'Colour for ' + row.gene\"\n pTooltip=\"Colour\"\n tooltipPosition=\"top\"\n (click)=\"openGeneStyle($event, row.gene, genePop)\"\n >\n <svg viewBox=\"-1.2 -1.2 2.4 2.4\" class=\"sc-glyph-svg\"><circle r=\"0.75\"></circle></svg>\n </button>\n <span class=\"sc-group-label\" [title]=\"row.gene\">{{ row.gene }}</span>\n <span class=\"sc-gene-count\" *ngIf=\"row.count !== null\" title=\"Transcripts in view\">{{\n row.count | number\n }}</span>\n </div>\n <small class=\"sc-hint\" *ngIf=\"allGenesMatched > allRows.length\">\n Showing {{ allRows.length | number }} of {{ allGenesMatched | number }} genes: filter to find the others.\n </small>\n <small class=\"sc-hint\" *ngIf=\"allGenesMatched === 0\">No gene matches.</small>\n </ng-container>\n <ng-container *ngIf=\"geneTreeOpen && !view.transcriptAllGenes\">\n <ng-container *ngFor=\"let node of sortedTree; trackBy: trackByNode\">\n <div class=\"sc-gene-row sc-gene-group\" *ngIf=\"node.name\">\n <button type=\"button\" class=\"sc-eye\" (click)=\"onGenesShown(node.genes, !groupShown.get(node.name))\">\n <i\n class=\"pi\"\n [class.pi-eye]=\"groupShown.get(node.name)\"\n [class.pi-eye-slash]=\"!groupShown.get(node.name)\"\n ></i>\n </button>\n <span class=\"sc-group-label\" [title]=\"node.name\">{{ node.name }}</span>\n <span class=\"sc-count\">({{ node.genes.length }})</span>\n <button type=\"button\" class=\"sc-icon-btn\" (click)=\"toggleGeneGroup(node.name)\">\n <i\n class=\"pi\"\n [class.pi-chevron-down]=\"!collapsedGeneGroups.has(node.name)\"\n [class.pi-chevron-right]=\"collapsedGeneGroups.has(node.name)\"\n ></i>\n </button>\n </div>\n <ng-container *ngIf=\"!node.name || !collapsedGeneGroups.has(node.name)\">\n <div\n class=\"sc-gene-row sc-gene-leaf\"\n [class.nested]=\"!!node.name\"\n *ngFor=\"let gene of node.genes; trackBy: trackByLabelString\"\n >\n <button type=\"button\" class=\"sc-eye\" (click)=\"onGenesShown([gene], !rows.get(gene)?.shown)\">\n <i class=\"pi\" [class.pi-eye]=\"rows.get(gene)?.shown\" [class.pi-eye-slash]=\"!rows.get(gene)?.shown\"></i>\n </button>\n <!-- The gene's marker, in its colour: its icon in Icons mode, a dot for circles.\n Clicking it opens the icon and colour picker (as Xenium Explorer does). -->\n <button\n type=\"button\"\n class=\"sc-gene-icon\"\n [style.color]=\"rows.get(gene)?.swatch\"\n [attr.aria-label]=\"'Icon and colour for ' + gene\"\n pTooltip=\"Icon and colour\"\n tooltipPosition=\"top\"\n (click)=\"openGeneStyle($event, gene, genePop)\"\n >\n <svg viewBox=\"-1.2 -1.2 2.4 2.4\" class=\"sc-glyph-svg\">\n <polygon\n *ngIf=\"view.transcriptMode === 'glyphs'; else dotIcon\"\n [attr.points]=\"rows.get(gene)?.points\"\n ></polygon>\n <ng-template #dotIcon><circle r=\"0.75\"></circle></ng-template>\n </svg>\n </button>\n <span class=\"sc-group-label\">{{ gene }}</span>\n <span\n class=\"sc-gene-count\"\n *ngIf=\"rows.get(gene)?.count as n; else zeroCount\"\n title=\"Transcripts in view\"\n >{{ n | number }}</span\n >\n <ng-template #zeroCount>\n <span class=\"sc-gene-count\" *ngIf=\"geneCounts\" title=\"Transcripts in view\">0</span>\n </ng-template>\n </div>\n </ng-container>\n </ng-container>\n </ng-container>\n <!-- One picker for every gene row, filled for the gene that opened it. -->\n <p-overlayPanel #genePop styleClass=\"sc-gene-style\" appendTo=\"body\">\n <ng-template pTemplate=\"content\">\n <spatial-gene-style\n *ngIf=\"styleGene as gene\"\n [gene]=\"gene\"\n what=\"Transcript\"\n [color]=\"styleColorOf(gene)\"\n [glyph]=\"styleGlyph ?? 'circle'\"\n [showIcons]=\"!view.transcriptAllGenes\"\n [iconHint]=\"\n view.transcriptMode !== 'glyphs' ? 'Icons show when the transcript point style is Icons.' : null\n \"\n (colorChange)=\"onGeneColor(gene, $event)\"\n (glyphChange)=\"onGlyph(gene, $event)\"\n (resetStyle)=\"resetGeneStyle(gene)\"\n ></spatial-gene-style>\n </ng-template>\n </p-overlayPanel>\n <div class=\"sc-gene-footer\">\n {{ (view.transcriptAllGenes ? geneTotal : view.transcriptGenes.length) | number }}/{{ geneTotal | number }}\n genes selected\n </div>\n</div>\n", styles: [".sc-hint{font-size:.75rem;color:var(--text-color-secondary, #6c757d)}.sc-error{color:var(--red-600, #c62828)}.sc-section{display:flex;flex-direction:column;gap:.35rem}.sc-lbl{font-size:.78rem;color:var(--text-color-secondary, #6c757d);white-space:nowrap}.sc-row{display:flex;align-items:center;gap:.6rem}.sc-row p-slider,.sc-row p-dropdown,.sc-row p-treeSelect{flex:1 1 0;min-width:0}:host ::ng-deep .sc-row p-slider .p-slider{width:100%}:host ::ng-deep .sc-row p-dropdown .p-dropdown,:host ::ng-deep .sc-row p-treeSelect .p-treeselect{width:100%}.sc-row .sc-lbl{flex:0 0 calc(50% - .6rem);min-width:0;overflow:hidden;text-overflow:ellipsis}.sc-cmap-option{display:inline-flex;align-items:center;gap:.4rem}.sc-cmap-swatch{width:3.5rem;height:.7rem;border-radius:2px;display:block}.sc-val{flex:0 0 4rem;text-align:right;font-size:.78rem;font-variant-numeric:tabular-nums;white-space:nowrap}:host ::ng-deep .sc-full,:host ::ng-deep .sc-full .p-dropdown,:host ::ng-deep .sc-full .p-autocomplete,:host ::ng-deep .sc-full input{width:100%}.sc-colorbar{height:.75rem;border-radius:2px;border:1px solid rgba(0,0,0,.2)}.sc-colorbar-ends{display:flex;justify-content:space-between;font-size:.7rem;color:var(--text-color-secondary, #6c757d);margin-top:.2rem}.sc-panel{border:1px solid var(--surface-border, #dee2e6);border-radius:6px;margin-bottom:.5rem;overflow:hidden}.sc-panel-head{display:flex;align-items:center;gap:.6rem;padding:.5rem .7rem;cursor:pointer;-webkit-user-select:none;user-select:none;background:var(--surface-100, #f5f6f7)}.sc-panel-head .sc-panel-title{flex:1;font-weight:600}.sc-panel.open>.sc-panel-head{background:var(--primary-color, #2196f3);color:var(--primary-color-text, #fff)}.sc-panel-body{display:flex;flex-direction:column;gap:.45rem;padding:.6rem .75rem .75rem}.sc-subhead{display:flex;align-items:center;gap:.5rem;margin-top:.4rem;font-size:.72rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--text-color-secondary, #6c757d)}.sc-subhead:after{content:\"\";flex:1;border-top:1px solid var(--surface-border, #dee2e6)}.sc-subsection{display:flex;flex-direction:column;gap:.45rem}.sc-subsection-head{cursor:pointer;-webkit-user-select:none;user-select:none}.sc-subsection-head i{font-size:.65rem}.sc-subsection-head:hover .sc-subsection-title{color:var(--primary-color, #3b82f6)}.sc-subsection-body{display:flex;flex-direction:column;gap:.45rem;padding-left:.6rem;border-left:2px solid var(--surface-border, #dee2e6)}:host ::ng-deep .sc-buttons .p-button{padding:.35rem .75rem;font-size:.85rem}.sc-row-picker p-dropdown,.sc-row-picker p-multiSelect,.sc-row-picker p-treeSelect{flex:1 1 0;min-width:0}:host ::ng-deep .sc-row-picker .sc-variant{width:6.5rem}:host ::ng-deep .sc-row-picker p-multiselect .p-multiselect{width:100%}:host ::ng-deep .sc-row-picker p-dropdown:has(.sc-variant){flex:0 0 6.5rem}:host ::ng-deep .sc-row-picker p-treeselect:has(.sc-palette){flex:0 0 3rem}:host ::ng-deep .sc-palette .p-treeselect-label{width:0;padding:0}.sc-icon-btn{flex:0 0 auto;border:0;background:transparent;cursor:pointer;padding:.25rem .35rem;font:inherit;font-size:1.05rem;color:var(--text-color, #333);border-radius:4px}.sc-icon-btn:hover{background:var(--surface-200, #e9ecef)}.sc-icon-btn.active{color:var(--primary-color, #2196f3);font-weight:700}.sc-icon-btn:disabled{opacity:.5;cursor:default}.sc-small-btn{margin-left:auto;border:1px solid var(--surface-border, #ced4da);background:var(--surface-0, #fff);border-radius:4px;padding:.2rem .6rem;font:inherit;font-size:.8rem;cursor:pointer}:host ::ng-deep .sc-group-heading{font-size:.7rem;font-weight:700;letter-spacing:.05em;text-transform:uppercase;opacity:.7}.sc-group-list,.sc-gene-tree{max-height:16rem;overflow-y:auto;border:1px solid var(--surface-border, #dee2e6);border-radius:4px;padding:.25rem .4rem}.sc-group-row,.sc-gene-row{display:flex;align-items:center;gap:.45rem;padding:.15rem 0;font-size:.88rem}.sc-group-row .sc-group-label,.sc-gene-row .sc-group-label{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sc-group-all,.sc-gene-root,.sc-gene-group{font-weight:600}.sc-group-all .sc-icon-btn,.sc-gene-root .sc-icon-btn,.sc-gene-group .sc-icon-btn{margin-left:auto;font-size:.85rem}.sc-count{flex:0 0 auto;font-size:.78rem;color:var(--text-color-secondary, #6c757d)}.sc-glyph-option{display:inline-flex;align-items:center;gap:.4rem}.sc-glyph-svg{width:1rem;height:1rem;fill:currentColor}:host ::ng-deep .sc-glyph-pick .p-dropdown-label{padding:.2rem .4rem}.sc-color-input{width:2.5rem;height:1.8rem;border:1px solid var(--surface-border, #ced4da);border-radius:4px;padding:0;background:none}.sc-row-number p-slider,.sc-row-range p-slider{flex:1 1 0;min-width:0}:host ::ng-deep .sc-num{width:4.5rem;padding:.3rem .4rem;text-align:center}:host ::ng-deep .sc-row-number p-inputnumber,:host ::ng-deep .sc-row-range p-inputnumber{flex:0 0 auto}.sc-gene-icon{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:1.4rem;height:1.4rem;padding:0;border:1px solid transparent;border-radius:4px;background:transparent;cursor:pointer}.sc-gene-icon:hover,.sc-gene-icon:focus-visible{border-color:var(--surface-border, rgba(0, 0, 0, .2))}.sc-seltx-toggle{width:100%;padding:0;background:none;border:0;cursor:pointer;font-family:inherit;text-align:left}.sc-seltx-toggle i{font-size:.65rem}.sc-seltx-toggle:hover{color:var(--primary-color, #3b82f6)}.sc-seltx{display:flex;flex-direction:column;gap:.35rem}.sc-seltx-head{display:flex;align-items:baseline;gap:.5rem;min-width:0}.sc-seltx-label{font-size:.82rem;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sc-seltx-summary{display:flex;align-items:center;justify-content:space-between;font-size:.78rem}.sc-seltx-list{list-style:none;margin:0;padding:0;max-height:16rem;overflow-y:auto;font-size:.78rem}.sc-seltx-list.stale{opacity:.55}.sc-seltx-list li{display:grid;grid-template-columns:minmax(4rem,7rem) 1fr auto;align-items:center;gap:.5rem;padding:.1rem 0}.sc-seltx-gene{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sc-seltx-bar{height:.45rem;border-radius:2px;background:var(--surface-200, #e9ecef);overflow:hidden}.sc-seltx-bar span{display:block;height:100%;background:var(--primary-color, #3b82f6)}.sc-seltx-count{font-variant-numeric:tabular-nums;text-align:right;min-width:3rem}.sc-seltx-swatch{display:inline-block;width:.6rem;height:.6rem;margin-right:.35rem;border-radius:2px;vertical-align:baseline}.sc-seltx-measures{display:grid;grid-template-columns:minmax(4rem,1fr) auto;gap:.1rem .75rem;margin:0;font-size:.78rem}.sc-seltx-measures dt{color:var(--text-color-secondary, #6c757d);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sc-seltx-measures dd{margin:0;text-align:right;font-variant-numeric:tabular-nums}:host{display:contents}.sc-gene-group,.sc-gene-leaf{padding-left:1rem}.sc-gene-leaf.nested{padding-left:2rem}.sc-eye{flex:0 0 auto;border:0;background:transparent;cursor:pointer;padding:0;color:var(--text-color-secondary, #6c757d)}.sc-eye .pi-eye{color:var(--text-color, #333)}.sc-eye:disabled{cursor:default;opacity:.5}.sc-gene-sort{display:flex;align-items:center;gap:.25rem;font-size:.8rem}.sc-gene-sort .sc-lbl{margin-right:auto}.sc-sort-btn{border:1px solid var(--surface-border, #ced4da);background:var(--surface-0, #fff);color:var(--text-color, #333);border-radius:4px;padding:.1rem .5rem;font:inherit;cursor:pointer}.sc-sort-btn.active{border-color:var(--primary-color, #2196f3);color:var(--primary-color, #2196f3);font-weight:600}.sc-gene-filter{width:calc(100% - 1rem);margin:.2rem 0 .2rem 1rem;font-size:.8rem;padding:.2rem .4rem}.sc-gene-footer{text-align:right;font-size:.78rem;padding:.2rem 0;color:var(--text-color-secondary, #6c757d)}.sc-gene-count{margin-left:auto;font-variant-numeric:tabular-nums;opacity:.8;padding-left:.5rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i1.DecimalPipe, name: "number" }, { kind: "ngmodule", type: SharedModule }, { kind: "directive", type: i2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3.InputText, selector: "[pInputText]", inputs: ["variant"] }, { kind: "ngmodule", type: OverlayPanelModule }, { kind: "component", type: i4.OverlayPanel, selector: "p-overlayPanel", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "showCloseIcon", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions"], outputs: ["onShow", "onHide"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5.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: SpatialGeneStyleComponent, selector: "spatial-gene-style", inputs: ["gene", "what", "color", "glyph", "iconHint", "showIcons"], outputs: ["colorChange", "glyphChange", "resetStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
347
347
  }
348
348
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: SpatialGeneTreeComponent, decorators: [{
349
349
  type: Component,
@@ -354,7 +354,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImpor
354
354
  OverlayPanelModule,
355
355
  TooltipModule,
356
356
  SpatialGeneStyleComponent,
357
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"sc-subhead\">Selected genes</div>\n<div class=\"sc-gene-sort\" *ngIf=\"sortShown\" role=\"group\" aria-label=\"Sort genes\">\n <span class=\"sc-lbl\">Sort by</span>\n <button\n type=\"button\"\n class=\"sc-sort-btn\"\n [class.active]=\"!byCount\"\n [attr.aria-pressed]=\"!byCount\"\n (click)=\"onGeneSort('name')\"\n >\n Name\n </button>\n <button\n type=\"button\"\n class=\"sc-sort-btn\"\n [class.active]=\"byCount\"\n [attr.aria-pressed]=\"byCount\"\n title=\"Transcripts in view, most first\"\n (click)=\"onGeneSort('count')\"\n >\n Count\n </button>\n</div>\n<div class=\"sc-gene-tree\">\n <div class=\"sc-gene-row sc-gene-root\">\n <button\n type=\"button\"\n class=\"sc-eye\"\n (click)=\"\n view.transcriptAllGenes ? onAllGenesShown(!rootShown) : onGenesShown(view.transcriptGenes, !rootShown)\n \"\n >\n <i class=\"pi\" [class.pi-eye]=\"rootShown\" [class.pi-eye-slash]=\"!rootShown\"></i>\n </button>\n <span class=\"sc-group-label\">Genes</span>\n <span class=\"sc-count\"\n >({{ (view.transcriptAllGenes ? geneTotal : view.transcriptGenes.length) | number }}/{{\n geneTotal | number\n }})</span\n >\n <button\n type=\"button\"\n class=\"sc-icon-btn\"\n (click)=\"geneTreeOpen = !geneTreeOpen\"\n *ngIf=\"!view.transcriptAllGenes && view.transcriptGenes.length\"\n >\n <i class=\"pi\" [class.pi-chevron-down]=\"geneTreeOpen\" [class.pi-chevron-right]=\"!geneTreeOpen\"></i>\n </button>\n <button\n type=\"button\"\n class=\"sc-icon-btn\"\n (click)=\"toggleAllGenesOpen()\"\n *ngIf=\"view.transcriptAllGenes && allGeneList?.length\"\n [attr.aria-label]=\"allGenesOpen ? 'Hide the gene list' : 'Show every gene'\"\n >\n <i class=\"pi\" [class.pi-chevron-down]=\"allGenesOpen\" [class.pi-chevron-right]=\"!allGenesOpen\"></i>\n </button>\n </div>\n <!-- \"All genes\": every gene of the dataset, each with its eye when the dataset says which\n transcripts are whose (its gene list in code order). -->\n <ng-container *ngIf=\"allGenesOpen && view.transcriptAllGenes && allGeneList?.length\">\n <input\n pInputText\n class=\"sc-gene-filter\"\n placeholder=\"Filter genes\u2026\"\n aria-label=\"Filter genes\"\n [value]=\"allGenesFilter\"\n (input)=\"onAllGenesFilter($any($event.target).value)\"\n />\n <small class=\"sc-hint\" *ngIf=\"!canHideAllGenes\">\n This dataset does not say which transcripts are whose, so its genes cannot be hidden one by one.\n </small>\n <small class=\"sc-hint\" *ngIf=\"canHideAllGenes && view.transcriptMode === 'density'\">\n The density map draws every gene as one raster: genes are hidden one by one as circles or icons.\n </small>\n <div class=\"sc-gene-row sc-gene-leaf nested\" *ngFor=\"let row of allRows; trackBy: trackByAllRow\">\n <button\n type=\"button\"\n class=\"sc-eye\"\n [disabled]=\"!canHideAllGenes || view.transcriptMode === 'density'\"\n (click)=\"onAllGeneShown(row.gene, !row.shown)\"\n >\n <i class=\"pi\" [class.pi-eye]=\"row.shown\" [class.pi-eye-slash]=\"!row.shown\"></i>\n </button>\n <!-- The gene's colour among every gene; clicking it opens the colour picker. -->\n <button\n type=\"button\"\n class=\"sc-gene-icon\"\n *ngIf=\"row.swatch\"\n [style.color]=\"row.swatch\"\n [attr.aria-label]=\"'Colour for ' + row.gene\"\n pTooltip=\"Colour\"\n tooltipPosition=\"top\"\n (click)=\"openGeneStyle($event, row.gene, genePop)\"\n >\n <svg viewBox=\"-1.2 -1.2 2.4 2.4\" class=\"sc-glyph-svg\"><circle r=\"0.75\"></circle></svg>\n </button>\n <span class=\"sc-group-label\" [title]=\"row.gene\">{{ row.gene }}</span>\n <span class=\"sc-gene-count\" *ngIf=\"row.count !== null\" title=\"Transcripts in view\">{{\n row.count | number\n }}</span>\n </div>\n <small class=\"sc-hint\" *ngIf=\"allGenesMatched > allRows.length\">\n Showing {{ allRows.length | number }} of {{ allGenesMatched | number }} genes: filter to find the others.\n </small>\n <small class=\"sc-hint\" *ngIf=\"allGenesMatched === 0\">No gene matches.</small>\n </ng-container>\n <ng-container *ngIf=\"geneTreeOpen && !view.transcriptAllGenes\">\n <ng-container *ngFor=\"let node of sortedTree; trackBy: trackByNode\">\n <div class=\"sc-gene-row sc-gene-group\" *ngIf=\"node.name\">\n <button type=\"button\" class=\"sc-eye\" (click)=\"onGenesShown(node.genes, !groupShown.get(node.name))\">\n <i\n class=\"pi\"\n [class.pi-eye]=\"groupShown.get(node.name)\"\n [class.pi-eye-slash]=\"!groupShown.get(node.name)\"\n ></i>\n </button>\n <span class=\"sc-group-label\" [title]=\"node.name\">{{ node.name }}</span>\n <span class=\"sc-count\">({{ node.genes.length }})</span>\n <button type=\"button\" class=\"sc-icon-btn\" (click)=\"toggleGeneGroup(node.name)\">\n <i\n class=\"pi\"\n [class.pi-chevron-down]=\"!collapsedGeneGroups.has(node.name)\"\n [class.pi-chevron-right]=\"collapsedGeneGroups.has(node.name)\"\n ></i>\n </button>\n </div>\n <ng-container *ngIf=\"!node.name || !collapsedGeneGroups.has(node.name)\">\n <div\n class=\"sc-gene-row sc-gene-leaf\"\n [class.nested]=\"!!node.name\"\n *ngFor=\"let gene of node.genes; trackBy: trackByLabelString\"\n >\n <button type=\"button\" class=\"sc-eye\" (click)=\"onGenesShown([gene], !rows.get(gene)?.shown)\">\n <i class=\"pi\" [class.pi-eye]=\"rows.get(gene)?.shown\" [class.pi-eye-slash]=\"!rows.get(gene)?.shown\"></i>\n </button>\n <!-- The gene's marker, in its colour: its icon in Icons mode, a dot for circles.\n Clicking it opens the icon and colour picker (as Xenium Explorer does). -->\n <button\n type=\"button\"\n class=\"sc-gene-icon\"\n [style.color]=\"rows.get(gene)?.swatch\"\n [attr.aria-label]=\"'Icon and colour for ' + gene\"\n pTooltip=\"Icon and colour\"\n tooltipPosition=\"top\"\n (click)=\"openGeneStyle($event, gene, genePop)\"\n >\n <svg viewBox=\"-1.2 -1.2 2.4 2.4\" class=\"sc-glyph-svg\">\n <polygon\n *ngIf=\"view.transcriptMode === 'glyphs'; else dotIcon\"\n [attr.points]=\"rows.get(gene)?.points\"\n ></polygon>\n <ng-template #dotIcon><circle r=\"0.75\"></circle></ng-template>\n </svg>\n </button>\n <span class=\"sc-group-label\">{{ gene }}</span>\n <span\n class=\"sc-gene-count\"\n *ngIf=\"rows.get(gene)?.count as n; else zeroCount\"\n title=\"Transcripts in view\"\n >{{ n | number }}</span\n >\n <ng-template #zeroCount>\n <span class=\"sc-gene-count\" *ngIf=\"geneCounts\" title=\"Transcripts in view\">0</span>\n </ng-template>\n </div>\n </ng-container>\n </ng-container>\n </ng-container>\n <!-- One picker for every gene row, filled for the gene that opened it. -->\n <p-overlayPanel #genePop styleClass=\"sc-gene-style\" appendTo=\"body\">\n <ng-template pTemplate=\"content\">\n <spatial-gene-style\n *ngIf=\"styleGene as gene\"\n [gene]=\"gene\"\n what=\"Transcript\"\n [color]=\"styleColorOf(gene)\"\n [glyph]=\"styleGlyph ?? 'circle'\"\n [showIcons]=\"!view.transcriptAllGenes\"\n [iconHint]=\"\n view.transcriptMode !== 'glyphs' ? 'Icons show when the transcript point style is Icons.' : null\n \"\n (colorChange)=\"onGeneColor(gene, $event)\"\n (glyphChange)=\"onGlyph(gene, $event)\"\n (resetStyle)=\"resetGeneStyle(gene)\"\n ></spatial-gene-style>\n </ng-template>\n </p-overlayPanel>\n <div class=\"sc-gene-footer\">\n {{ (view.transcriptAllGenes ? geneTotal : view.transcriptGenes.length) | number }}/{{ geneTotal | number }}\n genes selected\n </div>\n</div>\n", styles: [".sc-hint{font-size:.75rem;color:var(--text-color-secondary, #6c757d)}.sc-error{color:var(--red-600, #c62828)}.sc-section{display:flex;flex-direction:column;gap:.35rem}.sc-lbl{font-size:.78rem;color:var(--text-color-secondary, #6c757d);white-space:nowrap}.sc-row{display:flex;align-items:center;gap:.6rem}.sc-row p-slider,.sc-row p-dropdown,.sc-row p-treeSelect{flex:1 1 0;min-width:0}:host ::ng-deep .sc-row p-slider .p-slider{width:100%}:host ::ng-deep .sc-row p-dropdown .p-dropdown,:host ::ng-deep .sc-row p-treeSelect .p-treeselect{width:100%}.sc-row .sc-lbl{flex:0 0 calc(50% - .6rem);min-width:0;overflow:hidden;text-overflow:ellipsis}.sc-cmap-option{display:inline-flex;align-items:center;gap:.4rem}.sc-cmap-swatch{width:3.5rem;height:.7rem;border-radius:2px;display:block}.sc-val{flex:0 0 4rem;text-align:right;font-size:.78rem;font-variant-numeric:tabular-nums;white-space:nowrap}:host ::ng-deep .sc-full,:host ::ng-deep .sc-full .p-dropdown,:host ::ng-deep .sc-full .p-autocomplete,:host ::ng-deep .sc-full input{width:100%}.sc-colorbar{height:.75rem;border-radius:2px;border:1px solid rgba(0,0,0,.2)}.sc-colorbar-ends{display:flex;justify-content:space-between;font-size:.7rem;color:var(--text-color-secondary, #6c757d);margin-top:.2rem}.sc-panel{border:1px solid var(--surface-border, #dee2e6);border-radius:6px;margin-bottom:.5rem;overflow:hidden}.sc-panel-head{display:flex;align-items:center;gap:.6rem;padding:.5rem .7rem;cursor:pointer;-webkit-user-select:none;user-select:none;background:var(--surface-100, #f5f6f7)}.sc-panel-head .sc-panel-title{flex:1;font-weight:600}.sc-panel.open>.sc-panel-head{background:var(--primary-color, #2196f3);color:var(--primary-color-text, #fff)}.sc-panel-body{display:flex;flex-direction:column;gap:.45rem;padding:.6rem .75rem .75rem}.sc-subhead{display:flex;align-items:center;gap:.5rem;margin-top:.4rem;font-size:.72rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--text-color-secondary, #6c757d)}.sc-subhead:after{content:\"\";flex:1;border-top:1px solid var(--surface-border, #dee2e6)}:host ::ng-deep .sc-buttons .p-button{padding:.35rem .75rem;font-size:.85rem}.sc-row-picker p-dropdown,.sc-row-picker p-multiSelect,.sc-row-picker p-treeSelect{flex:1 1 0;min-width:0}:host ::ng-deep .sc-row-picker .sc-variant{width:6.5rem}:host ::ng-deep .sc-row-picker p-multiselect .p-multiselect{width:100%}:host ::ng-deep .sc-row-picker p-dropdown:has(.sc-variant){flex:0 0 6.5rem}:host ::ng-deep .sc-row-picker p-treeselect:has(.sc-palette){flex:0 0 3rem}:host ::ng-deep .sc-palette .p-treeselect-label{width:0;padding:0}.sc-icon-btn{flex:0 0 auto;border:0;background:transparent;cursor:pointer;padding:.25rem .35rem;font:inherit;font-size:1.05rem;color:var(--text-color, #333);border-radius:4px}.sc-icon-btn:hover{background:var(--surface-200, #e9ecef)}.sc-icon-btn.active{color:var(--primary-color, #2196f3);font-weight:700}.sc-icon-btn:disabled{opacity:.5;cursor:default}.sc-small-btn{margin-left:auto;border:1px solid var(--surface-border, #ced4da);background:var(--surface-0, #fff);border-radius:4px;padding:.2rem .6rem;font:inherit;font-size:.8rem;cursor:pointer}:host ::ng-deep .sc-group-heading{font-size:.7rem;font-weight:700;letter-spacing:.05em;text-transform:uppercase;opacity:.7}.sc-group-list,.sc-gene-tree{max-height:16rem;overflow-y:auto;border:1px solid var(--surface-border, #dee2e6);border-radius:4px;padding:.25rem .4rem}.sc-group-row,.sc-gene-row{display:flex;align-items:center;gap:.45rem;padding:.15rem 0;font-size:.88rem}.sc-group-row .sc-group-label,.sc-gene-row .sc-group-label{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sc-group-all,.sc-gene-root,.sc-gene-group{font-weight:600}.sc-group-all .sc-icon-btn,.sc-gene-root .sc-icon-btn,.sc-gene-group .sc-icon-btn{margin-left:auto;font-size:.85rem}.sc-count{flex:0 0 auto;font-size:.78rem;color:var(--text-color-secondary, #6c757d)}.sc-glyph-option{display:inline-flex;align-items:center;gap:.4rem}.sc-glyph-svg{width:1rem;height:1rem;fill:currentColor}:host ::ng-deep .sc-glyph-pick .p-dropdown-label{padding:.2rem .4rem}.sc-color-input{width:2.5rem;height:1.8rem;border:1px solid var(--surface-border, #ced4da);border-radius:4px;padding:0;background:none}.sc-row-number p-slider,.sc-row-range p-slider{flex:1 1 0;min-width:0}:host ::ng-deep .sc-num{width:4.5rem;padding:.3rem .4rem;text-align:center}:host ::ng-deep .sc-row-number p-inputnumber,:host ::ng-deep .sc-row-range p-inputnumber{flex:0 0 auto}.sc-gene-icon{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:1.4rem;height:1.4rem;padding:0;border:1px solid transparent;border-radius:4px;background:transparent;cursor:pointer}.sc-gene-icon:hover,.sc-gene-icon:focus-visible{border-color:var(--surface-border, rgba(0, 0, 0, .2))}:host{display:contents}.sc-gene-group,.sc-gene-leaf{padding-left:1rem}.sc-gene-leaf.nested{padding-left:2rem}.sc-eye{flex:0 0 auto;border:0;background:transparent;cursor:pointer;padding:0;color:var(--text-color-secondary, #6c757d)}.sc-eye .pi-eye{color:var(--text-color, #333)}.sc-eye:disabled{cursor:default;opacity:.5}.sc-gene-sort{display:flex;align-items:center;gap:.25rem;font-size:.8rem}.sc-gene-sort .sc-lbl{margin-right:auto}.sc-sort-btn{border:1px solid var(--surface-border, #ced4da);background:var(--surface-0, #fff);color:var(--text-color, #333);border-radius:4px;padding:.1rem .5rem;font:inherit;cursor:pointer}.sc-sort-btn.active{border-color:var(--primary-color, #2196f3);color:var(--primary-color, #2196f3);font-weight:600}.sc-gene-filter{width:calc(100% - 1rem);margin:.2rem 0 .2rem 1rem;font-size:.8rem;padding:.2rem .4rem}.sc-gene-footer{text-align:right;font-size:.78rem;padding:.2rem 0;color:var(--text-color-secondary, #6c757d)}.sc-gene-count{margin-left:auto;font-variant-numeric:tabular-nums;opacity:.8;padding-left:.5rem}\n"] }]
357
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"sc-subhead\">Selected genes</div>\n<div class=\"sc-gene-sort\" *ngIf=\"sortShown\" role=\"group\" aria-label=\"Sort genes\">\n <span class=\"sc-lbl\">Sort by</span>\n <button\n type=\"button\"\n class=\"sc-sort-btn\"\n [class.active]=\"!byCount\"\n [attr.aria-pressed]=\"!byCount\"\n (click)=\"onGeneSort('name')\"\n >\n Name\n </button>\n <button\n type=\"button\"\n class=\"sc-sort-btn\"\n [class.active]=\"byCount\"\n [attr.aria-pressed]=\"byCount\"\n title=\"Transcripts in view, most first\"\n (click)=\"onGeneSort('count')\"\n >\n Count\n </button>\n</div>\n<div class=\"sc-gene-tree\">\n <div class=\"sc-gene-row sc-gene-root\">\n <button\n type=\"button\"\n class=\"sc-eye\"\n (click)=\"\n view.transcriptAllGenes ? onAllGenesShown(!rootShown) : onGenesShown(view.transcriptGenes, !rootShown)\n \"\n >\n <i class=\"pi\" [class.pi-eye]=\"rootShown\" [class.pi-eye-slash]=\"!rootShown\"></i>\n </button>\n <span class=\"sc-group-label\">Genes</span>\n <span class=\"sc-count\"\n >({{ (view.transcriptAllGenes ? geneTotal : view.transcriptGenes.length) | number }}/{{\n geneTotal | number\n }})</span\n >\n <button\n type=\"button\"\n class=\"sc-icon-btn\"\n (click)=\"geneTreeOpen = !geneTreeOpen\"\n *ngIf=\"!view.transcriptAllGenes && view.transcriptGenes.length\"\n >\n <i class=\"pi\" [class.pi-chevron-down]=\"geneTreeOpen\" [class.pi-chevron-right]=\"!geneTreeOpen\"></i>\n </button>\n <button\n type=\"button\"\n class=\"sc-icon-btn\"\n (click)=\"toggleAllGenesOpen()\"\n *ngIf=\"view.transcriptAllGenes && allGeneList?.length\"\n [attr.aria-label]=\"allGenesOpen ? 'Hide the gene list' : 'Show every gene'\"\n >\n <i class=\"pi\" [class.pi-chevron-down]=\"allGenesOpen\" [class.pi-chevron-right]=\"!allGenesOpen\"></i>\n </button>\n </div>\n <!-- \"All genes\": every gene of the dataset, each with its eye when the dataset says which\n transcripts are whose (its gene list in code order). -->\n <ng-container *ngIf=\"allGenesOpen && view.transcriptAllGenes && allGeneList?.length\">\n <input\n pInputText\n class=\"sc-gene-filter\"\n placeholder=\"Filter genes\u2026\"\n aria-label=\"Filter genes\"\n [value]=\"allGenesFilter\"\n (input)=\"onAllGenesFilter($any($event.target).value)\"\n />\n <small class=\"sc-hint\" *ngIf=\"!canHideAllGenes\">\n This dataset does not say which transcripts are whose, so its genes cannot be hidden one by one.\n </small>\n <small class=\"sc-hint\" *ngIf=\"canHideAllGenes && view.transcriptMode === 'density'\">\n The density map draws every gene as one raster: genes are hidden one by one as circles or icons.\n </small>\n <div class=\"sc-gene-row sc-gene-leaf nested\" *ngFor=\"let row of allRows; trackBy: trackByAllRow\">\n <button\n type=\"button\"\n class=\"sc-eye\"\n [disabled]=\"!canHideAllGenes || view.transcriptMode === 'density'\"\n (click)=\"onAllGeneShown(row.gene, !row.shown)\"\n >\n <i class=\"pi\" [class.pi-eye]=\"row.shown\" [class.pi-eye-slash]=\"!row.shown\"></i>\n </button>\n <!-- The gene's colour among every gene; clicking it opens the colour picker. -->\n <button\n type=\"button\"\n class=\"sc-gene-icon\"\n *ngIf=\"row.swatch\"\n [style.color]=\"row.swatch\"\n [attr.aria-label]=\"'Colour for ' + row.gene\"\n pTooltip=\"Colour\"\n tooltipPosition=\"top\"\n (click)=\"openGeneStyle($event, row.gene, genePop)\"\n >\n <svg viewBox=\"-1.2 -1.2 2.4 2.4\" class=\"sc-glyph-svg\"><circle r=\"0.75\"></circle></svg>\n </button>\n <span class=\"sc-group-label\" [title]=\"row.gene\">{{ row.gene }}</span>\n <span class=\"sc-gene-count\" *ngIf=\"row.count !== null\" title=\"Transcripts in view\">{{\n row.count | number\n }}</span>\n </div>\n <small class=\"sc-hint\" *ngIf=\"allGenesMatched > allRows.length\">\n Showing {{ allRows.length | number }} of {{ allGenesMatched | number }} genes: filter to find the others.\n </small>\n <small class=\"sc-hint\" *ngIf=\"allGenesMatched === 0\">No gene matches.</small>\n </ng-container>\n <ng-container *ngIf=\"geneTreeOpen && !view.transcriptAllGenes\">\n <ng-container *ngFor=\"let node of sortedTree; trackBy: trackByNode\">\n <div class=\"sc-gene-row sc-gene-group\" *ngIf=\"node.name\">\n <button type=\"button\" class=\"sc-eye\" (click)=\"onGenesShown(node.genes, !groupShown.get(node.name))\">\n <i\n class=\"pi\"\n [class.pi-eye]=\"groupShown.get(node.name)\"\n [class.pi-eye-slash]=\"!groupShown.get(node.name)\"\n ></i>\n </button>\n <span class=\"sc-group-label\" [title]=\"node.name\">{{ node.name }}</span>\n <span class=\"sc-count\">({{ node.genes.length }})</span>\n <button type=\"button\" class=\"sc-icon-btn\" (click)=\"toggleGeneGroup(node.name)\">\n <i\n class=\"pi\"\n [class.pi-chevron-down]=\"!collapsedGeneGroups.has(node.name)\"\n [class.pi-chevron-right]=\"collapsedGeneGroups.has(node.name)\"\n ></i>\n </button>\n </div>\n <ng-container *ngIf=\"!node.name || !collapsedGeneGroups.has(node.name)\">\n <div\n class=\"sc-gene-row sc-gene-leaf\"\n [class.nested]=\"!!node.name\"\n *ngFor=\"let gene of node.genes; trackBy: trackByLabelString\"\n >\n <button type=\"button\" class=\"sc-eye\" (click)=\"onGenesShown([gene], !rows.get(gene)?.shown)\">\n <i class=\"pi\" [class.pi-eye]=\"rows.get(gene)?.shown\" [class.pi-eye-slash]=\"!rows.get(gene)?.shown\"></i>\n </button>\n <!-- The gene's marker, in its colour: its icon in Icons mode, a dot for circles.\n Clicking it opens the icon and colour picker (as Xenium Explorer does). -->\n <button\n type=\"button\"\n class=\"sc-gene-icon\"\n [style.color]=\"rows.get(gene)?.swatch\"\n [attr.aria-label]=\"'Icon and colour for ' + gene\"\n pTooltip=\"Icon and colour\"\n tooltipPosition=\"top\"\n (click)=\"openGeneStyle($event, gene, genePop)\"\n >\n <svg viewBox=\"-1.2 -1.2 2.4 2.4\" class=\"sc-glyph-svg\">\n <polygon\n *ngIf=\"view.transcriptMode === 'glyphs'; else dotIcon\"\n [attr.points]=\"rows.get(gene)?.points\"\n ></polygon>\n <ng-template #dotIcon><circle r=\"0.75\"></circle></ng-template>\n </svg>\n </button>\n <span class=\"sc-group-label\">{{ gene }}</span>\n <span\n class=\"sc-gene-count\"\n *ngIf=\"rows.get(gene)?.count as n; else zeroCount\"\n title=\"Transcripts in view\"\n >{{ n | number }}</span\n >\n <ng-template #zeroCount>\n <span class=\"sc-gene-count\" *ngIf=\"geneCounts\" title=\"Transcripts in view\">0</span>\n </ng-template>\n </div>\n </ng-container>\n </ng-container>\n </ng-container>\n <!-- One picker for every gene row, filled for the gene that opened it. -->\n <p-overlayPanel #genePop styleClass=\"sc-gene-style\" appendTo=\"body\">\n <ng-template pTemplate=\"content\">\n <spatial-gene-style\n *ngIf=\"styleGene as gene\"\n [gene]=\"gene\"\n what=\"Transcript\"\n [color]=\"styleColorOf(gene)\"\n [glyph]=\"styleGlyph ?? 'circle'\"\n [showIcons]=\"!view.transcriptAllGenes\"\n [iconHint]=\"\n view.transcriptMode !== 'glyphs' ? 'Icons show when the transcript point style is Icons.' : null\n \"\n (colorChange)=\"onGeneColor(gene, $event)\"\n (glyphChange)=\"onGlyph(gene, $event)\"\n (resetStyle)=\"resetGeneStyle(gene)\"\n ></spatial-gene-style>\n </ng-template>\n </p-overlayPanel>\n <div class=\"sc-gene-footer\">\n {{ (view.transcriptAllGenes ? geneTotal : view.transcriptGenes.length) | number }}/{{ geneTotal | number }}\n genes selected\n </div>\n</div>\n", styles: [".sc-hint{font-size:.75rem;color:var(--text-color-secondary, #6c757d)}.sc-error{color:var(--red-600, #c62828)}.sc-section{display:flex;flex-direction:column;gap:.35rem}.sc-lbl{font-size:.78rem;color:var(--text-color-secondary, #6c757d);white-space:nowrap}.sc-row{display:flex;align-items:center;gap:.6rem}.sc-row p-slider,.sc-row p-dropdown,.sc-row p-treeSelect{flex:1 1 0;min-width:0}:host ::ng-deep .sc-row p-slider .p-slider{width:100%}:host ::ng-deep .sc-row p-dropdown .p-dropdown,:host ::ng-deep .sc-row p-treeSelect .p-treeselect{width:100%}.sc-row .sc-lbl{flex:0 0 calc(50% - .6rem);min-width:0;overflow:hidden;text-overflow:ellipsis}.sc-cmap-option{display:inline-flex;align-items:center;gap:.4rem}.sc-cmap-swatch{width:3.5rem;height:.7rem;border-radius:2px;display:block}.sc-val{flex:0 0 4rem;text-align:right;font-size:.78rem;font-variant-numeric:tabular-nums;white-space:nowrap}:host ::ng-deep .sc-full,:host ::ng-deep .sc-full .p-dropdown,:host ::ng-deep .sc-full .p-autocomplete,:host ::ng-deep .sc-full input{width:100%}.sc-colorbar{height:.75rem;border-radius:2px;border:1px solid rgba(0,0,0,.2)}.sc-colorbar-ends{display:flex;justify-content:space-between;font-size:.7rem;color:var(--text-color-secondary, #6c757d);margin-top:.2rem}.sc-panel{border:1px solid var(--surface-border, #dee2e6);border-radius:6px;margin-bottom:.5rem;overflow:hidden}.sc-panel-head{display:flex;align-items:center;gap:.6rem;padding:.5rem .7rem;cursor:pointer;-webkit-user-select:none;user-select:none;background:var(--surface-100, #f5f6f7)}.sc-panel-head .sc-panel-title{flex:1;font-weight:600}.sc-panel.open>.sc-panel-head{background:var(--primary-color, #2196f3);color:var(--primary-color-text, #fff)}.sc-panel-body{display:flex;flex-direction:column;gap:.45rem;padding:.6rem .75rem .75rem}.sc-subhead{display:flex;align-items:center;gap:.5rem;margin-top:.4rem;font-size:.72rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--text-color-secondary, #6c757d)}.sc-subhead:after{content:\"\";flex:1;border-top:1px solid var(--surface-border, #dee2e6)}.sc-subsection{display:flex;flex-direction:column;gap:.45rem}.sc-subsection-head{cursor:pointer;-webkit-user-select:none;user-select:none}.sc-subsection-head i{font-size:.65rem}.sc-subsection-head:hover .sc-subsection-title{color:var(--primary-color, #3b82f6)}.sc-subsection-body{display:flex;flex-direction:column;gap:.45rem;padding-left:.6rem;border-left:2px solid var(--surface-border, #dee2e6)}:host ::ng-deep .sc-buttons .p-button{padding:.35rem .75rem;font-size:.85rem}.sc-row-picker p-dropdown,.sc-row-picker p-multiSelect,.sc-row-picker p-treeSelect{flex:1 1 0;min-width:0}:host ::ng-deep .sc-row-picker .sc-variant{width:6.5rem}:host ::ng-deep .sc-row-picker p-multiselect .p-multiselect{width:100%}:host ::ng-deep .sc-row-picker p-dropdown:has(.sc-variant){flex:0 0 6.5rem}:host ::ng-deep .sc-row-picker p-treeselect:has(.sc-palette){flex:0 0 3rem}:host ::ng-deep .sc-palette .p-treeselect-label{width:0;padding:0}.sc-icon-btn{flex:0 0 auto;border:0;background:transparent;cursor:pointer;padding:.25rem .35rem;font:inherit;font-size:1.05rem;color:var(--text-color, #333);border-radius:4px}.sc-icon-btn:hover{background:var(--surface-200, #e9ecef)}.sc-icon-btn.active{color:var(--primary-color, #2196f3);font-weight:700}.sc-icon-btn:disabled{opacity:.5;cursor:default}.sc-small-btn{margin-left:auto;border:1px solid var(--surface-border, #ced4da);background:var(--surface-0, #fff);border-radius:4px;padding:.2rem .6rem;font:inherit;font-size:.8rem;cursor:pointer}:host ::ng-deep .sc-group-heading{font-size:.7rem;font-weight:700;letter-spacing:.05em;text-transform:uppercase;opacity:.7}.sc-group-list,.sc-gene-tree{max-height:16rem;overflow-y:auto;border:1px solid var(--surface-border, #dee2e6);border-radius:4px;padding:.25rem .4rem}.sc-group-row,.sc-gene-row{display:flex;align-items:center;gap:.45rem;padding:.15rem 0;font-size:.88rem}.sc-group-row .sc-group-label,.sc-gene-row .sc-group-label{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sc-group-all,.sc-gene-root,.sc-gene-group{font-weight:600}.sc-group-all .sc-icon-btn,.sc-gene-root .sc-icon-btn,.sc-gene-group .sc-icon-btn{margin-left:auto;font-size:.85rem}.sc-count{flex:0 0 auto;font-size:.78rem;color:var(--text-color-secondary, #6c757d)}.sc-glyph-option{display:inline-flex;align-items:center;gap:.4rem}.sc-glyph-svg{width:1rem;height:1rem;fill:currentColor}:host ::ng-deep .sc-glyph-pick .p-dropdown-label{padding:.2rem .4rem}.sc-color-input{width:2.5rem;height:1.8rem;border:1px solid var(--surface-border, #ced4da);border-radius:4px;padding:0;background:none}.sc-row-number p-slider,.sc-row-range p-slider{flex:1 1 0;min-width:0}:host ::ng-deep .sc-num{width:4.5rem;padding:.3rem .4rem;text-align:center}:host ::ng-deep .sc-row-number p-inputnumber,:host ::ng-deep .sc-row-range p-inputnumber{flex:0 0 auto}.sc-gene-icon{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:1.4rem;height:1.4rem;padding:0;border:1px solid transparent;border-radius:4px;background:transparent;cursor:pointer}.sc-gene-icon:hover,.sc-gene-icon:focus-visible{border-color:var(--surface-border, rgba(0, 0, 0, .2))}.sc-seltx-toggle{width:100%;padding:0;background:none;border:0;cursor:pointer;font-family:inherit;text-align:left}.sc-seltx-toggle i{font-size:.65rem}.sc-seltx-toggle:hover{color:var(--primary-color, #3b82f6)}.sc-seltx{display:flex;flex-direction:column;gap:.35rem}.sc-seltx-head{display:flex;align-items:baseline;gap:.5rem;min-width:0}.sc-seltx-label{font-size:.82rem;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sc-seltx-summary{display:flex;align-items:center;justify-content:space-between;font-size:.78rem}.sc-seltx-list{list-style:none;margin:0;padding:0;max-height:16rem;overflow-y:auto;font-size:.78rem}.sc-seltx-list.stale{opacity:.55}.sc-seltx-list li{display:grid;grid-template-columns:minmax(4rem,7rem) 1fr auto;align-items:center;gap:.5rem;padding:.1rem 0}.sc-seltx-gene{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sc-seltx-bar{height:.45rem;border-radius:2px;background:var(--surface-200, #e9ecef);overflow:hidden}.sc-seltx-bar span{display:block;height:100%;background:var(--primary-color, #3b82f6)}.sc-seltx-count{font-variant-numeric:tabular-nums;text-align:right;min-width:3rem}.sc-seltx-swatch{display:inline-block;width:.6rem;height:.6rem;margin-right:.35rem;border-radius:2px;vertical-align:baseline}.sc-seltx-measures{display:grid;grid-template-columns:minmax(4rem,1fr) auto;gap:.1rem .75rem;margin:0;font-size:.78rem}.sc-seltx-measures dt{color:var(--text-color-secondary, #6c757d);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sc-seltx-measures dd{margin:0;text-align:right;font-variant-numeric:tabular-nums}:host{display:contents}.sc-gene-group,.sc-gene-leaf{padding-left:1rem}.sc-gene-leaf.nested{padding-left:2rem}.sc-eye{flex:0 0 auto;border:0;background:transparent;cursor:pointer;padding:0;color:var(--text-color-secondary, #6c757d)}.sc-eye .pi-eye{color:var(--text-color, #333)}.sc-eye:disabled{cursor:default;opacity:.5}.sc-gene-sort{display:flex;align-items:center;gap:.25rem;font-size:.8rem}.sc-gene-sort .sc-lbl{margin-right:auto}.sc-sort-btn{border:1px solid var(--surface-border, #ced4da);background:var(--surface-0, #fff);color:var(--text-color, #333);border-radius:4px;padding:.1rem .5rem;font:inherit;cursor:pointer}.sc-sort-btn.active{border-color:var(--primary-color, #2196f3);color:var(--primary-color, #2196f3);font-weight:600}.sc-gene-filter{width:calc(100% - 1rem);margin:.2rem 0 .2rem 1rem;font-size:.8rem;padding:.2rem .4rem}.sc-gene-footer{text-align:right;font-size:.78rem;padding:.2rem 0;color:var(--text-color-secondary, #6c757d)}.sc-gene-count{margin-left:auto;font-variant-numeric:tabular-nums;opacity:.8;padding-left:.5rem}\n"] }]
358
358
  }], ctorParameters: () => [{ type: i0.NgZone }, { type: i0.ChangeDetectorRef }], propDecorators: { controls: [{
359
359
  type: Input
360
360
  }], dataset: [{
@@ -366,4 +366,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImpor
366
366
  }], geneTotal: [{
367
367
  type: Input
368
368
  }] } });
369
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BhdGlhbC1nZW5lLXRyZWUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9zcGF0aWFsLWNvbnRyb2xzL3NwYXRpYWwtZ2VuZS10cmVlL3NwYXRpYWwtZ2VuZS10cmVlLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3NyYy9saWIvc3BhdGlhbC1jb250cm9scy9zcGF0aWFsLWdlbmUtdHJlZS9zcGF0aWFsLWdlbmUtdHJlZS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsS0FBSyxFQUNMLE1BQU0sR0FHUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUMzQyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDcEQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDMUQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBSWhELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQztBQUNwRSxPQUFPLEVBQUUsb0JBQW9CLEVBQXlDLE1BQU0sK0JBQStCLENBQUM7QUFDNUcsT0FBTyxFQUFFLDJCQUEyQixFQUFFLGNBQWMsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQzdGLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxlQUFlLEVBQUUsYUFBYSxFQUFFLGVBQWUsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ2pILE9BQU8sRUFBZ0IsYUFBYSxFQUFFLFdBQVcsRUFBRSxZQUFZLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUMzRyxPQUFPLEVBQUUsY0FBYyxFQUFFLGNB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QUF5Qjs7MkZBTWhCLHdCQUF3QjtrQkFmcEMsU0FBUzsrQkFDRSxtQkFBbUIsY0FDakIsSUFBSSxXQUNQO3dCQUNQLFlBQVk7d0JBQ1osWUFBWTt3QkFDWixlQUFlO3dCQUNmLGtCQUFrQjt3QkFDbEIsYUFBYTt3QkFDYix5QkFBeUI7cUJBQzFCLG1CQUdnQix1QkFBdUIsQ0FBQyxNQUFNOzJHQUl0QyxRQUFRO3NCQUFoQixLQUFLO2dCQUVHLE9BQU87c0JBQWYsS0FBSztnQkFFRyxJQUFJO3NCQUFaLEtBQUs7Z0JBRUcsVUFBVTtzQkFBbEIsS0FBSztnQkFFRyxTQUFTO3NCQUFqQixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIElucHV0LFxuICBOZ1pvbmUsXG4gIE9uQ2hhbmdlcyxcbiAgU2ltcGxlQ2hhbmdlcyxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgU2hhcmVkTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9hcGknO1xuaW1wb3J0IHsgSW5wdXRUZXh0TW9kdWxlIH0gZnJvbSAncHJpbWVuZy9pbnB1dHRleHQnO1xuaW1wb3J0IHsgT3ZlcmxheVBhbmVsTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9vdmVybGF5cGFuZWwnO1xuaW1wb3J0IHsgVG9vbHRpcE1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvdG9vbHRpcCc7XG5cbmltcG9ydCB0eXBlIHsgSVNwYXRpYWxDb250cm9scyB9IGZyb20gJy4uLy4uL2NvbnRyYWN0cy92aXN1YWxpemVyLmNvbnRyYWN0JztcbmltcG9ydCB0eXBlIHsgU3BhdGlhbERhdGFzZXQgfSBmcm9tICcuLi8uLi9jb250cmFjdHMvc3BhdGlhbC1kYXRhc2V0LmNvbnRyYWN0JztcbmltcG9ydCB7IEFMTF9HRU5FUyB9IGZyb20gJy4uLy4uL2NvbnRyYWN0cy9wb3J0cy9zcGF0aWFsLWRhdGEucG9ydCc7XG5pbXBvcnQgeyBERUZBVUxUX1NQQVRJQUxfVklFVywgU3BhdGlhbFZpZXdTdGF0ZSwgVHJhbnNjcmlwdEdseXBoTmFtZSB9IGZyb20gJy4uLy4uL2NvbnRyYWN0cy9kaXNwbGF5LXR5cGVzJztcbmltcG9ydCB7IERFRkFVTFRfQ0FURUdPUklDQUxfUEFMRVRURSwgZ3JvdXBDb2xvcnNLZXkgfSBmcm9tICcuLi8uLi9zcGF0aWFsL3NwYXRpYWwtZW5jb2RpbmcnO1xuaW1wb3J0IHsgY2VsbFR5cGVDb2x1bW5Gb3IsIGNsdXN0ZXJDb2xvck1hcCwgY2x1c3Rlck9mR2VuZSwgZGVmYXVsdEdseXBoRm9yIH0gZnJvbSAnLi4vLi4vc3BhdGlhbC9zcGF0aWFsLXRpbGVzJztcbmltcG9ydCB7IEdlbmVUcmVlTm9kZSwgYnVpbGRHZW5lVHJlZSwgZ2x5cGhQb2ludHMsIHRvZ2dsZUhpZGRlbiB9IGZyb20gJy4uLy4uL3NwYXRpYWwvc3BhdGlhbC1wYW5lbC1tb2RlbCc7XG5pbXBvcnQgeyBhbGxHZW5lU2hvd25CeSwgYWxsR2VuZXNIaWRkZW4sIHRvZ2dsZUFsbEdlbmVIaWRkZW4gfSBmcm9tICcuLi8uLi9zcGF0aWFsL3NwYXRpYWwtdGlsZS1tZXJnZSc7XG5pbXBvcnQgeyBTdXBlcnNlZGUgfSBmcm9tICcuLi8uLi91dGlsL3N1cGVyc2VkZSc7XG5pbXBvcnQgeyBTcGF0aWFsR2VuZVN0eWxlQ29tcG9uZW50IH0gZnJvbSAnLi4vc3BhdGlhbC1nZW5lLXN0eWxlL3NwYXRpYWwtZ2VuZS1zdHlsZS5jb21wb25lbnQnO1xuXG4vKiogUm93cyBvZiB0aGUgYWxsLWdlbmVzIGxpc3QgZHJhd24gYXQgb25jZTsgdGhlIGZpbHRlciBuYXJyb3dzIHRoZSByZXN0LiAqL1xuY29uc3QgQUxMX0dFTkVTX1JPV1MgPSAyMDA7XG5cbi8qKiBIb3cgdGhlIGdlbmUgcm93cyBhcmUgb3JkZXJlZDogYnkgbmFtZSwgb3IgYnkgdGhlaXIgdHJhbnNjcmlwdHMgaW4gdmlldywgbW9zdCBmaXJzdC4gKi9cbmV4cG9ydCB0eXBlIEdlbmVTb3J0ID0gJ25hbWUnIHwgJ2NvdW50JztcblxuLyoqIE5hbWVzIGluIHJlYWRpbmcgb3JkZXI6IGNhc2UgYXNpZGUsIGFuZCBgRzlgIGJlZm9yZSBgRzEwYC4gKi9cbmNvbnN0IGJ5TmFtZSA9IChhOiBzdHJpbmcsIGI6IHN0cmluZyk6IG51bWJlciA9PlxuICBhLmxvY2FsZUNvbXBhcmUoYiwgdW5kZWZpbmVkLCB7IG51bWVyaWM6IHRydWUsIHNlbnNpdGl2aXR5OiAnYmFzZScgfSk7XG5cbi8qKiBPbmUgZ2VuZSByb3cgYXMgdGhlIHRlbXBsYXRlIGRyYXdzIGl0LCBkZXJpdmVkIG9uY2UgcGVyIGlucHV0IGNoYW5nZS4gKi9cbmludGVyZmFjZSBHZW5lUm93VmlldyB7XG4gIHNob3duOiBib29sZWFuO1xuICBzd2F0Y2g6IHN0cmluZztcbiAgLyoqIFRoZSByb3cncyBnbHlwaCBvdXRsaW5lIChkcmF3biBpbiBJY29ucyBtb2RlKS4gKi9cbiAgcG9pbnRzOiBzdHJpbmc7XG4gIC8qKiBUcmFuc2NyaXB0cyBpbiB2aWV3LCBvciBudWxsIGJlZm9yZSB0aGUgcmVuZGVyZXIgcmVwb3J0cyBhbnkuICovXG4gIGNvdW50OiBudW1iZXIgfCBudWxsO1xufVxuXG4vKiogT25lIHJvdyBvZiB0aGUgYWxsLWdlbmVzIGxpc3QuICovXG5pbnRlcmZhY2UgQWxsR2VuZVJvd1ZpZXcge1xuICBnZW5lOiBzdHJpbmc7XG4gIHNob3duOiBib29sZWFuO1xuICAvKiogSXRzIGNvbG91ciB3aGVuIGNvbG91cmVkIGJ5IGdlbmUsIG9yIG51bGwgd2hlbiB0aGUgZGF0YXNldCdzIGNvZGUgb3JkZXIgaXMgdW5rbm93bi4gKi9cbiAgc3dhdGNoOiBzdHJpbmcgfCBudWxsO1xuICAvKiogSXRzIGNvZGUgaW4gdGhlIGRhdGFzZXQncyBnZW5lIGxpc3QgKHdoYXQgaXRzIHBhbGV0dGUgY29sb3VyIGlzIHBpY2tlZCBieSkuICovXG4gIGNvZGU6IG51bWJlcjtcbiAgY291bnQ6IG51bWJlciB8IG51bGw7XG59XG5cbi8qKlxuICogVGhlIHNlbGVjdGVkIHRyYW5zY3JpcHQgZ2VuZXMgYXMgWGVuaXVtIEV4cGxvcmVyJ3MgdHJlZTogdGhlIGdlbmUgZ3JvdXBzLCB0aGVuIHRoZVxuICogdW5ncm91cGVkIGdlbmVzLCBlYWNoIHJvdyB3aXRoIGFuIGV5ZSB0aGF0IGhpZGVzIGl0IHdpdGhvdXQgZGVzZWxlY3RpbmcgaXQsIGl0cyBtYXJrZXJcbiAqIGluIGl0cyBjb2xvdXIgKG9wZW5pbmcgb25lIGljb24tYW5kLWNvbG91ciBwaWNrZXIgcGVyIGdlbmUpLCBhbmQgaXRzIHRyYW5zY3JpcHQgY291bnQgaW5cbiAqIHZpZXcuIFdpdGggXCJBbGwgZ2VuZXNcIiBvbiwgdGhlIHJvb3QgZXllIGhpZGVzIG9yIHNob3dzIGV2ZXJ5IHRyYW5zY3JpcHQgYW5kIHRoZSByb290XG4gKiBleHBhbmRzIHRvIGV2ZXJ5IGdlbmUgb2YgdGhlIGRhdGFzZXQsIGVhY2ggd2l0aCBpdHMgZXllIHdoZW4gdGhlIGRhdGFzZXQgbGlzdHMgaXRzIGdlbmVzXG4gKiBpbiBjb2RlIG9yZGVyIChgdHJhbnNjcmlwdFRpbGVzLmdlbmVzYCksIGZpbHRlcmVkIGJ5IG5hbWUgcGFzdCBhIGZldyBodW5kcmVkLlxuICpcbiAqIEJvdGggbGlzdHMgYXJlIG9yZGVyZWQgYnkgbmFtZSwgb3IgYnkgdGhlaXIgdHJhbnNjcmlwdHMgaW4gdmlldywgbW9zdCBmaXJzdCAodGhlXG4gKiBzb3J0IHN3aXRjaCwgb2ZmZXJlZCBvbmNlIHRoZSByZW5kZXJlciByZXBvcnRzIGNvdW50cykuIFRoZSBhbGwtZ2VuZXMgbGlzdCBpcyBzb3J0ZWRcbiAqIGJlZm9yZSBpdCBpcyBjdXQgdG8gaXRzIGZpcnN0IHJvd3MsIHNvIGJ5IGNvdW50IHRob3NlIGFyZSB0aGUgZ2VuZXMgd2l0aCB0aGUgbW9zdFxuICogdHJhbnNjcmlwdHMgaW4gdmlldy5cbiAqXG4gKiBXcml0ZXMgb25seSB0aHJvdWdoIGBjb250cm9scy5zZXRWaWV3U3RhdGVgLlxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdzcGF0aWFsLWdlbmUtdHJlZScsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtcbiAgICBDb21tb25Nb2R1bGUsXG4gICAgU2hhcmVkTW9kdWxlLFxuICAgIElucHV0VGV4dE1vZHVsZSxcbiAgICBPdmVybGF5UGFuZWxNb2R1bGUsXG4gICAgVG9vbHRpcE1vZHVsZSxcbiAgICBTcGF0aWFsR2VuZVN0eWxlQ29tcG9uZW50LFxuICBdLFxuICB0ZW1wbGF0ZVVybDogJy4vc3BhdGlhbC1nZW5lLXRyZWUuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9zcGF0aWFsLWdlbmUtdHJlZS5jb21wb25lbnQuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgU3BhdGlhbEdlbmVUcmVlQ29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzIHtcbiAgLyoqIFRoZSBzcGF0aWFsIGNvbnRyb2xzIHRoaXMgcGFuZWwgcmVhZHMgYW5kIHdyaXRlcyB0aHJvdWdoOyBudWxsIHdpdGhvdXQgYSBgU1BBVElBTF9EQVRBX1BPUlRgLiAqL1xuICBASW5wdXQoKSBjb250cm9sczogSVNwYXRpYWxDb250cm9scyB8IG51bGwgPSBudWxsO1xuICAvKiogVGhlIGRhdGFzZXQgb24gb2ZmZXIsIG9yIG51bGwuICovXG4gIEBJbnB1dCgpIGRhdGFzZXQ6IFNwYXRpYWxEYXRhc2V0IHwgbnVsbCA9IG51bGw7XG4gIC8qKiBUaGUgY3VycmVudCBzcGF0aWFsIHZpZXcgc3RhdGU6IHdoYXQgaXMgZHJhd24sIGFuZCBob3cuICovXG4gIEBJbnB1dCgpIHZpZXc6IFNwYXRpYWxWaWV3U3RhdGUgPSBERUZBVUxUX1NQQVRJQUxfVklFVztcbiAgLyoqIFRyYW5zY3JpcHRzIG9mIGVhY2ggc2VsZWN0ZWQgZ2VuZSBpbiB0aGUgY3VycmVudCB2aWV3LCBmcm9tIHRoZSByZW5kZXJlci4gKi9cbiAgQElucHV0KCkgZ2VuZUNvdW50czogUmVjb3JkPHN0cmluZywgbnVtYmVyPiB8IG51bGwgPSBudWxsO1xuICAvKiogUmVhbCBnZW5lcyBpbiB0aGUgcGFuZWwg4oCUIHRoZSB0cmVlJ3MgZGVub21pbmF0b3IuICovXG4gIEBJbnB1dCgpIGdlbmVUb3RhbCA9IDA7XG5cbiAgLyoqIFN3YXRjaGVzIGluIHRoZSBwaWNrZXI6IHRoZSBjYXRlZ29yaWNhbCBwYWxldHRlIGdlbmVzIGFyZSBjb2xvdXJlZCBmcm9tIGJ5IGRlZmF1bHQuICovXG5cbiAgLyoqIFRoZSB0cmVlLCByZWJ1aWx0IHdoZW4gdGhlIHZpZXcgY2hhbmdlcyDigJQgbmV2ZXIgcGVyIGNoYW5nZS1kZXRlY3Rpb24gcGFzcy4gKi9cbiAgcHJvdGVjdGVkIGdlbmVUcmVlOiBHZW5lVHJlZU5vZGVbXSA9IFtdO1xuICAvKioge0BsaW5rIGdlbmVUcmVlfSB3aXRoIGVhY2ggbm9kZSdzIGdlbmVzIGluIHtAbGluayBnZW5lU29ydH0gb3JkZXI6IHdoYXQgdGhlIHRlbXBsYXRlIGRyYXdzLiAqL1xuICBwcm90ZWN0ZWQgc29ydGVkVHJlZTogR2VuZVRyZWVOb2RlW10gPSBbXTtcbiAgLyoqIFRoZSByb3dzJyBvcmRlci4gQnkgY291bnQgb25seSB3aGlsZSB0aGUgcmVuZGVyZXIgcmVwb3J0cyBjb3VudHMgKHNlZSB7QGxpbmsgc29ydFNob3dufSkuICovXG4gIHByb3RlY3RlZCBnZW5lU29ydDogR2VuZVNvcnQgPSAnbmFtZSc7XG4gIC8qKiBQZXIgZ2VuZTogaXRzIGV5ZSwgc3dhdGNoLCBnbHlwaCBhbmQgY291bnQg4oCUIHJlYnVpbHQgd2l0aCB0aGUgaW5wdXRzIChhbmQgd2hlbiB0aGVcbiAgICogIGNlbGxzJyBncm91cCBjb2xvdXJzIGFycml2ZSksIHNvIHRoZSB0ZW1wbGF0ZSBkb2VzIG5vIHBlci1yb3cgbG9va3VwcyBwZXIgY2hlY2suICovXG4gIHByb3RlY3RlZCByb3dzID0gbmV3IE1hcDxzdHJpbmcsIEdlbmVSb3dWaWV3PigpO1xuICAvKiogUGVyIG5hbWVkIGdyb3VwLCBhbmQgZm9yIHRoZSByb290OiB3aGV0aGVyIGFueSBvZiBpdHMgZ2VuZXMgaXMgc2hvd24uICovXG4gIHByb3RlY3RlZCBncm91cFNob3duID0gbmV3IE1hcDxzdHJpbmcsIGJvb2xlYW4+KCk7XG4gIHByb3RlY3RlZCByb290U2hvd24gPSBmYWxzZTtcbiAgcHJvdGVjdGVkIGNvbGxhcHNlZEdlbmVHcm91cHMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgcHJvdGVjdGVkIGdlbmVUcmVlT3BlbiA9IHRydWU7XG4gIC8qKiBUaGUgYWxsLWdlbmVzIGxpc3Qgc3RhcnRzIGNsb3NlZDogaXQgY2FuIHJ1biB0byB0aG91c2FuZHMgb2YgZ2VuZXMuICovXG4gIHByb3RlY3RlZCBhbGxHZW5lc09wZW4gPSBmYWxzZTtcbiAgLyoqIFRoZSBnZW5lcyBcIkFsbCBnZW5lc1wiIGxpc3RzLCBvciBudWxsIHdoZW4gdGhlIGRhdGFzZXQgbmFtZXMgbm9uZS4gKi9cbiAgcHJvdGVjdGVkIGFsbEdlbmVMaXN0OiByZWFkb25seSBzdHJpbmdbXSB8IG51bGwgPSBudWxsO1xuICAvKiogV2hldGhlciBhIGdlbmUgb2YgXCJBbGwgZ2VuZXNcIiBjYW4gYmUgaGlkZGVuOiB0aGUgZGF0YXNldCBsaXN0cyBpdHMgZ2VuZXMgaW4gY29kZSBvcmRlci4gKi9cbiAgcHJvdGVjdGVkIGNhbkhpZGVBbGxHZW5lcyA9IGZhbHNlO1xuICBwcm90ZWN0ZWQgYWxsR2VuZXNGaWx0ZXIgPSAnJztcbiAgLyoqIFRoZSBsaXN0J3Mgcm93cyBtYXRjaGluZyB0aGUgZmlsdGVyLCBhdCBtb3N0IHtAbGluayBBTExfR0VORVNfUk9XU30uICovXG4gIHByb3RlY3RlZCBhbGxSb3dzOiBBbGxHZW5lUm93Vmlld1tdID0gW107XG4gIC8qKiBIb3cgbWFueSBnZW5lcyBtYXRjaCB0aGUgZmlsdGVyLCBmb3IgdGhlIFwic2hvd2luZyBuIG9mIG1cIiBsaW5lLiAqL1xuICBwcm90ZWN0ZWQgYWxsR2VuZXNNYXRjaGVkID0gMDtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGFsbEdlbmVzUm93Q2FwID0gQUxMX0dFTkVTX1JPV1M7XG4gIC8qKiBUaGUgZ2VuZSB0aGUgb3BlbiBwaWNrZXIgZWRpdHMuICovXG4gIHByb3RlY3RlZCBzdHlsZUdlbmU6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuXG4gIC8qKiBDb2xvdXJzIG9mIHRoZSBjZWxscycgZ3JvdXBzLCBieSBuYW1lIOKAlCB3aGF0IGEgY2x1c3RlciBvZiB0aGUgc2FtZSBuYW1lIGlzIGRyYXduIGluLiAqL1xuICBwcml2YXRlIGNlbGxHcm91cENvbG9ycyA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KCk7XG4gIC8qKiBUaGUgZ3JvdXBpbmcge0BsaW5rIGNlbGxHcm91cENvbG9yc30gYmVsb25ncyB0byDigJQgYSByZXBlYXQgcmVxdWVzdCBmb3IgaXQgaXMgYSBuby1vcC4gKi9cbiAgcHJpdmF0ZSBjZWxsR3JvdXBDb2xvcnNGb3I6IHN0cmluZyB8IG51bGwgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gIC8qKiBMYXRlc3Qgd2lucyBhbW9uZyBjb2xvdXIgbG9hZHMgZm9yIHtAbGluayBjZWxsR3JvdXBDb2xvcnN9LiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IGNlbGxHcm91cENvbG9yc0xvYWQgPSBuZXcgU3VwZXJzZWRlKCk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSB6b25lOiBOZ1pvbmUsXG4gICAgcHJpdmF0ZSByZWFkb25seSBjZHI6IENoYW5nZURldGVjdG9yUmVmLFxuICApIHt9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGlmIChjaGFuZ2VzWyd2aWV3J10pIHRoaXMuZ2VuZVRyZWUgPSBidWlsZEdlbmVUcmVlKHRoaXMudmlldy50cmFuc2NyaXB0R2VuZXMsIHRoaXMudmlldy50cmFuc2NyaXB0R2VuZUdyb3Vwcyk7XG4gICAgLy8gQSBzYW1lLW5hbWVkIGdyb3VwaW5nIG9mIGEgbmV3IGRhdGFzZXQgaXMgbm90IHRoZSBvbGQgb25lLlxuICAgIGlmIChjaGFuZ2VzWydkYXRhc2V0J10pIHtcbiAgICAgIHRoaXMuY2VsbEdyb3VwQ29sb3JzRm9yID0gdW5kZWZpbmVkO1xuICAgICAgY29uc3QgY29kZWQgPSB0aGlzLmRhdGFzZXQ/LnRyYW5zY3JpcHRUaWxlcz8uZ2VuZXM7XG4gICAgICB0aGlzLmNhbkhpZGVBbGxHZW5lcyA9ICEhY29kZWQ/Lmxlbmd0aDtcbiAgICAgIHRoaXMuYWxsR2VuZUxpc3QgPSBjb2RlZD8ubGVuZ3RoID8gY29kZWQgOiAodGhpcy5kYXRhc2V0Py5mZWF0dXJlcz8ubmFtZXMgPz8gbnVsbCk7XG4gICAgfVxuICAgIHRoaXMucmVidWlsZFJvd3MoKTtcbiAgICB2b2lkIHRoaXMucmVmcmVzaENlbGxHcm91cENvbG9ycygpO1xuICB9XG5cbiAgcHJpdmF0ZSByZWJ1aWxkUm93cygpOiB2b2lkIHtcbiAgICBjb25zdCBnZW5lcyA9IHRoaXMudmlldy50cmFuc2NyaXB0R2VuZXM7XG4gICAgdGhpcy5yb3dzID0gbmV3IE1hcChcbiAgICAgIGdlbmVzLm1hcCgoZ2VuZSwgc2xvdCkgPT4gW1xuICAgICAgICBnZW5lLFxuICAgICAgICB7XG4gICAgICAgICAgc2hvd246IHRoaXMuaXNHZW5lU2hvd24oZ2VuZSksXG4gICAgICAgICAgc3dhdGNoOiB0aGlzLmdlbmVTd2F0Y2hPZihnZW5lKSxcbiAgICAgICAgICBwb2ludHM6IGdseXBoUG9pbnRzKHRoaXMuZ2x5cGhPZihnZW5lLCBzbG90KSksXG4gICAgICAgICAgY291bnQ6IHRoaXMuZ2VuZUNvdW50T2YoZ2VuZSksXG4gICAgICAgIH0sXG4gICAgICBdKSxcbiAgICApO1xuICAgIHRoaXMuZ3JvdXBTaG93biA9IG5ldyBNYXAoXG4gICAgICB0aGlzLmdlbmVUcmVlXG4gICAgICAgIC5maWx0ZXIoKG5vZGUpID0+IG5vZGUubmFtZSlcbiAgICAgICAgLm1hcCgobm9kZSkgPT4gW25vZGUubmFtZSBhcyBzdHJpbmcsIHRoaXMuYXJlR2VuZXNTaG93bihub2RlLmdlbmVzKV0pLFxuICAgICk7XG4gICAgdGhpcy5yb290U2hvd24gPSB0aGlzLnZpZXcudHJhbnNjcmlwdEFsbEdlbmVzID8gdGhpcy5hbnlPZkFsbEdlbmVzU2hvd24oKSA6IHRoaXMuYXJlR2VuZXNTaG93bihnZW5lcyk7XG4gICAgdGhpcy5zb3J0ZWRUcmVlID0gdGhpcy5nZW5lVHJlZS5tYXAoKG5vZGUpID0+ICh7IC4uLm5vZGUsIGdlbmVzOiB0aGlzLnNvcnRlZChub2RlLmdlbmVzKSB9KSk7XG4gICAgdGhpcy5yZWJ1aWxkQWxsUm93cygpO1xuICB9XG5cbiAgLyoqIFdoZXRoZXIgdGhlIHJvd3MgYXJlIG9yZGVyZWQgYnkgY291bnQ6IGNob3NlbiwgYW5kIGNvdW50cyB0byBvcmRlciBieS4gKi9cbiAgcHJvdGVjdGVkIGdldCBieUNvdW50KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmdlbmVTb3J0ID09PSAnY291bnQnICYmICEhdGhpcy5nZW5lQ291bnRzO1xuICB9XG5cbiAgLyoqIFRoZSBzb3J0IHN3aXRjaCBpcyBvZmZlcmVkIG9uY2UgdGhlcmUgYXJlIGNvdW50cyB0byBzb3J0IGJ5LiAqL1xuICBwcm90ZWN0ZWQgZ2V0IHNvcnRTaG93bigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISF0aGlzLmdlbmVDb3VudHM7XG4gIH1cblxuICBwcm90ZWN0ZWQgb25HZW5lU29ydChzb3J0OiBHZW5lU29ydCk6IHZvaWQge1xuICAgIGlmIChzb3J0ID09PSB0aGlzLmdlbmVTb3J0KSByZXR1cm47XG4gICAgdGhpcy5nZW5lU29ydCA9IHNvcnQ7XG4gICAgdGhpcy5yZWJ1aWxkUm93cygpO1xuICB9XG5cbiAgLyoqIGBnZW5lc2AgaW4gdGhlIHJvd3MnIG9yZGVyOiBieSBjb3VudCwgbW9zdCBmaXJzdCAodGllcyBieSBuYW1lKSwgZWxzZSBieSBuYW1lLiAqL1xuICBwcml2YXRlIHNvcnRlZChnZW5lczogcmVhZG9ubHkgc3RyaW5nW10pOiBzdHJpbmdbXSB7XG4gICAgaWYgKCF0aGlzLmJ5Q291bnQpIHJldHVybiBbLi4uZ2VuZXNdLnNvcnQoYnlOYW1lKTtcbiAgICBjb25zdCBjb3VudHMgPSB0aGlzLmdlbmVDb3VudHMgPz8ge307XG4gICAgcmV0dXJuIFsuLi5nZW5lc10uc29ydCgoYSwgYikgPT4gKGNvdW50c1tiXSA/PyAwKSAtIChjb3VudHNbYV0gPz8gMCkgfHwgYnlOYW1lKGEsIGIpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgYWxsLWdlbmVzIGxpc3QncyByb3dzOiB0aGUgZ2VuZXMgbWF0Y2hpbmcgdGhlIGZpbHRlciwgdXAgdG8gdGhlIGNhcC4gQnVpbHQgb25seSB3aGlsZVxuICAgKiB0aGUgbGlzdCBpcyBvcGVuOiB0aGUgY291bnRzIGluIHZpZXcgY2hhbmdlIHdpdGggZXZlcnkgcGFuLCBhbmQgdGhlIGxpc3QgY2FuIGJlIHRob3VzYW5kcy5cbiAgICovXG4gIHByaXZhdGUgcmVidWlsZEFsbFJvd3MoKTogdm9pZCB7XG4gICAgY29uc3QgbGlzdCA9IHRoaXMudmlldy50cmFuc2NyaXB0QWxsR2VuZXMgJiYgdGhpcy5hbGxHZW5lc09wZW4gPyB0aGlzLmFsbEdlbmVMaXN0IDogbnVsbDtcbiAgICBpZiAoIWxpc3QpIHtcbiAgICAgIHRoaXMuYWxsUm93cyA9IFtdO1xuICAgICAgdGhpcy5hbGxHZW5lc01hdGNoZWQgPSAwO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBuZWVkbGUgPSB0aGlzLmFsbEdlbmVzRmlsdGVyLnRyaW0oKS50b0xvd2VyQ2FzZSgpO1xuICAgIGNvbnN0IHNob3duID0gYWxsR2VuZVNob3duQnkodGhpcy52aWV3LnRyYW5zY3JpcHRBbGxHZW5lc0hpZGRlbik7XG4gICAgLy8gRXZlcnkgbWF0Y2gsIG9yZGVyZWQsIGFuZCBvbmx5IHRoZW4gY3V0OiBieSBjb3VudCB0aGUgZmlyc3Qgcm93cyBhcmUgdGhlIG1vc3QgYWJ1bmRhbnQuXG4gICAgY29uc3QgY29kZXMgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xuICAgIGxpc3QuZm9yRWFjaCgoZ2VuZSwgY29kZSkgPT4ge1xuICAgICAgLy8gQW4gZW1wdHkgbmFtZSBpcyBhIGNvZGUgbm8gdHJhbnNjcmlwdCBjYXJyaWVzIChhIGNvbnRyb2wgcHJvYmUpLlxuICAgICAgaWYgKCFnZW5lIHx8IChuZWVkbGUgJiYgIWdlbmUudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyhuZWVkbGUpKSkgcmV0dXJuO1xuICAgICAgaWYgKCFjb2Rlcy5oYXMoZ2VuZSkpIGNvZGVzLnNldChnZW5lLCBjb2RlKTtcbiAgICB9KTtcbiAgICB0aGlzLmFsbFJvd3MgPSB0aGlzLnNvcnRlZChbLi4uY29kZXMua2V5cygpXSlcbiAgICAgIC5zbGljZSgwLCBBTExfR0VORVNfUk9XUylcbiAgICAgIC5tYXAoKGdlbmUpID0+ICh7XG4gICAgICAgIGdlbmUsXG4gICAgICAgIHNob3duOiBzaG93bihnZW5lKSxcbiAgICAgICAgc3dhdGNoOiB0aGlzLmNhbkhpZGVBbGxHZW5lcyA/IHRoaXMuYWxsR2VuZUNvbG9yT2YoZ2VuZSwgY29kZXMuZ2V0KGdlbmUpISkgOiBudWxsLFxuICAgICAgICBjb2RlOiBjb2Rlcy5nZXQoZ2VuZSkhLFxuICAgICAgICBjb3VudDogdGhpcy5nZW5lQ291bnRPZihnZW5lKSxcbiAgICAgIH0pKTtcbiAgICB0aGlzLmFsbEdlbmVzTWF0Y2hlZCA9IGNvZGVzLnNpemU7XG4gIH1cblxuICAvKiogV2hldGhlciBcIkFsbCBnZW5lc1wiIGRyYXdzIGFueXRoaW5nOiBub3Qgc3dpdGNoZWQgb2ZmIHdob2xlLCBub3IgZXZlcnkgbGlzdGVkIGdlbmUgaGlkZGVuLiAqL1xuICBwcml2YXRlIGFueU9mQWxsR2VuZXNTaG93bigpOiBib29sZWFuIHtcbiAgICBpZiAoYWxsR2VuZXNIaWRkZW4odGhpcy52aWV3KSkgcmV0dXJuIGZhbHNlO1xuICAgIGlmICghdGhpcy5jYW5IaWRlQWxsR2VuZXMgfHwgIXRoaXMuYWxsR2VuZUxpc3QpIHJldHVybiB0cnVlO1xuICAgIGNvbnN0IHNob3duID0gYWxsR2VuZVNob3duQnkodGhpcy52aWV3LnRyYW5zY3JpcHRBbGxHZW5lc0hpZGRlbik7XG4gICAgcmV0dXJuIHRoaXMuYWxsR2VuZUxpc3Quc29tZSgoZykgPT4gZyAmJiBzaG93bihnKSk7XG4gIH1cblxuICAvKiogQSBnZW5lIG9mIFwiQWxsIGdlbmVzXCIgaW4gaXRzIGNvbG91ciBieSBnZW5lOiBpdHMgY2hvc2VuIG9uZSwgZWxzZSB0aGUgcGFsZXR0ZSdzIGJ5IGNvZGUuICovXG4gIHByaXZhdGUgYWxsR2VuZUNvbG9yT2YoZ2VuZTogc3RyaW5nLCBjb2RlOiBudW1iZXIpOiBzdHJpbmcge1xuICAgIHJldHVybiAoXG4gICAgICB0aGlzLnZpZXcudHJhbnNjcmlwdEdlbmVDb2xvcnNbZ2VuZV0gfHxcbiAgICAgIERFRkFVTFRfQ0FURUdPUklDQUxfUEFMRVRURVtjb2RlICUgREVGQVVMVF9DQVRFR09SSUNBTF9QQUxFVFRFLmxlbmd0aF1cbiAgICApO1xuICB9XG5cbiAgcHJvdGVjdGVkIHRvZ2dsZUFsbEdlbmVzT3BlbigpOiB2b2lkIHtcbiAgICB0aGlzLmFsbEdlbmVzT3BlbiA9ICF0aGlzLmFsbEdlbmVzT3BlbjtcbiAgICB0aGlzLnJlYnVpbGRBbGxSb3dzKCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgb25BbGxHZW5lc0ZpbHRlcih0ZXh0OiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmFsbEdlbmVzRmlsdGVyID0gdGV4dDtcbiAgICB0aGlzLnJlYnVpbGRBbGxSb3dzKCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgdG9nZ2xlR2VuZUdyb3VwKG5hbWU6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IG5leHQgPSBuZXcgU2V0KHRoaXMuY29sbGFwc2VkR2VuZUdyb3Vwcyk7XG4gICAgaWYgKG5leHQuaGFzKG5hbWUpKSBuZXh0LmRlbGV0ZShuYW1lKTtcbiAgICBlbHNlIG5leHQuYWRkKG5hbWUpO1xuICAgIHRoaXMuY29sbGFwc2VkR2VuZUdyb3VwcyA9IG5leHQ7XG4gIH1cblxuICBwcm90ZWN0ZWQgaXNHZW5lU2hvd24oZ2VuZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICF0aGlzLnZpZXcudHJhbnNjcmlwdEhpZGRlbkdlbmVzLmluY2x1ZGVzKGdlbmUpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFyZUdlbmVzU2hvd24oZ2VuZXM6IHN0cmluZ1tdKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGdlbmVzLnNvbWUoKGcpID0+IHRoaXMuaXNHZW5lU2hvd24oZykpO1xuICB9XG5cbiAgLyoqIFRoZSBleWUgdG9nZ2xlOiBoaWRlIG9yIHNob3cgZ2VuZXMgd2l0aG91dCByZW1vdmluZyB0aGVtIGZyb20gdGhlIHNlbGVjdGlvbi4gKi9cbiAgcHJvdGVjdGVkIG9uR2VuZXNTaG93bihnZW5lczogc3RyaW5nW10sIG9uOiBib29sZWFuKTogdm9pZCB7XG4gICAgdGhpcy5jb250cm9scz8uc2V0Vmlld1N0YXRlKHtcbiAgICAgIHRyYW5zY3JpcHRIaWRkZW5HZW5lczogdG9nZ2xlSGlkZGVuKHRoaXMudmlldy50cmFuc2NyaXB0SGlkZGVuR2VuZXMsIGdlbmVzLCBvbiksXG4gICAgfSk7XG4gIH1cblxuICAvKiogVGhlIHJvb3QgZXllIHdoaWxlIGV2ZXJ5IGdlbmUgaXMgZHJhd246IGhpZGUgb3Igc2hvdyB0aGVtIGFsbCAodGhlICfCsScgbGVhdmVzIFwiQWxsIGdlbmVzXCIpLiAqL1xuICBwcm90ZWN0ZWQgb25BbGxHZW5lc1Nob3duKG9uOiBib29sZWFuKTogdm9pZCB7XG4gICAgdGhpcy5jb250cm9scz8uc2V0Vmlld1N0YXRlKHsgdHJhbnNjcmlwdEFsbEdlbmVzSGlkZGVuOiBvbiA/IFtdIDogW0FMTF9HRU5FU10gfSk7XG4gIH1cblxuICAvKiogT25lIGdlbmUncyBleWUgaW4gdGhlIGFsbC1nZW5lcyBsaXN0LiBTaG93aW5nIG9uZSB3aGlsZSBhbGwgYXJlIG9mZiBzaG93cyBpdCBhbG9uZS4gKi9cbiAgcHJvdGVjdGVkIG9uQWxsR2VuZVNob3duKGdlbmU6IHN0cmluZywgb246IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuY2FuSGlkZUFsbEdlbmVzKSByZXR1cm47XG4gICAgdGhpcy5jb250cm9scz8uc2V0Vmlld1N0YXRlKHtcbiAgICAgIHRyYW5zY3JpcHRBbGxHZW5lc0hpZGRlbjogdG9nZ2xlQWxsR2VuZUhpZGRlbih0aGlzLnZpZXcudHJhbnNjcmlwdEFsbEdlbmVzSGlkZGVuLCBnZW5lLCBvbiksXG4gICAgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgb25HZW5lQ29sb3IoZ2VuZTogc3RyaW5nLCBoZXg6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuY29udHJvbHM/LnNldFZpZXdTdGF0ZSh7IHRyYW5zY3JpcHRHZW5lQ29sb3JzOiB7IC4uLnRoaXMudmlldy50cmFuc2NyaXB0R2VuZUNvbG9ycywgW2dlbmVdOiBoZXggfSB9KTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBwZXItZ2VuZSBpY29uIGFuZCBjb2xvdXIgcGlja2VyIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIHByb3RlY3RlZCBvcGVuR2VuZVN0eWxlKGV2ZW50OiBFdmVudCwgZ2VuZTogc3RyaW5nLCBwYW5lbDogeyB0b2dnbGUoZTogRXZlbnQpOiB2b2lkOyBoaWRlKCk6IHZvaWQgfSk6IHZvaWQge1xuICAgIGlmICh0aGlzLnN0eWxlR2VuZSA9PT0gZ2VuZSkge1xuICAgICAgcGFuZWwudG9nZ2xlKGV2ZW50KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5zdHlsZUdlbmUgPSBnZW5lO1xuICAgIHBhbmVsLmhpZGUoKTtcbiAgICAvLyBSZS1vcGVuIGFuY2hvcmVkIG9uIHRoZSByb3cgdGhhdCB3YXMgY2xpY2tlZCwgb25jZSB0aGUgcGFuZWwgaGFzIGNsb3NlZC5cbiAgICBzZXRUaW1lb3V0KCgpID0+IHBhbmVsLnRvZ2dsZShldmVudCkpO1xuICB9XG5cbiAgLyoqIFRoZSBpY29uIHRoZSBvcGVuIHBpY2tlciBzaG93cyBhcyBjaG9zZW4uICovXG4gIHByb3RlY3RlZCBnZXQgc3R5bGVHbHlwaCgpOiBUcmFuc2NyaXB0R2x5cGhOYW1lIHwgbnVsbCB7XG4gICAgY29uc3QgZ2VuZSA9IHRoaXMuc3R5bGVHZW5lO1xuICAgIHJldHVybiBnZW5lID8gdGhpcy5nbHlwaE9mKGdlbmUsIE1hdGgubWF4KDAsIHRoaXMudmlldy50cmFuc2NyaXB0R2VuZXMuaW5kZXhPZihnZW5lKSkpIDogbnVsbDtcbiAgfVxuXG4gIHByb3RlY3RlZCBnbHlwaFBvaW50cyhnbHlwaDogVHJhbnNjcmlwdEdseXBoTmFtZSk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGdseXBoUG9pbnRzKGdseXBoKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBnbHlwaE9mKGdlbmU6IHN0cmluZywgc2xvdDogbnVtYmVyKTogVHJhbnNjcmlwdEdseXBoTmFtZSB7XG4gICAgcmV0dXJuIHRoaXMudmlldy50cmFuc2NyaXB0R2x5cGhzW2dlbmVdID8/IGRlZmF1bHRHbHlwaEZvcihzbG90KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvbkdseXBoKGdlbmU6IHN0cmluZywgZ2x5cGg6IFRyYW5zY3JpcHRHbHlwaE5hbWUpOiB2b2lkIHtcbiAgICB0aGlzLmNvbnRyb2xzPy5zZXRWaWV3U3RhdGUoeyB0cmFuc2NyaXB0R2x5cGhzOiB7IC4uLnRoaXMudmlldy50cmFuc2NyaXB0R2x5cGhzLCBbZ2VuZV06IGdseXBoIH0gfSk7XG4gIH1cblxuICAvKiogQmFjayB0byB0aGUgZ2VuZSdzIGRlZmF1bHQgaWNvbiBhbmQgY29sb3VyIChieSBpdHMgcG9zaXRpb24gaW4gdGhlIGxpc3QpLiAqL1xuICBwcm90ZWN0ZWQgcmVzZXRHZW5lU3R5bGUoZ2VuZTogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgY29sb3JzID0geyAuLi50aGlzLnZpZXcudHJhbnNjcmlwdEdlbmVDb2xvcnMgfTtcbiAgICBjb25zdCBnbHlwaHMgPSB7IC4uLnRoaXMudmlldy50cmFuc2NyaXB0R2x5cGhzIH07XG4gICAgZGVsZXRlIGNvbG9yc1tnZW5lXTtcbiAgICBkZWxldGUgZ2x5cGhzW2dlbmVdO1xuICAgIHRoaXMuY29udHJvbHM/LnNldFZpZXdTdGF0ZSh7IHRyYW5zY3JpcHRHZW5lQ29sb3JzOiBjb2xvcnMsIHRyYW5zY3JpcHRHbHlwaHM6IGdseXBocyB9KTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBjb2xvdXJzIGFuZCBjb3VudHMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgLyoqIFRoZSBjb2xvdXIgZ2VuZSBgc2xvdGAgaXMgZHJhd24gaW4gd2hlbiB0cmFuc2NyaXB0cyBhcmUgY29sb3VyZWQgYnkgZ2VuZS4gKi9cbiAgZ2VuZUNvbG9yKHNsb3Q6IG51bWJlcik6IHN0cmluZyB7XG4gICAgY29uc3QgZ2VuZSA9IHRoaXMudmlldz8udHJhbnNjcmlwdEdlbmVzW3Nsb3RdO1xuICAgIHJldHVybiAoXG4gICAgICAoZ2VuZSAmJiB0aGlzLnZpZXcudHJhbnNjcmlwdEdlbmVDb2xvcnNbZ2VuZV0pIHx8XG4gICAgICBERUZBVUxUX0NBVEVHT1JJQ0FMX1BBTEVUVEVbc2xvdCAlIERFRkFVTFRfQ0FURUdPUklDQUxfUEFMRVRURS5sZW5ndGhdXG4gICAgKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZW5lQ29sb3JPZihnZW5lOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmdlbmVDb2xvcihNYXRoLm1heCgwLCB0aGlzLnZpZXcudHJhbnNjcmlwdEdlbmVzLmluZGV4T2YoZ2VuZSkpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgY29sb3VyIHRoZSBvcGVuIHBpY2tlciBzaG93czogd2l0aCBcIkFsbCBnZW5lc1wiLCB0aGUgZ2VuZSdzIGNvbG91ciBhbW9uZyBldmVyeSBnZW5lIChpdHNcbiAgICogY2hvc2VuIG9uZSwgZWxzZSB0aGUgcGFsZXR0ZSdzIGJ5IGl0cyBjb2RlKSwgYXMgaXRzIHJvdyBhbmQgaXRzIG1hcmtlcnMgaGF2ZSBpdC5cbiAgICovXG4gIHByb3RlY3RlZCBzdHlsZUNvbG9yT2YoZ2VuZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBpZiAodGhpcy52aWV3LnRyYW5zY3JpcHRBbGxHZW5lcykge1xuICAgICAgY29uc3Qgcm93ID0gdGhpcy5hbGxSb3dzLmZpbmQoKHIpID0+IHIuZ2VuZSA9PT0gZ2VuZSk7XG4gICAgICBpZiAocm93KSByZXR1cm4gdGhpcy5hbGxHZW5lQ29sb3JPZihnZW5lLCByb3cuY29kZSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmdlbmVDb2xvck9mKGdlbmUpO1xuICB9XG5cbiAgLyoqIEluIENsdXN0ZXIgY29sb3VyaW5nLCBhIGdlbmUncyBzd2F0Y2ggaXMgaXRzIGNsdXN0ZXIncyBjb2xvdXIsIGFzIGl0cyBtYXJrZXJzIGFyZS4gKi9cbiAgcHJvdGVjdGVkIGdlbmVTd2F0Y2hPZihnZW5lOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGlmICh0aGlzLnZpZXcudHJhbnNjcmlwdENvbG9yQnkgIT09ICdjbHVzdGVyJykgcmV0dXJuIHRoaXMuZ2VuZUNvbG9yT2YoZ2VuZSk7XG4gICAgcmV0dXJuIHRoaXMuY2x1c3RlckNvbG9ycygpLmdldChjbHVzdGVyT2ZHZW5lKGdlbmUsIHRoaXMudmlldy50cmFuc2NyaXB0R2VuZUdyb3VwcykpID8/IHRoaXMuZ2VuZUNvbG9yT2YoZ2VuZSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2VuZUNvdW50T2YoZ2VuZTogc3RyaW5nKTogbnVtYmVyIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuZ2VuZUNvdW50cyA/ICh0aGlzLmdlbmVDb3VudHNbZ2VuZV0gPz8gMCkgOiBudWxsO1xuICB9XG5cbiAgcHJvdGVjdGVkIHRyYWNrQnlOb2RlID0gKF9pOiBudW1iZXIsIG5vZGU6IHsgbmFtZTogc3RyaW5nIHwgbnVsbCB9KSA9PiBub2RlLm5hbWUgPz8gJyc7XG4gIHByb3RlY3RlZCB0cmFja0J5TGFiZWxTdHJpbmcgPSAoX2k6IG51bWJlciwgczogc3RyaW5nKSA9PiBzO1xuICBwcm90ZWN0ZWQgdHJhY2tCeUFsbFJvdyA9IChfaTogbnVtYmVyLCByb3c6IEFsbEdlbmVSb3dWaWV3KSA9PiByb3cuZ2VuZTtcblxuICAvKipcbiAgICogVGhlIGNsdXN0ZXIgY29sb3VycywgcmVidWlsdCBvbmx5IHdoZW4gd2hhdCB0aGV5IGNvbWUgZnJvbSBjaGFuZ2VzLiBUaGUgdGVtcGxhdGUgYXNrc1xuICAgKiBvbmNlIHBlciBnZW5lIHJvdyBwZXIgY2hhbmdlLWRldGVjdGlvbiBwYXNzLCBhbmQgcmVidWlsZGluZyBwZXIgY2FsbCBtYWRlIHRoYXQgTyhHwrIpLlxuICAgKi9cbiAgcHJpdmF0ZSBjbHVzdGVyQ29sb3JzKCk6IE1hcDxzdHJpbmcsIHN0cmluZz4ge1xuICAgIGNvbnN0IHsgdHJhbnNjcmlwdEdlbmVzOiBnZW5lcywgdHJhbnNjcmlwdEdlbmVHcm91cHM6IGdyb3VwcyB9ID0gdGhpcy52aWV3O1xuICAgIGNvbnN0IGhpdCA9IHRoaXMuY2x1c3RlckNvbG9yTWVtbztcbiAgICBpZiAoaGl0ICYmIGhpdC5nZW5lcyA9PT0gZ2VuZXMgJiYgaGl0Lmdyb3VwcyA9PT0gZ3JvdXBzICYmIGhpdC5jZWxsQ29sb3JzID09PSB0aGlzLmNlbGxHcm91cENvbG9ycykge1xuICAgICAgcmV0dXJuIGhpdC5jb2xvcnM7XG4gICAgfVxuICAgIGNvbnN0IGNvbG9ycyA9IGNsdXN0ZXJDb2xvck1hcChnZW5lcywgZ3JvdXBzLCB0aGlzLmNlbGxHcm91cENvbG9ycywgREVGQVVMVF9DQVRFR09SSUNBTF9QQUxFVFRFKTtcbiAgICB0aGlzLmNsdXN0ZXJDb2xvck1lbW8gPSB7IGdlbmVzLCBncm91cHMsIGNlbGxDb2xvcnM6IHRoaXMuY2VsbEdyb3VwQ29sb3JzLCBjb2xvcnMgfTtcbiAgICByZXR1cm4gY29sb3JzO1xuICB9XG4gIHByaXZhdGUgY2x1c3RlckNvbG9yTWVtbzoge1xuICAgIGdlbmVzOiBTcGF0aWFsVmlld1N0YXRlWyd0cmFuc2NyaXB0R2VuZXMnXTtcbiAgICBncm91cHM6IFNwYXRpYWxWaWV3U3RhdGVbJ3RyYW5zY3JpcHRHZW5lR3JvdXBzJ107XG4gICAgY2VsbENvbG9yczogTWFwPHN0cmluZywgc3RyaW5nPjtcbiAgICBjb2xvcnM6IE1hcDxzdHJpbmcsIHN0cmluZz47XG4gIH0gfCBudWxsID0gbnVsbDtcblxuICBwcml2YXRlIGFzeW5jIHJlZnJlc2hDZWxsR3JvdXBDb2xvcnMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgY29sdW1uID0gdGhpcy5kYXRhc2V0ID8gY2VsbFR5cGVDb2x1bW5Gb3IodGhpcy5kYXRhc2V0LCB0aGlzLnZpZXcpIDogbnVsbDtcbiAgICAvLyBUaGUgdXNlcidzIGNvbG91cnMgZm9yIHRoZSBncm91cGluZyBhcmUgcGFydCBvZiB3aGF0IHRoZSBjbHVzdGVyIHN3YXRjaGVzIHNob3cuXG4gICAgY29uc3Qga2V5ID0gY29sdW1uID09PSBudWxsID8gbnVsbCA6IGAke2NvbHVtbn1cXHUwMDAxJHtncm91cENvbG9yc0tleShjb2x1bW4sIHRoaXMudmlldy5ncm91cENvbG9ycyl9YDtcbiAgICBpZiAoa2V5ID09PSB0aGlzLmNlbGxHcm91cENvbG9yc0ZvcikgcmV0dXJuO1xuICAgIHRoaXMuY2VsbEdyb3VwQ29sb3JzRm9yID0ga2V5O1xuICAgIGNvbnN0IHRhc2sgPSB0aGlzLmNlbGxHcm91cENvbG9yc0xvYWQubmV4dCgpO1xuICAgIGNvbnN0IG1hcCA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KCk7XG4gICAgY29uc3QgbWV0YSA9IGNvbHVtbiA/IHRoaXMuZGF0YXNldD8uY29sdW1ucy5maW5kKChjKSA9PiBjLm5hbWUgPT09IGNvbHVtbikgOiBudWxsO1xuICAgIGlmIChtZXRhICYmIG1ldGEua2luZCA9PT0gJ2NhdGVnb3JpY2FsJyAmJiB0aGlzLmNvbnRyb2xzKSB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBjb2xvcnMgPSBhd2FpdCB0aGlzLmNvbnRyb2xzLmNhdGVnb3J5Q29sb3JzKGNvbHVtbiEpO1xuICAgICAgICBtZXRhLmNhdGVnb3JpZXMuZm9yRWFjaCgoYywgaykgPT4ge1xuICAgICAgICAgIGlmIChjb2xvcnNba10pIG1hcC5zZXQoYywgY29sb3JzW2tdKTtcbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8gTm8gY29sb3VyczogcGFsZXR0ZSBjb2xvdXJzLCBhcyB0aGUgbWFya2VycyBmYWxsIGJhY2sgdG8uXG4gICAgICB9XG4gICAgfVxuICAgIC8vIFRoZSBjZWxscycgZ3JvdXBpbmcgY2hhbmdlZCB3aGlsZSB0aGUgY29sb3VycyBsb2FkZWQ6IHRoZSBuZXdlciByZXF1ZXN0IGFwcGxpZXMgaXRzIG93bi5cbiAgICBpZiAoIXRhc2suaXNDdXJyZW50KCkpIHJldHVybjtcbiAgICB0aGlzLnpvbmUucnVuKCgpID0+IHtcbiAgICAgIHRoaXMuY2VsbEdyb3VwQ29sb3JzID0gbWFwO1xuICAgICAgdGhpcy5yZWJ1aWxkUm93cygpO1xuICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfSk7XG4gIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJzYy1zdWJoZWFkXCI+U2VsZWN0ZWQgZ2VuZXM8L2Rpdj5cbjxkaXYgY2xhc3M9XCJzYy1nZW5lLXNvcnRcIiAqbmdJZj1cInNvcnRTaG93blwiIHJvbGU9XCJncm91cFwiIGFyaWEtbGFiZWw9XCJTb3J0IGdlbmVzXCI+XG4gIDxzcGFuIGNsYXNzPVwic2MtbGJsXCI+U29ydCBieTwvc3Bhbj5cbiAgPGJ1dHRvblxuICAgIHR5cGU9XCJidXR0b25cIlxuICAgIGNsYXNzPVwic2Mtc29ydC1idG5cIlxuICAgIFtjbGFzcy5hY3RpdmVdPVwiIWJ5Q291bnRcIlxuICAgIFthdHRyLmFyaWEtcHJlc3NlZF09XCIhYnlDb3VudFwiXG4gICAgKGNsaWNrKT1cIm9uR2VuZVNvcnQoJ25hbWUnKVwiXG4gID5cbiAgICBOYW1lXG4gIDwvYnV0dG9uPlxuICA8YnV0dG9uXG4gICAgdHlwZT1cImJ1dHRvblwiXG4gICAgY2xhc3M9XCJzYy1zb3J0LWJ0blwiXG4gICAgW2NsYXNzLmFjdGl2ZV09XCJieUNvdW50XCJcbiAgICBbYXR0ci5hcmlhLXByZXNzZWRdPVwiYnlDb3VudFwiXG4gICAgdGl0bGU9XCJUcmFuc2NyaXB0cyBpbiB2aWV3LCBtb3N0IGZpcnN0XCJcbiAgICAoY2xpY2spPVwib25HZW5lU29ydCgnY291bnQnKVwiXG4gID5cbiAgICBDb3VudFxuICA8L2J1dHRvbj5cbjwvZGl2PlxuPGRpdiBjbGFzcz1cInNjLWdlbmUtdHJlZVwiPlxuICA8ZGl2IGNsYXNzPVwic2MtZ2VuZS1yb3cgc2MtZ2VuZS1yb290XCI+XG4gICAgPGJ1dHRvblxuICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICBjbGFzcz1cInNjLWV5ZVwiXG4gICAgICAoY2xpY2spPVwiXG4gICAgICAgIHZpZXcudHJhbnNjcmlwdEFsbEdlbmVzID8gb25BbGxHZW5lc1Nob3duKCFyb290U2hvd24pIDogb25HZW5lc1Nob3duKHZpZXcudHJhbnNjcmlwdEdlbmVzLCAhcm9vdFNob3duKVxuICAgICAgXCJcbiAgICA+XG4gICAgICA8aSBjbGFzcz1cInBpXCIgW2NsYXNzLnBpLWV5ZV09XCJyb290U2hvd25cIiBbY2xhc3MucGktZXllLXNsYXNoXT1cIiFyb290U2hvd25cIj48L2k+XG4gICAgPC9idXR0b24+XG4gICAgPHNwYW4gY2xhc3M9XCJzYy1ncm91cC1sYWJlbFwiPkdlbmVzPC9zcGFuPlxuICAgIDxzcGFuIGNsYXNzPVwic2MtY291bnRcIlxuICAgICAgPih7eyAodmlldy50cmFuc2NyaXB0QWxsR2VuZXMgPyBnZW5lVG90YWwgOiB2aWV3LnRyYW5zY3JpcHRHZW5lcy5sZW5ndGgpIHwgbnVtYmVyIH19L3t7XG4gICAgICAgIGdlbmVUb3RhbCB8IG51bWJlclxuICAgICAgfX0pPC9zcGFuXG4gICAgPlxuICAgIDxidXR0b25cbiAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgY2xhc3M9XCJzYy1pY29uLWJ0blwiXG4gICAgICAoY2xpY2spPVwiZ2VuZVRyZWVPcGVuID0gIWdlbmVUcmVlT3BlblwiXG4gICAgICAqbmdJZj1cIiF2aWV3LnRyYW5zY3JpcHRBbGxHZW5lcyAmJiB2aWV3LnRyYW5zY3JpcHRHZW5lcy5sZW5ndGhcIlxuICAgID5cbiAgICAgIDxpIGNsYXNzPVwicGlcIiBbY2xhc3MucGktY2hldnJvbi1kb3duXT1cImdlbmVUcmVlT3BlblwiIFtjbGFzcy5waS1jaGV2cm9uLXJpZ2h0XT1cIiFnZW5lVHJlZU9wZW5cIj48L2k+XG4gICAgPC9idXR0b24+XG4gICAgPGJ1dHRvblxuICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICBjbGFzcz1cInNjLWljb24tYnRuXCJcbiAgICAgIChjbGljayk9XCJ0b2dnbGVBbGxHZW5lc09wZW4oKVwiXG4gICAgICAqbmdJZj1cInZpZXcudHJhbnNjcmlwdEFsbEdlbmVzICYmIGFsbEdlbmVMaXN0Py5sZW5ndGhcIlxuICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCJhbGxHZW5lc09wZW4gPyAnSGlkZSB0aGUgZ2VuZSBsaXN0JyA6ICdTaG93IGV2ZXJ5IGdlbmUnXCJcbiAgICA+XG4gICAgICA8aSBjbGFzcz1cInBpXCIgW2NsYXNzLnBpLWNoZXZyb24tZG93bl09XCJhbGxHZW5lc09wZW5cIiBbY2xhc3MucGktY2hldnJvbi1yaWdodF09XCIhYWxsR2VuZXNPcGVuXCI+PC9pPlxuICAgIDwvYnV0dG9uPlxuICA8L2Rpdj5cbiAgPCEtLSBcIkFsbCBnZW5lc1wiOiBldmVyeSBnZW5lIG9mIHRoZSBkYXRhc2V0LCBlYWNoIHdpdGggaXRzIGV5ZSB3aGVuIHRoZSBkYXRhc2V0IHNheXMgd2hpY2hcbiAgICAgICB0cmFuc2NyaXB0cyBhcmUgd2hvc2UgKGl0cyBnZW5lIGxpc3QgaW4gY29kZSBvcmRlcikuIC0tPlxuICA8bmctY29udGFpbmVyICpuZ0lmPVwiYWxsR2VuZXNPcGVuICYmIHZpZXcudHJhbnNjcmlwdEFsbEdlbmVzICYmIGFsbEdlbmVMaXN0Py5sZW5ndGhcIj5cbiAgICA8aW5wdXRcbiAgICAgIHBJbnB1dFRleHRcbiAgICAgIGNsYXNzPVwic2MtZ2VuZS1maWx0ZXJcIlxuICAgICAgcGxhY2Vob2xkZXI9XCJGaWx0ZXIgZ2VuZXPigKZcIlxuICAgICAgYXJpYS1sYWJlbD1cIkZpbHRlciBnZW5lc1wiXG4gICAgICBbdmFsdWVdPVwiYWxsR2VuZXNGaWx0ZXJcIlxuICAgICAgKGlucHV0KT1cIm9uQWxsR2VuZXNGaWx0ZXIoJGFueSgkZXZlbnQudGFyZ2V0KS52YWx1ZSlcIlxuICAgIC8+XG4gICAgPHNtYWxsIGNsYXNzPVwic2MtaGludFwiICpuZ0lmPVwiIWNhbkhpZGVBbGxHZW5lc1wiPlxuICAgICAgVGhpcyBkYXRhc2V0IGRvZXMgbm90IHNheSB3aGljaCB0cmFuc2NyaXB0cyBhcmUgd2hvc2UsIHNvIGl0cyBnZW5lcyBjYW5ub3QgYmUgaGlkZGVuIG9uZSBieSBvbmUuXG4gICAgPC9zbWFsbD5cbiAgICA8c21hbGwgY2xhc3M9XCJzYy1oaW50XCIgKm5nSWY9XCJjYW5IaWRlQWxsR2VuZXMgJiYgdmlldy50cmFuc2NyaXB0TW9kZSA9PT0gJ2RlbnNpdHknXCI+XG4gICAgICBUaGUgZGVuc2l0eSBtYXAgZHJhd3MgZXZlcnkgZ2VuZSBhcyBvbmUgcmFzdGVyOiBnZW5lcyBhcmUgaGlkZGVuIG9uZSBieSBvbmUgYXMgY2lyY2xlcyBvciBpY29ucy5cbiAgICA8L3NtYWxsPlxuICAgIDxkaXYgY2xhc3M9XCJzYy1nZW5lLXJvdyBzYy1nZW5lLWxlYWYgbmVzdGVkXCIgKm5nRm9yPVwibGV0IHJvdyBvZiBhbGxSb3dzOyB0cmFja0J5OiB0cmFja0J5QWxsUm93XCI+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICBjbGFzcz1cInNjLWV5ZVwiXG4gICAgICAgIFtkaXNhYmxlZF09XCIhY2FuSGlkZUFsbEdlbmVzIHx8IHZpZXcudHJhbnNjcmlwdE1vZGUgPT09ICdkZW5zaXR5J1wiXG4gICAgICAgIChjbGljayk9XCJvbkFsbEdlbmVTaG93bihyb3cuZ2VuZSwgIXJvdy5zaG93bilcIlxuICAgICAgPlxuICAgICAgICA8aSBjbGFzcz1cInBpXCIgW2NsYXNzLnBpLWV5ZV09XCJyb3cuc2hvd25cIiBbY2xhc3MucGktZXllLXNsYXNoXT1cIiFyb3cuc2hvd25cIj48L2k+XG4gICAgICA8L2J1dHRvbj5cbiAgICAgIDwhLS0gVGhlIGdlbmUncyBjb2xvdXIgYW1vbmcgZXZlcnkgZ2VuZTsgY2xpY2tpbmcgaXQgb3BlbnMgdGhlIGNvbG91ciBwaWNrZXIuIC0tPlxuICAgICAgPGJ1dHRvblxuICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgY2xhc3M9XCJzYy1nZW5lLWljb25cIlxuICAgICAgICAqbmdJZj1cInJvdy5zd2F0Y2hcIlxuICAgICAgICBbc3R5bGUuY29sb3JdPVwicm93LnN3YXRjaFwiXG4gICAgICAgIFthdHRyLmFyaWEtbGFiZWxdPVwiJ0NvbG91ciBmb3IgJyArIHJvdy5nZW5lXCJcbiAgICAgICAgcFRvb2x0aXA9XCJDb2xvdXJcIlxuICAgICAgICB0b29sdGlwUG9zaXRpb249XCJ0b3BcIlxuICAgICAgICAoY2xpY2spPVwib3BlbkdlbmVTdHlsZSgkZXZlbnQsIHJvdy5nZW5lLCBnZW5lUG9wKVwiXG4gICAgICA+XG4gICAgICAgIDxzdmcgdmlld0JveD1cIi0xLjIgLTEuMiAyLjQgMi40XCIgY2xhc3M9XCJzYy1nbHlwaC1zdmdcIj48Y2lyY2xlIHI9XCIwLjc1XCI+PC9jaXJjbGU+PC9zdmc+XG4gICAgICA8L2J1dHRvbj5cbiAgICAgIDxzcGFuIGNsYXNzPVwic2MtZ3JvdXAtbGFiZWxcIiBbdGl0bGVdPVwicm93LmdlbmVcIj57eyByb3cuZ2VuZSB9fTwvc3Bhbj5cbiAgICAgIDxzcGFuIGNsYXNzPVwic2MtZ2VuZS1jb3VudFwiICpuZ0lmPVwicm93LmNvdW50ICE9PSBudWxsXCIgdGl0bGU9XCJUcmFuc2NyaXB0cyBpbiB2aWV3XCI+e3tcbiAgICAgICAgcm93LmNvdW50IHwgbnVtYmVyXG4gICAgICB9fTwvc3Bhbj5cbiAgICA8L2Rpdj5cbiAgICA8c21hbGwgY2xhc3M9XCJzYy1oaW50XCIgKm5nSWY9XCJhbGxHZW5lc01hdGNoZWQgPiBhbGxSb3dzLmxlbmd0aFwiPlxuICAgICAgU2hvd2luZyB7eyBhbGxSb3dzLmxlbmd0aCB8IG51bWJlciB9fSBvZiB7eyBhbGxHZW5lc01hdGNoZWQgfCBudW1iZXIgfX0gZ2VuZXM6IGZpbHRlciB0byBmaW5kIHRoZSBvdGhlcnMuXG4gICAgPC9zbWFsbD5cbiAgICA8c21hbGwgY2xhc3M9XCJzYy1oaW50XCIgKm5nSWY9XCJhbGxHZW5lc01hdGNoZWQgPT09IDBcIj5ObyBnZW5lIG1hdGNoZXMuPC9zbWFsbD5cbiAgPC9uZy1jb250YWluZXI+XG4gIDxuZy1jb250YWluZXIgKm5nSWY9XCJnZW5lVHJlZU9wZW4gJiYgIXZpZXcudHJhbnNjcmlwdEFsbEdlbmVzXCI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgbm9kZSBvZiBzb3J0ZWRUcmVlOyB0cmFja0J5OiB0cmFja0J5Tm9kZVwiPlxuICAgICAgPGRpdiBjbGFzcz1cInNjLWdlbmUtcm93IHNjLWdlbmUtZ3JvdXBcIiAqbmdJZj1cIm5vZGUubmFtZVwiPlxuICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInNjLWV5ZVwiIChjbGljayk9XCJvbkdlbmVzU2hvd24obm9kZS5nZW5lcywgIWdyb3VwU2hvd24uZ2V0KG5vZGUubmFtZSkpXCI+XG4gICAgICAgICAgPGlcbiAgICAgICAgICAgIGNsYXNzPVwicGlcIlxuICAgICAgICAgICAgW2NsYXNzLnBpLWV5ZV09XCJncm91cFNob3duLmdldChub2RlLm5hbWUpXCJcbiAgICAgICAgICAgIFtjbGFzcy5waS1leWUtc2xhc2hdPVwiIWdyb3VwU2hvd24uZ2V0KG5vZGUubmFtZSlcIlxuICAgICAgICAgID48L2k+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8c3BhbiBjbGFzcz1cInNjLWdyb3VwLWxhYmVsXCIgW3RpdGxlXT1cIm5vZGUubmFtZVwiPnt7IG5vZGUubmFtZSB9fTwvc3Bhbj5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJzYy1jb3VudFwiPih7eyBub2RlLmdlbmVzLmxlbmd0aCB9fSk8L3NwYW4+XG4gICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwic2MtaWNvbi1idG5cIiAoY2xpY2spPVwidG9nZ2xlR2VuZUdyb3VwKG5vZGUubmFtZSlcIj5cbiAgICAgICAgICA8aVxuICAgICAgICAgICAgY2xhc3M9XCJwaVwiXG4gICAgICAgICAgICBbY2xhc3MucGktY2hldnJvbi1kb3duXT1cIiFjb2xsYXBzZWRHZW5lR3JvdXBzLmhhcyhub2RlLm5hbWUpXCJcbiAgICAgICAgICAgIFtjbGFzcy5waS1jaGV2cm9uLXJpZ2h0XT1cImNvbGxhcHNlZEdlbmVHcm91cHMuaGFzKG5vZGUubmFtZSlcIlxuICAgICAgICAgID48L2k+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIW5vZGUubmFtZSB8fCAhY29sbGFwc2VkR2VuZUdyb3Vwcy5oYXMobm9kZS5uYW1lKVwiPlxuICAgICAgICA8ZGl2XG4gICAgICAgICAgY2xhc3M9XCJzYy1nZW5lLXJvdyBzYy1nZW5lLWxlYWZcIlxuICAgICAgICAgIFtjbGFzcy5uZXN0ZWRdPVwiISFub2RlLm5hbWVcIlxuICAgICAgICAgICpuZ0Zvcj1cImxldCBnZW5lIG9mIG5vZGUuZ2VuZXM7IHRyYWNrQnk6IHRyYWNrQnlMYWJlbFN0cmluZ1wiXG4gICAgICAgID5cbiAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInNjLWV5ZVwiIChjbGljayk9XCJvbkdlbmVzU2hvd24oW2dlbmVdLCAhcm93cy5nZXQoZ2VuZSk/LnNob3duKVwiPlxuICAgICAgICAgICAgPGkgY2xhc3M9XCJwaVwiIFtjbGFzcy5waS1leWVdPVwicm93cy5nZXQoZ2VuZSk/LnNob3duXCIgW2NsYXNzLnBpLWV5ZS1zbGFzaF09XCIhcm93cy5nZXQoZ2VuZSk/LnNob3duXCI+PC9pPlxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIDwhLS0gVGhlIGdlbmUncyBtYXJrZXIsIGluIGl0cyBjb2xvdXI6IGl0cyBpY29uIGluIEljb25zIG1vZGUsIGEgZG90IGZvciBjaXJjbGVzLlxuICAgICAgICAgICAgICAgQ2xpY2tpbmcgaXQgb3BlbnMgdGhlIGljb24gYW5kIGNvbG91ciBwaWNrZXIgKGFzIFhlbml1bSBFeHBsb3JlciBkb2VzKS4gLS0+XG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICBjbGFzcz1cInNjLWdlbmUtaWNvblwiXG4gICAgICAgICAgICBbc3R5bGUuY29sb3JdPVwicm93cy5nZXQoZ2VuZSk/LnN3YXRjaFwiXG4gICAgICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cIidJY29uIGFuZCBjb2xvdXIgZm9yICcgKyBnZW5lXCJcbiAgICAgICAgICAgIHBUb29sdGlwPVwiSWNvbiBhbmQgY29sb3VyXCJcbiAgICAgICAgICAgIHRvb2x0aXBQb3NpdGlvbj1cInRvcFwiXG4gICAgICAgICAgICAoY2xpY2spPVwib3BlbkdlbmVTdHlsZSgkZXZlbnQsIGdlbmUsIGdlbmVQb3ApXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8c3ZnIHZpZXdCb3g9XCItMS4yIC0xLjIgMi40IDIuNFwiIGNsYXNzPVwic2MtZ2x5cGgtc3ZnXCI+XG4gICAgICAgICAgICAgIDxwb2x5Z29uXG4gICAgICAgICAgICAgICAgKm5nSWY9XCJ2aWV3LnRyYW5zY3JpcHRNb2RlID09PSAnZ2x5cGhzJzsgZWxzZSBkb3RJY29uXCJcbiAgICAgICAgICAgICAgICBbYXR0ci5wb2ludHNdPVwicm93cy5nZXQoZ2VuZSk/LnBvaW50c1wiXG4gICAgICAgICAgICAgID48L3BvbHlnb24+XG4gICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjZG90SWNvbj48Y2lyY2xlIHI9XCIwLjc1XCI+PC9jaXJjbGU+PC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2MtZ3JvdXAtbGFiZWxcIj57eyBnZW5lIH19PC9zcGFuPlxuICAgICAgICAgIDxzcGFuXG4gICAgICAgICAgICBjbGFzcz1cInNjLWdlbmUtY291bnRcIlxuICAgICAgICAgICAgKm5nSWY9XCJyb3dzLmdldChnZW5lKT8uY291bnQgYXMgbjsgZWxzZSB6ZXJvQ291bnRcIlxuICAgICAgICAgICAgdGl0bGU9XCJUcmFuc2NyaXB0cyBpbiB2aWV3XCJcbiAgICAgICAgICAgID57eyBuIHwgbnVtYmVyIH19PC9zcGFuXG4gICAgICAgICAgPlxuICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjemVyb0NvdW50PlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYy1nZW5lLWNvdW50XCIgKm5nSWY9XCJnZW5lQ291bnRzXCIgdGl0bGU9XCJUcmFuc2NyaXB0cyBpbiB2aWV3XCI+MDwvc3Bhbj5cbiAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgIDwvbmctY29udGFpbmVyPlxuICA8L25nLWNvbnRhaW5lcj5cbiAgPCEtLSBPbmUgcGlja2VyIGZvciBldmVyeSBnZW5lIHJvdywgZmlsbGVkIGZvciB0aGUgZ2VuZSB0aGF0IG9wZW5lZCBpdC4gLS0+XG4gIDxwLW92ZXJsYXlQYW5lbCAjZ2VuZVBvcCBzdHlsZUNsYXNzPVwic2MtZ2VuZS1zdHlsZVwiIGFwcGVuZFRvPVwiYm9keVwiPlxuICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJjb250ZW50XCI+XG4gICAgICA8c3BhdGlhbC1nZW5lLXN0eWxlXG4gICAgICAgICpuZ0lmPVwic3R5bGVHZW5lIGFzIGdlbmVcIlxuICAgICAgICBbZ2VuZV09XCJnZW5lXCJcbiAgICAgICAgd2hhdD1cIlRyYW5zY3JpcHRcIlxuICAgICAgICBbY29sb3JdPVwic3R5bGVDb2xvck9mKGdlbmUpXCJcbiAgICAgICAgW2dseXBoXT1cInN0eWxlR2x5cGggPz8gJ2NpcmNsZSdcIlxuICAgICAgICBbc2hvd0ljb25zXT1cIiF2aWV3LnRyYW5zY3JpcHRBbGxHZW5lc1wiXG4gICAgICAgIFtpY29uSGludF09XCJcbiAgICAgICAgICB2aWV3LnRyYW5zY3JpcHRNb2RlICE9PSAnZ2x5cGhzJyA/ICdJY29ucyBzaG93IHdoZW4gdGhlIHRyYW5zY3JpcHQgcG9pbnQgc3R5bGUgaXMgSWNvbnMuJyA6IG51bGxcbiAgICAgICAgXCJcbiAgICAgICAgKGNvbG9yQ2hhbmdlKT1cIm9uR2VuZUNvbG9yKGdlbmUsICRldmVudClcIlxuICAgICAgICAoZ2x5cGhDaGFuZ2UpPVwib25HbHlwaChnZW5lLCAkZXZlbnQpXCJcbiAgICAgICAgKHJlc2V0U3R5bGUpPVwicmVzZXRHZW5lU3R5bGUoZ2VuZSlcIlxuICAgICAgPjwvc3BhdGlhbC1nZW5lLXN0eWxlPlxuICAgIDwvbmctdGVtcGxhdGU+XG4gIDwvcC1vdmVybGF5UGFuZWw+XG4gIDxkaXYgY2xhc3M9XCJzYy1nZW5lLWZvb3RlclwiPlxuICAgIHt7ICh2aWV3LnRyYW5zY3JpcHRBbGxHZW5lcyA/IGdlbmVUb3RhbCA6IHZpZXcudHJhbnNjcmlwdEdlbmVzLmxlbmd0aCkgfCBudW1iZXIgfX0ve3sgZ2VuZVRvdGFsIHwgbnVtYmVyIH19XG4gICAgZ2VuZXMgc2VsZWN0ZWRcbiAgPC9kaXY+XG48L2Rpdj5cbiJdfQ==
369
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BhdGlhbC1nZW5lLXRyZWUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9zcGF0aWFsLWNvbnRyb2xzL3NwYXRpYWwtZ2VuZS10cmVlL3NwYXRpYWwtZ2VuZS10cmVlLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3NyYy9saWIvc3BhdGlhbC1jb250cm9scy9zcGF0aWFsLWdlbmUtdHJlZS9zcGF0aWFsLWdlbmUtdHJlZS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsS0FBSyxFQUNMLE1BQU0sR0FHUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUMzQyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDcEQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDMUQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBSWhELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQztBQUNwRSxPQUFPLEVBQUUsb0JBQW9CLEVBQXlDLE1BQU0sK0JBQStCLENBQUM7QUFDNUcsT0FBTyxFQUFFLDJCQUEyQixFQUFFLGNBQWMsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQzdGLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxlQUFlLEVBQUUsYUFBYSxFQUFFLGVBQWUsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ2pILE9BQU8sRUFBZ0IsYUFBYSxFQUFFLFdBQVcsRUFBRSxZQUFZLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUMzRyxPQUFPLEVBQUUsY0FBYyxFQUFFLGNB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QUF5Qjs7MkZBTWhCLHdCQUF3QjtrQkFmcEMsU0FBUzsrQkFDRSxtQkFBbUIsY0FDakIsSUFBSSxXQUNQO3dCQUNQLFlBQVk7d0JBQ1osWUFBWTt3QkFDWixlQUFlO3dCQUNmLGtCQUFrQjt3QkFDbEIsYUFBYTt3QkFDYix5QkFBeUI7cUJBQzFCLG1CQUdnQix1QkFBdUIsQ0FBQyxNQUFNOzJHQUl0QyxRQUFRO3NCQUFoQixLQUFLO2dCQUVHLE9BQU87c0JBQWYsS0FBSztnQkFFRyxJQUFJO3NCQUFaLEtBQUs7Z0JBRUcsVUFBVTtzQkFBbEIsS0FBSztnQkFFRyxTQUFTO3NCQUFqQixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIElucHV0LFxuICBOZ1pvbmUsXG4gIE9uQ2hhbmdlcyxcbiAgU2ltcGxlQ2hhbmdlcyxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgU2hhcmVkTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9hcGknO1xuaW1wb3J0IHsgSW5wdXRUZXh0TW9kdWxlIH0gZnJvbSAncHJpbWVuZy9pbnB1dHRleHQnO1xuaW1wb3J0IHsgT3ZlcmxheVBhbmVsTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9vdmVybGF5cGFuZWwnO1xuaW1wb3J0IHsgVG9vbHRpcE1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvdG9vbHRpcCc7XG5cbmltcG9ydCB0eXBlIHsgSVNwYXRpYWxDb250cm9scyB9IGZyb20gJy4uLy4uL2NvbnRyYWN0cy92aXN1YWxpemVyLmNvbnRyYWN0JztcbmltcG9ydCB0eXBlIHsgU3BhdGlhbERhdGFzZXQgfSBmcm9tICcuLi8uLi9jb250cmFjdHMvc3BhdGlhbC1kYXRhc2V0LmNvbnRyYWN0JztcbmltcG9ydCB7IEFMTF9HRU5FUyB9IGZyb20gJy4uLy4uL2NvbnRyYWN0cy9wb3J0cy9zcGF0aWFsLWRhdGEucG9ydCc7XG5pbXBvcnQgeyBERUZBVUxUX1NQQVRJQUxfVklFVywgU3BhdGlhbFZpZXdTdGF0ZSwgVHJhbnNjcmlwdEdseXBoTmFtZSB9IGZyb20gJy4uLy4uL2NvbnRyYWN0cy9kaXNwbGF5LXR5cGVzJztcbmltcG9ydCB7IERFRkFVTFRfQ0FURUdPUklDQUxfUEFMRVRURSwgZ3JvdXBDb2xvcnNLZXkgfSBmcm9tICcuLi8uLi9zcGF0aWFsL3NwYXRpYWwtZW5jb2RpbmcnO1xuaW1wb3J0IHsgY2VsbFR5cGVDb2x1bW5Gb3IsIGNsdXN0ZXJDb2xvck1hcCwgY2x1c3Rlck9mR2VuZSwgZGVmYXVsdEdseXBoRm9yIH0gZnJvbSAnLi4vLi4vc3BhdGlhbC9zcGF0aWFsLXRpbGVzJztcbmltcG9ydCB7IEdlbmVUcmVlTm9kZSwgYnVpbGRHZW5lVHJlZSwgZ2x5cGhQb2ludHMsIHRvZ2dsZUhpZGRlbiB9IGZyb20gJy4uLy4uL3NwYXRpYWwvc3BhdGlhbC1wYW5lbC1tb2RlbCc7XG5pbXBvcnQgeyBhbGxHZW5lU2hvd25CeSwgYWxsR2VuZXNIaWRkZW4sIHRvZ2dsZUFsbEdlbmVIaWRkZW4gfSBmcm9tICcuLi8uLi9zcGF0aWFsL3NwYXRpYWwtdGlsZS1tZXJnZSc7XG5pbXBvcnQgeyBTdXBlcnNlZGUgfSBmcm9tICcuLi8uLi91dGlsL3N1cGVyc2VkZSc7XG5pbXBvcnQgeyBTcGF0aWFsR2VuZVN0eWxlQ29tcG9uZW50IH0gZnJvbSAnLi4vc3BhdGlhbC1nZW5lLXN0eWxlL3NwYXRpYWwtZ2VuZS1zdHlsZS5jb21wb25lbnQnO1xuXG4vKiogUm93cyBvZiB0aGUgYWxsLWdlbmVzIGxpc3QgZHJhd24gYXQgb25jZTsgdGhlIGZpbHRlciBuYXJyb3dzIHRoZSByZXN0LiAqL1xuY29uc3QgQUxMX0dFTkVTX1JPV1MgPSAyMDA7XG5cbi8qKiBIb3cgdGhlIGdlbmUgcm93cyBhcmUgb3JkZXJlZDogYnkgbmFtZSwgb3IgYnkgdGhlaXIgdHJhbnNjcmlwdHMgaW4gdmlldywgbW9zdCBmaXJzdC4gKi9cbmV4cG9ydCB0eXBlIEdlbmVTb3J0ID0gJ25hbWUnIHwgJ2NvdW50JztcblxuLyoqIE5hbWVzIGluIHJlYWRpbmcgb3JkZXI6IGNhc2UgYXNpZGUsIGFuZCBgRzlgIGJlZm9yZSBgRzEwYC4gKi9cbmNvbnN0IGJ5TmFtZSA9IChhOiBzdHJpbmcsIGI6IHN0cmluZyk6IG51bWJlciA9PlxuICBhLmxvY2FsZUNvbXBhcmUoYiwgdW5kZWZpbmVkLCB7IG51bWVyaWM6IHRydWUsIHNlbnNpdGl2aXR5OiAnYmFzZScgfSk7XG5cbi8qKiBPbmUgZ2VuZSByb3cgYXMgdGhlIHRlbXBsYXRlIGRyYXdzIGl0LCBkZXJpdmVkIG9uY2UgcGVyIGlucHV0IGNoYW5nZS4gKi9cbmludGVyZmFjZSBHZW5lUm93VmlldyB7XG4gIHNob3duOiBib29sZWFuO1xuICBzd2F0Y2g6IHN0cmluZztcbiAgLyoqIFRoZSByb3cncyBnbHlwaCBvdXRsaW5lIChkcmF3biBpbiBJY29ucyBtb2RlKS4gKi9cbiAgcG9pbnRzOiBzdHJpbmc7XG4gIC8qKiBUcmFuc2NyaXB0cyBpbiB2aWV3LCBvciBudWxsIGJlZm9yZSB0aGUgcmVuZGVyZXIgcmVwb3J0cyBhbnkuICovXG4gIGNvdW50OiBudW1iZXIgfCBudWxsO1xufVxuXG4vKiogT25lIHJvdyBvZiB0aGUgYWxsLWdlbmVzIGxpc3QuICovXG5pbnRlcmZhY2UgQWxsR2VuZVJvd1ZpZXcge1xuICBnZW5lOiBzdHJpbmc7XG4gIHNob3duOiBib29sZWFuO1xuICAvKiogSXRzIGNvbG91ciB3aGVuIGNvbG91cmVkIGJ5IGdlbmUsIG9yIG51bGwgd2hlbiB0aGUgZGF0YXNldCdzIGNvZGUgb3JkZXIgaXMgdW5rbm93bi4gKi9cbiAgc3dhdGNoOiBzdHJpbmcgfCBudWxsO1xuICAvKiogSXRzIGNvZGUgaW4gdGhlIGRhdGFzZXQncyBnZW5lIGxpc3QgKHdoYXQgaXRzIHBhbGV0dGUgY29sb3VyIGlzIHBpY2tlZCBieSkuICovXG4gIGNvZGU6IG51bWJlcjtcbiAgY291bnQ6IG51bWJlciB8IG51bGw7XG59XG5cbi8qKlxuICogVGhlIHNlbGVjdGVkIHRyYW5zY3JpcHQgZ2VuZXMgYXMgWGVuaXVtIEV4cGxvcmVyJ3MgdHJlZTogdGhlIGdlbmUgZ3JvdXBzLCB0aGVuIHRoZVxuICogdW5ncm91cGVkIGdlbmVzLCBlYWNoIHJvdyB3aXRoIGFuIGV5ZSB0aGF0IGhpZGVzIGl0IHdpdGhvdXQgZGVzZWxlY3RpbmcgaXQsIGl0cyBtYXJrZXJcbiAqIGluIGl0cyBjb2xvdXIgKG9wZW5pbmcgb25lIGljb24tYW5kLWNvbG91ciBwaWNrZXIgcGVyIGdlbmUpLCBhbmQgaXRzIHRyYW5zY3JpcHQgY291bnQgaW5cbiAqIHZpZXcuIFdpdGggXCJBbGwgZ2VuZXNcIiBvbiwgdGhlIHJvb3QgZXllIGhpZGVzIG9yIHNob3dzIGV2ZXJ5IHRyYW5zY3JpcHQgYW5kIHRoZSByb290XG4gKiBleHBhbmRzIHRvIGV2ZXJ5IGdlbmUgb2YgdGhlIGRhdGFzZXQsIGVhY2ggd2l0aCBpdHMgZXllIHdoZW4gdGhlIGRhdGFzZXQgbGlzdHMgaXRzIGdlbmVzXG4gKiBpbiBjb2RlIG9yZGVyIChgdHJhbnNjcmlwdFRpbGVzLmdlbmVzYCksIGZpbHRlcmVkIGJ5IG5hbWUgcGFzdCBhIGZldyBodW5kcmVkLlxuICpcbiAqIEJvdGggbGlzdHMgYXJlIG9yZGVyZWQgYnkgbmFtZSwgb3IgYnkgdGhlaXIgdHJhbnNjcmlwdHMgaW4gdmlldywgbW9zdCBmaXJzdCAodGhlXG4gKiBzb3J0IHN3aXRjaCwgb2ZmZXJlZCBvbmNlIHRoZSByZW5kZXJlciByZXBvcnRzIGNvdW50cykuIFRoZSBhbGwtZ2VuZXMgbGlzdCBpcyBzb3J0ZWRcbiAqIGJlZm9yZSBpdCBpcyBjdXQgdG8gaXRzIGZpcnN0IHJvd3MsIHNvIGJ5IGNvdW50IHRob3NlIGFyZSB0aGUgZ2VuZXMgd2l0aCB0aGUgbW9zdFxuICogdHJhbnNjcmlwdHMgaW4gdmlldy5cbiAqXG4gKiBXcml0ZXMgb25seSB0aHJvdWdoIGBjb250cm9scy5zZXRWaWV3U3RhdGVgLlxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdzcGF0aWFsLWdlbmUtdHJlZScsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtcbiAgICBDb21tb25Nb2R1bGUsXG4gICAgU2hhcmVkTW9kdWxlLFxuICAgIElucHV0VGV4dE1vZHVsZSxcbiAgICBPdmVybGF5UGFuZWxNb2R1bGUsXG4gICAgVG9vbHRpcE1vZHVsZSxcbiAgICBTcGF0aWFsR2VuZVN0eWxlQ29tcG9uZW50LFxuICBdLFxuICB0ZW1wbGF0ZVVybDogJy4vc3BhdGlhbC1nZW5lLXRyZWUuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9zcGF0aWFsLWdlbmUtdHJlZS5jb21wb25lbnQuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgU3BhdGlhbEdlbmVUcmVlQ29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzIHtcbiAgLyoqIFRoZSBzcGF0aWFsIGNvbnRyb2xzIHRoaXMgcGFuZWwgcmVhZHMgYW5kIHdyaXRlcyB0aHJvdWdoOyBudWxsIHdpdGhvdXQgYSBgU1BBVElBTF9EQVRBX1BPUlRgLiAqL1xuICBASW5wdXQoKSBjb250cm9sczogSVNwYXRpYWxDb250cm9scyB8IG51bGwgPSBudWxsO1xuICAvKiogVGhlIGRhdGFzZXQgb24gb2ZmZXIsIG9yIG51bGwuICovXG4gIEBJbnB1dCgpIGRhdGFzZXQ6IFNwYXRpYWxEYXRhc2V0IHwgbnVsbCA9IG51bGw7XG4gIC8qKiBUaGUgY3VycmVudCBzcGF0aWFsIHZpZXcgc3RhdGU6IHdoYXQgaXMgZHJhd24sIGFuZCBob3cuICovXG4gIEBJbnB1dCgpIHZpZXc6IFNwYXRpYWxWaWV3U3RhdGUgPSBERUZBVUxUX1NQQVRJQUxfVklFVztcbiAgLyoqIFRyYW5zY3JpcHRzIG9mIGVhY2ggc2VsZWN0ZWQgZ2VuZSBpbiB0aGUgY3VycmVudCB2aWV3LCBmcm9tIHRoZSByZW5kZXJlci4gKi9cbiAgQElucHV0KCkgZ2VuZUNvdW50czogUmVjb3JkPHN0cmluZywgbnVtYmVyPiB8IG51bGwgPSBudWxsO1xuICAvKiogUmVhbCBnZW5lcyBpbiB0aGUgcGFuZWwg4oCUIHRoZSB0cmVlJ3MgZGVub21pbmF0b3IuICovXG4gIEBJbnB1dCgpIGdlbmVUb3RhbCA9IDA7XG5cbiAgLyoqIFN3YXRjaGVzIGluIHRoZSBwaWNrZXI6IHRoZSBjYXRlZ29yaWNhbCBwYWxldHRlIGdlbmVzIGFyZSBjb2xvdXJlZCBmcm9tIGJ5IGRlZmF1bHQuICovXG5cbiAgLyoqIFRoZSB0cmVlLCByZWJ1aWx0IHdoZW4gdGhlIHZpZXcgY2hhbmdlcyDigJQgbmV2ZXIgcGVyIGNoYW5nZS1kZXRlY3Rpb24gcGFzcy4gKi9cbiAgcHJvdGVjdGVkIGdlbmVUcmVlOiBHZW5lVHJlZU5vZGVbXSA9IFtdO1xuICAvKioge0BsaW5rIGdlbmVUcmVlfSB3aXRoIGVhY2ggbm9kZSdzIGdlbmVzIGluIHtAbGluayBnZW5lU29ydH0gb3JkZXI6IHdoYXQgdGhlIHRlbXBsYXRlIGRyYXdzLiAqL1xuICBwcm90ZWN0ZWQgc29ydGVkVHJlZTogR2VuZVRyZWVOb2RlW10gPSBbXTtcbiAgLyoqIFRoZSByb3dzJyBvcmRlci4gQnkgY291bnQgb25seSB3aGlsZSB0aGUgcmVuZGVyZXIgcmVwb3J0cyBjb3VudHMgKHNlZSB7QGxpbmsgc29ydFNob3dufSkuICovXG4gIHByb3RlY3RlZCBnZW5lU29ydDogR2VuZVNvcnQgPSAnbmFtZSc7XG4gIC8qKiBQZXIgZ2VuZTogaXRzIGV5ZSwgc3dhdGNoLCBnbHlwaCBhbmQgY291bnQg4oCUIHJlYnVpbHQgd2l0aCB0aGUgaW5wdXRzIChhbmQgd2hlbiB0aGVcbiAgICogIGNlbGxzJyBncm91cCBjb2xvdXJzIGFycml2ZSksIHNvIHRoZSB0ZW1wbGF0ZSBkb2VzIG5vIHBlci1yb3cgbG9va3VwcyBwZXIgY2hlY2suICovXG4gIHByb3RlY3RlZCByb3dzID0gbmV3IE1hcDxzdHJpbmcsIEdlbmVSb3dWaWV3PigpO1xuICAvKiogUGVyIG5hbWVkIGdyb3VwLCBhbmQgZm9yIHRoZSByb290OiB3aGV0aGVyIGFueSBvZiBpdHMgZ2VuZXMgaXMgc2hvd24uICovXG4gIHByb3RlY3RlZCBncm91cFNob3duID0gbmV3IE1hcDxzdHJpbmcsIGJvb2xlYW4+KCk7XG4gIHByb3RlY3RlZCByb290U2hvd24gPSBmYWxzZTtcbiAgcHJvdGVjdGVkIGNvbGxhcHNlZEdlbmVHcm91cHMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgcHJvdGVjdGVkIGdlbmVUcmVlT3BlbiA9IHRydWU7XG4gIC8qKiBUaGUgYWxsLWdlbmVzIGxpc3Qgc3RhcnRzIGNsb3NlZDogaXQgY2FuIHJ1biB0byB0aG91c2FuZHMgb2YgZ2VuZXMuICovXG4gIHByb3RlY3RlZCBhbGxHZW5lc09wZW4gPSBmYWxzZTtcbiAgLyoqIFRoZSBnZW5lcyBcIkFsbCBnZW5lc1wiIGxpc3RzLCBvciBudWxsIHdoZW4gdGhlIGRhdGFzZXQgbmFtZXMgbm9uZS4gKi9cbiAgcHJvdGVjdGVkIGFsbEdlbmVMaXN0OiByZWFkb25seSBzdHJpbmdbXSB8IG51bGwgPSBudWxsO1xuICAvKiogV2hldGhlciBhIGdlbmUgb2YgXCJBbGwgZ2VuZXNcIiBjYW4gYmUgaGlkZGVuOiB0aGUgZGF0YXNldCBsaXN0cyBpdHMgZ2VuZXMgaW4gY29kZSBvcmRlci4gKi9cbiAgcHJvdGVjdGVkIGNhbkhpZGVBbGxHZW5lcyA9IGZhbHNlO1xuICBwcm90ZWN0ZWQgYWxsR2VuZXNGaWx0ZXIgPSAnJztcbiAgLyoqIFRoZSBsaXN0J3Mgcm93cyBtYXRjaGluZyB0aGUgZmlsdGVyLCBhdCBtb3N0IHtAbGluayBBTExfR0VORVNfUk9XU30uICovXG4gIHByb3RlY3RlZCBhbGxSb3dzOiBBbGxHZW5lUm93Vmlld1tdID0gW107XG4gIC8qKiBIb3cgbWFueSBnZW5lcyBtYXRjaCB0aGUgZmlsdGVyLCBmb3IgdGhlIFwic2hvd2luZyBuIG9mIG1cIiBsaW5lLiAqL1xuICBwcm90ZWN0ZWQgYWxsR2VuZXNNYXRjaGVkID0gMDtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGFsbEdlbmVzUm93Q2FwID0gQUxMX0dFTkVTX1JPV1M7XG4gIC8qKiBUaGUgZ2VuZSB0aGUgb3BlbiBwaWNrZXIgZWRpdHMuICovXG4gIHByb3RlY3RlZCBzdHlsZUdlbmU6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuXG4gIC8qKiBDb2xvdXJzIG9mIHRoZSBjZWxscycgZ3JvdXBzLCBieSBuYW1lIOKAlCB3aGF0IGEgY2x1c3RlciBvZiB0aGUgc2FtZSBuYW1lIGlzIGRyYXduIGluLiAqL1xuICBwcml2YXRlIGNlbGxHcm91cENvbG9ycyA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KCk7XG4gIC8qKiBUaGUgZ3JvdXBpbmcge0BsaW5rIGNlbGxHcm91cENvbG9yc30gYmVsb25ncyB0byDigJQgYSByZXBlYXQgcmVxdWVzdCBmb3IgaXQgaXMgYSBuby1vcC4gKi9cbiAgcHJpdmF0ZSBjZWxsR3JvdXBDb2xvcnNGb3I6IHN0cmluZyB8IG51bGwgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gIC8qKiBMYXRlc3Qgd2lucyBhbW9uZyBjb2xvdXIgbG9hZHMgZm9yIHtAbGluayBjZWxsR3JvdXBDb2xvcnN9LiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IGNlbGxHcm91cENvbG9yc0xvYWQgPSBuZXcgU3VwZXJzZWRlKCk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSB6b25lOiBOZ1pvbmUsXG4gICAgcHJpdmF0ZSByZWFkb25seSBjZHI6IENoYW5nZURldGVjdG9yUmVmLFxuICApIHt9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGlmIChjaGFuZ2VzWyd2aWV3J10pIHRoaXMuZ2VuZVRyZWUgPSBidWlsZEdlbmVUcmVlKHRoaXMudmlldy50cmFuc2NyaXB0R2VuZXMsIHRoaXMudmlldy50cmFuc2NyaXB0R2VuZUdyb3Vwcyk7XG4gICAgLy8gQSBzYW1lLW5hbWVkIGdyb3VwaW5nIG9mIGEgbmV3IGRhdGFzZXQgaXMgbm90IHRoZSBvbGQgb25lLlxuICAgIGlmIChjaGFuZ2VzWydkYXRhc2V0J10pIHtcbiAgICAgIHRoaXMuY2VsbEdyb3VwQ29sb3JzRm9yID0gdW5kZWZpbmVkO1xuICAgICAgY29uc3QgY29kZWQgPSB0aGlzLmRhdGFzZXQ/LnRyYW5zY3JpcHRUaWxlcz8uZ2VuZXM7XG4gICAgICB0aGlzLmNhbkhpZGVBbGxHZW5lcyA9ICEhY29kZWQ/Lmxlbmd0aDtcbiAgICAgIHRoaXMuYWxsR2VuZUxpc3QgPSBjb2RlZD8ubGVuZ3RoID8gY29kZWQgOiAodGhpcy5kYXRhc2V0Py5mZWF0dXJlcz8ubmFtZXMgPz8gbnVsbCk7XG4gICAgfVxuICAgIHRoaXMucmVidWlsZFJvd3MoKTtcbiAgICB2b2lkIHRoaXMucmVmcmVzaENlbGxHcm91cENvbG9ycygpO1xuICB9XG5cbiAgcHJpdmF0ZSByZWJ1aWxkUm93cygpOiB2b2lkIHtcbiAgICBjb25zdCBnZW5lcyA9IHRoaXMudmlldy50cmFuc2NyaXB0R2VuZXM7XG4gICAgdGhpcy5yb3dzID0gbmV3IE1hcChcbiAgICAgIGdlbmVzLm1hcCgoZ2VuZSwgc2xvdCkgPT4gW1xuICAgICAgICBnZW5lLFxuICAgICAgICB7XG4gICAgICAgICAgc2hvd246IHRoaXMuaXNHZW5lU2hvd24oZ2VuZSksXG4gICAgICAgICAgc3dhdGNoOiB0aGlzLmdlbmVTd2F0Y2hPZihnZW5lKSxcbiAgICAgICAgICBwb2ludHM6IGdseXBoUG9pbnRzKHRoaXMuZ2x5cGhPZihnZW5lLCBzbG90KSksXG4gICAgICAgICAgY291bnQ6IHRoaXMuZ2VuZUNvdW50T2YoZ2VuZSksXG4gICAgICAgIH0sXG4gICAgICBdKSxcbiAgICApO1xuICAgIHRoaXMuZ3JvdXBTaG93biA9IG5ldyBNYXAoXG4gICAgICB0aGlzLmdlbmVUcmVlXG4gICAgICAgIC5maWx0ZXIoKG5vZGUpID0+IG5vZGUubmFtZSlcbiAgICAgICAgLm1hcCgobm9kZSkgPT4gW25vZGUubmFtZSBhcyBzdHJpbmcsIHRoaXMuYXJlR2VuZXNTaG93bihub2RlLmdlbmVzKV0pLFxuICAgICk7XG4gICAgdGhpcy5yb290U2hvd24gPSB0aGlzLnZpZXcudHJhbnNjcmlwdEFsbEdlbmVzID8gdGhpcy5hbnlPZkFsbEdlbmVzU2hvd24oKSA6IHRoaXMuYXJlR2VuZXNTaG93bihnZW5lcyk7XG4gICAgdGhpcy5zb3J0ZWRUcmVlID0gdGhpcy5nZW5lVHJlZS5tYXAoKG5vZGUpID0+ICh7IC4uLm5vZGUsIGdlbmVzOiB0aGlzLnNvcnRlZChub2RlLmdlbmVzKSB9KSk7XG4gICAgdGhpcy5yZWJ1aWxkQWxsUm93cygpO1xuICB9XG5cbiAgLyoqIFdoZXRoZXIgdGhlIHJvd3MgYXJlIG9yZGVyZWQgYnkgY291bnQ6IGNob3NlbiwgYW5kIGNvdW50cyB0byBvcmRlciBieS4gKi9cbiAgcHJvdGVjdGVkIGdldCBieUNvdW50KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmdlbmVTb3J0ID09PSAnY291bnQnICYmICEhdGhpcy5nZW5lQ291bnRzO1xuICB9XG5cbiAgLyoqIFRoZSBzb3J0IHN3aXRjaCBpcyBvZmZlcmVkIG9uY2UgdGhlcmUgYXJlIGNvdW50cyB0byBzb3J0IGJ5LiAqL1xuICBwcm90ZWN0ZWQgZ2V0IHNvcnRTaG93bigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISF0aGlzLmdlbmVDb3VudHM7XG4gIH1cblxuICBwcm90ZWN0ZWQgb25HZW5lU29ydChzb3J0OiBHZW5lU29ydCk6IHZvaWQge1xuICAgIGlmIChzb3J0ID09PSB0aGlzLmdlbmVTb3J0KSByZXR1cm47XG4gICAgdGhpcy5nZW5lU29ydCA9IHNvcnQ7XG4gICAgdGhpcy5yZWJ1aWxkUm93cygpO1xuICB9XG5cbiAgLyoqIGBnZW5lc2AgaW4gdGhlIHJvd3MnIG9yZGVyOiBieSBjb3VudCwgbW9zdCBmaXJzdCAodGllcyBieSBuYW1lKSwgZWxzZSBieSBuYW1lLiAqL1xuICBwcml2YXRlIHNvcnRlZChnZW5lczogcmVhZG9ubHkgc3RyaW5nW10pOiBzdHJpbmdbXSB7XG4gICAgaWYgKCF0aGlzLmJ5Q291bnQpIHJldHVybiBbLi4uZ2VuZXNdLnNvcnQoYnlOYW1lKTtcbiAgICBjb25zdCBjb3VudHMgPSB0aGlzLmdlbmVDb3VudHMgPz8ge307XG4gICAgcmV0dXJuIFsuLi5nZW5lc10uc29ydCgoYSwgYikgPT4gKGNvdW50c1tiXSA/PyAwKSAtIChjb3VudHNbYV0gPz8gMCkgfHwgYnlOYW1lKGEsIGIpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgYWxsLWdlbmVzIGxpc3QncyByb3dzOiB0aGUgZ2VuZXMgbWF0Y2hpbmcgdGhlIGZpbHRlciwgdXAgdG8gdGhlIGNhcC4gQnVpbHQgb25seSB3aGlsZVxuICAgKiB0aGUgbGlzdCBpcyBvcGVuOiB0aGUgY291bnRzIGluIHZpZXcgY2hhbmdlIHdpdGggZXZlcnkgcGFuLCBhbmQgdGhlIGxpc3QgY2FuIGJlIHRob3VzYW5kcy5cbiAgICovXG4gIHByaXZhdGUgcmVidWlsZEFsbFJvd3MoKTogdm9pZCB7XG4gICAgY29uc3QgbGlzdCA9IHRoaXMudmlldy50cmFuc2NyaXB0QWxsR2VuZXMgJiYgdGhpcy5hbGxHZW5lc09wZW4gPyB0aGlzLmFsbEdlbmVMaXN0IDogbnVsbDtcbiAgICBpZiAoIWxpc3QpIHtcbiAgICAgIHRoaXMuYWxsUm93cyA9IFtdO1xuICAgICAgdGhpcy5hbGxHZW5lc01hdGNoZWQgPSAwO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBuZWVkbGUgPSB0aGlzLmFsbEdlbmVzRmlsdGVyLnRyaW0oKS50b0xvd2VyQ2FzZSgpO1xuICAgIGNvbnN0IHNob3duID0gYWxsR2VuZVNob3duQnkodGhpcy52aWV3LnRyYW5zY3JpcHRBbGxHZW5lc0hpZGRlbik7XG4gICAgLy8gRXZlcnkgbWF0Y2gsIG9yZGVyZWQsIGFuZCBvbmx5IHRoZW4gY3V0OiBieSBjb3VudCB0aGUgZmlyc3Qgcm93cyBhcmUgdGhlIG1vc3QgYWJ1bmRhbnQuXG4gICAgY29uc3QgY29kZXMgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xuICAgIGxpc3QuZm9yRWFjaCgoZ2VuZSwgY29kZSkgPT4ge1xuICAgICAgLy8gQW4gZW1wdHkgbmFtZSBpcyBhIGNvZGUgbm8gdHJhbnNjcmlwdCBjYXJyaWVzIChhIGNvbnRyb2wgcHJvYmUpLlxuICAgICAgaWYgKCFnZW5lIHx8IChuZWVkbGUgJiYgIWdlbmUudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyhuZWVkbGUpKSkgcmV0dXJuO1xuICAgICAgaWYgKCFjb2Rlcy5oYXMoZ2VuZSkpIGNvZGVzLnNldChnZW5lLCBjb2RlKTtcbiAgICB9KTtcbiAgICB0aGlzLmFsbFJvd3MgPSB0aGlzLnNvcnRlZChbLi4uY29kZXMua2V5cygpXSlcbiAgICAgIC5zbGljZSgwLCBBTExfR0VORVNfUk9XUylcbiAgICAgIC5tYXAoKGdlbmUpID0+ICh7XG4gICAgICAgIGdlbmUsXG4gICAgICAgIHNob3duOiBzaG93bihnZW5lKSxcbiAgICAgICAgc3dhdGNoOiB0aGlzLmNhbkhpZGVBbGxHZW5lcyA/IHRoaXMuYWxsR2VuZUNvbG9yT2YoZ2VuZSwgY29kZXMuZ2V0KGdlbmUpISkgOiBudWxsLFxuICAgICAgICBjb2RlOiBjb2Rlcy5nZXQoZ2VuZSkhLFxuICAgICAgICBjb3VudDogdGhpcy5nZW5lQ291bnRPZihnZW5lKSxcbiAgICAgIH0pKTtcbiAgICB0aGlzLmFsbEdlbmVzTWF0Y2hlZCA9IGNvZGVzLnNpemU7XG4gIH1cblxuICAvKiogV2hldGhlciBcIkFsbCBnZW5lc1wiIGRyYXdzIGFueXRoaW5nOiBub3Qgc3dpdGNoZWQgb2ZmIHdob2xlLCBub3IgZXZlcnkgbGlzdGVkIGdlbmUgaGlkZGVuLiAqL1xuICBwcml2YXRlIGFueU9mQWxsR2VuZXNTaG93bigpOiBib29sZWFuIHtcbiAgICBpZiAoYWxsR2VuZXNIaWRkZW4odGhpcy52aWV3KSkgcmV0dXJuIGZhbHNlO1xuICAgIGlmICghdGhpcy5jYW5IaWRlQWxsR2VuZXMgfHwgIXRoaXMuYWxsR2VuZUxpc3QpIHJldHVybiB0cnVlO1xuICAgIGNvbnN0IHNob3duID0gYWxsR2VuZVNob3duQnkodGhpcy52aWV3LnRyYW5zY3JpcHRBbGxHZW5lc0hpZGRlbik7XG4gICAgcmV0dXJuIHRoaXMuYWxsR2VuZUxpc3Quc29tZSgoZykgPT4gZyAmJiBzaG93bihnKSk7XG4gIH1cblxuICAvKiogQSBnZW5lIG9mIFwiQWxsIGdlbmVzXCIgaW4gaXRzIGNvbG91ciBieSBnZW5lOiBpdHMgY2hvc2VuIG9uZSwgZWxzZSB0aGUgcGFsZXR0ZSdzIGJ5IGNvZGUuICovXG4gIHByaXZhdGUgYWxsR2VuZUNvbG9yT2YoZ2VuZTogc3RyaW5nLCBjb2RlOiBudW1iZXIpOiBzdHJpbmcge1xuICAgIHJldHVybiAoXG4gICAgICB0aGlzLnZpZXcudHJhbnNjcmlwdEdlbmVDb2xvcnNbZ2VuZV0gfHxcbiAgICAgIERFRkFVTFRfQ0FURUdPUklDQUxfUEFMRVRURVtjb2RlICUgREVGQVVMVF9DQVRFR09SSUNBTF9QQUxFVFRFLmxlbmd0aF1cbiAgICApO1xuICB9XG5cbiAgcHJvdGVjdGVkIHRvZ2dsZUFsbEdlbmVzT3BlbigpOiB2b2lkIHtcbiAgICB0aGlzLmFsbEdlbmVzT3BlbiA9ICF0aGlzLmFsbEdlbmVzT3BlbjtcbiAgICB0aGlzLnJlYnVpbGRBbGxSb3dzKCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgb25BbGxHZW5lc0ZpbHRlcih0ZXh0OiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmFsbEdlbmVzRmlsdGVyID0gdGV4dDtcbiAgICB0aGlzLnJlYnVpbGRBbGxSb3dzKCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgdG9nZ2xlR2VuZUdyb3VwKG5hbWU6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IG5leHQgPSBuZXcgU2V0KHRoaXMuY29sbGFwc2VkR2VuZUdyb3Vwcyk7XG4gICAgaWYgKG5leHQuaGFzKG5hbWUpKSBuZXh0LmRlbGV0ZShuYW1lKTtcbiAgICBlbHNlIG5leHQuYWRkKG5hbWUpO1xuICAgIHRoaXMuY29sbGFwc2VkR2VuZUdyb3VwcyA9IG5leHQ7XG4gIH1cblxuICBwcm90ZWN0ZWQgaXNHZW5lU2hvd24oZ2VuZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICF0aGlzLnZpZXcudHJhbnNjcmlwdEhpZGRlbkdlbmVzLmluY2x1ZGVzKGdlbmUpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFyZUdlbmVzU2hvd24oZ2VuZXM6IHN0cmluZ1tdKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGdlbmVzLnNvbWUoKGcpID0+IHRoaXMuaXNHZW5lU2hvd24oZykpO1xuICB9XG5cbiAgLyoqIFRoZSBleWUgdG9nZ2xlOiBoaWRlIG9yIHNob3cgZ2VuZXMgd2l0aG91dCByZW1vdmluZyB0aGVtIGZyb20gdGhlIHNlbGVjdGlvbi4gKi9cbiAgcHJvdGVjdGVkIG9uR2VuZXNTaG93bihnZW5lczogc3RyaW5nW10sIG9uOiBib29sZWFuKTogdm9pZCB7XG4gICAgdGhpcy5jb250cm9scz8uc2V0Vmlld1N0YXRlKHtcbiAgICAgIHRyYW5zY3JpcHRIaWRkZW5HZW5lczogdG9nZ2xlSGlkZGVuKHRoaXMudmlldy50cmFuc2NyaXB0SGlkZGVuR2VuZXMsIGdlbmVzLCBvbiksXG4gICAgfSk7XG4gIH1cblxuICAvKiogVGhlIHJvb3QgZXllIHdoaWxlIGV2ZXJ5IGdlbmUgaXMgZHJhd246IGhpZGUgb3Igc2hvdyB0aGVtIGFsbCAodGhlICfCsScgbGVhdmVzIFwiQWxsIGdlbmVzXCIpLiAqL1xuICBwcm90ZWN0ZWQgb25BbGxHZW5lc1Nob3duKG9uOiBib29sZWFuKTogdm9pZCB7XG4gICAgdGhpcy5jb250cm9scz8uc2V0Vmlld1N0YXRlKHsgdHJhbnNjcmlwdEFsbEdlbmVzSGlkZGVuOiBvbiA/IFtdIDogW0FMTF9HRU5FU10gfSk7XG4gIH1cblxuICAvKiogT25lIGdlbmUncyBleWUgaW4gdGhlIGFsbC1nZW5lcyBsaXN0LiBTaG93aW5nIG9uZSB3aGlsZSBhbGwgYXJlIG9mZiBzaG93cyBpdCBhbG9uZS4gKi9cbiAgcHJvdGVjdGVkIG9uQWxsR2VuZVNob3duKGdlbmU6IHN0cmluZywgb246IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuY2FuSGlkZUFsbEdlbmVzKSByZXR1cm47XG4gICAgdGhpcy5jb250cm9scz8uc2V0Vmlld1N0YXRlKHtcbiAgICAgIHRyYW5zY3JpcHRBbGxHZW5lc0hpZGRlbjogdG9nZ2xlQWxsR2VuZUhpZGRlbih0aGlzLnZpZXcudHJhbnNjcmlwdEFsbEdlbmVzSGlkZGVuLCBnZW5lLCBvbiksXG4gICAgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgb25HZW5lQ29sb3IoZ2VuZTogc3RyaW5nLCBoZXg6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuY29udHJvbHM/LnNldFZpZXdTdGF0ZSh7IHRyYW5zY3JpcHRHZW5lQ29sb3JzOiB7IC4uLnRoaXMudmlldy50cmFuc2NyaXB0R2VuZUNvbG9ycywgW2dlbmVdOiBoZXggfSB9KTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBwZXItZ2VuZSBpY29uIGFuZCBjb2xvdXIgcGlja2VyIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIHByb3RlY3RlZCBvcGVuR2VuZVN0eWxlKGV2ZW50OiBFdmVudCwgZ2VuZTogc3RyaW5nLCBwYW5lbDogeyB0b2dnbGUoZTogRXZlbnQpOiB2b2lkOyBoaWRlKCk6IHZvaWQgfSk6IHZvaWQge1xuICAgIGlmICh0aGlzLnN0eWxlR2VuZSA9PT0gZ2VuZSkge1xuICAgICAgcGFuZWwudG9nZ2xlKGV2ZW50KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5zdHlsZUdlbmUgPSBnZW5lO1xuICAgIHBhbmVsLmhpZGUoKTtcbiAgICAvLyBSZS1vcGVuIGFuY2hvcmVkIG9uIHRoZSByb3cgdGhhdCB3YXMgY2xpY2tlZCwgb25jZSB0aGUgcGFuZWwgaGFzIGNsb3NlZC5cbiAgICBzZXRUaW1lb3V0KCgpID0+IHBhbmVsLnRvZ2dsZShldmVudCkpO1xuICB9XG5cbiAgLyoqIFRoZSBpY29uIHRoZSBvcGVuIHBpY2tlciBzaG93cyBhcyBjaG9zZW4uICovXG4gIHByb3RlY3RlZCBnZXQgc3R5bGVHbHlwaCgpOiBUcmFuc2NyaXB0R2x5cGhOYW1lIHwgbnVsbCB7XG4gICAgY29uc3QgZ2VuZSA9IHRoaXMuc3R5bGVHZW5lO1xuICAgIHJldHVybiBnZW5lID8gdGhpcy5nbHlwaE9mKGdlbmUsIE1hdGgubWF4KDAsIHRoaXMudmlldy50cmFuc2NyaXB0R2VuZXMuaW5kZXhPZihnZW5lKSkpIDogbnVsbDtcbiAgfVxuXG4gIHByb3RlY3RlZCBnbHlwaFBvaW50cyhnbHlwaDogVHJhbnNjcmlwdEdseXBoTmFtZSk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGdseXBoUG9pbnRzKGdseXBoKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBnbHlwaE9mKGdlbmU6IHN0cmluZywgc2xvdDogbnVtYmVyKTogVHJhbnNjcmlwdEdseXBoTmFtZSB7XG4gICAgcmV0dXJuIHRoaXMudmlldy50cmFuc2NyaXB0R2x5cGhzW2dlbmVdID8/IGRlZmF1bHRHbHlwaEZvcihzbG90KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvbkdseXBoKGdlbmU6IHN0cmluZywgZ2x5cGg6IFRyYW5zY3JpcHRHbHlwaE5hbWUpOiB2b2lkIHtcbiAgICB0aGlzLmNvbnRyb2xzPy5zZXRWaWV3U3RhdGUoeyB0cmFuc2NyaXB0R2x5cGhzOiB7IC4uLnRoaXMudmlldy50cmFuc2NyaXB0R2x5cGhzLCBbZ2VuZV06IGdseXBoIH0gfSk7XG4gIH1cblxuICAvKiogQmFjayB0byB0aGUgZ2VuZSdzIGRlZmF1bHQgaWNvbiBhbmQgY29sb3VyIChieSBpdHMgcG9zaXRpb24gaW4gdGhlIGxpc3QpLiAqL1xuICBwcm90ZWN0ZWQgcmVzZXRHZW5lU3R5bGUoZ2VuZTogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgY29sb3JzID0geyAuLi50aGlzLnZpZXcudHJhbnNjcmlwdEdlbmVDb2xvcnMgfTtcbiAgICBjb25zdCBnbHlwaHMgPSB7IC4uLnRoaXMudmlldy50cmFuc2NyaXB0R2x5cGhzIH07XG4gICAgZGVsZXRlIGNvbG9yc1tnZW5lXTtcbiAgICBkZWxldGUgZ2x5cGhzW2dlbmVdO1xuICAgIHRoaXMuY29udHJvbHM/LnNldFZpZXdTdGF0ZSh7IHRyYW5zY3JpcHRHZW5lQ29sb3JzOiBjb2xvcnMsIHRyYW5zY3JpcHRHbHlwaHM6IGdseXBocyB9KTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBjb2xvdXJzIGFuZCBjb3VudHMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgLyoqIFRoZSBjb2xvdXIgZ2VuZSBgc2xvdGAgaXMgZHJhd24gaW4gd2hlbiB0cmFuc2NyaXB0cyBhcmUgY29sb3VyZWQgYnkgZ2VuZS4gKi9cbiAgZ2VuZUNvbG9yKHNsb3Q6IG51bWJlcik6IHN0cmluZyB7XG4gICAgY29uc3QgZ2VuZSA9IHRoaXMudmlldz8udHJhbnNjcmlwdEdlbmVzW3Nsb3RdO1xuICAgIHJldHVybiAoXG4gICAgICAoZ2VuZSAmJiB0aGlzLnZpZXcudHJhbnNjcmlwdEdlbmVDb2xvcnNbZ2VuZV0pIHx8XG4gICAgICBERUZBVUxUX0NBVEVHT1JJQ0FMX1BBTEVUVEVbc2xvdCAlIERFRkFVTFRfQ0FURUdPUklDQUxfUEFMRVRURS5sZW5ndGhdXG4gICAgKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZW5lQ29sb3JPZihnZW5lOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmdlbmVDb2xvcihNYXRoLm1heCgwLCB0aGlzLnZpZXcudHJhbnNjcmlwdEdlbmVzLmluZGV4T2YoZ2VuZSkpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgY29sb3VyIHRoZSBvcGVuIHBpY2tlciBzaG93czogd2l0aCBcIkFsbCBnZW5lc1wiLCB0aGUgZ2VuZSdzIGNvbG91ciBhbW9uZyBldmVyeSBnZW5lIChpdHNcbiAgICogY2hvc2VuIG9uZSwgZWxzZSB0aGUgcGFsZXR0ZSdzIGJ5IGl0cyBjb2RlKSwgYXMgaXRzIHJvdyBhbmQgaXRzIG1hcmtlcnMgaGF2ZSBpdC5cbiAgICovXG4gIHByb3RlY3RlZCBzdHlsZUNvbG9yT2YoZ2VuZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBpZiAodGhpcy52aWV3LnRyYW5zY3JpcHRBbGxHZW5lcykge1xuICAgICAgY29uc3Qgcm93ID0gdGhpcy5hbGxSb3dzLmZpbmQoKHIpID0+IHIuZ2VuZSA9PT0gZ2VuZSk7XG4gICAgICBpZiAocm93KSByZXR1cm4gdGhpcy5hbGxHZW5lQ29sb3JPZihnZW5lLCByb3cuY29kZSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmdlbmVDb2xvck9mKGdlbmUpO1xuICB9XG5cbiAgLyoqIEluIENsdXN0ZXIgY29sb3VyaW5nLCBhIGdlbmUncyBzd2F0Y2ggaXMgaXRzIGNsdXN0ZXIncyBjb2xvdXIsIGFzIGl0cyBtYXJrZXJzIGFyZS4gKi9cbiAgcHJvdGVjdGVkIGdlbmVTd2F0Y2hPZihnZW5lOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGlmICh0aGlzLnZpZXcudHJhbnNjcmlwdENvbG9yQnkgIT09ICdjbHVzdGVyJykgcmV0dXJuIHRoaXMuZ2VuZUNvbG9yT2YoZ2VuZSk7XG4gICAgcmV0dXJuIHRoaXMuY2x1c3RlckNvbG9ycygpLmdldChjbHVzdGVyT2ZHZW5lKGdlbmUsIHRoaXMudmlldy50cmFuc2NyaXB0R2VuZUdyb3VwcykpID8/IHRoaXMuZ2VuZUNvbG9yT2YoZ2VuZSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2VuZUNvdW50T2YoZ2VuZTogc3RyaW5nKTogbnVtYmVyIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuZ2VuZUNvdW50cyA/ICh0aGlzLmdlbmVDb3VudHNbZ2VuZV0gPz8gMCkgOiBudWxsO1xuICB9XG5cbiAgcHJvdGVjdGVkIHRyYWNrQnlOb2RlID0gKF9pOiBudW1iZXIsIG5vZGU6IHsgbmFtZTogc3RyaW5nIHwgbnVsbCB9KSA9PiBub2RlLm5hbWUgPz8gJyc7XG4gIHByb3RlY3RlZCB0cmFja0J5TGFiZWxTdHJpbmcgPSAoX2k6IG51bWJlciwgczogc3RyaW5nKSA9PiBzO1xuICBwcm90ZWN0ZWQgdHJhY2tCeUFsbFJvdyA9IChfaTogbnVtYmVyLCByb3c6IEFsbEdlbmVSb3dWaWV3KSA9PiByb3cuZ2VuZTtcblxuICAvKipcbiAgICogVGhlIGNsdXN0ZXIgY29sb3VycywgcmVidWlsdCBvbmx5IHdoZW4gd2hhdCB0aGV5IGNvbWUgZnJvbSBjaGFuZ2VzLiBUaGUgdGVtcGxhdGUgYXNrc1xuICAgKiBvbmNlIHBlciBnZW5lIHJvdyBwZXIgY2hhbmdlLWRldGVjdGlvbiBwYXNzLCBhbmQgcmVidWlsZGluZyBwZXIgY2FsbCBtYWRlIHRoYXQgTyhHwrIpLlxuICAgKi9cbiAgcHJpdmF0ZSBjbHVzdGVyQ29sb3JzKCk6IE1hcDxzdHJpbmcsIHN0cmluZz4ge1xuICAgIGNvbnN0IHsgdHJhbnNjcmlwdEdlbmVzOiBnZW5lcywgdHJhbnNjcmlwdEdlbmVHcm91cHM6IGdyb3VwcyB9ID0gdGhpcy52aWV3O1xuICAgIGNvbnN0IGhpdCA9IHRoaXMuY2x1c3RlckNvbG9yTWVtbztcbiAgICBpZiAoaGl0ICYmIGhpdC5nZW5lcyA9PT0gZ2VuZXMgJiYgaGl0Lmdyb3VwcyA9PT0gZ3JvdXBzICYmIGhpdC5jZWxsQ29sb3JzID09PSB0aGlzLmNlbGxHcm91cENvbG9ycykge1xuICAgICAgcmV0dXJuIGhpdC5jb2xvcnM7XG4gICAgfVxuICAgIGNvbnN0IGNvbG9ycyA9IGNsdXN0ZXJDb2xvck1hcChnZW5lcywgZ3JvdXBzLCB0aGlzLmNlbGxHcm91cENvbG9ycywgREVGQVVMVF9DQVRFR09SSUNBTF9QQUxFVFRFKTtcbiAgICB0aGlzLmNsdXN0ZXJDb2xvck1lbW8gPSB7IGdlbmVzLCBncm91cHMsIGNlbGxDb2xvcnM6IHRoaXMuY2VsbEdyb3VwQ29sb3JzLCBjb2xvcnMgfTtcbiAgICByZXR1cm4gY29sb3JzO1xuICB9XG4gIHByaXZhdGUgY2x1c3RlckNvbG9yTWVtbzoge1xuICAgIGdlbmVzOiBTcGF0aWFsVmlld1N0YXRlWyd0cmFuc2NyaXB0R2VuZXMnXTtcbiAgICBncm91cHM6IFNwYXRpYWxWaWV3U3RhdGVbJ3RyYW5zY3JpcHRHZW5lR3JvdXBzJ107XG4gICAgY2VsbENvbG9yczogTWFwPHN0cmluZywgc3RyaW5nPjtcbiAgICBjb2xvcnM6IE1hcDxzdHJpbmcsIHN0cmluZz47XG4gIH0gfCBudWxsID0gbnVsbDtcblxuICBwcml2YXRlIGFzeW5jIHJlZnJlc2hDZWxsR3JvdXBDb2xvcnMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgY29sdW1uID0gdGhpcy5kYXRhc2V0ID8gY2VsbFR5cGVDb2x1bW5Gb3IodGhpcy5kYXRhc2V0LCB0aGlzLnZpZXcpIDogbnVsbDtcbiAgICAvLyBUaGUgdXNlcidzIGNvbG91cnMgZm9yIHRoZSBncm91cGluZyBhcmUgcGFydCBvZiB3aGF0IHRoZSBjbHVzdGVyIHN3YXRjaGVzIHNob3cuXG4gICAgY29uc3Qga2V5ID0gY29sdW1uID09PSBudWxsID8gbnVsbCA6IGAke2NvbHVtbn1cXHUwMDAxJHtncm91cENvbG9yc0tleShjb2x1bW4sIHRoaXMudmlldy5ncm91cENvbG9ycyl9YDtcbiAgICBpZiAoa2V5ID09PSB0aGlzLmNlbGxHcm91cENvbG9yc0ZvcikgcmV0dXJuO1xuICAgIHRoaXMuY2VsbEdyb3VwQ29sb3JzRm9yID0ga2V5O1xuICAgIGNvbnN0IHRhc2sgPSB0aGlzLmNlbGxHcm91cENvbG9yc0xvYWQubmV4dCgpO1xuICAgIGNvbnN0IG1hcCA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KCk7XG4gICAgY29uc3QgbWV0YSA9IGNvbHVtbiA/IHRoaXMuZGF0YXNldD8uY29sdW1ucy5maW5kKChjKSA9PiBjLm5hbWUgPT09IGNvbHVtbikgOiBudWxsO1xuICAgIGlmIChtZXRhICYmIG1ldGEua2luZCA9PT0gJ2NhdGVnb3JpY2FsJyAmJiB0aGlzLmNvbnRyb2xzKSB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBjb2xvcnMgPSBhd2FpdCB0aGlzLmNvbnRyb2xzLmNhdGVnb3J5Q29sb3JzKGNvbHVtbiEpO1xuICAgICAgICBtZXRhLmNhdGVnb3JpZXMuZm9yRWFjaCgoYywgaykgPT4ge1xuICAgICAgICAgIGlmIChjb2xvcnNba10pIG1hcC5zZXQoYywgY29sb3JzW2tdKTtcbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8gTm8gY29sb3VyczogcGFsZXR0ZSBjb2xvdXJzLCBhcyB0aGUgbWFya2VycyBmYWxsIGJhY2sgdG8uXG4gICAgICB9XG4gICAgfVxuICAgIC8vIFRoZSBjZWxscycgZ3JvdXBpbmcgY2hhbmdlZCB3aGlsZSB0aGUgY29sb3VycyBsb2FkZWQ6IHRoZSBuZXdlciByZXF1ZXN0IGFwcGxpZXMgaXRzIG93bi5cbiAgICBpZiAoIXRhc2suaXNDdXJyZW50KCkpIHJldHVybjtcbiAgICB0aGlzLnpvbmUucnVuKCgpID0+IHtcbiAgICAgIHRoaXMuY2VsbEdyb3VwQ29sb3JzID0gbWFwO1xuICAgICAgdGhpcy5yZWJ1aWxkUm93cygpO1xuICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfSk7XG4gIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJzYy1zdWJoZWFkXCI+U2VsZWN0ZWQgZ2VuZXM8L2Rpdj5cbjxkaXYgY2xhc3M9XCJzYy1nZW5lLXNvcnRcIiAqbmdJZj1cInNvcnRTaG93blwiIHJvbGU9XCJncm91cFwiIGFyaWEtbGFiZWw9XCJTb3J0IGdlbmVzXCI+XG4gIDxzcGFuIGNsYXNzPVwic2MtbGJsXCI+U29ydCBieTwvc3Bhbj5cbiAgPGJ1dHRvblxuICAgIHR5cGU9XCJidXR0b25cIlxuICAgIGNsYXNzPVwic2Mtc29ydC1idG5cIlxuICAgIFtjbGFzcy5hY3RpdmVdPVwiIWJ5Q291bnRcIlxuICAgIFthdHRyLmFyaWEtcHJlc3NlZF09XCIhYnlDb3VudFwiXG4gICAgKGNsaWNrKT1cIm9uR2VuZVNvcnQoJ25hbWUnKVwiXG4gID5cbiAgICBOYW1lXG4gIDwvYnV0dG9uPlxuICA8YnV0dG9uXG4gICAgdHlwZT1cImJ1dHRvblwiXG4gICAgY2xhc3M9XCJzYy1zb3J0LWJ0blwiXG4gICAgW2NsYXNzLmFjdGl2ZV09XCJieUNvdW50XCJcbiAgICBbYXR0ci5hcmlhLXByZXNzZWRdPVwiYnlDb3VudFwiXG4gICAgdGl0bGU9XCJUcmFuc2NyaXB0cyBpbiB2aWV3LCBtb3N0IGZpcnN0XCJcbiAgICAoY2xpY2spPVwib25HZW5lU29ydCgnY291bnQnKVwiXG4gID5cbiAgICBDb3VudFxuICA8L2J1dHRvbj5cbjwvZGl2PlxuPGRpdiBjbGFzcz1cInNjLWdlbmUtdHJlZVwiPlxuICA8ZGl2IGNsYXNzPVwic2MtZ2VuZS1yb3cgc2MtZ2VuZS1yb290XCI+XG4gICAgPGJ1dHRvblxuICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICBjbGFzcz1cInNjLWV5ZVwiXG4gICAgICAoY2xpY2spPVwiXG4gICAgICAgIHZpZXcudHJhbnNjcmlwdEFsbEdlbmVzID8gb25BbGxHZW5lc1Nob3duKCFyb290U2hvd24pIDogb25HZW5lc1Nob3duKHZpZXcudHJhbnNjcmlwdEdlbmVzLCAhcm9vdFNob3duKVxuICAgICAgXCJcbiAgICA+XG4gICAgICA8aSBjbGFzcz1cInBpXCIgW2NsYXNzLnBpLWV5ZV09XCJyb290U2hvd25cIiBbY2xhc3MucGktZXllLXNsYXNoXT1cIiFyb290U2hvd25cIj48L2k+XG4gICAgPC9idXR0b24+XG4gICAgPHNwYW4gY2xhc3M9XCJzYy1ncm91cC1sYWJlbFwiPkdlbmVzPC9zcGFuPlxuICAgIDxzcGFuIGNsYXNzPVwic2MtY291bnRcIlxuICAgICAgPih7eyAodmlldy50cmFuc2NyaXB0QWxsR2VuZXMgPyBnZW5lVG90YWwgOiB2aWV3LnRyYW5zY3JpcHRHZW5lcy5sZW5ndGgpIHwgbnVtYmVyIH19L3t7XG4gICAgICAgIGdlbmVUb3RhbCB8IG51bWJlclxuICAgICAgfX0pPC9zcGFuXG4gICAgPlxuICAgIDxidXR0b25cbiAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgY2xhc3M9XCJzYy1pY29uLWJ0blwiXG4gICAgICAoY2xpY2spPVwiZ2VuZVRyZWVPcGVuID0gIWdlbmVUcmVlT3BlblwiXG4gICAgICAqbmdJZj1cIiF2aWV3LnRyYW5zY3JpcHRBbGxHZW5lcyAmJiB2aWV3LnRyYW5zY3JpcHRHZW5lcy5sZW5ndGhcIlxuICAgID5cbiAgICAgIDxpIGNsYXNzPVwicGlcIiBbY2xhc3MucGktY2hldnJvbi1kb3duXT1cImdlbmVUcmVlT3BlblwiIFtjbGFzcy5waS1jaGV2cm9uLXJpZ2h0XT1cIiFnZW5lVHJlZU9wZW5cIj48L2k+XG4gICAgPC9idXR0b24+XG4gICAgPGJ1dHRvblxuICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICBjbGFzcz1cInNjLWljb24tYnRuXCJcbiAgICAgIChjbGljayk9XCJ0b2dnbGVBbGxHZW5lc09wZW4oKVwiXG4gICAgICAqbmdJZj1cInZpZXcudHJhbnNjcmlwdEFsbEdlbmVzICYmIGFsbEdlbmVMaXN0Py5sZW5ndGhcIlxuICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCJhbGxHZW5lc09wZW4gPyAnSGlkZSB0aGUgZ2VuZSBsaXN0JyA6ICdTaG93IGV2ZXJ5IGdlbmUnXCJcbiAgICA+XG4gICAgICA8aSBjbGFzcz1cInBpXCIgW2NsYXNzLnBpLWNoZXZyb24tZG93bl09XCJhbGxHZW5lc09wZW5cIiBbY2xhc3MucGktY2hldnJvbi1yaWdodF09XCIhYWxsR2VuZXNPcGVuXCI+PC9pPlxuICAgIDwvYnV0dG9uPlxuICA8L2Rpdj5cbiAgPCEtLSBcIkFsbCBnZW5lc1wiOiBldmVyeSBnZW5lIG9mIHRoZSBkYXRhc2V0LCBlYWNoIHdpdGggaXRzIGV5ZSB3aGVuIHRoZSBkYXRhc2V0IHNheXMgd2hpY2hcbiAgICAgICB0cmFuc2NyaXB0cyBhcmUgd2hvc2UgKGl0cyBnZW5lIGxpc3QgaW4gY29kZSBvcmRlcikuIC0tPlxuICA8bmctY29udGFpbmVyICpuZ0lmPVwiYWxsR2VuZXNPcGVuICYmIHZpZXcudHJhbnNjcmlwdEFsbEdlbmVzICYmIGFsbEdlbmVMaXN0Py5sZW5ndGhcIj5cbiAgICA8aW5wdXRcbiAgICAgIHBJbnB1dFRleHRcbiAgICAgIGNsYXNzPVwic2MtZ2VuZS1maWx0ZXJcIlxuICAgICAgcGxhY2Vob2xkZXI9XCJGaWx0ZXIgZ2VuZXPigKZcIlxuICAgICAgYXJpYS1sYWJlbD1cIkZpbHRlciBnZW5lc1wiXG4gICAgICBbdmFsdWVdPVwiYWxsR2VuZXNGaWx0ZXJcIlxuICAgICAgKGlucHV0KT1cIm9uQWxsR2VuZXNGaWx0ZXIoJGFueSgkZXZlbnQudGFyZ2V0KS52YWx1ZSlcIlxuICAgIC8+XG4gICAgPHNtYWxsIGNsYXNzPVwic2MtaGludFwiICpuZ0lmPVwiIWNhbkhpZGVBbGxHZW5lc1wiPlxuICAgICAgVGhpcyBkYXRhc2V0IGRvZXMgbm90IHNheSB3aGljaCB0cmFuc2NyaXB0cyBhcmUgd2hvc2UsIHNvIGl0cyBnZW5lcyBjYW5ub3QgYmUgaGlkZGVuIG9uZSBieSBvbmUuXG4gICAgPC9zbWFsbD5cbiAgICA8c21hbGwgY2xhc3M9XCJzYy1oaW50XCIgKm5nSWY9XCJjYW5IaWRlQWxsR2VuZXMgJiYgdmlldy50cmFuc2NyaXB0TW9kZSA9PT0gJ2RlbnNpdHknXCI+XG4gICAgICBUaGUgZGVuc2l0eSBtYXAgZHJhd3MgZXZlcnkgZ2VuZSBhcyBvbmUgcmFzdGVyOiBnZW5lcyBhcmUgaGlkZGVuIG9uZSBieSBvbmUgYXMgY2lyY2xlcyBvciBpY29ucy5cbiAgICA8L3NtYWxsPlxuICAgIDxkaXYgY2xhc3M9XCJzYy1nZW5lLXJvdyBzYy1nZW5lLWxlYWYgbmVzdGVkXCIgKm5nRm9yPVwibGV0IHJvdyBvZiBhbGxSb3dzOyB0cmFja0J5OiB0cmFja0J5QWxsUm93XCI+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICBjbGFzcz1cInNjLWV5ZVwiXG4gICAgICAgIFtkaXNhYmxlZF09XCIhY2FuSGlkZUFsbEdlbmVzIHx8IHZpZXcudHJhbnNjcmlwdE1vZGUgPT09ICdkZW5zaXR5J1wiXG4gICAgICAgIChjbGljayk9XCJvbkFsbEdlbmVTaG93bihyb3cuZ2VuZSwgIXJvdy5zaG93bilcIlxuICAgICAgPlxuICAgICAgICA8aSBjbGFzcz1cInBpXCIgW2NsYXNzLnBpLWV5ZV09XCJyb3cuc2hvd25cIiBbY2xhc3MucGktZXllLXNsYXNoXT1cIiFyb3cuc2hvd25cIj48L2k+XG4gICAgICA8L2J1dHRvbj5cbiAgICAgIDwhLS0gVGhlIGdlbmUncyBjb2xvdXIgYW1vbmcgZXZlcnkgZ2VuZTsgY2xpY2tpbmcgaXQgb3BlbnMgdGhlIGNvbG91ciBwaWNrZXIuIC0tPlxuICAgICAgPGJ1dHRvblxuICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgY2xhc3M9XCJzYy1nZW5lLWljb25cIlxuICAgICAgICAqbmdJZj1cInJvdy5zd2F0Y2hcIlxuICAgICAgICBbc3R5bGUuY29sb3JdPVwicm93LnN3YXRjaFwiXG4gICAgICAgIFthdHRyLmFyaWEtbGFiZWxdPVwiJ0NvbG91ciBmb3IgJyArIHJvdy5nZW5lXCJcbiAgICAgICAgcFRvb2x0aXA9XCJDb2xvdXJcIlxuICAgICAgICB0b29sdGlwUG9zaXRpb249XCJ0b3BcIlxuICAgICAgICAoY2xpY2spPVwib3BlbkdlbmVTdHlsZSgkZXZlbnQsIHJvdy5nZW5lLCBnZW5lUG9wKVwiXG4gICAgICA+XG4gICAgICAgIDxzdmcgdmlld0JveD1cIi0xLjIgLTEuMiAyLjQgMi40XCIgY2xhc3M9XCJzYy1nbHlwaC1zdmdcIj48Y2lyY2xlIHI9XCIwLjc1XCI+PC9jaXJjbGU+PC9zdmc+XG4gICAgICA8L2J1dHRvbj5cbiAgICAgIDxzcGFuIGNsYXNzPVwic2MtZ3JvdXAtbGFiZWxcIiBbdGl0bGVdPVwicm93LmdlbmVcIj57eyByb3cuZ2VuZSB9fTwvc3Bhbj5cbiAgICAgIDxzcGFuIGNsYXNzPVwic2MtZ2VuZS1jb3VudFwiICpuZ0lmPVwicm93LmNvdW50ICE9PSBudWxsXCIgdGl0bGU9XCJUcmFuc2NyaXB0cyBpbiB2aWV3XCI+e3tcbiAgICAgICAgcm93LmNvdW50IHwgbnVtYmVyXG4gICAgICB9fTwvc3Bhbj5cbiAgICA8L2Rpdj5cbiAgICA8c21hbGwgY2xhc3M9XCJzYy1oaW50XCIgKm5nSWY9XCJhbGxHZW5lc01hdGNoZWQgPiBhbGxSb3dzLmxlbmd0aFwiPlxuICAgICAgU2hvd2luZyB7eyBhbGxSb3dzLmxlbmd0aCB8IG51bWJlciB9fSBvZiB7eyBhbGxHZW5lc01hdGNoZWQgfCBudW1iZXIgfX0gZ2VuZXM6IGZpbHRlciB0byBmaW5kIHRoZSBvdGhlcnMuXG4gICAgPC9zbWFsbD5cbiAgICA8c21hbGwgY2xhc3M9XCJzYy1oaW50XCIgKm5nSWY9XCJhbGxHZW5lc01hdGNoZWQgPT09IDBcIj5ObyBnZW5lIG1hdGNoZXMuPC9zbWFsbD5cbiAgPC9uZy1jb250YWluZXI+XG4gIDxuZy1jb250YWluZXIgKm5nSWY9XCJnZW5lVHJlZU9wZW4gJiYgIXZpZXcudHJhbnNjcmlwdEFsbEdlbmVzXCI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgbm9kZSBvZiBzb3J0ZWRUcmVlOyB0cmFja0J5OiB0cmFja0J5Tm9kZVwiPlxuICAgICAgPGRpdiBjbGFzcz1cInNjLWdlbmUtcm93IHNjLWdlbmUtZ3JvdXBcIiAqbmdJZj1cIm5vZGUubmFtZVwiPlxuICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInNjLWV5ZVwiIChjbGljayk9XCJvbkdlbmVzU2hvd24obm9kZS5nZW5lcywgIWdyb3VwU2hvd24uZ2V0KG5vZGUubmFtZSkpXCI+XG4gICAgICAgICAgPGlcbiAgICAgICAgICAgIGNsYXNzPVwicGlcIlxuICAgICAgICAgICAgW2NsYXNzLnBpLWV5ZV09XCJncm91cFNob3duLmdldChub2RlLm5hbWUpXCJcbiAgICAgICAgICAgIFtjbGFzcy5waS1leWUtc2xhc2hdPVwiIWdyb3VwU2hvd24uZ2V0KG5vZGUubmFtZSlcIlxuICAgICAgICAgID48L2k+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8c3BhbiBjbGFzcz1cInNjLWdyb3VwLWxhYmVsXCIgW3RpdGxlXT1cIm5vZGUubmFtZVwiPnt7IG5vZGUubmFtZSB9fTwvc3Bhbj5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJzYy1jb3VudFwiPih7eyBub2RlLmdlbmVzLmxlbmd0aCB9fSk8L3NwYW4+XG4gICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwic2MtaWNvbi1idG5cIiAoY2xpY2spPVwidG9nZ2xlR2VuZUdyb3VwKG5vZGUubmFtZSlcIj5cbiAgICAgICAgICA8aVxuICAgICAgICAgICAgY2xhc3M9XCJwaVwiXG4gICAgICAgICAgICBbY2xhc3MucGktY2hldnJvbi1kb3duXT1cIiFjb2xsYXBzZWRHZW5lR3JvdXBzLmhhcyhub2RlLm5hbWUpXCJcbiAgICAgICAgICAgIFtjbGFzcy5waS1jaGV2cm9uLXJpZ2h0XT1cImNvbGxhcHNlZEdlbmVHcm91cHMuaGFzKG5vZGUubmFtZSlcIlxuICAgICAgICAgID48L2k+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIW5vZGUubmFtZSB8fCAhY29sbGFwc2VkR2VuZUdyb3Vwcy5oYXMobm9kZS5uYW1lKVwiPlxuICAgICAgICA8ZGl2XG4gICAgICAgICAgY2xhc3M9XCJzYy1nZW5lLXJvdyBzYy1nZW5lLWxlYWZcIlxuICAgICAgICAgIFtjbGFzcy5uZXN0ZWRdPVwiISFub2RlLm5hbWVcIlxuICAgICAgICAgICpuZ0Zvcj1cImxldCBnZW5lIG9mIG5vZGUuZ2VuZXM7IHRyYWNrQnk6IHRyYWNrQnlMYWJlbFN0cmluZ1wiXG4gICAgICAgID5cbiAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInNjLWV5ZVwiIChjbGljayk9XCJvbkdlbmVzU2hvd24oW2dlbmVdLCAhcm93cy5nZXQoZ2VuZSk/LnNob3duKVwiPlxuICAgICAgICAgICAgPGkgY2xhc3M9XCJwaVwiIFtjbGFzcy5waS1leWVdPVwicm93cy5nZXQoZ2VuZSk/LnNob3duXCIgW2NsYXNzLnBpLWV5ZS1zbGFzaF09XCIhcm93cy5nZXQoZ2VuZSk/LnNob3duXCI+PC9pPlxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIDwhLS0gVGhlIGdlbmUncyBtYXJrZXIsIGluIGl0cyBjb2xvdXI6IGl0cyBpY29uIGluIEljb25zIG1vZGUsIGEgZG90IGZvciBjaXJjbGVzLlxuICAgICAgICAgICAgICAgQ2xpY2tpbmcgaXQgb3BlbnMgdGhlIGljb24gYW5kIGNvbG91ciBwaWNrZXIgKGFzIFhlbml1bSBFeHBsb3JlciBkb2VzKS4gLS0+XG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICBjbGFzcz1cInNjLWdlbmUtaWNvblwiXG4gICAgICAgICAgICBbc3R5bGUuY29sb3JdPVwicm93cy5nZXQoZ2VuZSk/LnN3YXRjaFwiXG4gICAgICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cIidJY29uIGFuZCBjb2xvdXIgZm9yICcgKyBnZW5lXCJcbiAgICAgICAgICAgIHBUb29sdGlwPVwiSWNvbiBhbmQgY29sb3VyXCJcbiAgICAgICAgICAgIHRvb2x0aXBQb3NpdGlvbj1cInRvcFwiXG4gICAgICAgICAgICAoY2xpY2spPVwib3BlbkdlbmVTdHlsZSgkZXZlbnQsIGdlbmUsIGdlbmVQb3ApXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8c3ZnIHZpZXdCb3g9XCItMS4yIC0xLjIgMi40IDIuNFwiIGNsYXNzPVwic2MtZ2x5cGgtc3ZnXCI+XG4gICAgICAgICAgICAgIDxwb2x5Z29uXG4gICAgICAgICAgICAgICAgKm5nSWY9XCJ2aWV3LnRyYW5zY3JpcHRNb2RlID09PSAnZ2x5cGhzJzsgZWxzZSBkb3RJY29uXCJcbiAgICAgICAgICAgICAgICBbYXR0ci5wb2ludHNdPVwicm93cy5nZXQoZ2VuZSk/LnBvaW50c1wiXG4gICAgICAgICAgICAgID48L3BvbHlnb24+XG4gICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjZG90SWNvbj48Y2lyY2xlIHI9XCIwLjc1XCI+PC9jaXJjbGU+PC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2MtZ3JvdXAtbGFiZWxcIj57eyBnZW5lIH19PC9zcGFuPlxuICAgICAgICAgIDxzcGFuXG4gICAgICAgICAgICBjbGFzcz1cInNjLWdlbmUtY291bnRcIlxuICAgICAgICAgICAgKm5nSWY9XCJyb3dzLmdldChnZW5lKT8uY291bnQgYXMgbjsgZWxzZSB6ZXJvQ291bnRcIlxuICAgICAgICAgICAgdGl0bGU9XCJUcmFuc2NyaXB0cyBpbiB2aWV3XCJcbiAgICAgICAgICAgID57eyBuIHwgbnVtYmVyIH19PC9zcGFuXG4gICAgICAgICAgPlxuICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjemVyb0NvdW50PlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYy1nZW5lLWNvdW50XCIgKm5nSWY9XCJnZW5lQ291bnRzXCIgdGl0bGU9XCJUcmFuc2NyaXB0cyBpbiB2aWV3XCI+MDwvc3Bhbj5cbiAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgIDwvbmctY29udGFpbmVyPlxuICA8L25nLWNvbnRhaW5lcj5cbiAgPCEtLSBPbmUgcGlja2VyIGZvciBldmVyeSBnZW5lIHJvdywgZmlsbGVkIGZvciB0aGUgZ2VuZSB0aGF0IG9wZW5lZCBpdC4gLS0+XG4gIDxwLW92ZXJsYXlQYW5lbCAjZ2VuZVBvcCBzdHlsZUNsYXNzPVwic2MtZ2VuZS1zdHlsZVwiIGFwcGVuZFRvPVwiYm9keVwiPlxuICAgIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJjb250ZW50XCI+XG4gICAgICA8c3BhdGlhbC1nZW5lLXN0eWxlXG4gICAgICAgICpuZ0lmPVwic3R5bGVHZW5lIGFzIGdlbmVcIlxuICAgICAgICBbZ2VuZV09XCJnZW5lXCJcbiAgICAgICAgd2hhdD1cIlRyYW5zY3JpcHRcIlxuICAgICAgICBbY29sb3JdPVwic3R5bGVDb2xvck9mKGdlbmUpXCJcbiAgICAgICAgW2dseXBoXT1cInN0eWxlR2x5cGggPz8gJ2NpcmNsZSdcIlxuICAgICAgICBbc2hvd0ljb25zXT1cIiF2aWV3LnRyYW5zY3JpcHRBbGxHZW5lc1wiXG4gICAgICAgIFtpY29uSGludF09XCJcbiAgICAgICAgICB2aWV3LnRyYW5zY3JpcHRNb2RlICE9PSAnZ2x5cGhzJyA/ICdJY29ucyBzaG93IHdoZW4gdGhlIHRyYW5zY3JpcHQgcG9pbnQgc3R5bGUgaXMgSWNvbnMuJyA6IG51bGxcbiAgICAgICAgXCJcbiAgICAgICAgKGNvbG9yQ2hhbmdlKT1cIm9uR2VuZUNvbG9yKGdlbmUsICRldmVudClcIlxuICAgICAgICAoZ2x5cGhDaGFuZ2UpPVwib25HbHlwaChnZW5lLCAkZXZlbnQpXCJcbiAgICAgICAgKHJlc2V0U3R5bGUpPVwicmVzZXRHZW5lU3R5bGUoZ2VuZSlcIlxuICAgICAgPjwvc3BhdGlhbC1nZW5lLXN0eWxlPlxuICAgIDwvbmctdGVtcGxhdGU+XG4gIDwvcC1vdmVybGF5UGFuZWw+XG4gIDxkaXYgY2xhc3M9XCJzYy1nZW5lLWZvb3RlclwiPlxuICAgIHt7ICh2aWV3LnRyYW5zY3JpcHRBbGxHZW5lcyA/IGdlbmVUb3RhbCA6IHZpZXcudHJhbnNjcmlwdEdlbmVzLmxlbmd0aCkgfCBudW1iZXIgfX0ve3sgZ2VuZVRvdGFsIHwgbnVtYmVyIH19XG4gICAgZ2VuZXMgc2VsZWN0ZWRcbiAgPC9kaXY+XG48L2Rpdj5cbiJdfQ==