@hestia-earth/ui-components 0.24.2 → 0.25.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 (34) hide show
  1. package/common/utils.d.ts +1 -0
  2. package/cycles/cycles-nodes/cycles-nodes.component.d.ts +1 -0
  3. package/esm2022/common/utils.mjs +2 -1
  4. package/esm2022/cycles/cycles-nodes/cycles-nodes.component.mjs +8 -6
  5. package/esm2022/engine/aggregation-engine.service.mjs +2 -2
  6. package/esm2022/engine/engine.service.mjs +3 -3
  7. package/esm2022/files/files-error-summary.model.mjs +1 -1
  8. package/esm2022/files/files-error.model.mjs +5 -3
  9. package/esm2022/files/files-form/files-form.component.mjs +1 -1
  10. package/esm2022/files/files-form.model.mjs +1 -1
  11. package/esm2022/impact-assessments/impact-assessments-indicator-breakdown-chart/impact-assessments-indicator-breakdown-chart.component.mjs +141 -122
  12. package/esm2022/impact-assessments/impact-assessments-products/impact-assessments-products.component.mjs +38 -13
  13. package/esm2022/node/node-logs-models/node-logs-models.component.mjs +8 -4
  14. package/esm2022/node/node-value-details/node-value-details.component.mjs +2 -1
  15. package/esm2022/schema/index.mjs +2 -1
  16. package/esm2022/schema/schema-validation.model.mjs +2 -0
  17. package/esm2022/sites/index.mjs +2 -2
  18. package/esm2022/sites/sites-nodes/sites-nodes.component.mjs +129 -0
  19. package/esm2022/sites/sites.module.mjs +4 -4
  20. package/fesm2022/hestia-earth-ui-components.mjs +1504 -1425
  21. package/fesm2022/hestia-earth-ui-components.mjs.map +1 -1
  22. package/files/files-error-summary.model.d.ts +2 -1
  23. package/files/files-error.model.d.ts +2 -20
  24. package/files/files-form.model.d.ts +1 -1
  25. package/impact-assessments/impact-assessments-indicator-breakdown-chart/impact-assessments-indicator-breakdown-chart.component.d.ts +35 -17
  26. package/impact-assessments/impact-assessments-products/impact-assessments-products.component.d.ts +16 -6
  27. package/node/node-logs-models/node-logs-models.component.d.ts +3 -0
  28. package/package.json +1 -1
  29. package/schema/index.d.ts +1 -0
  30. package/schema/schema-validation.model.d.ts +30 -0
  31. package/sites/index.d.ts +1 -1
  32. package/sites/{sites-measurements/sites-measurements.component.d.ts → sites-nodes/sites-nodes.component.d.ts} +24 -11
  33. package/sites/sites.module.d.ts +2 -2
  34. package/esm2022/sites/sites-measurements/sites-measurements.component.mjs +0 -101
@@ -1,12 +1,14 @@
1
- import { Component, Input, ViewChild } from '@angular/core';
2
- import { of } from 'rxjs';
3
- import { filter, groupBy, map, mergeAll, mergeMap, toArray } from 'rxjs/operators';
1
+ import { ChangeDetectionStrategy, Component, Input, ViewChild, computed, effect, signal } from '@angular/core';
2
+ import { toObservable, toSignal } from '@angular/core/rxjs-interop';
3
+ import { filter, groupBy, map, mergeAll, mergeMap, take, tap, toArray } from 'rxjs/operators';
4
4
  import { Chart } from 'chart.js';
5
5
  import ChartDataLabels from 'chartjs-plugin-datalabels';
6
6
  import { DataState } from '@hestia-earth/api';
7
7
  import { NodeType, TermTermType } from '@hestia-earth/schema';
8
8
  import { toPrecision, unique } from '@hestia-earth/utils';
9
+ import { of } from 'rxjs';
9
10
  import { matchTermType, matchType } from '../../search/search.model';
11
+ import { distinctUntilChangedDeep } from '../../common/rxjs-utils';
10
12
  import { Level, parseLines, parseMessage } from '../../common/logs-utils';
11
13
  import { listColor } from '../../common/color';
12
14
  import * as i0 from "@angular/core";
@@ -45,39 +47,74 @@ const logToCsv = (logs, impact) => [
45
47
  .map(v => [...v, impact.product?.term?.units].join(','))
46
48
  ].join('\n');
47
49
  export class ImpactAssessmentsIndicatorBreakdownChartComponent {
50
+ set impactAssessment(value) {
51
+ this._impactAssessment.set(value);
52
+ }
53
+ set indicators(value) {
54
+ this._indicators.set(value);
55
+ }
48
56
  constructor(ngZone, domSanitizer, searchService, nodeService) {
49
57
  this.ngZone = ngZone;
50
58
  this.domSanitizer = domSanitizer;
51
59
  this.searchService = searchService;
52
60
  this.nodeService = nodeService;
53
- this.logs = [];
54
- this.emissions = [];
55
- this.indicators = [];
56
- this.loading = true;
57
- this.terms = [];
58
- this.methods = [];
59
- this.noData = false;
60
- }
61
- async ngOnInit() {
62
- this.terms = unique((this.indicators || []).map(({ term }) => term).filter(Boolean));
63
- this.methods = unique((this.indicators || []).map(({ methodModel }) => methodModel).filter(Boolean));
64
- const impacts = [...(this.impactAssessment.impacts || []), ...(this.impactAssessment.endpoints || [])];
65
- this.logs = (await of({
66
- ...this.impactAssessment,
67
- dataState: DataState.recalculated
61
+ this._impactAssessment = signal(undefined);
62
+ this.impactAssessment$ = toObservable(this._impactAssessment);
63
+ this._indicators = signal([]);
64
+ this.allLogs = signal([]);
65
+ this.logs = computed(() => this.allLogs()
66
+ .filter(({ impactTermId, modelId }) => impactTermId === this.selectedTerm()?.['@id'] &&
67
+ (!this.selectedMethod() || modelId === this.selectedMethod()?.['@id']))
68
+ .sort((a, b) => b.value - a.value));
69
+ this.emissions = toSignal(this.searchService
70
+ .search$({
71
+ fields: ['@type', '@id', 'name'],
72
+ limit: 1000,
73
+ query: {
74
+ bool: {
75
+ must: [matchType(NodeType.Term)],
76
+ should: filterTermTypes.map(termType => matchTermType(termType)),
77
+ minimum_should_match: 1
78
+ }
79
+ }
68
80
  })
69
- .pipe(mergeMap(node => this.nodeService.getLog(node)), map(value => (value ? parseLines(value) : [])), mergeAll(), filter(({ data }) => data.logger === 'hestia_earth.models' && data.level === Level.debug), filter(({ data: { message } }) => !!message), map(({ data: { message } }) => parseMessage(message)), filter(message => 'node' in message), map(parseLog), filter(log => !!log.impactTermId && !!log.blankNodeTermId && !isNaN(log.value) && log.value > 0), groupBy(log => [log.impactTermId, log.blankNodeTermId, log.modelId].join('/')), mergeMap(group => group.pipe(toArray())), map((values) => {
81
+ .pipe(map(({ results }) => results)));
82
+ this.loading = signal(true);
83
+ this.selectedTerm = signal(undefined);
84
+ this.terms = computed(() => unique((this._indicators() || []).map(({ term }) => term).filter(Boolean)));
85
+ this.selectedMethod = signal(undefined);
86
+ this.methods = computed(() => unique((this._indicators() || []).map(({ methodModel }) => methodModel).filter(Boolean)));
87
+ this.impacts = computed(() => [
88
+ ...(this._impactAssessment()?.impacts || []),
89
+ ...(this._impactAssessment()?.endpoints || [])
90
+ ]);
91
+ this.noData = computed(() => this.logs()?.length === 0);
92
+ this.csvContent = computed(() => this.domSanitizer.bypassSecurityTrustResourceUrl(`data:text/html;charset=utf-8,${encodeURIComponent(logToCsv(this.logs(), this._impactAssessment()))}`));
93
+ this.id = computed(() => this._impactAssessment()?.['@id'] || this._impactAssessment()?.id);
94
+ this.downloadFilename = computed(() => `${this.id()}-logs.csv`);
95
+ this.total = computed(() => this.logs().reduce((prev, curr) => prev + curr.value, 0));
96
+ this.labels = computed(() => this.logs().map(({ blankNodeTermId }) => this.emissions()?.find(v => v['@id'] === blankNodeTermId)?.name || blankNodeTermId));
97
+ this.datasets = computed(() => [
98
+ {
99
+ label: this.selectedTerm()?.name ?? '',
100
+ data: this.logs().map(({ value }) => value),
101
+ backgroundColor: this.logs().map(listColor),
102
+ borderColor: this.logs().map(listColor)
103
+ }
104
+ ]);
105
+ this.impactAssessment$
106
+ .pipe(filter(v => !!v), distinctUntilChangedDeep(), take(1), tap(() => this.loading.set(true)), mergeMap(node => (node ? this.nodeService.getLog({ ...node, dataState: DataState.recalculated }) : of(''))), map(value => (value ? parseLines(value) : [])), mergeAll(), filter(({ data }) => data.logger === 'hestia_earth.models' && data.level === Level.debug), filter(({ data: { message } }) => !!message), map(({ data: { message } }) => parseMessage(message)), filter(message => 'node' in message), map(parseLog), filter(log => !!log.impactTermId && !!log.blankNodeTermId && !isNaN(log.value) && log.value > 0), groupBy(log => [log.impactTermId, log.blankNodeTermId, log.modelId].join('/')), mergeMap(group => group.pipe(toArray())), map((values) => {
70
107
  const log = values[0];
71
108
  const total = values.reduce((prev, curr) => prev + curr.value, 0);
72
109
  const blankNodes = [
73
- ...(this.impactAssessment.emissionsResourceUse || []),
74
- ...(this.impactAssessment.impacts || [])
110
+ ...(this._impactAssessment()?.emissionsResourceUse ?? []),
111
+ ...(this._impactAssessment()?.impacts ?? [])
75
112
  ].filter(v => v.term['@id'] === log.blankNodeTermId);
76
113
  const inputs = blankNodes
77
114
  .filter(v => v.inputs?.length)
78
115
  .map(v => ({ name: v.inputs.map(i => i['@id']).join(';'), value: v.value * log.coefficient }));
79
116
  const inputsValue = inputs.reduce((prev, curr) => prev + curr.value, 0);
80
- const impact = impacts.find(v => v.term['@id'] === log.impactTermId);
117
+ const impact = this.impacts().find(v => v.term['@id'] === log.impactTermId);
81
118
  // logs might exist but impact was not added => skip logs
82
119
  return impact
83
120
  ? {
@@ -88,122 +125,104 @@ export class ImpactAssessmentsIndicatorBreakdownChartComponent {
88
125
  inputsValue
89
126
  }
90
127
  : null;
91
- }), filter(log => !!log), toArray())
92
- .toPromise());
93
- this.csvContent = this.domSanitizer.bypassSecurityTrustResourceUrl(`data:text/html;charset=utf-8,${encodeURIComponent(logToCsv(this.logs, this.impactAssessment))}`);
94
- const { results } = await this.searchService.search({
95
- fields: ['@type', '@id', 'name'],
96
- limit: 1000,
97
- query: {
98
- bool: {
99
- must: [matchType(NodeType.Term)],
100
- should: filterTermTypes.map(termType => matchTermType(termType)),
101
- minimum_should_match: 1
102
- }
128
+ }), filter(log => !!log), toArray(), tap(() => this.loading.set(false)))
129
+ .subscribe((logs) => {
130
+ this.allLogs.set(logs);
131
+ this.initChart();
132
+ });
133
+ effect(() => {
134
+ // make sure selected term exists
135
+ const terms = this.terms();
136
+ const selectedTermId = this.selectedTerm()?.['@id'];
137
+ if (!selectedTermId || !terms.find(term => term['@id'] === selectedTermId)) {
138
+ this.selectedTerm.set(terms[0]);
139
+ }
140
+ this.initChart();
141
+ }, { allowSignalWrites: true });
142
+ effect(() => {
143
+ if (this.datasets().length) {
144
+ this.initChart();
103
145
  }
104
146
  });
105
- this.emissions = results;
106
- this.loading = false;
107
- this.selectedTerm = this.terms[0];
108
- this.updateChart();
109
147
  }
110
- get id() {
111
- return this.impactAssessment['@id'] || this.impactAssessment.id;
148
+ ngAfterViewInit() {
149
+ this.initChart();
112
150
  }
113
151
  initChart() {
114
- const logs = this.logs
115
- .filter(({ impactTermId, modelId }) => impactTermId === this.selectedTerm?.['@id'] &&
116
- (!this.selectedMethod || modelId === this.selectedMethod['@id']))
117
- .sort((a, b) => b.value - a.value);
118
- this.noData = logs.length === 0;
119
- const total = logs.reduce((prev, curr) => prev + curr.value, 0);
120
- const labels = logs.map(({ blankNodeTermId }) => this.emissions.find(v => v['@id'] === blankNodeTermId)?.name || blankNodeTermId);
121
- // display the breakdown by input
122
- // const inputs = logs.flatMap(v => v.inputs.map(i => i.name));
123
- // const datasets = [
124
- // ...inputs.map((input, index) => ({
125
- // label: input,
126
- // data: logs.map(log => log.inputs.find(({ name }) => name === input)?.value || 0),
127
- // backgroundColor: getColor(index),
128
- // borderColor: getColor(index)
129
- // })),
130
- // // add dataset for rest not linked to inputs
131
- // {
132
- // label: this.selectedTerm?.name ?? '',
133
- // data: logs.map(log => log.value - log.inputsValue),
134
- // backgroundColor: getColor(-1),
135
- // borderColor: getColor(-1)
136
- // }
137
- // ];
138
- const datasets = [
139
- {
140
- label: this.selectedTerm?.name ?? '',
141
- data: logs.map(({ value }) => value),
142
- backgroundColor: logs.map(listColor),
143
- borderColor: logs.map(listColor)
144
- }
145
- ];
146
- if (this.chart) {
147
- this.chart.destroy();
152
+ if (!this.chartRef) {
153
+ return;
148
154
  }
149
- this.chart = new Chart(this.chartRef?.nativeElement, {
150
- type: 'horizontalBar',
151
- data: {
152
- labels,
153
- datasets
154
- },
155
- plugins: [ChartDataLabels],
156
- options: {
157
- plugins: {
158
- datalabels: {
159
- color: 'black',
160
- formatter: value => {
161
- const ratio = toPrecision((value * 100) / total, 2);
162
- return value > 0 ? `${toPrecision(value, 3)} (${ratio}%)` : '';
163
- },
164
- align: 'end'
165
- }
166
- },
167
- responsive: true,
168
- maintainAspectRatio: false,
169
- legend: {
170
- display: false
171
- },
172
- tooltips: {
173
- enabled: false,
174
- callbacks: {
175
- title: (tooltipItems, data) => data.datasets[tooltipItems[0].datasetIndex]?.label || '',
176
- label: tooltipItem => {
177
- const value = +(tooltipItem.value || '0');
178
- const ratio = toPrecision((value * 100) / total, 2);
179
- return value > 0 ? `${toPrecision(value, 3)} (${ratio}%)` : '';
180
- }
181
- }
155
+ const labels = this.labels();
156
+ const datasets = this.datasets();
157
+ const total = this.total();
158
+ this.ngZone.runOutsideAngular(() => {
159
+ if (this.chart) {
160
+ this.chart.destroy();
161
+ }
162
+ this.chart = new Chart(this.chartRef?.nativeElement, {
163
+ type: 'horizontalBar',
164
+ data: {
165
+ labels,
166
+ datasets
182
167
  },
183
- scales: {
184
- xAxes: [
185
- {
186
- display: true
168
+ plugins: [ChartDataLabels],
169
+ options: {
170
+ plugins: {
171
+ datalabels: {
172
+ color: 'black',
173
+ formatter: value => {
174
+ const ratio = toPrecision((value * 100) / total, 2);
175
+ return value > 0 ? `${toPrecision(value, 3)} (${ratio}%)` : '';
176
+ },
177
+ align: 'end'
187
178
  }
188
- ],
189
- yAxes: [
190
- {
191
- position: 'left'
179
+ },
180
+ responsive: true,
181
+ maintainAspectRatio: false,
182
+ legend: {
183
+ display: false
184
+ },
185
+ tooltips: {
186
+ enabled: false,
187
+ callbacks: {
188
+ title: (tooltipItems, data) => data.datasets[tooltipItems[0].datasetIndex]?.label || '',
189
+ label: tooltipItem => {
190
+ const value = +(tooltipItem.value || '0');
191
+ const ratio = toPrecision((value * 100) / total, 2);
192
+ return value > 0 ? `${toPrecision(value, 3)} (${ratio}%)` : '';
193
+ }
192
194
  }
193
- ]
195
+ },
196
+ scales: {
197
+ xAxes: [
198
+ {
199
+ display: true
200
+ }
201
+ ],
202
+ yAxes: [
203
+ {
204
+ position: 'left'
205
+ }
206
+ ]
207
+ }
194
208
  }
195
- }
209
+ });
196
210
  });
197
211
  }
198
- updateChart() {
199
- this.ngZone.runOutsideAngular(() => this.initChart());
212
+ selectTerm({ target: { value } }) {
213
+ const term = this.terms().find(term => term['@id'] === value);
214
+ this.selectedTerm.set(term);
215
+ }
216
+ selectMethod({ target: { value } }) {
217
+ const term = this.methods().find(term => term['@id'] === value);
218
+ this.selectedMethod.set(term);
200
219
  }
201
220
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: ImpactAssessmentsIndicatorBreakdownChartComponent, deps: [{ token: i0.NgZone }, { token: i1.DomSanitizer }, { token: i2.HeSearchService }, { token: i3.HeNodeService }], target: i0.ɵɵFactoryTarget.Component }); }
202
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.8", type: ImpactAssessmentsIndicatorBreakdownChartComponent, selector: "he-impact-assessments-indicator-breakdown-chart", inputs: { impactAssessment: "impactAssessment", indicators: "indicators" }, viewQueries: [{ propertyName: "chartRef", first: true, predicate: ["chart"], descendants: true }], ngImport: i0, template: "<div class=\"p-3\" [class.is-hidden]=\"loading || !terms?.length\">\n <div class=\"columns\">\n <div class=\"column\">\n <div class=\"field has-addons\">\n <div class=\"control\">\n <span class=\"button is-small is-static is-secondary\">Select an Indicator</span>\n </div>\n <div class=\"control is-expanded\">\n <div class=\"select is-fullwidth is-small is-secondary\">\n <select (change)=\"updateChart()\" [(ngModel)]=\"selectedTerm\" id=\"selectedTerm\">\n <option *ngFor=\"let term of terms\" [ngValue]=\"term\">{{ term.name }} ({{ term.units }})</option>\n </select>\n </div>\n </div>\n <div class=\"control is-expanded\" *ngIf=\"methods?.length\">\n <div class=\"select is-fullwidth is-small is-secondary\">\n <select (change)=\"updateChart()\" [(ngModel)]=\"selectedMethod\" id=\"selectedMethod\">\n <option [ngValue]=\"undefined\">Filter Model</option>\n <option *ngFor=\"let term of methods\" [ngValue]=\"term\">{{ term.name }}</option>\n </select>\n </div>\n </div>\n </div>\n </div>\n <div class=\"column is-narrow\">\n <a\n class=\"button is-ghost is-small\"\n [href]=\"csvContent\"\n [download]=\"id + '-logs.csv'\"\n nbgTooltip=\"Download as CSV\"\n placement=\"bottom\">\n <fa-icon icon=\"download\"></fa-icon>\n </a>\n </div>\n </div>\n\n <p class=\"is-size-7\" *ngIf=\"!selectedMethod\">\n <i>Selecting a Model is recommended to avoid duplicated entries.</i>\n </p>\n\n <div class=\"mt-1\">\n <p *ngIf=\"noData\" class=\"has-text-centered\">\n <span>No breakdown available for {{ selectedTerm?.name }}</span>\n <span class=\"pl-1\" *ngIf=\"selectedMethod\">({{ selectedMethod.name }})</span>\n <span>.</span>\n </p>\n <div class=\"chart-container h-100\">\n <canvas #chart></canvas>\n </div>\n </div>\n</div>\n\n<ng-container *ngIf=\"loading\">\n <div class=\"has-text-center py-3\">\n <fa-icon icon=\"spinner\" [pulse]=\"true\" size=\"lg\"></fa-icon>\n </div>\n</ng-container>\n", styles: [":host{display:block;overflow:visible}.chart-container{height:400px;position:relative}\n"], dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i5.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i5.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i6.FaIconComponent, selector: "fa-icon", inputs: ["icon", "title", "animation", "spin", "pulse", "mask", "styles", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "classes", "transform", "a11yRole"] }] }); }
221
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.8", type: ImpactAssessmentsIndicatorBreakdownChartComponent, selector: "he-impact-assessments-indicator-breakdown-chart", inputs: { impactAssessment: "impactAssessment", indicators: "indicators" }, viewQueries: [{ propertyName: "chartRef", first: true, predicate: ["chart"], descendants: true }], ngImport: i0, template: "<div class=\"p-3\" *ngIf=\"!loading(); else loader\" [class.is-hidden]=\"!terms()?.length\">\n <div class=\"columns\">\n <div class=\"column\">\n <div class=\"field has-addons\">\n <div class=\"control\">\n <span class=\"button is-small is-static is-secondary\">Select an Indicator</span>\n </div>\n <div class=\"control is-expanded\" *ngIf=\"terms()?.length\">\n <div class=\"select is-fullwidth is-small is-secondary\">\n <select (change)=\"selectTerm($event)\">\n <option *ngFor=\"let term of terms()\" [value]=\"term['@id']\">{{ term.name }} ({{ term.units }})</option>\n </select>\n </div>\n </div>\n <div class=\"control is-expanded\" *ngIf=\"methods()?.length\">\n <div class=\"select is-fullwidth is-small is-secondary\">\n <select (change)=\"selectMethod($event)\">\n <option [ngValue]=\"undefined\">Filter Model</option>\n <option *ngFor=\"let term of methods()\" [value]=\"term['@id']\">{{ term.name }}</option>\n </select>\n </div>\n </div>\n </div>\n </div>\n <div class=\"column is-narrow\">\n <a\n class=\"button is-ghost is-small\"\n [href]=\"csvContent()\"\n [download]=\"downloadFilename()\"\n nbgTooltip=\"Download as CSV\"\n placement=\"bottom\">\n <fa-icon icon=\"download\"></fa-icon>\n </a>\n </div>\n </div>\n\n <p class=\"is-size-7\" *ngIf=\"!selectedMethod()\">\n <i>Selecting a Model is recommended to avoid duplicated entries.</i>\n </p>\n</div>\n\n<div class=\"is-mt-1\">\n <p *ngIf=\"!loading() && noData()\" class=\"has-text-centered\">\n <span>No breakdown available for</span>\n <span class=\"is-pl-1\" *ngIf=\"selectedTerm()\">{{ selectedTerm().name }}</span>\n <span class=\"is-pl-1\" *ngIf=\"selectedMethod()\">({{ selectedMethod().name }})</span>\n <span>.</span>\n </p>\n <div class=\"chart-container h-100\">\n <canvas #chart></canvas>\n </div>\n</div>\n\n<ng-template #loader>\n <div class=\"has-text-center py-3\">\n <fa-icon icon=\"spinner\" [pulse]=\"true\" size=\"lg\"></fa-icon>\n </div>\n</ng-template>\n", styles: [":host{display:block;overflow:visible}.chart-container{height:400px;position:relative}\n"], dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i5.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "component", type: i6.FaIconComponent, selector: "fa-icon", inputs: ["icon", "title", "animation", "spin", "pulse", "mask", "styles", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "classes", "transform", "a11yRole"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
203
222
  }
204
223
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.8", ngImport: i0, type: ImpactAssessmentsIndicatorBreakdownChartComponent, decorators: [{
205
224
  type: Component,
206
- args: [{ selector: 'he-impact-assessments-indicator-breakdown-chart', template: "<div class=\"p-3\" [class.is-hidden]=\"loading || !terms?.length\">\n <div class=\"columns\">\n <div class=\"column\">\n <div class=\"field has-addons\">\n <div class=\"control\">\n <span class=\"button is-small is-static is-secondary\">Select an Indicator</span>\n </div>\n <div class=\"control is-expanded\">\n <div class=\"select is-fullwidth is-small is-secondary\">\n <select (change)=\"updateChart()\" [(ngModel)]=\"selectedTerm\" id=\"selectedTerm\">\n <option *ngFor=\"let term of terms\" [ngValue]=\"term\">{{ term.name }} ({{ term.units }})</option>\n </select>\n </div>\n </div>\n <div class=\"control is-expanded\" *ngIf=\"methods?.length\">\n <div class=\"select is-fullwidth is-small is-secondary\">\n <select (change)=\"updateChart()\" [(ngModel)]=\"selectedMethod\" id=\"selectedMethod\">\n <option [ngValue]=\"undefined\">Filter Model</option>\n <option *ngFor=\"let term of methods\" [ngValue]=\"term\">{{ term.name }}</option>\n </select>\n </div>\n </div>\n </div>\n </div>\n <div class=\"column is-narrow\">\n <a\n class=\"button is-ghost is-small\"\n [href]=\"csvContent\"\n [download]=\"id + '-logs.csv'\"\n nbgTooltip=\"Download as CSV\"\n placement=\"bottom\">\n <fa-icon icon=\"download\"></fa-icon>\n </a>\n </div>\n </div>\n\n <p class=\"is-size-7\" *ngIf=\"!selectedMethod\">\n <i>Selecting a Model is recommended to avoid duplicated entries.</i>\n </p>\n\n <div class=\"mt-1\">\n <p *ngIf=\"noData\" class=\"has-text-centered\">\n <span>No breakdown available for {{ selectedTerm?.name }}</span>\n <span class=\"pl-1\" *ngIf=\"selectedMethod\">({{ selectedMethod.name }})</span>\n <span>.</span>\n </p>\n <div class=\"chart-container h-100\">\n <canvas #chart></canvas>\n </div>\n </div>\n</div>\n\n<ng-container *ngIf=\"loading\">\n <div class=\"has-text-center py-3\">\n <fa-icon icon=\"spinner\" [pulse]=\"true\" size=\"lg\"></fa-icon>\n </div>\n</ng-container>\n", styles: [":host{display:block;overflow:visible}.chart-container{height:400px;position:relative}\n"] }]
225
+ args: [{ selector: 'he-impact-assessments-indicator-breakdown-chart', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"p-3\" *ngIf=\"!loading(); else loader\" [class.is-hidden]=\"!terms()?.length\">\n <div class=\"columns\">\n <div class=\"column\">\n <div class=\"field has-addons\">\n <div class=\"control\">\n <span class=\"button is-small is-static is-secondary\">Select an Indicator</span>\n </div>\n <div class=\"control is-expanded\" *ngIf=\"terms()?.length\">\n <div class=\"select is-fullwidth is-small is-secondary\">\n <select (change)=\"selectTerm($event)\">\n <option *ngFor=\"let term of terms()\" [value]=\"term['@id']\">{{ term.name }} ({{ term.units }})</option>\n </select>\n </div>\n </div>\n <div class=\"control is-expanded\" *ngIf=\"methods()?.length\">\n <div class=\"select is-fullwidth is-small is-secondary\">\n <select (change)=\"selectMethod($event)\">\n <option [ngValue]=\"undefined\">Filter Model</option>\n <option *ngFor=\"let term of methods()\" [value]=\"term['@id']\">{{ term.name }}</option>\n </select>\n </div>\n </div>\n </div>\n </div>\n <div class=\"column is-narrow\">\n <a\n class=\"button is-ghost is-small\"\n [href]=\"csvContent()\"\n [download]=\"downloadFilename()\"\n nbgTooltip=\"Download as CSV\"\n placement=\"bottom\">\n <fa-icon icon=\"download\"></fa-icon>\n </a>\n </div>\n </div>\n\n <p class=\"is-size-7\" *ngIf=\"!selectedMethod()\">\n <i>Selecting a Model is recommended to avoid duplicated entries.</i>\n </p>\n</div>\n\n<div class=\"is-mt-1\">\n <p *ngIf=\"!loading() && noData()\" class=\"has-text-centered\">\n <span>No breakdown available for</span>\n <span class=\"is-pl-1\" *ngIf=\"selectedTerm()\">{{ selectedTerm().name }}</span>\n <span class=\"is-pl-1\" *ngIf=\"selectedMethod()\">({{ selectedMethod().name }})</span>\n <span>.</span>\n </p>\n <div class=\"chart-container h-100\">\n <canvas #chart></canvas>\n </div>\n</div>\n\n<ng-template #loader>\n <div class=\"has-text-center py-3\">\n <fa-icon icon=\"spinner\" [pulse]=\"true\" size=\"lg\"></fa-icon>\n </div>\n</ng-template>\n", styles: [":host{display:block;overflow:visible}.chart-container{height:400px;position:relative}\n"] }]
207
226
  }], ctorParameters: function () { return [{ type: i0.NgZone }, { type: i1.DomSanitizer }, { type: i2.HeSearchService }, { type: i3.HeNodeService }]; }, propDecorators: { chartRef: [{
208
227
  type: ViewChild,
209
228
  args: ['chart']
@@ -212,4 +231,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.8", ngImpor
212
231
  }], indicators: [{
213
232
  type: Input
214
233
  }] } });
215
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1wYWN0LWFzc2Vzc21lbnRzLWluZGljYXRvci1icmVha2Rvd24tY2hhcnQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2ltcGFjdC1hc3Nlc3NtZW50cy9pbXBhY3QtYXNzZXNzbWVudHMtaW5kaWNhdG9yLWJyZWFrZG93bi1jaGFydC9pbXBhY3QtYXNzZXNzbWVudHMtaW5kaWNhdG9yLWJyZWFrZG93bi1jaGFydC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9zcmMvaW1wYWN0LWFzc2Vzc21lbnRzL2ltcGFjdC1hc3Nlc3NtZW50cy1pbmRpY2F0b3ItYnJlYWtkb3duLWNoYXJ0L2ltcGFjdC1hc3Nlc3NtZW50cy1pbmRpY2F0b3ItYnJlYWtkb3duLWNoYXJ0LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQWMsS0FBSyxFQUFrQixTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFeEYsT0FBTyxFQUFFLEVBQUUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMxQixPQUFPLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNuRixPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBQ2pDLE9BQU8sZUFBZSxNQUFNLDJCQUEyQixDQUFDO0FBQ3hELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUM5QyxPQUFPLEVBQW1ELFFBQVEsRUFBUSxZQUFZLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNySCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRTFELE9BQU8sRUFBRSxhQUFhLEVBQUUsU0FBUyxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFHckUsT0FBTyxFQUFF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O3VCQUFDLE9BQU87Z0JBS1gsZ0JBQWdCO3NCQUR0QixLQUFLO2dCQUdDLFVBQVU7c0JBRGhCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIEVsZW1lbnRSZWYsIElucHV0LCBOZ1pvbmUsIE9uSW5pdCwgVmlld0NoaWxkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBEb21TYW5pdGl6ZXIsIFNhZmVSZXNvdXJjZVVybCB9IGZyb20gJ0Bhbmd1bGFyL3BsYXRmb3JtLWJyb3dzZXInO1xuaW1wb3J0IHsgb2YgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IGZpbHRlciwgZ3JvdXBCeSwgbWFwLCBtZXJnZUFsbCwgbWVyZ2VNYXAsIHRvQXJyYXkgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBDaGFydCB9IGZyb20gJ2NoYXJ0LmpzJztcbmltcG9ydCBDaGFydERhdGFMYWJlbHMgZnJvbSAnY2hhcnRqcy1wbHVnaW4tZGF0YWxhYmVscyc7XG5pbXBvcnQgeyBEYXRhU3RhdGUgfSBmcm9tICdAaGVzdGlhLWVhcnRoL2FwaSc7XG5pbXBvcnQgeyBJSW1wYWN0QXNzZXNzbWVudEpTT05MRCwgSW5kaWNhdG9yLCBJVGVybUpTT05MRCwgTm9kZVR5cGUsIFRlcm0sIFRlcm1UZXJtVHlwZSB9IGZyb20gJ0BoZXN0aWEtZWFydGgvc2NoZW1hJztcbmltcG9ydCB7IHRvUHJlY2lzaW9uLCB1bmlxdWUgfSBmcm9tICdAaGVzdGlhLWVhcnRoL3V0aWxzJztcblxuaW1wb3J0IHsgbWF0Y2hUZXJtVHlwZSwgbWF0Y2hUeXBlIH0gZnJvbSAnLi4vLi4vc2VhcmNoL3NlYXJjaC5tb2RlbCc7XG5pbXBvcnQgeyBIZVNlYXJjaFNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZWFyY2gvc2VhcmNoLnNlcnZpY2UnO1xuaW1wb3J0IHsgSGVOb2RlU2VydmljZSB9IGZyb20gJy4uLy4uL25vZGUvbm9kZS5zZXJ2aWNlJztcbmltcG9ydCB7IExldmVsLCBwYXJzZUxpbmVzLCBwYXJzZU1lc3NhZ2UgfSBmcm9tICcuLi8uLi9jb21tb24vbG9ncy11dGlscyc7XG5pbXBvcnQgeyBsaXN0Q29sb3IgfSBmcm9tICcuLi8uLi9jb21tb24vY29sb3InO1xuXG5pbnRlcmZhY2UgSUxvZyB7XG4gIG1vZGVsSWQ6IHN0cmluZztcbiAgaW1wYWN0VGVybUlkOiBzdHJpbmc7XG4gIGltcGFjdFRlcm1Vbml0cz86IHN0cmluZztcbiAgYmxhbmtOb2RlVGVybUlkOiBzdHJpbmc7XG4gIGNvZWZmaWNpZW50OiBudW1iZXI7XG4gIHZhbHVlOiBudW1iZXI7XG4gIC8vIHN0b3JlIGFsbCBpbmRpY2F0b3JzIHdpdGggaW5wdXRzXG4gIGlucHV0cz86IHtcbiAgICBuYW1lOiBzdHJpbmc7XG4gICAgdmFsdWU6IG51bWJlcjtcbiAgfVtdO1xuICBpbnB1dHNWYWx1ZT86IG51bWJlcjtcbn1cblxuY29uc3QgcGFyc2VMb2cgPSAoZGF0YTogYW55KTogSUxvZyA9PiAoe1xuICBtb2RlbElkOiBkYXRhLm1vZGVsLFxuICBpbXBhY3RUZXJtSWQ6IGRhdGFbJ2tleS90ZXJtJ10gfHwgZGF0YS50ZXJtIHx8IGRhdGEuaW5kaWNhdG9yLFxuICBibGFua05vZGVUZXJtSWQ6IGRhdGEubm9kZSxcbiAgY29lZmZpY2llbnQ6ICtkYXRhLmNvZWZmaWNpZW50LFxuICB2YWx1ZTogK2RhdGEudmFsdWUgKiArZGF0YS5jb2VmZmljaWVudFxufSk7XG5cbmNvbnN0IGZpbHRlclRlcm1UeXBlcyA9IFtUZXJtVGVybVR5cGUuZW1pc3Npb24sIFRlcm1UZXJtVHlwZS5jaGFyYWN0ZXJpc2VkSW5kaWNhdG9yXTtcblxuY29uc3QgY3N2SGVhZGVycyA9IFtcbiAgJ0ltcGFjdCcsXG4gICdJbXBhY3QgVW5pdCcsXG4gICdNZXRob2QnLFxuICAnRW1pc3Npb24nLFxuICAnVmFsdWUnLFxuICAnSW5wdXRzJyxcbiAgJ0lucHV0cyB2YWx1ZScsXG4gICdGdW5jdGlvbmFsIFVuaXQnXG5dO1xuXG5jb25zdCBsb2dUb0NzdiA9IChsb2dzOiBJTG9nW10sIGltcGFjdDogSUltcGFjdEFzc2Vzc21lbnRKU09OTEQpID0+XG4gIFtcbiAgICBjc3ZIZWFkZXJzLmpvaW4oJywnKSxcbiAgICAuLi5sb2dzXG4gICAgICAuc29ydCgoYSwgYikgPT4gYS5pbXBhY3RUZXJtSWQubG9jYWxlQ29tcGFyZShiLmltcGFjdFRlcm1JZCkpXG4gICAgICAuZmxhdE1hcCgoeyBpbXBhY3RUZXJtSWQsIGltcGFjdFRlcm1Vbml0cywgbW9kZWxJZCwgYmxhbmtOb2RlVGVybUlkLCB2YWx1ZSwgaW5wdXRzIH0pID0+IFtcbiAgICAgICAgW2ltcGFjdFRlcm1JZCwgaW1wYWN0VGVybVVuaXRzLCBtb2RlbElkLCBibGFua05vZGVUZXJtSWQsIHZhbHVlLCAnJywgJyddLFxuICAgICAgICAuLi5pbnB1dHMubWFwKHYgPT4gW2ltcGFjdFRlcm1JZCwgaW1wYWN0VGVybVVuaXRzLCBtb2RlbElkLCBibGFua05vZGVUZXJtSWQsICcnLCB2Lm5hbWUsIHYudmFsdWVdKVxuICAgICAgXSlcbiAgICAgIC5tYXAodiA9PiBbLi4udiwgaW1wYWN0LnByb2R1Y3Q/LnRlcm0/LnVuaXRzXS5qb2luKCcsJykpXG4gIF0uam9pbignXFxuJyk7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2hlLWltcGFjdC1hc3Nlc3NtZW50cy1pbmRpY2F0b3ItYnJlYWtkb3duLWNoYXJ0JyxcbiAgdGVtcGxhdGVVcmw6ICcuL2ltcGFjdC1hc3Nlc3NtZW50cy1pbmRpY2F0b3ItYnJlYWtkb3duLWNoYXJ0LmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vaW1wYWN0LWFzc2Vzc21lbnRzLWluZGljYXRvci1icmVha2Rvd24tY2hhcnQuY29tcG9uZW50LnNjc3MnXVxufSlcbmV4cG9ydCBjbGFzcyBJbXBhY3RBc3Nlc3NtZW50c0luZGljYXRvckJyZWFrZG93bkNoYXJ0Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgcHJpdmF0ZSBsb2dzOiBJTG9nW10gPSBbXTtcbiAgcHJpdmF0ZSBlbWlzc2lvbnM6IElUZXJtSlNPTkxEW10gPSBbXTtcblxuICBAVmlld0NoaWxkKCdjaGFydCcpXG4gIHByaXZhdGUgY2hhcnRSZWY/OiBFbGVtZW50UmVmO1xuICBwcml2YXRlIGNoYXJ0OiBhbnk7XG5cbiAgQElucHV0KClcbiAgcHVibGljIGltcGFjdEFzc2Vzc21lbnQ/OiBJSW1wYWN0QXNzZXNzbWVudEpTT05MRDtcbiAgQElucHV0KClcbiAgcHVibGljIGluZGljYXRvcnM6IEluZGljYXRvcltdID0gW107XG5cbiAgcHVibGljIGxvYWRpbmcgPSB0cnVlO1xuICBwdWJsaWMgdGVybXM6IFRlcm1bXSA9IFtdO1xuICBwdWJsaWMgc2VsZWN0ZWRUZXJtPzogVGVybTtcbiAgcHVibGljIG1ldGhvZHM6IFRlcm1bXSA9IFtdO1xuICBwdWJsaWMgc2VsZWN0ZWRNZXRob2Q/OiBUZXJtO1xuICBwdWJsaWMgbm9EYXRhID0gZmFsc2U7XG4gIHB1YmxpYyBjc3ZDb250ZW50PzogU2FmZVJlc291cmNlVXJsO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgbmdab25lOiBOZ1pvbmUsXG4gICAgcHJpdmF0ZSBkb21TYW5pdGl6ZXI6IERvbVNhbml0aXplcixcbiAgICBwcml2YXRlIHNlYXJjaFNlcnZpY2U6IEhlU2VhcmNoU2VydmljZSxcbiAgICBwcml2YXRlIG5vZGVTZXJ2aWNlOiBIZU5vZGVTZXJ2aWNlXG4gICkge31cblxuICBhc3luYyBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLnRlcm1zID0gdW5pcXVlKCh0aGlzLmluZGljYXRvcnMgfHwgW10pLm1hcCgoeyB0ZXJtIH0pID0+IHRlcm0hKS5maWx0ZXIoQm9vbGVhbikpO1xuICAgIHRoaXMubWV0aG9kcyA9IHVuaXF1ZSgodGhpcy5pbmRpY2F0b3JzIHx8IFtdKS5tYXAoKHsgbWV0aG9kTW9kZWwgfSkgPT4gbWV0aG9kTW9kZWwhKS5maWx0ZXIoQm9vbGVhbikpO1xuXG4gICAgY29uc3QgaW1wYWN0cyA9IFsuLi4odGhpcy5pbXBhY3RBc3Nlc3NtZW50LmltcGFjdHMgfHwgW10pLCAuLi4odGhpcy5pbXBhY3RBc3Nlc3NtZW50LmVuZHBvaW50cyB8fCBbXSldO1xuXG4gICAgdGhpcy5sb2dzID0gKGF3YWl0IG9mKHtcbiAgICAgIC4uLnRoaXMuaW1wYWN0QXNzZXNzbWVudCxcbiAgICAgIGRhdGFTdGF0ZTogRGF0YVN0YXRlLnJlY2FsY3VsYXRlZFxuICAgIH0pXG4gICAgICAucGlwZShcbiAgICAgICAgbWVyZ2VNYXAobm9kZSA9PiB0aGlzLm5vZGVTZXJ2aWNlLmdldExvZyhub2RlKSksXG4gICAgICAgIG1hcCh2YWx1ZSA9PiAodmFsdWUgPyBwYXJzZUxpbmVzKHZhbHVlKSA6IFtdKSksXG4gICAgICAgIG1lcmdlQWxsKCksXG4gICAgICAgIGZpbHRlcigoeyBkYXRhIH0pID0+IGRhdGEubG9nZ2VyID09PSAnaGVzdGlhX2VhcnRoLm1vZGVscycgJiYgZGF0YS5sZXZlbCA9PT0gTGV2ZWwuZGVidWcpLFxuICAgICAgICBmaWx0ZXIoKHsgZGF0YTogeyBtZXNzYWdlIH0gfSkgPT4gISFtZXNzYWdlKSxcbiAgICAgICAgbWFwKCh7IGRhdGE6IHsgbWVzc2FnZSB9IH0pID0+IHBhcnNlTWVzc2FnZShtZXNzYWdlKSksXG4gICAgICAgIGZpbHRlcihtZXNzYWdlID0+ICdub2RlJyBpbiBtZXNzYWdlKSxcbiAgICAgICAgbWFwKHBhcnNlTG9nKSxcbiAgICAgICAgZmlsdGVyKGxvZyA9PiAhIWxvZy5pbXBhY3RUZXJtSWQgJiYgISFsb2cuYmxhbmtOb2RlVGVybUlkICYmICFpc05hTihsb2cudmFsdWUpICYmIGxvZy52YWx1ZSA+IDApLFxuICAgICAgICBncm91cEJ5KGxvZyA9PiBbbG9nLmltcGFjdFRlcm1JZCwgbG9nLmJsYW5rTm9kZVRlcm1JZCwgbG9nLm1vZGVsSWRdLmpvaW4oJy8nKSksXG4gICAgICAgIG1lcmdlTWFwKGdyb3VwID0+IGdyb3VwLnBpcGUodG9BcnJheSgpKSksXG4gICAgICAgIG1hcCgodmFsdWVzOiBJTG9nW10pID0+IHtcbiAgICAgICAgICBjb25zdCBsb2cgPSB2YWx1ZXNbMF07XG4gICAgICAgICAgY29uc3QgdG90YWwgPSB2YWx1ZXMucmVkdWNlKChwcmV2LCBjdXJyKSA9PiBwcmV2ICsgY3Vyci52YWx1ZSwgMCk7XG4gICAgICAgICAgY29uc3QgYmxhbmtOb2RlcyA9IFtcbiAgICAgICAgICAgIC4uLih0aGlzLmltcGFjdEFzc2Vzc21lbnQuZW1pc3Npb25zUmVzb3VyY2VVc2UgfHwgW10pLFxuICAgICAgICAgICAgLi4uKHRoaXMuaW1wYWN0QXNzZXNzbWVudC5pbXBhY3RzIHx8IFtdKVxuICAgICAgICAgIF0uZmlsdGVyKHYgPT4gdi50ZXJtWydAaWQnXSA9PT0gbG9nLmJsYW5rTm9kZVRlcm1JZCk7XG5cbiAgICAgICAgICBjb25zdCBpbnB1dHMgPSBibGFua05vZGVzXG4gICAgICAgICAgICAuZmlsdGVyKHYgPT4gdi5pbnB1dHM/Lmxlbmd0aClcbiAgICAgICAgICAgIC5tYXAodiA9PiAoeyBuYW1lOiB2LmlucHV0cy5tYXAoaSA9PiBpWydAaWQnXSkuam9pbignOycpLCB2YWx1ZTogdi52YWx1ZSAqIGxvZy5jb2VmZmljaWVudCB9KSk7XG4gICAgICAgICAgY29uc3QgaW5wdXRzVmFsdWUgPSBpbnB1dHMucmVkdWNlKChwcmV2LCBjdXJyKSA9PiBwcmV2ICsgY3Vyci52YWx1ZSwgMCk7XG5cbiAgICAgICAgICBjb25zdCBpbXBhY3QgPSBpbXBhY3RzLmZpbmQodiA9PiB2LnRlcm1bJ0BpZCddID09PSBsb2cuaW1wYWN0VGVybUlkKTtcblxuICAgICAgICAgIC8vIGxvZ3MgbWlnaHQgZXhpc3QgYnV0IGltcGFjdCB3YXMgbm90IGFkZGVkID0+IHNraXAgbG9nc1xuICAgICAgICAgIHJldHVybiBpbXBhY3RcbiAgICAgICAgICAgID8ge1xuICAgICAgICAgICAgICAgIC4uLmxvZyxcbiAgICAgICAgICAgICAgICBpbXBhY3RUZXJtVW5pdHM6IGltcGFjdC50ZXJtPy51bml0cyxcbiAgICAgICAgICAgICAgICB2YWx1ZTogdG90YWwsXG4gICAgICAgICAgICAgICAgaW5wdXRzLFxuICAgICAgICAgICAgICAgIGlucHV0c1ZhbHVlXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDogbnVsbDtcbiAgICAgICAgfSksXG4gICAgICAgIGZpbHRlcihsb2cgPT4gISFsb2cpLFxuICAgICAgICB0b0FycmF5KClcbiAgICAgIClcbiAgICAgIC50b1Byb21pc2UoKSkgYXMgSUxvZ1tdO1xuICAgIHRoaXMuY3N2Q29udGVudCA9IHRoaXMuZG9tU2FuaXRpemVyLmJ5cGFzc1NlY3VyaXR5VHJ1c3RSZXNvdXJjZVVybChcbiAgICAgIGBkYXRhOnRleHQvaHRtbDtjaGFyc2V0PXV0Zi04LCR7ZW5jb2RlVVJJQ29tcG9uZW50KGxvZ1RvQ3N2KHRoaXMubG9ncywgdGhpcy5pbXBhY3RBc3Nlc3NtZW50KSl9YFxuICAgICk7XG5cbiAgICBjb25zdCB7IHJlc3VsdHMgfSA9IGF3YWl0IHRoaXMuc2VhcmNoU2VydmljZS5zZWFyY2g8SVRlcm1KU09OTEQsIE5vZGVUeXBlLlRlcm0+KHtcbiAgICAgIGZpZWxkczogWydAdHlwZScsICdAaWQnLCAnbmFtZSddLFxuICAgICAgbGltaXQ6IDEwMDAsXG4gICAgICBxdWVyeToge1xuICAgICAgICBib29sOiB7XG4gICAgICAgICAgbXVzdDogW21hdGNoVHlwZShOb2RlVHlwZS5UZXJtKV0sXG4gICAgICAgICAgc2hvdWxkOiBmaWx0ZXJUZXJtVHlwZXMubWFwKHRlcm1UeXBlID0+IG1hdGNoVGVybVR5cGUodGVybVR5cGUpKSxcbiAgICAgICAgICBtaW5pbXVtX3Nob3VsZF9tYXRjaDogMVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gICAgdGhpcy5lbWlzc2lvbnMgPSByZXN1bHRzO1xuXG4gICAgdGhpcy5sb2FkaW5nID0gZmFsc2U7XG5cbiAgICB0aGlzLnNlbGVjdGVkVGVybSA9IHRoaXMudGVybXNbMF07XG4gICAgdGhpcy51cGRhdGVDaGFydCgpO1xuICB9XG5cbiAgcHVibGljIGdldCBpZCgpIHtcbiAgICByZXR1cm4gdGhpcy5pbXBhY3RBc3Nlc3NtZW50IVsnQGlkJ10gfHwgKHRoaXMuaW1wYWN0QXNzZXNzbWVudCBhcyBhbnkpLmlkO1xuICB9XG5cbiAgcHJpdmF0ZSBpbml0Q2hhcnQoKSB7XG4gICAgY29uc3QgbG9ncyA9IHRoaXMubG9nc1xuICAgICAgLmZpbHRlcihcbiAgICAgICAgKHsgaW1wYWN0VGVybUlkLCBtb2RlbElkIH0pID0+XG4gICAgICAgICAgaW1wYWN0VGVybUlkID09PSB0aGlzLnNlbGVjdGVkVGVybT8uWydAaWQnXSAmJlxuICAgICAgICAgICghdGhpcy5zZWxlY3RlZE1ldGhvZCB8fCBtb2RlbElkID09PSB0aGlzLnNlbGVjdGVkTWV0aG9kWydAaWQnXSlcbiAgICAgIClcbiAgICAgIC5zb3J0KChhLCBiKSA9PiBiLnZhbHVlIC0gYS52YWx1ZSk7XG4gICAgdGhpcy5ub0RhdGEgPSBsb2dzLmxlbmd0aCA9PT0gMDtcblxuICAgIGNvbnN0IHRvdGFsID0gbG9ncy5yZWR1Y2UoKHByZXYsIGN1cnIpID0+IHByZXYgKyBjdXJyLnZhbHVlLCAwKTtcbiAgICBjb25zdCBsYWJlbHMgPSBsb2dzLm1hcChcbiAgICAgICh7IGJsYW5rTm9kZVRlcm1JZCB9KSA9PiB0aGlzLmVtaXNzaW9ucy5maW5kKHYgPT4gdlsnQGlkJ10gPT09IGJsYW5rTm9kZVRlcm1JZCk/Lm5hbWUgfHwgYmxhbmtOb2RlVGVybUlkXG4gICAgKTtcblxuICAgIC8vIGRpc3BsYXkgdGhlIGJyZWFrZG93biBieSBpbnB1dFxuICAgIC8vIGNvbnN0IGlucHV0cyA9IGxvZ3MuZmxhdE1hcCh2ID0+IHYuaW5wdXRzLm1hcChpID0+IGkubmFtZSkpO1xuICAgIC8vIGNvbnN0IGRhdGFzZXRzID0gW1xuICAgIC8vICAgLi4uaW5wdXRzLm1hcCgoaW5wdXQsIGluZGV4KSA9PiAoe1xuICAgIC8vICAgICBsYWJlbDogaW5wdXQsXG4gICAgLy8gICAgIGRhdGE6IGxvZ3MubWFwKGxvZyA9PiBsb2cuaW5wdXRzLmZpbmQoKHsgbmFtZSB9KSA9PiBuYW1lID09PSBpbnB1dCk/LnZhbHVlIHx8IDApLFxuICAgIC8vICAgICBiYWNrZ3JvdW5kQ29sb3I6IGdldENvbG9yKGluZGV4KSxcbiAgICAvLyAgICAgYm9yZGVyQ29sb3I6IGdldENvbG9yKGluZGV4KVxuICAgIC8vICAgfSkpLFxuICAgIC8vICAgLy8gYWRkIGRhdGFzZXQgZm9yIHJlc3Qgbm90IGxpbmtlZCB0byBpbnB1dHNcbiAgICAvLyAgIHtcbiAgICAvLyAgICAgbGFiZWw6IHRoaXMuc2VsZWN0ZWRUZXJtPy5uYW1lID8/ICcnLFxuICAgIC8vICAgICBkYXRhOiBsb2dzLm1hcChsb2cgPT4gbG9nLnZhbHVlIC0gbG9nLmlucHV0c1ZhbHVlKSxcbiAgICAvLyAgICAgYmFja2dyb3VuZENvbG9yOiBnZXRDb2xvcigtMSksXG4gICAgLy8gICAgIGJvcmRlckNvbG9yOiBnZXRDb2xvcigtMSlcbiAgICAvLyAgIH1cbiAgICAvLyBdO1xuXG4gICAgY29uc3QgZGF0YXNldHMgPSBbXG4gICAgICB7XG4gICAgICAgIGxhYmVsOiB0aGlzLnNlbGVjdGVkVGVybT8ubmFtZSA/PyAnJyxcbiAgICAgICAgZGF0YTogbG9ncy5tYXAoKHsgdmFsdWUgfSkgPT4gdmFsdWUpLFxuICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IGxvZ3MubWFwKGxpc3RDb2xvciksXG4gICAgICAgIGJvcmRlckNvbG9yOiBsb2dzLm1hcChsaXN0Q29sb3IpXG4gICAgICB9XG4gICAgXTtcblxuICAgIGlmICh0aGlzLmNoYXJ0KSB7XG4gICAgICB0aGlzLmNoYXJ0LmRlc3Ryb3koKTtcbiAgICB9XG4gICAgdGhpcy5jaGFydCA9IG5ldyBDaGFydCh0aGlzLmNoYXJ0UmVmPy5uYXRpdmVFbGVtZW50LCB7XG4gICAgICB0eXBlOiAnaG9yaXpvbnRhbEJhcicsXG4gICAgICBkYXRhOiB7XG4gICAgICAgIGxhYmVscyxcbiAgICAgICAgZGF0YXNldHNcbiAgICAgIH0sXG4gICAgICBwbHVnaW5zOiBbQ2hhcnREYXRhTGFiZWxzXSxcbiAgICAgIG9wdGlvbnM6IHtcbiAgICAgICAgcGx1Z2luczoge1xuICAgICAgICAgIGRhdGFsYWJlbHM6IHtcbiAgICAgICAgICAgIGNvbG9yOiAnYmxhY2snLFxuICAgICAgICAgICAgZm9ybWF0dGVyOiB2YWx1ZSA9PiB7XG4gICAgICAgICAgICAgIGNvbnN0IHJhdGlvID0gdG9QcmVjaXNpb24oKHZhbHVlICogMTAwKSAvIHRvdGFsLCAyKTtcbiAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlID4gMCA/IGAke3RvUHJlY2lzaW9uKHZhbHVlLCAzKX0gKCR7cmF0aW99JSlgIDogJyc7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYWxpZ246ICdlbmQnXG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICByZXNwb25zaXZlOiB0cnVlLFxuICAgICAgICBtYWludGFpbkFzcGVjdFJhdGlvOiBmYWxzZSxcbiAgICAgICAgbGVnZW5kOiB7XG4gICAgICAgICAgZGlzcGxheTogZmFsc2VcbiAgICAgICAgfSxcbiAgICAgICAgdG9vbHRpcHM6IHtcbiAgICAgICAgICBlbmFibGVkOiBmYWxzZSxcbiAgICAgICAgICBjYWxsYmFja3M6IHtcbiAgICAgICAgICAgIHRpdGxlOiAodG9vbHRpcEl0ZW1zLCBkYXRhKSA9PiBkYXRhLmRhdGFzZXRzIVt0b29sdGlwSXRlbXNbMF0uZGF0YXNldEluZGV4IV0/LmxhYmVsIHx8ICcnLFxuICAgICAgICAgICAgbGFiZWw6IHRvb2x0aXBJdGVtID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSArKHRvb2x0aXBJdGVtLnZhbHVlIHx8ICcwJyk7XG4gICAgICAgICAgICAgIGNvbnN0IHJhdGlvID0gdG9QcmVjaXNpb24oKHZhbHVlICogMTAwKSAvIHRvdGFsLCAyKTtcbiAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlID4gMCA/IGAke3RvUHJlY2lzaW9uKHZhbHVlLCAzKX0gKCR7cmF0aW99JSlgIDogJyc7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBzY2FsZXM6IHtcbiAgICAgICAgICB4QXhlczogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBkaXNwbGF5OiB0cnVlXG4gICAgICAgICAgICB9XG4gICAgICAgICAgXSxcbiAgICAgICAgICB5QXhlczogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBwb3NpdGlvbjogJ2xlZnQnXG4gICAgICAgICAgICB9XG4gICAgICAgICAgXVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgdXBkYXRlQ2hhcnQoKSB7XG4gICAgdGhpcy5uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4gdGhpcy5pbml0Q2hhcnQoKSk7XG4gIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJwLTNcIiBbY2xhc3MuaXMtaGlkZGVuXT1cImxvYWRpbmcgfHwgIXRlcm1zPy5sZW5ndGhcIj5cbiAgPGRpdiBjbGFzcz1cImNvbHVtbnNcIj5cbiAgICA8ZGl2IGNsYXNzPVwiY29sdW1uXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiZmllbGQgaGFzLWFkZG9uc1wiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY29udHJvbFwiPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYnV0dG9uIGlzLXNtYWxsIGlzLXN0YXRpYyBpcy1zZWNvbmRhcnlcIj5TZWxlY3QgYW4gSW5kaWNhdG9yPC9zcGFuPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNvbnRyb2wgaXMtZXhwYW5kZWRcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VsZWN0IGlzLWZ1bGx3aWR0aCBpcy1zbWFsbCBpcy1zZWNvbmRhcnlcIj5cbiAgICAgICAgICAgIDxzZWxlY3QgKGNoYW5nZSk9XCJ1cGRhdGVDaGFydCgpXCIgWyhuZ01vZGVsKV09XCJzZWxlY3RlZFRlcm1cIiBpZD1cInNlbGVjdGVkVGVybVwiPlxuICAgICAgICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCB0ZXJtIG9mIHRlcm1zXCIgW25nVmFsdWVdPVwidGVybVwiPnt7IHRlcm0ubmFtZSB9fSAoe3sgdGVybS51bml0cyB9fSk8L29wdGlvbj5cbiAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNvbnRyb2wgaXMtZXhwYW5kZWRcIiAqbmdJZj1cIm1ldGhvZHM/Lmxlbmd0aFwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZWxlY3QgaXMtZnVsbHdpZHRoIGlzLXNtYWxsIGlzLXNlY29uZGFyeVwiPlxuICAgICAgICAgICAgPHNlbGVjdCAoY2hhbmdlKT1cInVwZGF0ZUNoYXJ0KClcIiBbKG5nTW9kZWwpXT1cInNlbGVjdGVkTWV0aG9kXCIgaWQ9XCJzZWxlY3RlZE1ldGhvZFwiPlxuICAgICAgICAgICAgICA8b3B0aW9uIFtuZ1ZhbHVlXT1cInVuZGVmaW5lZFwiPkZpbHRlciBNb2RlbDwvb3B0aW9uPlxuICAgICAgICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCB0ZXJtIG9mIG1ldGhvZHNcIiBbbmdWYWx1ZV09XCJ0ZXJtXCI+e3sgdGVybS5uYW1lIH19PC9vcHRpb24+XG4gICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwiY29sdW1uIGlzLW5hcnJvd1wiPlxuICAgICAgPGFcbiAgICAgICAgY2xhc3M9XCJidXR0b24gaXMtZ2hvc3QgaXMtc21hbGxcIlxuICAgICAgICBbaHJlZl09XCJjc3ZDb250ZW50XCJcbiAgICAgICAgW2Rvd25sb2FkXT1cImlkICsgJy1sb2dzLmNzdidcIlxuICAgICAgICBuYmdUb29sdGlwPVwiRG93bmxvYWQgYXMgQ1NWXCJcbiAgICAgICAgcGxhY2VtZW50PVwiYm90dG9tXCI+XG4gICAgICAgIDxmYS1pY29uIGljb249XCJkb3dubG9hZFwiPjwvZmEtaWNvbj5cbiAgICAgIDwvYT5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG5cbiAgPHAgY2xhc3M9XCJpcy1zaXplLTdcIiAqbmdJZj1cIiFzZWxlY3RlZE1ldGhvZFwiPlxuICAgIDxpPlNlbGVjdGluZyBhIE1vZGVsIGlzIHJlY29tbWVuZGVkIHRvIGF2b2lkIGR1cGxpY2F0ZWQgZW50cmllcy48L2k+XG4gIDwvcD5cblxuICA8ZGl2IGNsYXNzPVwibXQtMVwiPlxuICAgIDxwICpuZ0lmPVwibm9EYXRhXCIgY2xhc3M9XCJoYXMtdGV4dC1jZW50ZXJlZFwiPlxuICAgICAgPHNwYW4+Tm8gYnJlYWtkb3duIGF2YWlsYWJsZSBmb3Ige3sgc2VsZWN0ZWRUZXJtPy5uYW1lIH19PC9zcGFuPlxuICAgICAgPHNwYW4gY2xhc3M9XCJwbC0xXCIgKm5nSWY9XCJzZWxlY3RlZE1ldGhvZFwiPih7eyBzZWxlY3RlZE1ldGhvZC5uYW1lIH19KTwvc3Bhbj5cbiAgICAgIDxzcGFuPi48L3NwYW4+XG4gICAgPC9wPlxuICAgIDxkaXYgY2xhc3M9XCJjaGFydC1jb250YWluZXIgaC0xMDBcIj5cbiAgICAgIDxjYW52YXMgI2NoYXJ0PjwvY2FudmFzPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvZGl2PlxuXG48bmctY29udGFpbmVyICpuZ0lmPVwibG9hZGluZ1wiPlxuICA8ZGl2IGNsYXNzPVwiaGFzLXRleHQtY2VudGVyIHB5LTNcIj5cbiAgICA8ZmEtaWNvbiBpY29uPVwic3Bpbm5lclwiIFtwdWxzZV09XCJ0cnVlXCIgc2l6ZT1cImxnXCI+PC9mYS1pY29uPlxuICA8L2Rpdj5cbjwvbmctY29udGFpbmVyPlxuIl19
234
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1wYWN0LWFzc2Vzc21lbnRzLWluZGljYXRvci1icmVha2Rvd24tY2hhcnQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2ltcGFjdC1hc3Nlc3NtZW50cy9pbXBhY3QtYXNzZXNzbWVudHMtaW5kaWNhdG9yLWJyZWFrZG93bi1jaGFydC9pbXBhY3QtYXNzZXNzbWVudHMtaW5kaWNhdG9yLWJyZWFrZG93bi1jaGFydC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9zcmMvaW1wYWN0LWFzc2Vzc21lbnRzL2ltcGFjdC1hc3Nlc3NtZW50cy1pbmRpY2F0b3ItYnJlYWtkb3duLWNoYXJ0L2ltcGFjdC1hc3Nlc3NtZW50cy1pbmRpY2F0b3ItYnJlYWtkb3duLWNoYXJ0LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFFTCx1QkFBdUIsRUFDdkIsU0FBUyxFQUVULEtBQUssRUFFTCxTQUFTLEVBQ1QsUUFBUSxFQUNSLE1BQU0sRUFDTixNQUFNLEVBQ1AsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUFFLFlBQVksRUFBRSxRQUFRLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNwRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzlGLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDakMsT0FBTyxlQUFlLE1BQU0sMkJBQTJCLENBQUM7QUFDeEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQzlDLE9BQU8sRUFBbUQsUUFBUSxFQUFRLFlBQVksRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ3JILE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxFQUFFLE1BQU0scUJBQXFC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QyxLQUFLLENBQUMsS0FBSyxLQUFLLENBQUMsQ0FBQztRQUM5RCxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM5QixDQUFDO0lBRVMsWUFBWSxDQUFDLEVBQUUsTUFBTSxFQUFFLEVBQUUsS0FBSyxFQUFFLEVBQUU7UUFDMUMsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxLQUFLLENBQUMsQ0FBQztRQUNoRSxJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNoQyxDQUFDOzhHQS9PVSxpREFBaUQ7a0dBQWpELGlEQUFpRCxzUUNuRjlELG1yRUEwREE7OzJGRHlCYSxpREFBaUQ7a0JBTjdELFNBQVM7K0JBQ0UsaURBQWlELG1CQUcxQyx1QkFBdUIsQ0FBQyxNQUFNO2tMQUl2QyxRQUFRO3NCQURmLFNBQVM7dUJBQUMsT0FBTztnQkFPZCxnQkFBZ0I7c0JBRG5CLEtBQUs7Z0JBT0YsVUFBVTtzQkFEYixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQWZ0ZXJWaWV3SW5pdCxcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENvbXBvbmVudCxcbiAgRWxlbWVudFJlZixcbiAgSW5wdXQsXG4gIE5nWm9uZSxcbiAgVmlld0NoaWxkLFxuICBjb21wdXRlZCxcbiAgZWZmZWN0LFxuICBzaWduYWxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBEb21TYW5pdGl6ZXIgfSBmcm9tICdAYW5ndWxhci9wbGF0Zm9ybS1icm93c2VyJztcbmltcG9ydCB7IHRvT2JzZXJ2YWJsZSwgdG9TaWduYWwgfSBmcm9tICdAYW5ndWxhci9jb3JlL3J4anMtaW50ZXJvcCc7XG5pbXBvcnQgeyBmaWx0ZXIsIGdyb3VwQnksIG1hcCwgbWVyZ2VBbGwsIG1lcmdlTWFwLCB0YWtlLCB0YXAsIHRvQXJyYXkgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBDaGFydCB9IGZyb20gJ2NoYXJ0LmpzJztcbmltcG9ydCBDaGFydERhdGFMYWJlbHMgZnJvbSAnY2hhcnRqcy1wbHVnaW4tZGF0YWxhYmVscyc7XG5pbXBvcnQgeyBEYXRhU3RhdGUgfSBmcm9tICdAaGVzdGlhLWVhcnRoL2FwaSc7XG5pbXBvcnQgeyBJSW1wYWN0QXNzZXNzbWVudEpTT05MRCwgSW5kaWNhdG9yLCBJVGVybUpTT05MRCwgTm9kZVR5cGUsIFRlcm0sIFRlcm1UZXJtVHlwZSB9IGZyb20gJ0BoZXN0aWEtZWFydGgvc2NoZW1hJztcbmltcG9ydCB7IHRvUHJlY2lzaW9uLCB1bmlxdWUgfSBmcm9tICdAaGVzdGlhLWVhcnRoL3V0aWxzJztcbmltcG9ydCB7IG9mIH0gZnJvbSAncnhqcyc7XG5cbmltcG9ydCB7IG1hdGNoVGVybVR5cGUsIG1hdGNoVHlwZSB9IGZyb20gJy4uLy4uL3NlYXJjaC9zZWFyY2gubW9kZWwnO1xuaW1wb3J0IHsgSGVTZWFyY2hTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VhcmNoL3NlYXJjaC5zZXJ2aWNlJztcbmltcG9ydCB7IEhlTm9kZVNlcnZpY2UgfSBmcm9tICcuLi8uLi9ub2RlL25vZGUuc2VydmljZSc7XG5pbXBvcnQgeyBkaXN0aW5jdFVudGlsQ2hhbmdlZERlZXAgfSBmcm9tICcuLi8uLi9jb21tb24vcnhqcy11dGlscyc7XG5pbXBvcnQgeyBMZXZlbCwgcGFyc2VMaW5lcywgcGFyc2VNZXNzYWdlIH0gZnJvbSAnLi4vLi4vY29tbW9uL2xvZ3MtdXRpbHMnO1xuaW1wb3J0IHsgbGlzdENvbG9yIH0gZnJvbSAnLi4vLi4vY29tbW9uL2NvbG9yJztcblxuaW50ZXJmYWNlIElMb2cge1xuICBtb2RlbElkOiBzdHJpbmc7XG4gIGltcGFjdFRlcm1JZDogc3RyaW5nO1xuICBpbXBhY3RUZXJtVW5pdHM/OiBzdHJpbmc7XG4gIGJsYW5rTm9kZVRlcm1JZDogc3RyaW5nO1xuICBjb2VmZmljaWVudDogbnVtYmVyO1xuICB2YWx1ZTogbnVtYmVyO1xuICAvLyBzdG9yZSBhbGwgaW5kaWNhdG9ycyB3aXRoIGlucHV0c1xuICBpbnB1dHM/OiB7XG4gICAgbmFtZTogc3RyaW5nO1xuICAgIHZhbHVlOiBudW1iZXI7XG4gIH1bXTtcbiAgaW5wdXRzVmFsdWU/OiBudW1iZXI7XG59XG5cbmNvbnN0IHBhcnNlTG9nID0gKGRhdGE6IGFueSk6IElMb2cgPT4gKHtcbiAgbW9kZWxJZDogZGF0YS5tb2RlbCxcbiAgaW1wYWN0VGVybUlkOiBkYXRhWydrZXkvdGVybSddIHx8IGRhdGEudGVybSB8fCBkYXRhLmluZGljYXRvcixcbiAgYmxhbmtOb2RlVGVybUlkOiBkYXRhLm5vZGUsXG4gIGNvZWZmaWNpZW50OiArZGF0YS5jb2VmZmljaWVudCxcbiAgdmFsdWU6ICtkYXRhLnZhbHVlICogK2RhdGEuY29lZmZpY2llbnRcbn0pO1xuXG5jb25zdCBmaWx0ZXJUZXJtVHlwZXMgPSBbVGVybVRlcm1UeXBlLmVtaXNzaW9uLCBUZXJtVGVybVR5cGUuY2hhcmFjdGVyaXNlZEluZGljYXRvcl07XG5cbmNvbnN0IGNzdkhlYWRlcnMgPSBbXG4gICdJbXBhY3QnLFxuICAnSW1wYWN0IFVuaXQnLFxuICAnTWV0aG9kJyxcbiAgJ0VtaXNzaW9uJyxcbiAgJ1ZhbHVlJyxcbiAgJ0lucHV0cycsXG4gICdJbnB1dHMgdmFsdWUnLFxuICAnRnVuY3Rpb25hbCBVbml0J1xuXTtcblxuY29uc3QgbG9nVG9Dc3YgPSAobG9nczogSUxvZ1tdLCBpbXBhY3Q6IElJbXBhY3RBc3Nlc3NtZW50SlNPTkxEKSA9PlxuICBbXG4gICAgY3N2SGVhZGVycy5qb2luKCcsJyksXG4gICAgLi4ubG9nc1xuICAgICAgLnNvcnQoKGEsIGIpID0+IGEuaW1wYWN0VGVybUlkLmxvY2FsZUNvbXBhcmUoYi5pbXBhY3RUZXJtSWQpKVxuICAgICAgLmZsYXRNYXAoKHsgaW1wYWN0VGVybUlkLCBpbXBhY3RUZXJtVW5pdHMsIG1vZGVsSWQsIGJsYW5rTm9kZVRlcm1JZCwgdmFsdWUsIGlucHV0cyB9KSA9PiBbXG4gICAgICAgIFtpbXBhY3RUZXJtSWQsIGltcGFjdFRlcm1Vbml0cywgbW9kZWxJZCwgYmxhbmtOb2RlVGVybUlkLCB2YWx1ZSwgJycsICcnXSxcbiAgICAgICAgLi4uaW5wdXRzLm1hcCh2ID0+IFtpbXBhY3RUZXJtSWQsIGltcGFjdFRlcm1Vbml0cywgbW9kZWxJZCwgYmxhbmtOb2RlVGVybUlkLCAnJywgdi5uYW1lLCB2LnZhbHVlXSlcbiAgICAgIF0pXG4gICAgICAubWFwKHYgPT4gWy4uLnYsIGltcGFjdC5wcm9kdWN0Py50ZXJtPy51bml0c10uam9pbignLCcpKVxuICBdLmpvaW4oJ1xcbicpO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdoZS1pbXBhY3QtYXNzZXNzbWVudHMtaW5kaWNhdG9yLWJyZWFrZG93bi1jaGFydCcsXG4gIHRlbXBsYXRlVXJsOiAnLi9pbXBhY3QtYXNzZXNzbWVudHMtaW5kaWNhdG9yLWJyZWFrZG93bi1jaGFydC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2ltcGFjdC1hc3Nlc3NtZW50cy1pbmRpY2F0b3ItYnJlYWtkb3duLWNoYXJ0LmNvbXBvbmVudC5zY3NzJ10sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoXG59KVxuZXhwb3J0IGNsYXNzIEltcGFjdEFzc2Vzc21lbnRzSW5kaWNhdG9yQnJlYWtkb3duQ2hhcnRDb21wb25lbnQgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0IHtcbiAgQFZpZXdDaGlsZCgnY2hhcnQnKVxuICBwcml2YXRlIGNoYXJ0UmVmPzogRWxlbWVudFJlZjtcbiAgcHJpdmF0ZSBjaGFydDogYW55O1xuXG4gIHByaXZhdGUgX2ltcGFjdEFzc2Vzc21lbnQgPSBzaWduYWwodW5kZWZpbmVkIGFzIElJbXBhY3RBc3Nlc3NtZW50SlNPTkxEKTtcbiAgcHJpdmF0ZSBpbXBhY3RBc3Nlc3NtZW50JCA9IHRvT2JzZXJ2YWJsZSh0aGlzLl9pbXBhY3RBc3Nlc3NtZW50KTtcbiAgQElucHV0KClcbiAgc2V0IGltcGFjdEFzc2Vzc21lbnQodmFsdWU6IElJbXBhY3RBc3Nlc3NtZW50SlNPTkxEKSB7XG4gICAgdGhpcy5faW1wYWN0QXNzZXNzbWVudC5zZXQodmFsdWUpO1xuICB9XG5cbiAgcHJpdmF0ZSBfaW5kaWNhdG9ycyA9IHNpZ25hbChbXSBhcyBJbmRpY2F0b3JbXSk7XG4gIEBJbnB1dCgpXG4gIHNldCBpbmRpY2F0b3JzKHZhbHVlOiBJbmRpY2F0b3JbXSkge1xuICAgIHRoaXMuX2luZGljYXRvcnMuc2V0KHZhbHVlKTtcbiAgfVxuXG4gIHByaXZhdGUgYWxsTG9ncyA9IHNpZ25hbChbXSBhcyBJTG9nW10pO1xuICBwcml2YXRlIGxvZ3MgPSBjb21wdXRlZCgoKSA9PlxuICAgIHRoaXMuYWxsTG9ncygpXG4gICAgICAuZmlsdGVyKFxuICAgICAgICAoeyBpbXBhY3RUZXJtSWQsIG1vZGVsSWQgfSkgPT5cbiAgICAgICAgICBpbXBhY3RUZXJtSWQgPT09IHRoaXMuc2VsZWN0ZWRUZXJtKCk/LlsnQGlkJ10gJiZcbiAgICAgICAgICAoIXRoaXMuc2VsZWN0ZWRNZXRob2QoKSB8fCBtb2RlbElkID09PSB0aGlzLnNlbGVjdGVkTWV0aG9kKCk/LlsnQGlkJ10pXG4gICAgICApXG4gICAgICAuc29ydCgoYSwgYikgPT4gYi52YWx1ZSAtIGEudmFsdWUpXG4gICk7XG5cbiAgcHJpdmF0ZSBlbWlzc2lvbnMgPSB0b1NpZ25hbChcbiAgICB0aGlzLnNlYXJjaFNlcnZpY2VcbiAgICAgIC5zZWFyY2gkPElUZXJtSlNPTkxELCBOb2RlVHlwZS5UZXJtPih7XG4gICAgICAgIGZpZWxkczogWydAdHlwZScsICdAaWQnLCAnbmFtZSddLFxuICAgICAgICBsaW1pdDogMTAwMCxcbiAgICAgICAgcXVlcnk6IHtcbiAgICAgICAgICBib29sOiB7XG4gICAgICAgICAgICBtdXN0OiBbbWF0Y2hUeXBlKE5vZGVUeXBlLlRlcm0pXSxcbiAgICAgICAgICAgIHNob3VsZDogZmlsdGVyVGVybVR5cGVzLm1hcCh0ZXJtVHlwZSA9PiBtYXRjaFRlcm1UeXBlKHRlcm1UeXBlKSksXG4gICAgICAgICAgICBtaW5pbXVtX3Nob3VsZF9tYXRjaDogMVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSlcbiAgICAgIC5waXBlKG1hcCgoeyByZXN1bHRzIH0pID0+IHJlc3VsdHMpKVxuICApO1xuXG4gIHByb3RlY3RlZCBsb2FkaW5nID0gc2lnbmFsKHRydWUpO1xuXG4gIHByb3RlY3RlZCBzZWxlY3RlZFRlcm0gPSBzaWduYWwodW5kZWZpbmVkIGFzIFRlcm0pO1xuICBwcm90ZWN0ZWQgdGVybXMgPSBjb21wdXRlZCgoKSA9PiB1bmlxdWUoKHRoaXMuX2luZGljYXRvcnMoKSB8fCBbXSkubWFwKCh7IHRlcm0gfSkgPT4gdGVybSEpLmZpbHRlcihCb29sZWFuKSkpO1xuXG4gIHByb3RlY3RlZCBzZWxlY3RlZE1ldGhvZCA9IHNpZ25hbCh1bmRlZmluZWQgYXMgVGVybSk7XG4gIHByb3RlY3RlZCBtZXRob2RzID0gY29tcHV0ZWQoKCkgPT5cbiAgICB1bmlxdWUoKHRoaXMuX2luZGljYXRvcnMoKSB8fCBbXSkubWFwKCh7IG1ldGhvZE1vZGVsIH0pID0+IG1ldGhvZE1vZGVsISkuZmlsdGVyKEJvb2xlYW4pKVxuICApO1xuXG4gIHByaXZhdGUgaW1wYWN0cyA9IGNvbXB1dGVkKCgpID0+IFtcbiAgICAuLi4odGhpcy5faW1wYWN0QXNzZXNzbWVudCgpPy5pbXBhY3RzIHx8IFtdKSxcbiAgICAuLi4odGhpcy5faW1wYWN0QXNzZXNzbWVudCgpPy5lbmRwb2ludHMgfHwgW10pXG4gIF0pO1xuICBwcm90ZWN0ZWQgbm9EYXRhID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5sb2dzKCk/Lmxlbmd0aCA9PT0gMCk7XG5cbiAgcHJvdGVjdGVkIGNzdkNvbnRlbnQgPSBjb21wdXRlZCgoKSA9PlxuICAgIHRoaXMuZG9tU2FuaXRpemVyLmJ5cGFzc1NlY3VyaXR5VHJ1c3RSZXNvdXJjZVVybChcbiAgICAgIGBkYXRhOnRleHQvaHRtbDtjaGFyc2V0PXV0Zi04LCR7ZW5jb2RlVVJJQ29tcG9uZW50KGxvZ1RvQ3N2KHRoaXMubG9ncygpLCB0aGlzLl9pbXBhY3RBc3Nlc3NtZW50KCkpKX1gXG4gICAgKVxuICApO1xuICBwcml2YXRlIGlkID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5faW1wYWN0QXNzZXNzbWVudCgpPy5bJ0BpZCddIHx8ICh0aGlzLl9pbXBhY3RBc3Nlc3NtZW50KCkgYXMgYW55KT8uaWQpO1xuICBwcm90ZWN0ZWQgZG93bmxvYWRGaWxlbmFtZSA9IGNvbXB1dGVkKCgpID0+IGAke3RoaXMuaWQoKX0tbG9ncy5jc3ZgKTtcblxuICBwcml2YXRlIHRvdGFsID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5sb2dzKCkucmVkdWNlKChwcmV2LCBjdXJyKSA9PiBwcmV2ICsgY3Vyci52YWx1ZSwgMCkpO1xuICBwcml2YXRlIGxhYmVscyA9IGNvbXB1dGVkKCgpID0+XG4gICAgdGhpcy5sb2dzKCkubWFwKFxuICAgICAgKHsgYmxhbmtOb2RlVGVybUlkIH0pID0+IHRoaXMuZW1pc3Npb25zKCk/LmZpbmQodiA9PiB2WydAaWQnXSA9PT0gYmxhbmtOb2RlVGVybUlkKT8ubmFtZSB8fCBibGFua05vZGVUZXJtSWRcbiAgICApXG4gICk7XG4gIHByaXZhdGUgZGF0YXNldHMgPSBjb21wdXRlZCgoKSA9PiBbXG4gICAge1xuICAgICAgbGFiZWw6IHRoaXMuc2VsZWN0ZWRUZXJtKCk/Lm5hbWUgPz8gJycsXG4gICAgICBkYXRhOiB0aGlzLmxvZ3MoKS5tYXAoKHsgdmFsdWUgfSkgPT4gdmFsdWUpLFxuICAgICAgYmFja2dyb3VuZENvbG9yOiB0aGlzLmxvZ3MoKS5tYXAobGlzdENvbG9yKSxcbiAgICAgIGJvcmRlckNvbG9yOiB0aGlzLmxvZ3MoKS5tYXAobGlzdENvbG9yKVxuICAgIH1cbiAgXSk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBuZ1pvbmU6IE5nWm9uZSxcbiAgICBwcml2YXRlIGRvbVNhbml0aXplcjogRG9tU2FuaXRpemVyLFxuICAgIHByaXZhdGUgc2VhcmNoU2VydmljZTogSGVTZWFyY2hTZXJ2aWNlLFxuICAgIHByaXZhdGUgbm9kZVNlcnZpY2U6IEhlTm9kZVNlcnZpY2VcbiAgKSB7XG4gICAgdGhpcy5pbXBhY3RBc3Nlc3NtZW50JFxuICAgICAgLnBpcGUoXG4gICAgICAgIGZpbHRlcih2ID0+ICEhdiksXG4gICAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkRGVlcCgpLFxuICAgICAgICB0YWtlKDEpLFxuICAgICAgICB0YXAoKCkgPT4gdGhpcy5sb2FkaW5nLnNldCh0cnVlKSksXG4gICAgICAgIG1lcmdlTWFwKG5vZGUgPT4gKG5vZGUgPyB0aGlzLm5vZGVTZXJ2aWNlLmdldExvZyh7IC4uLm5vZGUsIGRhdGFTdGF0ZTogRGF0YVN0YXRlLnJlY2FsY3VsYXRlZCB9KSA6IG9mKCcnKSkpLFxuICAgICAgICBtYXAodmFsdWUgPT4gKHZhbHVlID8gcGFyc2VMaW5lcyh2YWx1ZSkgOiBbXSkpLFxuICAgICAgICBtZXJnZUFsbCgpLFxuICAgICAgICBmaWx0ZXIoKHsgZGF0YSB9KSA9PiBkYXRhLmxvZ2dlciA9PT0gJ2hlc3RpYV9lYXJ0aC5tb2RlbHMnICYmIGRhdGEubGV2ZWwgPT09IExldmVsLmRlYnVnKSxcbiAgICAgICAgZmlsdGVyKCh7IGRhdGE6IHsgbWVzc2FnZSB9IH0pID0+ICEhbWVzc2FnZSksXG4gICAgICAgIG1hcCgoeyBkYXRhOiB7IG1lc3NhZ2UgfSB9KSA9PiBwYXJzZU1lc3NhZ2UobWVzc2FnZSkpLFxuICAgICAgICBmaWx0ZXIobWVzc2FnZSA9PiAnbm9kZScgaW4gbWVzc2FnZSksXG4gICAgICAgIG1hcChwYXJzZUxvZyksXG4gICAgICAgIGZpbHRlcihsb2cgPT4gISFsb2cuaW1wYWN0VGVybUlkICYmICEhbG9nLmJsYW5rTm9kZVRlcm1JZCAmJiAhaXNOYU4obG9nLnZhbHVlKSAmJiBsb2cudmFsdWUgPiAwKSxcbiAgICAgICAgZ3JvdXBCeShsb2cgPT4gW2xvZy5pbXBhY3RUZXJtSWQsIGxvZy5ibGFua05vZGVUZXJtSWQsIGxvZy5tb2RlbElkXS5qb2luKCcvJykpLFxuICAgICAgICBtZXJnZU1hcChncm91cCA9PiBncm91cC5waXBlKHRvQXJyYXkoKSkpLFxuICAgICAgICBtYXAoKHZhbHVlczogSUxvZ1tdKSA9PiB7XG4gICAgICAgICAgY29uc3QgbG9nID0gdmFsdWVzWzBdO1xuICAgICAgICAgIGNvbnN0IHRvdGFsID0gdmFsdWVzLnJlZHVjZSgocHJldiwgY3VycikgPT4gcHJldiArIGN1cnIudmFsdWUsIDApO1xuICAgICAgICAgIGNvbnN0IGJsYW5rTm9kZXMgPSBbXG4gICAgICAgICAgICAuLi4odGhpcy5faW1wYWN0QXNzZXNzbWVudCgpPy5lbWlzc2lvbnNSZXNvdXJjZVVzZSA/PyBbXSksXG4gICAgICAgICAgICAuLi4odGhpcy5faW1wYWN0QXNzZXNzbWVudCgpPy5pbXBhY3RzID8/IFtdKVxuICAgICAgICAgIF0uZmlsdGVyKHYgPT4gdi50ZXJtWydAaWQnXSA9PT0gbG9nLmJsYW5rTm9kZVRlcm1JZCk7XG5cbiAgICAgICAgICBjb25zdCBpbnB1dHMgPSBibGFua05vZGVzXG4gICAgICAgICAgICAuZmlsdGVyKHYgPT4gdi5pbnB1dHM/Lmxlbmd0aClcbiAgICAgICAgICAgIC5tYXAodiA9PiAoeyBuYW1lOiB2LmlucHV0cy5tYXAoaSA9PiBpWydAaWQnXSkuam9pbignOycpLCB2YWx1ZTogdi52YWx1ZSAqIGxvZy5jb2VmZmljaWVudCB9KSk7XG4gICAgICAgICAgY29uc3QgaW5wdXRzVmFsdWUgPSBpbnB1dHMucmVkdWNlKChwcmV2LCBjdXJyKSA9PiBwcmV2ICsgY3Vyci52YWx1ZSwgMCk7XG5cbiAgICAgICAgICBjb25zdCBpbXBhY3QgPSB0aGlzLmltcGFjdHMoKS5maW5kKHYgPT4gdi50ZXJtWydAaWQnXSA9PT0gbG9nLmltcGFjdFRlcm1JZCk7XG5cbiAgICAgICAgICAvLyBsb2dzIG1pZ2h0IGV4aXN0IGJ1dCBpbXBhY3Qgd2FzIG5vdCBhZGRlZCA9PiBza2lwIGxvZ3NcbiAgICAgICAgICByZXR1cm4gaW1wYWN0XG4gICAgICAgICAgICA/IHtcbiAgICAgICAgICAgICAgICAuLi5sb2csXG4gICAgICAgICAgICAgICAgaW1wYWN0VGVybVVuaXRzOiBpbXBhY3QudGVybT8udW5pdHMsXG4gICAgICAgICAgICAgICAgdmFsdWU6IHRvdGFsLFxuICAgICAgICAgICAgICAgIGlucHV0cyxcbiAgICAgICAgICAgICAgICBpbnB1dHNWYWx1ZVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA6IG51bGw7XG4gICAgICAgIH0pLFxuICAgICAgICBmaWx0ZXIobG9nID0+ICEhbG9nKSxcbiAgICAgICAgdG9BcnJheSgpLFxuICAgICAgICB0YXAoKCkgPT4gdGhpcy5sb2FkaW5nLnNldChmYWxzZSkpXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKChsb2dzOiBJTG9nW10pID0+IHtcbiAgICAgICAgdGhpcy5hbGxMb2dzLnNldChsb2dzKTtcbiAgICAgICAgdGhpcy5pbml0Q2hhcnQoKTtcbiAgICAgIH0pO1xuXG4gICAgZWZmZWN0KFxuICAgICAgKCkgPT4ge1xuICAgICAgICAvLyBtYWtlIHN1cmUgc2VsZWN0ZWQgdGVybSBleGlzdHNcbiAgICAgICAgY29uc3QgdGVybXMgPSB0aGlzLnRlcm1zKCk7XG4gICAgICAgIGNvbnN0IHNlbGVjdGVkVGVybUlkID0gdGhpcy5zZWxlY3RlZFRlcm0oKT8uWydAaWQnXTtcbiAgICAgICAgaWYgKCFzZWxlY3RlZFRlcm1JZCB8fCAhdGVybXMuZmluZCh0ZXJtID0+IHRlcm1bJ0BpZCddID09PSBzZWxlY3RlZFRlcm1JZCkpIHtcbiAgICAgICAgICB0aGlzLnNlbGVjdGVkVGVybS5zZXQodGVybXNbMF0pO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuaW5pdENoYXJ0KCk7XG4gICAgICB9LFxuICAgICAgeyBhbGxvd1NpZ25hbFdyaXRlczogdHJ1ZSB9XG4gICAgKTtcblxuICAgIGVmZmVjdCgoKSA9PiB7XG4gICAgICBpZiAodGhpcy5kYXRhc2V0cygpLmxlbmd0aCkge1xuICAgICAgICB0aGlzLmluaXRDaGFydCgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgbmdBZnRlclZpZXdJbml0KCkge1xuICAgIHRoaXMuaW5pdENoYXJ0KCk7XG4gIH1cblxuICBwcml2YXRlIGluaXRDaGFydCgpIHtcbiAgICBpZiAoIXRoaXMuY2hhcnRSZWYpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBsYWJlbHMgPSB0aGlzLmxhYmVscygpO1xuICAgIGNvbnN0IGRhdGFzZXRzID0gdGhpcy5kYXRhc2V0cygpO1xuICAgIGNvbnN0IHRvdGFsID0gdGhpcy50b3RhbCgpO1xuXG4gICAgdGhpcy5uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgaWYgKHRoaXMuY2hhcnQpIHtcbiAgICAgICAgdGhpcy5jaGFydC5kZXN0cm95KCk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuY2hhcnQgPSBuZXcgQ2hhcnQodGhpcy5jaGFydFJlZj8ubmF0aXZlRWxlbWVudCwge1xuICAgICAgICB0eXBlOiAnaG9yaXpvbnRhbEJhcicsXG4gICAgICAgIGRhdGE6IHtcbiAgICAgICAgICBsYWJlbHMsXG4gICAgICAgICAgZGF0YXNldHNcbiAgICAgICAgfSxcbiAgICAgICAgcGx1Z2luczogW0NoYXJ0RGF0YUxhYmVsc10sXG4gICAgICAgIG9wdGlvbnM6IHtcbiAgICAgICAgICBwbHVnaW5zOiB7XG4gICAgICAgICAgICBkYXRhbGFiZWxzOiB7XG4gICAgICAgICAgICAgIGNvbG9yOiAnYmxhY2snLFxuICAgICAgICAgICAgICBmb3JtYXR0ZXI6IHZhbHVlID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCByYXRpbyA9IHRvUHJlY2lzaW9uKCh2YWx1ZSAqIDEwMCkgLyB0b3RhbCwgMik7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlID4gMCA/IGAke3RvUHJlY2lzaW9uKHZhbHVlLCAzKX0gKCR7cmF0aW99JSlgIDogJyc7XG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIGFsaWduOiAnZW5kJ1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgICAgcmVzcG9uc2l2ZTogdHJ1ZSxcbiAgICAgICAgICBtYWludGFpbkFzcGVjdFJhdGlvOiBmYWxzZSxcbiAgICAgICAgICBsZWdlbmQ6IHtcbiAgICAgICAgICAgIGRpc3BsYXk6IGZhbHNlXG4gICAgICAgICAgfSxcbiAgICAgICAgICB0b29sdGlwczoge1xuICAgICAgICAgICAgZW5hYmxlZDogZmFsc2UsXG4gICAgICAgICAgICBjYWxsYmFja3M6IHtcbiAgICAgICAgICAgICAgdGl0bGU6ICh0b29sdGlwSXRlbXMsIGRhdGEpID0+IGRhdGEuZGF0YXNldHMhW3Rvb2x0aXBJdGVtc1swXS5kYXRhc2V0SW5kZXghXT8ubGFiZWwgfHwgJycsXG4gICAgICAgICAgICAgIGxhYmVsOiB0b29sdGlwSXRlbSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSArKHRvb2x0aXBJdGVtLnZhbHVlIHx8ICcwJyk7XG4gICAgICAgICAgICAgICAgY29uc3QgcmF0aW8gPSB0b1ByZWNpc2lvbigodmFsdWUgKiAxMDApIC8gdG90YWwsIDIpO1xuICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZSA+IDAgPyBgJHt0b1ByZWNpc2lvbih2YWx1ZSwgMyl9ICgke3JhdGlvfSUpYCA6ICcnO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgICBzY2FsZXM6IHtcbiAgICAgICAgICAgIHhBeGVzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBkaXNwbGF5OiB0cnVlXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICB5QXhlczogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcG9zaXRpb246ICdsZWZ0J1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBdXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBzZWxlY3RUZXJtKHsgdGFyZ2V0OiB7IHZhbHVlIH0gfSkge1xuICAgIGNvbnN0IHRlcm0gPSB0aGlzLnRlcm1zKCkuZmluZCh0ZXJtID0+IHRlcm1bJ0BpZCddID09PSB2YWx1ZSk7XG4gICAgdGhpcy5zZWxlY3RlZFRlcm0uc2V0KHRlcm0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIHNlbGVjdE1ldGhvZCh7IHRhcmdldDogeyB2YWx1ZSB9IH0pIHtcbiAgICBjb25zdCB0ZXJtID0gdGhpcy5tZXRob2RzKCkuZmluZCh0ZXJtID0+IHRlcm1bJ0BpZCddID09PSB2YWx1ZSk7XG4gICAgdGhpcy5zZWxlY3RlZE1ldGhvZC5zZXQodGVybSk7XG4gIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJwLTNcIiAqbmdJZj1cIiFsb2FkaW5nKCk7IGVsc2UgbG9hZGVyXCIgW2NsYXNzLmlzLWhpZGRlbl09XCIhdGVybXMoKT8ubGVuZ3RoXCI+XG4gIDxkaXYgY2xhc3M9XCJjb2x1bW5zXCI+XG4gICAgPGRpdiBjbGFzcz1cImNvbHVtblwiPlxuICAgICAgPGRpdiBjbGFzcz1cImZpZWxkIGhhcy1hZGRvbnNcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNvbnRyb2xcIj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImJ1dHRvbiBpcy1zbWFsbCBpcy1zdGF0aWMgaXMtc2Vjb25kYXJ5XCI+U2VsZWN0IGFuIEluZGljYXRvcjwvc3Bhbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjb250cm9sIGlzLWV4cGFuZGVkXCIgKm5nSWY9XCJ0ZXJtcygpPy5sZW5ndGhcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VsZWN0IGlzLWZ1bGx3aWR0aCBpcy1zbWFsbCBpcy1zZWNvbmRhcnlcIj5cbiAgICAgICAgICAgIDxzZWxlY3QgKGNoYW5nZSk9XCJzZWxlY3RUZXJtKCRldmVudClcIj5cbiAgICAgICAgICAgICAgPG9wdGlvbiAqbmdGb3I9XCJsZXQgdGVybSBvZiB0ZXJtcygpXCIgW3ZhbHVlXT1cInRlcm1bJ0BpZCddXCI+e3sgdGVybS5uYW1lIH19ICh7eyB0ZXJtLnVuaXRzIH19KTwvb3B0aW9uPlxuICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY29udHJvbCBpcy1leHBhbmRlZFwiICpuZ0lmPVwibWV0aG9kcygpPy5sZW5ndGhcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VsZWN0IGlzLWZ1bGx3aWR0aCBpcy1zbWFsbCBpcy1zZWNvbmRhcnlcIj5cbiAgICAgICAgICAgIDxzZWxlY3QgKGNoYW5nZSk9XCJzZWxlY3RNZXRob2QoJGV2ZW50KVwiPlxuICAgICAgICAgICAgICA8b3B0aW9uIFtuZ1ZhbHVlXT1cInVuZGVmaW5lZFwiPkZpbHRlciBNb2RlbDwvb3B0aW9uPlxuICAgICAgICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCB0ZXJtIG9mIG1ldGhvZHMoKVwiIFt2YWx1ZV09XCJ0ZXJtWydAaWQnXVwiPnt7IHRlcm0ubmFtZSB9fTwvb3B0aW9uPlxuICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cImNvbHVtbiBpcy1uYXJyb3dcIj5cbiAgICAgIDxhXG4gICAgICAgIGNsYXNzPVwiYnV0dG9uIGlzLWdob3N0IGlzLXNtYWxsXCJcbiAgICAgICAgW2hyZWZdPVwiY3N2Q29udGVudCgpXCJcbiAgICAgICAgW2Rvd25sb2FkXT1cImRvd25sb2FkRmlsZW5hbWUoKVwiXG4gICAgICAgIG5iZ1Rvb2x0aXA9XCJEb3dubG9hZCBhcyBDU1ZcIlxuICAgICAgICBwbGFjZW1lbnQ9XCJib3R0b21cIj5cbiAgICAgICAgPGZhLWljb24gaWNvbj1cImRvd25sb2FkXCI+PC9mYS1pY29uPlxuICAgICAgPC9hPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cblxuICA8cCBjbGFzcz1cImlzLXNpemUtN1wiICpuZ0lmPVwiIXNlbGVjdGVkTWV0aG9kKClcIj5cbiAgICA8aT5TZWxlY3RpbmcgYSBNb2RlbCBpcyByZWNvbW1lbmRlZCB0byBhdm9pZCBkdXBsaWNhdGVkIGVudHJpZXMuPC9pPlxuICA8L3A+XG48L2Rpdj5cblxuPGRpdiBjbGFzcz1cImlzLW10LTFcIj5cbiAgPHAgKm5nSWY9XCIhbG9hZGluZygpICYmIG5vRGF0YSgpXCIgY2xhc3M9XCJoYXMtdGV4dC1jZW50ZXJlZFwiPlxuICAgIDxzcGFuPk5vIGJyZWFrZG93biBhdmFpbGFibGUgZm9yPC9zcGFuPlxuICAgIDxzcGFuIGNsYXNzPVwiaXMtcGwtMVwiICpuZ0lmPVwic2VsZWN0ZWRUZXJtKClcIj57eyBzZWxlY3RlZFRlcm0oKS5uYW1lIH19PC9zcGFuPlxuICAgIDxzcGFuIGNsYXNzPVwiaXMtcGwtMVwiICpuZ0lmPVwic2VsZWN0ZWRNZXRob2QoKVwiPih7eyBzZWxlY3RlZE1ldGhvZCgpLm5hbWUgfX0pPC9zcGFuPlxuICAgIDxzcGFuPi48L3NwYW4+XG4gIDwvcD5cbiAgPGRpdiBjbGFzcz1cImNoYXJ0LWNvbnRhaW5lciBoLTEwMFwiPlxuICAgIDxjYW52YXMgI2NoYXJ0PjwvY2FudmFzPlxuICA8L2Rpdj5cbjwvZGl2PlxuXG48bmctdGVtcGxhdGUgI2xvYWRlcj5cbiAgPGRpdiBjbGFzcz1cImhhcy10ZXh0LWNlbnRlciBweS0zXCI+XG4gICAgPGZhLWljb24gaWNvbj1cInNwaW5uZXJcIiBbcHVsc2VdPVwidHJ1ZVwiIHNpemU9XCJsZ1wiPjwvZmEtaWNvbj5cbiAgPC9kaXY+XG48L25nLXRlbXBsYXRlPlxuIl19