@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
@@ -1,4 +1,4 @@
1
- import { CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, ChangeDetectorRef, Component, DestroyRef, ElementRef, NgZone, ViewChild, inject, } from '@angular/core';
1
+ import { CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, Component, DestroyRef, ElementRef, NgZone, ViewChild, inject, signal, } from '@angular/core';
2
2
  import { FormsModule } from '@angular/forms';
3
3
  import { MatButton } from '@angular/material/button';
4
4
  import { MatDialog } from '@angular/material/dialog';
@@ -35,15 +35,15 @@ import * as i4 from "@firestitch/menu";
35
35
  // turn via [requestData].
36
36
  export class ReportComponent {
37
37
  // The single report the viewer and chat are focused on.
38
- selected = null;
39
- report = null;
40
- loadingReports = true;
41
- editMode = false;
38
+ selected = signal(null);
39
+ report = signal(null);
40
+ loadingReports = signal(true);
41
+ editMode = signal(false);
42
42
  // The report toolbar IS an fs-filter: the picker rides in its heading
43
43
  // template, the menu becomes its actions, and report-level filter groups
44
44
  // become its items. Rebuilt whenever the loaded report (and thus its groups)
45
45
  // changes; the menu's show-guards keep working while no report is selected.
46
- reportFilterConfig;
46
+ reportFilterConfig = signal(null);
47
47
  _split;
48
48
  _chatPanel;
49
49
  // Only the canvas knows which page is on screen, and a page-scoped export
@@ -56,18 +56,17 @@ export class ReportComponent {
56
56
  _reportService = inject(ReportService);
57
57
  _filterState = inject(ReportFilterStateService);
58
58
  _exportService = inject(ReportExportService);
59
+ _collector = inject(ReportExportCollectorService);
59
60
  _process = inject(FsProcess);
60
61
  _prompt = inject(FsPrompt);
61
62
  _dialog = inject(MatDialog);
62
63
  _destroyRef = inject(DestroyRef);
63
- _cdRef = inject(ChangeDetectorRef);
64
64
  _zone = inject(NgZone);
65
65
  constructor() {
66
66
  this._buildReportConfig();
67
67
  this._reportService.load()
68
68
  .pipe(finalize(() => {
69
- this.loadingReports = false;
70
- this._cdRef.markForCheck();
69
+ this.loadingReports.set(false);
71
70
  }), takeUntilDestroyed(this._destroyRef))
72
71
  .subscribe({ error: () => undefined });
73
72
  }
@@ -75,8 +74,8 @@ export class ReportComponent {
75
74
  return this._reportService.filter(keyword);
76
75
  };
77
76
  reportChange(report) {
78
- this.report = null;
79
- this.editMode = false;
77
+ this.report.set(null);
78
+ this.editMode.set(false);
80
79
  this._buildReportConfig();
81
80
  if (report) {
82
81
  this._loadReport(report.id);
@@ -91,13 +90,12 @@ export class ReportComponent {
91
90
  })
92
91
  .pipe(switchMap((name) => this._reportService.create(name)), takeUntilDestroyed(this._destroyRef))
93
92
  .subscribe((report) => {
94
- this.selected = report;
95
- this._cdRef.markForCheck();
93
+ this.selected.set(report);
96
94
  this._loadReport(report.id);
97
95
  });
98
96
  }
99
97
  toggleEditMode() {
100
- this.editMode = !this.editMode;
98
+ this.editMode.update((editMode) => !editMode);
101
99
  }
102
100
  // The edit tools live in this toolbar, but the canvas owns what they act on
103
101
  // (the active page, the header/footer bands, which layer is live).
@@ -114,11 +112,11 @@ export class ReportComponent {
114
112
  // list and structure both reload on save (a layout switch re-renders the
115
113
  // whole canvas).
116
114
  reportSettings() {
117
- if (!this.report) {
115
+ if (!this.report()) {
118
116
  return;
119
117
  }
120
118
  this._dialog.open(ReportSettingsComponent, {
121
- data: { report: this.report },
119
+ data: { report: this.report() },
122
120
  width: '460px',
123
121
  })
124
122
  .afterClosed()
@@ -127,26 +125,25 @@ export class ReportComponent {
127
125
  // The dialog confirms + performs the delete itself; we just react to
128
126
  // what it reports back.
129
127
  if (result?.action === 'deleted') {
130
- this.selected = null;
131
- this.report = null;
128
+ this.selected.set(null);
129
+ this.report.set(null);
132
130
  this._buildReportConfig();
133
- this._cdRef.markForCheck();
134
131
  return;
135
132
  }
136
- if (result?.action === 'saved' && this.selected) {
137
- this._loadReport(this.selected.id);
138
- this._refreshReportName(this.selected.id);
133
+ if (result?.action === 'saved' && this.selected()) {
134
+ this._loadReport(this.selected().id);
135
+ this._refreshReportName(this.selected().id);
139
136
  }
140
137
  });
141
138
  }
142
139
  // Component settings — title, exact geometry, and the diagnostic views
143
140
  // (SQL, config, filter wiring).
144
141
  componentSettings(component) {
145
- if (!this.report) {
142
+ if (!this.report()) {
146
143
  return;
147
144
  }
148
145
  const dialogRef = this._dialog.open(ComponentSettingsComponent, {
149
- data: { report: this.report, component },
146
+ data: { report: this.report(), component },
150
147
  width: '640px',
151
148
  });
152
149
  // Filter add/remove/level changes persist immediately inside the dialog (no
@@ -164,16 +161,16 @@ export class ReportComponent {
164
161
  // gone from the report, so reload rather than patching it out locally —
165
162
  // its filters went with it, which the report bar has to be rebuilt for.
166
163
  if (result?.deleted) {
167
- if (this.selected) {
168
- this._loadReport(this.selected.id);
164
+ if (this.selected()) {
165
+ this._loadReport(this.selected().id);
169
166
  }
170
167
  return;
171
168
  }
172
169
  // The report's filter groups changed, so the report bar and the
173
170
  // on-component strips have to be rebuilt from a fresh report.
174
171
  if (filtersChanged) {
175
- if (this.selected) {
176
- this._loadReport(this.selected.id);
172
+ if (this.selected()) {
173
+ this._loadReport(this.selected().id);
177
174
  }
178
175
  return;
179
176
  }
@@ -188,8 +185,8 @@ export class ReportComponent {
188
185
  // The canvas changed the report's structure (added a page) — re-fetch so the
189
186
  // new page renders; the canvas lands the view on it.
190
187
  onCanvasReportChanged() {
191
- if (this.selected) {
192
- this._loadReport(this.selected.id);
188
+ if (this.selected()) {
189
+ this._loadReport(this.selected().id);
193
190
  }
194
191
  }
195
192
  // Export the report to PowerPoint, entirely client-side: every component's
@@ -197,32 +194,37 @@ export class ReportComponent {
197
194
  // the visible one), then pptxgenjs builds a deck of NATIVE editable charts —
198
195
  // page = slide, positions 1:1. The dock shows progress until the file saves.
199
196
  exportPowerpoint() {
200
- if (!this.report) {
197
+ if (!this.report()) {
201
198
  return;
202
199
  }
203
- this._process.run('Exporting PowerPoint', this._exportService.powerpoint(this.report));
200
+ this._process.run('Exporting PowerPoint', this._exportService.powerpoint(this.report()));
204
201
  }
205
202
  // Export to PDF, entirely client-side: same collection pass, charts rendered
206
203
  // through an offscreen ECharts instance at 3× pixel ratio (pixel-identical
207
204
  // to the screen), tables via jspdf-autotable — page = PDF page.
208
205
  exportPdf() {
209
- if (!this.report) {
206
+ if (!this.report()) {
210
207
  return;
211
208
  }
212
- this._process.run('Exporting PDF', this._exportService.pdf(this.report));
209
+ this._process.run('Exporting PDF', this._exportService.pdf(this.report()));
213
210
  }
214
- // The raw data behind the whole report in one action: the server exports every
215
- // component's full filtered dataset and zips one CSV per component, foldered
216
- // by page. `thisPage` narrows it to the page the canvas is showing. Unlike the
217
- // PDF/PowerPoint exports this is entirely server-side — nothing is collected
218
- // in the browser, so it is not capped by what a slide can hold.
211
+ // The whole report as files in one action: the server writes one CSV per
212
+ // component, each what the screen shows (a chart or KPI as drawn, at the
213
+ // viewer's group-by grain; a list in full), and zips them foldered by page
214
+ // with an Export Notes.txt that records the filters as the bar reads them.
215
+ // Lists use their saved default sort; a header click is carried only by a
216
+ // component's own CSV export. `thisPage` narrows it to the page the canvas is
217
+ // showing. Unlike the PDF/PowerPoint exports the files are written
218
+ // server-side, so they are not capped by what a slide can hold.
219
219
  exportData(thisPage = false) {
220
- const report = this.report;
220
+ const report = this.report();
221
221
  if (!report) {
222
222
  return;
223
223
  }
224
224
  const pageId = thisPage ? this._canvas?.activePage?.id ?? null : null;
225
- this._process.download('Exporting data', this._reportData.exportReport(report.id, this._filterState.resolveForReport(report, pageId), pageId));
225
+ const filters = this._filterState.resolveForReport(report, pageId);
226
+ this._process.download('Exporting data', this._collector.getFilterSummary(report)
227
+ .pipe(switchMap((lines) => this._reportData.exportReport(report.id, filters, pageId, this._filterState.frequency(), lines))));
226
228
  }
227
229
  // React to each chat turn (fs-chat handles the request + persistence); we
228
230
  // only care about the report side effects this context's backend flags.
@@ -230,12 +232,12 @@ export class ReportComponent {
230
232
  // The agent changed the report's structure — re-fetch it. Session filter
231
233
  // values survive (the filter-state service keeps values for groups that
232
234
  // still exist).
233
- if (response.reportChanged && this.selected) {
234
- this._loadReport(this.selected.id);
235
+ if (response.reportChanged && this.selected()) {
236
+ this._loadReport(this.selected().id);
235
237
  }
236
238
  // A rename changes nothing structural — refresh the picker chip label.
237
- if (response.reportRenamed && this.selected) {
238
- this._refreshReportName(this.selected.id);
239
+ if (response.reportRenamed && this.selected()) {
240
+ this._refreshReportName(this.selected().id);
239
241
  }
240
242
  }
241
243
  // Drag the divider between the chat and canvas panes (pointer-capture loop
@@ -272,16 +274,17 @@ export class ReportComponent {
272
274
  this._reportData.get(reportId)
273
275
  .pipe(takeUntilDestroyed(this._destroyRef))
274
276
  .subscribe((report) => {
275
- this.report = report;
277
+ this.report.set(report);
278
+ // No URL state in this view: nothing is restored from the URL and
279
+ // nothing listens to urlChanges(), so its filters stay session-only.
276
280
  this._filterState.init(report);
277
281
  this._buildReportConfig();
278
- this._cdRef.markForCheck();
279
282
  });
280
283
  }
281
284
  // Report-level filter groups in their saved order — the ones that render in
282
285
  // the toolbar (component-level groups render on their components).
283
286
  _reportGroups() {
284
- return (this.report?.filterGroups ?? [])
287
+ return (this.report()?.filterGroups ?? [])
285
288
  .filter((group) => group.level === 'report' || group.level === 'both')
286
289
  .sort((a, b) => a.order - b.order);
287
290
  }
@@ -299,7 +302,7 @@ export class ReportComponent {
299
302
  // The stored default is part of the signature: saving a new default in report
300
303
  // settings rebuilds the config, but without a key change fs-filter keeps
301
304
  // rendering the values it was created with until a full page reload.
302
- groupBySignature(this.report),
305
+ groupBySignature(this.report()),
303
306
  ...this._reportGroups().map((group) => `${group.id}:${group.level}:${group.label}:${defaultSignature(group)}`),
304
307
  ].join('|');
305
308
  }
@@ -308,10 +311,10 @@ export class ReportComponent {
308
311
  // the picker, not here. Only built/used once a report is loaded (the template
309
312
  // gates it on `report`).
310
313
  _buildReportConfig() {
311
- const reportId = this.report?.id ?? null;
314
+ const reportId = this.report()?.id ?? null;
312
315
  // Drop a grain the control no longer offers — the agent can narrow the list
313
316
  // mid-session, and an override the viewer can't see is worse than none.
314
- if (this.report && !isGranularityOffered(this.report, this._filterState.frequency())) {
317
+ if (this.report() && !isGranularityOffered(this.report(), this._filterState.frequency())) {
315
318
  this._filterState.setFrequency(null);
316
319
  }
317
320
  const items = reportId
@@ -325,7 +328,7 @@ export class ReportComponent {
325
328
  if (groupByItem) {
326
329
  items.unshift(groupByItem);
327
330
  }
328
- this.reportFilterConfig = {
331
+ this.reportFilterConfig.set({
329
332
  // Never touch the URL or persist filter state — report filters are
330
333
  // session-only, owned by ReportFilterStateService.
331
334
  queryParam: false,
@@ -338,14 +341,14 @@ export class ReportComponent {
338
341
  // Not a filter group — the grain is read straight off the query.
339
342
  this._filterState.setFrequency(query?.[GROUP_BY_ITEM] || null);
340
343
  },
341
- };
344
+ });
342
345
  }
343
346
  // The report's group-by control as an fs-filter item, or null when the report
344
347
  // has none to show. Seeded from the session state so the grain the viewer
345
348
  // picked survives the report being re-fetched after a chat edit.
346
349
  _groupByItem() {
347
- return this.report
348
- ? groupByFilterItem(this.report, this._filterState.frequency())
350
+ return this.report()
351
+ ? groupByFilterItem(this.report(), this._filterState.frequency())
349
352
  : null;
350
353
  }
351
354
  _refreshReportName(reportId) {
@@ -354,11 +357,10 @@ export class ReportComponent {
354
357
  .subscribe((reports) => {
355
358
  const renamed = reports.find((report) => report.id === reportId);
356
359
  if (renamed) {
357
- this.selected = renamed;
358
- if (this.report) {
359
- this.report = { ...this.report, name: renamed.name };
360
+ this.selected.set(renamed);
361
+ if (this.report()) {
362
+ this.report.set({ ...this.report(), name: renamed.name });
360
363
  }
361
- this._cdRef.markForCheck();
362
364
  }
363
365
  });
364
366
  }
@@ -374,7 +376,7 @@ export class ReportComponent {
374
376
  // Tree-shaken ECharts core + the 'report' house theme, loaded lazily with
375
377
  // this route's chunk.
376
378
  provideEchartsCore({ echarts: () => import('../../theme/echarts').then((module) => module.default) }),
377
- ], viewQueries: [{ propertyName: "_split", first: true, predicate: ["split"], descendants: true, static: true }, { propertyName: "_chatPanel", first: true, predicate: ["chatPanel"], descendants: true, read: ElementRef, static: true }, { propertyName: "_canvas", first: true, predicate: ReportCanvasComponent, descendants: true }], ngImport: i0, template: "<div\n #split\n class=\"report fs-row.align-start\">\n <fs-ai-chat\n #chatPanel\n class=\"chat\"\n style=\"min-height: 500px;\"\n basePath=\"reports\"\n [requestData]=\"{ reportId: selected?.id ?? null }\"\n [introMessage]=\"introMessage\"\n (response)=\"onChatResponse($event)\">\n </fs-ai-chat>\n <div\n class=\"resizer\"\n (pointerdown)=\"onResizeStart($event)\">\n </div>\n <div class=\"viewer fs-flex fs-column\">\n <div class=\"fs-row.align-center.gap-sm\">\n <fs-autocomplete-chips\n class=\"fs-flex\"\n [fetch]=\"fetchReports\"\n [(ngModel)]=\"selected\"\n [disabled]=\"loadingReports\"\n [padless]=\"true\"\n [multiple]=\"false\"\n [fetchOnFocus]=\"true\"\n (ngModelChange)=\"reportChange($event)\"\n placeholder=\"Report\"\n name=\"report\">\n <ng-template\n fsAutocompleteChipsTemplate\n let-object=\"object\">\n {{ object.name }}\n </ng-template>\n <ng-template\n fsAutocompleteChipsStatic\n (click)=\"createReport()\">\n Create Report\n </ng-template>\n </fs-autocomplete-chips>\n @if (report && editMode) {\n <!-- What layout editing can add or switch to, and the way out of it \u2014\n the same outlined buttons as the fs-ai-report toolbar. -->\n <button\n mat-stroked-button\n type=\"button\"\n matTooltip=\"Add a block of text\"\n (click)=\"addText()\">\n <mat-icon>title</mat-icon>\n Add text\n </button>\n <button\n mat-stroked-button\n type=\"button\"\n class=\"master-toggle\"\n [class.active]=\"isMasterMode\"\n [matTooltip]=\"isMasterMode ? 'Back to editing this page' : 'Edit the header and footer shown on every page'\"\n (click)=\"toggleMasterMode()\">\n <mat-icon>web_asset</mat-icon>\n Header & footer\n </button>\n <button\n mat-stroked-button\n type=\"button\"\n (click)=\"toggleEditMode()\">\n <mat-icon>check</mat-icon>\n Done editing\n </button>\n }\n @if (report) {\n <fs-menu>\n <ng-template\n fs-menu-item\n (click)=\"reportSettings()\">\n <mat-icon>\n tune\n </mat-icon>\n Report settings\n </ng-template>\n <ng-template\n fs-menu-item\n (click)=\"toggleEditMode()\"\n [disabled]=\"editMode\">\n <mat-icon>\n dashboard_customize\n </mat-icon>\n {{ editMode ? 'Done editing layout' : 'Edit layout' }}\n </ng-template>\n <ng-template\n fs-menu-item\n (click)=\"exportPowerpoint()\">\n <mat-icon>\n slideshow\n </mat-icon>\n Export PowerPoint\n </ng-template>\n <ng-template\n fs-menu-item\n (click)=\"exportPdf()\">\n <mat-icon>\n picture_as_pdf\n </mat-icon>\n Export PDF\n </ng-template>\n <ng-template\n fs-menu-item\n (click)=\"exportData()\">\n <mat-icon>\n table_view\n </mat-icon>\n Export Raw Data\n </ng-template>\n @if ((report?.pages?.length ?? 0) > 1) {\n <ng-template\n fs-menu-item\n (click)=\"exportData(true)\">\n <mat-icon>\n table_view\n </mat-icon>\n Export Raw Data (This Page)\n </ng-template>\n }\n </fs-menu>\n }\n </div>\n @if (report) {\n <!-- Report-level filters only (the report's actions live in the menu\n above). fs-filter reads its config once at init, so it's keyed on the\n filter signature: when the report-level filter set changes the block\n is recreated and re-reads the rebuilt config. -->\n @if (reportHasFilters) {\n @for (key of [reportFilterKey]; track key) {\n <fs-filter [config]=\"reportFilterConfig\"></fs-filter>\n }\n }\n <app-report-canvas\n [report]=\"report\"\n [editMode]=\"editMode\"\n (componentSettings)=\"componentSettings($event)\"\n (reportChanged)=\"onCanvasReportChanged()\">\n </app-report-canvas>\n }\n </div>\n</div>", styles: [".report{height:100%;min-height:500px}.report .chat{display:block;flex:0 0 25%;width:100%;height:100%;min-height:500px;min-width:0;border:none}.report .viewer{display:flex;flex-direction:column;min-width:0;height:100%;overflow:hidden}.report .viewer fs-filter{flex:0 0 auto;margin-top:10px;margin-bottom:0}.report .viewer ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}.report .resizer{flex:0 0 11px;align-self:stretch;display:flex;justify-content:center;cursor:col-resize;touch-action:none;-webkit-user-select:none;user-select:none}.report .resizer:before{content:\"\";width:0px;background:#0000001f;transition:width .12s ease,background-color .12s ease}.report .resizer:hover:before{width:3px;background:var(--brand-primary-color)}.report.resizing{cursor:col-resize;-webkit-user-select:none;user-select:none}.report.resizing .resizer:before{width:3px;background:var(--brand-primary-color)}.report.resizing .chat,.report.resizing .viewer{pointer-events:none}::ng-deep body.body-report-reports .mat-mdc-card-content{display:flex;flex-direction:column;box-sizing:border-box}::ng-deep body.body-report-reports .mat-mdc-card-content mat-tab-nav-panel{flex:1;min-height:0}::ng-deep body.body-report-reports .mat-mdc-card-content mat-tab-nav-panel router-outlet+ng-component{height:100%}.master-toggle.active{background:#eceff3}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: FsAutocompleteChipsModule }, { kind: "component", type: i2.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: i2.FsAutocompleteObjectDirective, selector: "[fsAutocompleteObject],[fsAutocompleteChipsTemplate]" }, { kind: "directive", type: i2.FsAutocompleteChipsStaticDirective, selector: "[fsAutocompleteChipsStatic]", inputs: ["show", "disable"], outputs: ["click", "selected"] }, { kind: "ngmodule", type: FsFilterModule }, { kind: "component", type: i3.FilterComponent, selector: "fs-filter", inputs: ["config"], outputs: ["closed", "opened", "ready"] }, { kind: "ngmodule", type: FsMenuModule }, { kind: "component", type: i4.FsMenuComponent, selector: "fs-menu", inputs: ["class", "buttonClass", "buttonType", "buttonColor"], outputs: ["opened", "closed"] }, { kind: "directive", type: i4.FsMenuItemDirective, selector: "fs-menu-group,[fs-menu-item]" }, { kind: "component", type: FsAiChatComponent, selector: "fs-ai-chat", inputs: ["basePath", "requestData", "ready", "introMessage", "showThinking"], outputs: ["response", "showThinkingChange"] }, { kind: "component", type: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: ReportCanvasComponent, selector: "app-report-canvas", inputs: ["report", "editMode", "pageId"], outputs: ["componentSettings", "reportChanged", "pageChanged"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
379
+ ], viewQueries: [{ propertyName: "_split", first: true, predicate: ["split"], descendants: true, static: true }, { propertyName: "_chatPanel", first: true, predicate: ["chatPanel"], descendants: true, read: ElementRef, static: true }, { propertyName: "_canvas", first: true, predicate: ReportCanvasComponent, descendants: true }], ngImport: i0, template: "<div\n #split\n class=\"report fs-row.align-start\">\n <fs-ai-chat\n #chatPanel\n class=\"chat\"\n style=\"min-height: 500px;\"\n basePath=\"reports\"\n [requestData]=\"{ reportId: selected()?.id ?? null }\"\n [introMessage]=\"introMessage\"\n (response)=\"onChatResponse($event)\">\n </fs-ai-chat>\n <div\n class=\"resizer\"\n (pointerdown)=\"onResizeStart($event)\">\n </div>\n <div class=\"viewer fs-flex fs-column\">\n <div class=\"fs-row.align-center.gap-sm\">\n <fs-autocomplete-chips\n class=\"fs-flex\"\n [fetch]=\"fetchReports\"\n [(ngModel)]=\"selected\"\n [disabled]=\"loadingReports()\"\n [padless]=\"true\"\n [multiple]=\"false\"\n [fetchOnFocus]=\"true\"\n (ngModelChange)=\"reportChange($event)\"\n placeholder=\"Report\"\n name=\"report\">\n <ng-template\n fsAutocompleteChipsTemplate\n let-object=\"object\">\n {{ object.name }}\n </ng-template>\n <ng-template\n fsAutocompleteChipsStatic\n (click)=\"createReport()\">\n Create Report\n </ng-template>\n </fs-autocomplete-chips>\n @if (report() && editMode()) {\n <!-- What layout editing can add or switch to, and the way out of it \u2014\n the same outlined buttons as the fs-ai-report toolbar. -->\n <button\n mat-stroked-button\n type=\"button\"\n matTooltip=\"Add a block of text\"\n (click)=\"addText()\">\n <mat-icon>title</mat-icon>\n Add text\n </button>\n <button\n mat-stroked-button\n type=\"button\"\n class=\"master-toggle\"\n [class.active]=\"isMasterMode\"\n [matTooltip]=\"isMasterMode ? 'Back to editing this page' : 'Edit the header and footer shown on every page'\"\n (click)=\"toggleMasterMode()\">\n <mat-icon>web_asset</mat-icon>\n Header & footer\n </button>\n <button\n mat-stroked-button\n type=\"button\"\n (click)=\"toggleEditMode()\">\n <mat-icon>check</mat-icon>\n Done editing\n </button>\n }\n @if (report()) {\n <fs-menu>\n <ng-template\n fs-menu-item\n (click)=\"reportSettings()\">\n <mat-icon>\n tune\n </mat-icon>\n Report settings\n </ng-template>\n <ng-template\n fs-menu-item\n (click)=\"toggleEditMode()\"\n [disabled]=\"editMode()\">\n <mat-icon>\n dashboard_customize\n </mat-icon>\n {{ editMode() ? 'Done editing layout' : 'Edit layout' }}\n </ng-template>\n <ng-template\n fs-menu-item\n (click)=\"exportPowerpoint()\">\n <mat-icon>\n slideshow\n </mat-icon>\n Export PowerPoint\n </ng-template>\n <ng-template\n fs-menu-item\n (click)=\"exportPdf()\">\n <mat-icon>\n picture_as_pdf\n </mat-icon>\n Export PDF\n </ng-template>\n <ng-template\n fs-menu-item\n (click)=\"exportData()\">\n <mat-icon>\n table_view\n </mat-icon>\n Export Raw Data\n </ng-template>\n @if ((report()?.pages?.length ?? 0) > 1) {\n <ng-template\n fs-menu-item\n (click)=\"exportData(true)\">\n <mat-icon>\n table_view\n </mat-icon>\n Export Raw Data (This Page)\n </ng-template>\n }\n </fs-menu>\n }\n </div>\n @if (report()) {\n <!-- Report-level filters only (the report's actions live in the menu\n above). fs-filter reads its config once at init, so it's keyed on the\n filter signature: when the report-level filter set changes the block\n is recreated and re-reads the rebuilt config. -->\n @if (reportHasFilters) {\n @for (key of [reportFilterKey]; track key) {\n <fs-filter [config]=\"reportFilterConfig()\"></fs-filter>\n }\n }\n <app-report-canvas\n [report]=\"report()\"\n [editMode]=\"editMode()\"\n (componentSettings)=\"componentSettings($event)\"\n (reportChanged)=\"onCanvasReportChanged()\">\n </app-report-canvas>\n }\n </div>\n</div>", styles: [".report{height:100%;min-height:500px}.report .chat{display:block;flex:0 0 25%;width:100%;height:100%;min-height:500px;min-width:0;border:none}.report .viewer{display:flex;flex-direction:column;min-width:0;height:100%;overflow:hidden}.report .viewer fs-filter{flex:0 0 auto;margin-top:10px;margin-bottom:0}.report .viewer ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}.report .resizer{flex:0 0 11px;align-self:stretch;display:flex;justify-content:center;cursor:col-resize;touch-action:none;-webkit-user-select:none;user-select:none}.report .resizer:before{content:\"\";width:0px;background:#0000001f;transition:width .12s ease,background-color .12s ease}.report .resizer:hover:before{width:3px;background:var(--brand-primary-color)}.report.resizing{cursor:col-resize;-webkit-user-select:none;user-select:none}.report.resizing .resizer:before{width:3px;background:var(--brand-primary-color)}.report.resizing .chat,.report.resizing .viewer{pointer-events:none}::ng-deep body.body-report-reports .mat-mdc-card-content{display:flex;flex-direction:column;box-sizing:border-box}::ng-deep body.body-report-reports .mat-mdc-card-content mat-tab-nav-panel{flex:1;min-height:0}::ng-deep body.body-report-reports .mat-mdc-card-content mat-tab-nav-panel router-outlet+ng-component{height:100%}.master-toggle.active{background:#eceff3}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: FsAutocompleteChipsModule }, { kind: "component", type: i2.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: i2.FsAutocompleteObjectDirective, selector: "[fsAutocompleteObject],[fsAutocompleteChipsTemplate]" }, { kind: "directive", type: i2.FsAutocompleteChipsStaticDirective, selector: "[fsAutocompleteChipsStatic]", inputs: ["show", "disable"], outputs: ["click", "selected"] }, { kind: "ngmodule", type: FsFilterModule }, { kind: "component", type: i3.FilterComponent, selector: "fs-filter", inputs: ["config"], outputs: ["closed", "opened", "ready"] }, { kind: "ngmodule", type: FsMenuModule }, { kind: "component", type: i4.FsMenuComponent, selector: "fs-menu", inputs: ["class", "buttonClass", "buttonType", "buttonColor"], outputs: ["opened", "closed"] }, { kind: "directive", type: i4.FsMenuItemDirective, selector: "fs-menu-group,[fs-menu-item]" }, { kind: "component", type: FsAiChatComponent, selector: "fs-ai-chat", inputs: ["basePath", "requestData", "ready", "introMessage", "showThinking"], outputs: ["response", "showThinkingChange"] }, { kind: "component", type: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: ReportCanvasComponent, selector: "app-report-canvas", inputs: ["report", "editMode", "pageId"], outputs: ["componentSettings", "reportChanged", "pageChanged"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
378
380
  }
379
381
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportComponent, decorators: [{
380
382
  type: Component,
@@ -399,7 +401,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
399
401
  MatIcon,
400
402
  MatTooltip,
401
403
  ReportCanvasComponent,
402
- ], template: "<div\n #split\n class=\"report fs-row.align-start\">\n <fs-ai-chat\n #chatPanel\n class=\"chat\"\n style=\"min-height: 500px;\"\n basePath=\"reports\"\n [requestData]=\"{ reportId: selected?.id ?? null }\"\n [introMessage]=\"introMessage\"\n (response)=\"onChatResponse($event)\">\n </fs-ai-chat>\n <div\n class=\"resizer\"\n (pointerdown)=\"onResizeStart($event)\">\n </div>\n <div class=\"viewer fs-flex fs-column\">\n <div class=\"fs-row.align-center.gap-sm\">\n <fs-autocomplete-chips\n class=\"fs-flex\"\n [fetch]=\"fetchReports\"\n [(ngModel)]=\"selected\"\n [disabled]=\"loadingReports\"\n [padless]=\"true\"\n [multiple]=\"false\"\n [fetchOnFocus]=\"true\"\n (ngModelChange)=\"reportChange($event)\"\n placeholder=\"Report\"\n name=\"report\">\n <ng-template\n fsAutocompleteChipsTemplate\n let-object=\"object\">\n {{ object.name }}\n </ng-template>\n <ng-template\n fsAutocompleteChipsStatic\n (click)=\"createReport()\">\n Create Report\n </ng-template>\n </fs-autocomplete-chips>\n @if (report && editMode) {\n <!-- What layout editing can add or switch to, and the way out of it \u2014\n the same outlined buttons as the fs-ai-report toolbar. -->\n <button\n mat-stroked-button\n type=\"button\"\n matTooltip=\"Add a block of text\"\n (click)=\"addText()\">\n <mat-icon>title</mat-icon>\n Add text\n </button>\n <button\n mat-stroked-button\n type=\"button\"\n class=\"master-toggle\"\n [class.active]=\"isMasterMode\"\n [matTooltip]=\"isMasterMode ? 'Back to editing this page' : 'Edit the header and footer shown on every page'\"\n (click)=\"toggleMasterMode()\">\n <mat-icon>web_asset</mat-icon>\n Header & footer\n </button>\n <button\n mat-stroked-button\n type=\"button\"\n (click)=\"toggleEditMode()\">\n <mat-icon>check</mat-icon>\n Done editing\n </button>\n }\n @if (report) {\n <fs-menu>\n <ng-template\n fs-menu-item\n (click)=\"reportSettings()\">\n <mat-icon>\n tune\n </mat-icon>\n Report settings\n </ng-template>\n <ng-template\n fs-menu-item\n (click)=\"toggleEditMode()\"\n [disabled]=\"editMode\">\n <mat-icon>\n dashboard_customize\n </mat-icon>\n {{ editMode ? 'Done editing layout' : 'Edit layout' }}\n </ng-template>\n <ng-template\n fs-menu-item\n (click)=\"exportPowerpoint()\">\n <mat-icon>\n slideshow\n </mat-icon>\n Export PowerPoint\n </ng-template>\n <ng-template\n fs-menu-item\n (click)=\"exportPdf()\">\n <mat-icon>\n picture_as_pdf\n </mat-icon>\n Export PDF\n </ng-template>\n <ng-template\n fs-menu-item\n (click)=\"exportData()\">\n <mat-icon>\n table_view\n </mat-icon>\n Export Raw Data\n </ng-template>\n @if ((report?.pages?.length ?? 0) > 1) {\n <ng-template\n fs-menu-item\n (click)=\"exportData(true)\">\n <mat-icon>\n table_view\n </mat-icon>\n Export Raw Data (This Page)\n </ng-template>\n }\n </fs-menu>\n }\n </div>\n @if (report) {\n <!-- Report-level filters only (the report's actions live in the menu\n above). fs-filter reads its config once at init, so it's keyed on the\n filter signature: when the report-level filter set changes the block\n is recreated and re-reads the rebuilt config. -->\n @if (reportHasFilters) {\n @for (key of [reportFilterKey]; track key) {\n <fs-filter [config]=\"reportFilterConfig\"></fs-filter>\n }\n }\n <app-report-canvas\n [report]=\"report\"\n [editMode]=\"editMode\"\n (componentSettings)=\"componentSettings($event)\"\n (reportChanged)=\"onCanvasReportChanged()\">\n </app-report-canvas>\n }\n </div>\n</div>", styles: [".report{height:100%;min-height:500px}.report .chat{display:block;flex:0 0 25%;width:100%;height:100%;min-height:500px;min-width:0;border:none}.report .viewer{display:flex;flex-direction:column;min-width:0;height:100%;overflow:hidden}.report .viewer fs-filter{flex:0 0 auto;margin-top:10px;margin-bottom:0}.report .viewer ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}.report .resizer{flex:0 0 11px;align-self:stretch;display:flex;justify-content:center;cursor:col-resize;touch-action:none;-webkit-user-select:none;user-select:none}.report .resizer:before{content:\"\";width:0px;background:#0000001f;transition:width .12s ease,background-color .12s ease}.report .resizer:hover:before{width:3px;background:var(--brand-primary-color)}.report.resizing{cursor:col-resize;-webkit-user-select:none;user-select:none}.report.resizing .resizer:before{width:3px;background:var(--brand-primary-color)}.report.resizing .chat,.report.resizing .viewer{pointer-events:none}::ng-deep body.body-report-reports .mat-mdc-card-content{display:flex;flex-direction:column;box-sizing:border-box}::ng-deep body.body-report-reports .mat-mdc-card-content mat-tab-nav-panel{flex:1;min-height:0}::ng-deep body.body-report-reports .mat-mdc-card-content mat-tab-nav-panel router-outlet+ng-component{height:100%}.master-toggle.active{background:#eceff3}\n"] }]
404
+ ], template: "<div\n #split\n class=\"report fs-row.align-start\">\n <fs-ai-chat\n #chatPanel\n class=\"chat\"\n style=\"min-height: 500px;\"\n basePath=\"reports\"\n [requestData]=\"{ reportId: selected()?.id ?? null }\"\n [introMessage]=\"introMessage\"\n (response)=\"onChatResponse($event)\">\n </fs-ai-chat>\n <div\n class=\"resizer\"\n (pointerdown)=\"onResizeStart($event)\">\n </div>\n <div class=\"viewer fs-flex fs-column\">\n <div class=\"fs-row.align-center.gap-sm\">\n <fs-autocomplete-chips\n class=\"fs-flex\"\n [fetch]=\"fetchReports\"\n [(ngModel)]=\"selected\"\n [disabled]=\"loadingReports()\"\n [padless]=\"true\"\n [multiple]=\"false\"\n [fetchOnFocus]=\"true\"\n (ngModelChange)=\"reportChange($event)\"\n placeholder=\"Report\"\n name=\"report\">\n <ng-template\n fsAutocompleteChipsTemplate\n let-object=\"object\">\n {{ object.name }}\n </ng-template>\n <ng-template\n fsAutocompleteChipsStatic\n (click)=\"createReport()\">\n Create Report\n </ng-template>\n </fs-autocomplete-chips>\n @if (report() && editMode()) {\n <!-- What layout editing can add or switch to, and the way out of it \u2014\n the same outlined buttons as the fs-ai-report toolbar. -->\n <button\n mat-stroked-button\n type=\"button\"\n matTooltip=\"Add a block of text\"\n (click)=\"addText()\">\n <mat-icon>title</mat-icon>\n Add text\n </button>\n <button\n mat-stroked-button\n type=\"button\"\n class=\"master-toggle\"\n [class.active]=\"isMasterMode\"\n [matTooltip]=\"isMasterMode ? 'Back to editing this page' : 'Edit the header and footer shown on every page'\"\n (click)=\"toggleMasterMode()\">\n <mat-icon>web_asset</mat-icon>\n Header & footer\n </button>\n <button\n mat-stroked-button\n type=\"button\"\n (click)=\"toggleEditMode()\">\n <mat-icon>check</mat-icon>\n Done editing\n </button>\n }\n @if (report()) {\n <fs-menu>\n <ng-template\n fs-menu-item\n (click)=\"reportSettings()\">\n <mat-icon>\n tune\n </mat-icon>\n Report settings\n </ng-template>\n <ng-template\n fs-menu-item\n (click)=\"toggleEditMode()\"\n [disabled]=\"editMode()\">\n <mat-icon>\n dashboard_customize\n </mat-icon>\n {{ editMode() ? 'Done editing layout' : 'Edit layout' }}\n </ng-template>\n <ng-template\n fs-menu-item\n (click)=\"exportPowerpoint()\">\n <mat-icon>\n slideshow\n </mat-icon>\n Export PowerPoint\n </ng-template>\n <ng-template\n fs-menu-item\n (click)=\"exportPdf()\">\n <mat-icon>\n picture_as_pdf\n </mat-icon>\n Export PDF\n </ng-template>\n <ng-template\n fs-menu-item\n (click)=\"exportData()\">\n <mat-icon>\n table_view\n </mat-icon>\n Export Raw Data\n </ng-template>\n @if ((report()?.pages?.length ?? 0) > 1) {\n <ng-template\n fs-menu-item\n (click)=\"exportData(true)\">\n <mat-icon>\n table_view\n </mat-icon>\n Export Raw Data (This Page)\n </ng-template>\n }\n </fs-menu>\n }\n </div>\n @if (report()) {\n <!-- Report-level filters only (the report's actions live in the menu\n above). fs-filter reads its config once at init, so it's keyed on the\n filter signature: when the report-level filter set changes the block\n is recreated and re-reads the rebuilt config. -->\n @if (reportHasFilters) {\n @for (key of [reportFilterKey]; track key) {\n <fs-filter [config]=\"reportFilterConfig()\"></fs-filter>\n }\n }\n <app-report-canvas\n [report]=\"report()\"\n [editMode]=\"editMode()\"\n (componentSettings)=\"componentSettings($event)\"\n (reportChanged)=\"onCanvasReportChanged()\">\n </app-report-canvas>\n }\n </div>\n</div>", styles: [".report{height:100%;min-height:500px}.report .chat{display:block;flex:0 0 25%;width:100%;height:100%;min-height:500px;min-width:0;border:none}.report .viewer{display:flex;flex-direction:column;min-width:0;height:100%;overflow:hidden}.report .viewer fs-filter{flex:0 0 auto;margin-top:10px;margin-bottom:0}.report .viewer ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}.report .resizer{flex:0 0 11px;align-self:stretch;display:flex;justify-content:center;cursor:col-resize;touch-action:none;-webkit-user-select:none;user-select:none}.report .resizer:before{content:\"\";width:0px;background:#0000001f;transition:width .12s ease,background-color .12s ease}.report .resizer:hover:before{width:3px;background:var(--brand-primary-color)}.report.resizing{cursor:col-resize;-webkit-user-select:none;user-select:none}.report.resizing .resizer:before{width:3px;background:var(--brand-primary-color)}.report.resizing .chat,.report.resizing .viewer{pointer-events:none}::ng-deep body.body-report-reports .mat-mdc-card-content{display:flex;flex-direction:column;box-sizing:border-box}::ng-deep body.body-report-reports .mat-mdc-card-content mat-tab-nav-panel{flex:1;min-height:0}::ng-deep body.body-report-reports .mat-mdc-card-content mat-tab-nav-panel router-outlet+ng-component{height:100%}.master-toggle.active{background:#eceff3}\n"] }]
403
405
  }], ctorParameters: () => [], propDecorators: { _split: [{
404
406
  type: ViewChild,
405
407
  args: ['split', { static: true }]
@@ -410,4 +412,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
410
412
  type: ViewChild,
411
413
  args: [ReportCanvasComponent]
412
414
  }] } });
413
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvcmVwb3J0cy92aWV3cy9yZXBvcnQvcmVwb3J0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvcmVwb3J0cy92aWV3cy9yZXBvcnQvcmVwb3J0LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxzQkFBc0IsRUFBRSx1QkFBdUIsRUFBRSxpQkFBaUIsRUFBRSxTQUFTLEVBQzdFLFVBQVUsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxNQUFNLEdBQ2xELE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUU3QyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDckQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNqRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFFdkQsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDM0UsT0FBTyxFQUFnQixjQUFjLEVBQXFCLE1BQU0sb0JBQW9CLENBQUM7QUFDckYsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ2hELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNoRCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFFOUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFaEUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sNEJBQTRCLENB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d0JBQ1QsT0FBTzt3QkFDUCxVQUFVO3dCQUNWLHFCQUFxQjtxQkFDdEI7d0RBaUJPLE1BQU07c0JBRGIsU0FBUzt1QkFBQyxPQUFPLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO2dCQUk1QixVQUFVO3NCQURqQixTQUFTO3VCQUFDLFdBQVcsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRTtnQkFNbEQsT0FBTztzQkFEZCxTQUFTO3VCQUFDLHFCQUFxQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENVU1RPTV9FTEVNRU5UU19TQ0hFTUEsIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDaGFuZ2VEZXRlY3RvclJlZiwgQ29tcG9uZW50LFxuICBEZXN0cm95UmVmLCBFbGVtZW50UmVmLCBOZ1pvbmUsIFZpZXdDaGlsZCwgaW5qZWN0LFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuXG5pbXBvcnQgeyBNYXRCdXR0b24gfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9idXR0b24nO1xuaW1wb3J0IHsgTWF0RGlhbG9nIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZGlhbG9nJztcbmltcG9ydCB7IE1hdEljb24gfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9pY29uJztcbmltcG9ydCB7IE1hdFRvb2x0aXAgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC90b29sdGlwJztcblxuaW1wb3J0IHsgRnNBdXRvY29tcGxldGVDaGlwc01vZHVsZSB9IGZyb20gJ0BmaXJlc3RpdGNoL2F1dG9jb21wbGV0ZS1jaGlwcyc7XG5pbXBvcnQgeyBGaWx0ZXJDb25maWcsIEZzRmlsdGVyTW9kdWxlLCBJRmlsdGVyQ29uZmlnSXRlbSB9IGZyb20gJ0BmaXJlc3RpdGNoL2ZpbHRlcic7XG5pbXBvcnQgeyBGc01lbnVNb2R1bGUgfSBmcm9tICdAZmlyZXN0aXRjaC9tZW51JztcbmltcG9ydCB7IEZzUHJvY2VzcyB9IGZyb20gJ0BmaXJlc3RpdGNoL3Byb2Nlc3MnO1xuaW1wb3J0IHsgRnNQcm9tcHQgfSBmcm9tICdAZmlyZXN0aXRjaC9wcm9tcHQnO1xuXG5pbXBvcnQgeyBmaW5hbGl6ZSwgc3dpdGNoTWFwLCB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IHRha2VVbnRpbERlc3Ryb3llZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUvcnhqcy1pbnRlcm9wJztcbmltcG9ydCB7IHByb3ZpZGVFY2hhcnRzQ29yZSB9IGZyb20gJ25neC1lY2hhcnRzJztcblxuaW1wb3J0IHsgRnNBaUNoYXRDb21wb25lbnQsIEZzQWlDaGF0UmVzcG9uc2UgfSBmcm9tICdAZmlyZXN0aXRjaC9haSc7XG5cbmltcG9ydCB7IFJlcG9ydENhbnZhc0NvbXBvbmVudCB9IGZyb20gJy4uLy4uL2NvbXBvbmVudHMvcmVwb3J0LWNhbnZhcy9yZXBvcnQtY2FudmFzLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBSZXBvcnREYXRhIH0gZnJvbSAnLi4vLi4vZGF0YS9yZXBvcnQuZGF0YSc7XG5pbXBvcnQgeyBDb21wb25lbnRTZXR0aW5nc0NvbXBvbmVudCwgQ29tcG9uZW50U2V0dGluZ3NSZXN1bHQgfSBmcm9tICcuLi8uLi9kaWFsb2dzL2NvbXBvbmVudC1zZXR0aW5ncy9jb21wb25lbnQtc2V0dGluZ3MuY29tcG9uZW50JztcbmltcG9ydCB7IFJlcG9ydFNldHRpbmdzQ29tcG9uZW50LCBSZXBvcnRTZXR0aW5nc1Jlc3VsdCB9IGZyb20gJy4uLy4uL2RpYWxvZ3MvcmVwb3J0LXNldHRpbmdzL3JlcG9ydC1zZXR0aW5ncy5jb21wb25lbnQnO1xuaW1wb3J0IHsgUmVwb3J0RXhwb3J0Q29sbGVjdG9yU2VydmljZSB9IGZyb20gJy4uLy4uL2V4cG9ydC9yZXBvcnQtZXhwb3J0LWNvbGxlY3Rvci5zZXJ2aWNlJztcbmltcG9ydCB7IFJlcG9ydEV4cG9ydFNlcnZpY2UgfSBmcm9tICcuLi8uLi9leHBvcnQvcmVwb3J0LWV4cG9ydC5zZXJ2aWNlJztcbmltcG9ydCB7IFJlcG9ydFBkZlNlcnZpY2UgfSBmcm9tICcuLi8uLi9leHBvcnQvcmVwb3J0LXBkZi5zZXJ2aWNlJztcbmltcG9ydCB7IFJlcG9ydFBwdHhTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vZXhwb3J0L3JlcG9ydC1wcHR4LnNlcnZpY2UnO1xuaW1wb3J0IHtcbiAgQ2hhcnRHcmFudWxhcml0eSwgUmVwb3J0LFxuICBSZXBvcnRDb21wb25lbnQgYXMgUmVwb3J0Q29tcG9uZW50TW9kZWwsIFJlcG9ydEZpbHRlckdyb3VwLCBSZXBvcnRMaXN0SXRlbSxcbn0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9yZXBvcnQuaW50ZXJmYWNlJztcbmltcG9ydCB7XG4gIEdST1VQX0JZX0lURU0sIGZpbHRlckl0ZW1Gb3JHcm91cCwgZ3JvdXBCeUZpbHRlckl0ZW0sIGdyb3VwQnlTaWduYXR1cmUsIGdyb3VwVmFsdWVzRnJvbVF1ZXJ5LFxuICBpc0dyYW51bGFyaXR5T2ZmZXJlZCxcbn0gZnJvbSAnLi4vLi4vcmVwb3J0LWZpbHRlci1pdGVtcyc7XG5pbXBvcnQgeyBSZXBvcnRGaWx0ZXJTdGF0ZVNlcnZpY2UsIGRlZmF1bHRTaWduYXR1cmUgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9yZXBvcnQtZmlsdGVyLXN0YXRlLnNlcnZpY2UnO1xuaW1wb3J0IHsgUmVwb3J0U2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL3JlcG9ydC5zZXJ2aWNlJztcblxuXG4vLyBUaGUgUmVwb3J0cyBwYWdlOiBBSSBjaGF0IG9uIHRoZSBsZWZ0LCB0aGUgcmVwb3J0IGNhbnZhcyBvbiB0aGUgcmlnaHQg4oCUXG4vLyBhIHNwbGl0LXBhbmUgbGF5b3V0OyB0aGUgdmlld2VyIGlzIG91ciBvd24gY2FudmFzIChubyBpZnJhbWUsIG5vIGVtYmVkIFVSTHMpLlxuLy8gVGhlIGNoYXQgaXMgYWx3YXlzIHNjb3BlZCB0byB0aGUgc2VsZWN0ZWQgcmVwb3J0OyBpdHMgaWQgcmlkZXMgb24gZXZlcnlcbi8vIHR1cm4gdmlhIFtyZXF1ZXN0RGF0YV0uXG5AQ29tcG9uZW50KHtcbiAgdGVtcGxhdGVVcmw6ICcuL3JlcG9ydC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3JlcG9ydC5jb21wb25lbnQuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgc2NoZW1hczogW0NVU1RPTV9FTEVNRU5UU19TQ0hFTUFdLFxuICBwcm92aWRlcnM6IFtcbiAgICAvLyBTZXNzaW9uIGZpbHRlciBzdGF0ZSBpcyBwZXItb3Blbi1yZXBvcnQtcGFnZSwgbm90IGFwcC1nbG9iYWw7IHRoZSBleHBvcnRcbiAgICAvLyBzZXJ2aWNlcyByZXNvbHZlIGZpbHRlcnMgdGhyb3VnaCBpdCwgc28gdGhleSBsaXZlIGF0IHRoZSBzYW1lIGxldmVsLlxuICAgIFJlcG9ydEZpbHRlclN0YXRlU2VydmljZSxcbiAgICBSZXBvcnRFeHBvcnRDb2xsZWN0b3JTZXJ2aWNlLFxuICAgIFJlcG9ydFBwdHhTZXJ2aWNlLFxuICAgIFJlcG9ydFBkZlNlcnZpY2UsXG4gICAgUmVwb3J0RXhwb3J0U2VydmljZSxcbiAgICAvLyBUcmVlLXNoYWtlbiBFQ2hhcnRzIGNvcmUgKyB0aGUgJ3JlcG9ydCcgaG91c2UgdGhlbWUsIGxvYWRlZCBsYXppbHkgd2l0aFxuICAgIC8vIHRoaXMgcm91dGUncyBjaHVuay5cbiAgICBwcm92aWRlRWNoYXJ0c0NvcmUoeyBlY2hhcnRzOiAoKSA9PiBpbXBvcnQoJy4uLy4uL3RoZW1lL2VjaGFydHMnKS50aGVuKChtb2R1bGUpID0+IG1vZHVsZS5kZWZhdWx0KSB9KSxcbiAgXSxcbiAgaW1wb3J0czogW1xuICAgIEZvcm1zTW9kdWxlLFxuICAgIEZzQXV0b2NvbXBsZXRlQ2hpcHNNb2R1bGUsXG4gICAgRnNGaWx0ZXJNb2R1bGUsXG4gICAgRnNNZW51TW9kdWxlLFxuICAgIEZzQWlDaGF0Q29tcG9uZW50LFxuICAgIE1hdEJ1dHRvbixcbiAgICBNYXRJY29uLFxuICAgIE1hdFRvb2x0aXAsXG4gICAgUmVwb3J0Q2FudmFzQ29tcG9uZW50LFxuICBdLFxufSlcbmV4cG9ydCBjbGFzcyBSZXBvcnRDb21wb25lbnQge1xuXG4gIC8vIFRoZSBzaW5nbGUgcmVwb3J0IHRoZSB2aWV3ZXIgYW5kIGNoYXQgYXJlIGZvY3VzZWQgb24uXG4gIHB1YmxpYyBzZWxlY3RlZDogUmVwb3J0TGlzdEl0ZW0gfCBudWxsID0gbnVsbDtcbiAgcHVibGljIHJlcG9ydDogUmVwb3J0IHwgbnVsbCA9IG51bGw7XG4gIHB1YmxpYyBsb2FkaW5nUmVwb3J0cyA9IHRydWU7XG4gIHB1YmxpYyBlZGl0TW9kZSA9IGZhbHNlO1xuXG4gIC8vIFRoZSByZXBvcnQgdG9vbGJhciBJUyBhbiBmcy1maWx0ZXI6IHRoZSBwaWNrZXIgcmlkZXMgaW4gaXRzIGhlYWRpbmdcbiAgLy8gdGVtcGxhdGUsIHRoZSBtZW51IGJlY29tZXMgaXRzIGFjdGlvbnMsIGFuZCByZXBvcnQtbGV2ZWwgZmlsdGVyIGdyb3Vwc1xuICAvLyBiZWNvbWUgaXRzIGl0ZW1zLiBSZWJ1aWx0IHdoZW5ldmVyIHRoZSBsb2FkZWQgcmVwb3J0IChhbmQgdGh1cyBpdHMgZ3JvdXBzKVxuICAvLyBjaGFuZ2VzOyB0aGUgbWVudSdzIHNob3ctZ3VhcmRzIGtlZXAgd29ya2luZyB3aGlsZSBubyByZXBvcnQgaXMgc2VsZWN0ZWQuXG4gIHB1YmxpYyByZXBvcnRGaWx0ZXJDb25maWchOiBGaWx0ZXJDb25maWc7XG5cbiAgQFZpZXdDaGlsZCgnc3BsaXQnLCB7IHN0YXRpYzogdHJ1ZSB9KVxuICBwcml2YXRlIF9zcGxpdCE6IEVsZW1lbnRSZWY8SFRNTERpdkVsZW1lbnQ+O1xuXG4gIEBWaWV3Q2hpbGQoJ2NoYXRQYW5lbCcsIHsgc3RhdGljOiB0cnVlLCByZWFkOiBFbGVtZW50UmVmIH0pXG4gIHByaXZhdGUgX2NoYXRQYW5lbCE6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+O1xuXG4gIC8vIE9ubHkgdGhlIGNhbnZhcyBrbm93cyB3aGljaCBwYWdlIGlzIG9uIHNjcmVlbiwgYW5kIGEgcGFnZS1zY29wZWQgZXhwb3J0XG4gIC8vIGhhcyB0byBhc2sgaXQuXG4gIEBWaWV3Q2hpbGQoUmVwb3J0Q2FudmFzQ29tcG9uZW50KVxuICBwcml2YXRlIF9jYW52YXM/OiBSZXBvcnRDYW52YXNDb21wb25lbnQ7XG5cbiAgcHVibGljIHJlYWRvbmx5IGludHJvTWVzc2FnZSA9IHtcbiAgICB0ZXh0OiAnJyxcbiAgfTtcblxuICBwcml2YXRlIF9yZXBvcnREYXRhID0gaW5qZWN0KFJlcG9ydERhdGEpO1xuICBwcml2YXRlIF9yZXBvcnRTZXJ2aWNlID0gaW5qZWN0KFJlcG9ydFNlcnZpY2UpO1xuICBwcml2YXRlIF9maWx0ZXJTdGF0ZSA9IGluamVjdChSZXBvcnRGaWx0ZXJTdGF0ZVNlcnZpY2UpO1xuICBwcml2YXRlIF9leHBvcnRTZXJ2aWNlID0gaW5qZWN0KFJlcG9ydEV4cG9ydFNlcnZpY2UpO1xuICBwcml2YXRlIF9wcm9jZXNzID0gaW5qZWN0KEZzUHJvY2Vzcyk7XG4gIHByaXZhdGUgX3Byb21wdCA9IGluamVjdChGc1Byb21wdCk7XG4gIHByaXZhdGUgX2RpYWxvZyA9IGluamVjdChNYXREaWFsb2cpO1xuICBwcml2YXRlIF9kZXN0cm95UmVmID0gaW5qZWN0KERlc3Ryb3lSZWYpO1xuICBwcml2YXRlIF9jZFJlZiA9IGluamVjdChDaGFuZ2VEZXRlY3RvclJlZik7XG4gIHByaXZhdGUgX3pvbmUgPSBpbmplY3QoTmdab25lKTtcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLl9idWlsZFJlcG9ydENvbmZpZygpO1xuXG4gICAgdGhpcy5fcmVwb3J0U2VydmljZS5sb2FkKClcbiAgICAgIC5waXBlKFxuICAgICAgICBmaW5hbGl6ZSgoKSA9PiB7XG4gICAgICAgICAgdGhpcy5sb2FkaW5nUmVwb3J0cyA9IGZhbHNlO1xuICAgICAgICAgIHRoaXMuX2NkUmVmLm1hcmtGb3JDaGVjaygpO1xuICAgICAgICB9KSxcbiAgICAgICAgdGFrZVVudGlsRGVzdHJveWVkKHRoaXMuX2Rlc3Ryb3lSZWYpLFxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSh7IGVycm9yOiAoKSA9PiB1bmRlZmluZWQgfSk7XG4gIH1cblxuICBwdWJsaWMgZmV0Y2hSZXBvcnRzID0gKGtleXdvcmQ6IHN0cmluZykgPT4ge1xuICAgIHJldHVybiB0aGlzLl9yZXBvcnRTZXJ2aWNlLmZpbHRlcihrZXl3b3JkKTtcbiAgfTtcblxuICBwdWJsaWMgcmVwb3J0Q2hhbmdlKHJlcG9ydDogUmVwb3J0TGlzdEl0ZW0gfCBudWxsKTogdm9pZCB7XG4gICAgdGhpcy5yZXBvcnQgPSBudWxsO1xuICAgIHRoaXMuZWRpdE1vZGUgPSBmYWxzZTtcbiAgICB0aGlzLl9idWlsZFJlcG9ydENvbmZpZygpO1xuXG4gICAgaWYgKHJlcG9ydCkge1xuICAgICAgdGhpcy5fbG9hZFJlcG9ydChyZXBvcnQuaWQpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBjcmVhdGVSZXBvcnQoKTogdm9pZCB7XG4gICAgdGhpcy5fcHJvbXB0LmlucHV0KHtcbiAgICAgIHRpdGxlOiAnQ3JlYXRlIFJlcG9ydCcsXG4gICAgICBsYWJlbDogJ05hbWUnLFxuICAgICAgY29tbWl0TGFiZWw6ICdDcmVhdGUnLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgfSlcbiAgICAgIC5waXBlKFxuICAgICAgICBzd2l0Y2hNYXAoKG5hbWU6IHN0cmluZykgPT4gdGhpcy5fcmVwb3J0U2VydmljZS5jcmVhdGUobmFtZSkpLFxuICAgICAgICB0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5fZGVzdHJveVJlZiksXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKChyZXBvcnQ6IFJlcG9ydExpc3RJdGVtKSA9PiB7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWQgPSByZXBvcnQ7XG4gICAgICAgIHRoaXMuX2NkUmVmLm1hcmtGb3JDaGVjaygpO1xuICAgICAgICB0aGlzLl9sb2FkUmVwb3J0KHJlcG9ydC5pZCk7XG4gICAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyB0b2dnbGVFZGl0TW9kZSgpOiB2b2lkIHtcbiAgICB0aGlzLmVkaXRNb2RlID0gIXRoaXMuZWRpdE1vZGU7XG4gIH1cblxuICAvLyBUaGUgZWRpdCB0b29scyBsaXZlIGluIHRoaXMgdG9vbGJhciwgYnV0IHRoZSBjYW52YXMgb3ducyB3aGF0IHRoZXkgYWN0IG9uXG4gIC8vICh0aGUgYWN0aXZlIHBhZ2UsIHRoZSBoZWFkZXIvZm9vdGVyIGJhbmRzLCB3aGljaCBsYXllciBpcyBsaXZlKS5cbiAgcHVibGljIGdldCBpc01hc3Rlck1vZGUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX2NhbnZhcz8ubWFzdGVyTW9kZSgpID8/IGZhbHNlO1xuICB9XG5cbiAgcHVibGljIGFkZFRleHQoKTogdm9pZCB7XG4gICAgdGhpcy5fY2FudmFzPy5hZGRUZXh0KCk7XG4gIH1cblxuICBwdWJsaWMgdG9nZ2xlTWFzdGVyTW9kZSgpOiB2b2lkIHtcbiAgICB0aGlzLl9jYW52YXM/LnRvZ2dsZU1hc3Rlck1vZGUoKTtcbiAgfVxuXG4gIC8vIFJlcG9ydCBzZXR0aW5ncyDigJQgbmFtZSwgcGFnZSBzaXplLCBvcmllbnRhdGlvbiwgbGF5b3V0IG1vZGUuIFRoZSBwaWNrZXJcbiAgLy8gbGlzdCBhbmQgc3RydWN0dXJlIGJvdGggcmVsb2FkIG9uIHNhdmUgKGEgbGF5b3V0IHN3aXRjaCByZS1yZW5kZXJzIHRoZVxuICAvLyB3aG9sZSBjYW52YXMpLlxuICBwdWJsaWMgcmVwb3J0U2V0dGluZ3MoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnJlcG9ydCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuX2RpYWxvZy5vcGVuPFJlcG9ydFNldHRpbmdzQ29tcG9uZW50LCB1bmtub3duLCBSZXBvcnRTZXR0aW5nc1Jlc3VsdD4oUmVwb3J0U2V0dGluZ3NDb21wb25lbnQsIHtcbiAgICAgIGRhdGE6IHsgcmVwb3J0OiB0aGlzLnJlcG9ydCB9LFxuICAgICAgd2lkdGg6ICc0NjBweCcsXG4gICAgfSlcbiAgICAgIC5hZnRlckNsb3NlZCgpXG4gICAgICAucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5fZGVzdHJveVJlZikpXG4gICAgICAuc3Vic2NyaWJlKChyZXN1bHQpID0+IHtcbiAgICAgICAgLy8gVGhlIGRpYWxvZyBjb25maXJtcyArIHBlcmZvcm1zIHRoZSBkZWxldGUgaXRzZWxmOyB3ZSBqdXN0IHJlYWN0IHRvXG4gICAgICAgIC8vIHdoYXQgaXQgcmVwb3J0cyBiYWNrLlxuICAgICAgICBpZiAocmVzdWx0Py5hY3Rpb24gPT09ICdkZWxldGVkJykge1xuICAgICAgICAgIHRoaXMuc2VsZWN0ZWQgPSBudWxsO1xuICAgICAgICAgIHRoaXMucmVwb3J0ID0gbnVsbDtcbiAgICAgICAgICB0aGlzLl9idWlsZFJlcG9ydENvbmZpZygpO1xuICAgICAgICAgIHRoaXMuX2NkUmVmLm1hcmtGb3JDaGVjaygpO1xuXG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHJlc3VsdD8uYWN0aW9uID09PSAnc2F2ZWQnICYmIHRoaXMuc2VsZWN0ZWQpIHtcbiAgICAgICAgICB0aGlzLl9sb2FkUmVwb3J0KHRoaXMuc2VsZWN0ZWQuaWQpO1xuICAgICAgICAgIHRoaXMuX3JlZnJlc2hSZXBvcnROYW1lKHRoaXMuc2VsZWN0ZWQuaWQpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgfVxuXG4gIC8vIENvbXBvbmVudCBzZXR0aW5ncyDigJQgdGl0bGUsIGV4YWN0IGdlb21ldHJ5LCBhbmQgdGhlIGRpYWdub3N0aWMgdmlld3NcbiAgLy8gKFNRTCwgY29uZmlnLCBmaWx0ZXIgd2lyaW5nKS5cbiAgcHVibGljIGNvbXBvbmVudFNldHRpbmdzKGNvbXBvbmVudDogUmVwb3J0Q29tcG9uZW50TW9kZWwpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMucmVwb3J0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgZGlhbG9nUmVmID0gdGhpcy5fZGlhbG9nLm9wZW48Q29tcG9uZW50U2V0dGluZ3NDb21wb25lbnQsIHVua25vd24sIENvbXBvbmVudFNldHRpbmdzUmVzdWx0PihcbiAgICAgIENvbXBvbmVudFNldHRpbmdzQ29tcG9uZW50LFxuICAgICAge1xuICAgICAgICBkYXRhOiB7IHJlcG9ydDogdGhpcy5yZXBvcnQsIGNvbXBvbmVudCB9LFxuICAgICAgICB3aWR0aDogJzY0MHB4JyxcbiAgICAgIH0sXG4gICAgKTtcblxuICAgIC8vIEZpbHRlciBhZGQvcmVtb3ZlL2xldmVsIGNoYW5nZXMgcGVyc2lzdCBpbW1lZGlhdGVseSBpbnNpZGUgdGhlIGRpYWxvZyAobm9cbiAgICAvLyBcInNhdmVcIikgYW5kIGNhbiBsZWF2ZSBpdCBieSBhbiBleGl0IHRoYXQgY2FycmllcyBubyByZXN1bHQsIHNvIHRoZXkgYXJlXG4gICAgLy8gYW5ub3VuY2VkIGFzIHRoZXkgbGFuZC4gVGhlIHJlbG9hZCB3YWl0cyBmb3IgdGhlIGNsb3NlIHNvIHRoZSBjYW52YXMgaXNuJ3RcbiAgICAvLyByZS1yZW5kZXJpbmcgdW5kZXJuZWF0aCBhbiBvcGVuIGRpYWxvZy5cbiAgICBsZXQgZmlsdGVyc0NoYW5nZWQgPSBmYWxzZTtcbiAgICBkaWFsb2dSZWYuY29tcG9uZW50SW5zdGFuY2UuZmlsdGVyc0NoYW5nZWRcbiAgICAgIC5waXBlKHRha2VVbnRpbChkaWFsb2dSZWYuYWZ0ZXJDbG9zZWQoKSkpXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IGZpbHRlcnNDaGFuZ2VkID0gdHJ1ZSk7XG5cbiAgICBkaWFsb2dSZWYuYWZ0ZXJDbG9zZWQoKVxuICAgICAgLnBpcGUodGFrZVVudGlsRGVzdHJveWVkKHRoaXMuX2Rlc3Ryb3lSZWYpKVxuICAgICAgLnN1YnNjcmliZSgocmVzdWx0KSA9PiB7XG4gICAgICAgIC8vIFRoZSBkaWFsb2cgY29uZmlybXMgKyBwZXJmb3JtcyB0aGUgZGVsZXRlIGl0c2VsZi4gVGhlIGNvbXBvbmVudCBpc1xuICAgICAgICAvLyBnb25lIGZyb20gdGhlIHJlcG9ydCwgc28gcmVsb2FkIHJhdGhlciB0aGFuIHBhdGNoaW5nIGl0IG91dCBsb2NhbGx5IOKAlFxuICAgICAgICAvLyBpdHMgZmlsdGVycyB3ZW50IHdpdGggaXQsIHdoaWNoIHRoZSByZXBvcnQgYmFyIGhhcyB0byBiZSByZWJ1aWx0IGZvci5cbiAgICAgICAgaWYgKHJlc3VsdD8uZGVsZXRlZCkge1xuICAgICAgICAgIGlmICh0aGlzLnNlbGVjdGVkKSB7XG4gICAgICAgICAgICB0aGlzLl9sb2FkUmVwb3J0KHRoaXMuc2VsZWN0ZWQuaWQpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFRoZSByZXBvcnQncyBmaWx0ZXIgZ3JvdXBzIGNoYW5nZWQsIHNvIHRoZSByZXBvcnQgYmFyIGFuZCB0aGVcbiAgICAgICAgLy8gb24tY29tcG9uZW50IHN0cmlwcyBoYXZlIHRvIGJlIHJlYnVpbHQgZnJvbSBhIGZyZXNoIHJlcG9ydC5cbiAgICAgICAgaWYgKGZpbHRlcnNDaGFuZ2VkKSB7XG4gICAgICAgICAgaWYgKHRoaXMuc2VsZWN0ZWQpIHtcbiAgICAgICAgICAgIHRoaXMuX2xvYWRSZXBvcnQodGhpcy5zZWxlY3RlZC5pZCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gTm90aGluZyBlbHNlIGluIHRoZSBkaWFsb2cgdG91Y2hlcyB0aGUgcXVlcnkg4oCUIHRpdGxlIGFuZCBwYWRkaW5nIGFyZVxuICAgICAgICAvLyBwcmVzZW50YXRpb24uIFJlcGFpbnQgdGhlIG9uZSBjb21wb25lbnQgaXQgd2FzIG9wZW5lZCBmb3IgYW5kIGxlYXZlXG4gICAgICAgIC8vIGV2ZXJ5IG90aGVyIGNvbXBvbmVudCdzIGRhdGEsIGFuZCBpdHMgcXVlcnksIGFsb25lLlxuICAgICAgICBpZiAocmVzdWx0Py5zZXR0aW5ncykge1xuICAgICAgICAgIHRoaXMuX2NhbnZhcz8uYXBwbHlDb21wb25lbnRTZXR0aW5ncyhjb21wb25lbnQuaWQsIHJlc3VsdC5zZXR0aW5ncyk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9XG5cbiAgLy8gVGhlIGNhbnZhcyBjaGFuZ2VkIHRoZSByZXBvcnQncyBzdHJ1Y3R1cmUgKGFkZGVkIGEgcGFnZSkg4oCUIHJlLWZldGNoIHNvIHRoZVxuICAvLyBuZXcgcGFnZSByZW5kZXJzOyB0aGUgY2FudmFzIGxhbmRzIHRoZSB2aWV3IG9uIGl0LlxuICBwdWJsaWMgb25DYW52YXNSZXBvcnRDaGFuZ2VkKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnNlbGVjdGVkKSB7XG4gICAgICB0aGlzLl9sb2FkUmVwb3J0KHRoaXMuc2VsZWN0ZWQuaWQpO1xuICAgIH1cbiAgfVxuXG4gIC8vIEV4cG9ydCB0aGUgcmVwb3J0IHRvIFBvd2VyUG9pbnQsIGVudGlyZWx5IGNsaWVudC1zaWRlOiBldmVyeSBjb21wb25lbnQnc1xuICAvLyBkYXRhIGlzIGZldGNoZWQgZnJlc2ggd2l0aCB0aGUgY3VycmVudCBmaWx0ZXIgc3RhdGUgKGFsbCBwYWdlcywgbm90IGp1c3RcbiAgLy8gdGhlIHZpc2libGUgb25lKSwgdGhlbiBwcHR4Z2VuanMgYnVpbGRzIGEgZGVjayBvZiBOQVRJVkUgZWRpdGFibGUgY2hhcnRzIOKAlFxuICAvLyBwYWdlID0gc2xpZGUsIHBvc2l0aW9ucyAxOjEuIFRoZSBkb2NrIHNob3dzIHByb2dyZXNzIHVudGlsIHRoZSBmaWxlIHNhdmVzLlxuICBwdWJsaWMgZXhwb3J0UG93ZXJwb2ludCgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMucmVwb3J0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5fcHJvY2Vzcy5ydW4oXG4gICAgICAnRXhwb3J0aW5nIFBvd2VyUG9pbnQnLFxuICAgICAgdGhpcy5fZXhwb3J0U2VydmljZS5wb3dlcnBvaW50KHRoaXMucmVwb3J0KSxcbiAgICApO1xuICB9XG5cbiAgLy8gRXhwb3J0IHRvIFBERiwgZW50aXJlbHkgY2xpZW50LXNpZGU6IHNhbWUgY29sbGVjdGlvbiBwYXNzLCBjaGFydHMgcmVuZGVyZWRcbiAgLy8gdGhyb3VnaCBhbiBvZmZzY3JlZW4gRUNoYXJ0cyBpbnN0YW5jZSBhdCAzw5cgcGl4ZWwgcmF0aW8gKHBpeGVsLWlkZW50aWNhbFxuICAvLyB0byB0aGUgc2NyZWVuKSwgdGFibGVzIHZpYSBqc3BkZi1hdXRvdGFibGUg4oCUIHBhZ2UgPSBQREYgcGFnZS5cbiAgcHVibGljIGV4cG9ydFBkZigpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMucmVwb3J0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5fcHJvY2Vzcy5ydW4oXG4gICAgICAnRXhwb3J0aW5nIFBERicsXG4gICAgICB0aGlzLl9leHBvcnRTZXJ2aWNlLnBkZih0aGlzLnJlcG9ydCksXG4gICAgKTtcbiAgfVxuXG4gIC8vIFRoZSByYXcgZGF0YSBiZWhpbmQgdGhlIHdob2xlIHJlcG9ydCBpbiBvbmUgYWN0aW9uOiB0aGUgc2VydmVyIGV4cG9ydHMgZXZlcnlcbiAgLy8gY29tcG9uZW50J3MgZnVsbCBmaWx0ZXJlZCBkYXRhc2V0IGFuZCB6aXBzIG9uZSBDU1YgcGVyIGNvbXBvbmVudCwgZm9sZGVyZWRcbiAgLy8gYnkgcGFnZS4gYHRoaXNQYWdlYCBuYXJyb3dzIGl0IHRvIHRoZSBwYWdlIHRoZSBjYW52YXMgaXMgc2hvd2luZy4gVW5saWtlIHRoZVxuICAvLyBQREYvUG93ZXJQb2ludCBleHBvcnRzIHRoaXMgaXMgZW50aXJlbHkgc2VydmVyLXNpZGUg4oCUIG5vdGhpbmcgaXMgY29sbGVjdGVkXG4gIC8vIGluIHRoZSBicm93c2VyLCBzbyBpdCBpcyBub3QgY2FwcGVkIGJ5IHdoYXQgYSBzbGlkZSBjYW4gaG9sZC5cbiAgcHVibGljIGV4cG9ydERhdGEodGhpc1BhZ2UgPSBmYWxzZSk6IHZvaWQge1xuICAgIGNvbnN0IHJlcG9ydCA9IHRoaXMucmVwb3J0O1xuICAgIGlmICghcmVwb3J0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgcGFnZUlkID0gdGhpc1BhZ2UgPyB0aGlzLl9jYW52YXM/LmFjdGl2ZVBhZ2U/LmlkID8/IG51bGwgOiBudWxsO1xuXG4gICAgdGhpcy5fcHJvY2Vzcy5kb3dubG9hZChcbiAgICAgICdFeHBvcnRpbmcgZGF0YScsXG4gICAgICB0aGlzLl9yZXBvcnREYXRhLmV4cG9ydFJlcG9ydChyZXBvcnQuaWQsIHRoaXMuX2ZpbHRlclN0YXRlLnJlc29sdmVGb3JSZXBvcnQocmVwb3J0LCBwYWdlSWQpLCBwYWdlSWQpLFxuICAgICk7XG4gIH1cblxuICAvLyBSZWFjdCB0byBlYWNoIGNoYXQgdHVybiAoZnMtY2hhdCBoYW5kbGVzIHRoZSByZXF1ZXN0ICsgcGVyc2lzdGVuY2UpOyB3ZVxuICAvLyBvbmx5IGNhcmUgYWJvdXQgdGhlIHJlcG9ydCBzaWRlIGVmZmVjdHMgdGhpcyBjb250ZXh0J3MgYmFja2VuZCBmbGFncy5cbiAgcHVibGljIG9uQ2hhdFJlc3BvbnNlKHJlc3BvbnNlOiBGc0FpQ2hhdFJlc3BvbnNlKTogdm9pZCB7XG4gICAgLy8gVGhlIGFnZW50IGNoYW5nZWQgdGhlIHJlcG9ydCdzIHN0cnVjdHVyZSDigJQgcmUtZmV0Y2ggaXQuIFNlc3Npb24gZmlsdGVyXG4gICAgLy8gdmFsdWVzIHN1cnZpdmUgKHRoZSBmaWx0ZXItc3RhdGUgc2VydmljZSBrZWVwcyB2YWx1ZXMgZm9yIGdyb3VwcyB0aGF0XG4gICAgLy8gc3RpbGwgZXhpc3QpLlxuICAgIGlmIChyZXNwb25zZS5yZXBvcnRDaGFuZ2VkICYmIHRoaXMuc2VsZWN0ZWQpIHtcbiAgICAgIHRoaXMuX2xvYWRSZXBvcnQodGhpcy5zZWxlY3RlZC5pZCk7XG4gICAgfVxuXG4gICAgLy8gQSByZW5hbWUgY2hhbmdlcyBub3RoaW5nIHN0cnVjdHVyYWwg4oCUIHJlZnJlc2ggdGhlIHBpY2tlciBjaGlwIGxhYmVsLlxuICAgIGlmIChyZXNwb25zZS5yZXBvcnRSZW5hbWVkICYmIHRoaXMuc2VsZWN0ZWQpIHtcbiAgICAgIHRoaXMuX3JlZnJlc2hSZXBvcnROYW1lKHRoaXMuc2VsZWN0ZWQuaWQpO1xuICAgIH1cbiAgfVxuXG4gIC8vIERyYWcgdGhlIGRpdmlkZXIgYmV0d2VlbiB0aGUgY2hhdCBhbmQgY2FudmFzIHBhbmVzIChwb2ludGVyLWNhcHR1cmUgbG9vcFxuICAvLyBvdXRzaWRlIEFuZ3VsYXIpLlxuICBwdWJsaWMgb25SZXNpemVTdGFydChldmVudDogUG9pbnRlckV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuICAgIGNvbnN0IGhhbmRsZSA9IGV2ZW50LnRhcmdldCBhcyBIVE1MRWxlbWVudDtcbiAgICBoYW5kbGUuc2V0UG9pbnRlckNhcHR1cmUoZXZlbnQucG9pbnRlcklkKTtcbiAgICB0aGlzLl9zcGxpdC5uYXRpdmVFbGVtZW50LmNsYXNzTGlzdC5hZGQoJ3Jlc2l6aW5nJyk7XG5cbiAgICB0aGlzLl96b25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgIGNvbnN0IG1vdmUgPSAoZTogUG9pbnRlckV2ZW50KSA9PiB0aGlzLl9yZXNpemVUbyhlLmNsaWVudFgpO1xuICAgICAgY29uc3QgZW5kID0gKCkgPT4ge1xuICAgICAgICBoYW5kbGUucmVsZWFzZVBvaW50ZXJDYXB0dXJlKGV2ZW50LnBvaW50ZXJJZCk7XG4gICAgICAgIGhhbmRsZS5yZW1vdmVFdmVudExpc3RlbmVyKCdwb2ludGVybW92ZScsIG1vdmUpO1xuICAgICAgICBoYW5kbGUucmVtb3ZlRXZlbnRMaXN0ZW5lcigncG9pbnRlcnVwJywgZW5kKTtcbiAgICAgICAgaGFuZGxlLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJjYW5jZWwnLCBlbmQpO1xuICAgICAgICB0aGlzLl9zcGxpdC5uYXRpdmVFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoJ3Jlc2l6aW5nJyk7XG4gICAgICB9O1xuXG4gICAgICBoYW5kbGUuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcm1vdmUnLCBtb3ZlKTtcbiAgICAgIGhhbmRsZS5hZGRFdmVudExpc3RlbmVyKCdwb2ludGVydXAnLCBlbmQpO1xuICAgICAgaGFuZGxlLmFkZEV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJjYW5jZWwnLCBlbmQpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBfcmVzaXplVG8oY2xpZW50WDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgcmVjdCA9IHRoaXMuX3NwbGl0Lm5hdGl2ZUVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgaWYgKHJlY3Qud2lkdGggPT09IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCByYXRpbyA9IChjbGllbnRYIC0gcmVjdC5sZWZ0KSAvIHJlY3Qud2lkdGg7XG4gICAgY29uc3QgY2xhbXBlZCA9IE1hdGgubWluKDAuOCwgTWF0aC5tYXgoMC4yLCByYXRpbykpO1xuICAgIHRoaXMuX2NoYXRQYW5lbC5uYXRpdmVFbGVtZW50LnN0eWxlLmZsZXhCYXNpcyA9IGAke2NsYW1wZWQgKiAxMDB9JWA7XG4gIH1cblxuICBwcml2YXRlIF9sb2FkUmVwb3J0KHJlcG9ydElkOiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLl9yZXBvcnREYXRhLmdldChyZXBvcnRJZClcbiAgICAgIC5waXBlKHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLl9kZXN0cm95UmVmKSlcbiAgICAgIC5zdWJzY3JpYmUoKHJlcG9ydDogUmVwb3J0KSA9PiB7XG4gICAgICAgIHRoaXMucmVwb3J0ID0gcmVwb3J0O1xuICAgICAgICB0aGlzLl9maWx0ZXJTdGF0ZS5pbml0KHJlcG9ydCk7XG4gICAgICAgIHRoaXMuX2J1aWxkUmVwb3J0Q29uZmlnKCk7XG4gICAgICAgIHRoaXMuX2NkUmVmLm1hcmtGb3JDaGVjaygpO1xuICAgICAgfSk7XG4gIH1cblxuICAvLyBSZXBvcnQtbGV2ZWwgZmlsdGVyIGdyb3VwcyBpbiB0aGVpciBzYXZlZCBvcmRlciDigJQgdGhlIG9uZXMgdGhhdCByZW5kZXIgaW5cbiAgLy8gdGhlIHRvb2xiYXIgKGNvbXBvbmVudC1sZXZlbCBncm91cHMgcmVuZGVyIG9uIHRoZWlyIGNvbXBvbmVudHMpLlxuICBwcml2YXRlIF9yZXBvcnRHcm91cHMoKTogUmVwb3J0RmlsdGVyR3JvdXBbXSB7XG4gICAgcmV0dXJuICh0aGlzLnJlcG9ydD8uZmlsdGVyR3JvdXBzID8/IFtdKVxuICAgICAgLmZpbHRlcigoZ3JvdXApID0+IGdyb3VwLmxldmVsID09PSAncmVwb3J0JyB8fCBncm91cC5sZXZlbCA9PT0gJ2JvdGgnKVxuICAgICAgLnNvcnQoKGEsIGIpID0+IGEub3JkZXIgLSBiLm9yZGVyKTtcbiAgfVxuXG4gIC8vIEdhdGVzIHRoZSB0b29sYmFyIGZzLWZpbHRlciBzbyBpdCBpc24ndCByZW5kZXJlZCAodGFraW5nIHNwYWNlKSB3aGVuIHRoZXJlXG4gIC8vIGlzIG5vdGhpbmcgdG8gcHV0IGluIGl0IOKAlCBubyByZXBvcnQtbGV2ZWwgZmlsdGVycyBhbmQgbm8gZ3JvdXAtYnkgY29udHJvbC5cbiAgcHVibGljIGdldCByZXBvcnRIYXNGaWx0ZXJzKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9yZXBvcnRHcm91cHMoKS5sZW5ndGggPiAwIHx8ICEhdGhpcy5fZ3JvdXBCeUl0ZW0oKTtcbiAgfVxuXG4gIC8vIGZzLWZpbHRlciByZWFkcyBpdHMgY29uZmlnIG9ubHkgb25jZSAoYXQgaW5pdCkg4oCUIHJlLWJpbmRpbmcgZG9lcyBub3RoaW5nLlxuICAvLyBUaGUgdGVtcGxhdGUga2V5cyB0aGUgdG9vbGJhciBmcy1maWx0ZXIgb24gdGhpcyBzaWduYXR1cmUgc28gaXQncyByZWNyZWF0ZWRcbiAgLy8gKGFuZCByZS1yZWFkcyB0aGUgcmVidWlsdCBjb25maWcpIHdoZW5ldmVyIHRoZSByZXBvcnQtbGV2ZWwgZmlsdGVyIHNldFxuICAvLyBjaGFuZ2VzLCBlLmcuIGFmdGVyIHRoZSBjb21wb25lbnQgc2V0dGluZ3MgZGlhbG9nIGFkZHMvbW92ZXMgYSBmaWx0ZXIuXG4gIHB1YmxpYyBnZXQgcmVwb3J0RmlsdGVyS2V5KCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIFtcbiAgICAgIC8vIFRoZSBzdG9yZWQgZGVmYXVsdCBpcyBwYXJ0IG9mIHRoZSBzaWduYXR1cmU6IHNhdmluZyBhIG5ldyBkZWZhdWx0IGluIHJlcG9ydFxuICAgICAgLy8gc2V0dGluZ3MgcmVidWlsZHMgdGhlIGNvbmZpZywgYnV0IHdpdGhvdXQgYSBrZXkgY2hhbmdlIGZzLWZpbHRlciBrZWVwc1xuICAgICAgLy8gcmVuZGVyaW5nIHRoZSB2YWx1ZXMgaXQgd2FzIGNyZWF0ZWQgd2l0aCB1bnRpbCBhIGZ1bGwgcGFnZSByZWxvYWQuXG4gICAgICBncm91cEJ5U2lnbmF0dXJlKHRoaXMucmVwb3J0KSxcbiAgICAgIC4uLnRoaXMuX3JlcG9ydEdyb3VwcygpLm1hcCgoZ3JvdXApID0+IGAke2dyb3VwLmlkfToke2dyb3VwLmxldmVsfToke2dyb3VwLmxhYmVsfToke2RlZmF1bHRTaWduYXR1cmUoZ3JvdXApfWApLFxuICAgIF0uam9pbignfCcpO1xuICB9XG5cbiAgLy8gKFJlKWJ1aWxkIHRoZSB0b29sYmFyIGZzLWZpbHRlciBjb25maWcg4oCUIHRoZSByZXBvcnQtbGV2ZWwgZmlsdGVyIGl0ZW1zIGFuZFxuICAvLyB0aGVuIHRoZSBncm91cC1ieSBjb250cm9sLiBUaGUgcmVwb3J0J3MgYWN0aW9ucyBsaXZlIGluIHRoZSBmcy1tZW51IGJlc2lkZVxuICAvLyB0aGUgcGlja2VyLCBub3QgaGVyZS4gT25seSBidWlsdC91c2VkIG9uY2UgYSByZXBvcnQgaXMgbG9hZGVkICh0aGUgdGVtcGxhdGVcbiAgLy8gZ2F0ZXMgaXQgb24gYHJlcG9ydGApLlxuICBwcml2YXRlIF9idWlsZFJlcG9ydENvbmZpZygpOiB2b2lkIHtcbiAgICBjb25zdCByZXBvcnRJZCA9IHRoaXMucmVwb3J0Py5pZCA/PyBudWxsO1xuXG4gICAgLy8gRHJvcCBhIGdyYWluIHRoZSBjb250cm9sIG5vIGxvbmdlciBvZmZlcnMg4oCUIHRoZSBhZ2VudCBjYW4gbmFycm93IHRoZSBsaXN0XG4gICAgLy8gbWlkLXNlc3Npb24sIGFuZCBhbiBvdmVycmlkZSB0aGUgdmlld2VyIGNhbid0IHNlZSBpcyB3b3JzZSB0aGFuIG5vbmUuXG4gICAgaWYgKHRoaXMucmVwb3J0ICYmICFpc0dyYW51bGFyaXR5T2ZmZXJlZCh0aGlzLnJlcG9ydCwgdGhpcy5fZmlsdGVyU3RhdGUuZnJlcXVlbmN5KCkpKSB7XG4gICAgICB0aGlzLl9maWx0ZXJTdGF0ZS5zZXRGcmVxdWVuY3kobnVsbCk7XG4gICAgfVxuXG4gICAgY29uc3QgaXRlbXMgPSByZXBvcnRJZFxuICAgICAgPyB0aGlzLl9yZXBvcnRHcm91cHMoKS5tYXAoKGdyb3VwKSA9PlxuICAgICAgICBmaWx0ZXJJdGVtRm9yR3JvdXAoZ3JvdXAsIHRoaXMuX3JlcG9ydERhdGEsIHJlcG9ydElkLCB0aGlzLl9maWx0ZXJTdGF0ZS52YWx1ZShncm91cC5pZCkpKVxuICAgICAgOiBbXTtcblxuICAgIC8vIFRoZSBncm91cC1ieSBjb250cm9sIGxlYWRzIHRoZSBiYXIsIGFoZWFkIG9mIGV2ZXJ5IGZpbHRlcjogaXQgc2V0cyB0aGVcbiAgICAvLyBncmFpbiB0aGUgd2hvbGUgcmVwb3J0IGlzIHJlYWQgYXQsIHNvIGl0IGlzIHRoZSBmaXJzdCB0aGluZyBhIHZpZXdlclxuICAgIC8vIGRlY2lkZXMuIEl0IGlzIG5vdCBhIGZpbHRlciBncm91cCDigJQgaXQgcmUtYnVja2V0cyByb3dzIHJhdGhlciB0aGFuXG4gICAgLy8gbmFycm93aW5nIHRoZW0g4oCUIHNvIGl0IGlzIHBsYWNlZCBoZXJlIHJhdGhlciB0aGFuIG9yZGVyZWQgYW1vbmcgdGhlbS5cbiAgICBjb25zdCBncm91cEJ5SXRlbSA9IHRoaXMuX2dyb3VwQnlJdGVtKCk7XG4gICAgaWYgKGdyb3VwQnlJdGVtKSB7XG4gICAgICBpdGVtcy51bnNoaWZ0KGdyb3VwQnlJdGVtKTtcbiAgICB9XG5cbiAgICB0aGlzLnJlcG9ydEZpbHRlckNvbmZpZyA9IHtcbiAgICAgIC8vIE5ldmVyIHRvdWNoIHRoZSBVUkwgb3IgcGVyc2lzdCBmaWx0ZXIgc3RhdGUg4oCUIHJlcG9ydCBmaWx0ZXJzIGFyZVxuICAgICAgLy8gc2Vzc2lvbi1vbmx5LCBvd25lZCBieSBSZXBvcnRGaWx0ZXJTdGF0ZVNlcnZpY2UuXG4gICAgICBxdWVyeVBhcmFtOiBmYWxzZSxcbiAgICAgIHBlcnNpc3Q6IGZhbHNlLFxuICAgICAgaXRlbXMsXG4gICAgICBjaGFuZ2U6IChxdWVyeSkgPT4ge1xuICAgICAgICBmb3IgKGNvbnN0IHsgZ3JvdXBJZCwgdmFsdWUgfSBvZiBncm91cFZhbHVlc0Zyb21RdWVyeShxdWVyeSA/PyB7fSwgdGhpcy5fcmVwb3J0R3JvdXBzKCkpKSB7XG4gICAgICAgICAgdGhpcy5fZmlsdGVyU3RhdGUuc2V0VmFsdWUoZ3JvdXBJZCwgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIC8vIE5vdCBhIGZpbHRlciBncm91cCDigJQgdGhlIGdyYWluIGlzIHJlYWQgc3RyYWlnaHQgb2ZmIHRoZSBxdWVyeS5cbiAgICAgICAgdGhpcy5fZmlsdGVyU3RhdGUuc2V0RnJlcXVlbmN5KChxdWVyeT8uW0dST1VQX0JZX0lURU1dIGFzIENoYXJ0R3JhbnVsYXJpdHkpIHx8IG51bGwpO1xuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgLy8gVGhlIHJlcG9ydCdzIGdyb3VwLWJ5IGNvbnRyb2wgYXMgYW4gZnMtZmlsdGVyIGl0ZW0sIG9yIG51bGwgd2hlbiB0aGUgcmVwb3J0XG4gIC8vIGhhcyBub25lIHRvIHNob3cuIFNlZWRlZCBmcm9tIHRoZSBzZXNzaW9uIHN0YXRlIHNvIHRoZSBncmFpbiB0aGUgdmlld2VyXG4gIC8vIHBpY2tlZCBzdXJ2aXZlcyB0aGUgcmVwb3J0IGJlaW5nIHJlLWZldGNoZWQgYWZ0ZXIgYSBjaGF0IGVkaXQuXG4gIHByaXZhdGUgX2dyb3VwQnlJdGVtKCk6IElGaWx0ZXJDb25maWdJdGVtIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMucmVwb3J0XG4gICAgICA/IGdyb3VwQnlGaWx0ZXJJdGVtKHRoaXMucmVwb3J0LCB0aGlzLl9maWx0ZXJTdGF0ZS5mcmVxdWVuY3koKSlcbiAgICAgIDogbnVsbDtcbiAgfVxuXG4gIHByaXZhdGUgX3JlZnJlc2hSZXBvcnROYW1lKHJlcG9ydElkOiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLl9yZXBvcnRTZXJ2aWNlLmxvYWQoKVxuICAgICAgLnBpcGUodGFrZVVudGlsRGVzdHJveWVkKHRoaXMuX2Rlc3Ryb3lSZWYpKVxuICAgICAgLnN1YnNjcmliZSgocmVwb3J0czogUmVwb3J0TGlzdEl0ZW1bXSkgPT4ge1xuICAgICAgICBjb25zdCByZW5hbWVkID0gcmVwb3J0cy5maW5kKChyZXBvcnQpID0+IHJlcG9ydC5pZCA9PT0gcmVwb3J0SWQpO1xuICAgICAgICBpZiAocmVuYW1lZCkge1xuICAgICAgICAgIHRoaXMuc2VsZWN0ZWQgPSByZW5hbWVkO1xuICAgICAgICAgIGlmICh0aGlzLnJlcG9ydCkge1xuICAgICAgICAgICAgdGhpcy5yZXBvcnQgPSB7IC4uLnRoaXMucmVwb3J0LCBuYW1lOiByZW5hbWVkLm5hbWUgfTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5fY2RSZWYubWFya0ZvckNoZWNrKCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9XG59XG4iLCI8ZGl2XG4gICAgI3NwbGl0XG4gICAgY2xhc3M9XCJyZXBvcnQgZnMtcm93LmFsaWduLXN0YXJ0XCI+XG4gIDxmcy1haS1jaGF0XG4gICAgI2NoYXRQYW5lbFxuICAgIGNsYXNzPVwiY2hhdFwiXG4gICAgc3R5bGU9XCJtaW4taGVpZ2h0OiA1MDBweDtcIlxuICAgIGJhc2VQYXRoPVwicmVwb3J0c1wiXG4gICAgW3JlcXVlc3REYXRhXT1cInsgcmVwb3J0SWQ6IHNlbGVjdGVkPy5pZCA/PyBudWxsIH1cIlxuICAgIFtpbnRyb01lc3NhZ2VdPVwiaW50cm9NZXNzYWdlXCJcbiAgICAocmVzcG9uc2UpPVwib25DaGF0UmVzcG9uc2UoJGV2ZW50KVwiPlxuICA8L2ZzLWFpLWNoYXQ+XG4gIDxkaXZcbiAgICBjbGFzcz1cInJlc2l6ZXJcIlxuICAgIChwb2ludGVyZG93bik9XCJvblJlc2l6ZVN0YXJ0KCRldmVudClcIj5cbiAgPC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJ2aWV3ZXIgZnMtZmxleCBmcy1jb2x1bW5cIj5cbiAgICA8ZGl2IGNsYXNzPVwiZnMtcm93LmFsaWduLWNlbnRlci5nYXAtc21cIj5cbiAgICAgIDxmcy1hdXRvY29tcGxldGUtY2hpcHNcbiAgICAgICAgICBjbGFzcz1cImZzLWZsZXhcIlxuICAgICAgICAgIFtmZXRjaF09XCJmZXRjaFJlcG9ydHNcIlxuICAgICAgICAgIFsobmdNb2RlbCldPVwic2VsZWN0ZWRcIlxuICAgICAgICAgIFtkaXNhYmxlZF09XCJsb2FkaW5nUmVwb3J0c1wiXG4gICAgICAgICAgW3BhZGxlc3NdPVwidHJ1ZVwiXG4gICAgICAgICAgW211bHRpcGxlXT1cImZhbHNlXCJcbiAgICAgICAgICBbZmV0Y2hPbkZvY3VzXT1cInRydWVcIlxuICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cInJlcG9ydENoYW5nZSgkZXZlbnQpXCJcbiAgICAgICAgICBwbGFjZWhvbGRlcj1cIlJlcG9ydFwiXG4gICAgICAgICAgbmFtZT1cInJlcG9ydFwiPlxuICAgICAgICA8bmctdGVtcGxhdGVcbiAgICAgICAgICAgIGZzQXV0b2NvbXBsZXRlQ2hpcHNUZW1wbGF0ZVxuICAgICAgICAgICAgbGV0LW9iamVjdD1cIm9iamVjdFwiPlxuICAgICAgICAgIHt7IG9iamVjdC5uYW1lIH19XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgIDxuZy10ZW1wbGF0ZVxuICAgICAgICAgICAgZnNBdXRvY29tcGxldGVDaGlwc1N0YXRpY1xuICAgICAgICAgICAgKGNsaWNrKT1cImNyZWF0ZVJlcG9ydCgpXCI+XG4gICAgICAgICAgQ3JlYXRlIFJlcG9ydFxuICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgPC9mcy1hdXRvY29tcGxldGUtY2hpcHM+XG4gICAgICBAaWYgKHJlcG9ydCAmJiBlZGl0TW9kZSkge1xuICAgICAgICA8IS0tIFdoYXQgbGF5b3V0IGVkaXRpbmcgY2FuIGFkZCBvciBzd2l0Y2ggdG8sIGFuZCB0aGUgd2F5IG91dCBvZiBpdCDigJRcbiAgICAgICAgICAgICB0aGUgc2FtZSBvdXRsaW5lZCBidXR0b25zIGFzIHRoZSBmcy1haS1yZXBvcnQgdG9vbGJhci4gLS0+XG4gICAgICAgIDxidXR0b25cbiAgICAgICAgICAgIG1hdC1zdHJva2VkLWJ1dHRvblxuICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICBtYXRUb29sdGlwPVwiQWRkIGEgYmxvY2sgb2YgdGV4dFwiXG4gICAgICAgICAgICAoY2xpY2spPVwiYWRkVGV4dCgpXCI+XG4gICAgICAgICAgPG1hdC1pY29uPnRpdGxlPC9tYXQtaWNvbj5cbiAgICAgICAgICBBZGQgdGV4dFxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgbWF0LXN0cm9rZWQtYnV0dG9uXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIGNsYXNzPVwibWFzdGVyLXRvZ2dsZVwiXG4gICAgICAgICAgICBbY2xhc3MuYWN0aXZlXT1cImlzTWFzdGVyTW9kZVwiXG4gICAgICAgICAgICBbbWF0VG9vbHRpcF09XCJpc01hc3Rlck1vZGUgPyAnQmFjayB0byBlZGl0aW5nIHRoaXMgcGFnZScgOiAnRWRpdCB0aGUgaGVhZGVyIGFuZCBmb290ZXIgc2hvd24gb24gZXZlcnkgcGFnZSdcIlxuICAgICAgICAgICAgKGNsaWNrKT1cInRvZ2dsZU1hc3Rlck1vZGUoKVwiPlxuICAgICAgICAgIDxtYXQtaWNvbj53ZWJfYXNzZXQ8L21hdC1pY29uPlxuICAgICAgICAgIEhlYWRlciAmIGZvb3RlclxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgbWF0LXN0cm9rZWQtYnV0dG9uXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIChjbGljayk9XCJ0b2dnbGVFZGl0TW9kZSgpXCI+XG4gICAgICAgICAgPG1hdC1pY29uPmNoZWNrPC9tYXQtaWNvbj5cbiAgICAgICAgICBEb25lIGVkaXRpbmdcbiAgICAgICAgPC9idXR0b24+XG4gICAgICB9XG4gICAgICBAaWYgKHJlcG9ydCkge1xuICAgICAgICA8ZnMtbWVudT5cbiAgICAgICAgICA8bmctdGVtcGxhdGVcbiAgICAgICAgICAgICAgZnMtbWVudS1pdGVtXG4gICAgICAgICAgICAgIChjbGljayk9XCJyZXBvcnRTZXR0aW5ncygpXCI+XG4gICAgICAgICAgICA8bWF0LWljb24+XG4gICAgICAgICAgICAgIHR1bmVcbiAgICAgICAgICAgIDwvbWF0LWljb24+XG4gICAgICAgICAgICBSZXBvcnQgc2V0dGluZ3NcbiAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgIDxuZy10ZW1wbGF0ZVxuICAgICAgICAgICAgICBmcy1tZW51LWl0ZW1cbiAgICAgICAgICAgICAgKGNsaWNrKT1cInRvZ2dsZUVkaXRNb2RlKClcIlxuICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiZWRpdE1vZGVcIj5cbiAgICAgICAgICAgIDxtYXQtaWNvbj5cbiAgICAgICAgICAgICAgZGFzaGJvYXJkX2N1c3RvbWl6ZVxuICAgICAgICAgICAgPC9tYXQtaWNvbj5cbiAgICAgICAgICAgIHt7IGVkaXRNb2RlID8gJ0RvbmUgZWRpdGluZyBsYXlvdXQnIDogJ0VkaXQgbGF5b3V0JyB9fVxuICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgPG5nLXRlbXBsYXRlXG4gICAgICAgICAgICAgIGZzLW1lbnUtaXRlbVxuICAgICAgICAgICAgICAoY2xpY2spPVwiZXhwb3J0UG93ZXJwb2ludCgpXCI+XG4gICAgICAgICAgICA8bWF0LWljb24+XG4gICAgICAgICAgICAgIHNsaWRlc2hvd1xuICAgICAgICAgICAgPC9tYXQtaWNvbj5cbiAgICAgICAgICAgIEV4cG9ydCBQb3dlclBvaW50XG4gICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICA8bmctdGVtcGxhdGVcbiAgICAgICAgICAgICAgZnMtbWVudS1pdGVtXG4gICAgICAgICAgICAgIChjbGljayk9XCJleHBvcnRQZGYoKVwiPlxuICAgICAgICAgICAgPG1hdC1pY29uPlxuICAgICAgICAgICAgICBwaWN0dXJlX2FzX3BkZlxuICAgICAgICAgICAgPC9tYXQtaWNvbj5cbiAgICAgICAgICAgIEV4cG9ydCBQREZcbiAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgIDxuZy10ZW1wbGF0ZVxuICAgICAgICAgICAgICBmcy1tZW51LWl0ZW1cbiAgICAgICAgICAgICAgKGNsaWNrKT1cImV4cG9ydERhdGEoKVwiPlxuICAgICAgICAgICAgPG1hdC1pY29uPlxuICAgICAgICAgICAgICB0YWJsZV92aWV3XG4gICAgICAgICAgICA8L21hdC1pY29uPlxuICAgICAgICAgICAgRXhwb3J0IFJhdyBEYXRhXG4gICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICBAaWYgKChyZXBvcnQ/LnBhZ2VzPy5sZW5ndGggPz8gMCkgPiAxKSB7XG4gICAgICAgICAgICA8bmctdGVtcGxhdGVcbiAgICAgICAgICAgICAgICBmcy1tZW51LWl0ZW1cbiAgICAgICAgICAgICAgICAoY2xpY2spPVwiZXhwb3J0RGF0YSh0cnVlKVwiPlxuICAgICAgICAgICAgICA8bWF0LWljb24+XG4gICAgICAgICAgICAgICAgdGFibGVfdmlld1xuICAgICAgICAgICAgICA8L21hdC1pY29uPlxuICAgICAgICAgICAgICBFeHBvcnQgUmF3IERhdGEgKFRoaXMgUGFnZSlcbiAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgfVxuICAgICAgICA8L2ZzLW1lbnU+XG4gICAgICB9XG4gICAgPC9kaXY+XG4gICAgQGlmIChyZXBvcnQpIHtcbiAgICAgIDwhLS0gUmVwb3J0LWxldmVsIGZpbHRlcnMgb25seSAodGhlIHJlcG9ydCdzIGFjdGlvbnMgbGl2ZSBpbiB0aGUgbWVudVxuICAgICAgICAgICBhYm92ZSkuIGZzLWZpbHRlciByZWFkcyBpdHMgY29uZmlnIG9uY2UgYXQgaW5pdCwgc28gaXQncyBrZXllZCBvbiB0aGVcbiAgICAgICAgICAgZmlsdGVyIHNpZ25hdHVyZTogd2hlbiB0aGUgcmVwb3J0LWxldmVsIGZpbHRlciBzZXQgY2hhbmdlcyB0aGUgYmxvY2tcbiAgICAgICAgICAgaXMgcmVjcmVhdGVkIGFuZCByZS1yZWFkcyB0aGUgcmVidWlsdCBjb25maWcuIC0tPlxuICAgICAgQGlmIChyZXBvcnRIYXNGaWx0ZXJzKSB7XG4gICAgICAgIEBmb3IgKGtleSBvZiBbcmVwb3J0RmlsdGVyS2V5XTsgdHJhY2sga2V5KSB7XG4gICAgICAgICAgPGZzLWZpbHRlciBbY29uZmlnXT1cInJlcG9ydEZpbHRlckNvbmZpZ1wiPjwvZnMtZmlsdGVyPlxuICAgICAgICB9XG4gICAgICB9XG4gICAgICA8YXBwLXJlcG9ydC1jYW52YXNcbiAgICAgICAgW3JlcG9ydF09XCJyZXBvcnRcIlxuICAgICAgICBbZWRpdE1vZGVdPVwiZWRpdE1vZGVcIlxuICAgICAgICAoY29tcG9uZW50U2V0dGluZ3MpPVwiY29tcG9uZW50U2V0dGluZ3MoJGV2ZW50KVwiXG4gICAgICAgIChyZXBvcnRDaGFuZ2VkKT1cIm9uQ2FudmFzUmVwb3J0Q2hhbmdlZCgpXCI+XG4gICAgICA8L2FwcC1yZXBvcnQtY2FudmFzPlxuICAgIH1cbiAgPC9kaXY+XG48L2Rpdj4iXX0=
415
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvcmVwb3J0cy92aWV3cy9yZXBvcnQvcmVwb3J0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvcmVwb3J0cy92aWV3cy9yZXBvcnQvcmVwb3J0LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxzQkFBc0IsRUFBRSx1QkFBdUIsRUFBRSxTQUFTLEVBQzFELFVBQVUsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsTUFBTSxHQUMxRCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFN0MsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDakQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBRXZELE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQzNFLE9BQU8sRUFBZ0IsY0FBYyxFQUFxQixNQUFNLG9CQUFvQixDQUFDO0FBQ3JGLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNoRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDaEQsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBRTlDLE9BQU8sRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRWhFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDRCQUE0QixDQUFD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VUFBVSxpUkFDVixxQkFBcUI7OzRGQUdaLGVBQWU7a0JBOUIzQixTQUFTO3NDQUdTLHVCQUF1QixDQUFDLE1BQU0sY0FDbkMsSUFBSSxXQUNQLENBQUMsc0JBQXNCLENBQUMsYUFDdEI7d0JBQ1QsMkVBQTJFO3dCQUMzRSx1RUFBdUU7d0JBQ3ZFLHdCQUF3Qjt3QkFDeEIsNEJBQTRCO3dCQUM1QixpQkFBaUI7d0JBQ2pCLGdCQUFnQjt3QkFDaEIsbUJBQW1CO3dCQUNuQiwwRUFBMEU7d0JBQzFFLHNCQUFzQjt3QkFDdEIsa0JBQWtCLENBQUMsRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLHFCQUFxQixDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztxQkFDdEcsV0FDUTt3QkFDUCxXQUFXO3dCQUNYLHlCQUF5Qjt3QkFDekIsY0FBYzt3QkFDZCxZQUFZO3dCQUNaLGlCQUFpQjt3QkFDakIsU0FBUzt3QkFDVCxPQUFPO3dCQUNQLFVBQVU7d0JBQ1YscUJBQXFCO3FCQUN0Qjt3REFpQk8sTUFBTTtzQkFEYixTQUFTO3VCQUFDLE9BQU8sRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0JBSTVCLFVBQVU7c0JBRGpCLFNBQVM7dUJBQUMsV0FBVyxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFO2dCQU1sRCxPQUFPO3NCQURkLFNBQVM7dUJBQUMscUJBQXFCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ1VTVE9NX0VMRU1FTlRTX1NDSEVNQSwgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCxcbiAgRGVzdHJveVJlZiwgRWxlbWVudFJlZiwgTmdab25lLCBWaWV3Q2hpbGQsIGluamVjdCwgc2lnbmFsLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuXG5pbXBvcnQgeyBNYXRCdXR0b24gfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9idXR0b24nO1xuaW1wb3J0IHsgTWF0RGlhbG9nIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZGlhbG9nJztcbmltcG9ydCB7IE1hdEljb24gfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9pY29uJztcbmltcG9ydCB7IE1hdFRvb2x0aXAgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC90b29sdGlwJztcblxuaW1wb3J0IHsgRnNBdXRvY29tcGxldGVDaGlwc01vZHVsZSB9IGZyb20gJ0BmaXJlc3RpdGNoL2F1dG9jb21wbGV0ZS1jaGlwcyc7XG5pbXBvcnQgeyBGaWx0ZXJDb25maWcsIEZzRmlsdGVyTW9kdWxlLCBJRmlsdGVyQ29uZmlnSXRlbSB9IGZyb20gJ0BmaXJlc3RpdGNoL2ZpbHRlcic7XG5pbXBvcnQgeyBGc01lbnVNb2R1bGUgfSBmcm9tICdAZmlyZXN0aXRjaC9tZW51JztcbmltcG9ydCB7IEZzUHJvY2VzcyB9IGZyb20gJ0BmaXJlc3RpdGNoL3Byb2Nlc3MnO1xuaW1wb3J0IHsgRnNQcm9tcHQgfSBmcm9tICdAZmlyZXN0aXRjaC9wcm9tcHQnO1xuXG5pbXBvcnQgeyBmaW5hbGl6ZSwgc3dpdGNoTWFwLCB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IHRha2VVbnRpbERlc3Ryb3llZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUvcnhqcy1pbnRlcm9wJztcbmltcG9ydCB7IHByb3ZpZGVFY2hhcnRzQ29yZSB9IGZyb20gJ25neC1lY2hhcnRzJztcblxuaW1wb3J0IHsgRnNBaUNoYXRDb21wb25lbnQsIEZzQWlDaGF0UmVzcG9uc2UgfSBmcm9tICdAZmlyZXN0aXRjaC9haSc7XG5cbmltcG9ydCB7IFJlcG9ydENhbnZhc0NvbXBvbmVudCB9IGZyb20gJy4uLy4uL2NvbXBvbmVudHMvcmVwb3J0LWNhbnZhcy9yZXBvcnQtY2FudmFzLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBSZXBvcnREYXRhIH0gZnJvbSAnLi4vLi4vZGF0YS9yZXBvcnQuZGF0YSc7XG5pbXBvcnQgeyBDb21wb25lbnRTZXR0aW5nc0NvbXBvbmVudCwgQ29tcG9uZW50U2V0dGluZ3NSZXN1bHQgfSBmcm9tICcuLi8uLi9kaWFsb2dzL2NvbXBvbmVudC1zZXR0aW5ncy9jb21wb25lbnQtc2V0dGluZ3MuY29tcG9uZW50JztcbmltcG9ydCB7IFJlcG9ydFNldHRpbmdzQ29tcG9uZW50LCBSZXBvcnRTZXR0aW5nc1Jlc3VsdCB9IGZyb20gJy4uLy4uL2RpYWxvZ3MvcmVwb3J0LXNldHRpbmdzL3JlcG9ydC1zZXR0aW5ncy5jb21wb25lbnQnO1xuaW1wb3J0IHsgUmVwb3J0RXhwb3J0Q29sbGVjdG9yU2VydmljZSB9IGZyb20gJy4uLy4uL2V4cG9ydC9yZXBvcnQtZXhwb3J0LWNvbGxlY3Rvci5zZXJ2aWNlJztcbmltcG9ydCB7IFJlcG9ydEV4cG9ydFNlcnZpY2UgfSBmcm9tICcuLi8uLi9leHBvcnQvcmVwb3J0LWV4cG9ydC5zZXJ2aWNlJztcbmltcG9ydCB7IFJlcG9ydFBkZlNlcnZpY2UgfSBmcm9tICcuLi8uLi9leHBvcnQvcmVwb3J0LXBkZi5zZXJ2aWNlJztcbmltcG9ydCB7IFJlcG9ydFBwdHhTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vZXhwb3J0L3JlcG9ydC1wcHR4LnNlcnZpY2UnO1xuaW1wb3J0IHtcbiAgQ2hhcnRHcmFudWxhcml0eSwgUmVwb3J0LFxuICBSZXBvcnRDb21wb25lbnQgYXMgUmVwb3J0Q29tcG9uZW50TW9kZWwsIFJlcG9ydEZpbHRlckdyb3VwLCBSZXBvcnRMaXN0SXRlbSxcbn0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9yZXBvcnQuaW50ZXJmYWNlJztcbmltcG9ydCB7XG4gIEdST1VQX0JZX0lURU0sIGZpbHRlckl0ZW1Gb3JHcm91cCwgZ3JvdXBCeUZpbHRlckl0ZW0sIGdyb3VwQnlTaWduYXR1cmUsIGdyb3VwVmFsdWVzRnJvbVF1ZXJ5LFxuICBpc0dyYW51bGFyaXR5T2ZmZXJlZCxcbn0gZnJvbSAnLi4vLi4vcmVwb3J0LWZpbHRlci1pdGVtcyc7XG5pbXBvcnQgeyBSZXBvcnRGaWx0ZXJTdGF0ZVNlcnZpY2UsIGRlZmF1bHRTaWduYXR1cmUgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9yZXBvcnQtZmlsdGVyLXN0YXRlLnNlcnZpY2UnO1xuaW1wb3J0IHsgUmVwb3J0U2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL3JlcG9ydC5zZXJ2aWNlJztcblxuXG4vLyBUaGUgUmVwb3J0cyBwYWdlOiBBSSBjaGF0IG9uIHRoZSBsZWZ0LCB0aGUgcmVwb3J0IGNhbnZhcyBvbiB0aGUgcmlnaHQg4oCUXG4vLyBhIHNwbGl0LXBhbmUgbGF5b3V0OyB0aGUgdmlld2VyIGlzIG91ciBvd24gY2FudmFzIChubyBpZnJhbWUsIG5vIGVtYmVkIFVSTHMpLlxuLy8gVGhlIGNoYXQgaXMgYWx3YXlzIHNjb3BlZCB0byB0aGUgc2VsZWN0ZWQgcmVwb3J0OyBpdHMgaWQgcmlkZXMgb24gZXZlcnlcbi8vIHR1cm4gdmlhIFtyZXF1ZXN0RGF0YV0uXG5AQ29tcG9uZW50KHtcbiAgdGVtcGxhdGVVcmw6ICcuL3JlcG9ydC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3JlcG9ydC5jb21wb25lbnQuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgc2NoZW1hczogW0NVU1RPTV9FTEVNRU5UU19TQ0hFTUFdLFxuICBwcm92aWRlcnM6IFtcbiAgICAvLyBTZXNzaW9uIGZpbHRlciBzdGF0ZSBpcyBwZXItb3Blbi1yZXBvcnQtcGFnZSwgbm90IGFwcC1nbG9iYWw7IHRoZSBleHBvcnRcbiAgICAvLyBzZXJ2aWNlcyByZXNvbHZlIGZpbHRlcnMgdGhyb3VnaCBpdCwgc28gdGhleSBsaXZlIGF0IHRoZSBzYW1lIGxldmVsLlxuICAgIFJlcG9ydEZpbHRlclN0YXRlU2VydmljZSxcbiAgICBSZXBvcnRFeHBvcnRDb2xsZWN0b3JTZXJ2aWNlLFxuICAgIFJlcG9ydFBwdHhTZXJ2aWNlLFxuICAgIFJlcG9ydFBkZlNlcnZpY2UsXG4gICAgUmVwb3J0RXhwb3J0U2VydmljZSxcbiAgICAvLyBUcmVlLXNoYWtlbiBFQ2hhcnRzIGNvcmUgKyB0aGUgJ3JlcG9ydCcgaG91c2UgdGhlbWUsIGxvYWRlZCBsYXppbHkgd2l0aFxuICAgIC8vIHRoaXMgcm91dGUncyBjaHVuay5cbiAgICBwcm92aWRlRWNoYXJ0c0NvcmUoeyBlY2hhcnRzOiAoKSA9PiBpbXBvcnQoJy4uLy4uL3RoZW1lL2VjaGFydHMnKS50aGVuKChtb2R1bGUpID0+IG1vZHVsZS5kZWZhdWx0KSB9KSxcbiAgXSxcbiAgaW1wb3J0czogW1xuICAgIEZvcm1zTW9kdWxlLFxuICAgIEZzQXV0b2NvbXBsZXRlQ2hpcHNNb2R1bGUsXG4gICAgRnNGaWx0ZXJNb2R1bGUsXG4gICAgRnNNZW51TW9kdWxlLFxuICAgIEZzQWlDaGF0Q29tcG9uZW50LFxuICAgIE1hdEJ1dHRvbixcbiAgICBNYXRJY29uLFxuICAgIE1hdFRvb2x0aXAsXG4gICAgUmVwb3J0Q2FudmFzQ29tcG9uZW50LFxuICBdLFxufSlcbmV4cG9ydCBjbGFzcyBSZXBvcnRDb21wb25lbnQge1xuXG4gIC8vIFRoZSBzaW5nbGUgcmVwb3J0IHRoZSB2aWV3ZXIgYW5kIGNoYXQgYXJlIGZvY3VzZWQgb24uXG4gIHB1YmxpYyByZWFkb25seSBzZWxlY3RlZCA9IHNpZ25hbDxSZXBvcnRMaXN0SXRlbSB8IG51bGw+KG51bGwpO1xuICBwdWJsaWMgcmVhZG9ubHkgcmVwb3J0ID0gc2lnbmFsPFJlcG9ydCB8IG51bGw+KG51bGwpO1xuICBwdWJsaWMgcmVhZG9ubHkgbG9hZGluZ1JlcG9ydHMgPSBzaWduYWwodHJ1ZSk7XG4gIHB1YmxpYyByZWFkb25seSBlZGl0TW9kZSA9IHNpZ25hbChmYWxzZSk7XG5cbiAgLy8gVGhlIHJlcG9ydCB0b29sYmFyIElTIGFuIGZzLWZpbHRlcjogdGhlIHBpY2tlciByaWRlcyBpbiBpdHMgaGVhZGluZ1xuICAvLyB0ZW1wbGF0ZSwgdGhlIG1lbnUgYmVjb21lcyBpdHMgYWN0aW9ucywgYW5kIHJlcG9ydC1sZXZlbCBmaWx0ZXIgZ3JvdXBzXG4gIC8vIGJlY29tZSBpdHMgaXRlbXMuIFJlYnVpbHQgd2hlbmV2ZXIgdGhlIGxvYWRlZCByZXBvcnQgKGFuZCB0aHVzIGl0cyBncm91cHMpXG4gIC8vIGNoYW5nZXM7IHRoZSBtZW51J3Mgc2hvdy1ndWFyZHMga2VlcCB3b3JraW5nIHdoaWxlIG5vIHJlcG9ydCBpcyBzZWxlY3RlZC5cbiAgcHVibGljIHJlYWRvbmx5IHJlcG9ydEZpbHRlckNvbmZpZyA9IHNpZ25hbDxGaWx0ZXJDb25maWc+KG51bGwpO1xuXG4gIEBWaWV3Q2hpbGQoJ3NwbGl0JywgeyBzdGF0aWM6IHRydWUgfSlcbiAgcHJpdmF0ZSBfc3BsaXQhOiBFbGVtZW50UmVmPEhUTUxEaXZFbGVtZW50PjtcblxuICBAVmlld0NoaWxkKCdjaGF0UGFuZWwnLCB7IHN0YXRpYzogdHJ1ZSwgcmVhZDogRWxlbWVudFJlZiB9KVxuICBwcml2YXRlIF9jaGF0UGFuZWwhOiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PjtcblxuICAvLyBPbmx5IHRoZSBjYW52YXMga25vd3Mgd2hpY2ggcGFnZSBpcyBvbiBzY3JlZW4sIGFuZCBhIHBhZ2Utc2NvcGVkIGV4cG9ydFxuICAvLyBoYXMgdG8gYXNrIGl0LlxuICBAVmlld0NoaWxkKFJlcG9ydENhbnZhc0NvbXBvbmVudClcbiAgcHJpdmF0ZSBfY2FudmFzPzogUmVwb3J0Q2FudmFzQ29tcG9uZW50O1xuXG4gIHB1YmxpYyByZWFkb25seSBpbnRyb01lc3NhZ2UgPSB7XG4gICAgdGV4dDogJycsXG4gIH07XG5cbiAgcHJpdmF0ZSBfcmVwb3J0RGF0YSA9IGluamVjdChSZXBvcnREYXRhKTtcbiAgcHJpdmF0ZSBfcmVwb3J0U2VydmljZSA9IGluamVjdChSZXBvcnRTZXJ2aWNlKTtcbiAgcHJpdmF0ZSBfZmlsdGVyU3RhdGUgPSBpbmplY3QoUmVwb3J0RmlsdGVyU3RhdGVTZXJ2aWNlKTtcbiAgcHJpdmF0ZSBfZXhwb3J0U2VydmljZSA9IGluamVjdChSZXBvcnRFeHBvcnRTZXJ2aWNlKTtcbiAgcHJpdmF0ZSBfY29sbGVjdG9yID0gaW5qZWN0KFJlcG9ydEV4cG9ydENvbGxlY3RvclNlcnZpY2UpO1xuICBwcml2YXRlIF9wcm9jZXNzID0gaW5qZWN0KEZzUHJvY2Vzcyk7XG4gIHByaXZhdGUgX3Byb21wdCA9IGluamVjdChGc1Byb21wdCk7XG4gIHByaXZhdGUgX2RpYWxvZyA9IGluamVjdChNYXREaWFsb2cpO1xuICBwcml2YXRlIF9kZXN0cm95UmVmID0gaW5qZWN0KERlc3Ryb3lSZWYpO1xuICBwcml2YXRlIF96b25lID0gaW5qZWN0KE5nWm9uZSk7XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgdGhpcy5fYnVpbGRSZXBvcnRDb25maWcoKTtcblxuICAgIHRoaXMuX3JlcG9ydFNlcnZpY2UubG9hZCgpXG4gICAgICAucGlwZShcbiAgICAgICAgZmluYWxpemUoKCkgPT4ge1xuICAgICAgICAgIHRoaXMubG9hZGluZ1JlcG9ydHMuc2V0KGZhbHNlKTtcbiAgICAgICAgfSksXG4gICAgICAgIHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLl9kZXN0cm95UmVmKSxcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUoeyBlcnJvcjogKCkgPT4gdW5kZWZpbmVkIH0pO1xuICB9XG5cbiAgcHVibGljIGZldGNoUmVwb3J0cyA9IChrZXl3b3JkOiBzdHJpbmcpID0+IHtcbiAgICByZXR1cm4gdGhpcy5fcmVwb3J0U2VydmljZS5maWx0ZXIoa2V5d29yZCk7XG4gIH07XG5cbiAgcHVibGljIHJlcG9ydENoYW5nZShyZXBvcnQ6IFJlcG9ydExpc3RJdGVtIHwgbnVsbCk6IHZvaWQge1xuICAgIHRoaXMucmVwb3J0LnNldChudWxsKTtcbiAgICB0aGlzLmVkaXRNb2RlLnNldChmYWxzZSk7XG4gICAgdGhpcy5fYnVpbGRSZXBvcnRDb25maWcoKTtcblxuICAgIGlmIChyZXBvcnQpIHtcbiAgICAgIHRoaXMuX2xvYWRSZXBvcnQocmVwb3J0LmlkKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgY3JlYXRlUmVwb3J0KCk6IHZvaWQge1xuICAgIHRoaXMuX3Byb21wdC5pbnB1dCh7XG4gICAgICB0aXRsZTogJ0NyZWF0ZSBSZXBvcnQnLFxuICAgICAgbGFiZWw6ICdOYW1lJyxcbiAgICAgIGNvbW1pdExhYmVsOiAnQ3JlYXRlJyxcbiAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgIH0pXG4gICAgICAucGlwZShcbiAgICAgICAgc3dpdGNoTWFwKChuYW1lOiBzdHJpbmcpID0+IHRoaXMuX3JlcG9ydFNlcnZpY2UuY3JlYXRlKG5hbWUpKSxcbiAgICAgICAgdGFrZVVudGlsRGVzdHJveWVkKHRoaXMuX2Rlc3Ryb3lSZWYpLFxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgocmVwb3J0OiBSZXBvcnRMaXN0SXRlbSkgPT4ge1xuICAgICAgICB0aGlzLnNlbGVjdGVkLnNldChyZXBvcnQpO1xuICAgICAgICB0aGlzLl9sb2FkUmVwb3J0KHJlcG9ydC5pZCk7XG4gICAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyB0b2dnbGVFZGl0TW9kZSgpOiB2b2lkIHtcbiAgICB0aGlzLmVkaXRNb2RlLnVwZGF0ZSgoZWRpdE1vZGUpID0+ICFlZGl0TW9kZSk7XG4gIH1cblxuICAvLyBUaGUgZWRpdCB0b29scyBsaXZlIGluIHRoaXMgdG9vbGJhciwgYnV0IHRoZSBjYW52YXMgb3ducyB3aGF0IHRoZXkgYWN0IG9uXG4gIC8vICh0aGUgYWN0aXZlIHBhZ2UsIHRoZSBoZWFkZXIvZm9vdGVyIGJhbmRzLCB3aGljaCBsYXllciBpcyBsaXZlKS5cbiAgcHVibGljIGdldCBpc01hc3Rlck1vZGUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX2NhbnZhcz8ubWFzdGVyTW9kZSgpID8/IGZhbHNlO1xuICB9XG5cbiAgcHVibGljIGFkZFRleHQoKTogdm9pZCB7XG4gICAgdGhpcy5fY2FudmFzPy5hZGRUZXh0KCk7XG4gIH1cblxuICBwdWJsaWMgdG9nZ2xlTWFzdGVyTW9kZSgpOiB2b2lkIHtcbiAgICB0aGlzLl9jYW52YXM/LnRvZ2dsZU1hc3Rlck1vZGUoKTtcbiAgfVxuXG4gIC8vIFJlcG9ydCBzZXR0aW5ncyDigJQgbmFtZSwgcGFnZSBzaXplLCBvcmllbnRhdGlvbiwgbGF5b3V0IG1vZGUuIFRoZSBwaWNrZXJcbiAgLy8gbGlzdCBhbmQgc3RydWN0dXJlIGJvdGggcmVsb2FkIG9uIHNhdmUgKGEgbGF5b3V0IHN3aXRjaCByZS1yZW5kZXJzIHRoZVxuICAvLyB3aG9sZSBjYW52YXMpLlxuICBwdWJsaWMgcmVwb3J0U2V0dGluZ3MoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnJlcG9ydCgpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5fZGlhbG9nLm9wZW48UmVwb3J0U2V0dGluZ3NDb21wb25lbnQsIHVua25vd24sIFJlcG9ydFNldHRpbmdzUmVzdWx0PihSZXBvcnRTZXR0aW5nc0NvbXBvbmVudCwge1xuICAgICAgZGF0YTogeyByZXBvcnQ6IHRoaXMucmVwb3J0KCkgfSxcbiAgICAgIHdpZHRoOiAnNDYwcHgnLFxuICAgIH0pXG4gICAgICAuYWZ0ZXJDbG9zZWQoKVxuICAgICAgLnBpcGUodGFrZVVudGlsRGVzdHJveWVkKHRoaXMuX2Rlc3Ryb3lSZWYpKVxuICAgICAgLnN1YnNjcmliZSgocmVzdWx0KSA9PiB7XG4gICAgICAgIC8vIFRoZSBkaWFsb2cgY29uZmlybXMgKyBwZXJmb3JtcyB0aGUgZGVsZXRlIGl0c2VsZjsgd2UganVzdCByZWFjdCB0b1xuICAgICAgICAvLyB3aGF0IGl0IHJlcG9ydHMgYmFjay5cbiAgICAgICAgaWYgKHJlc3VsdD8uYWN0aW9uID09PSAnZGVsZXRlZCcpIHtcbiAgICAgICAgICB0aGlzLnNlbGVjdGVkLnNldChudWxsKTtcbiAgICAgICAgICB0aGlzLnJlcG9ydC5zZXQobnVsbCk7XG4gICAgICAgICAgdGhpcy5fYnVpbGRSZXBvcnRDb25maWcoKTtcblxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChyZXN1bHQ/LmFjdGlvbiA9PT0gJ3NhdmVkJyAmJiB0aGlzLnNlbGVjdGVkKCkpIHtcbiAgICAgICAgICB0aGlzLl9sb2FkUmVwb3J0KHRoaXMuc2VsZWN0ZWQoKS5pZCk7XG4gICAgICAgICAgdGhpcy5fcmVmcmVzaFJlcG9ydE5hbWUodGhpcy5zZWxlY3RlZCgpLmlkKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cblxuICAvLyBDb21wb25lbnQgc2V0dGluZ3Mg4oCUIHRpdGxlLCBleGFjdCBnZW9tZXRyeSwgYW5kIHRoZSBkaWFnbm9zdGljIHZpZXdzXG4gIC8vIChTUUwsIGNvbmZpZywgZmlsdGVyIHdpcmluZykuXG4gIHB1YmxpYyBjb21wb25lbnRTZXR0aW5ncyhjb21wb25lbnQ6IFJlcG9ydENvbXBvbmVudE1vZGVsKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnJlcG9ydCgpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgZGlhbG9nUmVmID0gdGhpcy5fZGlhbG9nLm9wZW48Q29tcG9uZW50U2V0dGluZ3NDb21wb25lbnQsIHVua25vd24sIENvbXBvbmVudFNldHRpbmdzUmVzdWx0PihcbiAgICAgIENvbXBvbmVudFNldHRpbmdzQ29tcG9uZW50LFxuICAgICAge1xuICAgICAgICBkYXRhOiB7IHJlcG9ydDogdGhpcy5yZXBvcnQoKSwgY29tcG9uZW50IH0sXG4gICAgICAgIHdpZHRoOiAnNjQwcHgnLFxuICAgICAgfSxcbiAgICApO1xuXG4gICAgLy8gRmlsdGVyIGFkZC9yZW1vdmUvbGV2ZWwgY2hhbmdlcyBwZXJzaXN0IGltbWVkaWF0ZWx5IGluc2lkZSB0aGUgZGlhbG9nIChub1xuICAgIC8vIFwic2F2ZVwiKSBhbmQgY2FuIGxlYXZlIGl0IGJ5IGFuIGV4aXQgdGhhdCBjYXJyaWVzIG5vIHJlc3VsdCwgc28gdGhleSBhcmVcbiAgICAvLyBhbm5vdW5jZWQgYXMgdGhleSBsYW5kLiBUaGUgcmVsb2FkIHdhaXRzIGZvciB0aGUgY2xvc2Ugc28gdGhlIGNhbnZhcyBpc24ndFxuICAgIC8vIHJlLXJlbmRlcmluZyB1bmRlcm5lYXRoIGFuIG9wZW4gZGlhbG9nLlxuICAgIGxldCBmaWx0ZXJzQ2hhbmdlZCA9IGZhbHNlO1xuICAgIGRpYWxvZ1JlZi5jb21wb25lbnRJbnN0YW5jZS5maWx0ZXJzQ2hhbmdlZFxuICAgICAgLnBpcGUodGFrZVVudGlsKGRpYWxvZ1JlZi5hZnRlckNsb3NlZCgpKSlcbiAgICAgIC5zdWJzY3JpYmUoKCkgPT4gZmlsdGVyc0NoYW5nZWQgPSB0cnVlKTtcblxuICAgIGRpYWxvZ1JlZi5hZnRlckNsb3NlZCgpXG4gICAgICAucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5fZGVzdHJveVJlZikpXG4gICAgICAuc3Vic2NyaWJlKChyZXN1bHQpID0+IHtcbiAgICAgICAgLy8gVGhlIGRpYWxvZyBjb25maXJtcyArIHBlcmZvcm1zIHRoZSBkZWxldGUgaXRzZWxmLiBUaGUgY29tcG9uZW50IGlzXG4gICAgICAgIC8vIGdvbmUgZnJvbSB0aGUgcmVwb3J0LCBzbyByZWxvYWQgcmF0aGVyIHRoYW4gcGF0Y2hpbmcgaXQgb3V0IGxvY2FsbHkg4oCUXG4gICAgICAgIC8vIGl0cyBmaWx0ZXJzIHdlbnQgd2l0aCBpdCwgd2hpY2ggdGhlIHJlcG9ydCBiYXIgaGFzIHRvIGJlIHJlYnVpbHQgZm9yLlxuICAgICAgICBpZiAocmVzdWx0Py5kZWxldGVkKSB7XG4gICAgICAgICAgaWYgKHRoaXMuc2VsZWN0ZWQoKSkge1xuICAgICAgICAgICAgdGhpcy5fbG9hZFJlcG9ydCh0aGlzLnNlbGVjdGVkKCkuaWQpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFRoZSByZXBvcnQncyBmaWx0ZXIgZ3JvdXBzIGNoYW5nZWQsIHNvIHRoZSByZXBvcnQgYmFyIGFuZCB0aGVcbiAgICAgICAgLy8gb24tY29tcG9uZW50IHN0cmlwcyBoYXZlIHRvIGJlIHJlYnVpbHQgZnJvbSBhIGZyZXNoIHJlcG9ydC5cbiAgICAgICAgaWYgKGZpbHRlcnNDaGFuZ2VkKSB7XG4gICAgICAgICAgaWYgKHRoaXMuc2VsZWN0ZWQoKSkge1xuICAgICAgICAgICAgdGhpcy5fbG9hZFJlcG9ydCh0aGlzLnNlbGVjdGVkKCkuaWQpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIE5vdGhpbmcgZWxzZSBpbiB0aGUgZGlhbG9nIHRvdWNoZXMgdGhlIHF1ZXJ5IOKAlCB0aXRsZSBhbmQgcGFkZGluZyBhcmVcbiAgICAgICAgLy8gcHJlc2VudGF0aW9uLiBSZXBhaW50IHRoZSBvbmUgY29tcG9uZW50IGl0IHdhcyBvcGVuZWQgZm9yIGFuZCBsZWF2ZVxuICAgICAgICAvLyBldmVyeSBvdGhlciBjb21wb25lbnQncyBkYXRhLCBhbmQgaXRzIHF1ZXJ5LCBhbG9uZS5cbiAgICAgICAgaWYgKHJlc3VsdD8uc2V0dGluZ3MpIHtcbiAgICAgICAgICB0aGlzLl9jYW52YXM/LmFwcGx5Q29tcG9uZW50U2V0dGluZ3MoY29tcG9uZW50LmlkLCByZXN1bHQuc2V0dGluZ3MpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgfVxuXG4gIC8vIFRoZSBjYW52YXMgY2hhbmdlZCB0aGUgcmVwb3J0J3Mgc3RydWN0dXJlIChhZGRlZCBhIHBhZ2UpIOKAlCByZS1mZXRjaCBzbyB0aGVcbiAgLy8gbmV3IHBhZ2UgcmVuZGVyczsgdGhlIGNhbnZhcyBsYW5kcyB0aGUgdmlldyBvbiBpdC5cbiAgcHVibGljIG9uQ2FudmFzUmVwb3J0Q2hhbmdlZCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5zZWxlY3RlZCgpKSB7XG4gICAgICB0aGlzLl9sb2FkUmVwb3J0KHRoaXMuc2VsZWN0ZWQoKS5pZCk7XG4gICAgfVxuICB9XG5cbiAgLy8gRXhwb3J0IHRoZSByZXBvcnQgdG8gUG93ZXJQb2ludCwgZW50aXJlbHkgY2xpZW50LXNpZGU6IGV2ZXJ5IGNvbXBvbmVudCdzXG4gIC8vIGRhdGEgaXMgZmV0Y2hlZCBmcmVzaCB3aXRoIHRoZSBjdXJyZW50IGZpbHRlciBzdGF0ZSAoYWxsIHBhZ2VzLCBub3QganVzdFxuICAvLyB0aGUgdmlzaWJsZSBvbmUpLCB0aGVuIHBwdHhnZW5qcyBidWlsZHMgYSBkZWNrIG9mIE5BVElWRSBlZGl0YWJsZSBjaGFydHMg4oCUXG4gIC8vIHBhZ2UgPSBzbGlkZSwgcG9zaXRpb25zIDE6MS4gVGhlIGRvY2sgc2hvd3MgcHJvZ3Jlc3MgdW50aWwgdGhlIGZpbGUgc2F2ZXMuXG4gIHB1YmxpYyBleHBvcnRQb3dlcnBvaW50KCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5yZXBvcnQoKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuX3Byb2Nlc3MucnVuKFxuICAgICAgJ0V4cG9ydGluZyBQb3dlclBvaW50JyxcbiAgICAgIHRoaXMuX2V4cG9ydFNlcnZpY2UucG93ZXJwb2ludCh0aGlzLnJlcG9ydCgpKSxcbiAgICApO1xuICB9XG5cbiAgLy8gRXhwb3J0IHRvIFBERiwgZW50aXJlbHkgY2xpZW50LXNpZGU6IHNhbWUgY29sbGVjdGlvbiBwYXNzLCBjaGFydHMgcmVuZGVyZWRcbiAgLy8gdGhyb3VnaCBhbiBvZmZzY3JlZW4gRUNoYXJ0cyBpbnN0YW5jZSBhdCAzw5cgcGl4ZWwgcmF0aW8gKHBpeGVsLWlkZW50aWNhbFxuICAvLyB0byB0aGUgc2NyZWVuKSwgdGFibGVzIHZpYSBqc3BkZi1hdXRvdGFibGUg4oCUIHBhZ2UgPSBQREYgcGFnZS5cbiAgcHVibGljIGV4cG9ydFBkZigpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMucmVwb3J0KCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLl9wcm9jZXNzLnJ1bihcbiAgICAgICdFeHBvcnRpbmcgUERGJyxcbiAgICAgIHRoaXMuX2V4cG9ydFNlcnZpY2UucGRmKHRoaXMucmVwb3J0KCkpLFxuICAgICk7XG4gIH1cblxuICAvLyBUaGUgd2hvbGUgcmVwb3J0IGFzIGZpbGVzIGluIG9uZSBhY3Rpb246IHRoZSBzZXJ2ZXIgd3JpdGVzIG9uZSBDU1YgcGVyXG4gIC8vIGNvbXBvbmVudCwgZWFjaCB3aGF0IHRoZSBzY3JlZW4gc2hvd3MgKGEgY2hhcnQgb3IgS1BJIGFzIGRyYXduLCBhdCB0aGVcbiAgLy8gdmlld2VyJ3MgZ3JvdXAtYnkgZ3JhaW47IGEgbGlzdCBpbiBmdWxsKSwgYW5kIHppcHMgdGhlbSBmb2xkZXJlZCBieSBwYWdlXG4gIC8vIHdpdGggYW4gRXhwb3J0IE5vdGVzLnR4dCB0aGF0IHJlY29yZHMgdGhlIGZpbHRlcnMgYXMgdGhlIGJhciByZWFkcyB0aGVtLlxuICAvLyBMaXN0cyB1c2UgdGhlaXIgc2F2ZWQgZGVmYXVsdCBzb3J0OyBhIGhlYWRlciBjbGljayBpcyBjYXJyaWVkIG9ubHkgYnkgYVxuICAvLyBjb21wb25lbnQncyBvd24gQ1NWIGV4cG9ydC4gYHRoaXNQYWdlYCBuYXJyb3dzIGl0IHRvIHRoZSBwYWdlIHRoZSBjYW52YXMgaXNcbiAgLy8gc2hvd2luZy4gVW5saWtlIHRoZSBQREYvUG93ZXJQb2ludCBleHBvcnRzIHRoZSBmaWxlcyBhcmUgd3JpdHRlblxuICAvLyBzZXJ2ZXItc2lkZSwgc28gdGhleSBhcmUgbm90IGNhcHBlZCBieSB3aGF0IGEgc2xpZGUgY2FuIGhvbGQuXG4gIHB1YmxpYyBleHBvcnREYXRhKHRoaXNQYWdlID0gZmFsc2UpOiB2b2lkIHtcbiAgICBjb25zdCByZXBvcnQgPSB0aGlzLnJlcG9ydCgpO1xuICAgIGlmICghcmVwb3J0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgcGFnZUlkID0gdGhpc1BhZ2UgPyB0aGlzLl9jYW52YXM/LmFjdGl2ZVBhZ2U/LmlkID8/IG51bGwgOiBudWxsO1xuICAgIGNvbnN0IGZpbHRlcnMgPSB0aGlzLl9maWx0ZXJTdGF0ZS5yZXNvbHZlRm9yUmVwb3J0KHJlcG9ydCwgcGFnZUlkKTtcblxuICAgIHRoaXMuX3Byb2Nlc3MuZG93bmxvYWQoXG4gICAgICAnRXhwb3J0aW5nIGRhdGEnLFxuICAgICAgdGhpcy5fY29sbGVjdG9yLmdldEZpbHRlclN1bW1hcnkocmVwb3J0KVxuICAgICAgICAucGlwZShcbiAgICAgICAgICBzd2l0Y2hNYXAoKGxpbmVzKSA9PiB0aGlzLl9yZXBvcnREYXRhLmV4cG9ydFJlcG9ydChcbiAgICAgICAgICAgIHJlcG9ydC5pZCxcbiAgICAgICAgICAgIGZpbHRlcnMsXG4gICAgICAgICAgICBwYWdlSWQsXG4gICAgICAgICAgICB0aGlzLl9maWx0ZXJTdGF0ZS5mcmVxdWVuY3koKSxcbiAgICAgICAgICAgIGxpbmVzLFxuICAgICAgICAgICkpLFxuICAgICAgICApLFxuICAgICk7XG4gIH1cblxuICAvLyBSZWFjdCB0byBlYWNoIGNoYXQgdHVybiAoZnMtY2hhdCBoYW5kbGVzIHRoZSByZXF1ZXN0ICsgcGVyc2lzdGVuY2UpOyB3ZVxuICAvLyBvbmx5IGNhcmUgYWJvdXQgdGhlIHJlcG9ydCBzaWRlIGVmZmVjdHMgdGhpcyBjb250ZXh0J3MgYmFja2VuZCBmbGFncy5cbiAgcHVibGljIG9uQ2hhdFJlc3BvbnNlKHJlc3BvbnNlOiBGc0FpQ2hhdFJlc3BvbnNlKTogdm9pZCB7XG4gICAgLy8gVGhlIGFnZW50IGNoYW5nZWQgdGhlIHJlcG9ydCdzIHN0cnVjdHVyZSDigJQgcmUtZmV0Y2ggaXQuIFNlc3Npb24gZmlsdGVyXG4gICAgLy8gdmFsdWVzIHN1cnZpdmUgKHRoZSBmaWx0ZXItc3RhdGUgc2VydmljZSBrZWVwcyB2YWx1ZXMgZm9yIGdyb3VwcyB0aGF0XG4gICAgLy8gc3RpbGwgZXhpc3QpLlxuICAgIGlmIChyZXNwb25zZS5yZXBvcnRDaGFuZ2VkICYmIHRoaXMuc2VsZWN0ZWQoKSkge1xuICAgICAgdGhpcy5fbG9hZFJlcG9ydCh0aGlzLnNlbGVjdGVkKCkuaWQpO1xuICAgIH1cblxuICAgIC8vIEEgcmVuYW1lIGNoYW5nZXMgbm90aGluZyBzdHJ1Y3R1cmFsIOKAlCByZWZyZXNoIHRoZSBwaWNrZXIgY2hpcCBsYWJlbC5cbiAgICBpZiAocmVzcG9uc2UucmVwb3J0UmVuYW1lZCAmJiB0aGlzLnNlbGVjdGVkKCkpIHtcbiAgICAgIHRoaXMuX3JlZnJlc2hSZXBvcnROYW1lKHRoaXMuc2VsZWN0ZWQoKS5pZCk7XG4gICAgfVxuICB9XG5cbiAgLy8gRHJhZyB0aGUgZGl2aWRlciBiZXR3ZWVuIHRoZSBjaGF0IGFuZCBjYW52YXMgcGFuZXMgKHBvaW50ZXItY2FwdHVyZSBsb29wXG4gIC8vIG91dHNpZGUgQW5ndWxhcikuXG4gIHB1YmxpYyBvblJlc2l6ZVN0YXJ0KGV2ZW50OiBQb2ludGVyRXZlbnQpOiB2b2lkIHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgY29uc3QgaGFuZGxlID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxFbGVtZW50O1xuICAgIGhhbmRsZS5zZXRQb2ludGVyQ2FwdHVyZShldmVudC5wb2ludGVySWQpO1xuICAgIHRoaXMuX3NwbGl0Lm5hdGl2ZUVsZW1lbnQuY2xhc3NMaXN0LmFkZCgncmVzaXppbmcnKTtcblxuICAgIHRoaXMuX3pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgY29uc3QgbW92ZSA9IChlOiBQb2ludGVyRXZlbnQpID0+IHRoaXMuX3Jlc2l6ZVRvKGUuY2xpZW50WCk7XG4gICAgICBjb25zdCBlbmQgPSAoKSA9PiB7XG4gICAgICAgIGhhbmRsZS5yZWxlYXNlUG9pbnRlckNhcHR1cmUoZXZlbnQucG9pbnRlcklkKTtcbiAgICAgICAgaGFuZGxlLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJtb3ZlJywgbW92ZSk7XG4gICAgICAgIGhhbmRsZS5yZW1vdmVFdmVudExpc3RlbmVyKCdwb2ludGVydXAnLCBlbmQpO1xuICAgICAgICBoYW5kbGUucmVtb3ZlRXZlbnRMaXN0ZW5lcigncG9pbnRlcmNhbmNlbCcsIGVuZCk7XG4gICAgICAgIHRoaXMuX3NwbGl0Lm5hdGl2ZUVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZSgncmVzaXppbmcnKTtcbiAgICAgIH07XG5cbiAgICAgIGhhbmRsZS5hZGRFdmVudExpc3RlbmVyKCdwb2ludGVybW92ZScsIG1vdmUpO1xuICAgICAgaGFuZGxlLmFkZEV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJ1cCcsIGVuZCk7XG4gICAgICBoYW5kbGUuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcmNhbmNlbCcsIGVuZCk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIF9yZXNpemVUbyhjbGllbnRYOiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCByZWN0ID0gdGhpcy5fc3BsaXQubmF0aXZlRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICBpZiAocmVjdC53aWR0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHJhdGlvID0gKGNsaWVudFggLSByZWN0LmxlZnQpIC8gcmVjdC53aWR0aDtcbiAgICBjb25zdCBjbGFtcGVkID0gTWF0aC5taW4oMC44LCBNYXRoLm1heCgwLjIsIHJhdGlvKSk7XG4gICAgdGhpcy5fY2hhdFBhbmVsLm5hdGl2ZUVsZW1lbnQuc3R5bGUuZmxleEJhc2lzID0gYCR7Y2xhbXBlZCAqIDEwMH0lYDtcbiAgfVxuXG4gIHByaXZhdGUgX2xvYWRSZXBvcnQocmVwb3J0SWQ6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMuX3JlcG9ydERhdGEuZ2V0KHJlcG9ydElkKVxuICAgICAgLnBpcGUodGFrZVVudGlsRGVzdHJveWVkKHRoaXMuX2Rlc3Ryb3lSZWYpKVxuICAgICAgLnN1YnNjcmliZSgocmVwb3J0OiBSZXBvcnQpID0+IHtcbiAgICAgICAgdGhpcy5yZXBvcnQuc2V0KHJlcG9ydCk7XG4gICAgICAgIC8vIE5vIFVSTCBzdGF0ZSBpbiB0aGlzIHZpZXc6IG5vdGhpbmcgaXMgcmVzdG9yZWQgZnJvbSB0aGUgVVJMIGFuZFxuICAgICAgICAvLyBub3RoaW5nIGxpc3RlbnMgdG8gdXJsQ2hhbmdlcygpLCBzbyBpdHMgZmlsdGVycyBzdGF5IHNlc3Npb24tb25seS5cbiAgICAgICAgdGhpcy5fZmlsdGVyU3RhdGUuaW5pdChyZXBvcnQpO1xuICAgICAgICB0aGlzLl9idWlsZFJlcG9ydENvbmZpZygpO1xuICAgICAgfSk7XG4gIH1cblxuICAvLyBSZXBvcnQtbGV2ZWwgZmlsdGVyIGdyb3VwcyBpbiB0aGVpciBzYXZlZCBvcmRlciDigJQgdGhlIG9uZXMgdGhhdCByZW5kZXIgaW5cbiAgLy8gdGhlIHRvb2xiYXIgKGNvbXBvbmVudC1sZXZlbCBncm91cHMgcmVuZGVyIG9uIHRoZWlyIGNvbXBvbmVudHMpLlxuICBwcml2YXRlIF9yZXBvcnRHcm91cHMoKTogUmVwb3J0RmlsdGVyR3JvdXBbXSB7XG4gICAgcmV0dXJuICh0aGlzLnJlcG9ydCgpPy5maWx0ZXJHcm91cHMgPz8gW10pXG4gICAgICAuZmlsdGVyKChncm91cCkgPT4gZ3JvdXAubGV2ZWwgPT09ICdyZXBvcnQnIHx8IGdyb3VwLmxldmVsID09PSAnYm90aCcpXG4gICAgICAuc29ydCgoYSwgYikgPT4gYS5vcmRlciAtIGIub3JkZXIpO1xuICB9XG5cbiAgLy8gR2F0ZXMgdGhlIHRvb2xiYXIgZnMtZmlsdGVyIHNvIGl0IGlzbid0IHJlbmRlcmVkICh0YWtpbmcgc3BhY2UpIHdoZW4gdGhlcmVcbiAgLy8gaXMgbm90aGluZyB0byBwdXQgaW4gaXQg4oCUIG5vIHJlcG9ydC1sZXZlbCBmaWx0ZXJzIGFuZCBubyBncm91cC1ieSBjb250cm9sLlxuICBwdWJsaWMgZ2V0IHJlcG9ydEhhc0ZpbHRlcnMoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX3JlcG9ydEdyb3VwcygpLmxlbmd0aCA+IDAgfHwgISF0aGlzLl9ncm91cEJ5SXRlbSgpO1xuICB9XG5cbiAgLy8gZnMtZmlsdGVyIHJlYWRzIGl0cyBjb25maWcgb25seSBvbmNlIChhdCBpbml0KSDigJQgcmUtYmluZGluZyBkb2VzIG5vdGhpbmcuXG4gIC8vIFRoZSB0ZW1wbGF0ZSBrZXlzIHRoZSB0b29sYmFyIGZzLWZpbHRlciBvbiB0aGlzIHNpZ25hdHVyZSBzbyBpdCdzIHJlY3JlYXRlZFxuICAvLyAoYW5kIHJlLXJlYWRzIHRoZSByZWJ1aWx0IGNvbmZpZykgd2hlbmV2ZXIgdGhlIHJlcG9ydC1sZXZlbCBmaWx0ZXIgc2V0XG4gIC8vIGNoYW5nZXMsIGUuZy4gYWZ0ZXIgdGhlIGNvbXBvbmVudCBzZXR0aW5ncyBkaWFsb2cgYWRkcy9tb3ZlcyBhIGZpbHRlci5cbiAgcHVibGljIGdldCByZXBvcnRGaWx0ZXJLZXkoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gW1xuICAgICAgLy8gVGhlIHN0b3JlZCBkZWZhdWx0IGlzIHBhcnQgb2YgdGhlIHNpZ25hdHVyZTogc2F2aW5nIGEgbmV3IGRlZmF1bHQgaW4gcmVwb3J0XG4gICAgICAvLyBzZXR0aW5ncyByZWJ1aWxkcyB0aGUgY29uZmlnLCBidXQgd2l0aG91dCBhIGtleSBjaGFuZ2UgZnMtZmlsdGVyIGtlZXBzXG4gICAgICAvLyByZW5kZXJpbmcgdGhlIHZhbHVlcyBpdCB3YXMgY3JlYXRlZCB3aXRoIHVudGlsIGEgZnVsbCBwYWdlIHJlbG9hZC5cbiAgICAgIGdyb3VwQnlTaWduYXR1cmUodGhpcy5yZXBvcnQoKSksXG4gICAgICAuLi50aGlzLl9yZXBvcnRHcm91cHMoKS5tYXAoKGdyb3VwKSA9PiBgJHtncm91cC5pZH06JHtncm91cC5sZXZlbH06JHtncm91cC5sYWJlbH06JHtkZWZhdWx0U2lnbmF0dXJlKGdyb3VwKX1gKSxcbiAgICBdLmpvaW4oJ3wnKTtcbiAgfVxuXG4gIC8vIChSZSlidWlsZCB0aGUgdG9vbGJhciBmcy1maWx0ZXIgY29uZmlnIOKAlCB0aGUgcmVwb3J0LWxldmVsIGZpbHRlciBpdGVtcyBhbmRcbiAgLy8gdGhlbiB0aGUgZ3JvdXAtYnkgY29udHJvbC4gVGhlIHJlcG9ydCdzIGFjdGlvbnMgbGl2ZSBpbiB0aGUgZnMtbWVudSBiZXNpZGVcbiAgLy8gdGhlIHBpY2tlciwgbm90IGhlcmUuIE9ubHkgYnVpbHQvdXNlZCBvbmNlIGEgcmVwb3J0IGlzIGxvYWRlZCAodGhlIHRlbXBsYXRlXG4gIC8vIGdhdGVzIGl0IG9uIGByZXBvcnRgKS5cbiAgcHJpdmF0ZSBfYnVpbGRSZXBvcnRDb25maWcoKTogdm9pZCB7XG4gICAgY29uc3QgcmVwb3J0SWQgPSB0aGlzLnJlcG9ydCgpPy5pZCA/PyBudWxsO1xuXG4gICAgLy8gRHJvcCBhIGdyYWluIHRoZSBjb250cm9sIG5vIGxvbmdlciBvZmZlcnMg4oCUIHRoZSBhZ2VudCBjYW4gbmFycm93IHRoZSBsaXN0XG4gICAgLy8gbWlkLXNlc3Npb24sIGFuZCBhbiBvdmVycmlkZSB0aGUgdmlld2VyIGNhbid0IHNlZSBpcyB3b3JzZSB0aGFuIG5vbmUuXG4gICAgaWYgKHRoaXMucmVwb3J0KCkgJiYgIWlzR3JhbnVsYXJpdHlPZmZlcmVkKHRoaXMucmVwb3J0KCksIHRoaXMuX2ZpbHRlclN0YXRlLmZyZXF1ZW5jeSgpKSkge1xuICAgICAgdGhpcy5fZmlsdGVyU3RhdGUuc2V0RnJlcXVlbmN5KG51bGwpO1xuICAgIH1cblxuICAgIGNvbnN0IGl0ZW1zID0gcmVwb3J0SWRcbiAgICAgID8gdGhpcy5fcmVwb3J0R3JvdXBzKCkubWFwKChncm91cCkgPT5cbiAgICAgICAgZmlsdGVySXRlbUZvckdyb3VwKGdyb3VwLCB0aGlzLl9yZXBvcnREYXRhLCByZXBvcnRJZCwgdGhpcy5fZmlsdGVyU3RhdGUudmFsdWUoZ3JvdXAuaWQpKSlcbiAgICAgIDogW107XG5cbiAgICAvLyBUaGUgZ3JvdXAtYnkgY29udHJvbCBsZWFkcyB0aGUgYmFyLCBhaGVhZCBvZiBldmVyeSBmaWx0ZXI6IGl0IHNldHMgdGhlXG4gICAgLy8gZ3JhaW4gdGhlIHdob2xlIHJlcG9ydCBpcyByZWFkIGF0LCBzbyBpdCBpcyB0aGUgZmlyc3QgdGhpbmcgYSB2aWV3ZXJcbiAgICAvLyBkZWNpZGVzLiBJdCBpcyBub3QgYSBmaWx0ZXIgZ3JvdXAg4oCUIGl0IHJlLWJ1Y2tldHMgcm93cyByYXRoZXIgdGhhblxuICAgIC8vIG5hcnJvd2luZyB0aGVtIOKAlCBzbyBpdCBpcyBwbGFjZWQgaGVyZSByYXRoZXIgdGhhbiBvcmRlcmVkIGFtb25nIHRoZW0uXG4gICAgY29uc3QgZ3JvdXBCeUl0ZW0gPSB0aGlzLl9ncm91cEJ5SXRlbSgpO1xuICAgIGlmIChncm91cEJ5SXRlbSkge1xuICAgICAgaXRlbXMudW5zaGlmdChncm91cEJ5SXRlbSk7XG4gICAgfVxuXG4gICAgdGhpcy5yZXBvcnRGaWx0ZXJDb25maWcuc2V0KHtcbiAgICAgIC8vIE5ldmVyIHRvdWNoIHRoZSBVUkwgb3IgcGVyc2lzdCBmaWx0ZXIgc3RhdGUg4oCUIHJlcG9ydCBmaWx0ZXJzIGFyZVxuICAgICAgLy8gc2Vzc2lvbi1vbmx5LCBvd25lZCBieSBSZXBvcnRGaWx0ZXJTdGF0ZVNlcnZpY2UuXG4gICAgICBxdWVyeVBhcmFtOiBmYWxzZSxcbiAgICAgIHBlcnNpc3Q6IGZhbHNlLFxuICAgICAgaXRlbXMsXG4gICAgICBjaGFuZ2U6IChxdWVyeSkgPT4ge1xuICAgICAgICBmb3IgKGNvbnN0IHsgZ3JvdXBJZCwgdmFsdWUgfSBvZiBncm91cFZhbHVlc0Zyb21RdWVyeShxdWVyeSA/PyB7fSwgdGhpcy5fcmVwb3J0R3JvdXBzKCkpKSB7XG4gICAgICAgICAgdGhpcy5fZmlsdGVyU3RhdGUuc2V0VmFsdWUoZ3JvdXBJZCwgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIC8vIE5vdCBhIGZpbHRlciBncm91cCDigJQgdGhlIGdyYWluIGlzIHJlYWQgc3RyYWlnaHQgb2ZmIHRoZSBxdWVyeS5cbiAgICAgICAgdGhpcy5fZmlsdGVyU3RhdGUuc2V0RnJlcXVlbmN5KChxdWVyeT8uW0dST1VQX0JZX0lURU1dIGFzIENoYXJ0R3JhbnVsYXJpdHkpIHx8IG51bGwpO1xuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIC8vIFRoZSByZXBvcnQncyBncm91cC1ieSBjb250cm9sIGFzIGFuIGZzLWZpbHRlciBpdGVtLCBvciBudWxsIHdoZW4gdGhlIHJlcG9ydFxuICAvLyBoYXMgbm9uZSB0byBzaG93LiBTZWVkZWQgZnJvbSB0aGUgc2Vzc2lvbiBzdGF0ZSBzbyB0aGUgZ3JhaW4gdGhlIHZpZXdlclxuICAvLyBwaWNrZWQgc3Vydml2ZXMgdGhlIHJlcG9ydCBiZWluZyByZS1mZXRjaGVkIGFmdGVyIGEgY2hhdCBlZGl0LlxuICBwcml2YXRlIF9ncm91cEJ5SXRlbSgpOiBJRmlsdGVyQ29uZmlnSXRlbSB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLnJlcG9ydCgpXG4gICAgICA/IGdyb3VwQnlGaWx0ZXJJdGVtKHRoaXMucmVwb3J0KCksIHRoaXMuX2ZpbHRlclN0YXRlLmZyZXF1ZW5jeSgpKVxuICAgICAgOiBudWxsO1xuICB9XG5cbiAgcHJpdmF0ZSBfcmVmcmVzaFJlcG9ydE5hbWUocmVwb3J0SWQ6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMuX3JlcG9ydFNlcnZpY2UubG9hZCgpXG4gICAgICAucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5fZGVzdHJveVJlZikpXG4gICAgICAuc3Vic2NyaWJlKChyZXBvcnRzOiBSZXBvcnRMaXN0SXRlbVtdKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlbmFtZWQgPSByZXBvcnRzLmZpbmQoKHJlcG9ydCkgPT4gcmVwb3J0LmlkID09PSByZXBvcnRJZCk7XG4gICAgICAgIGlmIChyZW5hbWVkKSB7XG4gICAgICAgICAgdGhpcy5zZWxlY3RlZC5zZXQocmVuYW1lZCk7XG4gICAgICAgICAgaWYgKHRoaXMucmVwb3J0KCkpIHtcbiAgICAgICAgICAgIHRoaXMucmVwb3J0LnNldCh7IC4uLnRoaXMucmVwb3J0KCksIG5hbWU6IHJlbmFtZWQubmFtZSB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9XG59XG4iLCI8ZGl2XG4gICAgI3NwbGl0XG4gICAgY2xhc3M9XCJyZXBvcnQgZnMtcm93LmFsaWduLXN0YXJ0XCI+XG4gIDxmcy1haS1jaGF0XG4gICAgI2NoYXRQYW5lbFxuICAgIGNsYXNzPVwiY2hhdFwiXG4gICAgc3R5bGU9XCJtaW4taGVpZ2h0OiA1MDBweDtcIlxuICAgIGJhc2VQYXRoPVwicmVwb3J0c1wiXG4gICAgW3JlcXVlc3REYXRhXT1cInsgcmVwb3J0SWQ6IHNlbGVjdGVkKCk/LmlkID8/IG51bGwgfVwiXG4gICAgW2ludHJvTWVzc2FnZV09XCJpbnRyb01lc3NhZ2VcIlxuICAgIChyZXNwb25zZSk9XCJvbkNoYXRSZXNwb25zZSgkZXZlbnQpXCI+XG4gIDwvZnMtYWktY2hhdD5cbiAgPGRpdlxuICAgIGNsYXNzPVwicmVzaXplclwiXG4gICAgKHBvaW50ZXJkb3duKT1cIm9uUmVzaXplU3RhcnQoJGV2ZW50KVwiPlxuICA8L2Rpdj5cbiAgPGRpdiBjbGFzcz1cInZpZXdlciBmcy1mbGV4IGZzLWNvbHVtblwiPlxuICAgIDxkaXYgY2xhc3M9XCJmcy1yb3cuYWxpZ24tY2VudGVyLmdhcC1zbVwiPlxuICAgICAgPGZzLWF1dG9jb21wbGV0ZS1jaGlwc1xuICAgICAgICAgIGNsYXNzPVwiZnMtZmxleFwiXG4gICAgICAgICAgW2ZldGNoXT1cImZldGNoUmVwb3J0c1wiXG4gICAgICAgICAgWyhuZ01vZGVsKV09XCJzZWxlY3RlZFwiXG4gICAgICAgICAgW2Rpc2FibGVkXT1cImxvYWRpbmdSZXBvcnRzKClcIlxuICAgICAgICAgIFtwYWRsZXNzXT1cInRydWVcIlxuICAgICAgICAgIFttdWx0aXBsZV09XCJmYWxzZVwiXG4gICAgICAgICAgW2ZldGNoT25Gb2N1c109XCJ0cnVlXCJcbiAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJyZXBvcnRDaGFuZ2UoJGV2ZW50KVwiXG4gICAgICAgICAgcGxhY2Vob2xkZXI9XCJSZXBvcnRcIlxuICAgICAgICAgIG5hbWU9XCJyZXBvcnRcIj5cbiAgICAgICAgPG5nLXRlbXBsYXRlXG4gICAgICAgICAgICBmc0F1dG9jb21wbGV0ZUNoaXBzVGVtcGxhdGVcbiAgICAgICAgICAgIGxldC1vYmplY3Q9XCJvYmplY3RcIj5cbiAgICAgICAgICB7eyBvYmplY3QubmFtZSB9fVxuICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICA8bmctdGVtcGxhdGVcbiAgICAgICAgICAgIGZzQXV0b2NvbXBsZXRlQ2hpcHNTdGF0aWNcbiAgICAgICAgICAgIChjbGljayk9XCJjcmVhdGVSZXBvcnQoKVwiPlxuICAgICAgICAgIENyZWF0ZSBSZXBvcnRcbiAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgIDwvZnMtYXV0b2NvbXBsZXRlLWNoaXBzPlxuICAgICAgQGlmIChyZXBvcnQoKSAmJiBlZGl0TW9kZSgpKSB7XG4gICAgICAgIDwhLS0gV2hhdCBsYXlvdXQgZWRpdGluZyBjYW4gYWRkIG9yIHN3aXRjaCB0bywgYW5kIHRoZSB3YXkgb3V0IG9mIGl0IOKAlFxuICAgICAgICAgICAgIHRoZSBzYW1lIG91dGxpbmVkIGJ1dHRvbnMgYXMgdGhlIGZzLWFpLXJlcG9ydCB0b29sYmFyLiAtLT5cbiAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgbWF0LXN0cm9rZWQtYnV0dG9uXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIG1hdFRvb2x0aXA9XCJBZGQgYSBibG9jayBvZiB0ZXh0XCJcbiAgICAgICAgICAgIChjbGljayk9XCJhZGRUZXh0KClcIj5cbiAgICAgICAgICA8bWF0LWljb24+dGl0bGU8L21hdC1pY29uPlxuICAgICAgICAgIEFkZCB0ZXh0XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICBtYXQtc3Ryb2tlZC1idXR0b25cbiAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgY2xhc3M9XCJtYXN0ZXItdG9nZ2xlXCJcbiAgICAgICAgICAgIFtjbGFzcy5hY3RpdmVdPVwiaXNNYXN0ZXJNb2RlXCJcbiAgICAgICAgICAgIFttYXRUb29sdGlwXT1cImlzTWFzdGVyTW9kZSA/ICdCYWNrIHRvIGVkaXRpbmcgdGhpcyBwYWdlJyA6ICdFZGl0IHRoZSBoZWFkZXIgYW5kIGZvb3RlciBzaG93biBvbiBldmVyeSBwYWdlJ1wiXG4gICAgICAgICAgICAoY2xpY2spPVwidG9nZ2xlTWFzdGVyTW9kZSgpXCI+XG4gICAgICAgICAgPG1hdC1pY29uPndlYl9hc3NldDwvbWF0LWljb24+XG4gICAgICAgICAgSGVhZGVyICYgZm9vdGVyXG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICBtYXQtc3Ryb2tlZC1idXR0b25cbiAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgKGNsaWNrKT1cInRvZ2dsZUVkaXRNb2RlKClcIj5cbiAgICAgICAgICA8bWF0LWljb24+Y2hlY2s8L21hdC1pY29uPlxuICAgICAgICAgIERvbmUgZWRpdGluZ1xuICAgICAgICA8L2J1dHRvbj5cbiAgICAgIH1cbiAgICAgIEBpZiAocmVwb3J0KCkpIHtcbiAgICAgICAgPGZzLW1lbnU+XG4gICAgICAgICAgPG5nLXRlbXBsYXRlXG4gICAgICAgICAgICAgIGZzLW1lbnUtaXRlbVxuICAgICAgICAgICAgICAoY2xpY2spPVwicmVwb3J0U2V0dGluZ3MoKVwiPlxuICAgICAgICAgICAgPG1hdC1pY29uPlxuICAgICAgICAgICAgICB0dW5lXG4gICAgICAgICAgICA8L21hdC1pY29uPlxuICAgICAgICAgICAgUmVwb3J0IHNldHRpbmdzXG4gICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICA8bmctdGVtcGxhdGVcbiAgICAgICAgICAgICAgZnMtbWVudS1pdGVtXG4gICAgICAgICAgICAgIChjbGljayk9XCJ0b2dnbGVFZGl0TW9kZSgpXCJcbiAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImVkaXRNb2RlKClcIj5cbiAgICAgICAgICAgIDxtYXQtaWNvbj5cbiAgICAgICAgICAgICAgZGFzaGJvYXJkX2N1c3RvbWl6ZVxuICAgICAgICAgICAgPC9tYXQtaWNvbj5cbiAgICAgICAgICAgIHt7IGVkaXRNb2RlKCkgPyAnRG9uZSBlZGl0aW5nIGxheW91dCcgOiAnRWRpdCBsYXlvdXQnIH19XG4gICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICA8bmctdGVtcGxhdGVcbiAgICAgICAgICAgICAgZnMtbWVudS1pdGVtXG4gICAgICAgICAgICAgIChjbGljayk9XCJleHBvcnRQb3dlcnBvaW50KClcIj5cbiAgICAgICAgICAgIDxtYXQtaWNvbj5cbiAgICAgICAgICAgICAgc2xpZGVzaG93XG4gICAgICAgICAgICA8L21hdC1pY29uPlxuICAgICAgICAgICAgRXhwb3J0IFBvd2VyUG9pbnRcbiAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgIDxuZy10ZW1wbGF0ZVxuICAgICAgICAgICAgICBmcy1tZW51LWl0ZW1cbiAgICAgICAgICAgICAgKGNsaWNrKT1cImV4cG9ydFBkZigpXCI+XG4gICAgICAgICAgICA8bWF0LWljb24+XG4gICAgICAgICAgICAgIHBpY3R1cmVfYXNfcGRmXG4gICAgICAgICAgICA8L21hdC1pY29uPlxuICAgICAgICAgICAgRXhwb3J0IFBERlxuICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgPG5nLXRlbXBsYXRlXG4gICAgICAgICAgICAgIGZzLW1lbnUtaXRlbVxuICAgICAgICAgICAgICAoY2xpY2spPVwiZXhwb3J0RGF0YSgpXCI+XG4gICAgICAgICAgICA8bWF0LWljb24+XG4gICAgICAgICAgICAgIHRhYmxlX3ZpZXdcbiAgICAgICAgICAgIDwvbWF0LWljb24+XG4gICAgICAgICAgICBFeHBvcnQgUmF3IERhdGFcbiAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgIEBpZiAoKHJlcG9ydCgpPy5wYWdlcz8ubGVuZ3RoID8/IDApID4gMSkge1xuICAgICAgICAgICAgPG5nLXRlbXBsYXRlXG4gICAgICAgICAgICAgICAgZnMtbWVudS1pdGVtXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cImV4cG9ydERhdGEodHJ1ZSlcIj5cbiAgICAgICAgICAgICAgPG1hdC1pY29uPlxuICAgICAgICAgICAgICAgIHRhYmxlX3ZpZXdcbiAgICAgICAgICAgICAgPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgRXhwb3J0IFJhdyBEYXRhIChUaGlzIFBhZ2UpXG4gICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgIH1cbiAgICAgICAgPC9mcy1tZW51PlxuICAgICAgfVxuICAgIDwvZGl2PlxuICAgIEBpZiAocmVwb3J0KCkpIHtcbiAgICAgIDwhLS0gUmVwb3J0LWxldmVsIGZpbHRlcnMgb25seSAodGhlIHJlcG9ydCdzIGFjdGlvbnMgbGl2ZSBpbiB0aGUgbWVudVxuICAgICAgICAgICBhYm92ZSkuIGZzLWZpbHRlciByZWFkcyBpdHMgY29uZmlnIG9uY2UgYXQgaW5pdCwgc28gaXQncyBrZXllZCBvbiB0aGVcbiAgICAgICAgICAgZmlsdGVyIHNpZ25hdHVyZTogd2hlbiB0aGUgcmVwb3J0LWxldmVsIGZpbHRlciBzZXQgY2hhbmdlcyB0aGUgYmxvY2tcbiAgICAgICAgICAgaXMgcmVjcmVhdGVkIGFuZCByZS1yZWFkcyB0aGUgcmVidWlsdCBjb25maWcuIC0tPlxuICAgICAgQGlmIChyZXBvcnRIYXNGaWx0ZXJzKSB7XG4gICAgICAgIEBmb3IgKGtleSBvZiBbcmVwb3J0RmlsdGVyS2V5XTsgdHJhY2sga2V5KSB7XG4gICAgICAgICAgPGZzLWZpbHRlciBbY29uZmlnXT1cInJlcG9ydEZpbHRlckNvbmZpZygpXCI+PC9mcy1maWx0ZXI+XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIDxhcHAtcmVwb3J0LWNhbnZhc1xuICAgICAgICBbcmVwb3J0XT1cInJlcG9ydCgpXCJcbiAgICAgICAgW2VkaXRNb2RlXT1cImVkaXRNb2RlKClcIlxuICAgICAgICAoY29tcG9uZW50U2V0dGluZ3MpPVwiY29tcG9uZW50U2V0dGluZ3MoJGV2ZW50KVwiXG4gICAgICAgIChyZXBvcnRDaGFuZ2VkKT1cIm9uQ2FudmFzUmVwb3J0Q2hhbmdlZCgpXCI+XG4gICAgICA8L2FwcC1yZXBvcnQtY2FudmFzPlxuICAgIH1cbiAgPC9kaXY+XG48L2Rpdj4iXX0=