@firestitch/report 18.4.0 → 18.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/app/reports/components/component-list/component-list.component.d.ts +3 -6
  2. package/app/reports/components/report-canvas/report-canvas.component.d.ts +4 -4
  3. package/app/reports/components/report-component/report-component.component.d.ts +5 -5
  4. package/app/reports/components/timezone-select/timezone-select.component.d.ts +4 -6
  5. package/app/reports/consts/report-week.const.d.ts +2 -0
  6. package/app/reports/data/report-ai-chat.data.d.ts +12 -0
  7. package/app/reports/data/report.data.d.ts +3 -3
  8. package/app/reports/dialogs/component-settings/component-settings.component.d.ts +6 -6
  9. package/app/reports/dialogs/global-settings/components/semantic-database/semantic-database.component.d.ts +3 -0
  10. package/app/reports/dialogs/report-settings/report-settings.component.d.ts +5 -0
  11. package/app/reports/export/report-export-collector.service.d.ts +14 -2
  12. package/app/reports/export/report-pdf.service.d.ts +14 -1
  13. package/app/reports/export/report-pptx.service.d.ts +6 -1
  14. package/app/reports/format.d.ts +7 -0
  15. package/app/reports/interfaces/report-chat-viewer-filter.interface.d.ts +7 -0
  16. package/app/reports/interfaces/report-chat-viewer-state.interface.d.ts +7 -0
  17. package/app/reports/interfaces/report.interface.d.ts +19 -3
  18. package/app/reports/option-builder.d.ts +13 -1
  19. package/app/reports/pipes/report-date.pipe.d.ts +7 -0
  20. package/app/reports/report-filter-items.d.ts +5 -0
  21. package/app/reports/report-url-state.d.ts +14 -0
  22. package/app/reports/services/report-filter-state.service.d.ts +24 -2
  23. package/app/reports/text.d.ts +1 -0
  24. package/app/reports/theme/palette.d.ts +2 -0
  25. package/app/reports/theme/typography.d.ts +2 -0
  26. package/app/reports/views/report/fs-ai-report.component.d.ts +16 -8
  27. package/app/reports/views/report/report.component.d.ts +6 -6
  28. package/esm2022/app/reports/components/component-list/component-list.component.mjs +29 -104
  29. package/esm2022/app/reports/components/report-canvas/report-canvas.component.mjs +52 -44
  30. package/esm2022/app/reports/components/report-component/report-component.component.mjs +55 -35
  31. package/esm2022/app/reports/components/timezone-select/timezone-select.component.mjs +23 -23
  32. package/esm2022/app/reports/consts/report-week.const.mjs +7 -0
  33. package/esm2022/app/reports/data/report-ai-chat.data.mjs +25 -0
  34. package/esm2022/app/reports/data/report.data.mjs +22 -9
  35. package/esm2022/app/reports/dialogs/component-settings/component-settings.component.mjs +25 -26
  36. package/esm2022/app/reports/dialogs/global-settings/components/semantic-database/semantic-database.component.mjs +28 -14
  37. package/esm2022/app/reports/dialogs/global-settings/global-settings.component.mjs +3 -3
  38. package/esm2022/app/reports/dialogs/report-settings/report-settings.component.mjs +38 -13
  39. package/esm2022/app/reports/export/report-export-collector.service.mjs +92 -28
  40. package/esm2022/app/reports/export/report-export.service.mjs +11 -8
  41. package/esm2022/app/reports/export/report-pdf.service.mjs +241 -81
  42. package/esm2022/app/reports/export/report-pptx.service.mjs +143 -60
  43. package/esm2022/app/reports/format.mjs +119 -8
  44. package/esm2022/app/reports/interfaces/report-chat-viewer-filter.interface.mjs +2 -0
  45. package/esm2022/app/reports/interfaces/report-chat-viewer-state.interface.mjs +2 -0
  46. package/esm2022/app/reports/interfaces/report.interface.mjs +1 -1
  47. package/esm2022/app/reports/option-builder.mjs +230 -17
  48. package/esm2022/app/reports/pipes/report-date.pipe.mjs +21 -0
  49. package/esm2022/app/reports/report-filter-items.mjs +42 -10
  50. package/esm2022/app/reports/report-url-state.mjs +144 -0
  51. package/esm2022/app/reports/services/report-filter-state.service.mjs +308 -64
  52. package/esm2022/app/reports/text.mjs +2 -2
  53. package/esm2022/app/reports/theme/echarts.mjs +6 -5
  54. package/esm2022/app/reports/theme/palette.mjs +9 -1
  55. package/esm2022/app/reports/theme/typography.mjs +6 -0
  56. package/esm2022/app/reports/views/report/fs-ai-report.component.mjs +191 -90
  57. package/esm2022/app/reports/views/report/report.component.mjs +64 -62
  58. package/fesm2022/{firestitch-report-echarts-CFkoNvo_.mjs → firestitch-report-echarts-B9nl9XKM.mjs} +6 -6
  59. package/fesm2022/firestitch-report-echarts-B9nl9XKM.mjs.map +1 -0
  60. package/fesm2022/{firestitch-report-firestitch-report-PZzkYYTD.mjs → firestitch-report-firestitch-report-Bb65HEYB.mjs} +2348 -1161
  61. package/fesm2022/firestitch-report-firestitch-report-Bb65HEYB.mjs.map +1 -0
  62. package/fesm2022/firestitch-report.mjs +1 -1
  63. package/package.json +1 -1
  64. package/app/reports/dialogs/report-settings/report-settings-default.d.ts +0 -2
  65. package/esm2022/app/reports/dialogs/report-settings/report-settings-default.mjs +0 -22
  66. package/fesm2022/firestitch-report-echarts-CFkoNvo_.mjs.map +0 -1
  67. package/fesm2022/firestitch-report-firestitch-report-PZzkYYTD.mjs.map +0 -1
@@ -20,8 +20,7 @@ import { forkJoin } from 'rxjs';
20
20
  import { switchMap, tap } from 'rxjs/operators';
21
21
  import { ReportData } from '../../data/report.data';
22
22
  import { DEFAULT_HEADING_SIZE, HEADER_FOOTER_MAX, PAGE_DIMENSION_MAX, PAGE_DIMENSION_MIN } from '../../layout';
23
- import { loadGroupOptions, matchOptions, resolveOptionValues } from '../../report-filter-items';
24
- import { dateFromBound, dateToBound } from './report-settings-default';
23
+ import { dateFromBound, dateToBound, loadGroupOptions, matchOptions, relativeLabel, resolveOptionValues, } from '../../report-filter-items';
25
24
  import * as i0 from "@angular/core";
26
25
  import * as i1 from "@angular/forms";
27
26
  import * as i2 from "@firestitch/form";
@@ -62,12 +61,15 @@ export class ReportSettingsComponent {
62
61
  footerHeight = 0;
63
62
  headerFooterMax = HEADER_FOOTER_MAX;
64
63
  layout = 'freeform';
65
- // Empty until the report has one; app-timezone-select then defaults it to the
66
- // viewer's browser zone (which Save persists, making the report's zone explicit).
64
+ // Seeded with the zone the report actually uses: its own stored zone, else
65
+ // the application default the server resolved (effectiveTimezone). Save sends
66
+ // it only when it differs from that effective zone, so opening and saving a
67
+ // report that follows the default never pins it to a zone.
67
68
  timezone = '';
68
69
  headingSize = DEFAULT_HEADING_SIZE;
69
70
  // The report-level filters and their editable default values (Filters tab).
70
71
  filterRows = signal([]);
72
+ relativeLabel = relativeLabel;
71
73
  _data = inject(MAT_DIALOG_DATA);
72
74
  _dialogRef = inject(MatDialogRef);
73
75
  _reportData = inject(ReportData);
@@ -82,7 +84,7 @@ export class ReportSettingsComponent {
82
84
  this.headerHeight = report.config?.headerFooter?.headerHeight ?? 0;
83
85
  this.footerHeight = report.config?.headerFooter?.footerHeight ?? 0;
84
86
  this.layout = report.layout ?? 'freeform';
85
- this.timezone = report.timezone ?? '';
87
+ this.timezone = report.timezone ?? report.effectiveTimezone ?? '';
86
88
  this.headingSize = report.config?.styles?.heading?.size ?? DEFAULT_HEADING_SIZE;
87
89
  this._buildFilterRows(report);
88
90
  }
@@ -110,7 +112,7 @@ export class ReportSettingsComponent {
110
112
  pageWidth: this._pageDimension(this.pageWidth),
111
113
  pageHeight: this._pageDimension(this.pageHeight),
112
114
  layout: this.layout,
113
- timezone: this.timezone,
115
+ ...this._timezoneSetting(),
114
116
  styles: { heading: { size: this.headingSize } },
115
117
  headerFooter: {
116
118
  headerHeight: this._pageDimension(this.headerHeight) || 0,
@@ -128,6 +130,12 @@ export class ReportSettingsComponent {
128
130
  this._dialogRef.close({ action: 'saved' });
129
131
  }));
130
132
  };
133
+ // Drop the row's stored rolling preset (Clear). A new row object rather than
134
+ // a mutation, so the signal sees the change; the @for tracks group.id, so
135
+ // the row's bindings survive the swap.
136
+ clearRelative(row) {
137
+ this.filterRows.update((rows) => rows.map((item) => (item === row ? { ...item, relative: null } : item)));
138
+ }
131
139
  // The page dimension as a real number for the wire. fsMaskNumber hands back
132
140
  // the unmasked string it built with a fixed '.' radix (which is the whole
133
141
  // point of the mask - a native number input paints the viewer's locale
@@ -137,6 +145,16 @@ export class ReportSettingsComponent {
137
145
  _pageDimension(value) {
138
146
  return typeof value === 'number' ? value : parseFloat(value);
139
147
  }
148
+ // The zone for the settings PUT, sent only when it moves the report off the
149
+ // zone it already uses, so an untouched dialog never pins a report that
150
+ // follows the application default. A server too old to send
151
+ // effectiveTimezone gets the zone every time, as it always did.
152
+ _timezoneSetting() {
153
+ const effectiveTimezone = this._data.report.effectiveTimezone;
154
+ return effectiveTimezone === undefined || this.timezone !== effectiveTimezone
155
+ ? { timezone: this.timezone }
156
+ : {};
157
+ }
140
158
  // Build one editable row per report-level filter group (level report or both),
141
159
  // in bar order, seeding each draft from the group's stored default.
142
160
  _buildFilterRows(report) {
@@ -154,6 +172,7 @@ export class ReportSettingsComponent {
154
172
  label: group.label || group.filters?.[0]?.filterColumn || 'Filter',
155
173
  start: dateFromBound(groupDefault?.start),
156
174
  end: dateFromBound(groupDefault?.end),
175
+ relative: groupDefault?.relative ?? null,
157
176
  // Named below, once the option list carrying their labels is in.
158
177
  values: [],
159
178
  value: groupDefault?.value ?? '',
@@ -182,13 +201,18 @@ export class ReportSettingsComponent {
182
201
  });
183
202
  }
184
203
  // The draft default normalized to the wire shape for this row's type, or null
185
- // when empty (which clears the stored default).
204
+ // when empty (which clears the stored default). A date range is the picked
205
+ // dates when there are any, else the carried rolling preset, never both: the
206
+ // server refuses a relative preset combined with dates.
186
207
  _rowDefault(row) {
187
208
  switch (row.group.type) {
188
209
  case 'dateRange': {
189
210
  const start = dateToBound(row.start);
190
211
  const end = dateToBound(row.end);
191
- return (start || end) ? { start: start ?? undefined, end: end ?? undefined } : null;
212
+ if (start || end) {
213
+ return { start: start ?? undefined, end: end ?? undefined };
214
+ }
215
+ return row.relative ? { relative: row.relative } : null;
192
216
  }
193
217
  case 'select':
194
218
  return row.values.length ? { values: row.values.map((option) => option.value) } : null;
@@ -206,8 +230,9 @@ export class ReportSettingsComponent {
206
230
  const after = JSON.stringify(this._normalize(this._rowDefault(row)));
207
231
  return before !== after;
208
232
  }
209
- // A stable comparison form: drop relative (not authored here) and undefined
210
- // keys so a no-op edit doesn't read as a change.
233
+ // A stable comparison form: empty and undefined keys are dropped so a no-op
234
+ // edit doesn't read as a change. relative is compared like the rest: the row
235
+ // carries it, so an untouched rolling default reads as unchanged.
211
236
  _normalize(value) {
212
237
  if (!value) {
213
238
  return null;
@@ -231,7 +256,7 @@ export class ReportSettingsComponent {
231
256
  return Object.keys(normalized).length ? normalized : null;
232
257
  }
233
258
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportSettingsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
234
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ReportSettingsComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: "<form\n fsForm\n [submit]=\"save\">\n <fs-dialog>\n <h1 mat-dialog-title>\n Report Settings\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 <mat-form-field>\n <mat-label>\n Name\n </mat-label>\n <input\n matInput\n [(ngModel)]=\"name\"\n name=\"name\"\n [fsFormRequired]=\"true\">\n </mat-form-field>\n <!--\n The page, typed in inches. Orientation is not asked for because it\n is not an independent choice - a page wider than it is tall IS\n landscape - so the two numbers say everything there is to say.\n -->\n <div class=\"fs-row.gap-sm.align-start\">\n <mat-form-field class=\"fs-flex\">\n <mat-label>\n Width\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"1\"\n [(ngModel)]=\"pageWidth\"\n name=\"pageWidth\"\n [fsFormRequired]=\"true\"\n [fsFormMin]=\"pageDimensionMin\"\n [fsFormMax]=\"pageDimensionMax\">\n <div matTextSuffix>\n inches\n </div>\n </mat-form-field>\n <mat-form-field class=\"fs-flex\">\n <mat-label>\n Height\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"1\"\n [(ngModel)]=\"pageHeight\"\n name=\"pageHeight\"\n [fsFormRequired]=\"true\"\n [fsFormMin]=\"pageDimensionMin\"\n [fsFormMax]=\"pageDimensionMax\">\n <div matTextSuffix>\n inches\n </div>\n </mat-form-field>\n </div>\n <!--\n How deep the header and footer bands are. Their content is edited\n on the canvas (Edit layout \u2192 Header & footer); these reserve the\n space for it, and 0 means no band.\n -->\n <mat-form-field class=\"full-width\">\n <mat-label>\n Header height\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"2\"\n [(ngModel)]=\"headerHeight\"\n name=\"headerHeight\"\n [fsFormMin]=\"0\"\n [fsFormMax]=\"headerFooterMax\">\n <div matTextSuffix>\n inches\n </div>\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Footer height\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"2\"\n [(ngModel)]=\"footerHeight\"\n name=\"footerHeight\"\n [fsFormMin]=\"0\"\n [fsFormMax]=\"headerFooterMax\">\n <div matTextSuffix>\n inches\n </div>\n </mat-form-field>\n <mat-form-field>\n <mat-label>\n Layout\n </mat-label>\n <mat-select\n [(ngModel)]=\"layout\"\n name=\"layout\">\n <mat-option value=\"freeform\">\n Freeform \u2014 position components anywhere on the page\n </mat-option>\n <mat-option value=\"flow\">\n Flow \u2014 components flow into rows by width %\n </mat-option>\n </mat-select>\n <mat-hint>\n Freeform is like PowerPoint; Flow is like a responsive dashboard.\n </mat-hint>\n </mat-form-field>\n <fs-ai-report-timezone-select [(timezone)]=\"timezone\"></fs-ai-report-timezone-select>\n </div>\n </mat-tab>\n <mat-tab\n label=\"Styles\"\n name=\"styles\">\n <div class=\"fs-column tab-body\">\n <mat-form-field>\n <mat-label>\n Heading Size\n </mat-label>\n <input\n matInput\n type=\"number\"\n step=\"1\"\n min=\"6\"\n max=\"96\"\n [(ngModel)]=\"headingSize\"\n name=\"headingSize\"\n [fsFormMin]=\"6\"\n [fsFormMax]=\"96\">\n <span matTextSuffix>\n pt\n </span>\n <mat-hint>\n Applies to component titles. Points map 1:1 to PDF and PowerPoint.\n </mat-hint>\n </mat-form-field>\n </div>\n </mat-tab>\n <mat-tab\n label=\"Filters\"\n name=\"filters\">\n <div class=\"fs-column tab-body\">\n @if (filterRows().length) {\n @for (row of filterRows(); track row.group.id) {\n @switch (row.group.type) {\n @case ('dateRange') {\n <div class=\"fs-row.gap-sm.align-center fs-flex\">\n <mat-form-field class=\"fs-flex\">\n <mat-label>\n Default From {{ row.label }}\n </mat-label>\n <input\n matInput\n fsDatePicker\n [(ngModel)]=\"row.start\"\n [name]=\"'start' + row.group.id\">\n </mat-form-field>\n <mat-form-field class=\"fs-flex\">\n <mat-label>\n Default To {{ row.label }}\n </mat-label>\n <input\n matInput\n fsDatePicker\n [(ngModel)]=\"row.end\"\n [name]=\"'end' + row.group.id\">\n </mat-form-field>\n </div>\n }\n @case ('select') {\n <fs-autocomplete-chips\n class=\"fs-flex\"\n [label]=\"'Default ' + row.label\"\n [fetch]=\"row.fetch\"\n [(ngModel)]=\"row.values\"\n [name]=\"'values' + row.group.id\"\n [multiple]=\"true\"\n [fetchOnFocus]=\"true\">\n <ng-template\n fsAutocompleteChipsTemplate\n let-object=\"object\">\n {{ object.name }}\n </ng-template>\n </fs-autocomplete-chips>\n }\n @default {\n <mat-form-field class=\"fs-flex\">\n <mat-label>\n Default {{ row.label }}\n </mat-label>\n <input\n matInput\n [(ngModel)]=\"row.value\"\n [name]=\"'value' + row.group.id\">\n </mat-form-field>\n }\n }\n }\n } @else {\n <fs-message-info>\n This report has no report-level filters yet. Add a filter to a\n component (its settings \u2192 Filters) and show it in the report bar,\n then set its default here.\n </fs-message-info>\n }\n </div>\n </mat-tab>\n </mat-tab-group>\n </mat-dialog-content>\n <mat-dialog-actions>\n <fs-form-dialog-actions>\n <button\n type=\"button\"\n mat-button\n color=\"warn\"\n (click)=\"delete()\">\n Delete\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}\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.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { 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.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { 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: "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: FsMessageModule }, { kind: "component", type: i5.FsMessageInfoComponent, selector: "fs-message-info" }, { 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: FsDatePickerModule }, { kind: "component", type: i7.FsDatePickerComponent, selector: "[fsDatePicker]", inputs: ["minYear", "maxYear", "minDate", "maxDate", "startOfDay", "view", "format", "minutes", "width"], outputs: ["change"] }, { kind: "ngmodule", type: FsAutocompleteChipsModule }, { kind: "component", type: i8.FsAutocompleteChipsComponent, selector: "fs-autocomplete-chips", inputs: ["fetch", "appearance", "floatLabel", "readonly", "size", "label", "placeholder", "chipImage", "chipBackground", "chipColor", "chipIcon", "chipIconColor", "chipClass", "chipPadding", "shape", "hint", "allowText", "allowObject", "delay", "minPanelWidth", "maxPanelHeight", "validateText", "removable", "allowClear", "color", "background", "orderable", "padless", "initOnClick", "fetchOnFocus", "multiple", "multipleAdd", "confirm", "disabled", "groupBy", "panelWidth", "panelClass", "compareWith"], outputs: ["selected", "removed", "reordered", "clear", "panelOpened", "panelClosed"] }, { kind: "directive", type: i8.FsAutocompleteObjectDirective, selector: "[fsAutocompleteObject],[fsAutocompleteChipsTemplate]" }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i9.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass"], exportAs: ["matTab"] }, { kind: "component", type: i9.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: "component", type: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { 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: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { 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: 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: MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: TimezoneSelectComponent, selector: "fs-ai-report-timezone-select", inputs: ["placeholder", "required", "disabled", "timezone"], outputs: ["timezoneChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
259
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ReportSettingsComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: "<form\n fsForm\n [submit]=\"save\">\n <fs-dialog>\n <h1 mat-dialog-title>\n Report Settings\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 <mat-form-field>\n <mat-label>\n Name\n </mat-label>\n <input\n matInput\n [(ngModel)]=\"name\"\n name=\"name\"\n [fsFormRequired]=\"true\">\n </mat-form-field>\n <!--\n The page, typed in inches. Orientation is not asked for because it\n is not an independent choice - a page wider than it is tall IS\n landscape - so the two numbers say everything there is to say.\n -->\n <div class=\"fs-row.gap-sm.align-start\">\n <mat-form-field class=\"fs-flex\">\n <mat-label>\n Width\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"1\"\n [(ngModel)]=\"pageWidth\"\n name=\"pageWidth\"\n [fsFormRequired]=\"true\"\n [fsFormMin]=\"pageDimensionMin\"\n [fsFormMax]=\"pageDimensionMax\">\n <div matTextSuffix>\n inches\n </div>\n </mat-form-field>\n <mat-form-field class=\"fs-flex\">\n <mat-label>\n Height\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"1\"\n [(ngModel)]=\"pageHeight\"\n name=\"pageHeight\"\n [fsFormRequired]=\"true\"\n [fsFormMin]=\"pageDimensionMin\"\n [fsFormMax]=\"pageDimensionMax\">\n <div matTextSuffix>\n inches\n </div>\n </mat-form-field>\n </div>\n <!--\n How deep the header and footer bands are. Their content is edited\n on the canvas (Edit layout \u2192 Header & footer); these reserve the\n space for it, and 0 means no band.\n -->\n <mat-form-field class=\"full-width\">\n <mat-label>\n Header height\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"2\"\n [(ngModel)]=\"headerHeight\"\n name=\"headerHeight\"\n [fsFormMin]=\"0\"\n [fsFormMax]=\"headerFooterMax\">\n <div matTextSuffix>\n inches\n </div>\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Footer height\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"2\"\n [(ngModel)]=\"footerHeight\"\n name=\"footerHeight\"\n [fsFormMin]=\"0\"\n [fsFormMax]=\"headerFooterMax\">\n <div matTextSuffix>\n inches\n </div>\n </mat-form-field>\n <mat-form-field>\n <mat-label>\n Layout\n </mat-label>\n <mat-select\n [(ngModel)]=\"layout\"\n name=\"layout\">\n <mat-option value=\"freeform\">\n Freeform \u2014 position components anywhere on the page\n </mat-option>\n <mat-option value=\"flow\">\n Flow \u2014 components flow into rows by width %\n </mat-option>\n </mat-select>\n <mat-hint>\n Freeform is like PowerPoint; Flow is like a responsive dashboard.\n </mat-hint>\n </mat-form-field>\n <fs-ai-report-timezone-select [(timezone)]=\"timezone\"></fs-ai-report-timezone-select>\n </div>\n </mat-tab>\n <mat-tab\n label=\"Styles\"\n name=\"styles\">\n <div class=\"fs-column tab-body\">\n <mat-form-field>\n <mat-label>\n Heading Size\n </mat-label>\n <input\n matInput\n type=\"number\"\n step=\"1\"\n min=\"6\"\n max=\"96\"\n [(ngModel)]=\"headingSize\"\n name=\"headingSize\"\n [fsFormMin]=\"6\"\n [fsFormMax]=\"96\">\n <span matTextSuffix>\n pt\n </span>\n <mat-hint>\n Applies to component titles. Points map 1:1 to PDF and PowerPoint.\n </mat-hint>\n </mat-form-field>\n </div>\n </mat-tab>\n <mat-tab\n label=\"Filters\"\n name=\"filters\">\n <div class=\"fs-column tab-body\">\n @if (filterRows().length) {\n @for (row of filterRows(); track row.group.id) {\n @switch (row.group.type) {\n @case ('dateRange') {\n <div class=\"fs-row.gap-sm.align-center fs-flex\">\n <mat-form-field class=\"fs-flex\">\n <mat-label>\n Default From {{ row.label }}\n </mat-label>\n <input\n matInput\n fsDatePicker\n [(ngModel)]=\"row.start\"\n [name]=\"'start' + row.group.id\">\n </mat-form-field>\n <mat-form-field class=\"fs-flex\">\n <mat-label>\n Default To {{ row.label }}\n </mat-label>\n <input\n matInput\n fsDatePicker\n [(ngModel)]=\"row.end\"\n [name]=\"'end' + row.group.id\">\n </mat-form-field>\n </div>\n <!-- A stored rolling preset cannot be authored here, only\n kept, replaced by picking dates, or cleared. type=\"button\"\n keeps Clear from submitting the form. -->\n @if (row.relative && !row.start && !row.end) {\n <div class=\"fs-row.gap-sm.align-center\">\n <mat-hint class=\"fs-flex\">\n Rolling default: {{ relativeLabel(row.relative) }}. Pick dates to replace it.\n </mat-hint>\n <button\n mat-button\n type=\"button\"\n (click)=\"clearRelative(row)\">\n Clear\n </button>\n </div>\n }\n }\n @case ('select') {\n <fs-autocomplete-chips\n class=\"fs-flex\"\n [label]=\"'Default ' + row.label\"\n [fetch]=\"row.fetch\"\n [(ngModel)]=\"row.values\"\n [name]=\"'values' + row.group.id\"\n [multiple]=\"true\"\n [fetchOnFocus]=\"true\">\n <ng-template\n fsAutocompleteChipsTemplate\n let-object=\"object\">\n {{ object.name }}\n </ng-template>\n </fs-autocomplete-chips>\n }\n @default {\n <mat-form-field class=\"fs-flex\">\n <mat-label>\n Default {{ row.label }}\n </mat-label>\n <input\n matInput\n [(ngModel)]=\"row.value\"\n [name]=\"'value' + row.group.id\">\n </mat-form-field>\n }\n }\n }\n } @else {\n <fs-message-info>\n This report has no report-level filters yet. Add a filter to a\n component (its settings \u2192 Filters) and show it in the report bar,\n then set its default here.\n </fs-message-info>\n }\n </div>\n </mat-tab>\n </mat-tab-group>\n </mat-dialog-content>\n <mat-dialog-actions>\n <fs-form-dialog-actions>\n <button\n type=\"button\"\n mat-button\n color=\"warn\"\n (click)=\"delete()\">\n Delete\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}\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.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { 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.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { 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: "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: FsMessageModule }, { kind: "component", type: i5.FsMessageInfoComponent, selector: "fs-message-info" }, { 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: FsDatePickerModule }, { kind: "component", type: i7.FsDatePickerComponent, selector: "[fsDatePicker]", inputs: ["minYear", "maxYear", "minDate", "maxDate", "startOfDay", "view", "format", "minutes", "width"], outputs: ["change"] }, { kind: "ngmodule", type: FsAutocompleteChipsModule }, { kind: "component", type: i8.FsAutocompleteChipsComponent, selector: "fs-autocomplete-chips", inputs: ["fetch", "appearance", "floatLabel", "readonly", "size", "label", "placeholder", "chipImage", "chipBackground", "chipColor", "chipIcon", "chipIconColor", "chipClass", "chipPadding", "shape", "hint", "allowText", "allowObject", "delay", "minPanelWidth", "maxPanelHeight", "validateText", "removable", "allowClear", "color", "background", "orderable", "padless", "initOnClick", "fetchOnFocus", "multiple", "multipleAdd", "confirm", "disabled", "groupBy", "panelWidth", "panelClass", "compareWith"], outputs: ["selected", "removed", "reordered", "clear", "panelOpened", "panelClosed"] }, { kind: "directive", type: i8.FsAutocompleteObjectDirective, selector: "[fsAutocompleteObject],[fsAutocompleteChipsTemplate]" }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i9.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass"], exportAs: ["matTab"] }, { kind: "component", type: i9.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: "component", type: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { 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: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { 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: 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: MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: TimezoneSelectComponent, selector: "fs-ai-report-timezone-select", inputs: ["placeholder", "required", "disabled", "timezone"], outputs: ["timezoneChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
235
260
  }
236
261
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportSettingsComponent, decorators: [{
237
262
  type: Component,
@@ -257,6 +282,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
257
282
  MatSelect,
258
283
  MatOption,
259
284
  TimezoneSelectComponent,
260
- ], template: "<form\n fsForm\n [submit]=\"save\">\n <fs-dialog>\n <h1 mat-dialog-title>\n Report Settings\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 <mat-form-field>\n <mat-label>\n Name\n </mat-label>\n <input\n matInput\n [(ngModel)]=\"name\"\n name=\"name\"\n [fsFormRequired]=\"true\">\n </mat-form-field>\n <!--\n The page, typed in inches. Orientation is not asked for because it\n is not an independent choice - a page wider than it is tall IS\n landscape - so the two numbers say everything there is to say.\n -->\n <div class=\"fs-row.gap-sm.align-start\">\n <mat-form-field class=\"fs-flex\">\n <mat-label>\n Width\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"1\"\n [(ngModel)]=\"pageWidth\"\n name=\"pageWidth\"\n [fsFormRequired]=\"true\"\n [fsFormMin]=\"pageDimensionMin\"\n [fsFormMax]=\"pageDimensionMax\">\n <div matTextSuffix>\n inches\n </div>\n </mat-form-field>\n <mat-form-field class=\"fs-flex\">\n <mat-label>\n Height\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"1\"\n [(ngModel)]=\"pageHeight\"\n name=\"pageHeight\"\n [fsFormRequired]=\"true\"\n [fsFormMin]=\"pageDimensionMin\"\n [fsFormMax]=\"pageDimensionMax\">\n <div matTextSuffix>\n inches\n </div>\n </mat-form-field>\n </div>\n <!--\n How deep the header and footer bands are. Their content is edited\n on the canvas (Edit layout \u2192 Header & footer); these reserve the\n space for it, and 0 means no band.\n -->\n <mat-form-field class=\"full-width\">\n <mat-label>\n Header height\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"2\"\n [(ngModel)]=\"headerHeight\"\n name=\"headerHeight\"\n [fsFormMin]=\"0\"\n [fsFormMax]=\"headerFooterMax\">\n <div matTextSuffix>\n inches\n </div>\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Footer height\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"2\"\n [(ngModel)]=\"footerHeight\"\n name=\"footerHeight\"\n [fsFormMin]=\"0\"\n [fsFormMax]=\"headerFooterMax\">\n <div matTextSuffix>\n inches\n </div>\n </mat-form-field>\n <mat-form-field>\n <mat-label>\n Layout\n </mat-label>\n <mat-select\n [(ngModel)]=\"layout\"\n name=\"layout\">\n <mat-option value=\"freeform\">\n Freeform \u2014 position components anywhere on the page\n </mat-option>\n <mat-option value=\"flow\">\n Flow \u2014 components flow into rows by width %\n </mat-option>\n </mat-select>\n <mat-hint>\n Freeform is like PowerPoint; Flow is like a responsive dashboard.\n </mat-hint>\n </mat-form-field>\n <fs-ai-report-timezone-select [(timezone)]=\"timezone\"></fs-ai-report-timezone-select>\n </div>\n </mat-tab>\n <mat-tab\n label=\"Styles\"\n name=\"styles\">\n <div class=\"fs-column tab-body\">\n <mat-form-field>\n <mat-label>\n Heading Size\n </mat-label>\n <input\n matInput\n type=\"number\"\n step=\"1\"\n min=\"6\"\n max=\"96\"\n [(ngModel)]=\"headingSize\"\n name=\"headingSize\"\n [fsFormMin]=\"6\"\n [fsFormMax]=\"96\">\n <span matTextSuffix>\n pt\n </span>\n <mat-hint>\n Applies to component titles. Points map 1:1 to PDF and PowerPoint.\n </mat-hint>\n </mat-form-field>\n </div>\n </mat-tab>\n <mat-tab\n label=\"Filters\"\n name=\"filters\">\n <div class=\"fs-column tab-body\">\n @if (filterRows().length) {\n @for (row of filterRows(); track row.group.id) {\n @switch (row.group.type) {\n @case ('dateRange') {\n <div class=\"fs-row.gap-sm.align-center fs-flex\">\n <mat-form-field class=\"fs-flex\">\n <mat-label>\n Default From {{ row.label }}\n </mat-label>\n <input\n matInput\n fsDatePicker\n [(ngModel)]=\"row.start\"\n [name]=\"'start' + row.group.id\">\n </mat-form-field>\n <mat-form-field class=\"fs-flex\">\n <mat-label>\n Default To {{ row.label }}\n </mat-label>\n <input\n matInput\n fsDatePicker\n [(ngModel)]=\"row.end\"\n [name]=\"'end' + row.group.id\">\n </mat-form-field>\n </div>\n }\n @case ('select') {\n <fs-autocomplete-chips\n class=\"fs-flex\"\n [label]=\"'Default ' + row.label\"\n [fetch]=\"row.fetch\"\n [(ngModel)]=\"row.values\"\n [name]=\"'values' + row.group.id\"\n [multiple]=\"true\"\n [fetchOnFocus]=\"true\">\n <ng-template\n fsAutocompleteChipsTemplate\n let-object=\"object\">\n {{ object.name }}\n </ng-template>\n </fs-autocomplete-chips>\n }\n @default {\n <mat-form-field class=\"fs-flex\">\n <mat-label>\n Default {{ row.label }}\n </mat-label>\n <input\n matInput\n [(ngModel)]=\"row.value\"\n [name]=\"'value' + row.group.id\">\n </mat-form-field>\n }\n }\n }\n } @else {\n <fs-message-info>\n This report has no report-level filters yet. Add a filter to a\n component (its settings \u2192 Filters) and show it in the report bar,\n then set its default here.\n </fs-message-info>\n }\n </div>\n </mat-tab>\n </mat-tab-group>\n </mat-dialog-content>\n <mat-dialog-actions>\n <fs-form-dialog-actions>\n <button\n type=\"button\"\n mat-button\n color=\"warn\"\n (click)=\"delete()\">\n Delete\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}\n"] }]
285
+ ], template: "<form\n fsForm\n [submit]=\"save\">\n <fs-dialog>\n <h1 mat-dialog-title>\n Report Settings\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 <mat-form-field>\n <mat-label>\n Name\n </mat-label>\n <input\n matInput\n [(ngModel)]=\"name\"\n name=\"name\"\n [fsFormRequired]=\"true\">\n </mat-form-field>\n <!--\n The page, typed in inches. Orientation is not asked for because it\n is not an independent choice - a page wider than it is tall IS\n landscape - so the two numbers say everything there is to say.\n -->\n <div class=\"fs-row.gap-sm.align-start\">\n <mat-form-field class=\"fs-flex\">\n <mat-label>\n Width\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"1\"\n [(ngModel)]=\"pageWidth\"\n name=\"pageWidth\"\n [fsFormRequired]=\"true\"\n [fsFormMin]=\"pageDimensionMin\"\n [fsFormMax]=\"pageDimensionMax\">\n <div matTextSuffix>\n inches\n </div>\n </mat-form-field>\n <mat-form-field class=\"fs-flex\">\n <mat-label>\n Height\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"1\"\n [(ngModel)]=\"pageHeight\"\n name=\"pageHeight\"\n [fsFormRequired]=\"true\"\n [fsFormMin]=\"pageDimensionMin\"\n [fsFormMax]=\"pageDimensionMax\">\n <div matTextSuffix>\n inches\n </div>\n </mat-form-field>\n </div>\n <!--\n How deep the header and footer bands are. Their content is edited\n on the canvas (Edit layout \u2192 Header & footer); these reserve the\n space for it, and 0 means no band.\n -->\n <mat-form-field class=\"full-width\">\n <mat-label>\n Header height\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"2\"\n [(ngModel)]=\"headerHeight\"\n name=\"headerHeight\"\n [fsFormMin]=\"0\"\n [fsFormMax]=\"headerFooterMax\">\n <div matTextSuffix>\n inches\n </div>\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Footer height\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"2\"\n [(ngModel)]=\"footerHeight\"\n name=\"footerHeight\"\n [fsFormMin]=\"0\"\n [fsFormMax]=\"headerFooterMax\">\n <div matTextSuffix>\n inches\n </div>\n </mat-form-field>\n <mat-form-field>\n <mat-label>\n Layout\n </mat-label>\n <mat-select\n [(ngModel)]=\"layout\"\n name=\"layout\">\n <mat-option value=\"freeform\">\n Freeform \u2014 position components anywhere on the page\n </mat-option>\n <mat-option value=\"flow\">\n Flow \u2014 components flow into rows by width %\n </mat-option>\n </mat-select>\n <mat-hint>\n Freeform is like PowerPoint; Flow is like a responsive dashboard.\n </mat-hint>\n </mat-form-field>\n <fs-ai-report-timezone-select [(timezone)]=\"timezone\"></fs-ai-report-timezone-select>\n </div>\n </mat-tab>\n <mat-tab\n label=\"Styles\"\n name=\"styles\">\n <div class=\"fs-column tab-body\">\n <mat-form-field>\n <mat-label>\n Heading Size\n </mat-label>\n <input\n matInput\n type=\"number\"\n step=\"1\"\n min=\"6\"\n max=\"96\"\n [(ngModel)]=\"headingSize\"\n name=\"headingSize\"\n [fsFormMin]=\"6\"\n [fsFormMax]=\"96\">\n <span matTextSuffix>\n pt\n </span>\n <mat-hint>\n Applies to component titles. Points map 1:1 to PDF and PowerPoint.\n </mat-hint>\n </mat-form-field>\n </div>\n </mat-tab>\n <mat-tab\n label=\"Filters\"\n name=\"filters\">\n <div class=\"fs-column tab-body\">\n @if (filterRows().length) {\n @for (row of filterRows(); track row.group.id) {\n @switch (row.group.type) {\n @case ('dateRange') {\n <div class=\"fs-row.gap-sm.align-center fs-flex\">\n <mat-form-field class=\"fs-flex\">\n <mat-label>\n Default From {{ row.label }}\n </mat-label>\n <input\n matInput\n fsDatePicker\n [(ngModel)]=\"row.start\"\n [name]=\"'start' + row.group.id\">\n </mat-form-field>\n <mat-form-field class=\"fs-flex\">\n <mat-label>\n Default To {{ row.label }}\n </mat-label>\n <input\n matInput\n fsDatePicker\n [(ngModel)]=\"row.end\"\n [name]=\"'end' + row.group.id\">\n </mat-form-field>\n </div>\n <!-- A stored rolling preset cannot be authored here, only\n kept, replaced by picking dates, or cleared. type=\"button\"\n keeps Clear from submitting the form. -->\n @if (row.relative && !row.start && !row.end) {\n <div class=\"fs-row.gap-sm.align-center\">\n <mat-hint class=\"fs-flex\">\n Rolling default: {{ relativeLabel(row.relative) }}. Pick dates to replace it.\n </mat-hint>\n <button\n mat-button\n type=\"button\"\n (click)=\"clearRelative(row)\">\n Clear\n </button>\n </div>\n }\n }\n @case ('select') {\n <fs-autocomplete-chips\n class=\"fs-flex\"\n [label]=\"'Default ' + row.label\"\n [fetch]=\"row.fetch\"\n [(ngModel)]=\"row.values\"\n [name]=\"'values' + row.group.id\"\n [multiple]=\"true\"\n [fetchOnFocus]=\"true\">\n <ng-template\n fsAutocompleteChipsTemplate\n let-object=\"object\">\n {{ object.name }}\n </ng-template>\n </fs-autocomplete-chips>\n }\n @default {\n <mat-form-field class=\"fs-flex\">\n <mat-label>\n Default {{ row.label }}\n </mat-label>\n <input\n matInput\n [(ngModel)]=\"row.value\"\n [name]=\"'value' + row.group.id\">\n </mat-form-field>\n }\n }\n }\n } @else {\n <fs-message-info>\n This report has no report-level filters yet. Add a filter to a\n component (its settings \u2192 Filters) and show it in the report bar,\n then set its default here.\n </fs-message-info>\n }\n </div>\n </mat-tab>\n </mat-tab-group>\n </mat-dialog-content>\n <mat-dialog-actions>\n <fs-form-dialog-actions>\n <button\n type=\"button\"\n mat-button\n color=\"warn\"\n (click)=\"delete()\">\n Delete\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}\n"] }]
261
286
  }] });
262
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0LXNldHRpbmdzLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvcmVwb3J0cy9kaWFsb2dzL3JlcG9ydC1zZXR0aW5ncy9yZXBvcnQtc2V0dGluZ3MuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9yZXBvcnRzL2RpYWxvZ3MvcmVwb3J0LXNldHRpbmdzL3JlcG9ydC1zZXR0aW5ncy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBVSxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3ZHLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ2hFLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUU3QyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDckQsT0FBTyxFQUFFLGVBQWUsRUFBRSxnQkFBZ0IsRUFBRSxnQkFBZ0IsRUFBRSxZQUFZLEVBQUUsY0FBYyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDN0gsT0FBTyxFQUFFLFlBQVksRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQzFGLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNuRCxPQUFPLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ2hFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUV2RCxPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUMzRSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUM1RCxPQUFPLEVBQUUs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O3dCQUNmLFlBQVk7d0JBQ1osa0JBQWtCO3dCQUNsQix5QkFBeUI7d0JBQ3pCLGFBQWE7d0JBQ2IsU0FBUzt3QkFDVCxjQUFjO3dCQUNkLGdCQUFnQjt3QkFDaEIsZ0JBQWdCO3dCQUNoQixZQUFZO3dCQUNaLFFBQVE7d0JBQ1IsT0FBTzt3QkFDUCxTQUFTO3dCQUNULFFBQVE7d0JBQ1IsU0FBUzt3QkFDVCxTQUFTO3dCQUNULHVCQUF1QjtxQkFDeEIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ29tcG9uZW50LCBEZXN0cm95UmVmLCBPbkluaXQsIGluamVjdCwgc2lnbmFsIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyB0YWtlVW50aWxEZXN0cm95ZWQgfSBmcm9tICdAYW5ndWxhci9jb3JlL3J4anMtaW50ZXJvcCc7XG5pbXBvcnQgeyBGb3Jtc01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcblxuaW1wb3J0IHsgTWF0QnV0dG9uIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvYnV0dG9uJztcbmltcG9ydCB7IE1BVF9ESUFMT0dfREFUQSwgTWF0RGlhbG9nQWN0aW9ucywgTWF0RGlhbG9nQ29udGVudCwgTWF0RGlhbG9nUmVmLCBNYXREaWFsb2dUaXRsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2RpYWxvZyc7XG5pbXBvcnQgeyBNYXRGb3JtRmllbGQsIE1hdExhYmVsLCBNYXRIaW50LCBNYXRTdWZmaXggfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9mb3JtLWZpZWxkJztcbmltcG9ydCB7IE1hdElucHV0IH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvaW5wdXQnO1xuaW1wb3J0IHsgTWF0T3B0aW9uLCBNYXRTZWxlY3QgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9zZWxlY3QnO1xuaW1wb3J0IHsgTWF0VGFic01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3RhYnMnO1xuXG5pbXBvcnQgeyBGc0F1dG9jb21wbGV0ZUNoaXBzTW9kdWxlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvYXV0b2NvbXBsZXRlLWNoaXBzJztcbmltcG9ydCB7IEZzRGF0ZVBpY2tlck1vZHVsZSB9IGZyb20gJ0BmaXJlc3RpdGNoL2RhdGVwaWNrZXInO1xuaW1wb3J0IHsgRnNEaWFsb2dNb2R1bGUgfSBmcm9tICdAZmlyZXN0aXRjaC9kaWFsb2cnO1xuaW1wb3J0IHsgRnNGb3JtTW9kdWxlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvZm9ybSc7XG5pbXBvcnQgeyBGc01hc2tNb2R1bGUgfSBmcm9tICdAZmlyZXN0aXRjaC9tYXNrJztcbmltcG9ydCB7IEZzTWVzc2FnZSwgRnNNZXNzYWdlTW9kdWxlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvbWVzc2FnZSc7XG5pbXBvcnQgeyBGc1Byb21wdCB9IGZyb20gJ0BmaXJlc3RpdGNoL3Byb21wdCc7XG5pbXBvcnQgeyBGc1RhYnNNb2R1bGUgfSBmcm9tICdAZmlyZXN0aXRjaC90YWJzJztcblxuaW1wb3J0IHsgVGltZXpvbmVTZWxlY3RDb21wb25lbnQgfSBmcm9tICcuLi8uLi9jb21wb25lbnRzL3RpbWV6b25lLXNlbGVjdC90aW1lem9uZS1zZWxlY3QuY29tcG9uZW50JztcblxuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgZm9ya0pvaW4gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IHN3aXRjaE1hcCwgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBSZXBvcnREYXRhIH0gZnJvbSAnLi4vLi4vZGF0YS9yZXBvcnQuZGF0YSc7XG5pbXBvcnQge1xuICBGaWx0ZXJHcm91cERlZmF1bHQsXG4gIFJlcG9ydCxcbiAgUmVwb3J0RmlsdGVyR3JvdXAsXG59IGZyb20gJy4uLy4uL2ludGVyZmFjZXMvcmVwb3J0LmludGVyZmFjZSc7XG5pbXBvcnQgeyBERUZBVUxUX0hFQURJTkdfU0laRSwgSEVBREVSX0ZPT1RFUl9NQVgsIFBBR0VfRElNRU5TSU9OX01BWCwgUEFHRV9ESU1FTlNJT05fTUlOIH0gZnJvbSAnLi4vLi4vbGF5b3V0JztcbmltcG9ydCB7IGxvYWRHcm91cE9wdGlvbnMsIG1hdGNoT3B0aW9ucywgcmVzb2x2ZU9wdGlvblZhbHVlcyB9IGZyb20gJy4uLy4uL3JlcG9ydC1maWx0ZXItaXRlbXMnO1xuaW1wb3J0IHsgZGF0ZUZyb21Cb3VuZCwgZGF0ZVRvQm91bmQgfSBmcm9tICcuL3JlcG9ydC1zZXR0aW5ncy1kZWZhdWx0JztcblxuXG4vLyBXaGF0IHRoZSBkaWFsb2cgaGFuZHMgYmFjayB3aGVuIGl0IGNsb3Nlcywgc28gdGhlIHBhZ2Uga25vd3Mgd2hhdCBoYXBwZW5lZFxuLy8gd2l0aG91dCBzbmlmZmluZyBtYWdpYyBzdHJpbmdzLiBBIGRpc21pc3NlZCBkaWFsb2cgY2xvc2VzIHdpdGggYHVuZGVmaW5lZGAuXG5leHBvcnQgaW50ZXJmYWNlIFJlcG9ydFNldHRpbmdzUmVzdWx0IHtcbiAgYWN0aW9uOiAnc2F2ZWQnIHwgJ2RlbGV0ZWQnO1xufVxuXG5cbi8vIE9uZSByZXBvcnQtbGV2ZWwgZmlsdGVyIGluIHRoZSBGaWx0ZXJzIHRhYjogaXRzIGdyb3VwLCB0aGUgaW5mZXJyZWQgaW50ZXJmYWNlLFxuLy8gYW5kIGFuIGVkaXRhYmxlIGRyYWZ0IGRlZmF1bHQuIFRoZSBkcmFmdCBmaWVsZHMgdXNlZCBkZXBlbmQgb24gdGhlIHR5cGVcbi8vIChkYXRlUmFuZ2Ug4oaSIHN0YXJ0L2VuZCBEYXRlczsgc2VsZWN0IOKGkiB2YWx1ZXM7IGtleXdvcmQg4oaSIHRleHQpLiBgZmV0Y2hgIGxvYWRzXG4vLyB0aGUgc2VsZWN0IG9wdGlvbnMgdGhlIHNhbWUgd2F5IHRoZSByZXBvcnQgYmFyIGRvZXMuXG5pbnRlcmZhY2UgRmlsdGVyRGVmYXVsdFJvdyB7XG4gIGdyb3VwOiBSZXBvcnRGaWx0ZXJHcm91cDtcbiAgbGFiZWw6IHN0cmluZztcbiAgc3RhcnQ6IERhdGUgfCBudWxsO1xuICBlbmQ6IERhdGUgfCBudWxsO1xuICB2YWx1ZXM6IHsgbmFtZTogc3RyaW5nOyB2YWx1ZTogdW5rbm93biB9W107XG4gIHZhbHVlOiBzdHJpbmc7XG4gIGZldGNoOiAoa2V5d29yZD86IHN0cmluZykgPT4gT2JzZXJ2YWJsZTx7IG5hbWU6IHN0cmluZzsgdmFsdWU6IHVua25vd24gfVtdPjtcbn1cblxuXG4vLyBSZXBvcnQgc2V0dGluZ3MsIGluIHRocmVlIHRhYnM6XG4vLyAgIFNldHRpbmdzIOKAlCBuYW1lICsgcGFnZSBzZXR1cCAoc2l6ZSBpbiBpbmNoZXMsIGhlYWRlci9mb290ZXIgYmFuZCBkZXB0aHMsXG4vLyAgIGxheW91dCBtb2RlKS5cbi8vICAgU3R5bGVzICAg4oCUIHRoZSByZXBvcnQncyB0eXBvZ3JhcGhpYyBzdHlsZXMgKHNpemVzIGluIFBPSU5UUywgMToxIHdpdGhcbi8vICAgUERGL1Bvd2VyUG9pbnQpOyB0aGUgSGVhZGluZyBzaXplIHRvIHN0YXJ0LlxuLy8gICBGaWx0ZXJzICDigJQgdGhlIHJlcG9ydC1sZXZlbCBmaWx0ZXJzIGFuZCB0aGVpciBERUZBVUxUIHZhbHVlcy4gQSBkZWZhdWx0XG4vLyAgIHNlZWRzIHRoZSByZXBvcnQgYmFyIG9uIGV2ZXJ5IG9wZW4gKGZvciBldmVyeSB2aWV3ZXIpIGJ1dCBzdGF5c1xuLy8gICB1c2VyLWNoYW5nZWFibGUg4oCUIGl0IHByZS1maWxscyB0aGUgY29udHJvbCwgaXQgZG9lc24ndCBsb2NrIGl0LiBUaGlzIGlzIHRoZVxuLy8gICBmaXggZm9yIGhlYXZ5IHJlcG9ydHMgb3BlbmluZyBibGFuayBhbmQgdGltaW5nIG91dDogYSBkZWZhdWx0IG1vbnRoICtcbi8vICAgb3JnYW5pemF0aW9uIHNjb3BlcyB0aGUgbGFuZGluZyBwYWdlIGZyb20gdGhlIGZpcnN0IGxvYWQuXG5AQ29tcG9uZW50KHtcbiAgdGVtcGxhdGVVcmw6ICcuL3JlcG9ydC1zZXR0aW5ncy5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3JlcG9ydC1zZXR0aW5ncy5jb21wb25lbnQuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIEZvcm1zTW9kdWxlLFxuICAgIEZzRm9ybU1vZHVsZSxcbiAgICBGc01hc2tNb2R1bGUsXG4gICAgRnNEaWFsb2dNb2R1bGUsXG4gICAgRnNNZXNzYWdlTW9kdWxlLFxuICAgIEZzVGFic01vZHVsZSxcbiAgICBGc0RhdGVQaWNrZXJNb2R1bGUsXG4gICAgRnNBdXRvY29tcGxldGVDaGlwc01vZHVsZSxcbiAgICBNYXRUYWJzTW9kdWxlLFxuICAgIE1hdEJ1dHRvbixcbiAgICBNYXREaWFsb2dUaXRsZSxcbiAgICBNYXREaWFsb2dDb250ZW50LFxuICAgIE1hdERpYWxvZ0FjdGlvbnMsXG4gICAgTWF0Rm9ybUZpZWxkLFxuICAgIE1hdExhYmVsLFxuICAgIE1hdEhpbnQsXG4gICAgTWF0U3VmZml4LFxuICAgIE1hdElucHV0LFxuICAgIE1hdFNlbGVjdCxcbiAgICBNYXRPcHRpb24sXG4gICAgVGltZXpvbmVTZWxlY3RDb21wb25lbnQsXG4gIF0sXG59KVxuZXhwb3J0IGNsYXNzIFJlcG9ydFNldHRpbmdzQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcblxuICBwdWJsaWMgc2VsZWN0ZWRUYWIgPSAnc2V0dGluZ3MnO1xuXG4gIHB1YmxpYyBuYW1lID0gJyc7XG4gIC8vIFRoZSBwYWdlIGluIGluY2hlcy4gTm8gaW5pdGlhbGl6ZXI6IGV2ZXJ5IHJlcG9ydCBjYXJyaWVzIGEgc2l6ZSwgYW5kXG4gIC8vIG5nT25Jbml0IHNlZWRzIGJvdGggYmVmb3JlIHRoZSB0YWIgcmVuZGVycywgc28gYSBwbGFjZWhvbGRlciBoZXJlIGNvdWxkIG9ubHlcbiAgLy8gZXZlciBiZSBhIHdyb25nIG51bWJlciBicmllZmx5IHNob3dpbmcgYXMgdGhlIG9wZXJhdG9yJ3Mgb3duLlxuICAvL1xuICAvLyBUeXBlZCBgbnVtYmVyIHwgc3RyaW5nYCBiZWNhdXNlIGZzTWFza051bWJlciBpcyB0aGUgY29udHJvbDogaXQgaXMgc2VlZGVkXG4gIC8vIHdpdGggdGhlIHJlcG9ydCdzIG51bWJlciBidXQgaGFuZHMgYmFjayB0aGUgdW5tYXNrZWQgU1RSSU5HIHRoZSBvcGVyYXRvclxuICAvLyB0eXBlZC4gU2F2ZSBjYXN0cyBpdCBvbmNlLCBvbiB0aGUgd2F5IG91dCDigJQgc2VlIGBfcGFnZURpbWVuc2lvbigpYC5cbiAgcHVibGljIHBhZ2VXaWR0aDogbnVtYmVyIHwgc3RyaW5nO1xuICBwdWJsaWMgcGFnZUhlaWdodDogbnVtYmVyIHwgc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgcGFnZURpbWVuc2lvbk1pbiA9IFBBR0VfRElNRU5TSU9OX01JTjtcbiAgcHVibGljIHJlYWRvbmx5IHBhZ2VEaW1lbnNpb25NYXggPSBQQUdFX0RJTUVOU0lPTl9NQVg7XG4gIC8vIFRoZSBoZWFkZXIgYW5kIGZvb3RlciBiYW5kIGRlcHRocywgaW5jaGVzIOKAlCB0eXBlZCBsaWtlIHRoZSBwYWdlIHNpemVcbiAgLy8gYmVjYXVzZSBmc01hc2tOdW1iZXIgaGFuZHMgYmFjayBhIHN0cmluZy5cbiAgcHVibGljIGhlYWRlckhlaWdodDogbnVtYmVyIHwgc3RyaW5nID0gMDtcbiAgcHVibGljIGZvb3RlckhlaWdodDogbnVtYmVyIHwgc3RyaW5nID0gMDtcbiAgcHVibGljIHJlYWRvbmx5IGhlYWRlckZvb3Rlck1heCA9IEhFQURFUl9GT09URVJfTUFYO1xuICBwdWJsaWMgbGF5b3V0OiAnZnJlZWZvcm0nIHwgJ2Zsb3cnID0gJ2ZyZWVmb3JtJztcbiAgLy8gRW1wdHkgdW50aWwgdGhlIHJlcG9ydCBoYXMgb25lOyBhcHAtdGltZXpvbmUtc2VsZWN0IHRoZW4gZGVmYXVsdHMgaXQgdG8gdGhlXG4gIC8vIHZpZXdlcidzIGJyb3dzZXIgem9uZSAod2hpY2ggU2F2ZSBwZXJzaXN0cywgbWFraW5nIHRoZSByZXBvcnQncyB6b25lIGV4cGxpY2l0KS5cbiAgcHVibGljIHRpbWV6b25lID0gJyc7XG4gIHB1YmxpYyBoZWFkaW5nU2l6ZSA9IERFRkFVTFRfSEVBRElOR19TSVpFO1xuXG4gIC8vIFRoZSByZXBvcnQtbGV2ZWwgZmlsdGVycyBhbmQgdGhlaXIgZWRpdGFibGUgZGVmYXVsdCB2YWx1ZXMgKEZpbHRlcnMgdGFiKS5cbiAgcHVibGljIHJlYWRvbmx5IGZpbHRlclJvd3MgPSBzaWduYWw8RmlsdGVyRGVmYXVsdFJvd1tdPihbXSk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfZGF0YTogeyByZXBvcnQ6IFJlcG9ydCB9ID0gaW5qZWN0KE1BVF9ESUFMT0dfREFUQSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX2RpYWxvZ1JlZiA9IGluamVjdDxNYXREaWFsb2dSZWY8UmVwb3J0U2V0dGluZ3NDb21wb25lbnQsIFJlcG9ydFNldHRpbmdzUmVzdWx0Pj4oTWF0RGlhbG9nUmVmKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfcmVwb3J0RGF0YSA9IGluamVjdChSZXBvcnREYXRhKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfbWVzc2FnZSA9IGluamVjdChGc01lc3NhZ2UpO1xuICBwcml2YXRlIHJlYWRvbmx5IF9wcm9tcHQgPSBpbmplY3QoRnNQcm9tcHQpO1xuICBwcml2YXRlIHJlYWRvbmx5IF9kZXN0cm95UmVmID0gaW5qZWN0KERlc3Ryb3lSZWYpO1xuXG4gIHB1YmxpYyBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICBjb25zdCByZXBvcnQgPSB0aGlzLl9kYXRhLnJlcG9ydDtcbiAgICB0aGlzLm5hbWUgPSByZXBvcnQubmFtZTtcbiAgICB0aGlzLnBhZ2VXaWR0aCA9IHJlcG9ydC5wYWdlV2lkdGg7XG4gICAgdGhpcy5wYWdlSGVpZ2h0ID0gcmVwb3J0LnBhZ2VIZWlnaHQ7XG4gICAgdGhpcy5oZWFkZXJIZWlnaHQgPSByZXBvcnQuY29uZmlnPy5oZWFkZXJGb290ZXI/LmhlYWRlckhlaWdodCA/PyAwO1xuICAgIHRoaXMuZm9vdGVySGVpZ2h0ID0gcmVwb3J0LmNvbmZpZz8uaGVhZGVyRm9vdGVyPy5mb290ZXJIZWlnaHQgPz8gMDtcbiAgICB0aGlzLmxheW91dCA9IHJlcG9ydC5sYXlvdXQgPz8gJ2ZyZWVmb3JtJztcbiAgICB0aGlzLnRpbWV6b25lID0gcmVwb3J0LnRpbWV6b25lID8/ICcnO1xuICAgIHRoaXMuaGVhZGluZ1NpemUgPSByZXBvcnQuY29uZmlnPy5zdHlsZXM/LmhlYWRpbmc/LnNpemUgPz8gREVGQVVMVF9IRUFESU5HX1NJWkU7XG5cbiAgICB0aGlzLl9idWlsZEZpbHRlclJvd3MocmVwb3J0KTtcbiAgfVxuXG4gIC8vIENvbmZpcm0gYW5kIGRlbGV0ZSBoZXJlLCB3aGlsZSB0aGUgZGlhbG9nIGlzIHN0aWxsIG9wZW4sIHRoZW4gY2xvc2Ugd2l0aFxuICAvLyBhIGBkZWxldGVkYCByZXN1bHQuIFRoZSBwYWdlIHJlYWN0cyB0byB0aGUgcmVzdWx0OyBpdCBubyBsb25nZXIgb3ducyB0aGVcbiAgLy8gcHJvbXB0IG9yIHRoZSBBUEkgY2FsbC5cbiAgcHVibGljIGRlbGV0ZSgpOiB2b2lkIHtcbiAgICB0aGlzLl9wcm9tcHQuY29uZmlybSh7XG4gICAgICB0aXRsZTogJ0RlbGV0ZSBSZXBvcnQnLFxuICAgICAgdGVtcGxhdGU6IGBEZWxldGUgXCIke3RoaXMuX2RhdGEucmVwb3J0Lm5hbWV9XCI/IFRoaXMgY2Fubm90IGJlIHVuZG9uZS5gLFxuICAgIH0pXG4gICAgICAucGlwZShcbiAgICAgICAgc3dpdGNoTWFwKCgpID0+IHRoaXMuX3JlcG9ydERhdGEuZGVsZXRlKHRoaXMuX2RhdGEucmVwb3J0LmlkKSksXG4gICAgICAgIHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLl9kZXN0cm95UmVmKSxcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICB0aGlzLl9tZXNzYWdlLnN1Y2Nlc3MoJ1JlcG9ydCBkZWxldGVkJyk7XG4gICAgICAgIHRoaXMuX2RpYWxvZ1JlZi5jbG9zZSh7IGFjdGlvbjogJ2RlbGV0ZWQnIH0pO1xuICAgICAgfSk7XG4gIH1cblxuICBwdWJsaWMgc2F2ZSA9ICgpID0+IHtcbiAgICBjb25zdCByZXBvcnRJZCA9IHRoaXMuX2RhdGEucmVwb3J0LmlkO1xuXG4gICAgLy8gUGVyc2lzdCB0aGUgcmVwb3J0IHNldHRpbmdzIGFuZCBlYWNoIGNoYW5nZWQgZmlsdGVyIGRlZmF1bHQgdG9nZXRoZXIsIHNvXG4gICAgLy8gdGhlIHNpbmdsZSBTYXZlIGNvdmVycyBhbGwgdGhyZWUgdGFicy4gVGhlIHJlcG9ydCByZWxvYWRzIG9uIHRoZSBgc2F2ZWRgXG4gICAgLy8gcmVzdWx0LCByZS1zZWVkaW5nIHRoZSBiYXIgZnJvbSB0aGUgbmV3IGRlZmF1bHRzLlxuICAgIGNvbnN0IHNldHRpbmdzJCA9IHRoaXMuX3JlcG9ydERhdGEudXBkYXRlKHJlcG9ydElkLCB7XG4gICAgICBuYW1lOiB0aGlzLm5hbWUsXG4gICAgICBwYWdlV2lkdGg6IHRoaXMuX3BhZ2VEaW1lbnNpb24odGhpcy5wYWdlV2lkdGgpLFxuICAgICAgcGFnZUhlaWdodDogdGhpcy5fcGFnZURpbWVuc2lvbih0aGlzLnBhZ2VIZWlnaHQpLFxuICAgICAgbGF5b3V0OiB0aGlzLmxheW91dCxcbiAgICAgIHRpbWV6b25lOiB0aGlzLnRpbWV6b25lLFxuICAgICAgc3R5bGVzOiB7IGhlYWRpbmc6IHsgc2l6ZTogdGhpcy5oZWFkaW5nU2l6ZSB9IH0sXG4gICAgICBoZWFkZXJGb290ZXI6IHtcbiAgICAgICAgaGVhZGVySGVpZ2h0OiB0aGlzLl9wYWdlRGltZW5zaW9uKHRoaXMuaGVhZGVySGVpZ2h0KSB8fCAwLFxuICAgICAgICBmb290ZXJIZWlnaHQ6IHRoaXMuX3BhZ2VEaW1lbnNpb24odGhpcy5mb290ZXJIZWlnaHQpIHx8IDAsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgY29uc3QgZGVmYXVsdHMkID0gdGhpcy5maWx0ZXJSb3dzKClcbiAgICAgIC5maWx0ZXIoKHJvdykgPT4gdGhpcy5fZGVmYXVsdENoYW5nZWQocm93KSlcbiAgICAgIC5tYXAoKHJvdykgPT4gdGhpcy5fcmVwb3J0RGF0YS51cGRhdGVGaWx0ZXJHcm91cChyZXBvcnRJZCwgcm93Lmdyb3VwLmlkLCB7XG4gICAgICAgIGRlZmF1bHQ6IHRoaXMuX3Jvd0RlZmF1bHQocm93KSxcbiAgICAgIH0pKTtcblxuICAgIHJldHVybiBmb3JrSm9pbihbc2V0dGluZ3MkLCAuLi5kZWZhdWx0cyRdKVxuICAgICAgLnBpcGUoXG4gICAgICAgIHRhcCgoKSA9PiB7XG4gICAgICAgICAgdGhpcy5fbWVzc2FnZS5zdWNjZXNzKCdSZXBvcnQgc2V0dGluZ3Mgc2F2ZWQnKTtcbiAgICAgICAgICB0aGlzLl9kaWFsb2dSZWYuY2xvc2UoeyBhY3Rpb246ICdzYXZlZCcgfSk7XG4gICAgICAgIH0pLFxuICAgICAgKTtcbiAgfTtcblxuICAvLyBUaGUgcGFnZSBkaW1lbnNpb24gYXMgYSByZWFsIG51bWJlciBmb3IgdGhlIHdpcmUuIGZzTWFza051bWJlciBoYW5kcyBiYWNrXG4gIC8vIHRoZSB1bm1hc2tlZCBzdHJpbmcgaXQgYnVpbHQgd2l0aCBhIGZpeGVkICcuJyByYWRpeCAod2hpY2ggaXMgdGhlIHdob2xlXG4gIC8vIHBvaW50IG9mIHRoZSBtYXNrIC0gYSBuYXRpdmUgbnVtYmVyIGlucHV0IHBhaW50cyB0aGUgdmlld2VyJ3MgbG9jYWxlXG4gIC8vIHNlcGFyYXRvciBpbnN0ZWFkKSwgc28gdGhlIGNhc3QgaGVyZSBpcyBhIHN0cmFpZ2h0IHBhcnNlIGFuZCBuZXZlciBzZWVzIGFcbiAgLy8gY29tbWEuIFRoZSBiYWNrZW5kIHJlamVjdHMgYW55dGhpbmcgbm9uLW51bWVyaWMgcmF0aGVyIHRoYW4gY29lcmNpbmcsIHNvIGFcbiAgLy8gTmFOIGZhaWxzIGxvdWRseSBpbnN0ZWFkIG9mIHNpbGVudGx5IHN0b3JpbmcgYSB3cm9uZyBwYWdlIHNpemUuXG4gIHByaXZhdGUgX3BhZ2VEaW1lbnNpb24odmFsdWU6IG51bWJlciB8IHN0cmluZyk6IG51bWJlciB7XG4gICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicgPyB2YWx1ZSA6IHBhcnNlRmxvYXQodmFsdWUpO1xuICB9XG5cbiAgLy8gQnVpbGQgb25lIGVkaXRhYmxlIHJvdyBwZXIgcmVwb3J0LWxldmVsIGZpbHRlciBncm91cCAobGV2ZWwgcmVwb3J0IG9yIGJvdGgpLFxuICAvLyBpbiBiYXIgb3JkZXIsIHNlZWRpbmcgZWFjaCBkcmFmdCBmcm9tIHRoZSBncm91cCdzIHN0b3JlZCBkZWZhdWx0LlxuICBwcml2YXRlIF9idWlsZEZpbHRlclJvd3MocmVwb3J0OiBSZXBvcnQpOiB2b2lkIHtcbiAgICBjb25zdCByZXBvcnRJZCA9IHJlcG9ydC5pZDtcblxuICAgIGNvbnN0IGJ1aWx0ID0gKHJlcG9ydC5maWx0ZXJHcm91cHMgPz8gW10pXG4gICAgICAuZmlsdGVyKChncm91cCkgPT4gZ3JvdXAubGV2ZWwgPT09ICdyZXBvcnQnIHx8IGdyb3VwLmxldmVsID09PSAnYm90aCcpXG4gICAgICAuc29ydCgoYSwgYikgPT4gYS5vcmRlciAtIGIub3JkZXIpXG4gICAgICAubWFwKChncm91cCkgPT4ge1xuICAgICAgICBjb25zdCBncm91cERlZmF1bHQgPSBncm91cC5jb25maWc/LmRlZmF1bHQ7XG4gICAgICAgIC8vIE9uZSBzaGFyZWQsIHJlcGxheWVkIG9wdGlvbiBzdHJlYW0gcGVyIGdyb3VwOiB0aGUgY2hpcHMgZmV0Y2ggYW5kIHRoZVxuICAgICAgICAvLyBzdG9yZWQgZGVmYXVsdCdzIGxhYmVscyByZWFkIHRoZSBzYW1lIGxpc3QsIHNvIGl0IGlzIGZldGNoZWQgb25jZS5cbiAgICAgICAgY29uc3Qgb3B0aW9ucyQgPSBsb2FkR3JvdXBPcHRpb25zKGdyb3VwLCB0aGlzLl9yZXBvcnREYXRhLCByZXBvcnRJZCk7XG5cbiAgICAgICAgY29uc3Qgcm93OiBGaWx0ZXJEZWZhdWx0Um93ID0ge1xuICAgICAgICAgIGdyb3VwLFxuICAgICAgICAgIGxhYmVsOiBncm91cC5sYWJlbCB8fCBncm91cC5maWx0ZXJzPy5bMF0/LmZpbHRlckNvbHVtbiB8fCAnRmlsdGVyJyxcbiAgICAgICAgICBzdGFydDogZGF0ZUZyb21Cb3VuZChncm91cERlZmF1bHQ/LnN0YXJ0KSxcbiAgICAgICAgICBlbmQ6IGRhdGVGcm9tQm91bmQoZ3JvdXBEZWZhdWx0Py5lbmQpLFxuICAgICAgICAgIC8vIE5hbWVkIGJlbG93LCBvbmNlIHRoZSBvcHRpb24gbGlzdCBjYXJyeWluZyB0aGVpciBsYWJlbHMgaXMgaW4uXG4gICAgICAgICAgdmFsdWVzOiBbXSxcbiAgICAgICAgICB2YWx1ZTogZ3JvdXBEZWZhdWx0Py52YWx1ZSA/PyAnJyxcbiAgICAgICAgICAvLyBmcy1hdXRvY29tcGxldGUtY2hpcHMgZmV0Y2g6IHRoZSBncm91cCdzIGRpc3RpbmN0IG9wdGlvbnMsIG5hbWUtZmlsdGVyZWQuXG4gICAgICAgICAgLy8gU2FtZSBsb2FkZXIgdGhlIHJlcG9ydCBiYXIgdXNlcywgc28gdGhlIHR3byBuZXZlciBkcmlmdC5cbiAgICAgICAgICBmZXRjaDogKGtleXdvcmQ/OiBzdHJpbmcpID0+IG1hdGNoT3B0aW9ucyhvcHRpb25zJCwga2V5d29yZCksXG4gICAgICAgIH07XG5cbiAgICAgICAgcmV0dXJuIHsgcm93LCBvcHRpb25zJCwgdmFsdWVzOiBncm91cERlZmF1bHQ/LnZhbHVlcyA/PyBbXSB9O1xuICAgICAgfSk7XG5cbiAgICBjb25zdCByb3dzID0gYnVpbHQubWFwKChlbnRyeSkgPT4gZW50cnkucm93KTtcbiAgICBjb25zdCBzZWVkZWQgPSBidWlsdC5maWx0ZXIoKGVudHJ5KSA9PiBlbnRyeS52YWx1ZXMubGVuZ3RoKTtcblxuICAgIC8vIE5vdGhpbmcgdG8gbmFtZSDigJQgcHVibGlzaCBpbW1lZGlhdGVseSByYXRoZXIgdGhhbiB3YWl0aW5nIG9uIGEgcmVxdWVzdFxuICAgIC8vIG5vIHJvdyBuZWVkcy5cbiAgICBpZiAoIXNlZWRlZC5sZW5ndGgpIHtcbiAgICAgIHRoaXMuZmlsdGVyUm93cy5zZXQocm93cyk7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBBIHN0b3JlZCBzZWxlY3QgZGVmYXVsdCBob2xkcyBpZHMsIHNvIGl0cyBjaGlwcyBjYW4gb25seSBiZSBuYW1lZCBvbmNlIHRoZVxuICAgIC8vIG9wdGlvbiBsaXN0IGlzIGluLiBSZXNvbHZlIGV2ZXJ5IHNlZWRlZCByb3cgZmlyc3QgYW5kIHB1Ymxpc2ggdGhlIHJvd3MgaW5cbiAgICAvLyBvbmUgZ28sIHNvIHRoZSB0YWIgbmV2ZXIgcmVuZGVycyBhIGNoaXAgc2hvd2luZyBhIHJhdyBpZC5cbiAgICBmb3JrSm9pbihzZWVkZWQubWFwKChlbnRyeSkgPT4gcmVzb2x2ZU9wdGlvblZhbHVlcyhlbnRyeS5vcHRpb25zJCwgZW50cnkudmFsdWVzKSkpXG4gICAgICAucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5fZGVzdHJveVJlZikpXG4gICAgICAuc3Vic2NyaWJlKChyZXNvbHZlZCkgPT4ge1xuICAgICAgICByZXNvbHZlZC5mb3JFYWNoKCh2YWx1ZXMsIGluZGV4KSA9PiBzZWVkZWRbaW5kZXhdLnJvdy52YWx1ZXMgPSB2YWx1ZXMpO1xuICAgICAgICB0aGlzLmZpbHRlclJvd3Muc2V0KHJvd3MpO1xuICAgICAgfSk7XG4gIH1cblxuICAvLyBUaGUgZHJhZnQgZGVmYXVsdCBub3JtYWxpemVkIHRvIHRoZSB3aXJlIHNoYXBlIGZvciB0aGlzIHJvdydzIHR5cGUsIG9yIG51bGxcbiAgLy8gd2hlbiBlbXB0eSAod2hpY2ggY2xlYXJzIHRoZSBzdG9yZWQgZGVmYXVsdCkuXG4gIHByaXZhdGUgX3Jvd0RlZmF1bHQocm93OiBGaWx0ZXJEZWZhdWx0Um93KTogRmlsdGVyR3JvdXBEZWZhdWx0IHwgbnVsbCB7XG4gICAgc3dpdGNoIChyb3cuZ3JvdXAudHlwZSkge1xuICAgICAgY2FzZSAnZGF0ZVJhbmdlJzoge1xuICAgICAgICBjb25zdCBzdGFydCA9IGRhdGVUb0JvdW5kKHJvdy5zdGFydCk7XG4gICAgICAgIGNvbnN0IGVuZCA9IGRhdGVUb0JvdW5kKHJvdy5lbmQpO1xuXG4gICAgICAgIHJldHVybiAoc3RhcnQgfHwgZW5kKSA/IHsgc3RhcnQ6IHN0YXJ0ID8/IHVuZGVmaW5lZCwgZW5kOiBlbmQgPz8gdW5kZWZpbmVkIH0gOiBudWxsO1xuICAgICAgfVxuXG4gICAgICBjYXNlICdzZWxlY3QnOlxuICAgICAgICByZXR1cm4gcm93LnZhbHVlcy5sZW5ndGggPyB7IHZhbHVlczogcm93LnZhbHVlcy5tYXAoKG9wdGlvbikgPT4gb3B0aW9uLnZhbHVlKSB9IDogbnVsbDtcblxuICAgICAgY2FzZSAna2V5d29yZCc6XG4gICAgICBkZWZhdWx0OiB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gcm93LnZhbHVlLnRyaW0oKTtcblxuICAgICAgICByZXR1cm4gdmFsdWUgPyB7IHZhbHVlIH0gOiBudWxsO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIFdoZXRoZXIgdGhlIHJvdydzIGRyYWZ0IGRpZmZlcnMgZnJvbSB0aGUgZ3JvdXAncyBzdG9yZWQgZGVmYXVsdCDigJQgb25seVxuICAvLyBjaGFuZ2VkIHJvd3MgYXJlIHBlcnNpc3RlZCBvbiBTYXZlLlxuICBwcml2YXRlIF9kZWZhdWx0Q2hhbmdlZChyb3c6IEZpbHRlckRlZmF1bHRSb3cpOiBib29sZWFuIHtcbiAgICBjb25zdCBiZWZvcmUgPSBKU09OLnN0cmluZ2lmeSh0aGlzLl9ub3JtYWxpemUocm93Lmdyb3VwLmNvbmZpZz8uZGVmYXVsdCA/PyBudWxsKSk7XG4gICAgY29uc3QgYWZ0ZXIgPSBKU09OLnN0cmluZ2lmeSh0aGlzLl9ub3JtYWxpemUodGhpcy5fcm93RGVmYXVsdChyb3cpKSk7XG5cbiAgICByZXR1cm4gYmVmb3JlICE9PSBhZnRlcjtcbiAgfVxuXG4gIC8vIEEgc3RhYmxlIGNvbXBhcmlzb24gZm9ybTogZHJvcCByZWxhdGl2ZSAobm90IGF1dGhvcmVkIGhlcmUpIGFuZCB1bmRlZmluZWRcbiAgLy8ga2V5cyBzbyBhIG5vLW9wIGVkaXQgZG9lc24ndCByZWFkIGFzIGEgY2hhbmdlLlxuICBwcml2YXRlIF9ub3JtYWxpemUodmFsdWU6IEZpbHRlckdyb3VwRGVmYXVsdCB8IG51bGwpOiBGaWx0ZXJHcm91cERlZmF1bHQgfCBudWxsIHtcbiAgICBpZiAoIXZhbHVlKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCBub3JtYWxpemVkOiBGaWx0ZXJHcm91cERlZmF1bHQgPSB7fTtcbiAgICBpZiAodmFsdWUuc3RhcnQpIHtcbiAgICAgIG5vcm1hbGl6ZWQuc3RhcnQgPSB2YWx1ZS5zdGFydDtcbiAgICB9XG4gICAgaWYgKHZhbHVlLmVuZCkge1xuICAgICAgbm9ybWFsaXplZC5lbmQgPSB2YWx1ZS5lbmQ7XG4gICAgfVxuICAgIGlmICh2YWx1ZS52YWx1ZXM/Lmxlbmd0aCkge1xuICAgICAgbm9ybWFsaXplZC52YWx1ZXMgPSB2YWx1ZS52YWx1ZXM7XG4gICAgfVxuICAgIGlmICh2YWx1ZS52YWx1ZSkge1xuICAgICAgbm9ybWFsaXplZC52YWx1ZSA9IHZhbHVlLnZhbHVlO1xuICAgIH1cbiAgICBpZiAodmFsdWUucmVsYXRpdmUpIHtcbiAgICAgIG5vcm1hbGl6ZWQucmVsYXRpdmUgPSB2YWx1ZS5yZWxhdGl2ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gT2JqZWN0LmtleXMobm9ybWFsaXplZCkubGVuZ3RoID8gbm9ybWFsaXplZCA6IG51bGw7XG4gIH1cbn1cbiIsIjxmb3JtXG4gICAgZnNGb3JtXG4gICAgW3N1Ym1pdF09XCJzYXZlXCI+XG4gIDxmcy1kaWFsb2c+XG4gICAgPGgxIG1hdC1kaWFsb2ctdGl0bGU+XG4gICAgICBSZXBvcnQgU2V0dGluZ3NcbiAgICA8L2gxPlxuICAgIDxtYXQtZGlhbG9nLWNvbnRlbnQ+XG4gICAgICA8bWF0LXRhYi1ncm91cCBbKHNlbGVjdGVkKV09XCJzZWxlY3RlZFRhYlwiPlxuICAgICAgICA8bWF0LXRhYlxuICAgICAgICAgICAgbGFiZWw9XCJTZXR0aW5nc1wiXG4gICAgICAgICAgICBuYW1lPVwic2V0dGluZ3NcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZnMtY29sdW1uIHRhYi1ib2R5XCI+XG4gICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgIDxtYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgTmFtZVxuICAgICAgICAgICAgICA8L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cIm5hbWVcIlxuICAgICAgICAgICAgICAgIG5hbWU9XCJuYW1lXCJcbiAgICAgICAgICAgICAgICBbZnNGb3JtUmVxdWlyZWRdPVwidHJ1ZVwiPlxuICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgIDwhLS1cbiAgICAgICAgICAgICAgVGhlIHBhZ2UsIHR5cGVkIGluIGluY2hlcy4gT3JpZW50YXRpb24gaXMgbm90IGFza2VkIGZvciBiZWNhdXNlIGl0XG4gICAgICAgICAgICAgIGlzIG5vdCBhbiBpbmRlcGVuZGVudCBjaG9pY2UgLSBhIHBhZ2Ugd2lkZXIgdGhhbiBpdCBpcyB0YWxsIElTXG4gICAgICAgICAgICAgIGxhbmRzY2FwZSAtIHNvIHRoZSB0d28gbnVtYmVycyBzYXkgZXZlcnl0aGluZyB0aGVyZSBpcyB0byBzYXkuXG4gICAgICAgICAgICAtLT5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmcy1yb3cuZ2FwLXNtLmFsaWduLXN0YXJ0XCI+XG4gICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBjbGFzcz1cImZzLWZsZXhcIj5cbiAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgV2lkdGhcbiAgICAgICAgICAgICAgICA8L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgICAgICAgICAgZnNNYXNrTnVtYmVyXG4gICAgICAgICAgICAgICAgICAgIFtzY2FsZV09XCIxXCJcbiAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJwYWdlV2lkdGhcIlxuICAgICAgICAgICAgICAgICAgICBuYW1lPVwicGFnZVdpZHRoXCJcbiAgICAgICAgICAgICAgICAgICAgW2ZzRm9ybVJlcXVpcmVkXT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgICBbZnNGb3JtTWluXT1cInBhZ2VEaW1lbnNpb25NaW5cIlxuICAgICAgICAgICAgICAgICAgICBbZnNGb3JtTWF4XT1cInBhZ2VEaW1lbnNpb25NYXhcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IG1hdFRleHRTdWZmaXg+XG4gICAgICAgICAgICAgICAgICBpbmNoZXNcbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwiZnMtZmxleFwiPlxuICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICBIZWlnaHRcbiAgICAgICAgICAgICAgICA8L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgICAgICAgICAgZnNNYXNrTnVtYmVyXG4gICAgICAgICAgICAgICAgICAgIFtzY2FsZV09XCIxXCJcbiAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJwYWdlSGVpZ2h0XCJcbiAgICAgICAgICAgICAgICAgICAgbmFtZT1cInBhZ2VIZWlnaHRcIlxuICAgICAgICAgICAgICAgICAgICBbZnNGb3JtUmVxdWlyZWRdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgIFtmc0Zvcm1NaW5dPVwicGFnZURpbWVuc2lvbk1pblwiXG4gICAgICAgICAgICAgICAgICAgIFtmc0Zvcm1NYXhdPVwicGFnZURpbWVuc2lvbk1heFwiPlxuICAgICAgICAgICAgICAgIDxkaXYgbWF0VGV4dFN1ZmZpeD5cbiAgICAgICAgICAgICAgICAgIGluY2hlc1xuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8IS0tXG4gICAgICAgICAgICAgIEhvdyBkZWVwIHRoZSBoZWFkZXIgYW5kIGZvb3RlciBiYW5kcyBhcmUuIFRoZWlyIGNvbnRlbnQgaXMgZWRpdGVkXG4gICAgICAgICAgICAgIG9uIHRoZSBjYW52YXMgKEVkaXQgbGF5b3V0IOKGkiBIZWFkZXIgJiBmb290ZXIpOyB0aGVzZSByZXNlcnZlIHRoZVxuICAgICAgICAgICAgICBzcGFjZSBmb3IgaXQsIGFuZCAwIG1lYW5zIG5vIGJhbmQuXG4gICAgICAgICAgICAtLT5cbiAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBjbGFzcz1cImZ1bGwtd2lkdGhcIj5cbiAgICAgICAgICAgICAgPG1hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICBIZWFkZXIgaGVpZ2h0XG4gICAgICAgICAgICAgIDwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgIG1hdElucHV0XG4gICAgICAgICAgICAgICAgICBmc01hc2tOdW1iZXJcbiAgICAgICAgICAgICAgICAgIFtzY2FsZV09XCIyXCJcbiAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwiaGVhZGVySGVpZ2h0XCJcbiAgICAgICAgICAgICAgICAgIG5hbWU9XCJoZWFkZXJIZWlnaHRcIlxuICAgICAgICAgICAgICAgICAgW2ZzRm9ybU1pbl09XCIwXCJcbiAgICAgICAgICAgICAgICAgIFtmc0Zvcm1NYXhdPVwiaGVhZGVyRm9vdGVyTWF4XCI+XG4gICAgICAgICAgICAgIDxkaXYgbWF0VGV4dFN1ZmZpeD5cbiAgICAgICAgICAgICAgICBpbmNoZXNcbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwiZnVsbC13aWR0aFwiPlxuICAgICAgICAgICAgICA8bWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgIEZvb3RlciBoZWlnaHRcbiAgICAgICAgICAgICAgPC9tYXQtbGFiZWw+XG4gICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgICAgICAgIGZzTWFza051bWJlclxuICAgICAgICAgICAgICAgICAgW3NjYWxlXT1cIjJcIlxuICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJmb290ZXJIZWlnaHRcIlxuICAgICAgICAgICAgICAgICAgbmFtZT1cImZvb3RlckhlaWdodFwiXG4gICAgICAgICAgICAgICAgICBbZnNGb3JtTWluXT1cIjBcIlxuICAgICAgICAgICAgICAgICAgW2ZzRm9ybU1heF09XCJoZWFkZXJGb290ZXJNYXhcIj5cbiAgICAgICAgICAgICAgPGRpdiBtYXRUZXh0U3VmZml4PlxuICAgICAgICAgICAgICAgIGluY2hlc1xuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgIDxtYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgTGF5b3V0XG4gICAgICAgICAgICAgIDwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICA8bWF0LXNlbGVjdFxuICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJsYXlvdXRcIlxuICAgICAgICAgICAgICAgICAgbmFtZT1cImxheW91dFwiPlxuICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uIHZhbHVlPVwiZnJlZWZvcm1cIj5cbiAgICAgICAgICAgICAgICAgIEZyZWVmb3JtIOKAlCBwb3NpdGlvbiBjb21wb25lbnRzIGFueXdoZXJlIG9uIHRoZSBwYWdlXG4gICAgICAgICAgICAgICAgPC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uIHZhbHVlPVwiZmxvd1wiPlxuICAgICAgICAgICAgICAgICAgRmxvdyDigJQgY29tcG9uZW50cyBmbG93IGludG8gcm93cyBieSB3aWR0aCAlXG4gICAgICAgICAgICAgICAgPC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICA8L21hdC1zZWxlY3Q+XG4gICAgICAgICAgICAgIDxtYXQtaGludD5cbiAgICAgICAgICAgICAgICBGcmVlZm9ybSBpcyBsaWtlIFBvd2VyUG9pbnQ7IEZsb3cgaXMgbGlrZSBhIHJlc3BvbnNpdmUgZGFzaGJvYXJkLlxuICAgICAgICAgICAgICA8L21hdC1oaW50PlxuICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgIDxmcy1haS1yZXBvcnQtdGltZXpvbmUtc2VsZWN0IFsodGltZXpvbmUpXT1cInRpbWV6b25lXCI+PC9mcy1haS1yZXBvcnQtdGltZXpvbmUtc2VsZWN0PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L21hdC10YWI+XG4gICAgICAgIDxtYXQtdGFiXG4gICAgICAgICAgICBsYWJlbD1cIlN0eWxlc1wiXG4gICAgICAgICAgICBuYW1lPVwic3R5bGVzXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImZzLWNvbHVtbiB0YWItYm9keVwiPlxuICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICA8bWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgIEhlYWRpbmcgU2l6ZVxuICAgICAgICAgICAgICA8L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgICAgICB0eXBlPVwibnVtYmVyXCJcbiAgICAgICAgICAgICAgICBzdGVwPVwiMVwiXG4gICAgICAgICAgICAgICAgbWluPVwiNlwiXG4gICAgICAgICAgICAgICAgbWF4PVwiOTZcIlxuICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwiaGVhZGluZ1NpemVcIlxuICAgICAgICAgICAgICAgIG5hbWU9XCJoZWFkaW5nU2l6ZVwiXG4gICAgICAgICAgICAgICAgW2ZzRm9ybU1pbl09XCI2XCJcbiAgICAgICAgICAgICAgICBbZnNGb3JtTWF4XT1cIjk2XCI+XG4gICAgICAgICAgICAgIDxzcGFuIG1hdFRleHRTdWZmaXg+XG4gICAgICAgICAgICAgICAgcHRcbiAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICA8bWF0LWhpbnQ+XG4gICAgICAgICAgICAgICAgQXBwbGllcyB0byBjb21wb25lbnQgdGl0bGVzLiBQb2ludHMgbWFwIDE6MSB0byBQREYgYW5kIFBvd2VyUG9pbnQuXG4gICAgICAgICAgICAgIDwvbWF0LWhpbnQ+XG4gICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L21hdC10YWI+XG4gICAgICAgIDxtYXQtdGFiXG4gICAgICAgICAgICBsYWJlbD1cIkZpbHRlcnNcIlxuICAgICAgICAgICAgbmFtZT1cImZpbHRlcnNcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZnMtY29sdW1uIHRhYi1ib2R5XCI+XG4gICAgICAgICAgICBAaWYgKGZpbHRlclJvd3MoKS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgQGZvciAocm93IG9mIGZpbHRlclJvd3MoKTsgdHJhY2sgcm93Lmdyb3VwLmlkKSB7XG4gICAgICAgICAgICAgICAgQHN3aXRjaCAocm93Lmdyb3VwLnR5cGUpIHtcbiAgICAgICAgICAgICAgICAgIEBjYXNlICgnZGF0ZVJhbmdlJykge1xuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZnMtcm93LmdhcC1zbS5hbGlnbi1jZW50ZXIgZnMtZmxleFwiPlxuICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBjbGFzcz1cImZzLWZsZXhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIERlZmF1bHQgRnJvbSB7eyByb3cubGFiZWwgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICAgIG1hdElucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGZzRGF0ZVBpY2tlclxuICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cInJvdy5zdGFydFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtuYW1lXT1cIidzdGFydCcgKyByb3cuZ3JvdXAuaWRcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBjbGFzcz1cImZzLWZsZXhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIERlZmF1bHQgVG8ge3sgcm93LmxhYmVsIH19XG4gICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRJbnB1dFxuICAgICAgICAgICAgICAgICAgICAgICAgICBmc0RhdGVQaWNrZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJyb3cuZW5kXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW25hbWVdPVwiJ2VuZCcgKyByb3cuZ3JvdXAuaWRcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIEBjYXNlICgnc2VsZWN0Jykge1xuICAgICAgICAgICAgICAgICAgICA8ZnMtYXV0b2NvbXBsZXRlLWNoaXBzXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZzLWZsZXhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2xhYmVsXT1cIidEZWZhdWx0ICcgKyByb3cubGFiZWxcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2ZldGNoXT1cInJvdy5mZXRjaFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cInJvdy52YWx1ZXNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW25hbWVdPVwiJ3ZhbHVlcycgKyByb3cuZ3JvdXAuaWRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW211bHRpcGxlXT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2ZldGNoT25Gb2N1c109XCJ0cnVlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGZzQXV0b2NvbXBsZXRlQ2hpcHNUZW1wbGF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQtb2JqZWN0PVwib2JqZWN0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICB7eyBvYmplY3QubmFtZSB9fVxuICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgIDwvZnMtYXV0b2NvbXBsZXRlLWNoaXBzPlxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgQGRlZmF1bHQge1xuICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgY2xhc3M9XCJmcy1mbGV4XCI+XG4gICAgICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgIERlZmF1bHQge3sgcm93LmxhYmVsIH19XG4gICAgICAgICAgICAgICAgICAgICAgPC9tYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICBtYXRJbnB1dFxuICAgICAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJyb3cudmFsdWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW25hbWVdPVwiJ3ZhbHVlJyArIHJvdy5ncm91cC5pZFwiPlxuICAgICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgIDxmcy1tZXNzYWdlLWluZm8+XG4gICAgICAgICAgICAgICAgVGhpcyByZXBvcnQgaGFzIG5vIHJlcG9ydC1sZXZlbCBmaWx0ZXJzIHlldC4gQWRkIGEgZmlsdGVyIHRvIGFcbiAgICAgICAgICAgICAgICBjb21wb25lbnQgKGl0cyBzZXR0aW5ncyDihpIgRmlsdGVycykgYW5kIHNob3cgaXQgaW4gdGhlIHJlcG9ydCBiYXIsXG4gICAgICAgICAgICAgICAgdGhlbiBzZXQgaXRzIGRlZmF1bHQgaGVyZS5cbiAgICAgICAgICAgICAgPC9mcy1tZXNzYWdlLWluZm8+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvbWF0LXRhYj5cbiAgICAgIDwvbWF0LXRhYi1ncm91cD5cbiAgICA8L21hdC1kaWFsb2ctY29udGVudD5cbiAgICA8bWF0LWRpYWxvZy1hY3Rpb25zPlxuICAgICAgPGZzLWZvcm0tZGlhbG9nLWFjdGlvbnM+XG4gICAgICAgIDxidXR0b25cbiAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgbWF0LWJ1dHRvblxuICAgICAgICAgICAgY29sb3I9XCJ3YXJuXCJcbiAgICAgICAgICAgIChjbGljayk9XCJkZWxldGUoKVwiPlxuICAgICAgICAgIERlbGV0ZVxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgIDwvZnMtZm9ybS1kaWFsb2ctYWN0aW9ucz5cbiAgICA8L21hdC1kaWFsb2ctYWN0aW9ucz5cbiAgPC9mcy1kaWFsb2c+XG48L2Zvcm0+Il19
287
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0LXNldHRpbmdzLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvcmVwb3J0cy9kaWFsb2dzL3JlcG9ydC1zZXR0aW5ncy9yZXBvcnQtc2V0dGluZ3MuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9yZXBvcnRzL2RpYWxvZ3MvcmVwb3J0LXNldHRpbmdzL3JlcG9ydC1zZXR0aW5ncy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBVSxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3ZHLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ2hFLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUU3QyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDckQsT0FBTyxFQUFFLGVBQWUsRUFBRSxnQkFBZ0IsRUFBRSxnQkFBZ0IsRUFBRSxZQUFZLEVBQUUsY0FBYyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDN0gsT0FBTyxFQUFFLFlBQVksRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQzFGLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNuRCxPQUFPLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ2hFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUV2RCxPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUMzRSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUM1RCxPQUFPLEVBQUUs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WUFBWTt3QkFDWixRQUFRO3dCQUNSLE9BQU87d0JBQ1AsU0FBUzt3QkFDVCxRQUFRO3dCQUNSLFNBQVM7d0JBQ1QsU0FBUzt3QkFDVCx1QkFBdUI7cUJBQ3hCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCwgRGVzdHJveVJlZiwgT25Jbml0LCBpbmplY3QsIHNpZ25hbCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgdGFrZVVudGlsRGVzdHJveWVkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZS9yeGpzLWludGVyb3AnO1xuaW1wb3J0IHsgRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5cbmltcG9ydCB7IE1hdEJ1dHRvbiB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2J1dHRvbic7XG5pbXBvcnQgeyBNQVRfRElBTE9HX0RBVEEsIE1hdERpYWxvZ0FjdGlvbnMsIE1hdERpYWxvZ0NvbnRlbnQsIE1hdERpYWxvZ1JlZiwgTWF0RGlhbG9nVGl0bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9kaWFsb2cnO1xuaW1wb3J0IHsgTWF0Rm9ybUZpZWxkLCBNYXRMYWJlbCwgTWF0SGludCwgTWF0U3VmZml4IH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZm9ybS1maWVsZCc7XG5pbXBvcnQgeyBNYXRJbnB1dCB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2lucHV0JztcbmltcG9ydCB7IE1hdE9wdGlvbiwgTWF0U2VsZWN0IH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvc2VsZWN0JztcbmltcG9ydCB7IE1hdFRhYnNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC90YWJzJztcblxuaW1wb3J0IHsgRnNBdXRvY29tcGxldGVDaGlwc01vZHVsZSB9IGZyb20gJ0BmaXJlc3RpdGNoL2F1dG9jb21wbGV0ZS1jaGlwcyc7XG5pbXBvcnQgeyBGc0RhdGVQaWNrZXJNb2R1bGUgfSBmcm9tICdAZmlyZXN0aXRjaC9kYXRlcGlja2VyJztcbmltcG9ydCB7IEZzRGlhbG9nTW9kdWxlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvZGlhbG9nJztcbmltcG9ydCB7IEZzRm9ybU1vZHVsZSB9IGZyb20gJ0BmaXJlc3RpdGNoL2Zvcm0nO1xuaW1wb3J0IHsgRnNNYXNrTW9kdWxlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvbWFzayc7XG5pbXBvcnQgeyBGc01lc3NhZ2UsIEZzTWVzc2FnZU1vZHVsZSB9IGZyb20gJ0BmaXJlc3RpdGNoL21lc3NhZ2UnO1xuaW1wb3J0IHsgRnNQcm9tcHQgfSBmcm9tICdAZmlyZXN0aXRjaC9wcm9tcHQnO1xuaW1wb3J0IHsgRnNUYWJzTW9kdWxlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvdGFicyc7XG5cbmltcG9ydCB7IFRpbWV6b25lU2VsZWN0Q29tcG9uZW50IH0gZnJvbSAnLi4vLi4vY29tcG9uZW50cy90aW1lem9uZS1zZWxlY3QvdGltZXpvbmUtc2VsZWN0LmNvbXBvbmVudCc7XG5cbmltcG9ydCB7IE9ic2VydmFibGUsIGZvcmtKb2luIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBzd2l0Y2hNYXAsIHRhcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHsgUmVwb3J0RGF0YSB9IGZyb20gJy4uLy4uL2RhdGEvcmVwb3J0LmRhdGEnO1xuaW1wb3J0IHtcbiAgRmlsdGVyR3JvdXBEZWZhdWx0LFxuICBSZXBvcnQsXG4gIFJlcG9ydEZpbHRlckdyb3VwLFxufSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL3JlcG9ydC5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgREVGQVVMVF9IRUFESU5HX1NJWkUsIEhFQURFUl9GT09URVJfTUFYLCBQQUdFX0RJTUVOU0lPTl9NQVgsIFBBR0VfRElNRU5TSU9OX01JTiB9IGZyb20gJy4uLy4uL2xheW91dCc7XG5pbXBvcnQge1xuICBkYXRlRnJvbUJvdW5kLCBkYXRlVG9Cb3VuZCwgbG9hZEdyb3VwT3B0aW9ucywgbWF0Y2hPcHRpb25zLCByZWxhdGl2ZUxhYmVsLCByZXNvbHZlT3B0aW9uVmFsdWVzLFxufSBmcm9tICcuLi8uLi9yZXBvcnQtZmlsdGVyLWl0ZW1zJztcblxuXG4vLyBXaGF0IHRoZSBkaWFsb2cgaGFuZHMgYmFjayB3aGVuIGl0IGNsb3Nlcywgc28gdGhlIHBhZ2Uga25vd3Mgd2hhdCBoYXBwZW5lZFxuLy8gd2l0aG91dCBzbmlmZmluZyBtYWdpYyBzdHJpbmdzLiBBIGRpc21pc3NlZCBkaWFsb2cgY2xvc2VzIHdpdGggYHVuZGVmaW5lZGAuXG5leHBvcnQgaW50ZXJmYWNlIFJlcG9ydFNldHRpbmdzUmVzdWx0IHtcbiAgYWN0aW9uOiAnc2F2ZWQnIHwgJ2RlbGV0ZWQnO1xufVxuXG5cbi8vIE9uZSByZXBvcnQtbGV2ZWwgZmlsdGVyIGluIHRoZSBGaWx0ZXJzIHRhYjogaXRzIGdyb3VwLCB0aGUgaW5mZXJyZWQgaW50ZXJmYWNlLFxuLy8gYW5kIGFuIGVkaXRhYmxlIGRyYWZ0IGRlZmF1bHQuIFRoZSBkcmFmdCBmaWVsZHMgdXNlZCBkZXBlbmQgb24gdGhlIHR5cGVcbi8vIChkYXRlUmFuZ2Ug4oaSIHN0YXJ0L2VuZCBEYXRlcyBvciBhIHN0b3JlZCByb2xsaW5nIGByZWxhdGl2ZWAgcHJlc2V0OyBzZWxlY3Qg4oaSXG4vLyB2YWx1ZXM7IGtleXdvcmQg4oaSIHRleHQpLiBgZmV0Y2hgIGxvYWRzIHRoZSBzZWxlY3Qgb3B0aW9ucyB0aGUgc2FtZSB3YXkgdGhlXG4vLyByZXBvcnQgYmFyIGRvZXMuXG5pbnRlcmZhY2UgRmlsdGVyRGVmYXVsdFJvdyB7XG4gIGdyb3VwOiBSZXBvcnRGaWx0ZXJHcm91cDtcbiAgbGFiZWw6IHN0cmluZztcbiAgc3RhcnQ6IERhdGUgfCBudWxsO1xuICBlbmQ6IERhdGUgfCBudWxsO1xuICAvLyBUaGUgc3RvcmVkIHJvbGxpbmcgcHJlc2V0IChlLmcuICdsYXN0MTJNb250aHMnKS4gTm90IGF1dGhvcmVkIGhlcmU6IGl0IGlzXG4gIC8vIGNhcnJpZWQgc28gYW4gdW50b3VjaGVkIG9uZSBpcyBzZW50IGJhY2sgYXMgaXQgd2FzLCBhbmQgcGlja2VkIGRhdGVzIG9yXG4gIC8vIENsZWFyIHJlcGxhY2UgaXQuXG4gIHJlbGF0aXZlOiBzdHJpbmcgfCBudWxsO1xuICB2YWx1ZXM6IHsgbmFtZTogc3RyaW5nOyB2YWx1ZTogdW5rbm93biB9W107XG4gIHZhbHVlOiBzdHJpbmc7XG4gIGZldGNoOiAoa2V5d29yZD86IHN0cmluZykgPT4gT2JzZXJ2YWJsZTx7IG5hbWU6IHN0cmluZzsgdmFsdWU6IHVua25vd24gfVtdPjtcbn1cblxuXG4vLyBSZXBvcnQgc2V0dGluZ3MsIGluIHRocmVlIHRhYnM6XG4vLyAgIFNldHRpbmdzIOKAlCBuYW1lICsgcGFnZSBzZXR1cCAoc2l6ZSBpbiBpbmNoZXMsIGhlYWRlci9mb290ZXIgYmFuZCBkZXB0aHMsXG4vLyAgIGxheW91dCBtb2RlKS5cbi8vICAgU3R5bGVzICAg4oCUIHRoZSByZXBvcnQncyB0eXBvZ3JhcGhpYyBzdHlsZXMgKHNpemVzIGluIFBPSU5UUywgMToxIHdpdGhcbi8vICAgUERGL1Bvd2VyUG9pbnQpOyB0aGUgSGVhZGluZyBzaXplIHRvIHN0YXJ0LlxuLy8gICBGaWx0ZXJzICDigJQgdGhlIHJlcG9ydC1sZXZlbCBmaWx0ZXJzIGFuZCB0aGVpciBERUZBVUxUIHZhbHVlcy4gQSBkZWZhdWx0XG4vLyAgIHNlZWRzIHRoZSByZXBvcnQgYmFyIG9uIGV2ZXJ5IG9wZW4gKGZvciBldmVyeSB2aWV3ZXIpIGJ1dCBzdGF5c1xuLy8gICB1c2VyLWNoYW5nZWFibGUg4oCUIGl0IHByZS1maWxscyB0aGUgY29udHJvbCwgaXQgZG9lc24ndCBsb2NrIGl0LiBUaGlzIGlzIHRoZVxuLy8gICBmaXggZm9yIGhlYXZ5IHJlcG9ydHMgb3BlbmluZyBibGFuayBhbmQgdGltaW5nIG91dDogYSBkZWZhdWx0IG1vbnRoICtcbi8vICAgb3JnYW5pemF0aW9uIHNjb3BlcyB0aGUgbGFuZGluZyBwYWdlIGZyb20gdGhlIGZpcnN0IGxvYWQuXG5AQ29tcG9uZW50KHtcbiAgdGVtcGxhdGVVcmw6ICcuL3JlcG9ydC1zZXR0aW5ncy5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3JlcG9ydC1zZXR0aW5ncy5jb21wb25lbnQuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIEZvcm1zTW9kdWxlLFxuICAgIEZzRm9ybU1vZHVsZSxcbiAgICBGc01hc2tNb2R1bGUsXG4gICAgRnNEaWFsb2dNb2R1bGUsXG4gICAgRnNNZXNzYWdlTW9kdWxlLFxuICAgIEZzVGFic01vZHVsZSxcbiAgICBGc0RhdGVQaWNrZXJNb2R1bGUsXG4gICAgRnNBdXRvY29tcGxldGVDaGlwc01vZHVsZSxcbiAgICBNYXRUYWJzTW9kdWxlLFxuICAgIE1hdEJ1dHRvbixcbiAgICBNYXREaWFsb2dUaXRsZSxcbiAgICBNYXREaWFsb2dDb250ZW50LFxuICAgIE1hdERpYWxvZ0FjdGlvbnMsXG4gICAgTWF0Rm9ybUZpZWxkLFxuICAgIE1hdExhYmVsLFxuICAgIE1hdEhpbnQsXG4gICAgTWF0U3VmZml4LFxuICAgIE1hdElucHV0LFxuICAgIE1hdFNlbGVjdCxcbiAgICBNYXRPcHRpb24sXG4gICAgVGltZXpvbmVTZWxlY3RDb21wb25lbnQsXG4gIF0sXG59KVxuZXhwb3J0IGNsYXNzIFJlcG9ydFNldHRpbmdzQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcblxuICBwdWJsaWMgc2VsZWN0ZWRUYWIgPSAnc2V0dGluZ3MnO1xuXG4gIHB1YmxpYyBuYW1lID0gJyc7XG4gIC8vIFRoZSBwYWdlIGluIGluY2hlcy4gTm8gaW5pdGlhbGl6ZXI6IGV2ZXJ5IHJlcG9ydCBjYXJyaWVzIGEgc2l6ZSwgYW5kXG4gIC8vIG5nT25Jbml0IHNlZWRzIGJvdGggYmVmb3JlIHRoZSB0YWIgcmVuZGVycywgc28gYSBwbGFjZWhvbGRlciBoZXJlIGNvdWxkIG9ubHlcbiAgLy8gZXZlciBiZSBhIHdyb25nIG51bWJlciBicmllZmx5IHNob3dpbmcgYXMgdGhlIG9wZXJhdG9yJ3Mgb3duLlxuICAvL1xuICAvLyBUeXBlZCBgbnVtYmVyIHwgc3RyaW5nYCBiZWNhdXNlIGZzTWFza051bWJlciBpcyB0aGUgY29udHJvbDogaXQgaXMgc2VlZGVkXG4gIC8vIHdpdGggdGhlIHJlcG9ydCdzIG51bWJlciBidXQgaGFuZHMgYmFjayB0aGUgdW5tYXNrZWQgU1RSSU5HIHRoZSBvcGVyYXRvclxuICAvLyB0eXBlZC4gU2F2ZSBjYXN0cyBpdCBvbmNlLCBvbiB0aGUgd2F5IG91dCDigJQgc2VlIGBfcGFnZURpbWVuc2lvbigpYC5cbiAgcHVibGljIHBhZ2VXaWR0aDogbnVtYmVyIHwgc3RyaW5nO1xuICBwdWJsaWMgcGFnZUhlaWdodDogbnVtYmVyIHwgc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgcGFnZURpbWVuc2lvbk1pbiA9IFBBR0VfRElNRU5TSU9OX01JTjtcbiAgcHVibGljIHJlYWRvbmx5IHBhZ2VEaW1lbnNpb25NYXggPSBQQUdFX0RJTUVOU0lPTl9NQVg7XG4gIC8vIFRoZSBoZWFkZXIgYW5kIGZvb3RlciBiYW5kIGRlcHRocywgaW5jaGVzIOKAlCB0eXBlZCBsaWtlIHRoZSBwYWdlIHNpemVcbiAgLy8gYmVjYXVzZSBmc01hc2tOdW1iZXIgaGFuZHMgYmFjayBhIHN0cmluZy5cbiAgcHVibGljIGhlYWRlckhlaWdodDogbnVtYmVyIHwgc3RyaW5nID0gMDtcbiAgcHVibGljIGZvb3RlckhlaWdodDogbnVtYmVyIHwgc3RyaW5nID0gMDtcbiAgcHVibGljIHJlYWRvbmx5IGhlYWRlckZvb3Rlck1heCA9IEhFQURFUl9GT09URVJfTUFYO1xuICBwdWJsaWMgbGF5b3V0OiAnZnJlZWZvcm0nIHwgJ2Zsb3cnID0gJ2ZyZWVmb3JtJztcbiAgLy8gU2VlZGVkIHdpdGggdGhlIHpvbmUgdGhlIHJlcG9ydCBhY3R1YWxseSB1c2VzOiBpdHMgb3duIHN0b3JlZCB6b25lLCBlbHNlXG4gIC8vIHRoZSBhcHBsaWNhdGlvbiBkZWZhdWx0IHRoZSBzZXJ2ZXIgcmVzb2x2ZWQgKGVmZmVjdGl2ZVRpbWV6b25lKS4gU2F2ZSBzZW5kc1xuICAvLyBpdCBvbmx5IHdoZW4gaXQgZGlmZmVycyBmcm9tIHRoYXQgZWZmZWN0aXZlIHpvbmUsIHNvIG9wZW5pbmcgYW5kIHNhdmluZyBhXG4gIC8vIHJlcG9ydCB0aGF0IGZvbGxvd3MgdGhlIGRlZmF1bHQgbmV2ZXIgcGlucyBpdCB0byBhIHpvbmUuXG4gIHB1YmxpYyB0aW1lem9uZSA9ICcnO1xuICBwdWJsaWMgaGVhZGluZ1NpemUgPSBERUZBVUxUX0hFQURJTkdfU0laRTtcblxuICAvLyBUaGUgcmVwb3J0LWxldmVsIGZpbHRlcnMgYW5kIHRoZWlyIGVkaXRhYmxlIGRlZmF1bHQgdmFsdWVzIChGaWx0ZXJzIHRhYikuXG4gIHB1YmxpYyByZWFkb25seSBmaWx0ZXJSb3dzID0gc2lnbmFsPEZpbHRlckRlZmF1bHRSb3dbXT4oW10pO1xuICBwdWJsaWMgcmVhZG9ubHkgcmVsYXRpdmVMYWJlbCA9IHJlbGF0aXZlTGFiZWw7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfZGF0YTogeyByZXBvcnQ6IFJlcG9ydCB9ID0gaW5qZWN0KE1BVF9ESUFMT0dfREFUQSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX2RpYWxvZ1JlZiA9IGluamVjdDxNYXREaWFsb2dSZWY8UmVwb3J0U2V0dGluZ3NDb21wb25lbnQsIFJlcG9ydFNldHRpbmdzUmVzdWx0Pj4oTWF0RGlhbG9nUmVmKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfcmVwb3J0RGF0YSA9IGluamVjdChSZXBvcnREYXRhKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfbWVzc2FnZSA9IGluamVjdChGc01lc3NhZ2UpO1xuICBwcml2YXRlIHJlYWRvbmx5IF9wcm9tcHQgPSBpbmplY3QoRnNQcm9tcHQpO1xuICBwcml2YXRlIHJlYWRvbmx5IF9kZXN0cm95UmVmID0gaW5qZWN0KERlc3Ryb3lSZWYpO1xuXG4gIHB1YmxpYyBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICBjb25zdCByZXBvcnQgPSB0aGlzLl9kYXRhLnJlcG9ydDtcbiAgICB0aGlzLm5hbWUgPSByZXBvcnQubmFtZTtcbiAgICB0aGlzLnBhZ2VXaWR0aCA9IHJlcG9ydC5wYWdlV2lkdGg7XG4gICAgdGhpcy5wYWdlSGVpZ2h0ID0gcmVwb3J0LnBhZ2VIZWlnaHQ7XG4gICAgdGhpcy5oZWFkZXJIZWlnaHQgPSByZXBvcnQuY29uZmlnPy5oZWFkZXJGb290ZXI/LmhlYWRlckhlaWdodCA/PyAwO1xuICAgIHRoaXMuZm9vdGVySGVpZ2h0ID0gcmVwb3J0LmNvbmZpZz8uaGVhZGVyRm9vdGVyPy5mb290ZXJIZWlnaHQgPz8gMDtcbiAgICB0aGlzLmxheW91dCA9IHJlcG9ydC5sYXlvdXQgPz8gJ2ZyZWVmb3JtJztcbiAgICB0aGlzLnRpbWV6b25lID0gcmVwb3J0LnRpbWV6b25lID8/IHJlcG9ydC5lZmZlY3RpdmVUaW1lem9uZSA/PyAnJztcbiAgICB0aGlzLmhlYWRpbmdTaXplID0gcmVwb3J0LmNvbmZpZz8uc3R5bGVzPy5oZWFkaW5nPy5zaXplID8/IERFRkFVTFRfSEVBRElOR19TSVpFO1xuXG4gICAgdGhpcy5fYnVpbGRGaWx0ZXJSb3dzKHJlcG9ydCk7XG4gIH1cblxuICAvLyBDb25maXJtIGFuZCBkZWxldGUgaGVyZSwgd2hpbGUgdGhlIGRpYWxvZyBpcyBzdGlsbCBvcGVuLCB0aGVuIGNsb3NlIHdpdGhcbiAgLy8gYSBgZGVsZXRlZGAgcmVzdWx0LiBUaGUgcGFnZSByZWFjdHMgdG8gdGhlIHJlc3VsdDsgaXQgbm8gbG9uZ2VyIG93bnMgdGhlXG4gIC8vIHByb21wdCBvciB0aGUgQVBJIGNhbGwuXG4gIHB1YmxpYyBkZWxldGUoKTogdm9pZCB7XG4gICAgdGhpcy5fcHJvbXB0LmNvbmZpcm0oe1xuICAgICAgdGl0bGU6ICdEZWxldGUgUmVwb3J0JyxcbiAgICAgIHRlbXBsYXRlOiBgRGVsZXRlIFwiJHt0aGlzLl9kYXRhLnJlcG9ydC5uYW1lfVwiPyBUaGlzIGNhbm5vdCBiZSB1bmRvbmUuYCxcbiAgICB9KVxuICAgICAgLnBpcGUoXG4gICAgICAgIHN3aXRjaE1hcCgoKSA9PiB0aGlzLl9yZXBvcnREYXRhLmRlbGV0ZSh0aGlzLl9kYXRhLnJlcG9ydC5pZCkpLFxuICAgICAgICB0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5fZGVzdHJveVJlZiksXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgdGhpcy5fbWVzc2FnZS5zdWNjZXNzKCdSZXBvcnQgZGVsZXRlZCcpO1xuICAgICAgICB0aGlzLl9kaWFsb2dSZWYuY2xvc2UoeyBhY3Rpb246ICdkZWxldGVkJyB9KTtcbiAgICAgIH0pO1xuICB9XG5cbiAgcHVibGljIHNhdmUgPSAoKSA9PiB7XG4gICAgY29uc3QgcmVwb3J0SWQgPSB0aGlzLl9kYXRhLnJlcG9ydC5pZDtcblxuICAgIC8vIFBlcnNpc3QgdGhlIHJlcG9ydCBzZXR0aW5ncyBhbmQgZWFjaCBjaGFuZ2VkIGZpbHRlciBkZWZhdWx0IHRvZ2V0aGVyLCBzb1xuICAgIC8vIHRoZSBzaW5nbGUgU2F2ZSBjb3ZlcnMgYWxsIHRocmVlIHRhYnMuIFRoZSByZXBvcnQgcmVsb2FkcyBvbiB0aGUgYHNhdmVkYFxuICAgIC8vIHJlc3VsdCwgcmUtc2VlZGluZyB0aGUgYmFyIGZyb20gdGhlIG5ldyBkZWZhdWx0cy5cbiAgICBjb25zdCBzZXR0aW5ncyQgPSB0aGlzLl9yZXBvcnREYXRhLnVwZGF0ZShyZXBvcnRJZCwge1xuICAgICAgbmFtZTogdGhpcy5uYW1lLFxuICAgICAgcGFnZVdpZHRoOiB0aGlzLl9wYWdlRGltZW5zaW9uKHRoaXMucGFnZVdpZHRoKSxcbiAgICAgIHBhZ2VIZWlnaHQ6IHRoaXMuX3BhZ2VEaW1lbnNpb24odGhpcy5wYWdlSGVpZ2h0KSxcbiAgICAgIGxheW91dDogdGhpcy5sYXlvdXQsXG4gICAgICAuLi50aGlzLl90aW1lem9uZVNldHRpbmcoKSxcbiAgICAgIHN0eWxlczogeyBoZWFkaW5nOiB7IHNpemU6IHRoaXMuaGVhZGluZ1NpemUgfSB9LFxuICAgICAgaGVhZGVyRm9vdGVyOiB7XG4gICAgICAgIGhlYWRlckhlaWdodDogdGhpcy5fcGFnZURpbWVuc2lvbih0aGlzLmhlYWRlckhlaWdodCkgfHwgMCxcbiAgICAgICAgZm9vdGVySGVpZ2h0OiB0aGlzLl9wYWdlRGltZW5zaW9uKHRoaXMuZm9vdGVySGVpZ2h0KSB8fCAwLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGNvbnN0IGRlZmF1bHRzJCA9IHRoaXMuZmlsdGVyUm93cygpXG4gICAgICAuZmlsdGVyKChyb3cpID0+IHRoaXMuX2RlZmF1bHRDaGFuZ2VkKHJvdykpXG4gICAgICAubWFwKChyb3cpID0+IHRoaXMuX3JlcG9ydERhdGEudXBkYXRlRmlsdGVyR3JvdXAocmVwb3J0SWQsIHJvdy5ncm91cC5pZCwge1xuICAgICAgICBkZWZhdWx0OiB0aGlzLl9yb3dEZWZhdWx0KHJvdyksXG4gICAgICB9KSk7XG5cbiAgICByZXR1cm4gZm9ya0pvaW4oW3NldHRpbmdzJCwgLi4uZGVmYXVsdHMkXSlcbiAgICAgIC5waXBlKFxuICAgICAgICB0YXAoKCkgPT4ge1xuICAgICAgICAgIHRoaXMuX21lc3NhZ2Uuc3VjY2VzcygnUmVwb3J0IHNldHRpbmdzIHNhdmVkJyk7XG4gICAgICAgICAgdGhpcy5fZGlhbG9nUmVmLmNsb3NlKHsgYWN0aW9uOiAnc2F2ZWQnIH0pO1xuICAgICAgICB9KSxcbiAgICAgICk7XG4gIH07XG5cbiAgLy8gRHJvcCB0aGUgcm93J3Mgc3RvcmVkIHJvbGxpbmcgcHJlc2V0IChDbGVhcikuIEEgbmV3IHJvdyBvYmplY3QgcmF0aGVyIHRoYW5cbiAgLy8gYSBtdXRhdGlvbiwgc28gdGhlIHNpZ25hbCBzZWVzIHRoZSBjaGFuZ2U7IHRoZSBAZm9yIHRyYWNrcyBncm91cC5pZCwgc29cbiAgLy8gdGhlIHJvdydzIGJpbmRpbmdzIHN1cnZpdmUgdGhlIHN3YXAuXG4gIHB1YmxpYyBjbGVhclJlbGF0aXZlKHJvdzogRmlsdGVyRGVmYXVsdFJvdyk6IHZvaWQge1xuICAgIHRoaXMuZmlsdGVyUm93cy51cGRhdGUoKHJvd3MpID0+IHJvd3MubWFwKChpdGVtKSA9PiAoaXRlbSA9PT0gcm93ID8geyAuLi5pdGVtLCByZWxhdGl2ZTogbnVsbCB9IDogaXRlbSkpKTtcbiAgfVxuXG4gIC8vIFRoZSBwYWdlIGRpbWVuc2lvbiBhcyBhIHJlYWwgbnVtYmVyIGZvciB0aGUgd2lyZS4gZnNNYXNrTnVtYmVyIGhhbmRzIGJhY2tcbiAgLy8gdGhlIHVubWFza2VkIHN0cmluZyBpdCBidWlsdCB3aXRoIGEgZml4ZWQgJy4nIHJhZGl4ICh3aGljaCBpcyB0aGUgd2hvbGVcbiAgLy8gcG9pbnQgb2YgdGhlIG1hc2sgLSBhIG5hdGl2ZSBudW1iZXIgaW5wdXQgcGFpbnRzIHRoZSB2aWV3ZXIncyBsb2NhbGVcbiAgLy8gc2VwYXJhdG9yIGluc3RlYWQpLCBzbyB0aGUgY2FzdCBoZXJlIGlzIGEgc3RyYWlnaHQgcGFyc2UgYW5kIG5ldmVyIHNlZXMgYVxuICAvLyBjb21tYS4gVGhlIGJhY2tlbmQgcmVqZWN0cyBhbnl0aGluZyBub24tbnVtZXJpYyByYXRoZXIgdGhhbiBjb2VyY2luZywgc28gYVxuICAvLyBOYU4gZmFpbHMgbG91ZGx5IGluc3RlYWQgb2Ygc2lsZW50bHkgc3RvcmluZyBhIHdyb25nIHBhZ2Ugc2l6ZS5cbiAgcHJpdmF0ZSBfcGFnZURpbWVuc2lvbih2YWx1ZTogbnVtYmVyIHwgc3RyaW5nKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJyA/IHZhbHVlIDogcGFyc2VGbG9hdCh2YWx1ZSk7XG4gIH1cblxuICAvLyBUaGUgem9uZSBmb3IgdGhlIHNldHRpbmdzIFBVVCwgc2VudCBvbmx5IHdoZW4gaXQgbW92ZXMgdGhlIHJlcG9ydCBvZmYgdGhlXG4gIC8vIHpvbmUgaXQgYWxyZWFkeSB1c2VzLCBzbyBhbiB1bnRvdWNoZWQgZGlhbG9nIG5ldmVyIHBpbnMgYSByZXBvcnQgdGhhdFxuICAvLyBmb2xsb3dzIHRoZSBhcHBsaWNhdGlvbiBkZWZhdWx0LiBBIHNlcnZlciB0b28gb2xkIHRvIHNlbmRcbiAgLy8gZWZmZWN0aXZlVGltZXpvbmUgZ2V0cyB0aGUgem9uZSBldmVyeSB0aW1lLCBhcyBpdCBhbHdheXMgZGlkLlxuICBwcml2YXRlIF90aW1lem9uZVNldHRpbmcoKTogeyB0aW1lem9uZT86IHN0cmluZyB9IHtcbiAgICBjb25zdCBlZmZlY3RpdmVUaW1lem9uZSA9IHRoaXMuX2RhdGEucmVwb3J0LmVmZmVjdGl2ZVRpbWV6b25lO1xuXG4gICAgcmV0dXJuIGVmZmVjdGl2ZVRpbWV6b25lID09PSB1bmRlZmluZWQgfHwgdGhpcy50aW1lem9uZSAhPT0gZWZmZWN0aXZlVGltZXpvbmVcbiAgICAgID8geyB0aW1lem9uZTogdGhpcy50aW1lem9uZSB9XG4gICAgICA6IHt9O1xuICB9XG5cbiAgLy8gQnVpbGQgb25lIGVkaXRhYmxlIHJvdyBwZXIgcmVwb3J0LWxldmVsIGZpbHRlciBncm91cCAobGV2ZWwgcmVwb3J0IG9yIGJvdGgpLFxuICAvLyBpbiBiYXIgb3JkZXIsIHNlZWRpbmcgZWFjaCBkcmFmdCBmcm9tIHRoZSBncm91cCdzIHN0b3JlZCBkZWZhdWx0LlxuICBwcml2YXRlIF9idWlsZEZpbHRlclJvd3MocmVwb3J0OiBSZXBvcnQpOiB2b2lkIHtcbiAgICBjb25zdCByZXBvcnRJZCA9IHJlcG9ydC5pZDtcblxuICAgIGNvbnN0IGJ1aWx0ID0gKHJlcG9ydC5maWx0ZXJHcm91cHMgPz8gW10pXG4gICAgICAuZmlsdGVyKChncm91cCkgPT4gZ3JvdXAubGV2ZWwgPT09ICdyZXBvcnQnIHx8IGdyb3VwLmxldmVsID09PSAnYm90aCcpXG4gICAgICAuc29ydCgoYSwgYikgPT4gYS5vcmRlciAtIGIub3JkZXIpXG4gICAgICAubWFwKChncm91cCkgPT4ge1xuICAgICAgICBjb25zdCBncm91cERlZmF1bHQgPSBncm91cC5jb25maWc/LmRlZmF1bHQ7XG4gICAgICAgIC8vIE9uZSBzaGFyZWQsIHJlcGxheWVkIG9wdGlvbiBzdHJlYW0gcGVyIGdyb3VwOiB0aGUgY2hpcHMgZmV0Y2ggYW5kIHRoZVxuICAgICAgICAvLyBzdG9yZWQgZGVmYXVsdCdzIGxhYmVscyByZWFkIHRoZSBzYW1lIGxpc3QsIHNvIGl0IGlzIGZldGNoZWQgb25jZS5cbiAgICAgICAgY29uc3Qgb3B0aW9ucyQgPSBsb2FkR3JvdXBPcHRpb25zKGdyb3VwLCB0aGlzLl9yZXBvcnREYXRhLCByZXBvcnRJZCk7XG5cbiAgICAgICAgY29uc3Qgcm93OiBGaWx0ZXJEZWZhdWx0Um93ID0ge1xuICAgICAgICAgIGdyb3VwLFxuICAgICAgICAgIGxhYmVsOiBncm91cC5sYWJlbCB8fCBncm91cC5maWx0ZXJzPy5bMF0/LmZpbHRlckNvbHVtbiB8fCAnRmlsdGVyJyxcbiAgICAgICAgICBzdGFydDogZGF0ZUZyb21Cb3VuZChncm91cERlZmF1bHQ/LnN0YXJ0KSxcbiAgICAgICAgICBlbmQ6IGRhdGVGcm9tQm91bmQoZ3JvdXBEZWZhdWx0Py5lbmQpLFxuICAgICAgICAgIHJlbGF0aXZlOiBncm91cERlZmF1bHQ/LnJlbGF0aXZlID8/IG51bGwsXG4gICAgICAgICAgLy8gTmFtZWQgYmVsb3csIG9uY2UgdGhlIG9wdGlvbiBsaXN0IGNhcnJ5aW5nIHRoZWlyIGxhYmVscyBpcyBpbi5cbiAgICAgICAgICB2YWx1ZXM6IFtdLFxuICAgICAgICAgIHZhbHVlOiBncm91cERlZmF1bHQ/LnZhbHVlID8/ICcnLFxuICAgICAgICAgIC8vIGZzLWF1dG9jb21wbGV0ZS1jaGlwcyBmZXRjaDogdGhlIGdyb3VwJ3MgZGlzdGluY3Qgb3B0aW9ucywgbmFtZS1maWx0ZXJlZC5cbiAgICAgICAgICAvLyBTYW1lIGxvYWRlciB0aGUgcmVwb3J0IGJhciB1c2VzLCBzbyB0aGUgdHdvIG5ldmVyIGRyaWZ0LlxuICAgICAgICAgIGZldGNoOiAoa2V5d29yZD86IHN0cmluZykgPT4gbWF0Y2hPcHRpb25zKG9wdGlvbnMkLCBrZXl3b3JkKSxcbiAgICAgICAgfTtcblxuICAgICAgICByZXR1cm4geyByb3csIG9wdGlvbnMkLCB2YWx1ZXM6IGdyb3VwRGVmYXVsdD8udmFsdWVzID8/IFtdIH07XG4gICAgICB9KTtcblxuICAgIGNvbnN0IHJvd3MgPSBidWlsdC5tYXAoKGVudHJ5KSA9PiBlbnRyeS5yb3cpO1xuICAgIGNvbnN0IHNlZWRlZCA9IGJ1aWx0LmZpbHRlcigoZW50cnkpID0+IGVudHJ5LnZhbHVlcy5sZW5ndGgpO1xuXG4gICAgLy8gTm90aGluZyB0byBuYW1lIOKAlCBwdWJsaXNoIGltbWVkaWF0ZWx5IHJhdGhlciB0aGFuIHdhaXRpbmcgb24gYSByZXF1ZXN0XG4gICAgLy8gbm8gcm93IG5lZWRzLlxuICAgIGlmICghc2VlZGVkLmxlbmd0aCkge1xuICAgICAgdGhpcy5maWx0ZXJSb3dzLnNldChyb3dzKTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIEEgc3RvcmVkIHNlbGVjdCBkZWZhdWx0IGhvbGRzIGlkcywgc28gaXRzIGNoaXBzIGNhbiBvbmx5IGJlIG5hbWVkIG9uY2UgdGhlXG4gICAgLy8gb3B0aW9uIGxpc3QgaXMgaW4uIFJlc29sdmUgZXZlcnkgc2VlZGVkIHJvdyBmaXJzdCBhbmQgcHVibGlzaCB0aGUgcm93cyBpblxuICAgIC8vIG9uZSBnbywgc28gdGhlIHRhYiBuZXZlciByZW5kZXJzIGEgY2hpcCBzaG93aW5nIGEgcmF3IGlkLlxuICAgIGZvcmtKb2luKHNlZWRlZC5tYXAoKGVudHJ5KSA9PiByZXNvbHZlT3B0aW9uVmFsdWVzKGVudHJ5Lm9wdGlvbnMkLCBlbnRyeS52YWx1ZXMpKSlcbiAgICAgIC5waXBlKHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLl9kZXN0cm95UmVmKSlcbiAgICAgIC5zdWJzY3JpYmUoKHJlc29sdmVkKSA9PiB7XG4gICAgICAgIHJlc29sdmVkLmZvckVhY2goKHZhbHVlcywgaW5kZXgpID0+IHNlZWRlZFtpbmRleF0ucm93LnZhbHVlcyA9IHZhbHVlcyk7XG4gICAgICAgIHRoaXMuZmlsdGVyUm93cy5zZXQocm93cyk7XG4gICAgICB9KTtcbiAgfVxuXG4gIC8vIFRoZSBkcmFmdCBkZWZhdWx0IG5vcm1hbGl6ZWQgdG8gdGhlIHdpcmUgc2hhcGUgZm9yIHRoaXMgcm93J3MgdHlwZSwgb3IgbnVsbFxuICAvLyB3aGVuIGVtcHR5ICh3aGljaCBjbGVhcnMgdGhlIHN0b3JlZCBkZWZhdWx0KS4gQSBkYXRlIHJhbmdlIGlzIHRoZSBwaWNrZWRcbiAgLy8gZGF0ZXMgd2hlbiB0aGVyZSBhcmUgYW55LCBlbHNlIHRoZSBjYXJyaWVkIHJvbGxpbmcgcHJlc2V0LCBuZXZlciBib3RoOiB0aGVcbiAgLy8gc2VydmVyIHJlZnVzZXMgYSByZWxhdGl2ZSBwcmVzZXQgY29tYmluZWQgd2l0aCBkYXRlcy5cbiAgcHJpdmF0ZSBfcm93RGVmYXVsdChyb3c6IEZpbHRlckRlZmF1bHRSb3cpOiBGaWx0ZXJHcm91cERlZmF1bHQgfCBudWxsIHtcbiAgICBzd2l0Y2ggKHJvdy5ncm91cC50eXBlKSB7XG4gICAgICBjYXNlICdkYXRlUmFuZ2UnOiB7XG4gICAgICAgIGNvbnN0IHN0YXJ0ID0gZGF0ZVRvQm91bmQocm93LnN0YXJ0KTtcbiAgICAgICAgY29uc3QgZW5kID0gZGF0ZVRvQm91bmQocm93LmVuZCk7XG5cbiAgICAgICAgaWYgKHN0YXJ0IHx8IGVuZCkge1xuICAgICAgICAgIHJldHVybiB7IHN0YXJ0OiBzdGFydCA/PyB1bmRlZmluZWQsIGVuZDogZW5kID8/IHVuZGVmaW5lZCB9O1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJvdy5yZWxhdGl2ZSA/IHsgcmVsYXRpdmU6IHJvdy5yZWxhdGl2ZSB9IDogbnVsbDtcbiAgICAgIH1cblxuICAgICAgY2FzZSAnc2VsZWN0JzpcbiAgICAgICAgcmV0dXJuIHJvdy52YWx1ZXMubGVuZ3RoID8geyB2YWx1ZXM6IHJvdy52YWx1ZXMubWFwKChvcHRpb24pID0+IG9wdGlvbi52YWx1ZSkgfSA6IG51bGw7XG5cbiAgICAgIGNhc2UgJ2tleXdvcmQnOlxuICAgICAgZGVmYXVsdDoge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IHJvdy52YWx1ZS50cmltKCk7XG5cbiAgICAgICAgcmV0dXJuIHZhbHVlID8geyB2YWx1ZSB9IDogbnVsbDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBXaGV0aGVyIHRoZSByb3cncyBkcmFmdCBkaWZmZXJzIGZyb20gdGhlIGdyb3VwJ3Mgc3RvcmVkIGRlZmF1bHQg4oCUIG9ubHlcbiAgLy8gY2hhbmdlZCByb3dzIGFyZSBwZXJzaXN0ZWQgb24gU2F2ZS5cbiAgcHJpdmF0ZSBfZGVmYXVsdENoYW5nZWQocm93OiBGaWx0ZXJEZWZhdWx0Um93KTogYm9vbGVhbiB7XG4gICAgY29uc3QgYmVmb3JlID0gSlNPTi5zdHJpbmdpZnkodGhpcy5fbm9ybWFsaXplKHJvdy5ncm91cC5jb25maWc/LmRlZmF1bHQgPz8gbnVsbCkpO1xuICAgIGNvbnN0IGFmdGVyID0gSlNPTi5zdHJpbmdpZnkodGhpcy5fbm9ybWFsaXplKHRoaXMuX3Jvd0RlZmF1bHQocm93KSkpO1xuXG4gICAgcmV0dXJuIGJlZm9yZSAhPT0gYWZ0ZXI7XG4gIH1cblxuICAvLyBBIHN0YWJsZSBjb21wYXJpc29uIGZvcm06IGVtcHR5IGFuZCB1bmRlZmluZWQga2V5cyBhcmUgZHJvcHBlZCBzbyBhIG5vLW9wXG4gIC8vIGVkaXQgZG9lc24ndCByZWFkIGFzIGEgY2hhbmdlLiByZWxhdGl2ZSBpcyBjb21wYXJlZCBsaWtlIHRoZSByZXN0OiB0aGUgcm93XG4gIC8vIGNhcnJpZXMgaXQsIHNvIGFuIHVudG91Y2hlZCByb2xsaW5nIGRlZmF1bHQgcmVhZHMgYXMgdW5jaGFuZ2VkLlxuICBwcml2YXRlIF9ub3JtYWxpemUodmFsdWU6IEZpbHRlckdyb3VwRGVmYXVsdCB8IG51bGwpOiBGaWx0ZXJHcm91cERlZmF1bHQgfCBudWxsIHtcbiAgICBpZiAoIXZhbHVlKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCBub3JtYWxpemVkOiBGaWx0ZXJHcm91cERlZmF1bHQgPSB7fTtcbiAgICBpZiAodmFsdWUuc3RhcnQpIHtcbiAgICAgIG5vcm1hbGl6ZWQuc3RhcnQgPSB2YWx1ZS5zdGFydDtcbiAgICB9XG4gICAgaWYgKHZhbHVlLmVuZCkge1xuICAgICAgbm9ybWFsaXplZC5lbmQgPSB2YWx1ZS5lbmQ7XG4gICAgfVxuICAgIGlmICh2YWx1ZS52YWx1ZXM/Lmxlbmd0aCkge1xuICAgICAgbm9ybWFsaXplZC52YWx1ZXMgPSB2YWx1ZS52YWx1ZXM7XG4gICAgfVxuICAgIGlmICh2YWx1ZS52YWx1ZSkge1xuICAgICAgbm9ybWFsaXplZC52YWx1ZSA9IHZhbHVlLnZhbHVlO1xuICAgIH1cbiAgICBpZiAodmFsdWUucmVsYXRpdmUpIHtcbiAgICAgIG5vcm1hbGl6ZWQucmVsYXRpdmUgPSB2YWx1ZS5yZWxhdGl2ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gT2JqZWN0LmtleXMobm9ybWFsaXplZCkubGVuZ3RoID8gbm9ybWFsaXplZCA6IG51bGw7XG4gIH1cbn1cbiIsIjxmb3JtXG4gICAgZnNGb3JtXG4gICAgW3N1Ym1pdF09XCJzYXZlXCI+XG4gIDxmcy1kaWFsb2c+XG4gICAgPGgxIG1hdC1kaWFsb2ctdGl0bGU+XG4gICAgICBSZXBvcnQgU2V0dGluZ3NcbiAgICA8L2gxPlxuICAgIDxtYXQtZGlhbG9nLWNvbnRlbnQ+XG4gICAgICA8bWF0LXRhYi1ncm91cCBbKHNlbGVjdGVkKV09XCJzZWxlY3RlZFRhYlwiPlxuICAgICAgICA8bWF0LXRhYlxuICAgICAgICAgICAgbGFiZWw9XCJTZXR0aW5nc1wiXG4gICAgICAgICAgICBuYW1lPVwic2V0dGluZ3NcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZnMtY29sdW1uIHRhYi1ib2R5XCI+XG4gICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgIDxtYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgTmFtZVxuICAgICAgICAgICAgICA8L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cIm5hbWVcIlxuICAgICAgICAgICAgICAgIG5hbWU9XCJuYW1lXCJcbiAgICAgICAgICAgICAgICBbZnNGb3JtUmVxdWlyZWRdPVwidHJ1ZVwiPlxuICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgIDwhLS1cbiAgICAgICAgICAgICAgVGhlIHBhZ2UsIHR5cGVkIGluIGluY2hlcy4gT3JpZW50YXRpb24gaXMgbm90IGFza2VkIGZvciBiZWNhdXNlIGl0XG4gICAgICAgICAgICAgIGlzIG5vdCBhbiBpbmRlcGVuZGVudCBjaG9pY2UgLSBhIHBhZ2Ugd2lkZXIgdGhhbiBpdCBpcyB0YWxsIElTXG4gICAgICAgICAgICAgIGxhbmRzY2FwZSAtIHNvIHRoZSB0d28gbnVtYmVycyBzYXkgZXZlcnl0aGluZyB0aGVyZSBpcyB0byBzYXkuXG4gICAgICAgICAgICAtLT5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmcy1yb3cuZ2FwLXNtLmFsaWduLXN0YXJ0XCI+XG4gICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBjbGFzcz1cImZzLWZsZXhcIj5cbiAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgV2lkdGhcbiAgICAgICAgICAgICAgICA8L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgICAgICAgICAgZnNNYXNrTnVtYmVyXG4gICAgICAgICAgICAgICAgICAgIFtzY2FsZV09XCIxXCJcbiAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJwYWdlV2lkdGhcIlxuICAgICAgICAgICAgICAgICAgICBuYW1lPVwicGFnZVdpZHRoXCJcbiAgICAgICAgICAgICAgICAgICAgW2ZzRm9ybVJlcXVpcmVkXT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgICBbZnNGb3JtTWluXT1cInBhZ2VEaW1lbnNpb25NaW5cIlxuICAgICAgICAgICAgICAgICAgICBbZnNGb3JtTWF4XT1cInBhZ2VEaW1lbnNpb25NYXhcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IG1hdFRleHRTdWZmaXg+XG4gICAgICAgICAgICAgICAgICBpbmNoZXNcbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwiZnMtZmxleFwiPlxuICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICBIZWlnaHRcbiAgICAgICAgICAgICAgICA8L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgICAgICAgICAgZnNNYXNrTnVtYmVyXG4gICAgICAgICAgICAgICAgICAgIFtzY2FsZV09XCIxXCJcbiAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJwYWdlSGVpZ2h0XCJcbiAgICAgICAgICAgICAgICAgICAgbmFtZT1cInBhZ2VIZWlnaHRcIlxuICAgICAgICAgICAgICAgICAgICBbZnNGb3JtUmVxdWlyZWRdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgIFtmc0Zvcm1NaW5dPVwicGFnZURpbWVuc2lvbk1pblwiXG4gICAgICAgICAgICAgICAgICAgIFtmc0Zvcm1NYXhdPVwicGFnZURpbWVuc2lvbk1heFwiPlxuICAgICAgICAgICAgICAgIDxkaXYgbWF0VGV4dFN1ZmZpeD5cbiAgICAgICAgICAgICAgICAgIGluY2hlc1xuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8IS0tXG4gICAgICAgICAgICAgIEhvdyBkZWVwIHRoZSBoZWFkZXIgYW5kIGZvb3RlciBiYW5kcyBhcmUuIFRoZWlyIGNvbnRlbnQgaXMgZWRpdGVkXG4gICAgICAgICAgICAgIG9uIHRoZSBjYW52YXMgKEVkaXQgbGF5b3V0IOKGkiBIZWFkZXIgJiBmb290ZXIpOyB0aGVzZSByZXNlcnZlIHRoZVxuICAgICAgICAgICAgICBzcGFjZSBmb3IgaXQsIGFuZCAwIG1lYW5zIG5vIGJhbmQuXG4gICAgICAgICAgICAtLT5cbiAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBjbGFzcz1cImZ1bGwtd2lkdGhcIj5cbiAgICAgICAgICAgICAgPG1hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICBIZWFkZXIgaGVpZ2h0XG4gICAgICAgICAgICAgIDwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgIG1hdElucHV0XG4gICAgICAgICAgICAgICAgICBmc01hc2tOdW1iZXJcbiAgICAgICAgICAgICAgICAgIFtzY2FsZV09XCIyXCJcbiAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwiaGVhZGVySGVpZ2h0XCJcbiAgICAgICAgICAgICAgICAgIG5hbWU9XCJoZWFkZXJIZWlnaHRcIlxuICAgICAgICAgICAgICAgICAgW2ZzRm9ybU1pbl09XCIwXCJcbiAgICAgICAgICAgICAgICAgIFtmc0Zvcm1NYXhdPVwiaGVhZGVyRm9vdGVyTWF4XCI+XG4gICAgICAgICAgICAgIDxkaXYgbWF0VGV4dFN1ZmZpeD5cbiAgICAgICAgICAgICAgICBpbmNoZXNcbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwiZnVsbC13aWR0aFwiPlxuICAgICAgICAgICAgICA8bWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgIEZvb3RlciBoZWlnaHRcbiAgICAgICAgICAgICAgPC9tYXQtbGFiZWw+XG4gICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgICAgICAgIGZzTWFza051bWJlclxuICAgICAgICAgICAgICAgICAgW3NjYWxlXT1cIjJcIlxuICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJmb290ZXJIZWlnaHRcIlxuICAgICAgICAgICAgICAgICAgbmFtZT1cImZvb3RlckhlaWdodFwiXG4gICAgICAgICAgICAgICAgICBbZnNGb3JtTWluXT1cIjBcIlxuICAgICAgICAgICAgICAgICAgW2ZzRm9ybU1heF09XCJoZWFkZXJGb290ZXJNYXhcIj5cbiAgICAgICAgICAgICAgPGRpdiBtYXRUZXh0U3VmZml4PlxuICAgICAgICAgICAgICAgIGluY2hlc1xuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgIDxtYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgTGF5b3V0XG4gICAgICAgICAgICAgIDwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICA8bWF0LXNlbGVjdFxuICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJsYXlvdXRcIlxuICAgICAgICAgICAgICAgICAgbmFtZT1cImxheW91dFwiPlxuICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uIHZhbHVlPVwiZnJlZWZvcm1cIj5cbiAgICAgICAgICAgICAgICAgIEZyZWVmb3JtIOKAlCBwb3NpdGlvbiBjb21wb25lbnRzIGFueXdoZXJlIG9uIHRoZSBwYWdlXG4gICAgICAgICAgICAgICAgPC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uIHZhbHVlPVwiZmxvd1wiPlxuICAgICAgICAgICAgICAgICAgRmxvdyDigJQgY29tcG9uZW50cyBmbG93IGludG8gcm93cyBieSB3aWR0aCAlXG4gICAgICAgICAgICAgICAgPC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICA8L21hdC1zZWxlY3Q+XG4gICAgICAgICAgICAgIDxtYXQtaGludD5cbiAgICAgICAgICAgICAgICBGcmVlZm9ybSBpcyBsaWtlIFBvd2VyUG9pbnQ7IEZsb3cgaXMgbGlrZSBhIHJlc3BvbnNpdmUgZGFzaGJvYXJkLlxuICAgICAgICAgICAgICA8L21hdC1oaW50PlxuICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgIDxmcy1haS1yZXBvcnQtdGltZXpvbmUtc2VsZWN0IFsodGltZXpvbmUpXT1cInRpbWV6b25lXCI+PC9mcy1haS1yZXBvcnQtdGltZXpvbmUtc2VsZWN0PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L21hdC10YWI+XG4gICAgICAgIDxtYXQtdGFiXG4gICAgICAgICAgICBsYWJlbD1cIlN0eWxlc1wiXG4gICAgICAgICAgICBuYW1lPVwic3R5bGVzXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImZzLWNvbHVtbiB0YWItYm9keVwiPlxuICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICA8bWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgIEhlYWRpbmcgU2l6ZVxuICAgICAgICAgICAgICA8L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgICAgICB0eXBlPVwibnVtYmVyXCJcbiAgICAgICAgICAgICAgICBzdGVwPVwiMVwiXG4gICAgICAgICAgICAgICAgbWluPVwiNlwiXG4gICAgICAgICAgICAgICAgbWF4PVwiOTZcIlxuICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwiaGVhZGluZ1NpemVcIlxuICAgICAgICAgICAgICAgIG5hbWU9XCJoZWFkaW5nU2l6ZVwiXG4gICAgICAgICAgICAgICAgW2ZzRm9ybU1pbl09XCI2XCJcbiAgICAgICAgICAgICAgICBbZnNGb3JtTWF4XT1cIjk2XCI+XG4gICAgICAgICAgICAgIDxzcGFuIG1hdFRleHRTdWZmaXg+XG4gICAgICAgICAgICAgICAgcHRcbiAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICA8bWF0LWhpbnQ+XG4gICAgICAgICAgICAgICAgQXBwbGllcyB0byBjb21wb25lbnQgdGl0bGVzLiBQb2ludHMgbWFwIDE6MSB0byBQREYgYW5kIFBvd2VyUG9pbnQuXG4gICAgICAgICAgICAgIDwvbWF0LWhpbnQ+XG4gICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L21hdC10YWI+XG4gICAgICAgIDxtYXQtdGFiXG4gICAgICAgICAgICBsYWJlbD1cIkZpbHRlcnNcIlxuICAgICAgICAgICAgbmFtZT1cImZpbHRlcnNcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZnMtY29sdW1uIHRhYi1ib2R5XCI+XG4gICAgICAgICAgICBAaWYgKGZpbHRlclJvd3MoKS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgQGZvciAocm93IG9mIGZpbHRlclJvd3MoKTsgdHJhY2sgcm93Lmdyb3VwLmlkKSB7XG4gICAgICAgICAgICAgICAgQHN3aXRjaCAocm93Lmdyb3VwLnR5cGUpIHtcbiAgICAgICAgICAgICAgICAgIEBjYXNlICgnZGF0ZVJhbmdlJykge1xuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZnMtcm93LmdhcC1zbS5hbGlnbi1jZW50ZXIgZnMtZmxleFwiPlxuICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBjbGFzcz1cImZzLWZsZXhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIERlZmF1bHQgRnJvbSB7eyByb3cubGFiZWwgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICAgIG1hdElucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGZzRGF0ZVBpY2tlclxuICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cInJvdy5zdGFydFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtuYW1lXT1cIidzdGFydCcgKyByb3cuZ3JvdXAuaWRcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBjbGFzcz1cImZzLWZsZXhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIERlZmF1bHQgVG8ge3sgcm93LmxhYmVsIH19XG4gICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRJbnB1dFxuICAgICAgICAgICAgICAgICAgICAgICAgICBmc0RhdGVQaWNrZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJyb3cuZW5kXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW25hbWVdPVwiJ2VuZCcgKyByb3cuZ3JvdXAuaWRcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPCEtLSBBIHN0b3JlZCByb2xsaW5nIHByZXNldCBjYW5ub3QgYmUgYXV0aG9yZWQgaGVyZSwgb25seVxuICAgICAgICAgICAgICAgICAgICAgICAgIGtlcHQsIHJlcGxhY2VkIGJ5IHBpY2tpbmcgZGF0ZXMsIG9yIGNsZWFyZWQuIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgIGtlZXBzIENsZWFyIGZyb20gc3VibWl0dGluZyB0aGUgZm9ybS4gLS0+XG4gICAgICAgICAgICAgICAgICAgIEBpZiAocm93LnJlbGF0aXZlICYmICFyb3cuc3RhcnQgJiYgIXJvdy5lbmQpIHtcbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZnMtcm93LmdhcC1zbS5hbGlnbi1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaGludCBjbGFzcz1cImZzLWZsZXhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgUm9sbGluZyBkZWZhdWx0OiB7eyByZWxhdGl2ZUxhYmVsKHJvdy5yZWxhdGl2ZSkgfX0uIFBpY2sgZGF0ZXMgdG8gcmVwbGFjZSBpdC5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWhpbnQ+XG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0LWJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJjbGVhclJlbGF0aXZlKHJvdylcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xlYXJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICBAY2FzZSAoJ3NlbGVjdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgPGZzLWF1dG9jb21wbGV0ZS1jaGlwc1xuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmcy1mbGV4XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtsYWJlbF09XCInRGVmYXVsdCAnICsgcm93LmxhYmVsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtmZXRjaF09XCJyb3cuZmV0Y2hcIlxuICAgICAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJyb3cudmFsdWVzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtuYW1lXT1cIid2YWx1ZXMnICsgcm93Lmdyb3VwLmlkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFttdWx0aXBsZV09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtmZXRjaE9uRm9jdXNdPVwidHJ1ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICBmc0F1dG9jb21wbGV0ZUNoaXBzVGVtcGxhdGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0LW9iamVjdD1cIm9iamVjdFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAge3sgb2JqZWN0Lm5hbWUgfX1cbiAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICA8L2ZzLWF1dG9jb21wbGV0ZS1jaGlwcz5cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIEBkZWZhdWx0IHtcbiAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwiZnMtZmxleFwiPlxuICAgICAgICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICBEZWZhdWx0IHt7IHJvdy5sYWJlbCB9fVxuICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwicm93LnZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtuYW1lXT1cIid2YWx1ZScgKyByb3cuZ3JvdXAuaWRcIj5cbiAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICA8ZnMtbWVzc2FnZS1pbmZvPlxuICAgICAgICAgICAgICAgIFRoaXMgcmVwb3J0IGhhcyBubyByZXBvcnQtbGV2ZWwgZmlsdGVycyB5ZXQuIEFkZCBhIGZpbHRlciB0byBhXG4gICAgICAgICAgICAgICAgY29tcG9uZW50IChpdHMgc2V0dGluZ3Mg4oaSIEZpbHRlcnMpIGFuZCBzaG93IGl0IGluIHRoZSByZXBvcnQgYmFyLFxuICAgICAgICAgICAgICAgIHRoZW4gc2V0IGl0cyBkZWZhdWx0IGhlcmUuXG4gICAgICAgICAgICAgIDwvZnMtbWVzc2FnZS1pbmZvPlxuICAgICAgICAgICAgfVxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L21hdC10YWI+XG4gICAgICA8L21hdC10YWItZ3JvdXA+XG4gICAgPC9tYXQtZGlhbG9nLWNvbnRlbnQ+XG4gICAgPG1hdC1kaWFsb2ctYWN0aW9ucz5cbiAgICAgIDxmcy1mb3JtLWRpYWxvZy1hY3Rpb25zPlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIG1hdC1idXR0b25cbiAgICAgICAgICAgIGNvbG9yPVwid2FyblwiXG4gICAgICAgICAgICAoY2xpY2spPVwiZGVsZXRlKClcIj5cbiAgICAgICAgICBEZWxldGVcbiAgICAgICAgPC9idXR0b24+XG4gICAgICA8L2ZzLWZvcm0tZGlhbG9nLWFjdGlvbnM+XG4gICAgPC9tYXQtZGlhbG9nLWFjdGlvbnM+XG4gIDwvZnMtZGlhbG9nPlxuPC9mb3JtPiJdfQ==