@firestitch/report 18.18.2 → 18.20.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/chart-axis-settings.d.ts +4 -0
- package/app/reports/components/report-canvas/report-canvas.component.d.ts +5 -1
- package/app/reports/components/report-component/report-component.component.d.ts +1 -0
- package/app/reports/dialogs/component-settings/component-settings.component.d.ts +24 -0
- package/app/reports/enums/report-chart-date-label.enum.d.ts +2 -1
- package/app/reports/enums/report-chart-span-mode.enum.d.ts +5 -0
- package/app/reports/enums/report-chart-span-through.enum.d.ts +3 -0
- package/app/reports/format.d.ts +1 -0
- package/app/reports/interfaces/canvas-landing-input.interface.d.ts +1 -0
- package/app/reports/interfaces/report-chart-axis-settings.interface.d.ts +6 -0
- package/app/reports/interfaces/report-chart-span.interface.d.ts +6 -0
- package/app/reports/interfaces/report.interface.d.ts +5 -0
- package/app/reports/views/report/fs-ai-report.component.d.ts +3 -0
- package/esm2022/app/reports/canvas-landing-page.mjs +7 -1
- package/esm2022/app/reports/chart-axis-settings.mjs +24 -0
- package/esm2022/app/reports/components/report-canvas/report-canvas.component.mjs +36 -4
- package/esm2022/app/reports/components/report-component/report-component.component.mjs +27 -4
- package/esm2022/app/reports/dialogs/component-settings/component-settings.component.mjs +121 -16
- package/esm2022/app/reports/enums/report-chart-date-label.enum.mjs +5 -2
- package/esm2022/app/reports/enums/report-chart-span-mode.enum.mjs +10 -0
- package/esm2022/app/reports/enums/report-chart-span-through.enum.mjs +11 -0
- package/esm2022/app/reports/format.mjs +3 -1
- package/esm2022/app/reports/interfaces/canvas-landing-input.interface.mjs +1 -1
- package/esm2022/app/reports/interfaces/report-chart-axis-settings.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-chart-span.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report.interface.mjs +1 -1
- package/esm2022/app/reports/option-builder.mjs +34 -10
- package/esm2022/app/reports/views/report/fs-ai-report.component.mjs +32 -8
- package/esm2022/public_api.mjs +4 -1
- package/fesm2022/{firestitch-report-echarts-DKuqS_De.mjs → firestitch-report-echarts-CgZBsQWf.mjs} +2 -2
- package/fesm2022/{firestitch-report-echarts-DKuqS_De.mjs.map → firestitch-report-echarts-CgZBsQWf.mjs.map} +1 -1
- package/fesm2022/{firestitch-report-firestitch-report-CkTkXk5B.mjs → firestitch-report-firestitch-report-BQseFyHJ.mjs} +312 -59
- package/fesm2022/firestitch-report-firestitch-report-BQseFyHJ.mjs.map +1 -0
- package/fesm2022/firestitch-report.mjs +1 -1
- package/package.json +1 -1
- package/public_api.d.ts +3 -0
- package/fesm2022/firestitch-report-firestitch-report-CkTkXk5B.mjs.map +0 -1
|
@@ -10,6 +10,7 @@ import { MatOption, MatSelect } from '@angular/material/select';
|
|
|
10
10
|
import { MatSlideToggle } from '@angular/material/slide-toggle';
|
|
11
11
|
import { MatTabsModule } from '@angular/material/tabs';
|
|
12
12
|
import { MatTooltip } from '@angular/material/tooltip';
|
|
13
|
+
import { FsDatePickerModule } from '@firestitch/datepicker';
|
|
13
14
|
import { FsDialogModule } from '@firestitch/dialog';
|
|
14
15
|
import { FsFormModule } from '@firestitch/form';
|
|
15
16
|
import { FsLabelModule } from '@firestitch/label';
|
|
@@ -19,26 +20,32 @@ import { FsMessage } from '@firestitch/message';
|
|
|
19
20
|
import { FsPrompt } from '@firestitch/prompt';
|
|
20
21
|
import { FsTabsModule } from '@firestitch/tabs';
|
|
21
22
|
import { switchMap, tap } from 'rxjs/operators';
|
|
23
|
+
import { chartAxisSettings, sameChartAxisSettings } from '../../chart-axis-settings';
|
|
22
24
|
import { ReportData } from '../../data/report.data';
|
|
23
25
|
import { ReportChangePolarity } from '../../enums/report-change-polarity.enum';
|
|
26
|
+
import { ReportChartDateLabel } from '../../enums/report-chart-date-label.enum';
|
|
27
|
+
import { ReportChartSpanMode } from '../../enums/report-chart-span-mode.enum';
|
|
28
|
+
import { ReportChartSpanThrough } from '../../enums/report-chart-span-through.enum';
|
|
24
29
|
import { ReportValueFormat } from '../../enums/report-value-format.enum';
|
|
25
30
|
import { ReportValueFormula } from '../../enums/report-value-formula.enum';
|
|
26
31
|
import { resolveFormatContext } from '../../format';
|
|
27
32
|
import { KPI_SPARKLINE_DEFAULT_GRANULARITY, KPI_SPARKLINE_DEFAULT_PERIODS, kpiCardSettings, sameKpiCardSettings, } from '../../kpi-card';
|
|
28
33
|
import { GRANULARITY_OPTIONS, } from '../../interfaces/report.interface';
|
|
29
34
|
import { DEFAULT_COMPONENT_PADDING } from '../../layout';
|
|
35
|
+
import { dateFromBound, dateToBound } from '../../report-filter-items';
|
|
30
36
|
import { FILTER_TYPE_OPTIONS, barPlacement, barPlacementOptions, componentToggleState, filterLevel, filterLevelChoices, shownOnComponent, typeSelectState, valueFilterLevel, valuePlacementOptions, } from '../../filter-settings-rules';
|
|
31
37
|
import { escapeHtml, fieldToken, fillTitleTokens, textFields } from '../../text';
|
|
32
38
|
import { operandKeys, reportComponents, valueKey } from '../../values';
|
|
33
39
|
import * as i0 from "@angular/core";
|
|
34
40
|
import * as i1 from "@angular/forms";
|
|
35
|
-
import * as i2 from "@firestitch/
|
|
36
|
-
import * as i3 from "@firestitch/
|
|
37
|
-
import * as i4 from "@firestitch/
|
|
38
|
-
import * as i5 from "@firestitch/
|
|
39
|
-
import * as i6 from "@firestitch/
|
|
40
|
-
import * as i7 from "@
|
|
41
|
-
import * as i8 from "@
|
|
41
|
+
import * as i2 from "@firestitch/datepicker";
|
|
42
|
+
import * as i3 from "@firestitch/form";
|
|
43
|
+
import * as i4 from "@firestitch/mask";
|
|
44
|
+
import * as i5 from "@firestitch/dialog";
|
|
45
|
+
import * as i6 from "@firestitch/label";
|
|
46
|
+
import * as i7 from "@firestitch/tabs";
|
|
47
|
+
import * as i8 from "@angular/material/tabs";
|
|
48
|
+
import * as i9 from "@firestitch/menu";
|
|
42
49
|
// What a rise in a KPI's value means, for the Increase is select.
|
|
43
50
|
const KPI_CHANGE_POLARITY_OPTIONS = [
|
|
44
51
|
{ value: ReportChangePolarity.Good, name: 'Good news — a rise shows green' },
|
|
@@ -48,6 +55,23 @@ const KPI_CHANGE_POLARITY_OPTIONS = [
|
|
|
48
55
|
// A KPI sparkline's periods stay within 2 to 60.
|
|
49
56
|
const KPI_SPARKLINE_MIN_PERIODS = 2;
|
|
50
57
|
const KPI_SPARKLINE_MAX_PERIODS = 60;
|
|
58
|
+
// How a time axis writes its period labels, for the Date labels select.
|
|
59
|
+
const CHART_DATE_LABEL_OPTIONS = [
|
|
60
|
+
{ value: ReportChartDateLabel.Short, name: 'Short — May' },
|
|
61
|
+
{ value: ReportChartDateLabel.Long, name: 'Long — May 2026' },
|
|
62
|
+
{ value: ReportChartDateLabel.Numeric, name: 'Numeric — 2026-05' },
|
|
63
|
+
{ value: ReportChartDateLabel.PeriodEnd, name: 'Period end — 5/31/2026' },
|
|
64
|
+
];
|
|
65
|
+
// The periods a time axis draws, for the Periods shown select.
|
|
66
|
+
const CHART_SPAN_MODE_OPTIONS = [
|
|
67
|
+
{ value: ReportChartSpanMode.None, name: 'The date filter\'s range' },
|
|
68
|
+
{ value: ReportChartSpanMode.Periods, name: 'The last periods, up to the date filter\'s end' },
|
|
69
|
+
{ value: ReportChartSpanMode.Start, name: 'Every period since a date, up to the date filter\'s end' },
|
|
70
|
+
];
|
|
71
|
+
// A span's periods stay within 1 to 400, the server's bounds.
|
|
72
|
+
const CHART_SPAN_MIN_PERIODS = 1;
|
|
73
|
+
const CHART_SPAN_MAX_PERIODS = 400;
|
|
74
|
+
const CHART_SPAN_DEFAULT_PERIODS = 3;
|
|
51
75
|
// A percent KPI's target is entered as the percent shown (15 for 15%) and
|
|
52
76
|
// stored as the 0-1 ratio its value arrives in; the server refuses a stored
|
|
53
77
|
// target above 100, which is 10,000% here.
|
|
@@ -68,6 +92,9 @@ const FORMULA_LINES = {
|
|
|
68
92
|
// reads. On a derived KPI its card: what a rise means, a target and a
|
|
69
93
|
// sparkline (number formats stay with the AI). Position/size are tuned by
|
|
70
94
|
// dragging on the canvas; height behaviour follows from the component type.
|
|
95
|
+
// On a chart over time its axis: how the periods are labelled and, on a
|
|
96
|
+
// derived chart, which periods it draws (a span that ends where the date
|
|
97
|
+
// filter ends, which the server runs).
|
|
71
98
|
// Filters — ONE listing of every filterable column on this component. Each
|
|
72
99
|
// row carries two toggles: show in the report bar and/or show on this
|
|
73
100
|
// component (both, either, or neither). The interface (date range vs value
|
|
@@ -134,6 +161,21 @@ export class ComponentSettingsComponent {
|
|
|
134
161
|
sparkline = signal(false);
|
|
135
162
|
sparklineGranularity = signal(KPI_SPARKLINE_DEFAULT_GRANULARITY);
|
|
136
163
|
sparklinePeriods = signal(KPI_SPARKLINE_DEFAULT_PERIODS);
|
|
164
|
+
// ---- Time axis state (a chart over time only) ----
|
|
165
|
+
dateLabelOptions = CHART_DATE_LABEL_OPTIONS;
|
|
166
|
+
spanModeOptions = CHART_SPAN_MODE_OPTIONS;
|
|
167
|
+
spanMinPeriods = CHART_SPAN_MIN_PERIODS;
|
|
168
|
+
spanMaxPeriods = CHART_SPAN_MAX_PERIODS;
|
|
169
|
+
ReportChartSpanMode = ReportChartSpanMode;
|
|
170
|
+
timeAxis = signal(false);
|
|
171
|
+
// A span is run by the server on the chart's document, so a chart written
|
|
172
|
+
// as SQL has none.
|
|
173
|
+
spanAllowed = signal(false);
|
|
174
|
+
dateLabel = signal(ReportChartDateLabel.Short);
|
|
175
|
+
spanMode = signal(ReportChartSpanMode.None);
|
|
176
|
+
// The periods as typed: fsMaskNumber hands back the unmasked string.
|
|
177
|
+
spanPeriods = signal(CHART_SPAN_DEFAULT_PERIODS);
|
|
178
|
+
spanStart = signal(null);
|
|
137
179
|
// ---- SQL tab state ----
|
|
138
180
|
// The statement, once fetched. Null while it is in flight, and null when the
|
|
139
181
|
// component's document could not be compiled (sqlError then says why).
|
|
@@ -188,6 +230,7 @@ export class ComponentSettingsComponent {
|
|
|
188
230
|
this.paddingLeft = padding?.left ?? DEFAULT_COMPONENT_PADDING;
|
|
189
231
|
this.configJson = JSON.stringify(this.component.config ?? {}, null, 2);
|
|
190
232
|
this._seedKpiCard();
|
|
233
|
+
this._seedTimeAxis();
|
|
191
234
|
this._seedFilters(this.report, this.component.id);
|
|
192
235
|
// A formula has no statement to compile and no columns to filter on, and
|
|
193
236
|
// the server would refuse both requests.
|
|
@@ -267,23 +310,38 @@ export class ComponentSettingsComponent {
|
|
|
267
310
|
const kpi = this.kpiCard() ? this._kpiCardSettings() : null;
|
|
268
311
|
const kpiChanged = !!kpi
|
|
269
312
|
&& !sameKpiCardSettings(kpi, kpiCardSettings(this.component.config));
|
|
313
|
+
// A chart's time-axis keys go the same way: dateLabel always, span only
|
|
314
|
+
// where the chart can take one, so a chart written as SQL is never sent
|
|
315
|
+
// a key the server refuses.
|
|
316
|
+
const axis = this.timeAxis() ? this._chartAxisSettings() : null;
|
|
317
|
+
const axisChanged = !!axis
|
|
318
|
+
&& !sameChartAxisSettings(axis, chartAxisSettings(this.component.config));
|
|
270
319
|
return this._reportData.updateComponent(this.report.id, this.component.id, {
|
|
271
320
|
title: settings.title,
|
|
272
321
|
...(this.isValue() ? {} : { padding: settings.padding }),
|
|
273
322
|
...(kpiChanged ? kpi : {}),
|
|
323
|
+
...(axisChanged ? this._sentAxisKeys(axis) : {}),
|
|
274
324
|
})
|
|
275
325
|
.pipe(tap((response) => {
|
|
276
|
-
// The card
|
|
277
|
-
// the config it returns. A server that returns no
|
|
278
|
-
// save them, so the
|
|
326
|
+
// The card and the axis are drawn from the keys the server saved,
|
|
327
|
+
// read back from the config it returns. A server that returns no
|
|
328
|
+
// config did not save them, so the component keeps what it had and
|
|
329
|
+
// the dialog says so.
|
|
279
330
|
const saved = kpiChanged ? this._savedKpiCard(response) : null;
|
|
280
|
-
|
|
281
|
-
|
|
331
|
+
const savedAxis = axisChanged ? this._savedChartAxis(response) : null;
|
|
332
|
+
if ((kpiChanged && !saved) || (axisChanged && !savedAxis)) {
|
|
333
|
+
this._message.warning('Component saved, but the server did not save the card or axis settings');
|
|
282
334
|
}
|
|
283
335
|
else {
|
|
284
336
|
this._message.success(this.isValue() ? 'Value saved' : 'Component saved');
|
|
285
337
|
}
|
|
286
|
-
this._dialogRef.close({
|
|
338
|
+
this._dialogRef.close({
|
|
339
|
+
settings: {
|
|
340
|
+
...settings,
|
|
341
|
+
...(saved ? { kpi: saved } : {}),
|
|
342
|
+
...(savedAxis ? { chartAxis: savedAxis } : {}),
|
|
343
|
+
},
|
|
344
|
+
});
|
|
287
345
|
}));
|
|
288
346
|
};
|
|
289
347
|
// The type a column's filter will be made with. Only a column with no
|
|
@@ -429,6 +487,52 @@ export class ComponentSettingsComponent {
|
|
|
429
487
|
this.sparklineGranularity.set(config.sparkline?.granularity ?? KPI_SPARKLINE_DEFAULT_GRANULARITY);
|
|
430
488
|
this.sparklinePeriods.set(config.sparkline?.periods ?? KPI_SPARKLINE_DEFAULT_PERIODS);
|
|
431
489
|
}
|
|
490
|
+
// A chart over time's axis keys, from its config. Only a derived chart
|
|
491
|
+
// takes a span; a chart with none reads the date filter's range.
|
|
492
|
+
_seedTimeAxis() {
|
|
493
|
+
const config = (this.component.config ?? {});
|
|
494
|
+
const span = config.xAxis?.span;
|
|
495
|
+
this.timeAxis.set(this.component.type === 'chart' && config.xAxis?.kind === 'time');
|
|
496
|
+
this.spanAllowed.set(this.timeAxis() && !this.component.sql);
|
|
497
|
+
this.dateLabel.set(config.xAxis?.dateLabel ?? ReportChartDateLabel.Short);
|
|
498
|
+
this.spanMode.set(span?.start
|
|
499
|
+
? ReportChartSpanMode.Start
|
|
500
|
+
: (span?.periods ? ReportChartSpanMode.Periods : ReportChartSpanMode.None));
|
|
501
|
+
this.spanPeriods.set(span?.periods ?? CHART_SPAN_DEFAULT_PERIODS);
|
|
502
|
+
this.spanStart.set(dateFromBound(span?.start));
|
|
503
|
+
}
|
|
504
|
+
// Short is what an absent dateLabel reads, so it is saved as absent. A
|
|
505
|
+
// chart that cannot take a span keeps the one it has (none).
|
|
506
|
+
_chartAxisSettings() {
|
|
507
|
+
return {
|
|
508
|
+
dateLabel: this.dateLabel() === ReportChartDateLabel.Short ? null : this.dateLabel(),
|
|
509
|
+
span: this.spanAllowed() ? this._span() : chartAxisSettings(this.component.config).span,
|
|
510
|
+
};
|
|
511
|
+
}
|
|
512
|
+
_span() {
|
|
513
|
+
const through = ReportChartSpanThrough.FilterEnd;
|
|
514
|
+
switch (this.spanMode()) {
|
|
515
|
+
case ReportChartSpanMode.Periods:
|
|
516
|
+
return { through, periods: this._number(this.spanPeriods()) ?? CHART_SPAN_DEFAULT_PERIODS };
|
|
517
|
+
case ReportChartSpanMode.Start: {
|
|
518
|
+
const start = dateToBound(this.spanStart());
|
|
519
|
+
return start ? { through, start } : null;
|
|
520
|
+
}
|
|
521
|
+
default:
|
|
522
|
+
return null;
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
// The axis keys as the settings route takes them: the span only from a
|
|
526
|
+
// chart that can take one.
|
|
527
|
+
_sentAxisKeys(axis) {
|
|
528
|
+
return this.spanAllowed() ? { ...axis } : { dateLabel: axis.dateLabel };
|
|
529
|
+
}
|
|
530
|
+
// The axis keys the server saved, from the config its response carries;
|
|
531
|
+
// null when it carries none.
|
|
532
|
+
_savedChartAxis(response) {
|
|
533
|
+
const config = response?.config;
|
|
534
|
+
return config && typeof config === 'object' ? chartAxisSettings(config) : null;
|
|
535
|
+
}
|
|
432
536
|
// The card keys the server saved, from the config its response carries;
|
|
433
537
|
// null when it carries none (a server that does not save them).
|
|
434
538
|
_savedKpiCard(response) {
|
|
@@ -587,12 +691,13 @@ export class ComponentSettingsComponent {
|
|
|
587
691
|
.replace(/\b\w/g, (character) => character.toUpperCase());
|
|
588
692
|
}
|
|
589
693
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ComponentSettingsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
590
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ComponentSettingsComponent, isStandalone: true, selector: "ng-component", viewQueries: [{ propertyName: "_titleInput", first: true, predicate: ["titleInput"], descendants: true, isSignal: true }], ngImport: i0, template: "<form\n fsForm\n [submit]=\"save\">\n <fs-dialog>\n <h1 mat-dialog-title>\n {{ heading() }}\n </h1>\n <mat-dialog-content>\n <mat-tab-group [(selected)]=\"selectedTab\">\n <mat-tab\n label=\"Settings\"\n name=\"settings\">\n <div class=\"fs-column tab-body\">\n <!-- A value's Name is just its name. A title may carry the page,\n report and filter fields a text block's words do: Insert\n field puts one in at the caret, and the hint says how the\n title reads where the component is drawn. -->\n @if (isValue()) {\n <mat-form-field>\n <mat-label>\n Name\n </mat-label>\n <input\n matInput\n [ngModel]=\"title()\"\n (ngModelChange)=\"title.set($event)\"\n name=\"title\"\n [fsFormRequired]=\"true\">\n </mat-form-field>\n } @else {\n <mat-form-field>\n <mat-label>\n Title\n </mat-label>\n <input\n #titleInput\n matInput\n [ngModel]=\"title()\"\n (ngModelChange)=\"title.set($event)\"\n name=\"title\">\n <!-- The button swallows its own click: the form field would\n otherwise put focus back in the input while the menu is\n open, and a key pressed then would move the caret the\n field goes in at. -->\n <button\n mat-icon-button\n matIconSuffix\n type=\"button\"\n aria-label=\"Insert field\"\n [fsMenuTriggerFor]=\"insertFieldMenu\"\n (click)=\"$event.stopPropagation()\">\n <mat-icon>sell</mat-icon>\n </button>\n @if (titleShownAs()) {\n <mat-hint>\n Shows as: {{ titleShownAs() }}\n </mat-hint>\n }\n </mat-form-field>\n <fs-menu #insertFieldMenu>\n @for (entry of titleFields(); track entry.field) {\n <ng-template\n fs-menu-item\n (click)=\"insertField(entry.field)\">\n {{ entry.name }}\n </ng-template>\n }\n </fs-menu>\n }\n <!-- A formula value is read-only beyond its name: what it works\n out is the AI's to change. A formula this viewer cannot\n read has no line, and no row. -->\n @if (formulaLine()) {\n <fs-label-field>\n <fs-label>\n Formula\n </fs-label>\n {{ formulaLine() }}\n <fs-label-message>\n Worked out on the server; it follows the filters of the values it reads.\n </fs-label-message>\n </fs-label-field>\n }\n <!-- A value sits inside a text block's words: no box, no padding. -->\n @if (!isValue()) {\n <div class=\"subheading-2\">\n Padding\n </div>\n <div class=\"geometry-row\">\n <mat-form-field>\n <mat-label>\n Top\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"3\"\n [(ngModel)]=\"paddingTop\"\n name=\"paddingTop\"\n [fsFormMin]=\"0\">\n <div matTextSuffix>\n in\n </div>\n </mat-form-field>\n <mat-form-field>\n <mat-label>\n Right\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"3\"\n [(ngModel)]=\"paddingRight\"\n name=\"paddingRight\"\n [fsFormMin]=\"0\">\n <div matTextSuffix>\n in\n </div>\n </mat-form-field>\n <mat-form-field>\n <mat-label>\n Bottom\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"3\"\n [(ngModel)]=\"paddingBottom\"\n name=\"paddingBottom\"\n [fsFormMin]=\"0\">\n <div matTextSuffix>\n in\n </div>\n </mat-form-field>\n <mat-form-field>\n <mat-label>\n Left\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"3\"\n [(ngModel)]=\"paddingLeft\"\n name=\"paddingLeft\"\n [fsFormMin]=\"0\">\n <div matTextSuffix>\n in\n </div>\n </mat-form-field>\n </div>\n }\n <!-- A derived KPI's card: what a rise means, a target and a\n sparkline. The server computes the progress and the points. -->\n @if (kpiCard()) {\n <div class=\"subheading-2\">\n Card\n </div>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Increase is\n </mat-label>\n <mat-select\n [ngModel]=\"increaseIs()\"\n (ngModelChange)=\"increaseIs.set($event)\"\n name=\"increaseIs\">\n @for (option of kpiPolarityOptions; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n </mat-select>\n <mat-hint>\n Colors the change and decides when the target is met.\n </mat-hint>\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Target\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"6\"\n [signed]=\"true\"\n [ngModel]=\"targetValue()\"\n (ngModelChange)=\"targetValue.set($event)\"\n name=\"targetValue\"\n [validate]=\"validateTarget\">\n @if (targetPercent()) {\n <div matTextSuffix>\n %\n </div>\n }\n <mat-hint>\n The value to reach. Leave empty for no target.\n </mat-hint>\n </mat-form-field>\n @if (hasTarget()) {\n <mat-form-field class=\"full-width\">\n <mat-label>\n Target label\n </mat-label>\n <input\n matInput\n [ngModel]=\"targetLabel()\"\n (ngModelChange)=\"targetLabel.set($event)\"\n name=\"targetLabel\">\n <mat-hint>\n Shown before the target, such as Goal. Empty reads Target.\n </mat-hint>\n </mat-form-field>\n }\n <fs-label-field>\n <mat-slide-toggle\n [ngModel]=\"sparkline()\"\n (ngModelChange)=\"sparkline.set($event)\"\n name=\"sparkline\">\n Sparkline\n </mat-slide-toggle>\n <mat-hint>\n A small trend line of the value over its last periods.\n </mat-hint>\n </fs-label-field>\n @if (sparkline()) {\n <mat-form-field class=\"full-width\">\n <mat-label>\n Sparkline period\n </mat-label>\n <mat-select\n [ngModel]=\"sparklineGranularity()\"\n (ngModelChange)=\"sparklineGranularity.set($event)\"\n name=\"sparklineGranularity\">\n @for (option of granularityOptions; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Sparkline periods\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"0\"\n [ngModel]=\"sparklinePeriods()\"\n (ngModelChange)=\"sparklinePeriods.set($event)\"\n name=\"sparklinePeriods\"\n [fsFormRequired]=\"true\"\n [fsFormInteger]=\"true\"\n [fsFormMin]=\"sparklineMinPeriods\"\n [fsFormMax]=\"sparklineMaxPeriods\">\n <mat-hint>\n How many periods the line covers, {{ sparklineMinPeriods }} to {{ sparklineMaxPeriods }}.\n </mat-hint>\n </mat-form-field>\n }\n }\n </div>\n </mat-tab>\n <!-- A formula runs no statement and follows the filters of the values\n it reads, so it has neither a Filters nor an SQL tab. -->\n @if (!isFormula()) {\n <mat-tab\n label=\"Filters\"\n name=\"filters\">\n <div class=\"tab-body\">\n @if (columnsError()) {\n <div class=\"filters-empty error\">\n {{ columnsError() }}\n </div>\n } @else if (rows().length) {\n <!-- Every filterable column. Pick where its control shows: in\n the report bar (every page, or this page only), on this\n component, both, or neither. The interface follows the\n data; a numeric column can be values or a number range.\n A value sits inside text and has no component to show a\n control on, so it gets the report bar column only. -->\n <table class=\"filter-table\">\n <thead>\n <tr>\n <th class=\"filter-col-name\">\n Filter\n </th>\n <th class=\"filter-col-type\">\n Type\n </th>\n <th class=\"filter-col-select\">\n Report bar\n </th>\n @if (!isValue()) {\n <th class=\"filter-col-toggle\">\n This component\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (row of rows(); track row.column) {\n <tr>\n <td class=\"filter-col-name\">\n {{ row.label }}\n </td>\n <td class=\"filter-col-type\">\n @if (row.typeSelect.show) {\n <mat-form-field\n [subscriptSizing]=\"'dynamic'\"\n [matTooltip]=\"row.typeSelect.tooltip\">\n <mat-select\n [panelWidth]=\"null\"\n [ngModel]=\"row.type\"\n (ngModelChange)=\"setType(row, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n [disabled]=\"row.typeSelect.disabled\"\n aria-label=\"Type\">\n @for (option of typeOptions; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n } @else {\n {{ typeLabel(row.type) }}\n }\n </td>\n <td class=\"filter-col-select\">\n <mat-form-field [subscriptSizing]=\"'dynamic'\">\n <mat-select\n [panelWidth]=\"null\"\n [ngModel]=\"row.placement\"\n (ngModelChange)=\"setPlacement(row, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n aria-label=\"Report bar\">\n @for (option of row.placementOptions; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </td>\n @if (!isValue()) {\n <td class=\"filter-col-toggle\">\n <mat-slide-toggle\n [ngModel]=\"row.component\"\n (ngModelChange)=\"setComponent(row, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n [disabled]=\"row.componentToggle.disabled\"\n [matTooltip]=\"row.componentToggle.tooltip\">\n </mat-slide-toggle>\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n } @else {\n <div class=\"filters-empty\">\n This component has no filterable columns yet \u2014 give it some SQL first.\n </div>\n }\n </div>\n </mat-tab>\n <mat-tab\n label=\"SQL\"\n name=\"sql\">\n <div class=\"tab-body\">\n @if (sqlError()) {\n <div class=\"filters-empty error\">\n {{ sqlError() }}\n </div>\n } @else if (sql()) {\n @if (sqlBaseline()) {\n <!-- A derived component's statement is compiled from its\n document with no viewer state, so it is not byte-for-byte\n what produced the numbers on screen. Said here rather than\n left for the reader to discover. -->\n <div class=\"filters-empty\">\n Compiled from this component's query \u2014 no filters applied, times in {{ sqlTimezone() }}.\n </div>\n }\n <pre class=\"code-block\">{{ sql() }}</pre>\n } @else {\n <div class=\"filters-empty\">\n This component has no SQL yet.\n </div>\n }\n </div>\n </mat-tab>\n }\n <mat-tab\n label=\"Config\"\n name=\"config\">\n <div class=\"tab-body\">\n <pre class=\"code-block\">\n {{ configJson }}\n </pre>\n </div>\n </mat-tab>\n </mat-tab-group>\n </mat-dialog-content>\n <mat-dialog-actions>\n <!-- Save | Delete | Cancel, the standard order. fs-form-dialog-actions\n renders its own Save/Done BEFORE the projected content, which would\n put Delete after Cancel, so `[save]=\"false\"` foots the row here and\n all three buttons are projected in order. Save submits the Settings\n tab; the other tabs persist as you touch them, so they get Done. -->\n <fs-form-dialog-actions [save]=\"false\">\n @if (selectedTab === 'settings') {\n <button\n mat-button\n type=\"submit\"\n color=\"primary\">\n Save\n </button>\n } @else {\n <button\n mat-button\n type=\"button\"\n color=\"primary\"\n [mat-dialog-close]=\"null\">\n Done\n </button>\n }\n <button\n mat-button\n type=\"button\"\n color=\"warn\"\n (click)=\"delete()\">\n Delete\n </button>\n <button\n mat-button\n type=\"button\"\n class=\"cancel-button\"\n [mat-dialog-close]=\"null\">\n Cancel\n </button>\n </fs-form-dialog-actions>\n </mat-dialog-actions>\n </fs-dialog>\n</form>", styles: ["mat-form-field{width:100%}.tab-body{padding-top:16px}.geometry-row{display:flex;gap:8px}.geometry-row mat-form-field{flex:1}.filter-table{border-spacing:0;width:100%;border-collapse:collapse}.filter-table thead th{color:#8f8f8f;font-weight:400;font-size:85%;text-align:left;padding:8px 16px}.filter-table tbody tr{clip-path:xywh(0 3px 100% calc(100% - 6px) round 10px)}.filter-table tbody td{border:none;background-color:#fafafa;padding:8px 16px;vertical-align:middle;text-align:left}.filter-table .filter-col-name{font-weight:600;color:#1f2933}.filter-table .filter-col-type{color:#7b8794;width:150px}.filter-table .filter-col-select{width:160px}.filter-table td.filter-col-type,.filter-table td.filter-col-select{padding-left:8px;padding-right:8px}.filter-table td.filter-col-type mat-form-field,.filter-table td.filter-col-select mat-form-field{width:100%;--mat-form-field-container-height: 36px;--mat-form-field-container-vertical-padding: 6px}.filter-table td.filter-col-type ::ng-deep .mat-mdc-form-field-infix,.filter-table td.filter-col-select ::ng-deep .mat-mdc-form-field-infix{width:auto}.filter-table td.filter-col-type ::ng-deep .mat-mdc-form-field-subscript-wrapper,.filter-table td.filter-col-select ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}.filter-table .filter-col-toggle,.filter-table th.filter-col-toggle{width:110px;text-align:center}.filters-empty{font-size:13px;color:#7b8794;padding:8px 0 4px}.filters-empty.error{color:#e15759}.code-block{margin:0;padding:10px 12px;background:#1f2933;color:#e4e7eb;border-radius:6px;font-family:JetBrains Mono,Consolas,monospace;font-size:12px;line-height:1.5;white-space:pre-wrap;word-break:break-word;max-height:240px;overflow:auto}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: FsFormModule }, { kind: "directive", type: i2.FsFormDirective, selector: "[fsForm]", inputs: ["wrapperSelector", "messageSelector", "hintSelector", "labelSelector", "autocomplete", "shortcuts", "confirm", "confirmDialog", "confirmDrawer", "confirmBrowser", "dirtySubmitButton", "submit", "successDelay", "errorDelay", "deactivationGuard"], outputs: ["fsForm", "invalid", "valid", "submitted", "reseted", "cleared"], exportAs: ["fsForm"] }, { kind: "directive", type: i2.FsFormRequiredDirective, selector: "[fsFormRequired],[ngModel][required]", inputs: ["fsFormRequired", "required", "fsFormRequiredMessage"] }, { kind: "directive", type: i2.FsFormMinDirective, selector: "[fsFormMin]", inputs: ["fsFormMin", "fsFormMinMessage"] }, { kind: "directive", type: i2.FsFormMaxDirective, selector: "[fsFormMax]", inputs: ["fsFormMax", "fsFormMaxMessage"] }, { kind: "directive", type: i2.FsFormIntegerDirective, selector: "[fsFormInteger]", inputs: ["fsFormInteger", "fsFormIntegerMessage"] }, { kind: "directive", type: i2.FsFormValidateDirective, selector: "[validate]", inputs: ["validate", "validateData", "validateOnSubmit"] }, { kind: "component", type: i2.FsFormDialogActionsComponent, selector: "fs-form-dialog-actions", inputs: ["save", "create", "close", "done", "closeData", "name"] }, { kind: "directive", type: i2.FsFormNoFsValidatorsDirective, selector: "[ngModel]:not([required]):not([fsFormRequired]):not([fsFormCompare]):not([fsFormDateRange]):not([fsFormEmail]):not([fsFormEmails]):not([fsFormFunction]):not([fsFormGreater]):not([fsFormGreaterEqual]):not([fsFormInteger]):not([fsFormLesser]):not([fsFormMax]):not([fsFormMaxLength]):not([fsFormMin]):not([fsFormMinLength]):not([fsFormNumeric]):not([fsFormPattern]):not([fsFormPhone]):not([fsFormUrl]):not([validate])" }, { kind: "directive", type: i2.FsButtonDirective, selector: "[mat-raised-button],[mat-button],[mat-flat-button],[mat-stroked-button]", inputs: ["name", "dirtySubmit"] }, { kind: "ngmodule", type: FsMaskModule }, { kind: "directive", type: i3.FsMaskNumberDirective, selector: "[fsMaskNumber]" }, { kind: "ngmodule", type: FsDialogModule }, { kind: "component", type: i4.FsDialogComponent, selector: "fs-dialog", inputs: ["mobileMode", "mobileButtonPlacement", "mobileWidth", "mode", "buttonLayout"] }, { kind: "ngmodule", type: FsLabelModule }, { kind: "component", type: i5.FsLabelComponent, selector: "fs-label" }, { kind: "component", type: i5.FsLabelFieldComponent, selector: "fs-label-field", inputs: ["appearance", "showOutline", "disabled", "focused", "hoverable", "padless"] }, { kind: "component", type: i5.FsLabelMessageComponent, selector: "fs-label-message" }, { kind: "ngmodule", type: FsTabsModule }, { kind: "directive", type: i6.FsTabsHeaderTabGroupDirective, selector: "mat-tab-group, matTabGroup, [matTabGroup]", inputs: ["orientation", "selected", "selectedData"], outputs: ["selectedChange", "selectedDataChange"], exportAs: ["fsTabsHeaderTabGroup"] }, { kind: "directive", type: i6.FsTabsTabDirective, selector: "mat-tab,matTab", inputs: ["name", "data"], exportAs: ["fsTabsTab"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i7.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass"], exportAs: ["matTab"] }, { kind: "component", type: i7.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "directive", type: MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { 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: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: FsMenuModule }, { kind: "component", type: i8.FsMenuComponent, selector: "fs-menu", inputs: ["class", "buttonClass", "buttonType", "buttonColor"], outputs: ["opened", "closed"] }, { kind: "directive", type: i8.FsMenuItemDirective, selector: "fs-menu-group,[fs-menu-item]" }, { kind: "directive", type: i8.FsMenuTriggerDirective, selector: "[fsMenuTriggerFor]", inputs: ["fsMenuTriggerFor"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
694
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ComponentSettingsComponent, isStandalone: true, selector: "ng-component", viewQueries: [{ propertyName: "_titleInput", first: true, predicate: ["titleInput"], descendants: true, isSignal: true }], ngImport: i0, template: "<form\n fsForm\n [submit]=\"save\">\n <fs-dialog>\n <h1 mat-dialog-title>\n {{ heading() }}\n </h1>\n <mat-dialog-content>\n <mat-tab-group [(selected)]=\"selectedTab\">\n <mat-tab\n label=\"Settings\"\n name=\"settings\">\n <div class=\"fs-column tab-body\">\n <!-- A value's Name is just its name. A title may carry the page,\n report and filter fields a text block's words do: Insert\n field puts one in at the caret, and the hint says how the\n title reads where the component is drawn. -->\n @if (isValue()) {\n <mat-form-field>\n <mat-label>\n Name\n </mat-label>\n <input\n matInput\n [ngModel]=\"title()\"\n (ngModelChange)=\"title.set($event)\"\n name=\"title\"\n [fsFormRequired]=\"true\">\n </mat-form-field>\n } @else {\n <mat-form-field>\n <mat-label>\n Title\n </mat-label>\n <input\n #titleInput\n matInput\n [ngModel]=\"title()\"\n (ngModelChange)=\"title.set($event)\"\n name=\"title\">\n <!-- The button swallows its own click: the form field would\n otherwise put focus back in the input while the menu is\n open, and a key pressed then would move the caret the\n field goes in at. -->\n <button\n mat-icon-button\n matIconSuffix\n type=\"button\"\n aria-label=\"Insert field\"\n [fsMenuTriggerFor]=\"insertFieldMenu\"\n (click)=\"$event.stopPropagation()\">\n <mat-icon>sell</mat-icon>\n </button>\n @if (titleShownAs()) {\n <mat-hint>\n Shows as: {{ titleShownAs() }}\n </mat-hint>\n }\n </mat-form-field>\n <fs-menu #insertFieldMenu>\n @for (entry of titleFields(); track entry.field) {\n <ng-template\n fs-menu-item\n (click)=\"insertField(entry.field)\">\n {{ entry.name }}\n </ng-template>\n }\n </fs-menu>\n }\n <!-- A formula value is read-only beyond its name: what it works\n out is the AI's to change. A formula this viewer cannot\n read has no line, and no row. -->\n @if (formulaLine()) {\n <fs-label-field>\n <fs-label>\n Formula\n </fs-label>\n {{ formulaLine() }}\n <fs-label-message>\n Worked out on the server; it follows the filters of the values it reads.\n </fs-label-message>\n </fs-label-field>\n }\n <!-- A value sits inside a text block's words: no box, no padding. -->\n @if (!isValue()) {\n <div class=\"subheading-2\">\n Padding\n </div>\n <div class=\"geometry-row\">\n <mat-form-field>\n <mat-label>\n Top\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"3\"\n [(ngModel)]=\"paddingTop\"\n name=\"paddingTop\"\n [fsFormMin]=\"0\">\n <div matTextSuffix>\n in\n </div>\n </mat-form-field>\n <mat-form-field>\n <mat-label>\n Right\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"3\"\n [(ngModel)]=\"paddingRight\"\n name=\"paddingRight\"\n [fsFormMin]=\"0\">\n <div matTextSuffix>\n in\n </div>\n </mat-form-field>\n <mat-form-field>\n <mat-label>\n Bottom\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"3\"\n [(ngModel)]=\"paddingBottom\"\n name=\"paddingBottom\"\n [fsFormMin]=\"0\">\n <div matTextSuffix>\n in\n </div>\n </mat-form-field>\n <mat-form-field>\n <mat-label>\n Left\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"3\"\n [(ngModel)]=\"paddingLeft\"\n name=\"paddingLeft\"\n [fsFormMin]=\"0\">\n <div matTextSuffix>\n in\n </div>\n </mat-form-field>\n </div>\n }\n <!-- A derived KPI's card: what a rise means, a target and a\n sparkline. The server computes the progress and the points. -->\n @if (kpiCard()) {\n <div class=\"subheading-2\">\n Card\n </div>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Increase is\n </mat-label>\n <mat-select\n [ngModel]=\"increaseIs()\"\n (ngModelChange)=\"increaseIs.set($event)\"\n name=\"increaseIs\">\n @for (option of kpiPolarityOptions; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n </mat-select>\n <mat-hint>\n Colors the change and decides when the target is met.\n </mat-hint>\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Target\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"6\"\n [signed]=\"true\"\n [ngModel]=\"targetValue()\"\n (ngModelChange)=\"targetValue.set($event)\"\n name=\"targetValue\"\n [validate]=\"validateTarget\">\n @if (targetPercent()) {\n <div matTextSuffix>\n %\n </div>\n }\n <mat-hint>\n The value to reach. Leave empty for no target.\n </mat-hint>\n </mat-form-field>\n @if (hasTarget()) {\n <mat-form-field class=\"full-width\">\n <mat-label>\n Target label\n </mat-label>\n <input\n matInput\n [ngModel]=\"targetLabel()\"\n (ngModelChange)=\"targetLabel.set($event)\"\n name=\"targetLabel\">\n <mat-hint>\n Shown before the target, such as Goal. Empty reads Target.\n </mat-hint>\n </mat-form-field>\n }\n <fs-label-field>\n <mat-slide-toggle\n [ngModel]=\"sparkline()\"\n (ngModelChange)=\"sparkline.set($event)\"\n name=\"sparkline\">\n Sparkline\n </mat-slide-toggle>\n <mat-hint>\n A small trend line of the value over its last periods.\n </mat-hint>\n </fs-label-field>\n @if (sparkline()) {\n <mat-form-field class=\"full-width\">\n <mat-label>\n Sparkline period\n </mat-label>\n <mat-select\n [ngModel]=\"sparklineGranularity()\"\n (ngModelChange)=\"sparklineGranularity.set($event)\"\n name=\"sparklineGranularity\">\n @for (option of granularityOptions; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Sparkline periods\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"0\"\n [ngModel]=\"sparklinePeriods()\"\n (ngModelChange)=\"sparklinePeriods.set($event)\"\n name=\"sparklinePeriods\"\n [fsFormRequired]=\"true\"\n [fsFormInteger]=\"true\"\n [fsFormMin]=\"sparklineMinPeriods\"\n [fsFormMax]=\"sparklineMaxPeriods\">\n <mat-hint>\n How many periods the line covers, {{ sparklineMinPeriods }} to {{ sparklineMaxPeriods }}.\n </mat-hint>\n </mat-form-field>\n }\n }\n <!-- A chart over time: how its periods are labelled and, on a\n derived chart, which periods it draws. The server runs the\n span, so the screen and every export draw the same periods;\n the KPIs and values on the page keep the date filter's range. -->\n @if (timeAxis()) {\n <div class=\"subheading-2\">\n Time axis\n </div>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Date labels\n </mat-label>\n <mat-select\n [ngModel]=\"dateLabel()\"\n (ngModelChange)=\"dateLabel.set($event)\"\n name=\"dateLabel\">\n @for (option of dateLabelOptions; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n </mat-select>\n <mat-hint>\n Period end labels each period by its last day: a week by its Sunday.\n </mat-hint>\n </mat-form-field>\n @if (spanAllowed()) {\n <mat-form-field class=\"full-width\">\n <mat-label>\n Periods shown\n </mat-label>\n <mat-select\n [ngModel]=\"spanMode()\"\n (ngModelChange)=\"spanMode.set($event)\"\n name=\"spanMode\">\n @for (option of spanModeOptions; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n </mat-select>\n <mat-hint>\n With no date filter set, the chart ends at the current period.\n </mat-hint>\n </mat-form-field>\n @if (spanMode() === ReportChartSpanMode.Periods) {\n <mat-form-field class=\"full-width\">\n <mat-label>\n Periods\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"0\"\n [ngModel]=\"spanPeriods()\"\n (ngModelChange)=\"spanPeriods.set($event)\"\n name=\"spanPeriods\"\n [fsFormRequired]=\"true\"\n [fsFormInteger]=\"true\"\n [fsFormMin]=\"spanMinPeriods\"\n [fsFormMax]=\"spanMaxPeriods\">\n <mat-hint>\n How many periods the chart draws, {{ spanMinPeriods }} to {{ spanMaxPeriods }}; 3 on a monthly chart is the last three months.\n </mat-hint>\n </mat-form-field>\n } @else if (spanMode() === ReportChartSpanMode.Start) {\n <mat-form-field class=\"full-width\">\n <mat-label>\n Since\n </mat-label>\n <input\n matInput\n fsDatePicker\n [ngModel]=\"spanStart()\"\n (ngModelChange)=\"spanStart.set($event)\"\n name=\"spanStart\"\n [fsFormRequired]=\"true\">\n <mat-hint>\n The chart draws every period from this day, such as a go-live.\n </mat-hint>\n </mat-form-field>\n }\n }\n }\n </div>\n </mat-tab>\n <!-- A formula runs no statement and follows the filters of the values\n it reads, so it has neither a Filters nor an SQL tab. -->\n @if (!isFormula()) {\n <mat-tab\n label=\"Filters\"\n name=\"filters\">\n <div class=\"tab-body\">\n @if (columnsError()) {\n <div class=\"filters-empty error\">\n {{ columnsError() }}\n </div>\n } @else if (rows().length) {\n <!-- Every filterable column. Pick where its control shows: in\n the report bar (every page, or this page only), on this\n component, both, or neither. The interface follows the\n data; a numeric column can be values or a number range.\n A value sits inside text and has no component to show a\n control on, so it gets the report bar column only. -->\n <table class=\"filter-table\">\n <thead>\n <tr>\n <th class=\"filter-col-name\">\n Filter\n </th>\n <th class=\"filter-col-type\">\n Type\n </th>\n <th class=\"filter-col-select\">\n Report bar\n </th>\n @if (!isValue()) {\n <th class=\"filter-col-toggle\">\n This component\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (row of rows(); track row.column) {\n <tr>\n <td class=\"filter-col-name\">\n {{ row.label }}\n </td>\n <td class=\"filter-col-type\">\n @if (row.typeSelect.show) {\n <mat-form-field\n [subscriptSizing]=\"'dynamic'\"\n [matTooltip]=\"row.typeSelect.tooltip\">\n <mat-select\n [panelWidth]=\"null\"\n [ngModel]=\"row.type\"\n (ngModelChange)=\"setType(row, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n [disabled]=\"row.typeSelect.disabled\"\n aria-label=\"Type\">\n @for (option of typeOptions; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n } @else {\n {{ typeLabel(row.type) }}\n }\n </td>\n <td class=\"filter-col-select\">\n <mat-form-field [subscriptSizing]=\"'dynamic'\">\n <mat-select\n [panelWidth]=\"null\"\n [ngModel]=\"row.placement\"\n (ngModelChange)=\"setPlacement(row, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n aria-label=\"Report bar\">\n @for (option of row.placementOptions; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </td>\n @if (!isValue()) {\n <td class=\"filter-col-toggle\">\n <mat-slide-toggle\n [ngModel]=\"row.component\"\n (ngModelChange)=\"setComponent(row, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n [disabled]=\"row.componentToggle.disabled\"\n [matTooltip]=\"row.componentToggle.tooltip\">\n </mat-slide-toggle>\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n } @else {\n <div class=\"filters-empty\">\n This component has no filterable columns yet \u2014 give it some SQL first.\n </div>\n }\n </div>\n </mat-tab>\n <mat-tab\n label=\"SQL\"\n name=\"sql\">\n <div class=\"tab-body\">\n @if (sqlError()) {\n <div class=\"filters-empty error\">\n {{ sqlError() }}\n </div>\n } @else if (sql()) {\n @if (sqlBaseline()) {\n <!-- A derived component's statement is compiled from its\n document with no viewer state, so it is not byte-for-byte\n what produced the numbers on screen. Said here rather than\n left for the reader to discover. -->\n <div class=\"filters-empty\">\n Compiled from this component's query \u2014 no filters applied, times in {{ sqlTimezone() }}.\n </div>\n }\n <pre class=\"code-block\">{{ sql() }}</pre>\n } @else {\n <div class=\"filters-empty\">\n This component has no SQL yet.\n </div>\n }\n </div>\n </mat-tab>\n }\n <mat-tab\n label=\"Config\"\n name=\"config\">\n <div class=\"tab-body\">\n <pre class=\"code-block\">\n {{ configJson }}\n </pre>\n </div>\n </mat-tab>\n </mat-tab-group>\n </mat-dialog-content>\n <mat-dialog-actions>\n <!-- Save | Delete | Cancel, the standard order. fs-form-dialog-actions\n renders its own Save/Done BEFORE the projected content, which would\n put Delete after Cancel, so `[save]=\"false\"` foots the row here and\n all three buttons are projected in order. Save submits the Settings\n tab; the other tabs persist as you touch them, so they get Done. -->\n <fs-form-dialog-actions [save]=\"false\">\n @if (selectedTab === 'settings') {\n <button\n mat-button\n type=\"submit\"\n color=\"primary\">\n Save\n </button>\n } @else {\n <button\n mat-button\n type=\"button\"\n color=\"primary\"\n [mat-dialog-close]=\"null\">\n Done\n </button>\n }\n <button\n mat-button\n type=\"button\"\n color=\"warn\"\n (click)=\"delete()\">\n Delete\n </button>\n <button\n mat-button\n type=\"button\"\n class=\"cancel-button\"\n [mat-dialog-close]=\"null\">\n Cancel\n </button>\n </fs-form-dialog-actions>\n </mat-dialog-actions>\n </fs-dialog>\n</form>", styles: ["mat-form-field{width:100%}.tab-body{padding-top:16px}.geometry-row{display:flex;gap:8px}.geometry-row mat-form-field{flex:1}.filter-table{border-spacing:0;width:100%;border-collapse:collapse}.filter-table thead th{color:#8f8f8f;font-weight:400;font-size:85%;text-align:left;padding:8px 16px}.filter-table tbody tr{clip-path:xywh(0 3px 100% calc(100% - 6px) round 10px)}.filter-table tbody td{border:none;background-color:#fafafa;padding:8px 16px;vertical-align:middle;text-align:left}.filter-table .filter-col-name{font-weight:600;color:#1f2933}.filter-table .filter-col-type{color:#7b8794;width:150px}.filter-table .filter-col-select{width:160px}.filter-table td.filter-col-type,.filter-table td.filter-col-select{padding-left:8px;padding-right:8px}.filter-table td.filter-col-type mat-form-field,.filter-table td.filter-col-select mat-form-field{width:100%;--mat-form-field-container-height: 36px;--mat-form-field-container-vertical-padding: 6px}.filter-table td.filter-col-type ::ng-deep .mat-mdc-form-field-infix,.filter-table td.filter-col-select ::ng-deep .mat-mdc-form-field-infix{width:auto}.filter-table td.filter-col-type ::ng-deep .mat-mdc-form-field-subscript-wrapper,.filter-table td.filter-col-select ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}.filter-table .filter-col-toggle,.filter-table th.filter-col-toggle{width:110px;text-align:center}.filters-empty{font-size:13px;color:#7b8794;padding:8px 0 4px}.filters-empty.error{color:#e15759}.code-block{margin:0;padding:10px 12px;background:#1f2933;color:#e4e7eb;border-radius:6px;font-family:JetBrains Mono,Consolas,monospace;font-size:12px;line-height:1.5;white-space:pre-wrap;word-break:break-word;max-height:240px;overflow:auto}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: FsDatePickerModule }, { kind: "component", type: i2.FsDatePickerComponent, selector: "[fsDatePicker]", inputs: ["minYear", "maxYear", "minDate", "maxDate", "startOfDay", "view", "format", "minutes", "width"], outputs: ["change"] }, { kind: "ngmodule", type: FsFormModule }, { kind: "directive", type: i3.FsFormDirective, selector: "[fsForm]", inputs: ["wrapperSelector", "messageSelector", "hintSelector", "labelSelector", "autocomplete", "shortcuts", "confirm", "confirmDialog", "confirmDrawer", "confirmBrowser", "dirtySubmitButton", "submit", "successDelay", "errorDelay", "deactivationGuard"], outputs: ["fsForm", "invalid", "valid", "submitted", "reseted", "cleared"], exportAs: ["fsForm"] }, { kind: "directive", type: i3.FsFormRequiredDirective, selector: "[fsFormRequired],[ngModel][required]", inputs: ["fsFormRequired", "required", "fsFormRequiredMessage"] }, { kind: "directive", type: i3.FsFormMinDirective, selector: "[fsFormMin]", inputs: ["fsFormMin", "fsFormMinMessage"] }, { kind: "directive", type: i3.FsFormMaxDirective, selector: "[fsFormMax]", inputs: ["fsFormMax", "fsFormMaxMessage"] }, { kind: "directive", type: i3.FsFormIntegerDirective, selector: "[fsFormInteger]", inputs: ["fsFormInteger", "fsFormIntegerMessage"] }, { kind: "directive", type: i3.FsFormValidateDirective, selector: "[validate]", inputs: ["validate", "validateData", "validateOnSubmit"] }, { kind: "component", type: i3.FsFormDialogActionsComponent, selector: "fs-form-dialog-actions", inputs: ["save", "create", "close", "done", "closeData", "name"] }, { kind: "directive", type: i3.FsFormNoFsValidatorsDirective, selector: "[ngModel]:not([required]):not([fsFormRequired]):not([fsFormCompare]):not([fsFormDateRange]):not([fsFormEmail]):not([fsFormEmails]):not([fsFormFunction]):not([fsFormGreater]):not([fsFormGreaterEqual]):not([fsFormInteger]):not([fsFormLesser]):not([fsFormMax]):not([fsFormMaxLength]):not([fsFormMin]):not([fsFormMinLength]):not([fsFormNumeric]):not([fsFormPattern]):not([fsFormPhone]):not([fsFormUrl]):not([validate])" }, { kind: "directive", type: i3.FsButtonDirective, selector: "[mat-raised-button],[mat-button],[mat-flat-button],[mat-stroked-button]", inputs: ["name", "dirtySubmit"] }, { kind: "ngmodule", type: FsMaskModule }, { kind: "directive", type: i4.FsMaskNumberDirective, selector: "[fsMaskNumber]" }, { kind: "ngmodule", type: FsDialogModule }, { kind: "component", type: i5.FsDialogComponent, selector: "fs-dialog", inputs: ["mobileMode", "mobileButtonPlacement", "mobileWidth", "mode", "buttonLayout"] }, { kind: "ngmodule", type: FsLabelModule }, { kind: "component", type: i6.FsLabelComponent, selector: "fs-label" }, { kind: "component", type: i6.FsLabelFieldComponent, selector: "fs-label-field", inputs: ["appearance", "showOutline", "disabled", "focused", "hoverable", "padless"] }, { kind: "component", type: i6.FsLabelMessageComponent, selector: "fs-label-message" }, { kind: "ngmodule", type: FsTabsModule }, { kind: "directive", type: i7.FsTabsHeaderTabGroupDirective, selector: "mat-tab-group, matTabGroup, [matTabGroup]", inputs: ["orientation", "selected", "selectedData"], outputs: ["selectedChange", "selectedDataChange"], exportAs: ["fsTabsHeaderTabGroup"] }, { kind: "directive", type: i7.FsTabsTabDirective, selector: "mat-tab,matTab", inputs: ["name", "data"], exportAs: ["fsTabsTab"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i8.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass"], exportAs: ["matTab"] }, { kind: "component", type: i8.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "directive", type: MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { 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: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: FsMenuModule }, { kind: "component", type: i9.FsMenuComponent, selector: "fs-menu", inputs: ["class", "buttonClass", "buttonType", "buttonColor"], outputs: ["opened", "closed"] }, { kind: "directive", type: i9.FsMenuItemDirective, selector: "fs-menu-group,[fs-menu-item]" }, { kind: "directive", type: i9.FsMenuTriggerDirective, selector: "[fsMenuTriggerFor]", inputs: ["fsMenuTriggerFor"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
591
695
|
}
|
|
592
696
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ComponentSettingsComponent, decorators: [{
|
|
593
697
|
type: Component,
|
|
594
698
|
args: [{ changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
|
|
595
699
|
FormsModule,
|
|
700
|
+
FsDatePickerModule,
|
|
596
701
|
FsFormModule,
|
|
597
702
|
FsMaskModule,
|
|
598
703
|
FsDialogModule,
|
|
@@ -616,6 +721,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
616
721
|
MatSlideToggle,
|
|
617
722
|
MatTooltip,
|
|
618
723
|
FsMenuModule,
|
|
619
|
-
], template: "<form\n fsForm\n [submit]=\"save\">\n <fs-dialog>\n <h1 mat-dialog-title>\n {{ heading() }}\n </h1>\n <mat-dialog-content>\n <mat-tab-group [(selected)]=\"selectedTab\">\n <mat-tab\n label=\"Settings\"\n name=\"settings\">\n <div class=\"fs-column tab-body\">\n <!-- A value's Name is just its name. A title may carry the page,\n report and filter fields a text block's words do: Insert\n field puts one in at the caret, and the hint says how the\n title reads where the component is drawn. -->\n @if (isValue()) {\n <mat-form-field>\n <mat-label>\n Name\n </mat-label>\n <input\n matInput\n [ngModel]=\"title()\"\n (ngModelChange)=\"title.set($event)\"\n name=\"title\"\n [fsFormRequired]=\"true\">\n </mat-form-field>\n } @else {\n <mat-form-field>\n <mat-label>\n Title\n </mat-label>\n <input\n #titleInput\n matInput\n [ngModel]=\"title()\"\n (ngModelChange)=\"title.set($event)\"\n name=\"title\">\n <!-- The button swallows its own click: the form field would\n otherwise put focus back in the input while the menu is\n open, and a key pressed then would move the caret the\n field goes in at. -->\n <button\n mat-icon-button\n matIconSuffix\n type=\"button\"\n aria-label=\"Insert field\"\n [fsMenuTriggerFor]=\"insertFieldMenu\"\n (click)=\"$event.stopPropagation()\">\n <mat-icon>sell</mat-icon>\n </button>\n @if (titleShownAs()) {\n <mat-hint>\n Shows as: {{ titleShownAs() }}\n </mat-hint>\n }\n </mat-form-field>\n <fs-menu #insertFieldMenu>\n @for (entry of titleFields(); track entry.field) {\n <ng-template\n fs-menu-item\n (click)=\"insertField(entry.field)\">\n {{ entry.name }}\n </ng-template>\n }\n </fs-menu>\n }\n <!-- A formula value is read-only beyond its name: what it works\n out is the AI's to change. A formula this viewer cannot\n read has no line, and no row. -->\n @if (formulaLine()) {\n <fs-label-field>\n <fs-label>\n Formula\n </fs-label>\n {{ formulaLine() }}\n <fs-label-message>\n Worked out on the server; it follows the filters of the values it reads.\n </fs-label-message>\n </fs-label-field>\n }\n <!-- A value sits inside a text block's words: no box, no padding. -->\n @if (!isValue()) {\n <div class=\"subheading-2\">\n Padding\n </div>\n <div class=\"geometry-row\">\n <mat-form-field>\n <mat-label>\n Top\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"3\"\n [(ngModel)]=\"paddingTop\"\n name=\"paddingTop\"\n [fsFormMin]=\"0\">\n <div matTextSuffix>\n in\n </div>\n </mat-form-field>\n <mat-form-field>\n <mat-label>\n Right\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"3\"\n [(ngModel)]=\"paddingRight\"\n name=\"paddingRight\"\n [fsFormMin]=\"0\">\n <div matTextSuffix>\n in\n </div>\n </mat-form-field>\n <mat-form-field>\n <mat-label>\n Bottom\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"3\"\n [(ngModel)]=\"paddingBottom\"\n name=\"paddingBottom\"\n [fsFormMin]=\"0\">\n <div matTextSuffix>\n in\n </div>\n </mat-form-field>\n <mat-form-field>\n <mat-label>\n Left\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"3\"\n [(ngModel)]=\"paddingLeft\"\n name=\"paddingLeft\"\n [fsFormMin]=\"0\">\n <div matTextSuffix>\n in\n </div>\n </mat-form-field>\n </div>\n }\n <!-- A derived KPI's card: what a rise means, a target and a\n sparkline. The server computes the progress and the points. -->\n @if (kpiCard()) {\n <div class=\"subheading-2\">\n Card\n </div>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Increase is\n </mat-label>\n <mat-select\n [ngModel]=\"increaseIs()\"\n (ngModelChange)=\"increaseIs.set($event)\"\n name=\"increaseIs\">\n @for (option of kpiPolarityOptions; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n </mat-select>\n <mat-hint>\n Colors the change and decides when the target is met.\n </mat-hint>\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Target\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"6\"\n [signed]=\"true\"\n [ngModel]=\"targetValue()\"\n (ngModelChange)=\"targetValue.set($event)\"\n name=\"targetValue\"\n [validate]=\"validateTarget\">\n @if (targetPercent()) {\n <div matTextSuffix>\n %\n </div>\n }\n <mat-hint>\n The value to reach. Leave empty for no target.\n </mat-hint>\n </mat-form-field>\n @if (hasTarget()) {\n <mat-form-field class=\"full-width\">\n <mat-label>\n Target label\n </mat-label>\n <input\n matInput\n [ngModel]=\"targetLabel()\"\n (ngModelChange)=\"targetLabel.set($event)\"\n name=\"targetLabel\">\n <mat-hint>\n Shown before the target, such as Goal. Empty reads Target.\n </mat-hint>\n </mat-form-field>\n }\n <fs-label-field>\n <mat-slide-toggle\n [ngModel]=\"sparkline()\"\n (ngModelChange)=\"sparkline.set($event)\"\n name=\"sparkline\">\n Sparkline\n </mat-slide-toggle>\n <mat-hint>\n A small trend line of the value over its last periods.\n </mat-hint>\n </fs-label-field>\n @if (sparkline()) {\n <mat-form-field class=\"full-width\">\n <mat-label>\n Sparkline period\n </mat-label>\n <mat-select\n [ngModel]=\"sparklineGranularity()\"\n (ngModelChange)=\"sparklineGranularity.set($event)\"\n name=\"sparklineGranularity\">\n @for (option of granularityOptions; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Sparkline periods\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"0\"\n [ngModel]=\"sparklinePeriods()\"\n (ngModelChange)=\"sparklinePeriods.set($event)\"\n name=\"sparklinePeriods\"\n [fsFormRequired]=\"true\"\n [fsFormInteger]=\"true\"\n [fsFormMin]=\"sparklineMinPeriods\"\n [fsFormMax]=\"sparklineMaxPeriods\">\n <mat-hint>\n How many periods the line covers, {{ sparklineMinPeriods }} to {{ sparklineMaxPeriods }}.\n </mat-hint>\n </mat-form-field>\n }\n }\n </div>\n </mat-tab>\n <!-- A formula runs no statement and follows the filters of the values\n it reads, so it has neither a Filters nor an SQL tab. -->\n @if (!isFormula()) {\n <mat-tab\n label=\"Filters\"\n name=\"filters\">\n <div class=\"tab-body\">\n @if (columnsError()) {\n <div class=\"filters-empty error\">\n {{ columnsError() }}\n </div>\n } @else if (rows().length) {\n <!-- Every filterable column. Pick where its control shows: in\n the report bar (every page, or this page only), on this\n component, both, or neither. The interface follows the\n data; a numeric column can be values or a number range.\n A value sits inside text and has no component to show a\n control on, so it gets the report bar column only. -->\n <table class=\"filter-table\">\n <thead>\n <tr>\n <th class=\"filter-col-name\">\n Filter\n </th>\n <th class=\"filter-col-type\">\n Type\n </th>\n <th class=\"filter-col-select\">\n Report bar\n </th>\n @if (!isValue()) {\n <th class=\"filter-col-toggle\">\n This component\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (row of rows(); track row.column) {\n <tr>\n <td class=\"filter-col-name\">\n {{ row.label }}\n </td>\n <td class=\"filter-col-type\">\n @if (row.typeSelect.show) {\n <mat-form-field\n [subscriptSizing]=\"'dynamic'\"\n [matTooltip]=\"row.typeSelect.tooltip\">\n <mat-select\n [panelWidth]=\"null\"\n [ngModel]=\"row.type\"\n (ngModelChange)=\"setType(row, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n [disabled]=\"row.typeSelect.disabled\"\n aria-label=\"Type\">\n @for (option of typeOptions; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n } @else {\n {{ typeLabel(row.type) }}\n }\n </td>\n <td class=\"filter-col-select\">\n <mat-form-field [subscriptSizing]=\"'dynamic'\">\n <mat-select\n [panelWidth]=\"null\"\n [ngModel]=\"row.placement\"\n (ngModelChange)=\"setPlacement(row, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n aria-label=\"Report bar\">\n @for (option of row.placementOptions; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </td>\n @if (!isValue()) {\n <td class=\"filter-col-toggle\">\n <mat-slide-toggle\n [ngModel]=\"row.component\"\n (ngModelChange)=\"setComponent(row, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n [disabled]=\"row.componentToggle.disabled\"\n [matTooltip]=\"row.componentToggle.tooltip\">\n </mat-slide-toggle>\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n } @else {\n <div class=\"filters-empty\">\n This component has no filterable columns yet \u2014 give it some SQL first.\n </div>\n }\n </div>\n </mat-tab>\n <mat-tab\n label=\"SQL\"\n name=\"sql\">\n <div class=\"tab-body\">\n @if (sqlError()) {\n <div class=\"filters-empty error\">\n {{ sqlError() }}\n </div>\n } @else if (sql()) {\n @if (sqlBaseline()) {\n <!-- A derived component's statement is compiled from its\n document with no viewer state, so it is not byte-for-byte\n what produced the numbers on screen. Said here rather than\n left for the reader to discover. -->\n <div class=\"filters-empty\">\n Compiled from this component's query \u2014 no filters applied, times in {{ sqlTimezone() }}.\n </div>\n }\n <pre class=\"code-block\">{{ sql() }}</pre>\n } @else {\n <div class=\"filters-empty\">\n This component has no SQL yet.\n </div>\n }\n </div>\n </mat-tab>\n }\n <mat-tab\n label=\"Config\"\n name=\"config\">\n <div class=\"tab-body\">\n <pre class=\"code-block\">\n {{ configJson }}\n </pre>\n </div>\n </mat-tab>\n </mat-tab-group>\n </mat-dialog-content>\n <mat-dialog-actions>\n <!-- Save | Delete | Cancel, the standard order. fs-form-dialog-actions\n renders its own Save/Done BEFORE the projected content, which would\n put Delete after Cancel, so `[save]=\"false\"` foots the row here and\n all three buttons are projected in order. Save submits the Settings\n tab; the other tabs persist as you touch them, so they get Done. -->\n <fs-form-dialog-actions [save]=\"false\">\n @if (selectedTab === 'settings') {\n <button\n mat-button\n type=\"submit\"\n color=\"primary\">\n Save\n </button>\n } @else {\n <button\n mat-button\n type=\"button\"\n color=\"primary\"\n [mat-dialog-close]=\"null\">\n Done\n </button>\n }\n <button\n mat-button\n type=\"button\"\n color=\"warn\"\n (click)=\"delete()\">\n Delete\n </button>\n <button\n mat-button\n type=\"button\"\n class=\"cancel-button\"\n [mat-dialog-close]=\"null\">\n Cancel\n </button>\n </fs-form-dialog-actions>\n </mat-dialog-actions>\n </fs-dialog>\n</form>", styles: ["mat-form-field{width:100%}.tab-body{padding-top:16px}.geometry-row{display:flex;gap:8px}.geometry-row mat-form-field{flex:1}.filter-table{border-spacing:0;width:100%;border-collapse:collapse}.filter-table thead th{color:#8f8f8f;font-weight:400;font-size:85%;text-align:left;padding:8px 16px}.filter-table tbody tr{clip-path:xywh(0 3px 100% calc(100% - 6px) round 10px)}.filter-table tbody td{border:none;background-color:#fafafa;padding:8px 16px;vertical-align:middle;text-align:left}.filter-table .filter-col-name{font-weight:600;color:#1f2933}.filter-table .filter-col-type{color:#7b8794;width:150px}.filter-table .filter-col-select{width:160px}.filter-table td.filter-col-type,.filter-table td.filter-col-select{padding-left:8px;padding-right:8px}.filter-table td.filter-col-type mat-form-field,.filter-table td.filter-col-select mat-form-field{width:100%;--mat-form-field-container-height: 36px;--mat-form-field-container-vertical-padding: 6px}.filter-table td.filter-col-type ::ng-deep .mat-mdc-form-field-infix,.filter-table td.filter-col-select ::ng-deep .mat-mdc-form-field-infix{width:auto}.filter-table td.filter-col-type ::ng-deep .mat-mdc-form-field-subscript-wrapper,.filter-table td.filter-col-select ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}.filter-table .filter-col-toggle,.filter-table th.filter-col-toggle{width:110px;text-align:center}.filters-empty{font-size:13px;color:#7b8794;padding:8px 0 4px}.filters-empty.error{color:#e15759}.code-block{margin:0;padding:10px 12px;background:#1f2933;color:#e4e7eb;border-radius:6px;font-family:JetBrains Mono,Consolas,monospace;font-size:12px;line-height:1.5;white-space:pre-wrap;word-break:break-word;max-height:240px;overflow:auto}\n"] }]
|
|
724
|
+
], template: "<form\n fsForm\n [submit]=\"save\">\n <fs-dialog>\n <h1 mat-dialog-title>\n {{ heading() }}\n </h1>\n <mat-dialog-content>\n <mat-tab-group [(selected)]=\"selectedTab\">\n <mat-tab\n label=\"Settings\"\n name=\"settings\">\n <div class=\"fs-column tab-body\">\n <!-- A value's Name is just its name. A title may carry the page,\n report and filter fields a text block's words do: Insert\n field puts one in at the caret, and the hint says how the\n title reads where the component is drawn. -->\n @if (isValue()) {\n <mat-form-field>\n <mat-label>\n Name\n </mat-label>\n <input\n matInput\n [ngModel]=\"title()\"\n (ngModelChange)=\"title.set($event)\"\n name=\"title\"\n [fsFormRequired]=\"true\">\n </mat-form-field>\n } @else {\n <mat-form-field>\n <mat-label>\n Title\n </mat-label>\n <input\n #titleInput\n matInput\n [ngModel]=\"title()\"\n (ngModelChange)=\"title.set($event)\"\n name=\"title\">\n <!-- The button swallows its own click: the form field would\n otherwise put focus back in the input while the menu is\n open, and a key pressed then would move the caret the\n field goes in at. -->\n <button\n mat-icon-button\n matIconSuffix\n type=\"button\"\n aria-label=\"Insert field\"\n [fsMenuTriggerFor]=\"insertFieldMenu\"\n (click)=\"$event.stopPropagation()\">\n <mat-icon>sell</mat-icon>\n </button>\n @if (titleShownAs()) {\n <mat-hint>\n Shows as: {{ titleShownAs() }}\n </mat-hint>\n }\n </mat-form-field>\n <fs-menu #insertFieldMenu>\n @for (entry of titleFields(); track entry.field) {\n <ng-template\n fs-menu-item\n (click)=\"insertField(entry.field)\">\n {{ entry.name }}\n </ng-template>\n }\n </fs-menu>\n }\n <!-- A formula value is read-only beyond its name: what it works\n out is the AI's to change. A formula this viewer cannot\n read has no line, and no row. -->\n @if (formulaLine()) {\n <fs-label-field>\n <fs-label>\n Formula\n </fs-label>\n {{ formulaLine() }}\n <fs-label-message>\n Worked out on the server; it follows the filters of the values it reads.\n </fs-label-message>\n </fs-label-field>\n }\n <!-- A value sits inside a text block's words: no box, no padding. -->\n @if (!isValue()) {\n <div class=\"subheading-2\">\n Padding\n </div>\n <div class=\"geometry-row\">\n <mat-form-field>\n <mat-label>\n Top\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"3\"\n [(ngModel)]=\"paddingTop\"\n name=\"paddingTop\"\n [fsFormMin]=\"0\">\n <div matTextSuffix>\n in\n </div>\n </mat-form-field>\n <mat-form-field>\n <mat-label>\n Right\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"3\"\n [(ngModel)]=\"paddingRight\"\n name=\"paddingRight\"\n [fsFormMin]=\"0\">\n <div matTextSuffix>\n in\n </div>\n </mat-form-field>\n <mat-form-field>\n <mat-label>\n Bottom\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"3\"\n [(ngModel)]=\"paddingBottom\"\n name=\"paddingBottom\"\n [fsFormMin]=\"0\">\n <div matTextSuffix>\n in\n </div>\n </mat-form-field>\n <mat-form-field>\n <mat-label>\n Left\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"3\"\n [(ngModel)]=\"paddingLeft\"\n name=\"paddingLeft\"\n [fsFormMin]=\"0\">\n <div matTextSuffix>\n in\n </div>\n </mat-form-field>\n </div>\n }\n <!-- A derived KPI's card: what a rise means, a target and a\n sparkline. The server computes the progress and the points. -->\n @if (kpiCard()) {\n <div class=\"subheading-2\">\n Card\n </div>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Increase is\n </mat-label>\n <mat-select\n [ngModel]=\"increaseIs()\"\n (ngModelChange)=\"increaseIs.set($event)\"\n name=\"increaseIs\">\n @for (option of kpiPolarityOptions; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n </mat-select>\n <mat-hint>\n Colors the change and decides when the target is met.\n </mat-hint>\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Target\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"6\"\n [signed]=\"true\"\n [ngModel]=\"targetValue()\"\n (ngModelChange)=\"targetValue.set($event)\"\n name=\"targetValue\"\n [validate]=\"validateTarget\">\n @if (targetPercent()) {\n <div matTextSuffix>\n %\n </div>\n }\n <mat-hint>\n The value to reach. Leave empty for no target.\n </mat-hint>\n </mat-form-field>\n @if (hasTarget()) {\n <mat-form-field class=\"full-width\">\n <mat-label>\n Target label\n </mat-label>\n <input\n matInput\n [ngModel]=\"targetLabel()\"\n (ngModelChange)=\"targetLabel.set($event)\"\n name=\"targetLabel\">\n <mat-hint>\n Shown before the target, such as Goal. Empty reads Target.\n </mat-hint>\n </mat-form-field>\n }\n <fs-label-field>\n <mat-slide-toggle\n [ngModel]=\"sparkline()\"\n (ngModelChange)=\"sparkline.set($event)\"\n name=\"sparkline\">\n Sparkline\n </mat-slide-toggle>\n <mat-hint>\n A small trend line of the value over its last periods.\n </mat-hint>\n </fs-label-field>\n @if (sparkline()) {\n <mat-form-field class=\"full-width\">\n <mat-label>\n Sparkline period\n </mat-label>\n <mat-select\n [ngModel]=\"sparklineGranularity()\"\n (ngModelChange)=\"sparklineGranularity.set($event)\"\n name=\"sparklineGranularity\">\n @for (option of granularityOptions; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Sparkline periods\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"0\"\n [ngModel]=\"sparklinePeriods()\"\n (ngModelChange)=\"sparklinePeriods.set($event)\"\n name=\"sparklinePeriods\"\n [fsFormRequired]=\"true\"\n [fsFormInteger]=\"true\"\n [fsFormMin]=\"sparklineMinPeriods\"\n [fsFormMax]=\"sparklineMaxPeriods\">\n <mat-hint>\n How many periods the line covers, {{ sparklineMinPeriods }} to {{ sparklineMaxPeriods }}.\n </mat-hint>\n </mat-form-field>\n }\n }\n <!-- A chart over time: how its periods are labelled and, on a\n derived chart, which periods it draws. The server runs the\n span, so the screen and every export draw the same periods;\n the KPIs and values on the page keep the date filter's range. -->\n @if (timeAxis()) {\n <div class=\"subheading-2\">\n Time axis\n </div>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Date labels\n </mat-label>\n <mat-select\n [ngModel]=\"dateLabel()\"\n (ngModelChange)=\"dateLabel.set($event)\"\n name=\"dateLabel\">\n @for (option of dateLabelOptions; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n </mat-select>\n <mat-hint>\n Period end labels each period by its last day: a week by its Sunday.\n </mat-hint>\n </mat-form-field>\n @if (spanAllowed()) {\n <mat-form-field class=\"full-width\">\n <mat-label>\n Periods shown\n </mat-label>\n <mat-select\n [ngModel]=\"spanMode()\"\n (ngModelChange)=\"spanMode.set($event)\"\n name=\"spanMode\">\n @for (option of spanModeOptions; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n </mat-select>\n <mat-hint>\n With no date filter set, the chart ends at the current period.\n </mat-hint>\n </mat-form-field>\n @if (spanMode() === ReportChartSpanMode.Periods) {\n <mat-form-field class=\"full-width\">\n <mat-label>\n Periods\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"0\"\n [ngModel]=\"spanPeriods()\"\n (ngModelChange)=\"spanPeriods.set($event)\"\n name=\"spanPeriods\"\n [fsFormRequired]=\"true\"\n [fsFormInteger]=\"true\"\n [fsFormMin]=\"spanMinPeriods\"\n [fsFormMax]=\"spanMaxPeriods\">\n <mat-hint>\n How many periods the chart draws, {{ spanMinPeriods }} to {{ spanMaxPeriods }}; 3 on a monthly chart is the last three months.\n </mat-hint>\n </mat-form-field>\n } @else if (spanMode() === ReportChartSpanMode.Start) {\n <mat-form-field class=\"full-width\">\n <mat-label>\n Since\n </mat-label>\n <input\n matInput\n fsDatePicker\n [ngModel]=\"spanStart()\"\n (ngModelChange)=\"spanStart.set($event)\"\n name=\"spanStart\"\n [fsFormRequired]=\"true\">\n <mat-hint>\n The chart draws every period from this day, such as a go-live.\n </mat-hint>\n </mat-form-field>\n }\n }\n }\n </div>\n </mat-tab>\n <!-- A formula runs no statement and follows the filters of the values\n it reads, so it has neither a Filters nor an SQL tab. -->\n @if (!isFormula()) {\n <mat-tab\n label=\"Filters\"\n name=\"filters\">\n <div class=\"tab-body\">\n @if (columnsError()) {\n <div class=\"filters-empty error\">\n {{ columnsError() }}\n </div>\n } @else if (rows().length) {\n <!-- Every filterable column. Pick where its control shows: in\n the report bar (every page, or this page only), on this\n component, both, or neither. The interface follows the\n data; a numeric column can be values or a number range.\n A value sits inside text and has no component to show a\n control on, so it gets the report bar column only. -->\n <table class=\"filter-table\">\n <thead>\n <tr>\n <th class=\"filter-col-name\">\n Filter\n </th>\n <th class=\"filter-col-type\">\n Type\n </th>\n <th class=\"filter-col-select\">\n Report bar\n </th>\n @if (!isValue()) {\n <th class=\"filter-col-toggle\">\n This component\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (row of rows(); track row.column) {\n <tr>\n <td class=\"filter-col-name\">\n {{ row.label }}\n </td>\n <td class=\"filter-col-type\">\n @if (row.typeSelect.show) {\n <mat-form-field\n [subscriptSizing]=\"'dynamic'\"\n [matTooltip]=\"row.typeSelect.tooltip\">\n <mat-select\n [panelWidth]=\"null\"\n [ngModel]=\"row.type\"\n (ngModelChange)=\"setType(row, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n [disabled]=\"row.typeSelect.disabled\"\n aria-label=\"Type\">\n @for (option of typeOptions; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n } @else {\n {{ typeLabel(row.type) }}\n }\n </td>\n <td class=\"filter-col-select\">\n <mat-form-field [subscriptSizing]=\"'dynamic'\">\n <mat-select\n [panelWidth]=\"null\"\n [ngModel]=\"row.placement\"\n (ngModelChange)=\"setPlacement(row, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n aria-label=\"Report bar\">\n @for (option of row.placementOptions; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </td>\n @if (!isValue()) {\n <td class=\"filter-col-toggle\">\n <mat-slide-toggle\n [ngModel]=\"row.component\"\n (ngModelChange)=\"setComponent(row, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n [disabled]=\"row.componentToggle.disabled\"\n [matTooltip]=\"row.componentToggle.tooltip\">\n </mat-slide-toggle>\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n } @else {\n <div class=\"filters-empty\">\n This component has no filterable columns yet \u2014 give it some SQL first.\n </div>\n }\n </div>\n </mat-tab>\n <mat-tab\n label=\"SQL\"\n name=\"sql\">\n <div class=\"tab-body\">\n @if (sqlError()) {\n <div class=\"filters-empty error\">\n {{ sqlError() }}\n </div>\n } @else if (sql()) {\n @if (sqlBaseline()) {\n <!-- A derived component's statement is compiled from its\n document with no viewer state, so it is not byte-for-byte\n what produced the numbers on screen. Said here rather than\n left for the reader to discover. -->\n <div class=\"filters-empty\">\n Compiled from this component's query \u2014 no filters applied, times in {{ sqlTimezone() }}.\n </div>\n }\n <pre class=\"code-block\">{{ sql() }}</pre>\n } @else {\n <div class=\"filters-empty\">\n This component has no SQL yet.\n </div>\n }\n </div>\n </mat-tab>\n }\n <mat-tab\n label=\"Config\"\n name=\"config\">\n <div class=\"tab-body\">\n <pre class=\"code-block\">\n {{ configJson }}\n </pre>\n </div>\n </mat-tab>\n </mat-tab-group>\n </mat-dialog-content>\n <mat-dialog-actions>\n <!-- Save | Delete | Cancel, the standard order. fs-form-dialog-actions\n renders its own Save/Done BEFORE the projected content, which would\n put Delete after Cancel, so `[save]=\"false\"` foots the row here and\n all three buttons are projected in order. Save submits the Settings\n tab; the other tabs persist as you touch them, so they get Done. -->\n <fs-form-dialog-actions [save]=\"false\">\n @if (selectedTab === 'settings') {\n <button\n mat-button\n type=\"submit\"\n color=\"primary\">\n Save\n </button>\n } @else {\n <button\n mat-button\n type=\"button\"\n color=\"primary\"\n [mat-dialog-close]=\"null\">\n Done\n </button>\n }\n <button\n mat-button\n type=\"button\"\n color=\"warn\"\n (click)=\"delete()\">\n Delete\n </button>\n <button\n mat-button\n type=\"button\"\n class=\"cancel-button\"\n [mat-dialog-close]=\"null\">\n Cancel\n </button>\n </fs-form-dialog-actions>\n </mat-dialog-actions>\n </fs-dialog>\n</form>", styles: ["mat-form-field{width:100%}.tab-body{padding-top:16px}.geometry-row{display:flex;gap:8px}.geometry-row mat-form-field{flex:1}.filter-table{border-spacing:0;width:100%;border-collapse:collapse}.filter-table thead th{color:#8f8f8f;font-weight:400;font-size:85%;text-align:left;padding:8px 16px}.filter-table tbody tr{clip-path:xywh(0 3px 100% calc(100% - 6px) round 10px)}.filter-table tbody td{border:none;background-color:#fafafa;padding:8px 16px;vertical-align:middle;text-align:left}.filter-table .filter-col-name{font-weight:600;color:#1f2933}.filter-table .filter-col-type{color:#7b8794;width:150px}.filter-table .filter-col-select{width:160px}.filter-table td.filter-col-type,.filter-table td.filter-col-select{padding-left:8px;padding-right:8px}.filter-table td.filter-col-type mat-form-field,.filter-table td.filter-col-select mat-form-field{width:100%;--mat-form-field-container-height: 36px;--mat-form-field-container-vertical-padding: 6px}.filter-table td.filter-col-type ::ng-deep .mat-mdc-form-field-infix,.filter-table td.filter-col-select ::ng-deep .mat-mdc-form-field-infix{width:auto}.filter-table td.filter-col-type ::ng-deep .mat-mdc-form-field-subscript-wrapper,.filter-table td.filter-col-select ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}.filter-table .filter-col-toggle,.filter-table th.filter-col-toggle{width:110px;text-align:center}.filters-empty{font-size:13px;color:#7b8794;padding:8px 0 4px}.filters-empty.error{color:#e15759}.code-block{margin:0;padding:10px 12px;background:#1f2933;color:#e4e7eb;border-radius:6px;font-family:JetBrains Mono,Consolas,monospace;font-size:12px;line-height:1.5;white-space:pre-wrap;word-break:break-word;max-height:240px;overflow:auto}\n"] }]
|
|
620
725
|
}] });
|
|
621
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcG9uZW50LXNldHRpbmdzLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvcmVwb3J0cy9kaWFsb2dzL2NvbXBvbmVudC1zZXR0aW5ncy9jb21wb25lbnQtc2V0dGluZ3MuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9yZXBvcnRzL2RpYWxvZ3MvY29tcG9uZW50LXNldHRpbmdzL2NvbXBvbmVudC1zZXR0aW5ncy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBYyxZQUFZLEVBQVUsUUFBUSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsU0FBUyxHQUN0SCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNoRSxPQUFPLEVBQW1CLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRTlELE9BQU8sRUFBRSxlQUFlLEVBQUUsZ0JBQWdCLEVBQUUsY0FBYyxFQUFFLGdCQUFnQixFQUFFLFlBQVksRUFBRSxjQUFjLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUM3SSxPQUFPLEVBQUUsWUFBWSxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDMUYsT0FBTyxFQUFFLFNBQVMsRUFBRSxhQUFhLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNwRSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDakQsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ25ELE9BQU8sRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDaEUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGdDQUFnQyxD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K0hBQ2QsZ0JBQWdCLHlHQUNoQixnQkFBZ0IsNEhBQ2hCLGNBQWMscUxBQ2QsWUFBWSw0TEFDWixPQUFPLDhFQUNQLFFBQVEsc0RBQ1IsU0FBUyxxSEFDVCxTQUFTLGlMQUNULE9BQU8sMklBQ1AsYUFBYSw2RkFDYixRQUFRLGlVQUNSLFNBQVMscUpBQ1QsU0FBUyx3ZUFDVCxjQUFjLDBVQUNkLFVBQVUsZ1JBQ1YsWUFBWTs7NEZBR0gsMEJBQTBCO2tCQWhDdEMsU0FBUztzQ0FHUyx1QkFBdUIsQ0FBQyxNQUFNLGNBQ25DLElBQUksV0FDUDt3QkFDUCxXQUFXO3dCQUNYLFlBQVk7d0JBQ1osWUFBWTt3QkFDWixjQUFjO3dCQUNkLGFBQWE7d0JBQ2IsWUFBWTt3QkFDWixhQUFhO3dCQUNiLGNBQWM7d0JBQ2QsZ0JBQWdCO3dCQUNoQixnQkFBZ0I7d0JBQ2hCLGNBQWM7d0JBQ2QsWUFBWTt3QkFDWixPQUFPO3dCQUNQLFFBQVE7d0JBQ1IsU0FBUzt3QkFDVCxTQUFTO3dCQUNULE9BQU87d0JBQ1AsYUFBYTt3QkFDYixRQUFRO3dCQUNSLFNBQVM7d0JBQ1QsU0FBUzt3QkFDVCxjQUFjO3dCQUNkLFVBQVU7d0JBQ1YsWUFBWTtxQkFDYiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDb21wb25lbnQsIERlc3Ryb3lSZWYsIEVsZW1lbnRSZWYsIEV2ZW50RW1pdHRlciwgT25Jbml0LCBjb21wdXRlZCwgaW5qZWN0LCBzaWduYWwsIHZpZXdDaGlsZCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyB0YWtlVW50aWxEZXN0cm95ZWQgfSBmcm9tICdAYW5ndWxhci9jb3JlL3J4anMtaW50ZXJvcCc7XG5pbXBvcnQgeyBBYnN0cmFjdENvbnRyb2wsIEZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuXG5pbXBvcnQgeyBNQVRfRElBTE9HX0RBVEEsIE1hdERpYWxvZ0FjdGlvbnMsIE1hdERpYWxvZ0Nsb3NlLCBNYXREaWFsb2dDb250ZW50LCBNYXREaWFsb2dSZWYsIE1hdERpYWxvZ1RpdGxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZGlhbG9nJztcbmltcG9ydCB7IE1hdEZvcm1GaWVsZCwgTWF0SGludCwgTWF0TGFiZWwsIE1hdFN1ZmZpeCB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2Zvcm0tZmllbGQnO1xuaW1wb3J0IHsgTWF0QnV0dG9uLCBNYXRJY29uQnV0dG9uIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvYnV0dG9uJztcbmltcG9ydCB7IE1hdEljb24gfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9pY29uJztcbmltcG9ydCB7IE1hdElucHV0IH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvaW5wdXQnO1xuaW1wb3J0IHsgTWF0T3B0aW9uLCBNYXRTZWxlY3QgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9zZWxlY3QnO1xuaW1wb3J0IHsgTWF0U2xpZGVUb2dnbGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9zbGlkZS10b2dnbGUnO1xuaW1wb3J0IHsgTWF0VGFic01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3RhYnMnO1xuaW1wb3J0IHsgTWF0VG9vbHRpcCB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3Rvb2x0aXAnO1xuXG5pbXBvcnQgeyBGc0RpYWxvZ01vZHVsZSB9IGZyb20gJ0BmaXJlc3RpdGNoL2RpYWxvZyc7XG5pbXBvcnQgeyBGc0Zvcm1Nb2R1bGUgfSBmcm9tICdAZmlyZXN0aXRjaC9mb3JtJztcbmltcG9ydCB7IEZzTGFiZWxNb2R1bGUgfSBmcm9tICdAZmlyZXN0aXRjaC9sYWJlbCc7XG5pbXBvcnQgeyBGc01hc2tNb2R1bGUgfSBmcm9tICdAZmlyZXN0aXRjaC9tYXNrJztcbmltcG9ydCB7IEZzTWVudU1vZHVsZSB9IGZyb20gJ0BmaXJlc3RpdGNoL21lbnUnO1xuaW1wb3J0IHsgRnNNZXNzYWdlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvbWVzc2FnZSc7XG5pbXBvcnQgeyBGc1Byb21wdCB9IGZyb20gJ0BmaXJlc3RpdGNoL3Byb21wdCc7XG5pbXBvcnQgeyBGc1RhYnNNb2R1bGUgfSBmcm9tICdAZmlyZXN0aXRjaC90YWJzJztcblxuaW1wb3J0IHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgc3dpdGNoTWFwLCB0YXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IFJlcG9ydERhdGEgfSBmcm9tICcuLi8uLi9kYXRhL3JlcG9ydC5kYXRhJztcbmltcG9ydCB7IFJlcG9ydENoYW5nZVBvbGFyaXR5IH0gZnJvbSAnLi4vLi4vZW51bXMvcmVwb3J0LWNoYW5nZS1wb2xhcml0eS5lbnVtJztcbmltcG9ydCB7IFJlcG9ydFZhbHVlRm9ybWF0IH0gZnJvbSAnLi4vLi4vZW51bXMvcmVwb3J0LXZhbHVlLWZvcm1hdC5lbnVtJztcbmltcG9ydCB7IFJlcG9ydFZhbHVlRm9ybXVsYSB9IGZyb20gJy4uLy4uL2VudW1zL3JlcG9ydC12YWx1ZS1mb3JtdWxhLmVudW0nO1xuaW1wb3J0IHsgcmVzb2x2ZUZvcm1hdENvbnRleHQgfSBmcm9tICcuLi8uLi9mb3JtYXQnO1xuaW1wb3J0IHtcbiAgS1BJX1NQQVJLTElORV9ERUZBVUxUX0dSQU5VTEFSSVRZLFxuICBLUElfU1BBUktMSU5FX0RFRkFVTFRfUEVSSU9EUyxcbiAga3BpQ2FyZFNldHRpbmdzLFxuICBzYW1lS3BpQ2FyZFNldHRpbmdzLFxufSBmcm9tICcuLi8uLi9rcGktY2FyZCc7XG5pbXBvcnQge1xuICBDaGFydEdyYW51bGFyaXR5LFxuICBDb21wb25lbnRTZXR0aW5ncyxcbiAgR1JBTlVMQVJJVFlfT1BUSU9OUyxcbiAgS3BpQ2FyZFNldHRpbmdzLFxuICBLcGlDb25maWcsXG4gIFJlcG9ydCxcbiAgUmVwb3J0Q29tcG9uZW50LFxuICBSZXBvcnRDb21wb25lbnRTcWwsXG4gIFJlcG9ydEZpbHRlcixcbiAgUmVwb3J0RmlsdGVyR3JvdXAsXG4gIFJlcG9ydEZpbHRlckxldmVsLFxuICBSZXBvcnRGaWx0ZXJUeXBlLFxuICBSZXBvcnRGaWx0ZXJhYmxlQ29sdW1uLFxufSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL3JlcG9ydC5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgREVGQVVMVF9DT01QT05FTlRfUEFERElORyB9IGZyb20gJy4uLy4uL2xheW91dCc7XG5pbXBvcnQge1xuICBGSUxURVJfVFlQRV9PUFRJT05TLFxuICBiYXJQbGFjZW1lbnQsXG4gIGJhclBsYWNlbWVudE9wdGlvbnMsXG4gIGNvbXBvbmVudFRvZ2dsZVN0YXRlLFxuICBmaWx0ZXJMZXZlbCxcbiAgZmlsdGVyTGV2ZWxDaG9pY2VzLFxuICBzaG93bk9uQ29tcG9uZW50LFxuICB0eXBlU2VsZWN0U3RhdGUsXG4gIHZhbHVlRmlsdGVyTGV2ZWwsXG4gIHZhbHVlUGxhY2VtZW50T3B0aW9ucyxcbn0gZnJvbSAnLi4vLi4vZmlsdGVyLXNldHRpbmdzLXJ1bGVzJztcbmltcG9ydCB7IEZpbHRlckJhclBsYWNlbWVudCB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMvZmlsdGVyLWJhci1wbGFjZW1lbnQudHlwZSc7XG5pbXBvcnQgeyBGaWx0ZXJDb21wb25lbnRUb2dnbGVTdGF0ZSB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMvZmlsdGVyLWNvbXBvbmVudC10b2dnbGUtc3RhdGUuaW50ZXJmYWNlJztcbmltcG9ydCB7IEZpbHRlclNldHRpbmdzT3B0aW9uIH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9maWx0ZXItc2V0dGluZ3Mtb3B0aW9uLmludGVyZmFjZSc7XG5pbXBvcnQgeyBGaWx0ZXJUeXBlU2VsZWN0U3RhdGUgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL2ZpbHRlci10eXBlLXNlbGVjdC1zdGF0ZS5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgVGV4dFRva2VuQ29udGV4dCwgZXNjYXBlSHRtbCwgZmllbGRUb2tlbiwgZmlsbFRpdGxlVG9rZW5zLCB0ZXh0RmllbGRzIH0gZnJvbSAnLi4vLi4vdGV4dCc7XG5pbXBvcnQgeyBvcGVyYW5kS2V5cywgcmVwb3J0Q29tcG9uZW50cywgdmFsdWVLZXkgfSBmcm9tICcuLi8uLi92YWx1ZXMnO1xuXG5cbi8vIFdoYXQgdGhlIGRpYWxvZyBoYW5kcyBiYWNrLiBUaGUgU2V0dGluZ3MgdGFiJ3MgU2F2ZSBjYXJyaWVzIHRoZSBuZXdcbi8vIGBzZXR0aW5nc2A7IERlbGV0ZSBjYXJyaWVzIGBkZWxldGVkYCBhbmQgbm8gc2V0dGluZ3MsIGJlY2F1c2UgdGhlIGNvbXBvbmVudFxuLy8gaXQgd2FzIG9wZW5lZCBmb3Igbm8gbG9uZ2VyIGV4aXN0cy4gRXZlcnkgb3RoZXIgZXhpdCAoQ2FuY2VsLCBEb25lLCBFc2NhcGUsXG4vLyBiYWNrZHJvcCkgY2xvc2VzIHdpdGggbm8gcmVzdWx0IOKAlCBmaWx0ZXIgd29yayBpcyBhbm5vdW5jZWQgYXMgaXQgaGFwcGVuc1xuLy8gaW5zdGVhZCwgdGhyb3VnaCBgZmlsdGVyc0NoYW5nZWRgLlxuZXhwb3J0IGludGVyZmFjZSBDb21wb25lbnRTZXR0aW5nc1Jlc3VsdCB7XG4gIHNldHRpbmdzPzogQ29tcG9uZW50U2V0dGluZ3M7XG4gIGRlbGV0ZWQ/OiBib29sZWFuO1xufVxuXG4vLyBXaGF0IHRoZSBkaWFsb2cgb3BlbnMgd2l0aDogdGhlIHJlcG9ydCwgdGhlIGNvbXBvbmVudCwgYW5kIHdoYXQgdGhlIHRva2Vuc1xuLy8gb2YgdGhlIGNvbXBvbmVudCdzIHRpdGxlIGZpbGwgd2l0aCB3aGVyZSBpdCBpcyBkcmF3biAoaXRzIHBhZ2Uncywgb3IgdGhlXG4vLyBtYXN0ZXIncyBmb3IgYSBoZWFkZXIgb3IgZm9vdGVyIGNvbXBvbmVudCksIGZvciB0aGUgdGl0bGUncyBJbnNlcnQgZmllbGRcbi8vIG1lbnUgYW5kIHRoZSBsaW5lIHNheWluZyBob3cgdGhlIHRpdGxlIHJlYWRzLlxuZXhwb3J0IGludGVyZmFjZSBDb21wb25lbnRTZXR0aW5nc0RpYWxvZ0RhdGEge1xuICByZXBvcnQ6IFJlcG9ydDtcbiAgY29tcG9uZW50OiBSZXBvcnRDb21wb25lbnQ7XG4gIHRva2VuczogVGV4dFRva2VuQ29udGV4dDtcbn1cblxuLy8gV2hhdCB0aGUgc2V0dGluZ3MgZW5kcG9pbnQgcmV0dXJucyBmb3IgdGhlIGNvbXBvbmVudDogaXRzIGlkIGFuZCwgZnJvbSBhXG4vLyBzZXJ2ZXIgdGhhdCBzYXZlcyBhIEtQSSdzIGNhcmQga2V5cywgdGhlIHdob2xlIGNvbmZpZyBhcyBzYXZlZC5cbmludGVyZmFjZSBDb21wb25lbnRTZXR0aW5nc1Jlc3BvbnNlIHtcbiAgaWQ6IG51bWJlcjtcbiAgY29uZmlnPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gfCBudWxsO1xufVxuXG5cbi8vIFdoYXQgYSByaXNlIGluIGEgS1BJJ3MgdmFsdWUgbWVhbnMsIGZvciB0aGUgSW5jcmVhc2UgaXMgc2VsZWN0LlxuY29uc3QgS1BJX0NIQU5HRV9QT0xBUklUWV9PUFRJT05TOiB7IHZhbHVlOiBSZXBvcnRDaGFuZ2VQb2xhcml0eTsgbmFtZTogc3RyaW5nIH1bXSA9IFtcbiAgeyB2YWx1ZTogUmVwb3J0Q2hhbmdlUG9sYXJpdHkuR29vZCwgbmFtZTogJ0dvb2QgbmV3cyDigJQgYSByaXNlIHNob3dzIGdyZWVuJyB9LFxuICB7IHZhbHVlOiBSZXBvcnRDaGFuZ2VQb2xhcml0eS5CYWQsIG5hbWU6ICdCYWQgbmV3cyDigJQgYSByaXNlIHNob3dzIHJlZCcgfSxcbiAgeyB2YWx1ZTogUmVwb3J0Q2hhbmdlUG9sYXJpdHkuTmV1dHJhbCwgbmFtZTogJ05laXRoZXIg4oCUIG5vIGNvbG9yJyB9LFxuXTtcblxuLy8gQSBLUEkgc3BhcmtsaW5lJ3MgcGVyaW9kcyBzdGF5IHdpdGhpbiAyIHRvIDYwLlxuY29uc3QgS1BJX1NQQVJLTElORV9NSU5fUEVSSU9EUyA9IDI7XG5jb25zdCBLUElfU1BBUktMSU5FX01BWF9QRVJJT0RTID0gNjA7XG5cbi8vIEEgcGVyY2VudCBLUEkncyB0YXJnZXQgaXMgZW50ZXJlZCBhcyB0aGUgcGVyY2VudCBzaG93biAoMTUgZm9yIDE1JSkgYW5kXG4vLyBzdG9yZWQgYXMgdGhlIDAtMSByYXRpbyBpdHMgdmFsdWUgYXJyaXZlcyBpbjsgdGhlIHNlcnZlciByZWZ1c2VzIGEgc3RvcmVkXG4vLyB0YXJnZXQgYWJvdmUgMTAwLCB3aGljaCBpcyAxMCwwMDAlIGhlcmUuXG5jb25zdCBLUElfUEVSQ0VOVF9UQVJHRVRfTUFYID0gMTAwMDA7XG5cbi8vIEhvdyBhIGZvcm11bGEgdmFsdWUncyBTZXR0aW5ncyB0YWIgd3JpdGVzIG91dCB3aGF0IGl0IHdvcmtzIG91dCwgaW4gaXRzXG4vLyBvcGVyYW5kcycgbmFtZXMuXG5jb25zdCBGT1JNVUxBX0xJTkVTOiBSZWNvcmQ8UmVwb3J0VmFsdWVGb3JtdWxhLCAobmFtZXM6IHN0cmluZ1tdKSA9PiBzdHJpbmc+ID0ge1xuICBbUmVwb3J0VmFsdWVGb3JtdWxhLkNoYW5nZV06IChuYW1lcykgPT4gbmFtZXMuam9pbignIOKIkiAnKSxcbiAgW1JlcG9ydFZhbHVlRm9ybXVsYS5QZXJjZW50Q2hhbmdlXTogKFthLCBiXSkgPT4gYCUgY2hhbmdlIG9mICR7YX0gb3ZlciAke2J9YCxcbiAgW1JlcG9ydFZhbHVlRm9ybXVsYS5SYXRpb106IChuYW1lcykgPT4gbmFtZXMuam9pbignIMO3ICcpLFxuICBbUmVwb3J0VmFsdWVGb3JtdWxhLlN1bV06IChuYW1lcykgPT4gbmFtZXMuam9pbignICsgJyksXG59O1xuXG5cbi8vIE9uZSByb3cgb2YgdGhlIEZpbHRlcnMgdGFiIGxpc3Rpbmc6IGEgZmlsdGVyYWJsZSBjb2x1bW4sIGl0cyBmaWx0ZXIncyB0eXBlXG4vLyAodGhlIGluZmVycmVkIG9uZSwgdGhlIG9uZSBwaWNrZWQsIG9yIHRoZSBmaWx0ZXIncyBvd24pLCBhbmQgd2hlcmUgaXRzXG4vLyBmaWx0ZXIgc2hvd3MgKHRoZSBSZXBvcnQgYmFyIHNlbGVjdCBhbmQgdGhlIFRoaXMgY29tcG9uZW50IHRvZ2dsZSkuXG5pbnRlcmZhY2UgRmlsdGVyUm93IHtcbiAgY29sdW1uOiBzdHJpbmc7XG4gIHR5cGU6IFJlcG9ydEZpbHRlclR5cGU7XG4gIGxhYmVsOiBzdHJpbmc7XG4gIHBsYWNlbWVudDogRmlsdGVyQmFyUGxhY2VtZW50O1xuICBjb21wb25lbnQ6IGJvb2xlYW47XG4gIHR5cGVTZWxlY3Q6IEZpbHRlclR5cGVTZWxlY3RTdGF0ZTtcbiAgcGxhY2VtZW50T3B0aW9uczogRmlsdGVyU2V0dGluZ3NPcHRpb248RmlsdGVyQmFyUGxhY2VtZW50PltdO1xuICBjb21wb25lbnRUb2dnbGU6IEZpbHRlckNvbXBvbmVudFRvZ2dsZVN0YXRlO1xufVxuXG5cbi8vIENvbXBvbmVudCBzZXR0aW5ncywgaW4gdGFiczpcbi8vICAgU2V0dGluZ3Mg4oCUIHRpdGxlIGFuZCBjb250ZW50IHBhZGRpbmcgKGEgdmFsdWU6IGp1c3QgaXRzIG5hbWUsIHNpbmNlIGl0XG4vLyAgIHNpdHMgaW5zaWRlIGEgdGV4dCBibG9jaydzIHdvcmRzIGFuZCBoYXMgbm8gYm94KS4gQSB0aXRsZSBtYXkgY2FycnkgdGhlXG4vLyAgIHBhZ2UsIHJlcG9ydCBhbmQgZmlsdGVyIGZpZWxkcyBhIHRleHQgYmxvY2sncyB3b3JkcyBkbzogaXRzIEluc2VydCBmaWVsZFxuLy8gICBtZW51IHB1dHMgb25lIGluIGF0IHRoZSBjYXJldCwgYW5kIHRoZSBsaW5lIHVuZGVyIGl0IHNheXMgaG93IHRoZSB0aXRsZVxuLy8gICByZWFkcy4gT24gYSBkZXJpdmVkIEtQSSBpdHMgY2FyZDogd2hhdCBhIHJpc2UgbWVhbnMsIGEgdGFyZ2V0IGFuZCBhXG4vLyAgIHNwYXJrbGluZSAobnVtYmVyIGZvcm1hdHMgc3RheSB3aXRoIHRoZSBBSSkuIFBvc2l0aW9uL3NpemUgYXJlIHR1bmVkIGJ5XG4vLyAgIGRyYWdnaW5nIG9uIHRoZSBjYW52YXM7IGhlaWdodCBiZWhhdmlvdXIgZm9sbG93cyBmcm9tIHRoZSBjb21wb25lbnQgdHlwZS5cbi8vICAgRmlsdGVycyAg4oCUIE9ORSBsaXN0aW5nIG9mIGV2ZXJ5IGZpbHRlcmFibGUgY29sdW1uIG9uIHRoaXMgY29tcG9uZW50LiBFYWNoXG4vLyAgIHJvdyBjYXJyaWVzIHR3byB0b2dnbGVzOiBzaG93IGluIHRoZSByZXBvcnQgYmFyIGFuZC9vciBzaG93IG9uIHRoaXNcbi8vICAgY29tcG9uZW50IChib3RoLCBlaXRoZXIsIG9yIG5laXRoZXIpLiBUaGUgaW50ZXJmYWNlIChkYXRlIHJhbmdlIHZzIHZhbHVlXG4vLyAgIHBpY2tlcikgaXMgaW5mZXJyZWQgZnJvbSB0aGUgZGF0YSwgbmV2ZXIgY2hvc2VuLiBFYWNoIHRvZ2dsZSBwZXJzaXN0c1xuLy8gICBpbW1lZGlhdGVseSBhbmQgcmVmcmVzaGVzIHRoZSBpbi1kaWFsb2cgbGlzdC4gQSB2YWx1ZSBoYXMgbm8gY29tcG9uZW50XG4vLyAgIHRvIHNob3cgYSBmaWx0ZXIgb24sIHNvIGl0IGdldHMgdGhlIHJlcG9ydCBiYXIgdG9nZ2xlIG9ubHkuXG4vLyAgIFNRTCAvIENvbmZpZyDigJQgcmVhZC1vbmx5IGRpYWdub3N0aWNzLlxuLy8gQSBmb3JtdWxhIHZhbHVlIGhhcyBubyBGaWx0ZXJzIG9yIFNRTCB0YWI6IHRoZSBzZXJ2ZXIgd29ya3MgaXQgb3V0IG9mIG90aGVyXG4vLyB2YWx1ZXMgb24gaXRzIHBhZ2UsIHNvIGl0IHJ1bnMgbm8gc3RhdGVtZW50IGFuZCBmb2xsb3dzIHRoZSBmaWx0ZXJzIG9mIHRoZVxuLy8gdmFsdWVzIGl0IHJlYWRzLiBJdHMgU2V0dGluZ3MgdGFiIHNheXMgd2hhdCBpdCB3b3JrcyBvdXQsIHVuZGVyIGl0cyBuYW1lLlxuQENvbXBvbmVudCh7XG4gIHRlbXBsYXRlVXJsOiAnLi9jb21wb25lbnQtc2V0dGluZ3MuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9jb21wb25lbnQtc2V0dGluZ3MuY29tcG9uZW50LnNjc3MnXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtcbiAgICBGb3Jtc01vZHVsZSxcbiAgICBGc0Zvcm1Nb2R1bGUsXG4gICAgRnNNYXNrTW9kdWxlLFxuICAgIEZzRGlhbG9nTW9kdWxlLFxuICAgIEZzTGFiZWxNb2R1bGUsXG4gICAgRnNUYWJzTW9kdWxlLFxuICAgIE1hdFRhYnNNb2R1bGUsXG4gICAgTWF0RGlhbG9nVGl0bGUsXG4gICAgTWF0RGlhbG9nQ29udGVudCxcbiAgICBNYXREaWFsb2dBY3Rpb25zLFxuICAgIE1hdERpYWxvZ0Nsb3NlLFxuICAgIE1hdEZvcm1GaWVsZCxcbiAgICBNYXRIaW50LFxuICAgIE1hdExhYmVsLFxuICAgIE1hdFN1ZmZpeCxcbiAgICBNYXRCdXR0b24sXG4gICAgTWF0SWNvbixcbiAgICBNYXRJY29uQnV0dG9uLFxuICAgIE1hdElucHV0LFxuICAgIE1hdE9wdGlvbixcbiAgICBNYXRTZWxlY3QsXG4gICAgTWF0U2xpZGVUb2dnbGUsXG4gICAgTWF0VG9vbHRpcCxcbiAgICBGc01lbnVNb2R1bGUsXG4gIF0sXG59KVxuZXhwb3J0IGNsYXNzIENvbXBvbmVudFNldHRpbmdzQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcblxuICAvLyBBIGZpbHRlciB3YXMgYWRkZWQsIHJlbW92ZWQgb3IgcmUtbGV2ZWxsZWQsIHNvIHRoZSByZXBvcnQncyBmaWx0ZXIgZ3JvdXBzXG4gIC8vIGNoYW5nZWQuIFRob3NlIG11dGF0aW9ucyBwZXJzaXN0IHRoZSBtb21lbnQgdGhleSBhcmUgY2xpY2tlZCBhbmQgdGhlIGRpYWxvZ1xuICAvLyBjYW4gdGhlbiBiZSBkaXNtaXNzZWQgYnkgYSByb3V0ZSB0aGF0IGNhcnJpZXMgbm8gcmVzdWx0IChFc2NhcGUsIGJhY2tkcm9wKSxcbiAgLy8gc28gdGhlIHBhZ2UgaXMgdG9sZCBoZXJlIHJhdGhlciB0aGFuIHRocm91Z2ggdGhlIGNsb3NlIHJlc3VsdC5cbiAgcHVibGljIHJlYWRvbmx5IGZpbHRlcnNDaGFuZ2VkID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG4gIHB1YmxpYyBjb21wb25lbnQ6IFJlcG9ydENvbXBvbmVudDtcbiAgcHVibGljIHJlcG9ydDogUmVwb3J0O1xuXG4gIHB1YmxpYyBzZWxlY3RlZFRhYiA9ICdzZXR0aW5ncyc7XG5cbiAgcHVibGljIHJlYWRvbmx5IHRpdGxlID0gc2lnbmFsKCcnKTtcblxuICAvLyBXaGF0IHRoZSB0aXRsZSdzIEluc2VydCBmaWVsZCBtZW51IGxpc3RzLCBpbiBvcmRlcjogdGhlIHBhZ2UgYW5kIHJlcG9ydFxuICAvLyBmaWVsZHMsIHRoZW4gZWFjaCBmaWx0ZXIgb2YgdGhlIHJlcG9ydCBpbiB0aGUgZmlsdGVyIGJhcidzIG9yZGVyLiBBIHZhbHVlXG4gIC8vIHRva2VuIGlzIG5ldmVyIG9mZmVyZWQ6IHZhbHVlcyBiZWxvbmcgdG8gYSBwYWdlJ3MgdGV4dC5cbiAgcHVibGljIHJlYWRvbmx5IHRpdGxlRmllbGRzID0gY29tcHV0ZWQoKCkgPT4gdGV4dEZpZWxkcyh0aGlzLl9kYXRhLnRva2VucykpO1xuXG4gIC8vIEhvdyB0aGUgdGl0bGUgcmVhZHMgd2hlcmUgdGhlIGNvbXBvbmVudCBpcyBkcmF3biwgd2hpbGUgaXQgaG9sZHMgYSB0b2tlblxuICAvLyAoJ1NpZ24tdXBzIOKAlCBTZXB0ZW1iZXIgMjAyNicpOyBlbXB0eSBmb3IgYSB0aXRsZSB3aXRoIG5vbmUsIGFuZCBmb3IgYVxuICAvLyB2YWx1ZSwgd2hvc2UgTmFtZSBpcyBqdXN0IGl0cyBuYW1lLlxuICBwdWJsaWMgcmVhZG9ubHkgdGl0bGVTaG93bkFzID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGNvbnN0IHRpdGxlID0gdGhpcy50aXRsZSgpO1xuICAgIGNvbnN0IHNob3duID0gZmlsbFRpdGxlVG9rZW5zKHRpdGxlLCB0aGlzLl9kYXRhLnRva2Vucyk7XG5cbiAgICByZXR1cm4gIXRoaXMuaXNWYWx1ZSgpICYmIHNob3duICE9PSB0aXRsZSA/IHNob3duIDogJyc7XG4gIH0pO1xuXG4gIC8vIFRoZSBkaWFsb2cncyBoZWFkaW5nOiB0aGUgdGl0bGUgYXMgaXQgcmVhZHMgKGEgdmFsdWUncyBOYW1lIGFzIGl0IGlzKSxcbiAgLy8gZWxzZSB3aGF0IHRoZSBjb21wb25lbnQgaXMuXG4gIHB1YmxpYyByZWFkb25seSBoZWFkaW5nID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5fc2hvd25UaXRsZSgpIHx8ICh0aGlzLmlzVmFsdWUoKSA/ICdWYWx1ZScgOiAnQ29tcG9uZW50JykpO1xuXG4gIC8vIENvbXBvbmVudCBwYWRkaW5nIGluIGluY2hlcy4gYG51bWJlciB8IHN0cmluZ2AgZm9yIHRoZSBzYW1lIHJlYXNvbiBhcyB0aGVcbiAgLy8gcGFnZSBkaW1lbnNpb25zIGluIHJlcG9ydC1zZXR0aW5nczogZnNNYXNrTnVtYmVyIHNlZWRzIGZyb20gdGhlIG51bWJlciBidXRcbiAgLy8gaGFuZHMgYmFjayB0aGUgdW5tYXNrZWQgc3RyaW5nLCBhbmQgc2F2ZSBjYXN0cyBpdCBvbmNlIG9uIHRoZSB3YXkgb3V0LlxuICBwdWJsaWMgcGFkZGluZ1RvcDogbnVtYmVyIHwgc3RyaW5nID0gREVGQVVMVF9DT01QT05FTlRfUEFERElORztcbiAgcHVibGljIHBhZGRpbmdSaWdodDogbnVtYmVyIHwgc3RyaW5nID0gREVGQVVMVF9DT01QT05FTlRfUEFERElORztcbiAgcHVibGljIHBhZGRpbmdCb3R0b206IG51bWJlciB8IHN0cmluZyA9IERFRkFVTFRfQ09NUE9ORU5UX1BBRERJTkc7XG4gIHB1YmxpYyBwYWRkaW5nTGVmdDogbnVtYmVyIHwgc3RyaW5nID0gREVGQVVMVF9DT01QT05FTlRfUEFERElORztcblxuICBwdWJsaWMgY29uZmlnSnNvbiA9ICcnO1xuXG4gIC8vIC0tLS0gS1BJIGNhcmQgc3RhdGUgKGEgZGVyaXZlZCBLUEkgb25seSkgLS0tLVxuICBwdWJsaWMgcmVhZG9ubHkga3BpUG9sYXJpdHlPcHRpb25zID0gS1BJX0NIQU5HRV9QT0xBUklUWV9PUFRJT05TO1xuICBwdWJsaWMgcmVhZG9ubHkgZ3JhbnVsYXJpdHlPcHRpb25zID0gR1JBTlVMQVJJVFlfT1BUSU9OUztcbiAgcHVibGljIHJlYWRvbmx5IHNwYXJrbGluZU1pblBlcmlvZHMgPSBLUElfU1BBUktMSU5FX01JTl9QRVJJT0RTO1xuICBwdWJsaWMgcmVhZG9ubHkgc3BhcmtsaW5lTWF4UGVyaW9kcyA9IEtQSV9TUEFSS0xJTkVfTUFYX1BFUklPRFM7XG4gIHB1YmxpYyByZWFkb25seSBrcGlDYXJkID0gc2lnbmFsKGZhbHNlKTtcbiAgLy8gQSB2YWx1ZSBpbnNpZGUgYSB0ZXh0IGJsb2NrOiBubyBib3gsIHNvIG5vIHBhZGRpbmcuXG4gIHB1YmxpYyByZWFkb25seSBpc1ZhbHVlID0gc2lnbmFsKGZhbHNlKTtcbiAgLy8gQSBmb3JtdWxhIHZhbHVlOiBubyBzdGF0ZW1lbnQsIGNvbHVtbnMgb3IgZmlsdGVycyBvZiBpdHMgb3duLlxuICBwdWJsaWMgcmVhZG9ubHkgaXNGb3JtdWxhID0gc2lnbmFsKGZhbHNlKTtcbiAgLy8gV2hhdCBhIGZvcm11bGEgd29ya3Mgb3V0LCBpbiBpdHMgb3BlcmFuZHMnIG5hbWVzOyBlbXB0eSBmb3IgYW55IG90aGVyXG4gIC8vIGNvbXBvbmVudC5cbiAgcHVibGljIHJlYWRvbmx5IGZvcm11bGFMaW5lID0gY29tcHV0ZWQoKCkgPT4gKHRoaXMuaXNGb3JtdWxhKCkgPyB0aGlzLl9mb3JtdWxhTGluZSgpIDogJycpKTtcbiAgcHVibGljIHJlYWRvbmx5IGluY3JlYXNlSXMgPSBzaWduYWw8UmVwb3J0Q2hhbmdlUG9sYXJpdHk+KFJlcG9ydENoYW5nZVBvbGFyaXR5Lkdvb2QpO1xuICAvLyBUaGUgdGFyZ2V0IGFzIHR5cGVkOiBmc01hc2tOdW1iZXIgaGFuZHMgYmFjayB0aGUgdW5tYXNrZWQgc3RyaW5nLiBFbXB0eVxuICAvLyBtZWFucyBubyB0YXJnZXQuIEEgcGVyY2VudCBLUEkncyBpcyBpbiBwZXJjZW50ICh0YXJnZXRQZXJjZW50KS5cbiAgcHVibGljIHJlYWRvbmx5IHRhcmdldFZhbHVlID0gc2lnbmFsPG51bWJlciB8IHN0cmluZyB8IG51bGw+KG51bGwpO1xuICBwdWJsaWMgcmVhZG9ubHkgdGFyZ2V0TGFiZWwgPSBzaWduYWwoJycpO1xuICBwdWJsaWMgcmVhZG9ubHkgdGFyZ2V0UGVyY2VudCA9IHNpZ25hbChmYWxzZSk7XG4gIHB1YmxpYyByZWFkb25seSBoYXNUYXJnZXQgPSBjb21wdXRlZCgoKSA9PiB0aGlzLl9udW1iZXIodGhpcy50YXJnZXRWYWx1ZSgpKSAhPT0gbnVsbCk7XG4gIHB1YmxpYyByZWFkb25seSBzcGFya2xpbmUgPSBzaWduYWwoZmFsc2UpO1xuICBwdWJsaWMgcmVhZG9ubHkgc3BhcmtsaW5lR3JhbnVsYXJpdHkgPSBzaWduYWw8Q2hhcnRHcmFudWxhcml0eT4oS1BJX1NQQVJLTElORV9ERUZBVUxUX0dSQU5VTEFSSVRZKTtcbiAgcHVibGljIHJlYWRvbmx5IHNwYXJrbGluZVBlcmlvZHMgPSBzaWduYWw8bnVtYmVyIHwgc3RyaW5nPihLUElfU1BBUktMSU5FX0RFRkFVTFRfUEVSSU9EUyk7XG5cbiAgLy8gLS0tLSBTUUwgdGFiIHN0YXRlIC0tLS1cbiAgLy8gVGhlIHN0YXRlbWVudCwgb25jZSBmZXRjaGVkLiBOdWxsIHdoaWxlIGl0IGlzIGluIGZsaWdodCwgYW5kIG51bGwgd2hlbiB0aGVcbiAgLy8gY29tcG9uZW50J3MgZG9jdW1lbnQgY291bGQgbm90IGJlIGNvbXBpbGVkIChzcWxFcnJvciB0aGVuIHNheXMgd2h5KS5cbiAgcHVibGljIHJlYWRvbmx5IHNxbCA9IHNpZ25hbDxzdHJpbmcgfCBudWxsPihudWxsKTtcbiAgLy8gVHJ1ZSB3aGVuIHRoZSBzdGF0ZW1lbnQgaXMgYSBERVJJVkVEIGJhc2VsaW5lOiBubyBmaWx0ZXJzLCB0aGUgYXV0aG9yZWRcbiAgLy8gZ3JhaW4sIHRpbWVzIGluIHRoZSByZXBvcnQncyBlZmZlY3RpdmUgem9uZS4gVGhlIHRhYiBzYXlzIHNvLCBiZWNhdXNlIHRoZVxuICAvLyBudW1iZXJzIG9uIHNjcmVlbiBjb21lIGZyb20gdGhpcyBzdGF0ZW1lbnQgcGx1cyB0aGUgdmlld2VyJ3Mgb3duIGNob2ljZXNcbiAgLy8gYW5kIHRoZSB0d28gY2FuIGRpZmZlci5cbiAgcHVibGljIHJlYWRvbmx5IHNxbEJhc2VsaW5lID0gc2lnbmFsKGZhbHNlKTtcbiAgLy8gVGhlIHpvbmUgdGhlIHN0YXRlbWVudCB3YXMgY29tcGlsZWQgaW46IHRoZSByZXBvcnQncyBlZmZlY3RpdmUgem9uZSwgc2VudFxuICAvLyB3aXRoIHRoZSBTUUwuIEEgc2VydmVyIHRvbyBvbGQgdG8gc2VuZCBpdCBjb21waWxlZCBpbiBVVEMuXG4gIHB1YmxpYyByZWFkb25seSBzcWxUaW1lem9uZSA9IHNpZ25hbCgnVVRDJyk7XG4gIHB1YmxpYyByZWFkb25seSBzcWxFcnJvciA9IHNpZ25hbDxzdHJpbmcgfCBudWxsPihudWxsKTtcblxuICAvLyAtLS0tIGZpbHRlciBtYW5hZ2VtZW50IHN0YXRlIC0tLS1cbiAgLy8gT25lIHJvdyBwZXIgZmlsdGVyYWJsZSBjb2x1bW4uIFRoZSBwbGFjZW1lbnQgYW5kIHRoZSB0b2dnbGUgY2hhbmdlXG4gIC8vIG9wdGltaXN0aWNhbGx5IG9uIGNsaWNrIChzbyB0aGUgVUkgbmV2ZXIgYmxpbmtzIHdoaWxlIHRoZSByZXF1ZXN0IGlzIGluXG4gIC8vIGZsaWdodCkgYW5kIHJlY29uY2lsZSBmcm9tIHRoZSBzZXJ2ZXIgb24gcmVsb2FkLlxuICBwdWJsaWMgcmVhZG9ubHkgcm93cyA9IHNpZ25hbDxGaWx0ZXJSb3dbXT4oW10pO1xuICBwdWJsaWMgcmVhZG9ubHkgY29sdW1uc0Vycm9yID0gc2lnbmFsPHN0cmluZyB8IG51bGw+KG51bGwpO1xuICAvLyBUaGUgVHlwZSBzZWxlY3QncyBjaG9pY2VzLiBBIHJvdydzIFR5cGUgc2VsZWN0LCBSZXBvcnQgYmFyIHNlbGVjdCBhbmRcbiAgLy8gVGhpcyBjb21wb25lbnQgdG9nZ2xlIGZvbGxvdyB0aGUgcnVsZXMgaW4gZmlsdGVyLXNldHRpbmdzLXJ1bGVzLnRzLlxuICBwdWJsaWMgcmVhZG9ubHkgdHlwZU9wdGlvbnMgPSBGSUxURVJfVFlQRV9PUFRJT05TO1xuXG4gIC8vIFRoZSByYXcgaW5wdXRzIHRoZSByb3dzIGFyZSBidWlsdCBmcm9tLlxuICBwcml2YXRlIF9maWx0ZXJhYmxlQ29sdW1uczogUmVwb3J0RmlsdGVyYWJsZUNvbHVtbltdID0gW107XG4gIHByaXZhdGUgX2ZpbHRlcnM6IFJlcG9ydEZpbHRlcltdID0gW107XG4gIHByaXZhdGUgX2dyb3Vwc0J5SWQgPSBuZXcgTWFwPG51bWJlciwgUmVwb3J0RmlsdGVyR3JvdXA+KCk7XG4gIC8vIFRoZSB0eXBlIHBpY2tlZCBmb3IgYSBjb2x1bW4gd2l0aCBubyBmaWx0ZXIgeWV0LCBzbyBhIHJlbG9hZCBrZWVwcyBpdC5cbiAgcHJpdmF0ZSBfcGlja2VkVHlwZXMgPSBuZXcgTWFwPHN0cmluZywgUmVwb3J0RmlsdGVyVHlwZT4oKTtcblxuICBwcml2YXRlIHJlYWRvbmx5IF90eXBlTGFiZWxzOiBSZWNvcmQ8UmVwb3J0RmlsdGVyVHlwZSwgc3RyaW5nPiA9IHtcbiAgICBzZWxlY3Q6ICdQaWNrIHZhbHVlcycsXG4gICAgZGF0ZVJhbmdlOiAnRGF0ZSByYW5nZScsXG4gICAga2V5d29yZDogJ1NlYXJjaCB0ZXh0JyxcbiAgICBudW1iZXJSYW5nZTogJ051bWJlciByYW5nZScsXG4gIH07XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfZGF0YTogQ29tcG9uZW50U2V0dGluZ3NEaWFsb2dEYXRhID0gaW5qZWN0KE1BVF9ESUFMT0dfREFUQSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX3RpdGxlSW5wdXQgPSB2aWV3Q2hpbGQ8RWxlbWVudFJlZjxIVE1MSW5wdXRFbGVtZW50Pj4oJ3RpdGxlSW5wdXQnKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfZGlhbG9nUmVmID0gaW5qZWN0PE1hdERpYWxvZ1JlZjxDb21wb25lbnRTZXR0aW5nc0NvbXBvbmVudCwgQ29tcG9uZW50U2V0dGluZ3NSZXN1bHQ+PihNYXREaWFsb2dSZWYpO1xuICBwcml2YXRlIHJlYWRvbmx5IF9yZXBvcnREYXRhID0gaW5qZWN0KFJlcG9ydERhdGEpO1xuICBwcml2YXRlIHJlYWRvbmx5IF9tZXNzYWdlID0gaW5qZWN0KEZzTWVzc2FnZSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX3Byb21wdCA9IGluamVjdChGc1Byb21wdCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX2Rlc3Ryb3lSZWYgPSBpbmplY3QoRGVzdHJveVJlZik7XG5cbiAgcHVibGljIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMucmVwb3J0ID0gdGhpcy5fZGF0YS5yZXBvcnQ7XG4gICAgdGhpcy5jb21wb25lbnQgPSB0aGlzLl9kYXRhLmNvbXBvbmVudDtcblxuICAgIHRoaXMudGl0bGUuc2V0KHRoaXMuY29tcG9uZW50LnRpdGxlID8/ICcnKTtcbiAgICB0aGlzLmlzVmFsdWUuc2V0KHRoaXMuY29tcG9uZW50LnR5cGUgPT09ICd2YWx1ZScpO1xuICAgIHRoaXMuaXNGb3JtdWxhLnNldCghIXRoaXMuY29tcG9uZW50LmNvbmZpZz8uZm9ybXVsYSk7XG5cbiAgICBjb25zdCBwYWRkaW5nID0gdGhpcy5jb21wb25lbnQuY29uZmlnPy5wYWRkaW5nO1xuICAgIHRoaXMucGFkZGluZ1RvcCA9IHBhZGRpbmc/LnRvcCA/PyBERUZBVUxUX0NPTVBPTkVOVF9QQURESU5HO1xuICAgIHRoaXMucGFkZGluZ1JpZ2h0ID0gcGFkZGluZz8ucmlnaHQgPz8gREVGQVVMVF9DT01QT05FTlRfUEFERElORztcbiAgICB0aGlzLnBhZGRpbmdCb3R0b20gPSBwYWRkaW5nPy5ib3R0b20gPz8gREVGQVVMVF9DT01QT05FTlRfUEFERElORztcbiAgICB0aGlzLnBhZGRpbmdMZWZ0ID0gcGFkZGluZz8ubGVmdCA/PyBERUZBVUxUX0NPTVBPTkVOVF9QQURESU5HO1xuXG4gICAgdGhpcy5jb25maWdKc29uID0gSlNPTi5zdHJpbmdpZnkodGhpcy5jb21wb25lbnQuY29uZmlnID8/IHt9LCBudWxsLCAyKTtcblxuICAgIHRoaXMuX3NlZWRLcGlDYXJkKCk7XG5cbiAgICB0aGlzLl9zZWVkRmlsdGVycyh0aGlzLnJlcG9ydCwgdGhpcy5jb21wb25lbnQuaWQpO1xuXG4gICAgLy8gQSBmb3JtdWxhIGhhcyBubyBzdGF0ZW1lbnQgdG8gY29tcGlsZSBhbmQgbm8gY29sdW1ucyB0byBmaWx0ZXIgb24sIGFuZFxuICAgIC8vIHRoZSBzZXJ2ZXIgd291bGQgcmVmdXNlIGJvdGggcmVxdWVzdHMuXG4gICAgaWYgKCF0aGlzLmlzRm9ybXVsYSgpKSB7XG4gICAgICB0aGlzLl9sb2FkQ29sdW1ucygpO1xuICAgICAgdGhpcy5fbG9hZFNxbCgpO1xuICAgIH1cbiAgfVxuXG4gIC8vIEh1bWFuLWZyaWVuZGx5IG5hbWUgZm9yIHRoZSBpbmZlcnJlZCBpbnRlcmZhY2Ugc2hvd24gYmVzaWRlIGVhY2ggY29sdW1uLlxuICBwdWJsaWMgdHlwZUxhYmVsKHR5cGU6IFJlcG9ydEZpbHRlclR5cGUpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLl90eXBlTGFiZWxzW3R5cGVdID8/IHR5cGU7XG4gIH1cblxuICAvLyBDb25maXJtIGFuZCBkZWxldGUgaGVyZSwgd2hpbGUgdGhlIGRpYWxvZyBpcyBzdGlsbCBvcGVuLCB0aGVuIGNsb3NlIHdpdGggYVxuICAvLyBgZGVsZXRlZGAgcmVzdWx0IGZvciB0aGUgcGFnZSB0byBhY3Qgb24g4oCUIHRoZSBzYW1lIHNoYXBlIHRoZSByZXBvcnRcbiAgLy8gc2V0dGluZ3MgZGlhbG9nIHVzZXMgZm9yIGRlbGV0aW5nIGEgcmVwb3J0LlxuICAvL1xuICAvLyBUaGUgY29uZmlybSBzYXlzIGl0IGNhbm5vdCBiZSB1bmRvbmUgYmVjYXVzZSwgZnJvbSB0aGUgVUksIGl0IGNhbm5vdDogdGhlXG4gIC8vIHJvdyBpcyBzb2Z0LWRlbGV0ZWQgc2VydmVyLXNpZGUgYnV0IG5vdGhpbmcgaGVyZSByZXN0b3JlcyBhIGNvbXBvbmVudC5cbiAgLy8gQSB2YWx1ZSdzIGNvbmZpcm0gYWxzbyBzYXlzIHdoYXQgZ29lcyB3aXRoIGl0OiB0aGUgc2VydmVyIHRha2VzIGl0c1xuICAvLyB0b2tlbnMgb3V0IG9mIGV2ZXJ5IHRleHQgb24gaXRzIHBhZ2UsIG5vdCBqdXN0IHRoZSBvbmUgaXQgd2FzIG9wZW5lZCBmcm9tLFxuICAvLyBhbmQgZGVsZXRlcyB0aGUgZm9ybXVsYXMgdGhhdCByZWFkIGl0IChfZGVwZW5kZW50c05vdGUpLlxuICAvL1xuICAvLyBUaGUgcHJvbXB0IHJlbmRlcnMgaXRzIHRlbXBsYXRlIGFzIGh0bWwsIHNvIGV2ZXJ5IG5hbWUgaW4gaXQgaXMgZXNjYXBlZC5cbiAgcHVibGljIGRlbGV0ZSgpOiB2b2lkIHtcbiAgICB0aGlzLl9wcm9tcHQuY29uZmlybSh0aGlzLmlzVmFsdWUoKVxuICAgICAgPyB7XG4gICAgICAgIHRpdGxlOiAnRGVsZXRlIFZhbHVlJyxcbiAgICAgICAgdGVtcGxhdGU6IGBEZWxldGUgdGhlIHZhbHVlIFwiJHtlc2NhcGVIdG1sKHRoaXMuY29tcG9uZW50LnRpdGxlIHx8IHZhbHVlS2V5KHRoaXMuY29tcG9uZW50KSl9XCI/IEl0IGlzIGFsc28gdGFrZW4gb3V0IG9mIGV2ZXJ5IHRleHQgb24gdGhpcyBwYWdlLiBUaGlzIGNhbm5vdCBiZSB1bmRvbmUuJHt0aGlzLl9kZXBlbmRlbnRzTm90ZSgpfWAsXG4gICAgICB9XG4gICAgICA6IHtcbiAgICAgICAgdGl0bGU6ICdEZWxldGUgQ29tcG9uZW50JyxcbiAgICAgICAgdGVtcGxhdGU6IGBBcmUgeW91IHN1cmUgeW91IHdvdWxkIGxpa2UgdG8gZGVsZXRlIFwiJHtlc2NhcGVIdG1sKHRoaXMuX3Nob3duVGl0bGUoKSB8fCAndGhpcyBjb21wb25lbnQnKX1cIj8gVGhpcyBjYW5ub3QgYmUgdW5kb25lLmAsXG4gICAgICB9KVxuICAgICAgLnBpcGUoXG4gICAgICAgIHN3aXRjaE1hcCgoKSA9PiB0aGlzLl9yZXBvcnREYXRhLmRlbGV0ZUNvbXBvbmVudCh0aGlzLnJlcG9ydC5pZCwgdGhpcy5jb21wb25lbnQuaWQpKSxcbiAgICAgICAgdGFwKCgpID0+IHtcbiAgICAgICAgICB0aGlzLl9tZXNzYWdlLnN1Y2Nlc3ModGhpcy5pc1ZhbHVlKCkgPyAnVmFsdWUgZGVsZXRlZCcgOiAnQ29tcG9uZW50IGRlbGV0ZWQnKTtcbiAgICAgICAgICB0aGlzLl9kaWFsb2dSZWYuY2xvc2UoeyBkZWxldGVkOiB0cnVlIH0pO1xuICAgICAgICB9KSxcbiAgICAgICAgdGFrZVVudGlsRGVzdHJveWVkKHRoaXMuX2Rlc3Ryb3lSZWYpLFxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgpO1xuICB9XG5cbiAgLy8gUHV0cyBhIGZpZWxkJ3MgdG9rZW4gaW50byB0aGUgdGl0bGUgYXQgdGhlIGNhcmV0LCBvdmVyIGFueSB0ZXh0IHNlbGVjdGVkXG4gIC8vIHRoZXJlLCBhcyBpZiBpdCB3ZXJlIHR5cGVkOiB0aGUgbW9kZWwgZm9sbG93cyBhbmQgdGhlIGZpZWxkIGlzIGRpcnR5LiBUaGVcbiAgLy8gaW5wdXQga2VlcHMgaXRzIGNhcmV0IHdoaWxlIHRoZSBtZW51IGlzIG9wZW47IGZvY3VzIGNvbWVzIGJhY2sgdG8gaXQgb25jZVxuICAvLyB0aGUgbWVudSBoYXMgaGFuZGVkIGZvY3VzIGJhY2sgdG8gaXRzIGJ1dHRvbi5cbiAgcHVibGljIGluc2VydEZpZWxkKGZpZWxkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBpbnB1dCA9IHRoaXMuX3RpdGxlSW5wdXQoKT8ubmF0aXZlRWxlbWVudDtcbiAgICBpZiAoIWlucHV0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgZW5kID0gaW5wdXQudmFsdWUubGVuZ3RoO1xuICAgIGlucHV0LnNldFJhbmdlVGV4dChmaWVsZFRva2VuKGZpZWxkKSwgaW5wdXQuc2VsZWN0aW9uU3RhcnQgPz8gZW5kLCBpbnB1dC5zZWxlY3Rpb25FbmQgPz8gZW5kLCAnZW5kJyk7XG4gICAgaW5wdXQuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoJ2lucHV0JykpO1xuICAgIHNldFRpbWVvdXQoKCkgPT4gaW5wdXQuZm9jdXMoKSk7XG4gIH1cblxuICAvLyBBIHBlcmNlbnQgdGFyZ2V0J3MgYm91bmQsIGluIHRoZSBwZXJjZW50IGl0IGlzIHR5cGVkIGluLiBJdCByZWFkcyB0aGVcbiAgLy8gY29udHJvbCwgd2hpY2ggZnNGb3JtIHZhbGlkYXRlcyBiZWZvcmUgbmdNb2RlbENoYW5nZSB1cGRhdGVzIHRoZSBzaWduYWwuXG4gIHB1YmxpYyB2YWxpZGF0ZVRhcmdldCA9IChjb250cm9sOiBBYnN0cmFjdENvbnRyb2wpOiB2b2lkID0+IHtcbiAgICBjb25zdCB2YWx1ZSA9IHRoaXMuX251bWJlcihjb250cm9sLnZhbHVlKTtcblxuICAgIGlmICh0aGlzLnRhcmdldFBlcmNlbnQoKSAmJiB2YWx1ZSAhPT0gbnVsbCAmJiB2YWx1ZSA+IEtQSV9QRVJDRU5UX1RBUkdFVF9NQVgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQSBwZXJjZW50IHRhcmdldCBjYW4gYmUgYXQgbW9zdCAxMCwwMDAlJyk7XG4gICAgfVxuICB9O1xuXG4gIHB1YmxpYyBzYXZlID0gKCkgPT4ge1xuICAgIGNvbnN0IHNldHRpbmdzOiBDb21wb25lbnRTZXR0aW5ncyA9IHtcbiAgICAgIC8vIFRoZSBzZXJ2ZXIgdHJpbXMgYSB0aXRsZTsgYSB2YWx1ZSdzIE5hbWUgaXMgd2hhdCBpdHMgY2hpcHMgc2hvdywgc28gaXRcbiAgICAgIC8vIGdvZXMgYXMgdGhlIHNlcnZlciBrZWVwcyBpdC5cbiAgICAgIHRpdGxlOiB0aGlzLmlzVmFsdWUoKSA/IHRoaXMudGl0bGUoKS50cmltKCkgOiB0aGlzLnRpdGxlKCksXG4gICAgICBwYWRkaW5nOiB7XG4gICAgICAgIHRvcDogdGhpcy5fcGFkZGluZyh0aGlzLnBhZGRpbmdUb3ApLFxuICAgICAgICByaWdodDogdGhpcy5fcGFkZGluZyh0aGlzLnBhZGRpbmdSaWdodCksXG4gICAgICAgIGJvdHRvbTogdGhpcy5fcGFkZGluZyh0aGlzLnBhZGRpbmdCb3R0b20pLFxuICAgICAgICBsZWZ0OiB0aGlzLl9wYWRkaW5nKHRoaXMucGFkZGluZ0xlZnQpLFxuICAgICAgfSxcbiAgICB9O1xuXG4gICAgLy8gVGhlIGNhcmQga2V5cyBnbyBhcyBjb25maWcga2V5cyBiZXNpZGUgdGhlIHBhZGRpbmcgKGluY3JlYXNlSXMsIHRhcmdldFxuICAgIC8vIGFuZCBzcGFya2xpbmUsIG51bGwgdG8gcmVtb3ZlIG9uZSksIGFuZCBvbmx5IHdoZW4gdGhleSBjaGFuZ2VkLCBzbyBhXG4gICAgLy8gdGl0bGUgZWRpdCBuZXZlciB0b3VjaGVzIHRoZW0uXG4gICAgY29uc3Qga3BpID0gdGhpcy5rcGlDYXJkKCkgPyB0aGlzLl9rcGlDYXJkU2V0dGluZ3MoKSA6IG51bGw7XG4gICAgY29uc3Qga3BpQ2hhbmdlZCA9ICEha3BpXG4gICAgICAmJiAhc2FtZUtwaUNhcmRTZXR0aW5ncyhrcGksIGtwaUNhcmRTZXR0aW5ncyh0aGlzLmNvbXBvbmVudC5jb25maWcgYXMgS3BpQ29uZmlnKSk7XG5cbiAgICByZXR1cm4gdGhpcy5fcmVwb3J0RGF0YS51cGRhdGVDb21wb25lbnQodGhpcy5yZXBvcnQuaWQsIHRoaXMuY29tcG9uZW50LmlkLCB7XG4gICAgICB0aXRsZTogc2V0dGluZ3MudGl0bGUsXG4gICAgICAuLi4odGhpcy5pc1ZhbHVlKCkgPyB7fSA6IHsgcGFkZGluZzogc2V0dGluZ3MucGFkZGluZyB9KSxcbiAgICAgIC4uLihrcGlDaGFuZ2VkID8ga3BpIDoge30pLFxuICAgIH0pXG4gICAgICAucGlwZShcbiAgICAgICAgdGFwKChyZXNwb25zZTogQ29tcG9uZW50U2V0dGluZ3NSZXNwb25zZSkgPT4ge1xuICAgICAgICAgIC8vIFRoZSBjYXJkIGlzIGRyYXduIGZyb20gdGhlIGtleXMgdGhlIHNlcnZlciBzYXZlZCwgcmVhZCBiYWNrIGZyb21cbiAgICAgICAgICAvLyB0aGUgY29uZmlnIGl0IHJldHVybnMuIEEgc2VydmVyIHRoYXQgcmV0dXJucyBubyBjb25maWcgZGlkIG5vdFxuICAgICAgICAgIC8vIHNhdmUgdGhlbSwgc28gdGhlIGNhcmQga2VlcHMgd2hhdCBpdCBoYWQgYW5kIHRoZSBkaWFsb2cgc2F5cyBzby5cbiAgICAgICAgICBjb25zdCBzYXZlZCA9IGtwaUNoYW5nZWQgPyB0aGlzLl9zYXZlZEtwaUNhcmQocmVzcG9uc2UpIDogbnVsbDtcblxuICAgICAgICAgIGlmIChrcGlDaGFuZ2VkICYmICFzYXZlZCkge1xuICAgICAgICAgICAgdGhpcy5fbWVzc2FnZS53YXJuaW5nKCdDb21wb25lbnQgc2F2ZWQsIGJ1dCB0aGUgc2VydmVyIGRpZCBub3Qgc2F2ZSB0aGUgY2FyZCBzZXR0aW5ncycpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9tZXNzYWdlLnN1Y2Nlc3ModGhpcy5pc1ZhbHVlKCkgPyAnVmFsdWUgc2F2ZWQnIDogJ0NvbXBvbmVudCBzYXZlZCcpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHRoaXMuX2RpYWxvZ1JlZi5jbG9zZSh7IHNldHRpbmdzOiBzYXZlZCA/IHsgLi4uc2V0dGluZ3MsIGtwaTogc2F2ZWQgfSA6IHNldHRpbmdzIH0pO1xuICAgICAgICB9KSxcbiAgICAgICk7XG4gIH07XG5cbiAgLy8gVGhlIHR5cGUgYSBjb2x1bW4ncyBmaWx0ZXIgd2lsbCBiZSBtYWRlIHdpdGguIE9ubHkgYSBjb2x1bW4gd2l0aCBub1xuICAvLyBmaWx0ZXIgb2ZmZXJzIHRoZSBwaWNrICh0aGUgVHlwZSBzZWxlY3QgaXMgbG9ja2VkIG90aGVyd2lzZSksIGFuZCBub3RoaW5nXG4gIC8vIGlzIHNhdmVkIHVudGlsIHRoZSBmaWx0ZXIgaXMgbWFkZS5cbiAgcHVibGljIHNldFR5cGUocm93OiBGaWx0ZXJSb3csIHR5cGU6IFJlcG9ydEZpbHRlclR5cGUpOiB2b2lkIHtcbiAgICB0aGlzLl9waWNrZWRUeXBlcy5zZXQocm93LmNvbHVtbiwgdHlwZSk7XG4gICAgdGhpcy5fcGF0Y2hSb3cocm93LCB7IHR5cGUgfSk7XG4gIH1cblxuICAvLyBXaGVyZSB0aGUgcm93J3MgZmlsdGVyIHNob3dzIGluIHRoZSByZXBvcnQgYmFyLiBUaGlzIHBhZ2Ugb25seSBzaG93cyBpdFxuICAvLyBpbiBpdHMgcGFnZSdzIGJhciBhbG9uZSwgc28gdGhlIFRoaXMgY29tcG9uZW50IHRvZ2dsZSBnb2VzIG9mZiBhbmQgbG9ja3MuXG4gIC8vIEEgdmFsdWUgaGFzIHRoaXMgc2VsZWN0IG9ubHksIHdpdGggaXRzIG93biBydWxlcyAoX2FwcGx5VmFsdWVMZXZlbCkuXG4gIHB1YmxpYyBzZXRQbGFjZW1lbnQocm93OiBGaWx0ZXJSb3csIHBsYWNlbWVudDogRmlsdGVyQmFyUGxhY2VtZW50KTogdm9pZCB7XG4gICAgY29uc3QgcGF0Y2hlZCA9IHRoaXMuX3BhdGNoUm93KHJvdywge1xuICAgICAgcGxhY2VtZW50LFxuICAgICAgY29tcG9uZW50OiBwbGFjZW1lbnQgPT09ICdwYWdlJyA/IGZhbHNlIDogcm93LmNvbXBvbmVudCxcbiAgICAgIGNvbXBvbmVudFRvZ2dsZTogY29tcG9uZW50VG9nZ2xlU3RhdGUocGxhY2VtZW50KSxcbiAgICB9KTtcblxuICAgIGlmICh0aGlzLmlzVmFsdWUoKSkge1xuICAgICAgdGhpcy5fYXBwbHlWYWx1ZUxldmVsKHBhdGNoZWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9hcHBseUxldmVsKHBhdGNoZWQpO1xuICAgIH1cbiAgfVxuXG4gIC8vIEEgdmFsdWUgaGFzIG5vIFRoaXMgY29tcG9uZW50IHRvZ2dsZS5cbiAgcHVibGljIHNldENvbXBvbmVudChyb3c6IEZpbHRlclJvdywgY29tcG9uZW50OiBib29sZWFuKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaXNWYWx1ZSgpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5fYXBwbHlMZXZlbCh0aGlzLl9wYXRjaFJvdyhyb3csIHsgY29tcG9uZW50IH0pKTtcbiAgfVxuXG4gIC8vIFBlcnNpc3QgdGhlIGxldmVsIHRoZSByb3cncyBjb250cm9scyBhc2sgZm9yLCB0aGVuIHJlY29uY2lsZSBvbiByZWxvYWQuXG4gIC8vIE5vIGxldmVsIOKGkiBubyBmaWx0ZXIgKHJlbW92ZWQpOyBvdGhlcndpc2UgdGhlIGZpbHRlciBleGlzdHMgYXQgdGhhdFxuICAvLyBsZXZlbC4gQSBzZXJ2ZXIgcmVmdXNhbCAoYSBwYWdlIGZpbHRlciB3aG9zZSBtZW1iZXJzIHNpdCBvbiB0d28gcGFnZXMpXG4gIC8vIHNob3dzIGl0cyBvd24gdGV4dCBhbmQgdGhlIHJvdyBzbmFwcyBiYWNrLlxuICBwcml2YXRlIF9hcHBseUxldmVsKHJvdzogRmlsdGVyUm93KTogdm9pZCB7XG4gICAgY29uc3QgbGV2ZWwgPSBmaWx0ZXJMZXZlbChyb3cucGxhY2VtZW50LCByb3cuY29tcG9uZW50KTtcbiAgICBjb25zdCBleGlzdGluZyA9IHRoaXMuX2ZpbHRlcnMuZmluZCgoZmlsdGVyKSA9PiBmaWx0ZXIuZmlsdGVyQ29sdW1uID09PSByb3cuY29sdW1uKTtcblxuICAgIGlmICghbGV2ZWwpIHtcbiAgICAgIGlmIChleGlzdGluZykge1xuICAgICAgICB0aGlzLl9ydW4odGhpcy5fcmVwb3J0RGF0YS5kZWxldGVGaWx0ZXIodGhpcy5yZXBvcnQuaWQsIGV4aXN0aW5nLmlkKSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoZXhpc3RpbmcpIHtcbiAgICAgIHRoaXMuX3J1bih0aGlzLl9yZXBvcnREYXRhLnVwZGF0ZUZpbHRlckdyb3VwKHRoaXMucmVwb3J0LmlkLCBleGlzdGluZy5maWx0ZXJHcm91cElkLCB7IGxldmVsIH0pKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fYWRkRmlsdGVyKHJvdywgbGV2ZWwpO1xuICAgIH1cbiAgfVxuXG4gIC8vIEEgdmFsdWUncyBSZXBvcnQgYmFyIHNlbGVjdCwgdGhlIG9ubHkgY29udHJvbCBpdCBoYXMuIEl0cyBmaWx0ZXIncyBncm91cFxuICAvLyBtYXkgYmUgc2hhcmVkICh0aGUgcmVwb3J0J3MgUGVyaW9kLCBzYXkpLCBhbmQgYSB2YWx1ZSBoYXMgbm8gc3RyaXAgb2YgaXRzXG4gIC8vIG93biwgc28gYSBwaWNrIG5ldmVyIGxvd2VycyB0aGUgZ3JvdXAgKHZhbHVlRmlsdGVyTGV2ZWwpLiBBIHBpY2sgdGhhdFxuICAvLyBtb3ZlcyBub3RoaW5nIHB1dHMgdGhlIHJvdyBiYWNrIGFzIHRoZSBncm91cCBzdGFuZHMuXG4gIHByaXZhdGUgX2FwcGx5VmFsdWVMZXZlbChyb3c6IEZpbHRlclJvdyk6IHZvaWQge1xuICAgIGNvbnN0IGV4aXN0aW5nID0gdGhpcy5fZmlsdGVycy5maW5kKChmaWx0ZXIpID0+IGZpbHRlci5maWx0ZXJDb2x1bW4gPT09IHJvdy5jb2x1bW4pO1xuICAgIGNvbnN0IGN1cnJlbnQgPSBleGlzdGluZyA/IHRoaXMuX2dyb3Vwc0J5SWQuZ2V0KGV4aXN0aW5nLmZpbHRlckdyb3VwSWQpPy5sZXZlbCA6IHVuZGVmaW5lZDtcbiAgICBjb25zdCBsZXZlbCA9IHZhbHVlRmlsdGVyTGV2ZWwocm93LnBsYWNlbWVudCwgY3VycmVudCk7XG5cbiAgICBpZiAoIWxldmVsKSB7XG4gICAgICBpZiAoZXhpc3RpbmcpIHtcbiAgICAgICAgdGhpcy5fcnVuKHRoaXMuX3JlcG9ydERhdGEuZGVsZXRlRmlsdGVyKHRoaXMucmVwb3J0LmlkLCBleGlzdGluZy5pZCkpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoIWV4aXN0aW5nKSB7XG4gICAgICB0aGlzLl9hZGRGaWx0ZXIocm93LCBsZXZlbCk7XG4gICAgfSBlbHNlIGlmIChsZXZlbCAhPT0gY3VycmVudCkge1xuICAgICAgdGhpcy5fcnVuKHRoaXMuX3JlcG9ydERhdGEudXBkYXRlRmlsdGVyR3JvdXAodGhpcy5yZXBvcnQuaWQsIGV4aXN0aW5nLmZpbHRlckdyb3VwSWQsIHsgbGV2ZWwgfSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9yZWJ1aWxkUm93cygpO1xuICAgIH1cbiAgfVxuXG4gIC8vIFRoZSB0eXBlIGdvZXMgb25seSB3aGVuIHRoZSBhdXRob3IgY291bGQgcGljayBpdDsgb3RoZXJ3aXNlIHRoZSBzZXJ2ZXJcbiAgLy8gaW5mZXJzIGl0LCBhcyBpdCBhbHdheXMgaGFzLlxuICBwcml2YXRlIF9hZGRGaWx0ZXIocm93OiBGaWx0ZXJSb3csIGxldmVsOiBSZXBvcnRGaWx0ZXJMZXZlbCk6IHZvaWQge1xuICAgIHRoaXMuX3J1bih0aGlzLl9yZXBvcnREYXRhLmFkZEZpbHRlcih0aGlzLnJlcG9ydC5pZCwgdGhpcy5jb21wb25lbnQuaWQsIHtcbiAgICAgIGZpbHRlckNvbHVtbjogcm93LmNvbHVtbixcbiAgICAgIGxhYmVsOiByb3cubGFiZWwsXG4gICAgICBsZXZlbCxcbiAgICAgIC4uLihyb3cudHlwZVNlbGVjdC5zaG93ID8geyB0eXBlOiByb3cudHlwZSB9IDoge30pLFxuICAgIH0pKTtcbiAgfVxuXG4gIC8vIEEgbmV3IHJvdyBvYmplY3QgcmF0aGVyIHRoYW4gYSBtdXRhdGlvbiwgc28gdGhlIHNpZ25hbCBzZWVzIHRoZSBjaGFuZ2U7XG4gIC8vIHRoZSBAZm9yIHRyYWNrcyB0aGUgY29sdW1uLCBzbyB0aGUgcm93J3MgY29udHJvbHMgc3Vydml2ZSB0aGUgc3dhcC5cbiAgcHJpdmF0ZSBfcGF0Y2hSb3cocm93OiBGaWx0ZXJSb3csIHBhdGNoOiBQYXJ0aWFsPEZpbHRlclJvdz4pOiBGaWx0ZXJSb3cge1xuICAgIGNvbnN0IHBhdGNoZWQgPSB7IC4uLnJvdywgLi4ucGF0Y2ggfTtcbiAgICB0aGlzLnJvd3MudXBkYXRlKChyb3dzKSA9PiByb3dzLm1hcCgoaXRlbSkgPT4gKGl0ZW0uY29sdW1uID09PSByb3cuY29sdW1uID8gcGF0Y2hlZCA6IGl0ZW0pKSk7XG5cbiAgICByZXR1cm4gcGF0Y2hlZDtcbiAgfVxuXG4gIC8vIFRoZSBzdG9yZWQgdGl0bGUgYXMgaXQgcmVhZHMgd2hlcmUgdGhlIGNvbXBvbmVudCBpcyBkcmF3biwgaXRzIHRva2Vuc1xuICAvLyBmaWxsZWQ7IGEgdmFsdWUncyBOYW1lIGFzIGl0IGlzLlxuICBwcml2YXRlIF9zaG93blRpdGxlKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuaXNWYWx1ZSgpID8gdGhpcy5jb21wb25lbnQudGl0bGUgPz8gJycgOiBmaWxsVGl0bGVUb2tlbnModGhpcy5jb21wb25lbnQudGl0bGUsIHRoaXMuX2RhdGEudG9rZW5zKTtcbiAgfVxuXG4gIC8vIFdoYXQgYSBmb3JtdWxhIHdvcmtzIG91dCwgbmFtaW5nIGVhY2ggb3BlcmFuZCBhcyBpdHMgY2hpcHMgZG8uIEFuIG9wIHRoaXNcbiAgLy8gdmlld2VyIGRvZXMgbm90IGtub3cgcmVhZHMgbm90aGluZy5cbiAgcHJpdmF0ZSBfZm9ybXVsYUxpbmUoKTogc3RyaW5nIHtcbiAgICBjb25zdCBmb3JtdWxhID0gdGhpcy5jb21wb25lbnQuY29uZmlnPy5mb3JtdWxhO1xuICAgIGNvbnN0IGxpbmUgPSBmb3JtdWxhID8gRk9STVVMQV9MSU5FU1tmb3JtdWxhLm9wXSA6IHVuZGVmaW5lZDtcbiAgICBjb25zdCB2YWx1ZXMgPSB0aGlzLl9sYXllclZhbHVlcygpO1xuXG4gICAgcmV0dXJuIGxpbmUgPyBsaW5lKG9wZXJhbmRLZXlzKHRoaXMuY29tcG9uZW50KS5tYXAoKGtleSkgPT4gdGhpcy5fdmFsdWVOYW1lKHZhbHVlcywga2V5KSkpIDogJyc7XG4gIH1cblxuICAvLyBUaGUgc2VudGVuY2UgYSBxdWVyeSB2YWx1ZSdzIGRlbGV0ZSBjb25maXJtIGVuZHMgd2l0aCB3aGVuIGZvcm11bGFzIG9uIGl0c1xuICAvLyBsYXllciByZWFkIGl0OiB0aGUgc2VydmVyIGRlbGV0ZXMgdGhvc2Ugd2l0aCBpdC4gRW1wdHkgd2hlbiBub25lIGRvZXMsIGFuZFxuICAvLyBmb3IgYSBmb3JtdWxhLCB3aG9zZSBvcGVyYW5kcyBzdGF5LlxuICBwcml2YXRlIF9kZXBlbmRlbnRzTm90ZSgpOiBzdHJpbmcge1xuICAgIGlmICh0aGlzLmlzRm9ybXVsYSgpKSB7XG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuXG4gICAgY29uc3Qga2V5ID0gdmFsdWVLZXkodGhpcy5jb21wb25lbnQpO1xuICAgIGNvbnN0IG5hbWVzID0gdGhpcy5fbGF5ZXJWYWx1ZXMoKVxuICAgICAgLmZpbHRlcigodmFsdWUpID0+IG9wZXJhbmRLZXlzKHZhbHVlKS5pbmNsdWRlcyhrZXkpKVxuICAgICAgLm1hcCgodmFsdWUpID0+IGVzY2FwZUh0bWwodmFsdWUudGl0bGUgfHwgdmFsdWVLZXkodmFsdWUpKSk7XG5cbiAgICByZXR1cm4gbmFtZXMubGVuZ3RoID8gYCBUaGUgdmFsdWVzIHdvcmtlZCBvdXQgZnJvbSBpdCBhcmUgZGVsZXRlZCB0b286ICR7bmFtZXMuam9pbignLCAnKX0uYCA6ICcnO1xuICB9XG5cbiAgLy8gVGhlIHZhbHVlcyBvZiB0aGUgbGF5ZXIgdGhpcyB2YWx1ZSBiZWxvbmdzIHRvOiB0aGUgcGFnZSB3aG9zZSB2YWx1ZXMgaG9sZFxuICAvLyBpdCwgZWxzZSB0aGUgbWFzdGVyJ3MgKGEgaGVhZGVyIG9yIGZvb3RlciB2YWx1ZSkuXG4gIHByaXZhdGUgX2xheWVyVmFsdWVzKCk6IFJlcG9ydENvbXBvbmVudFtdIHtcbiAgICBjb25zdCBwYWdlID0gKHRoaXMucmVwb3J0LnBhZ2VzID8/IFtdKVxuICAgICAgLmZpbmQoKGNhbmRpZGF0ZSkgPT4gKGNhbmRpZGF0ZS52YWx1ZXMgPz8gW10pLnNvbWUoKHZhbHVlKSA9PiB2YWx1ZS5pZCA9PT0gdGhpcy5jb21wb25lbnQuaWQpKTtcblxuICAgIHJldHVybiAocGFnZSA/PyB0aGlzLnJlcG9ydC5tYXN0ZXIpPy52YWx1ZXMgPz8gW107XG4gIH1cblxuICAvLyBXaGF0IGEgdmFsdWUgaXMgY2FsbGVkIHdoZXJlIGl0cyBjaGlwcyBzaG93IGl0OiBpdHMgbmFtZSwgZWxzZSBpdHMga2V5LlxuICAvLyBUaGUgbmV3ZXN0IHZhbHVlIGhvbGRzIGEga2V5LCBhcyBpdCBkb2VzIGluIHRoZSB0ZXh0J3MgdG9rZW5zLlxuICBwcml2YXRlIF92YWx1ZU5hbWUodmFsdWVzOiBSZXBvcnRDb21wb25lbnRbXSwga2V5OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IHZhbHVlID0gdmFsdWVzLmZpbHRlcigoY2FuZGlkYXRlKSA9PiB2YWx1ZUtleShjYW5kaWRhdGUpID09PSBrZXkpLnBvcCgpO1xuXG4gICAgcmV0dXJuIHZhbHVlPy50aXRsZSB8fCBrZXk7XG4gIH1cblxuICAvLyBBIGRlcml2ZWQgS1BJJ3MgY2FyZCBrZXlzLCBmcm9tIGl0cyBjb25maWcuIEEgc3FsLW1vZGUgS1BJIGNhbm5vdCBjYXJyeVxuICAvLyB0aGVtLCBzbyBpdCBnZXRzIG5vIGNhcmQgZmllbGRzLlxuICBwcml2YXRlIF9zZWVkS3BpQ2FyZCgpOiB2b2lkIHtcbiAgICBjb25zdCBjb25maWcgPSAodGhpcy5jb21wb25lbnQuY29uZmlnID8/IHt9KSBhcyBLcGlDb25maWc7XG5cbiAgICB0aGlzLmtwaUNhcmQuc2V0KHRoaXMuY29tcG9uZW50LnR5cGUgPT09ICdrcGknICYmICF0aGlzLmNvbXBvbmVudC5zcWwpO1xuICAgIHRoaXMuaW5jcmVhc2VJcy5zZXQoY29uZmlnLmluY3JlYXNlSXMgPz8gUmVwb3J0Q2hhbmdlUG9sYXJpdHkuR29vZCk7XG4gICAgdGhpcy50YXJnZXRQZXJjZW50LnNldChjb25maWcubWVhc3VyZT8uZm9ybWF0ID09PSBSZXBvcnRWYWx1ZUZvcm1hdC5QZXJjZW50XG4gICAgICAmJiByZXNvbHZlRm9ybWF0Q29udGV4dCh0aGlzLnJlcG9ydCkucmF0aW9QZXJjZW50KTtcbiAgICB0aGlzLnRhcmdldFZhbHVlLnNldCh0aGlzLl90YXJnZXRTaG93bihjb25maWcudGFyZ2V0Py52YWx1ZSA/PyBudWxsKSk7XG4gICAgdGhpcy50YXJnZXRMYWJlbC5zZXQoY29uZmlnLnRhcmdldD8ubGFiZWwgPz8gJycpO1xuICAgIHRoaXMuc3BhcmtsaW5lLnNldCghIWNvbmZpZy5zcGFya2xpbmUpO1xuICAgIHRoaXMuc3BhcmtsaW5lR3JhbnVsYXJpdHkuc2V0KGNvbmZpZy5zcGFya2xpbmU/LmdyYW51bGFyaXR5ID8/IEtQSV9TUEFSS0xJTkVfREVGQVVMVF9HUkFOVUxBUklUWSk7XG4gICAgdGhpcy5zcGFya2xpbmVQZXJpb2RzLnNldChjb25maWcuc3BhcmtsaW5lPy5wZXJpb2RzID8/IEtQSV9TUEFSS0xJTkVfREVGQVVMVF9QRVJJT0RTKTtcbiAgfVxuXG4gIC8vIFRoZSBjYXJkIGtleXMgdGhlIHNlcnZlciBzYXZlZCwgZnJvbSB0aGUgY29uZmlnIGl0cyByZXNwb25zZSBjYXJyaWVzO1xuICAvLyBudWxsIHdoZW4gaXQgY2FycmllcyBub25lIChhIHNlcnZlciB0aGF0IGRvZXMgbm90IHNhdmUgdGhlbSkuXG4gIHByaXZhdGUgX3NhdmVkS3BpQ2FyZChyZXNwb25zZTogQ29tcG9uZW50U2V0dGluZ3NSZXNwb25zZSB8IG51bGwgfCB1bmRlZmluZWQpOiBLcGlDYXJkU2V0dGluZ3MgfCBudWxsIHtcbiAgICBjb25zdCBjb25maWcgPSByZXNwb25zZT8uY29uZmlnO1xuXG4gICAgcmV0dXJuIGNvbmZpZyAmJiB0eXBlb2YgY29uZmlnID09PSAnb2JqZWN0JyA/IGtwaUNhcmRTZXR0aW5ncyhjb25maWcgYXMgS3BpQ29uZmlnKSA6IG51bGw7XG4gIH1cblxuICAvLyBHb29kIGlzIHdoYXQgYW4gYWJzZW50IGluY3JlYXNlSXMgcmVhZHMsIHNvIGl0IGlzIHNhdmVkIGFzIGFic2VudC5cbiAgcHJpdmF0ZSBfa3BpQ2FyZFNldHRpbmdzKCk6IEtwaUNhcmRTZXR0aW5ncyB7XG4gICAgY29uc3QgdGFyZ2V0ID0gdGhpcy5fbnVtYmVyKHRoaXMudGFyZ2V0VmFsdWUoKSk7XG4gICAgY29uc3QgbGFiZWwgPSB0aGlzLnRhcmdldExhYmVsKCkudHJpbSgpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGluY3JlYXNlSXM6IHRoaXMuaW5jcmVhc2VJcygpID09PSBSZXBvcnRDaGFuZ2VQb2xhcml0eS5Hb29kID8gbnVsbCA6IHRoaXMuaW5jcmVhc2VJcygpLFxuICAgICAgdGFyZ2V0OiB0YXJnZXQgPT09IG51bGwgPyBudWxsIDogeyB2YWx1ZTogdGhpcy5fdGFyZ2V0U3RvcmVkKHRhcmdldCksIGxhYmVsOiBsYWJlbCB8fCBudWxsIH0sXG4gICAgICBzcGFya2xpbmU6IHRoaXMuc3BhcmtsaW5lKClcbiAgICAgICAgPyB7IGdyYW51bGFyaXR5OiB0aGlzLnNwYXJrbGluZUdyYW51bGFyaXR5KCksIHBlcmlvZHM6IHRoaXMuX251bWJlcih0aGlzLnNwYXJrbGluZVBlcmlvZHMoKSkgfVxuICAgICAgICA6IG51bGwsXG4gICAgfTtcbiAgfVxuXG4gIC8vIEEgc3RvcmVkIHJhdGlvIGFzIHRoZSBwZXJjZW50IHR5cGVkLCByb3VuZGVkIHNvIDAuMTUgcmVhZHMgMTUgYW5kIG5vdFxuICAvLyAxNS4wMDAwMDAwMDAwMDAwMDIuXG4gIHByaXZhdGUgX3RhcmdldFNob3duKHZhbHVlOiBudW1iZXIgfCBudWxsKTogbnVtYmVyIHwgbnVsbCB7XG4gICAgaWYgKHZhbHVlID09PSBudWxsIHx8ICF0aGlzLnRhcmdldFBlcmNlbnQoKSkge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cblxuICAgIHJldHVybiBNYXRoLnJvdW5kKHZhbHVlICogMTAwICogMWU2KSAvIDFlNjtcbiAgfVxuXG4gIHByaXZhdGUgX3RhcmdldFN0b3JlZCh2YWx1ZTogbnVtYmVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy50YXJnZXRQZXJjZW50KCkgPyB2YWx1ZSAvIDEwMCA6IHZhbHVlO1xuICB9XG5cbiAgLy8gQSB0eXBlZCBudW1iZXIsIG9yIG51bGwgd2hlbiB0aGUgZmllbGQgaXMgZW1wdHkuXG4gIHByaXZhdGUgX251bWJlcih2YWx1ZTogbnVtYmVyIHwgc3RyaW5nIHwgbnVsbCk6IG51bWJlciB8IG51bGwge1xuICAgIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gJycpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IG51bWJlciA9IHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicgPyB2YWx1ZSA6IHBhcnNlRmxvYXQodmFsdWUpO1xuXG4gICAgcmV0dXJuIE51bWJlci5pc0Zpbml0ZShudW1iZXIpID8gbnVtYmVyIDogbnVsbDtcbiAgfVxuXG4gIC8vIFRoZSBwYWRkaW5nIGFzIGEgcmVhbCBudW1iZXIgZm9yIHRoZSB3aXJlLiBmc01hc2tOdW1iZXIgaGFuZHMgYmFjayB0aGVcbiAgLy8gdW5tYXNrZWQgc3RyaW5nIGl0IGJ1aWx0IHdpdGggYSBmaXhlZCAnLicgcmFkaXgsIHNvIHRoaXMgaXMgYSBzdHJhaWdodFxuICAvLyBwYXJzZSAtIHRoZSB3aG9sZSByZWFzb24gZm9yIHRoZSBtYXNrIGlzIHRoYXQgYSBuYXRpdmUgbnVtYmVyIGlucHV0IHdvdWxkXG4gIC8vIHBhaW50IChhbmQgcmVhZCBiYWNrKSB0aGUgdmlld2VyJ3Mgb3duIGxvY2FsZSBzZXBhcmF0b3IgaW5zdGVhZC5cbiAgcHJpdmF0ZSBfcGFkZGluZyh2YWx1ZTogbnVtYmVyIHwgc3RyaW5nKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJyA/IHZhbHVlIDogcGFyc2VGbG9hdCh2YWx1ZSk7XG4gIH1cblxuICAvLyBSdW4gYSBmaWx0ZXIgbXV0YXRpb24sIHRoZW4gcmVsb2FkIHRvIHJlY29uY2lsZSB0aGUgb3B0aW1pc3RpYyBzdGF0ZS5cbiAgcHJpdmF0ZSBfcnVuKHJlcXVlc3Q6IE9ic2VydmFibGU8dW5rbm93bj4pOiB2b2lkIHtcbiAgICByZXF1ZXN0LnN1YnNjcmliZSh7XG4gICAgICBuZXh0OiAoKSA9PiB0aGlzLl9hZnRlck11dGF0aW9uKCksXG4gICAgICBlcnJvcjogKGVycm9yKSA9PiB0aGlzLl9tdXRhdGlvbkVycm9yKGVycm9yKSxcbiAgICB9KTtcbiAgfVxuXG4gIC8vIEJ1aWxkIHRoZSByb3cgdmlldy1tb2RlbCBmcm9tIHRoZSBsb2FkZWQgY29sdW1ucyArIGZpbHRlcnMvZ3JvdXBzLiBFYWNoXG4gIC8vIHJvdydzIGNvbnRyb2xzIHJlZmxlY3Qgd2hlcmUgaXRzIGZpbHRlciBncm91cCBjdXJyZW50bHkgc2hvd3M7IGEgY29sdW1uXG4gIC8vIHdpdGggYSBmaWx0ZXIgc2hvd3MgdGhlIGZpbHRlcidzIG93biB0eXBlLiBBIHZhbHVlJ3Mgcm93cyBuZXZlciByZWFkIGFzXG4gIC8vIG9uIGEgY29tcG9uZW50OiBpdCBoYXMgbm8gc3RyaXAsIHdoYXRldmVyIGxldmVsIGEgZ3JvdXAgaXQgc2hhcmVzIGlzIGF0LFxuICAvLyBhbmQgaXRzIFJlcG9ydCBiYXIgc2VsZWN0IG9mZmVycyBubyBwaWNrIHRoYXQgbG93ZXJzIHRoYXQgZ3JvdXAuXG4gIHByaXZhdGUgX3JlYnVpbGRSb3dzKCk6IHZvaWQge1xuICAgIGNvbnN0IGxldmVsQ2hvaWNlcyA9IGZpbHRlckxldmVsQ2hvaWNlcyh0aGlzLnJlcG9ydC52aWV3ZXJGZWF0dXJlcywgdGhpcy5fb25QYWdlKCkpO1xuXG4gICAgdGhpcy5yb3dzLnNldCh0aGlzLl9maWx0ZXJhYmxlQ29sdW1ucy5tYXAoKGNvbHVtbikgPT4ge1xuICAgICAgY29uc3QgZmlsdGVyID0gdGhpcy5fZmlsdGVycy5maW5kKChjYW5kaWRhdGUpID0+IGNhbmRpZGF0ZS5maWx0ZXJDb2x1bW4gPT09IGNvbHVtbi5jb2x1bW4pO1xuICAgICAgY29uc3QgZ3JvdXAgPSBmaWx0ZXIgPyB0aGlzLl9ncm91cHNCeUlkLmdldChmaWx0ZXIuZmlsdGVyR3JvdXBJZCkgOiB1bmRlZmluZWQ7XG4gICAgICBjb25zdCBwbGFjZW1lbnQgPSBiYXJQbGFjZW1lbnQoZ3JvdXA/LmxldmVsKTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29sdW1uOiBjb2x1bW4uY29sdW1uLFxuICAgICAgICB0eXBlOiBncm91cD8udHlwZVxuICAgICAgICAgID8/IHRoaXMuX3BpY2tlZFR5cGVzLmdldChjb2x1bW4uY29sdW1uKVxuICAgICAgICAgID8/IGNvbHVtbi50eXBlcz8uWzBdXG4gICAgICAgICAgPz8gY29sdW1uLnR5cGUsXG4gICAgICAgIGxhYmVsOiBmaWx0ZXI/LmxhYmVsXG4gICAgICAgICAgfHwgdGhpcy5fZ3JvdXBzQnlJZC5nZXQoZmlsdGVyPy5maWx0ZXJHcm91cElkID8/IC0xKT8ubGFiZWxcbiAgICAgICAgICB8fCB0aGlzLl9odW1hbml6ZShjb2x1bW4uY29sdW1uKSxcbiAgICAgICAgcGxhY2VtZW50LFxuICAgICAgICBjb21wb25lbnQ6ICF0aGlzLmlzVmFsdWUoKSAmJiBzaG93bk9uQ29tcG9uZW50KGdyb3VwPy5sZXZlbCksXG4gICAgICAgIHR5cGVTZWxlY3Q6IHR5cGVTZWxlY3RTdGF0ZShjb2x1bW4udHlwZXMsICEhZmlsdGVyLCB0aGlzLnJlcG9ydC52aWV3ZXJGZWF0dXJlcyksXG4gICAgICAgIHBsYWNlbWVudE9wdGlvbnM6IHRoaXMuaXNWYWx1ZSgpXG4gICAgICAgICAgPyB2YWx1ZVBsYWNlbWVudE9wdGlvbnMobGV2ZWxDaG9pY2VzLCBncm91cD8ubGV2ZWwpXG4gICAgICAgICAgOiBiYXJQbGFjZW1lbnRPcHRpb25zKGxldmVsQ2hvaWNlcywgcGxhY2VtZW50KSxcbiAgICAgICAgY29tcG9uZW50VG9nZ2xlOiBjb21wb25lbnRUb2dnbGVTdGF0ZShwbGFjZW1lbnQpLFxuICAgICAgfTtcbiAgICB9KSk7XG4gIH1cblxuICAvLyBXaGV0aGVyIHRoZSBjb21wb25lbnQgc2l0cyBvbiBhIHBhZ2U6IGFtb25nIGl0cyBjb21wb25lbnRzLCBvciwgZm9yIGFcbiAgLy8gdmFsdWUsIGl0cyB2YWx1ZXMuIEEgaGVhZGVyIG9yIGZvb3RlciBjb21wb25lbnQgb3IgdmFsdWUgc2l0cyBvbiBub25lLFxuICAvLyBzbyBpdHMgZmlsdGVycyBjYW5ub3QgYmUgcGFnZSBmaWx0ZXJzLlxuICBwcml2YXRlIF9vblBhZ2UoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICh0aGlzLnJlcG9ydC5wYWdlcyA/PyBbXSlcbiAgICAgIC5zb21lKChwYWdlKSA9PiBbLi4uKHBhZ2UuY29tcG9uZW50cyA/PyBbXSksIC4uLihwYWdlLnZhbHVlcyA/PyBbXSldXG4gICAgICAgIC5zb21lKChjYW5kaWRhdGUpID0+IGNhbmRpZGF0ZS5pZCA9PT0gdGhpcy5jb21wb25lbnQuaWQpKTtcbiAgfVxuXG4gIC8vIEFmdGVyIGFueSBmaWx0ZXIgbXV0YXRpb246IHJlLWZldGNoIHRoZSByZXBvcnQgc28gdGhlIGRpYWxvZydzIGZpbHRlciBsaXN0XG4gIC8vIChhbmQgdGhlIHBhcmVudCBjYW52YXMsIG9uIGNsb3NlKSByZWZsZWN0IHRoZSBuZXcgZ3JvdXBzL2xldmVscy5cbiAgcHJpdmF0ZSBfYWZ0ZXJNdXRhdGlvbigpOiB2b2lkIHtcbiAgICB0aGlzLmZpbHRlcnNDaGFuZ2VkLmVtaXQoKTtcblxuICAgIHRoaXMuX3JlcG9ydERhdGEuZ2V0KHRoaXMucmVwb3J0LmlkKVxuICAgICAgLnN1YnNjcmliZSgocmVwb3J0OiBSZXBvcnQpID0+IHtcbiAgICAgICAgdGhpcy5yZXBvcnQgPSByZXBvcnQ7XG4gICAgICAgIHRoaXMuX3NlZWRGaWx0ZXJzKHJlcG9ydCwgdGhpcy5jb21wb25lbnQuaWQpO1xuICAgICAgfSk7XG4gIH1cblxuICBwcml2YXRlIF9tdXRhdGlvbkVycm9yKGVycm9yOiBhbnkpOiB2b2lkIHtcbiAgICB0aGlzLl9tZXNzYWdlLmVycm9yKGVycm9yPy5lcnJvcj8ubWVzc2FnZSA/PyBlcnJvcj8ubWVzc2FnZSA/PyAnRmlsdGVyIG9wZXJhdGlvbiBmYWlsZWQnKTtcbiAgICAvLyBSZS1zZWVkIGZyb20gdGhlIHNlcnZlciBzbyB0aGUgb3B0aW1pc3RpYyB0b2dnbGUgc25hcHMgYmFjayB0byB0cnV0aC5cbiAgICB0aGlzLl9hZnRlck11dGF0aW9uKCk7XG4gIH1cblxuICAvLyBUaGUgY29tcG9uZW50J3MgZmlsdGVycyBhbmQgdGhlIGdyb3VwcyB0aGV5IHNpdCBpbiwgZnJvbSB0aGUgcmVwb3J0IGFzXG4gIC8vIGxhc3QgbG9hZGVkLiBBIHZhbHVlIGlzIGxpc3RlZCBpbiBpdHMgcGFnZSdzIHZhbHVlcywgbm90IGl0cyBjb21wb25lbnRzLlxuICBwcml2YXRlIF9zZWVkRmlsdGVycyhyZXBvcnQ6IFJlcG9ydCwgY29tcG9uZW50SWQ6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMuX2dyb3Vwc0J5SWQgPSBuZXcgTWFwKChyZXBvcnQuZmlsdGVyR3JvdXBzID8/IFtdKS5tYXAoKGdyb3VwKSA9PiBbZ3JvdXAuaWQsIGdyb3VwXSkpO1xuXG4gICAgY29uc3QgY29tcG9uZW50ID0gcmVwb3J0Q29tcG9uZW50cyhyZXBvcnQpXG4gICAgICAuZmluZCgoY2FuZGlkYXRlKSA9PiBjYW5kaWRhdGUuaWQgPT09IGNvbXBvbmVudElkKTtcblxuICAgIHRoaXMuX2ZpbHRlcnMgPSBjb21wb25lbnQ/LmZpbHRlcnMgPz8gW107XG4gICAgdGhpcy5fcmVidWlsZFJvd3MoKTtcbiAgfVxuXG4gIC8vIFRoZSBzdGF0ZW1lbnQgdGhlIFNRTCB0YWIgc2hvd3MuIEZldGNoZWQgcmF0aGVyIHRoYW4gcmVhZCBvZmYgdGhlXG4gIC8vIGNvbXBvbmVudDogYSBkZXJpdmVkIGNvbXBvbmVudCBzdG9yZXMgYSBkb2N1bWVudCwgbm90IFNRTCwgc28gaXRzXG4gIC8vIHN0YXRlbWVudCBvbmx5IGV4aXN0cyBvbmNlIHRoZSBiYWNrZW5kIGNvbXBpbGVzIGl0LlxuICAvL1xuICAvLyBMb2FkZWQgaW4gbmdPbkluaXQgYmVzaWRlIHRoZSBjb2x1bW5zLCBOT1Qgb24gdGFiIGFjdGl2YXRpb24uIFRoZSB0YWJzIGFyZVxuICAvLyBub3QgbGF6eSAobm8gbWF0VGFiQ29udGVudCksIGFuZCBzd2l0Y2hpbmcgdGhlIHRhYi1ncm91cCdzIGBbKHNlbGVjdGVkKV1gXG4gIC8vIGJhbmFuYS1ib3ggdG8gYSBvbmUtd2F5IGJpbmRpbmcgcGx1cyAoc2VsZWN0ZWRDaGFuZ2UpIHRvIGdldCBhIGhvb2sgd291bGRcbiAgLy8gYnJlYWsgaXQ6IEZzVGFic0hlYWRlclRhYkdyb3VwRGlyZWN0aXZlIHNlbGYtYXNzaWducyBgdGhpcy5zZWxlY3RlZGAgYmVmb3JlXG4gIC8vIGl0IGVtaXRzLCBzbyB0aGUgZXZlbnQgaXMgZmlsdGVyZWQgb3V0IGFuZCB0aGUgbG9hZCB3b3VsZCBuZXZlciBmaXJlLiBPbmVcbiAgLy8gc21hbGwgcmVxdWVzdCB3aGVuIGEgZGlhbG9nIG9wZW5zIGlzIG5vdCB3b3J0aCB0aGF0IHJpc2suXG4gIHByaXZhdGUgX2xvYWRTcWwoKTogdm9pZCB7XG4gICAgdGhpcy5fcmVwb3J0RGF0YS5jb21wb25lbnRTcWwodGhpcy5yZXBvcnQuaWQsIHRoaXMuY29tcG9uZW50LmlkKVxuICAgICAgLnN1YnNjcmliZSh7XG4gICAgICAgIG5leHQ6IChwcmV2aWV3OiBSZXBvcnRDb21wb25lbnRTcWwpID0+IHtcbiAgICAgICAgICB0aGlzLnNxbC5zZXQocHJldmlldz8uc3FsID8/IG51bGwpO1xuICAgICAgICAgIHRoaXMuc3FsQmFzZWxpbmUuc2V0KCEhcHJldmlldz8uYmFzZWxpbmUpO1xuICAgICAgICAgIHRoaXMuc3FsVGltZXpvbmUuc2V0KHByZXZpZXc/LnRpbWV6b25lIHx8ICdVVEMnKTtcbiAgICAgICAgICB0aGlzLnNxbEVycm9yLnNldChwcmV2aWV3Py5lcnJvciA/PyBudWxsKTtcbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3I6IChlcnJvcikgPT4ge1xuICAgICAgICAgIHRoaXMuc3FsLnNldChudWxsKTtcbiAgICAgICAgICB0aGlzLnNxbEVycm9yLnNldChlcnJvcj8uZXJyb3I/Lm1lc3NhZ2UgPz8gJ0NvdWxkIG5vdCByZWFkIHRoZSBjb21wb25lbnQgU1FMJyk7XG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgX2xvYWRDb2x1bW5zKCk6IHZvaWQge1xuICAgIHRoaXMuX3JlcG9ydERhdGEuY29tcG9uZW50Q29sdW1ucyh0aGlzLnJlcG9ydC5pZCwgdGhpcy5jb21wb25lbnQuaWQpXG4gICAgICAuc3Vic2NyaWJlKHtcbiAgICAgICAgbmV4dDogKGNvbHVtbnM6IFJlcG9ydEZpbHRlcmFibGVDb2x1bW5bXSkgPT4ge1xuICAgICAgICAgIHRoaXMuX2ZpbHRlcmFibGVDb2x1bW5zID0gY29sdW1ucyA/PyBbXTtcbiAgICAgICAgICB0aGlzLl9yZWJ1aWxkUm93cygpO1xuICAgICAgICB9LFxuICAgICAgICBlcnJvcjogKGVycm9yKSA9PiB7XG4gICAgICAgICAgdGhpcy5jb2x1bW5zRXJyb3Iuc2V0KGVycm9yPy5lcnJvcj8ubWVzc2FnZSA/PyAnQ291bGQgbm90IHJlYWQgdGhlIGNvbXBvbmVudCBjb2x1bW5zJyk7XG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgX2h1bWFuaXplKGNvbHVtbjogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gY29sdW1uXG4gICAgICAucmVwbGFjZSgvW19cXC1dKy9nLCAnICcpXG4gICAgICAucmVwbGFjZSgvXFxzKy9nLCAnICcpXG4gICAgICAudHJpbSgpXG4gICAgICAucmVwbGFjZSgvXFxiXFx3L2csIChjaGFyYWN0ZXIpID0+IGNoYXJhY3Rlci50b1VwcGVyQ2FzZSgpKTtcbiAgfVxufVxuIiwiPGZvcm1cbiAgICBmc0Zvcm1cbiAgICBbc3VibWl0XT1cInNhdmVcIj5cbiAgPGZzLWRpYWxvZz5cbiAgICA8aDEgbWF0LWRpYWxvZy10aXRsZT5cbiAgICAgIHt7IGhlYWRpbmcoKSB9fVxuICAgIDwvaDE+XG4gICAgPG1hdC1kaWFsb2ctY29udGVudD5cbiAgICAgIDxtYXQtdGFiLWdyb3VwIFsoc2VsZWN0ZWQpXT1cInNlbGVjdGVkVGFiXCI+XG4gICAgICAgIDxtYXQtdGFiXG4gICAgICAgICAgICBsYWJlbD1cIlNldHRpbmdzXCJcbiAgICAgICAgICAgIG5hbWU9XCJzZXR0aW5nc1wiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJmcy1jb2x1bW4gdGFiLWJvZHlcIj5cbiAgICAgICAgICAgIDwhLS0gQSB2YWx1ZSdzIE5hbWUgaXMganVzdCBpdHMgbmFtZS4gQSB0aXRsZSBtYXkgY2FycnkgdGhlIHBhZ2UsXG4gICAgICAgICAgICAgICAgIHJlcG9ydCBhbmQgZmlsdGVyIGZpZWxkcyBhIHRleHQgYmxvY2sncyB3b3JkcyBkbzogSW5zZXJ0XG4gICAgICAgICAgICAgICAgIGZpZWxkIHB1dHMgb25lIGluIGF0IHRoZSBjYXJldCwgYW5kIHRoZSBoaW50IHNheXMgaG93IHRoZVxuICAgICAgICAgICAgICAgICB0aXRsZSByZWFkcyB3aGVyZSB0aGUgY29tcG9uZW50IGlzIGRyYXduLiAtLT5cbiAgICAgICAgICAgIEBpZiAoaXNWYWx1ZSgpKSB7XG4gICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgTmFtZVxuICAgICAgICAgICAgICAgIDwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cInRpdGxlKClcIlxuICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwidGl0bGUuc2V0KCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgbmFtZT1cInRpdGxlXCJcbiAgICAgICAgICAgICAgICAgIFtmc0Zvcm1SZXF1aXJlZF09XCJ0cnVlXCI+XG4gICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICBUaXRsZVxuICAgICAgICAgICAgICAgIDwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgI3RpdGxlSW5wdXRcbiAgICAgICAgICAgICAgICAgIG1hdElucHV0XG4gICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJ0aXRsZSgpXCJcbiAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cInRpdGxlLnNldCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgIG5hbWU9XCJ0aXRsZVwiPlxuICAgICAgICAgICAgICAgIDwhLS0gVGhlIGJ1dHRvbiBzd2FsbG93cyBpdHMgb3duIGNsaWNrOiB0aGUgZm9ybSBmaWVsZCB3b3VsZFxuICAgICAgICAgICAgICAgICAgICAgb3RoZXJ3aXNlIHB1dCBmb2N1cyBiYWNrIGluIHRoZSBpbnB1dCB3aGlsZSB0aGUgbWVudSBpc1xuICAgICAgICAgICAgICAgICAgICAgb3BlbiwgYW5kIGEga2V5IHByZXNzZWQgdGhlbiB3b3VsZCBtb3ZlIHRoZSBjYXJldCB0aGVcbiAgICAgICAgICAgICAgICAgICAgIGZpZWxkIGdvZXMgaW4gYXQuIC0tPlxuICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgICAgbWF0LWljb24tYnV0dG9uXG4gICAgICAgICAgICAgICAgICAgIG1hdEljb25TdWZmaXhcbiAgICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICAgIGFyaWEtbGFiZWw9XCJJbnNlcnQgZmllbGRcIlxuICAgICAgICAgICAgICAgICAgICBbZnNNZW51VHJpZ2dlckZvcl09XCJpbnNlcnRGaWVsZE1lbnVcIlxuICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCI+XG4gICAgICAgICAgICAgICAgICA8bWF0LWljb24+c2VsbDwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgQGlmICh0aXRsZVNob3duQXMoKSkge1xuICAgICAgICAgICAgICAgICAgPG1hdC1oaW50PlxuICAgICAgICAgICAgICAgICAgICBTaG93cyBhczoge3sgdGl0bGVTaG93bkFzKCkgfX1cbiAgICAgICAgICAgICAgICAgIDwvbWF0LWhpbnQ+XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICA8ZnMtbWVudSAjaW5zZXJ0RmllbGRNZW51PlxuICAgICAgICAgICAgICAgIEBmb3IgKGVudHJ5IG9mIHRpdGxlRmllbGRzKCk7IHRyYWNrIGVudHJ5LmZpZWxkKSB7XG4gICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGVcbiAgICAgICAgICAgICAgICAgICAgICBmcy1tZW51LWl0ZW1cbiAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiaW5zZXJ0RmllbGQoZW50cnkuZmllbGQpXCI+XG4gICAgICAgICAgICAgICAgICAgIHt7IGVudHJ5Lm5hbWUgfX1cbiAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICA8L2ZzLW1lbnU+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICA8IS0tIEEgZm9ybXVsYSB2YWx1ZSBpcyByZWFkLW9ubHkgYmV5b25kIGl0cyBuYW1lOiB3aGF0IGl0IHdvcmtzXG4gICAgICAgICAgICAgICAgIG91dCBpcyB0aGUgQUkncyB0byBjaGFuZ2UuIEEgZm9ybXVsYSB0aGlzIHZpZXdlciBjYW5ub3RcbiAgICAgICAgICAgICAgICAgcmVhZCBoYXMgbm8gbGluZSwgYW5kIG5vIHJvdy4gLS0+XG4gICAgICAgICAgICBAaWYgKGZvcm11bGFMaW5lKCkpIHtcbiAgICAgICAgICAgICAgPGZzLWxhYmVsLWZpZWxkPlxuICAgICAgICAgICAgICAgIDxmcy1sYWJlbD5cbiAgICAgICAgICAgICAgICAgIEZvcm11bGFcbiAgICAgICAgICAgICAgICA8L2ZzLWxhYmVsPlxuICAgICAgICAgICAgICAgIHt7IGZvcm11bGFMaW5lKCkgfX1cbiAgICAgICAgICAgICAgICA8ZnMtbGFiZWwtbWVzc2FnZT5cbiAgICAgICAgICAgICAgICAgIFdvcmtlZCBvdXQgb24gdGhlIHNlcnZlcjsgaXQgZm9sbG93cyB0aGUgZmlsdGVycyBvZiB0aGUgdmFsdWVzIGl0IHJlYWRzLlxuICAgICAgICAgICAgICAgIDwvZnMtbGFiZWwtbWVzc2FnZT5cbiAgICAgICAgICAgICAgPC9mcy1sYWJlbC1maWVsZD5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwhLS0gQSB2YWx1ZSBzaXRzIGluc2lkZSBhIHRleHQgYmxvY2sncyB3b3Jkczogbm8gYm94LCBubyBwYWRkaW5nLiAtLT5cbiAgICAgICAgICAgIEBpZiAoIWlzVmFsdWUoKSkge1xuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3ViaGVhZGluZy0yXCI+XG4gICAgICAgICAgICAgICAgUGFkZGluZ1xuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImdlb21ldHJ5LXJvd1wiPlxuICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIFRvcFxuICAgICAgICAgICAgICAgICAgPC9tYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgICAgICAgICAgZnNNYXNrTnVtYmVyXG4gICAgICAgICAgICAgICAgICAgIFtzY2FsZV09XCIzXCJcbiAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJwYWRkaW5nVG9wXCJcbiAgICAgICAgICAgICAgICAgICAgbmFtZT1cInBhZGRpbmdUb3BcIlxuICAgICAgICAgICAgICAgICAgICBbZnNGb3JtTWluXT1cIjBcIj5cbiAgICAgICAgICAgICAgICAgIDxkaXYgbWF0VGV4dFN1ZmZpeD5cbiAgICAgICAgICAgICAgICAgICAgaW5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgUmlnaHRcbiAgICAgICAgICAgICAgICAgIDwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgIG1hdElucHV0XG4gICAgICAgICAgICAgICAgICAgIGZzTWFza051bWJlclxuICAgICAgICAgICAgICAgICAgICBbc2NhbGVdPVwiM1wiXG4gICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwicGFkZGluZ1JpZ2h0XCJcbiAgICAgICAgICAgICAgICAgICAgbmFtZT1cInBhZGRpbmdSaWdodFwiXG4gICAgICAgICAgICAgICAgICAgIFtmc0Zvcm1NaW5dPVwiMFwiPlxuICAgICAgICAgICAgICAgICAgPGRpdiBtYXRUZXh0U3VmZml4PlxuICAgICAgICAgICAgICAgICAgICBpblxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgICBCb3R0b21cbiAgICAgICAgICAgICAgICAgIDwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgIG1hdElucHV0XG4gICAgICAgICAgICAgICAgICAgIGZzTWFza051bWJlclxuICAgICAgICAgICAgICAgICAgICBbc2NhbGVdPVwiM1wiXG4gICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwicGFkZGluZ0JvdHRvbVwiXG4gICAgICAgICAgICAgICAgICAgIG5hbWU9XCJwYWRkaW5nQm90dG9tXCJcbiAgICAgICAgICAgICAgICAgICAgW2ZzRm9ybU1pbl09XCIwXCI+XG4gICAgICAgICAgICAgICAgICA8ZGl2IG1hdFRleHRTdWZmaXg+XG4gICAgICAgICAgICAgICAgICAgIGluXG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIExlZnRcbiAgICAgICAgICAgICAgICAgIDwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgIG1hdElucHV0XG4gICAgICAgICAgICAgICAgICAgIGZzTWFza051bWJlclxuICAgICAgICAgICAgICAgICAgICBbc2NhbGVdPVwiM1wiXG4gICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwicGFkZGluZ0xlZnRcIlxuICAgICAgICAgICAgICAgICAgICBuYW1lPVwicGFkZGluZ0xlZnRcIlxuICAgICAgICAgICAgICAgICAgICBbZnNGb3JtTWluXT1cIjBcIj5cbiAgICAgICAgICAgICAgICAgIDxkaXYgbWF0VGV4dFN1ZmZpeD5cbiAgICAgICAgICAgICAgICAgICAgaW5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgPCEtLSBBIGRlcml2ZWQgS1BJJ3MgY2FyZDogd2hhdCBhIHJpc2UgbWVhbnMsIGEgdGFyZ2V0IGFuZCBhXG4gICAgICAgICAgICAgICAgIHNwYXJrbGluZS4gVGhlIHNlcnZlciBjb21wdXRlcyB0aGUgcHJvZ3Jlc3MgYW5kIHRoZSBwb2ludHMuIC0tPlxuICAgICAgICAgICAgQGlmIChrcGlDYXJkKCkpIHtcbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN1YmhlYWRpbmctMlwiPlxuICAgICAgICAgICAgICAgIENhcmRcbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBjbGFzcz1cImZ1bGwtd2lkdGhcIj5cbiAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgSW5jcmVhc2UgaXNcbiAgICAgICAgICAgICAgICA8L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICA8bWF0LXNlbGVjdFxuICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJpbmNyZWFzZUlzKClcIlxuICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJpbmNyZWFzZUlzLnNldCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgbmFtZT1cImluY3JlYXNlSXNcIj5cbiAgICAgICAgICAgICAgICAgIEBmb3IgKG9wdGlvbiBvZiBrcGlQb2xhcml0eU9wdGlvbnM7IHRyYWNrIG9wdGlvbi52YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiBbdmFsdWVdPVwib3B0aW9uLnZhbHVlXCI+XG4gICAgICAgICAgICAgICAgICAgICAge3sgb3B0aW9uLm5hbWUgfX1cbiAgICAgICAgICAgICAgICAgICAgPC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIDwvbWF0LXNlbGVjdD5cbiAgICAgICAgICAgICAgICA8bWF0LWhpbnQ+XG4gICAgICAgICAgICAgICAgICBDb2xvcnMgdGhlIGNoYW5nZSBhbmQgZGVjaWRlcyB3aGVuIHRoZSB0YXJnZXQgaXMgbWV0LlxuICAgICAgICAgICAgICAgIDwvbWF0LWhpbnQ+XG4gICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBjbGFzcz1cImZ1bGwtd2lkdGhcIj5cbiAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgVGFyZ2V0XG4gICAgICAgICAgICAgICAgPC9tYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICBtYXRJbnB1dFxuICAgICAgICAgICAgICAgICAgZnNNYXNrTnVtYmVyXG4gICAgICAgICAgICAgICAgICBbc2NhbGVdPVwiNlwiXG4gICAgICAgICAgICAgICAgICBbc2lnbmVkXT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgW25nTW9kZWxdPVwidGFyZ2V0VmFsdWUoKVwiXG4gICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJ0YXJnZXRWYWx1ZS5zZXQoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICBuYW1lPVwidGFyZ2V0VmFsdWVcIlxuICAgICAgICAgICAgICAgICAgW3ZhbGlkYXRlXT1cInZhbGlkYXRlVGFyZ2V0XCI+XG4gICAgICAgICAgICAgICAgQGlmICh0YXJnZXRQZXJjZW50KCkpIHtcbiAgICAgICAgICAgICAgICAgIDxkaXYgbWF0VGV4dFN1ZmZpeD5cbiAgICAgICAgICAgICAgICAgICAgJVxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIDxtYXQtaGludD5cbiAgICAgICAgICAgICAgICAgIFRoZSB2YWx1ZSB0byByZWFjaC4gTGVhdmUgZW1wdHkgZm9yIG5vIHRhcmdldC5cbiAgICAgICAgICAgICAgICA8L21hdC1oaW50PlxuICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICBAaWYgKGhhc1RhcmdldCgpKSB7XG4gICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwiZnVsbC13aWR0aFwiPlxuICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgVGFyZ2V0IGxhYmVsXG4gICAgICAgICAgICAgICAgICA8L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgICBtYXRJbnB1dFxuICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJ0YXJnZXRMYWJlbCgpXCJcbiAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwidGFyZ2V0TGFiZWwuc2V0KCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICBuYW1lPVwidGFyZ2V0TGFiZWxcIj5cbiAgICAgICAgICAgICAgICAgIDxtYXQtaGludD5cbiAgICAgICAgICAgICAgICAgICAgU2hvd24gYmVmb3JlIHRoZSB0YXJnZXQsIHN1Y2ggYXMgR29hbC4gRW1wdHkgcmVhZHMgVGFyZ2V0LlxuICAgICAgICAgICAgICAgICAgPC9tYXQtaGludD5cbiAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIDxmcy1sYWJlbC1maWVsZD5cbiAgICAgICAgICAgICAgICA8bWF0LXNsaWRlLXRvZ2dsZVxuICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJzcGFya2xpbmUoKVwiXG4gICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cInNwYXJrbGluZS5zZXQoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgIG5hbWU9XCJzcGFya2xpbmVcIj5cbiAgICAgICAgICAgICAgICAgIFNwYXJrbGluZVxuICAgICAgICAgICAgICAgIDwvbWF0LXNsaWRlLXRvZ2dsZT5cbiAgICAgICAgICAgICAgICA8bWF0LWhpbnQ+XG4gICAgICAgICAgICAgICAgICBBIHNtYWxsIHRyZW5kIGxpbmUgb2YgdGhlIHZhbHVlIG92ZXIgaXRzIGxhc3QgcGVyaW9kcy5cbiAgICAgICAgICAgICAgICA8L21hdC1oaW50PlxuICAgICAgICAgICAgICA8L2ZzLWxhYmVsLWZpZWxkPlxuICAgICAgICAgICAgICBAaWYgKHNwYXJrbGluZSgpKSB7XG4gICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwiZnVsbC13aWR0aFwiPlxuICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgU3BhcmtsaW5lIHBlcmlvZFxuICAgICAgICAgICAgICAgICAgPC9tYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICA8bWF0LXNlbGVjdFxuICAgICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cInNwYXJrbGluZUdyYW51bGFyaXR5KClcIlxuICAgICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cInNwYXJrbGluZUdyYW51bGFyaXR5LnNldCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICBuYW1lPVwic3BhcmtsaW5lR3JhbnVsYXJpdHlcIj5cbiAgICAgICAgICAgICAgICAgICAgQGZvciAob3B0aW9uIG9mIGdyYW51bGFyaXR5T3B0aW9uczsgdHJhY2sgb3B0aW9uLnZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gW3ZhbHVlXT1cIm9wdGlvbi52YWx1ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAge3sgb3B0aW9uLm5hbWUgfX1cbiAgICAgICAgICAgICAgICAgICAgICA8L21hdC1vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIDwvbWF0LXNlbGVjdD5cbiAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBjbGFzcz1cImZ1bGwtd2lkdGhcIj5cbiAgICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIFNwYXJrbGluZSBwZXJpb2RzXG4gICAgICAgICAgICAgICAgICA8L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgICBtYXRJbnB1dFxuICAgICAgICAgICAgICAgICAgICBmc01hc2tOdW1iZXJcbiAgICAgICAgICAgICAgICAgICAgW3NjYWxlXT1cIjBcIlxuICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJzcGFya2xpbmVQZXJpb2RzKClcIlxuICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJzcGFya2xpbmVQZXJpb2RzLnNldCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgbmFtZT1cInNwYXJrbGluZVBlcmlvZHNcIlxuICAgICAgICAgICAgICAgICAgICBbZnNGb3JtUmVxdWlyZWRdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgIFtmc0Zvcm1JbnRlZ2VyXT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgICBbZnNGb3JtTWluXT1cInNwYXJrbGluZU1pblBlcmlvZHNcIlxuICAgICAgICAgICAgICAgICAgICBbZnNGb3JtTWF4XT1cInNwYXJrbGluZU1heFBlcmlvZHNcIj5cbiAgICAgICAgICAgICAgICAgIDxtYXQtaGludD5cbiAgICAgICAgICAgICAgICAgICAgSG93IG1hbnkgcGVyaW9kcyB0aGUgbGluZSBjb3ZlcnMsIHt7IHNwYXJrbGluZU1pblBlcmlvZHMgfX0gdG8ge3sgc3BhcmtsaW5lTWF4UGVyaW9kcyB9fS5cbiAgICAgICAgICAgICAgICAgIDwvbWF0LWhpbnQ+XG4gICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L21hdC10YWI+XG4gICAgICAgIDwhLS0gQSBmb3JtdWxhIHJ1bnMgbm8gc3RhdGVtZW50IGFuZCBmb2xsb3dzIHRoZSBmaWx0ZXJzIG9mIHRoZSB2YWx1ZXNcbiAgICAgICAgICAgICBpdCByZWFkcywgc28gaXQgaGFzIG5laXRoZXIgYSBGaWx0ZXJzIG5vciBhbiBTUUwgdGFiLiAtLT5cbiAgICAgICAgQGlmICghaXNGb3JtdWxhKCkpIHtcbiAgICAgICAgICA8bWF0LXRhYlxuICAgICAgICAgICAgICBsYWJlbD1cIkZpbHRlcnNcIlxuICAgICAgICAgICAgICBuYW1lPVwiZmlsdGVyc1wiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRhYi1ib2R5XCI+XG4gICAgICAgICAgICAgIEBpZiAoY29sdW1uc0Vycm9yKCkpIHtcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmlsdGVycy1lbXB0eSBlcnJvclwiPlxuICAgICAgICAgICAgICAgICAge3sgY29sdW1uc0Vycm9yKCkgfX1cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgfSBAZWxzZSBpZiAocm93cygpLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIDwhLS0gRXZlcnkgZmlsdGVyYWJsZSBjb2x1bW4uIFBpY2sgd2hlcmUgaXRzIGNvbnRyb2wgc2hvd3M6IGluXG4gICAgICAgICAgICAgICAgICAgICB0aGUgcmVwb3J0IGJhciAoZXZlcnkgcGFnZSwgb3IgdGhpcyBwYWdlIG9ubHkpLCBvbiB0aGlzXG4gICAgICAgICAgICAgICAgICAgICBjb21wb25lbnQsIGJvdGgsIG9yIG5laXRoZXIuIFRoZSBpbnRlcmZhY2UgZm9sbG93cyB0aGVcbiAgICAgICAgICAgICAgICAgICAgIGRhdGE7IGEgbnVtZXJpYyBjb2x1bW4gY2FuIGJlIHZhbHVlcyBvciBhIG51bWJlciByYW5nZS5cbiAgICAgICAgICAgICAgICAgICAgIEEgdmFsdWUgc2l0cyBpbnNpZGUgdGV4dCBhbmQgaGFzIG5vIGNvbXBvbmVudCB0byBzaG93IGFcbiAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2wgb24sIHNvIGl0IGdldHMgdGhlIHJlcG9ydCBiYXIgY29sdW1uIG9ubHkuIC0tPlxuICAgICAgICAgICAgICAgIDx0YWJsZSBjbGFzcz1cImZpbHRlci10YWJsZVwiPlxuICAgICAgICAgICAgICAgICAgPHRoZWFkPlxuICAgICAgICAgICAgICAgICAgICA8dHI+XG4gICAgICAgICAgICAgICAgICAgICAgPHRoIGNsYXNzPVwiZmlsdGVyLWNvbC1uYW1lXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICBGaWx0ZXJcbiAgICAgICAgICAgICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgICAgICAgICAgIDx0aCBjbGFzcz1cImZpbHRlci1jb2wtdHlwZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgVHlwZVxuICAgICAgICAgICAgICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgPHRoIGNsYXNzPVwiZmlsdGVyLWNvbC1zZWxlY3RcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIFJlcG9ydCBiYXJcbiAgICAgICAgICAgICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgICAgICAgICAgIEBpZiAoIWlzVmFsdWUoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgPHRoIGNsYXNzPVwiZmlsdGVyLWNvbC10b2dnbGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcyBjb21wb25lbnRcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgICAgICAgPC90aGVhZD5cbiAgICAgICAgICAgICAgICAgIDx0Ym9keT5cbiAgICAgICAgICAgICAgICAgICAgQGZvciAocm93IG9mIHJvd3MoKTsgdHJhY2sgcm93LmNvbHVtbikge1xuICAgICAgICAgICAgICAgICAgICAgIDx0cj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz1cImZpbHRlci1jb2wtbmFtZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICB7eyByb3cubGFiZWwgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJmaWx0ZXItY29sLXR5cGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgQGlmIChyb3cudHlwZVNlbGVjdC5zaG93KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdWJzY3JpcHRTaXppbmddPVwiJ2R5bmFtaWMnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW21hdFRvb2x0aXBdPVwicm93LnR5cGVTZWxlY3QudG9vbHRpcFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1zZWxlY3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcGFuZWxXaWR0aF09XCJudWxsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJyb3cudHlwZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwic2V0VHlwZShyb3csICRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsT3B0aW9uc109XCJ7IHN0YW5kYWxvbmU6IHRydWUgfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cInJvdy50eXBlU2VsZWN0LmRpc2FibGVkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmlhLWxhYmVsPVwiVHlwZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAZm9yIChvcHRpb24gb2YgdHlwZU9wdGlvbnM7IHRyYWNrIG9wdGlvbi52YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uIFt2YWx1ZV09XCJvcHRpb24udmFsdWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IG9wdGlvbi5uYW1lIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgdHlwZUxhYmVsKHJvdy50eXBlKSB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwiZmlsdGVyLWNvbC1zZWxlY3RcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIFtzdWJzY3JpcHRTaXppbmddPVwiJ2R5bmFtaWMnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1zZWxlY3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BhbmVsV2lkdGhdPVwibnVsbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cInJvdy5wbGFjZW1lbnRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJzZXRQbGFjZW1lbnQocm93LCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nTW9kZWxPcHRpb25zXT1cInsgc3RhbmRhbG9uZTogdHJ1ZSB9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJpYS1sYWJlbD1cIlJlcG9ydCBiYXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBmb3IgKG9wdGlvbiBvZiByb3cucGxhY2VtZW50T3B0aW9uczsgdHJhY2sgb3B0aW9uLnZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uIFt2YWx1ZV09XCJvcHRpb24udmFsdWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBvcHRpb24ubmFtZSB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAoIWlzVmFsdWUoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJmaWx0ZXItY29sLXRvZ2dsZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtc2xpZGUtdG9nZ2xlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJyb3cuY29tcG9uZW50XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cInNldENvbXBvbmVudChyb3csICRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nTW9kZWxPcHRpb25zXT1cInsgc3RhbmRhbG9uZTogdHJ1ZSB9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJyb3cuY29tcG9uZW50VG9nZ2xlLmRpc2FibGVkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFttYXRUb29sdGlwXT1cInJvdy5jb21wb25lbnRUb2dnbGUudG9vbHRpcFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LXNsaWRlLXRvZ2dsZT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICA8L3Rib2R5PlxuICAgICAgICAgICAgICAgIDwvdGFibGU+XG4gICAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmaWx0ZXJzLWVtcHR5XCI+XG4gICAgICAgICAgICAgICAgICBUaGlzIGNvbXBvbmVudCBoYXMgbm8gZmlsdGVyYWJsZSBjb2x1bW5zIHlldCDigJQgZ2l2ZSBpdCBzb21lIFNRTCBmaXJzdC5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9tYXQtdGFiPlxuICAgICAgICAgIDxtYXQtdGFiXG4gICAgICAgICAgICAgIGxhYmVsPVwiU1FMXCJcbiAgICAgICAgICAgICAgbmFtZT1cInNxbFwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRhYi1ib2R5XCI+XG4gICAgICAgICAgICAgIEBpZiAoc3FsRXJyb3IoKSkge1xuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmaWx0ZXJzLWVtcHR5IGVycm9yXCI+XG4gICAgICAgICAgICAgICAgICB7eyBzcWxFcnJvcigpIH19XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIH0gQGVsc2UgaWYgKHNxbCgpKSB7XG4gICAgICAgICAgICAgICAgQGlmIChzcWxCYXNlbGluZSgpKSB7XG4gICAgICAgICAgICAgICAgICA8IS0tIEEgZGVyaXZlZCBjb21wb25lbnQncyBzdGF0ZW1lbnQgaXMgY29tcGlsZWQgZnJvbSBpdHNcbiAgICAgICAgICAgICAgICAgICAgICAgZG9jdW1lbnQgd2l0aCBubyB2aWV3ZXIgc3RhdGUsIHNvIGl0IGlzIG5vdCBieXRlLWZvci1ieXRlXG4gICAgICAgICAgICAgICAgICAgICAgIHdoYXQgcHJvZHVjZWQgdGhlIG51bWJlcnMgb24gc2NyZWVuLiBTYWlkIGhlcmUgcmF0aGVyIHRoYW5cbiAgICAgICAgICAgICAgICAgICAgICAgbGVmdCBmb3IgdGhlIHJlYWRlciB0byBkaXNjb3Zlci4gLS0+XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmlsdGVycy1lbXB0eVwiPlxuICAgICAgICAgICAgICAgICAgICBDb21waWxlZCBmcm9tIHRoaXMgY29tcG9uZW50J3MgcXVlcnkg4oCUIG5vIGZpbHRlcnMgYXBwbGllZCwgdGltZXMgaW4ge3sgc3FsVGltZXpvbmUoKSB9fS5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICA8cHJlIGNsYXNzPVwiY29kZS1ibG9ja1wiPnt7IHNxbCgpIH19PC9wcmU+XG4gICAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmaWx0ZXJzLWVtcHR5XCI+XG4gICAgICAgICAgICAgICAgICBUaGlzIGNvbXBvbmVudCBoYXMgbm8gU1FMIHlldC5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9tYXQtdGFiPlxuICAgICAgICB9XG4gICAgICAgIDxtYXQtdGFiXG4gICAgICAgICAgICBsYWJlbD1cIkNvbmZpZ1wiXG4gICAgICAgICAgICBuYW1lPVwiY29uZmlnXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInRhYi1ib2R5XCI+XG4gICAgICAgICAgICA8cHJlIGNsYXNzPVwiY29kZS1ibG9ja1wiPlxuICAgICAgICAgICAgICB7eyBjb25maWdKc29uIH19XG4gICAgICAgICAgICA8L3ByZT5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9tYXQtdGFiPlxuICAgICAgPC9tYXQtdGFiLWdyb3VwPlxuICAgIDwvbWF0LWRpYWxvZy1jb250ZW50PlxuICAgIDxtYXQtZGlhbG9nLWFjdGlvbnM+XG4gICAgICA8IS0tIFNhdmUgfCBEZWxldGUgfCBDYW5jZWwsIHRoZSBzdGFuZGFyZCBvcmRlci4gZnMtZm9ybS1kaWFsb2ctYWN0aW9uc1xuICAgICAgICAgICByZW5kZXJzIGl0cyBvd24gU2F2ZS9Eb25lIEJFRk9SRSB0aGUgcHJvamVjdGVkIGNvbnRlbnQsIHdoaWNoIHdvdWxkXG4gICAgICAgICAgIHB1dCBEZWxldGUgYWZ0ZXIgQ2FuY2VsLCBzbyBgW3NhdmVdPVwiZmFsc2VcImAgZm9vdHMgdGhlIHJvdyBoZXJlIGFuZFxuICAgICAgICAgICBhbGwgdGhyZWUgYnV0dG9ucyBhcmUgcHJvamVjdGVkIGluIG9yZGVyLiBTYXZlIHN1Ym1pdHMgdGhlIFNldHRpbmdzXG4gICAgICAgICAgIHRhYjsgdGhlIG90aGVyIHRhYnMgcGVyc2lzdCBhcyB5b3UgdG91Y2ggdGhlbSwgc28gdGhleSBnZXQgRG9uZS4gLS0+XG4gICAgICA8ZnMtZm9ybS1kaWFsb2ctYWN0aW9ucyBbc2F2ZV09XCJmYWxzZVwiPlxuICAgICAgICBAaWYgKHNlbGVjdGVkVGFiID09PSAnc2V0dGluZ3MnKSB7XG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICBtYXQtYnV0dG9uXG4gICAgICAgICAgICAgIHR5cGU9XCJzdWJtaXRcIlxuICAgICAgICAgICAgICBjb2xvcj1cInByaW1hcnlcIj5cbiAgICAgICAgICAgIFNhdmVcbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICBtYXQtYnV0dG9uXG4gICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICBjb2xvcj1cInByaW1hcnlcIlxuICAgICAgICAgICAgICBbbWF0LWRpYWxvZy1jbG9zZV09XCJudWxsXCI+XG4gICAgICAgICAgICBEb25lXG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgIH1cbiAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgbWF0LWJ1dHRvblxuICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICBjb2xvcj1cIndhcm5cIlxuICAgICAgICAgICAgKGNsaWNrKT1cImRlbGV0ZSgpXCI+XG4gICAgICAgICAgRGVsZXRlXG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICBtYXQtYnV0dG9uXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIGNsYXNzPVwiY2FuY2VsLWJ1dHRvblwiXG4gICAgICAgICAgICBbbWF0LWRpYWxvZy1jbG9zZV09XCJudWxsXCI+XG4gICAgICAgICAgQ2FuY2VsXG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgPC9mcy1mb3JtLWRpYWxvZy1hY3Rpb25zPlxuICAgIDwvbWF0LWRpYWxvZy1hY3Rpb25zPlxuICA8L2ZzLWRpYWxvZz5cbjwvZm9ybT4iXX0=
|
|
726
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcG9uZW50LXNldHRpbmdzLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvcmVwb3J0cy9kaWFsb2dzL2NvbXBvbmVudC1zZXR0aW5ncy9jb21wb25lbnQtc2V0dGluZ3MuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9yZXBvcnRzL2RpYWxvZ3MvY29tcG9uZW50LXNldHRpbmdzL2NvbXBvbmVudC1zZXR0aW5ncy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBYyxZQUFZLEVBQVUsUUFBUSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsU0FBUyxHQUN0SCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNoRSxPQUFPLEVBQW1CLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRTlELE9BQU8sRUFBRSxlQUFlLEVBQUUsZ0JBQWdCLEVBQUUsY0FBYyxFQUFFLGdCQUFnQixFQUFFLFlBQVksRUFBRSxjQUFjLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUM3SSxPQUFPLEVBQUUsWUFBWSxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDMUYsT0FBTyxFQUFFLFNBQVMsRUFBRSxhQUFhLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNwRSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDakQsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ25ELE9BQU8sRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDaEUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGdDQUFnQyxD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d0JBQ2hCLGdCQUFnQjt3QkFDaEIsY0FBYzt3QkFDZCxZQUFZO3dCQUNaLE9BQU87d0JBQ1AsUUFBUTt3QkFDUixTQUFTO3dCQUNULFNBQVM7d0JBQ1QsT0FBTzt3QkFDUCxhQUFhO3dCQUNiLFFBQVE7d0JBQ1IsU0FBUzt3QkFDVCxTQUFTO3dCQUNULGNBQWM7d0JBQ2QsVUFBVTt3QkFDVixZQUFZO3FCQUNiIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCwgRGVzdHJveVJlZiwgRWxlbWVudFJlZiwgRXZlbnRFbWl0dGVyLCBPbkluaXQsIGNvbXB1dGVkLCBpbmplY3QsIHNpZ25hbCwgdmlld0NoaWxkLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IHRha2VVbnRpbERlc3Ryb3llZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUvcnhqcy1pbnRlcm9wJztcbmltcG9ydCB7IEFic3RyYWN0Q29udHJvbCwgRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5cbmltcG9ydCB7IE1BVF9ESUFMT0dfREFUQSwgTWF0RGlhbG9nQWN0aW9ucywgTWF0RGlhbG9nQ2xvc2UsIE1hdERpYWxvZ0NvbnRlbnQsIE1hdERpYWxvZ1JlZiwgTWF0RGlhbG9nVGl0bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9kaWFsb2cnO1xuaW1wb3J0IHsgTWF0Rm9ybUZpZWxkLCBNYXRIaW50LCBNYXRMYWJlbCwgTWF0U3VmZml4IH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZm9ybS1maWVsZCc7XG5pbXBvcnQgeyBNYXRCdXR0b24sIE1hdEljb25CdXR0b24gfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9idXR0b24nO1xuaW1wb3J0IHsgTWF0SWNvbiB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2ljb24nO1xuaW1wb3J0IHsgTWF0SW5wdXQgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9pbnB1dCc7XG5pbXBvcnQgeyBNYXRPcHRpb24sIE1hdFNlbGVjdCB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3NlbGVjdCc7XG5pbXBvcnQgeyBNYXRTbGlkZVRvZ2dsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3NsaWRlLXRvZ2dsZSc7XG5pbXBvcnQgeyBNYXRUYWJzTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvdGFicyc7XG5pbXBvcnQgeyBNYXRUb29sdGlwIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvdG9vbHRpcCc7XG5cbmltcG9ydCB7IEZzRGF0ZVBpY2tlck1vZHVsZSB9IGZyb20gJ0BmaXJlc3RpdGNoL2RhdGVwaWNrZXInO1xuaW1wb3J0IHsgRnNEaWFsb2dNb2R1bGUgfSBmcm9tICdAZmlyZXN0aXRjaC9kaWFsb2cnO1xuaW1wb3J0IHsgRnNGb3JtTW9kdWxlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvZm9ybSc7XG5pbXBvcnQgeyBGc0xhYmVsTW9kdWxlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvbGFiZWwnO1xuaW1wb3J0IHsgRnNNYXNrTW9kdWxlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvbWFzayc7XG5pbXBvcnQgeyBGc01lbnVNb2R1bGUgfSBmcm9tICdAZmlyZXN0aXRjaC9tZW51JztcbmltcG9ydCB7IEZzTWVzc2FnZSB9IGZyb20gJ0BmaXJlc3RpdGNoL21lc3NhZ2UnO1xuaW1wb3J0IHsgRnNQcm9tcHQgfSBmcm9tICdAZmlyZXN0aXRjaC9wcm9tcHQnO1xuaW1wb3J0IHsgRnNUYWJzTW9kdWxlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvdGFicyc7XG5cbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IHN3aXRjaE1hcCwgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBjaGFydEF4aXNTZXR0aW5ncywgc2FtZUNoYXJ0QXhpc1NldHRpbmdzIH0gZnJvbSAnLi4vLi4vY2hhcnQtYXhpcy1zZXR0aW5ncyc7XG5pbXBvcnQgeyBSZXBvcnREYXRhIH0gZnJvbSAnLi4vLi4vZGF0YS9yZXBvcnQuZGF0YSc7XG5pbXBvcnQgeyBSZXBvcnRDaGFuZ2VQb2xhcml0eSB9IGZyb20gJy4uLy4uL2VudW1zL3JlcG9ydC1jaGFuZ2UtcG9sYXJpdHkuZW51bSc7XG5pbXBvcnQgeyBSZXBvcnRDaGFydERhdGVMYWJlbCB9IGZyb20gJy4uLy4uL2VudW1zL3JlcG9ydC1jaGFydC1kYXRlLWxhYmVsLmVudW0nO1xuaW1wb3J0IHsgUmVwb3J0Q2hhcnRTcGFuTW9kZSB9IGZyb20gJy4uLy4uL2VudW1zL3JlcG9ydC1jaGFydC1zcGFuLW1vZGUuZW51bSc7XG5pbXBvcnQgeyBSZXBvcnRDaGFydFNwYW5UaHJvdWdoIH0gZnJvbSAnLi4vLi4vZW51bXMvcmVwb3J0LWNoYXJ0LXNwYW4tdGhyb3VnaC5lbnVtJztcbmltcG9ydCB7IFJlcG9ydFZhbHVlRm9ybWF0IH0gZnJvbSAnLi4vLi4vZW51bXMvcmVwb3J0LXZhbHVlLWZvcm1hdC5lbnVtJztcbmltcG9ydCB7IFJlcG9ydFZhbHVlRm9ybXVsYSB9IGZyb20gJy4uLy4uL2VudW1zL3JlcG9ydC12YWx1ZS1mb3JtdWxhLmVudW0nO1xuaW1wb3J0IHsgcmVzb2x2ZUZvcm1hdENvbnRleHQgfSBmcm9tICcuLi8uLi9mb3JtYXQnO1xuaW1wb3J0IHtcbiAgS1BJX1NQQVJLTElORV9ERUZBVUxUX0dSQU5VTEFSSVRZLFxuICBLUElfU1BBUktMSU5FX0RFRkFVTFRfUEVSSU9EUyxcbiAga3BpQ2FyZFNldHRpbmdzLFxuICBzYW1lS3BpQ2FyZFNldHRpbmdzLFxufSBmcm9tICcuLi8uLi9rcGktY2FyZCc7XG5pbXBvcnQgeyBSZXBvcnRDaGFydEF4aXNTZXR0aW5ncyB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMvcmVwb3J0LWNoYXJ0LWF4aXMtc2V0dGluZ3MuaW50ZXJmYWNlJztcbmltcG9ydCB7IFJlcG9ydENoYXJ0U3BhbiB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMvcmVwb3J0LWNoYXJ0LXNwYW4uaW50ZXJmYWNlJztcbmltcG9ydCB7XG4gIENoYXJ0Q29uZmlnLFxuICBDaGFydEdyYW51bGFyaXR5LFxuICBDb21wb25lbnRTZXR0aW5ncyxcbiAgR1JBTlVMQVJJVFlfT1BUSU9OUyxcbiAgS3BpQ2FyZFNldHRpbmdzLFxuICBLcGlDb25maWcsXG4gIFJlcG9ydCxcbiAgUmVwb3J0Q29tcG9uZW50LFxuICBSZXBvcnRDb21wb25lbnRTcWwsXG4gIFJlcG9ydEZpbHRlcixcbiAgUmVwb3J0RmlsdGVyR3JvdXAsXG4gIFJlcG9ydEZpbHRlckxldmVsLFxuICBSZXBvcnRGaWx0ZXJUeXBlLFxuICBSZXBvcnRGaWx0ZXJhYmxlQ29sdW1uLFxufSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL3JlcG9ydC5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgREVGQVVMVF9DT01QT05FTlRfUEFERElORyB9IGZyb20gJy4uLy4uL2xheW91dCc7XG5pbXBvcnQgeyBkYXRlRnJvbUJvdW5kLCBkYXRlVG9Cb3VuZCB9IGZyb20gJy4uLy4uL3JlcG9ydC1maWx0ZXItaXRlbXMnO1xuaW1wb3J0IHtcbiAgRklMVEVSX1RZUEVfT1BUSU9OUyxcbiAgYmFyUGxhY2VtZW50LFxuICBiYXJQbGFjZW1lbnRPcHRpb25zLFxuICBjb21wb25lbnRUb2dnbGVTdGF0ZSxcbiAgZmlsdGVyTGV2ZWwsXG4gIGZpbHRlckxldmVsQ2hvaWNlcyxcbiAgc2hvd25PbkNvbXBvbmVudCxcbiAgdHlwZVNlbGVjdFN0YXRlLFxuICB2YWx1ZUZpbHRlckxldmVsLFxuICB2YWx1ZVBsYWNlbWVudE9wdGlvbnMsXG59IGZyb20gJy4uLy4uL2ZpbHRlci1zZXR0aW5ncy1ydWxlcyc7XG5pbXBvcnQgeyBGaWx0ZXJCYXJQbGFjZW1lbnQgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL2ZpbHRlci1iYXItcGxhY2VtZW50LnR5cGUnO1xuaW1wb3J0IHsgRmlsdGVyQ29tcG9uZW50VG9nZ2xlU3RhdGUgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL2ZpbHRlci1jb21wb25lbnQtdG9nZ2xlLXN0YXRlLmludGVyZmFjZSc7XG5pbXBvcnQgeyBGaWx0ZXJTZXR0aW5nc09wdGlvbiB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMvZmlsdGVyLXNldHRpbmdzLW9wdGlvbi5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgRmlsdGVyVHlwZVNlbGVjdFN0YXRlIH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9maWx0ZXItdHlwZS1zZWxlY3Qtc3RhdGUuaW50ZXJmYWNlJztcbmltcG9ydCB7IFRleHRUb2tlbkNvbnRleHQsIGVzY2FwZUh0bWwsIGZpZWxkVG9rZW4sIGZpbGxUaXRsZVRva2VucywgdGV4dEZpZWxkcyB9IGZyb20gJy4uLy4uL3RleHQnO1xuaW1wb3J0IHsgb3BlcmFuZEtleXMsIHJlcG9ydENvbXBvbmVudHMsIHZhbHVlS2V5IH0gZnJvbSAnLi4vLi4vdmFsdWVzJztcblxuXG4vLyBXaGF0IHRoZSBkaWFsb2cgaGFuZHMgYmFjay4gVGhlIFNldHRpbmdzIHRhYidzIFNhdmUgY2FycmllcyB0aGUgbmV3XG4vLyBgc2V0dGluZ3NgOyBEZWxldGUgY2FycmllcyBgZGVsZXRlZGAgYW5kIG5vIHNldHRpbmdzLCBiZWNhdXNlIHRoZSBjb21wb25lbnRcbi8vIGl0IHdhcyBvcGVuZWQgZm9yIG5vIGxvbmdlciBleGlzdHMuIEV2ZXJ5IG90aGVyIGV4aXQgKENhbmNlbCwgRG9uZSwgRXNjYXBlLFxuLy8gYmFja2Ryb3ApIGNsb3NlcyB3aXRoIG5vIHJlc3VsdCDigJQgZmlsdGVyIHdvcmsgaXMgYW5ub3VuY2VkIGFzIGl0IGhhcHBlbnNcbi8vIGluc3RlYWQsIHRocm91Z2ggYGZpbHRlcnNDaGFuZ2VkYC5cbmV4cG9ydCBpbnRlcmZhY2UgQ29tcG9uZW50U2V0dGluZ3NSZXN1bHQge1xuICBzZXR0aW5ncz86IENvbXBvbmVudFNldHRpbmdzO1xuICBkZWxldGVkPzogYm9vbGVhbjtcbn1cblxuLy8gV2hhdCB0aGUgZGlhbG9nIG9wZW5zIHdpdGg6IHRoZSByZXBvcnQsIHRoZSBjb21wb25lbnQsIGFuZCB3aGF0IHRoZSB0b2tlbnNcbi8vIG9mIHRoZSBjb21wb25lbnQncyB0aXRsZSBmaWxsIHdpdGggd2hlcmUgaXQgaXMgZHJhd24gKGl0cyBwYWdlJ3MsIG9yIHRoZVxuLy8gbWFzdGVyJ3MgZm9yIGEgaGVhZGVyIG9yIGZvb3RlciBjb21wb25lbnQpLCBmb3IgdGhlIHRpdGxlJ3MgSW5zZXJ0IGZpZWxkXG4vLyBtZW51IGFuZCB0aGUgbGluZSBzYXlpbmcgaG93IHRoZSB0aXRsZSByZWFkcy5cbmV4cG9ydCBpbnRlcmZhY2UgQ29tcG9uZW50U2V0dGluZ3NEaWFsb2dEYXRhIHtcbiAgcmVwb3J0OiBSZXBvcnQ7XG4gIGNvbXBvbmVudDogUmVwb3J0Q29tcG9uZW50O1xuICB0b2tlbnM6IFRleHRUb2tlbkNvbnRleHQ7XG59XG5cbi8vIFdoYXQgdGhlIHNldHRpbmdzIGVuZHBvaW50IHJldHVybnMgZm9yIHRoZSBjb21wb25lbnQ6IGl0cyBpZCBhbmQsIGZyb20gYVxuLy8gc2VydmVyIHRoYXQgc2F2ZXMgYSBLUEkncyBjYXJkIGtleXMsIHRoZSB3aG9sZSBjb25maWcgYXMgc2F2ZWQuXG5pbnRlcmZhY2UgQ29tcG9uZW50U2V0dGluZ3NSZXNwb25zZSB7XG4gIGlkOiBudW1iZXI7XG4gIGNvbmZpZz86IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHwgbnVsbDtcbn1cblxuXG4vLyBXaGF0IGEgcmlzZSBpbiBhIEtQSSdzIHZhbHVlIG1lYW5zLCBmb3IgdGhlIEluY3JlYXNlIGlzIHNlbGVjdC5cbmNvbnN0IEtQSV9DSEFOR0VfUE9MQVJJVFlfT1BUSU9OUzogeyB2YWx1ZTogUmVwb3J0Q2hhbmdlUG9sYXJpdHk7IG5hbWU6IHN0cmluZyB9W10gPSBbXG4gIHsgdmFsdWU6IFJlcG9ydENoYW5nZVBvbGFyaXR5Lkdvb2QsIG5hbWU6ICdHb29kIG5ld3Mg4oCUIGEgcmlzZSBzaG93cyBncmVlbicgfSxcbiAgeyB2YWx1ZTogUmVwb3J0Q2hhbmdlUG9sYXJpdHkuQmFkLCBuYW1lOiAnQmFkIG5ld3Mg4oCUIGEgcmlzZSBzaG93cyByZWQnIH0sXG4gIHsgdmFsdWU6IFJlcG9ydENoYW5nZVBvbGFyaXR5Lk5ldXRyYWwsIG5hbWU6ICdOZWl0aGVyIOKAlCBubyBjb2xvcicgfSxcbl07XG5cbi8vIEEgS1BJIHNwYXJrbGluZSdzIHBlcmlvZHMgc3RheSB3aXRoaW4gMiB0byA2MC5cbmNvbnN0IEtQSV9TUEFSS0xJTkVfTUlOX1BFUklPRFMgPSAyO1xuY29uc3QgS1BJX1NQQVJLTElORV9NQVhfUEVSSU9EUyA9IDYwO1xuXG4vLyBIb3cgYSB0aW1lIGF4aXMgd3JpdGVzIGl0cyBwZXJpb2QgbGFiZWxzLCBmb3IgdGhlIERhdGUgbGFiZWxzIHNlbGVjdC5cbmNvbnN0IENIQVJUX0RBVEVfTEFCRUxfT1BUSU9OUzogeyB2YWx1ZTogUmVwb3J0Q2hhcnREYXRlTGFiZWw7IG5hbWU6IHN0cmluZyB9W10gPSBbXG4gIHsgdmFsdWU6IFJlcG9ydENoYXJ0RGF0ZUxhYmVsLlNob3J0LCBuYW1lOiAnU2hvcnQg4oCUIE1heScgfSxcbiAgeyB2YWx1ZTogUmVwb3J0Q2hhcnREYXRlTGFiZWwuTG9uZywgbmFtZTogJ0xvbmcg4oCUIE1heSAyMDI2JyB9LFxuICB7IHZhbHVlOiBSZXBvcnRDaGFydERhdGVMYWJlbC5OdW1lcmljLCBuYW1lOiAnTnVtZXJpYyDigJQgMjAyNi0wNScgfSxcbiAgeyB2YWx1ZTogUmVwb3J0Q2hhcnREYXRlTGFiZWwuUGVyaW9kRW5kLCBuYW1lOiAnUGVyaW9kIGVuZCDigJQgNS8zMS8yMDI2JyB9LFxuXTtcblxuLy8gVGhlIHBlcmlvZHMgYSB0aW1lIGF4aXMgZHJhd3MsIGZvciB0aGUgUGVyaW9kcyBzaG93biBzZWxlY3QuXG5jb25zdCBDSEFSVF9TUEFOX01PREVfT1BUSU9OUzogeyB2YWx1ZTogUmVwb3J0Q2hhcnRTcGFuTW9kZTsgbmFtZTogc3RyaW5nIH1bXSA9IFtcbiAgeyB2YWx1ZTogUmVwb3J0Q2hhcnRTcGFuTW9kZS5Ob25lLCBuYW1lOiAnVGhlIGRhdGUgZmlsdGVyXFwncyByYW5nZScgfSxcbiAgeyB2YWx1ZTogUmVwb3J0Q2hhcnRTcGFuTW9kZS5QZXJpb2RzLCBuYW1lOiAnVGhlIGxhc3QgcGVyaW9kcywgdXAgdG8gdGhlIGRhdGUgZmlsdGVyXFwncyBlbmQnIH0sXG4gIHsgdmFsdWU6IFJlcG9ydENoYXJ0U3Bhbk1vZGUuU3RhcnQsIG5hbWU6ICdFdmVyeSBwZXJpb2Qgc2luY2UgYSBkYXRlLCB1cCB0byB0aGUgZGF0ZSBmaWx0ZXJcXCdzIGVuZCcgfSxcbl07XG5cbi8vIEEgc3BhbidzIHBlcmlvZHMgc3RheSB3aXRoaW4gMSB0byA0MDAsIHRoZSBzZXJ2ZXIncyBib3VuZHMuXG5jb25zdCBDSEFSVF9TUEFOX01JTl9QRVJJT0RTID0gMTtcbmNvbnN0IENIQVJUX1NQQU5fTUFYX1BFUklPRFMgPSA0MDA7XG5jb25zdCBDSEFSVF9TUEFOX0RFRkFVTFRfUEVSSU9EUyA9IDM7XG5cbi8vIEEgcGVyY2VudCBLUEkncyB0YXJnZXQgaXMgZW50ZXJlZCBhcyB0aGUgcGVyY2VudCBzaG93biAoMTUgZm9yIDE1JSkgYW5kXG4vLyBzdG9yZWQgYXMgdGhlIDAtMSByYXRpbyBpdHMgdmFsdWUgYXJyaXZlcyBpbjsgdGhlIHNlcnZlciByZWZ1c2VzIGEgc3RvcmVkXG4vLyB0YXJnZXQgYWJvdmUgMTAwLCB3aGljaCBpcyAxMCwwMDAlIGhlcmUuXG5jb25zdCBLUElfUEVSQ0VOVF9UQVJHRVRfTUFYID0gMTAwMDA7XG5cbi8vIEhvdyBhIGZvcm11bGEgdmFsdWUncyBTZXR0aW5ncyB0YWIgd3JpdGVzIG91dCB3aGF0IGl0IHdvcmtzIG91dCwgaW4gaXRzXG4vLyBvcGVyYW5kcycgbmFtZXMuXG5jb25zdCBGT1JNVUxBX0xJTkVTOiBSZWNvcmQ8UmVwb3J0VmFsdWVGb3JtdWxhLCAobmFtZXM6IHN0cmluZ1tdKSA9PiBzdHJpbmc+ID0ge1xuICBbUmVwb3J0VmFsdWVGb3JtdWxhLkNoYW5nZV06IChuYW1lcykgPT4gbmFtZXMuam9pbignIOKIkiAnKSxcbiAgW1JlcG9ydFZhbHVlRm9ybXVsYS5QZXJjZW50Q2hhbmdlXTogKFthLCBiXSkgPT4gYCUgY2hhbmdlIG9mICR7YX0gb3ZlciAke2J9YCxcbiAgW1JlcG9ydFZhbHVlRm9ybXVsYS5SYXRpb106IChuYW1lcykgPT4gbmFtZXMuam9pbignIMO3ICcpLFxuICBbUmVwb3J0VmFsdWVGb3JtdWxhLlN1bV06IChuYW1lcykgPT4gbmFtZXMuam9pbignICsgJyksXG59O1xuXG5cbi8vIE9uZSByb3cgb2YgdGhlIEZpbHRlcnMgdGFiIGxpc3Rpbmc6IGEgZmlsdGVyYWJsZSBjb2x1bW4sIGl0cyBmaWx0ZXIncyB0eXBlXG4vLyAodGhlIGluZmVycmVkIG9uZSwgdGhlIG9uZSBwaWNrZWQsIG9yIHRoZSBmaWx0ZXIncyBvd24pLCBhbmQgd2hlcmUgaXRzXG4vLyBmaWx0ZXIgc2hvd3MgKHRoZSBSZXBvcnQgYmFyIHNlbGVjdCBhbmQgdGhlIFRoaXMgY29tcG9uZW50IHRvZ2dsZSkuXG5pbnRlcmZhY2UgRmlsdGVyUm93IHtcbiAgY29sdW1uOiBzdHJpbmc7XG4gIHR5cGU6IFJlcG9ydEZpbHRlclR5cGU7XG4gIGxhYmVsOiBzdHJpbmc7XG4gIHBsYWNlbWVudDogRmlsdGVyQmFyUGxhY2VtZW50O1xuICBjb21wb25lbnQ6IGJvb2xlYW47XG4gIHR5cGVTZWxlY3Q6IEZpbHRlclR5cGVTZWxlY3RTdGF0ZTtcbiAgcGxhY2VtZW50T3B0aW9uczogRmlsdGVyU2V0dGluZ3NPcHRpb248RmlsdGVyQmFyUGxhY2VtZW50PltdO1xuICBjb21wb25lbnRUb2dnbGU6IEZpbHRlckNvbXBvbmVudFRvZ2dsZVN0YXRlO1xufVxuXG5cbi8vIENvbXBvbmVudCBzZXR0aW5ncywgaW4gdGFiczpcbi8vICAgU2V0dGluZ3Mg4oCUIHRpdGxlIGFuZCBjb250ZW50IHBhZGRpbmcgKGEgdmFsdWU6IGp1c3QgaXRzIG5hbWUsIHNpbmNlIGl0XG4vLyAgIHNpdHMgaW5zaWRlIGEgdGV4dCBibG9jaydzIHdvcmRzIGFuZCBoYXMgbm8gYm94KS4gQSB0aXRsZSBtYXkgY2FycnkgdGhlXG4vLyAgIHBhZ2UsIHJlcG9ydCBhbmQgZmlsdGVyIGZpZWxkcyBhIHRleHQgYmxvY2sncyB3b3JkcyBkbzogaXRzIEluc2VydCBmaWVsZFxuLy8gICBtZW51IHB1dHMgb25lIGluIGF0IHRoZSBjYXJldCwgYW5kIHRoZSBsaW5lIHVuZGVyIGl0IHNheXMgaG93IHRoZSB0aXRsZVxuLy8gICByZWFkcy4gT24gYSBkZXJpdmVkIEtQSSBpdHMgY2FyZDogd2hhdCBhIHJpc2UgbWVhbnMsIGEgdGFyZ2V0IGFuZCBhXG4vLyAgIHNwYXJrbGluZSAobnVtYmVyIGZvcm1hdHMgc3RheSB3aXRoIHRoZSBBSSkuIFBvc2l0aW9uL3NpemUgYXJlIHR1bmVkIGJ5XG4vLyAgIGRyYWdnaW5nIG9uIHRoZSBjYW52YXM7IGhlaWdodCBiZWhhdmlvdXIgZm9sbG93cyBmcm9tIHRoZSBjb21wb25lbnQgdHlwZS5cbi8vICAgT24gYSBjaGFydCBvdmVyIHRpbWUgaXRzIGF4aXM6IGhvdyB0aGUgcGVyaW9kcyBhcmUgbGFiZWxsZWQgYW5kLCBvbiBhXG4vLyAgIGRlcml2ZWQgY2hhcnQsIHdoaWNoIHBlcmlvZHMgaXQgZHJhd3MgKGEgc3BhbiB0aGF0IGVuZHMgd2hlcmUgdGhlIGRhdGVcbi8vICAgZmlsdGVyIGVuZHMsIHdoaWNoIHRoZSBzZXJ2ZXIgcnVucykuXG4vLyAgIEZpbHRlcnMgIOKAlCBPTkUgbGlzdGluZyBvZiBldmVyeSBmaWx0ZXJhYmxlIGNvbHVtbiBvbiB0aGlzIGNvbXBvbmVudC4gRWFjaFxuLy8gICByb3cgY2FycmllcyB0d28gdG9nZ2xlczogc2hvdyBpbiB0aGUgcmVwb3J0IGJhciBhbmQvb3Igc2hvdyBvbiB0aGlzXG4vLyAgIGNvbXBvbmVudCAoYm90aCwgZWl0aGVyLCBvciBuZWl0aGVyKS4gVGhlIGludGVyZmFjZSAoZGF0ZSByYW5nZSB2cyB2YWx1ZVxuLy8gICBwaWNrZXIpIGlzIGluZmVycmVkIGZyb20gdGhlIGRhdGEsIG5ldmVyIGNob3Nlbi4gRWFjaCB0b2dnbGUgcGVyc2lzdHNcbi8vICAgaW1tZWRpYXRlbHkgYW5kIHJlZnJlc2hlcyB0aGUgaW4tZGlhbG9nIGxpc3QuIEEgdmFsdWUgaGFzIG5vIGNvbXBvbmVudFxuLy8gICB0byBzaG93IGEgZmlsdGVyIG9uLCBzbyBpdCBnZXRzIHRoZSByZXBvcnQgYmFyIHRvZ2dsZSBvbmx5LlxuLy8gICBTUUwgLyBDb25maWcg4oCUIHJlYWQtb25seSBkaWFnbm9zdGljcy5cbi8vIEEgZm9ybXVsYSB2YWx1ZSBoYXMgbm8gRmlsdGVycyBvciBTUUwgdGFiOiB0aGUgc2VydmVyIHdvcmtzIGl0IG91dCBvZiBvdGhlclxuLy8gdmFsdWVzIG9uIGl0cyBwYWdlLCBzbyBpdCBydW5zIG5vIHN0YXRlbWVudCBhbmQgZm9sbG93cyB0aGUgZmlsdGVycyBvZiB0aGVcbi8vIHZhbHVlcyBpdCByZWFkcy4gSXRzIFNldHRpbmdzIHRhYiBzYXlzIHdoYXQgaXQgd29ya3Mgb3V0LCB1bmRlciBpdHMgbmFtZS5cbkBDb21wb25lbnQoe1xuICB0ZW1wbGF0ZVVybDogJy4vY29tcG9uZW50LXNldHRpbmdzLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vY29tcG9uZW50LXNldHRpbmdzLmNvbXBvbmVudC5zY3NzJ10sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXG4gICAgRm9ybXNNb2R1bGUsXG4gICAgRnNEYXRlUGlja2VyTW9kdWxlLFxuICAgIEZzRm9ybU1vZHVsZSxcbiAgICBGc01hc2tNb2R1bGUsXG4gICAgRnNEaWFsb2dNb2R1bGUsXG4gICAgRnNMYWJlbE1vZHVsZSxcbiAgICBGc1RhYnNNb2R1bGUsXG4gICAgTWF0VGFic01vZHVsZSxcbiAgICBNYXREaWFsb2dUaXRsZSxcbiAgICBNYXREaWFsb2dDb250ZW50LFxuICAgIE1hdERpYWxvZ0FjdGlvbnMsXG4gICAgTWF0RGlhbG9nQ2xvc2UsXG4gICAgTWF0Rm9ybUZpZWxkLFxuICAgIE1hdEhpbnQsXG4gICAgTWF0TGFiZWwsXG4gICAgTWF0U3VmZml4LFxuICAgIE1hdEJ1dHRvbixcbiAgICBNYXRJY29uLFxuICAgIE1hdEljb25CdXR0b24sXG4gICAgTWF0SW5wdXQsXG4gICAgTWF0T3B0aW9uLFxuICAgIE1hdFNlbGVjdCxcbiAgICBNYXRTbGlkZVRvZ2dsZSxcbiAgICBNYXRUb29sdGlwLFxuICAgIEZzTWVudU1vZHVsZSxcbiAgXSxcbn0pXG5leHBvcnQgY2xhc3MgQ29tcG9uZW50U2V0dGluZ3NDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuXG4gIC8vIEEgZmlsdGVyIHdhcyBhZGRlZCwgcmVtb3ZlZCBvciByZS1sZXZlbGxlZCwgc28gdGhlIHJlcG9ydCdzIGZpbHRlciBncm91cHNcbiAgLy8gY2hhbmdlZC4gVGhvc2UgbXV0YXRpb25zIHBlcnNpc3QgdGhlIG1vbWVudCB0aGV5IGFyZSBjbGlja2VkIGFuZCB0aGUgZGlhbG9nXG4gIC8vIGNhbiB0aGVuIGJlIGRpc21pc3NlZCBieSBhIHJvdXRlIHRoYXQgY2FycmllcyBubyByZXN1bHQgKEVzY2FwZSwgYmFja2Ryb3ApLFxuICAvLyBzbyB0aGUgcGFnZSBpcyB0b2xkIGhlcmUgcmF0aGVyIHRoYW4gdGhyb3VnaCB0aGUgY2xvc2UgcmVzdWx0LlxuICBwdWJsaWMgcmVhZG9ubHkgZmlsdGVyc0NoYW5nZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cbiAgcHVibGljIGNvbXBvbmVudDogUmVwb3J0Q29tcG9uZW50O1xuICBwdWJsaWMgcmVwb3J0OiBSZXBvcnQ7XG5cbiAgcHVibGljIHNlbGVjdGVkVGFiID0gJ3NldHRpbmdzJztcblxuICBwdWJsaWMgcmVhZG9ubHkgdGl0bGUgPSBzaWduYWwoJycpO1xuXG4gIC8vIFdoYXQgdGhlIHRpdGxlJ3MgSW5zZXJ0IGZpZWxkIG1lbnUgbGlzdHMsIGluIG9yZGVyOiB0aGUgcGFnZSBhbmQgcmVwb3J0XG4gIC8vIGZpZWxkcywgdGhlbiBlYWNoIGZpbHRlciBvZiB0aGUgcmVwb3J0IGluIHRoZSBmaWx0ZXIgYmFyJ3Mgb3JkZXIuIEEgdmFsdWVcbiAgLy8gdG9rZW4gaXMgbmV2ZXIgb2ZmZXJlZDogdmFsdWVzIGJlbG9uZyB0byBhIHBhZ2UncyB0ZXh0LlxuICBwdWJsaWMgcmVhZG9ubHkgdGl0bGVGaWVsZHMgPSBjb21wdXRlZCgoKSA9PiB0ZXh0RmllbGRzKHRoaXMuX2RhdGEudG9rZW5zKSk7XG5cbiAgLy8gSG93IHRoZSB0aXRsZSByZWFkcyB3aGVyZSB0aGUgY29tcG9uZW50IGlzIGRyYXduLCB3aGlsZSBpdCBob2xkcyBhIHRva2VuXG4gIC8vICgnU2lnbi11cHMg4oCUIFNlcHRlbWJlciAyMDI2Jyk7IGVtcHR5IGZvciBhIHRpdGxlIHdpdGggbm9uZSwgYW5kIGZvciBhXG4gIC8vIHZhbHVlLCB3aG9zZSBOYW1lIGlzIGp1c3QgaXRzIG5hbWUuXG4gIHB1YmxpYyByZWFkb25seSB0aXRsZVNob3duQXMgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgY29uc3QgdGl0bGUgPSB0aGlzLnRpdGxlKCk7XG4gICAgY29uc3Qgc2hvd24gPSBmaWxsVGl0bGVUb2tlbnModGl0bGUsIHRoaXMuX2RhdGEudG9rZW5zKTtcblxuICAgIHJldHVybiAhdGhpcy5pc1ZhbHVlKCkgJiYgc2hvd24gIT09IHRpdGxlID8gc2hvd24gOiAnJztcbiAgfSk7XG5cbiAgLy8gVGhlIGRpYWxvZydzIGhlYWRpbmc6IHRoZSB0aXRsZSBhcyBpdCByZWFkcyAoYSB2YWx1ZSdzIE5hbWUgYXMgaXQgaXMpLFxuICAvLyBlbHNlIHdoYXQgdGhlIGNvbXBvbmVudCBpcy5cbiAgcHVibGljIHJlYWRvbmx5IGhlYWRpbmcgPSBjb21wdXRlZCgoKSA9PiB0aGlzLl9zaG93blRpdGxlKCkgfHwgKHRoaXMuaXNWYWx1ZSgpID8gJ1ZhbHVlJyA6ICdDb21wb25lbnQnKSk7XG5cbiAgLy8gQ29tcG9uZW50IHBhZGRpbmcgaW4gaW5jaGVzLiBgbnVtYmVyIHwgc3RyaW5nYCBmb3IgdGhlIHNhbWUgcmVhc29uIGFzIHRoZVxuICAvLyBwYWdlIGRpbWVuc2lvbnMgaW4gcmVwb3J0LXNldHRpbmdzOiBmc01hc2tOdW1iZXIgc2VlZHMgZnJvbSB0aGUgbnVtYmVyIGJ1dFxuICAvLyBoYW5kcyBiYWNrIHRoZSB1bm1hc2tlZCBzdHJpbmcsIGFuZCBzYXZlIGNhc3RzIGl0IG9uY2Ugb24gdGhlIHdheSBvdXQuXG4gIHB1YmxpYyBwYWRkaW5nVG9wOiBudW1iZXIgfCBzdHJpbmcgPSBERUZBVUxUX0NPTVBPTkVOVF9QQURESU5HO1xuICBwdWJsaWMgcGFkZGluZ1JpZ2h0OiBudW1iZXIgfCBzdHJpbmcgPSBERUZBVUxUX0NPTVBPTkVOVF9QQURESU5HO1xuICBwdWJsaWMgcGFkZGluZ0JvdHRvbTogbnVtYmVyIHwgc3RyaW5nID0gREVGQVVMVF9DT01QT05FTlRfUEFERElORztcbiAgcHVibGljIHBhZGRpbmdMZWZ0OiBudW1iZXIgfCBzdHJpbmcgPSBERUZBVUxUX0NPTVBPTkVOVF9QQURESU5HO1xuXG4gIHB1YmxpYyBjb25maWdKc29uID0gJyc7XG5cbiAgLy8gLS0tLSBLUEkgY2FyZCBzdGF0ZSAoYSBkZXJpdmVkIEtQSSBvbmx5KSAtLS0tXG4gIHB1YmxpYyByZWFkb25seSBrcGlQb2xhcml0eU9wdGlvbnMgPSBLUElfQ0hBTkdFX1BPTEFSSVRZX09QVElPTlM7XG4gIHB1YmxpYyByZWFkb25seSBncmFudWxhcml0eU9wdGlvbnMgPSBHUkFOVUxBUklUWV9PUFRJT05TO1xuICBwdWJsaWMgcmVhZG9ubHkgc3BhcmtsaW5lTWluUGVyaW9kcyA9IEtQSV9TUEFSS0xJTkVfTUlOX1BFUklPRFM7XG4gIHB1YmxpYyByZWFkb25seSBzcGFya2xpbmVNYXhQZXJpb2RzID0gS1BJX1NQQVJLTElORV9NQVhfUEVSSU9EUztcbiAgcHVibGljIHJlYWRvbmx5IGtwaUNhcmQgPSBzaWduYWwoZmFsc2UpO1xuICAvLyBBIHZhbHVlIGluc2lkZSBhIHRleHQgYmxvY2s6IG5vIGJveCwgc28gbm8gcGFkZGluZy5cbiAgcHVibGljIHJlYWRvbmx5IGlzVmFsdWUgPSBzaWduYWwoZmFsc2UpO1xuICAvLyBBIGZvcm11bGEgdmFsdWU6IG5vIHN0YXRlbWVudCwgY29sdW1ucyBvciBmaWx0ZXJzIG9mIGl0cyBvd24uXG4gIHB1YmxpYyByZWFkb25seSBpc0Zvcm11bGEgPSBzaWduYWwoZmFsc2UpO1xuICAvLyBXaGF0IGEgZm9ybXVsYSB3b3JrcyBvdXQsIGluIGl0cyBvcGVyYW5kcycgbmFtZXM7IGVtcHR5IGZvciBhbnkgb3RoZXJcbiAgLy8gY29tcG9uZW50LlxuICBwdWJsaWMgcmVhZG9ubHkgZm9ybXVsYUxpbmUgPSBjb21wdXRlZCgoKSA9PiAodGhpcy5pc0Zvcm11bGEoKSA/IHRoaXMuX2Zvcm11bGFMaW5lKCkgOiAnJykpO1xuICBwdWJsaWMgcmVhZG9ubHkgaW5jcmVhc2VJcyA9IHNpZ25hbDxSZXBvcnRDaGFuZ2VQb2xhcml0eT4oUmVwb3J0Q2hhbmdlUG9sYXJpdHkuR29vZCk7XG4gIC8vIFRoZSB0YXJnZXQgYXMgdHlwZWQ6IGZzTWFza051bWJlciBoYW5kcyBiYWNrIHRoZSB1bm1hc2tlZCBzdHJpbmcuIEVtcHR5XG4gIC8vIG1lYW5zIG5vIHRhcmdldC4gQSBwZXJjZW50IEtQSSdzIGlzIGluIHBlcmNlbnQgKHRhcmdldFBlcmNlbnQpLlxuICBwdWJsaWMgcmVhZG9ubHkgdGFyZ2V0VmFsdWUgPSBzaWduYWw8bnVtYmVyIHwgc3RyaW5nIHwgbnVsbD4obnVsbCk7XG4gIHB1YmxpYyByZWFkb25seSB0YXJnZXRMYWJlbCA9IHNpZ25hbCgnJyk7XG4gIHB1YmxpYyByZWFkb25seSB0YXJnZXRQZXJjZW50ID0gc2lnbmFsKGZhbHNlKTtcbiAgcHVibGljIHJlYWRvbmx5IGhhc1RhcmdldCA9IGNvbXB1dGVkKCgpID0+IHRoaXMuX251bWJlcih0aGlzLnRhcmdldFZhbHVlKCkpICE9PSBudWxsKTtcbiAgcHVibGljIHJlYWRvbmx5IHNwYXJrbGluZSA9IHNpZ25hbChmYWxzZSk7XG4gIHB1YmxpYyByZWFkb25seSBzcGFya2xpbmVHcmFudWxhcml0eSA9IHNpZ25hbDxDaGFydEdyYW51bGFyaXR5PihLUElfU1BBUktMSU5FX0RFRkFVTFRfR1JBTlVMQVJJVFkpO1xuICBwdWJsaWMgcmVhZG9ubHkgc3BhcmtsaW5lUGVyaW9kcyA9IHNpZ25hbDxudW1iZXIgfCBzdHJpbmc+KEtQSV9TUEFSS0xJTkVfREVGQVVMVF9QRVJJT0RTKTtcblxuICAvLyAtLS0tIFRpbWUgYXhpcyBzdGF0ZSAoYSBjaGFydCBvdmVyIHRpbWUgb25seSkgLS0tLVxuICBwdWJsaWMgcmVhZG9ubHkgZGF0ZUxhYmVsT3B0aW9ucyA9IENIQVJUX0RBVEVfTEFCRUxfT1BUSU9OUztcbiAgcHVibGljIHJlYWRvbmx5IHNwYW5Nb2RlT3B0aW9ucyA9IENIQVJUX1NQQU5fTU9ERV9PUFRJT05TO1xuICBwdWJsaWMgcmVhZG9ubHkgc3Bhbk1pblBlcmlvZHMgPSBDSEFSVF9TUEFOX01JTl9QRVJJT0RTO1xuICBwdWJsaWMgcmVhZG9ubHkgc3Bhbk1heFBlcmlvZHMgPSBDSEFSVF9TUEFOX01BWF9QRVJJT0RTO1xuICBwdWJsaWMgcmVhZG9ubHkgUmVwb3J0Q2hhcnRTcGFuTW9kZSA9IFJlcG9ydENoYXJ0U3Bhbk1vZGU7XG4gIHB1YmxpYyByZWFkb25seSB0aW1lQXhpcyA9IHNpZ25hbChmYWxzZSk7XG4gIC8vIEEgc3BhbiBpcyBydW4gYnkgdGhlIHNlcnZlciBvbiB0aGUgY2hhcnQncyBkb2N1bWVudCwgc28gYSBjaGFydCB3cml0dGVuXG4gIC8vIGFzIFNRTCBoYXMgbm9uZS5cbiAgcHVibGljIHJlYWRvbmx5IHNwYW5BbGxvd2VkID0gc2lnbmFsKGZhbHNlKTtcbiAgcHVibGljIHJlYWRvbmx5IGRhdGVMYWJlbCA9IHNpZ25hbDxSZXBvcnRDaGFydERhdGVMYWJlbD4oUmVwb3J0Q2hhcnREYXRlTGFiZWwuU2hvcnQpO1xuICBwdWJsaWMgcmVhZG9ubHkgc3Bhbk1vZGUgPSBzaWduYWw8UmVwb3J0Q2hhcnRTcGFuTW9kZT4oUmVwb3J0Q2hhcnRTcGFuTW9kZS5Ob25lKTtcbiAgLy8gVGhlIHBlcmlvZHMgYXMgdHlwZWQ6IGZzTWFza051bWJlciBoYW5kcyBiYWNrIHRoZSB1bm1hc2tlZCBzdHJpbmcuXG4gIHB1YmxpYyByZWFkb25seSBzcGFuUGVyaW9kcyA9IHNpZ25hbDxudW1iZXIgfCBzdHJpbmc+KENIQVJUX1NQQU5fREVGQVVMVF9QRVJJT0RTKTtcbiAgcHVibGljIHJlYWRvbmx5IHNwYW5TdGFydCA9IHNpZ25hbDxEYXRlIHwgbnVsbD4obnVsbCk7XG5cbiAgLy8gLS0tLSBTUUwgdGFiIHN0YXRlIC0tLS1cbiAgLy8gVGhlIHN0YXRlbWVudCwgb25jZSBmZXRjaGVkLiBOdWxsIHdoaWxlIGl0IGlzIGluIGZsaWdodCwgYW5kIG51bGwgd2hlbiB0aGVcbiAgLy8gY29tcG9uZW50J3MgZG9jdW1lbnQgY291bGQgbm90IGJlIGNvbXBpbGVkIChzcWxFcnJvciB0aGVuIHNheXMgd2h5KS5cbiAgcHVibGljIHJlYWRvbmx5IHNxbCA9IHNpZ25hbDxzdHJpbmcgfCBudWxsPihudWxsKTtcbiAgLy8gVHJ1ZSB3aGVuIHRoZSBzdGF0ZW1lbnQgaXMgYSBERVJJVkVEIGJhc2VsaW5lOiBubyBmaWx0ZXJzLCB0aGUgYXV0aG9yZWRcbiAgLy8gZ3JhaW4sIHRpbWVzIGluIHRoZSByZXBvcnQncyBlZmZlY3RpdmUgem9uZS4gVGhlIHRhYiBzYXlzIHNvLCBiZWNhdXNlIHRoZVxuICAvLyBudW1iZXJzIG9uIHNjcmVlbiBjb21lIGZyb20gdGhpcyBzdGF0ZW1lbnQgcGx1cyB0aGUgdmlld2VyJ3Mgb3duIGNob2ljZXNcbiAgLy8gYW5kIHRoZSB0d28gY2FuIGRpZmZlci5cbiAgcHVibGljIHJlYWRvbmx5IHNxbEJhc2VsaW5lID0gc2lnbmFsKGZhbHNlKTtcbiAgLy8gVGhlIHpvbmUgdGhlIHN0YXRlbWVudCB3YXMgY29tcGlsZWQgaW46IHRoZSByZXBvcnQncyBlZmZlY3RpdmUgem9uZSwgc2VudFxuICAvLyB3aXRoIHRoZSBTUUwuIEEgc2VydmVyIHRvbyBvbGQgdG8gc2VuZCBpdCBjb21waWxlZCBpbiBVVEMuXG4gIHB1YmxpYyByZWFkb25seSBzcWxUaW1lem9uZSA9IHNpZ25hbCgnVVRDJyk7XG4gIHB1YmxpYyByZWFkb25seSBzcWxFcnJvciA9IHNpZ25hbDxzdHJpbmcgfCBudWxsPihudWxsKTtcblxuICAvLyAtLS0tIGZpbHRlciBtYW5hZ2VtZW50IHN0YXRlIC0tLS1cbiAgLy8gT25lIHJvdyBwZXIgZmlsdGVyYWJsZSBjb2x1bW4uIFRoZSBwbGFjZW1lbnQgYW5kIHRoZSB0b2dnbGUgY2hhbmdlXG4gIC8vIG9wdGltaXN0aWNhbGx5IG9uIGNsaWNrIChzbyB0aGUgVUkgbmV2ZXIgYmxpbmtzIHdoaWxlIHRoZSByZXF1ZXN0IGlzIGluXG4gIC8vIGZsaWdodCkgYW5kIHJlY29uY2lsZSBmcm9tIHRoZSBzZXJ2ZXIgb24gcmVsb2FkLlxuICBwdWJsaWMgcmVhZG9ubHkgcm93cyA9IHNpZ25hbDxGaWx0ZXJSb3dbXT4oW10pO1xuICBwdWJsaWMgcmVhZG9ubHkgY29sdW1uc0Vycm9yID0gc2lnbmFsPHN0cmluZyB8IG51bGw+KG51bGwpO1xuICAvLyBUaGUgVHlwZSBzZWxlY3QncyBjaG9pY2VzLiBBIHJvdydzIFR5cGUgc2VsZWN0LCBSZXBvcnQgYmFyIHNlbGVjdCBhbmRcbiAgLy8gVGhpcyBjb21wb25lbnQgdG9nZ2xlIGZvbGxvdyB0aGUgcnVsZXMgaW4gZmlsdGVyLXNldHRpbmdzLXJ1bGVzLnRzLlxuICBwdWJsaWMgcmVhZG9ubHkgdHlwZU9wdGlvbnMgPSBGSUxURVJfVFlQRV9PUFRJT05TO1xuXG4gIC8vIFRoZSByYXcgaW5wdXRzIHRoZSByb3dzIGFyZSBidWlsdCBmcm9tLlxuICBwcml2YXRlIF9maWx0ZXJhYmxlQ29sdW1uczogUmVwb3J0RmlsdGVyYWJsZUNvbHVtbltdID0gW107XG4gIHByaXZhdGUgX2ZpbHRlcnM6IFJlcG9ydEZpbHRlcltdID0gW107XG4gIHByaXZhdGUgX2dyb3Vwc0J5SWQgPSBuZXcgTWFwPG51bWJlciwgUmVwb3J0RmlsdGVyR3JvdXA+KCk7XG4gIC8vIFRoZSB0eXBlIHBpY2tlZCBmb3IgYSBjb2x1bW4gd2l0aCBubyBmaWx0ZXIgeWV0LCBzbyBhIHJlbG9hZCBrZWVwcyBpdC5cbiAgcHJpdmF0ZSBfcGlja2VkVHlwZXMgPSBuZXcgTWFwPHN0cmluZywgUmVwb3J0RmlsdGVyVHlwZT4oKTtcblxuICBwcml2YXRlIHJlYWRvbmx5IF90eXBlTGFiZWxzOiBSZWNvcmQ8UmVwb3J0RmlsdGVyVHlwZSwgc3RyaW5nPiA9IHtcbiAgICBzZWxlY3Q6ICdQaWNrIHZhbHVlcycsXG4gICAgZGF0ZVJhbmdlOiAnRGF0ZSByYW5nZScsXG4gICAga2V5d29yZDogJ1NlYXJjaCB0ZXh0JyxcbiAgICBudW1iZXJSYW5nZTogJ051bWJlciByYW5nZScsXG4gIH07XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfZGF0YTogQ29tcG9uZW50U2V0dGluZ3NEaWFsb2dEYXRhID0gaW5qZWN0KE1BVF9ESUFMT0dfREFUQSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX3RpdGxlSW5wdXQgPSB2aWV3Q2hpbGQ8RWxlbWVudFJlZjxIVE1MSW5wdXRFbGVtZW50Pj4oJ3RpdGxlSW5wdXQnKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfZGlhbG9nUmVmID0gaW5qZWN0PE1hdERpYWxvZ1JlZjxDb21wb25lbnRTZXR0aW5nc0NvbXBvbmVudCwgQ29tcG9uZW50U2V0dGluZ3NSZXN1bHQ+PihNYXREaWFsb2dSZWYpO1xuICBwcml2YXRlIHJlYWRvbmx5IF9yZXBvcnREYXRhID0gaW5qZWN0KFJlcG9ydERhdGEpO1xuICBwcml2YXRlIHJlYWRvbmx5IF9tZXNzYWdlID0gaW5qZWN0KEZzTWVzc2FnZSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX3Byb21wdCA9IGluamVjdChGc1Byb21wdCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX2Rlc3Ryb3lSZWYgPSBpbmplY3QoRGVzdHJveVJlZik7XG5cbiAgcHVibGljIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMucmVwb3J0ID0gdGhpcy5fZGF0YS5yZXBvcnQ7XG4gICAgdGhpcy5jb21wb25lbnQgPSB0aGlzLl9kYXRhLmNvbXBvbmVudDtcblxuICAgIHRoaXMudGl0bGUuc2V0KHRoaXMuY29tcG9uZW50LnRpdGxlID8/ICcnKTtcbiAgICB0aGlzLmlzVmFsdWUuc2V0KHRoaXMuY29tcG9uZW50LnR5cGUgPT09ICd2YWx1ZScpO1xuICAgIHRoaXMuaXNGb3JtdWxhLnNldCghIXRoaXMuY29tcG9uZW50LmNvbmZpZz8uZm9ybXVsYSk7XG5cbiAgICBjb25zdCBwYWRkaW5nID0gdGhpcy5jb21wb25lbnQuY29uZmlnPy5wYWRkaW5nO1xuICAgIHRoaXMucGFkZGluZ1RvcCA9IHBhZGRpbmc/LnRvcCA/PyBERUZBVUxUX0NPTVBPTkVOVF9QQURESU5HO1xuICAgIHRoaXMucGFkZGluZ1JpZ2h0ID0gcGFkZGluZz8ucmlnaHQgPz8gREVGQVVMVF9DT01QT05FTlRfUEFERElORztcbiAgICB0aGlzLnBhZGRpbmdCb3R0b20gPSBwYWRkaW5nPy5ib3R0b20gPz8gREVGQVVMVF9DT01QT05FTlRfUEFERElORztcbiAgICB0aGlzLnBhZGRpbmdMZWZ0ID0gcGFkZGluZz8ubGVmdCA/PyBERUZBVUxUX0NPTVBPTkVOVF9QQURESU5HO1xuXG4gICAgdGhpcy5jb25maWdKc29uID0gSlNPTi5zdHJpbmdpZnkodGhpcy5jb21wb25lbnQuY29uZmlnID8/IHt9LCBudWxsLCAyKTtcblxuICAgIHRoaXMuX3NlZWRLcGlDYXJkKCk7XG4gICAgdGhpcy5fc2VlZFRpbWVBeGlzKCk7XG5cbiAgICB0aGlzLl9zZWVkRmlsdGVycyh0aGlzLnJlcG9ydCwgdGhpcy5jb21wb25lbnQuaWQpO1xuXG4gICAgLy8gQSBmb3JtdWxhIGhhcyBubyBzdGF0ZW1lbnQgdG8gY29tcGlsZSBhbmQgbm8gY29sdW1ucyB0byBmaWx0ZXIgb24sIGFuZFxuICAgIC8vIHRoZSBzZXJ2ZXIgd291bGQgcmVmdXNlIGJvdGggcmVxdWVzdHMuXG4gICAgaWYgKCF0aGlzLmlzRm9ybXVsYSgpKSB7XG4gICAgICB0aGlzLl9sb2FkQ29sdW1ucygpO1xuICAgICAgdGhpcy5fbG9hZFNxbCgpO1xuICAgIH1cbiAgfVxuXG4gIC8vIEh1bWFuLWZyaWVuZGx5IG5hbWUgZm9yIHRoZSBpbmZlcnJlZCBpbnRlcmZhY2Ugc2hvd24gYmVzaWRlIGVhY2ggY29sdW1uLlxuICBwdWJsaWMgdHlwZUxhYmVsKHR5cGU6IFJlcG9ydEZpbHRlclR5cGUpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLl90eXBlTGFiZWxzW3R5cGVdID8/IHR5cGU7XG4gIH1cblxuICAvLyBDb25maXJtIGFuZCBkZWxldGUgaGVyZSwgd2hpbGUgdGhlIGRpYWxvZyBpcyBzdGlsbCBvcGVuLCB0aGVuIGNsb3NlIHdpdGggYVxuICAvLyBgZGVsZXRlZGAgcmVzdWx0IGZvciB0aGUgcGFnZSB0byBhY3Qgb24g4oCUIHRoZSBzYW1lIHNoYXBlIHRoZSByZXBvcnRcbiAgLy8gc2V0dGluZ3MgZGlhbG9nIHVzZXMgZm9yIGRlbGV0aW5nIGEgcmVwb3J0LlxuICAvL1xuICAvLyBUaGUgY29uZmlybSBzYXlzIGl0IGNhbm5vdCBiZSB1bmRvbmUgYmVjYXVzZSwgZnJvbSB0aGUgVUksIGl0IGNhbm5vdDogdGhlXG4gIC8vIHJvdyBpcyBzb2Z0LWRlbGV0ZWQgc2VydmVyLXNpZGUgYnV0IG5vdGhpbmcgaGVyZSByZXN0b3JlcyBhIGNvbXBvbmVudC5cbiAgLy8gQSB2YWx1ZSdzIGNvbmZpcm0gYWxzbyBzYXlzIHdoYXQgZ29lcyB3aXRoIGl0OiB0aGUgc2VydmVyIHRha2VzIGl0c1xuICAvLyB0b2tlbnMgb3V0IG9mIGV2ZXJ5IHRleHQgb24gaXRzIHBhZ2UsIG5vdCBqdXN0IHRoZSBvbmUgaXQgd2FzIG9wZW5lZCBmcm9tLFxuICAvLyBhbmQgZGVsZXRlcyB0aGUgZm9ybXVsYXMgdGhhdCByZWFkIGl0IChfZGVwZW5kZW50c05vdGUpLlxuICAvL1xuICAvLyBUaGUgcHJvbXB0IHJlbmRlcnMgaXRzIHRlbXBsYXRlIGFzIGh0bWwsIHNvIGV2ZXJ5IG5hbWUgaW4gaXQgaXMgZXNjYXBlZC5cbiAgcHVibGljIGRlbGV0ZSgpOiB2b2lkIHtcbiAgICB0aGlzLl9wcm9tcHQuY29uZmlybSh0aGlzLmlzVmFsdWUoKVxuICAgICAgPyB7XG4gICAgICAgIHRpdGxlOiAnRGVsZXRlIFZhbHVlJyxcbiAgICAgICAgdGVtcGxhdGU6IGBEZWxldGUgdGhlIHZhbHVlIFwiJHtlc2NhcGVIdG1sKHRoaXMuY29tcG9uZW50LnRpdGxlIHx8IHZhbHVlS2V5KHRoaXMuY29tcG9uZW50KSl9XCI/IEl0IGlzIGFsc28gdGFrZW4gb3V0IG9mIGV2ZXJ5IHRleHQgb24gdGhpcyBwYWdlLiBUaGlzIGNhbm5vdCBiZSB1bmRvbmUuJHt0aGlzLl9kZXBlbmRlbnRzTm90ZSgpfWAsXG4gICAgICB9XG4gICAgICA6IHtcbiAgICAgICAgdGl0bGU6ICdEZWxldGUgQ29tcG9uZW50JyxcbiAgICAgICAgdGVtcGxhdGU6IGBBcmUgeW91IHN1cmUgeW91IHdvdWxkIGxpa2UgdG8gZGVsZXRlIFwiJHtlc2NhcGVIdG1sKHRoaXMuX3Nob3duVGl0bGUoKSB8fCAndGhpcyBjb21wb25lbnQnKX1cIj8gVGhpcyBjYW5ub3QgYmUgdW5kb25lLmAsXG4gICAgICB9KVxuICAgICAgLnBpcGUoXG4gICAgICAgIHN3aXRjaE1hcCgoKSA9PiB0aGlzLl9yZXBvcnREYXRhLmRlbGV0ZUNvbXBvbmVudCh0aGlzLnJlcG9ydC5pZCwgdGhpcy5jb21wb25lbnQuaWQpKSxcbiAgICAgICAgdGFwKCgpID0+IHtcbiAgICAgICAgICB0aGlzLl9tZXNzYWdlLnN1Y2Nlc3ModGhpcy5pc1ZhbHVlKCkgPyAnVmFsdWUgZGVsZXRlZCcgOiAnQ29tcG9uZW50IGRlbGV0ZWQnKTtcbiAgICAgICAgICB0aGlzLl9kaWFsb2dSZWYuY2xvc2UoeyBkZWxldGVkOiB0cnVlIH0pO1xuICAgICAgICB9KSxcbiAgICAgICAgdGFrZVVudGlsRGVzdHJveWVkKHRoaXMuX2Rlc3Ryb3lSZWYpLFxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgpO1xuICB9XG5cbiAgLy8gUHV0cyBhIGZpZWxkJ3MgdG9rZW4gaW50byB0aGUgdGl0bGUgYXQgdGhlIGNhcmV0LCBvdmVyIGFueSB0ZXh0IHNlbGVjdGVkXG4gIC8vIHRoZXJlLCBhcyBpZiBpdCB3ZXJlIHR5cGVkOiB0aGUgbW9kZWwgZm9sbG93cyBhbmQgdGhlIGZpZWxkIGlzIGRpcnR5LiBUaGVcbiAgLy8gaW5wdXQga2VlcHMgaXRzIGNhcmV0IHdoaWxlIHRoZSBtZW51IGlzIG9wZW47IGZvY3VzIGNvbWVzIGJhY2sgdG8gaXQgb25jZVxuICAvLyB0aGUgbWVudSBoYXMgaGFuZGVkIGZvY3VzIGJhY2sgdG8gaXRzIGJ1dHRvbi5cbiAgcHVibGljIGluc2VydEZpZWxkKGZpZWxkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBpbnB1dCA9IHRoaXMuX3RpdGxlSW5wdXQoKT8ubmF0aXZlRWxlbWVudDtcbiAgICBpZiAoIWlucHV0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgZW5kID0gaW5wdXQudmFsdWUubGVuZ3RoO1xuICAgIGlucHV0LnNldFJhbmdlVGV4dChmaWVsZFRva2VuKGZpZWxkKSwgaW5wdXQuc2VsZWN0aW9uU3RhcnQgPz8gZW5kLCBpbnB1dC5zZWxlY3Rpb25FbmQgPz8gZW5kLCAnZW5kJyk7XG4gICAgaW5wdXQuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoJ2lucHV0JykpO1xuICAgIHNldFRpbWVvdXQoKCkgPT4gaW5wdXQuZm9jdXMoKSk7XG4gIH1cblxuICAvLyBBIHBlcmNlbnQgdGFyZ2V0J3MgYm91bmQsIGluIHRoZSBwZXJjZW50IGl0IGlzIHR5cGVkIGluLiBJdCByZWFkcyB0aGVcbiAgLy8gY29udHJvbCwgd2hpY2ggZnNGb3JtIHZhbGlkYXRlcyBiZWZvcmUgbmdNb2RlbENoYW5nZSB1cGRhdGVzIHRoZSBzaWduYWwuXG4gIHB1YmxpYyB2YWxpZGF0ZVRhcmdldCA9IChjb250cm9sOiBBYnN0cmFjdENvbnRyb2wpOiB2b2lkID0+IHtcbiAgICBjb25zdCB2YWx1ZSA9IHRoaXMuX251bWJlcihjb250cm9sLnZhbHVlKTtcblxuICAgIGlmICh0aGlzLnRhcmdldFBlcmNlbnQoKSAmJiB2YWx1ZSAhPT0gbnVsbCAmJiB2YWx1ZSA+IEtQSV9QRVJDRU5UX1RBUkdFVF9NQVgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQSBwZXJjZW50IHRhcmdldCBjYW4gYmUgYXQgbW9zdCAxMCwwMDAlJyk7XG4gICAgfVxuICB9O1xuXG4gIHB1YmxpYyBzYXZlID0gKCkgPT4ge1xuICAgIGNvbnN0IHNldHRpbmdzOiBDb21wb25lbnRTZXR0aW5ncyA9IHtcbiAgICAgIC8vIFRoZSBzZXJ2ZXIgdHJpbXMgYSB0aXRsZTsgYSB2YWx1ZSdzIE5hbWUgaXMgd2hhdCBpdHMgY2hpcHMgc2hvdywgc28gaXRcbiAgICAgIC8vIGdvZXMgYXMgdGhlIHNlcnZlciBrZWVwcyBpdC5cbiAgICAgIHRpdGxlOiB0aGlzLmlzVmFsdWUoKSA/IHRoaXMudGl0bGUoKS50cmltKCkgOiB0aGlzLnRpdGxlKCksXG4gICAgICBwYWRkaW5nOiB7XG4gICAgICAgIHRvcDogdGhpcy5fcGFkZGluZyh0aGlzLnBhZGRpbmdUb3ApLFxuICAgICAgICByaWdodDogdGhpcy5fcGFkZGluZyh0aGlzLnBhZGRpbmdSaWdodCksXG4gICAgICAgIGJvdHRvbTogdGhpcy5fcGFkZGluZyh0aGlzLnBhZGRpbmdCb3R0b20pLFxuICAgICAgICBsZWZ0OiB0aGlzLl9wYWRkaW5nKHRoaXMucGFkZGluZ0xlZnQpLFxuICAgICAgfSxcbiAgICB9O1xuXG4gICAgLy8gVGhlIGNhcmQga2V5cyBnbyBhcyBjb25maWcga2V5cyBiZXNpZGUgdGhlIHBhZGRpbmcgKGluY3JlYXNlSXMsIHRhcmdldFxuICAgIC8vIGFuZCBzcGFya2xpbmUsIG51bGwgdG8gcmVtb3ZlIG9uZSksIGFuZCBvbmx5IHdoZW4gdGhleSBjaGFuZ2VkLCBzbyBhXG4gICAgLy8gdGl0bGUgZWRpdCBuZXZlciB0b3VjaGVzIHRoZW0uXG4gICAgY29uc3Qga3BpID0gdGhpcy5rcGlDYXJkKCkgPyB0aGlzLl9rcGlDYXJkU2V0dGluZ3MoKSA6IG51bGw7XG4gICAgY29uc3Qga3BpQ2hhbmdlZCA9ICEha3BpXG4gICAgICAmJiAhc2FtZUtwaUNhcmRTZXR0aW5ncyhrcGksIGtwaUNhcmRTZXR0aW5ncyh0aGlzLmNvbXBvbmVudC5jb25maWcgYXMgS3BpQ29uZmlnKSk7XG4gICAgLy8gQSBjaGFydCdzIHRpbWUtYXhpcyBrZXlzIGdvIHRoZSBzYW1lIHdheTogZGF0ZUxhYmVsIGFsd2F5cywgc3BhbiBvbmx5XG4gICAgLy8gd2hlcmUgdGhlIGNoYXJ0IGNhbiB0YWtlIG9uZSwgc28gYSBjaGFydCB3cml0dGVuIGFzIFNRTCBpcyBuZXZlciBzZW50XG4gICAgLy8gYSBrZXkgdGhlIHNlcnZlciByZWZ1c2VzLlxuICAgIGNvbnN0IGF4aXMgPSB0aGlzLnRpbWVBeGlzKCkgPyB0aGlzLl9jaGFydEF4aXNTZXR0aW5ncygpIDogbnVsbDtcbiAgICBjb25zdCBheGlzQ2hhbmdlZCA9ICEhYXhpc1xuICAgICAgJiYgIXNhbWVDaGFydEF4aXNTZXR0aW5ncyhheGlzLCBjaGFydEF4aXNTZXR0aW5ncyh0aGlzLmNvbXBvbmVudC5jb25maWcgYXMgQ2hhcnRDb25maWcpKTtcblxuICAgIHJldHVybiB0aGlzLl9yZXBvcnREYXRhLnVwZGF0ZUNvbXBvbmVudCh0aGlzLnJlcG9ydC5pZCwgdGhpcy5jb21wb25lbnQuaWQsIHtcbiAgICAgIHRpdGxlOiBzZXR0aW5ncy50aXRsZSxcbiAgICAgIC4uLih0aGlzLmlzVmFsdWUoKSA/IHt9IDogeyBwYWRkaW5nOiBzZXR0aW5ncy5wYWRkaW5nIH0pLFxuICAgICAgLi4uKGtwaUNoYW5nZWQgPyBrcGkgOiB7fSksXG4gICAgICAuLi4oYXhpc0NoYW5nZWQgPyB0aGlzLl9zZW50QXhpc0tleXMoYXhpcykgOiB7fSksXG4gICAgfSlcbiAgICAgIC5waXBlKFxuICAgICAgICB0YXAoKHJlc3BvbnNlOiBDb21wb25lbnRTZXR0aW5nc1Jlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgLy8gVGhlIGNhcmQgYW5kIHRoZSBheGlzIGFyZSBkcmF3biBmcm9tIHRoZSBrZXlzIHRoZSBzZXJ2ZXIgc2F2ZWQsXG4gICAgICAgICAgLy8gcmVhZCBiYWNrIGZyb20gdGhlIGNvbmZpZyBpdCByZXR1cm5zLiBBIHNlcnZlciB0aGF0IHJldHVybnMgbm9cbiAgICAgICAgICAvLyBjb25maWcgZGlkIG5vdCBzYXZlIHRoZW0sIHNvIHRoZSBjb21wb25lbnQga2VlcHMgd2hhdCBpdCBoYWQgYW5kXG4gICAgICAgICAgLy8gdGhlIGRpYWxvZyBzYXlzIHNvLlxuICAgICAgICAgIGNvbnN0IHNhdmVkID0ga3BpQ2hhbmdlZCA/IHRoaXMuX3NhdmVkS3BpQ2FyZChyZXNwb25zZSkgOiBudWxsO1xuICAgICAgICAgIGNvbnN0IHNhdmVkQXhpcyA9IGF4aXNDaGFuZ2VkID8gdGhpcy5fc2F2ZWRDaGFydEF4aXMocmVzcG9uc2UpIDogbnVsbDtcblxuICAgICAgICAgIGlmICgoa3BpQ2hhbmdlZCAmJiAhc2F2ZWQpIHx8IChheGlzQ2hhbmdlZCAmJiAhc2F2ZWRBeGlzKSkge1xuICAgICAgICAgICAgdGhpcy5fbWVzc2FnZS53YXJuaW5nKCdDb21wb25lbnQgc2F2ZWQsIGJ1dCB0aGUgc2VydmVyIGRpZCBub3Qgc2F2ZSB0aGUgY2FyZCBvciBheGlzIHNldHRpbmdzJyk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX21lc3NhZ2Uuc3VjY2Vzcyh0aGlzLmlzVmFsdWUoKSA/ICdWYWx1ZSBzYXZlZCcgOiAnQ29tcG9uZW50IHNhdmVkJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdGhpcy5fZGlhbG9nUmVmLmNsb3NlKHtcbiAgICAgICAgICAgIHNldHRpbmdzOiB7XG4gICAgICAgICAgICAgIC4uLnNldHRpbmdzLFxuICAgICAgICAgICAgICAuLi4oc2F2ZWQgPyB7IGtwaTogc2F2ZWQgfSA6IHt9KSxcbiAgICAgICAgICAgICAgLi4uKHNhdmVkQXhpcyA/IHsgY2hhcnRBeGlzOiBzYXZlZEF4aXMgfSA6IHt9KSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pLFxuICAgICAgKTtcbiAgfTtcblxuICAvLyBUaGUgdHlwZSBhIGNvbHVtbidzIGZpbHRlciB3aWxsIGJlIG1hZGUgd2l0aC4gT25seSBhIGNvbHVtbiB3aXRoIG5vXG4gIC8vIGZpbHRlciBvZmZlcnMgdGhlIHBpY2sgKHRoZSBUeXBlIHNlbGVjdCBpcyBsb2NrZWQgb3RoZXJ3aXNlKSwgYW5kIG5vdGhpbmdcbiAgLy8gaXMgc2F2ZWQgdW50aWwgdGhlIGZpbHRlciBpcyBtYWRlLlxuICBwdWJsaWMgc2V0VHlwZShyb3c6IEZpbHRlclJvdywgdHlwZTogUmVwb3J0RmlsdGVyVHlwZSk6IHZvaWQge1xuICAgIHRoaXMuX3BpY2tlZFR5cGVzLnNldChyb3cuY29sdW1uLCB0eXBlKTtcbiAgICB0aGlzLl9wYXRjaFJvdyhyb3csIHsgdHlwZSB9KTtcbiAgfVxuXG4gIC8vIFdoZXJlIHRoZSByb3cncyBmaWx0ZXIgc2hvd3MgaW4gdGhlIHJlcG9ydCBiYXIuIFRoaXMgcGFnZSBvbmx5IHNob3dzIGl0XG4gIC8vIGluIGl0cyBwYWdlJ3MgYmFyIGFsb25lLCBzbyB0aGUgVGhpcyBjb21wb25lbnQgdG9nZ2xlIGdvZXMgb2ZmIGFuZCBsb2Nrcy5cbiAgLy8gQSB2YWx1ZSBoYXMgdGhpcyBzZWxlY3Qgb25seSwgd2l0aCBpdHMgb3duIHJ1bGVzIChfYXBwbHlWYWx1ZUxldmVsKS5cbiAgcHVibGljIHNldFBsYWNlbWVudChyb3c6IEZpbHRlclJvdywgcGxhY2VtZW50OiBGaWx0ZXJCYXJQbGFjZW1lbnQpOiB2b2lkIHtcbiAgICBjb25zdCBwYXRjaGVkID0gdGhpcy5fcGF0Y2hSb3cocm93LCB7XG4gICAgICBwbGFjZW1lbnQsXG4gICAgICBjb21wb25lbnQ6IHBsYWNlbWVudCA9PT0gJ3BhZ2UnID8gZmFsc2UgOiByb3cuY29tcG9uZW50LFxuICAgICAgY29tcG9uZW50VG9nZ2xlOiBjb21wb25lbnRUb2dnbGVTdGF0ZShwbGFjZW1lbnQpLFxuICAgIH0pO1xuXG4gICAgaWYgKHRoaXMuaXNWYWx1ZSgpKSB7XG4gICAgICB0aGlzLl9hcHBseVZhbHVlTGV2ZWwocGF0Y2hlZCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX2FwcGx5TGV2ZWwocGF0Y2hlZCk7XG4gICAgfVxuICB9XG5cbiAgLy8gQSB2YWx1ZSBoYXMgbm8gVGhpcyBjb21wb25lbnQgdG9nZ2xlLlxuICBwdWJsaWMgc2V0Q29tcG9uZW50KHJvdzogRmlsdGVyUm93LCBjb21wb25lbnQ6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBpZiAodGhpcy5pc1ZhbHVlKCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLl9hcHBseUxldmVsKHRoaXMuX3BhdGNoUm93KHJvdywgeyBjb21wb25lbnQgfSkpO1xuICB9XG5cbiAgLy8gUGVyc2lzdCB0aGUgbGV2ZWwgdGhlIHJvdydzIGNvbnRyb2xzIGFzayBmb3IsIHRoZW4gcmVjb25jaWxlIG9uIHJlbG9hZC5cbiAgLy8gTm8gbGV2ZWwg4oaSIG5vIGZpbHRlciAocmVtb3ZlZCk7IG90aGVyd2lzZSB0aGUgZmlsdGVyIGV4aXN0cyBhdCB0aGF0XG4gIC8vIGxldmVsLiBBIHNlcnZlciByZWZ1c2FsIChhIHBhZ2UgZmlsdGVyIHdob3NlIG1lbWJlcnMgc2l0IG9uIHR3byBwYWdlcylcbiAgLy8gc2hvd3MgaXRzIG93biB0ZXh0IGFuZCB0aGUgcm93IHNuYXBzIGJhY2suXG4gIHByaXZhdGUgX2FwcGx5TGV2ZWwocm93OiBGaWx0ZXJSb3cpOiB2b2lkIHtcbiAgICBjb25zdCBsZXZlbCA9IGZpbHRlckxldmVsKHJvdy5wbGFjZW1lbnQsIHJvdy5jb21wb25lbnQpO1xuICAgIGNvbnN0IGV4aXN0aW5nID0gdGhpcy5fZmlsdGVycy5maW5kKChmaWx0ZXIpID0+IGZpbHRlci5maWx0ZXJDb2x1bW4gPT09IHJvdy5jb2x1bW4pO1xuXG4gICAgaWYgKCFsZXZlbCkge1xuICAgICAgaWYgKGV4aXN0aW5nKSB7XG4gICAgICAgIHRoaXMuX3J1bih0aGlzLl9yZXBvcnREYXRhLmRlbGV0ZUZpbHRlcih0aGlzLnJlcG9ydC5pZCwgZXhpc3RpbmcuaWQpKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChleGlzdGluZykge1xuICAgICAgdGhpcy5fcnVuKHRoaXMuX3JlcG9ydERhdGEudXBkYXRlRmlsdGVyR3JvdXAodGhpcy5yZXBvcnQuaWQsIGV4aXN0aW5nLmZpbHRlckdyb3VwSWQsIHsgbGV2ZWwgfSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9hZGRGaWx0ZXIocm93LCBsZXZlbCk7XG4gICAgfVxuICB9XG5cbiAgLy8gQSB2YWx1ZSdzIFJlcG9ydCBiYXIgc2VsZWN0LCB0aGUgb25seSBjb250cm9sIGl0IGhhcy4gSXRzIGZpbHRlcidzIGdyb3VwXG4gIC8vIG1heSBiZSBzaGFyZWQgKHRoZSByZXBvcnQncyBQZXJpb2QsIHNheSksIGFuZCBhIHZhbHVlIGhhcyBubyBzdHJpcCBvZiBpdHNcbiAgLy8gb3duLCBzbyBhIHBpY2sgbmV2ZXIgbG93ZXJzIHRoZSBncm91cCAodmFsdWVGaWx0ZXJMZXZlbCkuIEEgcGljayB0aGF0XG4gIC8vIG1vdmVzIG5vdGhpbmcgcHV0cyB0aGUgcm93IGJhY2sgYXMgdGhlIGdyb3VwIHN0YW5kcy5cbiAgcHJpdmF0ZSBfYXBwbHlWYWx1ZUxldmVsKHJvdzogRmlsdGVyUm93KTogdm9pZCB7XG4gICAgY29uc3QgZXhpc3RpbmcgPSB0aGlzLl9maWx0ZXJzLmZpbmQoKGZpbHRlcikgPT4gZmlsdGVyLmZpbHRlckNvbHVtbiA9PT0gcm93LmNvbHVtbik7XG4gICAgY29uc3QgY3VycmVudCA9IGV4aXN0aW5nID8gdGhpcy5fZ3JvdXBzQnlJZC5nZXQoZXhpc3RpbmcuZmlsdGVyR3JvdXBJZCk/LmxldmVsIDogdW5kZWZpbmVkO1xuICAgIGNvbnN0IGxldmVsID0gdmFsdWVGaWx0ZXJMZXZlbChyb3cucGxhY2VtZW50LCBjdXJyZW50KTtcblxuICAgIGlmICghbGV2ZWwpIHtcbiAgICAgIGlmIChleGlzdGluZykge1xuICAgICAgICB0aGlzLl9ydW4odGhpcy5fcmVwb3J0RGF0YS5kZWxldGVGaWx0ZXIodGhpcy5yZXBvcnQuaWQsIGV4aXN0aW5nLmlkKSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICghZXhpc3RpbmcpIHtcbiAgICAgIHRoaXMuX2FkZEZpbHRlcihyb3csIGxldmVsKTtcbiAgICB9IGVsc2UgaWYgKGxldmVsICE9PSBjdXJyZW50KSB7XG4gICAgICB0aGlzLl9ydW4odGhpcy5fcmVwb3J0RGF0YS51cGRhdGVGaWx0ZXJHcm91cCh0aGlzLnJlcG9ydC5pZCwgZXhpc3RpbmcuZmlsdGVyR3JvdXBJZCwgeyBsZXZlbCB9KSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX3JlYnVpbGRSb3dzKCk7XG4gICAgfVxuICB9XG5cbiAgLy8gVGhlIHR5cGUgZ29lcyBvbmx5IHdoZW4gdGhlIGF1dGhvciBjb3VsZCBwaWNrIGl0OyBvdGhlcndpc2UgdGhlIHNlcnZlclxuICAvLyBpbmZlcnMgaXQsIGFzIGl0IGFsd2F5cyBoYXMuXG4gIHByaXZhdGUgX2FkZEZpbHRlcihyb3c6IEZpbHRlclJvdywgbGV2ZWw6IFJlcG9ydEZpbHRlckxldmVsKTogdm9pZCB7XG4gICAgdGhpcy5fcnVuKHRoaXMuX3JlcG9ydERhdGEuYWRkRmlsdGVyKHRoaXMucmVwb3J0LmlkLCB0aGlzLmNvbXBvbmVudC5pZCwge1xuICAgICAgZmlsdGVyQ29sdW1uOiByb3cuY29sdW1uLFxuICAgICAgbGFiZWw6IHJvdy5sYWJlbCxcbiAgICAgIGxldmVsLFxuICAgICAgLi4uKHJvdy50eXBlU2VsZWN0LnNob3cgPyB7IHR5cGU6IHJvdy50eXBlIH0gOiB7fSksXG4gICAgfSkpO1xuICB9XG5cbiAgLy8gQSBuZXcgcm93IG9iamVjdCByYXRoZXIgdGhhbiBhIG11dGF0aW9uLCBzbyB0aGUgc2lnbmFsIHNlZXMgdGhlIGNoYW5nZTtcbiAgLy8gdGhlIEBmb3IgdHJhY2tzIHRoZSBjb2x1bW4sIHNvIHRoZSByb3cncyBjb250cm9scyBzdXJ2aXZlIHRoZSBzd2FwLlxuICBwcml2YXRlIF9wYXRjaFJvdyhyb3c6IEZpbHRlclJvdywgcGF0Y2g6IFBhcnRpYWw8RmlsdGVyUm93Pik6IEZpbHRlclJvdyB7XG4gICAgY29uc3QgcGF0Y2hlZCA9IHsgLi4ucm93LCAuLi5wYXRjaCB9O1xuICAgIHRoaXMucm93cy51cGRhdGUoKHJvd3MpID0+IHJvd3MubWFwKChpdGVtKSA9PiAoaXRlbS5jb2x1bW4gPT09IHJvdy5jb2x1bW4gPyBwYXRjaGVkIDogaXRlbSkpKTtcblxuICAgIHJldHVybiBwYXRjaGVkO1xuICB9XG5cbiAgLy8gVGhlIHN0b3JlZCB0aXRsZSBhcyBpdCByZWFkcyB3aGVyZSB0aGUgY29tcG9uZW50IGlzIGRyYXduLCBpdHMgdG9rZW5zXG4gIC8vIGZpbGxlZDsgYSB2YWx1ZSdzIE5hbWUgYXMgaXQgaXMuXG4gIHByaXZhdGUgX3Nob3duVGl0bGUoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5pc1ZhbHVlKCkgPyB0aGlzLmNvbXBvbmVudC50aXRsZSA/PyAnJyA6IGZpbGxUaXRsZVRva2Vucyh0aGlzLmNvbXBvbmVudC50aXRsZSwgdGhpcy5fZGF0YS50b2tlbnMpO1xuICB9XG5cbiAgLy8gV2hhdCBhIGZvcm11bGEgd29ya3Mgb3V0LCBuYW1pbmcgZWFjaCBvcGVyYW5kIGFzIGl0cyBjaGlwcyBkby4gQW4gb3AgdGhpc1xuICAvLyB2aWV3ZXIgZG9lcyBub3Qga25vdyByZWFkcyBub3RoaW5nLlxuICBwcml2YXRlIF9mb3JtdWxhTGluZSgpOiBzdHJpbmcge1xuICAgIGNvbnN0IGZvcm11bGEgPSB0aGlzLmNvbXBvbmVudC5jb25maWc/LmZvcm11bGE7XG4gICAgY29uc3QgbGluZSA9IGZvcm11bGEgPyBGT1JNVUxBX0xJTkVTW2Zvcm11bGEub3BdIDogdW5kZWZpbmVkO1xuICAgIGNvbnN0IHZhbHVlcyA9IHRoaXMuX2xheWVyVmFsdWVzKCk7XG5cbiAgICByZXR1cm4gbGluZSA/IGxpbmUob3BlcmFuZEtleXModGhpcy5jb21wb25lbnQpLm1hcCgoa2V5KSA9PiB0aGlzLl92YWx1ZU5hbWUodmFsdWVzLCBrZXkpKSkgOiAnJztcbiAgfVxuXG4gIC8vIFRoZSBzZW50ZW5jZSBhIHF1ZXJ5IHZhbHVlJ3MgZGVsZXRlIGNvbmZpcm0gZW5kcyB3aXRoIHdoZW4gZm9ybXVsYXMgb24gaXRzXG4gIC8vIGxheWVyIHJlYWQgaXQ6IHRoZSBzZXJ2ZXIgZGVsZXRlcyB0aG9zZSB3aXRoIGl0LiBFbXB0eSB3aGVuIG5vbmUgZG9lcywgYW5kXG4gIC8vIGZvciBhIGZvcm11bGEsIHdob3NlIG9wZXJhbmRzIHN0YXkuXG4gIHByaXZhdGUgX2RlcGVuZGVudHNOb3RlKCk6IHN0cmluZyB7XG4gICAgaWYgKHRoaXMuaXNGb3JtdWxhKCkpIHtcbiAgICAgIHJldHVybiAnJztcbiAgICB9XG5cbiAgICBjb25zdCBrZXkgPSB2YWx1ZUtleSh0aGlzLmNvbXBvbmVudCk7XG4gICAgY29uc3QgbmFtZXMgPSB0aGlzLl9sYXllclZhbHVlcygpXG4gICAgICAuZmlsdGVyKCh2YWx1ZSkgPT4gb3BlcmFuZEtleXModmFsdWUpLmluY2x1ZGVzKGtleSkpXG4gICAgICAubWFwKCh2YWx1ZSkgPT4gZXNjYXBlSHRtbCh2YWx1ZS50aXRsZSB8fCB2YWx1ZUtleSh2YWx1ZSkpKTtcblxuICAgIHJldHVybiBuYW1lcy5sZW5ndGggPyBgIFRoZSB2YWx1ZXMgd29ya2VkIG91dCBmcm9tIGl0IGFyZSBkZWxldGVkIHRvbzogJHtuYW1lcy5qb2luKCcsICcpfS5gIDogJyc7XG4gIH1cblxuICAvLyBUaGUgdmFsdWVzIG9mIHRoZSBsYXllciB0aGlzIHZhbHVlIGJlbG9uZ3MgdG86IHRoZSBwYWdlIHdob3NlIHZhbHVlcyBob2xkXG4gIC8vIGl0LCBlbHNlIHRoZSBtYXN0ZXIncyAoYSBoZWFkZXIgb3IgZm9vdGVyIHZhbHVlKS5cbiAgcHJpdmF0ZSBfbGF5ZXJWYWx1ZXMoKTogUmVwb3J0Q29tcG9uZW50W10ge1xuICAgIGNvbnN0IHBhZ2UgPSAodGhpcy5yZXBvcnQucGFnZXMgPz8gW10pXG4gICAgICAuZmluZCgoY2FuZGlkYXRlKSA9PiAoY2FuZGlkYXRlLnZhbHVlcyA/PyBbXSkuc29tZSgodmFsdWUpID0+IHZhbHVlLmlkID09PSB0aGlzLmNvbXBvbmVudC5pZCkpO1xuXG4gICAgcmV0dXJuIChwYWdlID8/IHRoaXMucmVwb3J0Lm1hc3Rlcik/LnZhbHVlcyA/PyBbXTtcbiAgfVxuXG4gIC8vIFdoYXQgYSB2YWx1ZSBpcyBjYWxsZWQgd2hlcmUgaXRzIGNoaXBzIHNob3cgaXQ6IGl0cyBuYW1lLCBlbHNlIGl0cyBrZXkuXG4gIC8vIFRoZSBuZXdlc3QgdmFsdWUgaG9sZHMgYSBrZXksIGFzIGl0IGRvZXMgaW4gdGhlIHRleHQncyB0b2tlbnMuXG4gIHByaXZhdGUgX3ZhbHVlTmFtZSh2YWx1ZXM6IFJlcG9ydENvbXBvbmVudFtdLCBrZXk6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3QgdmFsdWUgPSB2YWx1ZXMuZmlsdGVyKChjYW5kaWRhdGUpID0+IHZhbHVlS2V5KGNhbmRpZGF0ZSkgPT09IGtleSkucG9wKCk7XG5cbiAgICByZXR1cm4gdmFsdWU/LnRpdGxlIHx8IGtleTtcbiAgfVxuXG4gIC8vIEEgZGVyaXZlZCBLUEkncyBjYXJkIGtleXMsIGZyb20gaXRzIGNvbmZpZy4gQSBzcWwtbW9kZSBLUEkgY2Fubm90IGNhcnJ5XG4gIC8vIHRoZW0sIHNvIGl0IGdldHMgbm8gY2FyZCBmaWVsZHMuXG4gIHByaXZhdGUgX3NlZWRLcGlDYXJkKCk6IHZvaWQge1xuICAgIGNvbnN0IGNvbmZpZyA9ICh0aGlzLmNvbXBvbmVudC5jb25maWcgPz8ge30pIGFzIEtwaUNvbmZpZztcblxuICAgIHRoaXMua3BpQ2FyZC5zZXQodGhpcy5jb21wb25lbnQudHlwZSA9PT0gJ2twaScgJiYgIXRoaXMuY29tcG9uZW50LnNxbCk7XG4gICAgdGhpcy5pbmNyZWFzZUlzLnNldChjb25maWcuaW5jcmVhc2VJcyA/PyBSZXBvcnRDaGFuZ2VQb2xhcml0eS5Hb29kKTtcbiAgICB0aGlzLnRhcmdldFBlcmNlbnQuc2V0KGNvbmZpZy5tZWFzdXJlPy5mb3JtYXQgPT09IFJlcG9ydFZhbHVlRm9ybWF0LlBlcmNlbnRcbiAgICAgICYmIHJlc29sdmVGb3JtYXRDb250ZXh0KHRoaXMucmVwb3J0KS5yYXRpb1BlcmNlbnQpO1xuICAgIHRoaXMudGFyZ2V0VmFsdWUuc2V0KHRoaXMuX3RhcmdldFNob3duKGNvbmZpZy50YXJnZXQ/LnZhbHVlID8/IG51bGwpKTtcbiAgICB0aGlzLnRhcmdldExhYmVsLnNldChjb25maWcudGFyZ2V0Py5sYWJlbCA/PyAnJyk7XG4gICAgdGhpcy5zcGFya2xpbmUuc2V0KCEhY29uZmlnLnNwYXJrbGluZSk7XG4gICAgdGhpcy5zcGFya2xpbmVHcmFudWxhcml0eS5zZXQoY29uZmlnLnNwYXJrbGluZT8uZ3JhbnVsYXJpdHkgPz8gS1BJX1NQQVJLTElORV9ERUZBVUxUX0dSQU5VTEFSSVRZKTtcbiAgICB0aGlzLnNwYXJrbGluZVBlcmlvZHMuc2V0KGNvbmZpZy5zcGFya2xpbmU/LnBlcmlvZHMgPz8gS1BJX1NQQVJLTElORV9ERUZBVUxUX1BFUklPRFMpO1xuICB9XG5cbiAgLy8gQSBjaGFydCBvdmVyIHRpbWUncyBheGlzIGtleXMsIGZyb20gaXRzIGNvbmZpZy4gT25seSBhIGRlcml2ZWQgY2hhcnRcbiAgLy8gdGFrZXMgYSBzcGFuOyBhIGNoYXJ0IHdpdGggbm9uZSByZWFkcyB0aGUgZGF0ZSBmaWx0ZXIncyByYW5nZS5cbiAgcHJpdmF0ZSBfc2VlZFRpbWVBeGlzKCk6IHZvaWQge1xuICAgIGNvbnN0IGNvbmZpZyA9ICh0aGlzLmNvbXBvbmVudC5jb25maWcgPz8ge30pIGFzIENoYXJ0Q29uZmlnO1xuICAgIGNvbnN0IHNwYW4gPSBjb25maWcueEF4aXM/LnNwYW47XG5cbiAgICB0aGlzLnRpbWVBeGlzLnNldCh0aGlzLmNvbXBvbmVudC50eXBlID09PSAnY2hhcnQnICYmIGNvbmZpZy54QXhpcz8ua2luZCA9PT0gJ3RpbWUnKTtcbiAgICB0aGlzLnNwYW5BbGxvd2VkLnNldCh0aGlzLnRpbWVBeGlzKCkgJiYgIXRoaXMuY29tcG9uZW50LnNxbCk7XG4gICAgdGhpcy5kYXRlTGFiZWwuc2V0KGNvbmZpZy54QXhpcz8uZGF0ZUxhYmVsID8/IFJlcG9ydENoYXJ0RGF0ZUxhYmVsLlNob3J0KTtcbiAgICB0aGlzLnNwYW5Nb2RlLnNldChzcGFuPy5zdGFydFxuICAgICAgPyBSZXBvcnRDaGFydFNwYW5Nb2RlLlN0YXJ0XG4gICAgICA6IChzcGFuPy5wZXJpb2RzID8gUmVwb3J0Q2hhcnRTcGFuTW9kZS5QZXJpb2RzIDogUmVwb3J0Q2hhcnRTcGFuTW9kZS5Ob25lKSk7XG4gICAgdGhpcy5zcGFuUGVyaW9kcy5zZXQoc3Bhbj8ucGVyaW9kcyA/PyBDSEFSVF9TUEFOX0RFRkFVTFRfUEVSSU9EUyk7XG4gICAgdGhpcy5zcGFuU3RhcnQuc2V0KGRhdGVGcm9tQm91bmQoc3Bhbj8uc3RhcnQpKTtcbiAgfVxuXG4gIC8vIFNob3J0IGlzIHdoYXQgYW4gYWJzZW50IGRhdGVMYWJlbCByZWFkcywgc28gaXQgaXMgc2F2ZWQgYXMgYWJzZW50LiBBXG4gIC8vIGNoYXJ0IHRoYXQgY2Fubm90IHRha2UgYSBzcGFuIGtlZXBzIHRoZSBvbmUgaXQgaGFzIChub25lKS5cbiAgcHJpdmF0ZSBfY2hhcnRBeGlzU2V0dGluZ3MoKTogUmVwb3J0Q2hhcnRBeGlzU2V0dGluZ3Mge1xuICAgIHJldHVybiB7XG4gICAgICBkYXRlTGFiZWw6IHRoaXMuZGF0ZUxhYmVsKCkgPT09IFJlcG9ydENoYXJ0RGF0ZUxhYmVsLlNob3J0ID8gbnVsbCA6IHRoaXMuZGF0ZUxhYmVsKCksXG4gICAgICBzcGFuOiB0aGlzLnNwYW5BbGxvd2VkKCkgPyB0aGlzLl9zcGFuKCkgOiBjaGFydEF4aXNTZXR0aW5ncyh0aGlzLmNvbXBvbmVudC5jb25maWcgYXMgQ2hhcnRDb25maWcpLnNwYW4sXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgX3NwYW4oKTogUmVwb3J0Q2hhcnRTcGFuIHwgbnVsbCB7XG4gICAgY29uc3QgdGhyb3VnaCA9IFJlcG9ydENoYXJ0U3BhblRocm91Z2guRmlsdGVyRW5kO1xuXG4gICAgc3dpdGNoICh0aGlzLnNwYW5Nb2RlKCkpIHtcbiAgICAgIGNhc2UgUmVwb3J0Q2hhcnRTcGFuTW9kZS5QZXJpb2RzOlxuICAgICAgICByZXR1cm4geyB0aHJvdWdoLCBwZXJpb2RzOiB0aGlzLl9udW1iZXIodGhpcy5zcGFuUGVyaW9kcygpKSA/PyBDSEFSVF9TUEFOX0RFRkFVTFRfUEVSSU9EUyB9O1xuICAgICAgY2FzZSBSZXBvcnRDaGFydFNwYW5Nb2RlLlN0YXJ0OiB7XG4gICAgICAgIGNvbnN0IHN0YXJ0ID0gZGF0ZVRvQm91bmQodGhpcy5zcGFuU3RhcnQoKSk7XG5cbiAgICAgICAgcmV0dXJuIHN0YXJ0ID8geyB0aHJvdWdoLCBzdGFydCB9IDogbnVsbDtcbiAgICAgIH1cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuXG4gIC8vIFRoZSBheGlzIGtleXMgYXMgdGhlIHNldHRpbmdzIHJvdXRlIHRha2VzIHRoZW06IHRoZSBzcGFuIG9ubHkgZnJvbSBhXG4gIC8vIGNoYXJ0IHRoYXQgY2FuIHRha2Ugb25lLlxuICBwcml2YXRlIF9zZW50QXhpc0tleXMoYXhpczogUmVwb3J0Q2hhcnRBeGlzU2V0dGluZ3MpOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB7XG4gICAgcmV0dXJuIHRoaXMuc3BhbkFsbG93ZWQoKSA/IHsgLi4uYXhpcyB9IDogeyBkYXRlTGFiZWw6IGF4aXMuZGF0ZUxhYmVsIH07XG4gIH1cblxuICAvLyBUaGUgYXhpcyBrZXlzIHRoZSBzZXJ2ZXIgc2F2ZWQsIGZyb20gdGhlIGNvbmZpZyBpdHMgcmVzcG9uc2UgY2FycmllcztcbiAgLy8gbnVsbCB3aGVuIGl0IGNhcnJpZXMgbm9uZS5cbiAgcHJpdmF0ZSBfc2F2ZWRDaGFydEF4aXMocmVzcG9uc2U6IENvbXBvbmVudFNldHRpbmdzUmVzcG9uc2UgfCBudWxsIHwgdW5kZWZpbmVkKTogUmVwb3J0Q2hhcnRBeGlzU2V0dGluZ3MgfCBudWxsIHtcbiAgICBjb25zdCBjb25maWcgPSByZXNwb25zZT8uY29uZmlnO1xuXG4gICAgcmV0dXJuIGNvbmZpZyAmJiB0eXBlb2YgY29uZmlnID09PSAnb2JqZWN0JyA/IGNoYXJ0QXhpc1NldHRpbmdzKGNvbmZpZyBhcyBDaGFydENvbmZpZykgOiBudWxsO1xuICB9XG5cbiAgLy8gVGhlIGNhcmQga2V5cyB0aGUgc2VydmVyIHNhdmVkLCBmcm9tIHRoZSBjb25maWcgaXRzIHJlc3BvbnNlIGNhcnJpZXM7XG4gIC8vIG51bGwgd2hlbiBpdCBjYXJyaWVzIG5vbmUgKGEgc2VydmVyIHRoYXQgZG9lcyBub3Qgc2F2ZSB0aGVtKS5cbiAgcHJpdmF0ZSBfc2F2ZWRLcGlDYXJkKHJlc3BvbnNlOiBDb21wb25lbnRTZXR0aW5nc1Jlc3BvbnNlIHwgbnVsbCB8IHVuZGVmaW5lZCk6IEtwaUNhcmRTZXR0aW5ncyB8IG51bGwge1xuICAgIGNvbnN0IGNvbmZpZyA9IHJlc3BvbnNlPy5jb25maWc7XG5cbiAgICByZXR1cm4gY29uZmlnICYmIHR5cGVvZiBjb25maWcgPT09ICdvYmplY3QnID8ga3BpQ2FyZFNldHRpbmdzKGNvbmZpZyBhcyBLcGlDb25maWcpIDogbnVsbDtcbiAgfVxuXG4gIC8vIEdvb2QgaXMgd2hhdCBhbiBhYnNlbnQgaW5jcmVhc2VJcyByZWFkcywgc28gaXQgaXMgc2F2ZWQgYXMgYWJzZW50LlxuICBwcml2YXRlIF9rcGlDYXJkU2V0dGluZ3MoKTogS3BpQ2FyZFNldHRpbmdzIHtcbiAgICBjb25zdCB0YXJnZXQgPSB0aGlzLl9udW1iZXIodGhpcy50YXJnZXRWYWx1ZSgpKTtcbiAgICBjb25zdCBsYWJlbCA9IHRoaXMudGFyZ2V0TGFiZWwoKS50cmltKCk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgaW5jcmVhc2VJczogdGhpcy5pbmNyZWFzZUlzKCkgPT09IFJlcG9ydENoYW5nZVBvbGFyaXR5Lkdvb2QgPyBudWxsIDogdGhpcy5pbmNyZWFzZUlzKCksXG4gICAgICB0YXJnZXQ6IHRhcmdldCA9PT0gbnVsbCA/IG51bGwgOiB7IHZhbHVlOiB0aGlzLl90YXJnZXRTdG9yZWQodGFyZ2V0KSwgbGFiZWw6IGxhYmVsIHx8IG51bGwgfSxcbiAgICAgIHNwYXJrbGluZTogdGhpcy5zcGFya2xpbmUoKVxuICAgICAgICA/IHsgZ3JhbnVsYXJpdHk6IHRoaXMuc3BhcmtsaW5lR3JhbnVsYXJpdHkoKSwgcGVyaW9kczogdGhpcy5fbnVtYmVyKHRoaXMuc3BhcmtsaW5lUGVyaW9kcygpKSB9XG4gICAgICAgIDogbnVsbCxcbiAgICB9O1xuICB9XG5cbiAgLy8gQSBzdG9yZWQgcmF0aW8gYXMgdGhlIHBlcmNlbnQgdHlwZWQsIHJvdW5kZWQgc28gMC4xNSByZWFkcyAxNSBhbmQgbm90XG4gIC8vIDE1LjAwMDAwMDAwMDAwMDAwMi5cbiAgcHJpdmF0ZSBfdGFyZ2V0U2hvd24odmFsdWU6IG51bWJlciB8IG51bGwpOiBudW1iZXIgfCBudWxsIHtcbiAgICBpZiAodmFsdWUgPT09IG51bGwgfHwgIXRoaXMudGFyZ2V0UGVyY2VudCgpKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIE1hdGgucm91bmQodmFsdWUgKiAxMDAgKiAxZTYpIC8gMWU2O1xuICB9XG5cbiAgcHJpdmF0ZSBfdGFyZ2V0U3RvcmVkKHZhbHVlOiBudW1iZXIpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLnRhcmdldFBlcmNlbnQoKSA/IHZhbHVlIC8gMTAwIDogdmFsdWU7XG4gIH1cblxuICAvLyBBIHR5cGVkIG51bWJlciwgb3IgbnVsbCB3aGVuIHRoZSBmaWVsZCBpcyBlbXB0eS5cbiAgcHJpdmF0ZSBfbnVtYmVyKHZhbHVlOiBudW1iZXIgfCBzdHJpbmcgfCBudWxsKTogbnVtYmVyIHwgbnVsbCB7XG4gICAgaWYgKHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSAnJykge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgY29uc3QgbnVtYmVyID0gdHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJyA/IHZhbHVlIDogcGFyc2VGbG9hdCh2YWx1ZSk7XG5cbiAgICByZXR1cm4gTnVtYmVyLmlzRmluaXRlKG51bWJlcikgPyBudW1iZXIgOiBudWxsO1xuICB9XG5cbiAgLy8gVGhlIHBhZGRpbmcgYXMgYSByZWFsIG51bWJlciBmb3IgdGhlIHdpcmUuIGZzTWFza051bWJlciBoYW5kcyBiYWNrIHRoZVxuICAvLyB1bm1hc2tlZCBzdHJpbmcgaXQgYnVpbHQgd2l0aCBhIGZpeGVkICcuJyByYWRpeCwgc28gdGhpcyBpcyBhIHN0cmFpZ2h0XG4gIC8vIHBhcnNlIC0gdGhlIHdob2xlIHJlYXNvbiBmb3IgdGhlIG1hc2sgaXMgdGhhdCBhIG5hdGl2ZSBudW1iZXIgaW5wdXQgd291bGRcbiAgLy8gcGFpbnQgKGFuZCByZWFkIGJhY2spIHRoZSB2aWV3ZXIncyBvd24gbG9jYWxlIHNlcGFyYXRvciBpbnN0ZWFkLlxuICBwcml2YXRlIF9wYWRkaW5nKHZhbHVlOiBudW1iZXIgfCBzdHJpbmcpOiBudW1iZXIge1xuICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInID8gdmFsdWUgOiBwYXJzZUZsb2F0KHZhbHVlKTtcbiAgfVxuXG4gIC8vIFJ1biBhIGZpbHRlciBtdXRhdGlvbiwgdGhlbiByZWxvYWQgdG8gcmVjb25jaWxlIHRoZSBvcHRpbWlzdGljIHN0YXRlLlxuICBwcml2YXRlIF9ydW4ocmVxdWVzdDogT2JzZXJ2YWJsZTx1bmtub3duPik6IHZvaWQge1xuICAgIHJlcXVlc3Quc3Vic2NyaWJlKHtcbiAgICAgIG5leHQ6ICgpID0+IHRoaXMuX2FmdGVyTXV0YXRpb24oKSxcbiAgICAgIGVycm9yOiAoZXJyb3IpID0+IHRoaXMuX211dGF0aW9uRXJyb3IoZXJyb3IpLFxuICAgIH0pO1xuICB9XG5cbiAgLy8gQnVpbGQgdGhlIHJvdyB2aWV3LW1vZGVsIGZyb20gdGhlIGxvYWRlZCBjb2x1bW5zICsgZmlsdGVycy9ncm91cHMuIEVhY2hcbiAgLy8gcm93J3MgY29udHJvbHMgcmVmbGVjdCB3aGVyZSBpdHMgZmlsdGVyIGdyb3VwIGN1cnJlbnRseSBzaG93czsgYSBjb2x1bW5cbiAgLy8gd2l0aCBhIGZpbHRlciBzaG93cyB0aGUgZmlsdGVyJ3Mgb3duIHR5cGUuIEEgdmFsdWUncyByb3dzIG5ldmVyIHJlYWQgYXNcbiAgLy8gb24gYSBjb21wb25lbnQ6IGl0IGhhcyBubyBzdHJpcCwgd2hhdGV2ZXIgbGV2ZWwgYSBncm91cCBpdCBzaGFyZXMgaXMgYXQsXG4gIC8vIGFuZCBpdHMgUmVwb3J0IGJhciBzZWxlY3Qgb2ZmZXJzIG5vIHBpY2sgdGhhdCBsb3dlcnMgdGhhdCBncm91cC5cbiAgcHJpdmF0ZSBfcmVidWlsZFJvd3MoKTogdm9pZCB7XG4gICAgY29uc3QgbGV2ZWxDaG9pY2VzID0gZmlsdGVyTGV2ZWxDaG9pY2VzKHRoaXMucmVwb3J0LnZpZXdlckZlYXR1cmVzLCB0aGlzLl9vblBhZ2UoKSk7XG5cbiAgICB0aGlzLnJvd3Muc2V0KHRoaXMuX2ZpbHRlcmFibGVDb2x1bW5zLm1hcCgoY29sdW1uKSA9PiB7XG4gICAgICBjb25zdCBmaWx0ZXIgPSB0aGlzLl9maWx0ZXJzLmZpbmQoKGNhbmRpZGF0ZSkgPT4gY2FuZGlkYXRlLmZpbHRlckNvbHVtbiA9PT0gY29sdW1uLmNvbHVtbik7XG4gICAgICBjb25zdCBncm91cCA9IGZpbHRlciA/IHRoaXMuX2dyb3Vwc0J5SWQuZ2V0KGZpbHRlci5maWx0ZXJHcm91cElkKSA6IHVuZGVmaW5lZDtcbiAgICAgIGNvbnN0IHBsYWNlbWVudCA9IGJhclBsYWNlbWVudChncm91cD8ubGV2ZWwpO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb2x1bW46IGNvbHVtbi5jb2x1bW4sXG4gICAgICAgIHR5cGU6IGdyb3VwPy50eXBlXG4gICAgICAgICAgPz8gdGhpcy5fcGlja2VkVHlwZXMuZ2V0KGNvbHVtbi5jb2x1bW4pXG4gICAgICAgICAgPz8gY29sdW1uLnR5cGVzPy5bMF1cbiAgICAgICAgICA/PyBjb2x1bW4udHlwZSxcbiAgICAgICAgbGFiZWw6IGZpbHRlcj8ubGFiZWxcbiAgICAgICAgICB8fCB0aGlzLl9ncm91cHNCeUlkLmdldChmaWx0ZXI/LmZpbHRlckdyb3VwSWQgPz8gLTEpPy5sYWJlbFxuICAgICAgICAgIHx8IHRoaXMuX2h1bWFuaXplKGNvbHVtbi5jb2x1bW4pLFxuICAgICAgICBwbGFjZW1lbnQsXG4gICAgICAgIGNvbXBvbmVudDogIXRoaXMuaXNWYWx1ZSgpICYmIHNob3duT25Db21wb25lbnQoZ3JvdXA/LmxldmVsKSxcbiAgICAgICAgdHlwZVNlbGVjdDogdHlwZVNlbGVjdFN0YXRlKGNvbHVtbi50eXBlcywgISFmaWx0ZXIsIHRoaXMucmVwb3J0LnZpZXdlckZlYXR1cmVzKSxcbiAgICAgICAgcGxhY2VtZW50T3B0aW9uczogdGhpcy5pc1ZhbHVlKClcbiAgICAgICAgICA/IHZhbHVlUGxhY2VtZW50T3B0aW9ucyhsZXZlbENob2ljZXMsIGdyb3VwPy5sZXZlbClcbiAgICAgICAgICA6IGJhclBsYWNlbWVudE9wdGlvbnMobGV2ZWxDaG9pY2VzLCBwbGFjZW1lbnQpLFxuICAgICAgICBjb21wb25lbnRUb2dnbGU6IGNvbXBvbmVudFRvZ2dsZVN0YXRlKHBsYWNlbWVudCksXG4gICAgICB9O1xuICAgIH0pKTtcbiAgfVxuXG4gIC8vIFdoZXRoZXIgdGhlIGNvbXBvbmVudCBzaXRzIG9uIGEgcGFnZTogYW1vbmcgaXRzIGNvbXBvbmVudHMsIG9yLCBmb3IgYVxuICAvLyB2YWx1ZSwgaXRzIHZhbHVlcy4gQSBoZWFkZXIgb3IgZm9vdGVyIGNvbXBvbmVudCBvciB2YWx1ZSBzaXRzIG9uIG5vbmUsXG4gIC8vIHNvIGl0cyBmaWx0ZXJzIGNhbm5vdCBiZSBwYWdlIGZpbHRlcnMuXG4gIHByaXZhdGUgX29uUGFnZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gKHRoaXMucmVwb3J0LnBhZ2VzID8/IFtdKVxuICAgICAgLnNvbWUoKHBhZ2UpID0+IFsuLi4ocGFnZS5jb21wb25lbnRzID8/IFtdKSwgLi4uKHBhZ2UudmFsdWVzID8/IFtdKV1cbiAgICAgICAgLnNvbWUoKGNhbmRpZGF0ZSkgPT4gY2FuZGlkYXRlLmlkID09PSB0aGlzLmNvbXBvbmVudC5pZCkpO1xuICB9XG5cbiAgLy8gQWZ0ZXIgYW55IGZpbHRlciBtdXRhdGlvbjogcmUtZmV0Y2ggdGhlIHJlcG9ydCBzbyB0aGUgZGlhbG9nJ3MgZmlsdGVyIGxpc3RcbiAgLy8gKGFuZCB0aGUgcGFyZW50IGNhbnZhcywgb24gY2xvc2UpIHJlZmxlY3QgdGhlIG5ldyBncm91cHMvbGV2ZWxzLlxuICBwcml2YXRlIF9hZnRlck11dGF0aW9uKCk6IHZvaWQge1xuICAgIHRoaXMuZmlsdGVyc0NoYW5nZWQuZW1pdCgpO1xuXG4gICAgdGhpcy5fcmVwb3J0RGF0YS5nZXQodGhpcy5yZXBvcnQuaWQpXG4gICAgICAuc3Vic2NyaWJlKChyZXBvcnQ6IFJlcG9ydCkgPT4ge1xuICAgICAgICB0aGlzLnJlcG9ydCA9IHJlcG9ydDtcbiAgICAgICAgdGhpcy5fc2VlZEZpbHRlcnMocmVwb3J0LCB0aGlzLmNvbXBvbmVudC5pZCk7XG4gICAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgX211dGF0aW9uRXJyb3IoZXJyb3I6IGFueSk6IHZvaWQge1xuICAgIHRoaXMuX21lc3NhZ2UuZXJyb3IoZXJyb3I/LmVycm9yPy5tZXNzYWdlID8/IGVycm9yPy5tZXNzYWdlID8/ICdGaWx0ZXIgb3BlcmF0aW9uIGZhaWxlZCcpO1xuICAgIC8vIFJlLXNlZWQgZnJvbSB0aGUgc2VydmVyIHNvIHRoZSBvcHRpbWlzdGljIHRvZ2dsZSBzbmFwcyBiYWNrIHRvIHRydXRoLlxuICAgIHRoaXMuX2FmdGVyTXV0YXRpb24oKTtcbiAgfVxuXG4gIC8vIFRoZSBjb21wb25lbnQncyBmaWx0ZXJzIGFuZCB0aGUgZ3JvdXBzIHRoZXkgc2l0IGluLCBmcm9tIHRoZSByZXBvcnQgYXNcbiAgLy8gbGFzdCBsb2FkZWQuIEEgdmFsdWUgaXMgbGlzdGVkIGluIGl0cyBwYWdlJ3MgdmFsdWVzLCBub3QgaXRzIGNvbXBvbmVudHMuXG4gIHByaXZhdGUgX3NlZWRGaWx0ZXJzKHJlcG9ydDogUmVwb3J0LCBjb21wb25lbnRJZDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5fZ3JvdXBzQnlJZCA9IG5ldyBNYXAoKHJlcG9ydC5maWx0ZXJHcm91cHMgPz8gW10pLm1hcCgoZ3JvdXApID0+IFtncm91cC5pZCwgZ3JvdXBdKSk7XG5cbiAgICBjb25zdCBjb21wb25lbnQgPSByZXBvcnRDb21wb25lbnRzKHJlcG9ydClcbiAgICAgIC5maW5kKChjYW5kaWRhdGUpID0+IGNhbmRpZGF0ZS5pZCA9PT0gY29tcG9uZW50SWQpO1xuXG4gICAgdGhpcy5fZmlsdGVycyA9IGNvbXBvbmVudD8uZmlsdGVycyA/PyBbXTtcbiAgICB0aGlzLl9yZWJ1aWxkUm93cygpO1xuICB9XG5cbiAgLy8gVGhlIHN0YXRlbWVudCB0aGUgU1FMIHRhYiBzaG93cy4gRmV0Y2hlZCByYXRoZXIgdGhhbiByZWFkIG9mZiB0aGVcbiAgLy8gY29tcG9uZW50OiBhIGRlcml2ZWQgY29tcG9uZW50IHN0b3JlcyBhIGRvY3VtZW50LCBub3QgU1FMLCBzbyBpdHNcbiAgLy8gc3RhdGVtZW50IG9ubHkgZXhpc3RzIG9uY2UgdGhlIGJhY2tlbmQgY29tcGlsZXMgaXQuXG4gIC8vXG4gIC8vIExvYWRlZCBpbiBuZ09uSW5pdCBiZXNpZGUgdGhlIGNvbHVtbnMsIE5PVCBvbiB0YWIgYWN0aXZhdGlvbi4gVGhlIHRhYnMgYXJlXG4gIC8vIG5vdCBsYXp5IChubyBtYXRUYWJDb250ZW50KSwgYW5kIHN3aXRjaGluZyB0aGUgdGFiLWdyb3VwJ3MgYFsoc2VsZWN0ZWQpXWBcbiAgLy8gYmFuYW5hLWJveCB0byBhIG9uZS13YXkgYmluZGluZyBwbHVzIChzZWxlY3RlZENoYW5nZSkgdG8gZ2V0IGEgaG9vayB3b3VsZFxuICAvLyBicmVhayBpdDogRnNUYWJzSGVhZGVyVGFiR3JvdXBEaXJlY3RpdmUgc2VsZi1hc3NpZ25zIGB0aGlzLnNlbGVjdGVkYCBiZWZvcmVcbiAgLy8gaXQgZW1pdHMsIHNvIHRoZSBldmVudCBpcyBmaWx0ZXJlZCBvdXQgYW5kIHRoZSBsb2FkIHdvdWxkIG5ldmVyIGZpcmUuIE9uZVxuICAvLyBzbWFsbCByZXF1ZXN0IHdoZW4gYSBkaWFsb2cgb3BlbnMgaXMgbm90IHdvcnRoIHRoYXQgcmlzay5cbiAgcHJpdmF0ZSBfbG9hZFNxbCgpOiB2b2lkIHtcbiAgICB0aGlzLl9yZXBvcnREYXRhLmNvbXBvbmVudFNxbCh0aGlzLnJlcG9ydC5pZCwgdGhpcy5jb21wb25lbnQuaWQpXG4gICAgICAuc3Vic2NyaWJlKHtcbiAgICAgICAgbmV4dDogKHByZXZpZXc6IFJlcG9ydENvbXBvbmVudFNxbCkgPT4ge1xuICAgICAgICAgIHRoaXMuc3FsLnNldChwcmV2aWV3Py5zcWwgPz8gbnVsbCk7XG4gICAgICAgICAgdGhpcy5zcWxCYXNlbGluZS5zZXQoISFwcmV2aWV3Py5iYXNlbGluZSk7XG4gICAgICAgICAgdGhpcy5zcWxUaW1lem9uZS5zZXQocHJldmlldz8udGltZXpvbmUgfHwgJ1VUQycpO1xuICAgICAgICAgIHRoaXMuc3FsRXJyb3Iuc2V0KHByZXZpZXc/LmVycm9yID8/IG51bGwpO1xuICAgICAgICB9LFxuICAgICAgICBlcnJvcjogKGVycm9yKSA9PiB7XG4gICAgICAgICAgdGhpcy5zcWwuc2V0KG51bGwpO1xuICAgICAgICAgIHRoaXMuc3FsRXJyb3Iuc2V0KGVycm9yPy5lcnJvcj8ubWVzc2FnZSA/PyAnQ291bGQgbm90IHJlYWQgdGhlIGNvbXBvbmVudCBTUUwnKTtcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBfbG9hZENvbHVtbnMoKTogdm9pZCB7XG4gICAgdGhpcy5fcmVwb3J0RGF0YS5jb21wb25lbnRDb2x1bW5zKHRoaXMucmVwb3J0LmlkLCB0aGlzLmNvbXBvbmVudC5pZClcbiAgICAgIC5zdWJzY3JpYmUoe1xuICAgICAgICBuZXh0OiAoY29sdW1uczogUmVwb3J0RmlsdGVyYWJsZUNvbHVtbltdKSA9PiB7XG4gICAgICAgICAgdGhpcy5fZmlsdGVyYWJsZUNvbHVtbnMgPSBjb2x1bW5zID8/IFtdO1xuICAgICAgICAgIHRoaXMuX3JlYnVpbGRSb3dzKCk7XG4gICAgICAgIH0sXG4gICAgICAgIGVycm9yOiAoZXJyb3IpID0+IHtcbiAgICAgICAgICB0aGlzLmNvbHVtbnNFcnJvci5zZXQoZXJyb3I/LmVycm9yPy5tZXNzYWdlID8/ICdDb3VsZCBub3QgcmVhZCB0aGUgY29tcG9uZW50IGNvbHVtbnMnKTtcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBfaHVtYW5pemUoY29sdW1uOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiBjb2x1bW5cbiAgICAgIC5yZXBsYWNlKC9bX1xcLV0rL2csICcgJylcbiAgICAgIC5yZXBsYWNlKC9cXHMrL2csICcgJylcbiAgICAgIC50cmltKClcbiAgICAgIC5yZXBsYWNlKC9cXGJcXHcvZywgKGNoYXJhY3RlcikgPT4gY2hhcmFjdGVyLnRvVXBwZXJDYXNlKCkpO1xuICB9XG59XG4iLCI8Zm9ybVxuICAgIGZzRm9ybVxuICAgIFtzdWJtaXRdPVwic2F2ZVwiPlxuICA8ZnMtZGlhbG9nPlxuICAgIDxoMSBtYXQtZGlhbG9nLXRpdGxlPlxuICAgICAge3sgaGVhZGluZygpIH19XG4gICAgPC9oMT5cbiAgICA8bWF0LWRpYWxvZy1jb250ZW50PlxuICAgICAgPG1hdC10YWItZ3JvdXAgWyhzZWxlY3RlZCldPVwic2VsZWN0ZWRUYWJcIj5cbiAgICAgICAgPG1hdC10YWJcbiAgICAgICAgICAgIGxhYmVsPVwiU2V0dGluZ3NcIlxuICAgICAgICAgICAgbmFtZT1cInNldHRpbmdzXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImZzLWNvbHVtbiB0YWItYm9keVwiPlxuICAgICAgICAgICAgPCEtLSBBIHZhbHVlJ3MgTmFtZSBpcyBqdXN0IGl0cyBuYW1lLiBBIHRpdGxlIG1heSBjYXJyeSB0aGUgcGFnZSxcbiAgICAgICAgICAgICAgICAgcmVwb3J0IGFuZCBmaWx0ZXIgZmllbGRzIGEgdGV4dCBibG9jaydzIHdvcmRzIGRvOiBJbnNlcnRcbiAgICAgICAgICAgICAgICAgZmllbGQgcHV0cyBvbmUgaW4gYXQgdGhlIGNhcmV0LCBhbmQgdGhlIGhpbnQgc2F5cyBob3cgdGhlXG4gICAgICAgICAgICAgICAgIHRpdGxlIHJlYWRzIHdoZXJlIHRoZSBjb21wb25lbnQgaXMgZHJhd24uIC0tPlxuICAgICAgICAgICAgQGlmIChpc1ZhbHVlKCkpIHtcbiAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICBOYW1lXG4gICAgICAgICAgICAgICAgPC9tYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICBtYXRJbnB1dFxuICAgICAgICAgICAgICAgICAgW25nTW9kZWxdPVwidGl0bGUoKVwiXG4gICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJ0aXRsZS5zZXQoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICBuYW1lPVwidGl0bGVcIlxuICAgICAgICAgICAgICAgICAgW2ZzRm9ybVJlcXVpcmVkXT1cInRydWVcIj5cbiAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgICAgPG1hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgIFRpdGxlXG4gICAgICAgICAgICAgICAgPC9tYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAjdGl0bGVJbnB1dFxuICAgICAgICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cInRpdGxlKClcIlxuICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwidGl0bGUuc2V0KCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgbmFtZT1cInRpdGxlXCI+XG4gICAgICAgICAgICAgICAgPCEtLSBUaGUgYnV0dG9uIHN3YWxsb3dzIGl0cyBvd24gY2xpY2s6IHRoZSBmb3JtIGZpZWxkIHdvdWxkXG4gICAgICAgICAgICAgICAgICAgICBvdGhlcndpc2UgcHV0IGZvY3VzIGJhY2sgaW4gdGhlIGlucHV0IHdoaWxlIHRoZSBtZW51IGlzXG4gICAgICAgICAgICAgICAgICAgICBvcGVuLCBhbmQgYSBrZXkgcHJlc3NlZCB0aGVuIHdvdWxkIG1vdmUgdGhlIGNhcmV0IHRoZVxuICAgICAgICAgICAgICAgICAgICAgZmllbGQgZ29lcyBpbiBhdC4gLS0+XG4gICAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgICAgICBtYXQtaWNvbi1idXR0b25cbiAgICAgICAgICAgICAgICAgICAgbWF0SWNvblN1ZmZpeFxuICAgICAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgYXJpYS1sYWJlbD1cIkluc2VydCBmaWVsZFwiXG4gICAgICAgICAgICAgICAgICAgIFtmc01lbnVUcmlnZ2VyRm9yXT1cImluc2VydEZpZWxkTWVudVwiXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIj5cbiAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbj5zZWxsPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICBAaWYgKHRpdGxlU2hvd25BcygpKSB7XG4gICAgICAgICAgICAgICAgICA8bWF0LWhpbnQ+XG4gICAgICAgICAgICAgICAgICAgIFNob3dzIGFzOiB7eyB0aXRsZVNob3duQXMoKSB9fVxuICAgICAgICAgICAgICAgICAgPC9tYXQtaGludD5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgIDxmcy1tZW51ICNpbnNlcnRGaWVsZE1lbnU+XG4gICAgICAgICAgICAgICAgQGZvciAoZW50cnkgb2YgdGl0bGVGaWVsZHMoKTsgdHJhY2sgZW50cnkuZmllbGQpIHtcbiAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZVxuICAgICAgICAgICAgICAgICAgICAgIGZzLW1lbnUtaXRlbVxuICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJpbnNlcnRGaWVsZChlbnRyeS5maWVsZClcIj5cbiAgICAgICAgICAgICAgICAgICAge3sgZW50cnkubmFtZSB9fVxuICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIDwvZnMtbWVudT5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwhLS0gQSBmb3JtdWxhIHZhbHVlIGlzIHJlYWQtb25seSBiZXlvbmQgaXRzIG5hbWU6IHdoYXQgaXQgd29ya3NcbiAgICAgICAgICAgICAgICAgb3V0IGlzIHRoZSBBSSdzIHRvIGNoYW5nZS4gQSBmb3JtdWxhIHRoaXMgdmlld2VyIGNhbm5vdFxuICAgICAgICAgICAgICAgICByZWFkIGhhcyBubyBsaW5lLCBhbmQgbm8gcm93LiAtLT5cbiAgICAgICAgICAgIEBpZiAoZm9ybXVsYUxpbmUoKSkge1xuICAgICAgICAgICAgICA8ZnMtbGFiZWwtZmllbGQ+XG4gICAgICAgICAgICAgICAgPGZzLWxhYmVsPlxuICAgICAgICAgICAgICAgICAgRm9ybXVsYVxuICAgICAgICAgICAgICAgIDwvZnMtbGFiZWw+XG4gICAgICAgICAgICAgICAge3sgZm9ybXVsYUxpbmUoKSB9fVxuICAgICAgICAgICAgICAgIDxmcy1sYWJlbC1tZXNzYWdlPlxuICAgICAgICAgICAgICAgICAgV29ya2VkIG91dCBvbiB0aGUgc2VydmVyOyBpdCBmb2xsb3dzIHRoZSBmaWx0ZXJzIG9mIHRoZSB2YWx1ZXMgaXQgcmVhZHMuXG4gICAgICAgICAgICAgICAgPC9mcy1sYWJlbC1tZXNzYWdlPlxuICAgICAgICAgICAgICA8L2ZzLWxhYmVsLWZpZWxkPlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgPCEtLSBBIHZhbHVlIHNpdHMgaW5zaWRlIGEgdGV4dCBibG9jaydzIHdvcmRzOiBubyBib3gsIG5vIHBhZGRpbmcuIC0tPlxuICAgICAgICAgICAgQGlmICghaXNWYWx1ZSgpKSB7XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdWJoZWFkaW5nLTJcIj5cbiAgICAgICAgICAgICAgICBQYWRkaW5nXG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZ2VvbWV0cnktcm93XCI+XG4gICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgVG9wXG4gICAgICAgICAgICAgICAgICA8L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgICBtYXRJbnB1dFxuICAgICAgICAgICAgICAgICAgICBmc01hc2tOdW1iZXJcbiAgICAgICAgICAgICAgICAgICAgW3NjYWxlXT1cIjNcIlxuICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cInBhZGRpbmdUb3BcIlxuICAgICAgICAgICAgICAgICAgICBuYW1lPVwicGFkZGluZ1RvcFwiXG4gICAgICAgICAgICAgICAgICAgIFtmc0Zvcm1NaW5dPVwiMFwiPlxuICAgICAgICAgICAgICAgICAgPGRpdiBtYXRUZXh0U3VmZml4PlxuICAgICAgICAgICAgICAgICAgICBpblxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgICBSaWdodFxuICAgICAgICAgICAgICAgICAgPC9tYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgICAgICAgICAgZnNNYXNrTnVtYmVyXG4gICAgICAgICAgICAgICAgICAgIFtzY2FsZV09XCIzXCJcbiAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJwYWRkaW5nUmlnaHRcIlxuICAgICAgICAgICAgICAgICAgICBuYW1lPVwicGFkZGluZ1JpZ2h0XCJcbiAgICAgICAgICAgICAgICAgICAgW2ZzRm9ybU1pbl09XCIwXCI+XG4gICAgICAgICAgICAgICAgICA8ZGl2IG1hdFRleHRTdWZmaXg+XG4gICAgICAgICAgICAgICAgICAgIGluXG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIEJvdHRvbVxuICAgICAgICAgICAgICAgICAgPC9tYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgICAgICAgICAgZnNNYXNrTnVtYmVyXG4gICAgICAgICAgICAgICAgICAgIFtzY2FsZV09XCIzXCJcbiAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJwYWRkaW5nQm90dG9tXCJcbiAgICAgICAgICAgICAgICAgICAgbmFtZT1cInBhZGRpbmdCb3R0b21cIlxuICAgICAgICAgICAgICAgICAgICBbZnNGb3JtTWluXT1cIjBcIj5cbiAgICAgICAgICAgICAgICAgIDxkaXYgbWF0VGV4dFN1ZmZpeD5cbiAgICAgICAgICAgICAgICAgICAgaW5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgTGVmdFxuICAgICAgICAgICAgICAgICAgPC9tYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgICAgICAgICAgZnNNYXNrTnVtYmVyXG4gICAgICAgICAgICAgICAgICAgIFtzY2FsZV09XCIzXCJcbiAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJwYWRkaW5nTGVmdFwiXG4gICAgICAgICAgICAgICAgICAgIG5hbWU9XCJwYWRkaW5nTGVmdFwiXG4gICAgICAgICAgICAgICAgICAgIFtmc0Zvcm1NaW5dPVwiMFwiPlxuICAgICAgICAgICAgICAgICAgPGRpdiBtYXRUZXh0U3VmZml4PlxuICAgICAgICAgICAgICAgICAgICBpblxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICA8IS0tIEEgZGVyaXZlZCBLUEkncyBjYXJkOiB3aGF0IGEgcmlzZSBtZWFucywgYSB0YXJnZXQgYW5kIGFcbiAgICAgICAgICAgICAgICAgc3BhcmtsaW5lLiBUaGUgc2VydmVyIGNvbXB1dGVzIHRoZSBwcm9ncmVzcyBhbmQgdGhlIHBvaW50cy4gLS0+XG4gICAgICAgICAgICBAaWYgKGtwaUNhcmQoKSkge1xuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3ViaGVhZGluZy0yXCI+XG4gICAgICAgICAgICAgICAgQ2FyZFxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwiZnVsbC13aWR0aFwiPlxuICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICBJbmNyZWFzZSBpc1xuICAgICAgICAgICAgICAgIDwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgIDxtYXQtc2VsZWN0XG4gICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cImluY3JlYXNlSXMoKVwiXG4gICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cImluY3JlYXNlSXMuc2V0KCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICBuYW1lPVwiaW5jcmVhc2VJc1wiPlxuICAgICAgICAgICAgICAgICAgQGZvciAob3B0aW9uIG9mIGtwaVBvbGFyaXR5T3B0aW9uczsgdHJhY2sgb3B0aW9uLnZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uIFt2YWx1ZV09XCJvcHRpb24udmFsdWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICB7eyBvcHRpb24ubmFtZSB9fVxuICAgICAgICAgICAgICAgICAgICA8L21hdC1vcHRpb24+XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgPC9tYXQtc2VsZWN0PlxuICAgICAgICAgICAgICAgIDxtYXQtaGludD5cbiAgICAgICAgICAgICAgICAgIENvbG9ycyB0aGUgY2hhbmdlIGFuZCBkZWNpZGVzIHdoZW4gdGhlIHRhcmdldCBpcyBtZXQuXG4gICAgICAgICAgICAgICAgPC9tYXQtaGludD5cbiAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwiZnVsbC13aWR0aFwiPlxuICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICBUYXJnZXRcbiAgICAgICAgICAgICAgICA8L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgIG1hdElucHV0XG4gICAgICAgICAgICAgICAgICBmc01hc2tOdW1iZXJcbiAgICAgICAgICAgICAgICAgIFtzY2FsZV09XCI2XCJcbiAgICAgICAgICAgICAgICAgIFtzaWduZWRdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJ0YXJnZXRWYWx1ZSgpXCJcbiAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cInRhcmdldFZhbHVlLnNldCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgIG5hbWU9XCJ0YXJnZXRWYWx1ZVwiXG4gICAgICAgICAgICAgICAgICBbdmFsaWRhdGVdPVwidmFsaWRhdGVUYXJnZXRcIj5cbiAgICAgICAgICAgICAgICBAaWYgKHRhcmdldFBlcmNlbnQoKSkge1xuICAgICAgICAgICAgICAgICAgPGRpdiBtYXRUZXh0U3VmZml4PlxuICAgICAgICAgICAgICAgICAgICAlXG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgPG1hdC1oaW50PlxuICAgICAgICAgICAgICAgICAgVGhlIHZhbHVlIHRvIHJlYWNoLiBMZWF2ZSBlbXB0eSBmb3Igbm8gdGFyZ2V0LlxuICAgICAgICAgICAgICAgIDwvbWF0LWhpbnQ+XG4gICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgIEBpZiAoaGFzVGFyZ2V0KCkpIHtcbiAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgY2xhc3M9XCJmdWxsLXdpZHRoXCI+XG4gICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgICBUYXJnZXQgbGFiZWxcbiAgICAgICAgICAgICAgICAgIDwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgIG1hdElucHV0XG4gICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cInRhcmdldExhYmVsKClcIlxuICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJ0YXJnZXRMYWJlbC5zZXQoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgIG5hbWU9XCJ0YXJnZXRMYWJlbFwiPlxuICAgICAgICAgICAgICAgICAgPG1hdC1oaW50PlxuICAgICAgICAgICAgICAgICAgICBTaG93biBiZWZvcmUgdGhlIHRhcmdldCwgc3VjaCBhcyBHb2FsLiBFbXB0eSByZWFkcyBUYXJnZXQuXG4gICAgICAgICAgICAgICAgICA8L21hdC1oaW50PlxuICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgPGZzLWxhYmVsLWZpZWxkPlxuICAgICAgICAgICAgICAgIDxtYXQtc2xpZGUtdG9nZ2xlXG4gICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cInNwYXJrbGluZSgpXCJcbiAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwic3BhcmtsaW5lLnNldCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgbmFtZT1cInNwYXJrbGluZVwiPlxuICAgICAgICAgICAgICAgICAgU3BhcmtsaW5lXG4gICAgICAgICAgICAgICAgPC9tYXQtc2xpZGUtdG9nZ2xlPlxuICAgICAgICAgICAgICAgIDxtYXQtaGludD5cbiAgICAgICAgICAgICAgICAgIEEgc21hbGwgdHJlbmQgbGluZSBvZiB0aGUgdmFsdWUgb3ZlciBpdHMgbGFzdCBwZXJpb2RzLlxuICAgICAgICAgICAgICAgIDwvbWF0LWhpbnQ+XG4gICAgICAgICAgICAgIDwvZnMtbGFiZWwtZmllbGQ+XG4gICAgICAgICAgICAgIEBpZiAoc3BhcmtsaW5lKCkpIHtcbiAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgY2xhc3M9XCJmdWxsLXdpZHRoXCI+XG4gICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgICBTcGFya2xpbmUgcGVyaW9kXG4gICAgICAgICAgICAgICAgICA8L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgIDxtYXQtc2VsZWN0XG4gICAgICAgICAgICAgICAgICAgICAgW25nTW9kZWxdPVwic3BhcmtsaW5lR3JhbnVsYXJpdHkoKVwiXG4gICAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwic3BhcmtsaW5lR3JhbnVsYXJpdHkuc2V0KCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgIG5hbWU9XCJzcGFya2xpbmVHcmFudWxhcml0eVwiPlxuICAgICAgICAgICAgICAgICAgICBAZm9yIChvcHRpb24gb2YgZ3JhbnVsYXJpdHlPcHRpb25zOyB0cmFjayBvcHRpb24udmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiBbdmFsdWVdPVwib3B0aW9uLnZhbHVlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICB7eyBvcHRpb24ubmFtZSB9fVxuICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgPC9tYXQtc2VsZWN0PlxuICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwiZnVsbC13aWR0aFwiPlxuICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgU3BhcmtsaW5lIHBlcmlvZHNcbiAgICAgICAgICAgICAgICAgIDwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgIG1hdElucHV0XG4gICAgICAgICAgICAgICAgICAgIGZzTWFza051bWJlclxuICAgICAgICAgICAgICAgICAgICBbc2NhbGVdPVwiMFwiXG4gICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cInNwYXJrbGluZVBlcmlvZHMoKVwiXG4gICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cInNwYXJrbGluZVBlcmlvZHMuc2V0KCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICBuYW1lPVwic3BhcmtsaW5lUGVyaW9kc1wiXG4gICAgICAgICAgICAgICAgICAgIFtmc0Zvcm1SZXF1aXJlZF09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgW2ZzRm9ybUludGVnZXJdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgIFtmc0Zvcm1NaW5dPVwic3BhcmtsaW5lTWluUGVyaW9kc1wiXG4gICAgICAgICAgICAgICAgICAgIFtmc0Zvcm1NYXhdPVwic3BhcmtsaW5lTWF4UGVyaW9kc1wiPlxuICAgICAgICAgICAgICAgICAgPG1hdC1oaW50PlxuICAgICAgICAgICAgICAgICAgICBIb3cgbWFueSBwZXJpb2RzIHRoZSBsaW5lIGNvdmVycywge3sgc3BhcmtsaW5lTWluUGVyaW9kcyB9fSB0byB7eyBzcGFya2xpbmVNYXhQZXJpb2RzIH19LlxuICAgICAgICAgICAgICAgICAgPC9tYXQtaGludD5cbiAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICA8IS0tIEEgY2hhcnQgb3ZlciB0aW1lOiBob3cgaXRzIHBlcmlvZHMgYXJlIGxhYmVsbGVkIGFuZCwgb24gYVxuICAgICAgICAgICAgICAgICBkZXJpdmVkIGNoYXJ0LCB3aGljaCBwZXJpb2RzIGl0IGRyYXdzLiBUaGUgc2VydmVyIHJ1bnMgdGhlXG4gICAgICAgICAgICAgICAgIHNwYW4sIHNvIHRoZSBzY3JlZW4gYW5kIGV2ZXJ5IGV4cG9ydCBkcmF3IHRoZSBzYW1lIHBlcmlvZHM7XG4gICAgICAgICAgICAgICAgIHRoZSBLUElzIGFuZCB2YWx1ZXMgb24gdGhlIHBhZ2Uga2VlcCB0aGUgZGF0ZSBmaWx0ZXIncyByYW5nZS4gLS0+XG4gICAgICAgICAgICBAaWYgKHRpbWVBeGlzKCkpIHtcbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN1YmhlYWRpbmctMlwiPlxuICAgICAgICAgICAgICAgIFRpbWUgYXhpc1xuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwiZnVsbC13aWR0aFwiPlxuICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICBEYXRlIGxhYmVsc1xuICAgICAgICAgICAgICAgIDwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgIDxtYXQtc2VsZWN0XG4gICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cImRhdGVMYWJlbCgpXCJcbiAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwiZGF0ZUxhYmVsLnNldCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgbmFtZT1cImRhdGVMYWJlbFwiPlxuICAgICAgICAgICAgICAgICAgQGZvciAob3B0aW9uIG9mIGRhdGVMYWJlbE9wdGlvbnM7IHRyYWNrIG9wdGlvbi52YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiBbdmFsdWVdPVwib3B0aW9uLnZhbHVlXCI+XG4gICAgICAgICAgICAgICAgICAgICAge3sgb3B0aW9uLm5hbWUgfX1cbiAgICAgICAgICAgICAgICAgICAgPC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIDwvbWF0LXNlbGVjdD5cbiAgICAgICAgICAgICAgICA8bWF0LWhpbnQ+XG4gICAgICAgICAgICAgICAgICBQZXJpb2QgZW5kIGxhYmVscyBlYWNoIHBlcmlvZCBieSBpdHMgbGFzdCBkYXk6IGEgd2VlayBieSBpdHMgU3VuZGF5LlxuICAgICAgICAgICAgICAgIDwvbWF0LWhpbnQ+XG4gICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgIEBpZiAoc3BhbkFsbG93ZWQoKSkge1xuICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBjbGFzcz1cImZ1bGwtd2lkdGhcIj5cbiAgICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIFBlcmlvZHMgc2hvd25cbiAgICAgICAgICAgICAgICAgIDwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgPG1hdC1zZWxlY3RcbiAgICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJzcGFuTW9kZSgpXCJcbiAgICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJzcGFuTW9kZS5zZXQoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgbmFtZT1cInNwYW5Nb2RlXCI+XG4gICAgICAgICAgICAgICAgICAgIEBmb3IgKG9wdGlvbiBvZiBzcGFuTW9kZU9wdGlvbnM7IHRyYWNrIG9wdGlvbi52YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uIFt2YWx1ZV09XCJvcHRpb24udmFsdWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIHt7IG9wdGlvbi5uYW1lIH19XG4gICAgICAgICAgICAgICAgICAgICAgPC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICA8L21hdC1zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICA8bWF0LWhpbnQ+XG4gICAgICAgICAgICAgICAgICAgIFdpdGggbm8gZGF0ZSBmaWx0ZXIgc2V0LCB0aGUgY2hhcnQgZW5kcyBhdCB0aGUgY3VycmVudCBwZXJpb2QuXG4gICAgICAgICAgICAgICAgICA8L21hdC1oaW50PlxuICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgICAgQGlmIChzcGFuTW9kZSgpID09PSBSZXBvcnRDaGFydFNwYW5Nb2RlLlBlcmlvZHMpIHtcbiAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBjbGFzcz1cImZ1bGwtd2lkdGhcIj5cbiAgICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICBQZXJpb2RzXG4gICAgICAgICAgICAgICAgICAgIDwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICBtYXRJbnB1dFxuICAgICAgICAgICAgICAgICAgICAgIGZzTWFza051bWJlclxuICAgICAgICAgICAgICAgICAgICAgIFtzY2FsZV09XCIwXCJcbiAgICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJzcGFuUGVyaW9kcygpXCJcbiAgICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJzcGFuUGVyaW9kcy5zZXQoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgbmFtZT1cInNwYW5QZXJpb2RzXCJcbiAgICAgICAgICAgICAgICAgICAgICBbZnNGb3JtUmVxdWlyZWRdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgW2ZzRm9ybUludGVnZXJdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgW2ZzRm9ybU1pbl09XCJzcGFuTWluUGVyaW9kc1wiXG4gICAgICAgICAgICAgICAgICAgICAgW2ZzRm9ybU1heF09XCJzcGFuTWF4UGVyaW9kc1wiPlxuICAgICAgICAgICAgICAgICAgICA8bWF0LWhpbnQ+XG4gICAgICAgICAgICAgICAgICAgICAgSG93IG1hbnkgcGVyaW9kcyB0aGUgY2hhcnQgZHJhd3MsIHt7IHNwYW5NaW5QZXJpb2RzIH19IHRvIHt7IHNwYW5NYXhQZXJpb2RzIH19OyAzIG9uIGEgbW9udGhseSBjaGFydCBpcyB0aGUgbGFzdCB0aHJlZSBtb250aHMuXG4gICAgICAgICAgICAgICAgICAgIDwvbWF0LWhpbnQ+XG4gICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICAgIH0gQGVsc2UgaWYgKHNwYW5Nb2RlKCkgPT09IFJlcG9ydENoYXJ0U3Bhbk1vZGUuU3RhcnQpIHtcbiAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBjbGFzcz1cImZ1bGwtd2lkdGhcIj5cbiAgICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICBTaW5jZVxuICAgICAgICAgICAgICAgICAgICA8L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICBmc0RhdGVQaWNrZXJcbiAgICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJzcGFuU3RhcnQoKVwiXG4gICAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwic3BhblN0YXJ0LnNldCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICBuYW1lPVwic3BhblN0YXJ0XCJcbiAgICAgICAgICAgICAgICAgICAgICBbZnNGb3JtUmVxdWlyZWRdPVwidHJ1ZVwiPlxuICAgICAgICAgICAgICAgICAgICA8bWF0LWhpbnQ+XG4gICAgICAgICAgICAgICAgICAgICAgVGhlIGNoYXJ0IGRyYXdzIGV2ZXJ5IHBlcmlvZCBmcm9tIHRoaXMgZGF5LCBzdWNoIGFzIGEgZ28tbGl2ZS5cbiAgICAgICAgICAgICAgICAgICAgPC9tYXQtaGludD5cbiAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvbWF0LXRhYj5cbiAgICAgICAgPCEtLSBBIGZvcm11bGEgcnVucyBubyBzdGF0ZW1lbnQgYW5kIGZvbGxvd3MgdGhlIGZpbHRlcnMgb2YgdGhlIHZhbHVlc1xuICAgICAgICAgICAgIGl0IHJlYWRzLCBzbyBpdCBoYXMgbmVpdGhlciBhIEZpbHRlcnMgbm9yIGFuIFNRTCB0YWIuIC0tPlxuICAgICAgICBAaWYgKCFpc0Zvcm11bGEoKSkge1xuICAgICAgICAgIDxtYXQtdGFiXG4gICAgICAgICAgICAgIGxhYmVsPVwiRmlsdGVyc1wiXG4gICAgICAgICAgICAgIG5hbWU9XCJmaWx0ZXJzXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGFiLWJvZHlcIj5cbiAgICAgICAgICAgICAgQGlmIChjb2x1bW5zRXJyb3IoKSkge1xuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmaWx0ZXJzLWVtcHR5IGVycm9yXCI+XG4gICAgICAgICAgICAgICAgICB7eyBjb2x1bW5zRXJyb3IoKSB9fVxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICB9IEBlbHNlIGlmIChyb3dzKCkubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgPCEtLSBFdmVyeSBmaWx0ZXJhYmxlIGNvbHVtbi4gUGljayB3aGVyZSBpdHMgY29udHJvbCBzaG93czogaW5cbiAgICAgICAgICAgICAgICAgICAgIHRoZSByZXBvcnQgYmFyIChldmVyeSBwYWdlLCBvciB0aGlzIHBhZ2Ugb25seSksIG9uIHRoaXNcbiAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudCwgYm90aCwgb3IgbmVpdGhlci4gVGhlIGludGVyZmFjZSBmb2xsb3dzIHRoZVxuICAgICAgICAgICAgICAgICAgICAgZGF0YTsgYSBudW1lcmljIGNvbHVtbiBjYW4gYmUgdmFsdWVzIG9yIGEgbnVtYmVyIHJhbmdlLlxuICAgICAgICAgICAgICAgICAgICAgQSB2YWx1ZSBzaXRzIGluc2lkZSB0ZXh0IGFuZCBoYXMgbm8gY29tcG9uZW50IHRvIHNob3cgYVxuICAgICAgICAgICAgICAgICAgICAgY29udHJvbCBvbiwgc28gaXQgZ2V0cyB0aGUgcmVwb3J0IGJhciBjb2x1bW4gb25seS4gLS0+XG4gICAgICAgICAgICAgICAgPHRhYmxlIGNsYXNzPVwiZmlsdGVyLXRhYmxlXCI+XG4gICAgICAgICAgICAgICAgICA8dGhlYWQ+XG4gICAgICAgICAgICAgICAgICAgIDx0cj5cbiAgICAgICAgICAgICAgICAgICAgICA8dGggY2xhc3M9XCJmaWx0ZXItY29sLW5hbWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIEZpbHRlclxuICAgICAgICAgICAgICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgPHRoIGNsYXNzPVwiZmlsdGVyLWNvbC10eXBlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICBUeXBlXG4gICAgICAgICAgICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgICAgICAgICAgICA8dGggY2xhc3M9XCJmaWx0ZXItY29sLXNlbGVjdFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgUmVwb3J0IGJhclxuICAgICAgICAgICAgICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgQGlmICghaXNWYWx1ZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGggY2xhc3M9XCJmaWx0ZXItY29sLXRvZ2dsZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzIGNvbXBvbmVudFxuICAgICAgICAgICAgICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICAgICAgICA8L3RoZWFkPlxuICAgICAgICAgICAgICAgICAgPHRib2R5PlxuICAgICAgICAgICAgICAgICAgICBAZm9yIChyb3cgb2Ygcm93cygpOyB0cmFjayByb3cuY29sdW1uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgPHRyPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwiZmlsdGVyLWNvbC1uYW1lXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHt7IHJvdy5sYWJlbCB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz1cImZpbHRlci1jb2wtdHlwZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICBAaWYgKHJvdy50eXBlU2VsZWN0LnNob3cpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3N1YnNjcmlwdFNpemluZ109XCInZHluYW1pYydcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbWF0VG9vbHRpcF09XCJyb3cudHlwZVNlbGVjdC50b29sdGlwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LXNlbGVjdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwYW5lbFdpZHRoXT1cIm51bGxcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cInJvdy50eXBlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJzZXRUeXBlKHJvdywgJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nTW9kZWxPcHRpb25zXT1cInsgc3RhbmRhbG9uZTogdHJ1ZSB9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwicm93LnR5cGVTZWxlY3QuZGlzYWJsZWRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyaWEtbGFiZWw9XCJUeXBlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBmb3IgKG9wdGlvbiBvZiB0eXBlT3B0aW9uczsgdHJhY2sgb3B0aW9uLnZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gW3ZhbHVlXT1cIm9wdGlvbi52YWx1ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgb3B0aW9uLm5hbWUgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LXNlbGVjdD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyB0eXBlTGFiZWwocm93LnR5cGUpIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJmaWx0ZXItY29sLXNlbGVjdFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgW3N1YnNjcmlwdFNpemluZ109XCInZHluYW1pYydcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LXNlbGVjdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcGFuZWxXaWR0aF09XCJudWxsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nTW9kZWxdPVwicm93LnBsYWNlbWVudFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cInNldFBsYWNlbWVudChyb3csICRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbE9wdGlvbnNdPVwieyBzdGFuZGFsb25lOiB0cnVlIH1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmlhLWxhYmVsPVwiUmVwb3J0IGJhclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQGZvciAob3B0aW9uIG9mIHJvdy5wbGFjZW1lbnRPcHRpb25zOyB0cmFjayBvcHRpb24udmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gW3ZhbHVlXT1cIm9wdGlvbi52YWx1ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IG9wdGlvbi5uYW1lIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgQGlmICghaXNWYWx1ZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz1cImZpbHRlci1jb2wtdG9nZ2xlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1zbGlkZS10b2dnbGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cInJvdy5jb21wb25lbnRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwic2V0Q29tcG9uZW50KHJvdywgJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbE9wdGlvbnNdPVwieyBzdGFuZGFsb25lOiB0cnVlIH1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cInJvdy5jb21wb25lbnRUb2dnbGUuZGlzYWJsZWRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW21hdFRvb2x0aXBdPVwicm93LmNvbXBvbmVudFRvZ2dsZS50b29sdGlwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtc2xpZGUtdG9nZ2xlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIDwvdGJvZHk+XG4gICAgICAgICAgICAgICAgPC90YWJsZT5cbiAgICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZpbHRlcnMtZW1wdHlcIj5cbiAgICAgICAgICAgICAgICAgIFRoaXMgY29tcG9uZW50IGhhcyBubyBmaWx0ZXJhYmxlIGNvbHVtbnMgeWV0IOKAlCBnaXZlIGl0IHNvbWUgU1FMIGZpcnN0LlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L21hdC10YWI+XG4gICAgICAgICAgPG1hdC10YWJcbiAgICAgICAgICAgICAgbGFiZWw9XCJTUUxcIlxuICAgICAgICAgICAgICBuYW1lPVwic3FsXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGFiLWJvZHlcIj5cbiAgICAgICAgICAgICAgQGlmIChzcWxFcnJvcigpKSB7XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZpbHRlcnMtZW1wdHkgZXJyb3JcIj5cbiAgICAgICAgICAgICAgICAgIHt7IHNxbEVycm9yKCkgfX1cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgfSBAZWxzZSBpZiAoc3FsKCkpIHtcbiAgICAgICAgICAgICAgICBAaWYgKHNxbEJhc2VsaW5lKCkpIHtcbiAgICAgICAgICAgICAgICAgIDwhLS0gQSBkZXJpdmVkIGNvbXBvbmVudCdzIHN0YXRlbWVudCBpcyBjb21waWxlZCBmcm9tIGl0c1xuICAgICAgICAgICAgICAgICAgICAgICBkb2N1bWVudCB3aXRoIG5vIHZpZXdlciBzdGF0ZSwgc28gaXQgaXMgbm90IGJ5dGUtZm9yLWJ5dGVcbiAgICAgICAgICAgICAgICAgICAgICAgd2hhdCBwcm9kdWNlZCB0aGUgbnVtYmVycyBvbiBzY3JlZW4uIFNhaWQgaGVyZSByYXRoZXIgdGhhblxuICAgICAgICAgICAgICAgICAgICAgICBsZWZ0IGZvciB0aGUgcmVhZGVyIHRvIGRpc2NvdmVyLiAtLT5cbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmaWx0ZXJzLWVtcHR5XCI+XG4gICAgICAgICAgICAgICAgICAgIENvbXBpbGVkIGZyb20gdGhpcyBjb21wb25lbnQncyBxdWVyeSDigJQgbm8gZmlsdGVycyBhcHBsaWVkLCB0aW1lcyBpbiB7eyBzcWxUaW1lem9uZSgpIH19LlxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIDxwcmUgY2xhc3M9XCJjb2RlLWJsb2NrXCI+e3sgc3FsKCkgfX08L3ByZT5cbiAgICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZpbHRlcnMtZW1wdHlcIj5cbiAgICAgICAgICAgICAgICAgIFRoaXMgY29tcG9uZW50IGhhcyBubyBTUUwgeWV0LlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L21hdC10YWI+XG4gICAgICAgIH1cbiAgICAgICAgPG1hdC10YWJcbiAgICAgICAgICAgIGxhYmVsPVwiQ29uZmlnXCJcbiAgICAgICAgICAgIG5hbWU9XCJjb25maWdcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwidGFiLWJvZHlcIj5cbiAgICAgICAgICAgIDxwcmUgY2xhc3M9XCJjb2RlLWJsb2NrXCI+XG4gICAgICAgICAgICAgIHt7IGNvbmZpZ0pzb24gfX1cbiAgICAgICAgICAgIDwvcHJlPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L21hdC10YWI+XG4gICAgICA8L21hdC10YWItZ3JvdXA+XG4gICAgPC9tYXQtZGlhbG9nLWNvbnRlbnQ+XG4gICAgPG1hdC1kaWFsb2ctYWN0aW9ucz5cbiAgICAgIDwhLS0gU2F2ZSB8IERlbGV0ZSB8IENhbmNlbCwgdGhlIHN0YW5kYXJkIG9yZGVyLiBmcy1mb3JtLWRpYWxvZy1hY3Rpb25zXG4gICAgICAgICAgIHJlbmRlcnMgaXRzIG93biBTYXZlL0RvbmUgQkVGT1JFIHRoZSBwcm9qZWN0ZWQgY29udGVudCwgd2hpY2ggd291bGRcbiAgICAgICAgICAgcHV0IERlbGV0ZSBhZnRlciBDYW5jZWwsIHNvIGBbc2F2ZV09XCJmYWxzZVwiYCBmb290cyB0aGUgcm93IGhlcmUgYW5kXG4gICAgICAgICAgIGFsbCB0aHJlZSBidXR0b25zIGFyZSBwcm9qZWN0ZWQgaW4gb3JkZXIuIFNhdmUgc3VibWl0cyB0aGUgU2V0dGluZ3NcbiAgICAgICAgICAgdGFiOyB0aGUgb3RoZXIgdGFicyBwZXJzaXN0IGFzIHlvdSB0b3VjaCB0aGVtLCBzbyB0aGV5IGdldCBEb25lLiAtLT5cbiAgICAgIDxmcy1mb3JtLWRpYWxvZy1hY3Rpb25zIFtzYXZlXT1cImZhbHNlXCI+XG4gICAgICAgIEBpZiAoc2VsZWN0ZWRUYWIgPT09ICdzZXR0aW5ncycpIHtcbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgIG1hdC1idXR0b25cbiAgICAgICAgICAgICAgdHlwZT1cInN1Ym1pdFwiXG4gICAgICAgICAgICAgIGNvbG9yPVwicHJpbWFyeVwiPlxuICAgICAgICAgICAgU2F2ZVxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgIG1hdC1idXR0b25cbiAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgIGNvbG9yPVwicHJpbWFyeVwiXG4gICAgICAgICAgICAgIFttYXQtZGlhbG9nLWNsb3NlXT1cIm51bGxcIj5cbiAgICAgICAgICAgIERvbmVcbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgfVxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICBtYXQtYnV0dG9uXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIGNvbG9yPVwid2FyblwiXG4gICAgICAgICAgICAoY2xpY2spPVwiZGVsZXRlKClcIj5cbiAgICAgICAgICBEZWxldGVcbiAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDxidXR0b25cbiAgICAgICAgICAgIG1hdC1idXR0b25cbiAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgY2xhc3M9XCJjYW5jZWwtYnV0dG9uXCJcbiAgICAgICAgICAgIFttYXQtZGlhbG9nLWNsb3NlXT1cIm51bGxcIj5cbiAgICAgICAgICBDYW5jZWxcbiAgICAgICAgPC9idXR0b24+XG4gICAgICA8L2ZzLWZvcm0tZGlhbG9nLWFjdGlvbnM+XG4gICAgPC9tYXQtZGlhbG9nLWFjdGlvbnM+XG4gIDwvZnMtZGlhbG9nPlxuPC9mb3JtPiJdfQ==
|