raain-app 1.6.28 → 1.6.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.6.30] - 2026-02-24
11
+
12
+ ### Changed
13
+
14
+ - [RAD-162] Refactored cumulative-selector, raain-compare-stack, raain-details and raain-map components
15
+
10
16
  ## [1.6.28] - 2026-02-02
11
17
 
12
18
  ### Fixed
@@ -38,6 +38,8 @@ export class CumulativeSelectorComponent {
38
38
  const response = (await this.profileService.getCumulativePeriods(this.rainId, {
39
39
  provider: this.provider,
40
40
  forced: this.isAdmin,
41
+ periodBegin: this.currentPeriodBegin.toISOString(),
42
+ periodEnd: this.currentPeriodEnd.toISOString(),
41
43
  }));
42
44
  // Filter for existing custom cumulatives (window > 0)
43
45
  this.availablePeriods = response.periods.filter((p) => p.windowInMinutes > 0);
@@ -53,32 +55,22 @@ export class CumulativeSelectorComponent {
53
55
  this.cdr.markForCheck();
54
56
  }
55
57
  calculateCoverage() {
56
- if (!this.baseCumulatives) {
58
+ if (!this.baseCumulatives || !this.baseCumulatives.count) {
57
59
  this.coveragePercent = 0;
58
60
  this.canCreateNew = false;
59
61
  return;
60
62
  }
61
- const baseBegin = new Date(this.baseCumulatives.periodBegin);
62
- const baseEnd = new Date(this.baseCumulatives.periodEnd);
63
- // Check if current period is within base coverage
64
- const currentInRange = this.currentPeriodBegin >= baseBegin && this.currentPeriodEnd <= baseEnd;
65
- if (!currentInRange) {
66
- this.coveragePercent = 0;
67
- this.canCreateNew = false;
68
- return;
69
- }
70
- // Calculate expected number of base cumulatives needed
71
- const expectedCount = Math.ceil(this.currentWindowMinutes / this.timeStepInMinutes);
72
- // Check if enough base cumulatives exist
73
- // We assume coverage is complete if count >= expected (simplified check)
63
+ // Calculate expected number of base cumulatives (always 5-min granularity)
64
+ const baseTimeStep = 5;
65
+ const expectedCount = Math.ceil(this.currentWindowMinutes / baseTimeStep);
74
66
  if (this.baseCumulatives.count >= expectedCount) {
75
67
  this.coveragePercent = 100;
76
- this.canCreateNew = true;
77
68
  }
78
69
  else {
79
70
  this.coveragePercent = Math.round((this.baseCumulatives.count / expectedCount) * 100);
80
- this.canCreateNew = this.coveragePercent >= 100;
81
71
  }
72
+ // Allow creation as long as some base data exists
73
+ this.canCreateNew = this.coveragePercent > 0;
82
74
  }
83
75
  selectPeriod(period) {
84
76
  this.periodSelected.emit({
@@ -88,7 +80,7 @@ export class CumulativeSelectorComponent {
88
80
  });
89
81
  }
90
82
  async toggleExpand(period) {
91
- const key = `${period.windowInMinutes}-${period.provider}`;
83
+ const key = `${period.windowInMinutes}`;
92
84
  if (this.expandedPeriods.has(key)) {
93
85
  this.expandedPeriods.delete(key);
94
86
  this.cdr.markForCheck();
@@ -124,13 +116,13 @@ export class CumulativeSelectorComponent {
124
116
  });
125
117
  }
126
118
  isExpanded(period) {
127
- return this.expandedPeriods.has(`${period.windowInMinutes}-${period.provider}`);
119
+ return this.expandedPeriods.has(`${period.windowInMinutes}`);
128
120
  }
129
121
  isLoadingExpanded(period) {
130
- return this.loadingExpanded.has(`${period.windowInMinutes}-${period.provider}`);
122
+ return this.loadingExpanded.has(`${period.windowInMinutes}`);
131
123
  }
132
124
  getExpandedItems(period) {
133
- return this.expandedPeriods.get(`${period.windowInMinutes}-${period.provider}`) || [];
125
+ return this.expandedPeriods.get(`${period.windowInMinutes}`) || [];
134
126
  }
135
127
  getItemPeriodBegin(item) {
136
128
  const endDate = new Date(item.date);
@@ -183,7 +175,9 @@ export class CumulativeSelectorComponent {
183
175
  try {
184
176
  const progress = await this.profileService.getRainProgress(this.rainId);
185
177
  if (progress === 0) {
186
- // Queue is empty, check if cumulative exists (admin sees all cumulatives)
178
+ // Trigger background fetch from raain-ground via timeframeCumulative
179
+ await this.profileService.getRainTimeframe(this.rainId, this.currentPeriodBegin, this.currentPeriodEnd, this.isAdmin, this.provider, this.timeStepInMinutes, this.currentWindowMinutes);
180
+ // Check if cumulative now exists (admin sees all cumulatives)
187
181
  const response = (await this.profileService.getCumulativePeriods(this.rainId, {
188
182
  provider: this.provider,
189
183
  windowInMinutes: this.currentWindowMinutes,
@@ -226,10 +220,10 @@ export class CumulativeSelectorComponent {
226
220
  }
227
221
  }
228
222
  CumulativeSelectorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CumulativeSelectorComponent, deps: [{ token: i1.ProfileService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
229
- CumulativeSelectorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: CumulativeSelectorComponent, selector: "cumulative-selector", inputs: { rainId: "rainId", currentPeriodBegin: "currentPeriodBegin", currentPeriodEnd: "currentPeriodEnd", provider: "provider", timeStepInMinutes: "timeStepInMinutes", isAdmin: "isAdmin" }, outputs: { periodSelected: "periodSelected", cancelled: "cancelled" }, ngImport: i0, template: "<div class=\"cumulative-selector-overlay\">\n <div class=\"cumulative-selector-modal\">\n <div class=\"modal-header\">\n <h2>Select Cumulative Period</h2>\n <ion-button fill=\"clear\" (click)=\"cancel()\">\n <ion-icon name=\"close\"></ion-icon>\n </ion-button>\n </div>\n\n <div class=\"modal-content\">\n <!-- Loading state -->\n <div *ngIf=\"loading\" class=\"loading-state\">\n <ion-spinner name=\"crescent\"></ion-spinner>\n <p>Loading available periods...</p>\n </div>\n\n <!-- Error message -->\n <div *ngIf=\"errorMessage\" class=\"error-message\">\n <ion-icon name=\"warning-outline\"></ion-icon>\n <span>{{ errorMessage }}</span>\n </div>\n\n <!-- Available periods list -->\n <div *ngIf=\"!loading && availablePeriods.length > 0\" class=\"periods-section\">\n <h3>Available Cumulative Periods</h3>\n <ion-list>\n <ng-container *ngFor=\"let period of availablePeriods\">\n <!-- Period header (click to expand) -->\n <ion-item button (click)=\"toggleExpand(period)\" [disabled]=\"creating\">\n <ion-icon [name]=\"isExpanded(period) ? 'chevron-down' : 'chevron-forward'\" slot=\"start\"></ion-icon>\n <ion-label>\n <h2>{{ formatWindow(period.windowInMinutes) }}</h2>\n <p>{{ formatPeriod(period) }}</p>\n <p class=\"count-info\">{{ period.count }} cumulative(s) - click to expand</p>\n </ion-label>\n </ion-item>\n\n <!-- Expanded: individual cumulatives -->\n <div *ngIf=\"isExpanded(period)\" class=\"expanded-items\">\n <ion-spinner *ngIf=\"isLoadingExpanded(period)\" name=\"crescent\"></ion-spinner>\n <ion-list *ngIf=\"!isLoadingExpanded(period)\" class=\"nested-list\">\n <ion-item *ngFor=\"let item of getExpandedItems(period)\"\n button\n (click)=\"selectIndividualCumulative(item)\"\n class=\"nested-item\"\n [disabled]=\"creating\">\n <ion-icon name=\"time-outline\" slot=\"start\"></ion-icon>\n <ion-label>\n <h3>{{ getItemPeriodBegin(item) | date:'HH:mm' }} - {{ item.date | date:'HH:mm' }}</h3>\n </ion-label>\n <ion-icon name=\"chevron-forward\" slot=\"end\"></ion-icon>\n </ion-item>\n <ion-item *ngIf=\"getExpandedItems(period).length === 0\" class=\"nested-item\">\n <ion-label>\n <p>No individual cumulatives found</p>\n </ion-label>\n </ion-item>\n </ion-list>\n </div>\n </ng-container>\n </ion-list>\n </div>\n\n <!-- No periods available -->\n <div *ngIf=\"!loading && availablePeriods.length === 0\" class=\"no-periods\">\n <ion-icon name=\"information-circle-outline\"></ion-icon>\n <p>No cumulative periods available yet.</p>\n </div>\n\n <!-- Create new section (admin only) -->\n <div *ngIf=\"!loading && isAdmin\" class=\"create-section\">\n <h3>Create New Cumulative</h3>\n <div class=\"create-info\">\n <p>\n <strong>Period:</strong>\n {{ currentPeriodBegin?.toLocaleString() }} \u2192 {{ currentPeriodEnd?.toLocaleString() }}\n </p>\n <p>\n <strong>Window:</strong> {{ formatWindow(currentWindowMinutes) }}\n </p>\n <p *ngIf=\"baseCumulatives\" class=\"coverage-info\"\n [class.coverage-ok]=\"coveragePercent >= 100\"\n [class.coverage-warn]=\"coveragePercent > 0 && coveragePercent < 100\"\n [class.coverage-error]=\"coveragePercent === 0\">\n <ion-icon [name]=\"coveragePercent >= 100 ? 'checkmark-circle' : 'alert-circle'\"></ion-icon>\n Base data coverage: {{ coveragePercent }}%\n </p>\n <p *ngIf=\"!baseCumulatives\" class=\"coverage-error\">\n <ion-icon name=\"alert-circle\"></ion-icon>\n No base cumulatives available\n </p>\n </div>\n\n <!-- Creation progress -->\n <div *ngIf=\"creating\" class=\"creation-progress\">\n <ion-spinner name=\"crescent\"></ion-spinner>\n <span>{{ creationProgress }}</span>\n </div>\n\n <ion-button [disabled]=\"!canCreateNew || creating\"\n expand=\"block\"\n (click)=\"createNewPeriod()\">\n <ion-icon name=\"add-circle-outline\" slot=\"start\"></ion-icon>\n Create {{ formatWindow(currentWindowMinutes) }} Cumulative\n </ion-button>\n\n <p *ngIf=\"!canCreateNew && !creating\" class=\"create-hint\">\n Create is disabled because base 5-min cumulatives don't fully cover the selected period.\n </p>\n </div>\n </div>\n\n <div class=\"modal-footer\">\n <ion-button fill=\"outline\" (click)=\"cancel()\" [disabled]=\"creating\">\n Cancel\n </ion-button>\n </div>\n </div>\n</div>\n", styles: [".cumulative-selector-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.5);display:flex;align-items:center;justify-content:center;z-index:1000}.cumulative-selector-modal{background:var(--ion-background-color, #fff);border-radius:12px;max-width:500px;width:90%;max-height:80vh;display:flex;flex-direction:column;box-shadow:0 4px 20px #0000004d}.modal-header{display:flex;justify-content:space-between;align-items:center;padding:16px 20px;border-bottom:1px solid var(--ion-border-color, #ddd)}.modal-header h2{margin:0;font-size:1.25rem;font-weight:600}.modal-header ion-button{--padding-start: 8px;--padding-end: 8px}.modal-content{flex:1;overflow-y:auto;padding:16px 20px}.loading-state{display:flex;flex-direction:column;align-items:center;padding:40px 0}.loading-state ion-spinner{margin-bottom:16px}.loading-state p{color:var(--ion-color-medium)}.error-message{display:flex;align-items:center;gap:8px;padding:12px;background:var(--ion-color-danger-tint);color:var(--ion-color-danger);border-radius:8px;margin-bottom:16px}.error-message ion-icon{font-size:1.25rem}.periods-section{margin-bottom:24px}.periods-section h3{font-size:1rem;font-weight:600;margin-bottom:12px;color:var(--ion-color-dark)}.periods-section ion-list{border-radius:8px;overflow:hidden}.periods-section ion-item{--padding-start: 12px;--padding-end: 12px}.periods-section ion-item ion-label h2{font-weight:500}.periods-section ion-item ion-label p{font-size:.85rem;color:var(--ion-color-medium)}.periods-section ion-item ion-label .count-info{font-size:.75rem;color:var(--ion-color-primary)}.periods-section .expanded-items{background:var(--ion-color-light);padding:8px 0 8px 24px;border-left:3px solid var(--ion-color-primary);margin-left:16px}.periods-section .expanded-items ion-spinner{display:block;margin:16px auto}.periods-section .expanded-items .nested-list{background:transparent;padding:0}.periods-section .expanded-items .nested-list .nested-item{--background: transparent;--padding-start: 8px;--padding-top: 4px;--padding-bottom: 4px;--min-height: 32px}.periods-section .expanded-items .nested-list .nested-item ion-label{margin:0}.periods-section .expanded-items .nested-list .nested-item ion-label h3{font-size:.85rem;font-weight:500;margin:0}.periods-section .expanded-items .nested-list .nested-item ion-icon[slot=start]{color:var(--ion-color-primary);font-size:.9rem;margin-right:8px}.periods-section .expanded-items .nested-list .nested-item ion-icon[slot=end]{font-size:.8rem}.no-periods{display:flex;flex-direction:column;align-items:center;padding:24px;text-align:center;color:var(--ion-color-medium)}.no-periods ion-icon{font-size:2rem;margin-bottom:8px}.create-section{border-top:1px solid var(--ion-border-color, #ddd);padding-top:16px}.create-section h3{font-size:1rem;font-weight:600;margin-bottom:12px;color:var(--ion-color-dark)}.create-section .create-info{background:var(--ion-color-light);padding:12px;border-radius:8px;margin-bottom:16px}.create-section .create-info p{margin:4px 0;font-size:.9rem}.create-section .coverage-info{display:flex;align-items:center;gap:6px}.create-section .coverage-info ion-icon{font-size:1.1rem}.create-section .coverage-ok{color:var(--ion-color-success)}.create-section .coverage-warn{color:var(--ion-color-warning)}.create-section .coverage-error{color:var(--ion-color-danger)}.create-section .creation-progress{display:flex;align-items:center;gap:12px;padding:16px;background:var(--ion-color-primary-tint);border-radius:8px;margin-bottom:16px}.create-section .creation-progress ion-spinner{--color: var(--ion-color-primary)}.create-section .creation-progress span{color:var(--ion-color-primary);font-size:.9rem}.create-section .create-hint{font-size:.8rem;color:var(--ion-color-medium);text-align:center;margin-top:8px}.modal-footer{padding:16px 20px;border-top:1px solid var(--ion-border-color, #ddd);display:flex;justify-content:flex-end}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i3.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i3.IonItem, selector: "ion-item", inputs: ["button", "color", "counter", "counterFormatter", "detail", "detailIcon", "disabled", "download", "fill", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "shape", "target", "type"] }, { kind: "component", type: i3.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i3.IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: i3.IonSpinner, selector: "ion-spinner", inputs: ["color", "duration", "name", "paused"] }, { kind: "pipe", type: i2.DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
223
+ CumulativeSelectorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: CumulativeSelectorComponent, selector: "cumulative-selector", inputs: { rainId: "rainId", currentPeriodBegin: "currentPeriodBegin", currentPeriodEnd: "currentPeriodEnd", provider: "provider", timeStepInMinutes: "timeStepInMinutes", isAdmin: "isAdmin" }, outputs: { periodSelected: "periodSelected", cancelled: "cancelled" }, ngImport: i0, template: "<div class=\"cumulative-selector-overlay\">\n <div class=\"cumulative-selector-modal\">\n <div class=\"modal-header\">\n <h2>Select Cumulative Period</h2>\n <ion-button (click)=\"cancel()\" fill=\"clear\">\n <ion-icon name=\"close\"></ion-icon>\n </ion-button>\n </div>\n\n <div class=\"modal-content\">\n <!-- Loading state -->\n <div *ngIf=\"loading\" class=\"loading-state\">\n <ion-spinner name=\"crescent\"></ion-spinner>\n <p>Loading available periods...</p>\n </div>\n\n <!-- Error message -->\n <div *ngIf=\"errorMessage\" class=\"error-message\">\n <ion-icon name=\"warning-outline\"></ion-icon>\n <span>{{ errorMessage }}</span>\n </div>\n\n <!-- Available periods list -->\n <div *ngIf=\"!loading && availablePeriods.length > 0\" class=\"periods-section\">\n <h3>Available Cumulative Periods</h3>\n <ion-list>\n <ng-container *ngFor=\"let period of availablePeriods\">\n <!-- Period header (click to expand) -->\n <ion-item (click)=\"toggleExpand(period)\" [disabled]=\"creating\" button>\n <ion-icon [name]=\"isExpanded(period) ? 'chevron-down' : 'chevron-forward'\"\n slot=\"start\"></ion-icon>\n <ion-label>\n <h2>{{ formatWindow(period.windowInMinutes) }}</h2>\n <p>{{ formatPeriod(period) }}</p>\n <p class=\"count-info\">{{ period.count }} cumulative(s) - click to expand</p>\n </ion-label>\n </ion-item>\n\n <!-- Expanded: individual cumulatives -->\n <div *ngIf=\"isExpanded(period)\" class=\"expanded-items\">\n <ion-spinner *ngIf=\"isLoadingExpanded(period)\" name=\"crescent\"></ion-spinner>\n <ion-list *ngIf=\"!isLoadingExpanded(period)\" class=\"nested-list\">\n <ion-item (click)=\"selectIndividualCumulative(item)\"\n *ngFor=\"let item of getExpandedItems(period)\"\n [disabled]=\"creating\"\n button\n class=\"nested-item\">\n <ion-icon name=\"time-outline\" slot=\"start\"></ion-icon>\n <ion-label>\n <h3>{{ getItemPeriodBegin(item) | date:'HH:mm' }}\n - {{ item.date | date:'HH:mm' }}</h3>\n </ion-label>\n <ion-icon name=\"chevron-forward\" slot=\"end\"></ion-icon>\n </ion-item>\n <ion-item *ngIf=\"getExpandedItems(period).length === 0\" class=\"nested-item\">\n <ion-label>\n <p>No individual cumulatives found</p>\n </ion-label>\n </ion-item>\n </ion-list>\n </div>\n </ng-container>\n </ion-list>\n </div>\n\n <!-- No periods available -->\n <div *ngIf=\"!loading && availablePeriods.length === 0\" class=\"no-periods\">\n <ion-icon name=\"information-circle-outline\"></ion-icon>\n <p>No cumulative periods available yet.</p>\n </div>\n\n <!-- Create new section (admin only) -->\n <div *ngIf=\"!loading && isAdmin\" class=\"create-section\">\n <h3>Create New Cumulative</h3>\n <div class=\"create-info\">\n <p>\n <strong>Period:</strong>\n {{ currentPeriodBegin?.toLocaleString() }} \u2192 {{ currentPeriodEnd?.toLocaleString() }}\n </p>\n <p>\n <strong>Window:</strong> {{ formatWindow(currentWindowMinutes) }}\n </p>\n <p *ngIf=\"baseCumulatives\" [class.coverage-error]=\"coveragePercent === 0\"\n [class.coverage-ok]=\"coveragePercent >= 100\"\n [class.coverage-warn]=\"coveragePercent > 0 && coveragePercent < 100\"\n class=\"coverage-info\">\n <ion-icon [name]=\"coveragePercent >= 100 ? 'checkmark-circle' : 'alert-circle'\"></ion-icon>\n Base data coverage: {{ coveragePercent }}%\n </p>\n <p *ngIf=\"!baseCumulatives\" class=\"coverage-error\">\n <ion-icon name=\"alert-circle\"></ion-icon>\n No base cumulatives available\n </p>\n </div>\n\n <!-- Creation progress -->\n <div *ngIf=\"creating\" class=\"creation-progress\">\n <ion-spinner name=\"crescent\"></ion-spinner>\n <span>{{ creationProgress }}</span>\n </div>\n\n <ion-button (click)=\"createNewPeriod()\" [disabled]=\"!canCreateNew || creating\"\n expand=\"block\"\n id=\"createNewCumulative\">\n <ion-icon name=\"add-circle-outline\" slot=\"start\"></ion-icon>\n Create {{ formatWindow(currentWindowMinutes) }} Cumulative\n </ion-button>\n\n <p *ngIf=\"!canCreateNew && !creating\" class=\"create-hint\">\n Create is disabled because no base 5-min cumulatives exist for the selected period.\n </p>\n </div>\n </div>\n\n <div class=\"modal-footer\">\n <ion-button (click)=\"cancel()\" [disabled]=\"creating\" fill=\"outline\">\n Cancel\n </ion-button>\n </div>\n </div>\n</div>\n", styles: [".cumulative-selector-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.5);display:flex;align-items:center;justify-content:center;z-index:1000}.cumulative-selector-modal{background:var(--ion-background-color, #fff);border-radius:12px;max-width:500px;width:90%;max-height:80vh;display:flex;flex-direction:column;box-shadow:0 4px 20px #0000004d}.modal-header{display:flex;justify-content:space-between;align-items:center;padding:16px 20px;border-bottom:1px solid var(--ion-border-color, #ddd)}.modal-header h2{margin:0;font-size:1.25rem;font-weight:600}.modal-header ion-button{--padding-start: 8px;--padding-end: 8px}.modal-content{flex:1;overflow-y:auto;padding:16px 20px}.loading-state{display:flex;flex-direction:column;align-items:center;padding:40px 0}.loading-state ion-spinner{margin-bottom:16px}.loading-state p{color:var(--ion-color-medium)}.error-message{display:flex;align-items:center;gap:8px;padding:12px;background:var(--ion-color-danger-tint);color:var(--ion-color-danger);border-radius:8px;margin-bottom:16px}.error-message ion-icon{font-size:1.25rem}.periods-section{margin-bottom:24px}.periods-section h3{font-size:1rem;font-weight:600;margin-bottom:12px;color:var(--ion-color-dark)}.periods-section ion-list{border-radius:8px;overflow:hidden}.periods-section ion-item{--padding-start: 12px;--padding-end: 12px}.periods-section ion-item ion-label h2{font-weight:500}.periods-section ion-item ion-label p{font-size:.85rem;color:var(--ion-color-medium)}.periods-section ion-item ion-label .count-info{font-size:.75rem;color:var(--ion-color-primary)}.periods-section .expanded-items{background:var(--ion-color-light);padding:8px 0 8px 24px;border-left:3px solid var(--ion-color-primary);margin-left:16px}.periods-section .expanded-items ion-spinner{display:block;margin:16px auto}.periods-section .expanded-items .nested-list{background:transparent;padding:0}.periods-section .expanded-items .nested-list .nested-item{--background: transparent;--padding-start: 8px;--padding-top: 4px;--padding-bottom: 4px;--min-height: 32px}.periods-section .expanded-items .nested-list .nested-item ion-label{margin:0}.periods-section .expanded-items .nested-list .nested-item ion-label h3{font-size:.85rem;font-weight:500;margin:0}.periods-section .expanded-items .nested-list .nested-item ion-icon[slot=start]{color:var(--ion-color-primary);font-size:.9rem;margin-right:8px}.periods-section .expanded-items .nested-list .nested-item ion-icon[slot=end]{font-size:.8rem}.no-periods{display:flex;flex-direction:column;align-items:center;padding:24px;text-align:center;color:var(--ion-color-medium)}.no-periods ion-icon{font-size:2rem;margin-bottom:8px}.create-section{border-top:1px solid var(--ion-border-color, #ddd);padding-top:16px}.create-section h3{font-size:1rem;font-weight:600;margin-bottom:12px;color:var(--ion-color-dark)}.create-section .create-info{background:var(--ion-color-light);padding:12px;border-radius:8px;margin-bottom:16px}.create-section .create-info p{margin:4px 0;font-size:.9rem}.create-section .coverage-info{display:flex;align-items:center;gap:6px}.create-section .coverage-info ion-icon{font-size:1.1rem}.create-section .coverage-ok{color:var(--ion-color-success)}.create-section .coverage-warn{color:var(--ion-color-warning)}.create-section .coverage-error{color:var(--ion-color-danger)}.create-section .creation-progress{display:flex;align-items:center;gap:12px;padding:16px;background:var(--ion-color-primary-tint);border-radius:8px;margin-bottom:16px}.create-section .creation-progress ion-spinner{--color: var(--ion-color-primary)}.create-section .creation-progress span{color:var(--ion-color-primary);font-size:.9rem}.create-section .create-hint{font-size:.8rem;color:var(--ion-color-medium);text-align:center;margin-top:8px}.modal-footer{padding:16px 20px;border-top:1px solid var(--ion-border-color, #ddd);display:flex;justify-content:flex-end}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i3.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i3.IonItem, selector: "ion-item", inputs: ["button", "color", "counter", "counterFormatter", "detail", "detailIcon", "disabled", "download", "fill", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "shape", "target", "type"] }, { kind: "component", type: i3.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i3.IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: i3.IonSpinner, selector: "ion-spinner", inputs: ["color", "duration", "name", "paused"] }, { kind: "pipe", type: i2.DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
230
224
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CumulativeSelectorComponent, decorators: [{
231
225
  type: Component,
232
- args: [{ selector: 'cumulative-selector', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"cumulative-selector-overlay\">\n <div class=\"cumulative-selector-modal\">\n <div class=\"modal-header\">\n <h2>Select Cumulative Period</h2>\n <ion-button fill=\"clear\" (click)=\"cancel()\">\n <ion-icon name=\"close\"></ion-icon>\n </ion-button>\n </div>\n\n <div class=\"modal-content\">\n <!-- Loading state -->\n <div *ngIf=\"loading\" class=\"loading-state\">\n <ion-spinner name=\"crescent\"></ion-spinner>\n <p>Loading available periods...</p>\n </div>\n\n <!-- Error message -->\n <div *ngIf=\"errorMessage\" class=\"error-message\">\n <ion-icon name=\"warning-outline\"></ion-icon>\n <span>{{ errorMessage }}</span>\n </div>\n\n <!-- Available periods list -->\n <div *ngIf=\"!loading && availablePeriods.length > 0\" class=\"periods-section\">\n <h3>Available Cumulative Periods</h3>\n <ion-list>\n <ng-container *ngFor=\"let period of availablePeriods\">\n <!-- Period header (click to expand) -->\n <ion-item button (click)=\"toggleExpand(period)\" [disabled]=\"creating\">\n <ion-icon [name]=\"isExpanded(period) ? 'chevron-down' : 'chevron-forward'\" slot=\"start\"></ion-icon>\n <ion-label>\n <h2>{{ formatWindow(period.windowInMinutes) }}</h2>\n <p>{{ formatPeriod(period) }}</p>\n <p class=\"count-info\">{{ period.count }} cumulative(s) - click to expand</p>\n </ion-label>\n </ion-item>\n\n <!-- Expanded: individual cumulatives -->\n <div *ngIf=\"isExpanded(period)\" class=\"expanded-items\">\n <ion-spinner *ngIf=\"isLoadingExpanded(period)\" name=\"crescent\"></ion-spinner>\n <ion-list *ngIf=\"!isLoadingExpanded(period)\" class=\"nested-list\">\n <ion-item *ngFor=\"let item of getExpandedItems(period)\"\n button\n (click)=\"selectIndividualCumulative(item)\"\n class=\"nested-item\"\n [disabled]=\"creating\">\n <ion-icon name=\"time-outline\" slot=\"start\"></ion-icon>\n <ion-label>\n <h3>{{ getItemPeriodBegin(item) | date:'HH:mm' }} - {{ item.date | date:'HH:mm' }}</h3>\n </ion-label>\n <ion-icon name=\"chevron-forward\" slot=\"end\"></ion-icon>\n </ion-item>\n <ion-item *ngIf=\"getExpandedItems(period).length === 0\" class=\"nested-item\">\n <ion-label>\n <p>No individual cumulatives found</p>\n </ion-label>\n </ion-item>\n </ion-list>\n </div>\n </ng-container>\n </ion-list>\n </div>\n\n <!-- No periods available -->\n <div *ngIf=\"!loading && availablePeriods.length === 0\" class=\"no-periods\">\n <ion-icon name=\"information-circle-outline\"></ion-icon>\n <p>No cumulative periods available yet.</p>\n </div>\n\n <!-- Create new section (admin only) -->\n <div *ngIf=\"!loading && isAdmin\" class=\"create-section\">\n <h3>Create New Cumulative</h3>\n <div class=\"create-info\">\n <p>\n <strong>Period:</strong>\n {{ currentPeriodBegin?.toLocaleString() }} \u2192 {{ currentPeriodEnd?.toLocaleString() }}\n </p>\n <p>\n <strong>Window:</strong> {{ formatWindow(currentWindowMinutes) }}\n </p>\n <p *ngIf=\"baseCumulatives\" class=\"coverage-info\"\n [class.coverage-ok]=\"coveragePercent >= 100\"\n [class.coverage-warn]=\"coveragePercent > 0 && coveragePercent < 100\"\n [class.coverage-error]=\"coveragePercent === 0\">\n <ion-icon [name]=\"coveragePercent >= 100 ? 'checkmark-circle' : 'alert-circle'\"></ion-icon>\n Base data coverage: {{ coveragePercent }}%\n </p>\n <p *ngIf=\"!baseCumulatives\" class=\"coverage-error\">\n <ion-icon name=\"alert-circle\"></ion-icon>\n No base cumulatives available\n </p>\n </div>\n\n <!-- Creation progress -->\n <div *ngIf=\"creating\" class=\"creation-progress\">\n <ion-spinner name=\"crescent\"></ion-spinner>\n <span>{{ creationProgress }}</span>\n </div>\n\n <ion-button [disabled]=\"!canCreateNew || creating\"\n expand=\"block\"\n (click)=\"createNewPeriod()\">\n <ion-icon name=\"add-circle-outline\" slot=\"start\"></ion-icon>\n Create {{ formatWindow(currentWindowMinutes) }} Cumulative\n </ion-button>\n\n <p *ngIf=\"!canCreateNew && !creating\" class=\"create-hint\">\n Create is disabled because base 5-min cumulatives don't fully cover the selected period.\n </p>\n </div>\n </div>\n\n <div class=\"modal-footer\">\n <ion-button fill=\"outline\" (click)=\"cancel()\" [disabled]=\"creating\">\n Cancel\n </ion-button>\n </div>\n </div>\n</div>\n", styles: [".cumulative-selector-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.5);display:flex;align-items:center;justify-content:center;z-index:1000}.cumulative-selector-modal{background:var(--ion-background-color, #fff);border-radius:12px;max-width:500px;width:90%;max-height:80vh;display:flex;flex-direction:column;box-shadow:0 4px 20px #0000004d}.modal-header{display:flex;justify-content:space-between;align-items:center;padding:16px 20px;border-bottom:1px solid var(--ion-border-color, #ddd)}.modal-header h2{margin:0;font-size:1.25rem;font-weight:600}.modal-header ion-button{--padding-start: 8px;--padding-end: 8px}.modal-content{flex:1;overflow-y:auto;padding:16px 20px}.loading-state{display:flex;flex-direction:column;align-items:center;padding:40px 0}.loading-state ion-spinner{margin-bottom:16px}.loading-state p{color:var(--ion-color-medium)}.error-message{display:flex;align-items:center;gap:8px;padding:12px;background:var(--ion-color-danger-tint);color:var(--ion-color-danger);border-radius:8px;margin-bottom:16px}.error-message ion-icon{font-size:1.25rem}.periods-section{margin-bottom:24px}.periods-section h3{font-size:1rem;font-weight:600;margin-bottom:12px;color:var(--ion-color-dark)}.periods-section ion-list{border-radius:8px;overflow:hidden}.periods-section ion-item{--padding-start: 12px;--padding-end: 12px}.periods-section ion-item ion-label h2{font-weight:500}.periods-section ion-item ion-label p{font-size:.85rem;color:var(--ion-color-medium)}.periods-section ion-item ion-label .count-info{font-size:.75rem;color:var(--ion-color-primary)}.periods-section .expanded-items{background:var(--ion-color-light);padding:8px 0 8px 24px;border-left:3px solid var(--ion-color-primary);margin-left:16px}.periods-section .expanded-items ion-spinner{display:block;margin:16px auto}.periods-section .expanded-items .nested-list{background:transparent;padding:0}.periods-section .expanded-items .nested-list .nested-item{--background: transparent;--padding-start: 8px;--padding-top: 4px;--padding-bottom: 4px;--min-height: 32px}.periods-section .expanded-items .nested-list .nested-item ion-label{margin:0}.periods-section .expanded-items .nested-list .nested-item ion-label h3{font-size:.85rem;font-weight:500;margin:0}.periods-section .expanded-items .nested-list .nested-item ion-icon[slot=start]{color:var(--ion-color-primary);font-size:.9rem;margin-right:8px}.periods-section .expanded-items .nested-list .nested-item ion-icon[slot=end]{font-size:.8rem}.no-periods{display:flex;flex-direction:column;align-items:center;padding:24px;text-align:center;color:var(--ion-color-medium)}.no-periods ion-icon{font-size:2rem;margin-bottom:8px}.create-section{border-top:1px solid var(--ion-border-color, #ddd);padding-top:16px}.create-section h3{font-size:1rem;font-weight:600;margin-bottom:12px;color:var(--ion-color-dark)}.create-section .create-info{background:var(--ion-color-light);padding:12px;border-radius:8px;margin-bottom:16px}.create-section .create-info p{margin:4px 0;font-size:.9rem}.create-section .coverage-info{display:flex;align-items:center;gap:6px}.create-section .coverage-info ion-icon{font-size:1.1rem}.create-section .coverage-ok{color:var(--ion-color-success)}.create-section .coverage-warn{color:var(--ion-color-warning)}.create-section .coverage-error{color:var(--ion-color-danger)}.create-section .creation-progress{display:flex;align-items:center;gap:12px;padding:16px;background:var(--ion-color-primary-tint);border-radius:8px;margin-bottom:16px}.create-section .creation-progress ion-spinner{--color: var(--ion-color-primary)}.create-section .creation-progress span{color:var(--ion-color-primary);font-size:.9rem}.create-section .create-hint{font-size:.8rem;color:var(--ion-color-medium);text-align:center;margin-top:8px}.modal-footer{padding:16px 20px;border-top:1px solid var(--ion-border-color, #ddd);display:flex;justify-content:flex-end}\n"] }]
226
+ args: [{ selector: 'cumulative-selector', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"cumulative-selector-overlay\">\n <div class=\"cumulative-selector-modal\">\n <div class=\"modal-header\">\n <h2>Select Cumulative Period</h2>\n <ion-button (click)=\"cancel()\" fill=\"clear\">\n <ion-icon name=\"close\"></ion-icon>\n </ion-button>\n </div>\n\n <div class=\"modal-content\">\n <!-- Loading state -->\n <div *ngIf=\"loading\" class=\"loading-state\">\n <ion-spinner name=\"crescent\"></ion-spinner>\n <p>Loading available periods...</p>\n </div>\n\n <!-- Error message -->\n <div *ngIf=\"errorMessage\" class=\"error-message\">\n <ion-icon name=\"warning-outline\"></ion-icon>\n <span>{{ errorMessage }}</span>\n </div>\n\n <!-- Available periods list -->\n <div *ngIf=\"!loading && availablePeriods.length > 0\" class=\"periods-section\">\n <h3>Available Cumulative Periods</h3>\n <ion-list>\n <ng-container *ngFor=\"let period of availablePeriods\">\n <!-- Period header (click to expand) -->\n <ion-item (click)=\"toggleExpand(period)\" [disabled]=\"creating\" button>\n <ion-icon [name]=\"isExpanded(period) ? 'chevron-down' : 'chevron-forward'\"\n slot=\"start\"></ion-icon>\n <ion-label>\n <h2>{{ formatWindow(period.windowInMinutes) }}</h2>\n <p>{{ formatPeriod(period) }}</p>\n <p class=\"count-info\">{{ period.count }} cumulative(s) - click to expand</p>\n </ion-label>\n </ion-item>\n\n <!-- Expanded: individual cumulatives -->\n <div *ngIf=\"isExpanded(period)\" class=\"expanded-items\">\n <ion-spinner *ngIf=\"isLoadingExpanded(period)\" name=\"crescent\"></ion-spinner>\n <ion-list *ngIf=\"!isLoadingExpanded(period)\" class=\"nested-list\">\n <ion-item (click)=\"selectIndividualCumulative(item)\"\n *ngFor=\"let item of getExpandedItems(period)\"\n [disabled]=\"creating\"\n button\n class=\"nested-item\">\n <ion-icon name=\"time-outline\" slot=\"start\"></ion-icon>\n <ion-label>\n <h3>{{ getItemPeriodBegin(item) | date:'HH:mm' }}\n - {{ item.date | date:'HH:mm' }}</h3>\n </ion-label>\n <ion-icon name=\"chevron-forward\" slot=\"end\"></ion-icon>\n </ion-item>\n <ion-item *ngIf=\"getExpandedItems(period).length === 0\" class=\"nested-item\">\n <ion-label>\n <p>No individual cumulatives found</p>\n </ion-label>\n </ion-item>\n </ion-list>\n </div>\n </ng-container>\n </ion-list>\n </div>\n\n <!-- No periods available -->\n <div *ngIf=\"!loading && availablePeriods.length === 0\" class=\"no-periods\">\n <ion-icon name=\"information-circle-outline\"></ion-icon>\n <p>No cumulative periods available yet.</p>\n </div>\n\n <!-- Create new section (admin only) -->\n <div *ngIf=\"!loading && isAdmin\" class=\"create-section\">\n <h3>Create New Cumulative</h3>\n <div class=\"create-info\">\n <p>\n <strong>Period:</strong>\n {{ currentPeriodBegin?.toLocaleString() }} \u2192 {{ currentPeriodEnd?.toLocaleString() }}\n </p>\n <p>\n <strong>Window:</strong> {{ formatWindow(currentWindowMinutes) }}\n </p>\n <p *ngIf=\"baseCumulatives\" [class.coverage-error]=\"coveragePercent === 0\"\n [class.coverage-ok]=\"coveragePercent >= 100\"\n [class.coverage-warn]=\"coveragePercent > 0 && coveragePercent < 100\"\n class=\"coverage-info\">\n <ion-icon [name]=\"coveragePercent >= 100 ? 'checkmark-circle' : 'alert-circle'\"></ion-icon>\n Base data coverage: {{ coveragePercent }}%\n </p>\n <p *ngIf=\"!baseCumulatives\" class=\"coverage-error\">\n <ion-icon name=\"alert-circle\"></ion-icon>\n No base cumulatives available\n </p>\n </div>\n\n <!-- Creation progress -->\n <div *ngIf=\"creating\" class=\"creation-progress\">\n <ion-spinner name=\"crescent\"></ion-spinner>\n <span>{{ creationProgress }}</span>\n </div>\n\n <ion-button (click)=\"createNewPeriod()\" [disabled]=\"!canCreateNew || creating\"\n expand=\"block\"\n id=\"createNewCumulative\">\n <ion-icon name=\"add-circle-outline\" slot=\"start\"></ion-icon>\n Create {{ formatWindow(currentWindowMinutes) }} Cumulative\n </ion-button>\n\n <p *ngIf=\"!canCreateNew && !creating\" class=\"create-hint\">\n Create is disabled because no base 5-min cumulatives exist for the selected period.\n </p>\n </div>\n </div>\n\n <div class=\"modal-footer\">\n <ion-button (click)=\"cancel()\" [disabled]=\"creating\" fill=\"outline\">\n Cancel\n </ion-button>\n </div>\n </div>\n</div>\n", styles: [".cumulative-selector-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.5);display:flex;align-items:center;justify-content:center;z-index:1000}.cumulative-selector-modal{background:var(--ion-background-color, #fff);border-radius:12px;max-width:500px;width:90%;max-height:80vh;display:flex;flex-direction:column;box-shadow:0 4px 20px #0000004d}.modal-header{display:flex;justify-content:space-between;align-items:center;padding:16px 20px;border-bottom:1px solid var(--ion-border-color, #ddd)}.modal-header h2{margin:0;font-size:1.25rem;font-weight:600}.modal-header ion-button{--padding-start: 8px;--padding-end: 8px}.modal-content{flex:1;overflow-y:auto;padding:16px 20px}.loading-state{display:flex;flex-direction:column;align-items:center;padding:40px 0}.loading-state ion-spinner{margin-bottom:16px}.loading-state p{color:var(--ion-color-medium)}.error-message{display:flex;align-items:center;gap:8px;padding:12px;background:var(--ion-color-danger-tint);color:var(--ion-color-danger);border-radius:8px;margin-bottom:16px}.error-message ion-icon{font-size:1.25rem}.periods-section{margin-bottom:24px}.periods-section h3{font-size:1rem;font-weight:600;margin-bottom:12px;color:var(--ion-color-dark)}.periods-section ion-list{border-radius:8px;overflow:hidden}.periods-section ion-item{--padding-start: 12px;--padding-end: 12px}.periods-section ion-item ion-label h2{font-weight:500}.periods-section ion-item ion-label p{font-size:.85rem;color:var(--ion-color-medium)}.periods-section ion-item ion-label .count-info{font-size:.75rem;color:var(--ion-color-primary)}.periods-section .expanded-items{background:var(--ion-color-light);padding:8px 0 8px 24px;border-left:3px solid var(--ion-color-primary);margin-left:16px}.periods-section .expanded-items ion-spinner{display:block;margin:16px auto}.periods-section .expanded-items .nested-list{background:transparent;padding:0}.periods-section .expanded-items .nested-list .nested-item{--background: transparent;--padding-start: 8px;--padding-top: 4px;--padding-bottom: 4px;--min-height: 32px}.periods-section .expanded-items .nested-list .nested-item ion-label{margin:0}.periods-section .expanded-items .nested-list .nested-item ion-label h3{font-size:.85rem;font-weight:500;margin:0}.periods-section .expanded-items .nested-list .nested-item ion-icon[slot=start]{color:var(--ion-color-primary);font-size:.9rem;margin-right:8px}.periods-section .expanded-items .nested-list .nested-item ion-icon[slot=end]{font-size:.8rem}.no-periods{display:flex;flex-direction:column;align-items:center;padding:24px;text-align:center;color:var(--ion-color-medium)}.no-periods ion-icon{font-size:2rem;margin-bottom:8px}.create-section{border-top:1px solid var(--ion-border-color, #ddd);padding-top:16px}.create-section h3{font-size:1rem;font-weight:600;margin-bottom:12px;color:var(--ion-color-dark)}.create-section .create-info{background:var(--ion-color-light);padding:12px;border-radius:8px;margin-bottom:16px}.create-section .create-info p{margin:4px 0;font-size:.9rem}.create-section .coverage-info{display:flex;align-items:center;gap:6px}.create-section .coverage-info ion-icon{font-size:1.1rem}.create-section .coverage-ok{color:var(--ion-color-success)}.create-section .coverage-warn{color:var(--ion-color-warning)}.create-section .coverage-error{color:var(--ion-color-danger)}.create-section .creation-progress{display:flex;align-items:center;gap:12px;padding:16px;background:var(--ion-color-primary-tint);border-radius:8px;margin-bottom:16px}.create-section .creation-progress ion-spinner{--color: var(--ion-color-primary)}.create-section .creation-progress span{color:var(--ion-color-primary);font-size:.9rem}.create-section .create-hint{font-size:.8rem;color:var(--ion-color-medium);text-align:center;margin-top:8px}.modal-footer{padding:16px 20px;border-top:1px solid var(--ion-border-color, #ddd);display:flex;justify-content:flex-end}\n"] }]
233
227
  }], ctorParameters: function () { return [{ type: i1.ProfileService }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { rainId: [{
234
228
  type: Input
235
229
  }], currentPeriodBegin: [{
@@ -247,4 +241,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
247
241
  }], cancelled: [{
248
242
  type: Output
249
243
  }] } });
250
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3VtdWxhdGl2ZS1zZWxlY3Rvci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY29yZS9zaGFyZWQvY3VtdWxhdGl2ZS1zZWxlY3Rvci9jdW11bGF0aXZlLXNlbGVjdG9yLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uL3NyYy9jb3JlL3NoYXJlZC9jdW11bGF0aXZlLXNlbGVjdG9yL2N1bXVsYXRpdmUtc2VsZWN0b3IuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNILHVCQUF1QixFQUV2QixTQUFTLEVBQ1QsWUFBWSxFQUNaLEtBQUssRUFFTCxNQUFNLEdBQ1QsTUFBTSxlQUFlLENBQUM7Ozs7O0FBdUJ2QixNQUFNLE9BQU8sMkJBQTJCO0lBNEJwQyxZQUNZLGNBQThCLEVBQzlCLEdBQXNCO1FBRHRCLG1CQUFjLEdBQWQsY0FBYyxDQUFnQjtRQUM5QixRQUFHLEdBQUgsR0FBRyxDQUFtQjtRQXpCekIsc0JBQWlCLEdBQVcsQ0FBQyxDQUFDO1FBQzlCLFlBQU8sR0FBWSxLQUFLLENBQUM7UUFFeEIsbUJBQWMsR0FBRyxJQUFJLFlBQVksRUFBdUIsQ0FBQztRQUN6RCxjQUFTLEdBQUcsSUFBSSxZQUFZLEVBQVEsQ0FBQztRQUUvQyxxQkFBZ0IsR0FBdUIsRUFBRSxDQUFDO1FBQzFDLG9CQUFlLEdBQXFCLElBQUksQ0FBQztRQUN6QyxZQUFPLEdBQUcsSUFBSSxDQUFDO1FBQ2YsYUFBUSxHQUFHLEtBQUssQ0FBQztRQUNqQixxQkFBZ0IsR0FBRyxFQUFFLENBQUM7UUFDdEIsaUJBQVksR0FBRyxFQUFFLENBQUM7UUFFbEIsb0JBQWUsR0FBRyxDQUFDLENBQUM7UUFDcEIsaUJBQVksR0FBRyxLQUFLLENBQUM7UUFDckIseUJBQW9CLEdBQUcsQ0FBQyxDQUFDO1FBRXpCLG9CQUFlLEdBQXdDLElBQUksR0FBRyxFQUFFLENBQUM7UUFDakUsb0JBQWUsR0FBZ0IsSUFBSSxH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c0JBQTFCLEtBQUs7Z0JBQ0csZ0JBQWdCO3NCQUF4QixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csaUJBQWlCO3NCQUF6QixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFFSSxjQUFjO3NCQUF2QixNQUFNO2dCQUNHLFNBQVM7c0JBQWxCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICAgIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICAgIENoYW5nZURldGVjdG9yUmVmLFxuICAgIENvbXBvbmVudCxcbiAgICBFdmVudEVtaXR0ZXIsXG4gICAgSW5wdXQsXG4gICAgT25Jbml0LFxuICAgIE91dHB1dCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge1Byb2ZpbGVTZXJ2aWNlfSBmcm9tICcuLi9wcm9maWxlLnNlcnZpY2UnO1xuaW1wb3J0IHtcbiAgICBDdW11bGF0aXZlUGVyaW9kLFxuICAgIEluZGl2aWR1YWxDdW11bGF0aXZlLFxuICAgIFJhYWluQXBpUmFpbnNDdW11bGF0aXZlc0RldGFpbGVkUmVzcG9uc2UsXG4gICAgUmFhaW5BcGlSYWluc0N1bXVsYXRpdmVzTGlzdFJlc3BvbnNlLFxufSBmcm9tICdyYWFpbi1tb2RlbCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ3VtdWxhdGl2ZVNlbGVjdGlvbiB7XG4gICAgcGVyaW9kQmVnaW46IERhdGU7XG4gICAgcGVyaW9kRW5kOiBEYXRlO1xuICAgIHdpbmRvd0luTWludXRlczogbnVtYmVyO1xuICAgIGN1bXVsYXRpdmVJZD86IHN0cmluZztcbiAgICBjdW11bGF0aXZlRGF0ZT86IERhdGU7XG59XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnY3VtdWxhdGl2ZS1zZWxlY3RvcicsXG4gICAgdGVtcGxhdGVVcmw6ICcuL2N1bXVsYXRpdmUtc2VsZWN0b3IuY29tcG9uZW50Lmh0bWwnLFxuICAgIHN0eWxlVXJsczogWycuL2N1bXVsYXRpdmUtc2VsZWN0b3IuY29tcG9uZW50LnNjc3MnXSxcbiAgICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgQ3VtdWxhdGl2ZVNlbGVjdG9yQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgICBASW5wdXQoKSByYWluSWQ6IHN0cmluZztcbiAgICBASW5wdXQoKSBjdXJyZW50UGVyaW9kQmVnaW46IERhdGU7XG4gICAgQElucHV0KCkgY3VycmVudFBlcmlvZEVuZDogRGF0ZTtcbiAgICBASW5wdXQoKSBwcm92aWRlcjogc3RyaW5nO1xuICAgIEBJbnB1dCgpIHRpbWVTdGVwSW5NaW51dGVzOiBudW1iZXIgPSA1O1xuICAgIEBJbnB1dCgpIGlzQWRtaW46IGJvb2xlYW4gPSBmYWxzZTtcblxuICAgIEBPdXRwdXQoKSBwZXJpb2RTZWxlY3RlZCA9IG5ldyBFdmVudEVtaXR0ZXI8Q3VtdWxhdGl2ZVNlbGVjdGlvbj4oKTtcbiAgICBAT3V0cHV0KCkgY2FuY2VsbGVkID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG4gICAgYXZhaWxhYmxlUGVyaW9kczogQ3VtdWxhdGl2ZVBlcmlvZFtdID0gW107XG4gICAgYmFzZUN1bXVsYXRpdmVzOiBDdW11bGF0aXZlUGVyaW9kID0gbnVsbDtcbiAgICBsb2FkaW5nID0gdHJ1ZTtcbiAgICBjcmVhdGluZyA9IGZhbHNlO1xuICAgIGNyZWF0aW9uUHJvZ3Jlc3MgPSAnJztcbiAgICBlcnJvck1lc3NhZ2UgPSAnJztcblxuICAgIGNvdmVyYWdlUGVyY2VudCA9IDA7XG4gICAgY2FuQ3JlYXRlTmV3ID0gZmFsc2U7XG4gICAgY3VycmVudFdpbmRvd01pbnV0ZXMgPSAwO1xuXG4gICAgZXhwYW5kZWRQZXJpb2RzOiBNYXA8c3RyaW5nLCBJbmRpdmlkdWFsQ3VtdWxhdGl2ZVtdPiA9IG5ldyBNYXAoKTtcbiAgICBsb2FkaW5nRXhwYW5kZWQ6IFNldDxzdHJpbmc+ID0gbmV3IFNldCgpO1xuXG4gICAgcHJpdmF0ZSByZWFkb25seSBQT0xMX1RJTUVPVVRfTVMgPSA5MDAwMDA7IC8vIDkwMCBzZWNvbmRzXG4gICAgcHJpdmF0ZSByZWFkb25seSBQT0xMX0lOVEVSVkFMX01TID0gMzAwMDtcblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBwcml2YXRlIHByb2ZpbGVTZXJ2aWNlOiBQcm9maWxlU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSBjZHI6IENoYW5nZURldGVjdG9yUmVmXG4gICAgKSB7fVxuXG4gICAgYXN5bmMgbmdPbkluaXQoKSB7XG4gICAgICAgIHRoaXMuY3VycmVudFdpbmRvd01pbnV0ZXMgPSBNYXRoLnJvdW5kKFxuICAgICAgICAgICAgKHRoaXMuY3VycmVudFBlcmlvZEVuZC5nZXRUaW1lKCkgLSB0aGlzLmN1cnJlbnRQZXJpb2RCZWdpbi5nZXRUaW1lKCkpIC8gNjAwMDBcbiAgICAgICAgKTtcbiAgICAgICAgYXdhaXQgdGhpcy5sb2FkQXZhaWxhYmxlUGVyaW9kcygpO1xuICAgIH1cblxuICAgIGFzeW5jIGxvYWRBdmFpbGFibGVQZXJpb2RzKCkge1xuICAgICAgICB0aGlzLmxvYWRpbmcgPSB0cnVlO1xuICAgICAgICB0aGlzLmVycm9yTWVzc2FnZSA9ICcnO1xuICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gRmV0Y2ggYWxsIGN1bXVsYXRpdmUgcGVyaW9kcyAoYWRtaW4gc2VlcyBhbGwsIG5vbi1hZG1pbiBzZWVzIG9ubHkgY3VzdG9tZXItbGF1bmNoZWQpXG4gICAgICAgICAgICBjb25zdCByZXNwb25zZSA9IChhd2FpdCB0aGlzLnByb2ZpbGVTZXJ2aWNlLmdldEN1bXVsYXRpdmVQZXJpb2RzKHRoaXMucmFpbklkLCB7XG4gICAgICAgICAgICAgICAgcHJvdmlkZXI6IHRoaXMucHJvdmlkZXIsXG4gICAgICAgICAgICAgICAgZm9yY2VkOiB0aGlzLmlzQWRtaW4sXG4gICAgICAgICAgICB9KSkgYXMgUmFhaW5BcGlSYWluc0N1bXVsYXRpdmVzTGlzdFJlc3BvbnNlO1xuXG4gICAgICAgICAgICAvLyBGaWx0ZXIgZm9yIGV4aXN0aW5nIGN1c3RvbSBjdW11bGF0aXZlcyAod2luZG93ID4gMClcbiAgICAgICAgICAgIHRoaXMuYXZhaWxhYmxlUGVyaW9kcyA9IHJlc3BvbnNlLnBlcmlvZHMuZmlsdGVyKChwKSA9PiBwLndpbmRvd0luTWludXRlcyA+IDApO1xuXG4gICAgICAgICAgICAvLyBHZXQgYmFzZSBjdW11bGF0aXZlcyAod2luZG93ID0gMCkgdG8gY2hlY2sgY292ZXJhZ2VcbiAgICAgICAgICAgIHRoaXMuYmFzZUN1bXVsYXRpdmVzID0gcmVzcG9uc2UucGVyaW9kcy5maW5kKChwKSA9PiBwLndpbmRvd0luTWludXRlcyA9PT0gMCk7XG5cbiAgICAgICAgICAgIHRoaXMuY2FsY3VsYXRlQ292ZXJhZ2UoKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgdGhpcy5lcnJvck1lc3NhZ2UgPSAnRmFpbGVkIHRvIGxvYWQgY3VtdWxhdGl2ZSBwZXJpb2RzJztcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGxvYWRpbmcgY3VtdWxhdGl2ZSBwZXJpb2RzOicsIGUpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5sb2FkaW5nID0gZmFsc2U7XG4gICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgIH1cblxuICAgIGNhbGN1bGF0ZUNvdmVyYWdlKCkge1xuICAgICAgICBpZiAoIXRoaXMuYmFzZUN1bXVsYXRpdmVzKSB7XG4gICAgICAgICAgICB0aGlzLmNvdmVyYWdlUGVyY2VudCA9IDA7XG4gICAgICAgICAgICB0aGlzLmNhbkNyZWF0ZU5ldyA9IGZhbHNlO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgYmFzZUJlZ2luID0gbmV3IERhdGUodGhpcy5iYXNlQ3VtdWxhdGl2ZXMucGVyaW9kQmVnaW4pO1xuICAgICAgICBjb25zdCBiYXNlRW5kID0gbmV3IERhdGUodGhpcy5iYXNlQ3VtdWxhdGl2ZXMucGVyaW9kRW5kKTtcblxuICAgICAgICAvLyBDaGVjayBpZiBjdXJyZW50IHBlcmlvZCBpcyB3aXRoaW4gYmFzZSBjb3ZlcmFnZVxuICAgICAgICBjb25zdCBjdXJyZW50SW5SYW5nZSA9XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRQZXJpb2RCZWdpbiA+PSBiYXNlQmVnaW4gJiYgdGhpcy5jdXJyZW50UGVyaW9kRW5kIDw9IGJhc2VFbmQ7XG5cbiAgICAgICAgaWYgKCFjdXJyZW50SW5SYW5nZSkge1xuICAgICAgICAgICAgdGhpcy5jb3ZlcmFnZVBlcmNlbnQgPSAwO1xuICAgICAgICAgICAgdGhpcy5jYW5DcmVhdGVOZXcgPSBmYWxzZTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENhbGN1bGF0ZSBleHBlY3RlZCBudW1iZXIgb2YgYmFzZSBjdW11bGF0aXZlcyBuZWVkZWRcbiAgICAgICAgY29uc3QgZXhwZWN0ZWRDb3VudCA9IE1hdGguY2VpbCh0aGlzLmN1cnJlbnRXaW5kb3dNaW51dGVzIC8gdGhpcy50aW1lU3RlcEluTWludXRlcyk7XG5cbiAgICAgICAgLy8gQ2hlY2sgaWYgZW5vdWdoIGJhc2UgY3VtdWxhdGl2ZXMgZXhpc3RcbiAgICAgICAgLy8gV2UgYXNzdW1lIGNvdmVyYWdlIGlzIGNvbXBsZXRlIGlmIGNvdW50ID49IGV4cGVjdGVkIChzaW1wbGlmaWVkIGNoZWNrKVxuICAgICAgICBpZiAodGhpcy5iYXNlQ3VtdWxhdGl2ZXMuY291bnQgPj0gZXhwZWN0ZWRDb3VudCkge1xuICAgICAgICAgICAgdGhpcy5jb3ZlcmFnZVBlcmNlbnQgPSAxMDA7XG4gICAgICAgICAgICB0aGlzLmNhbkNyZWF0ZU5ldyA9IHRydWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNvdmVyYWdlUGVyY2VudCA9IE1hdGgucm91bmQoKHRoaXMuYmFzZUN1bXVsYXRpdmVzLmNvdW50IC8gZXhwZWN0ZWRDb3VudCkgKiAxMDApO1xuICAgICAgICAgICAgdGhpcy5jYW5DcmVhdGVOZXcgPSB0aGlzLmNvdmVyYWdlUGVyY2VudCA+PSAxMDA7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzZWxlY3RQZXJpb2QocGVyaW9kOiBDdW11bGF0aXZlUGVyaW9kKSB7XG4gICAgICAgIHRoaXMucGVyaW9kU2VsZWN0ZWQuZW1pdCh7XG4gICAgICAgICAgICBwZXJpb2RCZWdpbjogbmV3IERhdGUocGVyaW9kLnBlcmlvZEJlZ2luKSxcbiAgICAgICAgICAgIHBlcmlvZEVuZDogbmV3IERhdGUocGVyaW9kLnBlcmlvZEVuZCksXG4gICAgICAgICAgICB3aW5kb3dJbk1pbnV0ZXM6IHBlcmlvZC53aW5kb3dJbk1pbnV0ZXMsXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGFzeW5jIHRvZ2dsZUV4cGFuZChwZXJpb2Q6IEN1bXVsYXRpdmVQZXJpb2QpIHtcbiAgICAgICAgY29uc3Qga2V5ID0gYCR7cGVyaW9kLndpbmRvd0luTWludXRlc30tJHtwZXJpb2QucHJvdmlkZXJ9YDtcbiAgICAgICAgaWYgKHRoaXMuZXhwYW5kZWRQZXJpb2RzLmhhcyhrZXkpKSB7XG4gICAgICAgICAgICB0aGlzLmV4cGFuZGVkUGVyaW9kcy5kZWxldGUoa2V5KTtcbiAgICAgICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5sb2FkaW5nRXhwYW5kZWQuYWRkKGtleSk7XG4gICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCByZXNwb25zZSA9IChhd2FpdCB0aGlzLnByb2ZpbGVTZXJ2aWNlLmdldEN1bXVsYXRpdmVQZXJpb2RzKHRoaXMucmFpbklkLCB7XG4gICAgICAgICAgICAgICAgcHJvdmlkZXI6IHRoaXMucHJvdmlkZXIsXG4gICAgICAgICAgICAgICAgd2luZG93SW5NaW51dGVzOiBwZXJpb2Qud2luZG93SW5NaW51dGVzLFxuICAgICAgICAgICAgICAgIGZvcmNlZDogdGhpcy5pc0FkbWluLFxuICAgICAgICAgICAgICAgIGRldGFpbGVkOiB0cnVlLFxuICAgICAgICAgICAgfSkpIGFzIFJhYWluQXBpUmFpbnNDdW11bGF0aXZlc0RldGFpbGVkUmVzcG9uc2U7XG5cbiAgICAgICAgICAgIHRoaXMuZXhwYW5kZWRQZXJpb2RzLnNldChrZXksIHJlc3BvbnNlLmN1bXVsYXRpdmVzIHx8IFtdKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgbG9hZGluZyBpbmRpdmlkdWFsIGN1bXVsYXRpdmVzOicsIGUpO1xuICAgICAgICAgICAgdGhpcy5leHBhbmRlZFBlcmlvZHMuc2V0KGtleSwgW10pO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5sb2FkaW5nRXhwYW5kZWQuZGVsZXRlKGtleSk7XG4gICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgIH1cblxuICAgIHNlbGVjdEluZGl2aWR1YWxDdW11bGF0aXZlKGl0ZW06IEluZGl2aWR1YWxDdW11bGF0aXZlKSB7XG4gICAgICAgIGNvbnN0IGVuZERhdGUgPSBuZXcgRGF0ZShpdGVtLmRhdGUpO1xuICAgICAgICBjb25zdCBiZWdpbkRhdGUgPSBuZXcgRGF0ZShlbmREYXRlLmdldFRpbWUoKSAtIGl0ZW0ud2luZG93SW5NaW51dGVzICogNjAwMDApO1xuXG4gICAgICAgIHRoaXMucGVyaW9kU2VsZWN0ZWQuZW1pdCh7XG4gICAgICAgICAgICBwZXJpb2RCZWdpbjogYmVnaW5EYXRlLFxuICAgICAgICAgICAgcGVyaW9kRW5kOiBlbmREYXRlLFxuICAgICAgICAgICAgd2luZG93SW5NaW51dGVzOiBpdGVtLndpbmRvd0luTWludXRlcyxcbiAgICAgICAgICAgIGN1bXVsYXRpdmVJZDogaXRlbS5pZCxcbiAgICAgICAgICAgIGN1bXVsYXRpdmVEYXRlOiBlbmREYXRlLFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBpc0V4cGFuZGVkKHBlcmlvZDogQ3VtdWxhdGl2ZVBlcmlvZCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5leHBhbmRlZFBlcmlvZHMuaGFzKGAke3BlcmlvZC53aW5kb3dJbk1pbnV0ZXN9LSR7cGVyaW9kLnByb3ZpZGVyfWApO1xuICAgIH1cblxuICAgIGlzTG9hZGluZ0V4cGFuZGVkKHBlcmlvZDogQ3VtdWxhdGl2ZVBlcmlvZCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5sb2FkaW5nRXhwYW5kZWQuaGFzKGAke3BlcmlvZC53aW5kb3dJbk1pbnV0ZXN9LSR7cGVyaW9kLnByb3ZpZGVyfWApO1xuICAgIH1cblxuICAgIGdldEV4cGFuZGVkSXRlbXMocGVyaW9kOiBDdW11bGF0aXZlUGVyaW9kKTogSW5kaXZpZHVhbEN1bXVsYXRpdmVbXSB7XG4gICAgICAgIHJldHVybiB0aGlzLmV4cGFuZGVkUGVyaW9kcy5nZXQoYCR7cGVyaW9kLndpbmRvd0luTWludXRlc30tJHtwZXJpb2QucHJvdmlkZXJ9YCkgfHwgW107XG4gICAgfVxuXG4gICAgZ2V0SXRlbVBlcmlvZEJlZ2luKGl0ZW06IEluZGl2aWR1YWxDdW11bGF0aXZlKTogRGF0ZSB7XG4gICAgICAgIGNvbnN0IGVuZERhdGUgPSBuZXcgRGF0ZShpdGVtLmRhdGUpO1xuICAgICAgICByZXR1cm4gbmV3IERhdGUoZW5kRGF0ZS5nZXRUaW1lKCkgLSBpdGVtLndpbmRvd0luTWludXRlcyAqIDYwMDAwKTtcbiAgICB9XG5cbiAgICBhc3luYyBjcmVhdGVOZXdQZXJpb2QoKSB7XG4gICAgICAgIGlmICghdGhpcy5jYW5DcmVhdGVOZXcgfHwgdGhpcy5jcmVhdGluZykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5jcmVhdGluZyA9IHRydWU7XG4gICAgICAgIHRoaXMuY3JlYXRpb25Qcm9ncmVzcyA9ICdTdGFydGluZyBjdW11bGF0aXZlIGNvbXB1dGF0aW9uLi4uJztcbiAgICAgICAgdGhpcy5lcnJvck1lc3NhZ2UgPSAnJztcbiAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIFRyaWdnZXIgY3VtdWxhdGl2ZSBjcmVhdGlvblxuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5wcm9maWxlU2VydmljZS5jcmVhdGVDdW11bGF0aXZlUGVyaW9kKHRoaXMucmFpbklkLCB7XG4gICAgICAgICAgICAgICAgcGVyaW9kQmVnaW46IHRoaXMuY3VycmVudFBlcmlvZEJlZ2luLFxuICAgICAgICAgICAgICAgIHBlcmlvZEVuZDogdGhpcy5jdXJyZW50UGVyaW9kRW5kLFxuICAgICAgICAgICAgICAgIHByb3ZpZGVyOiB0aGlzLnByb3ZpZGVyLFxuICAgICAgICAgICAgICAgIHRpbWVTdGVwSW5NaW51dGVzOiB0aGlzLnRpbWVTdGVwSW5NaW51dGVzLFxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGlmICghcmVzdWx0KSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdGYWlsZWQgdG8gdHJpZ2dlciBjdW11bGF0aXZlIGNvbXB1dGF0aW9uJyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMuY3JlYXRpb25Qcm9ncmVzcyA9IGBKb2JzIHF1ZXVlZC4gUG9sbGluZyBmb3IgY29tcGxldGlvbi4uLmA7XG4gICAgICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcblxuICAgICAgICAgICAgLy8gUG9sbCBmb3IgY29tcGxldGlvblxuICAgICAgICAgICAgY29uc3Qgc3VjY2VzcyA9IGF3YWl0IHRoaXMucG9sbEZvckNvbXBsZXRpb24oKTtcblxuICAgICAgICAgICAgaWYgKHN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnBlcmlvZFNlbGVjdGVkLmVtaXQoe1xuICAgICAgICAgICAgICAgICAgICBwZXJpb2RCZWdpbjogdGhpcy5jdXJyZW50UGVyaW9kQmVnaW4sXG4gICAgICAgICAgICAgICAgICAgIHBlcmlvZEVuZDogdGhpcy5jdXJyZW50UGVyaW9kRW5kLFxuICAgICAgICAgICAgICAgICAgICB3aW5kb3dJbk1pbnV0ZXM6IHRoaXMuY3VycmVudFdpbmRvd01pbnV0ZXMsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuZXJyb3JNZXNzYWdlID0gJ1RpbWVvdXQgd2FpdGluZyBmb3IgY3VtdWxhdGl2ZSBjb21wdXRhdGlvbic7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHRoaXMuZXJyb3JNZXNzYWdlID0gYEVycm9yOiAke2UubWVzc2FnZSB8fCAnVW5rbm93biBlcnJvcid9YDtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGNyZWF0aW5nIGN1bXVsYXRpdmU6JywgZSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmNyZWF0aW5nID0gZmFsc2U7XG4gICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgcG9sbEZvckNvbXBsZXRpb24oKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgICAgIGNvbnN0IHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG5cbiAgICAgICAgd2hpbGUgKERhdGUubm93KCkgLSBzdGFydFRpbWUgPCB0aGlzLlBPTExfVElNRU9VVF9NUykge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBjb25zdCBwcm9ncmVzcyA9IGF3YWl0IHRoaXMucHJvZmlsZVNlcnZpY2UuZ2V0UmFpblByb2dyZXNzKHRoaXMucmFpbklkKTtcblxuICAgICAgICAgICAgICAgIGlmIChwcm9ncmVzcyA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBRdWV1ZSBpcyBlbXB0eSwgY2hlY2sgaWYgY3VtdWxhdGl2ZSBleGlzdHMgKGFkbWluIHNlZXMgYWxsIGN1bXVsYXRpdmVzKVxuICAgICAgICAgICAgICAgICAgICBjb25zdCByZXNwb25zZSA9IChhd2FpdCB0aGlzLnByb2ZpbGVTZXJ2aWNlLmdldEN1bXVsYXRpdmVQZXJpb2RzKHRoaXMucmFpbklkLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwcm92aWRlcjogdGhpcy5wcm92aWRlcixcbiAgICAgICAgICAgICAgICAgICAgICAgIHdpbmRvd0luTWludXRlczogdGhpcy5jdXJyZW50V2luZG93TWludXRlcyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvcmNlZDogdGhpcy5pc0FkbWluLFxuICAgICAgICAgICAgICAgICAgICB9KSkgYXMgUmFhaW5BcGlSYWluc0N1bXVsYXRpdmVzTGlzdFJlc3BvbnNlO1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGZvdW5kID0gcmVzcG9uc2UucGVyaW9kcy5maW5kKFxuICAgICAgICAgICAgICAgICAgICAgICAgKHApID0+IHAud2luZG93SW5NaW51dGVzID09PSB0aGlzLmN1cnJlbnRXaW5kb3dNaW51dGVzXG4gICAgICAgICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGZvdW5kKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IGVsYXBzZWQgPSBNYXRoLnJvdW5kKChEYXRlLm5vdygpIC0gc3RhcnRUaW1lKSAvIDEwMDApO1xuICAgICAgICAgICAgICAgIHRoaXMuY3JlYXRpb25Qcm9ncmVzcyA9IGBDb21wdXRpbmcuLi4gKCR7ZWxhcHNlZH1zLCBxdWV1ZTogJHtwcm9ncmVzc30pYDtcbiAgICAgICAgICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcblxuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuc2xlZXAodGhpcy5QT0xMX0lOVEVSVkFMX01TKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ1BvbGwgZXJyb3I6JywgZSk7XG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5zbGVlcCh0aGlzLlBPTExfSU5URVJWQUxfTVMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHByaXZhdGUgc2xlZXAobXM6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgbXMpKTtcbiAgICB9XG5cbiAgICBjYW5jZWwoKSB7XG4gICAgICAgIHRoaXMuY2FuY2VsbGVkLmVtaXQoKTtcbiAgICB9XG5cbiAgICBmb3JtYXRQZXJpb2QocGVyaW9kOiBDdW11bGF0aXZlUGVyaW9kKTogc3RyaW5nIHtcbiAgICAgICAgY29uc3QgYmVnaW4gPSBuZXcgRGF0ZShwZXJpb2QucGVyaW9kQmVnaW4pO1xuICAgICAgICBjb25zdCBlbmQgPSBuZXcgRGF0ZShwZXJpb2QucGVyaW9kRW5kKTtcbiAgICAgICAgcmV0dXJuIGAke2JlZ2luLnRvTG9jYWxlU3RyaW5nKCl9IOKGkiAke2VuZC50b0xvY2FsZVN0cmluZygpfWA7XG4gICAgfVxuXG4gICAgZm9ybWF0V2luZG93KG1pbnV0ZXM6IG51bWJlcik6IHN0cmluZyB7XG4gICAgICAgIGlmIChtaW51dGVzIDwgNjApIHtcbiAgICAgICAgICAgIHJldHVybiBgJHttaW51dGVzfSBtaW5gO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGhvdXJzID0gbWludXRlcyAvIDYwO1xuICAgICAgICByZXR1cm4gaG91cnMgPT09IDEgPyAnMSBob3VyJyA6IGAke2hvdXJzfSBob3Vyc2A7XG4gICAgfVxufVxuIiwiPGRpdiBjbGFzcz1cImN1bXVsYXRpdmUtc2VsZWN0b3Itb3ZlcmxheVwiPlxuICAgIDxkaXYgY2xhc3M9XCJjdW11bGF0aXZlLXNlbGVjdG9yLW1vZGFsXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJtb2RhbC1oZWFkZXJcIj5cbiAgICAgICAgICAgIDxoMj5TZWxlY3QgQ3VtdWxhdGl2ZSBQZXJpb2Q8L2gyPlxuICAgICAgICAgICAgPGlvbi1idXR0b24gZmlsbD1cImNsZWFyXCIgKGNsaWNrKT1cImNhbmNlbCgpXCI+XG4gICAgICAgICAgICAgICAgPGlvbi1pY29uIG5hbWU9XCJjbG9zZVwiPjwvaW9uLWljb24+XG4gICAgICAgICAgICA8L2lvbi1idXR0b24+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDxkaXYgY2xhc3M9XCJtb2RhbC1jb250ZW50XCI+XG4gICAgICAgICAgICA8IS0tIExvYWRpbmcgc3RhdGUgLS0+XG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwibG9hZGluZ1wiIGNsYXNzPVwibG9hZGluZy1zdGF0ZVwiPlxuICAgICAgICAgICAgICAgIDxpb24tc3Bpbm5lciBuYW1lPVwiY3Jlc2NlbnRcIj48L2lvbi1zcGlubmVyPlxuICAgICAgICAgICAgICAgIDxwPkxvYWRpbmcgYXZhaWxhYmxlIHBlcmlvZHMuLi48L3A+XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPCEtLSBFcnJvciBtZXNzYWdlIC0tPlxuICAgICAgICAgICAgPGRpdiAqbmdJZj1cImVycm9yTWVzc2FnZVwiIGNsYXNzPVwiZXJyb3ItbWVzc2FnZVwiPlxuICAgICAgICAgICAgICAgIDxpb24taWNvbiBuYW1lPVwid2FybmluZy1vdXRsaW5lXCI+PC9pb24taWNvbj5cbiAgICAgICAgICAgICAgICA8c3Bhbj57eyBlcnJvck1lc3NhZ2UgfX08L3NwYW4+XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPCEtLSBBdmFpbGFibGUgcGVyaW9kcyBsaXN0IC0tPlxuICAgICAgICAgICAgPGRpdiAqbmdJZj1cIiFsb2FkaW5nICYmIGF2YWlsYWJsZVBlcmlvZHMubGVuZ3RoID4gMFwiIGNsYXNzPVwicGVyaW9kcy1zZWN0aW9uXCI+XG4gICAgICAgICAgICAgICAgPGgzPkF2YWlsYWJsZSBDdW11bGF0aXZlIFBlcmlvZHM8L2gzPlxuICAgICAgICAgICAgICAgIDxpb24tbGlzdD5cbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgcGVyaW9kIG9mIGF2YWlsYWJsZVBlcmlvZHNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gUGVyaW9kIGhlYWRlciAoY2xpY2sgdG8gZXhwYW5kKSAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxpb24taXRlbSBidXR0b24gKGNsaWNrKT1cInRvZ2dsZUV4cGFuZChwZXJpb2QpXCIgW2Rpc2FibGVkXT1cImNyZWF0aW5nXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlvbi1pY29uIFtuYW1lXT1cImlzRXhwYW5kZWQocGVyaW9kKSA/ICdjaGV2cm9uLWRvd24nIDogJ2NoZXZyb24tZm9yd2FyZCdcIiBzbG90PVwic3RhcnRcIj48L2lvbi1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpb24tbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxoMj57eyBmb3JtYXRXaW5kb3cocGVyaW9kLndpbmRvd0luTWludXRlcykgfX08L2gyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cD57eyBmb3JtYXRQZXJpb2QocGVyaW9kKSB9fTwvcD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJjb3VudC1pbmZvXCI+e3sgcGVyaW9kLmNvdW50IH19IGN1bXVsYXRpdmUocykgLSBjbGljayB0byBleHBhbmQ8L3A+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9pb24tbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2lvbi1pdGVtPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tIEV4cGFuZGVkOiBpbmRpdmlkdWFsIGN1bXVsYXRpdmVzIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cImlzRXhwYW5kZWQocGVyaW9kKVwiIGNsYXNzPVwiZXhwYW5kZWQtaXRlbXNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW9uLXNwaW5uZXIgKm5nSWY9XCJpc0xvYWRpbmdFeHBhbmRlZChwZXJpb2QpXCIgbmFtZT1cImNyZXNjZW50XCI+PC9pb24tc3Bpbm5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW9uLWxpc3QgKm5nSWY9XCIhaXNMb2FkaW5nRXhwYW5kZWQocGVyaW9kKVwiIGNsYXNzPVwibmVzdGVkLWxpc3RcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlvbi1pdGVtICpuZ0Zvcj1cImxldCBpdGVtIG9mIGdldEV4cGFuZGVkSXRlbXMocGVyaW9kKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidXR0b25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJzZWxlY3RJbmRpdmlkdWFsQ3VtdWxhdGl2ZShpdGVtKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIm5lc3RlZC1pdGVtXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJjcmVhdGluZ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlvbi1pY29uIG5hbWU9XCJ0aW1lLW91dGxpbmVcIiBzbG90PVwic3RhcnRcIj48L2lvbi1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlvbi1sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aDM+e3sgZ2V0SXRlbVBlcmlvZEJlZ2luKGl0ZW0pIHwgZGF0ZTonSEg6bW0nIH19IC0ge3sgaXRlbS5kYXRlIHwgZGF0ZTonSEg6bW0nIH19PC9oMz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvaW9uLWxhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlvbi1pY29uIG5hbWU9XCJjaGV2cm9uLWZvcndhcmRcIiBzbG90PVwiZW5kXCI+PC9pb24taWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9pb24taXRlbT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlvbi1pdGVtICpuZ0lmPVwiZ2V0RXhwYW5kZWRJdGVtcyhwZXJpb2QpLmxlbmd0aCA9PT0gMFwiIGNsYXNzPVwibmVzdGVkLWl0ZW1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpb24tbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHA+Tm8gaW5kaXZpZHVhbCBjdW11bGF0aXZlcyBmb3VuZDwvcD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvaW9uLWxhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2lvbi1pdGVtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvaW9uLWxpc3Q+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgPC9pb24tbGlzdD5cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8IS0tIE5vIHBlcmlvZHMgYXZhaWxhYmxlIC0tPlxuICAgICAgICAgICAgPGRpdiAqbmdJZj1cIiFsb2FkaW5nICYmIGF2YWlsYWJsZVBlcmlvZHMubGVuZ3RoID09PSAwXCIgY2xhc3M9XCJuby1wZXJpb2RzXCI+XG4gICAgICAgICAgICAgICAgPGlvbi1pY29uIG5hbWU9XCJpbmZvcm1hdGlvbi1jaXJjbGUtb3V0bGluZVwiPjwvaW9uLWljb24+XG4gICAgICAgICAgICAgICAgPHA+Tm8gY3VtdWxhdGl2ZSBwZXJpb2RzIGF2YWlsYWJsZSB5ZXQuPC9wPlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDwhLS0gQ3JlYXRlIG5ldyBzZWN0aW9uIChhZG1pbiBvbmx5KSAtLT5cbiAgICAgICAgICAgIDxkaXYgKm5nSWY9XCIhbG9hZGluZyAmJiBpc0FkbWluXCIgY2xhc3M9XCJjcmVhdGUtc2VjdGlvblwiPlxuICAgICAgICAgICAgICAgIDxoMz5DcmVhdGUgTmV3IEN1bXVsYXRpdmU8L2gzPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjcmVhdGUtaW5mb1wiPlxuICAgICAgICAgICAgICAgICAgICA8cD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzdHJvbmc+UGVyaW9kOjwvc3Ryb25nPlxuICAgICAgICAgICAgICAgICAgICAgICAge3sgY3VycmVudFBlcmlvZEJlZ2luPy50b0xvY2FsZVN0cmluZygpIH19IOKGkiB7eyBjdXJyZW50UGVyaW9kRW5kPy50b0xvY2FsZVN0cmluZygpIH19XG4gICAgICAgICAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICAgICAgICAgICAgPHA+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3Ryb25nPldpbmRvdzo8L3N0cm9uZz4ge3sgZm9ybWF0V2luZG93KGN1cnJlbnRXaW5kb3dNaW51dGVzKSB9fVxuICAgICAgICAgICAgICAgICAgICA8L3A+XG4gICAgICAgICAgICAgICAgICAgIDxwICpuZ0lmPVwiYmFzZUN1bXVsYXRpdmVzXCIgY2xhc3M9XCJjb3ZlcmFnZS1pbmZvXCJcbiAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzLmNvdmVyYWdlLW9rXT1cImNvdmVyYWdlUGVyY2VudCA+PSAxMDBcIlxuICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3MuY292ZXJhZ2Utd2Fybl09XCJjb3ZlcmFnZVBlcmNlbnQgPiAwICYmIGNvdmVyYWdlUGVyY2VudCA8IDEwMFwiXG4gICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5jb3ZlcmFnZS1lcnJvcl09XCJjb3ZlcmFnZVBlcmNlbnQgPT09IDBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxpb24taWNvbiBbbmFtZV09XCJjb3ZlcmFnZVBlcmNlbnQgPj0gMTAwID8gJ2NoZWNrbWFyay1jaXJjbGUnIDogJ2FsZXJ0LWNpcmNsZSdcIj48L2lvbi1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgQmFzZSBkYXRhIGNvdmVyYWdlOiB7eyBjb3ZlcmFnZVBlcmNlbnQgfX0lXG4gICAgICAgICAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICAgICAgICAgICAgPHAgKm5nSWY9XCIhYmFzZUN1bXVsYXRpdmVzXCIgY2xhc3M9XCJjb3ZlcmFnZS1lcnJvclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGlvbi1pY29uIG5hbWU9XCJhbGVydC1jaXJjbGVcIj48L2lvbi1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgTm8gYmFzZSBjdW11bGF0aXZlcyBhdmFpbGFibGVcbiAgICAgICAgICAgICAgICAgICAgPC9wPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgPCEtLSBDcmVhdGlvbiBwcm9ncmVzcyAtLT5cbiAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiY3JlYXRpbmdcIiBjbGFzcz1cImNyZWF0aW9uLXByb2dyZXNzXCI+XG4gICAgICAgICAgICAgICAgICAgIDxpb24tc3Bpbm5lciBuYW1lPVwiY3Jlc2NlbnRcIj48L2lvbi1zcGlubmVyPlxuICAgICAgICAgICAgICAgICAgICA8c3Bhbj57eyBjcmVhdGlvblByb2dyZXNzIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgPGlvbi1idXR0b24gW2Rpc2FibGVkXT1cIiFjYW5DcmVhdGVOZXcgfHwgY3JlYXRpbmdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGFuZD1cImJsb2NrXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiY3JlYXRlTmV3UGVyaW9kKClcIj5cbiAgICAgICAgICAgICAgICAgICAgPGlvbi1pY29uIG5hbWU9XCJhZGQtY2lyY2xlLW91dGxpbmVcIiBzbG90PVwic3RhcnRcIj48L2lvbi1pY29uPlxuICAgICAgICAgICAgICAgICAgICBDcmVhdGUge3sgZm9ybWF0V2luZG93KGN1cnJlbnRXaW5kb3dNaW51dGVzKSB9fSBDdW11bGF0aXZlXG4gICAgICAgICAgICAgICAgPC9pb24tYnV0dG9uPlxuXG4gICAgICAgICAgICAgICAgPHAgKm5nSWY9XCIhY2FuQ3JlYXRlTmV3ICYmICFjcmVhdGluZ1wiIGNsYXNzPVwiY3JlYXRlLWhpbnRcIj5cbiAgICAgICAgICAgICAgICAgICAgQ3JlYXRlIGlzIGRpc2FibGVkIGJlY2F1c2UgYmFzZSA1LW1pbiBjdW11bGF0aXZlcyBkb24ndCBmdWxseSBjb3ZlciB0aGUgc2VsZWN0ZWQgcGVyaW9kLlxuICAgICAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8ZGl2IGNsYXNzPVwibW9kYWwtZm9vdGVyXCI+XG4gICAgICAgICAgICA8aW9uLWJ1dHRvbiBmaWxsPVwib3V0bGluZVwiIChjbGljayk9XCJjYW5jZWwoKVwiIFtkaXNhYmxlZF09XCJjcmVhdGluZ1wiPlxuICAgICAgICAgICAgICAgIENhbmNlbFxuICAgICAgICAgICAgPC9pb24tYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbjwvZGl2PlxuIl19
244
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3VtdWxhdGl2ZS1zZWxlY3Rvci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY29yZS9zaGFyZWQvY3VtdWxhdGl2ZS1zZWxlY3Rvci9jdW11bGF0aXZlLXNlbGVjdG9yLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uL3NyYy9jb3JlL3NoYXJlZC9jdW11bGF0aXZlLXNlbGVjdG9yL2N1bXVsYXRpdmUtc2VsZWN0b3IuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNILHVCQUF1QixFQUV2QixTQUFTLEVBQ1QsWUFBWSxFQUNaLEtBQUssRUFFTCxNQUFNLEdBQ1QsTUFBTSxlQUFlLENBQUM7Ozs7O0FBdUJ2QixNQUFNLE9BQU8sMkJBQTJCO0lBNEJwQyxZQUNZLGNBQThCLEVBQzlCLEdBQXNCO1FBRHRCLG1CQUFjLEdBQWQsY0FBYyxDQUFnQjtRQUM5QixRQUFHLEdBQUgsR0FBRyxDQUFtQjtRQXpCekIsc0JBQWlCLEdBQVcsQ0FBQyxDQUFDO1FBQzlCLFlBQU8sR0FBWSxLQUFLLENBQUM7UUFFeEIsbUJBQWMsR0FBRyxJQUFJLFlBQVksRUFBdUIsQ0FBQztRQUN6RCxjQUFTLEdBQUcsSUFBSSxZQUFZLEVBQVEsQ0FBQztRQUUvQyxxQkFBZ0IsR0FBdUIsRUFBRSxDQUFDO1FBQzFDLG9CQUFlLEdBQXFCLElBQUksQ0FBQztRQUN6QyxZQUFPLEdBQUcsSUFBSSxDQUFDO1FBQ2YsYUFBUSxHQUFHLEtBQUssQ0FBQztRQUNqQixxQkFBZ0IsR0FBRyxFQUFFLENBQUM7UUFDdEIsaUJBQVksR0FBRyxFQUFFLENBQUM7UUFFbEIsb0JBQWUsR0FBRyxDQUFDLENBQUM7UUFDcEIsaUJBQVksR0FBRyxLQUFLLENBQUM7UUFDckIseUJBQW9CLEdBQUcsQ0FBQyxDQUFDO1FBRXpCLG9CQUFlLEdBQXdDLElBQUksR0FBRyxFQUFFLENBQUM7UUFDakUsb0JBQWUsR0FBZ0IsSUFBSSxH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YztzQkFBdkIsTUFBTTtnQkFDRyxTQUFTO3NCQUFsQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBDb21wb25lbnQsXG4gICAgRXZlbnRFbWl0dGVyLFxuICAgIElucHV0LFxuICAgIE9uSW5pdCxcbiAgICBPdXRwdXQsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtQcm9maWxlU2VydmljZX0gZnJvbSAnLi4vcHJvZmlsZS5zZXJ2aWNlJztcbmltcG9ydCB7XG4gICAgQ3VtdWxhdGl2ZVBlcmlvZCxcbiAgICBJbmRpdmlkdWFsQ3VtdWxhdGl2ZSxcbiAgICBSYWFpbkFwaVJhaW5zQ3VtdWxhdGl2ZXNEZXRhaWxlZFJlc3BvbnNlLFxuICAgIFJhYWluQXBpUmFpbnNDdW11bGF0aXZlc0xpc3RSZXNwb25zZSxcbn0gZnJvbSAncmFhaW4tbW9kZWwnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEN1bXVsYXRpdmVTZWxlY3Rpb24ge1xuICAgIHBlcmlvZEJlZ2luOiBEYXRlO1xuICAgIHBlcmlvZEVuZDogRGF0ZTtcbiAgICB3aW5kb3dJbk1pbnV0ZXM6IG51bWJlcjtcbiAgICBjdW11bGF0aXZlSWQ/OiBzdHJpbmc7XG4gICAgY3VtdWxhdGl2ZURhdGU/OiBEYXRlO1xufVxuXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ2N1bXVsYXRpdmUtc2VsZWN0b3InLFxuICAgIHRlbXBsYXRlVXJsOiAnLi9jdW11bGF0aXZlLXNlbGVjdG9yLmNvbXBvbmVudC5odG1sJyxcbiAgICBzdHlsZVVybHM6IFsnLi9jdW11bGF0aXZlLXNlbGVjdG9yLmNvbXBvbmVudC5zY3NzJ10sXG4gICAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG59KVxuZXhwb3J0IGNsYXNzIEN1bXVsYXRpdmVTZWxlY3RvckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gICAgQElucHV0KCkgcmFpbklkOiBzdHJpbmc7XG4gICAgQElucHV0KCkgY3VycmVudFBlcmlvZEJlZ2luOiBEYXRlO1xuICAgIEBJbnB1dCgpIGN1cnJlbnRQZXJpb2RFbmQ6IERhdGU7XG4gICAgQElucHV0KCkgcHJvdmlkZXI6IHN0cmluZztcbiAgICBASW5wdXQoKSB0aW1lU3RlcEluTWludXRlczogbnVtYmVyID0gNTtcbiAgICBASW5wdXQoKSBpc0FkbWluOiBib29sZWFuID0gZmFsc2U7XG5cbiAgICBAT3V0cHV0KCkgcGVyaW9kU2VsZWN0ZWQgPSBuZXcgRXZlbnRFbWl0dGVyPEN1bXVsYXRpdmVTZWxlY3Rpb24+KCk7XG4gICAgQE91dHB1dCgpIGNhbmNlbGxlZCA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcblxuICAgIGF2YWlsYWJsZVBlcmlvZHM6IEN1bXVsYXRpdmVQZXJpb2RbXSA9IFtdO1xuICAgIGJhc2VDdW11bGF0aXZlczogQ3VtdWxhdGl2ZVBlcmlvZCA9IG51bGw7XG4gICAgbG9hZGluZyA9IHRydWU7XG4gICAgY3JlYXRpbmcgPSBmYWxzZTtcbiAgICBjcmVhdGlvblByb2dyZXNzID0gJyc7XG4gICAgZXJyb3JNZXNzYWdlID0gJyc7XG5cbiAgICBjb3ZlcmFnZVBlcmNlbnQgPSAwO1xuICAgIGNhbkNyZWF0ZU5ldyA9IGZhbHNlO1xuICAgIGN1cnJlbnRXaW5kb3dNaW51dGVzID0gMDtcblxuICAgIGV4cGFuZGVkUGVyaW9kczogTWFwPHN0cmluZywgSW5kaXZpZHVhbEN1bXVsYXRpdmVbXT4gPSBuZXcgTWFwKCk7XG4gICAgbG9hZGluZ0V4cGFuZGVkOiBTZXQ8c3RyaW5nPiA9IG5ldyBTZXQoKTtcblxuICAgIHByaXZhdGUgcmVhZG9ubHkgUE9MTF9USU1FT1VUX01TID0gOTAwMDAwOyAvLyA5MDAgc2Vjb25kc1xuICAgIHByaXZhdGUgcmVhZG9ubHkgUE9MTF9JTlRFUlZBTF9NUyA9IDMwMDA7XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJpdmF0ZSBwcm9maWxlU2VydmljZTogUHJvZmlsZVNlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgY2RyOiBDaGFuZ2VEZXRlY3RvclJlZlxuICAgICkge31cblxuICAgIGFzeW5jIG5nT25Jbml0KCkge1xuICAgICAgICB0aGlzLmN1cnJlbnRXaW5kb3dNaW51dGVzID0gTWF0aC5yb3VuZChcbiAgICAgICAgICAgICh0aGlzLmN1cnJlbnRQZXJpb2RFbmQuZ2V0VGltZSgpIC0gdGhpcy5jdXJyZW50UGVyaW9kQmVnaW4uZ2V0VGltZSgpKSAvIDYwMDAwXG4gICAgICAgICk7XG4gICAgICAgIGF3YWl0IHRoaXMubG9hZEF2YWlsYWJsZVBlcmlvZHMoKTtcbiAgICB9XG5cbiAgICBhc3luYyBsb2FkQXZhaWxhYmxlUGVyaW9kcygpIHtcbiAgICAgICAgdGhpcy5sb2FkaW5nID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5lcnJvck1lc3NhZ2UgPSAnJztcbiAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIEZldGNoIGFsbCBjdW11bGF0aXZlIHBlcmlvZHMgKGFkbWluIHNlZXMgYWxsLCBub24tYWRtaW4gc2VlcyBvbmx5IGN1c3RvbWVyLWxhdW5jaGVkKVxuICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSAoYXdhaXQgdGhpcy5wcm9maWxlU2VydmljZS5nZXRDdW11bGF0aXZlUGVyaW9kcyh0aGlzLnJhaW5JZCwge1xuICAgICAgICAgICAgICAgIHByb3ZpZGVyOiB0aGlzLnByb3ZpZGVyLFxuICAgICAgICAgICAgICAgIGZvcmNlZDogdGhpcy5pc0FkbWluLFxuICAgICAgICAgICAgICAgIHBlcmlvZEJlZ2luOiB0aGlzLmN1cnJlbnRQZXJpb2RCZWdpbi50b0lTT1N0cmluZygpLFxuICAgICAgICAgICAgICAgIHBlcmlvZEVuZDogdGhpcy5jdXJyZW50UGVyaW9kRW5kLnRvSVNPU3RyaW5nKCksXG4gICAgICAgICAgICB9KSkgYXMgUmFhaW5BcGlSYWluc0N1bXVsYXRpdmVzTGlzdFJlc3BvbnNlO1xuXG4gICAgICAgICAgICAvLyBGaWx0ZXIgZm9yIGV4aXN0aW5nIGN1c3RvbSBjdW11bGF0aXZlcyAod2luZG93ID4gMClcbiAgICAgICAgICAgIHRoaXMuYXZhaWxhYmxlUGVyaW9kcyA9IHJlc3BvbnNlLnBlcmlvZHMuZmlsdGVyKChwKSA9PiBwLndpbmRvd0luTWludXRlcyA+IDApO1xuXG4gICAgICAgICAgICAvLyBHZXQgYmFzZSBjdW11bGF0aXZlcyAod2luZG93ID0gMCkgdG8gY2hlY2sgY292ZXJhZ2VcbiAgICAgICAgICAgIHRoaXMuYmFzZUN1bXVsYXRpdmVzID0gcmVzcG9uc2UucGVyaW9kcy5maW5kKChwKSA9PiBwLndpbmRvd0luTWludXRlcyA9PT0gMCk7XG5cbiAgICAgICAgICAgIHRoaXMuY2FsY3VsYXRlQ292ZXJhZ2UoKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgdGhpcy5lcnJvck1lc3NhZ2UgPSAnRmFpbGVkIHRvIGxvYWQgY3VtdWxhdGl2ZSBwZXJpb2RzJztcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGxvYWRpbmcgY3VtdWxhdGl2ZSBwZXJpb2RzOicsIGUpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5sb2FkaW5nID0gZmFsc2U7XG4gICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgIH1cblxuICAgIGNhbGN1bGF0ZUNvdmVyYWdlKCkge1xuICAgICAgICBpZiAoIXRoaXMuYmFzZUN1bXVsYXRpdmVzIHx8ICF0aGlzLmJhc2VDdW11bGF0aXZlcy5jb3VudCkge1xuICAgICAgICAgICAgdGhpcy5jb3ZlcmFnZVBlcmNlbnQgPSAwO1xuICAgICAgICAgICAgdGhpcy5jYW5DcmVhdGVOZXcgPSBmYWxzZTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENhbGN1bGF0ZSBleHBlY3RlZCBudW1iZXIgb2YgYmFzZSBjdW11bGF0aXZlcyAoYWx3YXlzIDUtbWluIGdyYW51bGFyaXR5KVxuICAgICAgICBjb25zdCBiYXNlVGltZVN0ZXAgPSA1O1xuICAgICAgICBjb25zdCBleHBlY3RlZENvdW50ID0gTWF0aC5jZWlsKHRoaXMuY3VycmVudFdpbmRvd01pbnV0ZXMgLyBiYXNlVGltZVN0ZXApO1xuXG4gICAgICAgIGlmICh0aGlzLmJhc2VDdW11bGF0aXZlcy5jb3VudCA+PSBleHBlY3RlZENvdW50KSB7XG4gICAgICAgICAgICB0aGlzLmNvdmVyYWdlUGVyY2VudCA9IDEwMDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY292ZXJhZ2VQZXJjZW50ID0gTWF0aC5yb3VuZCgodGhpcy5iYXNlQ3VtdWxhdGl2ZXMuY291bnQgLyBleHBlY3RlZENvdW50KSAqIDEwMCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBBbGxvdyBjcmVhdGlvbiBhcyBsb25nIGFzIHNvbWUgYmFzZSBkYXRhIGV4aXN0c1xuICAgICAgICB0aGlzLmNhbkNyZWF0ZU5ldyA9IHRoaXMuY292ZXJhZ2VQZXJjZW50ID4gMDtcbiAgICB9XG5cbiAgICBzZWxlY3RQZXJpb2QocGVyaW9kOiBDdW11bGF0aXZlUGVyaW9kKSB7XG4gICAgICAgIHRoaXMucGVyaW9kU2VsZWN0ZWQuZW1pdCh7XG4gICAgICAgICAgICBwZXJpb2RCZWdpbjogbmV3IERhdGUocGVyaW9kLnBlcmlvZEJlZ2luKSxcbiAgICAgICAgICAgIHBlcmlvZEVuZDogbmV3IERhdGUocGVyaW9kLnBlcmlvZEVuZCksXG4gICAgICAgICAgICB3aW5kb3dJbk1pbnV0ZXM6IHBlcmlvZC53aW5kb3dJbk1pbnV0ZXMsXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGFzeW5jIHRvZ2dsZUV4cGFuZChwZXJpb2Q6IEN1bXVsYXRpdmVQZXJpb2QpIHtcbiAgICAgICAgY29uc3Qga2V5ID0gYCR7cGVyaW9kLndpbmRvd0luTWludXRlc31gO1xuICAgICAgICBpZiAodGhpcy5leHBhbmRlZFBlcmlvZHMuaGFzKGtleSkpIHtcbiAgICAgICAgICAgIHRoaXMuZXhwYW5kZWRQZXJpb2RzLmRlbGV0ZShrZXkpO1xuICAgICAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmxvYWRpbmdFeHBhbmRlZC5hZGQoa2V5KTtcbiAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gKGF3YWl0IHRoaXMucHJvZmlsZVNlcnZpY2UuZ2V0Q3VtdWxhdGl2ZVBlcmlvZHModGhpcy5yYWluSWQsIHtcbiAgICAgICAgICAgICAgICBwcm92aWRlcjogdGhpcy5wcm92aWRlcixcbiAgICAgICAgICAgICAgICB3aW5kb3dJbk1pbnV0ZXM6IHBlcmlvZC53aW5kb3dJbk1pbnV0ZXMsXG4gICAgICAgICAgICAgICAgZm9yY2VkOiB0aGlzLmlzQWRtaW4sXG4gICAgICAgICAgICAgICAgZGV0YWlsZWQ6IHRydWUsXG4gICAgICAgICAgICB9KSkgYXMgUmFhaW5BcGlSYWluc0N1bXVsYXRpdmVzRGV0YWlsZWRSZXNwb25zZTtcblxuICAgICAgICAgICAgdGhpcy5leHBhbmRlZFBlcmlvZHMuc2V0KGtleSwgcmVzcG9uc2UuY3VtdWxhdGl2ZXMgfHwgW10pO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBsb2FkaW5nIGluZGl2aWR1YWwgY3VtdWxhdGl2ZXM6JywgZSk7XG4gICAgICAgICAgICB0aGlzLmV4cGFuZGVkUGVyaW9kcy5zZXQoa2V5LCBbXSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmxvYWRpbmdFeHBhbmRlZC5kZWxldGUoa2V5KTtcbiAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfVxuXG4gICAgc2VsZWN0SW5kaXZpZHVhbEN1bXVsYXRpdmUoaXRlbTogSW5kaXZpZHVhbEN1bXVsYXRpdmUpIHtcbiAgICAgICAgY29uc3QgZW5kRGF0ZSA9IG5ldyBEYXRlKGl0ZW0uZGF0ZSk7XG4gICAgICAgIGNvbnN0IGJlZ2luRGF0ZSA9IG5ldyBEYXRlKGVuZERhdGUuZ2V0VGltZSgpIC0gaXRlbS53aW5kb3dJbk1pbnV0ZXMgKiA2MDAwMCk7XG5cbiAgICAgICAgdGhpcy5wZXJpb2RTZWxlY3RlZC5lbWl0KHtcbiAgICAgICAgICAgIHBlcmlvZEJlZ2luOiBiZWdpbkRhdGUsXG4gICAgICAgICAgICBwZXJpb2RFbmQ6IGVuZERhdGUsXG4gICAgICAgICAgICB3aW5kb3dJbk1pbnV0ZXM6IGl0ZW0ud2luZG93SW5NaW51dGVzLFxuICAgICAgICAgICAgY3VtdWxhdGl2ZUlkOiBpdGVtLmlkLFxuICAgICAgICAgICAgY3VtdWxhdGl2ZURhdGU6IGVuZERhdGUsXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGlzRXhwYW5kZWQocGVyaW9kOiBDdW11bGF0aXZlUGVyaW9kKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLmV4cGFuZGVkUGVyaW9kcy5oYXMoYCR7cGVyaW9kLndpbmRvd0luTWludXRlc31gKTtcbiAgICB9XG5cbiAgICBpc0xvYWRpbmdFeHBhbmRlZChwZXJpb2Q6IEN1bXVsYXRpdmVQZXJpb2QpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubG9hZGluZ0V4cGFuZGVkLmhhcyhgJHtwZXJpb2Qud2luZG93SW5NaW51dGVzfWApO1xuICAgIH1cblxuICAgIGdldEV4cGFuZGVkSXRlbXMocGVyaW9kOiBDdW11bGF0aXZlUGVyaW9kKTogSW5kaXZpZHVhbEN1bXVsYXRpdmVbXSB7XG4gICAgICAgIHJldHVybiB0aGlzLmV4cGFuZGVkUGVyaW9kcy5nZXQoYCR7cGVyaW9kLndpbmRvd0luTWludXRlc31gKSB8fCBbXTtcbiAgICB9XG5cbiAgICBnZXRJdGVtUGVyaW9kQmVnaW4oaXRlbTogSW5kaXZpZHVhbEN1bXVsYXRpdmUpOiBEYXRlIHtcbiAgICAgICAgY29uc3QgZW5kRGF0ZSA9IG5ldyBEYXRlKGl0ZW0uZGF0ZSk7XG4gICAgICAgIHJldHVybiBuZXcgRGF0ZShlbmREYXRlLmdldFRpbWUoKSAtIGl0ZW0ud2luZG93SW5NaW51dGVzICogNjAwMDApO1xuICAgIH1cblxuICAgIGFzeW5jIGNyZWF0ZU5ld1BlcmlvZCgpIHtcbiAgICAgICAgaWYgKCF0aGlzLmNhbkNyZWF0ZU5ldyB8fCB0aGlzLmNyZWF0aW5nKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmNyZWF0aW5nID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5jcmVhdGlvblByb2dyZXNzID0gJ1N0YXJ0aW5nIGN1bXVsYXRpdmUgY29tcHV0YXRpb24uLi4nO1xuICAgICAgICB0aGlzLmVycm9yTWVzc2FnZSA9ICcnO1xuICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gVHJpZ2dlciBjdW11bGF0aXZlIGNyZWF0aW9uXG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLnByb2ZpbGVTZXJ2aWNlLmNyZWF0ZUN1bXVsYXRpdmVQZXJpb2QodGhpcy5yYWluSWQsIHtcbiAgICAgICAgICAgICAgICBwZXJpb2RCZWdpbjogdGhpcy5jdXJyZW50UGVyaW9kQmVnaW4sXG4gICAgICAgICAgICAgICAgcGVyaW9kRW5kOiB0aGlzLmN1cnJlbnRQZXJpb2RFbmQsXG4gICAgICAgICAgICAgICAgcHJvdmlkZXI6IHRoaXMucHJvdmlkZXIsXG4gICAgICAgICAgICAgICAgdGltZVN0ZXBJbk1pbnV0ZXM6IHRoaXMudGltZVN0ZXBJbk1pbnV0ZXMsXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgaWYgKCFyZXN1bHQpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZhaWxlZCB0byB0cmlnZ2VyIGN1bXVsYXRpdmUgY29tcHV0YXRpb24nKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5jcmVhdGlvblByb2dyZXNzID0gYEpvYnMgcXVldWVkLiBQb2xsaW5nIGZvciBjb21wbGV0aW9uLi4uYDtcbiAgICAgICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuXG4gICAgICAgICAgICAvLyBQb2xsIGZvciBjb21wbGV0aW9uXG4gICAgICAgICAgICBjb25zdCBzdWNjZXNzID0gYXdhaXQgdGhpcy5wb2xsRm9yQ29tcGxldGlvbigpO1xuXG4gICAgICAgICAgICBpZiAoc3VjY2Vzcykge1xuICAgICAgICAgICAgICAgIHRoaXMucGVyaW9kU2VsZWN0ZWQuZW1pdCh7XG4gICAgICAgICAgICAgICAgICAgIHBlcmlvZEJlZ2luOiB0aGlzLmN1cnJlbnRQZXJpb2RCZWdpbixcbiAgICAgICAgICAgICAgICAgICAgcGVyaW9kRW5kOiB0aGlzLmN1cnJlbnRQZXJpb2RFbmQsXG4gICAgICAgICAgICAgICAgICAgIHdpbmRvd0luTWludXRlczogdGhpcy5jdXJyZW50V2luZG93TWludXRlcyxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lcnJvck1lc3NhZ2UgPSAnVGltZW91dCB3YWl0aW5nIGZvciBjdW11bGF0aXZlIGNvbXB1dGF0aW9uJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgdGhpcy5lcnJvck1lc3NhZ2UgPSBgRXJyb3I6ICR7ZS5tZXNzYWdlIHx8ICdVbmtub3duIGVycm9yJ31gO1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgY3JlYXRpbmcgY3VtdWxhdGl2ZTonLCBlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY3JlYXRpbmcgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBwb2xsRm9yQ29tcGxldGlvbigpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICAgICAgY29uc3Qgc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcblxuICAgICAgICB3aGlsZSAoRGF0ZS5ub3coKSAtIHN0YXJ0VGltZSA8IHRoaXMuUE9MTF9USU1FT1VUX01TKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHByb2dyZXNzID0gYXdhaXQgdGhpcy5wcm9maWxlU2VydmljZS5nZXRSYWluUHJvZ3Jlc3ModGhpcy5yYWluSWQpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHByb2dyZXNzID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFRyaWdnZXIgYmFja2dyb3VuZCBmZXRjaCBmcm9tIHJhYWluLWdyb3VuZCB2aWEgdGltZWZyYW1lQ3VtdWxhdGl2ZVxuICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnByb2ZpbGVTZXJ2aWNlLmdldFJhaW5UaW1lZnJhbWUoXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJhaW5JZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudFBlcmlvZEJlZ2luLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50UGVyaW9kRW5kLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0FkbWluLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm92aWRlcixcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudGltZVN0ZXBJbk1pbnV0ZXMsXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRXaW5kb3dNaW51dGVzXG4gICAgICAgICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgY3VtdWxhdGl2ZSBub3cgZXhpc3RzIChhZG1pbiBzZWVzIGFsbCBjdW11bGF0aXZlcylcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSAoYXdhaXQgdGhpcy5wcm9maWxlU2VydmljZS5nZXRDdW11bGF0aXZlUGVyaW9kcyh0aGlzLnJhaW5JZCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgcHJvdmlkZXI6IHRoaXMucHJvdmlkZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3dJbk1pbnV0ZXM6IHRoaXMuY3VycmVudFdpbmRvd01pbnV0ZXMsXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3JjZWQ6IHRoaXMuaXNBZG1pbixcbiAgICAgICAgICAgICAgICAgICAgfSkpIGFzIFJhYWluQXBpUmFpbnNDdW11bGF0aXZlc0xpc3RSZXNwb25zZTtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBmb3VuZCA9IHJlc3BvbnNlLnBlcmlvZHMuZmluZChcbiAgICAgICAgICAgICAgICAgICAgICAgIChwKSA9PiBwLndpbmRvd0luTWludXRlcyA9PT0gdGhpcy5jdXJyZW50V2luZG93TWludXRlc1xuICAgICAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChmb3VuZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjb25zdCBlbGFwc2VkID0gTWF0aC5yb3VuZCgoRGF0ZS5ub3coKSAtIHN0YXJ0VGltZSkgLyAxMDAwKTtcbiAgICAgICAgICAgICAgICB0aGlzLmNyZWF0aW9uUHJvZ3Jlc3MgPSBgQ29tcHV0aW5nLi4uICgke2VsYXBzZWR9cywgcXVldWU6ICR7cHJvZ3Jlc3N9KWA7XG4gICAgICAgICAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG5cbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnNsZWVwKHRoaXMuUE9MTF9JTlRFUlZBTF9NUyk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdQb2xsIGVycm9yOicsIGUpO1xuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuc2xlZXAodGhpcy5QT0xMX0lOVEVSVkFMX01TKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHNsZWVwKG1zOiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIG1zKSk7XG4gICAgfVxuXG4gICAgY2FuY2VsKCkge1xuICAgICAgICB0aGlzLmNhbmNlbGxlZC5lbWl0KCk7XG4gICAgfVxuXG4gICAgZm9ybWF0UGVyaW9kKHBlcmlvZDogQ3VtdWxhdGl2ZVBlcmlvZCk6IHN0cmluZyB7XG4gICAgICAgIGNvbnN0IGJlZ2luID0gbmV3IERhdGUocGVyaW9kLnBlcmlvZEJlZ2luKTtcbiAgICAgICAgY29uc3QgZW5kID0gbmV3IERhdGUocGVyaW9kLnBlcmlvZEVuZCk7XG4gICAgICAgIHJldHVybiBgJHtiZWdpbi50b0xvY2FsZVN0cmluZygpfSDihpIgJHtlbmQudG9Mb2NhbGVTdHJpbmcoKX1gO1xuICAgIH1cblxuICAgIGZvcm1hdFdpbmRvdyhtaW51dGVzOiBudW1iZXIpOiBzdHJpbmcge1xuICAgICAgICBpZiAobWludXRlcyA8IDYwKSB7XG4gICAgICAgICAgICByZXR1cm4gYCR7bWludXRlc30gbWluYDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBob3VycyA9IG1pbnV0ZXMgLyA2MDtcbiAgICAgICAgcmV0dXJuIGhvdXJzID09PSAxID8gJzEgaG91cicgOiBgJHtob3Vyc30gaG91cnNgO1xuICAgIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJjdW11bGF0aXZlLXNlbGVjdG9yLW92ZXJsYXlcIj5cbiAgICA8ZGl2IGNsYXNzPVwiY3VtdWxhdGl2ZS1zZWxlY3Rvci1tb2RhbFwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwibW9kYWwtaGVhZGVyXCI+XG4gICAgICAgICAgICA8aDI+U2VsZWN0IEN1bXVsYXRpdmUgUGVyaW9kPC9oMj5cbiAgICAgICAgICAgIDxpb24tYnV0dG9uIChjbGljayk9XCJjYW5jZWwoKVwiIGZpbGw9XCJjbGVhclwiPlxuICAgICAgICAgICAgICAgIDxpb24taWNvbiBuYW1lPVwiY2xvc2VcIj48L2lvbi1pY29uPlxuICAgICAgICAgICAgPC9pb24tYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8ZGl2IGNsYXNzPVwibW9kYWwtY29udGVudFwiPlxuICAgICAgICAgICAgPCEtLSBMb2FkaW5nIHN0YXRlIC0tPlxuICAgICAgICAgICAgPGRpdiAqbmdJZj1cImxvYWRpbmdcIiBjbGFzcz1cImxvYWRpbmctc3RhdGVcIj5cbiAgICAgICAgICAgICAgICA8aW9uLXNwaW5uZXIgbmFtZT1cImNyZXNjZW50XCI+PC9pb24tc3Bpbm5lcj5cbiAgICAgICAgICAgICAgICA8cD5Mb2FkaW5nIGF2YWlsYWJsZSBwZXJpb2RzLi4uPC9wPlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDwhLS0gRXJyb3IgbWVzc2FnZSAtLT5cbiAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJlcnJvck1lc3NhZ2VcIiBjbGFzcz1cImVycm9yLW1lc3NhZ2VcIj5cbiAgICAgICAgICAgICAgICA8aW9uLWljb24gbmFtZT1cIndhcm5pbmctb3V0bGluZVwiPjwvaW9uLWljb24+XG4gICAgICAgICAgICAgICAgPHNwYW4+e3sgZXJyb3JNZXNzYWdlIH19PC9zcGFuPlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDwhLS0gQXZhaWxhYmxlIHBlcmlvZHMgbGlzdCAtLT5cbiAgICAgICAgICAgIDxkaXYgKm5nSWY9XCIhbG9hZGluZyAmJiBhdmFpbGFibGVQZXJpb2RzLmxlbmd0aCA+IDBcIiBjbGFzcz1cInBlcmlvZHMtc2VjdGlvblwiPlxuICAgICAgICAgICAgICAgIDxoMz5BdmFpbGFibGUgQ3VtdWxhdGl2ZSBQZXJpb2RzPC9oMz5cbiAgICAgICAgICAgICAgICA8aW9uLWxpc3Q+XG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHBlcmlvZCBvZiBhdmFpbGFibGVQZXJpb2RzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tIFBlcmlvZCBoZWFkZXIgKGNsaWNrIHRvIGV4cGFuZCkgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICA8aW9uLWl0ZW0gKGNsaWNrKT1cInRvZ2dsZUV4cGFuZChwZXJpb2QpXCIgW2Rpc2FibGVkXT1cImNyZWF0aW5nXCIgYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpb24taWNvbiBbbmFtZV09XCJpc0V4cGFuZGVkKHBlcmlvZCkgPyAnY2hldnJvbi1kb3duJyA6ICdjaGV2cm9uLWZvcndhcmQnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2xvdD1cInN0YXJ0XCI+PC9pb24taWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW9uLWxhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aDI+e3sgZm9ybWF0V2luZG93KHBlcmlvZC53aW5kb3dJbk1pbnV0ZXMpIH19PC9oMj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHA+e3sgZm9ybWF0UGVyaW9kKHBlcmlvZCkgfX08L3A+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwiY291bnQtaW5mb1wiPnt7IHBlcmlvZC5jb3VudCB9fSBjdW11bGF0aXZlKHMpIC0gY2xpY2sgdG8gZXhwYW5kPC9wPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvaW9uLWxhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9pb24taXRlbT5cblxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBFeHBhbmRlZDogaW5kaXZpZHVhbCBjdW11bGF0aXZlcyAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJpc0V4cGFuZGVkKHBlcmlvZClcIiBjbGFzcz1cImV4cGFuZGVkLWl0ZW1zXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlvbi1zcGlubmVyICpuZ0lmPVwiaXNMb2FkaW5nRXhwYW5kZWQocGVyaW9kKVwiIG5hbWU9XCJjcmVzY2VudFwiPjwvaW9uLXNwaW5uZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlvbi1saXN0ICpuZ0lmPVwiIWlzTG9hZGluZ0V4cGFuZGVkKHBlcmlvZClcIiBjbGFzcz1cIm5lc3RlZC1saXN0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpb24taXRlbSAoY2xpY2spPVwic2VsZWN0SW5kaXZpZHVhbEN1bXVsYXRpdmUoaXRlbSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nRm9yPVwibGV0IGl0ZW0gb2YgZ2V0RXhwYW5kZWRJdGVtcyhwZXJpb2QpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJjcmVhdGluZ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidXR0b25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwibmVzdGVkLWl0ZW1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpb24taWNvbiBuYW1lPVwidGltZS1vdXRsaW5lXCIgc2xvdD1cInN0YXJ0XCI+PC9pb24taWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpb24tbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGgzPnt7IGdldEl0ZW1QZXJpb2RCZWdpbihpdGVtKSB8IGRhdGU6J0hIOm1tJyB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtIHt7IGl0ZW0uZGF0ZSB8IGRhdGU6J0hIOm1tJyB9fTwvaDM+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2lvbi1sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpb24taWNvbiBuYW1lPVwiY2hldnJvbi1mb3J3YXJkXCIgc2xvdD1cImVuZFwiPjwvaW9uLWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvaW9uLWl0ZW0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpb24taXRlbSAqbmdJZj1cImdldEV4cGFuZGVkSXRlbXMocGVyaW9kKS5sZW5ndGggPT09IDBcIiBjbGFzcz1cIm5lc3RlZC1pdGVtXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW9uLWxhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwPk5vIGluZGl2aWR1YWwgY3VtdWxhdGl2ZXMgZm91bmQ8L3A+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2lvbi1sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9pb24taXRlbT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2lvbi1saXN0PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIDwvaW9uLWxpc3Q+XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPCEtLSBObyBwZXJpb2RzIGF2YWlsYWJsZSAtLT5cbiAgICAgICAgICAgIDxkaXYgKm5nSWY9XCIhbG9hZGluZyAmJiBhdmFpbGFibGVQZXJpb2RzLmxlbmd0aCA9PT0gMFwiIGNsYXNzPVwibm8tcGVyaW9kc1wiPlxuICAgICAgICAgICAgICAgIDxpb24taWNvbiBuYW1lPVwiaW5mb3JtYXRpb24tY2lyY2xlLW91dGxpbmVcIj48L2lvbi1pY29uPlxuICAgICAgICAgICAgICAgIDxwPk5vIGN1bXVsYXRpdmUgcGVyaW9kcyBhdmFpbGFibGUgeWV0LjwvcD5cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8IS0tIENyZWF0ZSBuZXcgc2VjdGlvbiAoYWRtaW4gb25seSkgLS0+XG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiIWxvYWRpbmcgJiYgaXNBZG1pblwiIGNsYXNzPVwiY3JlYXRlLXNlY3Rpb25cIj5cbiAgICAgICAgICAgICAgICA8aDM+Q3JlYXRlIE5ldyBDdW11bGF0aXZlPC9oMz5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY3JlYXRlLWluZm9cIj5cbiAgICAgICAgICAgICAgICAgICAgPHA+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3Ryb25nPlBlcmlvZDo8L3N0cm9uZz5cbiAgICAgICAgICAgICAgICAgICAgICAgIHt7IGN1cnJlbnRQZXJpb2RCZWdpbj8udG9Mb2NhbGVTdHJpbmcoKSB9fSDihpIge3sgY3VycmVudFBlcmlvZEVuZD8udG9Mb2NhbGVTdHJpbmcoKSB9fVxuICAgICAgICAgICAgICAgICAgICA8L3A+XG4gICAgICAgICAgICAgICAgICAgIDxwPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHN0cm9uZz5XaW5kb3c6PC9zdHJvbmc+IHt7IGZvcm1hdFdpbmRvdyhjdXJyZW50V2luZG93TWludXRlcykgfX1cbiAgICAgICAgICAgICAgICAgICAgPC9wPlxuICAgICAgICAgICAgICAgICAgICA8cCAqbmdJZj1cImJhc2VDdW11bGF0aXZlc1wiIFtjbGFzcy5jb3ZlcmFnZS1lcnJvcl09XCJjb3ZlcmFnZVBlcmNlbnQgPT09IDBcIlxuICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3MuY292ZXJhZ2Utb2tdPVwiY292ZXJhZ2VQZXJjZW50ID49IDEwMFwiXG4gICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5jb3ZlcmFnZS13YXJuXT1cImNvdmVyYWdlUGVyY2VudCA+IDAgJiYgY292ZXJhZ2VQZXJjZW50IDwgMTAwXCJcbiAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjb3ZlcmFnZS1pbmZvXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8aW9uLWljb24gW25hbWVdPVwiY292ZXJhZ2VQZXJjZW50ID49IDEwMCA/ICdjaGVja21hcmstY2lyY2xlJyA6ICdhbGVydC1jaXJjbGUnXCI+PC9pb24taWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIEJhc2UgZGF0YSBjb3ZlcmFnZToge3sgY292ZXJhZ2VQZXJjZW50IH19JVxuICAgICAgICAgICAgICAgICAgICA8L3A+XG4gICAgICAgICAgICAgICAgICAgIDxwICpuZ0lmPVwiIWJhc2VDdW11bGF0aXZlc1wiIGNsYXNzPVwiY292ZXJhZ2UtZXJyb3JcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxpb24taWNvbiBuYW1lPVwiYWxlcnQtY2lyY2xlXCI+PC9pb24taWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIE5vIGJhc2UgY3VtdWxhdGl2ZXMgYXZhaWxhYmxlXG4gICAgICAgICAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgIDwhLS0gQ3JlYXRpb24gcHJvZ3Jlc3MgLS0+XG4gICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cImNyZWF0aW5nXCIgY2xhc3M9XCJjcmVhdGlvbi1wcm9ncmVzc1wiPlxuICAgICAgICAgICAgICAgICAgICA8aW9uLXNwaW5uZXIgbmFtZT1cImNyZXNjZW50XCI+PC9pb24tc3Bpbm5lcj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4+e3sgY3JlYXRpb25Qcm9ncmVzcyB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgIDxpb24tYnV0dG9uIChjbGljayk9XCJjcmVhdGVOZXdQZXJpb2QoKVwiIFtkaXNhYmxlZF09XCIhY2FuQ3JlYXRlTmV3IHx8IGNyZWF0aW5nXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBhbmQ9XCJibG9ja1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWQ9XCJjcmVhdGVOZXdDdW11bGF0aXZlXCI+XG4gICAgICAgICAgICAgICAgICAgIDxpb24taWNvbiBuYW1lPVwiYWRkLWNpcmNsZS1vdXRsaW5lXCIgc2xvdD1cInN0YXJ0XCI+PC9pb24taWNvbj5cbiAgICAgICAgICAgICAgICAgICAgQ3JlYXRlIHt7IGZvcm1hdFdpbmRvdyhjdXJyZW50V2luZG93TWludXRlcykgfX0gQ3VtdWxhdGl2ZVxuICAgICAgICAgICAgICAgIDwvaW9uLWJ1dHRvbj5cblxuICAgICAgICAgICAgICAgIDxwICpuZ0lmPVwiIWNhbkNyZWF0ZU5ldyAmJiAhY3JlYXRpbmdcIiBjbGFzcz1cImNyZWF0ZS1oaW50XCI+XG4gICAgICAgICAgICAgICAgICAgIENyZWF0ZSBpcyBkaXNhYmxlZCBiZWNhdXNlIG5vIGJhc2UgNS1taW4gY3VtdWxhdGl2ZXMgZXhpc3QgZm9yIHRoZSBzZWxlY3RlZCBwZXJpb2QuXG4gICAgICAgICAgICAgICAgPC9wPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDxkaXYgY2xhc3M9XCJtb2RhbC1mb290ZXJcIj5cbiAgICAgICAgICAgIDxpb24tYnV0dG9uIChjbGljayk9XCJjYW5jZWwoKVwiIFtkaXNhYmxlZF09XCJjcmVhdGluZ1wiIGZpbGw9XCJvdXRsaW5lXCI+XG4gICAgICAgICAgICAgICAgQ2FuY2VsXG4gICAgICAgICAgICA8L2lvbi1idXR0b24+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuPC9kaXY+XG4iXX0=