@firestitch/report 18.11.0 → 18.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app/reports/components/component-grid/component-grid.component.d.ts +29 -0
- package/app/reports/components/component-grid/report-grid-formatter.d.ts +9 -0
- package/app/reports/data/report-grid-source.d.ts +22 -0
- package/app/reports/data/report.data.d.ts +3 -1
- package/app/reports/interfaces/report-chat-viewer-state.interface.d.ts +2 -0
- package/app/reports/interfaces/report-chat-viewer-tile.interface.d.ts +5 -0
- package/app/reports/interfaces/report-grid-config.interface.d.ts +5 -0
- package/app/reports/interfaces/report-grid-line.interface.d.ts +6 -0
- package/app/reports/interfaces/report-grid-params.interface.d.ts +7 -0
- package/app/reports/interfaces/report-grid-report.interface.d.ts +2 -0
- package/app/reports/interfaces/report-grid-session-layout.interface.d.ts +5 -0
- package/app/reports/interfaces/report.interface.d.ts +3 -2
- package/app/reports/report-chat-viewer-state.d.ts +4 -1
- package/app/reports/report-grid-layout.d.ts +4 -0
- package/app/reports/services/report-filter-state.service.d.ts +6 -0
- package/app/reports/views/report/fs-ai-report.component.d.ts +2 -0
- package/esm2022/app/reports/components/component-grid/component-grid.component.mjs +93 -0
- package/esm2022/app/reports/components/component-grid/report-grid-formatter.mjs +94 -0
- package/esm2022/app/reports/components/component-text/component-text.component.mjs +1 -1
- package/esm2022/app/reports/components/report-component/report-component.component.mjs +21 -14
- package/esm2022/app/reports/data/report-grid-source.mjs +105 -0
- package/esm2022/app/reports/data/report.data.mjs +13 -2
- package/esm2022/app/reports/interfaces/report-chat-viewer-state.interface.mjs +1 -1
- package/esm2022/app/reports/interfaces/report-chat-viewer-tile.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-grid-config.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-grid-line.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-grid-params.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-grid-report.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-grid-session-layout.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report.interface.mjs +1 -1
- package/esm2022/app/reports/report-chat-viewer-state.mjs +21 -6
- package/esm2022/app/reports/report-grid-layout.mjs +14 -0
- package/esm2022/app/reports/report-tile.mjs +5 -5
- package/esm2022/app/reports/services/report-filter-state.service.mjs +77 -11
- package/esm2022/app/reports/views/report/fs-ai-report.component.mjs +36 -13
- package/fesm2022/{firestitch-report-echarts-DKXlgu1D.mjs → firestitch-report-echarts-CoaGXKET.mjs} +2 -2
- package/fesm2022/{firestitch-report-echarts-DKXlgu1D.mjs.map → firestitch-report-echarts-CoaGXKET.mjs.map} +1 -1
- package/fesm2022/{firestitch-report-firestitch-report-Bnv62suw.mjs → firestitch-report-firestitch-report-CHPA7sla.mjs} +457 -52
- package/fesm2022/firestitch-report-firestitch-report-CHPA7sla.mjs.map +1 -0
- package/fesm2022/firestitch-report.mjs +1 -1
- package/package.json +4 -2
- package/fesm2022/firestitch-report-firestitch-report-Bnv62suw.mjs.map +0 -1
|
@@ -2,7 +2,7 @@ import { ChangeDetectionStrategy, Component, DestroyRef, ElementRef, EventEmitte
|
|
|
2
2
|
import { MatIconButton } from '@angular/material/button';
|
|
3
3
|
import { MatDialog } from '@angular/material/dialog';
|
|
4
4
|
import { MatIcon } from '@angular/material/icon';
|
|
5
|
-
import {
|
|
5
|
+
import { MatProgressSpinner } from '@angular/material/progress-spinner';
|
|
6
6
|
import { MatTooltip } from '@angular/material/tooltip';
|
|
7
7
|
import { FsFilterModule } from '@firestitch/filter';
|
|
8
8
|
import { FsMenuComponent, FsMenuModule } from '@firestitch/menu';
|
|
@@ -27,6 +27,7 @@ import { movedGroupValues, ReportFilterStateService } from '../../services/repor
|
|
|
27
27
|
import { isTimeSeriesChart } from '../../tile-data-state';
|
|
28
28
|
import { tileLoads } from '../../tile-loads';
|
|
29
29
|
import { ComponentChartComponent } from '../component-chart/component-chart.component';
|
|
30
|
+
import { ComponentGridComponent } from '../component-grid/component-grid.component';
|
|
30
31
|
import { ComponentKpiComponent } from '../component-kpi/component-kpi.component';
|
|
31
32
|
import { ComponentListComponent } from '../component-list/component-list.component';
|
|
32
33
|
import { ComponentTextComponent } from '../component-text/component-text.component';
|
|
@@ -40,6 +41,9 @@ import * as i2 from "@firestitch/menu";
|
|
|
40
41
|
const HANDLES = ['nw', 'n', 'ne', 'e', 'se', 's', 'sw', 'w'];
|
|
41
42
|
const MIN_W = 0.6; // inches
|
|
42
43
|
const MIN_H = 0.4; // inches
|
|
44
|
+
// The tiles that read their own rows: a list through FsList paging, a grid
|
|
45
|
+
// through fs-grid's source. This component loads every other tile's data.
|
|
46
|
+
const SELF_READING_TYPES = ['list', 'grid'];
|
|
43
47
|
// Two presses on a text block this close together open its editor. Detected
|
|
44
48
|
// here rather than with a dblclick listener because the drag loop claims the
|
|
45
49
|
// pointer on every press, and a browser is not obliged to deliver dblclick
|
|
@@ -52,7 +56,8 @@ const DOUBLE_PRESS_MS = 400;
|
|
|
52
56
|
// snapper); everything works at any zoom (pixel deltas ÷ zoom·96 → inches).
|
|
53
57
|
//
|
|
54
58
|
// Charts and KPIs fetch their own data here; lists fetch inside
|
|
55
|
-
// ComponentListComponent through FsList paging
|
|
59
|
+
// ComponentListComponent through FsList paging, and grids inside
|
|
60
|
+
// ComponentGridComponent through fs-grid's source.
|
|
56
61
|
export class ReportComponentComponent {
|
|
57
62
|
reportId;
|
|
58
63
|
component;
|
|
@@ -109,8 +114,9 @@ export class ReportComponentComponent {
|
|
|
109
114
|
// repaints the header and body.
|
|
110
115
|
filterConfig = signal(null);
|
|
111
116
|
data = signal(null);
|
|
112
|
-
//
|
|
113
|
-
//
|
|
117
|
+
// A load shows a spinner centred on the tile. `loading` is the first load,
|
|
118
|
+
// with nothing to show yet; a refetch keeps the data on screen, dimmed
|
|
119
|
+
// under the spinner (`refreshing`). The title is never dimmed.
|
|
114
120
|
loading = signal(false);
|
|
115
121
|
refreshing = signal(false);
|
|
116
122
|
error = signal(null);
|
|
@@ -179,9 +185,10 @@ export class ReportComponentComponent {
|
|
|
179
185
|
if (!this.isText) {
|
|
180
186
|
this._rebuildHeaderOnNewState();
|
|
181
187
|
}
|
|
182
|
-
// Lists fetch through FsList
|
|
183
|
-
//
|
|
184
|
-
|
|
188
|
+
// Lists fetch through FsList and grids through fs-grid's source (each
|
|
189
|
+
// reads its own rows); text has nothing to fetch, and a value is never
|
|
190
|
+
// drawn (it reads inside text).
|
|
191
|
+
if (!SELF_READING_TYPES.includes(this.component.type) && !this.isText && isDrawn(this.component)) {
|
|
185
192
|
// One load stream (tileLoads): the first load at once, then one per
|
|
186
193
|
// settled sweep of changes, each cancelling the one in flight, and an
|
|
187
194
|
// answer sent before a reset is dropped.
|
|
@@ -689,8 +696,7 @@ export class ReportComponentComponent {
|
|
|
689
696
|
}
|
|
690
697
|
// ----- data ----------------------------------------------------------------
|
|
691
698
|
// One request of the load stream (tileLoads), built from the state now. The
|
|
692
|
-
//
|
|
693
|
-
// data stays and the thin bar shows.
|
|
699
|
+
// spinner shows either way; a tile with data on screen keeps it, dimmed.
|
|
694
700
|
_load() {
|
|
695
701
|
const first = !this.data();
|
|
696
702
|
this.loading.set(first);
|
|
@@ -705,7 +711,7 @@ export class ReportComponentComponent {
|
|
|
705
711
|
return this._reportData.componentData(this.reportId, this.component.id, filters, state);
|
|
706
712
|
}
|
|
707
713
|
// A failed load clears the data with its message, so the next load starts
|
|
708
|
-
// from
|
|
714
|
+
// from an empty tile and never shows the data the failure replaced. A
|
|
709
715
|
// chart's answer gives its drill path.
|
|
710
716
|
_loaded(result) {
|
|
711
717
|
this.data.set(result.data);
|
|
@@ -758,22 +764,23 @@ export class ReportComponentComponent {
|
|
|
758
764
|
openAtPoint(anchor, click.pointer, this.zoom, () => this.markMenu?.openMenu(null));
|
|
759
765
|
}
|
|
760
766
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportComponentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
761
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ReportComponentComponent, isStandalone: true, selector: "app-report-component", inputs: { reportId: { classPropertyName: "reportId", publicName: "reportId", isSignal: false, isRequired: false, transformFunction: null }, component: { classPropertyName: "component", publicName: "component", isSignal: false, isRequired: false, transformFunction: null }, groups: { classPropertyName: "groups", publicName: "groups", isSignal: false, isRequired: false, transformFunction: null }, editMode: { classPropertyName: "editMode", publicName: "editMode", isSignal: false, isRequired: false, transformFunction: null }, zoom: { classPropertyName: "zoom", publicName: "zoom", isSignal: false, isRequired: false, transformFunction: null }, snapper: { classPropertyName: "snapper", publicName: "snapper", isSignal: false, isRequired: false, transformFunction: null }, selected: { classPropertyName: "selected", publicName: "selected", isSignal: false, isRequired: false, transformFunction: null }, tokens: { classPropertyName: "tokens", publicName: "tokens", isSignal: true, isRequired: false, transformFunction: null }, valueKeysElsewhere: { classPropertyName: "valueKeysElsewhere", publicName: "valueKeysElsewhere", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectComponent: "selectComponent", positionChanged: "positionChanged", openSettings: "openSettings", removed: "removed", valueSettings: "valueSettings", textSaved: "textSaved", valuesRemoved: "valuesRemoved" }, host: { properties: { "class.height-auto": "this.heightAuto" } }, viewQueries: [{ propertyName: "_text", first: true, predicate: ComponentTextComponent, descendants: true, isSignal: true }, { propertyName: "chartComponent", first: true, predicate: ComponentChartComponent, descendants: true }, { propertyName: "markMenu", first: true, predicate: ["markMenu"], descendants: true }, { propertyName: "markAnchor", first: true, predicate: ["markAnchor"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n class=\"component-box\"\n [class.editing]=\"editMode\"\n [class.text]=\"isText\"\n [class.selected]=\"selected\"\n [style.padding]=\"bodyPadding\"\n (pointerdown)=\"onComponentPointerDown($event)\"\n (mousedown)=\"stopCanvasPan($event)\"\n (touchstart)=\"stopCanvasPan($event)\">\n <!-- The header is an fs-filter: heading template = title (and the edit-mode\n drag handle), actions = the menu, items = component-level filter groups,\n the same strip for every type (lists included). fs-filter reads its\n config once, so the block is keyed on the component-filter set to be\n recreated when it changes. The title shows its tokens filled, and a\n filter change repaints it in place (shownTitle). -->\n <!-- A text block has no title bar \u2014 it IS its words, like a text box on a\n slide \u2014 so it gets neither the header nor the data actions. -->\n @for (key of isText ? [] : [filterKey]; track key) {\n <fs-filter\n class=\"component-filter\"\n [config]=\"filterConfig()\">\n <ng-template fsFilterHeading>\n <div\n class=\"component-title\"\n (pointerdown)=\"onDragStart($event)\">\n <!-- While the chart is drilled the title leads its breadcrumb:\n 'Title \u203A 2026 \u203A Q3', the title as the viewer reads it\n (shownTitle). The title goes back to the top and each\n crumb to the period it names; the last is where the chart is.\n A long path is cut at its left end, so the crumbs nearest the\n chart stay in view. While the layout is edited the crumbs are\n plain text (the stylesheet; drillTo does nothing then). -->\n @if (drillCrumbs().length) {\n <span class=\"drill-path\">\n <span dir=\"ltr\">\n <a\n class=\"drill-crumb\"\n tabindex=\"0\"\n (click)=\"drillTo(0)\"\n (keydown.enter)=\"drillTo(0)\">\n {{ shownTitle }}\n </a>\n @for (label of drillCrumbs(); track $index; let last = $last) {\n <span class=\"drill-separator\">{{ drillSeparator }}</span>\n @if (last) {\n <span>{{ label }}</span>\n } @else {\n <a\n class=\"drill-crumb\"\n tabindex=\"0\"\n (click)=\"drillTo($index + 1)\"\n (keydown.enter)=\"drillTo($index + 1)\">\n {{ label }}\n </a>\n }\n }\n </span>\n </span>\n } @else {\n {{ shownTitle }}\n }\n @if (truncated) {\n <mat-icon\n class=\"truncated-icon\"\n matTooltip=\"Showing a truncated result \u2014 refine the filters to see everything.\">\n warning_amber\n </mat-icon>\n }\n </div>\n </ng-template>\n </fs-filter>\n }\n <!-- The actions menu is floated top-right (absolute) rather than living in\n fs-filter's actions slot, so its ~40px button height no longer drives the\n header row's height. It overlays the box corner; the heading reserves\n right padding so a long title ellipsises before it. -->\n @if (!isText || (editMode && !textEditing())) {\n <button\n mat-icon-button\n class=\"component-menu\"\n [fsMenuTriggerFor]=\"menu\"\n (pointerdown)=\"$event.stopPropagation()\"\n (mousedown)=\"stopCanvasPan($event)\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <!-- Beside its trigger, inside the same block: an fs-menu that finds no\n trigger of its own draws one. -->\n <fs-menu #menu>\n <ng-template\n fs-menu-item\n [hidden]=\"!isText\"\n (click)=\"editText()\">\n <mat-icon>edit</mat-icon>\n <span>Edit text</span>\n </ng-template>\n <ng-template\n fs-menu-item\n [hidden]=\"!isText\"\n (click)=\"deleteText()\">\n <mat-icon>delete</mat-icon>\n <span>Delete</span>\n </ng-template>\n <ng-template\n fs-menu-item\n [hidden]=\"!drillCrumbs().length || editMode\"\n (click)=\"drillUp()\">\n <mat-icon>arrow_upward</mat-icon>\n <span>Drill up</span>\n </ng-template>\n <ng-template\n fs-menu-item\n [hidden]=\"!drillCrumbs().length || editMode\"\n (click)=\"drillTo(0)\">\n <mat-icon>vertical_align_top</mat-icon>\n <span>Back to top</span>\n </ng-template>\n <ng-template\n fs-menu-item\n [hidden]=\"isText\"\n (click)=\"settings()\">\n <mat-icon>tune</mat-icon>\n <span>Settings</span>\n </ng-template>\n <ng-template\n fs-menu-item\n [hidden]=\"isText\"\n (click)=\"exportCsv()\">\n <mat-icon>download</mat-icon>\n <span>Export CSV</span>\n </ng-template>\n <ng-template\n fs-menu-item\n [hidden]=\"!hidesColumns\"\n (click)=\"chooseColumns()\">\n <mat-icon>view_column</mat-icon>\n <span>Columns</span>\n </ng-template>\n </fs-menu>\n }\n <div class=\"component-body\">\n <!-- A refetch keeps the data on screen under a thin bar; the shimmer\n below is for the first load only. -->\n @if (refreshing()) {\n <mat-progress-bar\n class=\"refresh-bar\"\n aria-label=\"Refreshing data\"\n [mode]=\"'indeterminate'\">\n </mat-progress-bar>\n }\n @if (isText) {\n <app-report-component-text\n [html]=\"textHtml() ?? component.config?.html ?? ''\"\n [tokens]=\"tokens()\"\n [editing]=\"textEditing()\"\n [shownElsewhere]=\"shownElsewhere\"\n (saved)=\"onTextSaved($event)\"\n (editEnded)=\"textEditing.set(false)\"\n (valueSettings)=\"valueSettings.emit($event)\">\n </app-report-component-text>\n } @else if (component.type === 'list') {\n @for (key of [listResetKey()]; track key) {\n <app-report-component-list\n [reportId]=\"reportId\"\n [component]=\"component\">\n </app-report-component-list>\n }\n } @else if (loading()) {\n <div class=\"component-state\">\n <div class=\"loading-shimmer\"></div>\n </div>\n } @else if (error()) {\n <div class=\"component-state error\">\n {{ error() }}\n </div>\n } @else if (!data()?.rows?.length) {\n <div class=\"component-state\">\n {{ emptyMessage() }}\n </div>\n } @else if (component.type === 'kpi') {\n <app-report-component-kpi\n [component]=\"component\"\n [data]=\"data()\"\n (markClick)=\"onMarkClick($event)\">\n </app-report-component-kpi>\n } @else {\n <app-report-component-chart\n [component]=\"component\"\n [data]=\"data()\"\n [actions]=\"tileActions()\"\n [(legendSelected)]=\"legendSelected\"\n (markClick)=\"onMarkClick($event)\"\n (markMiss)=\"onMarkMiss()\">\n </app-report-component-chart>\n }\n <!-- In edit mode a transparent veil over the body makes the WHOLE\n component draggable (industry standard: you grab the object, not just\n its title bar) and keeps inner widgets from swallowing the gesture. -->\n @if (editMode && !textEditing()) {\n <div\n class=\"drag-veil\"\n (pointerdown)=\"onDragStart($event)\">\n </div>\n }\n </div>\n</div>\n<!-- The mark menu, for a click whose mark offers two or more actions. It\n opens at the click: its trigger is a zero-size anchor that\n anchor-at-point.ts moves there first. -->\n@if (!isText && !editMode) {\n <span\n #markAnchor\n [style.position]=\"'absolute'\"\n [fsMenuTriggerFor]=\"markMenu\">\n </span>\n <fs-menu #markMenu>\n @for (action of markMenuActions(); track action) {\n <ng-template\n fs-menu-item\n (click)=\"runMarkAction(action)\">\n {{ markActionLabels[action] }}\n </ng-template>\n }\n </fs-menu>\n}\n<!-- Handles live OUTSIDE the clipped box so they straddle its edges. -->\n@if (editMode && selected) {\n @for (handle of resizeHandles; track handle) {\n <div\n class=\"handle handle-{{ handle }}\"\n (mousedown)=\"stopCanvasPan($event)\"\n (pointerdown)=\"onResizeStart($event, handle)\">\n </div>\n }\n}", styles: [":host{position:absolute;display:flex;flex-direction:column;font-size:10px;--mdc-outlined-button-container-height: 30px;--mdc-outlined-button-label-text-size: 10px;--mat-outlined-button-horizontal-padding: 15px;--mdc-text-button-container-height: 30px;--mdc-text-button-label-text-size: 10px;--mat-text-button-horizontal-padding: 15px;--mat-button-outlined-container-height: 30px;--mat-button-outlined-label-text-size: 10px;--mat-button-outlined-horizontal-padding: 15px;--mat-button-text-container-height: 30px;--mat-button-text-label-text-size: 10px;--mat-button-text-horizontal-padding: 15px}.component-box{position:relative;width:100%;flex:1 1 auto;min-height:0;box-sizing:border-box;display:flex;flex-direction:column;background:#fff;border:1px solid #e4e7eb;border-radius:6px;overflow:hidden;transition:box-shadow .12s ease,border-color .12s ease;cursor:default}.component-box.editing .component-title{cursor:grab}.component-box.editing .component-title:active{cursor:grabbing}.component-box.editing .drill-crumb{pointer-events:none}.component-box.editing:hover{border-color:#9db3c8;box-shadow:0 2px 8px #0f172a14}.component-box.selected{border-color:var(--brand-primary-color);box-shadow:0 0 0 1px var(--brand-primary-color),0 4px 14px #2196f32e}.component-box.text{background:transparent;border-color:transparent;border-radius:0;overflow:visible}.component-box.text.editing{border-style:dashed;border-color:#cbd2d9}.component-box.text.editing:hover{box-shadow:none}.component-box.text.selected{border-style:solid;border-color:var(--brand-primary-color);box-shadow:0 0 0 1px var(--brand-primary-color)}:host ::ng-deep .component-filter .filter-bar-container{align-items:center!important}.component-filter{flex:0 0 auto;display:block;padding:0 0 4px}.component-filter .component-title{display:flex;align-items:center;gap:4px;-webkit-user-select:none;user-select:none;padding-right:40px;font-size:var(--report-heading-size);font-weight:600;color:#1f2933;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.component-filter .component-title .truncated-icon{font-size:16px;width:16px;height:16px;color:#f59e0b}.component-filter .component-title .drill-path{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;direction:rtl;text-align:left}.component-filter .component-title .drill-crumb{color:inherit;cursor:pointer;text-decoration:none}.component-filter .component-title .drill-crumb:hover,.component-filter .component-title .drill-crumb:focus-visible{text-decoration:underline}.component-filter .component-title .drill-separator{opacity:.6}.component-menu{position:absolute;top:2px;right:2px;z-index:30}.component-body{flex:1 1 auto;min-height:0;position:relative}.refresh-bar{position:absolute;top:0;left:0;right:0;z-index:1;pointer-events:none;--mdc-linear-progress-track-height: 2px;--mdc-linear-progress-active-indicator-height: 2px;--mat-progress-bar-track-height: 2px;--mat-progress-bar-active-indicator-height: 2px}:host(.height-auto) .component-state{min-height:120px}.drag-veil{position:absolute;inset:0;cursor:grab;touch-action:none}.drag-veil:active{cursor:grabbing}.component-state{width:100%;height:100%;display:flex;align-items:center;justify-content:center;font-size:12px;color:#7b8794;padding:8px;text-align:center}.component-state.error{color:#e15759}.loading-shimmer{width:70%;height:60%;border-radius:6px;background:linear-gradient(100deg,#f0f4f8 40%,#e4ebf2,#f0f4f8 60%);background-size:200% 100%;animation:shimmer 1.2s infinite linear}@keyframes shimmer{to{background-position-x:-200%}}.handle{position:absolute;width:14px;height:14px;display:flex;align-items:center;justify-content:center;touch-action:none;z-index:20;transform:scale(calc(1 / var(--canvas-zoom, 1)))}.handle:before{content:\"\";width:8px;height:8px;background:#fff;border:1.5px solid var(--brand-primary-color);border-radius:2px;box-shadow:0 1px 2px #0f172a33}.handle-nw{left:-7px;top:-7px;cursor:nwse-resize}.handle-n{left:calc(50% - 7px);top:-7px;cursor:ns-resize}.handle-ne{right:-7px;top:-7px;cursor:nesw-resize}.handle-e{right:-7px;top:calc(50% - 7px);cursor:ew-resize}.handle-se{right:-7px;bottom:-7px;cursor:nwse-resize}.handle-s{left:calc(50% - 7px);bottom:-7px;cursor:ns-resize}.handle-sw{left:-7px;bottom:-7px;cursor:nesw-resize}.handle-w{left:-7px;top:calc(50% - 7px);cursor:ew-resize}\n"], dependencies: [{ kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: FsFilterModule }, { kind: "component", type: i1.FilterComponent, selector: "fs-filter", inputs: ["config"], outputs: ["closed", "opened", "ready"] }, { kind: "directive", type: i1.FilterHeadingDirective, selector: "[fsFilterHeading]" }, { kind: "ngmodule", type: FsMenuModule }, { kind: "component", type: i2.FsMenuComponent, selector: "fs-menu", inputs: ["class", "buttonClass", "buttonType", "buttonColor"], outputs: ["opened", "closed"] }, { kind: "directive", type: i2.FsMenuItemDirective, selector: "fs-menu-group,[fs-menu-item]" }, { kind: "directive", type: i2.FsMenuTriggerDirective, selector: "[fsMenuTriggerFor]", inputs: ["fsMenuTriggerFor"] }, { kind: "component", type: ComponentChartComponent, selector: "app-report-component-chart", inputs: ["component", "data", "legendSelected", "actions"], outputs: ["legendSelectedChange", "markClick", "markMiss"] }, { kind: "component", type: ComponentKpiComponent, selector: "app-report-component-kpi", inputs: ["component", "data"], outputs: ["markClick"] }, { kind: "component", type: ComponentListComponent, selector: "app-report-component-list", inputs: ["reportId", "component"] }, { kind: "component", type: ComponentTextComponent, selector: "app-report-component-text", inputs: ["html", "tokens", "editing", "shownElsewhere"], outputs: ["saved", "editEnded", "valueSettings"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
767
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ReportComponentComponent, isStandalone: true, selector: "app-report-component", inputs: { reportId: { classPropertyName: "reportId", publicName: "reportId", isSignal: false, isRequired: false, transformFunction: null }, component: { classPropertyName: "component", publicName: "component", isSignal: false, isRequired: false, transformFunction: null }, groups: { classPropertyName: "groups", publicName: "groups", isSignal: false, isRequired: false, transformFunction: null }, editMode: { classPropertyName: "editMode", publicName: "editMode", isSignal: false, isRequired: false, transformFunction: null }, zoom: { classPropertyName: "zoom", publicName: "zoom", isSignal: false, isRequired: false, transformFunction: null }, snapper: { classPropertyName: "snapper", publicName: "snapper", isSignal: false, isRequired: false, transformFunction: null }, selected: { classPropertyName: "selected", publicName: "selected", isSignal: false, isRequired: false, transformFunction: null }, tokens: { classPropertyName: "tokens", publicName: "tokens", isSignal: true, isRequired: false, transformFunction: null }, valueKeysElsewhere: { classPropertyName: "valueKeysElsewhere", publicName: "valueKeysElsewhere", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectComponent: "selectComponent", positionChanged: "positionChanged", openSettings: "openSettings", removed: "removed", valueSettings: "valueSettings", textSaved: "textSaved", valuesRemoved: "valuesRemoved" }, host: { properties: { "class.height-auto": "this.heightAuto" } }, viewQueries: [{ propertyName: "_text", first: true, predicate: ComponentTextComponent, descendants: true, isSignal: true }, { propertyName: "chartComponent", first: true, predicate: ComponentChartComponent, descendants: true }, { propertyName: "markMenu", first: true, predicate: ["markMenu"], descendants: true }, { propertyName: "markAnchor", first: true, predicate: ["markAnchor"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n class=\"component-box\"\n [class.editing]=\"editMode\"\n [class.text]=\"isText\"\n [class.selected]=\"selected\"\n [class.refreshing]=\"refreshing()\"\n [style.padding]=\"bodyPadding\"\n (pointerdown)=\"onComponentPointerDown($event)\"\n (mousedown)=\"stopCanvasPan($event)\"\n (touchstart)=\"stopCanvasPan($event)\">\n <!-- The header is an fs-filter: heading template = title (and the edit-mode\n drag handle), actions = the menu, items = component-level filter groups,\n the same strip for every type (lists included). fs-filter reads its\n config once, so the block is keyed on the component-filter set to be\n recreated when it changes. The title shows its tokens filled, and a\n filter change repaints it in place (shownTitle). -->\n <!-- A text block has no title bar \u2014 it IS its words, like a text box on a\n slide \u2014 so it gets neither the header nor the data actions. -->\n @for (key of isText ? [] : [filterKey]; track key) {\n <fs-filter\n class=\"component-filter\"\n [config]=\"filterConfig()\">\n <ng-template fsFilterHeading>\n <div\n class=\"component-title\"\n (pointerdown)=\"onDragStart($event)\">\n <!-- While the chart is drilled the title leads its breadcrumb:\n 'Title \u203A 2026 \u203A Q3', the title as the viewer reads it\n (shownTitle). The title goes back to the top and each\n crumb to the period it names; the last is where the chart is.\n A long path is cut at its left end, so the crumbs nearest the\n chart stay in view. While the layout is edited the crumbs are\n plain text (the stylesheet; drillTo does nothing then). -->\n @if (drillCrumbs().length) {\n <span class=\"drill-path\">\n <span dir=\"ltr\">\n <a\n class=\"drill-crumb\"\n tabindex=\"0\"\n (click)=\"drillTo(0)\"\n (keydown.enter)=\"drillTo(0)\">\n {{ shownTitle }}\n </a>\n @for (label of drillCrumbs(); track $index; let last = $last) {\n <span class=\"drill-separator\">{{ drillSeparator }}</span>\n @if (last) {\n <span>{{ label }}</span>\n } @else {\n <a\n class=\"drill-crumb\"\n tabindex=\"0\"\n (click)=\"drillTo($index + 1)\"\n (keydown.enter)=\"drillTo($index + 1)\">\n {{ label }}\n </a>\n }\n }\n </span>\n </span>\n } @else {\n {{ shownTitle }}\n }\n @if (truncated) {\n <mat-icon\n class=\"truncated-icon\"\n matTooltip=\"Showing a truncated result \u2014 refine the filters to see everything.\">\n warning_amber\n </mat-icon>\n }\n </div>\n </ng-template>\n </fs-filter>\n }\n <!-- The actions menu is floated top-right (absolute) rather than living in\n fs-filter's actions slot, so its ~40px button height no longer drives the\n header row's height. It overlays the box corner; the heading reserves\n right padding so a long title ellipsises before it. -->\n @if (!isText || (editMode && !textEditing())) {\n <button\n mat-icon-button\n class=\"component-menu\"\n [fsMenuTriggerFor]=\"menu\"\n (pointerdown)=\"$event.stopPropagation()\"\n (mousedown)=\"stopCanvasPan($event)\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <!-- Beside its trigger, inside the same block: an fs-menu that finds no\n trigger of its own draws one. -->\n <fs-menu #menu>\n <ng-template\n fs-menu-item\n [hidden]=\"!isText\"\n (click)=\"editText()\">\n <mat-icon>edit</mat-icon>\n <span>Edit text</span>\n </ng-template>\n <ng-template\n fs-menu-item\n [hidden]=\"!isText\"\n (click)=\"deleteText()\">\n <mat-icon>delete</mat-icon>\n <span>Delete</span>\n </ng-template>\n <ng-template\n fs-menu-item\n [hidden]=\"!drillCrumbs().length || editMode\"\n (click)=\"drillUp()\">\n <mat-icon>arrow_upward</mat-icon>\n <span>Drill up</span>\n </ng-template>\n <ng-template\n fs-menu-item\n [hidden]=\"!drillCrumbs().length || editMode\"\n (click)=\"drillTo(0)\">\n <mat-icon>vertical_align_top</mat-icon>\n <span>Back to top</span>\n </ng-template>\n <ng-template\n fs-menu-item\n [hidden]=\"isText\"\n (click)=\"settings()\">\n <mat-icon>tune</mat-icon>\n <span>Settings</span>\n </ng-template>\n <ng-template\n fs-menu-item\n [hidden]=\"isText\"\n (click)=\"exportCsv()\">\n <mat-icon>download</mat-icon>\n <span>Export CSV</span>\n </ng-template>\n <ng-template\n fs-menu-item\n [hidden]=\"!hidesColumns\"\n (click)=\"chooseColumns()\">\n <mat-icon>view_column</mat-icon>\n <span>Columns</span>\n </ng-template>\n </fs-menu>\n }\n <div class=\"component-body\">\n @if (isText) {\n <app-report-component-text\n [html]=\"textHtml() ?? component.config?.html ?? ''\"\n [tokens]=\"tokens()\"\n [editing]=\"textEditing()\"\n [shownElsewhere]=\"shownElsewhere\"\n (saved)=\"onTextSaved($event)\"\n (editEnded)=\"textEditing.set(false)\"\n (valueSettings)=\"valueSettings.emit($event)\">\n </app-report-component-text>\n } @else if (component.type === 'list') {\n @for (key of [listResetKey()]; track key) {\n <app-report-component-list\n [reportId]=\"reportId\"\n [component]=\"component\">\n </app-report-component-list>\n }\n } @else if (component.type === 'grid') {\n <app-report-component-grid\n [reportId]=\"reportId\"\n [component]=\"component\">\n </app-report-component-grid>\n } @else if (loading()) {\n <!-- Holds the tile's height for the spinner on the first load. -->\n <div class=\"component-state\"></div>\n } @else if (error()) {\n <div class=\"component-state error\">\n {{ error() }}\n </div>\n } @else if (!data()?.rows?.length) {\n <div class=\"component-state\">\n {{ emptyMessage() }}\n </div>\n } @else if (component.type === 'kpi') {\n <app-report-component-kpi\n [component]=\"component\"\n [data]=\"data()\"\n (markClick)=\"onMarkClick($event)\">\n </app-report-component-kpi>\n } @else {\n <app-report-component-chart\n [component]=\"component\"\n [data]=\"data()\"\n [actions]=\"tileActions()\"\n [(legendSelected)]=\"legendSelected\"\n (markClick)=\"onMarkClick($event)\"\n (markMiss)=\"onMarkMiss()\">\n </app-report-component-chart>\n }\n <!-- In edit mode a transparent veil over the body makes the WHOLE\n component draggable (industry standard: you grab the object, not just\n its title bar) and keeps inner widgets from swallowing the gesture. -->\n @if (editMode && !textEditing()) {\n <div\n class=\"drag-veil\"\n (pointerdown)=\"onDragStart($event)\">\n </div>\n }\n </div>\n <!-- A load: a spinner centred on the whole tile. On a refetch the body and\n the menu are dimmed under it (.refreshing); the title is not. -->\n @if (loading() || refreshing()) {\n <mat-progress-spinner\n class=\"load-spinner\"\n aria-label=\"Loading data\"\n mode=\"indeterminate\"\n [diameter]=\"15\">\n </mat-progress-spinner>\n }\n</div>\n<!-- The mark menu, for a click whose mark offers two or more actions. It\n opens at the click: its trigger is a zero-size anchor that\n anchor-at-point.ts moves there first. -->\n@if (!isText && !editMode) {\n <span\n #markAnchor\n [style.position]=\"'absolute'\"\n [fsMenuTriggerFor]=\"markMenu\">\n </span>\n <fs-menu #markMenu>\n @for (action of markMenuActions(); track action) {\n <ng-template\n fs-menu-item\n (click)=\"runMarkAction(action)\">\n {{ markActionLabels[action] }}\n </ng-template>\n }\n </fs-menu>\n}\n<!-- Handles live OUTSIDE the clipped box so they straddle its edges. -->\n@if (editMode && selected) {\n @for (handle of resizeHandles; track handle) {\n <div\n class=\"handle handle-{{ handle }}\"\n (mousedown)=\"stopCanvasPan($event)\"\n (pointerdown)=\"onResizeStart($event, handle)\">\n </div>\n }\n}", styles: [":host{position:absolute;display:flex;flex-direction:column;font-size:10px;--mdc-outlined-button-container-height: 30px;--mdc-outlined-button-label-text-size: 10px;--mat-outlined-button-horizontal-padding: 15px;--mdc-text-button-container-height: 30px;--mdc-text-button-label-text-size: 10px;--mat-text-button-horizontal-padding: 15px;--mat-button-outlined-container-height: 30px;--mat-button-outlined-label-text-size: 10px;--mat-button-outlined-horizontal-padding: 15px;--mat-button-text-container-height: 30px;--mat-button-text-label-text-size: 10px;--mat-button-text-horizontal-padding: 15px}.component-box{position:relative;width:100%;flex:1 1 auto;min-height:0;box-sizing:border-box;display:flex;flex-direction:column;background:#fff;border:1px solid #e4e7eb;border-radius:6px;overflow:hidden;transition:box-shadow .12s ease,border-color .12s ease;cursor:default}.component-box.editing .component-title{cursor:grab}.component-box.editing .component-title:active{cursor:grabbing}.component-box.editing .drill-crumb{pointer-events:none}.component-box.editing:hover{border-color:#9db3c8;box-shadow:0 2px 8px #0f172a14}.component-box.selected{border-color:var(--brand-primary-color);box-shadow:0 0 0 1px var(--brand-primary-color),0 4px 14px #2196f32e}.component-box.text{background:transparent;border-color:transparent;border-radius:0;overflow:visible}.component-box.text.editing{border-style:dashed;border-color:#cbd2d9}.component-box.text.editing:hover{box-shadow:none}.component-box.text.selected{border-style:solid;border-color:var(--brand-primary-color);box-shadow:0 0 0 1px var(--brand-primary-color)}:host ::ng-deep .component-filter .filter-bar-container{align-items:center!important}.component-filter{flex:0 0 auto;display:block;padding:0 0 4px}.component-filter .component-title{display:flex;align-items:center;gap:4px;-webkit-user-select:none;user-select:none;padding-right:40px;font-size:var(--report-heading-size);font-weight:600;color:#1f2933;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.component-filter .component-title .truncated-icon{font-size:16px;width:16px;height:16px;color:#f59e0b}.component-filter .component-title .drill-path{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;direction:rtl;text-align:left}.component-filter .component-title .drill-crumb{color:inherit;cursor:pointer;text-decoration:none}.component-filter .component-title .drill-crumb:hover,.component-filter .component-title .drill-crumb:focus-visible{text-decoration:underline}.component-filter .component-title .drill-separator{opacity:.6}.component-menu{position:absolute;top:2px;right:2px;z-index:30}.component-body{flex:1 1 auto;min-height:0;position:relative}.component-box.refreshing .component-body,.component-box.refreshing .component-menu{opacity:.35;transition:opacity .15s ease}.load-spinner{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%) scale(calc(1 / var(--canvas-zoom, 1)));z-index:25;pointer-events:none}:host(.height-auto) .component-state{min-height:120px}.drag-veil{position:absolute;inset:0;cursor:grab;touch-action:none}.drag-veil:active{cursor:grabbing}.component-state{width:100%;height:100%;display:flex;align-items:center;justify-content:center;font-size:12px;color:#7b8794;padding:8px;text-align:center}.component-state.error{color:#e15759}.handle{position:absolute;width:14px;height:14px;display:flex;align-items:center;justify-content:center;touch-action:none;z-index:20;transform:scale(calc(1 / var(--canvas-zoom, 1)))}.handle:before{content:\"\";width:8px;height:8px;background:#fff;border:1.5px solid var(--brand-primary-color);border-radius:2px;box-shadow:0 1px 2px #0f172a33}.handle-nw{left:-7px;top:-7px;cursor:nwse-resize}.handle-n{left:calc(50% - 7px);top:-7px;cursor:ns-resize}.handle-ne{right:-7px;top:-7px;cursor:nesw-resize}.handle-e{right:-7px;top:calc(50% - 7px);cursor:ew-resize}.handle-se{right:-7px;bottom:-7px;cursor:nwse-resize}.handle-s{left:calc(50% - 7px);bottom:-7px;cursor:ns-resize}.handle-sw{left:-7px;bottom:-7px;cursor:nesw-resize}.handle-w{left:-7px;top:calc(50% - 7px);cursor:ew-resize}\n"], dependencies: [{ kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: FsFilterModule }, { kind: "component", type: i1.FilterComponent, selector: "fs-filter", inputs: ["config"], outputs: ["closed", "opened", "ready"] }, { kind: "directive", type: i1.FilterHeadingDirective, selector: "[fsFilterHeading]" }, { kind: "ngmodule", type: FsMenuModule }, { kind: "component", type: i2.FsMenuComponent, selector: "fs-menu", inputs: ["class", "buttonClass", "buttonType", "buttonColor"], outputs: ["opened", "closed"] }, { kind: "directive", type: i2.FsMenuItemDirective, selector: "fs-menu-group,[fs-menu-item]" }, { kind: "directive", type: i2.FsMenuTriggerDirective, selector: "[fsMenuTriggerFor]", inputs: ["fsMenuTriggerFor"] }, { kind: "component", type: ComponentChartComponent, selector: "app-report-component-chart", inputs: ["component", "data", "legendSelected", "actions"], outputs: ["legendSelectedChange", "markClick", "markMiss"] }, { kind: "component", type: ComponentGridComponent, selector: "app-report-component-grid", inputs: ["reportId", "component"] }, { kind: "component", type: ComponentKpiComponent, selector: "app-report-component-kpi", inputs: ["component", "data"], outputs: ["markClick"] }, { kind: "component", type: ComponentListComponent, selector: "app-report-component-list", inputs: ["reportId", "component"] }, { kind: "component", type: ComponentTextComponent, selector: "app-report-component-text", inputs: ["html", "tokens", "editing", "shownElsewhere"], outputs: ["saved", "editEnded", "valueSettings"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
762
768
|
}
|
|
763
769
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportComponentComponent, decorators: [{
|
|
764
770
|
type: Component,
|
|
765
771
|
args: [{ selector: 'app-report-component', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
|
|
766
772
|
MatIcon,
|
|
767
773
|
MatIconButton,
|
|
768
|
-
|
|
774
|
+
MatProgressSpinner,
|
|
769
775
|
MatTooltip,
|
|
770
776
|
FsFilterModule,
|
|
771
777
|
FsMenuModule,
|
|
772
778
|
ComponentChartComponent,
|
|
779
|
+
ComponentGridComponent,
|
|
773
780
|
ComponentKpiComponent,
|
|
774
781
|
ComponentListComponent,
|
|
775
782
|
ComponentTextComponent,
|
|
776
|
-
], template: "<div\n class=\"component-box\"\n [class.editing]=\"editMode\"\n [class.text]=\"isText\"\n [class.selected]=\"selected\"\n [style.padding]=\"bodyPadding\"\n (pointerdown)=\"onComponentPointerDown($event)\"\n (mousedown)=\"stopCanvasPan($event)\"\n (touchstart)=\"stopCanvasPan($event)\">\n <!-- The header is an fs-filter: heading template = title (and the edit-mode\n drag handle), actions = the menu, items = component-level filter groups,\n the same strip for every type (lists included). fs-filter reads its\n config once, so the block is keyed on the component-filter set to be\n recreated when it changes. The title shows its tokens filled, and a\n filter change repaints it in place (shownTitle). -->\n <!-- A text block has no title bar \u2014 it IS its words, like a text box on a\n slide \u2014 so it gets neither the header nor the data actions. -->\n @for (key of isText ? [] : [filterKey]; track key) {\n <fs-filter\n class=\"component-filter\"\n [config]=\"filterConfig()\">\n <ng-template fsFilterHeading>\n <div\n class=\"component-title\"\n (pointerdown)=\"onDragStart($event)\">\n <!-- While the chart is drilled the title leads its breadcrumb:\n 'Title \u203A 2026 \u203A Q3', the title as the viewer reads it\n (shownTitle). The title goes back to the top and each\n crumb to the period it names; the last is where the chart is.\n A long path is cut at its left end, so the crumbs nearest the\n chart stay in view. While the layout is edited the crumbs are\n plain text (the stylesheet; drillTo does nothing then). -->\n @if (drillCrumbs().length) {\n <span class=\"drill-path\">\n <span dir=\"ltr\">\n <a\n class=\"drill-crumb\"\n tabindex=\"0\"\n (click)=\"drillTo(0)\"\n (keydown.enter)=\"drillTo(0)\">\n {{ shownTitle }}\n </a>\n @for (label of drillCrumbs(); track $index; let last = $last) {\n <span class=\"drill-separator\">{{ drillSeparator }}</span>\n @if (last) {\n <span>{{ label }}</span>\n } @else {\n <a\n class=\"drill-crumb\"\n tabindex=\"0\"\n (click)=\"drillTo($index + 1)\"\n (keydown.enter)=\"drillTo($index + 1)\">\n {{ label }}\n </a>\n }\n }\n </span>\n </span>\n } @else {\n {{ shownTitle }}\n }\n @if (truncated) {\n <mat-icon\n class=\"truncated-icon\"\n matTooltip=\"Showing a truncated result \u2014 refine the filters to see everything.\">\n warning_amber\n </mat-icon>\n }\n </div>\n </ng-template>\n </fs-filter>\n }\n <!-- The actions menu is floated top-right (absolute) rather than living in\n fs-filter's actions slot, so its ~40px button height no longer drives the\n header row's height. It overlays the box corner; the heading reserves\n right padding so a long title ellipsises before it. -->\n @if (!isText || (editMode && !textEditing())) {\n <button\n mat-icon-button\n class=\"component-menu\"\n [fsMenuTriggerFor]=\"menu\"\n (pointerdown)=\"$event.stopPropagation()\"\n (mousedown)=\"stopCanvasPan($event)\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <!-- Beside its trigger, inside the same block: an fs-menu that finds no\n trigger of its own draws one. -->\n <fs-menu #menu>\n <ng-template\n fs-menu-item\n [hidden]=\"!isText\"\n (click)=\"editText()\">\n <mat-icon>edit</mat-icon>\n <span>Edit text</span>\n </ng-template>\n <ng-template\n fs-menu-item\n [hidden]=\"!isText\"\n (click)=\"deleteText()\">\n <mat-icon>delete</mat-icon>\n <span>Delete</span>\n </ng-template>\n <ng-template\n fs-menu-item\n [hidden]=\"!drillCrumbs().length || editMode\"\n (click)=\"drillUp()\">\n <mat-icon>arrow_upward</mat-icon>\n <span>Drill up</span>\n </ng-template>\n <ng-template\n fs-menu-item\n [hidden]=\"!drillCrumbs().length || editMode\"\n (click)=\"drillTo(0)\">\n <mat-icon>vertical_align_top</mat-icon>\n <span>Back to top</span>\n </ng-template>\n <ng-template\n fs-menu-item\n [hidden]=\"isText\"\n (click)=\"settings()\">\n <mat-icon>tune</mat-icon>\n <span>Settings</span>\n </ng-template>\n <ng-template\n fs-menu-item\n [hidden]=\"isText\"\n (click)=\"exportCsv()\">\n <mat-icon>download</mat-icon>\n <span>Export CSV</span>\n </ng-template>\n <ng-template\n fs-menu-item\n [hidden]=\"!hidesColumns\"\n (click)=\"chooseColumns()\">\n <mat-icon>view_column</mat-icon>\n <span>Columns</span>\n </ng-template>\n </fs-menu>\n }\n <div class=\"component-body\">\n <!-- A refetch keeps the data on screen under a thin bar; the shimmer\n below is for the first load only. -->\n @if (refreshing()) {\n <mat-progress-bar\n class=\"refresh-bar\"\n aria-label=\"Refreshing data\"\n [mode]=\"'indeterminate'\">\n </mat-progress-bar>\n }\n @if (isText) {\n <app-report-component-text\n [html]=\"textHtml() ?? component.config?.html ?? ''\"\n [tokens]=\"tokens()\"\n [editing]=\"textEditing()\"\n [shownElsewhere]=\"shownElsewhere\"\n (saved)=\"onTextSaved($event)\"\n (editEnded)=\"textEditing.set(false)\"\n (valueSettings)=\"valueSettings.emit($event)\">\n </app-report-component-text>\n } @else if (component.type === 'list') {\n @for (key of [listResetKey()]; track key) {\n <app-report-component-list\n [reportId]=\"reportId\"\n [component]=\"component\">\n </app-report-component-list>\n }\n } @else if (loading()) {\n <div class=\"component-state\">\n <div class=\"loading-shimmer\"></div>\n </div>\n } @else if (error()) {\n <div class=\"component-state error\">\n {{ error() }}\n </div>\n } @else if (!data()?.rows?.length) {\n <div class=\"component-state\">\n {{ emptyMessage() }}\n </div>\n } @else if (component.type === 'kpi') {\n <app-report-component-kpi\n [component]=\"component\"\n [data]=\"data()\"\n (markClick)=\"onMarkClick($event)\">\n </app-report-component-kpi>\n } @else {\n <app-report-component-chart\n [component]=\"component\"\n [data]=\"data()\"\n [actions]=\"tileActions()\"\n [(legendSelected)]=\"legendSelected\"\n (markClick)=\"onMarkClick($event)\"\n (markMiss)=\"onMarkMiss()\">\n </app-report-component-chart>\n }\n <!-- In edit mode a transparent veil over the body makes the WHOLE\n component draggable (industry standard: you grab the object, not just\n its title bar) and keeps inner widgets from swallowing the gesture. -->\n @if (editMode && !textEditing()) {\n <div\n class=\"drag-veil\"\n (pointerdown)=\"onDragStart($event)\">\n </div>\n }\n </div>\n</div>\n<!-- The mark menu, for a click whose mark offers two or more actions. It\n opens at the click: its trigger is a zero-size anchor that\n anchor-at-point.ts moves there first. -->\n@if (!isText && !editMode) {\n <span\n #markAnchor\n [style.position]=\"'absolute'\"\n [fsMenuTriggerFor]=\"markMenu\">\n </span>\n <fs-menu #markMenu>\n @for (action of markMenuActions(); track action) {\n <ng-template\n fs-menu-item\n (click)=\"runMarkAction(action)\">\n {{ markActionLabels[action] }}\n </ng-template>\n }\n </fs-menu>\n}\n<!-- Handles live OUTSIDE the clipped box so they straddle its edges. -->\n@if (editMode && selected) {\n @for (handle of resizeHandles; track handle) {\n <div\n class=\"handle handle-{{ handle }}\"\n (mousedown)=\"stopCanvasPan($event)\"\n (pointerdown)=\"onResizeStart($event, handle)\">\n </div>\n }\n}", styles: [":host{position:absolute;display:flex;flex-direction:column;font-size:10px;--mdc-outlined-button-container-height: 30px;--mdc-outlined-button-label-text-size: 10px;--mat-outlined-button-horizontal-padding: 15px;--mdc-text-button-container-height: 30px;--mdc-text-button-label-text-size: 10px;--mat-text-button-horizontal-padding: 15px;--mat-button-outlined-container-height: 30px;--mat-button-outlined-label-text-size: 10px;--mat-button-outlined-horizontal-padding: 15px;--mat-button-text-container-height: 30px;--mat-button-text-label-text-size: 10px;--mat-button-text-horizontal-padding: 15px}.component-box{position:relative;width:100%;flex:1 1 auto;min-height:0;box-sizing:border-box;display:flex;flex-direction:column;background:#fff;border:1px solid #e4e7eb;border-radius:6px;overflow:hidden;transition:box-shadow .12s ease,border-color .12s ease;cursor:default}.component-box.editing .component-title{cursor:grab}.component-box.editing .component-title:active{cursor:grabbing}.component-box.editing .drill-crumb{pointer-events:none}.component-box.editing:hover{border-color:#9db3c8;box-shadow:0 2px 8px #0f172a14}.component-box.selected{border-color:var(--brand-primary-color);box-shadow:0 0 0 1px var(--brand-primary-color),0 4px 14px #2196f32e}.component-box.text{background:transparent;border-color:transparent;border-radius:0;overflow:visible}.component-box.text.editing{border-style:dashed;border-color:#cbd2d9}.component-box.text.editing:hover{box-shadow:none}.component-box.text.selected{border-style:solid;border-color:var(--brand-primary-color);box-shadow:0 0 0 1px var(--brand-primary-color)}:host ::ng-deep .component-filter .filter-bar-container{align-items:center!important}.component-filter{flex:0 0 auto;display:block;padding:0 0 4px}.component-filter .component-title{display:flex;align-items:center;gap:4px;-webkit-user-select:none;user-select:none;padding-right:40px;font-size:var(--report-heading-size);font-weight:600;color:#1f2933;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.component-filter .component-title .truncated-icon{font-size:16px;width:16px;height:16px;color:#f59e0b}.component-filter .component-title .drill-path{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;direction:rtl;text-align:left}.component-filter .component-title .drill-crumb{color:inherit;cursor:pointer;text-decoration:none}.component-filter .component-title .drill-crumb:hover,.component-filter .component-title .drill-crumb:focus-visible{text-decoration:underline}.component-filter .component-title .drill-separator{opacity:.6}.component-menu{position:absolute;top:2px;right:2px;z-index:30}.component-body{flex:1 1 auto;min-height:0;position:relative}.refresh-bar{position:absolute;top:0;left:0;right:0;z-index:1;pointer-events:none;--mdc-linear-progress-track-height: 2px;--mdc-linear-progress-active-indicator-height: 2px;--mat-progress-bar-track-height: 2px;--mat-progress-bar-active-indicator-height: 2px}:host(.height-auto) .component-state{min-height:120px}.drag-veil{position:absolute;inset:0;cursor:grab;touch-action:none}.drag-veil:active{cursor:grabbing}.component-state{width:100%;height:100%;display:flex;align-items:center;justify-content:center;font-size:12px;color:#7b8794;padding:8px;text-align:center}.component-state.error{color:#e15759}.loading-shimmer{width:70%;height:60%;border-radius:6px;background:linear-gradient(100deg,#f0f4f8 40%,#e4ebf2,#f0f4f8 60%);background-size:200% 100%;animation:shimmer 1.2s infinite linear}@keyframes shimmer{to{background-position-x:-200%}}.handle{position:absolute;width:14px;height:14px;display:flex;align-items:center;justify-content:center;touch-action:none;z-index:20;transform:scale(calc(1 / var(--canvas-zoom, 1)))}.handle:before{content:\"\";width:8px;height:8px;background:#fff;border:1.5px solid var(--brand-primary-color);border-radius:2px;box-shadow:0 1px 2px #0f172a33}.handle-nw{left:-7px;top:-7px;cursor:nwse-resize}.handle-n{left:calc(50% - 7px);top:-7px;cursor:ns-resize}.handle-ne{right:-7px;top:-7px;cursor:nesw-resize}.handle-e{right:-7px;top:calc(50% - 7px);cursor:ew-resize}.handle-se{right:-7px;bottom:-7px;cursor:nwse-resize}.handle-s{left:calc(50% - 7px);bottom:-7px;cursor:ns-resize}.handle-sw{left:-7px;bottom:-7px;cursor:nesw-resize}.handle-w{left:-7px;top:calc(50% - 7px);cursor:ew-resize}\n"] }]
|
|
783
|
+
], template: "<div\n class=\"component-box\"\n [class.editing]=\"editMode\"\n [class.text]=\"isText\"\n [class.selected]=\"selected\"\n [class.refreshing]=\"refreshing()\"\n [style.padding]=\"bodyPadding\"\n (pointerdown)=\"onComponentPointerDown($event)\"\n (mousedown)=\"stopCanvasPan($event)\"\n (touchstart)=\"stopCanvasPan($event)\">\n <!-- The header is an fs-filter: heading template = title (and the edit-mode\n drag handle), actions = the menu, items = component-level filter groups,\n the same strip for every type (lists included). fs-filter reads its\n config once, so the block is keyed on the component-filter set to be\n recreated when it changes. The title shows its tokens filled, and a\n filter change repaints it in place (shownTitle). -->\n <!-- A text block has no title bar \u2014 it IS its words, like a text box on a\n slide \u2014 so it gets neither the header nor the data actions. -->\n @for (key of isText ? [] : [filterKey]; track key) {\n <fs-filter\n class=\"component-filter\"\n [config]=\"filterConfig()\">\n <ng-template fsFilterHeading>\n <div\n class=\"component-title\"\n (pointerdown)=\"onDragStart($event)\">\n <!-- While the chart is drilled the title leads its breadcrumb:\n 'Title \u203A 2026 \u203A Q3', the title as the viewer reads it\n (shownTitle). The title goes back to the top and each\n crumb to the period it names; the last is where the chart is.\n A long path is cut at its left end, so the crumbs nearest the\n chart stay in view. While the layout is edited the crumbs are\n plain text (the stylesheet; drillTo does nothing then). -->\n @if (drillCrumbs().length) {\n <span class=\"drill-path\">\n <span dir=\"ltr\">\n <a\n class=\"drill-crumb\"\n tabindex=\"0\"\n (click)=\"drillTo(0)\"\n (keydown.enter)=\"drillTo(0)\">\n {{ shownTitle }}\n </a>\n @for (label of drillCrumbs(); track $index; let last = $last) {\n <span class=\"drill-separator\">{{ drillSeparator }}</span>\n @if (last) {\n <span>{{ label }}</span>\n } @else {\n <a\n class=\"drill-crumb\"\n tabindex=\"0\"\n (click)=\"drillTo($index + 1)\"\n (keydown.enter)=\"drillTo($index + 1)\">\n {{ label }}\n </a>\n }\n }\n </span>\n </span>\n } @else {\n {{ shownTitle }}\n }\n @if (truncated) {\n <mat-icon\n class=\"truncated-icon\"\n matTooltip=\"Showing a truncated result \u2014 refine the filters to see everything.\">\n warning_amber\n </mat-icon>\n }\n </div>\n </ng-template>\n </fs-filter>\n }\n <!-- The actions menu is floated top-right (absolute) rather than living in\n fs-filter's actions slot, so its ~40px button height no longer drives the\n header row's height. It overlays the box corner; the heading reserves\n right padding so a long title ellipsises before it. -->\n @if (!isText || (editMode && !textEditing())) {\n <button\n mat-icon-button\n class=\"component-menu\"\n [fsMenuTriggerFor]=\"menu\"\n (pointerdown)=\"$event.stopPropagation()\"\n (mousedown)=\"stopCanvasPan($event)\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <!-- Beside its trigger, inside the same block: an fs-menu that finds no\n trigger of its own draws one. -->\n <fs-menu #menu>\n <ng-template\n fs-menu-item\n [hidden]=\"!isText\"\n (click)=\"editText()\">\n <mat-icon>edit</mat-icon>\n <span>Edit text</span>\n </ng-template>\n <ng-template\n fs-menu-item\n [hidden]=\"!isText\"\n (click)=\"deleteText()\">\n <mat-icon>delete</mat-icon>\n <span>Delete</span>\n </ng-template>\n <ng-template\n fs-menu-item\n [hidden]=\"!drillCrumbs().length || editMode\"\n (click)=\"drillUp()\">\n <mat-icon>arrow_upward</mat-icon>\n <span>Drill up</span>\n </ng-template>\n <ng-template\n fs-menu-item\n [hidden]=\"!drillCrumbs().length || editMode\"\n (click)=\"drillTo(0)\">\n <mat-icon>vertical_align_top</mat-icon>\n <span>Back to top</span>\n </ng-template>\n <ng-template\n fs-menu-item\n [hidden]=\"isText\"\n (click)=\"settings()\">\n <mat-icon>tune</mat-icon>\n <span>Settings</span>\n </ng-template>\n <ng-template\n fs-menu-item\n [hidden]=\"isText\"\n (click)=\"exportCsv()\">\n <mat-icon>download</mat-icon>\n <span>Export CSV</span>\n </ng-template>\n <ng-template\n fs-menu-item\n [hidden]=\"!hidesColumns\"\n (click)=\"chooseColumns()\">\n <mat-icon>view_column</mat-icon>\n <span>Columns</span>\n </ng-template>\n </fs-menu>\n }\n <div class=\"component-body\">\n @if (isText) {\n <app-report-component-text\n [html]=\"textHtml() ?? component.config?.html ?? ''\"\n [tokens]=\"tokens()\"\n [editing]=\"textEditing()\"\n [shownElsewhere]=\"shownElsewhere\"\n (saved)=\"onTextSaved($event)\"\n (editEnded)=\"textEditing.set(false)\"\n (valueSettings)=\"valueSettings.emit($event)\">\n </app-report-component-text>\n } @else if (component.type === 'list') {\n @for (key of [listResetKey()]; track key) {\n <app-report-component-list\n [reportId]=\"reportId\"\n [component]=\"component\">\n </app-report-component-list>\n }\n } @else if (component.type === 'grid') {\n <app-report-component-grid\n [reportId]=\"reportId\"\n [component]=\"component\">\n </app-report-component-grid>\n } @else if (loading()) {\n <!-- Holds the tile's height for the spinner on the first load. -->\n <div class=\"component-state\"></div>\n } @else if (error()) {\n <div class=\"component-state error\">\n {{ error() }}\n </div>\n } @else if (!data()?.rows?.length) {\n <div class=\"component-state\">\n {{ emptyMessage() }}\n </div>\n } @else if (component.type === 'kpi') {\n <app-report-component-kpi\n [component]=\"component\"\n [data]=\"data()\"\n (markClick)=\"onMarkClick($event)\">\n </app-report-component-kpi>\n } @else {\n <app-report-component-chart\n [component]=\"component\"\n [data]=\"data()\"\n [actions]=\"tileActions()\"\n [(legendSelected)]=\"legendSelected\"\n (markClick)=\"onMarkClick($event)\"\n (markMiss)=\"onMarkMiss()\">\n </app-report-component-chart>\n }\n <!-- In edit mode a transparent veil over the body makes the WHOLE\n component draggable (industry standard: you grab the object, not just\n its title bar) and keeps inner widgets from swallowing the gesture. -->\n @if (editMode && !textEditing()) {\n <div\n class=\"drag-veil\"\n (pointerdown)=\"onDragStart($event)\">\n </div>\n }\n </div>\n <!-- A load: a spinner centred on the whole tile. On a refetch the body and\n the menu are dimmed under it (.refreshing); the title is not. -->\n @if (loading() || refreshing()) {\n <mat-progress-spinner\n class=\"load-spinner\"\n aria-label=\"Loading data\"\n mode=\"indeterminate\"\n [diameter]=\"15\">\n </mat-progress-spinner>\n }\n</div>\n<!-- The mark menu, for a click whose mark offers two or more actions. It\n opens at the click: its trigger is a zero-size anchor that\n anchor-at-point.ts moves there first. -->\n@if (!isText && !editMode) {\n <span\n #markAnchor\n [style.position]=\"'absolute'\"\n [fsMenuTriggerFor]=\"markMenu\">\n </span>\n <fs-menu #markMenu>\n @for (action of markMenuActions(); track action) {\n <ng-template\n fs-menu-item\n (click)=\"runMarkAction(action)\">\n {{ markActionLabels[action] }}\n </ng-template>\n }\n </fs-menu>\n}\n<!-- Handles live OUTSIDE the clipped box so they straddle its edges. -->\n@if (editMode && selected) {\n @for (handle of resizeHandles; track handle) {\n <div\n class=\"handle handle-{{ handle }}\"\n (mousedown)=\"stopCanvasPan($event)\"\n (pointerdown)=\"onResizeStart($event, handle)\">\n </div>\n }\n}", styles: [":host{position:absolute;display:flex;flex-direction:column;font-size:10px;--mdc-outlined-button-container-height: 30px;--mdc-outlined-button-label-text-size: 10px;--mat-outlined-button-horizontal-padding: 15px;--mdc-text-button-container-height: 30px;--mdc-text-button-label-text-size: 10px;--mat-text-button-horizontal-padding: 15px;--mat-button-outlined-container-height: 30px;--mat-button-outlined-label-text-size: 10px;--mat-button-outlined-horizontal-padding: 15px;--mat-button-text-container-height: 30px;--mat-button-text-label-text-size: 10px;--mat-button-text-horizontal-padding: 15px}.component-box{position:relative;width:100%;flex:1 1 auto;min-height:0;box-sizing:border-box;display:flex;flex-direction:column;background:#fff;border:1px solid #e4e7eb;border-radius:6px;overflow:hidden;transition:box-shadow .12s ease,border-color .12s ease;cursor:default}.component-box.editing .component-title{cursor:grab}.component-box.editing .component-title:active{cursor:grabbing}.component-box.editing .drill-crumb{pointer-events:none}.component-box.editing:hover{border-color:#9db3c8;box-shadow:0 2px 8px #0f172a14}.component-box.selected{border-color:var(--brand-primary-color);box-shadow:0 0 0 1px var(--brand-primary-color),0 4px 14px #2196f32e}.component-box.text{background:transparent;border-color:transparent;border-radius:0;overflow:visible}.component-box.text.editing{border-style:dashed;border-color:#cbd2d9}.component-box.text.editing:hover{box-shadow:none}.component-box.text.selected{border-style:solid;border-color:var(--brand-primary-color);box-shadow:0 0 0 1px var(--brand-primary-color)}:host ::ng-deep .component-filter .filter-bar-container{align-items:center!important}.component-filter{flex:0 0 auto;display:block;padding:0 0 4px}.component-filter .component-title{display:flex;align-items:center;gap:4px;-webkit-user-select:none;user-select:none;padding-right:40px;font-size:var(--report-heading-size);font-weight:600;color:#1f2933;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.component-filter .component-title .truncated-icon{font-size:16px;width:16px;height:16px;color:#f59e0b}.component-filter .component-title .drill-path{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;direction:rtl;text-align:left}.component-filter .component-title .drill-crumb{color:inherit;cursor:pointer;text-decoration:none}.component-filter .component-title .drill-crumb:hover,.component-filter .component-title .drill-crumb:focus-visible{text-decoration:underline}.component-filter .component-title .drill-separator{opacity:.6}.component-menu{position:absolute;top:2px;right:2px;z-index:30}.component-body{flex:1 1 auto;min-height:0;position:relative}.component-box.refreshing .component-body,.component-box.refreshing .component-menu{opacity:.35;transition:opacity .15s ease}.load-spinner{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%) scale(calc(1 / var(--canvas-zoom, 1)));z-index:25;pointer-events:none}:host(.height-auto) .component-state{min-height:120px}.drag-veil{position:absolute;inset:0;cursor:grab;touch-action:none}.drag-veil:active{cursor:grabbing}.component-state{width:100%;height:100%;display:flex;align-items:center;justify-content:center;font-size:12px;color:#7b8794;padding:8px;text-align:center}.component-state.error{color:#e15759}.handle{position:absolute;width:14px;height:14px;display:flex;align-items:center;justify-content:center;touch-action:none;z-index:20;transform:scale(calc(1 / var(--canvas-zoom, 1)))}.handle:before{content:\"\";width:8px;height:8px;background:#fff;border:1.5px solid var(--brand-primary-color);border-radius:2px;box-shadow:0 1px 2px #0f172a33}.handle-nw{left:-7px;top:-7px;cursor:nwse-resize}.handle-n{left:calc(50% - 7px);top:-7px;cursor:ns-resize}.handle-ne{right:-7px;top:-7px;cursor:nesw-resize}.handle-e{right:-7px;top:calc(50% - 7px);cursor:ew-resize}.handle-se{right:-7px;bottom:-7px;cursor:nwse-resize}.handle-s{left:calc(50% - 7px);bottom:-7px;cursor:ns-resize}.handle-sw{left:-7px;bottom:-7px;cursor:nesw-resize}.handle-w{left:-7px;top:calc(50% - 7px);cursor:ew-resize}\n"] }]
|
|
777
784
|
}], propDecorators: { reportId: [{
|
|
778
785
|
type: Input
|
|
779
786
|
}], component: [{
|
|
@@ -807,4 +814,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
807
814
|
type: HostBinding,
|
|
808
815
|
args: ['class.height-auto']
|
|
809
816
|
}] } });
|
|
810
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0LWNvbXBvbmVudC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBwL3JlcG9ydHMvY29tcG9uZW50cy9yZXBvcnQtY29tcG9uZW50L3JlcG9ydC1jb21wb25lbnQuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9yZXBvcnRzL2NvbXBvbmVudHMvcmVwb3J0LWNvbXBvbmVudC9yZXBvcnQtY29tcG9uZW50LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCx1QkFBdUIsRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFDMUQsWUFBWSxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFxQixNQUFNLEVBQWlCLFNBQVMsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUMvRyxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxTQUFTLEdBQ2pDLE1BQU0sZUFBZSxDQUFDO0FBR3ZCLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDckQsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ2pELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNoRSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFFdkQsT0FBTyxFQUFnQixjQUFjLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNsRSxPQUFPLEVBQUUsZUFBZSxFQUFFLFlBQVksRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ2pFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNoRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDaEQsT0FBTyxF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LEVBQUUsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7SUFDckYsQ0FBQzt3R0ExMUJVLHdCQUF3Qjs0RkFBeEIsd0JBQXdCLDBqREF5SEEsc0JBQXNCLGlHQXBFOUMsdUJBQXVCLHVQQzlKcEMsMjlRQXlPQyxzeElENUlHLE9BQU8sMklBQ1AsYUFBYSw2RkFDYixjQUFjLHlLQUNkLFVBQVUsZ1JBQ1YsY0FBYyx5UEFDZCxZQUFZLHdaQUNaLHVCQUF1QiwrTEFDdkIscUJBQXFCLDRIQUNyQixzQkFBc0IseUdBQ3RCLHNCQUFzQjs7NEZBR2Isd0JBQXdCO2tCQW5CcEMsU0FBUzsrQkFDRSxzQkFBc0IsbUJBR2YsdUJBQXVCLENBQUMsTUFBTSxjQUNuQyxJQUFJLFdBQ1A7d0JBQ1AsT0FBTzt3QkFDUCxhQUFhO3dCQUNiLGNBQWM7d0JBQ2QsVUFBVTt3QkFDVixjQUFjO3dCQUNkLFlBQVk7d0JBQ1osdUJBQXVCO3dCQUN2QixxQkFBcUI7d0JBQ3JCLHNCQUFzQjt3QkFDdEIsc0JBQXNCO3FCQUN2Qjs4QkFJZSxRQUFRO3NCQUF2QixLQUFLO2dCQUNVLFNBQVM7c0JBQXhCLEtBQUs7Z0JBQ1UsTUFBTTtzQkFBckIsS0FBSztnQkFDVSxRQUFRO3NCQUF2QixLQUFLO2dCQUVVLElBQUk7c0JBQW5CLEtBQUs7Z0JBQ1UsT0FBTztzQkFBdEIsS0FBSztnQkFDVSxRQUFRO3NCQUF2QixLQUFLO2dCQUVXLGVBQWU7c0JBQS9CLE1BQU07Z0JBQ1UsZUFBZTtzQkFBL0IsTUFBTTtnQkFDVSxZQUFZO3NCQUE1QixNQUFNO2dCQXlDQSxjQUFjO3NCQURwQixTQUFTO3VCQUFDLHVCQUF1QjtnQkErRDNCLFFBQVE7c0JBRGQsU0FBUzt1QkFBQyxVQUFVO2dCQUlkLFVBQVU7c0JBRGhCLFNBQVM7dUJBQUMsWUFBWTtnQkErbUJaLFVBQVU7c0JBRHBCLFdBQVc7dUJBQUMsbUJBQW1CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCwgRGVzdHJveVJlZiwgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLCBIb3N0QmluZGluZywgSW5wdXQsIE5nWm9uZSwgT25DaGFuZ2VzLCBPbkluaXQsIE91dHB1dCwgU2ltcGxlQ2hhbmdlcywgVmlld0NoaWxkLCBjb21wdXRlZCwgaW5qZWN0LFxuICBpbnB1dCwgb3V0cHV0LCBzaWduYWwsIHZpZXdDaGlsZCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cblxuaW1wb3J0IHsgTWF0SWNvbkJ1dHRvbiB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2J1dHRvbic7XG5pbXBvcnQgeyBNYXREaWFsb2cgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9kaWFsb2cnO1xuaW1wb3J0IHsgTWF0SWNvbiB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2ljb24nO1xuaW1wb3J0IHsgTWF0UHJvZ3Jlc3NCYXIgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9wcm9ncmVzcy1iYXInO1xuaW1wb3J0IHsgTWF0VG9vbHRpcCB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3Rvb2x0aXAnO1xuXG5pbXBvcnQgeyBGaWx0ZXJDb25maWcsIEZzRmlsdGVyTW9kdWxlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvZmlsdGVyJztcbmltcG9ydCB7IEZzTWVudUNvbXBvbmVudCwgRnNNZW51TW9kdWxlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvbWVudSc7XG5pbXBvcnQgeyBGc01lc3NhZ2UgfSBmcm9tICdAZmlyZXN0aXRjaC9tZXNzYWdlJztcbmltcG9ydCB7IEZzUHJvY2VzcyB9IGZyb20gJ0BmaXJlc3RpdGNoL3Byb2Nlc3MnO1xuaW1wb3J0IHsgRnNQcm9tcHQgfSBmcm9tICdAZmlyZXN0aXRjaC9wcm9tcHQnO1xuXG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBTdWJqZWN0LCBmaWx0ZXIgYXMgcnhGaWx0ZXIsIG1hcCwgc3dpdGNoTWFwLCB0YXAgfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgdGFrZVVudGlsRGVzdHJveWVkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZS9yeGpzLWludGVyb3AnO1xuXG5pbXBvcnQgeyBvcGVuQXRQb2ludCB9IGZyb20gJy4uLy4uL2FuY2hvci1hdC1wb2ludCc7XG5pbXBvcnQgeyBSZXBvcnREYXRhIH0gZnJvbSAnLi4vLi4vZGF0YS9yZXBvcnQuZGF0YSc7XG5pbXBvcnQgeyBMaXN0Q29sdW1uc0NvbXBvbmVudCwgTGlzdENvbHVtbnNEaWFsb2dEYXRhIH0gZnJvbSAnLi4vLi4vZGlhbG9ncy9saXN0LWNvbHVtbnMvbGlzdC1jb2x1bW5zLmNvbXBvbmVudCc7XG5pbXBvcnQge1xuICBEUklMTF9DUlVNQl9TRVBBUkFUT1IsIERSSUxMX1JFU0VUX01FU1NBR0UsIGFkb3B0ZWREcmlsbFBhdGgsIGRyaWxsQ3J1bWJMYWJlbHMsIGRyaWxsT3V0c2lkZU1lc3NhZ2UsXG4gIGRyaWxsUmVzZXROb3RlZCxcbn0gZnJvbSAnLi4vLi4vZHJpbGwtY3J1bWJzJztcbmltcG9ydCB7XG4gIENvbXBvbmVudERhdGEsXG4gIENvbXBvbmVudFNldHRpbmdzLFxuICBGaWx0ZXJHcm91cFZhbHVlLFxuICBLcGlDb25maWcsXG4gIFJlcG9ydENvbXBvbmVudCBhcyBSZXBvcnRDb21wb25lbnRNb2RlbCxcbiAgUmVwb3J0RmlsdGVyR3JvdXAsXG59IGZyb20gJy4uLy4uL2ludGVyZmFjZXMvcmVwb3J0LmludGVyZmFjZSc7XG5pbXBvcnQgeyBSZXBvcnRNYXJrQWN0aW9uIH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9yZXBvcnQtbWFyay1hY3Rpb24udHlwZSc7XG5pbXBvcnQgeyBSZXBvcnRNYXJrQ2xpY2sgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL3JlcG9ydC1tYXJrLWNsaWNrLmludGVyZmFjZSc7XG5pbXBvcnQgeyBUaWxlTG9hZFJlc3VsdCB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMvdGlsZS1sb2FkLXJlc3VsdC5pbnRlcmZhY2UnO1xuaW1wb3J0IHsga3BpQ2FyZFNldHRpbmdzLCBzYW1lS3BpQ2FyZFNldHRpbmdzIH0gZnJvbSAnLi4vLi4va3BpLWNhcmQnO1xuaW1wb3J0IHsgY29tcG9uZW50UGFkZGluZ0NzcyB9IGZyb20gJy4uLy4uL2xheW91dCc7XG5pbXBvcnQgeyBsaXN0SGlkZWFibGVDb2x1bW5zIH0gZnJvbSAnLi4vLi4vbGlzdC1jb25maWcnO1xuaW1wb3J0IHtcbiAgTUFSS19BQ1RJT05fTEFCRUxTLCBkZWNpZGVNYXJrQ2xpY2ssIGRyaWxsRG93blBhdGgsIG1hcmtBY3Rpb25zLCB0aWxlTWFya0FjdGlvbnMsXG59IGZyb20gJy4uLy4uL21hcmstY2xpY2snO1xuaW1wb3J0IHtcbiAgTElTVF9TRUFSQ0hfSVRFTSwgZmlsdGVySXRlbUZvckdyb3VwLCBncm91cFZhbHVlc0Zyb21RdWVyeSwgbGlzdFNlYXJjaEl0ZW0sXG59IGZyb20gJy4uLy4uL3JlcG9ydC1maWx0ZXItaXRlbXMnO1xuaW1wb3J0IHsgZ3JvdXBWYWx1ZVNpZ25hdHVyZSB9IGZyb20gJy4uLy4uL3JlcG9ydC1maWx0ZXItaXRlbXMnO1xuaW1wb3J0IHsgb2ZmZXJlZFZpZXdlckZlYXR1cmVzIH0gZnJvbSAnLi4vLi4vcmVwb3J0LXZpZXdlci1mZWF0dXJlcyc7XG5pbXBvcnQgeyBSZXBvcnRGaWx0ZXJPcHRpb25zU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL3JlcG9ydC1maWx0ZXItb3B0aW9ucy5zZXJ2aWNlJztcbmltcG9ydCB7IG1vdmVkR3JvdXBWYWx1ZXMsIFJlcG9ydEZpbHRlclN0YXRlU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL3JlcG9ydC1maWx0ZXItc3RhdGUuc2VydmljZSc7XG5pbXBvcnQgeyBpc1RpbWVTZXJpZXNDaGFydCB9IGZyb20gJy4uLy4uL3RpbGUtZGF0YS1zdGF0ZSc7XG5pbXBvcnQgeyB0aWxlTG9hZHMgfSBmcm9tICcuLi8uLi90aWxlLWxvYWRzJztcbmltcG9ydCB7IENvbXBvbmVudENoYXJ0Q29tcG9uZW50IH0gZnJvbSAnLi4vY29tcG9uZW50LWNoYXJ0L2NvbXBvbmVudC1jaGFydC5jb21wb25lbnQnO1xuaW1wb3J0IHsgQ29tcG9uZW50S3BpQ29tcG9uZW50IH0gZnJvbSAnLi4vY29tcG9uZW50LWtwaS9jb21wb25lbnQta3BpLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBDb21wb25lbnRMaXN0Q29tcG9uZW50IH0gZnJvbSAnLi4vY29tcG9uZW50LWxpc3QvY29tcG9uZW50LWxpc3QuY29tcG9uZW50JztcbmltcG9ydCB7IENvbXBvbmVudFRleHRDb21wb25lbnQgfSBmcm9tICcuLi9jb21wb25lbnQtdGV4dC9jb21wb25lbnQtdGV4dC5jb21wb25lbnQnO1xuaW1wb3J0IHsgVGV4dFRva2VuQ29udGV4dCwgZmlsbFRpdGxlVG9rZW5zIH0gZnJvbSAnLi4vLi4vdGV4dCc7XG5pbXBvcnQgeyBOT19WQUxVRV9LRVlTLCBpc0RyYXduLCB2YWx1ZUtleXMgfSBmcm9tICcuLi8uLi92YWx1ZXMnO1xuaW1wb3J0IHsgQ2FudmFzU25hcHBlciwgUFhfUEVSX0lOQ0ggfSBmcm9tICcuLi9yZXBvcnQtY2FudmFzL3JlcG9ydC1jYW52YXMuY29tcG9uZW50JztcblxuXG4vLyBSZXNpemUgaGFuZGxlcywgbmFtZWQgYnkgY29tcGFzcyBkaXJlY3Rpb24uXG5jb25zdCBIQU5ETEVTID0gWydudycsICduJywgJ25lJywgJ2UnLCAnc2UnLCAncycsICdzdycsICd3J10gYXMgY29uc3Q7XG50eXBlIEhhbmRsZSA9IHR5cGVvZiBIQU5ETEVTW251bWJlcl07XG5cbmNvbnN0IE1JTl9XID0gMC42OyAvLyBpbmNoZXNcbmNvbnN0IE1JTl9IID0gMC40OyAvLyBpbmNoZXNcblxuLy8gVHdvIHByZXNzZXMgb24gYSB0ZXh0IGJsb2NrIHRoaXMgY2xvc2UgdG9nZXRoZXIgb3BlbiBpdHMgZWRpdG9yLiBEZXRlY3RlZFxuLy8gaGVyZSByYXRoZXIgdGhhbiB3aXRoIGEgZGJsY2xpY2sgbGlzdGVuZXIgYmVjYXVzZSB0aGUgZHJhZyBsb29wIGNsYWltcyB0aGVcbi8vIHBvaW50ZXIgb24gZXZlcnkgcHJlc3MsIGFuZCBhIGJyb3dzZXIgaXMgbm90IG9ibGlnZWQgdG8gZGVsaXZlciBkYmxjbGlja1xuLy8gdGhyb3VnaCBhIGNhcHR1cmVkLCBkZWZhdWx0LXByZXZlbnRlZCBwb2ludGVyLlxuY29uc3QgRE9VQkxFX1BSRVNTX01TID0gNDAwO1xuXG4vLyBPbmUgY29tcG9uZW50IG9uIHRoZSBwYWdlOiB0aXRsZSBiYXIsIHRoZSB0eXBlLXNwZWNpZmljIGJvZHkgKGNoYXJ0IHwgbGlzdFxuLy8gfCBrcGkpLCBhIG1lbnUgKHNldHRpbmdzLCBmaWx0ZXIgdG9nZ2xlcywgZXhwb3J0KSDigJQgYW5kIHRoZSBlZGl0aW5nXG4vLyBpbnRlcmFjdGlvbnM6IGNsaWNrIHNlbGVjdHM7IHRoZSBzZWxlY3Rpb24gZnJhbWUgc2hvd3MgOCByZXNpemUgaGFuZGxlcztcbi8vIGRyYWdnaW5nIHRoZSBib2R5IG1vdmVzIHdpdGggc21hcnQgYWxpZ25tZW50IGd1aWRlcyAodmlhIHRoZSBjYW52YXNcbi8vIHNuYXBwZXIpOyBldmVyeXRoaW5nIHdvcmtzIGF0IGFueSB6b29tIChwaXhlbCBkZWx0YXMgw7cgem9vbcK3OTYg4oaSIGluY2hlcykuXG4vL1xuLy8gQ2hhcnRzIGFuZCBLUElzIGZldGNoIHRoZWlyIG93biBkYXRhIGhlcmU7IGxpc3RzIGZldGNoIGluc2lkZVxuLy8gQ29tcG9uZW50TGlzdENvbXBvbmVudCB0aHJvdWdoIEZzTGlzdCBwYWdpbmcuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhcHAtcmVwb3J0LWNvbXBvbmVudCcsXG4gIHRlbXBsYXRlVXJsOiAnLi9yZXBvcnQtY29tcG9uZW50LmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vcmVwb3J0LWNvbXBvbmVudC5jb21wb25lbnQuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIE1hdEljb24sXG4gICAgTWF0SWNvbkJ1dHRvbixcbiAgICBNYXRQcm9ncmVzc0JhcixcbiAgICBNYXRUb29sdGlwLFxuICAgIEZzRmlsdGVyTW9kdWxlLFxuICAgIEZzTWVudU1vZHVsZSxcbiAgICBDb21wb25lbnRDaGFydENvbXBvbmVudCxcbiAgICBDb21wb25lbnRLcGlDb21wb25lbnQsXG4gICAgQ29tcG9uZW50TGlzdENvbXBvbmVudCxcbiAgICBDb21wb25lbnRUZXh0Q29tcG9uZW50LFxuICBdLFxufSlcbmV4cG9ydCBjbGFzcyBSZXBvcnRDb21wb25lbnRDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcyB7XG5cbiAgQElucHV0KCkgcHVibGljIHJlcG9ydElkOiBudW1iZXI7XG4gIEBJbnB1dCgpIHB1YmxpYyBjb21wb25lbnQ6IFJlcG9ydENvbXBvbmVudE1vZGVsO1xuICBASW5wdXQoKSBwdWJsaWMgZ3JvdXBzOiBNYXA8bnVtYmVyLCBSZXBvcnRGaWx0ZXJHcm91cD47XG4gIEBJbnB1dCgpIHB1YmxpYyBlZGl0TW9kZSA9IGZhbHNlO1xuICAvLyBUaGUgY2FudmFzIHpvb20g4oCUIGNvbnZlcnRzIG9uLXNjcmVlbiBwaXhlbCBkZWx0YXMgYmFjayB0byBpbmNoZXMuXG4gIEBJbnB1dCgpIHB1YmxpYyB6b29tID0gMTtcbiAgQElucHV0KCkgcHVibGljIHNuYXBwZXI6IENhbnZhc1NuYXBwZXIgfCBudWxsID0gbnVsbDtcbiAgQElucHV0KCkgcHVibGljIHNlbGVjdGVkID0gZmFsc2U7XG5cbiAgQE91dHB1dCgpIHB1YmxpYyBzZWxlY3RDb21wb25lbnQgPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlcj4oKTtcbiAgQE91dHB1dCgpIHB1YmxpYyBwb3NpdGlvbkNoYW5nZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHsgY29tcG9uZW50SWQ6IG51bWJlciB9ICYgUmVjb3JkPHN0cmluZywgbnVtYmVyPj4oKTtcbiAgQE91dHB1dCgpIHB1YmxpYyBvcGVuU2V0dGluZ3MgPSBuZXcgRXZlbnRFbWl0dGVyPFJlcG9ydENvbXBvbmVudE1vZGVsPigpO1xuXG4gIC8vIFdoYXQgdGhlIHt7dG9rZW5zfX0gb2YgYSB0ZXh0IGJsb2NrLCBhbmQgb2YgYW55IGNvbXBvbmVudCdzIHRpdGxlLCBmaWxsXG4gIC8vIHdpdGggd2hlcmUgaXQgaXMgZHJhd246IGl0cyBwYWdlJ3MsIG9yIHRoZSBtYXN0ZXIncyBmb3IgYSBoZWFkZXIgb3JcbiAgLy8gZm9vdGVyIGNvbXBvbmVudC5cbiAgcHVibGljIHJlYWRvbmx5IHRva2VucyA9IGlucHV0PFRleHRUb2tlbkNvbnRleHQ+KHsgcGFnZU51bWJlcjogMSwgcGFnZU5hbWU6ICcnLCByZXBvcnROYW1lOiAnJyB9KTtcblxuICAvLyBUaGUgdmFsdWUga2V5cyB0aGUgb3RoZXIgdGV4dCBibG9ja3Mgb2YgYSB0ZXh0J3MgbGF5ZXIgc2hvdywgcmVhZCBieSB0aGVcbiAgLy8gY2FudmFzIHdoZW4gdGhlIHRleHQncyBlZGl0b3IgYXNrcy5cbiAgcHVibGljIHJlYWRvbmx5IHZhbHVlS2V5c0Vsc2V3aGVyZSA9IGlucHV0PCgodGV4dDogUmVwb3J0Q29tcG9uZW50TW9kZWwpID0+IFJlYWRvbmx5U2V0PHN0cmluZz4pIHwgbnVsbD4obnVsbCk7XG5cbiAgLy8gQSB0ZXh0IGJsb2NrIHdhcyBkZWxldGVkIGZyb20gaXRzIG1lbnUg4oCUIHRoZSBjYW52YXMgZHJvcHMgaXQuXG4gIHB1YmxpYyByZWFkb25seSByZW1vdmVkID0gb3V0cHV0PG51bWJlcj4oKTtcblxuICAvLyBBIHZhbHVlJ3Mgc2V0dGluZ3Mgd2VyZSBhc2tlZCBmb3IgZnJvbSBpdHMgY2hpcCBpbiB0aGUgdGV4dCwgYnkgdGhlXG4gIC8vIHZhbHVlJ3Mga2V5LiBUaGUgY2FudmFzIG9wZW5zIHRoZW0uXG4gIHB1YmxpYyByZWFkb25seSB2YWx1ZVNldHRpbmdzID0gb3V0cHV0PHN0cmluZz4oKTtcblxuICAvLyBUaGUgdGV4dCdzIGh0bWwgd2FzIHNhdmVkLiBFbWl0dGVkIG9uIHRoZSByZXNwb25zZSwgc28gdGhlIHNlcnZlciBhbHJlYWR5XG4gIC8vIGhvbGRzIHRoZSBodG1sIHdoZW4gdGhlIGNhbnZhcyByZWFkcyB0aGUgdmFsdWVzIGl0IHNob3dzLlxuICBwdWJsaWMgcmVhZG9ubHkgdGV4dFNhdmVkID0gb3V0cHV0PHN0cmluZz4oKTtcblxuICAvLyBEZWxldGluZyB0aGUgdGV4dCBhbHNvIGRlbGV0ZWQgdGhlIHZhbHVlcyBubyBvdGhlciB0ZXh0IG9uIGl0cyBwYWdlIHJlYWRzLFxuICAvLyBieSBpZC4gVGhlIGNhbnZhcyBoYXMgdGhlIHJlcG9ydCByZWxvYWRlZC5cbiAgcHVibGljIHJlYWRvbmx5IHZhbHVlc1JlbW92ZWQgPSBvdXRwdXQ8bnVtYmVyW10+KCk7XG5cbiAgLy8gVGhlIHRleHQgYmxvY2sncyBlZGl0b3IgaXMgb3BlbiAoZG91YmxlLXByZXNzIGluIGVkaXQgbW9kZSkuIENsb3NlZCBieSBmb2N1c1xuICAvLyBsZWF2aW5nIHRoZSBibG9jaywgYnkgZGVzZWxlY3RpbmcgaXQsIG9yIGJ5IGxlYXZpbmcgZWRpdCBtb2RlIOKAlCBlYWNoIG9mXG4gIC8vIHdoaWNoIHNhdmVzLlxuICBwdWJsaWMgcmVhZG9ubHkgdGV4dEVkaXRpbmcgPSBzaWduYWwoZmFsc2UpO1xuICAvLyBBIHRleHQgYmxvY2sncyBodG1sIGFzIGxhc3Qgc2F2ZWQgaGVyZTsgbnVsbCB1bnRpbCB0aGVuLCBzbyB0aGUgYmxvY2tcbiAgLy8gc2hvd3MgaXRzIHN0b3JlZCBodG1sLlxuICBwdWJsaWMgcmVhZG9ubHkgdGV4dEh0bWwgPSBzaWduYWw8c3RyaW5nIHwgbnVsbD4obnVsbCk7XG5cbiAgLy8gV2hhdCB0aGUgb3RoZXIgdGV4dCBibG9ja3Mgb2YgdGhpcyB0ZXh0J3MgbGF5ZXIgc2hvdywgZm9yIGl0cyBlZGl0b3Inc1xuICAvLyBub3RpY2UuIFN0YWJsZSwgc28gdGhlIHRleHQgYmxvY2sncyBpbnB1dCBuZXZlciBjaGFuZ2VzOyBpdCBhc2tzIHdoZW4gYW5cbiAgLy8gZWRpdCB0YWtlcyBhIHZhbHVlJ3MgbGFzdCBjaGlwIG91dC5cbiAgcHVibGljIHJlYWRvbmx5IHNob3duRWxzZXdoZXJlID0gKCk6IFJlYWRvbmx5U2V0PHN0cmluZz4gPT5cbiAgICB0aGlzLnZhbHVlS2V5c0Vsc2V3aGVyZSgpPy4odGhpcy5jb21wb25lbnQpID8/IE5PX1ZBTFVFX0tFWVM7XG5cbiAgQFZpZXdDaGlsZChDb21wb25lbnRDaGFydENvbXBvbmVudClcbiAgcHVibGljIGNoYXJ0Q29tcG9uZW50OiBDb21wb25lbnRDaGFydENvbXBvbmVudDtcblxuICAvLyBSZXNpemUgaGFuZGxlcyBieSB0eXBlOiBhIGZpeGVkLWhlaWdodCBjb21wb25lbnQgKGNoYXJ0L2xpc3QpXG4gIC8vIGdldHMgYWxsIGVpZ2h0IChyZXNpemUgd2lkdGggQU5EIGhlaWdodCk7IGFuIGF1dG8taGVpZ2h0IG9uZSAoa3BpKSBnZXRzXG4gIC8vIG9ubHkgdGhlIHNpZGUgaGFuZGxlcyBzaW5jZSBpdHMgaGVpZ2h0IGZpdHMgaXRzIGNvbnRlbnQgYW5kIGNhbid0IGJlIHNldC5cbiAgcHVibGljIGdldCByZXNpemVIYW5kbGVzKCk6IHJlYWRvbmx5IEhhbmRsZVtdIHtcbiAgICByZXR1cm4gdGhpcy5faGVpZ2h0QXV0byA/IFsnZScsICd3J10gOiBIQU5ETEVTO1xuICB9XG5cbiAgLy8gVGhlIGNvbXBvbmVudCdzIGhlYWRlciBJUyBhbiBmcy1maWx0ZXI6IGhlYWRpbmcgdGVtcGxhdGUgPSBpdHMgdGl0bGUgKGFuZFxuICAvLyB0aGUgZHJhZyBoYW5kbGUpLCBhY3Rpb25zID0gdGhlIFNldHRpbmdzIC8gZmlsdGVyLXRvZ2dsZXMgLyBFeHBvcnQgbWVudSxcbiAgLy8gaXRlbXMgPSBpdHMgY29tcG9uZW50LWxldmVsIGZpbHRlciBncm91cHMsIGZvciBldmVyeSBjb21wb25lbnQgdHlwZSwgbGlzdHNcbiAgLy8gaW5jbHVkZWQsIHBsdXMgYSBsaXN0J3Mgc2VhcmNoIGJveC4gUmVidWlsdCB3aGVuIGEgZmlsdGVyIHRvZ2dsZSBjaGFuZ2VzIHdoaWNoIGdyb3VwcyBzaG93LFxuICAvLyBhbmQgd2hlbiB0aGUgc2V0dGluZ3MgZGlhbG9nIGNoYW5nZXMgdGhlIHRpdGxlIG9yIHBhZGRpbmc6IHNldHRpbmcgaXRcbiAgLy8gcmVwYWludHMgdGhlIGhlYWRlciBhbmQgYm9keS5cbiAgcHVibGljIHJlYWRvbmx5IGZpbHRlckNvbmZpZyA9IHNpZ25hbDxGaWx0ZXJDb25maWcgfCBudWxsPihudWxsKTtcblxuICBwdWJsaWMgcmVhZG9ubHkgZGF0YSA9IHNpZ25hbDxDb21wb25lbnREYXRhIHwgbnVsbD4obnVsbCk7XG4gIC8vIFRoZSBzaGltbWVyOiBvbmx5IHdoaWxlIHRoZSB0aWxlIGhhcyBubyBkYXRhIHRvIHNob3cgeWV0LiBBIHJlZmV0Y2gga2VlcHNcbiAgLy8gdGhlIGRhdGEgb24gc2NyZWVuIGFuZCBzZXRzIGByZWZyZXNoaW5nYCwgYSB0aGluIGJhciBvdmVyIHRoZSBib2R5LlxuICBwdWJsaWMgcmVhZG9ubHkgbG9hZGluZyA9IHNpZ25hbChmYWxzZSk7XG4gIHB1YmxpYyByZWFkb25seSByZWZyZXNoaW5nID0gc2lnbmFsKGZhbHNlKTtcbiAgcHVibGljIHJlYWRvbmx5IGVycm9yID0gc2lnbmFsPHN0cmluZyB8IG51bGw+KG51bGwpO1xuXG4gIC8vIFdoaWNoIG9mIGEgY2hhcnQncyBsZWdlbmQgZW50cmllcyBhcmUgb24sIGJ5IHNlcmllcyBuYW1lLiBIZWxkIGhlcmUgYW5kXG4gIC8vIGhhbmRlZCB0byBlYWNoIG9wdGlvbiB0aGUgY2hhcnQgYnVpbGRzOiBuZ3gtZWNoYXJ0cyBzZXRzIGFuIG9wdGlvbiB3aXRoXG4gIC8vIG5vdE1lcmdlLCB3aGljaCB3b3VsZCBvdGhlcndpc2UgdHVybiBldmVyeSBlbnRyeSBiYWNrIG9uIGF0IGVhY2ggcmVmZXRjaC5cbiAgcHVibGljIHJlYWRvbmx5IGxlZ2VuZFNlbGVjdGVkID0gc2lnbmFsPFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIGJvb2xlYW4+Pj4oe30pO1xuXG4gIC8vIEEgbGlzdCBpcyBkcmF3biBhZ2FpbiB3aGVuIGEgcmVzZXQgbW92ZXMgaXRzIHNvcnQ6IEZzTGlzdCByZWFkcyBpdHMgc29ydFxuICAvLyBvbmx5IHdoZW4gaXQgaXMgY3JlYXRlZC4gRXZlcnkgb3RoZXIgcmVzZXQgcmVsb2FkcyBpdCBpbiBwbGFjZS5cbiAgcHVibGljIHJlYWRvbmx5IGxpc3RSZXNldEtleSA9IGNvbXB1dGVkKCgpID0+IHRoaXMuX2ZpbHRlclN0YXRlLmxpc3RTb3J0UmVzZXRzKCkuZ2V0KHRoaXMuY29tcG9uZW50Py5pZCkgPz8gMCk7XG5cbiAgLy8gV2hhdCBhIGNsaWNrIG9uIHRoaXMgdGlsZSdzIG1hcmtzIG1heSBkbyBvbiBpdHMgbGFzdCBhbnN3ZXI6IHRoZSBjaGFydFxuICAvLyBzaG93cyBhIGhhbmQgYW5kIGEgdG9vbHRpcCBoaW50IGZvciB0aGVtLiAoV2hpbGUgdGhlIGxheW91dCBpcyBlZGl0ZWQgYVxuICAvLyB2ZWlsIGNvdmVycyB0aGUgYm9keSwgc28gbm8gbWFyayBpcyBob3ZlcmVkIG9yIGNsaWNrZWQuKVxuICBwdWJsaWMgcmVhZG9ubHkgdGlsZUFjdGlvbnMgPSBjb21wdXRlZDxSZXBvcnRNYXJrQWN0aW9uW10+KCgpID0+IHRpbGVNYXJrQWN0aW9ucyh7XG4gICAgZGF0YTogdGhpcy5kYXRhKCksXG4gICAgZmVhdHVyZXM6IHRoaXMuX29mZmVyZWRGZWF0dXJlcygpLFxuICB9KSk7XG5cbiAgLy8gVGhlIGFjdGlvbnMgdGhlIG1hcmsgbWVudSBsaXN0cyBmb3IgdGhlIGNsaWNrIGl0IHdhcyBvcGVuZWQgb24uXG4gIHB1YmxpYyByZWFkb25seSBtYXJrTWVudUFjdGlvbnMgPSBzaWduYWw8UmVwb3J0TWFya0FjdGlvbltdPihbXSk7XG4gIHB1YmxpYyByZWFkb25seSBtYXJrQWN0aW9uTGFiZWxzID0gTUFSS19BQ1RJT05fTEFCRUxTO1xuXG4gIC8vIFRoZSBicmVhZGNydW1iIGFmdGVyIHRoZSB0aXRsZSB3aGlsZSB0aGUgY2hhcnQgaXMgZHJpbGxlZCAoJzIwMjYnLCAnUTMnKSxcbiAgLy8gb25lIGxhYmVsIHBlciBzdGVwIG9mIGl0cyBwYXRoLCBpbiB0aGUgcmVwb3J0J3MgbG9jYWxlLiBFbXB0eSBhdCB0aGUgdG9wXG4gIC8vIGFuZCB3aGlsZSB0aGUgdmlld2VyIGlzIG5vdCBvZmZlcmVkIGRyaWxsOiBhIHBhdGggYW4gb2xkZXIgc2VydmVyIG5ldmVyXG4gIC8vIGFwcGxpZXMgaXMga2VwdCBpbiB0aGUgc3RhdGUsIGJ1dCBub3Qgc2hvd24uXG4gIHB1YmxpYyByZWFkb25seSBkcmlsbENydW1icyA9IGNvbXB1dGVkPHN0cmluZ1tdPigoKSA9PiAodGhpcy5fb2ZmZXJlZEZlYXR1cmVzKCkuaW5jbHVkZXMoJ2RyaWxsJylcbiAgICA/IGRyaWxsQ3J1bWJMYWJlbHModGhpcy5fZmlsdGVyU3RhdGUuZHJpbGwodGhpcy5jb21wb25lbnQ/LmlkKSwgdGhpcy5fZmlsdGVyU3RhdGUuZm9ybWF0Q29udGV4dCgpKVxuICAgIDogW10pKTtcbiAgcHVibGljIHJlYWRvbmx5IGRyaWxsU2VwYXJhdG9yID0gRFJJTExfQ1JVTUJfU0VQQVJBVE9SO1xuXG4gIC8vIFdoYXQgYW4gZW1wdHkgdGlsZSBzYXlzOiB0aGUgZHJpbGxlZCBwZXJpb2QgaXQgcmVhZHMgbm8gZGF5IG9mLCBlbHNlXG4gIC8vICdObyBkYXRhJy5cbiAgcHVibGljIHJlYWRvbmx5IGVtcHR5TWVzc2FnZSA9IGNvbXB1dGVkKCgpID0+IGRyaWxsT3V0c2lkZU1lc3NhZ2UoXG4gICAgdGhpcy5kYXRhKCk/LmRyaWxsLFxuICAgIHRoaXMuX2ZpbHRlclN0YXRlLmZvcm1hdENvbnRleHQoKSxcbiAgKSA/PyAnTm8gZGF0YScpO1xuXG4gIEBWaWV3Q2hpbGQoJ21hcmtNZW51JylcbiAgcHVibGljIG1hcmtNZW51OiBGc01lbnVDb21wb25lbnQ7XG5cbiAgQFZpZXdDaGlsZCgnbWFya0FuY2hvcicpXG4gIHB1YmxpYyBtYXJrQW5jaG9yOiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PjtcblxuICBwcml2YXRlIHJlYWRvbmx5IF90ZXh0ID0gdmlld0NoaWxkKENvbXBvbmVudFRleHRDb21wb25lbnQpO1xuICBwcml2YXRlIF9yZWZyZXNoJCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG4gIC8vIFRoZSBzdGF0ZSB2ZXJzaW9uIHRoZSBoZWFkZXIgd2FzIGxhc3QgYnVpbHQgZm9yIChmaWx0ZXJLZXkpLlxuICBwcml2YXRlIHJlYWRvbmx5IF9oZWFkZXJWZXJzaW9uID0gc2lnbmFsKDApO1xuICAvLyBUaGUgaGVhZGVyIGdyb3VwcycgdmFsdWVzIGFzIHRoZSBoZWFkZXIgbGFzdCBzaG93ZWQgdGhlbTogYXMgaXQgd2FzXG4gIC8vIGJ1aWx0LCB0aGVuIGFzIGl0cyBvd24gYmFyIHJlcG9ydGVkIGVhY2ggY2hhbmdlLiBmaWx0ZXJLZXkgY2FycmllcyB0aGVpclxuICAvLyBzaWduYXR1cmUgYXMgYnVpbHQuXG4gIHByaXZhdGUgX3Nob3duID0gbmV3IE1hcDxudW1iZXIsIEZpbHRlckdyb3VwVmFsdWUgfCBudWxsPigpO1xuICBwcml2YXRlIHJlYWRvbmx5IF9oZWFkZXJWYWx1ZXMgPSBzaWduYWwoJycpO1xuICBwcml2YXRlIF9yZXBvcnREYXRhID0gaW5qZWN0KFJlcG9ydERhdGEpO1xuICBwcml2YXRlIF9maWx0ZXJTdGF0ZSA9IGluamVjdChSZXBvcnRGaWx0ZXJTdGF0ZVNlcnZpY2UpO1xuICBwcml2YXRlIF9maWx0ZXJPcHRpb25zID0gaW5qZWN0KFJlcG9ydEZpbHRlck9wdGlvbnNTZXJ2aWNlKTtcbiAgcHJpdmF0ZSBfcHJvY2VzcyA9IGluamVjdChGc1Byb2Nlc3MpO1xuICBwcml2YXRlIF9tZXNzYWdlID0gaW5qZWN0KEZzTWVzc2FnZSk7XG4gIHByaXZhdGUgX3Byb21wdCA9IGluamVjdChGc1Byb21wdCk7XG4gIHByaXZhdGUgX2RpYWxvZyA9IGluamVjdChNYXREaWFsb2cpO1xuICBwcml2YXRlIF9sYXN0UHJlc3MgPSAwO1xuICBwcml2YXRlIF9kZXN0cm95UmVmID0gaW5qZWN0KERlc3Ryb3lSZWYpO1xuICBwcml2YXRlIF96b25lID0gaW5qZWN0KE5nWm9uZSk7XG4gIHByaXZhdGUgX2hvc3Q6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+ID0gaW5qZWN0KEVsZW1lbnRSZWYpO1xuICAvLyBUaGUgZmVhdHVyZXMgYSBtYXJrIGFjdGlvbiBuZWVkczogc2VydmVkIGJ5IHRoZSByZXBvcnQncyBzZXJ2ZXIgYW5kXG4gIC8vIGltcGxlbWVudGVkIGJ5IHRoaXMgdmlld2VyLlxuICBwcml2YXRlIHJlYWRvbmx5IF9vZmZlcmVkRmVhdHVyZXMgPSBjb21wdXRlZCgoKSA9PiBvZmZlcmVkVmlld2VyRmVhdHVyZXModGhpcy5fZmlsdGVyU3RhdGUudmlld2VyRmVhdHVyZXMoKSkpO1xuICAvLyBUaGUgbWFyayBhIGZpcnN0IHRhcCBwcmV2aWV3ZWQgKGRlY2lkZU1hcmtDbGljayksIGFuZCB0aGUgY2xpY2sgdGhlIG1hcmtcbiAgLy8gbWVudSBpcyBvcGVuIGZvci5cbiAgcHJpdmF0ZSBfdG91Y2hlZE1hcms6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIF9tZW51Q2xpY2s6IFJlcG9ydE1hcmtDbGljayB8IG51bGwgPSBudWxsO1xuICAvLyBUaGUgZ3JvdXAtYnkgbW92ZWQgc2luY2UgdGhlIGxhc3QgYW5zd2VyOiBhIHBhdGggdGhlIHNlcnZlciB0aGVuIGRyb3BzXG4gIC8vIGJlY2F1c2UgaXQgbm8gbG9uZ2VyIHN0YXJ0cyBhdCB0aGUgY2hhcnQncyB0b3AgaXMgbm90IG5ld3MgdG8gdGhlIHZpZXdlci5cbiAgcHJpdmF0ZSBfZ3JhaW5Nb3ZlZCA9IGZhbHNlO1xuXG4gIHB1YmxpYyBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLl9idWlsZEZpbHRlckNvbmZpZygpO1xuXG4gICAgaWYgKCF0aGlzLmlzVGV4dCkge1xuICAgICAgdGhpcy5fcmVidWlsZEhlYWRlck9uTmV3U3RhdGUoKTtcbiAgICB9XG5cbiAgICAvLyBMaXN0cyBmZXRjaCB0aHJvdWdoIEZzTGlzdDsgdGV4dCBoYXMgbm90aGluZyB0byBmZXRjaCwgYW5kIGEgdmFsdWUgaXNcbiAgICAvLyBuZXZlciBkcmF3biAoaXQgcmVhZHMgaW5zaWRlIHRleHQpLlxuICAgIGlmICh0aGlzLmNvbXBvbmVudC50eXBlICE9PSAnbGlzdCcgJiYgIXRoaXMuaXNUZXh0ICYmIGlzRHJhd24odGhpcy5jb21wb25lbnQpKSB7XG4gICAgICAvLyBPbmUgbG9hZCBzdHJlYW0gKHRpbGVMb2Fkcyk6IHRoZSBmaXJzdCBsb2FkIGF0IG9uY2UsIHRoZW4gb25lIHBlclxuICAgICAgLy8gc2V0dGxlZCBzd2VlcCBvZiBjaGFuZ2VzLCBlYWNoIGNhbmNlbGxpbmcgdGhlIG9uZSBpbiBmbGlnaHQsIGFuZCBhblxuICAgICAgLy8gYW5zd2VyIHNlbnQgYmVmb3JlIGEgcmVzZXQgaXMgZHJvcHBlZC5cbiAgICAgIHRpbGVMb2Fkcyh0aGlzLl9yZWZyZXNoJCwgKCkgPT4gdGhpcy5fbG9hZCgpLCAoKSA9PiB0aGlzLl9maWx0ZXJTdGF0ZS5zdGF0ZVZlcnNpb24oKSlcbiAgICAgICAgLnBpcGUoXG4gICAgICAgICAgdGFwKChyZXN1bHQpID0+IHRoaXMuX2xvYWRlZChyZXN1bHQpKSxcbiAgICAgICAgICB0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5fZGVzdHJveVJlZiksXG4gICAgICAgIClcbiAgICAgICAgLnN1YnNjcmliZSgpO1xuXG4gICAgICB0aGlzLl9maWx0ZXJTdGF0ZS5jaGFuZ2VzRm9yKHRoaXMuY29tcG9uZW50KVxuICAgICAgICAucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5fZGVzdHJveVJlZikpXG4gICAgICAgIC5zdWJzY3JpYmUoKCkgPT4gdGhpcy5fcmVmcmVzaCQubmV4dCgpKTtcblxuICAgICAgLy8gQSBncm91cC1ieSBjaGFuZ2UgcmUtYnVja2V0cyBldmVyeSB0aW1lLXNlcmllcyBjaGFydDsgaXQgaXNuJ3Qgc2NvcGVkXG4gICAgICAvLyB0byBhIGZpbHRlciBncm91cCwgc28gaXQgcmlkZXMgaXRzIG93biBzdHJlYW0uXG4gICAgICBpZiAodGhpcy5faXNUaW1lU2VyaWVzKSB7XG4gICAgICAgIHRoaXMuX2ZpbHRlclN0YXRlLmZyZXF1ZW5jeUNoYW5nZXMoKVxuICAgICAgICAgIC5waXBlKHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLl9kZXN0cm95UmVmKSlcbiAgICAgICAgICAuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuX2dyYWluTW92ZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5fcmVmcmVzaCQubmV4dCgpO1xuICAgICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICAvLyBBIGRyaWxsIG1vdmVzIHRoaXMgY2hhcnQgYWxvbmUuXG4gICAgICB0aGlzLl9maWx0ZXJTdGF0ZS5kcmlsbENoYW5nZXModGhpcy5jb21wb25lbnQuaWQpXG4gICAgICAgIC5waXBlKHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLl9kZXN0cm95UmVmKSlcbiAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB0aGlzLl9yZWZyZXNoJC5uZXh0KCkpO1xuICAgIH1cbiAgfVxuXG4gIC8vIFRoZSByZXBvcnQgcmVsb2FkcyAoZS5nLiBhZnRlciB0aGUgc2V0dGluZ3MgZGlhbG9nIGFkZHMvbW92ZXMgYSBmaWx0ZXIpXG4gIC8vIGhhbmQgdGhpcyBpbnN0YW5jZSBmcmVzaCBgY29tcG9uZW50YC9gZ3JvdXBzYCBpbnB1dHMgd2l0aG91dCByZS1ydW5uaW5nXG4gIC8vIG5nT25Jbml0LiBSZWJ1aWxkIHRoZSBoZWFkZXIgY29uZmlnIHNvIHRoZSBpbmxpbmUgY29tcG9uZW50LWZpbHRlciBzdHJpcFxuICAvLyByZWZsZWN0cyB0aGUgbmV3IGZpbHRlcnM7IHRoZSB0ZW1wbGF0ZSByZWNyZWF0ZXMgdGhlIGZzLWZpbHRlciB2aWFcbiAgLy8gYGZpbHRlcktleWAgc28gaXQgYWN0dWFsbHkgcmUtcmVhZHMgdGhpcyBjb25maWcuXG4gIHB1YmxpYyBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgLy8gQ2xpY2tpbmcgYXdheSAoZGVzZWxlY3QpIG9yIGxlYXZpbmcgZWRpdCBtb2RlIGNsb3NlcyBhbiBvcGVuIHRleHQgZWRpdG9yLFxuICAgIC8vIHdoaWNoIGlzIHdoYXQgc2F2ZXMgaXQuXG4gICAgaWYgKChjaGFuZ2VzLnNlbGVjdGVkICYmICF0aGlzLnNlbGVjdGVkKSB8fCAoY2hhbmdlcy5lZGl0TW9kZSAmJiAhdGhpcy5lZGl0TW9kZSkpIHtcbiAgICAgIHRoaXMudGV4dEVkaXRpbmcuc2V0KGZhbHNlKTtcbiAgICB9XG5cbiAgICAvLyBBIG5ldyBjb21wb25lbnQgb2JqZWN0IGNhcnJpZXMgaXRzIG93biBzdG9yZWQgaHRtbC5cbiAgICBpZiAoY2hhbmdlcy5jb21wb25lbnQgJiYgIWNoYW5nZXMuY29tcG9uZW50LmZpcnN0Q2hhbmdlKSB7XG4gICAgICB0aGlzLnRleHRIdG1sLnNldChudWxsKTtcbiAgICB9XG5cbiAgICBjb25zdCBmaWx0ZXJzQ2hhbmdlZCA9IChjaGFuZ2VzLmNvbXBvbmVudCAmJiAhY2hhbmdlcy5jb21wb25lbnQuZmlyc3RDaGFuZ2UpXG4gICAgICB8fCAoY2hhbmdlcy5ncm91cHMgJiYgIWNoYW5nZXMuZ3JvdXBzLmZpcnN0Q2hhbmdlKTtcblxuICAgIGlmIChmaWx0ZXJzQ2hhbmdlZCkge1xuICAgICAgdGhpcy5fYnVpbGRGaWx0ZXJDb25maWcoKTtcbiAgICB9XG4gIH1cblxuICAvLyBmcy1maWx0ZXIgcmVhZHMgaXRzIGNvbmZpZyBvbmx5IG9uY2UgYXQgaW5pdCwgc28gdGhlIGhlYWRlciBpcyBrZXllZCBvbiB3aGF0XG4gIC8vIGl0IHJlbmRlcnMgdGhhdCBubyBzaWduYWwgY2FycmllczogdGhlIHNldCBvZiBjb21wb25lbnQtbGV2ZWwgZmlsdGVyIGdyb3Vwc1xuICAvLyBBTkQgdGhlIHN0b3JlZCB0aXRsZSwgd2hpY2ggbGl2ZXMgaW4gZnMtZmlsdGVyJ3MgaGVhZGluZyB0ZW1wbGF0ZS4gZnMtZmlsdGVyXG4gIC8vIGlzIE9uUHVzaCBhbmQgdGhlIGhlYWRpbmcgaXMgcmVuZGVyZWQgaW5zaWRlIElUUyB2aWV3LCBzbyBtYXJraW5nIHRoaXNcbiAgLy8gY29tcG9uZW50IGRvZXMgbm90IHJlcGFpbnQgYSBuZXcgdGl0bGUg4oCUIHJlY3JlYXRpbmcgdGhlIGJsb2NrIGRvZXMsIG9uY2UgYVxuICAvLyBzZXR0aW5ncyBzYXZlIGhhcyByZWJ1aWx0IHRoZSBjb25maWcuIFdoYXQgZmlsbHMgdGhlIHRpdGxlJ3MgdG9rZW5zIGlzXG4gIC8vIGFub3RoZXIgbWF0dGVyOiBzZWUgc2hvd25UaXRsZS4gVGhlIGtleSBhbHNvIGNhcnJpZXMgdGhlIHN0YXRlIHZlcnNpb25cbiAgLy8gdGhlIGhlYWRlciB3YXMgYnVpbHQgZm9yLCBzbyBhbiBhcHBsaWVkIHZpZXcsIHdoaWNoIHJlcGxhY2VzIGV2ZXJ5IHZhbHVlXG4gIC8vIGF0IG9uY2UsIHJlY3JlYXRlcyBpdCB3aXRoIHRoZSBuZXcgdmFsdWVzLiBBbmQgaXQgY2FycmllcyB0aGUgdmFsdWVzIHRoZVxuICAvLyBoZWFkZXIgd2FzIGJ1aWx0IHdpdGg6IGEgZ3JvdXAgc2hvd24gaGVyZSBhbmQgaW4gdGhlIHJlcG9ydCBiYXIgKGxldmVsXG4gIC8vICdib3RoJykgdGhhdCB0aGUgcmVwb3J0IGJhciBjaGFuZ2VzIGlzIGJ1aWx0IGFnYWluIGhlcmUsIHNvIHRoZSBoZWFkZXJcbiAgLy8gbmV2ZXIgc2hvd3MgJ1dlc3QnIHdoaWxlIHRoZSBkYXRhIGxlYXZlcyBXZXN0IG91dC5cbiAgcHVibGljIGdldCBmaWx0ZXJLZXkoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gW1xuICAgICAgdGhpcy5faGVhZGVyVmVyc2lvbigpLFxuICAgICAgdGhpcy5jb21wb25lbnQudGl0bGUsXG4gICAgICAuLi50aGlzLmNvbXBvbmVudEZpbHRlckdyb3Vwcy5tYXAoKGdyb3VwKSA9PiBgJHtncm91cC5pZH06JHtncm91cC5sZXZlbH1gKSxcbiAgICAgIHRoaXMuX2hlYWRlclZhbHVlcygpLFxuICAgIF0uam9pbignfCcpO1xuICB9XG5cbiAgLy8gVGhlIHRpdGxlIGFzIHRoZSB2aWV3ZXIgcmVhZHMgaXQ6IGl0cyBwYWdlLCByZXBvcnQgYW5kIGZpbHRlciBmaWVsZHMgZmlsbGVkXG4gIC8vIHdpdGggdGhlIHRva2VucyBvZiB0aGUgbGF5ZXIgaXQgaXMgZHJhd24gb24gKCdTaWduLXVwcyDigJQgU2VwdGVtYmVyIDIwMjYnKS5cbiAgLy8gVGhlIGhlYWRlciByZWFkcyBpdCwgYW5kIHRoZSBDU1YgZXhwb3J0IG5hbWVzIGl0cyBmaWxlIGFmdGVyIGl0LiBUaGVcbiAgLy8gdG9rZW5zIGFyZSBhIHNpZ25hbCwgcmVhZCBpbnNpZGUgZnMtZmlsdGVyJ3MgaGVhZGluZywgc28gYSBmaWx0ZXIgY2hhbmdlXG4gIC8vIHJlcGFpbnRzIHRoZSB0aXRsZSBpbiBwbGFjZSByYXRoZXIgdGhhbiB0aHJvdWdoIGZpbHRlcktleTogYSByZWNyZWF0ZWRcbiAgLy8gaGVhZGVyIHdvdWxkIGxvc2Ugd2hhdCB0aGUgdmlld2VyIGlzIGRvaW5nIGluIGl0cyBvd24gZmlsdGVycyAoYSBwaWNrXG4gIC8vIGxhbmRpbmcsIGEgaGFsZi10eXBlZCBrZXl3b3JkLCBhbiBvcGVuIHBpY2tlciksIGFuZCBlYWNoIGZpbHRlciBpbiBpdFxuICAvLyB3b3VsZCBzaG93IHRoZSB2YWx1ZSBpdCB3YXMgYnVpbHQgd2l0aC5cbiAgcHVibGljIGdldCBzaG93blRpdGxlKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGZpbGxUaXRsZVRva2Vucyh0aGlzLmNvbXBvbmVudC50aXRsZSwgdGhpcy50b2tlbnMoKSk7XG4gIH1cblxuICBwdWJsaWMgZ2V0IGlzVGV4dCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5jb21wb25lbnQudHlwZSA9PT0gJ3RleHQnO1xuICB9XG5cbiAgLy8gT3BlbiB0aGUgdGV4dCBlZGl0b3IgaW4gcGxhY2UuXG4gIHB1YmxpYyBlZGl0VGV4dCgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuZWRpdE1vZGUgfHwgIXRoaXMuaXNUZXh0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5zZWxlY3RDb21wb25lbnQuZW1pdCh0aGlzLmNvbXBvbmVudC5pZCk7XG4gICAgdGhpcy50ZXh0RWRpdGluZy5zZXQodHJ1ZSk7XG4gIH1cblxuICAvLyBUYWtlIGEgZGVsZXRlZCB2YWx1ZSdzIGNoaXBzIG91dCBvZiB0aGUgdGV4dCdzIG9wZW4gZWRpdG9yLlxuICBwdWJsaWMgcmVtb3ZlVmFsdWUoa2V5OiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLl90ZXh0KCk/LnJlbW92ZVZhbHVlKGtleSk7XG4gIH1cblxuICAvLyBUaGUgZWRpdG9yIGNsb3NlZCB3aXRoIGNoYW5nZWQgaHRtbC4gS2VwdCBsb2NhbGx5IGF0IG9uY2Ugc28gdGhlIGJsb2NrXG4gIC8vIHJlLXJlbmRlcnMgd2hhdCB3YXMgdHlwZWQsIHRoZW4gcmVwbGFjZWQgYnkgd2hhdCB0aGUgc2VydmVyIHN0b3JlZDogaXRcbiAgLy8gcmVidWlsZHMgdGhlIGh0bWwgZnJvbSBpdHMgYWxsb3dsaXN0IGFuZCBkcm9wcyBhbnkgdmFsdWUgdG9rZW4gaXRzIHBhZ2UgaGFzXG4gIC8vIG5vIHZhbHVlIGZvciwgc28gdGhlIGJsb2NrIG5ldmVyIGhvbGRzIGEgdG9rZW4gdGhlIHNlcnZlciBkb2Vzbid0LlxuICBwdWJsaWMgb25UZXh0U2F2ZWQoaHRtbDogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5fc2V0VGV4dEh0bWwoaHRtbCk7XG4gICAgdGhpcy5fcmVwb3J0RGF0YS51cGRhdGVDb21wb25lbnQodGhpcy5yZXBvcnRJZCwgdGhpcy5jb21wb25lbnQuaWQsIHsgaHRtbCB9KVxuICAgICAgLnBpcGUoXG4gICAgICAgIG1hcCgocmVzcG9uc2UpID0+ICh0eXBlb2YgcmVzcG9uc2U/LmNvbmZpZz8uaHRtbCA9PT0gJ3N0cmluZycgPyByZXNwb25zZS5jb25maWcuaHRtbCBhcyBzdHJpbmcgOiBodG1sKSksXG4gICAgICAgIHRhcCgoc3RvcmVkKSA9PiB7XG4gICAgICAgICAgdGhpcy5fc2V0VGV4dEh0bWwoc3RvcmVkKTtcbiAgICAgICAgICB0aGlzLnRleHRTYXZlZC5lbWl0KHN0b3JlZCk7XG4gICAgICAgIH0pLFxuICAgICAgICB0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5fZGVzdHJveVJlZiksXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKCk7XG4gIH1cblxuICAvLyBUaGUgc2VydmVyIGRlbGV0ZXMgdGhlIHRleHQgYW5kIHRoZW4gZXZlcnkgdmFsdWUgb24gaXRzIHBhZ2UgdGhhdCBubyBvdGhlclxuICAvLyB0ZXh0IHNob3dzLCBhbmQgYW5zd2VycyB3aXRoIHRoZWlyIGlkcy5cbiAgcHVibGljIGRlbGV0ZVRleHQoKTogdm9pZCB7XG4gICAgY29uc3QgdmFsdWVzTm90ZSA9IHZhbHVlS2V5cyh0aGlzLmNvbXBvbmVudC5jb25maWc/Lmh0bWwpLmxlbmd0aFxuICAgICAgPyAnIFZhbHVlcyBubyBvdGhlciB0ZXh0IG9uIHRoaXMgcGFnZSB1c2VzIGFyZSBkZWxldGVkIHdpdGggaXQuJ1xuICAgICAgOiAnJztcblxuICAgIHRoaXMuX3Byb21wdC5jb25maXJtKHtcbiAgICAgIHRpdGxlOiAnQ29uZmlybScsXG4gICAgICB0ZW1wbGF0ZTogYEFyZSB5b3Ugc3VyZSB5b3Ugd291bGQgbGlrZSB0byBkZWxldGUgdGhpcyB0ZXh0PyR7dmFsdWVzTm90ZX1gLFxuICAgIH0pXG4gICAgICAucGlwZShcbiAgICAgICAgc3dpdGNoTWFwKCgpID0+IHRoaXMuX3JlcG9ydERhdGEuZGVsZXRlQ29tcG9uZW50KHRoaXMucmVwb3J0SWQsIHRoaXMuY29tcG9uZW50LmlkKSksXG4gICAgICAgIHRhcCgocmVzcG9uc2U6IHsgcmVtb3ZlZFZhbHVlcz86IG51bWJlcltdIH0pID0+IHtcbiAgICAgICAgICBpZiAocmVzcG9uc2U/LnJlbW92ZWRWYWx1ZXM/Lmxlbmd0aCkge1xuICAgICAgICAgICAgdGhpcy52YWx1ZXNSZW1vdmVkLmVtaXQocmVzcG9uc2UucmVtb3ZlZFZhbHVlcyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMucmVtb3ZlZC5lbWl0KHRoaXMuY29tcG9uZW50LmlkKTtcbiAgICAgICAgfSksXG4gICAgICAgIHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLl9kZXN0cm95UmVmKSxcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUoKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgdHJ1bmNhdGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhIXRoaXMuZGF0YSgpPy50cnVuY2F0ZWQ7XG4gIH1cblxuICAvLyBDb250ZW50IHBhZGRpbmcgKHRoZSBjYW52YXMgem9vbSBzY2FsZXMgdGhlIHBhZ2UgYXMgYSB3aG9sZSkuIEVhY2ggZWRnZVxuICAvLyBkZWZhdWx0cyB0byAxLzhcIi5cbiAgcHVibGljIGdldCBib2R5UGFkZGluZygpOiBzdHJpbmcge1xuICAgIHJldHVybiBjb21wb25lbnRQYWRkaW5nQ3NzKHRoaXMuY29tcG9uZW50KTtcbiAgfVxuXG4gIC8vIFRoZSBjb21wb25lbnQtbGV2ZWwgZmlsdGVyIGdyb3VwcyB0aGF0IHNob3VsZCByZW5kZXIgYXMgYW4gaW5saW5lIGNvbnRyb2xcbiAgLy8gc3RyaXAgb24gVEhJUyBjb21wb25lbnQ6IGEgZ3JvdXAgaXMgaW5jbHVkZWQgd2hlbiBpdCdzIGxldmVsPWNvbXBvbmVudCBhbmRcbiAgLy8gaGFzIGFuIGVuYWJsZWQsIHNlc3Npb24tb24gZmlsdGVyIGhlcmUuIFJlcG9ydC1sZXZlbCBncm91cHMgbGl2ZSBpbiB0aGVcbiAgLy8gdG9wIGJhciBpbnN0ZWFkLiBMaXN0cyB1c2UgdGhpcyBzdHJpcCBsaWtlIGNoYXJ0cyBkbzogYSB2YWx1ZSBzZXQgaGVyZSBpc1xuICAvLyB0aGUgZ3JvdXAncyB2YWx1ZSwgc28gaXQgcmVhY2hlcyBldmVyeSBjb21wb25lbnQgaW4gdGhlIGdyb3VwLlxuICBwdWJsaWMgZ2V0IGNvbXBvbmVudEZpbHRlckdyb3VwcygpOiBSZXBvcnRGaWx0ZXJHcm91cFtdIHtcbiAgICBpZiAoIXRoaXMuZ3JvdXBzKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgY29uc3QgZ3JvdXBJZHMgPSBuZXcgU2V0PG51bWJlcj4oKTtcbiAgICBmb3IgKGNvbnN0IGZpbHRlciBvZiB0aGlzLmNvbXBvbmVudC5maWx0ZXJzID8/IFtdKSB7XG4gICAgICBpZiAoIWZpbHRlci5lbmFibGVkIHx8IHRoaXMuX2ZpbHRlclN0YXRlLmlzRmlsdGVyRGlzYWJsZWQoZmlsdGVyLmlkKSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGdyb3VwID0gdGhpcy5ncm91cHMuZ2V0KGZpbHRlci5maWx0ZXJHcm91cElkKTtcbiAgICAgIGlmIChncm91cCAmJiAoZ3JvdXAubGV2ZWwgPT09ICdjb21wb25lbnQnIHx8IGdyb3VwLmxldmVsID09PSAnYm90aCcpKSB7XG4gICAgICAgIGdyb3VwSWRzLmFkZChncm91cC5pZCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIFsuLi5ncm91cElkc10ubWFwKChpZCkgPT4gdGhpcy5ncm91cHMuZ2V0KGlkKSkuZmlsdGVyKEJvb2xlYW4pO1xuICB9XG5cbiAgcHVibGljIHNldHRpbmdzKCk6IHZvaWQge1xuICAgIHRoaXMub3BlblNldHRpbmdzLmVtaXQodGhpcy5jb21wb25lbnQpO1xuICB9XG5cbiAgLy8gV2hldGhlciB0aGUgbWVudSBvZmZlcnMgQ29sdW1uczogYSBwbGFpbiBsaXN0IHdpdGggbW9yZSB0aGFuIG9uZVxuICAvLyBjb25maWd1cmVkIGNvbHVtbi4gQSBjcm9zcy10YWIncyBjb2x1bW5zIGNvbWUgYW5kIGdvIHdpdGggdGhlIGRhdGEuXG4gIHB1YmxpYyBnZXQgaGlkZXNDb2x1bW5zKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmNvbXBvbmVudC50eXBlID09PSAnbGlzdCcgJiYgbGlzdEhpZGVhYmxlQ29sdW1ucyh0aGlzLmNvbXBvbmVudC5jb25maWcpLmxlbmd0aCA+IDE7XG4gIH1cblxuICAvLyBXaGljaCBvZiBhIHBsYWluIGxpc3QncyBjb2x1bW5zIHNob3cuIFRoZSBjaG9pY2UgaXMgdGhlIHZpZXdlcidzIChrZXB0IGluXG4gIC8vIHRoZSByZXBvcnQncyBzdGF0ZSwgbmV2ZXIgc2F2ZWQgdG8gdGhlIHJlcG9ydCksIGFuZCB0aGVcbiAgLy8gbGlzdCBoaWRlcyB0aGUgY29sdW1ucyBpbiBwbGFjZSwgd2l0aCBubyByZWZldGNoLlxuICBwdWJsaWMgY2hvb3NlQ29sdW1ucygpOiB2b2lkIHtcbiAgICBjb25zdCBjb2x1bW5zID0gKHRoaXMuY29tcG9uZW50LmNvbmZpZz8uY29sdW1ucyA/PyBbXSlcbiAgICAgIC5tYXAoKGNvbHVtbikgPT4gKHsgY29sdW1uOiBjb2x1bW4uY29sdW1uLCBsYWJlbDogY29sdW1uLmxhYmVsIHx8IGNvbHVtbi5jb2x1bW4gfSkpO1xuXG4gICAgdGhpcy5fZGlhbG9nLm9wZW48TGlzdENvbHVtbnNDb21wb25lbnQsIExpc3RDb2x1bW5zRGlhbG9nRGF0YSwgc3RyaW5nW10+KExpc3RDb2x1bW5zQ29tcG9uZW50LCB7XG4gICAgICBkYXRhOiB7IGNvbHVtbnMsIGhpZGRlbjogWy4uLnRoaXMuX2ZpbHRlclN0YXRlLmhpZGRlbkNvbHVtbnModGhpcy5jb21wb25lbnQuaWQpXSB9LFxuICAgICAgd2lkdGg6ICc0MDBweCcsXG4gICAgICBtYXhXaWR0aDogJzk1dncnLFxuICAgICAgYXV0b0ZvY3VzOiBmYWxzZSxcbiAgICB9KVxuICAgICAgLmFmdGVyQ2xvc2VkKClcbiAgICAgIC5waXBlKHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLl9kZXN0cm95UmVmKSlcbiAgICAgIC5zdWJzY3JpYmUoKGhpZGRlbikgPT4ge1xuICAgICAgICAvLyBDYW5jZWwgY2xvc2VzIHdpdGggbm90aGluZywgd2hpY2ggY2hhbmdlcyBub3RoaW5nLlxuICAgICAgICBpZiAoaGlkZGVuKSB7XG4gICAgICAgICAgdGhpcy5fZmlsdGVyU3RhdGUuc2V0SGlkZGVuQ29sdW1ucyh0aGlzLmNvbXBvbmVudC5pZCwgaGlkZGVuKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cblxuICAvLyBQcmVzZW50YXRpb24gc2V0dGluZ3Mgc2F2ZWQgZnJvbSB0aGUgc2V0dGluZ3MgZGlhbG9nLiBUaXRsZSBhbmQgcGFkZGluZyBhcmVcbiAgLy8gbm90IHBhcnQgb2YgdGhlIHF1ZXJ5LCBzbyB0aGUgZGF0YSBhbHJlYWR5IGZldGNoZWQgc3RpbGwgc3RhbmRzIOKAlCB0aGlzIG9ubHlcbiAgLy8gcmVwYWludHMuIFRoZSBoZWFkZXIgY29uZmlnIGlzIHJlYnVpbHQgYmVjYXVzZSBgZmlsdGVyS2V5YCBjaGFuZ2VzIHdpdGggdGhlXG4gIC8vIHRpdGxlIGFuZCByZWNyZWF0ZXMgdGhlIGZzLWZpbHRlciBibG9jayBhcm91bmQgaXQ7IHNldHRpbmcgdGhlIGNvbmZpZyBzaWduYWxcbiAgLy8gaXMgYWxzbyB3aGF0IHJlcGFpbnRzIHRoZSBuZXcgcGFkZGluZy4gVGhlIGNoYXJ0IGZvbGxvd3MgaXRzIGJveCBvbiBpdHMgb3duXG4gIC8vIChuZ3gtZWNoYXJ0cyBvYnNlcnZlcyB0aGUgaG9zdCksIHNvIG5vdGhpbmcgaXMgdG9sZCB0byByZXNpemUuIEEgS1BJJ3MgY2FyZFxuICAvLyBrZXlzIGFyZSBkaWZmZXJlbnQ6IHNldHRpbmdzLmtwaSBjYXJyaWVzIHRoZSBrZXlzIHRoZSBzZXJ2ZXIgc2F2ZWQgKG5ldmVyXG4gIC8vIHRoZSBvbmVzIHRoZSBkaWFsb2cgc2VudCksIGFuZCB0aGUgc2VydmVyIHNlbmRzIHRoZSB0YXJnZXQncyBwcm9ncmVzcyBhbmRcbiAgLy8gdGhlIHNwYXJrbGluZSdzIHBvaW50cyB3aXRoIHRoZSBkYXRhLCBzbyBhIGNoYW5nZSB0byB0aGVtIHJlbG9hZHMgaXQuXG4gIHB1YmxpYyBhcHBseVNldHRpbmdzKHNldHRpbmdzOiBDb21wb25lbnRTZXR0aW5ncyk6IHZvaWQge1xuICAgIGNvbnN0IGNhcmRDaGFuZ2VkID0gISFzZXR0aW5ncy5rcGlcbiAgICAgICYmICFzYW1lS3BpQ2FyZFNldHRpbmdzKHNldHRpbmdzLmtwaSwga3BpQ2FyZFNldHRpbmdzKHRoaXMuY29tcG9uZW50LmNvbmZpZyBhcyBLcGlDb25maWcpKTtcblxuICAgIHRoaXMuY29tcG9uZW50LnRpdGxlID0gc2V0dGluZ3MudGl0bGU7XG4gICAgdGhpcy5jb21wb25lbnQuY29uZmlnID0geyAuLi50aGlzLmNvbXBvbmVudC5jb25maWcsIHBhZGRpbmc6IHNldHRpbmdzLnBhZGRpbmcsIC4uLihzZXR0aW5ncy5rcGkgPz8ge30pIH07XG5cbiAgICB0aGlzLl9idWlsZEZpbHRlckNvbmZpZygpO1xuXG4gICAgaWYgKGNhcmRDaGFuZ2VkKSB7XG4gICAgICB0aGlzLl9yZWZyZXNoJC5uZXh0KCk7XG4gICAgfVxuICB9XG5cbiAgLy8gVGhlIENTViBpcyB3aGF0IHRoZSBzY3JlZW4gc2hvd3MsIHNvIGl0IGNhcnJpZXMgdGhlIHRpbGUncyBpbnRlcmFjdGlvblxuICAvLyBzdGF0ZSAodGlsZURhdGFTdGF0ZSk6IHRoZSBncm91cC1ieSBncmFpbiBmb3IgYSB0aW1lLXNlcmllcyBjaGFydCwgYVxuICAvLyBjaGFydCdzIGRyaWxsIHBhdGgsIHRoZSB2aWV3ZXIncyBoZWFkZXIgc29ydCwgc2VhcmNoIGFuZCBoaWRkZW4gY29sdW1uc1xuICAvLyBmb3IgYSBsaXN0IChhIHNlYXJjaGVkIGxpc3QgZXhwb3J0cyBvbmx5IHRoZSByb3dzIHRoZSBzZWFyY2ggbGVhdmVzLCBhbmRcbiAgLy8gdGhlIGhpZGRlbiBjb2x1bW5zIHN0YXkgb3V0IG9mIHRoZSBmaWxlKSwgYW5kIHRoZSBncm91cHMgdGhhdCBtYXRjaFxuICAvLyAnYW55JzsgYW5kIGl0cyB0aXRsZSBhcyB0aGUgaGVhZGVyIHJlYWRzIGl0IChzaG93blRpdGxlKSwgd2hpY2ggdGhlXG4gIC8vIHNlcnZlciBuYW1lcyB0aGUgZmlsZSBhZnRlci4gQSBub3RlIHRoZSBzZXJ2ZXIgcmV0dXJucyAodGhlIGZpbGUgd2FzXG4gIC8vIGN1dCkgaXMgc2hvd24gYmVmb3JlIHRoZSBkb3dubG9hZCBzdGFydHMsIHNvIGEgc2hvcnQgZmlsZSBuZXZlciBwYXNzZXNcbiAgLy8gZm9yIHRoZSB3aG9sZSByZXN1bHQuXG4gIHB1YmxpYyBleHBvcnRDc3YoKTogdm9pZCB7XG4gICAgY29uc3QgZmlsdGVycyA9IHRoaXMuX2ZpbHRlclN0YXRlLnJlc29sdmVGb3JDb21wb25lbnQodGhpcy5jb21wb25lbnQpO1xuICAgIGNvbnN0IHN0YXRlID0gdGhpcy5fZmlsdGVyU3RhdGUudGlsZVN0YXRlKHRoaXMuY29tcG9uZW50KTtcbiAgICBjb25zdCB0aXRsZSA9IHRoaXMuc2hvd25UaXRsZTtcblxuICAgIHRoaXMuX3Byb2Nlc3MuZG93bmxvYWQoXG4gICAgICBgRXhwb3J0aW5nICR7dGl0bGUgfHwgJ2NvbXBvbmVudCd9YCxcbiAgICAgIHRoaXMuX3JlcG9ydERhdGEuZXhwb3J0Q29tcG9uZW50KHRoaXMucmVwb3J0SWQsIHRoaXMuY29tcG9uZW50LmlkLCBmaWx0ZXJzLCBzdGF0ZSwgdGl0bGUpXG4gICAgICAgIC5waXBlKFxuICAgICAgICAgIHRhcCgoeyBub3RlcyB9KSA9PiBub3Rlcz8ubGVuZ3RoICYmIHRoaXMuX21lc3NhZ2Uud2FybmluZyhub3Rlcy5qb2luKCcgJykpKSxcbiAgICAgICAgICBtYXAoKHsgdXJsIH0pID0+IHVybCksXG4gICAgICAgICksXG4gICAgKTtcbiAgfVxuXG4gIC8vIFRoZSBvbmUgY2xpY2sgaGFuZGxlciAoQjEwLjIpOiBldmVyeSBjbGljayBvbiBhIG1hcmsgb2YgdGhpcyB0aWxlLCBhXG4gIC8vIGNoYXJ0J3Mgb3IgYSBLUEkncyB2YWx1ZSwgY29tZXMgaGVyZSwgc28gaXRzIGFjdGlvbnMgbmV2ZXIgY29tcGV0ZS4gVGhlXG4gIC8vIHJ1bGUgKGRlY2lkZU1hcmtDbGljaykgZG9lcyBub3RoaW5nIHdpdGhvdXQgYW4gYWN0aW9uLCBsZXRzIGEgZmlyc3QgdGFwXG4gIC8vIHNob3cgdGhlIHRvb2x0aXAsIHJ1bnMgYSBsb25lIGFjdGlvbiBhdCBvbmNlLCBhbmQgb3BlbnMgdGhlIG1hcmsgbWVudSBhdFxuICAvLyB0aGUgY2xpY2sgZm9yIHR3byBvciBtb3JlLiBOb3Qgd2hpbGUgdGhlIGxheW91dCBpcyBlZGl0ZWQuXG4gIHB1YmxpYyBvbk1hcmtDbGljayhjbGljazogUmVwb3J0TWFya0NsaWNrKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZWRpdE1vZGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBhY3Rpb25zID0gbWFya0FjdGlvbnMoY2xpY2ssIHsgZGF0YTogdGhpcy5kYXRhKCksIGZlYXR1cmVzOiB0aGlzLl9vZmZlcmVkRmVhdHVyZXMoKSB9KTtcbiAgICBjb25zdCBkZWNpc2lvbiA9IGRlY2lkZU1hcmtDbGljayhjbGljaywgYWN0aW9ucywgdGhpcy5fdG91Y2hlZE1hcmspO1xuICAgIHRoaXMuX3RvdWNoZWRNYXJrID0gZGVjaXNpb24udG91Y2hlZDtcblxuICAgIGlmIChkZWNpc2lvbi5vdXRjb21lID09PSAncnVuJykge1xuICAgICAgdGhpcy5fcnVuTWFya0FjdGlvbihkZWNpc2lvbi5hY3Rpb25zWzBdLCBjbGljayk7XG4gICAgfSBlbHNlIGlmIChkZWNpc2lvbi5vdXRjb21lID09PSAnbWVudScpIHtcbiAgICAgIHRoaXMuX29wZW5NYXJrTWVudShkZWNpc2lvbi5hY3Rpb25zLCBjbGljayk7XG4gICAgfVxuICB9XG5cbiAgLy8gQSBjbGljayBvciBhIHRhcCBvbiB0aGUgY2hhcnQgdGhhdCBoaXQgbm8gbWFyazogYSB0YXAgaGVsZCBmb3IgaXRzXG4gIC8vIHNlY29uZCB0YXAgaXMgbGV0IGdvLCBzbyB0YXBwaW5nIHRoYXQgbWFyayBhZ2FpbiBzaG93cyBpdHMgdG9vbHRpcCBmaXJzdC5cbiAgcHVibGljIG9uTWFya01pc3MoKTogdm9pZCB7XG4gICAgdGhpcy5fdG91Y2hlZE1hcmsgPSBudWxsO1xuICB9XG5cbiAgLy8gQSByb3cgb2YgdGhlIG1hcmsgbWVudTogcnVucyBpdHMgYWN0aW9uIGZvciB0aGUgY2xpY2sgdGhlIG1lbnUgb3BlbmVkIG9uLlxuICBwdWJsaWMgcnVuTWFya0FjdGlvbihhY3Rpb246IFJlcG9ydE1hcmtBY3Rpb24pOiB2b2lkIHtcbiAgICBjb25zdCBjbGljayA9IHRoaXMuX21lbnVDbGljaztcbiAgICB0aGlzLl9tZW51Q2xpY2sgPSBudWxsO1xuXG4gICAgaWYgKGNsaWNrKSB7XG4gICAgICB0aGlzLl9ydW5NYXJrQWN0aW9uKGFjdGlvbiwgY2xpY2spO1xuICAgIH1cbiAgfVxuXG4gIC8vIEJhY2sgdXAgdGhlIGRyaWxsIHBhdGggdG8gaXRzIGZpcnN0IGBkZXB0aGAgc3RlcHM6IDAgaXMgdGhlIGNoYXJ0J3MgdG9wXG4gIC8vICh0aGUgdGl0bGUncyBjcnVtYiBhbmQgQmFjayB0byB0b3ApLCBhbmQgYSBjcnVtYiBnb2VzIGJhY2sgdG8gdGhlIHBlcmlvZFxuICAvLyBpdCBuYW1lcy4gVGhlIGNoYXJ0IHJlYWRzIGFnYWluIChkcmlsbENoYW5nZXMpLlxuICBwdWJsaWMgZHJpbGxUbyhkZXB0aDogbnVtYmVyKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZWRpdE1vZGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLl9maWx0ZXJTdGF0ZS5zZXREcmlsbCh0aGlzLmNvbXBvbmVudC5pZCwgdGhpcy5fZmlsdGVyU3RhdGUuZHJpbGwodGhpcy5jb21wb25lbnQuaWQpLnNsaWNlKDAsIGRlcHRoKSk7XG4gIH1cblxuICAvLyBPbmUgbGV2ZWwgdXA6IHRoZSBwZXJpb2QgdGhlIGNoYXJ0IGlzIGRyaWxsZWQgaW50byBpcyBsZWZ0LlxuICBwdWJsaWMgZHJpbGxVcCgpOiB2b2lkIHtcbiAgICB0aGlzLmRyaWxsVG8oTWF0aC5tYXgoMCwgdGhpcy5fZmlsdGVyU3RhdGUuZHJpbGwodGhpcy5jb21wb25lbnQuaWQpLmxlbmd0aCAtIDEpKTtcbiAgfVxuXG4gIC8vIEFueSBpbnRlcmFjdGlvbiBpbnNpZGUgYSBjb21wb25lbnQgbXVzdCBuZXZlciBzdGFydCBhIGNhbnZhcyBwYW4gKHRoZVxuICAvLyB6b29tLXBhbiBob3N0IGxpc3RlbnMgZm9yIG1vdXNlZG93bi90b3VjaHN0YXJ0IGF0IHRoZSBjb250YWluZXIgbGV2ZWwpLlxuICBwdWJsaWMgc3RvcENhbnZhc1BhbihldmVudDogRXZlbnQpOiB2b2lkIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgfVxuXG4gIHB1YmxpYyBvbkNvbXBvbmVudFBvaW50ZXJEb3duKGV2ZW50OiBQb2ludGVyRXZlbnQpOiB2b2lkIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBpZiAodGhpcy5lZGl0TW9kZSAmJiAhdGhpcy5zZWxlY3RlZCkge1xuICAgICAgdGhpcy5zZWxlY3RDb21wb25lbnQuZW1pdCh0aGlzLmNvbXBvbmVudC5pZCk7XG4gICAgfVxuICB9XG5cbiAgLy8gLS0tLS0gZWRpdC1tb2RlIGdlc3R1cmVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gIHB1YmxpYyBvbkRyYWdTdGFydChldmVudDogUG9pbnRlckV2ZW50KTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmVkaXRNb2RlIHx8IHRoaXMudGV4dEVkaXRpbmcoKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIEEgc2Vjb25kIHByZXNzIG9uIGEgdGV4dCBibG9jayBvcGVucyBpdHMgZWRpdG9yIGluc3RlYWQgb2YgZHJhZ2dpbmcuXG4gICAgaWYgKHRoaXMuaXNUZXh0KSB7XG4gICAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICAgICAgY29uc3QgaXNEb3VibGVQcmVzcyA9IG5vdyAtIHRoaXMuX2xhc3RQcmVzcyA8IERPVUJMRV9QUkVTU19NUztcbiAgICAgIHRoaXMuX2xhc3RQcmVzcyA9IG5vdztcblxuICAgICAgaWYgKGlzRG91YmxlUHJlc3MpIHtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgIHRoaXMuZWRpdFRleHQoKTtcblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5zZWxlY3RDb21wb25lbnQuZW1pdCh0aGlzLmNvbXBvbmVudC5pZCk7XG5cbiAgICB0aGlzLl90cmFjayhldmVudCwgKGRlbHRhWCwgZGVsdGFZKSA9PiB7XG4gICAgICBsZXQgeCA9IE1hdGgubWF4KDAsIHRoaXMuX29yaWdpbi54ICsgdGhpcy5faW5jaGVzKGRlbHRhWCkpO1xuICAgICAgbGV0IHkgPSBNYXRoLm1heCgwLCB0aGlzLl9vcmlnaW4ueSArIHRoaXMuX2luY2hlcyhkZWx0YVkpKTtcblxuICAgICAgaWYgKHRoaXMuc25hcHBlcikge1xuICAgICAgICAoeyB4LCB5IH0gPSB0aGlzLnNuYXBwZXIuc25hcE1vdmUodGhpcy5jb21wb25lbnQsIHgsIHkpKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5jb21wb25lbnQueCA9IHg7XG4gICAgICB0aGlzLmNvbXBvbmVudC55ID0geTtcbiAgICAgIHRoaXMuX2FwcGx5R2VvbWV0cnkoKTtcbiAgICB9LCAoKSA9PiB0aGlzLl9lbWl0R2VvbWV0cnkoKSk7XG4gIH1cblxuICBwdWJsaWMgb25SZXNpemVTdGFydChldmVudDogUG9pbnRlckV2ZW50LCBoYW5kbGU6IEhhbmRsZSk6IHZvaWQge1xuICAgIGlmICghdGhpcy5lZGl0TW9kZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuc2VsZWN0Q29tcG9uZW50LmVtaXQodGhpcy5jb21wb25lbnQuaWQpO1xuXG4gICAgdGhpcy5fdHJhY2soZXZlbnQsIChkZWx0YVgsIGRlbHRhWSkgPT4ge1xuICAgICAgY29uc3QgZHggPSB0aGlzLl9pbmNoZXMoZGVsdGFYKTtcbiAgICAgIGNvbnN0IGR5ID0gdGhpcy5faW5jaGVzKGRlbHRhWSk7XG4gICAgICBsZXQgeyB4LCB5LCB3LCBoIH0gPSB0aGlzLl9vcmlnaW47XG5cbiAgICAgIGlmIChoYW5kbGUuaW5jbHVkZXMoJ2UnKSkge1xuICAgICAgICB3ID0gTWF0aC5tYXgoTUlOX1csIHRoaXMuX29yaWdpbi53ICsgZHgpO1xuICAgICAgfVxuICAgICAgaWYgKGhhbmRsZS5pbmNsdWRlcygncycpKSB7XG4gICAgICAgIGggPSBNYXRoLm1heChNSU5fSCwgdGhpcy5fb3JpZ2luLmggKyBkeSk7XG4gICAgICB9XG4gICAgICBpZiAoaGFuZGxlLmluY2x1ZGVzKCd3JykpIHtcbiAgICAgICAgY29uc3QgY2xhbXBlZCA9IE1hdGgubWluKGR4LCB0aGlzLl9vcmlnaW4udyAtIE1JTl9XKTtcbiAgICAgICAgeCA9IHRoaXMuX29yaWdpbi54ICsgY2xhbXBlZDtcbiAgICAgICAgdyA9IHRoaXMuX29yaWdpbi53IC0gY2xhbXBlZDtcbiAgICAgIH1cbiAgICAgIGlmIChoYW5kbGUuaW5jbHVkZXMoJ24nKSkge1xuICAgICAgICBjb25zdCBjbGFtcGVkID0gTWF0aC5taW4oZHksIHRoaXMuX29yaWdpbi5oIC0gTUlOX0gpO1xuICAgICAgICB5ID0gdGhpcy5fb3JpZ2luLnkgKyBjbGFtcGVkO1xuICAgICAgICBoID0gdGhpcy5fb3JpZ2luLmggLSBjbGFtcGVkO1xuICAgICAgfVxuXG4gICAgICBsZXQgZ2VvbWV0cnkgPSB7IHgsIHksIHcsIGggfTtcbiAgICAgIGlmICh0aGlzLnNuYXBwZXIpIHtcbiAgICAgICAgZ2VvbWV0cnkgPSB0aGlzLnNuYXBwZXIuc25hcFJlc2l6ZSh0aGlzLmNvbXBvbmVudCwgZ2VvbWV0cnksIGhhbmRsZSk7XG4gICAgICB9XG5cbiAgICAgIE9iamVjdC5hc3NpZ24odGhpcy5jb21wb25lbnQsIGdlb21ldHJ5KTtcbiAgICAgIHRoaXMuX2FwcGx5R2VvbWV0cnkoKTtcbiAgICAgIHRoaXMuY2hhcnRDb21wb25lbnQ/LnJlc2l6ZSgpO1xuICAgIH0sICgpID0+IHRoaXMuX2VtaXRHZW9tZXRyeSgpKTtcbiAgfVxuXG4gIC8vIChSZSlidWlsZCB0aGUgaGVhZGVyIGZzLWZpbHRlciBjb25maWc6IGhlYWRpbmcgdGVtcGxhdGUgcmVuZGVycyB0aGUgdGl0bGVcbiAgLy8gYW5kIGl0ZW1zIGFyZSB0aGlzIGNvbXBvbmVudCdzIGNvbXBvbmVudC1sZXZlbCBmaWx0ZXIgZ3JvdXBzLiBUaGUgYWN0aW9uc1xuICAvLyBtZW51IChTZXR0aW5ncyAvIEV4cG9ydCBDU1YpIGlzIE5PVCBoZXJlIOKAlCBpdCdzIGEgc3RhbmRhbG9uZSBrZWJhYiBmbG9hdGVkXG4gIC8vIHRvcC1yaWdodCBpbiB0aGUgdGVtcGxhdGUsIHNvIGl0cyBidXR0b24gaGVpZ2h0IG5vIGxvbmdlciBkcml2ZXMgdGhlIGhlYWRlclxuICAvLyByb3cncyBoZWlnaHQgKHdoaWNoIHdvdWxkIG90aGVyd2lzZSBpbmZsYXRlIHRoZSBoZWFkaW5nIGJ5IH40MHB4KS5cbiAgLy9cbiAgLy8gQSBsaXN0IGFsc28gZ2V0cyBhIHNlYXJjaCBib3ggb3ZlciBpdHMgdGV4dCBjb2x1bW5zLCB1bmxlc3MgaXRzIGhlYWRlclxuICAvLyBzaG93cyBhIGtleXdvcmQgZ3JvdXAgKFJlcG9ydEZpbHRlclN0YXRlU2VydmljZS5saXN0U2VhcmNoYWJsZSwgd2hpY2ggYWxzb1xuICAvLyBkcm9wcyBhIHNlYXJjaCBrZXB0IGZyb20gYmVmb3JlIHN1Y2ggYSBncm91cCBhcHBlYXJlZCkuXG4gIC8vXG4gIC8vIGByZXBvcnRlZGAgaXMgd2hhdCB0aGlzIGhlYWRlciBsYXN0IHJlcG9ydGVkIGZvciBlYWNoIG9mIGl0cyBncm91cHMsXG4gIC8vIHN0YXJ0aW5nIGZyb20gdGhlIHZhbHVlcyBpdCBpcyBidWlsdCB3aXRoLiBBIGNoYW5nZSBzZXRzIG9ubHkgdGhlIGdyb3Vwc1xuICAvLyB3aG9zZSBoZWFkZXIgdmFsdWUgbW92ZWQgKG1vdmVkR3JvdXBWYWx1ZXMpOiBmcy1maWx0ZXIgcmVwb3J0cyBldmVyeSBpdGVtXG4gIC8vIG9uIGFueSBjaGFuZ2UsIGFuZCBhIGdyb3VwIHNob3duIGluIHRoZSByZXBvcnQgYmFyIHRvbyBtYXkgaGF2ZSBjaGFuZ2VkXG4gIC8vIHRoZXJlIHNpbmNlLCB3aXRob3V0IHRoaXMgaGVhZGVyIGJlaW5nIHJlcGFpbnRlZC5cbiAgcHJpdmF0ZSBfc2V0VGV4dEh0bWwoaHRtbDogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5jb21wb25lbnQuY29uZmlnID0geyAuLi50aGlzLmNvbXBvbmVudC5jb25maWcsIGh0bWwgfTtcbiAgICB0aGlzLnRleHRIdG1sLnNldChodG1sKTtcbiAgfVxuXG4gIHByaXZhdGUgX2J1aWxkRmlsdGVyQ29uZmlnKCk6IHZvaWQge1xuICAgIGNvbnN0IGdyb3VwcyA9IHRoaXMuY29tcG9uZW50RmlsdGVyR3JvdXBzO1xuICAgIGNvbnN0IGxpc3RTZWFyY2ggPSB0aGlzLl9maWx0ZXJTdGF0ZS5saXN0U2VhcmNoYWJsZSh0aGlzLmNvbXBvbmVudCk7XG4gICAgY29uc3QgcmVwb3J0ZWQgPSBuZXcgTWFwKGdyb3Vwcy5tYXAoKGdyb3VwKSA9PiBbZ3JvdXAuaWQsIHRoaXMuX2ZpbHRlclN0YXRlLnZhbHVlKGdyb3VwLmlkKSA/PyBudWxsXSkpO1xuICAgIGNvbnN0IGZlYXR1cmVzID0gdGhpcy5fZmlsdGVyU3RhdGUudmlld2VyRmVhdHVyZXMoKTtcbiAgICBjb25zdCByZXBvcnQgPSB0aGlzLl9maWx0ZXJTdGF0ZS5yZXBvcnQoKTtcblxuICAgIHRoaXMuX3Nob3duID0gcmVwb3J0ZWQ7XG4gICAgdGhpcy5faGVhZGVyVmFsdWVzLnNldChbLi4ucmVwb3J0ZWQudmFsdWVzKCldLm1hcChncm91cFZhbHVlU2lnbmF0dXJlKS5qb2luKCd8JykpO1xuICAgIHRoaXMuX2hlYWRlclZlcnNpb24uc2V0KHRoaXMuX2ZpbHRlclN0YXRlLnN0YXRlVmVyc2lvbigpKTtcbiAgICB0aGlzLmZpbHRlckNvbmZpZy5zZXQoe1xuICAgICAgLy8gZnMtZmlsdGVyIG5ldmVyIHRvdWNoZXMgdGhlIFVSTCBvciBwZXJzaXN0cyBmaWx0ZXIgc3RhdGU6IGEgcmVwb3J0XG4gICAgICAvLyBrZWVwcyBubyBzdGF0ZSBpbiB0aGUgVVJMLiBUaGUgdmFsdWVzIGFyZSBvd25lZCBieVxuICAgICAgLy8gUmVwb3J0RmlsdGVyU3RhdGVTZXJ2aWNlLlxuICAgICAgcXVlcnlQYXJhbTogZmFsc2UsXG4gICAgICBwZXJzaXN0OiBmYWxzZSxcbiAgICAgIGl0ZW1zOiBbXG4gICAgICAgIC4uLmdyb3Vwcy5tYXAoKGdyb3VwKSA9PlxuICAgICAgICAgIGZpbHRlckl0ZW1Gb3JHcm91cChncm91cCwgdGhpcy5fZmlsdGVyT3B0aW9ucywgcmVwb3J0LCB0aGlzLl9maWx0ZXJTdGF0ZS52YWx1ZShncm91cC5pZCksIGZlYXR1cmVzKSksXG4gICAgICAgIC4uLihsaXN0U2VhcmNoID8gW2xpc3RTZWFyY2hJdGVtKHRoaXMuX2ZpbHRlclN0YXRlLmxpc3RTZWFyY2godGhpcy5jb21wb25lbnQuaWQpKV0gOiBbXSksXG4gICAgICBdLFxuICAgICAgLy8gVHlwaW5nIGluIHRoZSBzZWFyY2ggYm94IG11c3Qgbm90IHJlZmV0Y2ggdGhyb3VnaCB0aGUgZ3JvdXBzLCBub3Igc2V0XG4gICAgICAvLyBhIHN0YWxlIGdyb3VwIHZhbHVlIGJhY2ssIGFuZCBhIGdyb3VwIGNoYW5nZSBtdXN0IG5vdCByZWZldGNoIHRocm91Z2hcbiAgICAgIC8vIHRoZSBzZWFyY2guXG4gICAgICBjaGFuZ2U6IChxdWVyeSkgPT4ge1xuICAgICAgICBjb25zdCB2YWx1ZXMgPSBncm91cFZhbHVlc0Zyb21RdWVyeShxdWVyeSA/PyB7fSwgdGhpcy5jb21wb25lbnRGaWx0ZXJHcm91cHMpO1xuXG4gICAgICAgIGZvciAoY29uc3QgeyBncm91cElkLCB2YWx1ZSB9IG9mIG1vdmVkR3JvdXBWYWx1ZXMocmVwb3J0ZWQsIHZhbHVlcykpIHtcbiAgICAgICAgICB0aGlzLl9maWx0ZXJTdGF0ZS5zZXRWYWx1ZShncm91cElkLCB2YWx1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobGlzdFNlYXJjaCkge1xuICAgICAgICAgIHRoaXMuX2ZpbHRlclN0YXRlLnNldExpc3RTZWFyY2godGhpcy5jb21wb25lbnQuaWQsIFN0cmluZyhxdWVyeT8uW0xJU1RfU0VBUkNIX0lURU1dID8/ICcnKSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICAvLyAnQ2xlYXIgZmlsdGVycycgcHV0cyB0aGlzIGhlYWRlcidzIG93biBncm91cHMgYmFjayBvbiB0aGVpciBhdXRob3JlZFxuICAgICAgLy8gZGVmYXVsdHMuIGZzLWZpbHRlciByZXBvcnRzIGl0cyBvd24gY2xlYXJlZCBpdGVtcyAoY2hhbmdlKSBqdXN0XG4gICAgICAvLyBiZWZvcmUgdGhpcywgc28gdGhlIHJlc2V0IHdpbnMuXG4gICAgICBjbGVhcjogKCkgPT4gdGhpcy5fZmlsdGVyU3RhdGUucmVzZXRHcm91cHNUb0RlZmF1bHRzKGdyb3Vwcy5tYXAoKGdyb3VwKSA9PiBncm91cC5pZCkpLFxuICAgICAgLy8gVGhlIGNoaXAgc2hvd3MgZXhhY3RseSB3aGlsZSBvbmUgb2YgdGhvc2UgZ3JvdXBzIGRpZmZlcnMgZnJvbSB3aGF0XG4gICAgICAvLyB0aGF0IGNsZWFyIHB1dHMgYmFjayAoZ3JvdXBzRGlmZmVyRnJvbURlZmF1bHRzKS4gZnMtZmlsdGVyJ3Mgb3duIHJ1bGVcbiAgICAgIC8vIGNvbXBhcmVzIHRoZSBpdGVtcyB3aXRoIHRoZSB2YWx1ZXMgdGhpcyBoZWFkZXIgd2FzIGJ1aWx0IHdpdGgsIHdoaWNoXG4gICAgICAvLyBtYXkgYmUgdGhlIHZpZXdlcidzIG93biBwaWNrcywgYW5kIHdvdWxkIG9mZmVyIGEgY2xlYXIgdGhhdCBjaGFuZ2VzXG4gICAgICAvLyBub3RoaW5nLlxuICAgICAgY2xlYXJWaXNpYmxlOiAoKSA9PiB0aGlzLl9maWx0ZXJTdGF0ZS5ncm91cHNEaWZmZXJGcm9tRGVmYXVsdHMoZ3JvdXBzLm1hcCgoZ3JvdXApID0+IGdyb3VwLmlkKSksXG4gICAgfSk7XG4gIH1cblxuICAvLyByZXNldFRvRGVmYXVsdHMoKSBtb3ZlcyB0aGUgc3RhdGUgdmVyc2lvbiBhbmQgYW5ub3VuY2VzIGEgZnVsbCBjaGFuZ2VcbiAgLy8gKG51bGwpLiBUaGUgaGVhZGVyIGlzIGJ1aWx0IGFnYWluIGZvciB0aGUgbmV3IHZlcnNpb24sIGFuZFxuICAvLyBmaWx0ZXJLZXksIHdoaWNoIGNhcnJpZXMgaXQsIHJlY3JlYXRlcyB0aGUgYmxvY2s6IGZzLWZpbHRlciByZWFkcyBpdHNcbiAgLy8gY29uZmlnIG9uY2UuIEFueSBvdGhlciBmdWxsIGNoYW5nZSAoYSByZWxvYWQsIHRoZSBtYXRjaCkgbGVhdmVzIGl0IGJlLlxuICAvLyBBIGNoYW5nZSB0byBvbmUgZ3JvdXAgdGhlIGhlYWRlciBzaG93cyB3aXRoIGFub3RoZXIgdmFsdWUgKGFub3RoZXIgYmFyXG4gIC8vIHNldCBpdCkgYnVpbGRzIGl0IGFnYWluIHRvby5cbiAgcHJpdmF0ZSBfcmVidWlsZEhlYWRlck9uTmV3U3RhdGUoKTogdm9pZCB7XG4gICAgdGhpcy5fZmlsdGVyU3RhdGUuY2hhbmdlc0Zvcih0aGlzLmNvbXBvbmVudClcbiAgICAgIC5waXBlKFxuICAgICAgICByeEZpbHRlcigoZ3JvdXBJZCkgPT4gKGdyb3VwSWQgPT09IG51bGxcbiAgICAgICAgICA/IHRoaXMuX2ZpbHRlclN0YXRlLnN0YXRlVmVyc2lvbigpICE9PSB0aGlzLl9oZWFkZXJWZXJzaW9uKClcbiAgICAgICAgICA6IHRoaXMuX3Nob3dzT3RoZXJWYWx1ZShncm91cElkKSkpLFxuICAgICAgICB0YXAoKCkgPT4gdGhpcy5fYnVpbGRGaWx0ZXJDb25maWcoKSksXG4gICAgICAgIHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLl9kZXN0cm95UmVmKSxcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUoKTtcbiAgfVxuXG4gIC8vIFdoZXRoZXIgdGhlIGhlYWRlciBzaG93cyBhIGdyb3VwIHdpdGggYSB2YWx1ZSBvdGhlciB0aGFuIHRoZSBvbmUgc3RvcmVkXG4gIC8vIGZvciBpdC4gQSBjaGFuZ2UgdGhlIGhlYWRlcidzIG93biBiYXIgbWFkZSBpcyB3aGF0IGl0IHNob3dzIGFscmVhZHkuXG4gIHByaXZhdGUgX3Nob3dzT3RoZXJWYWx1ZShncm91cElkOiBudW1iZXIpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5fc2hvd24uaGFzKGdyb3VwSWQpXG4gICAgICAmJiBncm91cFZhbHVlU2lnbmF0dXJlKHRoaXMuX3Nob3duLmdldChncm91cElkKSkgIT09IGdyb3VwVmFsdWVTaWduYXR1cmUodGhpcy5fZmlsdGVyU3RhdGUudmFsdWUoZ3JvdXBJZCkpO1xuICB9XG5cbiAgcHJpdmF0ZSBfb3JpZ2luID0geyB4OiAwLCB5OiAwLCB3OiAwLCBoOiAwIH07XG5cbiAgLy8gUG9pbnRlci1jYXB0dXJlIGdlc3R1cmUgbG9vcDogcnVucyBvdXRzaWRlIEFuZ3VsYXIsIHJlcGFpbnRzIGltcGVyYXRpdmVseSxcbiAgLy8gYW5kIGZpbmlzaGVzIGJhY2sgaW5zaWRlIEFuZ3VsYXIgKHNlbGVjdGlvbi9wZXJzaXN0ZW5jZSkuXG4gIHByaXZhdGUgX3RyYWNrKFxuICAgIGV2ZW50OiBQb2ludGVyRXZlbnQsXG4gICAgb25Nb3ZlOiAoZGVsdGFYOiBudW1iZXIsIGRlbHRhWTogbnVtYmVyKSA9PiB2b2lkLFxuICAgIG9uRW5kOiAoKSA9PiB2b2lkLFxuICApOiB2b2lkIHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgY29uc3QgaGFuZGxlID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxFbGVtZW50O1xuICAgIGhhbmRsZS5zZXRQb2ludGVyQ2FwdHVyZShldmVudC5wb2ludGVySWQpO1xuXG4gICAgdGhpcy5fb3JpZ2luID0ge1xuICAgICAgeDogdGhpcy5jb21wb25lbnQueCxcbiAgICAgIHk6IHRoaXMuY29tcG9uZW50LnksXG4gICAgICB3OiB0aGlzLmNvbXBvbmVudC53LFxuICAgICAgaDogdGhpcy5jb21wb25lbnQuaCxcbiAgICB9O1xuICAgIGNvbnN0IHN0YXJ0WCA9IGV2ZW50LmNsaWVudFg7XG4gICAgY29uc3Qgc3RhcnRZID0gZXZlbnQuY2xpZW50WTtcblxuICAgIHRoaXMuX3pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgY29uc3QgbW92ZSA9IChlOiBQb2ludGVyRXZlbnQpID0+IG9uTW92ZShlLmNsaWVudFggLSBzdGFydFgsIGUuY2xpZW50WSAtIHN0YXJ0WSk7XG4gICAgICBjb25zdCBlbmQgPSAoKSA9PiB7XG4gICAgICAgIGhhbmRsZS5yZWxlYXNlUG9pbnRlckNhcHR1cmUoZXZlbnQucG9pbnRlcklkKTtcbiAgICAgICAgaGFuZGxlLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJtb3ZlJywgbW92ZSk7XG4gICAgICAgIGhhbmRsZS5yZW1vdmVFdmVudExpc3RlbmVyKCdwb2ludGVydXAnLCBlbmQpO1xuICAgICAgICBoYW5kbGUucmVtb3ZlRXZlbnRMaXN0ZW5lcigncG9pbnRlcmNhbmNlbCcsIGVuZCk7XG5cbiAgICAgICAgdGhpcy5fem9uZS5ydW4oKCkgPT4ge1xuICAgICAgICAgIHRoaXMuc25hcHBlcj8uY2xlYXIoKTtcbiAgICAgICAgICBvbkVuZCgpO1xuICAgICAgICB9KTtcbiAgICAgIH07XG5cbiAgICAgIGhhbmRsZS5hZGRFdmVudExpc3RlbmVyKCdwb2ludGVybW92ZScsIG1vdmUpO1xuICAgICAgaGFuZGxlLmFkZEV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJ1cCcsIGVuZCk7XG4gICAgICBoYW5kbGUuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcmNhbmNlbCcsIGVuZCk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIF9lbWl0R2VvbWV0cnkoKTogdm9pZCB7XG4gICAgdGhpcy5jb21wb25lbnQueCA9IHRoaXMuX3JvdW5kKHRoaXMuY29tcG9uZW50LngpO1xuICAgIHRoaXMuY29tcG9uZW50LnkgPSB0aGlzLl9yb3VuZCh0aGlzLmNvbXBvbmVudC55KTtcbiAgICB0aGlzLmNvbXBvbmVudC53ID0gdGhpcy5fcm91bmQoTWF0aC5tYXgoTUlOX1csIHRoaXMuY29tcG9uZW50LncpKTtcbiAgICB0aGlzLmNvbXBvbmVudC5oID0gdGhpcy5fcm91bmQoTWF0aC5tYXgoTUlOX0gsIHRoaXMuY29tcG9uZW50LmgpKTtcbiAgICB0aGlzLl9hcHBseUdlb21ldHJ5KCk7XG4gICAgdGhpcy5jaGFydENvbXBvbmVudD8ucmVzaXplKCk7XG5cbiAgICB0aGlzLnBvc2l0aW9uQ2hhbmdlZC5lbWl0KHtcbiAgICAgIGNvbXBvbmVudElkOiB0aGlzLmNvbXBvbmVudC5pZCxcbiAgICAgIHg6IHRoaXMuY29tcG9uZW50LngsXG4gICAgICB5OiB0aGlzLmNvbXBvbmVudC55LFxuICAgICAgdzogdGhpcy5jb21wb25lbnQudyxcbiAgICAgIGg6IHRoaXMuY29tcG9uZW50LmgsXG4gICAgfSk7XG4gIH1cblxuICAvLyBBIGNoYXJ0IG9uIGEgdGltZSB4LWF4aXMg4oCUIHRoZSBvbmx5IGNvbXBvbmVudCB0aGUgcmVwb3J0J3MgZ3JvdXAtYnkgY29udHJvbFxuICAvLyBhcHBsaWVzIHRvIChpc1RpbWVTZXJpZXNDaGFydCwgdGhlIGJyb3dzZXItc2lkZSBtaXJyb3Igb2YgdGhlIHNlcnZlcidzIHJ1bGUpLlxuICBwcml2YXRlIGdldCBfaXNUaW1lU2VyaWVzKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBpc1RpbWVTZXJpZXNDaGFydCh0aGlzLmNvbXBvbmVudCk7XG4gIH1cblxuICAvLyBBdXRvIGhlaWdodCAoYm94IGZpdHMgaXRzIGNvbnRlbnQpIHZzIGZpeGVkICh1c2UgYGhgIGV4YWN0bHkpLiBEZXJpdmVkIGZyb21cbiAgLy8gdHlwZSwgc2VydmVyLXNpZGU6IEtQSSB0aWxlcyBhcmUgYXV0bzsgY2hhcnRzIGFuZCBsaXN0cyBhcmUgZml4ZWQg4oCUIGNoYXJ0c1xuICAvLyBmaXQgdGhlIGJveCBhbmQgbmV2ZXIgb3ZlcmZsb3csIGxpc3RzIHNjcm9sbCBpbnNpZGUgaXQuXG4gIHByaXZhdGUgZ2V0IF9oZWlnaHRBdXRvKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmNvbXBvbmVudC5hdXRvSGVpZ2h0ICE9PSBmYWxzZTtcbiAgfVxuXG4gIC8vIERyaXZlcyB0aGUgYXV0by1vbmx5IENTUyBkZWZhdWx0IChlbXB0eS1zdGF0ZSBiYXNlbGluZSkgc28gaXQgbmV2ZXIgYXBwbGllc1xuICAvLyB0byBhIGZpeGVkLWhlaWdodCBjb21wb25lbnQuXG4gIEBIb3N0QmluZGluZygnY2xhc3MuaGVpZ2h0LWF1dG8nKVxuICBwdWJsaWMgZ2V0IGhlaWdodEF1dG8oKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX2hlaWdodEF1dG87XG4gIH1cblxuICAvLyBTY3JlZW4gcGl4ZWxzIOKGkiBpbmNoZXMgYXQgdGhlIGN1cnJlbnQgem9vbS5cbiAgcHJpdmF0ZSBfaW5jaGVzKHBpeGVsczogbnVtYmVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gcGl4ZWxzIC8gKHRoaXMuem9vbSAqIFBYX1BFUl9JTkNIKTtcbiAgfVxuXG4gIC8vIENsZWFuIHBlcnNpc3RlZCB2YWx1ZXM6IGh1bmRyZWR0aHMgb2YgYW4gaW5jaC5cbiAgcHJpdmF0ZSBfcm91bmQodmFsdWU6IG51bWJlcik6IG51bWJlciB7XG4gICAgcmV0dXJuIE1hdGgucm91bmQodmFsdWUgKiAxMDApIC8gMTAwO1xuICB9XG5cbiAgLy8gVGhlIGNhbnZhcyBwb3NpdGlvbnMgdGhlIGhvc3QgdmlhIFtzdHlsZV07IG1pZC1nZXN0dXJlIHdlIHNldCBpdCBkaXJlY3RseVxuICAvLyBzbyBPblB1c2ggbmV2ZXIgcmUtcmVuZGVycyBpbiB0aGUgbW92ZSBsb29wLlxuICBwcml2YXRlIF9hcHBseUdlb21ldHJ5KCk6IHZvaWQge1xuICAgIGNvbnN0IHN0eWxlID0gdGhpcy5faG9zdC5uYXRpdmVFbGVtZW50LnN0eWxlO1xuICAgIHN0eWxlLmxlZnQgPSBgJHt0aGlzLmNvbXBvbmVudC54ICogUFhfUEVSX0lOQ0h9cHhgO1xuICAgIHN0eWxlLnRvcCA9IGAke3RoaXMuY29tcG9uZW50LnkgKiBQWF9QRVJfSU5DSH1weGA7XG4gICAgc3R5bGUud2lkdGggPSBgJHt0aGlzLmNvbXBvbmVudC53ICogUFhfUEVSX0lOQ0h9cHhgO1xuXG4gICAgLy8gQXV0byAoa3BpKTogbm8gZml4ZWQgaGVpZ2h0IOKAlCB0aGUgYm94IHNpemVzIHRvIGl0cyBjb250ZW50LiBGaXhlZFxuICAgIC8vIChjaGFydC9saXN0KTogYGhgIGlzIHRoZSBleGFjdCBoZWlnaHQuIE1pcnJvcnMgdGhlIGNhbnZhcyBbc3R5bGVdIGJpbmRpbmdcbiAgICAvLyBzbyB0aGUgbWlkLWdlc3R1cmUgcGFpbnQgbWF0Y2hlcyB0aGUgcG9zdC1nZXN0dXJlIHJlLXJlbmRlci5cbiAgICBpZiAodGhpcy5faGVpZ2h0QXV0bykge1xuICAgICAgc3R5bGUuaGVpZ2h0ID0gJyc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0eWxlLmhlaWdodCA9IGAke3RoaXMuY29tcG9uZW50LmggKiBQWF9QRVJfSU5DSH1weGA7XG4gICAgfVxuICB9XG5cbiAgLy8gLS0tLS0gZGF0YSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgLy8gT25lIHJlcXVlc3Qgb2YgdGhlIGxvYWQgc3RyZWFtICh0aWxlTG9hZHMpLCBidWlsdCBmcm9tIHRoZSBzdGF0ZSBub3cuIFRoZVxuICAvLyBzaGltbWVyIHNob3dzIG9ubHkgd2hpbGUgdGhlIHRpbGUgaGFzIG5vdGhpbmcgb24gc2NyZWVuOyBvdGhlcndpc2UgdGhlXG4gIC8vIGRhdGEgc3RheXMgYW5kIHRoZSB0aGluIGJhciBzaG93cy5cbiAgcHJpdmF0ZSBfbG9hZCgpOiBPYnNlcnZhYmxlPENvbXBvbmVudERhdGE+IHtcbiAgICBjb25zdCBmaXJzdCA9ICF0aGlzLmRhdGEoKTtcblxuICAgIHRoaXMubG9hZGluZy5zZXQoZmlyc3QpO1xuICAgIHRoaXMucmVmcmVzaGluZy5zZXQoIWZpcnN0KTtcbiAgICB0aGlzLmVycm9yLnNldChudWxsKTtcblxuICAgIGNvbnN0IGZpbHRlcnMgPSB0aGlzLl9maWx0ZXJTdGF0ZS5yZXNvbHZlRm9yQ29tcG9uZW50KHRoaXMuY29tcG9uZW50KTtcbiAgICAvLyBUaGUgdGlsZSdzIGludGVyYWN0aW9uIHN0YXRlLCB0aGUgb25lIGl0cyBDU1YgYW5kIGV2ZXJ5IGV4cG9ydCBjYXJyeVxuICAgIC8vICh0aWxlRGF0YVN0YXRlKTogYSB0aW1lLXNlcmllcyBjaGFydCdzIGdyYWluICh3aGVuIHRoZSB2aWV3ZXIgcGlja2VkXG4gICAgLy8gb25lKSBzbyB0aGUgYmFja2VuZCByZS1idWNrZXRzLCBhIGNoYXJ0J3MgZHJpbGwgcGF0aCwgYW5kIHRoZSBncm91cHNcbiAgICAvLyB0aGF0IG1hdGNoICdhbnknLlxuICAgIGNvbnN0IHN0YXRlID0gdGhpcy5fZmlsdGVyU3RhdGUudGlsZVN0YXRlKHRoaXMuY29tcG9uZW50KTtcblxuICAgIHJldHVybiB0aGlzLl9yZXBvcnREYXRhLmNvbXBvbmVudERhdGEodGhpcy5yZXBvcnRJZCwgdGhpcy5jb21wb25lbnQuaWQsIGZpbHRlcnMsIHN0YXRlKTtcbiAgfVxuXG4gIC8vIEEgZmFpbGVkIGxvYWQgY2xlYXJzIHRoZSBkYXRhIHdpdGggaXRzIG1lc3NhZ2UsIHNvIHRoZSBuZXh0IGxvYWQgc3RhcnRzXG4gIC8vIGZyb20gdGhlIHNoaW1tZXIgYW5kIG5ldmVyIHNob3dzIHRoZSBkYXRhIHRoZSBmYWlsdXJlIHJlcGxhY2VkLiBBXG4gIC8vIGNoYXJ0J3MgYW5zd2VyIGdpdmVzIGl0cyBkcmlsbCBwYXRoLlxuICBwcml2YXRlIF9sb2FkZWQocmVzdWx0OiBUaWxlTG9hZFJlc3VsdDxDb21wb25lbnREYXRhPik6IHZvaWQge1xuICAgIHRoaXMuZGF0YS5zZXQocmVzdWx0LmRhdGEpO1xuICAgIHRoaXMuZXJyb3Iuc2V0KHJlc3VsdC5lcnJvcik7XG4gICAgdGhpcy5sb2FkaW5nLnNldChmYWxzZSk7XG4gICAgdGhpcy5yZWZyZXNoaW5nLnNldChmYWxzZSk7XG5cbiAgICBpZiAocmVzdWx0LmVycm9yID09PSBudWxsICYmIHJlc3VsdC5kYXRhKSB7XG4gICAgICB0aGlzLl9hZG9wdERyaWxsKHJlc3VsdC5kYXRhKTtcbiAgICB9XG4gIH1cblxuICAvLyBBIGNoYXJ0IHRha2VzIHRoZSBkcmlsbCBwYXRoIGl0cyBhbnN3ZXIgYXBwbGllZCAoYWRvcHRlZERyaWxsUGF0aCkgd2hpbGVcbiAgLy8gdGhlIHZpZXdlciBpcyBvZmZlcmVkIGRyaWxsOyBhbiBvbGRlciBzZXJ2ZXIgYXBwbGllcyBub25lLCBhbmQgdGhlIHBhdGhcbiAgLy8gc3RheXMgaW4gdGhlIHN0YXRlLiBXaGVuIHRoZSBwYXRoIGl0IHNlbnQgd2FzIGN1dCwgdGhlIHZpZXdlciBpcyB0b2xkXG4gIC8vIG9uY2UgKGRyaWxsUmVzZXROb3RlZCk6IHRoZSBzaG9ydGVyIHBhdGggaXMgd2hhdCB0aGUgY2hhcnQgcmVhZHMgZnJvbVxuICAvLyBub3cgb24sIHNvIHRoZSBzZXJ2ZXIgY3V0cyBub3RoaW5nIGFnYWluLlxuICBwcml2YXRlIF9hZG9wdERyaWxsKGRhdGE6IENvbXBvbmVudERhdGEpOiB2b2lkIHtcbiAgICBjb25zdCBncmFpbk1vdmVkID0gdGhpcy5fZ3JhaW5Nb3ZlZDtcbiAgICB0aGlzLl9ncmFpbk1vdmVkID0gZmFsc2U7XG5cbiAgICBpZiAodGhpcy5jb21wb25lbnQudHlwZSAhPT0gJ2NoYXJ0JyB8fCAhdGhpcy5fb2ZmZXJlZEZlYXR1cmVzKCkuaW5jbHVkZXMoJ2RyaWxsJykpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fZmlsdGVyU3RhdGUuYWRvcHREcmlsbCh0aGlzLmNvbXBvbmVudC5pZCwgYWRvcHRlZERyaWxsUGF0aChkYXRhLmRyaWxsKSlcbiAgICAgICYmIGRyaWxsUmVzZXROb3RlZChkYXRhLmRyaWxsLCBncmFpbk1vdmVkKSkge1xuICAgICAgdGhpcy5fbWVzc2FnZS53YXJuaW5nKERSSUxMX1JFU0VUX01FU1NBR0UpO1xuICAgIH1cbiAgfVxuXG4gIC8vIC0tLS0tIG1hcmsgY2xpY2tzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gIHByaXZhdGUgX3J1bk1hcmtBY3Rpb24oYWN0aW9uOiBSZXBvcnRNYXJrQWN0aW9uLCBjbGljazogUmVwb3J0TWFya0NsaWNrKTogdm9pZCB7XG4gICAgaWYgKGFjdGlvbiA9PT0gJ2RyaWxsJykge1xuICAgICAgdGhpcy5fZHJpbGxEb3duKGNsaWNrKTtcbiAgICB9XG4gIH1cblxuICAvLyBEcmlsbCBkb3duOiB0aGUgY2hhcnQncyBwYXRoIGdvZXMgb25lIGxldmVsIGJlbG93IHRoZSBwZXJpb2QgY2xpY2tlZCxcbiAgLy8gYW5kIHRoZSBjaGFydCByZWFkcyBhZ2FpbiAoZHJpbGxDaGFuZ2VzKS5cbiAgcHJpdmF0ZSBfZHJpbGxEb3duKGNsaWNrOiBSZXBvcnRNYXJrQ2xpY2spOiB2b2lkIHtcbiAgICBjb25zdCBwYXRoID0gZHJpbGxEb3duUGF0aCh0aGlzLmRhdGEoKT8uZHJpbGwsIGNsaWNrKTtcblxuICAgIGlmIChwYXRoKSB7XG4gICAgICB0aGlzLl9maWx0ZXJTdGF0ZS5zZXREcmlsbCh0aGlzLmNvbXBvbmVudC5pZCwgcGF0aCk7XG4gICAgfVxuICB9XG5cbiAgLy8gTGlzdHMgdGhlIGNsaWNrJ3MgYWN0aW9ucyBpbiB0aGUgbWFyayBtZW51IGFuZCBvcGVucyBpdCBhdCB0aGUgY2xpY2ssXG4gIC8vIHRocm91Z2ggdGhlIHplcm8tc2l6ZSBhbmNob3IgKG9wZW5BdFBvaW50KS5cbiAgcHJpdmF0ZSBfb3Blbk1hcmtNZW51KGFjdGlvbnM6IFJlcG9ydE1hcmtBY3Rpb25bXSwgY2xpY2s6IFJlcG9ydE1hcmtDbGljayk6IHZvaWQge1xuICAgIGNvbnN0IGFuY2hvciA9IHRoaXMubWFya0FuY2hvcj8ubmF0aXZlRWxlbWVudDtcblxuICAgIGlmICghYW5jaG9yKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5fbWVudUNsaWNrID0gY2xpY2s7XG4gICAgdGhpcy5tYXJrTWVudUFjdGlvbnMuc2V0KGFjdGlvbnMpO1xuICAgIG9wZW5BdFBvaW50KGFuY2hvciwgY2xpY2sucG9pbnRlciwgdGhpcy56b29tLCAoKSA9PiB0aGlzLm1hcmtNZW51Py5vcGVuTWVudShudWxsKSk7XG4gIH1cbn1cbiIsIjxkaXZcbiAgICBjbGFzcz1cImNvbXBvbmVudC1ib3hcIlxuICAgIFtjbGFzcy5lZGl0aW5nXT1cImVkaXRNb2RlXCJcbiAgICBbY2xhc3MudGV4dF09XCJpc1RleHRcIlxuICAgIFtjbGFzcy5zZWxlY3RlZF09XCJzZWxlY3RlZFwiXG4gICAgW3N0eWxlLnBhZGRpbmddPVwiYm9keVBhZGRpbmdcIlxuICAgIChwb2ludGVyZG93bik9XCJvbkNvbXBvbmVudFBvaW50ZXJEb3duKCRldmVudClcIlxuICAgIChtb3VzZWRvd24pPVwic3RvcENhbnZhc1BhbigkZXZlbnQpXCJcbiAgICAodG91Y2hzdGFydCk9XCJzdG9wQ2FudmFzUGFuKCRldmVudClcIj5cbiAgPCEtLSBUaGUgaGVhZGVyIGlzIGFuIGZzLWZpbHRlcjogaGVhZGluZyB0ZW1wbGF0ZSA9IHRpdGxlIChhbmQgdGhlIGVkaXQtbW9kZVxuICAgICAgIGRyYWcgaGFuZGxlKSwgYWN0aW9ucyA9IHRoZSBtZW51LCBpdGVtcyA9IGNvbXBvbmVudC1sZXZlbCBmaWx0ZXIgZ3JvdXBzLFxuICAgICAgIHRoZSBzYW1lIHN0cmlwIGZvciBldmVyeSB0eXBlIChsaXN0cyBpbmNsdWRlZCkuIGZzLWZpbHRlciByZWFkcyBpdHNcbiAgICAgICBjb25maWcgb25jZSwgc28gdGhlIGJsb2NrIGlzIGtleWVkIG9uIHRoZSBjb21wb25lbnQtZmlsdGVyIHNldCB0byBiZVxuICAgICAgIHJlY3JlYXRlZCB3aGVuIGl0IGNoYW5nZXMuIFRoZSB0aXRsZSBzaG93cyBpdHMgdG9rZW5zIGZpbGxlZCwgYW5kIGFcbiAgICAgICBmaWx0ZXIgY2hhbmdlIHJlcGFpbnRzIGl0IGluIHBsYWNlIChzaG93blRpdGxlKS4gLS0+XG4gIDwhLS0gQSB0ZXh0IGJsb2NrIGhhcyBubyB0aXRsZSBiYXIg4oCUIGl0IElTIGl0cyB3b3JkcywgbGlrZSBhIHRleHQgYm94IG9uIGFcbiAgICAgICBzbGlkZSDigJQgc28gaXQgZ2V0cyBuZWl0aGVyIHRoZSBoZWFkZXIgbm9yIHRoZSBkYXRhIGFjdGlvbnMuIC0tPlxuICBAZm9yIChrZXkgb2YgaXNUZXh0ID8gW10gOiBbZmlsdGVyS2V5XTsgdHJhY2sga2V5KSB7XG4gICAgPGZzLWZpbHRlclxuICAgICAgICBjbGFzcz1cImNvbXBvbmVudC1maWx0ZXJcIlxuICAgICAgICBbY29uZmlnXT1cImZpbHRlckNvbmZpZygpXCI+XG4gICAgICA8bmctdGVtcGxhdGUgZnNGaWx0ZXJIZWFkaW5nPlxuICAgICAgICA8ZGl2XG4gICAgICAgICAgICBjbGFzcz1cImNvbXBvbmVudC10aXRsZVwiXG4gICAgICAgICAgICAocG9pbnRlcmRvd24pPVwib25EcmFnU3RhcnQoJGV2ZW50KVwiPlxuICAgICAgICAgIDwhLS0gV2hpbGUgdGhlIGNoYXJ0IGlzIGRyaWxsZWQgdGhlIHRpdGxlIGxlYWRzIGl0cyBicmVhZGNydW1iOlxuICAgICAgICAgICAgICAgJ1RpdGxlIOKAuiAyMDI2IOKAuiBRMycsIHRoZSB0aXRsZSBhcyB0aGUgdmlld2VyIHJlYWRzIGl0XG4gICAgICAgICAgICAgICAoc2hvd25UaXRsZSkuIFRoZSB0aXRsZSBnb2VzIGJhY2sgdG8gdGhlIHRvcCBhbmQgZWFjaFxuICAgICAgICAgICAgICAgY3J1bWIgdG8gdGhlIHBlcmlvZCBpdCBuYW1lczsgdGhlIGxhc3QgaXMgd2hlcmUgdGhlIGNoYXJ0IGlzLlxuICAgICAgICAgICAgICAgQSBsb25nIHBhdGggaXMgY3V0IGF0IGl0cyBsZWZ0IGVuZCwgc28gdGhlIGNydW1icyBuZWFyZXN0IHRoZVxuICAgICAgICAgICAgICAgY2hhcnQgc3RheSBpbiB2aWV3LiBXaGlsZSB0aGUgbGF5b3V0IGlzIGVkaXRlZCB0aGUgY3J1bWJzIGFyZVxuICAgICAgICAgICAgICAgcGxhaW4gdGV4dCAodGhlIHN0eWxlc2hlZXQ7IGRyaWxsVG8gZG9lcyBub3RoaW5nIHRoZW4pLiAtLT5cbiAgICAgICAgICBAaWYgKGRyaWxsQ3J1bWJzKCkubGVuZ3RoKSB7XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRyaWxsLXBhdGhcIj5cbiAgICAgICAgICAgICAgPHNwYW4gZGlyPVwibHRyXCI+XG4gICAgICAgICAgICAgICAgPGFcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJkcmlsbC1jcnVtYlwiXG4gICAgICAgICAgICAgICAgICAgIHRhYmluZGV4PVwiMFwiXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJkcmlsbFRvKDApXCJcbiAgICAgICAgICAgICAgICAgICAgKGtleWRvd24uZW50ZXIpPVwiZHJpbGxUbygwKVwiPlxuICAgICAgICAgICAgICAgICAge3sgc2hvd25UaXRsZSB9fVxuICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICBAZm9yIChsYWJlbCBvZiBkcmlsbENydW1icygpOyB0cmFjayAkaW5kZXg7IGxldCBsYXN0ID0gJGxhc3QpIHtcbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZHJpbGwtc2VwYXJhdG9yXCI+e3sgZHJpbGxTZXBhcmF0b3IgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICBAaWYgKGxhc3QpIHtcbiAgICAgICAgICAgICAgICAgICAgPHNwYW4+e3sgbGFiZWwgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgPGFcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZHJpbGwtY3J1bWJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgdGFiaW5kZXg9XCIwXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJkcmlsbFRvKCRpbmRleCArIDEpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChrZXlkb3duLmVudGVyKT1cImRyaWxsVG8oJGluZGV4ICsgMSlcIj5cbiAgICAgICAgICAgICAgICAgICAgICB7eyBsYWJlbCB9fVxuICAgICAgICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICB7eyBzaG93blRpdGxlIH19XG4gICAgICAgICAgfVxuICAgICAgICAgIEBpZiAodHJ1bmNhdGVkKSB7XG4gICAgICAgICAgICA8bWF0LWljb25cbiAgICAgICAgICAgICAgICBjbGFzcz1cInRydW5jYXRlZC1pY29uXCJcbiAgICAgICAgICAgICAgICBtYXRUb29sdGlwPVwiU2hvd2luZyBhIHRydW5jYXRlZCByZXN1bHQg4oCUIHJlZmluZSB0aGUgZmlsdGVycyB0byBzZWUgZXZlcnl0aGluZy5cIj5cbiAgICAgICAgICAgICAgd2FybmluZ19hbWJlclxuICAgICAgICAgICAgPC9tYXQtaWNvbj5cbiAgICAgICAgICB9XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICA8L2ZzLWZpbHRlcj5cbiAgfVxuICA8IS0tIFRoZSBhY3Rpb25zIG1lbnUgaXMgZmxvYXRlZCB0b3AtcmlnaHQgKGFic29sdXRlKSByYXRoZXIgdGhhbiBsaXZpbmcgaW5cbiAgICAgICBmcy1maWx0ZXIncyBhY3Rpb25zIHNsb3QsIHNvIGl0cyB+NDBweCBidXR0b24gaGVpZ2h0IG5vIGxvbmdlciBkcml2ZXMgdGhlXG4gICAgICAgaGVhZGVyIHJvdydzIGhlaWdodC4gSXQgb3ZlcmxheXMgdGhlIGJveCBjb3JuZXI7IHRoZSBoZWFkaW5nIHJlc2VydmVzXG4gICAgICAgcmlnaHQgcGFkZGluZyBzbyBhIGxvbmcgdGl0bGUgZWxsaXBzaXNlcyBiZWZvcmUgaXQuIC0tPlxuICBAaWYgKCFpc1RleHQgfHwgKGVkaXRNb2RlICYmICF0ZXh0RWRpdGluZygpKSkge1xuICAgIDxidXR0b25cbiAgICAgICAgbWF0LWljb24tYnV0dG9uXG4gICAgICAgIGNsYXNzPVwiY29tcG9uZW50LW1lbnVcIlxuICAgICAgICBbZnNNZW51VHJpZ2dlckZvcl09XCJtZW51XCJcbiAgICAgICAgKHBvaW50ZXJkb3duKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXG4gICAgICAgIChtb3VzZWRvd24pPVwic3RvcENhbnZhc1BhbigkZXZlbnQpXCI+XG4gICAgICA8bWF0LWljb24+bW9yZV92ZXJ0PC9tYXQtaWNvbj5cbiAgICA8L2J1dHRvbj5cbiAgICA8IS0tIEJlc2lkZSBpdHMgdHJpZ2dlciwgaW5zaWRlIHRoZSBzYW1lIGJsb2NrOiBhbiBmcy1tZW51IHRoYXQgZmluZHMgbm9cbiAgICAgICAgIHRyaWdnZXIgb2YgaXRzIG93biBkcmF3cyBvbmUuIC0tPlxuICAgIDxmcy1tZW51ICNtZW51PlxuICAgICAgPG5nLXRlbXBsYXRlXG4gICAgICAgICAgZnMtbWVudS1pdGVtXG4gICAgICAgICAgW2hpZGRlbl09XCIhaXNUZXh0XCJcbiAgICAgICAgICAoY2xpY2spPVwiZWRpdFRleHQoKVwiPlxuICAgICAgICA8bWF0LWljb24+ZWRpdDwvbWF0LWljb24+XG4gICAgICAgIDxzcGFuPkVkaXQgdGV4dDwvc3Bhbj5cbiAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICA8bmctdGVtcGxhdGVcbiAgICAgICAgICBmcy1tZW51LWl0ZW1cbiAgICAgICAgICBbaGlkZGVuXT1cIiFpc1RleHRcIlxuICAgICAgICAgIChjbGljayk9XCJkZWxldGVUZXh0KClcIj5cbiAgICAgICAgPG1hdC1pY29uPmRlbGV0ZTwvbWF0LWljb24+XG4gICAgICAgIDxzcGFuPkRlbGV0ZTwvc3Bhbj5cbiAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICA8bmctdGVtcGxhdGVcbiAgICAgICAgICBmcy1tZW51LWl0ZW1cbiAgICAgICAgICBbaGlkZGVuXT1cIiFkcmlsbENydW1icygpLmxlbmd0aCB8fCBlZGl0TW9kZVwiXG4gICAgICAgICAgKGNsaWNrKT1cImRyaWxsVXAoKVwiPlxuICAgICAgICA8bWF0LWljb24+YXJyb3dfdXB3YXJkPC9tYXQtaWNvbj5cbiAgICAgICAgPHNwYW4+RHJpbGwgdXA8L3NwYW4+XG4gICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgPG5nLXRlbXBsYXRlXG4gICAgICAgICAgZnMtbWVudS1pdGVtXG4gICAgICAgICAgW2hpZGRlbl09XCIhZHJpbGxDcnVtYnMoKS5sZW5ndGggfHwgZWRpdE1vZGVcIlxuICAgICAgICAgIChjbGljayk9XCJkcmlsbFRvKDApXCI+XG4gICAgICAgIDxtYXQtaWNvbj52ZXJ0aWNhbF9hbGlnbl90b3A8L21hdC1pY29uPlxuICAgICAgICA8c3Bhbj5CYWNrIHRvIHRvcDwvc3Bhbj5cbiAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICA8bmctdGVtcGxhdGVcbiAgICAgICAgICBmcy1tZW51LWl0ZW1cbiAgICAgICAgICBbaGlkZGVuXT1cImlzVGV4dFwiXG4gICAgICAgICAgKGNsaWNrKT1cInNldHRpbmdzKClcIj5cbiAgICAgICAgPG1hdC1pY29uPnR1bmU8L21hdC1pY29uPlxuICAgICAgICA8c3Bhbj5TZXR0aW5nczwvc3Bhbj5cbiAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICA8bmctdGVtcGxhdGVcbiAgICAgICAgICBmcy1tZW51LWl0ZW1cbiAgICAgICAgICBbaGlkZGVuXT1cImlzVGV4dFwiXG4gICAgICAgICAgKGNsaWNrKT1cImV4cG9ydENzdigpXCI+XG4gICAgICAgIDxtYXQtaWNvbj5kb3dubG9hZDwvbWF0LWljb24+XG4gICAgICAgIDxzcGFuPkV4cG9ydCBDU1Y8L3NwYW4+XG4gICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgPG5nLXRlbXBsYXRlXG4gICAgICAgICAgZnMtbWVudS1pdGVtXG4gICAgICAgICAgW2hpZGRlbl09XCIhaGlkZXNDb2x1bW5zXCJcbiAgICAgICAgICAoY2xpY2spPVwiY2hvb3NlQ29sdW1ucygpXCI+XG4gICAgICAgIDxtYXQtaWNvbj52aWV3X2NvbHVtbjwvbWF0LWljb24+XG4gICAgICAgIDxzcGFuPkNvbHVtbnM8L3NwYW4+XG4gICAgICA8L25nLXRlbXBsYXRlPlxuICAgIDwvZnMtbWVudT5cbiAgfVxuICA8ZGl2IGNsYXNzPVwiY29tcG9uZW50LWJvZHlcIj5cbiAgICA8IS0tIEEgcmVmZXRjaCBrZWVwcyB0aGUgZGF0YSBvbiBzY3JlZW4gdW5kZXIgYSB0aGluIGJhcjsgdGhlIHNoaW1tZXJcbiAgICAgICAgIGJlbG93IGlzIGZvciB0aGUgZmlyc3QgbG9hZCBvbmx5LiAtLT5cbiAgICBAaWYgKHJlZnJlc2hpbmcoKSkge1xuICAgICAgPG1hdC1wcm9ncmVzcy1iYXJcbiAgICAgICAgY2xhc3M9XCJyZWZyZXNoLWJhclwiXG4gICAgICAgIGFyaWEtbGFiZWw9XCJSZWZyZXNoaW5nIGRhdGFcIlxuICAgICAgICBbbW9kZV09XCInaW5kZXRlcm1pbmF0ZSdcIj5cbiAgICAgIDwvbWF0LXByb2dyZXNzLWJhcj5cbiAgICB9XG4gICAgQGlmIChpc1RleHQpIHtcbiAgICAgIDxhcHAtcmVwb3J0LWNvbXBvbmVudC10ZXh0XG4gICAgICAgIFtodG1sXT1cInRleHRIdG1sKCkgPz8gY29tcG9uZW50LmNvbmZpZz8uaHRtbCA/PyAnJ1wiXG4gICAgICAgIFt0b2tlbnNdPVwidG9rZW5zKClcIlxuICAgICAgICBbZWRpdGluZ109XCJ0ZXh0RWRpdGluZygpXCJcbiAgICAgICAgW3Nob3duRWxzZXdoZXJlXT1cInNob3duRWxzZXdoZXJlXCJcbiAgICAgICAgKHNhdmVkKT1cIm9uVGV4dFNhdmVkKCRldmVudClcIlxuICAgICAgICAoZWRpdEVuZGVkKT1cInRleHRFZGl0aW5nLnNldChmYWxzZSlcIlxuICAgICAgICAodmFsdWVTZXR0aW5ncyk9XCJ2YWx1ZVNldHRpbmdzLmVtaXQoJGV2ZW50KVwiPlxuICAgICAgPC9hcHAtcmVwb3J0LWNvbXBvbmVudC10ZXh0PlxuICAgIH0gQGVsc2UgaWYgKGNvbXBvbmVudC50eXBlID09PSAnbGlzdCcpIHtcbiAgICAgIEBmb3IgKGtleSBvZiBbbGlzdFJlc2V0S2V5KCldOyB0cmFjayBrZXkpIHtcbiAgICAgICAgPGFwcC1yZXBvcnQtY29tcG9uZW50LWxpc3RcbiAgICAgICAgICBbcmVwb3J0SWRdPVwicmVwb3J0SWRcIlxuICAgICAgICAgIFtjb21wb25lbnRdPVwiY29tcG9uZW50XCI+XG4gICAgICAgIDwvYXBwLXJlcG9ydC1jb21wb25lbnQtbGlzdD5cbiAgICAgIH1cbiAgICB9IEBlbHNlIGlmIChsb2FkaW5nKCkpIHtcbiAgICAgIDxkaXYgY2xhc3M9XCJjb21wb25lbnQtc3RhdGVcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImxvYWRpbmctc2hpbW1lclwiPjwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgfSBAZWxzZSBpZiAoZXJyb3IoKSkge1xuICAgICAgPGRpdiBjbGFzcz1cImNvbXBvbmVudC1zdGF0ZSBlcnJvclwiPlxuICAgICAgICB7eyBlcnJvcigpIH19XG4gICAgICA8L2Rpdj5cbiAgICB9IEBlbHNlIGlmICghZGF0YSgpPy5yb3dzPy5sZW5ndGgpIHtcbiAgICAgIDxkaXYgY2xhc3M9XCJjb21wb25lbnQtc3RhdGVcIj5cbiAgICAgICAge3sgZW1wdHlNZXNzYWdlKCkgfX1cbiAgICAgIDwvZGl2PlxuICAgIH0gQGVsc2UgaWYgKGNvbXBvbmVudC50eXBlID09PSAna3BpJykge1xuICAgICAgPGFwcC1yZXBvcnQtY29tcG9uZW50LWtwaVxuICAgICAgICBbY29tcG9uZW50XT1cImNvbXBvbmVudFwiXG4gICAgICAgIFtkYXRhXT1cImRhdGEoKVwiXG4gICAgICAgIChtYXJrQ2xpY2spPVwib25NYXJrQ2xpY2soJGV2ZW50KVwiPlxuICAgICAgPC9hcHAtcmVwb3J0LWNvbXBvbmVudC1rcGk+XG4gICAgfSBAZWxzZSB7XG4gICAgICA8YXBwLXJlcG9ydC1jb21wb25lbnQtY2hhcnRcbiAgICAgICAgW2NvbXBvbmVudF09XCJjb21wb25lbnRcIlxuICAgICAgICBbZGF0YV09XCJkYXRhKClcIlxuICAgICAgICBbYWN0aW9uc109XCJ0aWxlQWN0aW9ucygpXCJcbiAgICAgICAgWyhsZWdlbmRTZWxlY3RlZCldPVwibGVnZW5kU2VsZWN0ZWRcIlxuICAgICAgICAobWFya0NsaWNrKT1cIm9uTWFya0NsaWNrKCRldmVudClcIlxuICAgICAgICAobWFya01pc3MpPVwib25NYXJrTWlzcygpXCI+XG4gICAgICA8L2FwcC1yZXBvcnQtY29tcG9uZW50LWNoYXJ0PlxuICAgIH1cbiAgICA8IS0tIEluIGVkaXQgbW9kZSBhIHRyYW5zcGFyZW50IHZlaWwgb3ZlciB0aGUgYm9keSBtYWtlcyB0aGUgV0hPTEVcbiAgICAgICAgIGNvbXBvbmVudCBkcmFnZ2FibGUgKGluZHVzdHJ5IHN0YW5kYXJkOiB5b3UgZ3JhYiB0aGUgb2JqZWN0LCBub3QganVzdFxuICAgICAgICAgaXRzIHRpdGxlIGJhcikgYW5kIGtlZXBzIGlubmVyIHdpZGdldHMgZnJvbSBzd2FsbG93aW5nIHRoZSBnZXN0dXJlLiAtLT5cbiAgICBAaWYgKGVkaXRNb2RlICYmICF0ZXh0RWRpdGluZygpKSB7XG4gICAgICA8ZGl2XG4gICAgICAgIGNsYXNzPVwiZHJhZy12ZWlsXCJcbiAgICAgICAgKHBvaW50ZXJkb3duKT1cIm9uRHJhZ1N0YXJ0KCRldmVudClcIj5cbiAgICAgIDwvZGl2PlxuICAgIH1cbiAgPC9kaXY+XG48L2Rpdj5cbjwhLS0gVGhlIG1hcmsgbWVudSwgZm9yIGEgY2xpY2sgd2hvc2UgbWFyayBvZmZlcnMgdHdvIG9yIG1vcmUgYWN0aW9ucy4gSXRcbiAgICAgb3BlbnMgYXQgdGhlIGNsaWNrOiBpdHMgdHJpZ2dlciBpcyBhIHplcm8tc2l6ZSBhbmNob3IgdGhhdFxuICAgICBhbmNob3ItYXQtcG9pbnQudHMgbW92ZXMgdGhlcmUgZmlyc3QuIC0tPlxuQGlmICghaXNUZXh0ICYmICFlZGl0TW9kZSkge1xuICA8c3BhblxuICAgICNtYXJrQW5jaG9yXG4gICAgW3N0eWxlLnBvc2l0aW9uXT1cIidhYnNvbHV0ZSdcIlxuICAgIFtmc01lbnVUcmlnZ2VyRm9yXT1cIm1hcmtNZW51XCI+XG4gIDwvc3Bhbj5cbiAgPGZzLW1lbnUgI21hcmtNZW51PlxuICAgIEBmb3IgKGFjdGlvbiBvZiBtYXJrTWVudUFjdGlvbnMoKTsgdHJhY2sgYWN0aW9uKSB7XG4gICAgICA8bmctdGVtcGxhdGVcbiAgICAgICAgICBmcy1tZW51LWl0ZW1cbiAgICAgICAgICAoY2xpY2spPVwicnVuTWFya0FjdGlvbihhY3Rpb24pXCI+XG4gICAgICAgIHt7IG1hcmtBY3Rpb25MYWJlbHNbYWN0aW9uXSB9fVxuICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICB9XG4gIDwvZnMtbWVudT5cbn1cbjwhLS0gSGFuZGxlcyBsaXZlIE9VVFNJREUgdGhlIGNsaXBwZWQgYm94IHNvIHRoZXkgc3RyYWRkbGUgaXRzIGVkZ2VzLiAtLT5cbkBpZiAoZWRpdE1vZGUgJiYgc2VsZWN0ZWQpIHtcbiAgQGZvciAoaGFuZGxlIG9mIHJlc2l6ZUhhbmRsZXM7IHRyYWNrIGhhbmRsZSkge1xuICAgIDxkaXZcbiAgICAgIGNsYXNzPVwiaGFuZGxlIGhhbmRsZS17eyBoYW5kbGUgfX1cIlxuICAgICAgKG1vdXNlZG93bik9XCJzdG9wQ2FudmFzUGFuKCRldmVudClcIlxuICAgICAgKHBvaW50ZXJkb3duKT1cIm9uUmVzaXplU3RhcnQoJGV2ZW50LCBoYW5kbGUpXCI+XG4gICAgPC9kaXY+XG4gIH1cbn0iXX0=
|
|
817
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0LWNvbXBvbmVudC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBwL3JlcG9ydHMvY29tcG9uZW50cy9yZXBvcnQtY29tcG9uZW50L3JlcG9ydC1jb21wb25lbnQuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9yZXBvcnRzL2NvbXBvbmVudHMvcmVwb3J0LWNvbXBvbmVudC9yZXBvcnQtY29tcG9uZW50LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCx1QkFBdUIsRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFDMUQsWUFBWSxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFxQixNQUFNLEVBQWlCLFNBQVMsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUMvRyxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxTQUFTLEdBQ2pDLE1BQU0sZUFBZSxDQUFDO0FBR3ZCLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDckQsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ2pELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBQ3hFLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUV2RCxPQUFPLEVBQWdCLGNBQWMsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ2xFLE9BQU8sRUFBRSxlQUFlLEVBQUUsWUFBWSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDakUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ2hELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNoRCxPQUFP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QWM7c0JBRHBCLFNBQVM7dUJBQUMsdUJBQXVCO2dCQWdFM0IsUUFBUTtzQkFEZCxTQUFTO3VCQUFDLFVBQVU7Z0JBSWQsVUFBVTtzQkFEaEIsU0FBUzt1QkFBQyxZQUFZO2dCQWduQlosVUFBVTtzQkFEcEIsV0FBVzt1QkFBQyxtQkFBbUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ29tcG9uZW50LCBEZXN0cm95UmVmLCBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsIEhvc3RCaW5kaW5nLCBJbnB1dCwgTmdab25lLCBPbkNoYW5nZXMsIE9uSW5pdCwgT3V0cHV0LCBTaW1wbGVDaGFuZ2VzLCBWaWV3Q2hpbGQsIGNvbXB1dGVkLCBpbmplY3QsXG4gIGlucHV0LCBvdXRwdXQsIHNpZ25hbCwgdmlld0NoaWxkLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuXG5pbXBvcnQgeyBNYXRJY29uQnV0dG9uIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvYnV0dG9uJztcbmltcG9ydCB7IE1hdERpYWxvZyB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2RpYWxvZyc7XG5pbXBvcnQgeyBNYXRJY29uIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvaWNvbic7XG5pbXBvcnQgeyBNYXRQcm9ncmVzc1NwaW5uZXIgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9wcm9ncmVzcy1zcGlubmVyJztcbmltcG9ydCB7IE1hdFRvb2x0aXAgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC90b29sdGlwJztcblxuaW1wb3J0IHsgRmlsdGVyQ29uZmlnLCBGc0ZpbHRlck1vZHVsZSB9IGZyb20gJ0BmaXJlc3RpdGNoL2ZpbHRlcic7XG5pbXBvcnQgeyBGc01lbnVDb21wb25lbnQsIEZzTWVudU1vZHVsZSB9IGZyb20gJ0BmaXJlc3RpdGNoL21lbnUnO1xuaW1wb3J0IHsgRnNNZXNzYWdlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvbWVzc2FnZSc7XG5pbXBvcnQgeyBGc1Byb2Nlc3MgfSBmcm9tICdAZmlyZXN0aXRjaC9wcm9jZXNzJztcbmltcG9ydCB7IEZzUHJvbXB0IH0gZnJvbSAnQGZpcmVzdGl0Y2gvcHJvbXB0JztcblxuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgU3ViamVjdCwgZmlsdGVyIGFzIHJ4RmlsdGVyLCBtYXAsIHN3aXRjaE1hcCwgdGFwIH0gZnJvbSAncnhqcyc7XG5cbmltcG9ydCB7IHRha2VVbnRpbERlc3Ryb3llZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUvcnhqcy1pbnRlcm9wJztcblxuaW1wb3J0IHsgb3BlbkF0UG9pbnQgfSBmcm9tICcuLi8uLi9hbmNob3ItYXQtcG9pbnQnO1xuaW1wb3J0IHsgUmVwb3J0RGF0YSB9IGZyb20gJy4uLy4uL2RhdGEvcmVwb3J0LmRhdGEnO1xuaW1wb3J0IHsgTGlzdENvbHVtbnNDb21wb25lbnQsIExpc3RDb2x1bW5zRGlhbG9nRGF0YSB9IGZyb20gJy4uLy4uL2RpYWxvZ3MvbGlzdC1jb2x1bW5zL2xpc3QtY29sdW1ucy5jb21wb25lbnQnO1xuaW1wb3J0IHtcbiAgRFJJTExfQ1JVTUJfU0VQQVJBVE9SLCBEUklMTF9SRVNFVF9NRVNTQUdFLCBhZG9wdGVkRHJpbGxQYXRoLCBkcmlsbENydW1iTGFiZWxzLCBkcmlsbE91dHNpZGVNZXNzYWdlLFxuICBkcmlsbFJlc2V0Tm90ZWQsXG59IGZyb20gJy4uLy4uL2RyaWxsLWNydW1icyc7XG5pbXBvcnQge1xuICBDb21wb25lbnREYXRhLFxuICBDb21wb25lbnRTZXR0aW5ncyxcbiAgRmlsdGVyR3JvdXBWYWx1ZSxcbiAgS3BpQ29uZmlnLFxuICBSZXBvcnRDb21wb25lbnQgYXMgUmVwb3J0Q29tcG9uZW50TW9kZWwsXG4gIFJlcG9ydENvbXBvbmVudFR5cGUsXG4gIFJlcG9ydEZpbHRlckdyb3VwLFxufSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL3JlcG9ydC5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgUmVwb3J0TWFya0FjdGlvbiB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMvcmVwb3J0LW1hcmstYWN0aW9uLnR5cGUnO1xuaW1wb3J0IHsgUmVwb3J0TWFya0NsaWNrIH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9yZXBvcnQtbWFyay1jbGljay5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgVGlsZUxvYWRSZXN1bHQgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL3RpbGUtbG9hZC1yZXN1bHQuaW50ZXJmYWNlJztcbmltcG9ydCB7IGtwaUNhcmRTZXR0aW5ncywgc2FtZUtwaUNhcmRTZXR0aW5ncyB9IGZyb20gJy4uLy4uL2twaS1jYXJkJztcbmltcG9ydCB7IGNvbXBvbmVudFBhZGRpbmdDc3MgfSBmcm9tICcuLi8uLi9sYXlvdXQnO1xuaW1wb3J0IHsgbGlzdEhpZGVhYmxlQ29sdW1ucyB9IGZyb20gJy4uLy4uL2xpc3QtY29uZmlnJztcbmltcG9ydCB7XG4gIE1BUktfQUNUSU9OX0xBQkVMUywgZGVjaWRlTWFya0NsaWNrLCBkcmlsbERvd25QYXRoLCBtYXJrQWN0aW9ucywgdGlsZU1hcmtBY3Rpb25zLFxufSBmcm9tICcuLi8uLi9tYXJrLWNsaWNrJztcbmltcG9ydCB7XG4gIExJU1RfU0VBUkNIX0lURU0sIGZpbHRlckl0ZW1Gb3JHcm91cCwgZ3JvdXBWYWx1ZXNGcm9tUXVlcnksIGxpc3RTZWFyY2hJdGVtLFxufSBmcm9tICcuLi8uLi9yZXBvcnQtZmlsdGVyLWl0ZW1zJztcbmltcG9ydCB7IGdyb3VwVmFsdWVTaWduYXR1cmUgfSBmcm9tICcuLi8uLi9yZXBvcnQtZmlsdGVyLWl0ZW1zJztcbmltcG9ydCB7IG9mZmVyZWRWaWV3ZXJGZWF0dXJlcyB9IGZyb20gJy4uLy4uL3JlcG9ydC12aWV3ZXItZmVhdHVyZXMnO1xuaW1wb3J0IHsgUmVwb3J0RmlsdGVyT3B0aW9uc1NlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9yZXBvcnQtZmlsdGVyLW9wdGlvbnMuc2VydmljZSc7XG5pbXBvcnQgeyBtb3ZlZEdyb3VwVmFsdWVzLCBSZXBvcnRGaWx0ZXJTdGF0ZVNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9yZXBvcnQtZmlsdGVyLXN0YXRlLnNlcnZpY2UnO1xuaW1wb3J0IHsgaXNUaW1lU2VyaWVzQ2hhcnQgfSBmcm9tICcuLi8uLi90aWxlLWRhdGEtc3RhdGUnO1xuaW1wb3J0IHsgdGlsZUxvYWRzIH0gZnJvbSAnLi4vLi4vdGlsZS1sb2Fkcyc7XG5pbXBvcnQgeyBDb21wb25lbnRDaGFydENvbXBvbmVudCB9IGZyb20gJy4uL2NvbXBvbmVudC1jaGFydC9jb21wb25lbnQtY2hhcnQuY29tcG9uZW50JztcbmltcG9ydCB7IENvbXBvbmVudEdyaWRDb21wb25lbnQgfSBmcm9tICcuLi9jb21wb25lbnQtZ3JpZC9jb21wb25lbnQtZ3JpZC5jb21wb25lbnQnO1xuaW1wb3J0IHsgQ29tcG9uZW50S3BpQ29tcG9uZW50IH0gZnJvbSAnLi4vY29tcG9uZW50LWtwaS9jb21wb25lbnQta3BpLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBDb21wb25lbnRMaXN0Q29tcG9uZW50IH0gZnJvbSAnLi4vY29tcG9uZW50LWxpc3QvY29tcG9uZW50LWxpc3QuY29tcG9uZW50JztcbmltcG9ydCB7IENvbXBvbmVudFRleHRDb21wb25lbnQgfSBmcm9tICcuLi9jb21wb25lbnQtdGV4dC9jb21wb25lbnQtdGV4dC5jb21wb25lbnQnO1xuaW1wb3J0IHsgVGV4dFRva2VuQ29udGV4dCwgZmlsbFRpdGxlVG9rZW5zIH0gZnJvbSAnLi4vLi4vdGV4dCc7XG5pbXBvcnQgeyBOT19WQUxVRV9LRVlTLCBpc0RyYXduLCB2YWx1ZUtleXMgfSBmcm9tICcuLi8uLi92YWx1ZXMnO1xuaW1wb3J0IHsgQ2FudmFzU25hcHBlciwgUFhfUEVSX0lOQ0ggfSBmcm9tICcuLi9yZXBvcnQtY2FudmFzL3JlcG9ydC1jYW52YXMuY29tcG9uZW50JztcblxuXG4vLyBSZXNpemUgaGFuZGxlcywgbmFtZWQgYnkgY29tcGFzcyBkaXJlY3Rpb24uXG5jb25zdCBIQU5ETEVTID0gWydudycsICduJywgJ25lJywgJ2UnLCAnc2UnLCAncycsICdzdycsICd3J10gYXMgY29uc3Q7XG50eXBlIEhhbmRsZSA9IHR5cGVvZiBIQU5ETEVTW251bWJlcl07XG5cbmNvbnN0IE1JTl9XID0gMC42OyAvLyBpbmNoZXNcbmNvbnN0IE1JTl9IID0gMC40OyAvLyBpbmNoZXNcblxuLy8gVGhlIHRpbGVzIHRoYXQgcmVhZCB0aGVpciBvd24gcm93czogYSBsaXN0IHRocm91Z2ggRnNMaXN0IHBhZ2luZywgYSBncmlkXG4vLyB0aHJvdWdoIGZzLWdyaWQncyBzb3VyY2UuIFRoaXMgY29tcG9uZW50IGxvYWRzIGV2ZXJ5IG90aGVyIHRpbGUncyBkYXRhLlxuY29uc3QgU0VMRl9SRUFESU5HX1RZUEVTOiByZWFkb25seSBSZXBvcnRDb21wb25lbnRUeXBlW10gPSBbJ2xpc3QnLCAnZ3JpZCddO1xuXG4vLyBUd28gcHJlc3NlcyBvbiBhIHRleHQgYmxvY2sgdGhpcyBjbG9zZSB0b2dldGhlciBvcGVuIGl0cyBlZGl0b3IuIERldGVjdGVkXG4vLyBoZXJlIHJhdGhlciB0aGFuIHdpdGggYSBkYmxjbGljayBsaXN0ZW5lciBiZWNhdXNlIHRoZSBkcmFnIGxvb3AgY2xhaW1zIHRoZVxuLy8gcG9pbnRlciBvbiBldmVyeSBwcmVzcywgYW5kIGEgYnJvd3NlciBpcyBub3Qgb2JsaWdlZCB0byBkZWxpdmVyIGRibGNsaWNrXG4vLyB0aHJvdWdoIGEgY2FwdHVyZWQsIGRlZmF1bHQtcHJldmVudGVkIHBvaW50ZXIuXG5jb25zdCBET1VCTEVfUFJFU1NfTVMgPSA0MDA7XG5cbi8vIE9uZSBjb21wb25lbnQgb24gdGhlIHBhZ2U6IHRpdGxlIGJhciwgdGhlIHR5cGUtc3BlY2lmaWMgYm9keSAoY2hhcnQgfCBsaXN0XG4vLyB8IGtwaSksIGEgbWVudSAoc2V0dGluZ3MsIGZpbHRlciB0b2dnbGVzLCBleHBvcnQpIOKAlCBhbmQgdGhlIGVkaXRpbmdcbi8vIGludGVyYWN0aW9uczogY2xpY2sgc2VsZWN0czsgdGhlIHNlbGVjdGlvbiBmcmFtZSBzaG93cyA4IHJlc2l6ZSBoYW5kbGVzO1xuLy8gZHJhZ2dpbmcgdGhlIGJvZHkgbW92ZXMgd2l0aCBzbWFydCBhbGlnbm1lbnQgZ3VpZGVzICh2aWEgdGhlIGNhbnZhc1xuLy8gc25hcHBlcik7IGV2ZXJ5dGhpbmcgd29ya3MgYXQgYW55IHpvb20gKHBpeGVsIGRlbHRhcyDDtyB6b29twrc5NiDihpIgaW5jaGVzKS5cbi8vXG4vLyBDaGFydHMgYW5kIEtQSXMgZmV0Y2ggdGhlaXIgb3duIGRhdGEgaGVyZTsgbGlzdHMgZmV0Y2ggaW5zaWRlXG4vLyBDb21wb25lbnRMaXN0Q29tcG9uZW50IHRocm91Z2ggRnNMaXN0IHBhZ2luZywgYW5kIGdyaWRzIGluc2lkZVxuLy8gQ29tcG9uZW50R3JpZENvbXBvbmVudCB0aHJvdWdoIGZzLWdyaWQncyBzb3VyY2UuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhcHAtcmVwb3J0LWNvbXBvbmVudCcsXG4gIHRlbXBsYXRlVXJsOiAnLi9yZXBvcnQtY29tcG9uZW50LmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vcmVwb3J0LWNvbXBvbmVudC5jb21wb25lbnQuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIE1hdEljb24sXG4gICAgTWF0SWNvbkJ1dHRvbixcbiAgICBNYXRQcm9ncmVzc1NwaW5uZXIsXG4gICAgTWF0VG9vbHRpcCxcbiAgICBGc0ZpbHRlck1vZHVsZSxcbiAgICBGc01lbnVNb2R1bGUsXG4gICAgQ29tcG9uZW50Q2hhcnRDb21wb25lbnQsXG4gICAgQ29tcG9uZW50R3JpZENvbXBvbmVudCxcbiAgICBDb21wb25lbnRLcGlDb21wb25lbnQsXG4gICAgQ29tcG9uZW50TGlzdENvbXBvbmVudCxcbiAgICBDb21wb25lbnRUZXh0Q29tcG9uZW50LFxuICBdLFxufSlcbmV4cG9ydCBjbGFzcyBSZXBvcnRDb21wb25lbnRDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcyB7XG5cbiAgQElucHV0KCkgcHVibGljIHJlcG9ydElkOiBudW1iZXI7XG4gIEBJbnB1dCgpIHB1YmxpYyBjb21wb25lbnQ6IFJlcG9ydENvbXBvbmVudE1vZGVsO1xuICBASW5wdXQoKSBwdWJsaWMgZ3JvdXBzOiBNYXA8bnVtYmVyLCBSZXBvcnRGaWx0ZXJHcm91cD47XG4gIEBJbnB1dCgpIHB1YmxpYyBlZGl0TW9kZSA9IGZhbHNlO1xuICAvLyBUaGUgY2FudmFzIHpvb20g4oCUIGNvbnZlcnRzIG9uLXNjcmVlbiBwaXhlbCBkZWx0YXMgYmFjayB0byBpbmNoZXMuXG4gIEBJbnB1dCgpIHB1YmxpYyB6b29tID0gMTtcbiAgQElucHV0KCkgcHVibGljIHNuYXBwZXI6IENhbnZhc1NuYXBwZXIgfCBudWxsID0gbnVsbDtcbiAgQElucHV0KCkgcHVibGljIHNlbGVjdGVkID0gZmFsc2U7XG5cbiAgQE91dHB1dCgpIHB1YmxpYyBzZWxlY3RDb21wb25lbnQgPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlcj4oKTtcbiAgQE91dHB1dCgpIHB1YmxpYyBwb3NpdGlvbkNoYW5nZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHsgY29tcG9uZW50SWQ6IG51bWJlciB9ICYgUmVjb3JkPHN0cmluZywgbnVtYmVyPj4oKTtcbiAgQE91dHB1dCgpIHB1YmxpYyBvcGVuU2V0dGluZ3MgPSBuZXcgRXZlbnRFbWl0dGVyPFJlcG9ydENvbXBvbmVudE1vZGVsPigpO1xuXG4gIC8vIFdoYXQgdGhlIHt7dG9rZW5zfX0gb2YgYSB0ZXh0IGJsb2NrLCBhbmQgb2YgYW55IGNvbXBvbmVudCdzIHRpdGxlLCBmaWxsXG4gIC8vIHdpdGggd2hlcmUgaXQgaXMgZHJhd246IGl0cyBwYWdlJ3MsIG9yIHRoZSBtYXN0ZXIncyBmb3IgYSBoZWFkZXIgb3JcbiAgLy8gZm9vdGVyIGNvbXBvbmVudC5cbiAgcHVibGljIHJlYWRvbmx5IHRva2VucyA9IGlucHV0PFRleHRUb2tlbkNvbnRleHQ+KHsgcGFnZU51bWJlcjogMSwgcGFnZU5hbWU6ICcnLCByZXBvcnROYW1lOiAnJyB9KTtcblxuICAvLyBUaGUgdmFsdWUga2V5cyB0aGUgb3RoZXIgdGV4dCBibG9ja3Mgb2YgYSB0ZXh0J3MgbGF5ZXIgc2hvdywgcmVhZCBieSB0aGVcbiAgLy8gY2FudmFzIHdoZW4gdGhlIHRleHQncyBlZGl0b3IgYXNrcy5cbiAgcHVibGljIHJlYWRvbmx5IHZhbHVlS2V5c0Vsc2V3aGVyZSA9IGlucHV0PCgodGV4dDogUmVwb3J0Q29tcG9uZW50TW9kZWwpID0+IFJlYWRvbmx5U2V0PHN0cmluZz4pIHwgbnVsbD4obnVsbCk7XG5cbiAgLy8gQSB0ZXh0IGJsb2NrIHdhcyBkZWxldGVkIGZyb20gaXRzIG1lbnUg4oCUIHRoZSBjYW52YXMgZHJvcHMgaXQuXG4gIHB1YmxpYyByZWFkb25seSByZW1vdmVkID0gb3V0cHV0PG51bWJlcj4oKTtcblxuICAvLyBBIHZhbHVlJ3Mgc2V0dGluZ3Mgd2VyZSBhc2tlZCBmb3IgZnJvbSBpdHMgY2hpcCBpbiB0aGUgdGV4dCwgYnkgdGhlXG4gIC8vIHZhbHVlJ3Mga2V5LiBUaGUgY2FudmFzIG9wZW5zIHRoZW0uXG4gIHB1YmxpYyByZWFkb25seSB2YWx1ZVNldHRpbmdzID0gb3V0cHV0PHN0cmluZz4oKTtcblxuICAvLyBUaGUgdGV4dCdzIGh0bWwgd2FzIHNhdmVkLiBFbWl0dGVkIG9uIHRoZSByZXNwb25zZSwgc28gdGhlIHNlcnZlciBhbHJlYWR5XG4gIC8vIGhvbGRzIHRoZSBodG1sIHdoZW4gdGhlIGNhbnZhcyByZWFkcyB0aGUgdmFsdWVzIGl0IHNob3dzLlxuICBwdWJsaWMgcmVhZG9ubHkgdGV4dFNhdmVkID0gb3V0cHV0PHN0cmluZz4oKTtcblxuICAvLyBEZWxldGluZyB0aGUgdGV4dCBhbHNvIGRlbGV0ZWQgdGhlIHZhbHVlcyBubyBvdGhlciB0ZXh0IG9uIGl0cyBwYWdlIHJlYWRzLFxuICAvLyBieSBpZC4gVGhlIGNhbnZhcyBoYXMgdGhlIHJlcG9ydCByZWxvYWRlZC5cbiAgcHVibGljIHJlYWRvbmx5IHZhbHVlc1JlbW92ZWQgPSBvdXRwdXQ8bnVtYmVyW10+KCk7XG5cbiAgLy8gVGhlIHRleHQgYmxvY2sncyBlZGl0b3IgaXMgb3BlbiAoZG91YmxlLXByZXNzIGluIGVkaXQgbW9kZSkuIENsb3NlZCBieSBmb2N1c1xuICAvLyBsZWF2aW5nIHRoZSBibG9jaywgYnkgZGVzZWxlY3RpbmcgaXQsIG9yIGJ5IGxlYXZpbmcgZWRpdCBtb2RlIOKAlCBlYWNoIG9mXG4gIC8vIHdoaWNoIHNhdmVzLlxuICBwdWJsaWMgcmVhZG9ubHkgdGV4dEVkaXRpbmcgPSBzaWduYWwoZmFsc2UpO1xuICAvLyBBIHRleHQgYmxvY2sncyBodG1sIGFzIGxhc3Qgc2F2ZWQgaGVyZTsgbnVsbCB1bnRpbCB0aGVuLCBzbyB0aGUgYmxvY2tcbiAgLy8gc2hvd3MgaXRzIHN0b3JlZCBodG1sLlxuICBwdWJsaWMgcmVhZG9ubHkgdGV4dEh0bWwgPSBzaWduYWw8c3RyaW5nIHwgbnVsbD4obnVsbCk7XG5cbiAgLy8gV2hhdCB0aGUgb3RoZXIgdGV4dCBibG9ja3Mgb2YgdGhpcyB0ZXh0J3MgbGF5ZXIgc2hvdywgZm9yIGl0cyBlZGl0b3Inc1xuICAvLyBub3RpY2UuIFN0YWJsZSwgc28gdGhlIHRleHQgYmxvY2sncyBpbnB1dCBuZXZlciBjaGFuZ2VzOyBpdCBhc2tzIHdoZW4gYW5cbiAgLy8gZWRpdCB0YWtlcyBhIHZhbHVlJ3MgbGFzdCBjaGlwIG91dC5cbiAgcHVibGljIHJlYWRvbmx5IHNob3duRWxzZXdoZXJlID0gKCk6IFJlYWRvbmx5U2V0PHN0cmluZz4gPT5cbiAgICB0aGlzLnZhbHVlS2V5c0Vsc2V3aGVyZSgpPy4odGhpcy5jb21wb25lbnQpID8/IE5PX1ZBTFVFX0tFWVM7XG5cbiAgQFZpZXdDaGlsZChDb21wb25lbnRDaGFydENvbXBvbmVudClcbiAgcHVibGljIGNoYXJ0Q29tcG9uZW50OiBDb21wb25lbnRDaGFydENvbXBvbmVudDtcblxuICAvLyBSZXNpemUgaGFuZGxlcyBieSB0eXBlOiBhIGZpeGVkLWhlaWdodCBjb21wb25lbnQgKGNoYXJ0L2xpc3QpXG4gIC8vIGdldHMgYWxsIGVpZ2h0IChyZXNpemUgd2lkdGggQU5EIGhlaWdodCk7IGFuIGF1dG8taGVpZ2h0IG9uZSAoa3BpKSBnZXRzXG4gIC8vIG9ubHkgdGhlIHNpZGUgaGFuZGxlcyBzaW5jZSBpdHMgaGVpZ2h0IGZpdHMgaXRzIGNvbnRlbnQgYW5kIGNhbid0IGJlIHNldC5cbiAgcHVibGljIGdldCByZXNpemVIYW5kbGVzKCk6IHJlYWRvbmx5IEhhbmRsZVtdIHtcbiAgICByZXR1cm4gdGhpcy5faGVpZ2h0QXV0byA/IFsnZScsICd3J10gOiBIQU5ETEVTO1xuICB9XG5cbiAgLy8gVGhlIGNvbXBvbmVudCdzIGhlYWRlciBJUyBhbiBmcy1maWx0ZXI6IGhlYWRpbmcgdGVtcGxhdGUgPSBpdHMgdGl0bGUgKGFuZFxuICAvLyB0aGUgZHJhZyBoYW5kbGUpLCBhY3Rpb25zID0gdGhlIFNldHRpbmdzIC8gZmlsdGVyLXRvZ2dsZXMgLyBFeHBvcnQgbWVudSxcbiAgLy8gaXRlbXMgPSBpdHMgY29tcG9uZW50LWxldmVsIGZpbHRlciBncm91cHMsIGZvciBldmVyeSBjb21wb25lbnQgdHlwZSwgbGlzdHNcbiAgLy8gaW5jbHVkZWQsIHBsdXMgYSBsaXN0J3Mgc2VhcmNoIGJveC4gUmVidWlsdCB3aGVuIGEgZmlsdGVyIHRvZ2dsZSBjaGFuZ2VzIHdoaWNoIGdyb3VwcyBzaG93LFxuICAvLyBhbmQgd2hlbiB0aGUgc2V0dGluZ3MgZGlhbG9nIGNoYW5nZXMgdGhlIHRpdGxlIG9yIHBhZGRpbmc6IHNldHRpbmcgaXRcbiAgLy8gcmVwYWludHMgdGhlIGhlYWRlciBhbmQgYm9keS5cbiAgcHVibGljIHJlYWRvbmx5IGZpbHRlckNvbmZpZyA9IHNpZ25hbDxGaWx0ZXJDb25maWcgfCBudWxsPihudWxsKTtcblxuICBwdWJsaWMgcmVhZG9ubHkgZGF0YSA9IHNpZ25hbDxDb21wb25lbnREYXRhIHwgbnVsbD4obnVsbCk7XG4gIC8vIEEgbG9hZCBzaG93cyBhIHNwaW5uZXIgY2VudHJlZCBvbiB0aGUgdGlsZS4gYGxvYWRpbmdgIGlzIHRoZSBmaXJzdCBsb2FkLFxuICAvLyB3aXRoIG5vdGhpbmcgdG8gc2hvdyB5ZXQ7IGEgcmVmZXRjaCBrZWVwcyB0aGUgZGF0YSBvbiBzY3JlZW4sIGRpbW1lZFxuICAvLyB1bmRlciB0aGUgc3Bpbm5lciAoYHJlZnJlc2hpbmdgKS4gVGhlIHRpdGxlIGlzIG5ldmVyIGRpbW1lZC5cbiAgcHVibGljIHJlYWRvbmx5IGxvYWRpbmcgPSBzaWduYWwoZmFsc2UpO1xuICBwdWJsaWMgcmVhZG9ubHkgcmVmcmVzaGluZyA9IHNpZ25hbChmYWxzZSk7XG4gIHB1YmxpYyByZWFkb25seSBlcnJvciA9IHNpZ25hbDxzdHJpbmcgfCBudWxsPihudWxsKTtcblxuICAvLyBXaGljaCBvZiBhIGNoYXJ0J3MgbGVnZW5kIGVudHJpZXMgYXJlIG9uLCBieSBzZXJpZXMgbmFtZS4gSGVsZCBoZXJlIGFuZFxuICAvLyBoYW5kZWQgdG8gZWFjaCBvcHRpb24gdGhlIGNoYXJ0IGJ1aWxkczogbmd4LWVjaGFydHMgc2V0cyBhbiBvcHRpb24gd2l0aFxuICAvLyBub3RNZXJnZSwgd2hpY2ggd291bGQgb3RoZXJ3aXNlIHR1cm4gZXZlcnkgZW50cnkgYmFjayBvbiBhdCBlYWNoIHJlZmV0Y2guXG4gIHB1YmxpYyByZWFkb25seSBsZWdlbmRTZWxlY3RlZCA9IHNpZ25hbDxSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCBib29sZWFuPj4+KHt9KTtcblxuICAvLyBBIGxpc3QgaXMgZHJhd24gYWdhaW4gd2hlbiBhIHJlc2V0IG1vdmVzIGl0cyBzb3J0OiBGc0xpc3QgcmVhZHMgaXRzIHNvcnRcbiAgLy8gb25seSB3aGVuIGl0IGlzIGNyZWF0ZWQuIEV2ZXJ5IG90aGVyIHJlc2V0IHJlbG9hZHMgaXQgaW4gcGxhY2UuXG4gIHB1YmxpYyByZWFkb25seSBsaXN0UmVzZXRLZXkgPSBjb21wdXRlZCgoKSA9PiB0aGlzLl9maWx0ZXJTdGF0ZS5saXN0U29ydFJlc2V0cygpLmdldCh0aGlzLmNvbXBvbmVudD8uaWQpID8/IDApO1xuXG4gIC8vIFdoYXQgYSBjbGljayBvbiB0aGlzIHRpbGUncyBtYXJrcyBtYXkgZG8gb24gaXRzIGxhc3QgYW5zd2VyOiB0aGUgY2hhcnRcbiAgLy8gc2hvd3MgYSBoYW5kIGFuZCBhIHRvb2x0aXAgaGludCBmb3IgdGhlbS4gKFdoaWxlIHRoZSBsYXlvdXQgaXMgZWRpdGVkIGFcbiAgLy8gdmVpbCBjb3ZlcnMgdGhlIGJvZHksIHNvIG5vIG1hcmsgaXMgaG92ZXJlZCBvciBjbGlja2VkLilcbiAgcHVibGljIHJlYWRvbmx5IHRpbGVBY3Rpb25zID0gY29tcHV0ZWQ8UmVwb3J0TWFya0FjdGlvbltdPigoKSA9PiB0aWxlTWFya0FjdGlvbnMoe1xuICAgIGRhdGE6IHRoaXMuZGF0YSgpLFxuICAgIGZlYXR1cmVzOiB0aGlzLl9vZmZlcmVkRmVhdHVyZXMoKSxcbiAgfSkpO1xuXG4gIC8vIFRoZSBhY3Rpb25zIHRoZSBtYXJrIG1lbnUgbGlzdHMgZm9yIHRoZSBjbGljayBpdCB3YXMgb3BlbmVkIG9uLlxuICBwdWJsaWMgcmVhZG9ubHkgbWFya01lbnVBY3Rpb25zID0gc2lnbmFsPFJlcG9ydE1hcmtBY3Rpb25bXT4oW10pO1xuICBwdWJsaWMgcmVhZG9ubHkgbWFya0FjdGlvbkxhYmVscyA9IE1BUktfQUNUSU9OX0xBQkVMUztcblxuICAvLyBUaGUgYnJlYWRjcnVtYiBhZnRlciB0aGUgdGl0bGUgd2hpbGUgdGhlIGNoYXJ0IGlzIGRyaWxsZWQgKCcyMDI2JywgJ1EzJyksXG4gIC8vIG9uZSBsYWJlbCBwZXIgc3RlcCBvZiBpdHMgcGF0aCwgaW4gdGhlIHJlcG9ydCdzIGxvY2FsZS4gRW1wdHkgYXQgdGhlIHRvcFxuICAvLyBhbmQgd2hpbGUgdGhlIHZpZXdlciBpcyBub3Qgb2ZmZXJlZCBkcmlsbDogYSBwYXRoIGFuIG9sZGVyIHNlcnZlciBuZXZlclxuICAvLyBhcHBsaWVzIGlzIGtlcHQgaW4gdGhlIHN0YXRlLCBidXQgbm90IHNob3duLlxuICBwdWJsaWMgcmVhZG9ubHkgZHJpbGxDcnVtYnMgPSBjb21wdXRlZDxzdHJpbmdbXT4oKCkgPT4gKHRoaXMuX29mZmVyZWRGZWF0dXJlcygpLmluY2x1ZGVzKCdkcmlsbCcpXG4gICAgPyBkcmlsbENydW1iTGFiZWxzKHRoaXMuX2ZpbHRlclN0YXRlLmRyaWxsKHRoaXMuY29tcG9uZW50Py5pZCksIHRoaXMuX2ZpbHRlclN0YXRlLmZvcm1hdENvbnRleHQoKSlcbiAgICA6IFtdKSk7XG4gIHB1YmxpYyByZWFkb25seSBkcmlsbFNlcGFyYXRvciA9IERSSUxMX0NSVU1CX1NFUEFSQVRPUjtcblxuICAvLyBXaGF0IGFuIGVtcHR5IHRpbGUgc2F5czogdGhlIGRyaWxsZWQgcGVyaW9kIGl0IHJlYWRzIG5vIGRheSBvZiwgZWxzZVxuICAvLyAnTm8gZGF0YScuXG4gIHB1YmxpYyByZWFkb25seSBlbXB0eU1lc3NhZ2UgPSBjb21wdXRlZCgoKSA9PiBkcmlsbE91dHNpZGVNZXNzYWdlKFxuICAgIHRoaXMuZGF0YSgpPy5kcmlsbCxcbiAgICB0aGlzLl9maWx0ZXJTdGF0ZS5mb3JtYXRDb250ZXh0KCksXG4gICkgPz8gJ05vIGRhdGEnKTtcblxuICBAVmlld0NoaWxkKCdtYXJrTWVudScpXG4gIHB1YmxpYyBtYXJrTWVudTogRnNNZW51Q29tcG9uZW50O1xuXG4gIEBWaWV3Q2hpbGQoJ21hcmtBbmNob3InKVxuICBwdWJsaWMgbWFya0FuY2hvcjogRWxlbWVudFJlZjxIVE1MRWxlbWVudD47XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfdGV4dCA9IHZpZXdDaGlsZChDb21wb25lbnRUZXh0Q29tcG9uZW50KTtcbiAgcHJpdmF0ZSBfcmVmcmVzaCQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuICAvLyBUaGUgc3RhdGUgdmVyc2lvbiB0aGUgaGVhZGVyIHdhcyBsYXN0IGJ1aWx0IGZvciAoZmlsdGVyS2V5KS5cbiAgcHJpdmF0ZSByZWFkb25seSBfaGVhZGVyVmVyc2lvbiA9IHNpZ25hbCgwKTtcbiAgLy8gVGhlIGhlYWRlciBncm91cHMnIHZhbHVlcyBhcyB0aGUgaGVhZGVyIGxhc3Qgc2hvd2VkIHRoZW06IGFzIGl0IHdhc1xuICAvLyBidWlsdCwgdGhlbiBhcyBpdHMgb3duIGJhciByZXBvcnRlZCBlYWNoIGNoYW5nZS4gZmlsdGVyS2V5IGNhcnJpZXMgdGhlaXJcbiAgLy8gc2lnbmF0dXJlIGFzIGJ1aWx0LlxuICBwcml2YXRlIF9zaG93biA9IG5ldyBNYXA8bnVtYmVyLCBGaWx0ZXJHcm91cFZhbHVlIHwgbnVsbD4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfaGVhZGVyVmFsdWVzID0gc2lnbmFsKCcnKTtcbiAgcHJpdmF0ZSBfcmVwb3J0RGF0YSA9IGluamVjdChSZXBvcnREYXRhKTtcbiAgcHJpdmF0ZSBfZmlsdGVyU3RhdGUgPSBpbmplY3QoUmVwb3J0RmlsdGVyU3RhdGVTZXJ2aWNlKTtcbiAgcHJpdmF0ZSBfZmlsdGVyT3B0aW9ucyA9IGluamVjdChSZXBvcnRGaWx0ZXJPcHRpb25zU2VydmljZSk7XG4gIHByaXZhdGUgX3Byb2Nlc3MgPSBpbmplY3QoRnNQcm9jZXNzKTtcbiAgcHJpdmF0ZSBfbWVzc2FnZSA9IGluamVjdChGc01lc3NhZ2UpO1xuICBwcml2YXRlIF9wcm9tcHQgPSBpbmplY3QoRnNQcm9tcHQpO1xuICBwcml2YXRlIF9kaWFsb2cgPSBpbmplY3QoTWF0RGlhbG9nKTtcbiAgcHJpdmF0ZSBfbGFzdFByZXNzID0gMDtcbiAgcHJpdmF0ZSBfZGVzdHJveVJlZiA9IGluamVjdChEZXN0cm95UmVmKTtcbiAgcHJpdmF0ZSBfem9uZSA9IGluamVjdChOZ1pvbmUpO1xuICBwcml2YXRlIF9ob3N0OiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PiA9IGluamVjdChFbGVtZW50UmVmKTtcbiAgLy8gVGhlIGZlYXR1cmVzIGEgbWFyayBhY3Rpb24gbmVlZHM6IHNlcnZlZCBieSB0aGUgcmVwb3J0J3Mgc2VydmVyIGFuZFxuICAvLyBpbXBsZW1lbnRlZCBieSB0aGlzIHZpZXdlci5cbiAgcHJpdmF0ZSByZWFkb25seSBfb2ZmZXJlZEZlYXR1cmVzID0gY29tcHV0ZWQoKCkgPT4gb2ZmZXJlZFZpZXdlckZlYXR1cmVzKHRoaXMuX2ZpbHRlclN0YXRlLnZpZXdlckZlYXR1cmVzKCkpKTtcbiAgLy8gVGhlIG1hcmsgYSBmaXJzdCB0YXAgcHJldmlld2VkIChkZWNpZGVNYXJrQ2xpY2spLCBhbmQgdGhlIGNsaWNrIHRoZSBtYXJrXG4gIC8vIG1lbnUgaXMgb3BlbiBmb3IuXG4gIHByaXZhdGUgX3RvdWNoZWRNYXJrOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBfbWVudUNsaWNrOiBSZXBvcnRNYXJrQ2xpY2sgfCBudWxsID0gbnVsbDtcbiAgLy8gVGhlIGdyb3VwLWJ5IG1vdmVkIHNpbmNlIHRoZSBsYXN0IGFuc3dlcjogYSBwYXRoIHRoZSBzZXJ2ZXIgdGhlbiBkcm9wc1xuICAvLyBiZWNhdXNlIGl0IG5vIGxvbmdlciBzdGFydHMgYXQgdGhlIGNoYXJ0J3MgdG9wIGlzIG5vdCBuZXdzIHRvIHRoZSB2aWV3ZXIuXG4gIHByaXZhdGUgX2dyYWluTW92ZWQgPSBmYWxzZTtcblxuICBwdWJsaWMgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5fYnVpbGRGaWx0ZXJDb25maWcoKTtcblxuICAgIGlmICghdGhpcy5pc1RleHQpIHtcbiAgICAgIHRoaXMuX3JlYnVpbGRIZWFkZXJPbk5ld1N0YXRlKCk7XG4gICAgfVxuXG4gICAgLy8gTGlzdHMgZmV0Y2ggdGhyb3VnaCBGc0xpc3QgYW5kIGdyaWRzIHRocm91Z2ggZnMtZ3JpZCdzIHNvdXJjZSAoZWFjaFxuICAgIC8vIHJlYWRzIGl0cyBvd24gcm93cyk7IHRleHQgaGFzIG5vdGhpbmcgdG8gZmV0Y2gsIGFuZCBhIHZhbHVlIGlzIG5ldmVyXG4gICAgLy8gZHJhd24gKGl0IHJlYWRzIGluc2lkZSB0ZXh0KS5cbiAgICBpZiAoIVNFTEZfUkVBRElOR19UWVBFUy5pbmNsdWRlcyh0aGlzLmNvbXBvbmVudC50eXBlKSAmJiAhdGhpcy5pc1RleHQgJiYgaXNEcmF3bih0aGlzLmNvbXBvbmVudCkpIHtcbiAgICAgIC8vIE9uZSBsb2FkIHN0cmVhbSAodGlsZUxvYWRzKTogdGhlIGZpcnN0IGxvYWQgYXQgb25jZSwgdGhlbiBvbmUgcGVyXG4gICAgICAvLyBzZXR0bGVkIHN3ZWVwIG9mIGNoYW5nZXMsIGVhY2ggY2FuY2VsbGluZyB0aGUgb25lIGluIGZsaWdodCwgYW5kIGFuXG4gICAgICAvLyBhbnN3ZXIgc2VudCBiZWZvcmUgYSByZXNldCBpcyBkcm9wcGVkLlxuICAgICAgdGlsZUxvYWRzKHRoaXMuX3JlZnJlc2gkLCAoKSA9PiB0aGlzLl9sb2FkKCksICgpID0+IHRoaXMuX2ZpbHRlclN0YXRlLnN0YXRlVmVyc2lvbigpKVxuICAgICAgICAucGlwZShcbiAgICAgICAgICB0YXAoKHJlc3VsdCkgPT4gdGhpcy5fbG9hZGVkKHJlc3VsdCkpLFxuICAgICAgICAgIHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLl9kZXN0cm95UmVmKSxcbiAgICAgICAgKVxuICAgICAgICAuc3Vic2NyaWJlKCk7XG5cbiAgICAgIHRoaXMuX2ZpbHRlclN0YXRlLmNoYW5nZXNGb3IodGhpcy5jb21wb25lbnQpXG4gICAgICAgIC5waXBlKHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLl9kZXN0cm95UmVmKSlcbiAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB0aGlzLl9yZWZyZXNoJC5uZXh0KCkpO1xuXG4gICAgICAvLyBBIGdyb3VwLWJ5IGNoYW5nZSByZS1idWNrZXRzIGV2ZXJ5IHRpbWUtc2VyaWVzIGNoYXJ0OyBpdCBpc24ndCBzY29wZWRcbiAgICAgIC8vIHRvIGEgZmlsdGVyIGdyb3VwLCBzbyBpdCByaWRlcyBpdHMgb3duIHN0cmVhbS5cbiAgICAgIGlmICh0aGlzLl9pc1RpbWVTZXJpZXMpIHtcbiAgICAgICAgdGhpcy5fZmlsdGVyU3RhdGUuZnJlcXVlbmN5Q2hhbmdlcygpXG4gICAgICAgICAgLnBpcGUodGFrZVVudGlsRGVzdHJveWVkKHRoaXMuX2Rlc3Ryb3lSZWYpKVxuICAgICAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5fZ3JhaW5Nb3ZlZCA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLl9yZWZyZXNoJC5uZXh0KCk7XG4gICAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIC8vIEEgZHJpbGwgbW92ZXMgdGhpcyBjaGFydCBhbG9uZS5cbiAgICAgIHRoaXMuX2ZpbHRlclN0YXRlLmRyaWxsQ2hhbmdlcyh0aGlzLmNvbXBvbmVudC5pZClcbiAgICAgICAgLnBpcGUodGFrZVVudGlsRGVzdHJveWVkKHRoaXMuX2Rlc3Ryb3lSZWYpKVxuICAgICAgICAuc3Vic2NyaWJlKCgpID0+IHRoaXMuX3JlZnJlc2gkLm5leHQoKSk7XG4gICAgfVxuICB9XG5cbiAgLy8gVGhlIHJlcG9ydCByZWxvYWRzIChlLmcuIGFmdGVyIHRoZSBzZXR0aW5ncyBkaWFsb2cgYWRkcy9tb3ZlcyBhIGZpbHRlcilcbiAgLy8gaGFuZCB0aGlzIGluc3RhbmNlIGZyZXNoIGBjb21wb25lbnRgL2Bncm91cHNgIGlucHV0cyB3aXRob3V0IHJlLXJ1bm5pbmdcbiAgLy8gbmdPbkluaXQuIFJlYnVpbGQgdGhlIGhlYWRlciBjb25maWcgc28gdGhlIGlubGluZSBjb21wb25lbnQtZmlsdGVyIHN0cmlwXG4gIC8vIHJlZmxlY3RzIHRoZSBuZXcgZmlsdGVyczsgdGhlIHRlbXBsYXRlIHJlY3JlYXRlcyB0aGUgZnMtZmlsdGVyIHZpYVxuICAvLyBgZmlsdGVyS2V5YCBzbyBpdCBhY3R1YWxseSByZS1yZWFkcyB0aGlzIGNvbmZpZy5cbiAgcHVibGljIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICAvLyBDbGlja2luZyBhd2F5IChkZXNlbGVjdCkgb3IgbGVhdmluZyBlZGl0IG1vZGUgY2xvc2VzIGFuIG9wZW4gdGV4dCBlZGl0b3IsXG4gICAgLy8gd2hpY2ggaXMgd2hhdCBzYXZlcyBpdC5cbiAgICBpZiAoKGNoYW5nZXMuc2VsZWN0ZWQgJiYgIXRoaXMuc2VsZWN0ZWQpIHx8IChjaGFuZ2VzLmVkaXRNb2RlICYmICF0aGlzLmVkaXRNb2RlKSkge1xuICAgICAgdGhpcy50ZXh0RWRpdGluZy5zZXQoZmFsc2UpO1xuICAgIH1cblxuICAgIC8vIEEgbmV3IGNvbXBvbmVudCBvYmplY3QgY2FycmllcyBpdHMgb3duIHN0b3JlZCBodG1sLlxuICAgIGlmIChjaGFuZ2VzLmNvbXBvbmVudCAmJiAhY2hhbmdlcy5jb21wb25lbnQuZmlyc3RDaGFuZ2UpIHtcbiAgICAgIHRoaXMudGV4dEh0bWwuc2V0KG51bGwpO1xuICAgIH1cblxuICAgIGNvbnN0IGZpbHRlcnNDaGFuZ2VkID0gKGNoYW5nZXMuY29tcG9uZW50ICYmICFjaGFuZ2VzLmNvbXBvbmVudC5maXJzdENoYW5nZSlcbiAgICAgIHx8IChjaGFuZ2VzLmdyb3VwcyAmJiAhY2hhbmdlcy5ncm91cHMuZmlyc3RDaGFuZ2UpO1xuXG4gICAgaWYgKGZpbHRlcnNDaGFuZ2VkKSB7XG4gICAgICB0aGlzLl9idWlsZEZpbHRlckNvbmZpZygpO1xuICAgIH1cbiAgfVxuXG4gIC8vIGZzLWZpbHRlciByZWFkcyBpdHMgY29uZmlnIG9ubHkgb25jZSBhdCBpbml0LCBzbyB0aGUgaGVhZGVyIGlzIGtleWVkIG9uIHdoYXRcbiAgLy8gaXQgcmVuZGVycyB0aGF0IG5vIHNpZ25hbCBjYXJyaWVzOiB0aGUgc2V0IG9mIGNvbXBvbmVudC1sZXZlbCBmaWx0ZXIgZ3JvdXBzXG4gIC8vIEFORCB0aGUgc3RvcmVkIHRpdGxlLCB3aGljaCBsaXZlcyBpbiBmcy1maWx0ZXIncyBoZWFkaW5nIHRlbXBsYXRlLiBmcy1maWx0ZXJcbiAgLy8gaXMgT25QdXNoIGFuZCB0aGUgaGVhZGluZyBpcyByZW5kZXJlZCBpbnNpZGUgSVRTIHZpZXcsIHNvIG1hcmtpbmcgdGhpc1xuICAvLyBjb21wb25lbnQgZG9lcyBub3QgcmVwYWludCBhIG5ldyB0aXRsZSDigJQgcmVjcmVhdGluZyB0aGUgYmxvY2sgZG9lcywgb25jZSBhXG4gIC8vIHNldHRpbmdzIHNhdmUgaGFzIHJlYnVpbHQgdGhlIGNvbmZpZy4gV2hhdCBmaWxscyB0aGUgdGl0bGUncyB0b2tlbnMgaXNcbiAgLy8gYW5vdGhlciBtYXR0ZXI6IHNlZSBzaG93blRpdGxlLiBUaGUga2V5IGFsc28gY2FycmllcyB0aGUgc3RhdGUgdmVyc2lvblxuICAvLyB0aGUgaGVhZGVyIHdhcyBidWlsdCBmb3IsIHNvIGFuIGFwcGxpZWQgdmlldywgd2hpY2ggcmVwbGFjZXMgZXZlcnkgdmFsdWVcbiAgLy8gYXQgb25jZSwgcmVjcmVhdGVzIGl0IHdpdGggdGhlIG5ldyB2YWx1ZXMuIEFuZCBpdCBjYXJyaWVzIHRoZSB2YWx1ZXMgdGhlXG4gIC8vIGhlYWRlciB3YXMgYnVpbHQgd2l0aDogYSBncm91cCBzaG93biBoZXJlIGFuZCBpbiB0aGUgcmVwb3J0IGJhciAobGV2ZWxcbiAgLy8gJ2JvdGgnKSB0aGF0IHRoZSByZXBvcnQgYmFyIGNoYW5nZXMgaXMgYnVpbHQgYWdhaW4gaGVyZSwgc28gdGhlIGhlYWRlclxuICAvLyBuZXZlciBzaG93cyAnV2VzdCcgd2hpbGUgdGhlIGRhdGEgbGVhdmVzIFdlc3Qgb3V0LlxuICBwdWJsaWMgZ2V0IGZpbHRlcktleSgpOiBzdHJpbmcge1xuICAgIHJldHVybiBbXG4gICAgICB0aGlzLl9oZWFkZXJWZXJzaW9uKCksXG4gICAgICB0aGlzLmNvbXBvbmVudC50aXRsZSxcbiAgICAgIC4uLnRoaXMuY29tcG9uZW50RmlsdGVyR3JvdXBzLm1hcCgoZ3JvdXApID0+IGAke2dyb3VwLmlkfToke2dyb3VwLmxldmVsfWApLFxuICAgICAgdGhpcy5faGVhZGVyVmFsdWVzKCksXG4gICAgXS5qb2luKCd8Jyk7XG4gIH1cblxuICAvLyBUaGUgdGl0bGUgYXMgdGhlIHZpZXdlciByZWFkcyBpdDogaXRzIHBhZ2UsIHJlcG9ydCBhbmQgZmlsdGVyIGZpZWxkcyBmaWxsZWRcbiAgLy8gd2l0aCB0aGUgdG9rZW5zIG9mIHRoZSBsYXllciBpdCBpcyBkcmF3biBvbiAoJ1NpZ24tdXBzIOKAlCBTZXB0ZW1iZXIgMjAyNicpLlxuICAvLyBUaGUgaGVhZGVyIHJlYWRzIGl0LCBhbmQgdGhlIENTViBleHBvcnQgbmFtZXMgaXRzIGZpbGUgYWZ0ZXIgaXQuIFRoZVxuICAvLyB0b2tlbnMgYXJlIGEgc2lnbmFsLCByZWFkIGluc2lkZSBmcy1maWx0ZXIncyBoZWFkaW5nLCBzbyBhIGZpbHRlciBjaGFuZ2VcbiAgLy8gcmVwYWludHMgdGhlIHRpdGxlIGluIHBsYWNlIHJhdGhlciB0aGFuIHRocm91Z2ggZmlsdGVyS2V5OiBhIHJlY3JlYXRlZFxuICAvLyBoZWFkZXIgd291bGQgbG9zZSB3aGF0IHRoZSB2aWV3ZXIgaXMgZG9pbmcgaW4gaXRzIG93biBmaWx0ZXJzIChhIHBpY2tcbiAgLy8gbGFuZGluZywgYSBoYWxmLXR5cGVkIGtleXdvcmQsIGFuIG9wZW4gcGlja2VyKSwgYW5kIGVhY2ggZmlsdGVyIGluIGl0XG4gIC8vIHdvdWxkIHNob3cgdGhlIHZhbHVlIGl0IHdhcyBidWlsdCB3aXRoLlxuICBwdWJsaWMgZ2V0IHNob3duVGl0bGUoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gZmlsbFRpdGxlVG9rZW5zKHRoaXMuY29tcG9uZW50LnRpdGxlLCB0aGlzLnRva2VucygpKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgaXNUZXh0KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmNvbXBvbmVudC50eXBlID09PSAndGV4dCc7XG4gIH1cblxuICAvLyBPcGVuIHRoZSB0ZXh0IGVkaXRvciBpbiBwbGFjZS5cbiAgcHVibGljIGVkaXRUZXh0KCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5lZGl0TW9kZSB8fCAhdGhpcy5pc1RleHQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnNlbGVjdENvbXBvbmVudC5lbWl0KHRoaXMuY29tcG9uZW50LmlkKTtcbiAgICB0aGlzLnRleHRFZGl0aW5nLnNldCh0cnVlKTtcbiAgfVxuXG4gIC8vIFRha2UgYSBkZWxldGVkIHZhbHVlJ3MgY2hpcHMgb3V0IG9mIHRoZSB0ZXh0J3Mgb3BlbiBlZGl0b3IuXG4gIHB1YmxpYyByZW1vdmVWYWx1ZShrZXk6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuX3RleHQoKT8ucmVtb3ZlVmFsdWUoa2V5KTtcbiAgfVxuXG4gIC8vIFRoZSBlZGl0b3IgY2xvc2VkIHdpdGggY2hhbmdlZCBodG1sLiBLZXB0IGxvY2FsbHkgYXQgb25jZSBzbyB0aGUgYmxvY2tcbiAgLy8gcmUtcmVuZGVycyB3aGF0IHdhcyB0eXBlZCwgdGhlbiByZXBsYWNlZCBieSB3aGF0IHRoZSBzZXJ2ZXIgc3RvcmVkOiBpdFxuICAvLyByZWJ1aWxkcyB0aGUgaHRtbCBmcm9tIGl0cyBhbGxvd2xpc3QgYW5kIGRyb3BzIGFueSB2YWx1ZSB0b2tlbiBpdHMgcGFnZSBoYXNcbiAgLy8gbm8gdmFsdWUgZm9yLCBzbyB0aGUgYmxvY2sgbmV2ZXIgaG9sZHMgYSB0b2tlbiB0aGUgc2VydmVyIGRvZXNuJ3QuXG4gIHB1YmxpYyBvblRleHRTYXZlZChodG1sOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLl9zZXRUZXh0SHRtbChodG1sKTtcbiAgICB0aGlzLl9yZXBvcnREYXRhLnVwZGF0ZUNvbXBvbmVudCh0aGlzLnJlcG9ydElkLCB0aGlzLmNvbXBvbmVudC5pZCwgeyBodG1sIH0pXG4gICAgICAucGlwZShcbiAgICAgICAgbWFwKChyZXNwb25zZSkgPT4gKHR5cGVvZiByZXNwb25zZT8uY29uZmlnPy5odG1sID09PSAnc3RyaW5nJyA/IHJlc3BvbnNlLmNvbmZpZy5odG1sIGFzIHN0cmluZyA6IGh0bWwpKSxcbiAgICAgICAgdGFwKChzdG9yZWQpID0+IHtcbiAgICAgICAgICB0aGlzLl9zZXRUZXh0SHRtbChzdG9yZWQpO1xuICAgICAgICAgIHRoaXMudGV4dFNhdmVkLmVtaXQoc3RvcmVkKTtcbiAgICAgICAgfSksXG4gICAgICAgIHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLl9kZXN0cm95UmVmKSxcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUoKTtcbiAgfVxuXG4gIC8vIFRoZSBzZXJ2ZXIgZGVsZXRlcyB0aGUgdGV4dCBhbmQgdGhlbiBldmVyeSB2YWx1ZSBvbiBpdHMgcGFnZSB0aGF0IG5vIG90aGVyXG4gIC8vIHRleHQgc2hvd3MsIGFuZCBhbnN3ZXJzIHdpdGggdGhlaXIgaWRzLlxuICBwdWJsaWMgZGVsZXRlVGV4dCgpOiB2b2lkIHtcbiAgICBjb25zdCB2YWx1ZXNOb3RlID0gdmFsdWVLZXlzKHRoaXMuY29tcG9uZW50LmNvbmZpZz8uaHRtbCkubGVuZ3RoXG4gICAgICA/ICcgVmFsdWVzIG5vIG90aGVyIHRleHQgb24gdGhpcyBwYWdlIHVzZXMgYXJlIGRlbGV0ZWQgd2l0aCBpdC4nXG4gICAgICA6ICcnO1xuXG4gICAgdGhpcy5fcHJvbXB0LmNvbmZpcm0oe1xuICAgICAgdGl0bGU6ICdDb25maXJtJyxcbiAgICAgIHRlbXBsYXRlOiBgQXJlIHlvdSBzdXJlIHlvdSB3b3VsZCBsaWtlIHRvIGRlbGV0ZSB0aGlzIHRleHQ/JHt2YWx1ZXNOb3RlfWAsXG4gICAgfSlcbiAgICAgIC5waXBlKFxuICAgICAgICBzd2l0Y2hNYXAoKCkgPT4gdGhpcy5fcmVwb3J0RGF0YS5kZWxldGVDb21wb25lbnQodGhpcy5yZXBvcnRJZCwgdGhpcy5jb21wb25lbnQuaWQpKSxcbiAgICAgICAgdGFwKChyZXNwb25zZTogeyByZW1vdmVkVmFsdWVzPzogbnVtYmVyW10gfSkgPT4ge1xuICAgICAgICAgIGlmIChyZXNwb25zZT8ucmVtb3ZlZFZhbHVlcz8ubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aGlzLnZhbHVlc1JlbW92ZWQuZW1pdChyZXNwb25zZS5yZW1vdmVkVmFsdWVzKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5yZW1vdmVkLmVtaXQodGhpcy5jb21wb25lbnQuaWQpO1xuICAgICAgICB9KSxcbiAgICAgICAgdGFrZVVudGlsRGVzdHJveWVkKHRoaXMuX2Rlc3Ryb3lSZWYpLFxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgpO1xuICB9XG5cbiAgcHVibGljIGdldCB0cnVuY2F0ZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICEhdGhpcy5kYXRhKCk/LnRydW5jYXRlZDtcbiAgfVxuXG4gIC8vIENvbnRlbnQgcGFkZGluZyAodGhlIGNhbnZhcyB6b29tIHNjYWxlcyB0aGUgcGFnZSBhcyBhIHdob2xlKS4gRWFjaCBlZGdlXG4gIC8vIGRlZmF1bHRzIHRvIDEvOFwiLlxuICBwdWJsaWMgZ2V0IGJvZHlQYWRkaW5nKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGNvbXBvbmVudFBhZGRpbmdDc3ModGhpcy5jb21wb25lbnQpO1xuICB9XG5cbiAgLy8gVGhlIGNvbXBvbmVudC1sZXZlbCBmaWx0ZXIgZ3JvdXBzIHRoYXQgc2hvdWxkIHJlbmRlciBhcyBhbiBpbmxpbmUgY29udHJvbFxuICAvLyBzdHJpcCBvbiBUSElTIGNvbXBvbmVudDogYSBncm91cCBpcyBpbmNsdWRlZCB3aGVuIGl0J3MgbGV2ZWw9Y29tcG9uZW50IGFuZFxuICAvLyBoYXMgYW4gZW5hYmxlZCwgc2Vzc2lvbi1vbiBmaWx0ZXIgaGVyZS4gUmVwb3J0LWxldmVsIGdyb3VwcyBsaXZlIGluIHRoZVxuICAvLyB0b3AgYmFyIGluc3RlYWQuIExpc3RzIHVzZSB0aGlzIHN0cmlwIGxpa2UgY2hhcnRzIGRvOiBhIHZhbHVlIHNldCBoZXJlIGlzXG4gIC8vIHRoZSBncm91cCdzIHZhbHVlLCBzbyBpdCByZWFjaGVzIGV2ZXJ5IGNvbXBvbmVudCBpbiB0aGUgZ3JvdXAuXG4gIHB1YmxpYyBnZXQgY29tcG9uZW50RmlsdGVyR3JvdXBzKCk6IFJlcG9ydEZpbHRlckdyb3VwW10ge1xuICAgIGlmICghdGhpcy5ncm91cHMpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG5cbiAgICBjb25zdCBncm91cElkcyA9IG5ldyBTZXQ8bnVtYmVyPigpO1xuICAgIGZvciAoY29uc3QgZmlsdGVyIG9mIHRoaXMuY29tcG9uZW50LmZpbHRlcnMgPz8gW10pIHtcbiAgICAgIGlmICghZmlsdGVyLmVuYWJsZWQgfHwgdGhpcy5fZmlsdGVyU3RhdGUuaXNGaWx0ZXJEaXNhYmxlZChmaWx0ZXIuaWQpKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY29uc3QgZ3JvdXAgPSB0aGlzLmdyb3Vwcy5nZXQoZmlsdGVyLmZpbHRlckdyb3VwSWQpO1xuICAgICAgaWYgKGdyb3VwICYmIChncm91cC5sZXZlbCA9PT0gJ2NvbXBvbmVudCcgfHwgZ3JvdXAubGV2ZWwgPT09ICdib3RoJykpIHtcbiAgICAgICAgZ3JvdXBJZHMuYWRkKGdyb3VwLmlkKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gWy4uLmdyb3VwSWRzXS5tYXAoKGlkKSA9PiB0aGlzLmdyb3Vwcy5nZXQoaWQpKS5maWx0ZXIoQm9vbGVhbik7XG4gIH1cblxuICBwdWJsaWMgc2V0dGluZ3MoKTogdm9pZCB7XG4gICAgdGhpcy5vcGVuU2V0dGluZ3MuZW1pdCh0aGlzLmNvbXBvbmVudCk7XG4gIH1cblxuICAvLyBXaGV0aGVyIHRoZSBtZW51IG9mZmVycyBDb2x1bW5zOiBhIHBsYWluIGxpc3Qgd2l0aCBtb3JlIHRoYW4gb25lXG4gIC8vIGNvbmZpZ3VyZWQgY29sdW1uLiBBIGNyb3NzLXRhYidzIGNvbHVtbnMgY29tZSBhbmQgZ28gd2l0aCB0aGUgZGF0YS5cbiAgcHVibGljIGdldCBoaWRlc0NvbHVtbnMoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuY29tcG9uZW50LnR5cGUgPT09ICdsaXN0JyAmJiBsaXN0SGlkZWFibGVDb2x1bW5zKHRoaXMuY29tcG9uZW50LmNvbmZpZykubGVuZ3RoID4gMTtcbiAgfVxuXG4gIC8vIFdoaWNoIG9mIGEgcGxhaW4gbGlzdCdzIGNvbHVtbnMgc2hvdy4gVGhlIGNob2ljZSBpcyB0aGUgdmlld2VyJ3MgKGtlcHQgaW5cbiAgLy8gdGhlIHJlcG9ydCdzIHN0YXRlLCBuZXZlciBzYXZlZCB0byB0aGUgcmVwb3J0KSwgYW5kIHRoZVxuICAvLyBsaXN0IGhpZGVzIHRoZSBjb2x1bW5zIGluIHBsYWNlLCB3aXRoIG5vIHJlZmV0Y2guXG4gIHB1YmxpYyBjaG9vc2VDb2x1bW5zKCk6IHZvaWQge1xuICAgIGNvbnN0IGNvbHVtbnMgPSAodGhpcy5jb21wb25lbnQuY29uZmlnPy5jb2x1bW5zID8/IFtdKVxuICAgICAgLm1hcCgoY29sdW1uKSA9PiAoeyBjb2x1bW46IGNvbHVtbi5jb2x1bW4sIGxhYmVsOiBjb2x1bW4ubGFiZWwgfHwgY29sdW1uLmNvbHVtbiB9KSk7XG5cbiAgICB0aGlzLl9kaWFsb2cub3BlbjxMaXN0Q29sdW1uc0NvbXBvbmVudCwgTGlzdENvbHVtbnNEaWFsb2dEYXRhLCBzdHJpbmdbXT4oTGlzdENvbHVtbnNDb21wb25lbnQsIHtcbiAgICAgIGRhdGE6IHsgY29sdW1ucywgaGlkZGVuOiBbLi4udGhpcy5fZmlsdGVyU3RhdGUuaGlkZGVuQ29sdW1ucyh0aGlzLmNvbXBvbmVudC5pZCldIH0sXG4gICAgICB3aWR0aDogJzQwMHB4JyxcbiAgICAgIG1heFdpZHRoOiAnOTV2dycsXG4gICAgICBhdXRvRm9jdXM6IGZhbHNlLFxuICAgIH0pXG4gICAgICAuYWZ0ZXJDbG9zZWQoKVxuICAgICAgLnBpcGUodGFrZVVudGlsRGVzdHJveWVkKHRoaXMuX2Rlc3Ryb3lSZWYpKVxuICAgICAgLnN1YnNjcmliZSgoaGlkZGVuKSA9PiB7XG4gICAgICAgIC8vIENhbmNlbCBjbG9zZXMgd2l0aCBub3RoaW5nLCB3aGljaCBjaGFuZ2VzIG5vdGhpbmcuXG4gICAgICAgIGlmIChoaWRkZW4pIHtcbiAgICAgICAgICB0aGlzLl9maWx0ZXJTdGF0ZS5zZXRIaWRkZW5Db2x1bW5zKHRoaXMuY29tcG9uZW50LmlkLCBoaWRkZW4pO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgfVxuXG4gIC8vIFByZXNlbnRhdGlvbiBzZXR0aW5ncyBzYXZlZCBmcm9tIHRoZSBzZXR0aW5ncyBkaWFsb2cuIFRpdGxlIGFuZCBwYWRkaW5nIGFyZVxuICAvLyBub3QgcGFydCBvZiB0aGUgcXVlcnksIHNvIHRoZSBkYXRhIGFscmVhZHkgZmV0Y2hlZCBzdGlsbCBzdGFuZHMg4oCUIHRoaXMgb25seVxuICAvLyByZXBhaW50cy4gVGhlIGhlYWRlciBjb25maWcgaXMgcmVidWlsdCBiZWNhdXNlIGBmaWx0ZXJLZXlgIGNoYW5nZXMgd2l0aCB0aGVcbiAgLy8gdGl0bGUgYW5kIHJlY3JlYXRlcyB0aGUgZnMtZmlsdGVyIGJsb2NrIGFyb3VuZCBpdDsgc2V0dGluZyB0aGUgY29uZmlnIHNpZ25hbFxuICAvLyBpcyBhbHNvIHdoYXQgcmVwYWludHMgdGhlIG5ldyBwYWRkaW5nLiBUaGUgY2hhcnQgZm9sbG93cyBpdHMgYm94IG9uIGl0cyBvd25cbiAgLy8gKG5neC1lY2hhcnRzIG9ic2VydmVzIHRoZSBob3N0KSwgc28gbm90aGluZyBpcyB0b2xkIHRvIHJlc2l6ZS4gQSBLUEkncyBjYXJkXG4gIC8vIGtleXMgYXJlIGRpZmZlcmVudDogc2V0dGluZ3Mua3BpIGNhcnJpZXMgdGhlIGtleXMgdGhlIHNlcnZlciBzYXZlZCAobmV2ZXJcbiAgLy8gdGhlIG9uZXMgdGhlIGRpYWxvZyBzZW50KSwgYW5kIHRoZSBzZXJ2ZXIgc2VuZHMgdGhlIHRhcmdldCdzIHByb2dyZXNzIGFuZFxuICAvLyB0aGUgc3BhcmtsaW5lJ3MgcG9pbnRzIHdpdGggdGhlIGRhdGEsIHNvIGEgY2hhbmdlIHRvIHRoZW0gcmVsb2FkcyBpdC5cbiAgcHVibGljIGFwcGx5U2V0dGluZ3Moc2V0dGluZ3M6IENvbXBvbmVudFNldHRpbmdzKTogdm9pZCB7XG4gICAgY29uc3QgY2FyZENoYW5nZWQgPSAhIXNldHRpbmdzLmtwaVxuICAgICAgJiYgIXNhbWVLcGlDYXJkU2V0dGluZ3Moc2V0dGluZ3Mua3BpLCBrcGlDYXJkU2V0dGluZ3ModGhpcy5jb21wb25lbnQuY29uZmlnIGFzIEtwaUNvbmZpZykpO1xuXG4gICAgdGhpcy5jb21wb25lbnQudGl0bGUgPSBzZXR0aW5ncy50aXRsZTtcbiAgICB0aGlzLmNvbXBvbmVudC5jb25maWcgPSB7IC4uLnRoaXMuY29tcG9uZW50LmNvbmZpZywgcGFkZGluZzogc2V0dGluZ3MucGFkZGluZywgLi4uKHNldHRpbmdzLmtwaSA/PyB7fSkgfTtcblxuICAgIHRoaXMuX2J1aWxkRmlsdGVyQ29uZmlnKCk7XG5cbiAgICBpZiAoY2FyZENoYW5nZWQpIHtcbiAgICAgIHRoaXMuX3JlZnJlc2gkLm5leHQoKTtcbiAgICB9XG4gIH1cblxuICAvLyBUaGUgQ1NWIGlzIHdoYXQgdGhlIHNjcmVlbiBzaG93cywgc28gaXQgY2FycmllcyB0aGUgdGlsZSdzIGludGVyYWN0aW9uXG4gIC8vIHN0YXRlICh0aWxlRGF0YVN0YXRlKTogdGhlIGdyb3VwLWJ5IGdyYWluIGZvciBhIHRpbWUtc2VyaWVzIGNoYXJ0LCBhXG4gIC8vIGNoYXJ0J3MgZHJpbGwgcGF0aCwgdGhlIHZpZXdlcidzIGhlYWRlciBzb3J0LCBzZWFyY2ggYW5kIGhpZGRlbiBjb2x1bW5zXG4gIC8vIGZvciBhIGxpc3QgKGEgc2VhcmNoZWQgbGlzdCBleHBvcnRzIG9ubHkgdGhlIHJvd3MgdGhlIHNlYXJjaCBsZWF2ZXMsIGFuZFxuICAvLyB0aGUgaGlkZGVuIGNvbHVtbnMgc3RheSBvdXQgb2YgdGhlIGZpbGUpLCBhbmQgdGhlIGdyb3VwcyB0aGF0IG1hdGNoXG4gIC8vICdhbnknOyBhbmQgaXRzIHRpdGxlIGFzIHRoZSBoZWFkZXIgcmVhZHMgaXQgKHNob3duVGl0bGUpLCB3aGljaCB0aGVcbiAgLy8gc2VydmVyIG5hbWVzIHRoZSBmaWxlIGFmdGVyLiBBIG5vdGUgdGhlIHNlcnZlciByZXR1cm5zICh0aGUgZmlsZSB3YXNcbiAgLy8gY3V0KSBpcyBzaG93biBiZWZvcmUgdGhlIGRvd25sb2FkIHN0YXJ0cywgc28gYSBzaG9ydCBmaWxlIG5ldmVyIHBhc3Nlc1xuICAvLyBmb3IgdGhlIHdob2xlIHJlc3VsdC5cbiAgcHVibGljIGV4cG9ydENzdigpOiB2b2lkIHtcbiAgICBjb25zdCBmaWx0ZXJzID0gdGhpcy5fZmlsdGVyU3RhdGUucmVzb2x2ZUZvckNvbXBvbmVudCh0aGlzLmNvbXBvbmVudCk7XG4gICAgY29uc3Qgc3RhdGUgPSB0aGlzLl9maWx0ZXJTdGF0ZS50aWxlU3RhdGUodGhpcy5jb21wb25lbnQpO1xuICAgIGNvbnN0IHRpdGxlID0gdGhpcy5zaG93blRpdGxlO1xuXG4gICAgdGhpcy5fcHJvY2Vzcy5kb3dubG9hZChcbiAgICAgIGBFeHBvcnRpbmcgJHt0aXRsZSB8fCAnY29tcG9uZW50J31gLFxuICAgICAgdGhpcy5fcmVwb3J0RGF0YS5leHBvcnRDb21wb25lbnQodGhpcy5yZXBvcnRJZCwgdGhpcy5jb21wb25lbnQuaWQsIGZpbHRlcnMsIHN0YXRlLCB0aXRsZSlcbiAgICAgICAgLnBpcGUoXG4gICAgICAgICAgdGFwKCh7IG5vdGVzIH0pID0+IG5vdGVzPy5sZW5ndGggJiYgdGhpcy5fbWVzc2FnZS53YXJuaW5nKG5vdGVzLmpvaW4oJyAnKSkpLFxuICAgICAgICAgIG1hcCgoeyB1cmwgfSkgPT4gdXJsKSxcbiAgICAgICAgKSxcbiAgICApO1xuICB9XG5cbiAgLy8gVGhlIG9uZSBjbGljayBoYW5kbGVyIChCMTAuMik6IGV2ZXJ5IGNsaWNrIG9uIGEgbWFyayBvZiB0aGlzIHRpbGUsIGFcbiAgLy8gY2hhcnQncyBvciBhIEtQSSdzIHZhbHVlLCBjb21lcyBoZXJlLCBzbyBpdHMgYWN0aW9ucyBuZXZlciBjb21wZXRlLiBUaGVcbiAgLy8gcnVsZSAoZGVjaWRlTWFya0NsaWNrKSBkb2VzIG5vdGhpbmcgd2l0aG91dCBhbiBhY3Rpb24sIGxldHMgYSBmaXJzdCB0YXBcbiAgLy8gc2hvdyB0aGUgdG9vbHRpcCwgcnVucyBhIGxvbmUgYWN0aW9uIGF0IG9uY2UsIGFuZCBvcGVucyB0aGUgbWFyayBtZW51IGF0XG4gIC8vIHRoZSBjbGljayBmb3IgdHdvIG9yIG1vcmUuIE5vdCB3aGlsZSB0aGUgbGF5b3V0IGlzIGVkaXRlZC5cbiAgcHVibGljIG9uTWFya0NsaWNrKGNsaWNrOiBSZXBvcnRNYXJrQ2xpY2spOiB2b2lkIHtcbiAgICBpZiAodGhpcy5lZGl0TW9kZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGFjdGlvbnMgPSBtYXJrQWN0aW9ucyhjbGljaywgeyBkYXRhOiB0aGlzLmRhdGEoKSwgZmVhdHVyZXM6IHRoaXMuX29mZmVyZWRGZWF0dXJlcygpIH0pO1xuICAgIGNvbnN0IGRlY2lzaW9uID0gZGVjaWRlTWFya0NsaWNrKGNsaWNrLCBhY3Rpb25zLCB0aGlzLl90b3VjaGVkTWFyayk7XG4gICAgdGhpcy5fdG91Y2hlZE1hcmsgPSBkZWNpc2lvbi50b3VjaGVkO1xuXG4gICAgaWYgKGRlY2lzaW9uLm91dGNvbWUgPT09ICdydW4nKSB7XG4gICAgICB0aGlzLl9ydW5NYXJrQWN0aW9uKGRlY2lzaW9uLmFjdGlvbnNbMF0sIGNsaWNrKTtcbiAgICB9IGVsc2UgaWYgKGRlY2lzaW9uLm91dGNvbWUgPT09ICdtZW51Jykge1xuICAgICAgdGhpcy5fb3Blbk1hcmtNZW51KGRlY2lzaW9uLmFjdGlvbnMsIGNsaWNrKTtcbiAgICB9XG4gIH1cblxuICAvLyBBIGNsaWNrIG9yIGEgdGFwIG9uIHRoZSBjaGFydCB0aGF0IGhpdCBubyBtYXJrOiBhIHRhcCBoZWxkIGZvciBpdHNcbiAgLy8gc2Vjb25kIHRhcCBpcyBsZXQgZ28sIHNvIHRhcHBpbmcgdGhhdCBtYXJrIGFnYWluIHNob3dzIGl0cyB0b29sdGlwIGZpcnN0LlxuICBwdWJsaWMgb25NYXJrTWlzcygpOiB2b2lkIHtcbiAgICB0aGlzLl90b3VjaGVkTWFyayA9IG51bGw7XG4gIH1cblxuICAvLyBBIHJvdyBvZiB0aGUgbWFyayBtZW51OiBydW5zIGl0cyBhY3Rpb24gZm9yIHRoZSBjbGljayB0aGUgbWVudSBvcGVuZWQgb24uXG4gIHB1YmxpYyBydW5NYXJrQWN0aW9uKGFjdGlvbjogUmVwb3J0TWFya0FjdGlvbik6IHZvaWQge1xuICAgIGNvbnN0IGNsaWNrID0gdGhpcy5fbWVudUNsaWNrO1xuICAgIHRoaXMuX21lbnVDbGljayA9IG51bGw7XG5cbiAgICBpZiAoY2xpY2spIHtcbiAgICAgIHRoaXMuX3J1bk1hcmtBY3Rpb24oYWN0aW9uLCBjbGljayk7XG4gICAgfVxuICB9XG5cbiAgLy8gQmFjayB1cCB0aGUgZHJpbGwgcGF0aCB0byBpdHMgZmlyc3QgYGRlcHRoYCBzdGVwczogMCBpcyB0aGUgY2hhcnQncyB0b3BcbiAgLy8gKHRoZSB0aXRsZSdzIGNydW1iIGFuZCBCYWNrIHRvIHRvcCksIGFuZCBhIGNydW1iIGdvZXMgYmFjayB0byB0aGUgcGVyaW9kXG4gIC8vIGl0IG5hbWVzLiBUaGUgY2hhcnQgcmVhZHMgYWdhaW4gKGRyaWxsQ2hhbmdlcykuXG4gIHB1YmxpYyBkcmlsbFRvKGRlcHRoOiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5lZGl0TW9kZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuX2ZpbHRlclN0YXRlLnNldERyaWxsKHRoaXMuY29tcG9uZW50LmlkLCB0aGlzLl9maWx0ZXJTdGF0ZS5kcmlsbCh0aGlzLmNvbXBvbmVudC5pZCkuc2xpY2UoMCwgZGVwdGgpKTtcbiAgfVxuXG4gIC8vIE9uZSBsZXZlbCB1cDogdGhlIHBlcmlvZCB0aGUgY2hhcnQgaXMgZHJpbGxlZCBpbnRvIGlzIGxlZnQuXG4gIHB1YmxpYyBkcmlsbFVwKCk6IHZvaWQge1xuICAgIHRoaXMuZHJpbGxUbyhNYXRoLm1heCgwLCB0aGlzLl9maWx0ZXJTdGF0ZS5kcmlsbCh0aGlzLmNvbXBvbmVudC5pZCkubGVuZ3RoIC0gMSkpO1xuICB9XG5cbiAgLy8gQW55IGludGVyYWN0aW9uIGluc2lkZSBhIGNvbXBvbmVudCBtdXN0IG5ldmVyIHN0YXJ0IGEgY2FudmFzIHBhbiAodGhlXG4gIC8vIHpvb20tcGFuIGhvc3QgbGlzdGVucyBmb3IgbW91c2Vkb3duL3RvdWNoc3RhcnQgYXQgdGhlIGNvbnRhaW5lciBsZXZlbCkuXG4gIHB1YmxpYyBzdG9wQ2FudmFzUGFuKGV2ZW50OiBFdmVudCk6IHZvaWQge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICB9XG5cbiAgcHVibGljIG9uQ29tcG9uZW50UG9pbnRlckRvd24oZXZlbnQ6IFBvaW50ZXJFdmVudCk6IHZvaWQge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGlmICh0aGlzLmVkaXRNb2RlICYmICF0aGlzLnNlbGVjdGVkKSB7XG4gICAgICB0aGlzLnNlbGVjdENvbXBvbmVudC5lbWl0KHRoaXMuY29tcG9uZW50LmlkKTtcbiAgICB9XG4gIH1cblxuICAvLyAtLS0tLSBlZGl0LW1vZGUgZ2VzdHVyZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgcHVibGljIG9uRHJhZ1N0YXJ0KGV2ZW50OiBQb2ludGVyRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuZWRpdE1vZGUgfHwgdGhpcy50ZXh0RWRpdGluZygpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gQSBzZWNvbmQgcHJlc3Mgb24gYSB0ZXh0IGJsb2NrIG9wZW5zIGl0cyBlZGl0b3IgaW5zdGVhZCBvZiBkcmFnZ2luZy5cbiAgICBpZiAodGhpcy5pc1RleHQpIHtcbiAgICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gICAgICBjb25zdCBpc0RvdWJsZVByZXNzID0gbm93IC0gdGhpcy5fbGFzdFByZXNzIDwgRE9VQkxFX1BSRVNTX01TO1xuICAgICAgdGhpcy5fbGFzdFByZXNzID0gbm93O1xuXG4gICAgICBpZiAoaXNEb3VibGVQcmVzcykge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgdGhpcy5lZGl0VGV4dCgpO1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLnNlbGVjdENvbXBvbmVudC5lbWl0KHRoaXMuY29tcG9uZW50LmlkKTtcblxuICAgIHRoaXMuX3RyYWNrKGV2ZW50LCAoZGVsdGFYLCBkZWx0YVkpID0+IHtcbiAgICAgIGxldCB4ID0gTWF0aC5tYXgoMCwgdGhpcy5fb3JpZ2luLnggKyB0aGlzLl9pbmNoZXMoZGVsdGFYKSk7XG4gICAgICBsZXQgeSA9IE1hdGgubWF4KDAsIHRoaXMuX29yaWdpbi55ICsgdGhpcy5faW5jaGVzKGRlbHRhWSkpO1xuXG4gICAgICBpZiAodGhpcy5zbmFwcGVyKSB7XG4gICAgICAgICh7IHgsIHkgfSA9IHRoaXMuc25hcHBlci5zbmFwTW92ZSh0aGlzLmNvbXBvbmVudCwgeCwgeSkpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmNvbXBvbmVudC54ID0geDtcbiAgICAgIHRoaXMuY29tcG9uZW50LnkgPSB5O1xuICAgICAgdGhpcy5fYXBwbHlHZW9tZXRyeSgpO1xuICAgIH0sICgpID0+IHRoaXMuX2VtaXRHZW9tZXRyeSgpKTtcbiAgfVxuXG4gIHB1YmxpYyBvblJlc2l6ZVN0YXJ0KGV2ZW50OiBQb2ludGVyRXZlbnQsIGhhbmRsZTogSGFuZGxlKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmVkaXRNb2RlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5zZWxlY3RDb21wb25lbnQuZW1pdCh0aGlzLmNvbXBvbmVudC5pZCk7XG5cbiAgICB0aGlzLl90cmFjayhldmVudCwgKGRlbHRhWCwgZGVsdGFZKSA9PiB7XG4gICAgICBjb25zdCBkeCA9IHRoaXMuX2luY2hlcyhkZWx0YVgpO1xuICAgICAgY29uc3QgZHkgPSB0aGlzLl9pbmNoZXMoZGVsdGFZKTtcbiAgICAgIGxldCB7IHgsIHksIHcsIGggfSA9IHRoaXMuX29yaWdpbjtcblxuICAgICAgaWYgKGhhbmRsZS5pbmNsdWRlcygnZScpKSB7XG4gICAgICAgIHcgPSBNYXRoLm1heChNSU5fVywgdGhpcy5fb3JpZ2luLncgKyBkeCk7XG4gICAgICB9XG4gICAgICBpZiAoaGFuZGxlLmluY2x1ZGVzKCdzJykpIHtcbiAgICAgICAgaCA9IE1hdGgubWF4KE1JTl9ILCB0aGlzLl9vcmlnaW4uaCArIGR5KTtcbiAgICAgIH1cbiAgICAgIGlmIChoYW5kbGUuaW5jbHVkZXMoJ3cnKSkge1xuICAgICAgICBjb25zdCBjbGFtcGVkID0gTWF0aC5taW4oZHgsIHRoaXMuX29yaWdpbi53IC0gTUlOX1cpO1xuICAgICAgICB4ID0gdGhpcy5fb3JpZ2luLnggKyBjbGFtcGVkO1xuICAgICAgICB3ID0gdGhpcy5fb3JpZ2luLncgLSBjbGFtcGVkO1xuICAgICAgfVxuICAgICAgaWYgKGhhbmRsZS5pbmNsdWRlcygnbicpKSB7XG4gICAgICAgIGNvbnN0IGNsYW1wZWQgPSBNYXRoLm1pbihkeSwgdGhpcy5fb3JpZ2luLmggLSBNSU5fSCk7XG4gICAgICAgIHkgPSB0aGlzLl9vcmlnaW4ueSArIGNsYW1wZWQ7XG4gICAgICAgIGggPSB0aGlzLl9vcmlnaW4uaCAtIGNsYW1wZWQ7XG4gICAgICB9XG5cbiAgICAgIGxldCBnZW9tZXRyeSA9IHsgeCwgeSwgdywgaCB9O1xuICAgICAgaWYgKHRoaXMuc25hcHBlcikge1xuICAgICAgICBnZW9tZXRyeSA9IHRoaXMuc25hcHBlci5zbmFwUmVzaXplKHRoaXMuY29tcG9uZW50LCBnZW9tZXRyeSwgaGFuZGxlKTtcbiAgICAgIH1cblxuICAgICAgT2JqZWN0LmFzc2lnbih0aGlzLmNvbXBvbmVudCwgZ2VvbWV0cnkpO1xuICAgICAgdGhpcy5fYXBwbHlHZW9tZXRyeSgpO1xuICAgICAgdGhpcy5jaGFydENvbXBvbmVudD8ucmVzaXplKCk7XG4gICAgfSwgKCkgPT4gdGhpcy5fZW1pdEdlb21ldHJ5KCkpO1xuICB9XG5cbiAgLy8gKFJlKWJ1aWxkIHRoZSBoZWFkZXIgZnMtZmlsdGVyIGNvbmZpZzogaGVhZGluZyB0ZW1wbGF0ZSByZW5kZXJzIHRoZSB0aXRsZVxuICAvLyBhbmQgaXRlbXMgYXJlIHRoaXMgY29tcG9uZW50J3MgY29tcG9uZW50LWxldmVsIGZpbHRlciBncm91cHMuIFRoZSBhY3Rpb25zXG4gIC8vIG1lbnUgKFNldHRpbmdzIC8gRXhwb3J0IENTVikgaXMgTk9UIGhlcmUg4oCUIGl0J3MgYSBzdGFuZGFsb25lIGtlYmFiIGZsb2F0ZWRcbiAgLy8gdG9wLXJpZ2h0IGluIHRoZSB0ZW1wbGF0ZSwgc28gaXRzIGJ1dHRvbiBoZWlnaHQgbm8gbG9uZ2VyIGRyaXZlcyB0aGUgaGVhZGVyXG4gIC8vIHJvdydzIGhlaWdodCAod2hpY2ggd291bGQgb3RoZXJ3aXNlIGluZmxhdGUgdGhlIGhlYWRpbmcgYnkgfjQwcHgpLlxuICAvL1xuICAvLyBBIGxpc3QgYWxzbyBnZXRzIGEgc2VhcmNoIGJveCBvdmVyIGl0cyB0ZXh0IGNvbHVtbnMsIHVubGVzcyBpdHMgaGVhZGVyXG4gIC8vIHNob3dzIGEga2V5d29yZCBncm91cCAoUmVwb3J0RmlsdGVyU3RhdGVTZXJ2aWNlLmxpc3RTZWFyY2hhYmxlLCB3aGljaCBhbHNvXG4gIC8vIGRyb3BzIGEgc2VhcmNoIGtlcHQgZnJvbSBiZWZvcmUgc3VjaCBhIGdyb3VwIGFwcGVhcmVkKS5cbiAgLy9cbiAgLy8gYHJlcG9ydGVkYCBpcyB3aGF0IHRoaXMgaGVhZGVyIGxhc3QgcmVwb3J0ZWQgZm9yIGVhY2ggb2YgaXRzIGdyb3VwcyxcbiAgLy8gc3RhcnRpbmcgZnJvbSB0aGUgdmFsdWVzIGl0IGlzIGJ1aWx0IHdpdGguIEEgY2hhbmdlIHNldHMgb25seSB0aGUgZ3JvdXBzXG4gIC8vIHdob3NlIGhlYWRlciB2YWx1ZSBtb3ZlZCAobW92ZWRHcm91cFZhbHVlcyk6IGZzLWZpbHRlciByZXBvcnRzIGV2ZXJ5IGl0ZW1cbiAgLy8gb24gYW55IGNoYW5nZSwgYW5kIGEgZ3JvdXAgc2hvd24gaW4gdGhlIHJlcG9ydCBiYXIgdG9vIG1heSBoYXZlIGNoYW5nZWRcbiAgLy8gdGhlcmUgc2luY2UsIHdpdGhvdXQgdGhpcyBoZWFkZXIgYmVpbmcgcmVwYWludGVkLlxuICBwcml2YXRlIF9zZXRUZXh0SHRtbChodG1sOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmNvbXBvbmVudC5jb25maWcgPSB7IC4uLnRoaXMuY29tcG9uZW50LmNvbmZpZywgaHRtbCB9O1xuICAgIHRoaXMudGV4dEh0bWwuc2V0KGh0bWwpO1xuICB9XG5cbiAgcHJpdmF0ZSBfYnVpbGRGaWx0ZXJDb25maWcoKTogdm9pZCB7XG4gICAgY29uc3QgZ3JvdXBzID0gdGhpcy5jb21wb25lbnRGaWx0ZXJHcm91cHM7XG4gICAgY29uc3QgbGlzdFNlYXJjaCA9IHRoaXMuX2ZpbHRlclN0YXRlLmxpc3RTZWFyY2hhYmxlKHRoaXMuY29tcG9uZW50KTtcbiAgICBjb25zdCByZXBvcnRlZCA9IG5ldyBNYXAoZ3JvdXBzLm1hcCgoZ3JvdXApID0+IFtncm91cC5pZCwgdGhpcy5fZmlsdGVyU3RhdGUudmFsdWUoZ3JvdXAuaWQpID8/IG51bGxdKSk7XG4gICAgY29uc3QgZmVhdHVyZXMgPSB0aGlzLl9maWx0ZXJTdGF0ZS52aWV3ZXJGZWF0dXJlcygpO1xuICAgIGNvbnN0IHJlcG9ydCA9IHRoaXMuX2ZpbHRlclN0YXRlLnJlcG9ydCgpO1xuXG4gICAgdGhpcy5fc2hvd24gPSByZXBvcnRlZDtcbiAgICB0aGlzLl9oZWFkZXJWYWx1ZXMuc2V0KFsuLi5yZXBvcnRlZC52YWx1ZXMoKV0ubWFwKGdyb3VwVmFsdWVTaWduYXR1cmUpLmpvaW4oJ3wnKSk7XG4gICAgdGhpcy5faGVhZGVyVmVyc2lvbi5zZXQodGhpcy5fZmlsdGVyU3RhdGUuc3RhdGVWZXJzaW9uKCkpO1xuICAgIHRoaXMuZmlsdGVyQ29uZmlnLnNldCh7XG4gICAgICAvLyBmcy1maWx0ZXIgbmV2ZXIgdG91Y2hlcyB0aGUgVVJMIG9yIHBlcnNpc3RzIGZpbHRlciBzdGF0ZTogYSByZXBvcnRcbiAgICAgIC8vIGtlZXBzIG5vIHN0YXRlIGluIHRoZSBVUkwuIFRoZSB2YWx1ZXMgYXJlIG93bmVkIGJ5XG4gICAgICAvLyBSZXBvcnRGaWx0ZXJTdGF0ZVNlcnZpY2UuXG4gICAgICBxdWVyeVBhcmFtOiBmYWxzZSxcbiAgICAgIHBlcnNpc3Q6IGZhbHNlLFxuICAgICAgaXRlbXM6IFtcbiAgICAgICAgLi4uZ3JvdXBzLm1hcCgoZ3JvdXApID0+XG4gICAgICAgICAgZmlsdGVySXRlbUZvckdyb3VwKGdyb3VwLCB0aGlzLl9maWx0ZXJPcHRpb25zLCByZXBvcnQsIHRoaXMuX2ZpbHRlclN0YXRlLnZhbHVlKGdyb3VwLmlkKSwgZmVhdHVyZXMpKSxcbiAgICAgICAgLi4uKGxpc3RTZWFyY2ggPyBbbGlzdFNlYXJjaEl0ZW0odGhpcy5fZmlsdGVyU3RhdGUubGlzdFNlYXJjaCh0aGlzLmNvbXBvbmVudC5pZCkpXSA6IFtdKSxcbiAgICAgIF0sXG4gICAgICAvLyBUeXBpbmcgaW4gdGhlIHNlYXJjaCBib3ggbXVzdCBub3QgcmVmZXRjaCB0aHJvdWdoIHRoZSBncm91cHMsIG5vciBzZXRcbiAgICAgIC8vIGEgc3RhbGUgZ3JvdXAgdmFsdWUgYmFjaywgYW5kIGEgZ3JvdXAgY2hhbmdlIG11c3Qgbm90IHJlZmV0Y2ggdGhyb3VnaFxuICAgICAgLy8gdGhlIHNlYXJjaC5cbiAgICAgIGNoYW5nZTogKHF1ZXJ5KSA9PiB7XG4gICAgICAgIGNvbnN0IHZhbHVlcyA9IGdyb3VwVmFsdWVzRnJvbVF1ZXJ5KHF1ZXJ5ID8/IHt9LCB0aGlzLmNvbXBvbmVudEZpbHRlckdyb3Vwcyk7XG5cbiAgICAgICAgZm9yIChjb25zdCB7IGdyb3VwSWQsIHZhbHVlIH0gb2YgbW92ZWRHcm91cFZhbHVlcyhyZXBvcnRlZCwgdmFsdWVzKSkge1xuICAgICAgICAgIHRoaXMuX2ZpbHRlclN0YXRlLnNldFZhbHVlKGdyb3VwSWQsIHZhbHVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChsaXN0U2VhcmNoKSB7XG4gICAgICAgICAgdGhpcy5fZmlsdGVyU3RhdGUuc2V0TGlzdFNlYXJjaCh0aGlzLmNvbXBvbmVudC5pZCwgU3RyaW5nKHF1ZXJ5Py5bTElTVF9TRUFSQ0hfSVRFTV0gPz8gJycpKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIC8vICdDbGVhciBmaWx0ZXJzJyBwdXRzIHRoaXMgaGVhZGVyJ3Mgb3duIGdyb3VwcyBiYWNrIG9uIHRoZWlyIGF1dGhvcmVkXG4gICAgICAvLyBkZWZhdWx0cy4gZnMtZmlsdGVyIHJlcG9ydHMgaXRzIG93biBjbGVhcmVkIGl0ZW1zIChjaGFuZ2UpIGp1c3RcbiAgICAgIC8vIGJlZm9yZSB0aGlzLCBzbyB0aGUgcmVzZXQgd2lucy5cbiAgICAgIGNsZWFyOiAoKSA9PiB0aGlzLl9maWx0ZXJTdGF0ZS5yZXNldEdyb3Vwc1RvRGVmYXVsdHMoZ3JvdXBzLm1hcCgoZ3JvdXApID0+IGdyb3VwLmlkKSksXG4gICAgICAvLyBUaGUgY2hpcCBzaG93cyBleGFjdGx5IHdoaWxlIG9uZSBvZiB0aG9zZSBncm91cHMgZGlmZmVycyBmcm9tIHdoYXRcbiAgICAgIC8vIHRoYXQgY2xlYXIgcHV0cyBiYWNrIChncm91cHNEaWZmZXJGcm9tRGVmYXVsdHMpLiBmcy1maWx0ZXIncyBvd24gcnVsZVxuICAgICAgLy8gY29tcGFyZXMgdGhlIGl0ZW1zIHdpdGggdGhlIHZhbHVlcyB0aGlzIGhlYWRlciB3YXMgYnVpbHQgd2l0aCwgd2hpY2hcbiAgICAgIC8vIG1heSBiZSB0aGUgdmlld2VyJ3Mgb3duIHBpY2tzLCBhbmQgd291bGQgb2ZmZXIgYSBjbGVhciB0aGF0IGNoYW5nZXNcbiAgICAgIC8vIG5vdGhpbmcuXG4gICAgICBjbGVhclZpc2libGU6ICgpID0+IHRoaXMuX2ZpbHRlclN0YXRlLmdyb3Vwc0RpZmZlckZyb21EZWZhdWx0cyhncm91cHMubWFwKChncm91cCkgPT4gZ3JvdXAuaWQpKSxcbiAgICB9KTtcbiAgfVxuXG4gIC8vIHJlc2V0VG9EZWZhdWx0cygpIG1vdmVzIHRoZSBzdGF0ZSB2ZXJzaW9uIGFuZCBhbm5vdW5jZXMgYSBmdWxsIGNoYW5nZVxuICAvLyAobnVsbCkuIFRoZSBoZWFkZXIgaXMgYnVpbHQgYWdhaW4gZm9yIHRoZSBuZXcgdmVyc2lvbiwgYW5kXG4gIC8vIGZpbHRlcktleSwgd2hpY2ggY2FycmllcyBpdCwgcmVjcmVhdGVzIHRoZSBibG9jazogZnMtZmlsdGVyIHJlYWRzIGl0c1xuICAvLyBjb25maWcgb25jZS4gQW55IG90aGVyIGZ1bGwgY2hhbmdlIChhIHJlbG9hZCwgdGhlIG1hdGNoKSBsZWF2ZXMgaXQgYmUuXG4gIC8vIEEgY2hhbmdlIHRvIG9uZSBncm91cCB0aGUgaGVhZGVyIHNob3dzIHdpdGggYW5vdGhlciB2YWx1ZSAoYW5vdGhlciBiYXJcbiAgLy8gc2V0IGl0KSBidWlsZHMgaXQgYWdhaW4gdG9vLlxuICBwcml2YXRlIF9yZWJ1aWxkSGVhZGVyT25OZXdTdGF0ZSgpOiB2b2lkIHtcbiAgICB0aGlzLl9maWx0ZXJTdGF0ZS5jaGFuZ2VzRm9yKHRoaXMuY29tcG9uZW50KVxuICAgICAgLnBpcGUoXG4gICAgICAgIHJ4RmlsdGVyKChncm91cElkKSA9PiAoZ3JvdXBJZCA9PT0gbnVsbFxuICAgICAgICAgID8gdGhpcy5fZmlsdGVyU3RhdGUuc3RhdGVWZXJzaW9uKCkgIT09IHRoaXMuX2hlYWRlclZlcnNpb24oKVxuICAgICAgICAgIDogdGhpcy5fc2hvd3NPdGhlclZhbHVlKGdyb3VwSWQpKSksXG4gICAgICAgIHRhcCgoKSA9PiB0aGlzLl9idWlsZEZpbHRlckNvbmZpZygpKSxcbiAgICAgICAgdGFrZVVudGlsRGVzdHJveWVkKHRoaXMuX2Rlc3Ryb3lSZWYpLFxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgpO1xuICB9XG5cbiAgLy8gV2hldGhlciB0aGUgaGVhZGVyIHNob3dzIGEgZ3JvdXAgd2l0aCBhIHZhbHVlIG90aGVyIHRoYW4gdGhlIG9uZSBzdG9yZWRcbiAgLy8gZm9yIGl0LiBBIGNoYW5nZSB0aGUgaGVhZGVyJ3Mgb3duIGJhciBtYWRlIGlzIHdoYXQgaXQgc2hvd3MgYWxyZWFkeS5cbiAgcHJpdmF0ZSBfc2hvd3NPdGhlclZhbHVlKGdyb3VwSWQ6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9zaG93bi5oYXMoZ3JvdXBJZClcbiAgICAgICYmIGdyb3VwVmFsdWVTaWduYXR1cmUodGhpcy5fc2hvd24uZ2V0KGdyb3VwSWQpKSAhPT0gZ3JvdXBWYWx1ZVNpZ25hdHVyZSh0aGlzLl9maWx0ZXJTdGF0ZS52YWx1ZShncm91cElkKSk7XG4gIH1cblxuICBwcml2YXRlIF9vcmlnaW4gPSB7IHg6IDAsIHk6IDAsIHc6IDAsIGg6IDAgfTtcblxuICAvLyBQb2ludGVyLWNhcHR1cmUgZ2VzdHVyZSBsb29wOiBydW5zIG91dHNpZGUgQW5ndWxhciwgcmVwYWludHMgaW1wZXJhdGl2ZWx5LFxuICAvLyBhbmQgZmluaXNoZXMgYmFjayBpbnNpZGUgQW5ndWxhciAoc2VsZWN0aW9uL3BlcnNpc3RlbmNlKS5cbiAgcHJpdmF0ZSBfdHJhY2soXG4gICAgZXZlbnQ6IFBvaW50ZXJFdmVudCxcbiAgICBvbk1vdmU6IChkZWx0YVg6IG51bWJlciwgZGVsdGFZOiBudW1iZXIpID0+IHZvaWQsXG4gICAgb25FbmQ6ICgpID0+IHZvaWQsXG4gICk6IHZvaWQge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG5cbiAgICBjb25zdCBoYW5kbGUgPSBldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQ7XG4gICAgaGFuZGxlLnNldFBvaW50ZXJDYXB0dXJlKGV2ZW50LnBvaW50ZXJJZCk7XG5cbiAgICB0aGlzLl9vcmlnaW4gPSB7XG4gICAgICB4OiB0aGlzLmNvbXBvbmVudC54LFxuICAgICAgeTogdGhpcy5jb21wb25lbnQueSxcbiAgICAgIHc6IHRoaXMuY29tcG9uZW50LncsXG4gICAgICBoOiB0aGlzLmNvbXBvbmVudC5oLFxuICAgIH07XG4gICAgY29uc3Qgc3RhcnRYID0gZXZlbnQuY2xpZW50WDtcbiAgICBjb25zdCBzdGFydFkgPSBldmVudC5jbGllbnRZO1xuXG4gICAgdGhpcy5fem9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XG4gICAgICBjb25zdCBtb3ZlID0gKGU6IFBvaW50ZXJFdmVudCkgPT4gb25Nb3ZlKGUuY2xpZW50WCAtIHN0YXJ0WCwgZS5jbGllbnRZIC0gc3RhcnRZKTtcbiAgICAgIGNvbnN0IGVuZCA9ICgpID0+IHtcbiAgICAgICAgaGFuZGxlLnJlbGVhc2VQb2ludGVyQ2FwdHVyZShldmVudC5wb2ludGVySWQpO1xuICAgICAgICBoYW5kbGUucmVtb3ZlRXZlbnRMaXN0ZW5lcigncG9pbnRlcm1vdmUnLCBtb3ZlKTtcbiAgICAgICAgaGFuZGxlLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJ1cCcsIGVuZCk7XG4gICAgICAgIGhhbmRsZS5yZW1vdmVFdmVudExpc3RlbmVyKCdwb2ludGVyY2FuY2VsJywgZW5kKTtcblxuICAgICAgICB0aGlzLl96b25lLnJ1bigoKSA9PiB7XG4gICAgICAgICAgdGhpcy5zbmFwcGVyPy5jbGVhcigpO1xuICAgICAgICAgIG9uRW5kKCk7XG4gICAgICAgIH0pO1xuICAgICAgfTtcblxuICAgICAgaGFuZGxlLmFkZEV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJtb3ZlJywgbW92ZSk7XG4gICAgICBoYW5kbGUuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcnVwJywgZW5kKTtcbiAgICAgIGhhbmRsZS5hZGRFdmVudExpc3RlbmVyKCdwb2ludGVyY2FuY2VsJywgZW5kKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgX2VtaXRHZW9tZXRyeSgpOiB2b2lkIHtcbiAgICB0aGlzLmNvbXBvbmVudC54ID0gdGhpcy5fcm91bmQodGhpcy5jb21wb25lbnQueCk7XG4gICAgdGhpcy5jb21wb25lbnQueSA9IHRoaXMuX3JvdW5kKHRoaXMuY29tcG9uZW50LnkpO1xuICAgIHRoaXMuY29tcG9uZW50LncgPSB0aGlzLl9yb3VuZChNYXRoLm1heChNSU5fVywgdGhpcy5jb21wb25lbnQudykpO1xuICAgIHRoaXMuY29tcG9uZW50LmggPSB0aGlzLl9yb3VuZChNYXRoLm1heChNSU5fSCwgdGhpcy5jb21wb25lbnQuaCkpO1xuICAgIHRoaXMuX2FwcGx5R2VvbWV0cnkoKTtcbiAgICB0aGlzLmNoYXJ0Q29tcG9uZW50Py5yZXNpemUoKTtcblxuICAgIHRoaXMucG9zaXRpb25DaGFuZ2VkLmVtaXQoe1xuICAgICAgY29tcG9uZW50SWQ6IHRoaXMuY29tcG9uZW50LmlkLFxuICAgICAgeDogdGhpcy5jb21wb25lbnQueCxcbiAgICAgIHk6IHRoaXMuY29tcG9uZW50LnksXG4gICAgICB3OiB0aGlzLmNvbXBvbmVudC53LFxuICAgICAgaDogdGhpcy5jb21wb25lbnQuaCxcbiAgICB9KTtcbiAgfVxuXG4gIC8vIEEgY2hhcnQgb24gYSB0aW1lIHgtYXhpcyDigJQgdGhlIG9ubHkgY29tcG9uZW50IHRoZSByZXBvcnQncyBncm91cC1ieSBjb250cm9sXG4gIC8vIGFwcGxpZXMgdG8gKGlzVGltZVNlcmllc0NoYXJ0LCB0aGUgYnJvd3Nlci1zaWRlIG1pcnJvciBvZiB0aGUgc2VydmVyJ3MgcnVsZSkuXG4gIHByaXZhdGUgZ2V0IF9pc1RpbWVTZXJpZXMoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGlzVGltZVNlcmllc0NoYXJ0KHRoaXMuY29tcG9uZW50KTtcbiAgfVxuXG4gIC8vIEF1dG8gaGVpZ2h0IChib3ggZml0cyBpdHMgY29udGVudCkgdnMgZml4ZWQgKHVzZSBgaGAgZXhhY3RseSkuIERlcml2ZWQgZnJvbVxuICAvLyB0eXBlLCBzZXJ2ZXItc2lkZTogS1BJIHRpbGVzIGFyZSBhdXRvOyBjaGFydHMgYW5kIGxpc3RzIGFyZSBmaXhlZCDigJQgY2hhcnRzXG4gIC8vIGZpdCB0aGUgYm94IGFuZCBuZXZlciBvdmVyZmxvdywgbGlzdHMgc2Nyb2xsIGluc2lkZSBpdC5cbiAgcHJpdmF0ZSBnZXQgX2hlaWdodEF1dG8oKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuY29tcG9uZW50LmF1dG9IZWlnaHQgIT09IGZhbHNlO1xuICB9XG5cbiAgLy8gRHJpdmVzIHRoZSBhdXRvLW9ubHkgQ1NTIGRlZmF1bHQgKGVtcHR5LXN0YXRlIGJhc2VsaW5lKSBzbyBpdCBuZXZlciBhcHBsaWVzXG4gIC8vIHRvIGEgZml4ZWQtaGVpZ2h0IGNvbXBvbmVudC5cbiAgQEhvc3RCaW5kaW5nKCdjbGFzcy5oZWlnaHQtYXV0bycpXG4gIHB1YmxpYyBnZXQgaGVpZ2h0QXV0bygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5faGVpZ2h0QXV0bztcbiAgfVxuXG4gIC8vIFNjcmVlbiBwaXhlbHMg4oaSIGluY2hlcyBhdCB0aGUgY3VycmVudCB6b29tLlxuICBwcml2YXRlIF9pbmNoZXMocGl4ZWxzOiBudW1iZXIpOiBudW1iZXIge1xuICAgIHJldHVybiBwaXhlbHMgLyAodGhpcy56b29tICogUFhfUEVSX0lOQ0gpO1xuICB9XG5cbiAgLy8gQ2xlYW4gcGVyc2lzdGVkIHZhbHVlczogaHVuZHJlZHRocyBvZiBhbiBpbmNoLlxuICBwcml2YXRlIF9yb3VuZCh2YWx1ZTogbnVtYmVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gTWF0aC5yb3VuZCh2YWx1ZSAqIDEwMCkgLyAxMDA7XG4gIH1cblxuICAvLyBUaGUgY2FudmFzIHBvc2l0aW9ucyB0aGUgaG9zdCB2aWEgW3N0eWxlXTsgbWlkLWdlc3R1cmUgd2Ugc2V0IGl0IGRpcmVjdGx5XG4gIC8vIHNvIE9uUHVzaCBuZXZlciByZS1yZW5kZXJzIGluIHRoZSBtb3ZlIGxvb3AuXG4gIHByaXZhdGUgX2FwcGx5R2VvbWV0cnkoKTogdm9pZCB7XG4gICAgY29uc3Qgc3R5bGUgPSB0aGlzLl9ob3N0Lm5hdGl2ZUVsZW1lbnQuc3R5bGU7XG4gICAgc3R5bGUubGVmdCA9IGAke3RoaXMuY29tcG9uZW50LnggKiBQWF9QRVJfSU5DSH1weGA7XG4gICAgc3R5bGUudG9wID0gYCR7dGhpcy5jb21wb25lbnQueSAqIFBYX1BFUl9JTkNIfXB4YDtcbiAgICBzdHlsZS53aWR0aCA9IGAke3RoaXMuY29tcG9uZW50LncgKiBQWF9QRVJfSU5DSH1weGA7XG5cbiAgICAvLyBBdXRvIChrcGkpOiBubyBmaXhlZCBoZWlnaHQg4oCUIHRoZSBib3ggc2l6ZXMgdG8gaXRzIGNvbnRlbnQuIEZpeGVkXG4gICAgLy8gKGNoYXJ0L2xpc3QpOiBgaGAgaXMgdGhlIGV4YWN0IGhlaWdodC4gTWlycm9ycyB0aGUgY2FudmFzIFtzdHlsZV0gYmluZGluZ1xuICAgIC8vIHNvIHRoZSBtaWQtZ2VzdHVyZSBwYWludCBtYXRjaGVzIHRoZSBwb3N0LWdlc3R1cmUgcmUtcmVuZGVyLlxuICAgIGlmICh0aGlzLl9oZWlnaHRBdXRvKSB7XG4gICAgICBzdHlsZS5oZWlnaHQgPSAnJztcbiAgICB9IGVsc2Uge1xuICAgICAgc3R5bGUuaGVpZ2h0ID0gYCR7dGhpcy5jb21wb25lbnQuaCAqIFBYX1BFUl9JTkNIfXB4YDtcbiAgICB9XG4gIH1cblxuICAvLyAtLS0tLSBkYXRhIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuICAvLyBPbmUgcmVxdWVzdCBvZiB0aGUgbG9hZCBzdHJlYW0gKHRpbGVMb2FkcyksIGJ1aWx0IGZyb20gdGhlIHN0YXRlIG5vdy4gVGhlXG4gIC8vIHNwaW5uZXIgc2hvd3MgZWl0aGVyIHdheTsgYSB0aWxlIHdpdGggZGF0YSBvbiBzY3JlZW4ga2VlcHMgaXQsIGRpbW1lZC5cbiAgcHJpdmF0ZSBfbG9hZCgpOiBPYnNlcnZhYmxlPENvbXBvbmVudERhdGE+IHtcbiAgICBjb25zdCBmaXJzdCA9ICF0aGlzLmRhdGEoKTtcblxuICAgIHRoaXMubG9hZGluZy5zZXQoZmlyc3QpO1xuICAgIHRoaXMucmVmcmVzaGluZy5zZXQoIWZpcnN0KTtcbiAgICB0aGlzLmVycm9yLnNldChudWxsKTtcblxuICAgIGNvbnN0IGZpbHRlcnMgPSB0aGlzLl9maWx0ZXJTdGF0ZS5yZXNvbHZlRm9yQ29tcG9uZW50KHRoaXMuY29tcG9uZW50KTtcbiAgICAvLyBUaGUgdGlsZSdzIGludGVyYWN0aW9uIHN0YXRlLCB0aGUgb25lIGl0cyBDU1YgYW5kIGV2ZXJ5IGV4cG9ydCBjYXJyeVxuICAgIC8vICh0aWxlRGF0YVN0YXRlKTogYSB0aW1lLXNlcmllcyBjaGFydCdzIGdyYWluICh3aGVuIHRoZSB2aWV3ZXIgcGlja2VkXG4gICAgLy8gb25lKSBzbyB0aGUgYmFja2VuZCByZS1idWNrZXRzLCBhIGNoYXJ0J3MgZHJpbGwgcGF0aCwgYW5kIHRoZSBncm91cHNcbiAgICAvLyB0aGF0IG1hdGNoICdhbnknLlxuICAgIGNvbnN0IHN0YXRlID0gdGhpcy5fZmlsdGVyU3RhdGUudGlsZVN0YXRlKHRoaXMuY29tcG9uZW50KTtcblxuICAgIHJldHVybiB0aGlzLl9yZXBvcnREYXRhLmNvbXBvbmVudERhdGEodGhpcy5yZXBvcnRJZCwgdGhpcy5jb21wb25lbnQuaWQsIGZpbHRlcnMsIHN0YXRlKTtcbiAgfVxuXG4gIC8vIEEgZmFpbGVkIGxvYWQgY2xlYXJzIHRoZSBkYXRhIHdpdGggaXRzIG1lc3NhZ2UsIHNvIHRoZSBuZXh0IGxvYWQgc3RhcnRzXG4gIC8vIGZyb20gYW4gZW1wdHkgdGlsZSBhbmQgbmV2ZXIgc2hvd3MgdGhlIGRhdGEgdGhlIGZhaWx1cmUgcmVwbGFjZWQuIEFcbiAgLy8gY2hhcnQncyBhbnN3ZXIgZ2l2ZXMgaXRzIGRyaWxsIHBhdGguXG4gIHByaXZhdGUgX2xvYWRlZChyZXN1bHQ6IFRpbGVMb2FkUmVzdWx0PENvbXBvbmVudERhdGE+KTogdm9pZCB7XG4gICAgdGhpcy5kYXRhLnNldChyZXN1bHQuZGF0YSk7XG4gICAgdGhpcy5lcnJvci5zZXQocmVzdWx0LmVycm9yKTtcbiAgICB0aGlzLmxvYWRpbmcuc2V0KGZhbHNlKTtcbiAgICB0aGlzLnJlZnJlc2hpbmcuc2V0KGZhbHNlKTtcblxuICAgIGlmIChyZXN1bHQuZXJyb3IgPT09IG51bGwgJiYgcmVzdWx0LmRhdGEpIHtcbiAgICAgIHRoaXMuX2Fkb3B0RHJpbGwocmVzdWx0LmRhdGEpO1xuICAgIH1cbiAgfVxuXG4gIC8vIEEgY2hhcnQgdGFrZXMgdGhlIGRyaWxsIHBhdGggaXRzIGFuc3dlciBhcHBsaWVkIChhZG9wdGVkRHJpbGxQYXRoKSB3aGlsZVxuICAvLyB0aGUgdmlld2VyIGlzIG9mZmVyZWQgZHJpbGw7IGFuIG9sZGVyIHNlcnZlciBhcHBsaWVzIG5vbmUsIGFuZCB0aGUgcGF0aFxuICAvLyBzdGF5cyBpbiB0aGUgc3RhdGUuIFdoZW4gdGhlIHBhdGggaXQgc2VudCB3YXMgY3V0LCB0aGUgdmlld2VyIGlzIHRvbGRcbiAgLy8gb25jZSAoZHJpbGxSZXNldE5vdGVkKTogdGhlIHNob3J0ZXIgcGF0aCBpcyB3aGF0IHRoZSBjaGFydCByZWFkcyBmcm9tXG4gIC8vIG5vdyBvbiwgc28gdGhlIHNlcnZlciBjdXRzIG5vdGhpbmcgYWdhaW4uXG4gIHByaXZhdGUgX2Fkb3B0RHJpbGwoZGF0YTogQ29tcG9uZW50RGF0YSk6IHZvaWQge1xuICAgIGNvbnN0IGdyYWluTW92ZWQgPSB0aGlzLl9ncmFpbk1vdmVkO1xuICAgIHRoaXMuX2dyYWluTW92ZWQgPSBmYWxzZTtcblxuICAgIGlmICh0aGlzLmNvbXBvbmVudC50eXBlICE9PSAnY2hhcnQnIHx8ICF0aGlzLl9vZmZlcmVkRmVhdHVyZXMoKS5pbmNsdWRlcygnZHJpbGwnKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9maWx0ZXJTdGF0ZS5hZG9wdERyaWxsKHRoaXMuY29tcG9uZW50LmlkLCBhZG9wdGVkRHJpbGxQYXRoKGRhdGEuZHJpbGwpKVxuICAgICAgJiYgZHJpbGxSZXNldE5vdGVkKGRhdGEuZHJpbGwsIGdyYWluTW92ZWQpKSB7XG4gICAgICB0aGlzLl9tZXNzYWdlLndhcm5pbmcoRFJJTExfUkVTRVRfTUVTU0FHRSk7XG4gICAgfVxuICB9XG5cbiAgLy8gLS0tLS0gbWFyayBjbGlja3MgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgcHJpdmF0ZSBfcnVuTWFya0FjdGlvbihhY3Rpb246IFJlcG9ydE1hcmtBY3Rpb24sIGNsaWNrOiBSZXBvcnRNYXJrQ2xpY2spOiB2b2lkIHtcbiAgICBpZiAoYWN0aW9uID09PSAnZHJpbGwnKSB7XG4gICAgICB0aGlzLl9kcmlsbERvd24oY2xpY2spO1xuICAgIH1cbiAgfVxuXG4gIC8vIERyaWxsIGRvd246IHRoZSBjaGFydCdzIHBhdGggZ29lcyBvbmUgbGV2ZWwgYmVsb3cgdGhlIHBlcmlvZCBjbGlja2VkLFxuICAvLyBhbmQgdGhlIGNoYXJ0IHJlYWRzIGFnYWluIChkcmlsbENoYW5nZXMpLlxuICBwcml2YXRlIF9kcmlsbERvd24oY2xpY2s6IFJlcG9ydE1hcmtDbGljayk6IHZvaWQge1xuICAgIGNvbnN0IHBhdGggPSBkcmlsbERvd25QYXRoKHRoaXMuZGF0YSgpPy5kcmlsbCwgY2xpY2spO1xuXG4gICAgaWYgKHBhdGgpIHtcbiAgICAgIHRoaXMuX2ZpbHRlclN0YXRlLnNldERyaWxsKHRoaXMuY29tcG9uZW50LmlkLCBwYXRoKTtcbiAgICB9XG4gIH1cblxuICAvLyBMaXN0cyB0aGUgY2xpY2sncyBhY3Rpb25zIGluIHRoZSBtYXJrIG1lbnUgYW5kIG9wZW5zIGl0IGF0IHRoZSBjbGljayxcbiAgLy8gdGhyb3VnaCB0aGUgemVyby1zaXplIGFuY2hvciAob3BlbkF0UG9pbnQpLlxuICBwcml2YXRlIF9vcGVuTWFya01lbnUoYWN0aW9uczogUmVwb3J0TWFya0FjdGlvbltdLCBjbGljazogUmVwb3J0TWFya0NsaWNrKTogdm9pZCB7XG4gICAgY29uc3QgYW5jaG9yID0gdGhpcy5tYXJrQW5jaG9yPy5uYXRpdmVFbGVtZW50O1xuXG4gICAgaWYgKCFhbmNob3IpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLl9tZW51Q2xpY2sgPSBjbGljaztcbiAgICB0aGlzLm1hcmtNZW51QWN0aW9ucy5zZXQoYWN0aW9ucyk7XG4gICAgb3BlbkF0UG9pbnQoYW5jaG9yLCBjbGljay5wb2ludGVyLCB0aGlzLnpvb20sICgpID0+IHRoaXMubWFya01lbnU/Lm9wZW5NZW51KG51bGwpKTtcbiAgfVxufVxuIiwiPGRpdlxuICAgIGNsYXNzPVwiY29tcG9uZW50LWJveFwiXG4gICAgW2NsYXNzLmVkaXRpbmddPVwiZWRpdE1vZGVcIlxuICAgIFtjbGFzcy50ZXh0XT1cImlzVGV4dFwiXG4gICAgW2NsYXNzLnNlbGVjdGVkXT1cInNlbGVjdGVkXCJcbiAgICBbY2xhc3MucmVmcmVzaGluZ109XCJyZWZyZXNoaW5nKClcIlxuICAgIFtzdHlsZS5wYWRkaW5nXT1cImJvZHlQYWRkaW5nXCJcbiAgICAocG9pbnRlcmRvd24pPVwib25Db21wb25lbnRQb2ludGVyRG93bigkZXZlbnQpXCJcbiAgICAobW91c2Vkb3duKT1cInN0b3BDYW52YXNQYW4oJGV2ZW50KVwiXG4gICAgKHRvdWNoc3RhcnQpPVwic3RvcENhbnZhc1BhbigkZXZlbnQpXCI+XG4gIDwhLS0gVGhlIGhlYWRlciBpcyBhbiBmcy1maWx0ZXI6IGhlYWRpbmcgdGVtcGxhdGUgPSB0aXRsZSAoYW5kIHRoZSBlZGl0LW1vZGVcbiAgICAgICBkcmFnIGhhbmRsZSksIGFjdGlvbnMgPSB0aGUgbWVudSwgaXRlbXMgPSBjb21wb25lbnQtbGV2ZWwgZmlsdGVyIGdyb3VwcyxcbiAgICAgICB0aGUgc2FtZSBzdHJpcCBmb3IgZXZlcnkgdHlwZSAobGlzdHMgaW5jbHVkZWQpLiBmcy1maWx0ZXIgcmVhZHMgaXRzXG4gICAgICAgY29uZmlnIG9uY2UsIHNvIHRoZSBibG9jayBpcyBrZXllZCBvbiB0aGUgY29tcG9uZW50LWZpbHRlciBzZXQgdG8gYmVcbiAgICAgICByZWNyZWF0ZWQgd2hlbiBpdCBjaGFuZ2VzLiBUaGUgdGl0bGUgc2hvd3MgaXRzIHRva2VucyBmaWxsZWQsIGFuZCBhXG4gICAgICAgZmlsdGVyIGNoYW5nZSByZXBhaW50cyBpdCBpbiBwbGFjZSAoc2hvd25UaXRsZSkuIC0tPlxuICA8IS0tIEEgdGV4dCBibG9jayBoYXMgbm8gdGl0bGUgYmFyIOKAlCBpdCBJUyBpdHMgd29yZHMsIGxpa2UgYSB0ZXh0IGJveCBvbiBhXG4gICAgICAgc2xpZGUg4oCUIHNvIGl0IGdldHMgbmVpdGhlciB0aGUgaGVhZGVyIG5vciB0aGUgZGF0YSBhY3Rpb25zLiAtLT5cbiAgQGZvciAoa2V5IG9mIGlzVGV4dCA/IFtdIDogW2ZpbHRlcktleV07IHRyYWNrIGtleSkge1xuICAgIDxmcy1maWx0ZXJcbiAgICAgICAgY2xhc3M9XCJjb21wb25lbnQtZmlsdGVyXCJcbiAgICAgICAgW2NvbmZpZ109XCJmaWx0ZXJDb25maWcoKVwiPlxuICAgICAgPG5nLXRlbXBsYXRlIGZzRmlsdGVySGVhZGluZz5cbiAgICAgICAgPGRpdlxuICAgICAgICAgICAgY2xhc3M9XCJjb21wb25lbnQtdGl0bGVcIlxuICAgICAgICAgICAgKHBvaW50ZXJkb3duKT1cIm9uRHJhZ1N0YXJ0KCRldmVudClcIj5cbiAgICAgICAgICA8IS0tIFdoaWxlIHRoZSBjaGFydCBpcyBkcmlsbGVkIHRoZSB0aXRsZSBsZWFkcyBpdHMgYnJlYWRjcnVtYjpcbiAgICAgICAgICAgICAgICdUaXRsZSDigLogMjAyNiDigLogUTMnLCB0aGUgdGl0bGUgYXMgdGhlIHZpZXdlciByZWFkcyBpdFxuICAgICAgICAgICAgICAgKHNob3duVGl0bGUpLiBUaGUgdGl0bGUgZ29lcyBiYWNrIHRvIHRoZSB0b3AgYW5kIGVhY2hcbiAgICAgICAgICAgICAgIGNydW1iIHRvIHRoZSBwZXJpb2QgaXQgbmFtZXM7IHRoZSBsYXN0IGlzIHdoZXJlIHRoZSBjaGFydCBpcy5cbiAgICAgICAgICAgICAgIEEgbG9uZyBwYXRoIGlzIGN1dCBhdCBpdHMgbGVmdCBlbmQsIHNvIHRoZSBjcnVtYnMgbmVhcmVzdCB0aGVcbiAgICAgICAgICAgICAgIGNoYXJ0IHN0YXkgaW4gdmlldy4gV2hpbGUgdGhlIGxheW91dCBpcyBlZGl0ZWQgdGhlIGNydW1icyBhcmVcbiAgICAgICAgICAgICAgIHBsYWluIHRleHQgKHRoZSBzdHlsZXNoZWV0OyBkcmlsbFRvIGRvZXMgbm90aGluZyB0aGVuKS4gLS0+XG4gICAgICAgICAgQGlmIChkcmlsbENydW1icygpLmxlbmd0aCkge1xuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkcmlsbC1wYXRoXCI+XG4gICAgICAgICAgICAgIDxzcGFuIGRpcj1cImx0clwiPlxuICAgICAgICAgICAgICAgIDxhXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZHJpbGwtY3J1bWJcIlxuICAgICAgICAgICAgICAgICAgICB0YWJpbmRleD1cIjBcIlxuICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiZHJpbGxUbygwKVwiXG4gICAgICAgICAgICAgICAgICAgIChrZXlkb3duLmVudGVyKT1cImRyaWxsVG8oMClcIj5cbiAgICAgICAgICAgICAgICAgIHt7IHNob3duVGl0bGUgfX1cbiAgICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICAgICAgQGZvciAobGFiZWwgb2YgZHJpbGxDcnVtYnMoKTsgdHJhY2sgJGluZGV4OyBsZXQgbGFzdCA9ICRsYXN0KSB7XG4gICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRyaWxsLXNlcGFyYXRvclwiPnt7IGRyaWxsU2VwYXJhdG9yIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgQGlmIChsYXN0KSB7XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuPnt7IGxhYmVsIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIDxhXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImRyaWxsLWNydW1iXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRhYmluZGV4PVwiMFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiZHJpbGxUbygkaW5kZXggKyAxKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAoa2V5ZG93bi5lbnRlcik9XCJkcmlsbFRvKCRpbmRleCArIDEpXCI+XG4gICAgICAgICAgICAgICAgICAgICAge3sgbGFiZWwgfX1cbiAgICAgICAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAge3sgc2hvd25UaXRsZSB9fVxuICAgICAgICAgIH1cbiAgICAgICAgICBAaWYgKHRydW5jYXRlZCkge1xuICAgICAgICAgICAgPG1hdC1pY29uXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJ0cnVuY2F0ZWQtaWNvblwiXG4gICAgICAgICAgICAgICAgbWF0VG9vbHRpcD1cIlNob3dpbmcgYSB0cnVuY2F0ZWQgcmVzdWx0IOKAlCByZWZpbmUgdGhlIGZpbHRlcnMgdG8gc2VlIGV2ZXJ5dGhpbmcuXCI+XG4gICAgICAgICAgICAgIHdhcm5pbmdfYW1iZXJcbiAgICAgICAgICAgIDwvbWF0LWljb24+XG4gICAgICAgICAgfVxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgPC9mcy1maWx0ZXI+XG4gIH1cbiAgPCEtLSBUaGUgYWN0aW9ucyBtZW51IGlzIGZsb2F0ZWQgdG9wLXJpZ2h0IChhYnNvbHV0ZSkgcmF0aGVyIHRoYW4gbGl2aW5nIGluXG4gICAgICAgZnMtZmlsdGVyJ3MgYWN0aW9ucyBzbG90LCBzbyBpdHMgfjQwcHggYnV0dG9uIGhlaWdodCBubyBsb25nZXIgZHJpdmVzIHRoZVxuICAgICAgIGhlYWRlciByb3cncyBoZWlnaHQuIEl0IG92ZXJsYXlzIHRoZSBib3ggY29ybmVyOyB0aGUgaGVhZGluZyByZXNlcnZlc1xuICAgICAgIHJpZ2h0IHBhZGRpbmcgc28gYSBsb25nIHRpdGxlIGVsbGlwc2lzZXMgYmVmb3JlIGl0LiAtLT5cbiAgQGlmICghaXNUZXh0IHx8IChlZGl0TW9kZSAmJiAhdGV4dEVkaXRpbmcoKSkpIHtcbiAgICA8YnV0dG9uXG4gICAgICAgIG1hdC1pY29uLWJ1dHRvblxuICAgICAgICBjbGFzcz1cImNvbXBvbmVudC1tZW51XCJcbiAgICAgICAgW2ZzTWVudVRyaWdnZXJGb3JdPVwibWVudVwiXG4gICAgICAgIChwb2ludGVyZG93bik9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxuICAgICAgICAobW91c2Vkb3duKT1cInN0b3BDYW52YXNQYW4oJGV2ZW50KVwiPlxuICAgICAgPG1hdC1pY29uPm1vcmVfdmVydDwvbWF0LWljb24+XG4gICAgPC9idXR0b24+XG4gICAgPCEtLSBCZXNpZGUgaXRzIHRyaWdnZXIsIGluc2lkZSB0aGUgc2FtZSBibG9jazogYW4gZnMtbWVudSB0aGF0IGZpbmRzIG5vXG4gICAgICAgICB0cmlnZ2VyIG9mIGl0cyBvd24gZHJhd3Mgb25lLiAtLT5cbiAgICA8ZnMtbWVudSAjbWVudT5cbiAgICAgIDxuZy10ZW1wbGF0ZVxuICAgICAgICAgIGZzLW1lbnUtaXRlbVxuICAgICAgICAgIFtoaWRkZW5dPVwiIWlzVGV4dFwiXG4gICAgICAgICAgKGNsaWNrKT1cImVkaXRUZXh0KClcIj5cbiAgICAgICAgPG1hdC1pY29uPmVkaXQ8L21hdC1pY29uPlxuICAgICAgICA8c3Bhbj5FZGl0IHRleHQ8L3NwYW4+XG4gICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgPG5nLXRlbXBsYXRlXG4gICAgICAgICAgZnMtbWVudS1pdGVtXG4gICAgICAgICAgW2hpZGRlbl09XCIhaXNUZXh0XCJcbiAgICAgICAgICAoY2xpY2spPVwiZGVsZXRlVGV4dCgpXCI+XG4gICAgICAgIDxtYXQtaWNvbj5kZWxldGU8L21hdC1pY29uPlxuICAgICAgICA8c3Bhbj5EZWxldGU8L3NwYW4+XG4gICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgPG5nLXRlbXBsYXRlXG4gICAgICAgICAgZnMtbWVudS1pdGVtXG4gICAgICAgICAgW2hpZGRlbl09XCIhZHJpbGxDcnVtYnMoKS5sZW5ndGggfHwgZWRpdE1vZGVcIlxuICAgICAgICAgIChjbGljayk9XCJkcmlsbFVwKClcIj5cbiAgICAgICAgPG1hdC1pY29uPmFycm93X3Vwd2FyZDwvbWF0LWljb24+XG4gICAgICAgIDxzcGFuPkRyaWxsIHVwPC9zcGFuPlxuICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgIDxuZy10ZW1wbGF0ZVxuICAgICAgICAgIGZzLW1lbnUtaXRlbVxuICAgICAgICAgIFtoaWRkZW5dPVwiIWRyaWxsQ3J1bWJzKCkubGVuZ3RoIHx8IGVkaXRNb2RlXCJcbiAgICAgICAgICAoY2xpY2spPVwiZHJpbGxUbygwKVwiPlxuICAgICAgICA8bWF0LWljb24+dmVydGljYWxfYWxpZ25fdG9wPC9tYXQtaWNvbj5cbiAgICAgICAgPHNwYW4+QmFjayB0byB0b3A8L3NwYW4+XG4gICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgPG5nLXRlbXBsYXRlXG4gICAgICAgICAgZnMtbWVudS1pdGVtXG4gICAgICAgICAgW2hpZGRlbl09XCJpc1RleHRcIlxuICAgICAgICAgIChjbGljayk9XCJzZXR0aW5ncygpXCI+XG4gICAgICAgIDxtYXQtaWNvbj50dW5lPC9tYXQtaWNvbj5cbiAgICAgICAgPHNwYW4+U2V0dGluZ3M8L3NwYW4+XG4gICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgPG5nLXRlbXBsYXRlXG4gICAgICAgICAgZnMtbWVudS1pdGVtXG4gICAgICAgICAgW2hpZGRlbl09XCJpc1RleHRcIlxuICAgICAgICAgIChjbGljayk9XCJleHBvcnRDc3YoKVwiPlxuICAgICAgICA8bWF0LWljb24+ZG93bmxvYWQ8L21hdC1pY29uPlxuICAgICAgICA8c3Bhbj5FeHBvcnQgQ1NWPC9zcGFuPlxuICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgIDxuZy10ZW1wbGF0ZVxuICAgICAgICAgIGZzLW1lbnUtaXRlbVxuICAgICAgICAgIFtoaWRkZW5dPVwiIWhpZGVzQ29sdW1uc1wiXG4gICAgICAgICAgKGNsaWNrKT1cImNob29zZUNvbHVtbnMoKVwiPlxuICAgICAgICA8bWF0LWljb24+dmlld19jb2x1bW48L21hdC1pY29uPlxuICAgICAgICA8c3Bhbj5Db2x1bW5zPC9zcGFuPlxuICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICA8L2ZzLW1lbnU+XG4gIH1cbiAgPGRpdiBjbGFzcz1cImNvbXBvbmVudC1ib2R5XCI+XG4gICAgQGlmIChpc1RleHQpIHtcbiAgICAgIDxhcHAtcmVwb3J0LWNvbXBvbmVudC10ZXh0XG4gICAgICAgIFtodG1sXT1cInRleHRIdG1sKCkgPz8gY29tcG9uZW50LmNvbmZpZz8uaHRtbCA/PyAnJ1wiXG4gICAgICAgIFt0b2tlbnNdPVwidG9rZW5zKClcIlxuICAgICAgICBbZWRpdGluZ109XCJ0ZXh0RWRpdGluZygpXCJcbiAgICAgICAgW3Nob3duRWxzZXdoZXJlXT1cInNob3duRWxzZXdoZXJlXCJcbiAgICAgICAgKHNhdmVkKT1cIm9uVGV4dFNhdmVkKCRldmVudClcIlxuICAgICAgICAoZWRpdEVuZGVkKT1cInRleHRFZGl0aW5nLnNldChmYWxzZSlcIlxuICAgICAgICAodmFsdWVTZXR0aW5ncyk9XCJ2YWx1ZVNldHRpbmdzLmVtaXQoJGV2ZW50KVwiPlxuICAgICAgPC9hcHAtcmVwb3J0LWNvbXBvbmVudC10ZXh0PlxuICAgIH0gQGVsc2UgaWYgKGNvbXBvbmVudC50eXBlID09PSAnbGlzdCcpIHtcbiAgICAgIEBmb3IgKGtleSBvZiBbbGlzdFJlc2V0S2V5KCldOyB0cmFjayBrZXkpIHtcbiAgICAgICAgPGFwcC1yZXBvcnQtY29tcG9uZW50LWxpc3RcbiAgICAgICAgICBbcmVwb3J0SWRdPVwicmVwb3J0SWRcIlxuICAgICAgICAgIFtjb21wb25lbnRdPVwiY29tcG9uZW50XCI+XG4gICAgICAgIDwvYXBwLXJlcG9ydC1jb21wb25lbnQtbGlzdD5cbiAgICAgIH1cbiAgICB9IEBlbHNlIGlmIChjb21wb25lbnQudHlwZSA9PT0gJ2dyaWQnKSB7XG4gICAgICA8YXBwLXJlcG9ydC1jb21wb25lbnQtZ3JpZFxuICAgICAgICBbcmVwb3J0SWRdPVwicmVwb3J0SWRcIlxuICAgICAgICBbY29tcG9uZW50XT1cImNvbXBvbmVudFwiPlxuICAgICAgPC9hcHAtcmVwb3J0LWNvbXBvbmVudC1ncmlkPlxuICAgIH0gQGVsc2UgaWYgKGxvYWRpbmcoKSkge1xuICAgICAgPCEtLSBIb2xkcyB0aGUgdGlsZSdzIGhlaWdodCBmb3IgdGhlIHNwaW5uZXIgb24gdGhlIGZpcnN0IGxvYWQuIC0tPlxuICAgICAgPGRpdiBjbGFzcz1cImNvbXBvbmVudC1zdGF0ZVwiPjwvZGl2PlxuICAgIH0gQGVsc2UgaWYgKGVycm9yKCkpIHtcbiAgICAgIDxkaXYgY2xhc3M9XCJjb21wb25lbnQtc3RhdGUgZXJyb3JcIj5cbiAgICAgICAge3sgZXJyb3IoKSB9fVxuICAgICAgPC9kaXY+XG4gICAgfSBAZWxzZSBpZiAoIWRhdGEoKT8ucm93cz8ubGVuZ3RoKSB7XG4gICAgICA8ZGl2IGNsYXNzPVwiY29tcG9uZW50LXN0YXRlXCI+XG4gICAgICAgIHt7IGVtcHR5TWVzc2FnZSgpIH19XG4gICAgICA8L2Rpdj5cbiAgICB9IEBlbHNlIGlmIChjb21wb25lbnQudHlwZSA9PT0gJ2twaScpIHtcbiAgICAgIDxhcHAtcmVwb3J0LWNvbXBvbmVudC1rcGlcbiAgICAgICAgW2NvbXBvbmVudF09XCJjb21wb25lbnRcIlxuICAgICAgICBbZGF0YV09XCJkYXRhKClcIlxuICAgICAgICAobWFya0NsaWNrKT1cIm9uTWFya0NsaWNrKCRldmVudClcIj5cbiAgICAgIDwvYXBwLXJlcG9ydC1jb21wb25lbnQta3BpPlxuICAgIH0gQGVsc2Uge1xuICAgICAgPGFwcC1yZXBvcnQtY29tcG9uZW50LWNoYXJ0XG4gICAgICAgIFtjb21wb25lbnRdPVwiY29tcG9uZW50XCJcbiAgICAgICAgW2RhdGFdPVwiZGF0YSgpXCJcbiAgICAgICAgW2FjdGlvbnNdPVwidGlsZUFjdGlvbnMoKVwiXG4gICAgICAgIFsobGVnZW5kU2VsZWN0ZWQpXT1cImxlZ2VuZFNlbGVjdGVkXCJcbiAgICAgICAgKG1hcmtDbGljayk9XCJvbk1hcmtDbGljaygkZXZlbnQpXCJcbiAgICAgICAgKG1hcmtNaXNzKT1cIm9uTWFya01pc3MoKVwiPlxuICAgICAgPC9hcHAtcmVwb3J0LWNvbXBvbmVudC1jaGFydD5cbiAgICB9XG4gICAgPCEtLSBJbiBlZGl0IG1vZGUgYSB0cmFuc3BhcmVudCB2ZWlsIG92ZXIgdGhlIGJvZHkgbWFrZXMgdGhlIFdIT0xFXG4gICAgICAgICBjb21wb25lbnQgZHJhZ2dhYmxlIChpbmR1c3RyeSBzdGFuZGFyZDogeW91IGdyYWIgdGhlIG9iamVjdCwgbm90IGp1c3RcbiAgICAgICAgIGl0cyB0aXRsZSBiYXIpIGFuZCBrZWVwcyBpbm5lciB3aWRnZXRzIGZyb20gc3dhbGxvd2luZyB0aGUgZ2VzdHVyZS4gLS0+XG4gICAgQGlmIChlZGl0TW9kZSAmJiAhdGV4dEVkaXRpbmcoKSkge1xuICAgICAgPGRpdlxuICAgICAgICBjbGFzcz1cImRyYWctdmVpbFwiXG4gICAgICAgIChwb2ludGVyZG93bik9XCJvbkRyYWdTdGFydCgkZXZlbnQpXCI+XG4gICAgICA8L2Rpdj5cbiAgICB9XG4gIDwvZGl2PlxuICA8IS0tIEEgbG9hZDogYSBzcGlubmVyIGNlbnRyZWQgb24gdGhlIHdob2xlIHRpbGUuIE9uIGEgcmVmZXRjaCB0aGUgYm9keSBhbmRcbiAgICAgICB0aGUgbWVudSBhcmUgZGltbWVkIHVuZGVyIGl0ICgucmVmcmVzaGluZyk7IHRoZSB0aXRsZSBpcyBub3QuIC0tPlxuICBAaWYgKGxvYWRpbmcoKSB8fCByZWZyZXNoaW5nKCkpIHtcbiAgICA8bWF0LXByb2dyZXNzLXNwaW5uZXJcbiAgICAgIGNsYXNzPVwibG9hZC1zcGlubmVyXCJcbiAgICAgIGFyaWEtbGFiZWw9XCJMb2FkaW5nIGRhdGFcIlxuICAgICAgbW9kZT1cImluZGV0ZXJtaW5hdGVcIlxuICAgICAgW2RpYW1ldGVyXT1cIjE1XCI+XG4gICAgPC9tYXQtcHJvZ3Jlc3Mtc3Bpbm5lcj5cbiAgfVxuPC9kaXY+XG48IS0tIFRoZSBtYXJrIG1lbnUsIGZvciBhIGNsaWNrIHdob3NlIG1hcmsgb2ZmZXJzIHR3byBvciBtb3JlIGFjdGlvbnMuIEl0XG4gICAgIG9wZW5zIGF0IHRoZSBjbGljazogaXRzIHRyaWdnZXIgaXMgYSB6ZXJvLXNpemUgYW5jaG9yIHRoYXRcbiAgICAgYW5jaG9yLWF0LXBvaW50LnRzIG1vdmVzIHRoZXJlIGZpcnN0LiAtLT5cbkBpZiAoIWlzVGV4dCAmJiAhZWRpdE1vZGUpIHtcbiAgPHNwYW5cbiAgICAjbWFya0FuY2hvclxuICAgIFtzdHlsZS5wb3NpdGlvbl09XCInYWJzb2x1dGUnXCJcbiAgICBbZnNNZW51VHJpZ2dlckZvcl09XCJtYXJrTWVudVwiPlxuICA8L3NwYW4+XG4gIDxmcy1tZW51ICNtYXJrTWVudT5cbiAgICBAZm9yIChhY3Rpb24gb2YgbWFya01lbnVBY3Rpb25zKCk7IHRyYWNrIGFjdGlvbikge1xuICAgICAgPG5nLXRlbXBsYXRlXG4gICAgICAgICAgZnMtbWVudS1pdGVtXG4gICAgICAgICAgKGNsaWNrKT1cInJ1bk1hcmtBY3Rpb24oYWN0aW9uKVwiPlxuICAgICAgICB7eyBtYXJrQWN0aW9uTGFiZWxzW2FjdGlvbl0gfX1cbiAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgfVxuICA8L2ZzLW1lbnU+XG59XG48IS0tIEhhbmRsZXMgbGl2ZSBPVVRTSURFIHRoZSBjbGlwcGVkIGJveCBzbyB0aGV5IHN0cmFkZGxlIGl0cyBlZGdlcy4gLS0+XG5AaWYgKGVkaXRNb2RlICYmIHNlbGVjdGVkKSB7XG4gIEBmb3IgKGhhbmRsZSBvZiByZXNpemVIYW5kbGVzOyB0cmFjayBoYW5kbGUpIHtcbiAgICA8ZGl2XG4gICAgICBjbGFzcz1cImhhbmRsZSBoYW5kbGUte3sgaGFuZGxlIH19XCJcbiAgICAgIChtb3VzZWRvd24pPVwic3RvcENhbnZhc1BhbigkZXZlbnQpXCJcbiAgICAgIChwb2ludGVyZG93bik9XCJvblJlc2l6ZVN0YXJ0KCRldmVudCwgaGFuZGxlKVwiPlxuICAgIDwvZGl2PlxuICB9XG59Il19
|