raain-app 1.6.21 → 1.6.24

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.
@@ -1,4 +1,4 @@
1
- import { ChangeDetectionStrategy, Component, Input, } from '@angular/core';
1
+ import { ChangeDetectionStrategy, Component, Input, ViewChild, } from '@angular/core';
2
2
  import { CartesianMeasureValue, TeamNode } from 'raain-model';
3
3
  import { DateRange, MapLatLng, TimeframeContainers } from 'raain-ui';
4
4
  import { mapDateRangeToString } from '../tools';
@@ -11,6 +11,7 @@ import * as i5 from "../raain-map/raain-map.component";
11
11
  import * as i6 from "../raain-compare-stack/raain-compare-stack.component";
12
12
  import * as i7 from "../raain-date-focus/raain-date-focus.component";
13
13
  import * as i8 from "../raain-date-dynamic/raain-date-dynamic.component";
14
+ import * as i9 from "../cumulative-selector/cumulative-selector.component";
14
15
  let TEST_DETECTION = 0;
15
16
  export class RaainDetailsComponent {
16
17
  constructor(storage, cdr) {
@@ -21,6 +22,7 @@ export class RaainDetailsComponent {
21
22
  this.showPixelMarkers = false;
22
23
  this.qualityIndicators = [];
23
24
  this.qualityIndicatorsLoading = false;
25
+ this.showCumulativeSelector = false;
24
26
  // Cached computed values (to avoid method calls in templates)
25
27
  this.percentOfComputations = 0;
26
28
  this.percentOfImages = 0;
@@ -256,14 +258,73 @@ export class RaainDetailsComponent {
256
258
  onTogglePixelMarkers() {
257
259
  // Toggle is bound to showPixelMarkers, raain-map handles marker display
258
260
  }
259
- async toggleCumulativeChanged(_$event) {
260
- this.storage.set('raain-toggleCumulative', this.toggleCumulative);
261
+ async onCumulativeToggleClick($event) {
262
+ console.log('[CumulativeToggle] click event', {
263
+ currentValue: this.toggleCumulative,
264
+ eventType: $event.type,
265
+ target: $event.target?.tagName,
266
+ });
267
+ $event.preventDefault();
268
+ $event.stopPropagation();
269
+ if (!this.toggleCumulative) {
270
+ console.log('[CumulativeToggle] showing popup, toggle stays OFF');
271
+ // Currently OFF, user wants to enable - show selector popup
272
+ this.showCumulativeSelector = true;
273
+ // Force reset the toggle visual state after ion-toggle's internal handler
274
+ setTimeout(() => {
275
+ if (this.cumulativeToggleRef) {
276
+ this.cumulativeToggleRef.checked = false;
277
+ console.log('[CumulativeToggle] force reset toggle to OFF');
278
+ }
279
+ }, 0);
280
+ this.cdr.markForCheck();
281
+ }
282
+ else {
283
+ console.log('[CumulativeToggle] turning OFF');
284
+ // Currently ON, user wants to disable - direct toggle off
285
+ this.toggleCumulative = false;
286
+ this.storage.set('raain-toggleCumulative', false);
287
+ this.dateShown = this.getDateBasedOnCumulativeMode(this.timeframeDates);
288
+ this.updateCumulativeDurationInMinutes();
289
+ if (this.toggleMap) {
290
+ this.updateRefreshManagerPeriod();
291
+ await this.refreshManager.refresh(false, this.toggleAdmin);
292
+ }
293
+ this.cdr.markForCheck();
294
+ }
295
+ console.log('[CumulativeToggle] after handler, toggleCumulative =', this.toggleCumulative);
296
+ }
297
+ async onCumulativePeriodSelected(selection) {
298
+ this.showCumulativeSelector = false;
299
+ // Update period to match selection
300
+ this.periodBegin = selection.periodBegin;
301
+ this.periodEnd = selection.periodEnd;
302
+ this.periodBeginAsString = RaainDetailsComponent.PeriodDisplay(this.periodBegin);
303
+ this.periodEndAsString = RaainDetailsComponent.PeriodDisplay(this.periodEnd);
304
+ // Calculate duration in hours
305
+ const durationMs = this.periodEnd.getTime() - this.periodBegin.getTime();
306
+ const durationHours = durationMs / RaainDetailsComponent.HOUR_MS;
307
+ this.periodDurationAsString = String(durationHours);
308
+ // Store cumulative period
309
+ this.storage.set('raain-periodBegin', this.periodBegin);
310
+ this.storage.set('raain-periodEnd', this.periodEnd);
311
+ this.storage.set('raain-periodDurationInHours', durationHours);
312
+ // Enable cumulative mode
313
+ this.toggleCumulative = true;
314
+ this.storage.set('raain-toggleCumulative', true);
261
315
  this.dateShown = this.getDateBasedOnCumulativeMode(this.timeframeDates);
262
316
  this.updateCumulativeDurationInMinutes();
317
+ // Refresh map
263
318
  if (this.toggleMap) {
264
- this.updateRefreshManagerPeriod(); // Update cumulative flag before refresh
319
+ this.updateRefreshManagerPeriod();
265
320
  await this.refreshManager.refresh(false, this.toggleAdmin);
266
321
  }
322
+ this.cdr.markForCheck();
323
+ }
324
+ onCumulativeSelectorCancelled() {
325
+ console.log('[CumulativeToggle] cancelled, toggleCumulative =', this.toggleCumulative);
326
+ this.showCumulativeSelector = false;
327
+ this.cdr.markForCheck();
267
328
  }
268
329
  updateCumulativeDurationInMinutes() {
269
330
  if (this.toggleCumulative) {
@@ -464,6 +525,8 @@ export class RaainDetailsComponent {
464
525
  const center = this.rainNode.getCenter();
465
526
  this.coordinates = new MapLatLng(center.lat, center.lng);
466
527
  this.teamNode = await this.profileService.getTeam(this.rainNode.getLink(TeamNode.TYPE).getId());
528
+ // Load all gauges linked to the rainNode on map
529
+ await this.compareManager.setGaugesInMap();
467
530
  if (this.periodBegin && this.periodEnd) {
468
531
  this.updateRefreshManagerPeriod();
469
532
  await this.refreshManager.refresh(false, this.toggleAdmin);
@@ -501,10 +564,10 @@ export class RaainDetailsComponent {
501
564
  RaainDetailsComponent.HOUR_MS = 60 * 60000;
502
565
  RaainDetailsComponent.DAY_MS = 24 * 60 * 60 * 1000;
503
566
  RaainDetailsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: RaainDetailsComponent, deps: [{ token: i1.Storage }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
504
- RaainDetailsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: RaainDetailsComponent, selector: "raain-details", inputs: { toggleAdmin: "toggleAdmin", rainNode: "rainNode", compareManager: "compareManager", refreshManager: "refreshManager", profileService: "profileService", radarService: "radarService" }, usesOnChanges: true, ngImport: i0, template: "<!-- Main content container -->\n<div *ngIf=\"rainNode\" class=\"raain-details-container\">\n\n <!-- Period selection section -->\n <ion-card class=\"period-card\">\n <ion-card-content>\n <div class=\"period-controls\">\n <div class=\"period-row\">\n\n <ion-button (click)=\"toggleHistory = !toggleHistory; onEnableCountHistoryTab(rainNode)\"\n fill=\"outline\">\n <ion-icon name=\"calendar-clear-outline\" slot=\"start\"></ion-icon>\n <ion-icon [name]=\"toggleHistory ? 'chevron-down' : 'chevron-forward'\" slot=\"end\"></ion-icon>\n </ion-button>\n\n <div class=\"period-start ion-hide-md-down\">\n <input (change)=\"onPeriodBeginChange($event)\"\n [disabled]=\"toggleCumulative\"\n [value]=\"periodBeginAsString\"\n class=\"datetime-input\"\n type=\"datetime-local\">\n </div>\n\n <div class=\"period-duration ion-hide-md-down\">\n <ion-select (ionDismiss)=\"onPeriodDurationChange($event)\"\n [(ngModel)]=\"periodDurationAsString\"\n class=\"duration-select\"\n id=\"periodDuration\"\n interface=\"popover\">\n <ion-select-option value=\"0.25\">15 minutes</ion-select-option>\n <ion-select-option value=\"0.5\">30 minutes</ion-select-option>\n <ion-select-option value=\"1\">1 hour</ion-select-option>\n <ion-select-option value=\"2\">2 hours</ion-select-option>\n <ion-select-option value=\"3\">3 hours</ion-select-option>\n <ion-select-option value=\"4\">4 hours</ion-select-option>\n <ion-select-option value=\"5\">5 hours</ion-select-option>\n <ion-select-option value=\"6\">6 hours</ion-select-option>\n <ion-select-option value=\"8\">8 hours</ion-select-option>\n <ion-select-option value=\"10\">10 hours</ion-select-option>\n <ion-select-option value=\"12\">12 hours</ion-select-option>\n <ion-select-option *ngIf=\"isAdmin\" value=\"24\">24 hours</ion-select-option>\n </ion-select>\n </div>\n\n <div class=\"period-start ion-hide-md-down\">\n <input (change)=\"onPeriodEndChange($event)\"\n [disabled]=\"!toggleCumulative\"\n [value]=\"periodEndAsString\"\n class=\"datetime-input\"\n type=\"datetime-local\">\n </div>\n\n <div class=\"toggle-cumulative\">\n <ion-label [class.text-primary]=\"toggleCumulative\">\n {{ toggleCumulative ? 'Cumulative' : 'Granular' }}\n </ion-label>\n <ion-toggle (ionChange)=\"toggleCumulativeChanged($event)\"\n [(ngModel)]=\"toggleCumulative\"\n [checked]=\"toggleCumulative\">\n </ion-toggle>\n </div>\n </div>\n\n <!-- Hidden label for change detection (uncomment to debug)\n <div class=\"hidden-label\">{{ onChangeDetectionTest(rainNode) }}</div>\n -->\n </div>\n\n <!-- Historical map section -->\n <div *ngIf=\"toggleHistory\" class=\"period-controls\">\n <raain-date-dynamic (changedDate)=\"onDateChangeInCount($event)\"\n [currentHeight]=\"300\"\n [fetchData]=\"fetchDataWrapper\"\n [points]=\"countPoints\">\n </raain-date-dynamic>\n </div>\n </ion-card-content>\n </ion-card>\n\n <!-- Map performance -->\n <ion-grid class=\"map-performance\">\n <ion-row id=\"progressAndRefresh\">\n <ion-col class=\"provider-selection\" size=\"12\" size-md=\"6\">\n <ion-button (click)=\"openQualityModal()\" class=\"quality-info-button\" fill=\"clear\">\n {{ refreshManager.rainComputationMapVersion }}\n <ion-icon name=\"help-circle-outline\" slot=\"end\"></ion-icon>\n </ion-button>\n <div *ngIf=\"availableProviders.length > 0 || availableTimeSteps.length > 0\" class=\"selection-row\">\n <ion-select (ionChange)=\"onProviderChanged($event)\"\n [value]=\"selectedProvider\"\n interface=\"popover\"\n label=\"Provider\"\n placeholder=\"Select Provider\">\n <ion-select-option *ngFor=\"let provider of availableProviders\" [value]=\"provider\">\n {{ provider }}\n </ion-select-option>\n </ion-select>\n\n <ion-select (ionChange)=\"onTimeStepChanged($event)\"\n [value]=\"selectedTimeStep\"\n interface=\"popover\"\n label=\"Time Step\"\n placeholder=\"Select Time Step\">\n <ion-select-option *ngFor=\"let step of availableTimeSteps\" [value]=\"step\">\n {{ step }} min\n </ion-select-option>\n </ion-select>\n </div>\n </ion-col>\n <ion-col class=\"ion-text-right\" size=\"12\" size-md=\"6\">\n <ion-label class=\"ion-margin-end\">\n <span *ngIf=\"percentOfComputations\">\n {{ percentOfComputations }}% Images\n <i *ngIf=\"countsPeriod.progress\" class=\"progress-indicator\">\n In Progress: {{ countsPeriod.progress }}...\n </i>\n </span>\n <span *ngIf=\"!percentOfComputations\">\n No image available\n </span>\n\n </ion-label>\n\n <ion-button (click)=\"refreshMap()\" [disabled]=\"refreshInProgress\" class=\"refresh-button\">\n Refresh Map\n </ion-button>\n </ion-col>\n </ion-row>\n\n <!-- status update row -->\n <ion-row>\n <!-- Progress col -->\n <ion-progress-bar\n [buffer]=\"(countsPeriod.progress / ((timeframeDates?.length || 10) +3))+0.01\"\n [style.visibility]=\"refreshInProgress ? 'visible' : 'hidden'\"\n [value]=\"countsPeriod.progress / ((timeframeDates?.length || 10) +3)\"\n color=\"primary\">\n </ion-progress-bar>\n\n <!-- Error col -->\n <ion-col (click)=\"showFullError = !showFullError\" *ngIf=\"refreshManager.lastError\" class=\"error-row\"\n size=\"12\">\n <div class=\"error-content\">\n <ion-icon class=\"error-icon\" name=\"warning-outline\"></ion-icon>\n <span [class.expanded]=\"showFullError\" class=\"error-text\">\n {{ showFullError ? refreshManager.lastError : truncatedError }}\n </span>\n <ion-icon [name]=\"showFullError ? 'chevron-up' : 'chevron-down'\" class=\"error-caret\"></ion-icon>\n </div>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n <!-- Map section -->\n <ion-card class=\"map-card\">\n <ion-card-content class=\"map-content\">\n <ion-grid>\n <ion-row *ngIf=\"toggleMap && percentOfImages\">\n <!-- Map component -->\n <ion-col class=\"map-column\" size-lg=\"7\" size-md=\"12\">\n <div class=\"map-container\">\n <raain-map #raainMapRef\n (changedDate)=\"onDateChangeInMap($event)\"\n (changedSum)=\"onSumChangeInMap($event)\"\n (selectedMarker)=\"onGaugeSelectInMap($event)\"\n [coordinates]=\"coordinates\"\n [cumulativeDurationInMinutes]=\"cumulativeDurationInMinutes\"\n [currentHeight]=\"500\"\n [defaultDate]=\"dateShown\"\n [markers]=\"{\n borders,\n gauges: compareManager.gaugesInMap,\n gaugesInCompare: compareManager.gaugesInCompare,\n selectedGauges: compareManager.selectedGauges,\n pixels: compareManager.selectedPixels,\n pixelsSolution: compareManager.pixelsSolutions?.length ? compareManager.pixelsSolutions[0] : [],\n speeds: compareManager.speeds\n }\"\n [showCumulative]=\"toggleCumulative\"\n [showVisiblePixelMarkers]=\"showPixelMarkers\"\n [sumFn]=\"refreshManager.sumFn\"\n [sumValues]=\"refreshManager.sumValues\"\n [timeframeContainers]=\"timeframeContainers\"\n [timeframeDates]=\"timeframeDates\">\n </raain-map>\n </div>\n\n <div class=\"data-column\">\n <!-- Technical details (collapsible for cleaner UI) -->\n <details class=\"technical-details\">\n <summary>Image Details</summary>\n <div class=\"details-content\">\n <div class=\"detail-row\">\n <span class=\"detail-label\">Computed:</span>\n <span class=\"detail-value\">{{ refreshManager.rainComputationMapDoneDate | date:'yyyy-MM-dd HH:mm' }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Version:</span>\n <span class=\"detail-value\">{{ refreshManager.rainComputationMapVersion }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Launched by:</span>\n <span class=\"detail-value\">{{ refreshManager.rainComputationMapLaunchedBy }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Time spent:</span>\n <span class=\"detail-value\">{{ refreshManager.rainComputationMapTimeSpentInMs }}\n ms</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Date:</span>\n <span class=\"detail-value\">{{ refreshManager.rainComputationMapDate?.toISOString() }}\n | {{ refreshManager.rainComputationMapDate | date:'yyyy-MM-dd HH:mm' }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Water in the map:</span>\n <span class=\"detail-value\">{{ sumDetails }}</span>\n <ion-toggle\n (ionChange)=\"onTogglePixelMarkers()\"\n [(ngModel)]=\"showPixelMarkers\"\n style=\"margin-left: 8px; transform: scale(0.7);\">\n </ion-toggle>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Source DBZ min:</span>\n <span class=\"detail-value\">{{ refreshManager.rainComputationMapOriginalMin }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Source DBZ max:</span>\n <span class=\"detail-value\">{{ refreshManager.rainComputationMapOriginalMax }}</span>\n </div>\n </div>\n </details>\n </div>\n </ion-col>\n\n <!-- Data panel -->\n <ion-col *ngIf=\"!!compareManager.compareVersion\" class=\"data-column\" size-lg=\"5\" size-md=\"12\">\n <div class=\"data-panel\">\n <!-- Compare stack component -->\n <div class=\"compare-stack\">\n <raain-compare-stack\n (selectedPoint)=\"onGaugeSelectInCompare($event)\"\n [compareManager]=\"compareManager\"\n [cumulative]=\"toggleCumulative\">\n </raain-compare-stack>\n </div>\n\n <!-- Technical details (collapsible for cleaner UI) -->\n <details class=\"technical-details\">\n <summary>Compare Details</summary>\n <div class=\"details-content\">\n <div [ngClass]=\"{'warning': refreshManager.rainComputationMapDoneDate?.getTime() > compareManager.currentQualityDoneDate?.getTime() + 60000}\"\n class=\"detail-row\">\n <span class=\"detail-label\">Computed:</span>\n <span class=\"detail-value\">{{ compareManager.currentQualityDoneDate | date:'yyyy-MM-dd HH:mm' }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Version:</span>\n <span class=\"detail-value\">{{ compareManager.compareVersion }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Launched by:</span>\n <span class=\"detail-value\">{{ compareManager.currentQualityLaunchedBy }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Time spent:</span>\n <span class=\"detail-value\">{{ compareManager.currentQualityTimeSpentInMs }}\n ms</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Gauges:</span>\n <span class=\"detail-value\">{{ compareManager.gaugesInCompare.length }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Points:</span>\n <span class=\"detail-value\">{{ compareManager.globalComparePoints.length }}</span>\n </div>\n </div>\n </details>\n </div>\n </ion-col>\n </ion-row>\n <ion-row>\n <!-- Bottom progress bar -->\n <ion-progress-bar *ngIf=\"refreshInProgress\"\n [buffer]=\"(countsPeriod.progress / ((timeframeDates?.length || 10) +3))+0.01\"\n [value]=\"countsPeriod.progress / ((timeframeDates?.length || 10) +3)\"\n color=\"primary\">\n </ion-progress-bar>\n </ion-row>\n </ion-grid>\n </ion-card-content>\n </ion-card>\n\n <!-- Gauge values section -->\n <ion-card *ngIf=\"gaugeSelectedPoints.length && gaugeSelectedPoints[0].values.length\" class=\"gauge-card\">\n <ion-card-header>\n <ion-card-title>\n <ion-icon name=\"analytics-outline\"></ion-icon>\n Selected Gauge Data\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <raain-date-focus\n [currentHeight]=\"300\"\n [focusDate]=\"periodBegin\"\n [focusRange]=\"DateRange.DAY\"\n [points]=\"gaugeSelectedPoints\"\n [withoutAll]=\"true\">\n </raain-date-focus>\n </ion-card-content>\n </ion-card>\n\n <!-- Quality Performance Modal -->\n <div (click)=\"closeQualityModal()\" *ngIf=\"showQualityModal\" class=\"quality-modal-overlay\">\n <div (click)=\"$event.stopPropagation()\" class=\"quality-modal-content\">\n <div class=\"quality-modal-header\">\n <h2>Model Quality Performance</h2>\n <ion-button (click)=\"closeQualityModal()\" fill=\"clear\">\n <ion-icon name=\"close-outline\"></ion-icon>\n </ion-button>\n </div>\n <div class=\"quality-modal-body\">\n <div *ngIf=\"qualityIndicatorsLoading\" class=\"quality-loading\">\n <ion-spinner name=\"crescent\"></ion-spinner>\n <span>Loading indicators...</span>\n </div>\n <div *ngIf=\"!qualityIndicatorsLoading && qualityIndicators.length === 0\" class=\"quality-empty\">\n No quality indicators available for this year.\n </div>\n <table *ngIf=\"!qualityIndicatorsLoading && qualityIndicators.length > 0\" class=\"quality-table\">\n <thead>\n <tr>\n <th>Model</th>\n <th>Compare</th>\n <th>Gauges</th>\n <th>Period</th>\n <th>Avg Quality</th>\n <th>Updated</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let indicator of qualityIndicators\">\n <td>{{ indicator.computingVersion }}</td>\n <td>{{ indicator.qualityVersion }}</td>\n <td>{{ indicator.provider }}<br>{{ indicator.timeStepInMinutes }} min</td>\n <td>{{ formatDate(indicator.startDate) }}<br>{{ formatDate(indicator.endDate) }}</td>\n <td>{{ indicator.averageQuality | number:'1.2-2' }}</td>\n <td>{{ formatDate(indicator.lastUpdatedAt) }}</td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n </div>\n\n</div>\n", styles: [".raain-details-container{max-width:var(--app-max-width);margin:0 auto;padding:0 0 24px}.raain-details-card{width:100%;margin-bottom:20px}.raain-details-card ion-card-header{border-bottom:1px solid rgba(var(--ion-color-medium-rgb),.2)}.raain-details-card ion-card-header ion-card-title{display:flex;align-items:center}.raain-details-card ion-card-header ion-card-title ion-icon{margin-right:8px;color:var(--ion-color-primary)}.node-info-card{background-color:var(--ion-color-light)}.node-info-card .node-header{display:flex;align-items:center}.node-info-card .node-header .node-status{margin-right:16px}.node-info-card .node-header .node-status ion-icon{font-size:24px}.node-info-card .node-header .node-titles{flex:1}.node-info-card .node-header .node-titles ion-card-title{margin:0;font-size:1.4rem;font-weight:600;color:var(--ion-color-dark)}.node-info-card .node-header .node-titles ion-card-subtitle{padding-left:0;margin:4px 0 0;font-size:.9rem;color:var(--ion-color-medium)}.count-map-card,.period-card{background-color:var(--ion-color-light)}.period-card ion-card-title{display:flex;align-items:center}.period-card ion-card-title ion-icon{margin-right:8px;color:var(--ion-color-primary);font-size:20px}.period-row{display:flex;flex-wrap:wrap;align-items:center;gap:16px;position:relative}.now-button{min-width:100px}#all-dates{display:flex;align-items:center;margin-left:auto}#all-dates .toggle-label{margin-right:8px;white-space:nowrap}.refresh-button ion-icon{margin-right:4px;color:var(--ion-color-light)}.provider-selection{display:flex;align-items:center}.quality-info-button{--padding-start: 8px;--padding-end: 8px;font-size:.85rem;color:var(--ion-color-medium)}.quality-info-button ion-icon{font-size:18px;margin-left:4px}.selection-row{display:flex;flex-direction:row;align-items:center;gap:12px}.selection-row ion-select{flex:0 0 auto;min-width:100px;margin-bottom:0;padding:4px 8px;border:1px solid rgba(var(--ion-color-medium-rgb),.3);border-radius:var(--ion-border-radius);background-color:var(--ion-color-light)}.period-start,.period-duration{display:flex;align-items:center}.toggle-cumulative{display:flex;align-items:center;gap:8px;margin-left:auto}.toggle-cumulative .text-primary{color:var(--ion-color-primary);font-weight:600}.hidden-label{display:none}.datetime-input,#periodDuration,.duration-select{padding:8px 12px;border:1px solid rgba(var(--ion-color-medium-rgb),.3);border-radius:var(--ion-border-radius);background-color:var(--ion-color-light);font-family:var(--ion-font-family)}.datetime-input:focus,#periodDuration:focus,.duration-select:focus{outline:none;border-color:var(--ion-color-primary)}#periodDuration,.duration-select{min-width:150px}.gauge-card{background-color:var(--ion-color-light)}.gauge-card ion-card-title{display:flex;align-items:center}.gauge-card ion-card-title ion-icon{margin-right:8px;color:var(--ion-color-primary);font-size:20px}.error-row{cursor:pointer;background-color:rgba(var(--ion-color-danger-rgb),.1);border-left:3px solid var(--ion-color-danger);margin-top:8px;border-radius:4px;transition:background-color .2s ease}.error-row:hover{background-color:rgba(var(--ion-color-danger-rgb),.15)}.error-row .error-content{display:flex;align-items:flex-start;padding:8px 12px;gap:8px}.error-row .error-icon{color:var(--ion-color-danger);font-size:18px;flex-shrink:0;margin-top:2px}.error-row .error-text{flex:1;color:var(--ion-color-danger-shade);font-size:.9rem;word-break:break-word}.error-row .error-text.expanded{white-space:pre-wrap}.error-row .error-caret{color:var(--ion-color-danger);font-size:16px;flex-shrink:0;margin-top:2px}raain-compare-stack{width:100%;display:block}@media (max-width: 768px){.period-row{flex-direction:row;justify-content:space-between;align-items:center}#all-dates{margin-left:auto;padding-left:8px}#all-dates .toggle-label{font-size:.9rem}.map-header{flex-direction:row;justify-content:space-between;align-items:center;gap:16px}}.quality-modal-overlay{position:fixed;inset:0;background-color:#00000080;display:flex;align-items:center;justify-content:center;z-index:9999}.quality-modal-content{background-color:var(--ion-background-color, #fff);border-radius:12px;width:95%;max-width:900px;max-height:80vh;overflow:auto;box-shadow:0 4px 24px #0003}.quality-modal-header{display:flex;align-items:center;justify-content:space-between;padding:16px 20px;border-bottom:1px solid rgba(var(--ion-color-medium-rgb),.2)}.quality-modal-header h2{margin:0;font-size:1.25rem;font-weight:600;color:var(--ion-color-dark)}.quality-modal-header ion-button{--padding-start: 8px;--padding-end: 8px}.quality-modal-body{padding:20px}.quality-table{width:100%;border-collapse:collapse;margin-top:16px;table-layout:fixed}.quality-table th,.quality-table td{width:16.66%;padding:12px 16px;text-align:center;vertical-align:top;border-bottom:1px solid rgba(var(--ion-color-medium-rgb),.2)}.quality-table th{background-color:rgba(var(--ion-color-primary-rgb),.1);font-weight:600;color:var(--ion-color-dark)}.quality-table td{color:var(--ion-color-dark-tint);font-size:.7rem}.quality-table tbody tr:hover{background-color:rgba(var(--ion-color-primary-rgb),.05)}.quality-loading{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:40px 20px;color:var(--ion-color-medium)}.quality-loading ion-spinner{margin-bottom:12px}.quality-empty{text-align:center;padding:40px 20px;color:var(--ion-color-medium);font-style:italic}\n"], dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i4.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i4.IonCard, selector: "ion-card", inputs: ["button", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i4.IonCardContent, selector: "ion-card-content", inputs: ["mode"] }, { kind: "component", type: i4.IonCardHeader, selector: "ion-card-header", inputs: ["color", "mode", "translucent"] }, { kind: "component", type: i4.IonCardTitle, selector: "ion-card-title", inputs: ["color", "mode"] }, { kind: "component", type: i4.IonCol, selector: "ion-col", inputs: ["offset", "offsetLg", "offsetMd", "offsetSm", "offsetXl", "offsetXs", "pull", "pullLg", "pullMd", "pullSm", "pullXl", "pullXs", "push", "pushLg", "pushMd", "pushSm", "pushXl", "pushXs", "size", "sizeLg", "sizeMd", "sizeSm", "sizeXl", "sizeXs"] }, { kind: "component", type: i4.IonGrid, selector: "ion-grid", inputs: ["fixed"] }, { kind: "component", type: i4.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i4.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i4.IonProgressBar, selector: "ion-progress-bar", inputs: ["buffer", "color", "mode", "reversed", "type", "value"] }, { kind: "component", type: i4.IonRow, selector: "ion-row" }, { kind: "component", type: i4.IonSelect, selector: "ion-select", inputs: ["cancelText", "compareWith", "disabled", "interface", "interfaceOptions", "mode", "multiple", "name", "okText", "placeholder", "selectedText", "value"] }, { kind: "component", type: i4.IonSelectOption, selector: "ion-select-option", inputs: ["disabled", "value"] }, { kind: "component", type: i4.IonSpinner, selector: "ion-spinner", inputs: ["color", "duration", "name", "paused"] }, { kind: "component", type: i4.IonToggle, selector: "ion-toggle", inputs: ["checked", "color", "disabled", "mode", "name", "value"] }, { kind: "directive", type: i4.BooleanValueAccessor, selector: "ion-checkbox,ion-toggle" }, { kind: "directive", type: i4.SelectValueAccessor, selector: "ion-range, ion-select, ion-radio-group, ion-segment, ion-datetime" }, { kind: "component", type: i5.RaainMapComponent, selector: "raain-map", inputs: ["coordinates", "markers", "timeframeContainers", "autoplay", "showMarkers", "showSpeedMarkers", "showVisiblePixelMarkers", "showCumulative", "cumulativeDurationInMinutes", "currentHeight", "timeframeDates", "defaultDate", "sumValues", "sumFn"], outputs: ["selectedMarker", "changedDate", "changedSum"] }, { kind: "component", type: i6.RaainCompareStackComponent, selector: "raain-compare-stack", inputs: ["compareManager", "currentHeight", "cumulative"], outputs: ["selectedPoint"] }, { kind: "component", type: i7.RaainDateFocusComponent, selector: "raain-date-focus", inputs: ["points", "focusDate", "focusRange", "withoutAll", "currentHeight"] }, { kind: "component", type: i8.RaainDateDynamicComponent, selector: "raain-date-dynamic", inputs: ["points", "focusDate", "focusRange", "withoutAll", "currentHeight", "fetchData"], outputs: ["changedDate"] }, { kind: "pipe", type: i2.DecimalPipe, name: "number" }, { kind: "pipe", type: i2.DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
567
+ RaainDetailsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: RaainDetailsComponent, selector: "raain-details", inputs: { toggleAdmin: "toggleAdmin", rainNode: "rainNode", compareManager: "compareManager", refreshManager: "refreshManager", profileService: "profileService", radarService: "radarService" }, viewQueries: [{ propertyName: "cumulativeToggleRef", first: true, predicate: ["cumulativeToggle"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<!-- Main content container -->\n<div *ngIf=\"rainNode\" class=\"raain-details-container\">\n\n <!-- Period selection section -->\n <ion-card class=\"period-card\">\n <ion-card-content>\n <div class=\"period-controls\">\n <div class=\"period-row\">\n\n <ion-button (click)=\"toggleHistory = !toggleHistory; onEnableCountHistoryTab(rainNode)\"\n fill=\"outline\">\n <ion-icon name=\"calendar-clear-outline\" slot=\"start\"></ion-icon>\n <ion-icon [name]=\"toggleHistory ? 'chevron-down' : 'chevron-forward'\" slot=\"end\"></ion-icon>\n </ion-button>\n\n <div class=\"period-start ion-hide-md-down\">\n <input (change)=\"onPeriodBeginChange($event)\"\n [disabled]=\"toggleCumulative\"\n [value]=\"periodBeginAsString\"\n class=\"datetime-input\"\n type=\"datetime-local\">\n </div>\n\n <div class=\"period-duration ion-hide-md-down\">\n <ion-select (ionDismiss)=\"onPeriodDurationChange($event)\"\n [(ngModel)]=\"periodDurationAsString\"\n [disabled]=\"toggleCumulative\"\n class=\"duration-select\"\n id=\"periodDuration\"\n interface=\"popover\">\n <ion-select-option value=\"0.25\">15 minutes</ion-select-option>\n <ion-select-option value=\"0.5\">30 minutes</ion-select-option>\n <ion-select-option value=\"1\">1 hour</ion-select-option>\n <ion-select-option value=\"2\">2 hours</ion-select-option>\n <ion-select-option value=\"3\">3 hours</ion-select-option>\n <ion-select-option value=\"4\">4 hours</ion-select-option>\n <ion-select-option value=\"5\">5 hours</ion-select-option>\n <ion-select-option value=\"6\">6 hours</ion-select-option>\n <ion-select-option value=\"8\">8 hours</ion-select-option>\n <ion-select-option value=\"10\">10 hours</ion-select-option>\n <ion-select-option value=\"12\">12 hours</ion-select-option>\n <ion-select-option *ngIf=\"isAdmin\" value=\"24\">24 hours</ion-select-option>\n </ion-select>\n </div>\n\n <div class=\"period-start ion-hide-md-down\">\n <input (change)=\"onPeriodEndChange($event)\"\n [disabled]=\"toggleCumulative\"\n [value]=\"periodEndAsString\"\n class=\"datetime-input\"\n type=\"datetime-local\">\n </div>\n\n <div class=\"toggle-cumulative\" (click)=\"onCumulativeToggleClick($event)\">\n <ion-label [class.text-primary]=\"toggleCumulative\">\n {{ toggleCumulative ? 'Cumulative' : 'Granular' }}\n </ion-label>\n <ion-toggle #cumulativeToggle [checked]=\"toggleCumulative\">\n </ion-toggle>\n </div>\n </div>\n\n <!-- Hidden label for change detection (uncomment to debug)\n <div class=\"hidden-label\">{{ onChangeDetectionTest(rainNode) }}</div>\n -->\n </div>\n\n <!-- Historical map section -->\n <div *ngIf=\"toggleHistory\" class=\"period-controls\">\n <raain-date-dynamic (changedDate)=\"onDateChangeInCount($event)\"\n [currentHeight]=\"300\"\n [fetchData]=\"fetchDataWrapper\"\n [points]=\"countPoints\">\n </raain-date-dynamic>\n </div>\n </ion-card-content>\n </ion-card>\n\n <!-- Map performance -->\n <ion-grid class=\"map-performance\">\n <ion-row id=\"progressAndRefresh\">\n <ion-col class=\"provider-selection\" size=\"12\" size-md=\"6\">\n <ion-button (click)=\"openQualityModal()\" class=\"quality-info-button\" fill=\"clear\">\n {{ refreshManager.rainComputationMapVersion }}\n <ion-icon name=\"help-circle-outline\" slot=\"end\"></ion-icon>\n </ion-button>\n <div *ngIf=\"availableProviders.length > 0 || availableTimeSteps.length > 0\" class=\"selection-row\">\n <ion-select (ionChange)=\"onProviderChanged($event)\"\n [value]=\"selectedProvider\"\n interface=\"popover\"\n label=\"Provider\"\n placeholder=\"Select Provider\">\n <ion-select-option *ngFor=\"let provider of availableProviders\" [value]=\"provider\">\n {{ provider }}\n </ion-select-option>\n </ion-select>\n\n <ion-select (ionChange)=\"onTimeStepChanged($event)\"\n [value]=\"selectedTimeStep\"\n interface=\"popover\"\n label=\"Time Step\"\n placeholder=\"Select Time Step\">\n <ion-select-option *ngFor=\"let step of availableTimeSteps\" [value]=\"step\">\n {{ step }} min\n </ion-select-option>\n </ion-select>\n </div>\n </ion-col>\n <ion-col class=\"ion-text-right\" size=\"12\" size-md=\"6\">\n <ion-label class=\"ion-margin-end\">\n <span *ngIf=\"percentOfComputations\">\n {{ percentOfComputations }}% Images\n <i *ngIf=\"countsPeriod.progress\" class=\"progress-indicator\">\n In Progress: {{ countsPeriod.progress }}...\n </i>\n </span>\n <span *ngIf=\"!percentOfComputations\">\n No image available\n </span>\n\n </ion-label>\n\n <ion-button (click)=\"refreshMap()\" [disabled]=\"refreshInProgress\" class=\"refresh-button\">\n Refresh Map\n </ion-button>\n </ion-col>\n </ion-row>\n\n <!-- status update row -->\n <ion-row>\n <!-- Progress col -->\n <ion-progress-bar\n [buffer]=\"(countsPeriod.progress / ((timeframeDates?.length || 10) +3))+0.01\"\n [style.visibility]=\"refreshInProgress ? 'visible' : 'hidden'\"\n [value]=\"countsPeriod.progress / ((timeframeDates?.length || 10) +3)\"\n color=\"primary\">\n </ion-progress-bar>\n\n <!-- Error col -->\n <ion-col (click)=\"showFullError = !showFullError\" *ngIf=\"refreshManager.lastError\" class=\"error-row\"\n size=\"12\">\n <div class=\"error-content\">\n <ion-icon class=\"error-icon\" name=\"warning-outline\"></ion-icon>\n <span [class.expanded]=\"showFullError\" class=\"error-text\">\n {{ showFullError ? refreshManager.lastError : truncatedError }}\n </span>\n <ion-icon [name]=\"showFullError ? 'chevron-up' : 'chevron-down'\" class=\"error-caret\"></ion-icon>\n </div>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n <!-- Map section -->\n <ion-card class=\"map-card\">\n <ion-card-content class=\"map-content\">\n <ion-grid>\n <ion-row *ngIf=\"toggleMap && percentOfImages\">\n <!-- Map component -->\n <ion-col class=\"map-column\" size-lg=\"7\" size-md=\"12\">\n <div class=\"map-container\">\n <raain-map #raainMapRef\n (changedDate)=\"onDateChangeInMap($event)\"\n (changedSum)=\"onSumChangeInMap($event)\"\n (selectedMarker)=\"onGaugeSelectInMap($event)\"\n [coordinates]=\"coordinates\"\n [cumulativeDurationInMinutes]=\"cumulativeDurationInMinutes\"\n [currentHeight]=\"500\"\n [defaultDate]=\"dateShown\"\n [markers]=\"{\n borders,\n gauges: compareManager.gaugesInMap,\n gaugesInCompare: compareManager.gaugesInCompare,\n selectedGauges: compareManager.selectedGauges,\n pixels: compareManager.selectedPixels,\n pixelsSolution: compareManager.pixelsSolutions?.length ? compareManager.pixelsSolutions[0] : [],\n speeds: compareManager.speeds\n }\"\n [showCumulative]=\"toggleCumulative\"\n [showVisiblePixelMarkers]=\"showPixelMarkers\"\n [sumFn]=\"refreshManager.sumFn\"\n [sumValues]=\"refreshManager.sumValues\"\n [timeframeContainers]=\"timeframeContainers\"\n [timeframeDates]=\"timeframeDates\">\n </raain-map>\n </div>\n\n <div class=\"data-column\">\n <!-- Technical details (collapsible for cleaner UI) -->\n <details class=\"technical-details\">\n <summary>Image Details</summary>\n <div class=\"details-content\">\n <div class=\"detail-row\">\n <span class=\"detail-label\">Computed:</span>\n <span class=\"detail-value\">{{ refreshManager.rainComputationMapDoneDate | date:'yyyy-MM-dd HH:mm' }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Version:</span>\n <span class=\"detail-value\">{{ refreshManager.rainComputationMapVersion }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Launched by:</span>\n <span class=\"detail-value\">{{ refreshManager.rainComputationMapLaunchedBy }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Time spent:</span>\n <span class=\"detail-value\">{{ refreshManager.rainComputationMapTimeSpentInMs }}\n ms</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Date:</span>\n <span class=\"detail-value\">{{ refreshManager.rainComputationMapDate?.toISOString() }}\n | {{ refreshManager.rainComputationMapDate | date:'yyyy-MM-dd HH:mm' }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Water in the map:</span>\n <span class=\"detail-value\">{{ sumDetails }}</span>\n <ion-toggle\n (ionChange)=\"onTogglePixelMarkers()\"\n [(ngModel)]=\"showPixelMarkers\"\n style=\"margin-left: 8px; transform: scale(0.7);\">\n </ion-toggle>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Source DBZ min:</span>\n <span class=\"detail-value\">{{ refreshManager.rainComputationMapOriginalMin }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Source DBZ max:</span>\n <span class=\"detail-value\">{{ refreshManager.rainComputationMapOriginalMax }}</span>\n </div>\n </div>\n </details>\n </div>\n </ion-col>\n\n <!-- Data panel -->\n <ion-col *ngIf=\"!!compareManager.compareVersion\" class=\"data-column\" size-lg=\"5\" size-md=\"12\">\n <div class=\"data-panel\">\n <!-- Compare stack component -->\n <div class=\"compare-stack\">\n <raain-compare-stack\n (selectedPoint)=\"onGaugeSelectInCompare($event)\"\n [compareManager]=\"compareManager\"\n [cumulative]=\"toggleCumulative\">\n </raain-compare-stack>\n </div>\n\n <!-- Technical details (collapsible for cleaner UI) -->\n <details class=\"technical-details\">\n <summary>Compare Details</summary>\n <div class=\"details-content\">\n <div [ngClass]=\"{'warning': refreshManager.rainComputationMapDoneDate?.getTime() > compareManager.currentQualityDoneDate?.getTime() + 60000}\"\n class=\"detail-row\">\n <span class=\"detail-label\">Computed:</span>\n <span class=\"detail-value\">{{ compareManager.currentQualityDoneDate | date:'yyyy-MM-dd HH:mm' }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Version:</span>\n <span class=\"detail-value\">{{ compareManager.compareVersion }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Launched by:</span>\n <span class=\"detail-value\">{{ compareManager.currentQualityLaunchedBy }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Time spent:</span>\n <span class=\"detail-value\">{{ compareManager.currentQualityTimeSpentInMs }}\n ms</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Gauges:</span>\n <span class=\"detail-value\">{{ compareManager.gaugesInCompare.length }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Points:</span>\n <span class=\"detail-value\">{{ compareManager.globalComparePoints.length }}</span>\n </div>\n </div>\n </details>\n </div>\n </ion-col>\n </ion-row>\n <ion-row>\n <!-- Bottom progress bar -->\n <ion-progress-bar *ngIf=\"refreshInProgress\"\n [buffer]=\"(countsPeriod.progress / ((timeframeDates?.length || 10) +3))+0.01\"\n [value]=\"countsPeriod.progress / ((timeframeDates?.length || 10) +3)\"\n color=\"primary\">\n </ion-progress-bar>\n </ion-row>\n </ion-grid>\n </ion-card-content>\n </ion-card>\n\n <!-- Gauge values section -->\n <ion-card *ngIf=\"gaugeSelectedPoints.length && gaugeSelectedPoints[0].values.length\" class=\"gauge-card\">\n <ion-card-header>\n <ion-card-title>\n <ion-icon name=\"analytics-outline\"></ion-icon>\n Selected Gauge Data\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <raain-date-focus\n [currentHeight]=\"300\"\n [focusDate]=\"periodBegin\"\n [focusRange]=\"DateRange.DAY\"\n [points]=\"gaugeSelectedPoints\"\n [withoutAll]=\"true\">\n </raain-date-focus>\n </ion-card-content>\n </ion-card>\n\n <!-- Quality Performance Modal -->\n <div (click)=\"closeQualityModal()\" *ngIf=\"showQualityModal\" class=\"quality-modal-overlay\">\n <div (click)=\"$event.stopPropagation()\" class=\"quality-modal-content\">\n <div class=\"quality-modal-header\">\n <h2>Model Quality Performance</h2>\n <ion-button (click)=\"closeQualityModal()\" fill=\"clear\">\n <ion-icon name=\"close-outline\"></ion-icon>\n </ion-button>\n </div>\n <div class=\"quality-modal-body\">\n <div *ngIf=\"qualityIndicatorsLoading\" class=\"quality-loading\">\n <ion-spinner name=\"crescent\"></ion-spinner>\n <span>Loading indicators...</span>\n </div>\n <div *ngIf=\"!qualityIndicatorsLoading && qualityIndicators.length === 0\" class=\"quality-empty\">\n No quality indicators available for this year.\n </div>\n <table *ngIf=\"!qualityIndicatorsLoading && qualityIndicators.length > 0\" class=\"quality-table\">\n <thead>\n <tr>\n <th>Model</th>\n <th>Compare</th>\n <th>Gauges</th>\n <th>Period</th>\n <th>Avg Quality</th>\n <th>Updated</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let indicator of qualityIndicators\">\n <td>{{ indicator.computingVersion }}</td>\n <td>{{ indicator.qualityVersion }}</td>\n <td>{{ indicator.provider }}<br>{{ indicator.timeStepInMinutes }} min</td>\n <td>{{ formatDate(indicator.startDate) }}<br>{{ formatDate(indicator.endDate) }}</td>\n <td>{{ indicator.averageQuality | number:'1.2-2' }}</td>\n <td>{{ formatDate(indicator.lastUpdatedAt) }}</td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n </div>\n\n <!-- Cumulative Selector Modal -->\n <cumulative-selector *ngIf=\"showCumulativeSelector\"\n [rainId]=\"rainNode?.id\"\n [currentPeriodBegin]=\"periodBegin\"\n [currentPeriodEnd]=\"periodEnd\"\n [provider]=\"selectedProvider\"\n [timeStepInMinutes]=\"selectedTimeStep\"\n [isAdmin]=\"toggleAdmin\"\n (periodSelected)=\"onCumulativePeriodSelected($event)\"\n (cancelled)=\"onCumulativeSelectorCancelled()\">\n </cumulative-selector>\n\n</div>\n", styles: [".raain-details-container{max-width:var(--app-max-width);margin:0 auto;padding:0 0 24px}.raain-details-card{width:100%;margin-bottom:20px}.raain-details-card ion-card-header{border-bottom:1px solid rgba(var(--ion-color-medium-rgb),.2)}.raain-details-card ion-card-header ion-card-title{display:flex;align-items:center}.raain-details-card ion-card-header ion-card-title ion-icon{margin-right:8px;color:var(--ion-color-primary)}.node-info-card{background-color:var(--ion-color-light)}.node-info-card .node-header{display:flex;align-items:center}.node-info-card .node-header .node-status{margin-right:16px}.node-info-card .node-header .node-status ion-icon{font-size:24px}.node-info-card .node-header .node-titles{flex:1}.node-info-card .node-header .node-titles ion-card-title{margin:0;font-size:1.4rem;font-weight:600;color:var(--ion-color-dark)}.node-info-card .node-header .node-titles ion-card-subtitle{padding-left:0;margin:4px 0 0;font-size:.9rem;color:var(--ion-color-medium)}.count-map-card,.period-card{background-color:var(--ion-color-light)}.period-card ion-card-title{display:flex;align-items:center}.period-card ion-card-title ion-icon{margin-right:8px;color:var(--ion-color-primary);font-size:20px}.period-row{display:flex;flex-wrap:wrap;align-items:center;gap:16px;position:relative}.now-button{min-width:100px}#all-dates{display:flex;align-items:center;margin-left:auto}#all-dates .toggle-label{margin-right:8px;white-space:nowrap}.refresh-button ion-icon{margin-right:4px;color:var(--ion-color-light)}.provider-selection{display:flex;align-items:center}.quality-info-button{--padding-start: 8px;--padding-end: 8px;font-size:.85rem;color:var(--ion-color-medium)}.quality-info-button ion-icon{font-size:18px;margin-left:4px}.selection-row{display:flex;flex-direction:row;align-items:center;gap:12px}.selection-row ion-select{flex:0 0 auto;min-width:100px;margin-bottom:0;padding:4px 8px;border:1px solid rgba(var(--ion-color-medium-rgb),.3);border-radius:var(--ion-border-radius);background-color:var(--ion-color-light)}.period-start,.period-duration{display:flex;align-items:center}.toggle-cumulative{display:flex;align-items:center;gap:8px;margin-left:auto}.toggle-cumulative .text-primary{color:var(--ion-color-primary);font-weight:600}.hidden-label{display:none}.datetime-input,#periodDuration,.duration-select{padding:8px 12px;border:1px solid rgba(var(--ion-color-medium-rgb),.3);border-radius:var(--ion-border-radius);background-color:var(--ion-color-light);font-family:var(--ion-font-family)}.datetime-input:focus,#periodDuration:focus,.duration-select:focus{outline:none;border-color:var(--ion-color-primary)}#periodDuration,.duration-select{min-width:150px}.gauge-card{background-color:var(--ion-color-light)}.gauge-card ion-card-title{display:flex;align-items:center}.gauge-card ion-card-title ion-icon{margin-right:8px;color:var(--ion-color-primary);font-size:20px}.error-row{cursor:pointer;background-color:rgba(var(--ion-color-danger-rgb),.1);border-left:3px solid var(--ion-color-danger);margin-top:8px;border-radius:4px;transition:background-color .2s ease}.error-row:hover{background-color:rgba(var(--ion-color-danger-rgb),.15)}.error-row .error-content{display:flex;align-items:flex-start;padding:8px 12px;gap:8px}.error-row .error-icon{color:var(--ion-color-danger);font-size:18px;flex-shrink:0;margin-top:2px}.error-row .error-text{flex:1;color:var(--ion-color-danger-shade);font-size:.9rem;word-break:break-word}.error-row .error-text.expanded{white-space:pre-wrap}.error-row .error-caret{color:var(--ion-color-danger);font-size:16px;flex-shrink:0;margin-top:2px}raain-compare-stack{width:100%;display:block}@media (max-width: 768px){.period-row{flex-direction:row;justify-content:space-between;align-items:center}#all-dates{margin-left:auto;padding-left:8px}#all-dates .toggle-label{font-size:.9rem}.map-header{flex-direction:row;justify-content:space-between;align-items:center;gap:16px}}.quality-modal-overlay{position:fixed;inset:0;background-color:#00000080;display:flex;align-items:center;justify-content:center;z-index:9999}.quality-modal-content{background-color:var(--ion-background-color, #fff);border-radius:12px;width:95%;max-width:900px;max-height:80vh;overflow:auto;box-shadow:0 4px 24px #0003}.quality-modal-header{display:flex;align-items:center;justify-content:space-between;padding:16px 20px;border-bottom:1px solid rgba(var(--ion-color-medium-rgb),.2)}.quality-modal-header h2{margin:0;font-size:1.25rem;font-weight:600;color:var(--ion-color-dark)}.quality-modal-header ion-button{--padding-start: 8px;--padding-end: 8px}.quality-modal-body{padding:20px}.quality-table{width:100%;border-collapse:collapse;margin-top:16px;table-layout:fixed}.quality-table th,.quality-table td{width:16.66%;padding:12px 16px;text-align:center;vertical-align:top;border-bottom:1px solid rgba(var(--ion-color-medium-rgb),.2)}.quality-table th{background-color:rgba(var(--ion-color-primary-rgb),.1);font-weight:600;color:var(--ion-color-dark)}.quality-table td{color:var(--ion-color-dark-tint);font-size:.7rem}.quality-table tbody tr:hover{background-color:rgba(var(--ion-color-primary-rgb),.05)}.quality-loading{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:40px 20px;color:var(--ion-color-medium)}.quality-loading ion-spinner{margin-bottom:12px}.quality-empty{text-align:center;padding:40px 20px;color:var(--ion-color-medium);font-style:italic}\n"], dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i4.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i4.IonCard, selector: "ion-card", inputs: ["button", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i4.IonCardContent, selector: "ion-card-content", inputs: ["mode"] }, { kind: "component", type: i4.IonCardHeader, selector: "ion-card-header", inputs: ["color", "mode", "translucent"] }, { kind: "component", type: i4.IonCardTitle, selector: "ion-card-title", inputs: ["color", "mode"] }, { kind: "component", type: i4.IonCol, selector: "ion-col", inputs: ["offset", "offsetLg", "offsetMd", "offsetSm", "offsetXl", "offsetXs", "pull", "pullLg", "pullMd", "pullSm", "pullXl", "pullXs", "push", "pushLg", "pushMd", "pushSm", "pushXl", "pushXs", "size", "sizeLg", "sizeMd", "sizeSm", "sizeXl", "sizeXs"] }, { kind: "component", type: i4.IonGrid, selector: "ion-grid", inputs: ["fixed"] }, { kind: "component", type: i4.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i4.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i4.IonProgressBar, selector: "ion-progress-bar", inputs: ["buffer", "color", "mode", "reversed", "type", "value"] }, { kind: "component", type: i4.IonRow, selector: "ion-row" }, { kind: "component", type: i4.IonSelect, selector: "ion-select", inputs: ["cancelText", "compareWith", "disabled", "interface", "interfaceOptions", "mode", "multiple", "name", "okText", "placeholder", "selectedText", "value"] }, { kind: "component", type: i4.IonSelectOption, selector: "ion-select-option", inputs: ["disabled", "value"] }, { kind: "component", type: i4.IonSpinner, selector: "ion-spinner", inputs: ["color", "duration", "name", "paused"] }, { kind: "component", type: i4.IonToggle, selector: "ion-toggle", inputs: ["checked", "color", "disabled", "mode", "name", "value"] }, { kind: "directive", type: i4.BooleanValueAccessor, selector: "ion-checkbox,ion-toggle" }, { kind: "directive", type: i4.SelectValueAccessor, selector: "ion-range, ion-select, ion-radio-group, ion-segment, ion-datetime" }, { kind: "component", type: i5.RaainMapComponent, selector: "raain-map", inputs: ["coordinates", "markers", "timeframeContainers", "autoplay", "showMarkers", "showSpeedMarkers", "showVisiblePixelMarkers", "showCumulative", "cumulativeDurationInMinutes", "currentHeight", "timeframeDates", "defaultDate", "sumValues", "sumFn"], outputs: ["selectedMarker", "changedDate", "changedSum"] }, { kind: "component", type: i6.RaainCompareStackComponent, selector: "raain-compare-stack", inputs: ["compareManager", "currentHeight", "cumulative"], outputs: ["selectedPoint"] }, { kind: "component", type: i7.RaainDateFocusComponent, selector: "raain-date-focus", inputs: ["points", "focusDate", "focusRange", "withoutAll", "currentHeight"] }, { kind: "component", type: i8.RaainDateDynamicComponent, selector: "raain-date-dynamic", inputs: ["points", "focusDate", "focusRange", "withoutAll", "currentHeight", "fetchData"], outputs: ["changedDate"] }, { kind: "component", type: i9.CumulativeSelectorComponent, selector: "cumulative-selector", inputs: ["rainId", "currentPeriodBegin", "currentPeriodEnd", "provider", "timeStepInMinutes", "isAdmin"], outputs: ["periodSelected", "cancelled"] }, { kind: "pipe", type: i2.DecimalPipe, name: "number" }, { kind: "pipe", type: i2.DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
505
568
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: RaainDetailsComponent, decorators: [{
506
569
  type: Component,
507
- args: [{ selector: 'raain-details', changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Main content container -->\n<div *ngIf=\"rainNode\" class=\"raain-details-container\">\n\n <!-- Period selection section -->\n <ion-card class=\"period-card\">\n <ion-card-content>\n <div class=\"period-controls\">\n <div class=\"period-row\">\n\n <ion-button (click)=\"toggleHistory = !toggleHistory; onEnableCountHistoryTab(rainNode)\"\n fill=\"outline\">\n <ion-icon name=\"calendar-clear-outline\" slot=\"start\"></ion-icon>\n <ion-icon [name]=\"toggleHistory ? 'chevron-down' : 'chevron-forward'\" slot=\"end\"></ion-icon>\n </ion-button>\n\n <div class=\"period-start ion-hide-md-down\">\n <input (change)=\"onPeriodBeginChange($event)\"\n [disabled]=\"toggleCumulative\"\n [value]=\"periodBeginAsString\"\n class=\"datetime-input\"\n type=\"datetime-local\">\n </div>\n\n <div class=\"period-duration ion-hide-md-down\">\n <ion-select (ionDismiss)=\"onPeriodDurationChange($event)\"\n [(ngModel)]=\"periodDurationAsString\"\n class=\"duration-select\"\n id=\"periodDuration\"\n interface=\"popover\">\n <ion-select-option value=\"0.25\">15 minutes</ion-select-option>\n <ion-select-option value=\"0.5\">30 minutes</ion-select-option>\n <ion-select-option value=\"1\">1 hour</ion-select-option>\n <ion-select-option value=\"2\">2 hours</ion-select-option>\n <ion-select-option value=\"3\">3 hours</ion-select-option>\n <ion-select-option value=\"4\">4 hours</ion-select-option>\n <ion-select-option value=\"5\">5 hours</ion-select-option>\n <ion-select-option value=\"6\">6 hours</ion-select-option>\n <ion-select-option value=\"8\">8 hours</ion-select-option>\n <ion-select-option value=\"10\">10 hours</ion-select-option>\n <ion-select-option value=\"12\">12 hours</ion-select-option>\n <ion-select-option *ngIf=\"isAdmin\" value=\"24\">24 hours</ion-select-option>\n </ion-select>\n </div>\n\n <div class=\"period-start ion-hide-md-down\">\n <input (change)=\"onPeriodEndChange($event)\"\n [disabled]=\"!toggleCumulative\"\n [value]=\"periodEndAsString\"\n class=\"datetime-input\"\n type=\"datetime-local\">\n </div>\n\n <div class=\"toggle-cumulative\">\n <ion-label [class.text-primary]=\"toggleCumulative\">\n {{ toggleCumulative ? 'Cumulative' : 'Granular' }}\n </ion-label>\n <ion-toggle (ionChange)=\"toggleCumulativeChanged($event)\"\n [(ngModel)]=\"toggleCumulative\"\n [checked]=\"toggleCumulative\">\n </ion-toggle>\n </div>\n </div>\n\n <!-- Hidden label for change detection (uncomment to debug)\n <div class=\"hidden-label\">{{ onChangeDetectionTest(rainNode) }}</div>\n -->\n </div>\n\n <!-- Historical map section -->\n <div *ngIf=\"toggleHistory\" class=\"period-controls\">\n <raain-date-dynamic (changedDate)=\"onDateChangeInCount($event)\"\n [currentHeight]=\"300\"\n [fetchData]=\"fetchDataWrapper\"\n [points]=\"countPoints\">\n </raain-date-dynamic>\n </div>\n </ion-card-content>\n </ion-card>\n\n <!-- Map performance -->\n <ion-grid class=\"map-performance\">\n <ion-row id=\"progressAndRefresh\">\n <ion-col class=\"provider-selection\" size=\"12\" size-md=\"6\">\n <ion-button (click)=\"openQualityModal()\" class=\"quality-info-button\" fill=\"clear\">\n {{ refreshManager.rainComputationMapVersion }}\n <ion-icon name=\"help-circle-outline\" slot=\"end\"></ion-icon>\n </ion-button>\n <div *ngIf=\"availableProviders.length > 0 || availableTimeSteps.length > 0\" class=\"selection-row\">\n <ion-select (ionChange)=\"onProviderChanged($event)\"\n [value]=\"selectedProvider\"\n interface=\"popover\"\n label=\"Provider\"\n placeholder=\"Select Provider\">\n <ion-select-option *ngFor=\"let provider of availableProviders\" [value]=\"provider\">\n {{ provider }}\n </ion-select-option>\n </ion-select>\n\n <ion-select (ionChange)=\"onTimeStepChanged($event)\"\n [value]=\"selectedTimeStep\"\n interface=\"popover\"\n label=\"Time Step\"\n placeholder=\"Select Time Step\">\n <ion-select-option *ngFor=\"let step of availableTimeSteps\" [value]=\"step\">\n {{ step }} min\n </ion-select-option>\n </ion-select>\n </div>\n </ion-col>\n <ion-col class=\"ion-text-right\" size=\"12\" size-md=\"6\">\n <ion-label class=\"ion-margin-end\">\n <span *ngIf=\"percentOfComputations\">\n {{ percentOfComputations }}% Images\n <i *ngIf=\"countsPeriod.progress\" class=\"progress-indicator\">\n In Progress: {{ countsPeriod.progress }}...\n </i>\n </span>\n <span *ngIf=\"!percentOfComputations\">\n No image available\n </span>\n\n </ion-label>\n\n <ion-button (click)=\"refreshMap()\" [disabled]=\"refreshInProgress\" class=\"refresh-button\">\n Refresh Map\n </ion-button>\n </ion-col>\n </ion-row>\n\n <!-- status update row -->\n <ion-row>\n <!-- Progress col -->\n <ion-progress-bar\n [buffer]=\"(countsPeriod.progress / ((timeframeDates?.length || 10) +3))+0.01\"\n [style.visibility]=\"refreshInProgress ? 'visible' : 'hidden'\"\n [value]=\"countsPeriod.progress / ((timeframeDates?.length || 10) +3)\"\n color=\"primary\">\n </ion-progress-bar>\n\n <!-- Error col -->\n <ion-col (click)=\"showFullError = !showFullError\" *ngIf=\"refreshManager.lastError\" class=\"error-row\"\n size=\"12\">\n <div class=\"error-content\">\n <ion-icon class=\"error-icon\" name=\"warning-outline\"></ion-icon>\n <span [class.expanded]=\"showFullError\" class=\"error-text\">\n {{ showFullError ? refreshManager.lastError : truncatedError }}\n </span>\n <ion-icon [name]=\"showFullError ? 'chevron-up' : 'chevron-down'\" class=\"error-caret\"></ion-icon>\n </div>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n <!-- Map section -->\n <ion-card class=\"map-card\">\n <ion-card-content class=\"map-content\">\n <ion-grid>\n <ion-row *ngIf=\"toggleMap && percentOfImages\">\n <!-- Map component -->\n <ion-col class=\"map-column\" size-lg=\"7\" size-md=\"12\">\n <div class=\"map-container\">\n <raain-map #raainMapRef\n (changedDate)=\"onDateChangeInMap($event)\"\n (changedSum)=\"onSumChangeInMap($event)\"\n (selectedMarker)=\"onGaugeSelectInMap($event)\"\n [coordinates]=\"coordinates\"\n [cumulativeDurationInMinutes]=\"cumulativeDurationInMinutes\"\n [currentHeight]=\"500\"\n [defaultDate]=\"dateShown\"\n [markers]=\"{\n borders,\n gauges: compareManager.gaugesInMap,\n gaugesInCompare: compareManager.gaugesInCompare,\n selectedGauges: compareManager.selectedGauges,\n pixels: compareManager.selectedPixels,\n pixelsSolution: compareManager.pixelsSolutions?.length ? compareManager.pixelsSolutions[0] : [],\n speeds: compareManager.speeds\n }\"\n [showCumulative]=\"toggleCumulative\"\n [showVisiblePixelMarkers]=\"showPixelMarkers\"\n [sumFn]=\"refreshManager.sumFn\"\n [sumValues]=\"refreshManager.sumValues\"\n [timeframeContainers]=\"timeframeContainers\"\n [timeframeDates]=\"timeframeDates\">\n </raain-map>\n </div>\n\n <div class=\"data-column\">\n <!-- Technical details (collapsible for cleaner UI) -->\n <details class=\"technical-details\">\n <summary>Image Details</summary>\n <div class=\"details-content\">\n <div class=\"detail-row\">\n <span class=\"detail-label\">Computed:</span>\n <span class=\"detail-value\">{{ refreshManager.rainComputationMapDoneDate | date:'yyyy-MM-dd HH:mm' }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Version:</span>\n <span class=\"detail-value\">{{ refreshManager.rainComputationMapVersion }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Launched by:</span>\n <span class=\"detail-value\">{{ refreshManager.rainComputationMapLaunchedBy }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Time spent:</span>\n <span class=\"detail-value\">{{ refreshManager.rainComputationMapTimeSpentInMs }}\n ms</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Date:</span>\n <span class=\"detail-value\">{{ refreshManager.rainComputationMapDate?.toISOString() }}\n | {{ refreshManager.rainComputationMapDate | date:'yyyy-MM-dd HH:mm' }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Water in the map:</span>\n <span class=\"detail-value\">{{ sumDetails }}</span>\n <ion-toggle\n (ionChange)=\"onTogglePixelMarkers()\"\n [(ngModel)]=\"showPixelMarkers\"\n style=\"margin-left: 8px; transform: scale(0.7);\">\n </ion-toggle>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Source DBZ min:</span>\n <span class=\"detail-value\">{{ refreshManager.rainComputationMapOriginalMin }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Source DBZ max:</span>\n <span class=\"detail-value\">{{ refreshManager.rainComputationMapOriginalMax }}</span>\n </div>\n </div>\n </details>\n </div>\n </ion-col>\n\n <!-- Data panel -->\n <ion-col *ngIf=\"!!compareManager.compareVersion\" class=\"data-column\" size-lg=\"5\" size-md=\"12\">\n <div class=\"data-panel\">\n <!-- Compare stack component -->\n <div class=\"compare-stack\">\n <raain-compare-stack\n (selectedPoint)=\"onGaugeSelectInCompare($event)\"\n [compareManager]=\"compareManager\"\n [cumulative]=\"toggleCumulative\">\n </raain-compare-stack>\n </div>\n\n <!-- Technical details (collapsible for cleaner UI) -->\n <details class=\"technical-details\">\n <summary>Compare Details</summary>\n <div class=\"details-content\">\n <div [ngClass]=\"{'warning': refreshManager.rainComputationMapDoneDate?.getTime() > compareManager.currentQualityDoneDate?.getTime() + 60000}\"\n class=\"detail-row\">\n <span class=\"detail-label\">Computed:</span>\n <span class=\"detail-value\">{{ compareManager.currentQualityDoneDate | date:'yyyy-MM-dd HH:mm' }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Version:</span>\n <span class=\"detail-value\">{{ compareManager.compareVersion }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Launched by:</span>\n <span class=\"detail-value\">{{ compareManager.currentQualityLaunchedBy }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Time spent:</span>\n <span class=\"detail-value\">{{ compareManager.currentQualityTimeSpentInMs }}\n ms</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Gauges:</span>\n <span class=\"detail-value\">{{ compareManager.gaugesInCompare.length }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Points:</span>\n <span class=\"detail-value\">{{ compareManager.globalComparePoints.length }}</span>\n </div>\n </div>\n </details>\n </div>\n </ion-col>\n </ion-row>\n <ion-row>\n <!-- Bottom progress bar -->\n <ion-progress-bar *ngIf=\"refreshInProgress\"\n [buffer]=\"(countsPeriod.progress / ((timeframeDates?.length || 10) +3))+0.01\"\n [value]=\"countsPeriod.progress / ((timeframeDates?.length || 10) +3)\"\n color=\"primary\">\n </ion-progress-bar>\n </ion-row>\n </ion-grid>\n </ion-card-content>\n </ion-card>\n\n <!-- Gauge values section -->\n <ion-card *ngIf=\"gaugeSelectedPoints.length && gaugeSelectedPoints[0].values.length\" class=\"gauge-card\">\n <ion-card-header>\n <ion-card-title>\n <ion-icon name=\"analytics-outline\"></ion-icon>\n Selected Gauge Data\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <raain-date-focus\n [currentHeight]=\"300\"\n [focusDate]=\"periodBegin\"\n [focusRange]=\"DateRange.DAY\"\n [points]=\"gaugeSelectedPoints\"\n [withoutAll]=\"true\">\n </raain-date-focus>\n </ion-card-content>\n </ion-card>\n\n <!-- Quality Performance Modal -->\n <div (click)=\"closeQualityModal()\" *ngIf=\"showQualityModal\" class=\"quality-modal-overlay\">\n <div (click)=\"$event.stopPropagation()\" class=\"quality-modal-content\">\n <div class=\"quality-modal-header\">\n <h2>Model Quality Performance</h2>\n <ion-button (click)=\"closeQualityModal()\" fill=\"clear\">\n <ion-icon name=\"close-outline\"></ion-icon>\n </ion-button>\n </div>\n <div class=\"quality-modal-body\">\n <div *ngIf=\"qualityIndicatorsLoading\" class=\"quality-loading\">\n <ion-spinner name=\"crescent\"></ion-spinner>\n <span>Loading indicators...</span>\n </div>\n <div *ngIf=\"!qualityIndicatorsLoading && qualityIndicators.length === 0\" class=\"quality-empty\">\n No quality indicators available for this year.\n </div>\n <table *ngIf=\"!qualityIndicatorsLoading && qualityIndicators.length > 0\" class=\"quality-table\">\n <thead>\n <tr>\n <th>Model</th>\n <th>Compare</th>\n <th>Gauges</th>\n <th>Period</th>\n <th>Avg Quality</th>\n <th>Updated</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let indicator of qualityIndicators\">\n <td>{{ indicator.computingVersion }}</td>\n <td>{{ indicator.qualityVersion }}</td>\n <td>{{ indicator.provider }}<br>{{ indicator.timeStepInMinutes }} min</td>\n <td>{{ formatDate(indicator.startDate) }}<br>{{ formatDate(indicator.endDate) }}</td>\n <td>{{ indicator.averageQuality | number:'1.2-2' }}</td>\n <td>{{ formatDate(indicator.lastUpdatedAt) }}</td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n </div>\n\n</div>\n", styles: [".raain-details-container{max-width:var(--app-max-width);margin:0 auto;padding:0 0 24px}.raain-details-card{width:100%;margin-bottom:20px}.raain-details-card ion-card-header{border-bottom:1px solid rgba(var(--ion-color-medium-rgb),.2)}.raain-details-card ion-card-header ion-card-title{display:flex;align-items:center}.raain-details-card ion-card-header ion-card-title ion-icon{margin-right:8px;color:var(--ion-color-primary)}.node-info-card{background-color:var(--ion-color-light)}.node-info-card .node-header{display:flex;align-items:center}.node-info-card .node-header .node-status{margin-right:16px}.node-info-card .node-header .node-status ion-icon{font-size:24px}.node-info-card .node-header .node-titles{flex:1}.node-info-card .node-header .node-titles ion-card-title{margin:0;font-size:1.4rem;font-weight:600;color:var(--ion-color-dark)}.node-info-card .node-header .node-titles ion-card-subtitle{padding-left:0;margin:4px 0 0;font-size:.9rem;color:var(--ion-color-medium)}.count-map-card,.period-card{background-color:var(--ion-color-light)}.period-card ion-card-title{display:flex;align-items:center}.period-card ion-card-title ion-icon{margin-right:8px;color:var(--ion-color-primary);font-size:20px}.period-row{display:flex;flex-wrap:wrap;align-items:center;gap:16px;position:relative}.now-button{min-width:100px}#all-dates{display:flex;align-items:center;margin-left:auto}#all-dates .toggle-label{margin-right:8px;white-space:nowrap}.refresh-button ion-icon{margin-right:4px;color:var(--ion-color-light)}.provider-selection{display:flex;align-items:center}.quality-info-button{--padding-start: 8px;--padding-end: 8px;font-size:.85rem;color:var(--ion-color-medium)}.quality-info-button ion-icon{font-size:18px;margin-left:4px}.selection-row{display:flex;flex-direction:row;align-items:center;gap:12px}.selection-row ion-select{flex:0 0 auto;min-width:100px;margin-bottom:0;padding:4px 8px;border:1px solid rgba(var(--ion-color-medium-rgb),.3);border-radius:var(--ion-border-radius);background-color:var(--ion-color-light)}.period-start,.period-duration{display:flex;align-items:center}.toggle-cumulative{display:flex;align-items:center;gap:8px;margin-left:auto}.toggle-cumulative .text-primary{color:var(--ion-color-primary);font-weight:600}.hidden-label{display:none}.datetime-input,#periodDuration,.duration-select{padding:8px 12px;border:1px solid rgba(var(--ion-color-medium-rgb),.3);border-radius:var(--ion-border-radius);background-color:var(--ion-color-light);font-family:var(--ion-font-family)}.datetime-input:focus,#periodDuration:focus,.duration-select:focus{outline:none;border-color:var(--ion-color-primary)}#periodDuration,.duration-select{min-width:150px}.gauge-card{background-color:var(--ion-color-light)}.gauge-card ion-card-title{display:flex;align-items:center}.gauge-card ion-card-title ion-icon{margin-right:8px;color:var(--ion-color-primary);font-size:20px}.error-row{cursor:pointer;background-color:rgba(var(--ion-color-danger-rgb),.1);border-left:3px solid var(--ion-color-danger);margin-top:8px;border-radius:4px;transition:background-color .2s ease}.error-row:hover{background-color:rgba(var(--ion-color-danger-rgb),.15)}.error-row .error-content{display:flex;align-items:flex-start;padding:8px 12px;gap:8px}.error-row .error-icon{color:var(--ion-color-danger);font-size:18px;flex-shrink:0;margin-top:2px}.error-row .error-text{flex:1;color:var(--ion-color-danger-shade);font-size:.9rem;word-break:break-word}.error-row .error-text.expanded{white-space:pre-wrap}.error-row .error-caret{color:var(--ion-color-danger);font-size:16px;flex-shrink:0;margin-top:2px}raain-compare-stack{width:100%;display:block}@media (max-width: 768px){.period-row{flex-direction:row;justify-content:space-between;align-items:center}#all-dates{margin-left:auto;padding-left:8px}#all-dates .toggle-label{font-size:.9rem}.map-header{flex-direction:row;justify-content:space-between;align-items:center;gap:16px}}.quality-modal-overlay{position:fixed;inset:0;background-color:#00000080;display:flex;align-items:center;justify-content:center;z-index:9999}.quality-modal-content{background-color:var(--ion-background-color, #fff);border-radius:12px;width:95%;max-width:900px;max-height:80vh;overflow:auto;box-shadow:0 4px 24px #0003}.quality-modal-header{display:flex;align-items:center;justify-content:space-between;padding:16px 20px;border-bottom:1px solid rgba(var(--ion-color-medium-rgb),.2)}.quality-modal-header h2{margin:0;font-size:1.25rem;font-weight:600;color:var(--ion-color-dark)}.quality-modal-header ion-button{--padding-start: 8px;--padding-end: 8px}.quality-modal-body{padding:20px}.quality-table{width:100%;border-collapse:collapse;margin-top:16px;table-layout:fixed}.quality-table th,.quality-table td{width:16.66%;padding:12px 16px;text-align:center;vertical-align:top;border-bottom:1px solid rgba(var(--ion-color-medium-rgb),.2)}.quality-table th{background-color:rgba(var(--ion-color-primary-rgb),.1);font-weight:600;color:var(--ion-color-dark)}.quality-table td{color:var(--ion-color-dark-tint);font-size:.7rem}.quality-table tbody tr:hover{background-color:rgba(var(--ion-color-primary-rgb),.05)}.quality-loading{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:40px 20px;color:var(--ion-color-medium)}.quality-loading ion-spinner{margin-bottom:12px}.quality-empty{text-align:center;padding:40px 20px;color:var(--ion-color-medium);font-style:italic}\n"] }]
570
+ args: [{ selector: 'raain-details', changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Main content container -->\n<div *ngIf=\"rainNode\" class=\"raain-details-container\">\n\n <!-- Period selection section -->\n <ion-card class=\"period-card\">\n <ion-card-content>\n <div class=\"period-controls\">\n <div class=\"period-row\">\n\n <ion-button (click)=\"toggleHistory = !toggleHistory; onEnableCountHistoryTab(rainNode)\"\n fill=\"outline\">\n <ion-icon name=\"calendar-clear-outline\" slot=\"start\"></ion-icon>\n <ion-icon [name]=\"toggleHistory ? 'chevron-down' : 'chevron-forward'\" slot=\"end\"></ion-icon>\n </ion-button>\n\n <div class=\"period-start ion-hide-md-down\">\n <input (change)=\"onPeriodBeginChange($event)\"\n [disabled]=\"toggleCumulative\"\n [value]=\"periodBeginAsString\"\n class=\"datetime-input\"\n type=\"datetime-local\">\n </div>\n\n <div class=\"period-duration ion-hide-md-down\">\n <ion-select (ionDismiss)=\"onPeriodDurationChange($event)\"\n [(ngModel)]=\"periodDurationAsString\"\n [disabled]=\"toggleCumulative\"\n class=\"duration-select\"\n id=\"periodDuration\"\n interface=\"popover\">\n <ion-select-option value=\"0.25\">15 minutes</ion-select-option>\n <ion-select-option value=\"0.5\">30 minutes</ion-select-option>\n <ion-select-option value=\"1\">1 hour</ion-select-option>\n <ion-select-option value=\"2\">2 hours</ion-select-option>\n <ion-select-option value=\"3\">3 hours</ion-select-option>\n <ion-select-option value=\"4\">4 hours</ion-select-option>\n <ion-select-option value=\"5\">5 hours</ion-select-option>\n <ion-select-option value=\"6\">6 hours</ion-select-option>\n <ion-select-option value=\"8\">8 hours</ion-select-option>\n <ion-select-option value=\"10\">10 hours</ion-select-option>\n <ion-select-option value=\"12\">12 hours</ion-select-option>\n <ion-select-option *ngIf=\"isAdmin\" value=\"24\">24 hours</ion-select-option>\n </ion-select>\n </div>\n\n <div class=\"period-start ion-hide-md-down\">\n <input (change)=\"onPeriodEndChange($event)\"\n [disabled]=\"toggleCumulative\"\n [value]=\"periodEndAsString\"\n class=\"datetime-input\"\n type=\"datetime-local\">\n </div>\n\n <div class=\"toggle-cumulative\" (click)=\"onCumulativeToggleClick($event)\">\n <ion-label [class.text-primary]=\"toggleCumulative\">\n {{ toggleCumulative ? 'Cumulative' : 'Granular' }}\n </ion-label>\n <ion-toggle #cumulativeToggle [checked]=\"toggleCumulative\">\n </ion-toggle>\n </div>\n </div>\n\n <!-- Hidden label for change detection (uncomment to debug)\n <div class=\"hidden-label\">{{ onChangeDetectionTest(rainNode) }}</div>\n -->\n </div>\n\n <!-- Historical map section -->\n <div *ngIf=\"toggleHistory\" class=\"period-controls\">\n <raain-date-dynamic (changedDate)=\"onDateChangeInCount($event)\"\n [currentHeight]=\"300\"\n [fetchData]=\"fetchDataWrapper\"\n [points]=\"countPoints\">\n </raain-date-dynamic>\n </div>\n </ion-card-content>\n </ion-card>\n\n <!-- Map performance -->\n <ion-grid class=\"map-performance\">\n <ion-row id=\"progressAndRefresh\">\n <ion-col class=\"provider-selection\" size=\"12\" size-md=\"6\">\n <ion-button (click)=\"openQualityModal()\" class=\"quality-info-button\" fill=\"clear\">\n {{ refreshManager.rainComputationMapVersion }}\n <ion-icon name=\"help-circle-outline\" slot=\"end\"></ion-icon>\n </ion-button>\n <div *ngIf=\"availableProviders.length > 0 || availableTimeSteps.length > 0\" class=\"selection-row\">\n <ion-select (ionChange)=\"onProviderChanged($event)\"\n [value]=\"selectedProvider\"\n interface=\"popover\"\n label=\"Provider\"\n placeholder=\"Select Provider\">\n <ion-select-option *ngFor=\"let provider of availableProviders\" [value]=\"provider\">\n {{ provider }}\n </ion-select-option>\n </ion-select>\n\n <ion-select (ionChange)=\"onTimeStepChanged($event)\"\n [value]=\"selectedTimeStep\"\n interface=\"popover\"\n label=\"Time Step\"\n placeholder=\"Select Time Step\">\n <ion-select-option *ngFor=\"let step of availableTimeSteps\" [value]=\"step\">\n {{ step }} min\n </ion-select-option>\n </ion-select>\n </div>\n </ion-col>\n <ion-col class=\"ion-text-right\" size=\"12\" size-md=\"6\">\n <ion-label class=\"ion-margin-end\">\n <span *ngIf=\"percentOfComputations\">\n {{ percentOfComputations }}% Images\n <i *ngIf=\"countsPeriod.progress\" class=\"progress-indicator\">\n In Progress: {{ countsPeriod.progress }}...\n </i>\n </span>\n <span *ngIf=\"!percentOfComputations\">\n No image available\n </span>\n\n </ion-label>\n\n <ion-button (click)=\"refreshMap()\" [disabled]=\"refreshInProgress\" class=\"refresh-button\">\n Refresh Map\n </ion-button>\n </ion-col>\n </ion-row>\n\n <!-- status update row -->\n <ion-row>\n <!-- Progress col -->\n <ion-progress-bar\n [buffer]=\"(countsPeriod.progress / ((timeframeDates?.length || 10) +3))+0.01\"\n [style.visibility]=\"refreshInProgress ? 'visible' : 'hidden'\"\n [value]=\"countsPeriod.progress / ((timeframeDates?.length || 10) +3)\"\n color=\"primary\">\n </ion-progress-bar>\n\n <!-- Error col -->\n <ion-col (click)=\"showFullError = !showFullError\" *ngIf=\"refreshManager.lastError\" class=\"error-row\"\n size=\"12\">\n <div class=\"error-content\">\n <ion-icon class=\"error-icon\" name=\"warning-outline\"></ion-icon>\n <span [class.expanded]=\"showFullError\" class=\"error-text\">\n {{ showFullError ? refreshManager.lastError : truncatedError }}\n </span>\n <ion-icon [name]=\"showFullError ? 'chevron-up' : 'chevron-down'\" class=\"error-caret\"></ion-icon>\n </div>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n <!-- Map section -->\n <ion-card class=\"map-card\">\n <ion-card-content class=\"map-content\">\n <ion-grid>\n <ion-row *ngIf=\"toggleMap && percentOfImages\">\n <!-- Map component -->\n <ion-col class=\"map-column\" size-lg=\"7\" size-md=\"12\">\n <div class=\"map-container\">\n <raain-map #raainMapRef\n (changedDate)=\"onDateChangeInMap($event)\"\n (changedSum)=\"onSumChangeInMap($event)\"\n (selectedMarker)=\"onGaugeSelectInMap($event)\"\n [coordinates]=\"coordinates\"\n [cumulativeDurationInMinutes]=\"cumulativeDurationInMinutes\"\n [currentHeight]=\"500\"\n [defaultDate]=\"dateShown\"\n [markers]=\"{\n borders,\n gauges: compareManager.gaugesInMap,\n gaugesInCompare: compareManager.gaugesInCompare,\n selectedGauges: compareManager.selectedGauges,\n pixels: compareManager.selectedPixels,\n pixelsSolution: compareManager.pixelsSolutions?.length ? compareManager.pixelsSolutions[0] : [],\n speeds: compareManager.speeds\n }\"\n [showCumulative]=\"toggleCumulative\"\n [showVisiblePixelMarkers]=\"showPixelMarkers\"\n [sumFn]=\"refreshManager.sumFn\"\n [sumValues]=\"refreshManager.sumValues\"\n [timeframeContainers]=\"timeframeContainers\"\n [timeframeDates]=\"timeframeDates\">\n </raain-map>\n </div>\n\n <div class=\"data-column\">\n <!-- Technical details (collapsible for cleaner UI) -->\n <details class=\"technical-details\">\n <summary>Image Details</summary>\n <div class=\"details-content\">\n <div class=\"detail-row\">\n <span class=\"detail-label\">Computed:</span>\n <span class=\"detail-value\">{{ refreshManager.rainComputationMapDoneDate | date:'yyyy-MM-dd HH:mm' }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Version:</span>\n <span class=\"detail-value\">{{ refreshManager.rainComputationMapVersion }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Launched by:</span>\n <span class=\"detail-value\">{{ refreshManager.rainComputationMapLaunchedBy }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Time spent:</span>\n <span class=\"detail-value\">{{ refreshManager.rainComputationMapTimeSpentInMs }}\n ms</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Date:</span>\n <span class=\"detail-value\">{{ refreshManager.rainComputationMapDate?.toISOString() }}\n | {{ refreshManager.rainComputationMapDate | date:'yyyy-MM-dd HH:mm' }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Water in the map:</span>\n <span class=\"detail-value\">{{ sumDetails }}</span>\n <ion-toggle\n (ionChange)=\"onTogglePixelMarkers()\"\n [(ngModel)]=\"showPixelMarkers\"\n style=\"margin-left: 8px; transform: scale(0.7);\">\n </ion-toggle>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Source DBZ min:</span>\n <span class=\"detail-value\">{{ refreshManager.rainComputationMapOriginalMin }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Source DBZ max:</span>\n <span class=\"detail-value\">{{ refreshManager.rainComputationMapOriginalMax }}</span>\n </div>\n </div>\n </details>\n </div>\n </ion-col>\n\n <!-- Data panel -->\n <ion-col *ngIf=\"!!compareManager.compareVersion\" class=\"data-column\" size-lg=\"5\" size-md=\"12\">\n <div class=\"data-panel\">\n <!-- Compare stack component -->\n <div class=\"compare-stack\">\n <raain-compare-stack\n (selectedPoint)=\"onGaugeSelectInCompare($event)\"\n [compareManager]=\"compareManager\"\n [cumulative]=\"toggleCumulative\">\n </raain-compare-stack>\n </div>\n\n <!-- Technical details (collapsible for cleaner UI) -->\n <details class=\"technical-details\">\n <summary>Compare Details</summary>\n <div class=\"details-content\">\n <div [ngClass]=\"{'warning': refreshManager.rainComputationMapDoneDate?.getTime() > compareManager.currentQualityDoneDate?.getTime() + 60000}\"\n class=\"detail-row\">\n <span class=\"detail-label\">Computed:</span>\n <span class=\"detail-value\">{{ compareManager.currentQualityDoneDate | date:'yyyy-MM-dd HH:mm' }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Version:</span>\n <span class=\"detail-value\">{{ compareManager.compareVersion }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Launched by:</span>\n <span class=\"detail-value\">{{ compareManager.currentQualityLaunchedBy }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Time spent:</span>\n <span class=\"detail-value\">{{ compareManager.currentQualityTimeSpentInMs }}\n ms</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Gauges:</span>\n <span class=\"detail-value\">{{ compareManager.gaugesInCompare.length }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Points:</span>\n <span class=\"detail-value\">{{ compareManager.globalComparePoints.length }}</span>\n </div>\n </div>\n </details>\n </div>\n </ion-col>\n </ion-row>\n <ion-row>\n <!-- Bottom progress bar -->\n <ion-progress-bar *ngIf=\"refreshInProgress\"\n [buffer]=\"(countsPeriod.progress / ((timeframeDates?.length || 10) +3))+0.01\"\n [value]=\"countsPeriod.progress / ((timeframeDates?.length || 10) +3)\"\n color=\"primary\">\n </ion-progress-bar>\n </ion-row>\n </ion-grid>\n </ion-card-content>\n </ion-card>\n\n <!-- Gauge values section -->\n <ion-card *ngIf=\"gaugeSelectedPoints.length && gaugeSelectedPoints[0].values.length\" class=\"gauge-card\">\n <ion-card-header>\n <ion-card-title>\n <ion-icon name=\"analytics-outline\"></ion-icon>\n Selected Gauge Data\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <raain-date-focus\n [currentHeight]=\"300\"\n [focusDate]=\"periodBegin\"\n [focusRange]=\"DateRange.DAY\"\n [points]=\"gaugeSelectedPoints\"\n [withoutAll]=\"true\">\n </raain-date-focus>\n </ion-card-content>\n </ion-card>\n\n <!-- Quality Performance Modal -->\n <div (click)=\"closeQualityModal()\" *ngIf=\"showQualityModal\" class=\"quality-modal-overlay\">\n <div (click)=\"$event.stopPropagation()\" class=\"quality-modal-content\">\n <div class=\"quality-modal-header\">\n <h2>Model Quality Performance</h2>\n <ion-button (click)=\"closeQualityModal()\" fill=\"clear\">\n <ion-icon name=\"close-outline\"></ion-icon>\n </ion-button>\n </div>\n <div class=\"quality-modal-body\">\n <div *ngIf=\"qualityIndicatorsLoading\" class=\"quality-loading\">\n <ion-spinner name=\"crescent\"></ion-spinner>\n <span>Loading indicators...</span>\n </div>\n <div *ngIf=\"!qualityIndicatorsLoading && qualityIndicators.length === 0\" class=\"quality-empty\">\n No quality indicators available for this year.\n </div>\n <table *ngIf=\"!qualityIndicatorsLoading && qualityIndicators.length > 0\" class=\"quality-table\">\n <thead>\n <tr>\n <th>Model</th>\n <th>Compare</th>\n <th>Gauges</th>\n <th>Period</th>\n <th>Avg Quality</th>\n <th>Updated</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let indicator of qualityIndicators\">\n <td>{{ indicator.computingVersion }}</td>\n <td>{{ indicator.qualityVersion }}</td>\n <td>{{ indicator.provider }}<br>{{ indicator.timeStepInMinutes }} min</td>\n <td>{{ formatDate(indicator.startDate) }}<br>{{ formatDate(indicator.endDate) }}</td>\n <td>{{ indicator.averageQuality | number:'1.2-2' }}</td>\n <td>{{ formatDate(indicator.lastUpdatedAt) }}</td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n </div>\n\n <!-- Cumulative Selector Modal -->\n <cumulative-selector *ngIf=\"showCumulativeSelector\"\n [rainId]=\"rainNode?.id\"\n [currentPeriodBegin]=\"periodBegin\"\n [currentPeriodEnd]=\"periodEnd\"\n [provider]=\"selectedProvider\"\n [timeStepInMinutes]=\"selectedTimeStep\"\n [isAdmin]=\"toggleAdmin\"\n (periodSelected)=\"onCumulativePeriodSelected($event)\"\n (cancelled)=\"onCumulativeSelectorCancelled()\">\n </cumulative-selector>\n\n</div>\n", styles: [".raain-details-container{max-width:var(--app-max-width);margin:0 auto;padding:0 0 24px}.raain-details-card{width:100%;margin-bottom:20px}.raain-details-card ion-card-header{border-bottom:1px solid rgba(var(--ion-color-medium-rgb),.2)}.raain-details-card ion-card-header ion-card-title{display:flex;align-items:center}.raain-details-card ion-card-header ion-card-title ion-icon{margin-right:8px;color:var(--ion-color-primary)}.node-info-card{background-color:var(--ion-color-light)}.node-info-card .node-header{display:flex;align-items:center}.node-info-card .node-header .node-status{margin-right:16px}.node-info-card .node-header .node-status ion-icon{font-size:24px}.node-info-card .node-header .node-titles{flex:1}.node-info-card .node-header .node-titles ion-card-title{margin:0;font-size:1.4rem;font-weight:600;color:var(--ion-color-dark)}.node-info-card .node-header .node-titles ion-card-subtitle{padding-left:0;margin:4px 0 0;font-size:.9rem;color:var(--ion-color-medium)}.count-map-card,.period-card{background-color:var(--ion-color-light)}.period-card ion-card-title{display:flex;align-items:center}.period-card ion-card-title ion-icon{margin-right:8px;color:var(--ion-color-primary);font-size:20px}.period-row{display:flex;flex-wrap:wrap;align-items:center;gap:16px;position:relative}.now-button{min-width:100px}#all-dates{display:flex;align-items:center;margin-left:auto}#all-dates .toggle-label{margin-right:8px;white-space:nowrap}.refresh-button ion-icon{margin-right:4px;color:var(--ion-color-light)}.provider-selection{display:flex;align-items:center}.quality-info-button{--padding-start: 8px;--padding-end: 8px;font-size:.85rem;color:var(--ion-color-medium)}.quality-info-button ion-icon{font-size:18px;margin-left:4px}.selection-row{display:flex;flex-direction:row;align-items:center;gap:12px}.selection-row ion-select{flex:0 0 auto;min-width:100px;margin-bottom:0;padding:4px 8px;border:1px solid rgba(var(--ion-color-medium-rgb),.3);border-radius:var(--ion-border-radius);background-color:var(--ion-color-light)}.period-start,.period-duration{display:flex;align-items:center}.toggle-cumulative{display:flex;align-items:center;gap:8px;margin-left:auto}.toggle-cumulative .text-primary{color:var(--ion-color-primary);font-weight:600}.hidden-label{display:none}.datetime-input,#periodDuration,.duration-select{padding:8px 12px;border:1px solid rgba(var(--ion-color-medium-rgb),.3);border-radius:var(--ion-border-radius);background-color:var(--ion-color-light);font-family:var(--ion-font-family)}.datetime-input:focus,#periodDuration:focus,.duration-select:focus{outline:none;border-color:var(--ion-color-primary)}#periodDuration,.duration-select{min-width:150px}.gauge-card{background-color:var(--ion-color-light)}.gauge-card ion-card-title{display:flex;align-items:center}.gauge-card ion-card-title ion-icon{margin-right:8px;color:var(--ion-color-primary);font-size:20px}.error-row{cursor:pointer;background-color:rgba(var(--ion-color-danger-rgb),.1);border-left:3px solid var(--ion-color-danger);margin-top:8px;border-radius:4px;transition:background-color .2s ease}.error-row:hover{background-color:rgba(var(--ion-color-danger-rgb),.15)}.error-row .error-content{display:flex;align-items:flex-start;padding:8px 12px;gap:8px}.error-row .error-icon{color:var(--ion-color-danger);font-size:18px;flex-shrink:0;margin-top:2px}.error-row .error-text{flex:1;color:var(--ion-color-danger-shade);font-size:.9rem;word-break:break-word}.error-row .error-text.expanded{white-space:pre-wrap}.error-row .error-caret{color:var(--ion-color-danger);font-size:16px;flex-shrink:0;margin-top:2px}raain-compare-stack{width:100%;display:block}@media (max-width: 768px){.period-row{flex-direction:row;justify-content:space-between;align-items:center}#all-dates{margin-left:auto;padding-left:8px}#all-dates .toggle-label{font-size:.9rem}.map-header{flex-direction:row;justify-content:space-between;align-items:center;gap:16px}}.quality-modal-overlay{position:fixed;inset:0;background-color:#00000080;display:flex;align-items:center;justify-content:center;z-index:9999}.quality-modal-content{background-color:var(--ion-background-color, #fff);border-radius:12px;width:95%;max-width:900px;max-height:80vh;overflow:auto;box-shadow:0 4px 24px #0003}.quality-modal-header{display:flex;align-items:center;justify-content:space-between;padding:16px 20px;border-bottom:1px solid rgba(var(--ion-color-medium-rgb),.2)}.quality-modal-header h2{margin:0;font-size:1.25rem;font-weight:600;color:var(--ion-color-dark)}.quality-modal-header ion-button{--padding-start: 8px;--padding-end: 8px}.quality-modal-body{padding:20px}.quality-table{width:100%;border-collapse:collapse;margin-top:16px;table-layout:fixed}.quality-table th,.quality-table td{width:16.66%;padding:12px 16px;text-align:center;vertical-align:top;border-bottom:1px solid rgba(var(--ion-color-medium-rgb),.2)}.quality-table th{background-color:rgba(var(--ion-color-primary-rgb),.1);font-weight:600;color:var(--ion-color-dark)}.quality-table td{color:var(--ion-color-dark-tint);font-size:.7rem}.quality-table tbody tr:hover{background-color:rgba(var(--ion-color-primary-rgb),.05)}.quality-loading{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:40px 20px;color:var(--ion-color-medium)}.quality-loading ion-spinner{margin-bottom:12px}.quality-empty{text-align:center;padding:40px 20px;color:var(--ion-color-medium);font-style:italic}\n"] }]
508
571
  }], ctorParameters: function () { return [{ type: i1.Storage }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { toggleAdmin: [{
509
572
  type: Input
510
573
  }], rainNode: [{
@@ -517,5 +580,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
517
580
  type: Input
518
581
  }], radarService: [{
519
582
  type: Input
583
+ }], cumulativeToggleRef: [{
584
+ type: ViewChild,
585
+ args: ['cumulativeToggle']
520
586
  }] } });
521
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmFhaW4tZGV0YWlscy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY29yZS9zaGFyZWQvcmFhaW4tZGV0YWlscy9yYWFpbi1kZXRhaWxzLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uL3NyYy9jb3JlL3NoYXJlZC9yYWFpbi1kZXRhaWxzL3JhYWluLWRldGFpbHMuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNILHVCQUF1QixFQUV2QixTQUFTLEVBQ1QsS0FBSyxHQUlSLE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sRUFBQyxxQkFBcUIsRUFBOEIsUUFBUSxFQUFDLE1BQU0sYUFBYSxDQUFDO0FBQ3hGLE9BQU8sRUFBQyxTQUFTLEVBQUUsU0FBUyxFQUFFLG1CQUFtQixFQUFDLE1BQU0sVUFBVSxDQUFDO0FBQ25FLE9BQU8sRUFBMkIsb0JBQW9CLEVBQWlCLE1BQU0sVUFBVSxDQUFDOzs7Ozs7Ozs7O0FBS3hGLElBQUksY0FBYyxHQUFHLENBQUMsQ0FBQztBQVF2QixNQUFNLE9BQU8scUJBQXFCO0lBMEU5QixZQUNjLE9BQWdCLEVBQ1QsR0FBc0I7UUFEN0IsWUFBTyxHQUFQLE9BQU8sQ0FBUztRQUNULFFBQUcsR0FBSCxHQUFHLENBQW1CO1FBM0RwQyx1QkFBa0IsR0FBYSxFQUFFLENBQUM7UUFDbEMsdUJBQWtCLEdBQWEsRUFBRSxDQUFDO1FBMENsQyxxQkFBZ0IsR0FBWSxLQUFLLENBQUM7UUFJbEMsc0JBQWlCLEdBQXVCLEVBQUUsQ0FBQztRQUMzQyw2QkFBd0IsR0FBWSxLQUFLLENBQUM7UUFFakQsOERBQThEO1FBQ3ZELDBCQUFxQixHQUFXLENBQUMsQ0FBQztRQUNsQyxvQkFBZSxHQUFXLENBQUMsQ0FBQztRQUM1QixtQkFBYyxHQUFXLEVBQUUsQ0FBQztRQUM1QixnQ0FBMkIsR0FBVyxFQUFFLENBQUM7UUFDN0IsY0FBUyxHQUFHLFNBQVMsQ0FBQztR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QyxRQUFRO3NCQURkLEtBQUs7Z0JBR0MsY0FBYztzQkFEcEIsS0FBSztnQkFHQyxjQUFjO3NCQURwQixLQUFLO2dCQUdDLGNBQWM7c0JBRHBCLEtBQUs7Z0JBR0MsWUFBWTtzQkFEbEIsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gICAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gICAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgQ29tcG9uZW50LFxuICAgIElucHV0LFxuICAgIE9uQ2hhbmdlcyxcbiAgICBPbkRlc3Ryb3ksXG4gICAgU2ltcGxlQ2hhbmdlcyxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge1Byb2ZpbGVTZXJ2aWNlfSBmcm9tICcuLi9wcm9maWxlLnNlcnZpY2UnO1xuaW1wb3J0IHtDYXJ0ZXNpYW5NZWFzdXJlVmFsdWUsIFF1YWxpdHlJbmRpY2F0b3IsIFJhaW5Ob2RlLCBUZWFtTm9kZX0gZnJvbSAncmFhaW4tbW9kZWwnO1xuaW1wb3J0IHtEYXRlUmFuZ2UsIE1hcExhdExuZywgVGltZWZyYW1lQ29udGFpbmVyc30gZnJvbSAncmFhaW4tdWknO1xuaW1wb3J0IHtDb21wYXJlTWFuYWdlciwgRnJhbWVTZXQsIG1hcERhdGVSYW5nZVRvU3RyaW5nLCBSZWZyZXNoTWFuYWdlcn0gZnJvbSAnLi4vdG9vbHMnO1xuaW1wb3J0IHtYWVR5cGV9IGZyb20gJy4uL3h5dHlwZSc7XG5pbXBvcnQge1JhZGFyU2VydmljZX0gZnJvbSAnLi4vcmFkYXIuc2VydmljZSc7XG5pbXBvcnQge1N0b3JhZ2V9IGZyb20gJy4uL3N0b3JhZ2Uuc2VydmljZSc7XG5cbmxldCBURVNUX0RFVEVDVElPTiA9IDA7XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAncmFhaW4tZGV0YWlscycsXG4gICAgdGVtcGxhdGVVcmw6ICdyYWFpbi1kZXRhaWxzLmNvbXBvbmVudC5odG1sJyxcbiAgICBzdHlsZVVybHM6IFsncmFhaW4tZGV0YWlscy5jb21wb25lbnQuc2NzcyddLFxuICAgIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxufSlcbmV4cG9ydCBjbGFzcyBSYWFpbkRldGFpbHNDb21wb25lbnQgaW1wbGVtZW50cyBPbkRlc3Ryb3ksIE9uQ2hhbmdlcyB7XG4gICAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgSE9VUl9NUyA9IDYwICogNjAwMDA7XG4gICAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgREFZX01TID0gMjQgKiA2MCAqIDYwICogMTAwMDtcblxuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIHRvZ2dsZUFkbWluOiBib29sZWFuO1xuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIHJhaW5Ob2RlOiBSYWluTm9kZTtcbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBjb21wYXJlTWFuYWdlcjogQ29tcGFyZU1hbmFnZXI7XG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgcmVmcmVzaE1hbmFnZXI6IFJlZnJlc2hNYW5hZ2VyO1xuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIHByb2ZpbGVTZXJ2aWNlOiBQcm9maWxlU2VydmljZTtcbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyByYWRhclNlcnZpY2U6IFJhZGFyU2VydmljZTtcblxuICAgIHB1YmxpYyBhdmFpbGFibGVQcm92aWRlcnM6IHN0cmluZ1tdID0gW107XG4gICAgcHVibGljIGF2YWlsYWJsZVRpbWVTdGVwczogbnVtYmVyW10gPSBbXTtcbiAgICBwdWJsaWMgc2VsZWN0ZWRQcm92aWRlcjogc3RyaW5nO1xuICAgIHB1YmxpYyBzZWxlY3RlZFRpbWVTdGVwOiBudW1iZXI7XG5cbiAgICBwdWJsaWMgcGVyaW9kQmVnaW46IERhdGU7XG4gICAgcHVibGljIHBlcmlvZEVuZDogRGF0ZTtcblxuICAgIC8vIHB1YmxpYyBVSSB2YXJpYWJsZXNcbiAgICBwdWJsaWMgdGVhbU5vZGU6IFRlYW1Ob2RlO1xuICAgIHB1YmxpYyBwZXJpb2RCZWdpbkFzU3RyaW5nOiBzdHJpbmc7XG4gICAgcHVibGljIHBlcmlvZEVuZEFzU3RyaW5nOiBzdHJpbmc7XG4gICAgcHVibGljIHBlcmlvZER1cmF0aW9uQXNTdHJpbmc6IHN0cmluZztcbiAgICBwdWJsaWMgZGF0ZVNob3duOiBEYXRlO1xuICAgIHB1YmxpYyBjb29yZGluYXRlczogTWFwTGF0TG5nO1xuICAgIHB1YmxpYyBib3JkZXJzOiBNYXBMYXRMbmdbXTtcbiAgICBwdWJsaWMgdGltZWZyYW1lQ29udGFpbmVyczogVGltZWZyYW1lQ29udGFpbmVycztcbiAgICBwdWJsaWMgY3VycmVudFRpbWVmcmFtZVRhcmdldDogRnJhbWVTZXQ7XG4gICAgcHVibGljIHRpbWVmcmFtZURhdGVzOiBEYXRlW107XG4gICAgcHVibGljIGNvdW50UG9pbnRzOiB7XG4gICAgICAgIGxhYmVsOiBzdHJpbmc7XG4gICAgICAgIHN0eWxlOiBzdHJpbmc7XG4gICAgICAgIHZhbHVlczoge2RhdGU6IERhdGU7IHZhbHVlOiBudW1iZXJ9W107XG4gICAgfVtdO1xuICAgIHB1YmxpYyBjb3VudHNQZXJpb2Q6IHtcbiAgICAgICAgcGVyY2VudEltYWdlcz86IFhZVHlwZVtdO1xuICAgICAgICBxdWV1ZVJ1bm5pbmc/OiBudW1iZXI7XG4gICAgICAgIHByb2dyZXNzPzogbnVtYmVyO1xuICAgIH07XG5cbiAgICBwdWJsaWMgZ2F1Z2VTZWxlY3RlZFBvaW50czoge1xuICAgICAgICBsYWJlbDogc3RyaW5nO1xuICAgICAgICBzdHlsZTogc3RyaW5nO1xuICAgICAgICB2YWx1ZXM6IHtkYXRlOiBEYXRlOyB2YWx1ZTogbnVtYmVyfVtdO1xuICAgIH1bXTtcbiAgICBwdWJsaWMgdG9nZ2xlSGlzdG9yeTogYm9vbGVhbjtcbiAgICBwdWJsaWMgdG9nZ2xlTWFwOiBib29sZWFuO1xuICAgIHB1YmxpYyB0b2dnbGVDb21wYXJlOiBib29sZWFuO1xuICAgIHB1YmxpYyB0b2dnbGVHYXVnZU1lYXN1cmVzOiBib29sZWFuO1xuICAgIHB1YmxpYyB0b2dnbGVSZW1vdmVDb21wYXJlRHVwbGljYXRlOiBib29sZWFuO1xuICAgIHB1YmxpYyB0b2dnbGVDdW11bGF0aXZlOiBib29sZWFuO1xuICAgIHB1YmxpYyByZWZyZXNoSW5Qcm9ncmVzczogYm9vbGVhbjtcbiAgICBwdWJsaWMgc3VtRGV0YWlsczogc3RyaW5nO1xuICAgIHB1YmxpYyBzaG93UGl4ZWxNYXJrZXJzOiBib29sZWFuID0gZmFsc2U7XG4gICAgcHVibGljIGlzQWRtaW46IGJvb2xlYW47XG4gICAgcHVibGljIHNob3dGdWxsRXJyb3I6IGJvb2xlYW47XG4gICAgcHVibGljIHNob3dRdWFsaXR5TW9kYWw6IGJvb2xlYW47XG4gICAgcHVibGljIHF1YWxpdHlJbmRpY2F0b3JzOiBRdWFsaXR5SW5kaWNhdG9yW10gPSBbXTtcbiAgICBwdWJsaWMgcXVhbGl0eUluZGljYXRvcnNMb2FkaW5nOiBib29sZWFuID0gZmFsc2U7XG5cbiAgICAvLyBDYWNoZWQgY29tcHV0ZWQgdmFsdWVzICh0byBhdm9pZCBtZXRob2QgY2FsbHMgaW4gdGVtcGxhdGVzKVxuICAgIHB1YmxpYyBwZXJjZW50T2ZDb21wdXRhdGlvbnM6IG51bWJlciA9IDA7XG4gICAgcHVibGljIHBlcmNlbnRPZkltYWdlczogbnVtYmVyID0gMDtcbiAgICBwdWJsaWMgdHJ1bmNhdGVkRXJyb3I6IHN0cmluZyA9ICcnO1xuICAgIHB1YmxpYyBjdW11bGF0aXZlRHVyYXRpb25Jbk1pbnV0ZXM6IG51bWJlciA9IDEwO1xuICAgIHByb3RlY3RlZCByZWFkb25seSBEYXRlUmFuZ2UgPSBEYXRlUmFuZ2U7XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJvdGVjdGVkIHN0b3JhZ2U6IFN0b3JhZ2UsXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgY2RyOiBDaGFuZ2VEZXRlY3RvclJlZlxuICAgICkge31cblxuICAgIHByaXZhdGUgc3RhdGljIFBlcmlvZERpc3BsYXkoZGF0ZTogRGF0ZSB8IHN0cmluZykge1xuICAgICAgICBsZXQgZCA9IG5ldyBEYXRlKCk7XG4gICAgICAgIGlmIChkYXRlKSB7XG4gICAgICAgICAgICBkID0gbmV3IERhdGUoZGF0ZSk7XG4gICAgICAgICAgICBjb25zdCB1c2VyVGltZXpvbmVPZmZzZXQgPSBkLmdldFRpbWV6b25lT2Zmc2V0KCkgKiA2MDAwMDtcbiAgICAgICAgICAgIGQgPSBuZXcgRGF0ZShkLmdldFRpbWUoKSAtIHVzZXJUaW1lem9uZU9mZnNldCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZXhhbXBsZUZvcm1hdHRlZERhdGUgPSAnMjAxNy0wNi0wMVQwODozMCc7XG4gICAgICAgIHJldHVybiBkLnRvSVNPU3RyaW5nKCkuc3Vic3RyaW5nKDAsIGV4YW1wbGVGb3JtYXR0ZWREYXRlLmxlbmd0aCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdGF0aWMgRGF0ZVVUQyhkYXRlOiBzdHJpbmcpIHtcbiAgICAgICAgY29uc3QgaGFzSVNPRm9ybWF0ID0gZGF0ZS5tYXRjaCgvXlxcZHs0fS1cXGR7Mn0tXFxkezJ9VFxcZHsyfTpcXGR7Mn06XFxkezJ9XFwuXFxkezN9WiQvKTtcbiAgICAgICAgbGV0IGQgPSBuZXcgRGF0ZShkYXRlKTtcbiAgICAgICAgaWYgKCFoYXNJU09Gb3JtYXQpIHtcbiAgICAgICAgICAgIGNvbnN0IHVzZXJUaW1lem9uZU9mZnNldCA9IGQuZ2V0VGltZXpvbmVPZmZzZXQoKSAqIDYwMDAwO1xuICAgICAgICAgICAgZCA9IG5ldyBEYXRlKGQuZ2V0VGltZSgpIC0gdXNlclRpbWV6b25lT2Zmc2V0KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZDtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0YXRpYyBNYXBDb3VudFRvRGF0ZVZhbHVlKGM6IFhZVHlwZSk6IHtkYXRlOiBEYXRlOyB2YWx1ZTogbnVtYmVyfSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBkYXRlOiBSYWFpbkRldGFpbHNDb21wb25lbnQuRGF0ZVVUQyhjLm5hbWUpLFxuICAgICAgICAgICAgdmFsdWU6IE1hdGgubWluKDEwMCwgYy54KSxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBhc3luYyBvcGVuUXVhbGl0eU1vZGFsKCkge1xuICAgICAgICB0aGlzLnNob3dRdWFsaXR5TW9kYWwgPSB0cnVlO1xuICAgICAgICB0aGlzLnF1YWxpdHlJbmRpY2F0b3JzTG9hZGluZyA9IHRydWU7XG4gICAgICAgIHRoaXMucXVhbGl0eUluZGljYXRvcnMgPSBbXTtcbiAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG5cbiAgICAgICAgaWYgKHRoaXMucmFpbk5vZGU/LmlkKSB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLnByb2ZpbGVTZXJ2aWNlLmdldEluZGljYXRvcnModGhpcy5yYWluTm9kZS5pZCk7XG4gICAgICAgICAgICB0aGlzLnF1YWxpdHlJbmRpY2F0b3JzID0gcmVzdWx0LmluZGljYXRvcnM7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnF1YWxpdHlJbmRpY2F0b3JzTG9hZGluZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICB9XG5cbiAgICBjbG9zZVF1YWxpdHlNb2RhbCgpIHtcbiAgICAgICAgdGhpcy5zaG93UXVhbGl0eU1vZGFsID0gZmFsc2U7XG4gICAgfVxuXG4gICAgZm9ybWF0RGF0ZShkYXRlU3RyOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICBjb25zdCBkYXRlID0gbmV3IERhdGUoZGF0ZVN0cik7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICBkYXRlLnRvTG9jYWxlRGF0ZVN0cmluZygpICtcbiAgICAgICAgICAgICcgJyArXG4gICAgICAgICAgICBkYXRlLnRvTG9jYWxlVGltZVN0cmluZyhbXSwge2hvdXI6ICcyLWRpZ2l0JywgbWludXRlOiAnMi1kaWdpdCd9KVxuICAgICAgICApO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBmZXRjaERhdGEoZm9jdXNEYXRlOiBEYXRlLCBmb2N1c1JhbmdlOiBEYXRlUmFuZ2UpIHtcbiAgICAgICAgY29uc3QgdmFsdWVzID0gW107XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgMTA7IGkrKykge1xuICAgICAgICAgICAgdmFsdWVzLnB1c2goe2RhdGU6IG5ldyBEYXRlKDIwMjAgKyBpLCAwKSwgdmFsdWU6IDEwfSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZmFrZURhdGEgPSBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgbGFiZWw6ICclIFJhaW55JyxcbiAgICAgICAgICAgICAgICBzdHlsZTogJ2JhcicsXG4gICAgICAgICAgICAgICAgdmFsdWVzLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBsYWJlbDogJyUgSW1hZ2VzJyxcbiAgICAgICAgICAgICAgICBzdHlsZTogJ2JhcicsXG4gICAgICAgICAgICAgICAgdmFsdWVzLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIC8vICB7XG4gICAgICAgICAgICAvLyAgICAgIGxhYmVsOiAnJSBRdWFsaXR5JyxcbiAgICAgICAgICAgIC8vICAgICAgc3R5bGU6ICdsaW5lJyxcbiAgICAgICAgICAgIC8vICAgICAgdmFsdWVzLFxuICAgICAgICAgICAgLy8gIH0sXG4gICAgICAgIF07XG5cbiAgICAgICAgY29uc3QgcmFuZ2UgPSBtYXBEYXRlUmFuZ2VUb1N0cmluZyhmb2N1c1JhbmdlKTtcbiAgICAgICAgbGV0IGRhdGEgPSBmYWtlRGF0YTtcbiAgICAgICAgaWYgKCF0aGlzLnJhaW5Ob2RlKSB7XG4gICAgICAgICAgICByZXR1cm4gZGF0YTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChmb2N1c1JhbmdlID09PSBEYXRlUmFuZ2UuQ0VOVFVSWSkge1xuICAgICAgICAgICAgLy8gZmFrZVxuICAgICAgICB9IGVsc2UgaWYgKGZvY3VzUmFuZ2UgPT09IERhdGVSYW5nZS5IT1VSKSB7XG4gICAgICAgICAgICBjb25zdCBob3VyQ291bnRzID0gYXdhaXQgdGhpcy5wcm9maWxlU2VydmljZS5nZXRDb3VudHNIb3VyKHRoaXMucmFpbk5vZGUuaWQsIHtcbiAgICAgICAgICAgICAgICBwZXJpb2RCZWdpbjogZm9jdXNEYXRlLFxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGRhdGEgPSBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBsYWJlbDogJ1JhaW55IENvdW50JyxcbiAgICAgICAgICAgICAgICAgICAgc3R5bGU6ICdsaW5lJyxcbiAgICAgICAgICAgICAgICAgICAgdmFsdWVzOiBob3VyQ291bnRzLnJhaW55Q291bnQubWFwKFJhYWluRGV0YWlsc0NvbXBvbmVudC5NYXBDb3VudFRvRGF0ZVZhbHVlKSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6ICclIEltYWdlcycsXG4gICAgICAgICAgICAgICAgICAgIHN0eWxlOiAnYmFyJyxcbiAgICAgICAgICAgICAgICAgICAgdmFsdWVzOiBob3VyQ291bnRzLnBlcmNlbnRJbWFnZXMubWFwKFJhYWluRGV0YWlsc0NvbXBvbmVudC5NYXBDb3VudFRvRGF0ZVZhbHVlKSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6ICdSYWlueSBTdW0nLFxuICAgICAgICAgICAgICAgICAgICBzdHlsZTogJ2xpbmUnLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZXM6IGhvdXJDb3VudHMucmFpbnlTdW0ubWFwKFJhYWluRGV0YWlsc0NvbXBvbmVudC5NYXBDb3VudFRvRGF0ZVZhbHVlKSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGNvdW50cyA9IGF3YWl0IHRoaXMucHJvZmlsZVNlcnZpY2UuZ2V0Q291bnRzKHRoaXMucmFpbk5vZGUuaWQsIHtcbiAgICAgICAgICAgICAgICByYW5nZSxcbiAgICAgICAgICAgICAgICBwZXJpb2RCZWdpbjogZm9jdXNEYXRlLFxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGRhdGEgPSBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBsYWJlbDogJyUgUmFpbnknLFxuICAgICAgICAgICAgICAgICAgICBzdHlsZTogJ2JhcicsXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlczogY291bnRzLnBlcmNlbnRSYWlueS5tYXAoUmFhaW5EZXRhaWxzQ29tcG9uZW50Lk1hcENvdW50VG9EYXRlVmFsdWUpLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBsYWJlbDogJyUgSW1hZ2VzJyxcbiAgICAgICAgICAgICAgICAgICAgc3R5bGU6ICdiYXInLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZXM6IGNvdW50cy5wZXJjZW50SW1hZ2VzLm1hcChSYWFpbkRldGFpbHNDb21wb25lbnQuTWFwQ291bnRUb0RhdGVWYWx1ZSksXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF07XG4gICAgICAgIH1cblxuICAgICAgICAvLyBjb25zb2xlLmxvZyhgZmV0Y2hEYXRhIERPTkUgJHtyYW5nZX1gLCBkYXRhKTtcbiAgICAgICAgcmV0dXJuIGRhdGE7XG4gICAgfVxuXG4gICAgLy8gV3JhcHBlciBmdW5jdGlvbiB0aGF0IHByZXNlcnZlcyB0aGUgYXN5bmMgbmF0dXJlIG9mIGZldGNoRGF0YVxuICAgIHB1YmxpYyBmZXRjaERhdGFXcmFwcGVyID0gYXN5bmMgKGZvY3VzRGF0ZTogRGF0ZSwgZm9jdXNSYW5nZTogRGF0ZVJhbmdlKSA9PiB7XG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmZldGNoRGF0YShmb2N1c0RhdGUsIGZvY3VzUmFuZ2UpO1xuICAgIH07XG5cbiAgICBwdWJsaWMgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgICAgICB0aGlzLmNoYW5nZShjaGFuZ2VzKS50aGVuKChpZ25vcmVkKSA9PiB7fSk7XG4gICAgfVxuXG4gICAgbmdPbkRlc3Ryb3koKSB7XG4gICAgICAgIHRoaXMuY2xlYW5BbGwoKTtcbiAgICB9XG5cbiAgICBhc3luYyBvbkVuYWJsZUNvdW50SGlzdG9yeVRhYihyYWluOiBSYWluTm9kZSkge1xuICAgICAgICBpZiAoIXRoaXMudG9nZ2xlSGlzdG9yeSkge1xuICAgICAgICAgICAgdGhpcy5jb3VudFBvaW50cyA9IFtdO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgYXN5bmMgb25QZXJpb2RCZWdpbkNoYW5nZShldmVudDogYW55KSB7XG4gICAgICAgIGNvbnN0IG5ld1ZhbHVlID0gZXZlbnQ/LnRhcmdldD8udmFsdWUgPz8gdGhpcy5wZXJpb2RCZWdpbkFzU3RyaW5nO1xuICAgICAgICB0aGlzLnBlcmlvZEJlZ2luID0gbmV3IERhdGUobmV3VmFsdWUpO1xuICAgICAgICB0aGlzLnBlcmlvZEJlZ2luQXNTdHJpbmcgPSBSYWFpbkRldGFpbHNDb21wb25lbnQuUGVyaW9kRGlzcGxheSh0aGlzLnBlcmlvZEJlZ2luKTtcbiAgICAgICAgdGhpcy5zdG9yYWdlLnNldCgncmFhaW4tcGVyaW9kQmVnaW4nLCB0aGlzLnBlcmlvZEJlZ2luKTtcblxuICAgICAgICBhd2FpdCB0aGlzLm9uUGVyaW9kRHVyYXRpb25DaGFuZ2UoZXZlbnQpO1xuICAgIH1cblxuICAgIGFzeW5jIG9uUGVyaW9kRW5kQ2hhbmdlKGV2ZW50OiBhbnkpIHtcbiAgICAgICAgY29uc3QgbmV3VmFsdWUgPSBldmVudD8udGFyZ2V0Py52YWx1ZSA/PyB0aGlzLnBlcmlvZEVuZEFzU3RyaW5nO1xuICAgICAgICB0aGlzLnBlcmlvZEVuZCA9IG5ldyBEYXRlKG5ld1ZhbHVlKTtcbiAgICAgICAgdGhpcy5wZXJpb2RFbmRBc1N0cmluZyA9IFJhYWluRGV0YWlsc0NvbXBvbmVudC5QZXJpb2REaXNwbGF5KHRoaXMucGVyaW9kRW5kKTtcbiAgICAgICAgdGhpcy5zdG9yYWdlLnNldCgncmFhaW4tcGVyaW9kRW5kJywgdGhpcy5wZXJpb2RFbmQpO1xuXG4gICAgICAgIHRoaXMucGVyaW9kQmVnaW4gPSBuZXcgRGF0ZShcbiAgICAgICAgICAgIHRoaXMucGVyaW9kRW5kLmdldFRpbWUoKSAtIHRoaXMuZ2V0RHVyYXRpb25JbkhvdXJzKCkgKiBSYWFpbkRldGFpbHNDb21wb25lbnQuSE9VUl9NU1xuICAgICAgICApO1xuICAgICAgICB0aGlzLnBlcmlvZEJlZ2luQXNTdHJpbmcgPSBSYWFpbkRldGFpbHNDb21wb25lbnQuUGVyaW9kRGlzcGxheSh0aGlzLnBlcmlvZEJlZ2luKTtcbiAgICAgICAgdGhpcy5zdG9yYWdlLnNldCgncmFhaW4tcGVyaW9kQmVnaW4nLCB0aGlzLnBlcmlvZEJlZ2luKTtcbiAgICAgICAgdGhpcy51cGRhdGVSZWZyZXNoTWFuYWdlclBlcmlvZCgpO1xuICAgIH1cblxuICAgIGFzeW5jIG9uUGVyaW9kRHVyYXRpb25DaGFuZ2UoX2V2ZW50OiBvYmplY3QpIHtcbiAgICAgICAgY29uc3QgZHVyYXRpb25JbkhvdXJzID0gdGhpcy5nZXREdXJhdGlvbkluSG91cnMoKTtcbiAgICAgICAgdGhpcy5wZXJpb2RFbmQgPSBuZXcgRGF0ZShcbiAgICAgICAgICAgIHRoaXMucGVyaW9kQmVnaW4uZ2V0VGltZSgpICsgZHVyYXRpb25JbkhvdXJzICogUmFhaW5EZXRhaWxzQ29tcG9uZW50LkhPVVJfTVNcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5wZXJpb2RFbmRBc1N0cmluZyA9IFJhYWluRGV0YWlsc0NvbXBvbmVudC5QZXJpb2REaXNwbGF5KHRoaXMucGVyaW9kRW5kKTtcbiAgICAgICAgdGhpcy5zdG9yYWdlLnNldCgncmFhaW4tcGVyaW9kRW5kJywgdGhpcy5wZXJpb2RFbmQpO1xuICAgICAgICB0aGlzLnN0b3JhZ2Uuc2V0KCdyYWFpbi1wZXJpb2REdXJhdGlvbkluSG91cnMnLCBkdXJhdGlvbkluSG91cnMpO1xuICAgICAgICB0aGlzLnVwZGF0ZVJlZnJlc2hNYW5hZ2VyUGVyaW9kKCk7XG4gICAgICAgIHRoaXMudXBkYXRlQ3VtdWxhdGl2ZUR1cmF0aW9uSW5NaW51dGVzKCk7XG4gICAgfVxuXG4gICAgYXN5bmMgb25EYXRlQ2hhbmdlSW5Db3VudChkYXRlQ2hhbmdlZDogRGF0ZSkge1xuICAgICAgICBjb25zdCBkYXRlU3RyaW5nID1cbiAgICAgICAgICAgIGRhdGVDaGFuZ2VkLnRvSVNPU3RyaW5nKCkuc3Vic3RyaW5nKDAsIDExKSArXG4gICAgICAgICAgICBkYXRlQ2hhbmdlZC50b0xvY2FsZVRpbWVTdHJpbmcoKS5zdWJzdHJpbmcoMCwgNSk7XG4gICAgICAgIHRoaXMucGVyaW9kRHVyYXRpb25Bc1N0cmluZyA9ICcxJztcblxuICAgICAgICBpZiAodGhpcy50b2dnbGVDdW11bGF0aXZlKSB7XG4gICAgICAgICAgICAvLyBDdW11bGF0aXZlOiBzZWxlY3QgcGVyaW9kRW5kXG4gICAgICAgICAgICB0aGlzLnBlcmlvZEVuZEFzU3RyaW5nID0gZGF0ZVN0cmluZztcbiAgICAgICAgICAgIGF3YWl0IHRoaXMub25QZXJpb2RFbmRDaGFuZ2UobnVsbCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBHcmFudWxhcjogc2VsZWN0IHBlcmlvZEJlZ2luXG4gICAgICAgICAgICB0aGlzLnBlcmlvZEJlZ2luQXNTdHJpbmcgPSBkYXRlU3RyaW5nO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5vblBlcmlvZEJlZ2luQ2hhbmdlKG51bGwpO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHRoaXMucmVmcmVzaE1hbmFnZXIucmVmcmVzaChmYWxzZSwgdGhpcy50b2dnbGVBZG1pbik7XG4gICAgfVxuXG4gICAgYXN5bmMgb25EYXRlQ2hhbmdlSW5NYXAoZGF0ZVNob3duOiBEYXRlKSB7XG4gICAgICAgIHRoaXMuZGF0ZVNob3duID0gZGF0ZVNob3duO1xuICAgICAgICBhd2FpdCB0aGlzLmZldGNoQW5kVXBkYXRlTWFwKCk7XG4gICAgICAgIGF3YWl0IHRoaXMucmVmcmVzaE1hbmFnZXIuc2V0UmVwb3J0UGVyaW9kKHRoaXMuZGF0ZVNob3duKTtcbiAgICB9XG5cbiAgICBhc3luYyBvblN1bUNoYW5nZUluTWFwKHN1bTogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMuc3VtRGV0YWlscyA9IHN1bTtcbiAgICB9XG5cbiAgICBhc3luYyBvbkdhdWdlU2VsZWN0SW5NYXAobWFwTGF0TG5nOiBNYXBMYXRMbmcpIHtcbiAgICAgICAgY29uc3QgZ2F1Z2VzRmlsdGVyZWQgPSB0aGlzLmNvbXBhcmVNYW5hZ2VyLmdhdWdlc0luTWFwLmZpbHRlcihcbiAgICAgICAgICAgIChnKSA9PiBnLmxhdCA9PT0gbWFwTGF0TG5nLmxhdCAmJiBnLmxuZyA9PT0gbWFwTGF0TG5nLmxuZ1xuICAgICAgICApO1xuICAgICAgICBpZiAoZ2F1Z2VzRmlsdGVyZWQubGVuZ3RoICE9PSAxKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZ2F1Z2VTZWxlY3RlZCA9IGdhdWdlc0ZpbHRlcmVkWzBdO1xuXG4gICAgICAgIGF3YWl0IHRoaXMucmVmcmVzaEdhdWdlVmFsdWVzKHtpZDogZ2F1Z2VTZWxlY3RlZC5pZCwgbmFtZTogZ2F1Z2VTZWxlY3RlZC5uYW1lfSk7XG5cbiAgICAgICAgYXdhaXQgdGhpcy5jb21wYXJlTWFuYWdlci5zZWxlY3RHYXVnZShnYXVnZVNlbGVjdGVkLmlkLCAwKTtcbiAgICB9XG5cbiAgICBhc3luYyByZWZyZXNoR2F1Z2VWYWx1ZXMoZ2F1Z2VTZWxlY3RlZDoge2lkOiBzdHJpbmc7IG5hbWU6IHN0cmluZ30pIHtcbiAgICAgICAgY29uc3QgZ2F1Z2VWYWx1ZVNob3dCZWdpbiA9IG5ldyBEYXRlKFxuICAgICAgICAgICAgdGhpcy5wZXJpb2RCZWdpbi5nZXRUaW1lKCkgLSBSYWFpbkRldGFpbHNDb21wb25lbnQuREFZX01TXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IGdhdWdlVmFsdWVTaG93RW5kID0gbmV3IERhdGUodGhpcy5wZXJpb2RFbmQuZ2V0VGltZSgpICsgUmFhaW5EZXRhaWxzQ29tcG9uZW50LkRBWV9NUyk7XG4gICAgICAgIGdhdWdlVmFsdWVTaG93QmVnaW4uc2V0SG91cnMoMCwgMCk7XG4gICAgICAgIGdhdWdlVmFsdWVTaG93RW5kLnNldEhvdXJzKDIzLCA1OSk7XG5cbiAgICAgICAgY29uc3QgZ2F1Z2VNZWFzdXJlcyA9IGF3YWl0IHRoaXMucHJvZmlsZVNlcnZpY2UuZ2V0R2F1Z2VNZWFzdXJlcyhcbiAgICAgICAgICAgIGdhdWdlU2VsZWN0ZWQuaWQsXG4gICAgICAgICAgICBnYXVnZVZhbHVlU2hvd0JlZ2luLFxuICAgICAgICAgICAgZ2F1Z2VWYWx1ZVNob3dFbmRcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3QgZ2F1Z2VWYWx1ZXM6IHtkYXRlOiBEYXRlOyB2YWx1ZTogbnVtYmVyfVtdID0gZ2F1Z2VNZWFzdXJlcy5tYXAoKGdtKSA9PiB7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICAgICAgICAgY29uc3QgY2FydGVzaWFuTWVhc3VyZVZhbHVlID0gbmV3IENhcnRlc2lhbk1lYXN1cmVWYWx1ZShnbS52YWx1ZXNbMF0gYXMgYW55KTtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgZGF0ZTogZ20uZGF0ZSxcbiAgICAgICAgICAgICAgICB2YWx1ZTogY2FydGVzaWFuTWVhc3VyZVZhbHVlLmdldENhcnRlc2lhblZhbHVlcygpWzBdLnZhbHVlLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZ2F1Z2VTZWxlY3RlZFBvaW50cyA9IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBsYWJlbDogZ2F1Z2VTZWxlY3RlZC5uYW1lLFxuICAgICAgICAgICAgICAgIHN0eWxlOiAnYmFyJyxcbiAgICAgICAgICAgICAgICB2YWx1ZXM6IGdhdWdlVmFsdWVzLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgXTtcbiAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfVxuXG4gICAgYXN5bmMgb25HYXVnZVNlbGVjdEluQ29tcGFyZShlOiB7cG9pbnQ6IFhZVHlwZTsgY29tcGFyZUluZGV4OiBudW1iZXJ9KSB7XG4gICAgICAgIGF3YWl0IHRoaXMucmVmcmVzaEdhdWdlVmFsdWVzKHtpZDogZS5wb2ludC5pZCwgbmFtZTogZS5wb2ludC5uYW1lfSk7XG5cbiAgICAgICAgYXdhaXQgdGhpcy5jb21wYXJlTWFuYWdlci5zZWxlY3RHYXVnZShlLnBvaW50LmlkLCBlLmNvbXBhcmVJbmRleCk7XG4gICAgfVxuXG4gICAgYXN5bmMgb25Ub2dnbGVNYXAoJGV2ZW50OiBFdmVudCkge1xuICAgICAgICAvLyBpZiAodGhpcy50b2dnbGVNYXApIHtcbiAgICAgICAgLy8gICAgYXdhaXQgdGhpcy5yZWZyZXNoTWFwKCk7XG4gICAgICAgIC8vIH1cbiAgICB9XG5cbiAgICBvblRvZ2dsZVBpeGVsTWFya2VycygpIHtcbiAgICAgICAgLy8gVG9nZ2xlIGlzIGJvdW5kIHRvIHNob3dQaXhlbE1hcmtlcnMsIHJhYWluLW1hcCBoYW5kbGVzIG1hcmtlciBkaXNwbGF5XG4gICAgfVxuXG4gICAgYXN5bmMgdG9nZ2xlQ3VtdWxhdGl2ZUNoYW5nZWQoXyRldmVudDogRXZlbnQpIHtcbiAgICAgICAgdGhpcy5zdG9yYWdlLnNldCgncmFhaW4tdG9nZ2xlQ3VtdWxhdGl2ZScsIHRoaXMudG9nZ2xlQ3VtdWxhdGl2ZSk7XG4gICAgICAgIHRoaXMuZGF0ZVNob3duID0gdGhpcy5nZXREYXRlQmFzZWRPbkN1bXVsYXRpdmVNb2RlKHRoaXMudGltZWZyYW1lRGF0ZXMpO1xuICAgICAgICB0aGlzLnVwZGF0ZUN1bXVsYXRpdmVEdXJhdGlvbkluTWludXRlcygpO1xuICAgICAgICBpZiAodGhpcy50b2dnbGVNYXApIHtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlUmVmcmVzaE1hbmFnZXJQZXJpb2QoKTsgLy8gVXBkYXRlIGN1bXVsYXRpdmUgZmxhZyBiZWZvcmUgcmVmcmVzaFxuICAgICAgICAgICAgYXdhaXQgdGhpcy5yZWZyZXNoTWFuYWdlci5yZWZyZXNoKGZhbHNlLCB0aGlzLnRvZ2dsZUFkbWluKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHVwZGF0ZUN1bXVsYXRpdmVEdXJhdGlvbkluTWludXRlcygpIHtcbiAgICAgICAgaWYgKHRoaXMudG9nZ2xlQ3VtdWxhdGl2ZSkge1xuICAgICAgICAgICAgLy8gQ3VtdWxhdGl2ZSBtb2RlOiB1c2UgcGVyaW9kIGR1cmF0aW9uXG4gICAgICAgICAgICB0aGlzLmN1bXVsYXRpdmVEdXJhdGlvbkluTWludXRlcyA9IHBhcnNlRmxvYXQodGhpcy5wZXJpb2REdXJhdGlvbkFzU3RyaW5nKSAqIDYwO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gR3JhbnVsYXIgbW9kZTogdXNlIHNlbGVjdGVkVGltZVN0ZXBcbiAgICAgICAgICAgIHRoaXMuY3VtdWxhdGl2ZUR1cmF0aW9uSW5NaW51dGVzID0gdGhpcy5zZWxlY3RlZFRpbWVTdGVwIHx8IDEwO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgYXN5bmMgb25Qcm92aWRlckNoYW5nZWQoJGV2ZW50OiBFdmVudCkge1xuICAgICAgICB0aGlzLnNlbGVjdGVkUHJvdmlkZXIgPSAoJGV2ZW50IGFzIEN1c3RvbUV2ZW50KT8uZGV0YWlsPy52YWx1ZTtcbiAgICAgICAgdGhpcy5zdG9yYWdlLnNldCgncmFhaW4tc2VsZWN0ZWRQcm92aWRlcicsIHRoaXMuc2VsZWN0ZWRQcm92aWRlcik7XG4gICAgICAgIGF3YWl0IHRoaXMuYXBwbHlSZWZyZXNoTWFuYWdlclNldHRpbmdzKCk7XG4gICAgfVxuXG4gICAgYXN5bmMgb25UaW1lU3RlcENoYW5nZWQoJGV2ZW50OiBFdmVudCkge1xuICAgICAgICB0aGlzLnNlbGVjdGVkVGltZVN0ZXAgPSAoJGV2ZW50IGFzIEN1c3RvbUV2ZW50KT8uZGV0YWlsPy52YWx1ZTtcbiAgICAgICAgdGhpcy5zdG9yYWdlLnNldCgncmFhaW4tc2VsZWN0ZWRUaW1lU3RlcCcsIHRoaXMuc2VsZWN0ZWRUaW1lU3RlcCk7XG4gICAgICAgIHRoaXMudXBkYXRlQ3VtdWxhdGl2ZUR1cmF0aW9uSW5NaW51dGVzKCk7XG4gICAgICAgIGF3YWl0IHRoaXMuYXBwbHlSZWZyZXNoTWFuYWdlclNldHRpbmdzKCk7XG4gICAgfVxuXG4gICAgYXN5bmMgbG9hZFByb3ZpZGVycygpIHtcbiAgICAgICAgaWYgKCF0aGlzLnJhaW5Ob2RlPy5pZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMucHJvZmlsZVNlcnZpY2UuZ2V0UHJvdmlkZXJzKHRoaXMucmFpbk5vZGUuaWQpO1xuICAgICAgICAgICAgdGhpcy5hdmFpbGFibGVQcm92aWRlcnMgPSByZXN1bHQucHJvdmlkZXJzO1xuICAgICAgICAgICAgdGhpcy5hdmFpbGFibGVUaW1lU3RlcHMgPSByZXN1bHQudGltZVN0ZXBJbk1pbnV0ZXM7XG5cbiAgICAgICAgICAgIC8vIExvYWQgc2F2ZWQgc2VsZWN0aW9ucyBvciB1c2UgZGVmYXVsdHNcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRQcm92aWRlciA9XG4gICAgICAgICAgICAgICAgdGhpcy5zdG9yYWdlLmdldCgncmFhaW4tc2VsZWN0ZWRQcm92aWRlcicpIHx8XG4gICAgICAgICAgICAgICAgKHRoaXMuYXZhaWxhYmxlUHJvdmlkZXJzLmxlbmd0aCA+IDAgPyB0aGlzLmF2YWlsYWJsZVByb3ZpZGVyc1swXSA6ICdSYWFpbicpO1xuICAgICAgICAgICAgdGhpcy5zZWxlY3RlZFRpbWVTdGVwID1cbiAgICAgICAgICAgICAgICB0aGlzLnN0b3JhZ2UuZ2V0KCdyYWFpbi1zZWxlY3RlZFRpbWVTdGVwJykgfHxcbiAgICAgICAgICAgICAgICAodGhpcy5hdmFpbGFibGVUaW1lU3RlcHMubGVuZ3RoID4gMCA/IHRoaXMuYXZhaWxhYmxlVGltZVN0ZXBzWzBdIDogMTApO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAvLyBTZXQgZmFsbGJhY2sgdmFsdWVzXG4gICAgICAgICAgICB0aGlzLmF2YWlsYWJsZVByb3ZpZGVycyA9IFsnUmFhaW4nXTtcbiAgICAgICAgICAgIHRoaXMuYXZhaWxhYmxlVGltZVN0ZXBzID0gWzUsIDEwLCAxNSwgMzAsIDYwXTtcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRQcm92aWRlciA9ICdSYWFpbic7XG4gICAgICAgICAgICB0aGlzLnNlbGVjdGVkVGltZVN0ZXAgPSAxMDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNldCBwcm92aWRlciBhbmQgdGltZVN0ZXAgb24gcmVmcmVzaE1hbmFnZXJcbiAgICAgICAgaWYgKHRoaXMucmVmcmVzaE1hbmFnZXIpIHtcbiAgICAgICAgICAgIHRoaXMucmVmcmVzaE1hbmFnZXIucHJvdmlkZXIgPSB0aGlzLnNlbGVjdGVkUHJvdmlkZXI7XG4gICAgICAgICAgICB0aGlzLnJlZnJlc2hNYW5hZ2VyLnRpbWVTdGVwSW5NaW51dGVzID0gdGhpcy5zZWxlY3RlZFRpbWVTdGVwO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgIH1cblxuICAgIG9uQ2hhbmdlRGV0ZWN0aW9uVGVzdChyYWluTm9kZTogUmFpbk5vZGUpIHtcbiAgICAgICAgY29uc29sZS5sb2coVEVTVF9ERVRFQ1RJT04rKywgJ29uQ2hhbmdlRGV0ZWN0aW9uVGVzdCcpO1xuICAgICAgICByZXR1cm4gJyc7XG4gICAgfVxuXG4gICAgdXBkYXRlVHJ1bmNhdGVkRXJyb3IoKSB7XG4gICAgICAgIGNvbnN0IGVycm9yID0gdGhpcy5yZWZyZXNoTWFuYWdlcj8ubGFzdEVycm9yIHx8ICcnO1xuICAgICAgICBpZiAoZXJyb3IubGVuZ3RoIDw9IDgwKSB7XG4gICAgICAgICAgICB0aGlzLnRydW5jYXRlZEVycm9yID0gZXJyb3I7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy50cnVuY2F0ZWRFcnJvciA9IGVycm9yLnN1YnN0cmluZygwLCA4MCkgKyAnLi4uJztcbiAgICB9XG5cbiAgICB1cGRhdGVDYWNoZWRWYWx1ZXMoKSB7XG4gICAgICAgIHRoaXMudXBkYXRlUGVyY2VudE9mSW1hZ2VzKCk7XG4gICAgICAgIHRoaXMudXBkYXRlUGVyY2VudE9mQ29tcHV0YXRpb25zKCk7XG4gICAgICAgIHRoaXMudXBkYXRlVHJ1bmNhdGVkRXJyb3IoKTtcbiAgICAgICAgdGhpcy51cGRhdGVDdW11bGF0aXZlRHVyYXRpb25Jbk1pbnV0ZXMoKTtcbiAgICB9XG5cbiAgICBhc3luYyByZWZyZXNoTWFwKCkge1xuICAgICAgICB0aGlzLmdhdWdlU2VsZWN0ZWRQb2ludHMgPSBbXTtcbiAgICAgICAgdGhpcy5kYXRlU2hvd24gPSB0aGlzLmdldERhdGVCYXNlZE9uQ3VtdWxhdGl2ZU1vZGUoKTtcbiAgICAgICAgdGhpcy5ib3JkZXJzID0gW107XG5cbiAgICAgICAgdGhpcy5jb21wYXJlTWFuYWdlci5jbGVhbkFsbCgpO1xuICAgICAgICBhd2FpdCB0aGlzLmNvbXBhcmVNYW5hZ2VyLnNldEdhdWdlc0luTWFwKCk7XG4gICAgICAgIGF3YWl0IHRoaXMucmVmcmVzaE1hbmFnZXIucmVmcmVzaChmYWxzZSwgdGhpcy50b2dnbGVBZG1pbik7XG4gICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgIH1cblxuICAgIGFzeW5jIHNldFBlcmlvZE9mTm93KCkge1xuICAgICAgICBjb25zdCBsYXN0MzBtbiA9IG5ldyBEYXRlKCk7XG4gICAgICAgIGxhc3QzMG1uLnNldE1pbnV0ZXMobGFzdDMwbW4uZ2V0TWludXRlcygpIC0gMzApO1xuICAgICAgICB0aGlzLnBlcmlvZEJlZ2luQXNTdHJpbmcgPVxuICAgICAgICAgICAgbGFzdDMwbW4udG9JU09TdHJpbmcoKS5zdWJzdHJpbmcoMCwgMTEpICsgbGFzdDMwbW4udG9Mb2NhbGVUaW1lU3RyaW5nKCkuc3Vic3RyaW5nKDAsIDUpO1xuICAgICAgICB0aGlzLnBlcmlvZER1cmF0aW9uQXNTdHJpbmcgPSAnMSc7XG4gICAgICAgIGF3YWl0IHRoaXMub25QZXJpb2RCZWdpbkNoYW5nZShudWxsKTtcbiAgICAgICAgYXdhaXQgdGhpcy5yZWZyZXNoTWFuYWdlci5yZWZyZXNoKGZhbHNlLCB0aGlzLnRvZ2dsZUFkbWluKTtcbiAgICB9XG5cbiAgICB1cGRhdGVQZXJjZW50T2ZJbWFnZXMoKSB7XG4gICAgICAgIGlmICghdGhpcy5jb3VudHNQZXJpb2Q/LnBlcmNlbnRJbWFnZXM/Lmxlbmd0aCkge1xuICAgICAgICAgICAgdGhpcy5wZXJjZW50T2ZJbWFnZXMgPSAwO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZHVyaW5nUGVyaW9kID0gdGhpcy5jb3VudHNQZXJpb2QucGVyY2VudEltYWdlcy5maWx0ZXIoXG4gICAgICAgICAgICAoYSkgPT5cbiAgICAgICAgICAgICAgICB0aGlzLnBlcmlvZEJlZ2luLmdldFRpbWUoKSA8PSBuZXcgRGF0ZShhLm5hbWUpLmdldFRpbWUoKSAmJlxuICAgICAgICAgICAgICAgIG5ldyBEYXRlKGEubmFtZSkuZ2V0VGltZSgpIDw9IHRoaXMucGVyaW9kRW5kLmdldFRpbWUoKVxuICAgICAgICApO1xuICAgICAgICBjb25zdCBzdW1tZWQgPSBkdXJpbmdQZXJpb2QucmVkdWNlKChhLCBiKSA9PiBhICsgKGIueCA/PyAwKSwgMCk7XG4gICAgICAgIHRoaXMucGVyY2VudE9mSW1hZ2VzID0gTWF0aC5yb3VuZChzdW1tZWQgLyBkdXJpbmdQZXJpb2QubGVuZ3RoKTtcbiAgICB9XG5cbiAgICB1cGRhdGVQZXJjZW50T2ZDb21wdXRhdGlvbnMoKSB7XG4gICAgICAgIGNvbnN0IHRpbWVsaW5lID0gdGhpcy5yZWZyZXNoTWFuYWdlcj8uZ2V0VGltZWxpbmVGcmFtZVNldCgpO1xuICAgICAgICBpZiAoIXRpbWVsaW5lPy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRoaXMucGVyY2VudE9mQ29tcHV0YXRpb25zID0gMDtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHRpbWVsaW5lV2l0aENvbXB1dGF0aW9uID0gdGltZWxpbmUuZmlsdGVyKFxuICAgICAgICAgICAgKGEpID0+ICEhYS5yYWluQ29tcHV0YXRpb25DdW11bGF0aXZlSWQgfHwgISFhLnJhaW5Db21wdXRhdGlvbklkXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IHJhdGlvID0gdGltZWxpbmVXaXRoQ29tcHV0YXRpb24ubGVuZ3RoIC8gdGltZWxpbmUubGVuZ3RoO1xuICAgICAgICB0aGlzLnBlcmNlbnRPZkNvbXB1dGF0aW9ucyA9IE1hdGgucm91bmQocmF0aW8gKiAxMDApO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0RGF0ZUJhc2VkT25DdW11bGF0aXZlTW9kZShmYWxsYmFja0RhdGVzPzogRGF0ZVtdKTogRGF0ZSB7XG4gICAgICAgIGlmIChmYWxsYmFja0RhdGVzPy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBjb25zdCBkYXRlRXhpc3RzID0gZmFsbGJhY2tEYXRlcy5zb21lKChkKSA9PiBkLmdldFRpbWUoKSA9PT0gdGhpcy5kYXRlU2hvd24/LmdldFRpbWUoKSk7XG4gICAgICAgICAgICBpZiAoIWRhdGVFeGlzdHMpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy50b2dnbGVDdW11bGF0aXZlXG4gICAgICAgICAgICAgICAgICAgID8gZmFsbGJhY2tEYXRlc1tmYWxsYmFja0RhdGVzLmxlbmd0aCAtIDFdXG4gICAgICAgICAgICAgICAgICAgIDogZmFsbGJhY2tEYXRlc1swXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy50b2dnbGVDdW11bGF0aXZlID8gdGhpcy5wZXJpb2RFbmQgOiB0aGlzLnBlcmlvZEJlZ2luO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0Q3VtdWxhdGl2ZUhvdXJzKCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiB0aGlzLnRvZ2dsZUN1bXVsYXRpdmUgPyBwYXJzZUZsb2F0KHRoaXMucGVyaW9kRHVyYXRpb25Bc1N0cmluZykgOiAwO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0RHVyYXRpb25JbkhvdXJzKCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiBwYXJzZUZsb2F0KHRoaXMucGVyaW9kRHVyYXRpb25Bc1N0cmluZyk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSB1cGRhdGVSZWZyZXNoTWFuYWdlclBlcmlvZCgpIHtcbiAgICAgICAgdGhpcy5yZWZyZXNoTWFuYWdlci5jdW11bGF0aXZlID0gdGhpcy50b2dnbGVDdW11bGF0aXZlO1xuXG4gICAgICAgIC8vIEFsaWduIGRhdGVzIHRvIDUtbWludXRlIGJvdW5kYXJpZXMgKGZsb29yKSBmb3IgY29uc2lzdGVuY3kgd2l0aCByYWFpbi1ncm91bmRcbiAgICAgICAgY29uc3QgYWxpZ25UbzVtaW5GbG9vciA9IChkYXRlOiBEYXRlKTogRGF0ZSA9PiB7XG4gICAgICAgICAgICBjb25zdCBtaW51dGVzID0gZGF0ZS5nZXRNaW51dGVzKCk7XG4gICAgICAgICAgICBjb25zdCBhbGlnbmVkTWludXRlcyA9IE1hdGguZmxvb3IobWludXRlcyAvIDUpICogNTtcbiAgICAgICAgICAgIHJldHVybiBuZXcgRGF0ZShcbiAgICAgICAgICAgICAgICBkYXRlLmdldEZ1bGxZZWFyKCksXG4gICAgICAgICAgICAgICAgZGF0ZS5nZXRNb250aCgpLFxuICAgICAgICAgICAgICAgIGRhdGUuZ2V0RGF0ZSgpLFxuICAgICAgICAgICAgICAgIGRhdGUuZ2V0SG91cnMoKSxcbiAgICAgICAgICAgICAgICBhbGlnbmVkTWludXRlcyxcbiAgICAgICAgICAgICAgICAwLFxuICAgICAgICAgICAgICAgIDBcbiAgICAgICAgICAgICk7XG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5yZWZyZXNoTWFuYWdlci5wZXJpb2QgPSB7XG4gICAgICAgICAgICBiZWdpbjogYWxpZ25UbzVtaW5GbG9vcih0aGlzLnBlcmlvZEJlZ2luKSxcbiAgICAgICAgICAgIGVuZDogYWxpZ25UbzVtaW5GbG9vcih0aGlzLnBlcmlvZEVuZCksXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBmZXRjaEFuZFVwZGF0ZU1hcCgpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5yZWZyZXNoTWFuYWdlci5mZXRjaChcbiAgICAgICAgICAgIHRoaXMuZGF0ZVNob3duLFxuICAgICAgICAgICAgdGhpcy50b2dnbGVHYXVnZU1lYXN1cmVzLFxuICAgICAgICAgICAgdGhpcy5nZXRDdW11bGF0aXZlSG91cnMoKVxuICAgICAgICApO1xuICAgICAgICB0aGlzLmN1cnJlbnRUaW1lZnJhbWVUYXJnZXQgPSB0aGlzLnJlZnJlc2hNYW5hZ2VyLmdldFRpbWVsaW5lU2VsZWN0ZWRGcmFtZVNldCgpO1xuICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGFwcGx5UmVmcmVzaE1hbmFnZXJTZXR0aW5ncygpIHtcbiAgICAgICAgaWYgKCF0aGlzLnJlZnJlc2hNYW5hZ2VyKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5yZWZyZXNoTWFuYWdlci5wcm92aWRlciA9IHRoaXMuc2VsZWN0ZWRQcm92aWRlcjtcbiAgICAgICAgdGhpcy5yZWZyZXNoTWFuYWdlci50aW1lU3RlcEluTWludXRlcyA9IHRoaXMuc2VsZWN0ZWRUaW1lU3RlcDtcbiAgICAgICAgYXdhaXQgdGhpcy5yZWZyZXNoTWFuYWdlci5yZWZyZXNoKGZhbHNlLCB0aGlzLnRvZ2dsZUFkbWluKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGNsZWFuQWxsKCkge1xuICAgICAgICB0aGlzLmJvcmRlcnMgPSBbXTtcbiAgICAgICAgdGhpcy5pc0FkbWluID0gZmFsc2U7XG4gICAgICAgIHRoaXMudGltZWZyYW1lQ29udGFpbmVycyA9IG5ldyBUaW1lZnJhbWVDb250YWluZXJzKFtdKTtcbiAgICAgICAgdGhpcy5jdXJyZW50VGltZWZyYW1lVGFyZ2V0ID0gbnVsbDtcbiAgICAgICAgdGhpcy50aW1lZnJhbWVEYXRlcyA9IFtdO1xuICAgICAgICB0aGlzLmNvdW50UG9pbnRzID0gW107XG4gICAgICAgIHRoaXMuY291bnRzUGVyaW9kID0ge3Byb2dyZXNzOiAwLCBxdWV1ZVJ1bm5pbmc6IDAsIHBlcmNlbnRJbWFnZXM6IFtdfTtcbiAgICAgICAgdGhpcy5nYXVnZVNlbGVjdGVkUG9pbnRzID0gW107XG5cbiAgICAgICAgdGhpcy50b2dnbGVIaXN0b3J5ID0gZmFsc2U7XG4gICAgICAgIHRoaXMudG9nZ2xlTWFwID0gdHJ1ZTtcbiAgICAgICAgdGhpcy50b2dnbGVDb21wYXJlID0gZmFsc2U7XG4gICAgICAgIHRoaXMudG9nZ2xlR2F1Z2VNZWFzdXJlcyA9IGZhbHNlO1xuICAgICAgICB0aGlzLnRvZ2dsZVJlbW92ZUNvbXBhcmVEdXBsaWNhdGUgPSB0cnVlO1xuICAgICAgICB0aGlzLnRvZ2dsZUN1bXVsYXRpdmUgPSB0aGlzLnN0b3JhZ2UuZ2V0KCdyYWFpbi10b2dnbGVDdW11bGF0aXZlJyk7XG5cbiAgICAgICAgdGhpcy5wZXJpb2RCZWdpbiA9IG5ldyBEYXRlKHRoaXMuc3RvcmFnZS5nZXQoJ3JhYWluLXBlcmlvZEJlZ2luJykpO1xuICAgICAgICB0aGlzLnBlcmlvZEVuZCA9IG5ldyBEYXRlKHRoaXMuc3RvcmFnZS5nZXQoJ3JhYWluLXBlcmlvZEVuZCcpKTtcbiAgICAgICAgdGhpcy5wZXJpb2RCZWdpbkFzU3RyaW5nID0gUmFhaW5EZXRhaWxzQ29tcG9uZW50LlBlcmlvZERpc3BsYXkodGhpcy5wZXJpb2RCZWdpbik7XG4gICAgICAgIHRoaXMucGVyaW9kRW5kQXNTdHJpbmcgPSBSYWFpbkRldGFpbHNDb21wb25lbnQuUGVyaW9kRGlzcGxheSh0aGlzLnBlcmlvZEVuZCk7XG4gICAgICAgIGNvbnN0IGR1cmF0aW9uTXMgPSB0aGlzLnBlcmlvZEVuZC5nZXRUaW1lKCkgLSB0aGlzLnBlcmlvZEJlZ2luLmdldFRpbWUoKTtcbiAgICAgICAgdGhpcy5wZXJpb2REdXJhdGlvbkFzU3RyaW5nID0gJycgKyBkdXJhdGlvbk1zIC8gUmFhaW5EZXRhaWxzQ29tcG9uZW50LkhPVVJfTVM7XG5cbiAgICAgICAgdGhpcy5kYXRlU2hvd24gPSB0aGlzLmdldERhdGVCYXNlZE9uQ3VtdWxhdGl2ZU1vZGUoKTtcbiAgICAgICAgdGhpcy5yZWZyZXNoSW5Qcm9ncmVzcyA9IGZhbHNlO1xuICAgICAgICB0aGlzLnNob3dGdWxsRXJyb3IgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5zaG93UXVhbGl0eU1vZGFsID0gZmFsc2U7XG4gICAgICAgIHRoaXMucXVhbGl0eUluZGljYXRvcnMgPSBbXTtcbiAgICAgICAgdGhpcy5xdWFsaXR5SW5kaWNhdG9yc0xvYWRpbmcgPSBmYWxzZTtcblxuICAgICAgICB0aGlzLmNvbXBhcmVNYW5hZ2VyPy5jbGVhbkFsbCgpO1xuICAgICAgICB0aGlzLnJlZnJlc2hNYW5hZ2VyPy5jbGVhbkFsbCgpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgaW5pdCgpIHtcbiAgICAgICAgdGhpcy5jbGVhbkFsbCgpO1xuICAgICAgICB0aGlzLnVwZGF0ZUNhY2hlZFZhbHVlcygpO1xuICAgICAgICBhd2FpdCB0aGlzLmluaXRSYWluKCk7XG4gICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgaW5pdFJhaW4oKSB7XG4gICAgICAgIGlmICghdGhpcy5yYWluTm9kZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5pc0FkbWluID0gdGhpcy5wcm9maWxlU2VydmljZS5pc0FkbWluKCk7XG5cbiAgICAgICAgdGhpcy5yZWZyZXNoTWFuYWdlci5yYWluTm9kZSA9IHRoaXMucmFpbk5vZGU7XG4gICAgICAgIHRoaXMuY29tcGFyZU1hbmFnZXIucmFpbk5vZGUgPSB0aGlzLnJhaW5Ob2RlO1xuXG4gICAgICAgIC8vIExvYWQgcHJvdmlkZXJzIGFuZCBzZXQgb24gcmVmcmVzaE1hbmFnZXJcbiAgICAgICAgYXdhaXQgdGhpcy5sb2FkUHJvdmlkZXJzKCk7XG5cbiAgICAgICAgdGhpcy5yZWZyZXNoTWFuYWdlci5zZXRNZXRob2RzKFxuICAgICAgICAgICAgdGhpcy5vblJlZnJlc2hJblByb2dyZXNzLmJpbmQodGhpcyksXG4gICAgICAgICAgICB0aGlzLm9uUmVmcmVzaERvbmUuYmluZCh0aGlzKSxcbiAgICAgICAgICAgIHRoaXMub25GZXRjaERvbmUuYmluZCh0aGlzKVxuICAgICAgICApO1xuXG4gICAgICAgIGNvbnN0IGNlbnRlciA9IHRoaXMucmFpbk5vZGUuZ2V0Q2VudGVyKCk7XG4gICAgICAgIHRoaXMuY29vcmRpbmF0ZXMgPSBuZXcgTWFwTGF0TG5nKGNlbnRlci5sYXQsIGNlbnRlci5sbmcpO1xuICAgICAgICB0aGlzLnRlYW1Ob2RlID0gYXdhaXQgdGhpcy5wcm9maWxlU2VydmljZS5nZXRUZWFtKFxuICAgICAgICAgICAgdGhpcy5yYWluTm9kZS5nZXRMaW5rKFRlYW1Ob2RlLlRZUEUpLmdldElkKClcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAodGhpcy5wZXJpb2RCZWdpbiAmJiB0aGlzLnBlcmlvZEVuZCkge1xuICAgICAgICAgICAgdGhpcy51cGRhdGVSZWZyZXNoTWFuYWdlclBlcmlvZCgpO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5yZWZyZXNoTWFuYWdlci5yZWZyZXNoKGZhbHNlLCB0aGlzLnRvZ2dsZUFkbWluKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgb25SZWZyZXNoSW5Qcm9ncmVzcyhcbiAgICAgICAgY291bnRQZXJpb2RzOiB7XG4gICAgICAgICAgICBwZXJjZW50SW1hZ2VzPzogWFlUeXBlW107XG4gICAgICAgICAgICBxdWV1ZVJ1bm5pbmc/OiBudW1iZXI7XG4gICAgICAgICAgICBwcm9ncmVzcz86IG51bWJlcjtcbiAgICAgICAgfSxcbiAgICAgICAgdGltZWZyYW1lRGF0ZXM6IERhdGVbXVxuICAgICkge1xuICAgICAgICB0aGlzLnJlZnJlc2hJblByb2dyZXNzID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5jb3VudHNQZXJpb2QgPSBjb3VudFBlcmlvZHM7XG4gICAgICAgIHRoaXMudGltZWZyYW1lRGF0ZXMgPSB0aW1lZnJhbWVEYXRlcztcbiAgICAgICAgdGhpcy51cGRhdGVDYWNoZWRWYWx1ZXMoKTtcbiAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBvblJlZnJlc2hEb25lKHRpbWVmcmFtZURhdGVzOiBEYXRlW10pIHtcbiAgICAgICAgdGhpcy50aW1lZnJhbWVEYXRlcyA9IHRpbWVmcmFtZURhdGVzO1xuICAgICAgICB0aGlzLnJlZnJlc2hJblByb2dyZXNzID0gZmFsc2U7XG4gICAgICAgIHRoaXMudXBkYXRlQ2FjaGVkVmFsdWVzKCk7XG4gICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuXG4gICAgICAgIGlmICh0aGlzLnRvZ2dsZU1hcCAmJiB0aW1lZnJhbWVEYXRlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB0aGlzLmRhdGVTaG93biA9IHRoaXMuZ2V0RGF0ZUJhc2VkT25DdW11bGF0aXZlTW9kZSh0aW1lZnJhbWVEYXRlcyk7XG4gICAgICAgICAgICBpZiAodGhpcy5kYXRlU2hvd24pIHtcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLmZldGNoQW5kVXBkYXRlTWFwKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIG9uRmV0Y2hEb25lKHRpbWVmcmFtZUNvbnRhaW5lcnM/OiBUaW1lZnJhbWVDb250YWluZXJzKSB7XG4gICAgICAgIGlmICh0aW1lZnJhbWVDb250YWluZXJzKSB7XG4gICAgICAgICAgICB0aGlzLnRpbWVmcmFtZUNvbnRhaW5lcnMgPSB0aW1lZnJhbWVDb250YWluZXJzO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgY2hhbmdlKF9jaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XG4gICAgICAgIGF3YWl0IHRoaXMuaW5pdCgpO1xuICAgIH1cbn1cbiIsIjwhLS0gTWFpbiBjb250ZW50IGNvbnRhaW5lciAtLT5cbjxkaXYgKm5nSWY9XCJyYWluTm9kZVwiIGNsYXNzPVwicmFhaW4tZGV0YWlscy1jb250YWluZXJcIj5cblxuICAgIDwhLS0gUGVyaW9kIHNlbGVjdGlvbiBzZWN0aW9uIC0tPlxuICAgIDxpb24tY2FyZCBjbGFzcz1cInBlcmlvZC1jYXJkXCI+XG4gICAgICAgIDxpb24tY2FyZC1jb250ZW50PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInBlcmlvZC1jb250cm9sc1wiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwZXJpb2Qtcm93XCI+XG5cbiAgICAgICAgICAgICAgICAgICAgPGlvbi1idXR0b24gKGNsaWNrKT1cInRvZ2dsZUhpc3RvcnkgPSAhdG9nZ2xlSGlzdG9yeTsgb25FbmFibGVDb3VudEhpc3RvcnlUYWIocmFpbk5vZGUpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbD1cIm91dGxpbmVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxpb24taWNvbiBuYW1lPVwiY2FsZW5kYXItY2xlYXItb3V0bGluZVwiIHNsb3Q9XCJzdGFydFwiPjwvaW9uLWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8aW9uLWljb24gW25hbWVdPVwidG9nZ2xlSGlzdG9yeSA/ICdjaGV2cm9uLWRvd24nIDogJ2NoZXZyb24tZm9yd2FyZCdcIiBzbG90PVwiZW5kXCI+PC9pb24taWNvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9pb24tYnV0dG9uPlxuXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwZXJpb2Qtc3RhcnQgaW9uLWhpZGUtbWQtZG93blwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IChjaGFuZ2UpPVwib25QZXJpb2RCZWdpbkNoYW5nZSgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwidG9nZ2xlQ3VtdWxhdGl2ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cInBlcmlvZEJlZ2luQXNTdHJpbmdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZGF0ZXRpbWUtaW5wdXRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJkYXRldGltZS1sb2NhbFwiPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicGVyaW9kLWR1cmF0aW9uIGlvbi1oaWRlLW1kLWRvd25cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxpb24tc2VsZWN0IChpb25EaXNtaXNzKT1cIm9uUGVyaW9kRHVyYXRpb25DaGFuZ2UoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cInBlcmlvZER1cmF0aW9uQXNTdHJpbmdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJkdXJhdGlvbi1zZWxlY3RcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWQ9XCJwZXJpb2REdXJhdGlvblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRlcmZhY2U9XCJwb3BvdmVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlvbi1zZWxlY3Qtb3B0aW9uIHZhbHVlPVwiMC4yNVwiPjE1IG1pbnV0ZXM8L2lvbi1zZWxlY3Qtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpb24tc2VsZWN0LW9wdGlvbiB2YWx1ZT1cIjAuNVwiPjMwIG1pbnV0ZXM8L2lvbi1zZWxlY3Qtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpb24tc2VsZWN0LW9wdGlvbiB2YWx1ZT1cIjFcIj4xIGhvdXI8L2lvbi1zZWxlY3Qtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpb24tc2VsZWN0LW9wdGlvbiB2YWx1ZT1cIjJcIj4yIGhvdXJzPC9pb24tc2VsZWN0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW9uLXNlbGVjdC1vcHRpb24gdmFsdWU9XCIzXCI+MyBob3VyczwvaW9uLXNlbGVjdC1vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlvbi1zZWxlY3Qtb3B0aW9uIHZhbHVlPVwiNFwiPjQgaG91cnM8L2lvbi1zZWxlY3Qtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpb24tc2VsZWN0LW9wdGlvbiB2YWx1ZT1cIjVcIj41IGhvdXJzPC9pb24tc2VsZWN0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW9uLXNlbGVjdC1vcHRpb24gdmFsdWU9XCI2XCI+NiBob3VyczwvaW9uLXNlbGVjdC1vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlvbi1zZWxlY3Qtb3B0aW9uIHZhbHVlPVwiOFwiPjggaG91cnM8L2lvbi1zZWxlY3Qtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpb24tc2VsZWN0LW9wdGlvbiB2YWx1ZT1cIjEwXCI+MTAgaG91cnM8L2lvbi1zZWxlY3Qtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpb24tc2VsZWN0LW9wdGlvbiB2YWx1ZT1cIjEyXCI+MTIgaG91cnM8L2lvbi1zZWxlY3Qtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpb24tc2VsZWN0LW9wdGlvbiAqbmdJZj1cImlzQWRtaW5cIiB2YWx1ZT1cIjI0XCI+MjQgaG91cnM8L2lvbi1zZWxlY3Qtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9pb24tc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicGVyaW9kLXN0YXJ0IGlvbi1oaWRlLW1kLWRvd25cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCAoY2hhbmdlKT1cIm9uUGVyaW9kRW5kQ2hhbmdlKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCIhdG9nZ2xlQ3VtdWxhdGl2ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cInBlcmlvZEVuZEFzU3RyaW5nXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImRhdGV0aW1lLWlucHV0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwiZGF0ZXRpbWUtbG9jYWxcIj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRvZ2dsZS1jdW11bGF0aXZlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8aW9uLWxhYmVsIFtjbGFzcy50ZXh0LXByaW1hcnldPVwidG9nZ2xlQ3VtdWxhdGl2ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IHRvZ2dsZUN1bXVsYXRpdmUgPyAnQ3VtdWxhdGl2ZScgOiAnR3JhbnVsYXInIH19XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2lvbi1sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxpb24tdG9nZ2xlIChpb25DaGFuZ2UpPVwidG9nZ2xlQ3VtdWxhdGl2ZUNoYW5nZWQoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cInRvZ2dsZUN1bXVsYXRpdmVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NoZWNrZWRdPVwidG9nZ2xlQ3VtdWxhdGl2ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9pb24tdG9nZ2xlPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgIDwhLS0gSGlkZGVuIGxhYmVsIGZvciBjaGFuZ2UgZGV0ZWN0aW9uICh1bmNvbW1lbnQgdG8gZGVidWcpXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImhpZGRlbi1sYWJlbFwiPnt7IG9uQ2hhbmdlRGV0ZWN0aW9uVGVzdChyYWluTm9kZSkgfX08L2Rpdj5cbiAgICAgICAgICAgICAgICAtLT5cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8IS0tIEhpc3RvcmljYWwgbWFwIHNlY3Rpb24gLS0+XG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwidG9nZ2xlSGlzdG9yeVwiIGNsYXNzPVwicGVyaW9kLWNvbnRyb2xzXCI+XG4gICAgICAgICAgICAgICAgPHJhYWluLWRhdGUtZHluYW1pYyAoY2hhbmdlZERhdGUpPVwib25EYXRlQ2hhbmdlSW5Db3VudCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjdXJyZW50SGVpZ2h0XT1cIjMwMFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZmV0Y2hEYXRhXT1cImZldGNoRGF0YVdyYXBwZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BvaW50c109XCJjb3VudFBvaW50c1wiPlxuICAgICAgICAgICAgICAgIDwvcmFhaW4tZGF0ZS1keW5hbWljPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvaW9uLWNhcmQtY29udGVudD5cbiAgICA8L2lvbi1jYXJkPlxuXG4gICAgPCEtLSBNYXAgcGVyZm9ybWFuY2UgLS0+XG4gICAgPGlvbi1ncmlkIGNsYXNzPVwibWFwLXBlcmZvcm1hbmNlXCI+XG4gICAgICAgIDxpb24tcm93IGlkPVwicHJvZ3Jlc3NBbmRSZWZyZXNoXCI+XG4gICAgICAgICAgICA8aW9uLWNvbCBjbGFzcz1cInByb3ZpZGVyLXNlbGVjdGlvblwiIHNpemU9XCIxMlwiIHNpemUtbWQ9XCI2XCI+XG4gICAgICAgICAgICAgICAgPGlvbi1idXR0b24gKGNsaWNrKT1cIm9wZW5RdWFsaXR5TW9kYWwoKVwiIGNsYXNzPVwicXVhbGl0eS1pbmZvLWJ1dHRvblwiIGZpbGw9XCJjbGVhclwiPlxuICAgICAgICAgICAgICAgICAgICB7eyByZWZyZXNoTWFuYWdlci5yYWluQ29tcHV0YXRpb25NYXBWZXJzaW9uIH19XG4gICAgICAgICAgICAgICAgICAgIDxpb24taWNvbiBuYW1lPVwiaGVscC1jaXJjbGUtb3V0bGluZVwiIHNsb3Q9XCJlbmRcIj48L2lvbi1pY29uPlxuICAgICAgICAgICAgICAgIDwvaW9uLWJ1dHRvbj5cbiAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiYXZhaWxhYmxlUHJvdmlkZXJzLmxlbmd0aCA+IDAgfHwgYXZhaWxhYmxlVGltZVN0ZXBzLmxlbmd0aCA+IDBcIiBjbGFzcz1cInNlbGVjdGlvbi1yb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgPGlvbi1zZWxlY3QgKGlvbkNoYW5nZSk9XCJvblByb3ZpZGVyQ2hhbmdlZCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cInNlbGVjdGVkUHJvdmlkZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRlcmZhY2U9XCJwb3BvdmVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw9XCJQcm92aWRlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiU2VsZWN0IFByb3ZpZGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8aW9uLXNlbGVjdC1vcHRpb24gKm5nRm9yPVwibGV0IHByb3ZpZGVyIG9mIGF2YWlsYWJsZVByb3ZpZGVyc1wiIFt2YWx1ZV09XCJwcm92aWRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IHByb3ZpZGVyIH19XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2lvbi1zZWxlY3Qtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICA8L2lvbi1zZWxlY3Q+XG5cbiAgICAgICAgICAgICAgICAgICAgPGlvbi1zZWxlY3QgKGlvbkNoYW5nZSk9XCJvblRpbWVTdGVwQ2hhbmdlZCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cInNlbGVjdGVkVGltZVN0ZXBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRlcmZhY2U9XCJwb3BvdmVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw9XCJUaW1lIFN0ZXBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIlNlbGVjdCBUaW1lIFN0ZXBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxpb24tc2VsZWN0LW9wdGlvbiAqbmdGb3I9XCJsZXQgc3RlcCBvZiBhdmFpbGFibGVUaW1lU3RlcHNcIiBbdmFsdWVdPVwic3RlcFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IHN0ZXAgfX0gbWluXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2lvbi1zZWxlY3Qtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICA8L2lvbi1zZWxlY3Q+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2lvbi1jb2w+XG4gICAgICAgICAgICA8aW9uLWNvbCBjbGFzcz1cImlvbi10ZXh0LXJpZ2h0XCIgc2l6ZT1cIjEyXCIgc2l6ZS1tZD1cIjZcIj5cbiAgICAgICAgICAgICAgICA8aW9uLWxhYmVsIGNsYXNzPVwiaW9uLW1hcmdpbi1lbmRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cInBlcmNlbnRPZkNvbXB1dGF0aW9uc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBwZXJjZW50T2ZDb21wdXRhdGlvbnMgfX0lIEltYWdlc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aSAqbmdJZj1cImNvdW50c1BlcmlvZC5wcm9ncmVzc1wiIGNsYXNzPVwicHJvZ3Jlc3MtaW5kaWNhdG9yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbiBQcm9ncmVzczoge3sgY291bnRzUGVyaW9kLnByb2dyZXNzIH19Li4uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvaT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwiIXBlcmNlbnRPZkNvbXB1dGF0aW9uc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBObyBpbWFnZSBhdmFpbGFibGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG5cbiAgICAgICAgICAgICAgICA8L2lvbi1sYWJlbD5cblxuICAgICAgICAgICAgICAgIDxpb24tYnV0dG9uIChjbGljayk9XCJyZWZyZXNoTWFwKClcIiBbZGlzYWJsZWRdPVwicmVmcmVzaEluUHJvZ3Jlc3NcIiBjbGFzcz1cInJlZnJlc2gtYnV0dG9uXCI+XG4gICAgICAgICAgICAgICAgICAgIFJlZnJlc2ggTWFwXG4gICAgICAgICAgICAgICAgPC9pb24tYnV0dG9uPlxuICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICA8L2lvbi1yb3c+XG5cbiAgICAgICAgPCEtLSBzdGF0dXMgdXBkYXRlIHJvdyAtLT5cbiAgICAgICAgPGlvbi1yb3c+XG4gICAgICAgICAgICA8IS0tIFByb2dyZXNzIGNvbCAtLT5cbiAgICAgICAgICAgIDxpb24tcHJvZ3Jlc3MtYmFyXG4gICAgICAgICAgICAgICAgICAgIFtidWZmZXJdPVwiKGNvdW50c1BlcmlvZC5wcm9ncmVzcyAvICgodGltZWZyYW1lRGF0ZXM/Lmxlbmd0aCB8fCAxMCkgKzMpKSswLjAxXCJcbiAgICAgICAgICAgICAgICAgICAgW3N0eWxlLnZpc2liaWxpdHldPVwicmVmcmVzaEluUHJvZ3Jlc3MgPyAndmlzaWJsZScgOiAnaGlkZGVuJ1wiXG4gICAgICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJjb3VudHNQZXJpb2QucHJvZ3Jlc3MgLyAoKHRpbWVmcmFtZURhdGVzPy5sZW5ndGggfHwgMTApICszKVwiXG4gICAgICAgICAgICAgICAgICAgIGNvbG9yPVwicHJpbWFyeVwiPlxuICAgICAgICAgICAgPC9pb24tcHJvZ3Jlc3MtYmFyPlxuXG4gICAgICAgICAgICA8IS0tIEVycm9yIGNvbCAtLT5cbiAgICAgICAgICAgIDxpb24tY29sIChjbGljayk9XCJzaG93RnVsbEVycm9yID0gIXNob3dGdWxsRXJyb3JcIiAqbmdJZj1cInJlZnJlc2hNYW5hZ2VyLmxhc3RFcnJvclwiIGNsYXNzPVwiZXJyb3Itcm93XCJcbiAgICAgICAgICAgICAgICAgICAgIHNpemU9XCIxMlwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJlcnJvci1jb250ZW50XCI+XG4gICAgICAgICAgICAgICAgICAgIDxpb24taWNvbiBjbGFzcz1cImVycm9yLWljb25cIiBuYW1lPVwid2FybmluZy1vdXRsaW5lXCI+PC9pb24taWNvbj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gW2NsYXNzLmV4cGFuZGVkXT1cInNob3dGdWxsRXJyb3JcIiBjbGFzcz1cImVycm9yLXRleHRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIHt7IHNob3dGdWxsRXJyb3IgPyByZWZyZXNoTWFuYWdlci5sYXN0RXJyb3IgOiB0cnVuY2F0ZWRFcnJvciB9fVxuICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDxpb24taWNvbiBbbmFtZV09XCJzaG93RnVsbEVycm9yID8gJ2NoZXZyb24tdXAnIDogJ2NoZXZyb24tZG93bidcIiBjbGFzcz1cImVycm9yLWNhcmV0XCI+PC9pb24taWNvbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvaW9uLWNvbD5cbiAgICAgICAgPC9pb24tcm93PlxuICAgIDwvaW9uLWdyaWQ+XG5cbiAgICA8IS0tIE1hcCBzZWN0aW9uIC0tPlxuICAgIDxpb24tY2FyZCBjbGFzcz1cIm1hcC1jYXJkXCI+XG4gICAgICAgIDxpb24tY2FyZC1jb250ZW50IGNsYXNzPVwibWFwLWNvbnRlbnRcIj5cbiAgICAgICAgICAgIDxpb24tZ3JpZD5cbiAgICAgICAgICAgICAgICA8aW9uLXJvdyAqbmdJZj1cInRvZ2dsZU1hcCAmJiBwZXJjZW50T2ZJbWFnZXNcIj5cbiAgICAgICAgICAgICAgICAgICAgPCEtLSBNYXAgY29tcG9uZW50IC0tPlxuICAgICAgICAgICAgICAgICAgICA8aW9uLWNvbCBjbGFzcz1cIm1hcC1jb2x1bW5cIiBzaXplLWxnPVwiN1wiIHNpemUtbWQ9XCIxMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1hcC1jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cmFhaW4tbWFwICNyYWFpbk1hcFJlZlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNoYW5nZWREYXRlKT1cIm9uRGF0ZUNoYW5nZUluTWFwKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNoYW5nZWRTdW0pPVwib25TdW1DaGFuZ2VJbk1hcCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzZWxlY3RlZE1hcmtlcik9XCJvbkdhdWdlU2VsZWN0SW5NYXAoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY29vcmRpbmF0ZXNdPVwiY29vcmRpbmF0ZXNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2N1bXVsYXRpdmVEdXJhdGlvbkluTWludXRlc109XCJjdW11bGF0aXZlRHVyYXRpb25Jbk1pbnV0ZXNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2N1cnJlbnRIZWlnaHRdPVwiNTAwXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkZWZhdWx0RGF0ZV09XCJkYXRlU2hvd25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW21hcmtlcnNdPVwie1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvcmRlcnMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2F1Z2VzOiBjb21wYXJlTWFuYWdlci5nYXVnZXNJbk1hcCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnYXVnZXNJbkNvbXBhcmU6IGNvbXBhcmVNYW5hZ2VyLmdhdWdlc0luQ29tcGFyZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZEdhdWdlczogY29tcGFyZU1hbmFnZXIuc2VsZWN0ZWRHYXVnZXMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGl4ZWxzOiBjb21wYXJlTWFuYWdlci5zZWxlY3RlZFBpeGVscyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaXhlbHNTb2x1dGlvbjogY29tcGFyZU1hbmFnZXIucGl4ZWxzU29sdXRpb25zPy5sZW5ndGggPyBjb21wYXJlTWFuYWdlci5waXhlbHNTb2x1dGlvbnNbMF0gOiBbXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVlZHM6IGNvbXBhcmVNYW5hZ2VyLnNwZWVkc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc2hvd0N1bXVsYXRpdmVdPVwidG9nZ2xlQ3VtdWxhdGl2ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc2hvd1Zpc2libGVQaXhlbE1hcmtlcnNdPVwic2hvd1BpeGVsTWFya2Vyc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3VtRm5dPVwicmVmcmVzaE1hbmFnZXIuc3VtRm5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3N1bVZhbHVlc109XCJyZWZyZXNoTWFuYWdlci5zdW1WYWx1ZXNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3RpbWVmcmFtZUNvbnRhaW5lcnNdPVwidGltZWZyYW1lQ29udGFpbmVyc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdGltZWZyYW1lRGF0ZXNdPVwidGltZWZyYW1lRGF0ZXNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3JhYWluLW1hcD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGF0YS1jb2x1bW5cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIFRlY2huaWNhbCBkZXRhaWxzIChjb2xsYXBzaWJsZSBmb3IgY2xlYW5lciBVSSkgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRldGFpbHMgY2xhc3M9XCJ0ZWNobmljYWwtZGV0YWlsc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3VtbWFyeT5JbWFnZSBEZXRhaWxzPC9zdW1tYXJ5PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGV0YWlscy1jb250ZW50XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGV0YWlsLXJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGV0YWlsLWxhYmVsXCI+Q29tcHV0ZWQ6PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGV0YWlsLXZhbHVlXCI+e3sgcmVmcmVzaE1hbmFnZXIucmFpbkNvbXB1dGF0aW9uTWFwRG9uZURhdGUgfCBkYXRlOid5eXl5LU1NLWRkIEhIOm1tJyB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRldGFpbC1yb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRldGFpbC1sYWJlbFwiPlZlcnNpb246PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGV0YWlsLXZhbHVlXCI+e3sgcmVmcmVzaE1hbmFnZXIucmFpbkNvbXB1dGF0aW9uTWFwVmVyc2lvbiB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRldGFpbC1yb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRldGFpbC1sYWJlbFwiPkxhdW5jaGVkIGJ5Ojwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRldGFpbC12YWx1ZVwiPnt7IHJlZnJlc2hNYW5hZ2VyLnJhaW5Db21wdXRhdGlvbk1hcExhdW5jaGVkQnkgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkZXRhaWwtcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkZXRhaWwtbGFiZWxcIj5UaW1lIHNwZW50Ojwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRldGFpbC12YWx1ZVwiPnt7IHJlZnJlc2hNYW5hZ2VyLnJhaW5Db21wdXRhdGlvbk1hcFRpbWVTcGVudEluTXMgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXM8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkZXRhaWwtcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkZXRhaWwtbGFiZWxcIj5EYXRlOjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRldGFpbC12YWx1ZVwiPnt7IHJlZnJlc2hNYW5hZ2VyLnJhaW5Db21wdXRhdGlvbk1hcERhdGU/LnRvSVNPU3RyaW5nKCkgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCB7eyByZWZyZXNoTWFuYWdlci5yYWluQ29tcHV0YXRpb25NYXBEYXRlIHwgZGF0ZToneXl5eS1NTS1kZCBISDptbScgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkZXRhaWwtcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkZXRhaWwtbGFiZWxcIj5XYXRlciBpbiB0aGUgbWFwOjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRldGFpbC12YWx1ZVwiPnt7IHN1bURldGFpbHMgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlvbi10b2dnbGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpb25DaGFuZ2UpPVwib25Ub2dnbGVQaXhlbE1hcmtlcnMoKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cInNob3dQaXhlbE1hcmtlcnNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCJtYXJnaW4tbGVmdDogOHB4OyB0cmFuc2Zvcm06IHNjYWxlKDAuNyk7XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9pb24tdG9nZ2xlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGV0YWlsLXJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGV0YWlsLWxhYmVsXCI+U291cmNlIERCWiBtaW46PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGV0YWlsLXZhbHVlXCI+e3sgcmVmcmVzaE1hbmFnZXIucmFpbkNvbXB1dGF0aW9uTWFwT3JpZ2luYWxNaW4gfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkZXRhaWwtcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkZXRhaWwtbGFiZWxcIj5Tb3VyY2UgREJaIG1heDo8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkZXRhaWwtdmFsdWVcIj57eyByZWZyZXNoTWFuYWdlci5yYWluQ29tcHV0YXRpb25NYXBPcmlnaW5hbE1heCB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2RldGFpbHM+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9pb24tY29sPlxuXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gRGF0YSBwYW5lbCAtLT5cbiAgICAgICAgICAgICAgICAgICAgPGlvbi1jb2wgKm5nSWY9XCIhIWNvbXBhcmVNYW5hZ2VyLmNvbXBhcmVWZXJzaW9uXCIgY2xhc3M9XCJkYXRhLWNvbHVtblwiIHNpemUtbGc9XCI1XCIgc2l6ZS1tZD1cIjEyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGF0YS1wYW5lbFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gQ29tcGFyZSBzdGFjayBjb21wb25lbnQgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbXBhcmUtc3RhY2tcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHJhYWluLWNvbXBhcmUtc3RhY2tcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc2VsZWN0ZWRQb2ludCk9XCJvbkdhdWdlU2VsZWN0SW5Db21wYXJlKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjb21wYXJlTWFuYWdlcl09XCJjb21wYXJlTWFuYWdlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2N1bXVsYXRpdmVdPVwidG9nZ2xlQ3VtdWxhdGl2ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3JhYWluLWNvbXBhcmUtc3RhY2s+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIFRlY2huaWNhbCBkZXRhaWxzIChjb2xsYXBzaWJsZSBmb3IgY2xlYW5lciBVSSkgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRldGFpbHMgY2xhc3M9XCJ0ZWNobmljYWwtZGV0YWlsc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3VtbWFyeT5Db21wYXJlIERldGFpbHM8L3N1bW1hcnk+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkZXRhaWxzLWNvbnRlbnRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgW25nQ2xhc3NdPVwieyd3YXJuaW5nJzogcmVmcmVzaE1hbmFnZXIucmFpbkNvbXB1dGF0aW9uTWFwRG9uZURhdGU/LmdldFRpbWUoKSA+IGNvbXBhcmVNYW5hZ2VyLmN1cnJlbnRRdWFsaXR5RG9uZURhdGU/LmdldFRpbWUoKSArIDYwMDAwfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZGV0YWlsLXJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGV0YWlsLWxhYmVsXCI+Q29tcHV0ZWQ6PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGV0YWlsLXZhbHVlXCI+e3sgY29tcGFyZU1hbmFnZXIuY3VycmVudFF1YWxpdHlEb25lRGF0ZSB8IGRhdGU6J3l5eXktTU0tZGQgSEg6bW0nIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGV0YWlsLXJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGV0YWlsLWxhYmVsXCI+VmVyc2lvbjo8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkZXRhaWwtdmFsdWVcIj57eyBjb21wYXJlTWFuYWdlci5jb21wYXJlVmVyc2lvbiB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRldGFpbC1yb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRldGFpbC1sYWJlbFwiPkxhdW5jaGVkIGJ5Ojwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRldGFpbC12YWx1ZVwiPnt7IGNvbXBhcmVNYW5hZ2VyLmN1cnJlbnRRdWFsaXR5TGF1bmNoZWRCeSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRldGFpbC1yb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRldGFpbC1sYWJlbFwiPlRpbWUgc3BlbnQ6PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGV0YWlsLXZhbHVlXCI+e3sgY29tcGFyZU1hbmFnZXIuY3VycmVudFF1YWxpdHlUaW1lU3BlbnRJbk1zIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1zPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGV0YWlsLXJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGV0YWlsLWxhYmVsXCI+R2F1Z2VzOjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRldGFpbC12YWx1ZVwiPnt7IGNvbXBhcmVNYW5hZ2VyLmdhdWdlc0luQ29tcGFyZS5sZW5ndGggfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkZXRhaWwtcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkZXRhaWwtbGFiZWxcIj5Qb2ludHM6PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGV0YWlsLXZhbHVlXCI+e3sgY29tcGFyZU1hbmFnZXIuZ2xvYmFsQ29tcGFyZVBvaW50cy5sZW5ndGggfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kZXRhaWxzPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvaW9uLWNvbD5cbiAgICAgICAgICAgICAgICA8L2lvbi1yb3c+XG4gICAgICAgICAgICAgICAgPGlvbi1yb3c+XG4gICAgICAgICAgICAgICAgICAgIDwhLS0gQm90dG9tIHByb2dyZXNzIGJhciAtLT5cbiAgICAgICAgICAgICAgICAgICAgPGlvbi1wcm9ncmVzcy1iYXIgKm5nSWY9XCJyZWZyZXNoSW5Qcm9ncmVzc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtidWZmZXJdPVwiKGNvdW50c1BlcmlvZC5wcm9ncmVzcyAvICgodGltZWZyYW1lRGF0ZXM/Lmxlbmd0aCB8fCAxMCkgKzMpKSswLjAxXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cImNvdW50c1BlcmlvZC5wcm9ncmVzcyAvICgodGltZWZyYW1lRGF0ZXM/Lmxlbmd0aCB8fCAxMCkgKzMpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3I9XCJwcmltYXJ5XCI+XG4gICAgICAgICAgICAgICAgICAgIDwvaW9uLXByb2dyZXNzLWJhcj5cbiAgICAgICAgICAgICAgICA8L2lvbi1yb3c+XG4gICAgICAgICAgICA8L2lvbi1ncmlkPlxuICAgICAgICA8L2lvbi1jYXJkLWNvbnRlbnQ+XG4gICAgPC9pb24tY2FyZD5cblxuICAgIDwhLS0gR2F1Z2UgdmFsdWVzIHNlY3Rpb24gLS0+XG4gICAgPGlvbi1jYXJkICpuZ0lmPVwiZ2F1Z2VTZWxlY3RlZFBvaW50cy5sZW5ndGggJiYgZ2F1Z2VTZWxlY3RlZFBvaW50c1swXS52YWx1ZXMubGVuZ3RoXCIgY2xhc3M9XCJnYXVnZS1jYXJkXCI+XG4gICAgICAgIDxpb24tY2FyZC1oZWFkZXI+XG4gICAgICAgICAgICA8aW9uLWNhcmQtdGl0bGU+XG4gICAgICAgICAgICAgICAgPGlvbi1pY29uIG5hbWU9XCJhbmFseXRpY3Mtb3V0bGluZVwiPjwvaW9uLWljb24+XG4gICAgICAgICAgICAgICAgU2VsZWN0ZWQgR2F1Z2UgRGF0YVxuICAgICAgICAgICAgPC9pb24tY2FyZC10aXRsZT5cbiAgICAgICAgPC9pb24tY2FyZC1oZWFkZXI+XG4gICAgICAgIDxpb24tY2FyZC1jb250ZW50PlxuICAgICAgICAgICAgPHJhYWluLWRhdGUtZm9jdXNcbiAgICAgICAgICAgICAgICAgICAgW2N1cnJlbnRIZWlnaHRdPVwiMzAwXCJcbiAgICAgICAgICAgICAgICAgICAgW2ZvY3VzRGF0ZV09XCJwZXJpb2RCZWdpblwiXG4gICAgICAgICAgICAgICAgICAgIFtmb2N1c1JhbmdlXT1cIkRhdGVSYW5nZS5EQVlcIlxuICAgICAgICAgICAgICAgICAgICBbcG9pbnRzXT1cImdhdWdlU2VsZWN0ZWRQb2ludHNcIlxuICAgICAgICAgICAgICAgICAgICBbd2l0aG91dEFsbF09XCJ0cnVlXCI+XG4gICAgICAgICAgICA8L3JhYWluLWRhdGUtZm9jdXM+XG4gICAgICAgIDwvaW9uLWNhcmQtY29udGVudD5cbiAgICA8L2lvbi1jYXJkPlxuXG4gICAgPCEtLSBRdWFsaXR5IFBlcmZvcm1hbmNlIE1vZGFsIC0tPlxuICAgIDxkaXYgKGNsaWNrKT1cImNsb3NlUXVhbGl0eU1vZGFsKClcIiAqbmdJZj1cInNob3dRdWFsaXR5TW9kYWxcIiBjbGFzcz1cInF1YWxpdHktbW9kYWwtb3ZlcmxheVwiPlxuICAgICAgICA8ZGl2IChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIiBjbGFzcz1cInF1YWxpdHktbW9kYWwtY29udGVudFwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInF1YWxpdHktbW9kYWwtaGVhZGVyXCI+XG4gICAgICAgICAgICAgICAgPGgyPk1vZGVsIFF1YWxpdHkgUGVyZm9ybWFuY2U8L2gyPlxuICAgICAgICAgICAgICAgIDxpb24tYnV0dG9uIChjbGljayk9XCJjbG9zZVF1YWxpdHlNb2RhbCgpXCIgZmlsbD1cImNsZWFyXCI+XG4gICAgICAgICAgICAgICAgICAgIDxpb24taWNvbiBuYW1lPVwiY2xvc2Utb3V0bGluZVwiPjwvaW9uLWljb24+XG4gICAgICAgICAgICAgICAgPC9pb24tYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwicXVhbGl0eS1tb2RhbC1ib2R5XCI+XG4gICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cInF1YWxpdHlJbmRpY2F0b3JzTG9hZGluZ1wiIGNsYXNzPVwicXVhbGl0eS1sb2FkaW5nXCI+XG4gICAgICAgICAgICAgICAgICAgIDxpb24tc3Bpbm5lciBuYW1lPVwiY3Jlc2NlbnRcIj48L2lvbi1zcGlubmVyPlxuICAgICAgICAgICAgICAgICAgICA8c3Bhbj5Mb2FkaW5nIGluZGljYXRvcnMuLi48L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cIiFxdWFsaXR5SW5kaWNhdG9yc0xvYWRpbmcgJiYgcXVhbGl0eUluZGljYXRvcnMubGVuZ3RoID09PSAwXCIgY2xhc3M9XCJxdWFsaXR5LWVtcHR5XCI+XG4gICAgICAgICAgICAgICAgICAgIE5vIHF1YWxpdHkgaW5kaWNhdG9ycyBhdmFpbGFibGUgZm9yIHRoaXMgeWVhci5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8dGFibGUgKm5nSWY9XCIhcXVhbGl0eUluZGljYXRvcnNMb2FkaW5nICYmIHF1YWxpdHlJbmRpY2F0b3JzLmxlbmd0aCA+IDBcIiBjbGFzcz1cInF1YWxpdHktdGFibGVcIj5cbiAgICAgICAgICAgICAgICAgICAgPHRoZWFkPlxuICAgICAgICAgICAgICAgICAgICA8dHI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGg+TW9kZWw8L3RoPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRoPkNvbXBhcmU8L3RoPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRoPkdhdWdlczwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGg+UGVyaW9kPC90aD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0aD5BdmcgUXVhbGl0eTwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGg+VXBkYXRlZDwvdGg+XG4gICAgICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICAgICAgICAgIDwvdGhlYWQ+XG4gICAgICAgICAgICAgICAgICAgIDx0Ym9keT5cbiAgICAgICAgICAgICAgICAgICAgPHRyICpuZ0Zvcj1cImxldCBpbmRpY2F0b3Igb2YgcXVhbGl0eUluZGljYXRvcnNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0ZD57eyBpbmRpY2F0b3IuY29tcHV0aW5nVmVyc2lvbiB9fTwvdGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGQ+e3sgaW5kaWNhdG9yLnF1YWxpdHlWZXJzaW9uIH19PC90ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0ZD57eyBpbmRpY2F0b3IucHJvdmlkZXIgfX08YnI+e3sgaW5kaWNhdG9yLnRpbWVTdGVwSW5NaW51dGVzIH19IG1pbjwvdGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGQ+e3sgZm9ybWF0RGF0ZShpbmRpY2F0b3Iuc3RhcnREYXRlKSB9fTxicj57eyBmb3JtYXREYXRlKGluZGljYXRvci5lbmREYXRlKSB9fTwvdGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGQ+e3sgaW5kaWNhdG9yLmF2ZXJhZ2VRdWFsaXR5IHwgbnVtYmVyOicxLjItMicgfX08L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRkPnt7IGZvcm1hdERhdGUoaW5kaWNhdG9yLmxhc3RVcGRhdGVkQXQpIH19PC90ZD5cbiAgICAgICAgICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICAgICAgICAgICAgPC90Ym9keT5cbiAgICAgICAgICAgICAgICA8L3RhYmxlPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG48L2Rpdj5cbiJdfQ==
587
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmFhaW4tZGV0YWlscy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY29yZS9zaGFyZWQvcmFhaW4tZGV0YWlscy9yYWFpbi1kZXRhaWxzLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uL3NyYy9jb3JlL3NoYXJlZC9yYWFpbi1kZXRhaWxzL3JhYWluLWRldGFpbHMuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNILHVCQUF1QixFQUV2QixTQUFTLEVBRVQsS0FBSyxFQUlMLFNBQVMsR0FDWixNQUFNLGVBQWUsQ0FBQztBQUd2QixPQUFPLEVBQUMscUJBQXFCLEVBQThCLFFBQVEsRUFBQyxNQUFNLGFBQWEsQ0FBQztBQUN4RixPQUFPLEVBQUMsU0FBUyxFQUFFLFNBQVMsRUFBRSxtQkFBbUIsRUFBQyxNQUFNLFVBQVUsQ0FBQztBQUNuRSxPQUFPLEVBQTJCLG9CQUFvQixFQUFpQixNQUFNLFVBQVUsQ0FBQzs7Ozs7Ozs7Ozs7QUFNeEYsSUFBSSxjQUFjLEdBQUcsQ0FBQyxDQUFDO0FBUXZCLE1BQU0sT0FBTyxxQkFBcUI7SUE2RTlCLFlBQ2MsT0FBZ0IsRUFDVCxHQUFzQjtRQUQ3QixZQUFPLEdBQVAsT0FBTyxDQUFTO1FBQ1QsUUFBRyxHQUFILEdBQUcsQ0FBbUI7UUE5RHBDLHVCQUFrQixHQUFhLEVBQUUsQ0FBQztRQUNsQyx1QkFBa0IsR0FBYSxFQUFFLENBQUM7UUEwQ2xDLHFCQUFnQixHQUFZLEtBQUssQ0FBQztRQUlsQyxzQkFBaUIsR0FBdUIsRUFBRSxDQUFDO1FBQzNDLDZCQUF3QixHQUFZLEtBQUssQ0FBQztRQUMxQywyQkFBc0IsR0FBWSxLQUFLLENBQUM7UUFJL0MsOERBQThEO1FBQ3ZELDBCQUFxQixHQUFXLENBQUMsQ0FBQztRQUNsQyxvQkFBZSxHQUFXLENBQUMsQ0FBQztRQUM1QixtQkFBYyxHQUFXLEVBQUUsQ0FBQztRQUM1QixnQ0FBMkIsR0FB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QUMsbUJBQXlDO1FBQy9ELElBQUksbUJBQW1CLEVBQUU7WUFDckIsSUFBSSxDQUFDLG1CQUFtQixHQUFHLG1CQUFtQixDQUFDO1NBQ2xEO1FBQ0QsSUFBSSxDQUFDLEdBQUcsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUM1QixDQUFDO0lBRU8sS0FBSyxDQUFDLE1BQU0sQ0FBQyxRQUF1QjtRQUN4QyxNQUFNLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUN0QixDQUFDOztBQXR1QnVCLDZCQUFPLEdBQUcsRUFBRSxHQUFHLEtBQUssQ0FBQztBQUNyQiw0QkFBTSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQzttSEFGNUMscUJBQXFCO3VHQUFyQixxQkFBcUIscVlDN0JsQyxnb3FCQWlYQTs0RkRwVmEscUJBQXFCO2tCQU5qQyxTQUFTOytCQUNJLGVBQWUsbUJBR1IsdUJBQXVCLENBQUMsTUFBTTs4SEFPeEMsV0FBVztzQkFEakIsS0FBSztnQkFHQyxRQUFRO3NCQURkLEtBQUs7Z0JBR0MsY0FBYztzQkFEcEIsS0FBSztnQkFHQyxjQUFjO3NCQURwQixLQUFLO2dCQUdDLGNBQWM7c0JBRHBCLEtBQUs7Z0JBR0MsWUFBWTtzQkFEbEIsS0FBSztnQkFzRHlCLG1CQUFtQjtzQkFBakQsU0FBUzt1QkFBQyxrQkFBa0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICAgIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICAgIENoYW5nZURldGVjdG9yUmVmLFxuICAgIENvbXBvbmVudCxcbiAgICBFbGVtZW50UmVmLFxuICAgIElucHV0LFxuICAgIE9uQ2hhbmdlcyxcbiAgICBPbkRlc3Ryb3ksXG4gICAgU2ltcGxlQ2hhbmdlcyxcbiAgICBWaWV3Q2hpbGQsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtJb25Ub2dnbGV9IGZyb20gJ0Bpb25pYy9hbmd1bGFyJztcbmltcG9ydCB7UHJvZmlsZVNlcnZpY2V9IGZyb20gJy4uL3Byb2ZpbGUuc2VydmljZSc7XG5pbXBvcnQge0NhcnRlc2lhbk1lYXN1cmVWYWx1ZSwgUXVhbGl0eUluZGljYXRvciwgUmFpbk5vZGUsIFRlYW1Ob2RlfSBmcm9tICdyYWFpbi1tb2RlbCc7XG5pbXBvcnQge0RhdGVSYW5nZSwgTWFwTGF0TG5nLCBUaW1lZnJhbWVDb250YWluZXJzfSBmcm9tICdyYWFpbi11aSc7XG5pbXBvcnQge0NvbXBhcmVNYW5hZ2VyLCBGcmFtZVNldCwgbWFwRGF0ZVJhbmdlVG9TdHJpbmcsIFJlZnJlc2hNYW5hZ2VyfSBmcm9tICcuLi90b29scyc7XG5pbXBvcnQge1hZVHlwZX0gZnJvbSAnLi4veHl0eXBlJztcbmltcG9ydCB7UmFkYXJTZXJ2aWNlfSBmcm9tICcuLi9yYWRhci5zZXJ2aWNlJztcbmltcG9ydCB7U3RvcmFnZX0gZnJvbSAnLi4vc3RvcmFnZS5zZXJ2aWNlJztcbmltcG9ydCB7Q3VtdWxhdGl2ZVNlbGVjdGlvbn0gZnJvbSAnLi4vY3VtdWxhdGl2ZS1zZWxlY3Rvci9jdW11bGF0aXZlLXNlbGVjdG9yLmNvbXBvbmVudCc7XG5cbmxldCBURVNUX0RFVEVDVElPTiA9IDA7XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAncmFhaW4tZGV0YWlscycsXG4gICAgdGVtcGxhdGVVcmw6ICdyYWFpbi1kZXRhaWxzLmNvbXBvbmVudC5odG1sJyxcbiAgICBzdHlsZVVybHM6IFsncmFhaW4tZGV0YWlscy5jb21wb25lbnQuc2NzcyddLFxuICAgIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxufSlcbmV4cG9ydCBjbGFzcyBSYWFpbkRldGFpbHNDb21wb25lbnQgaW1wbGVtZW50cyBPbkRlc3Ryb3ksIE9uQ2hhbmdlcyB7XG4gICAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgSE9VUl9NUyA9IDYwICogNjAwMDA7XG4gICAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgREFZX01TID0gMjQgKiA2MCAqIDYwICogMTAwMDtcblxuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIHRvZ2dsZUFkbWluOiBib29sZWFuO1xuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIHJhaW5Ob2RlOiBSYWluTm9kZTtcbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBjb21wYXJlTWFuYWdlcjogQ29tcGFyZU1hbmFnZXI7XG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgcmVmcmVzaE1hbmFnZXI6IFJlZnJlc2hNYW5hZ2VyO1xuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIHByb2ZpbGVTZXJ2aWNlOiBQcm9maWxlU2VydmljZTtcbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyByYWRhclNlcnZpY2U6IFJhZGFyU2VydmljZTtcblxuICAgIHB1YmxpYyBhdmFpbGFibGVQcm92aWRlcnM6IHN0cmluZ1tdID0gW107XG4gICAgcHVibGljIGF2YWlsYWJsZVRpbWVTdGVwczogbnVtYmVyW10gPSBbXTtcbiAgICBwdWJsaWMgc2VsZWN0ZWRQcm92aWRlcjogc3RyaW5nO1xuICAgIHB1YmxpYyBzZWxlY3RlZFRpbWVTdGVwOiBudW1iZXI7XG5cbiAgICBwdWJsaWMgcGVyaW9kQmVnaW46IERhdGU7XG4gICAgcHVibGljIHBlcmlvZEVuZDogRGF0ZTtcblxuICAgIC8vIHB1YmxpYyBVSSB2YXJpYWJsZXNcbiAgICBwdWJsaWMgdGVhbU5vZGU6IFRlYW1Ob2RlO1xuICAgIHB1YmxpYyBwZXJpb2RCZWdpbkFzU3RyaW5nOiBzdHJpbmc7XG4gICAgcHVibGljIHBlcmlvZEVuZEFzU3RyaW5nOiBzdHJpbmc7XG4gICAgcHVibGljIHBlcmlvZER1cmF0aW9uQXNTdHJpbmc6IHN0cmluZztcbiAgICBwdWJsaWMgZGF0ZVNob3duOiBEYXRlO1xuICAgIHB1YmxpYyBjb29yZGluYXRlczogTWFwTGF0TG5nO1xuICAgIHB1YmxpYyBib3JkZXJzOiBNYXBMYXRMbmdbXTtcbiAgICBwdWJsaWMgdGltZWZyYW1lQ29udGFpbmVyczogVGltZWZyYW1lQ29udGFpbmVycztcbiAgICBwdWJsaWMgY3VycmVudFRpbWVmcmFtZVRhcmdldDogRnJhbWVTZXQ7XG4gICAgcHVibGljIHRpbWVmcmFtZURhdGVzOiBEYXRlW107XG4gICAgcHVibGljIGNvdW50UG9pbnRzOiB7XG4gICAgICAgIGxhYmVsOiBzdHJpbmc7XG4gICAgICAgIHN0eWxlOiBzdHJpbmc7XG4gICAgICAgIHZhbHVlczoge2RhdGU6IERhdGU7IHZhbHVlOiBudW1iZXJ9W107XG4gICAgfVtdO1xuICAgIHB1YmxpYyBjb3VudHNQZXJpb2Q6IHtcbiAgICAgICAgcGVyY2VudEltYWdlcz86IFhZVHlwZVtdO1xuICAgICAgICBxdWV1ZVJ1bm5pbmc/OiBudW1iZXI7XG4gICAgICAgIHByb2dyZXNzPzogbnVtYmVyO1xuICAgIH07XG5cbiAgICBwdWJsaWMgZ2F1Z2VTZWxlY3RlZFBvaW50czoge1xuICAgICAgICBsYWJlbDogc3RyaW5nO1xuICAgICAgICBzdHlsZTogc3RyaW5nO1xuICAgICAgICB2YWx1ZXM6IHtkYXRlOiBEYXRlOyB2YWx1ZTogbnVtYmVyfVtdO1xuICAgIH1bXTtcbiAgICBwdWJsaWMgdG9nZ2xlSGlzdG9yeTogYm9vbGVhbjtcbiAgICBwdWJsaWMgdG9nZ2xlTWFwOiBib29sZWFuO1xuICAgIHB1YmxpYyB0b2dnbGVDb21wYXJlOiBib29sZWFuO1xuICAgIHB1YmxpYyB0b2dnbGVHYXVnZU1lYXN1cmVzOiBib29sZWFuO1xuICAgIHB1YmxpYyB0b2dnbGVSZW1vdmVDb21wYXJlRHVwbGljYXRlOiBib29sZWFuO1xuICAgIHB1YmxpYyB0b2dnbGVDdW11bGF0aXZlOiBib29sZWFuO1xuICAgIHB1YmxpYyByZWZyZXNoSW5Qcm9ncmVzczogYm9vbGVhbjtcbiAgICBwdWJsaWMgc3VtRGV0YWlsczogc3RyaW5nO1xuICAgIHB1YmxpYyBzaG93UGl4ZWxNYXJrZXJzOiBib29sZWFuID0gZmFsc2U7XG4gICAgcHVibGljIGlzQWRtaW46IGJvb2xlYW47XG4gICAgcHVibGljIHNob3dGdWxsRXJyb3I6IGJvb2xlYW47XG4gICAgcHVibGljIHNob3dRdWFsaXR5TW9kYWw6IGJvb2xlYW47XG4gICAgcHVibGljIHF1YWxpdHlJbmRpY2F0b3JzOiBRdWFsaXR5SW5kaWNhdG9yW10gPSBbXTtcbiAgICBwdWJsaWMgcXVhbGl0eUluZGljYXRvcnNMb2FkaW5nOiBib29sZWFuID0gZmFsc2U7XG4gICAgcHVibGljIHNob3dDdW11bGF0aXZlU2VsZWN0b3I6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAgIEBWaWV3Q2hpbGQoJ2N1bXVsYXRpdmVUb2dnbGUnKSBjdW11bGF0aXZlVG9nZ2xlUmVmOiBJb25Ub2dnbGU7XG5cbiAgICAvLyBDYWNoZWQgY29tcHV0ZWQgdmFsdWVzICh0byBhdm9pZCBtZXRob2QgY2FsbHMgaW4gdGVtcGxhdGVzKVxuICAgIHB1YmxpYyBwZXJjZW50T2ZDb21wdXRhdGlvbnM6IG51bWJlciA9IDA7XG4gICAgcHVibGljIHBlcmNlbnRPZkltYWdlczogbnVtYmVyID0gMDtcbiAgICBwdWJsaWMgdHJ1bmNhdGVkRXJyb3I6IHN0cmluZyA9ICcnO1xuICAgIHB1YmxpYyBjdW11bGF0aXZlRHVyYXRpb25Jbk1pbnV0ZXM6IG51bWJlciA9IDEwO1xuICAgIHByb3RlY3RlZCByZWFkb25seSBEYXRlUmFuZ2UgPSBEYXRlUmFuZ2U7XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJvdGVjdGVkIHN0b3JhZ2U6IFN0b3JhZ2UsXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgY2RyOiBDaGFuZ2VEZXRlY3RvclJlZlxuICAgICkge31cblxuICAgIHByaXZhdGUgc3RhdGljIFBlcmlvZERpc3BsYXkoZGF0ZTogRGF0ZSB8IHN0cmluZykge1xuICAgICAgICBsZXQgZCA9IG5ldyBEYXRlKCk7XG4gICAgICAgIGlmIChkYXRlKSB7XG4gICAgICAgICAgICBkID0gbmV3IERhdGUoZGF0ZSk7XG4gICAgICAgICAgICBjb25zdCB1c2VyVGltZXpvbmVPZmZzZXQgPSBkLmdldFRpbWV6b25lT2Zmc2V0KCkgKiA2MDAwMDtcbiAgICAgICAgICAgIGQgPSBuZXcgRGF0ZShkLmdldFRpbWUoKSAtIHVzZXJUaW1lem9uZU9mZnNldCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZXhhbXBsZUZvcm1hdHRlZERhdGUgPSAnMjAxNy0wNi0wMVQwODozMCc7XG4gICAgICAgIHJldHVybiBkLnRvSVNPU3RyaW5nKCkuc3Vic3RyaW5nKDAsIGV4YW1wbGVGb3JtYXR0ZWREYXRlLmxlbmd0aCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdGF0aWMgRGF0ZVVUQyhkYXRlOiBzdHJpbmcpIHtcbiAgICAgICAgY29uc3QgaGFzSVNPRm9ybWF0ID0gZGF0ZS5tYXRjaCgvXlxcZHs0fS1cXGR7Mn0tXFxkezJ9VFxcZHsyfTpcXGR7Mn06XFxkezJ9XFwuXFxkezN9WiQvKTtcbiAgICAgICAgbGV0IGQgPSBuZXcgRGF0ZShkYXRlKTtcbiAgICAgICAgaWYgKCFoYXNJU09Gb3JtYXQpIHtcbiAgICAgICAgICAgIGNvbnN0IHVzZXJUaW1lem9uZU9mZnNldCA9IGQuZ2V0VGltZXpvbmVPZmZzZXQoKSAqIDYwMDAwO1xuICAgICAgICAgICAgZCA9IG5ldyBEYXRlKGQuZ2V0VGltZSgpIC0gdXNlclRpbWV6b25lT2Zmc2V0KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZDtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0YXRpYyBNYXBDb3VudFRvRGF0ZVZhbHVlKGM6IFhZVHlwZSk6IHtkYXRlOiBEYXRlOyB2YWx1ZTogbnVtYmVyfSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBkYXRlOiBSYWFpbkRldGFpbHNDb21wb25lbnQuRGF0ZVVUQyhjLm5hbWUpLFxuICAgICAgICAgICAgdmFsdWU6IE1hdGgubWluKDEwMCwgYy54KSxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBhc3luYyBvcGVuUXVhbGl0eU1vZGFsKCkge1xuICAgICAgICB0aGlzLnNob3dRdWFsaXR5TW9kYWwgPSB0cnVlO1xuICAgICAgICB0aGlzLnF1YWxpdHlJbmRpY2F0b3JzTG9hZGluZyA9IHRydWU7XG4gICAgICAgIHRoaXMucXVhbGl0eUluZGljYXRvcnMgPSBbXTtcbiAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG5cbiAgICAgICAgaWYgKHRoaXMucmFpbk5vZGU/LmlkKSB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLnByb2ZpbGVTZXJ2aWNlLmdldEluZGljYXRvcnModGhpcy5yYWluTm9kZS5pZCk7XG4gICAgICAgICAgICB0aGlzLnF1YWxpdHlJbmRpY2F0b3JzID0gcmVzdWx0LmluZGljYXRvcnM7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnF1YWxpdHlJbmRpY2F0b3JzTG9hZGluZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICB9XG5cbiAgICBjbG9zZVF1YWxpdHlNb2RhbCgpIHtcbiAgICAgICAgdGhpcy5zaG93UXVhbGl0eU1vZGFsID0gZmFsc2U7XG4gICAgfVxuXG4gICAgZm9ybWF0RGF0ZShkYXRlU3RyOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICBjb25zdCBkYXRlID0gbmV3IERhdGUoZGF0ZVN0cik7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICBkYXRlLnRvTG9jYWxlRGF0ZVN0cmluZygpICtcbiAgICAgICAgICAgICcgJyArXG4gICAgICAgICAgICBkYXRlLnRvTG9jYWxlVGltZVN0cmluZyhbXSwge2hvdXI6ICcyLWRpZ2l0JywgbWludXRlOiAnMi1kaWdpdCd9KVxuICAgICAgICApO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBmZXRjaERhdGEoZm9jdXNEYXRlOiBEYXRlLCBmb2N1c1JhbmdlOiBEYXRlUmFuZ2UpIHtcbiAgICAgICAgY29uc3QgdmFsdWVzID0gW107XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgMTA7IGkrKykge1xuICAgICAgICAgICAgdmFsdWVzLnB1c2goe2RhdGU6IG5ldyBEYXRlKDIwMjAgKyBpLCAwKSwgdmFsdWU6IDEwfSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZmFrZURhdGEgPSBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgbGFiZWw6ICclIFJhaW55JyxcbiAgICAgICAgICAgICAgICBzdHlsZTogJ2JhcicsXG4gICAgICAgICAgICAgICAgdmFsdWVzLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBsYWJlbDogJyUgSW1hZ2VzJyxcbiAgICAgICAgICAgICAgICBzdHlsZTogJ2JhcicsXG4gICAgICAgICAgICAgICAgdmFsdWVzLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIC8vICB7XG4gICAgICAgICAgICAvLyAgICAgIGxhYmVsOiAnJSBRdWFsaXR5JyxcbiAgICAgICAgICAgIC8vICAgICAgc3R5bGU6ICdsaW5lJyxcbiAgICAgICAgICAgIC8vICAgICAgdmFsdWVzLFxuICAgICAgICAgICAgLy8gIH0sXG4gICAgICAgIF07XG5cbiAgICAgICAgY29uc3QgcmFuZ2UgPSBtYXBEYXRlUmFuZ2VUb1N0cmluZyhmb2N1c1JhbmdlKTtcbiAgICAgICAgbGV0IGRhdGEgPSBmYWtlRGF0YTtcbiAgICAgICAgaWYgKCF0aGlzLnJhaW5Ob2RlKSB7XG4gICAgICAgICAgICByZXR1cm4gZGF0YTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChmb2N1c1JhbmdlID09PSBEYXRlUmFuZ2UuQ0VOVFVSWSkge1xuICAgICAgICAgICAgLy8gZmFrZVxuICAgICAgICB9IGVsc2UgaWYgKGZvY3VzUmFuZ2UgPT09IERhdGVSYW5nZS5IT1VSKSB7XG4gICAgICAgICAgICBjb25zdCBob3VyQ291bnRzID0gYXdhaXQgdGhpcy5wcm9maWxlU2VydmljZS5nZXRDb3VudHNIb3VyKHRoaXMucmFpbk5vZGUuaWQsIHtcbiAgICAgICAgICAgICAgICBwZXJpb2RCZWdpbjogZm9jdXNEYXRlLFxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGRhdGEgPSBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBsYWJlbDogJ1JhaW55IENvdW50JyxcbiAgICAgICAgICAgICAgICAgICAgc3R5bGU6ICdsaW5lJyxcbiAgICAgICAgICAgICAgICAgICAgdmFsdWVzOiBob3VyQ291bnRzLnJhaW55Q291bnQubWFwKFJhYWluRGV0YWlsc0NvbXBvbmVudC5NYXBDb3VudFRvRGF0ZVZhbHVlKSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6ICclIEltYWdlcycsXG4gICAgICAgICAgICAgICAgICAgIHN0eWxlOiAnYmFyJyxcbiAgICAgICAgICAgICAgICAgICAgdmFsdWVzOiBob3VyQ291bnRzLnBlcmNlbnRJbWFnZXMubWFwKFJhYWluRGV0YWlsc0NvbXBvbmVudC5NYXBDb3VudFRvRGF0ZVZhbHVlKSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6ICdSYWlueSBTdW0nLFxuICAgICAgICAgICAgICAgICAgICBzdHlsZTogJ2xpbmUnLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZXM6IGhvdXJDb3VudHMucmFpbnlTdW0ubWFwKFJhYWluRGV0YWlsc0NvbXBvbmVudC5NYXBDb3VudFRvRGF0ZVZhbHVlKSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGNvdW50cyA9IGF3YWl0IHRoaXMucHJvZmlsZVNlcnZpY2UuZ2V0Q291bnRzKHRoaXMucmFpbk5vZGUuaWQsIHtcbiAgICAgICAgICAgICAgICByYW5nZSxcbiAgICAgICAgICAgICAgICBwZXJpb2RCZWdpbjogZm9jdXNEYXRlLFxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGRhdGEgPSBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBsYWJlbDogJyUgUmFpbnknLFxuICAgICAgICAgICAgICAgICAgICBzdHlsZTogJ2JhcicsXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlczogY291bnRzLnBlcmNlbnRSYWlueS5tYXAoUmFhaW5EZXRhaWxzQ29tcG9uZW50Lk1hcENvdW50VG9EYXRlVmFsdWUpLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBsYWJlbDogJyUgSW1hZ2VzJyxcbiAgICAgICAgICAgICAgICAgICAgc3R5bGU6ICdiYXInLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZXM6IGNvdW50cy5wZXJjZW50SW1hZ2VzLm1hcChSYWFpbkRldGFpbHNDb21wb25lbnQuTWFwQ291bnRUb0RhdGVWYWx1ZSksXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF07XG4gICAgICAgIH1cblxuICAgICAgICAvLyBjb25zb2xlLmxvZyhgZmV0Y2hEYXRhIERPTkUgJHtyYW5nZX1gLCBkYXRhKTtcbiAgICAgICAgcmV0dXJuIGRhdGE7XG4gICAgfVxuXG4gICAgLy8gV3JhcHBlciBmdW5jdGlvbiB0aGF0IHByZXNlcnZlcyB0aGUgYXN5bmMgbmF0dXJlIG9mIGZldGNoRGF0YVxuICAgIHB1YmxpYyBmZXRjaERhdGFXcmFwcGVyID0gYXN5bmMgKGZvY3VzRGF0ZTogRGF0ZSwgZm9jdXNSYW5nZTogRGF0ZVJhbmdlKSA9PiB7XG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmZldGNoRGF0YShmb2N1c0RhdGUsIGZvY3VzUmFuZ2UpO1xuICAgIH07XG5cbiAgICBwdWJsaWMgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgICAgICB0aGlzLmNoYW5nZShjaGFuZ2VzKS50aGVuKChpZ25vcmVkKSA9PiB7fSk7XG4gICAgfVxuXG4gICAgbmdPbkRlc3Ryb3koKSB7XG4gICAgICAgIHRoaXMuY2xlYW5BbGwoKTtcbiAgICB9XG5cbiAgICBhc3luYyBvbkVuYWJsZUNvdW50SGlzdG9yeVRhYihyYWluOiBSYWluTm9kZSkge1xuICAgICAgICBpZiAoIXRoaXMudG9nZ2xlSGlzdG9yeSkge1xuICAgICAgICAgICAgdGhpcy5jb3VudFBvaW50cyA9IFtdO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgYXN5bmMgb25QZXJpb2RCZWdpbkNoYW5nZShldmVudDogYW55KSB7XG4gICAgICAgIGNvbnN0IG5ld1ZhbHVlID0gZXZlbnQ/LnRhcmdldD8udmFsdWUgPz8gdGhpcy5wZXJpb2RCZWdpbkFzU3RyaW5nO1xuICAgICAgICB0aGlzLnBlcmlvZEJlZ2luID0gbmV3IERhdGUobmV3VmFsdWUpO1xuICAgICAgICB0aGlzLnBlcmlvZEJlZ2luQXNTdHJpbmcgPSBSYWFpbkRldGFpbHNDb21wb25lbnQuUGVyaW9kRGlzcGxheSh0aGlzLnBlcmlvZEJlZ2luKTtcbiAgICAgICAgdGhpcy5zdG9yYWdlLnNldCgncmFhaW4tcGVyaW9kQmVnaW4nLCB0aGlzLnBlcmlvZEJlZ2luKTtcblxuICAgICAgICBhd2FpdCB0aGlzLm9uUGVyaW9kRHVyYXRpb25DaGFuZ2UoZXZlbnQpO1xuICAgIH1cblxuICAgIGFzeW5jIG9uUGVyaW9kRW5kQ2hhbmdlKGV2ZW50OiBhbnkpIHtcbiAgICAgICAgY29uc3QgbmV3VmFsdWUgPSBldmVudD8udGFyZ2V0Py52YWx1ZSA/PyB0aGlzLnBlcmlvZEVuZEFzU3RyaW5nO1xuICAgICAgICB0aGlzLnBlcmlvZEVuZCA9IG5ldyBEYXRlKG5ld1ZhbHVlKTtcbiAgICAgICAgdGhpcy5wZXJpb2RFbmRBc1N0cmluZyA9IFJhYWluRGV0YWlsc0NvbXBvbmVudC5QZXJpb2REaXNwbGF5KHRoaXMucGVyaW9kRW5kKTtcbiAgICAgICAgdGhpcy5zdG9yYWdlLnNldCgncmFhaW4tcGVyaW9kRW5kJywgdGhpcy5wZXJpb2RFbmQpO1xuXG4gICAgICAgIHRoaXMucGVyaW9kQmVnaW4gPSBuZXcgRGF0ZShcbiAgICAgICAgICAgIHRoaXMucGVyaW9kRW5kLmdldFRpbWUoKSAtIHRoaXMuZ2V0RHVyYXRpb25JbkhvdXJzKCkgKiBSYWFpbkRldGFpbHNDb21wb25lbnQuSE9VUl9NU1xuICAgICAgICApO1xuICAgICAgICB0aGlzLnBlcmlvZEJlZ2luQXNTdHJpbmcgPSBSYWFpbkRldGFpbHNDb21wb25lbnQuUGVyaW9kRGlzcGxheSh0aGlzLnBlcmlvZEJlZ2luKTtcbiAgICAgICAgdGhpcy5zdG9yYWdlLnNldCgncmFhaW4tcGVyaW9kQmVnaW4nLCB0aGlzLnBlcmlvZEJlZ2luKTtcbiAgICAgICAgdGhpcy51cGRhdGVSZWZyZXNoTWFuYWdlclBlcmlvZCgpO1xuICAgIH1cblxuICAgIGFzeW5jIG9uUGVyaW9kRHVyYXRpb25DaGFuZ2UoX2V2ZW50OiBvYmplY3QpIHtcbiAgICAgICAgY29uc3QgZHVyYXRpb25JbkhvdXJzID0gdGhpcy5nZXREdXJhdGlvbkluSG91cnMoKTtcbiAgICAgICAgdGhpcy5wZXJpb2RFbmQgPSBuZXcgRGF0ZShcbiAgICAgICAgICAgIHRoaXMucGVyaW9kQmVnaW4uZ2V0VGltZSgpICsgZHVyYXRpb25JbkhvdXJzICogUmFhaW5EZXRhaWxzQ29tcG9uZW50LkhPVVJfTVNcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5wZXJpb2RFbmRBc1N0cmluZyA9IFJhYWluRGV0YWlsc0NvbXBvbmVudC5QZXJpb2REaXNwbGF5KHRoaXMucGVyaW9kRW5kKTtcbiAgICAgICAgdGhpcy5zdG9yYWdlLnNldCgncmFhaW4tcGVyaW9kRW5kJywgdGhpcy5wZXJpb2RFbmQpO1xuICAgICAgICB0aGlzLnN0b3JhZ2Uuc2V0KCdyYWFpbi1wZXJpb2REdXJhdGlvbkluSG91cnMnLCBkdXJhdGlvbkluSG91cnMpO1xuICAgICAgICB0aGlzLnVwZGF0ZVJlZnJlc2hNYW5hZ2VyUGVyaW9kKCk7XG4gICAgICAgIHRoaXMudXBkYXRlQ3VtdWxhdGl2ZUR1cmF0aW9uSW5NaW51dGVzKCk7XG4gICAgfVxuXG4gICAgYXN5bmMgb25EYXRlQ2hhbmdlSW5Db3VudChkYXRlQ2hhbmdlZDogRGF0ZSkge1xuICAgICAgICBjb25zdCBkYXRlU3RyaW5nID1cbiAgICAgICAgICAgIGRhdGVDaGFuZ2VkLnRvSVNPU3RyaW5nKCkuc3Vic3RyaW5nKDAsIDExKSArXG4gICAgICAgICAgICBkYXRlQ2hhbmdlZC50b0xvY2FsZVRpbWVTdHJpbmcoKS5zdWJzdHJpbmcoMCwgNSk7XG4gICAgICAgIHRoaXMucGVyaW9kRHVyYXRpb25Bc1N0cmluZyA9ICcxJztcblxuICAgICAgICBpZiAodGhpcy50b2dnbGVDdW11bGF0aXZlKSB7XG4gICAgICAgICAgICAvLyBDdW11bGF0aXZlOiBzZWxlY3QgcGVyaW9kRW5kXG4gICAgICAgICAgICB0aGlzLnBlcmlvZEVuZEFzU3RyaW5nID0gZGF0ZVN0cmluZztcbiAgICAgICAgICAgIGF3YWl0IHRoaXMub25QZXJpb2RFbmRDaGFuZ2UobnVsbCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBHcmFudWxhcjogc2VsZWN0IHBlcmlvZEJlZ2luXG4gICAgICAgICAgICB0aGlzLnBlcmlvZEJlZ2luQXNTdHJpbmcgPSBkYXRlU3RyaW5nO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5vblBlcmlvZEJlZ2luQ2hhbmdlKG51bGwpO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHRoaXMucmVmcmVzaE1hbmFnZXIucmVmcmVzaChmYWxzZSwgdGhpcy50b2dnbGVBZG1pbik7XG4gICAgfVxuXG4gICAgYXN5bmMgb25EYXRlQ2hhbmdlSW5NYXAoZGF0ZVNob3duOiBEYXRlKSB7XG4gICAgICAgIHRoaXMuZGF0ZVNob3duID0gZGF0ZVNob3duO1xuICAgICAgICBhd2FpdCB0aGlzLmZldGNoQW5kVXBkYXRlTWFwKCk7XG4gICAgICAgIGF3YWl0IHRoaXMucmVmcmVzaE1hbmFnZXIuc2V0UmVwb3J0UGVyaW9kKHRoaXMuZGF0ZVNob3duKTtcbiAgICB9XG5cbiAgICBhc3luYyBvblN1bUNoYW5nZUluTWFwKHN1bTogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMuc3VtRGV0YWlscyA9IHN1bTtcbiAgICB9XG5cbiAgICBhc3luYyBvbkdhdWdlU2VsZWN0SW5NYXAobWFwTGF0TG5nOiBNYXBMYXRMbmcpIHtcbiAgICAgICAgY29uc3QgZ2F1Z2VzRmlsdGVyZWQgPSB0aGlzLmNvbXBhcmVNYW5hZ2VyLmdhdWdlc0luTWFwLmZpbHRlcihcbiAgICAgICAgICAgIChnKSA9PiBnLmxhdCA9PT0gbWFwTGF0TG5nLmxhdCAmJiBnLmxuZyA9PT0gbWFwTGF0TG5nLmxuZ1xuICAgICAgICApO1xuICAgICAgICBpZiAoZ2F1Z2VzRmlsdGVyZWQubGVuZ3RoICE9PSAxKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZ2F1Z2VTZWxlY3RlZCA9IGdhdWdlc0ZpbHRlcmVkWzBdO1xuXG4gICAgICAgIGF3YWl0IHRoaXMucmVmcmVzaEdhdWdlVmFsdWVzKHtpZDogZ2F1Z2VTZWxlY3RlZC5pZCwgbmFtZTogZ2F1Z2VTZWxlY3RlZC5uYW1lfSk7XG5cbiAgICAgICAgYXdhaXQgdGhpcy5jb21wYXJlTWFuYWdlci5zZWxlY3RHYXVnZShnYXVnZVNlbGVjdGVkLmlkLCAwKTtcbiAgICB9XG5cbiAgICBhc3luYyByZWZyZXNoR2F1Z2VWYWx1ZXMoZ2F1Z2VTZWxlY3RlZDoge2lkOiBzdHJpbmc7IG5hbWU6IHN0cmluZ30pIHtcbiAgICAgICAgY29uc3QgZ2F1Z2VWYWx1ZVNob3dCZWdpbiA9IG5ldyBEYXRlKFxuICAgICAgICAgICAgdGhpcy5wZXJpb2RCZWdpbi5nZXRUaW1lKCkgLSBSYWFpbkRldGFpbHNDb21wb25lbnQuREFZX01TXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IGdhdWdlVmFsdWVTaG93RW5kID0gbmV3IERhdGUodGhpcy5wZXJpb2RFbmQuZ2V0VGltZSgpICsgUmFhaW5EZXRhaWxzQ29tcG9uZW50LkRBWV9NUyk7XG4gICAgICAgIGdhdWdlVmFsdWVTaG93QmVnaW4uc2V0SG91cnMoMCwgMCk7XG4gICAgICAgIGdhdWdlVmFsdWVTaG93RW5kLnNldEhvdXJzKDIzLCA1OSk7XG5cbiAgICAgICAgY29uc3QgZ2F1Z2VNZWFzdXJlcyA9IGF3YWl0IHRoaXMucHJvZmlsZVNlcnZpY2UuZ2V0R2F1Z2VNZWFzdXJlcyhcbiAgICAgICAgICAgIGdhdWdlU2VsZWN0ZWQuaWQsXG4gICAgICAgICAgICBnYXVnZVZhbHVlU2hvd0JlZ2luLFxuICAgICAgICAgICAgZ2F1Z2VWYWx1ZVNob3dFbmRcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3QgZ2F1Z2VWYWx1ZXM6IHtkYXRlOiBEYXRlOyB2YWx1ZTogbnVtYmVyfVtdID0gZ2F1Z2VNZWFzdXJlcy5tYXAoKGdtKSA9PiB7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICAgICAgICAgY29uc3QgY2FydGVzaWFuTWVhc3VyZVZhbHVlID0gbmV3IENhcnRlc2lhbk1lYXN1cmVWYWx1ZShnbS52YWx1ZXNbMF0gYXMgYW55KTtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgZGF0ZTogZ20uZGF0ZSxcbiAgICAgICAgICAgICAgICB2YWx1ZTogY2FydGVzaWFuTWVhc3VyZVZhbHVlLmdldENhcnRlc2lhblZhbHVlcygpWzBdLnZhbHVlLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZ2F1Z2VTZWxlY3RlZFBvaW50cyA9IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBsYWJlbDogZ2F1Z2VTZWxlY3RlZC5uYW1lLFxuICAgICAgICAgICAgICAgIHN0eWxlOiAnYmFyJyxcbiAgICAgICAgICAgICAgICB2YWx1ZXM6IGdhdWdlVmFsdWVzLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgXTtcbiAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfVxuXG4gICAgYXN5bmMgb25HYXVnZVNlbGVjdEluQ29tcGFyZShlOiB7cG9pbnQ6IFhZVHlwZTsgY29tcGFyZUluZGV4OiBudW1iZXJ9KSB7XG4gICAgICAgIGF3YWl0IHRoaXMucmVmcmVzaEdhdWdlVmFsdWVzKHtpZDogZS5wb2ludC5pZCwgbmFtZTogZS5wb2ludC5uYW1lfSk7XG5cbiAgICAgICAgYXdhaXQgdGhpcy5jb21wYXJlTWFuYWdlci5zZWxlY3RHYXVnZShlLnBvaW50LmlkLCBlLmNvbXBhcmVJbmRleCk7XG4gICAgfVxuXG4gICAgYXN5bmMgb25Ub2dnbGVNYXAoJGV2ZW50OiBFdmVudCkge1xuICAgICAgICAvLyBpZiAodGhpcy50b2dnbGVNYXApIHtcbiAgICAgICAgLy8gICAgYXdhaXQgdGhpcy5yZWZyZXNoTWFwKCk7XG4gICAgICAgIC8vIH1cbiAgICB9XG5cbiAgICBvblRvZ2dsZVBpeGVsTWFya2VycygpIHtcbiAgICAgICAgLy8gVG9nZ2xlIGlzIGJvdW5kIHRvIHNob3dQaXhlbE1hcmtlcnMsIHJhYWluLW1hcCBoYW5kbGVzIG1hcmtlciBkaXNwbGF5XG4gICAgfVxuXG4gICAgYXN5bmMgb25DdW11bGF0aXZlVG9nZ2xlQ2xpY2soJGV2ZW50OiBFdmVudCkge1xuICAgICAgICBjb25zb2xlLmxvZygnW0N1bXVsYXRpdmVUb2dnbGVdIGNsaWNrIGV2ZW50Jywge1xuICAgICAgICAgICAgY3VycmVudFZhbHVlOiB0aGlzLnRvZ2dsZUN1bXVsYXRpdmUsXG4gICAgICAgICAgICBldmVudFR5cGU6ICRldmVudC50eXBlLFxuICAgICAgICAgICAgdGFyZ2V0OiAoJGV2ZW50LnRhcmdldCBhcyBIVE1MRWxlbWVudCk/LnRhZ05hbWUsXG4gICAgICAgIH0pO1xuXG4gICAgICAgICRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG5cbiAgICAgICAgaWYgKCF0aGlzLnRvZ2dsZUN1bXVsYXRpdmUpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdbQ3VtdWxhdGl2ZVRvZ2dsZV0gc2hvd2luZyBwb3B1cCwgdG9nZ2xlIHN0YXlzIE9GRicpO1xuICAgICAgICAgICAgLy8gQ3VycmVudGx5IE9GRiwgdXNlciB3YW50cyB0byBlbmFibGUgLSBzaG93IHNlbGVjdG9yIHBvcHVwXG4gICAgICAgICAgICB0aGlzLnNob3dDdW11bGF0aXZlU2VsZWN0b3IgPSB0cnVlO1xuXG4gICAgICAgICAgICAvLyBGb3JjZSByZXNldCB0aGUgdG9nZ2xlIHZpc3VhbCBzdGF0ZSBhZnRlciBpb24tdG9nZ2xlJ3MgaW50ZXJuYWwgaGFuZGxlclxuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuY3VtdWxhdGl2ZVRvZ2dsZVJlZikge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmN1bXVsYXRpdmVUb2dnbGVSZWYuY2hlY2tlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnW0N1bXVsYXRpdmVUb2dnbGVdIGZvcmNlIHJlc2V0IHRvZ2dsZSB0byBPRkYnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LCAwKTtcblxuICAgICAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZygnW0N1bXVsYXRpdmVUb2dnbGVdIHR1cm5pbmcgT0ZGJyk7XG4gICAgICAgICAgICAvLyBDdXJyZW50bHkgT04sIHVzZXIgd2FudHMgdG8gZGlzYWJsZSAtIGRpcmVjdCB0b2dnbGUgb2ZmXG4gICAgICAgICAgICB0aGlzLnRvZ2dsZUN1bXVsYXRpdmUgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuc3RvcmFnZS5zZXQoJ3JhYWluLXRvZ2dsZUN1bXVsYXRpdmUnLCBmYWxzZSk7XG4gICAgICAgICAgICB0aGlzLmRhdGVTaG93biA9IHRoaXMuZ2V0RGF0ZUJhc2VkT25DdW11bGF0aXZlTW9kZSh0aGlzLnRpbWVmcmFtZURhdGVzKTtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlQ3VtdWxhdGl2ZUR1cmF0aW9uSW5NaW51dGVzKCk7XG4gICAgICAgICAgICBpZiAodGhpcy50b2dnbGVNYXApIHtcbiAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZVJlZnJlc2hNYW5hZ2VyUGVyaW9kKCk7XG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5yZWZyZXNoTWFuYWdlci5yZWZyZXNoKGZhbHNlLCB0aGlzLnRvZ2dsZUFkbWluKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnNvbGUubG9nKCdbQ3VtdWxhdGl2ZVRvZ2dsZV0gYWZ0ZXIgaGFuZGxlciwgdG9nZ2xlQ3VtdWxhdGl2ZSA9JywgdGhpcy50b2dnbGVDdW11bGF0aXZlKTtcbiAgICB9XG5cbiAgICBhc3luYyBvbkN1bXVsYXRpdmVQZXJpb2RTZWxlY3RlZChzZWxlY3Rpb246IEN1bXVsYXRpdmVTZWxlY3Rpb24pIHtcbiAgICAgICAgdGhpcy5zaG93Q3VtdWxhdGl2ZVNlbGVjdG9yID0gZmFsc2U7XG5cbiAgICAgICAgLy8gVXBkYXRlIHBlcmlvZCB0byBtYXRjaCBzZWxlY3Rpb25cbiAgICAgICAgdGhpcy5wZXJpb2RCZWdpbiA9IHNlbGVjdGlvbi5wZXJpb2RCZWdpbjtcbiAgICAgICAgdGhpcy5wZXJpb2RFbmQgPSBzZWxlY3Rpb24ucGVyaW9kRW5kO1xuICAgICAgICB0aGlzLnBlcmlvZEJlZ2luQXNTdHJpbmcgPSBSYWFpbkRldGFpbHNDb21wb25lbnQuUGVyaW9kRGlzcGxheSh0aGlzLnBlcmlvZEJlZ2luKTtcbiAgICAgICAgdGhpcy5wZXJpb2RFbmRBc1N0cmluZyA9IFJhYWluRGV0YWlsc0NvbXBvbmVudC5QZXJpb2REaXNwbGF5KHRoaXMucGVyaW9kRW5kKTtcblxuICAgICAgICAvLyBDYWxjdWxhdGUgZHVyYXRpb24gaW4gaG91cnNcbiAgICAgICAgY29uc3QgZHVyYXRpb25NcyA9IHRoaXMucGVyaW9kRW5kLmdldFRpbWUoKSAtIHRoaXMucGVyaW9kQmVnaW4uZ2V0VGltZSgpO1xuICAgICAgICBjb25zdCBkdXJhdGlvbkhvdXJzID0gZHVyYXRpb25NcyAvIFJhYWluRGV0YWlsc0NvbXBvbmVudC5IT1VSX01TO1xuICAgICAgICB0aGlzLnBlcmlvZER1cmF0aW9uQXNTdHJpbmcgPSBTdHJpbmcoZHVyYXRpb25Ib3Vycyk7XG5cbiAgICAgICAgLy8gU3RvcmUgY3VtdWxhdGl2ZSBwZXJpb2RcbiAgICAgICAgdGhpcy5zdG9yYWdlLnNldCgncmFhaW4tcGVyaW9kQmVnaW4nLCB0aGlzLnBlcmlvZEJlZ2luKTtcbiAgICAgICAgdGhpcy5zdG9yYWdlLnNldCgncmFhaW4tcGVyaW9kRW5kJywgdGhpcy5wZXJpb2RFbmQpO1xuICAgICAgICB0aGlzLnN0b3JhZ2Uuc2V0KCdyYWFpbi1wZXJpb2REdXJhdGlvbkluSG91cnMnLCBkdXJhdGlvbkhvdXJzKTtcblxuICAgICAgICAvLyBFbmFibGUgY3VtdWxhdGl2ZSBtb2RlXG4gICAgICAgIHRoaXMudG9nZ2xlQ3VtdWxhdGl2ZSA9IHRydWU7XG4gICAgICAgIHRoaXMuc3RvcmFnZS5zZXQoJ3JhYWluLXRvZ2dsZUN1bXVsYXRpdmUnLCB0cnVlKTtcblxuICAgICAgICB0aGlzLmRhdGVTaG93biA9IHRoaXMuZ2V0RGF0ZUJhc2VkT25DdW11bGF0aXZlTW9kZSh0aGlzLnRpbWVmcmFtZURhdGVzKTtcbiAgICAgICAgdGhpcy51cGRhdGVDdW11bGF0aXZlRHVyYXRpb25Jbk1pbnV0ZXMoKTtcblxuICAgICAgICAvLyBSZWZyZXNoIG1hcFxuICAgICAgICBpZiAodGhpcy50b2dnbGVNYXApIHtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlUmVmcmVzaE1hbmFnZXJQZXJpb2QoKTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMucmVmcmVzaE1hbmFnZXIucmVmcmVzaChmYWxzZSwgdGhpcy50b2dnbGVBZG1pbik7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICB9XG5cbiAgICBvbkN1bXVsYXRpdmVTZWxlY3RvckNhbmNlbGxlZCgpIHtcbiAgICAgICAgY29uc29sZS5sb2coJ1tDdW11bGF0aXZlVG9nZ2xlXSBjYW5jZWxsZWQsIHRvZ2dsZUN1bXVsYXRpdmUgPScsIHRoaXMudG9nZ2xlQ3VtdWxhdGl2ZSk7XG4gICAgICAgIHRoaXMuc2hvd0N1bXVsYXRpdmVTZWxlY3RvciA9IGZhbHNlO1xuICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICB9XG5cbiAgICB1cGRhdGVDdW11bGF0aXZlRHVyYXRpb25Jbk1pbnV0ZXMoKSB7XG4gICAgICAgIGlmICh0aGlzLnRvZ2dsZUN1bXVsYXRpdmUpIHtcbiAgICAgICAgICAgIC8vIEN1bXVsYXRpdmUgbW9kZTogdXNlIHBlcmlvZCBkdXJhdGlvblxuICAgICAgICAgICAgdGhpcy5jdW11bGF0aXZlRHVyYXRpb25Jbk1pbnV0ZXMgPSBwYXJzZUZsb2F0KHRoaXMucGVyaW9kRHVyYXRpb25Bc1N0cmluZykgKiA2MDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIEdyYW51bGFyIG1vZGU6IHVzZSBzZWxlY3RlZFRpbWVTdGVwXG4gICAgICAgICAgICB0aGlzLmN1bXVsYXRpdmVEdXJhdGlvbkluTWludXRlcyA9IHRoaXMuc2VsZWN0ZWRUaW1lU3RlcCB8fCAxMDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFzeW5jIG9uUHJvdmlkZXJDaGFuZ2VkKCRldmVudDogRXZlbnQpIHtcbiAgICAgICAgdGhpcy5zZWxlY3RlZFByb3ZpZGVyID0gKCRldmVudCBhcyBDdXN0b21FdmVudCk/LmRldGFpbD8udmFsdWU7XG4gICAgICAgIHRoaXMuc3RvcmFnZS5zZXQoJ3JhYWluLXNlbGVjdGVkUHJvdmlkZXInLCB0aGlzLnNlbGVjdGVkUHJvdmlkZXIpO1xuICAgICAgICBhd2FpdCB0aGlzLmFwcGx5UmVmcmVzaE1hbmFnZXJTZXR0aW5ncygpO1xuICAgIH1cblxuICAgIGFzeW5jIG9uVGltZVN0ZXBDaGFuZ2VkKCRldmVudDogRXZlbnQpIHtcbiAgICAgICAgdGhpcy5zZWxlY3RlZFRpbWVTdGVwID0gKCRldmVudCBhcyBDdXN0b21FdmVudCk/LmRldGFpbD8udmFsdWU7XG4gICAgICAgIHRoaXMuc3RvcmFnZS5zZXQoJ3JhYWluLXNlbGVjdGVkVGltZVN0ZXAnLCB0aGlzLnNlbGVjdGVkVGltZVN0ZXApO1xuICAgICAgICB0aGlzLnVwZGF0ZUN1bXVsYXRpdmVEdXJhdGlvbkluTWludXRlcygpO1xuICAgICAgICBhd2FpdCB0aGlzLmFwcGx5UmVmcmVzaE1hbmFnZXJTZXR0aW5ncygpO1xuICAgIH1cblxuICAgIGFzeW5jIGxvYWRQcm92aWRlcnMoKSB7XG4gICAgICAgIGlmICghdGhpcy5yYWluTm9kZT8uaWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLnByb2ZpbGVTZXJ2aWNlLmdldFByb3ZpZGVycyh0aGlzLnJhaW5Ob2RlLmlkKTtcbiAgICAgICAgICAgIHRoaXMuYXZhaWxhYmxlUHJvdmlkZXJzID0gcmVzdWx0LnByb3ZpZGVycztcbiAgICAgICAgICAgIHRoaXMuYXZhaWxhYmxlVGltZVN0ZXBzID0gcmVzdWx0LnRpbWVTdGVwSW5NaW51dGVzO1xuXG4gICAgICAgICAgICAvLyBMb2FkIHNhdmVkIHNlbGVjdGlvbnMgb3IgdXNlIGRlZmF1bHRzXG4gICAgICAgICAgICB0aGlzLnNlbGVjdGVkUHJvdmlkZXIgPVxuICAgICAgICAgICAgICAgIHRoaXMuc3RvcmFnZS5nZXQoJ3JhYWluLXNlbGVjdGVkUHJvdmlkZXInKSB8fFxuICAgICAgICAgICAgICAgICh0aGlzLmF2YWlsYWJsZVByb3ZpZGVycy5sZW5ndGggPiAwID8gdGhpcy5hdmFpbGFibGVQcm92aWRlcnNbMF0gOiAnUmFhaW4nKTtcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRUaW1lU3RlcCA9XG4gICAgICAgICAgICAgICAgdGhpcy5zdG9yYWdlLmdldCgncmFhaW4tc2VsZWN0ZWRUaW1lU3RlcCcpIHx8XG4gICAgICAgICAgICAgICAgKHRoaXMuYXZhaWxhYmxlVGltZVN0ZXBzLmxlbmd0aCA+IDAgPyB0aGlzLmF2YWlsYWJsZVRpbWVTdGVwc1swXSA6IDEwKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgLy8gU2V0IGZhbGxiYWNrIHZhbHVlc1xuICAgICAgICAgICAgdGhpcy5hdmFpbGFibGVQcm92aWRlcnMgPSBbJ1JhYWluJ107XG4gICAgICAgICAgICB0aGlzLmF2YWlsYWJsZVRpbWVTdGVwcyA9IFs1LCAxMCwgMTUsIDMwLCA2MF07XG4gICAgICAgICAgICB0aGlzLnNlbGVjdGVkUHJvdmlkZXIgPSAnUmFhaW4nO1xuICAgICAgICAgICAgdGhpcy5zZWxlY3RlZFRpbWVTdGVwID0gMTA7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXQgcHJvdmlkZXIgYW5kIHRpbWVTdGVwIG9uIHJlZnJlc2hNYW5hZ2VyXG4gICAgICAgIGlmICh0aGlzLnJlZnJlc2hNYW5hZ2VyKSB7XG4gICAgICAgICAgICB0aGlzLnJlZnJlc2hNYW5hZ2VyLnByb3ZpZGVyID0gdGhpcy5zZWxlY3RlZFByb3ZpZGVyO1xuICAgICAgICAgICAgdGhpcy5yZWZyZXNoTWFuYWdlci50aW1lU3RlcEluTWludXRlcyA9IHRoaXMuc2VsZWN0ZWRUaW1lU3RlcDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICB9XG5cbiAgICBvbkNoYW5nZURldGVjdGlvblRlc3QocmFpbk5vZGU6IFJhaW5Ob2RlKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKFRFU1RfREVURUNUSU9OKyssICdvbkNoYW5nZURldGVjdGlvblRlc3QnKTtcbiAgICAgICAgcmV0dXJuICcnO1xuICAgIH1cblxuICAgIHVwZGF0ZVRydW5jYXRlZEVycm9yKCkge1xuICAgICAgICBjb25zdCBlcnJvciA9IHRoaXMucmVmcmVzaE1hbmFnZXI/Lmxhc3RFcnJvciB8fCAnJztcbiAgICAgICAgaWYgKGVycm9yLmxlbmd0aCA8PSA4MCkge1xuICAgICAgICAgICAgdGhpcy50cnVuY2F0ZWRFcnJvciA9IGVycm9yO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudHJ1bmNhdGVkRXJyb3IgPSBlcnJvci5zdWJzdHJpbmcoMCwgODApICsgJy4uLic7XG4gICAgfVxuXG4gICAgdXBkYXRlQ2FjaGVkVmFsdWVzKCkge1xuICAgICAgICB0aGlzLnVwZGF0ZVBlcmNlbnRPZkltYWdlcygpO1xuICAgICAgICB0aGlzLnVwZGF0ZVBlcmNlbnRPZkNvbXB1dGF0aW9ucygpO1xuICAgICAgICB0aGlzLnVwZGF0ZVRydW5jYXRlZEVycm9yKCk7XG4gICAgICAgIHRoaXMudXBkYXRlQ3VtdWxhdGl2ZUR1cmF0aW9uSW5NaW51dGVzKCk7XG4gICAgfVxuXG4gICAgYXN5bmMgcmVmcmVzaE1hcCgpIHtcbiAgICAgICAgdGhpcy5nYXVnZVNlbGVjdGVkUG9pbnRzID0gW107XG4gICAgICAgIHRoaXMuZGF0ZVNob3duID0gdGhpcy5nZXREYXRlQmFzZWRPbkN1bXVsYXRpdmVNb2RlKCk7XG4gICAgICAgIHRoaXMuYm9yZGVycyA9IFtdO1xuXG4gICAgICAgIHRoaXMuY29tcGFyZU1hbmFnZXIuY2xlYW5BbGwoKTtcbiAgICAgICAgYXdhaXQgdGhpcy5jb21wYXJlTWFuYWdlci5zZXRHYXVnZXNJbk1hcCgpO1xuICAgICAgICBhd2FpdCB0aGlzLnJlZnJlc2hNYW5hZ2VyLnJlZnJlc2goZmFsc2UsIHRoaXMudG9nZ2xlQWRtaW4pO1xuICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICB9XG5cbiAgICBhc3luYyBzZXRQZXJpb2RPZk5vdygpIHtcbiAgICAgICAgY29uc3QgbGFzdDMwbW4gPSBuZXcgRGF0ZSgpO1xuICAgICAgICBsYXN0MzBtbi5zZXRNaW51dGVzKGxhc3QzMG1uLmdldE1pbnV0ZXMoKSAtIDMwKTtcbiAgICAgICAgdGhpcy5wZXJpb2RCZWdpbkFzU3RyaW5nID1cbiAgICAgICAgICAgIGxhc3QzMG1uLnRvSVNPU3RyaW5nKCkuc3Vic3RyaW5nKDAsIDExKSArIGxhc3QzMG1uLnRvTG9jYWxlVGltZVN0cmluZygpLnN1YnN0cmluZygwLCA1KTtcbiAgICAgICAgdGhpcy5wZXJpb2REdXJhdGlvbkFzU3RyaW5nID0gJzEnO1xuICAgICAgICBhd2FpdCB0aGlzLm9uUGVyaW9kQmVnaW5DaGFuZ2UobnVsbCk7XG4gICAgICAgIGF3YWl0IHRoaXMucmVmcmVzaE1hbmFnZXIucmVmcmVzaChmYWxzZSwgdGhpcy50b2dnbGVBZG1pbik7XG4gICAgfVxuXG4gICAgdXBkYXRlUGVyY2VudE9mSW1hZ2VzKCkge1xuICAgICAgICBpZiAoIXRoaXMuY291bnRzUGVyaW9kPy5wZXJjZW50SW1hZ2VzPy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRoaXMucGVyY2VudE9mSW1hZ2VzID0gMDtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGR1cmluZ1BlcmlvZCA9IHRoaXMuY291bnRzUGVyaW9kLnBlcmNlbnRJbWFnZXMuZmlsdGVyKFxuICAgICAgICAgICAgKGEpID0+XG4gICAgICAgICAgICAgICAgdGhpcy5wZXJpb2RCZWdpbi5nZXRUaW1lKCkgPD0gbmV3IERhdGUoYS5uYW1lKS5nZXRUaW1lKCkgJiZcbiAgICAgICAgICAgICAgICBuZXcgRGF0ZShhLm5hbWUpLmdldFRpbWUoKSA8PSB0aGlzLnBlcmlvZEVuZC5nZXRUaW1lKClcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3Qgc3VtbWVkID0gZHVyaW5nUGVyaW9kLnJlZHVjZSgoYSwgYikgPT4gYSArIChiLnggPz8gMCksIDApO1xuICAgICAgICB0aGlzLnBlcmNlbnRPZkltYWdlcyA9IE1hdGgucm91bmQoc3VtbWVkIC8gZHVyaW5nUGVyaW9kLmxlbmd0aCk7XG4gICAgfVxuXG4gICAgdXBkYXRlUGVyY2VudE9mQ29tcHV0YXRpb25zKCkge1xuICAgICAgICBjb25zdCB0aW1lbGluZSA9IHRoaXMucmVmcmVzaE1hbmFnZXI/LmdldFRpbWVsaW5lRnJhbWVTZXQoKTtcbiAgICAgICAgaWYgKCF0aW1lbGluZT8ubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aGlzLnBlcmNlbnRPZkNvbXB1dGF0aW9ucyA9IDA7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB0aW1lbGluZVdpdGhDb21wdXRhdGlvbiA9IHRpbWVsaW5lLmZpbHRlcihcbiAgICAgICAgICAgIChhKSA9PiAhIWEucmFpbkNvbXB1dGF0aW9uQ3VtdWxhdGl2ZUlkIHx8ICEhYS5yYWluQ29tcHV0YXRpb25JZFxuICAgICAgICApO1xuICAgICAgICBjb25zdCByYXRpbyA9IHRpbWVsaW5lV2l0aENvbXB1dGF0aW9uLmxlbmd0aCAvIHRpbWVsaW5lLmxlbmd0aDtcbiAgICAgICAgdGhpcy5wZXJjZW50T2ZDb21wdXRhdGlvbnMgPSBNYXRoLnJvdW5kKHJhdGlvICogMTAwKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldERhdGVCYXNlZE9uQ3VtdWxhdGl2ZU1vZGUoZmFsbGJhY2tEYXRlcz86IERhdGVbXSk6IERhdGUge1xuICAgICAgICBpZiAoZmFsbGJhY2tEYXRlcz8ubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgY29uc3QgZGF0ZUV4aXN0cyA9IGZhbGxiYWNrRGF0ZXMuc29tZSgoZCkgPT4gZC5nZXRUaW1lKCkgPT09IHRoaXMuZGF0ZVNob3duPy5nZXRUaW1lKCkpO1xuICAgICAgICAgICAgaWYgKCFkYXRlRXhpc3RzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMudG9nZ2xlQ3VtdWxhdGl2ZVxuICAgICAgICAgICAgICAgICAgICA/IGZhbGxiYWNrRGF0ZXNbZmFsbGJhY2tEYXRlcy5sZW5ndGggLSAxXVxuICAgICAgICAgICAgICAgICAgICA6IGZhbGxiYWNrRGF0ZXNbMF07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMudG9nZ2xlQ3VtdWxhdGl2ZSA/IHRoaXMucGVyaW9kRW5kIDogdGhpcy5wZXJpb2RCZWdpbjtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldEN1bXVsYXRpdmVIb3VycygpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gdGhpcy50b2dnbGVDdW11bGF0aXZlID8gcGFyc2VGbG9hdCh0aGlzLnBlcmlvZER1cmF0aW9uQXNTdHJpbmcpIDogMDtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldER1cmF0aW9uSW5Ib3VycygpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gcGFyc2VGbG9hdCh0aGlzLnBlcmlvZER1cmF0aW9uQXNTdHJpbmcpO1xuICAgIH1cblxuICAgIHByaXZhdGUgdXBkYXRlUmVmcmVzaE1hbmFnZXJQZXJpb2QoKSB7XG4gICAgICAgIHRoaXMucmVmcmVzaE1hbmFnZXIuY3VtdWxhdGl2ZSA9IHRoaXMudG9nZ2xlQ3VtdWxhdGl2ZTtcblxuICAgICAgICAvLyBBbGlnbiBkYXRlcyB0byA1LW1pbnV0ZSBib3VuZGFyaWVzIChmbG9vcikgZm9yIGNvbnNpc3RlbmN5IHdpdGggcmFhaW4tZ3JvdW5kXG4gICAgICAgIGNvbnN0IGFsaWduVG81bWluRmxvb3IgPSAoZGF0ZTogRGF0ZSk6IERhdGUgPT4ge1xuICAgICAgICAgICAgY29uc3QgbWludXRlcyA9IGRhdGUuZ2V0TWludXRlcygpO1xuICAgICAgICAgICAgY29uc3QgYWxpZ25lZE1pbnV0ZXMgPSBNYXRoLmZsb29yKG1pbnV0ZXMgLyA1KSAqIDU7XG4gICAgICAgICAgICByZXR1cm4gbmV3IERhdGUoXG4gICAgICAgICAgICAgICAgZGF0ZS5nZXRGdWxsWWVhcigpLFxuICAgICAgICAgICAgICAgIGRhdGUuZ2V0TW9udGgoKSxcbiAgICAgICAgICAgICAgICBkYXRlLmdldERhdGUoKSxcbiAgICAgICAgICAgICAgICBkYXRlLmdldEhvdXJzKCksXG4gICAgICAgICAgICAgICAgYWxpZ25lZE1pbnV0ZXMsXG4gICAgICAgICAgICAgICAgMCxcbiAgICAgICAgICAgICAgICAwXG4gICAgICAgICAgICApO1xuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMucmVmcmVzaE1hbmFnZXIucGVyaW9kID0ge1xuICAgICAgICAgICAgYmVnaW46IGFsaWduVG81bWluRmxvb3IodGhpcy5wZXJpb2RCZWdpbiksXG4gICAgICAgICAgICBlbmQ6IGFsaWduVG81bWluRmxvb3IodGhpcy5wZXJpb2RFbmQpLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgZmV0Y2hBbmRVcGRhdGVNYXAoKSB7XG4gICAgICAgIGF3YWl0IHRoaXMucmVmcmVzaE1hbmFnZXIuZmV0Y2goXG4gICAgICAgICAgICB0aGlzLmRhdGVTaG93bixcbiAgICAgICAgICAgIHRoaXMudG9nZ2xlR2F1Z2VNZWFzdXJlcyxcbiAgICAgICAgICAgIHRoaXMuZ2V0Q3VtdWxhdGl2ZUhvdXJzKClcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5jdXJyZW50VGltZWZyYW1lVGFyZ2V0ID0gdGhpcy5yZWZyZXNoTWFuYWdlci5nZXRUaW1lbGluZVNlbGVjdGVkRnJhbWVTZXQoKTtcbiAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBhcHBseVJlZnJlc2hNYW5hZ2VyU2V0dGluZ3MoKSB7XG4gICAgICAgIGlmICghdGhpcy5yZWZyZXNoTWFuYWdlcikge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucmVmcmVzaE1hbmFnZXIucHJvdmlkZXIgPSB0aGlzLnNlbGVjdGVkUHJvdmlkZXI7XG4gICAgICAgIHRoaXMucmVmcmVzaE1hbmFnZXIudGltZVN0ZXBJbk1pbnV0ZXMgPSB0aGlzLnNlbGVjdGVkVGltZVN0ZXA7XG4gICAgICAgIGF3YWl0IHRoaXMucmVmcmVzaE1hbmFnZXIucmVmcmVzaChmYWxzZSwgdGhpcy50b2dnbGVBZG1pbik7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjbGVhbkFsbCgpIHtcbiAgICAgICAgdGhpcy5ib3JkZXJzID0gW107XG4gICAgICAgIHRoaXMuaXNBZG1pbiA9IGZhbHNlO1xuICAgICAgICB0aGlzLnRpbWVmcmFtZUNvbnRhaW5lcnMgPSBuZXcgVGltZWZyYW1lQ29udGFpbmVycyhbXSk7XG4gICAgICAgIHRoaXMuY3VycmVudFRpbWVmcmFtZVRhcmdldCA9IG51bGw7XG4gICAgICAgIHRoaXMudGltZWZyYW1lRGF0ZXMgPSBbXTtcbiAgICAgICAgdGhpcy5jb3VudFBvaW50cyA9IFtdO1xuICAgICAgICB0aGlzLmNvdW50c1BlcmlvZCA9IHtwcm9ncmVzczogMCwgcXVldWVSdW5uaW5nOiAwLCBwZXJjZW50SW1hZ2VzOiBbXX07XG4gICAgICAgIHRoaXMuZ2F1Z2VTZWxlY3RlZFBvaW50cyA9IFtdO1xuXG4gICAgICAgIHRoaXMudG9nZ2xlSGlzdG9yeSA9IGZhbHNlO1xuICAgICAgICB0aGlzLnRvZ2dsZU1hcCA9IHRydWU7XG4gICAgICAgIHRoaXMudG9nZ2xlQ29tcGFyZSA9IGZhbHNlO1xuICAgICAgICB0aGlzLnRvZ2dsZUdhdWdlTWVhc3VyZXMgPSBmYWxzZTtcbiAgICAgICAgdGhpcy50b2dnbGVSZW1vdmVDb21wYXJlRHVwbGljYXRlID0gdHJ1ZTtcbiAgICAgICAgdGhpcy50b2dnbGVDdW11bGF0aXZlID0gdGhpcy5zdG9yYWdlLmdldCgncmFhaW4tdG9nZ2xlQ3VtdWxhdGl2ZScpO1xuXG4gICAgICAgIHRoaXMucGVyaW9kQmVnaW4gPSBuZXcgRGF0ZSh0aGlzLnN0b3JhZ2UuZ2V0KCdyYWFpbi1wZXJpb2RCZWdpbicpKTtcbiAgICAgICAgdGhpcy5wZXJpb2RFbmQgPSBuZXcgRGF0ZSh0aGlzLnN0b3JhZ2UuZ2V0KCdyYWFpbi1wZXJpb2RFbmQnKSk7XG4gICAgICAgIHRoaXMucGVyaW9kQmVnaW5Bc1N0cmluZyA9IFJhYWluRGV0YWlsc0NvbXBvbmVudC5QZXJpb2REaXNwbGF5KHRoaXMucGVyaW9kQmVnaW4pO1xuICAgICAgICB0aGlzLnBlcmlvZEVuZEFzU3RyaW5nID0gUmFhaW5EZXRhaWxzQ29tcG9uZW50LlBlcmlvZERpc3BsYXkodGhpcy5wZXJpb2RFbmQpO1xuICAgICAgICBjb25zdCBkdXJhdGlvbk1zID0gdGhpcy5wZXJpb2RFbmQuZ2V0VGltZSgpIC0gdGhpcy5wZXJpb2RCZWdpbi5nZXRUaW1lKCk7XG4gICAgICAgIHRoaXMucGVyaW9kRHVyYXRpb25Bc1N0cmluZyA9ICcnICsgZHVyYXRpb25NcyAvIFJhYWluRGV0YWlsc0NvbXBvbmVudC5IT1VSX01TO1xuXG4gICAgICAgIHRoaXMuZGF0ZVNob3duID0gdGhpcy5nZXREYXRlQmFzZWRPbkN1bXVsYXRpdmVNb2RlKCk7XG4gICAgICAgIHRoaXMucmVmcmVzaEluUHJvZ3Jlc3MgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5zaG93RnVsbEVycm9yID0gZmFsc2U7XG4gICAgICAgIHRoaXMuc2hvd1F1YWxpdHlNb2RhbCA9IGZhbHNlO1xuICAgICAgICB0aGlzLnF1YWxpdHlJbmRpY2F0b3JzID0gW107XG4gICAgICAgIHRoaXMucXVhbGl0eUluZGljYXRvcnNMb2FkaW5nID0gZmFsc2U7XG5cbiAgICAgICAgdGhpcy5jb21wYXJlTWFuYWdlcj8uY2xlYW5BbGwoKTtcbiAgICAgICAgdGhpcy5yZWZyZXNoTWFuYWdlcj8uY2xlYW5BbGwoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGluaXQoKSB7XG4gICAgICAgIHRoaXMuY2xlYW5BbGwoKTtcbiAgICAgICAgdGhpcy51cGRhdGVDYWNoZWRWYWx1ZXMoKTtcbiAgICAgICAgYXdhaXQgdGhpcy5pbml0UmFpbigpO1xuICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGluaXRSYWluKCkge1xuICAgICAgICBpZiAoIXRoaXMucmFpbk5vZGUpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuaXNBZG1pbiA9IHRoaXMucHJvZmlsZVNlcnZpY2UuaXNBZG1pbigpO1xuXG4gICAgICAgIHRoaXMucmVmcmVzaE1hbmFnZXIucmFpbk5vZGUgPSB0aGlzLnJhaW5Ob2RlO1xuICAgICAgICB0aGlzLmNvbXBhcmVNYW5hZ2VyLnJhaW5Ob2RlID0gdGhpcy5yYWluTm9kZTtcblxuICAgICAgICAvLyBMb2FkIHByb3ZpZGVycyBhbmQgc2V0IG9uIHJlZnJlc2hNYW5hZ2VyXG4gICAgICAgIGF3YWl0IHRoaXMubG9hZFByb3ZpZGVycygpO1xuXG4gICAgICAgIHRoaXMucmVmcmVzaE1hbmFnZXIuc2V0TWV0aG9kcyhcbiAgICAgICAgICAgIHRoaXMub25SZWZyZXNoSW5Qcm9ncmVzcy5iaW5kKHRoaXMpLFxuICAgICAgICAgICAgdGhpcy5vblJlZnJlc2hEb25lLmJpbmQodGhpcyksXG4gICAgICAgICAgICB0aGlzLm9uRmV0Y2hEb25lLmJpbmQodGhpcylcbiAgICAgICAgKTtcblxuICAgICAgICBjb25zdCBjZW50ZXIgPSB0aGlzLnJhaW5Ob2RlLmdldENlbnRlcigpO1xuICAgICAgICB0aGlzLmNvb3JkaW5hdGVzID0gbmV3IE1hcExhdExuZyhjZW50ZXIubGF0LCBjZW50ZXIubG5nKTtcbiAgICAgICAgdGhpcy50ZWFtTm9kZSA9IGF3YWl0IHRoaXMucHJvZmlsZVNlcnZpY2UuZ2V0VGVhbShcbiAgICAgICAgICAgIHRoaXMucmFpbk5vZGUuZ2V0TGluayhUZWFtTm9kZS5UWVBFKS5nZXRJZCgpXG4gICAgICAgICk7XG5cbiAgICAgICAgLy8gTG9hZCBhbGwgZ2F1Z2VzIGxpbmtlZCB0byB0aGUgcmFpbk5vZGUgb24gbWFwXG4gICAgICAgIGF3YWl0IHRoaXMuY29tcGFyZU1hbmFnZXIuc2V0R2F1Z2VzSW5NYXAoKTtcblxuICAgICAgICBpZiAodGhpcy5wZXJpb2RCZWdpbiAmJiB0aGlzLnBlcmlvZEVuZCkge1xuICAgICAgICAgICAgdGhpcy51cGRhdGVSZWZyZXNoTWFuYWdlclBlcmlvZCgpO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5yZWZyZXNoTWFuYWdlci5yZWZyZXNoKGZhbHNlLCB0aGlzLnRvZ2dsZUFkbWluKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgb25SZWZyZXNoSW5Qcm9ncmVzcyhcbiAgICAgICAgY291bnRQZXJpb2RzOiB7XG4gICAgICAgICAgICBwZXJjZW50SW1hZ2VzPzogWFlUeXBlW107XG4gICAgICAgICAgICBxdWV1ZVJ1bm5pbmc/OiBudW1iZXI7XG4gICAgICAgICAgICBwcm9ncmVzcz86IG51bWJlcjtcbiAgICAgICAgfSxcbiAgICAgICAgdGltZWZyYW1lRGF0ZXM6IERhdGVbXVxuICAgICkge1xuICAgICAgICB0aGlzLnJlZnJlc2hJblByb2dyZXNzID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5jb3VudHNQZXJpb2QgPSBjb3VudFBlcmlvZHM7XG4gICAgICAgIHRoaXMudGltZWZyYW1lRGF0ZXMgPSB0aW1lZnJhbWVEYXRlcztcbiAgICAgICAgdGhpcy51cGRhdGVDYWNoZWRWYWx1ZXMoKTtcbiAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBvblJlZnJlc2hEb25lKHRpbWVmcmFtZURhdGVzOiBEYXRlW10pIHtcbiAgICAgICAgdGhpcy50aW1lZnJhbWVEYXRlcyA9IHRpbWVmcmFtZURhdGVzO1xuICAgICAgICB0aGlzLnJlZnJlc2hJblByb2dyZXNzID0gZmFsc2U7XG4gICAgICAgIHRoaXMudXBkYXRlQ2FjaGVkVmFsdWVzKCk7XG4gICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuXG4gICAgICAgIGlmICh0aGlzLnRvZ2dsZU1hcCAmJiB0aW1lZnJhbWVEYXRlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB0aGlzLmRhdGVTaG93biA9IHRoaXMuZ2V0RGF0ZUJhc2VkT25DdW11bGF0aXZlTW9kZSh0aW1lZnJhbWVEYXRlcyk7XG4gICAgICAgICAgICBpZiAodGhpcy5kYXRlU2hvd24pIHtcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLmZldGNoQW5kVXBkYXRlTWFwKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIG9uRmV0Y2hEb25lKHRpbWVmcmFtZUNvbnRhaW5lcnM/OiBUaW1lZnJhbWVDb250YWluZXJzKSB7XG4gICAgICAgIGlmICh0aW1lZnJhbWVDb250YWluZXJzKSB7XG4gICAgICAgICAgICB0aGlzLnRpbWVmcmFtZUNvbnRhaW5lcnMgPSB0aW1lZnJhbWVDb250YWluZXJzO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgY2hhbmdlKF9jaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XG4gICAgICAgIGF3YWl0IHRoaXMuaW5pdCgpO1xuICAgIH1cbn1cbiIsIjwhLS0gTWFpbiBjb250ZW50IGNvbnRhaW5lciAtLT5cbjxkaXYgKm5nSWY9XCJyYWluTm9kZVwiIGNsYXNzPVwicmFhaW4tZGV0YWlscy1jb250YWluZXJcIj5cblxuICAgIDwhLS0gUGVyaW9kIHNlbGVjdGlvbiBzZWN0aW9uIC0tPlxuICAgIDxpb24tY2FyZCBjbGFzcz1cInBlcmlvZC1jYXJkXCI+XG4gICAgICAgIDxpb24tY2FyZC1jb250ZW50PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInBlcmlvZC1jb250cm9sc1wiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwZXJpb2Qtcm93XCI+XG5cbiAgICAgICAgICAgICAgICAgICAgPGlvbi1idXR0b24gKGNsaWNrKT1cInRvZ2dsZUhpc3RvcnkgPSAhdG9nZ2xlSGlzdG9yeTsgb25FbmFibGVDb3VudEhpc3RvcnlUYWIocmFpbk5vZGUpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbD1cIm91dGxpbmVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxpb24taWNvbiBuYW1lPVwiY2FsZW5kYXItY2xlYXItb3V0bGluZVwiIHNsb3Q9XCJzdGFydFwiPjwvaW9uLWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8aW9uLWljb24gW25hbWVdPVwidG9nZ2xlSGlzdG9yeSA/ICdjaGV2cm9uLWRvd24nIDogJ2NoZXZyb24tZm9yd2FyZCdcIiBzbG90PVwiZW5kXCI+PC9pb24taWNvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9pb24tYnV0dG9uPlxuXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwZXJpb2Qtc3RhcnQgaW9uLWhpZGUtbWQtZG93blwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IChjaGFuZ2UpPVwib25QZXJpb2RCZWdpbkNoYW5nZSgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwidG9nZ2xlQ3VtdWxhdGl2ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cInBlcmlvZEJlZ2luQXNTdHJpbmdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZGF0ZXRpbWUtaW5wdXRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJkYXRldGltZS1sb2NhbFwiPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicGVyaW9kLWR1cmF0aW9uIGlvbi1oaWRlLW1kLWRvd25cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxpb24tc2VsZWN0IChpb25EaXNtaXNzKT1cIm9uUGVyaW9kRHVyYXRpb25DaGFuZ2UoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cInBlcmlvZER1cmF0aW9uQXNTdHJpbmdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cInRvZ2dsZUN1bXVsYXRpdmVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJkdXJhdGlvbi1zZWxlY3RcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWQ9XCJwZXJpb2REdXJhdGlvblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRlcmZhY2U9XCJwb3BvdmVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlvbi1zZWxlY3Qtb3B0aW9uIHZhbHVlPVwiMC4yNVwiPjE1IG1pbnV0ZXM8L2lvbi1zZWxlY3Qtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpb24tc2VsZWN0LW9wdGlvbiB2YWx1ZT1cIjAuNVwiPjMwIG1pbnV0ZXM8L2lvbi1zZWxlY3Qtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpb24tc2VsZWN0LW9wdGlvbiB2YWx1ZT1cIjFcIj4xIGhvdXI8L2lvbi1zZWxlY3Qtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpb24tc2VsZWN0LW9wdGlvbiB2YWx1ZT1cIjJcIj4yIGhvdXJzPC9pb24tc2VsZWN0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW9uLXNlbGVjdC1vcHRpb24gdmFsdWU9XCIzXCI+MyBob3VyczwvaW9uLXNlbGVjdC1vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlvbi1zZWxlY3Qtb3B0aW9uIHZhbHVlPVwiNFwiPjQgaG91cnM8L2lvbi1zZWxlY3Qtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpb24tc2VsZWN0LW9wdGlvbiB2YWx1ZT1cIjVcIj41IGhvdXJzPC9pb24tc2VsZWN0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW9uLXNlbGVjdC1vcHRpb24gdmFsdWU9XCI2XCI+NiBob3VyczwvaW9uLXNlbGVjdC1vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlvbi1zZWxlY3Qtb3B0aW9uIHZhbHVlPVwiOFwiPjggaG91cnM8L2lvbi1zZWxlY3Qtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpb24tc2VsZWN0LW9wdGlvbiB2YWx1ZT1cIjEwXCI+MTAgaG91cnM8L2lvbi1zZWxlY3Qtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpb24tc2VsZWN0LW9wdGlvbiB2YWx1ZT1cIjEyXCI+MTIgaG91cnM8L2lvbi1zZWxlY3Qtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpb24tc2VsZWN0LW9wdGlvbiAqbmdJZj1cImlzQWRtaW5cIiB2YWx1ZT1cIjI0XCI+MjQgaG91cnM8L2lvbi1zZWxlY3Qtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9pb24tc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicGVyaW9kLXN0YXJ0IGlvbi1oaWRlLW1kLWRvd25cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCAoY2hhbmdlKT1cIm9uUGVyaW9kRW5kQ2hhbmdlKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJ0b2dnbGVDdW11bGF0aXZlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdmFsdWVdPVwicGVyaW9kRW5kQXNTdHJpbmdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZGF0ZXRpbWUtaW5wdXRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJkYXRldGltZS1sb2NhbFwiPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidG9nZ2xlLWN1bXVsYXRpdmVcIiAoY2xpY2spPVwib25DdW11bGF0aXZlVG9nZ2xlQ2xpY2soJGV2ZW50KVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGlvbi1sYWJlbCBbY2xhc3MudGV4dC1wcmltYXJ5XT1cInRvZ2dsZUN1bXVsYXRpdmVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyB0b2dnbGVDdW11bGF0aXZlID8gJ0N1bXVsYXRpdmUnIDogJ0dyYW51bGFyJyB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgPC9pb24tbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICA8aW9uLXRvZ2dsZSAjY3VtdWxhdGl2ZVRvZ2dsZSBbY2hlY2tlZF09XCJ0b2dnbGVDdW11bGF0aXZlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2lvbi10b2dnbGU+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgPCEtLSBIaWRkZW4gbGFiZWwgZm9yIGNoYW5nZSBkZXRlY3Rpb24gKHVuY29tbWVudCB0byBkZWJ1ZylcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaGlkZGVuLWxhYmVsXCI+e3sgb25DaGFuZ2VEZXRlY3Rpb25UZXN0KHJhaW5Ob2RlKSB9fTwvZGl2PlxuICAgICAgICAgICAgICAgIC0tPlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDwhLS0gSGlzdG9yaWNhbCBtYXAgc2VjdGlvbiAtLT5cbiAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJ0b2dnbGVIaXN0b3J5XCIgY2xhc3M9XCJwZXJpb2QtY29udHJvbHNcIj5cbiAgICAgICAgICAgICAgICA8cmFhaW4tZGF0ZS1keW5hbWljIChjaGFuZ2VkRGF0ZSk9XCJvbkRhdGVDaGFuZ2VJbkNvdW50KCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2N1cnJlbnRIZWlnaHRdPVwiMzAwXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtmZXRjaERhdGFdPVwiZmV0Y2hEYXRhV3JhcHBlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcG9pbnRzXT1cImNvdW50UG9pbnRzXCI+XG4gICAgICAgICAgICAgICAgPC9yYWFpbi1kYXRlLWR5bmFtaWM+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9pb24tY2FyZC1jb250ZW50PlxuICAgIDwvaW9uLWNhcmQ+XG5cbiAgICA8IS0tIE1hcCBwZXJmb3JtYW5jZSAtLT5cbiAgICA8aW9uLWdyaWQgY2xhc3M9XCJtYXAtcGVyZm9ybWFuY2VcIj5cbiAgICAgICAgPGlvbi1yb3cgaWQ9XCJwcm9ncmVzc0FuZFJlZnJlc2hcIj5cbiAgICAgICAgICAgIDxpb24tY29sIGNsYXNzPVwicHJvdmlkZXItc2VsZWN0aW9uXCIgc2l6ZT1cIjEyXCIgc2l6ZS1tZD1cIjZcIj5cbiAgICAgICAgICAgICAgICA8aW9uLWJ1dHRvbiAoY2xpY2spPVwib3BlblF1YWxpdHlNb2RhbCgpXCIgY2xhc3M9XCJxdWFsaXR5LWluZm8tYnV0dG9uXCIgZmlsbD1cImNsZWFyXCI+XG4gICAgICAgICAgICAgICAgICAgIHt7IHJlZnJlc2hNYW5hZ2VyLnJhaW5Db21wdXRhdGlvbk1hcFZlcnNpb24gfX1cbiAgICAgICAgICAgICAgICAgICAgPGlvbi1pY29uIG5hbWU9XCJoZWxwLWNpcmNsZS1vdXRsaW5lXCIgc2xvdD1cImVuZFwiPjwvaW9uLWljb24+XG4gICAgICAgICAgICAgICAgPC9pb24tYnV0dG9uPlxuICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJhdmFpbGFibGVQcm92aWRlcnMubGVuZ3RoID4gMCB8fCBhdmFpbGFibGVUaW1lU3RlcHMubGVuZ3RoID4gMFwiIGNsYXNzPVwic2VsZWN0aW9uLXJvd1wiPlxuICAgICAgICAgICAgICAgICAgICA8aW9uLXNlbGVjdCAoaW9uQ2hhbmdlKT1cIm9uUHJvdmlkZXJDaGFuZ2VkKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdmFsdWVdPVwic2VsZWN0ZWRQcm92aWRlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludGVyZmFjZT1cInBvcG92ZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbD1cIlByb3ZpZGVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJTZWxlY3QgUHJvdmlkZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxpb24tc2VsZWN0LW9wdGlvbiAqbmdGb3I9XCJsZXQgcHJvdmlkZXIgb2YgYXZhaWxhYmxlUHJvdmlkZXJzXCIgW3ZhbHVlXT1cInByb3ZpZGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgcHJvdmlkZXIgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvaW9uLXNlbGVjdC1vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgIDwvaW9uLXNlbGVjdD5cblxuICAgICAgICAgICAgICAgICAgICA8aW9uLXNlbGVjdCAoaW9uQ2hhbmdlKT1cIm9uVGltZVN0ZXBDaGFuZ2VkKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdmFsdWVdPVwic2VsZWN0ZWRUaW1lU3RlcFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludGVyZmFjZT1cInBvcG92ZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbD1cIlRpbWUgU3RlcFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiU2VsZWN0IFRpbWUgU3RlcFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGlvbi1zZWxlY3Qtb3B0aW9uICpuZ0Zvcj1cImxldCBzdGVwIG9mIGF2YWlsYWJsZVRpbWVTdGVwc1wiIFt2YWx1ZV09XCJzdGVwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgc3RlcCB9fSBtaW5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvaW9uLXNlbGVjdC1vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgIDwvaW9uLXNlbGVjdD5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvaW9uLWNvbD5cbiAgICAgICAgICAgIDxpb24tY29sIGNsYXNzPVwiaW9uLXRleHQtcmlnaHRcIiBzaXplPVwiMTJcIiBzaXplLW1kPVwiNlwiPlxuICAgICAgICAgICAgICAgIDxpb24tbGFiZWwgY2xhc3M9XCJpb24tbWFyZ2luLWVuZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwicGVyY2VudE9mQ29tcHV0YXRpb25zXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IHBlcmNlbnRPZkNvbXB1dGF0aW9ucyB9fSUgSW1hZ2VzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpICpuZ0lmPVwiY291bnRzUGVyaW9kLnByb2dyZXNzXCIgY2xhc3M9XCJwcm9ncmVzcy1pbmRpY2F0b3JcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluIFByb2dyZXNzOiB7eyBjb3VudHNQZXJpb2QucHJvZ3Jlc3MgfX0uLi5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9pPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCIhcGVyY2VudE9mQ29tcHV0YXRpb25zXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5vIGltYWdlIGF2YWlsYWJsZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cblxuICAgICAgICAgICAgICAgIDwvaW9uLWxhYmVsPlxuXG4gICAgICAgICAgICAgICAgPGlvbi1idXR0b24gKGNsaWNrKT1cInJlZnJlc2hNYXAoKVwiIFtkaXNhYmxlZF09XCJyZWZyZXNoSW5Qcm9ncmVzc1wiIGNsYXNzPVwicmVmcmVzaC1idXR0b25cIj5cbiAgICAgICAgICAgICAgICAgICAgUmVmcmVzaCBNYXBcbiAgICAgICAgICAgICAgICA8L2lvbi1idXR0b24+XG4gICAgICAgICAgICA8L2lvbi1jb2w+XG4gICAgICAgIDwvaW9uLXJvdz5cblxuICAgICAgICA8IS0tIHN0YXR1cyB1cGRhdGUgcm93IC0tPlxuICAgICAgICA8aW9uLXJvdz5cbiAgICAgICAgICAgIDwhLS0gUHJvZ3Jlc3MgY29sIC0tPlxuICAgICAgICAgICAgPGlvbi1wcm9ncmVzcy1iYXJcbiAgICAgICAgICAgICAgICAgICAgW2J1ZmZlcl09XCIoY291bnRzUGVyaW9kLnByb2dyZXNzIC8gKCh0aW1lZnJhbWVEYXRlcz8ubGVuZ3RoIHx8IDEwKSArMykpKzAuMDFcIlxuICAgICAgICAgICAgICAgICAgICBbc3R5bGUudmlzaWJpbGl0eV09XCJyZWZyZXNoSW5Qcm9ncmVzcyA/ICd2aXNpYmxlJyA6ICdoaWRkZW4nXCJcbiAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cImNvdW50c1BlcmlvZC5wcm9ncmVzcyAvICgodGltZWZyYW1lRGF0ZXM/Lmxlbmd0aCB8fCAxMCkgKzMpXCJcbiAgICAgICAgICAgICAgICAgICAgY29sb3I9XCJwcmltYXJ5XCI+XG4gICAgICAgICAgICA8L2lvbi1wcm9ncmVzcy1iYXI+XG5cbiAgICAgICAgICAgIDwhLS0gRXJyb3IgY29sIC0tPlxuICAgICAgICAgICAgPGlvbi1jb2wgKGNsaWNrKT1cInNob3dGdWxsRXJyb3IgPSAhc2hvd0Z1bGxFcnJvclwiICpuZ0lmPVwicmVmcmVzaE1hbmFnZXIubGFzdEVycm9yXCIgY2xhc3M9XCJlcnJvci1yb3dcIlxuICAgICAgICAgICAgICAgICAgICAgc2l6ZT1cIjEyXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImVycm9yLWNvbnRlbnRcIj5cbiAgICAgICAgICAgICAgICAgICAgPGlvbi1pY29uIGNsYXNzPVwiZXJyb3ItaWNvblwiIG5hbWU9XCJ3YXJuaW5nLW91dGxpbmVcIj48L2lvbi1pY29uPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBbY2xhc3MuZXhwYW5kZWRdPVwic2hvd0Z1bGxFcnJvclwiIGNsYXNzPVwiZXJyb3ItdGV4dFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAge3sgc2hvd0Z1bGxFcnJvciA/IHJlZnJlc2hNYW5hZ2VyLmxhc3RFcnJvciA6IHRydW5jYXRlZEVycm9yIH19XG4gICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPGlvbi1pY29uIFtuYW1lXT1cInNob3dGdWxsRXJyb3IgPyAnY2hldnJvbi11cCcgOiAnY2hldnJvbi1kb3duJ1wiIGNsYXNzPVwiZXJyb3ItY2FyZXRcIj48L2lvbi1pY29uPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICA8L2lvbi1yb3c+XG4gICAgPC9pb24tZ3JpZD5cblxuICAgIDwhLS0gTWFwIHNlY3Rpb24gLS0+XG4gICAgPGlvbi1jYXJkIGNsYXNzPVwibWFwLWNhcmRcIj5cbiAgICAgICAgPGlvbi1jYXJkLWNvbnRlbnQgY2xhc3M9XCJtYXAtY29udGVudFwiPlxuICAgICAgICAgICAgPGlvbi1ncmlkPlxuICAgICAgICAgICAgICAgIDxpb24tcm93ICpuZ0lmPVwidG9nZ2xlTWFwICYmIHBlcmNlbnRPZkltYWdlc1wiPlxuICAgICAgICAgICAgICAgICAgICA8IS0tIE1hcCBjb21wb25lbnQgLS0+XG4gICAgICAgICAgICAgICAgICAgIDxpb24tY29sIGNsYXNzPVwibWFwLWNvbHVtblwiIHNpemUtbGc9XCI3XCIgc2l6ZS1tZD1cIjEyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWFwLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxyYWFpbi1tYXAgI3JhYWluTWFwUmVmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2hhbmdlZERhdGUpPVwib25EYXRlQ2hhbmdlSW5NYXAoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2hhbmdlZFN1bSk9XCJvblN1bUNoYW5nZUluTWFwKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHNlbGVjdGVkTWFya2VyKT1cIm9uR2F1Z2VTZWxlY3RJbk1hcCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjb29yZGluYXRlc109XCJjb29yZGluYXRlc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY3VtdWxhdGl2ZUR1cmF0aW9uSW5NaW51dGVzXT1cImN1bXVsYXRpdmVEdXJhdGlvbkluTWludXRlc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY3VycmVudEhlaWdodF09XCI1MDBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2RlZmF1bHREYXRlXT1cImRhdGVTaG93blwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbWFya2Vyc109XCJ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9yZGVycyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnYXVnZXM6IGNvbXBhcmVNYW5hZ2VyLmdhdWdlc0luTWFwLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdhdWdlc0luQ29tcGFyZTogY29tcGFyZU1hbmFnZXIuZ2F1Z2VzSW5Db21wYXJlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkR2F1Z2VzOiBjb21wYXJlTWFuYWdlci5zZWxlY3RlZEdhdWdlcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaXhlbHM6IGNvbXBhcmVNYW5hZ2VyLnNlbGVjdGVkUGl4ZWxzLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpeGVsc1NvbHV0aW9uOiBjb21wYXJlTWFuYWdlci5waXhlbHNTb2x1dGlvbnM/Lmxlbmd0aCA/IGNvbXBhcmVNYW5hZ2VyLnBpeGVsc1NvbHV0aW9uc1swXSA6IFtdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWVkczogY29tcGFyZU1hbmFnZXIuc3BlZWRzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93Q3VtdWxhdGl2ZV09XCJ0b2dnbGVDdW11bGF0aXZlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93VmlzaWJsZVBpeGVsTWFya2Vyc109XCJzaG93UGl4ZWxNYXJrZXJzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdW1Gbl09XCJyZWZyZXNoTWFuYWdlci5zdW1GblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3VtVmFsdWVzXT1cInJlZnJlc2hNYW5hZ2VyLnN1bVZhbHVlc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdGltZWZyYW1lQ29udGFpbmVyc109XCJ0aW1lZnJhbWVDb250YWluZXJzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt0aW1lZnJhbWVEYXRlc109XCJ0aW1lZnJhbWVEYXRlc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvcmFhaW4tbWFwPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkYXRhLWNvbHVtblwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gVGVjaG5pY2FsIGRldGFpbHMgKGNvbGxhcHNpYmxlIGZvciBjbGVhbmVyIFVJKSAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGV0YWlscyBjbGFzcz1cInRlY2huaWNhbC1kZXRhaWxzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdW1tYXJ5PkltYWdlIERldGFpbHM8L3N1bW1hcnk+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkZXRhaWxzLWNvbnRlbnRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkZXRhaWwtcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkZXRhaWwtbGFiZWxcIj5Db21wdXRlZDo8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkZXRhaWwtdmFsdWVcIj57eyByZWZyZXNoTWFuYWdlci5yYWluQ29tcHV0YXRpb25NYXBEb25lRGF0ZSB8IGRhdGU6J3l5eXktTU0tZGQgSEg6bW0nIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGV0YWlsLXJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGV0YWlsLWxhYmVsXCI+VmVyc2lvbjo8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkZXRhaWwtdmFsdWVcIj57eyByZWZyZXNoTWFuYWdlci5yYWluQ29tcHV0YXRpb25NYXBWZXJzaW9uIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGV0YWlsLXJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGV0YWlsLWxhYmVsXCI+TGF1bmNoZWQgYnk6PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGV0YWlsLXZhbHVlXCI+e3sgcmVmcmVzaE1hbmFnZXIucmFpbkNvbXB1dGF0aW9uTWFwTGF1bmNoZWRCeSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRldGFpbC1yb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRldGFpbC1sYWJlbFwiPlRpbWUgc3BlbnQ6PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGV0YWlsLXZhbHVlXCI+e3sgcmVmcmVzaE1hbmFnZXIucmFpbkNvbXB1dGF0aW9uTWFwVGltZVNwZW50SW5NcyB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtczwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRldGFpbC1yb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRldGFpbC1sYWJlbFwiPkRhdGU6PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGV0YWlsLXZhbHVlXCI+e3sgcmVmcmVzaE1hbmFnZXIucmFpbkNvbXB1dGF0aW9uTWFwRGF0ZT8udG9JU09TdHJpbmcoKSB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IHt7IHJlZnJlc2hNYW5hZ2VyLnJhaW5Db21wdXRhdGlvbk1hcERhdGUgfCBkYXRlOid5eXl5LU1NLWRkIEhIOm1tJyB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRldGFpbC1yb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRldGFpbC1sYWJlbFwiPldhdGVyIGluIHRoZSBtYXA6PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGV0YWlsLXZhbHVlXCI+e3sgc3VtRGV0YWlscyB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW9uLXRvZ2dsZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGlvbkNoYW5nZSk9XCJvblRvZ2dsZVBpeGVsTWFya2VycygpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwic2hvd1BpeGVsTWFya2Vyc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHlsZT1cIm1hcmdpbi1sZWZ0OiA4cHg7IHRyYW5zZm9ybTogc2NhbGUoMC43KTtcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2lvbi10b2dnbGU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkZXRhaWwtcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkZXRhaWwtbGFiZWxcIj5Tb3VyY2UgREJaIG1pbjo8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkZXRhaWwtdmFsdWVcIj57eyByZWZyZXNoTWFuYWdlci5yYWluQ29tcHV0YXRpb25NYXBPcmlnaW5hbE1pbiB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRldGFpbC1yb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRldGFpbC1sYWJlbFwiPlNvdXJjZSBEQlogbWF4Ojwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRldGFpbC12YWx1ZVwiPnt7IHJlZnJlc2hNYW5hZ2VyLnJhaW5Db21wdXRhdGlvbk1hcE9yaWdpbmFsTWF4IH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGV0YWlscz5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2lvbi1jb2w+XG5cbiAgICAgICAgICAgICAgICAgICAgPCEtLSBEYXRhIHBhbmVsIC0tPlxuICAgICAgICAgICAgICAgICAgICA8aW9uLWNvbCAqbmdJZj1cIiEhY29tcGFyZU1hbmFnZXIuY29tcGFyZVZlcnNpb25cIiBjbGFzcz1cImRhdGEtY29sdW1uXCIgc2l6ZS1sZz1cIjVcIiBzaXplLW1kPVwiMTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkYXRhLXBhbmVsXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBDb21wYXJlIHN0YWNrIGNvbXBvbmVudCAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29tcGFyZS1zdGFja1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cmFhaW4tY29tcGFyZS1zdGFja1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzZWxlY3RlZFBvaW50KT1cIm9uR2F1Z2VTZWxlY3RJbkNvbXBhcmUoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NvbXBhcmVNYW5hZ2VyXT1cImNvbXBhcmVNYW5hZ2VyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY3VtdWxhdGl2ZV09XCJ0b2dnbGVDdW11bGF0aXZlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvcmFhaW4tY29tcGFyZS1zdGFjaz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gVGVjaG5pY2FsIGRldGFpbHMgKGNvbGxhcHNpYmxlIGZvciBjbGVhbmVyIFVJKSAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGV0YWlscyBjbGFzcz1cInRlY2huaWNhbC1kZXRhaWxzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdW1tYXJ5PkNvbXBhcmUgRGV0YWlsczwvc3VtbWFyeT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRldGFpbHMtY29udGVudFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBbbmdDbGFzc109XCJ7J3dhcm5pbmcnOiByZWZyZXNoTWFuYWdlci5yYWluQ29tcHV0YXRpb25NYXBEb25lRGF0ZT8uZ2V0VGltZSgpID4gY29tcGFyZU1hbmFnZXIuY3VycmVudFF1YWxpdHlEb25lRGF0ZT8uZ2V0VGltZSgpICsgNjAwMDB9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJkZXRhaWwtcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkZXRhaWwtbGFiZWxcIj5Db21wdXRlZDo8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkZXRhaWwtdmFsdWVcIj57eyBjb21wYXJlTWFuYWdlci5jdXJyZW50UXVhbGl0eURvbmVEYXRlIHwgZGF0ZToneXl5eS1NTS1kZCBISDptbScgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkZXRhaWwtcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkZXRhaWwtbGFiZWxcIj5WZXJzaW9uOjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRldGFpbC12YWx1ZVwiPnt7IGNvbXBhcmVNYW5hZ2VyLmNvbXBhcmVWZXJzaW9uIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGV0YWlsLXJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGV0YWlsLWxhYmVsXCI+TGF1bmNoZWQgYnk6PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGV0YWlsLXZhbHVlXCI+e3sgY29tcGFyZU1hbmFnZXIuY3VycmVudFF1YWxpdHlMYXVuY2hlZEJ5IH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGV0YWlsLXJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGV0YWlsLWxhYmVsXCI+VGltZSBzcGVudDo8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkZXRhaWwtdmFsdWVcIj57eyBjb21wYXJlTWFuYWdlci5jdXJyZW50UXVhbGl0eVRpbWVTcGVudEluTXMgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXM8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkZXRhaWwtcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkZXRhaWwtbGFiZWxcIj5HYXVnZXM6PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGV0YWlsLXZhbHVlXCI+e3sgY29tcGFyZU1hbmFnZXIuZ2F1Z2VzSW5Db21wYXJlLmxlbmd0aCB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRldGFpbC1yb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRldGFpbC1sYWJlbFwiPlBvaW50czo8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkZXRhaWwtdmFsdWVcIj57eyBjb21wYXJlTWFuYWdlci5nbG9iYWxDb21wYXJlUG9pbnRzLmxlbmd0aCB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2RldGFpbHM+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgICAgICAgIDwvaW9uLXJvdz5cbiAgICAgICAgICAgICAgICA8aW9uLXJvdz5cbiAgICAgICAgICAgICAgICAgICAgPCEtLSBCb3R0b20gcHJvZ3Jlc3MgYmFyIC0tPlxuICAgICAgICAgICAgICAgICAgICA8aW9uLXByb2dyZXNzLWJhciAqbmdJZj1cInJlZnJlc2hJblByb2dyZXNzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2J1ZmZlcl09XCIoY291bnRzUGVyaW9kLnByb2dyZXNzIC8gKCh0aW1lZnJhbWVEYXRlcz8ubGVuZ3RoIHx8IDEwKSArMykpKzAuMDFcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdmFsdWVdPVwiY291bnRzUGVyaW9kLnByb2dyZXNzIC8gKCh0aW1lZnJhbWVEYXRlcz8ubGVuZ3RoIHx8IDEwKSArMylcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvcj1cInByaW1hcnlcIj5cbiAgICAgICAgICAgICAgICAgICAgPC9pb24tcHJvZ3Jlc3MtYmFyPlxuICAgICAgICAgICAgICAgIDwvaW9uLXJvdz5cbiAgICAgICAgICAgIDwvaW9uLWdyaWQ+XG4gICAgICAgIDwvaW9uLWNhcmQtY29udGVudD5cbiAgICA8L2lvbi1jYXJkPlxuXG4gICAgPCEtLSBHYXVnZSB2YWx1ZXMgc2VjdGlvbiAtLT5cbiAgICA8aW9uLWNhcmQgKm5nSWY9XCJnYXVnZVNlbGVjdGVkUG9pbnRzLmxlbmd0aCAmJiBnYXVnZVNlbGVjdGVkUG9pbnRzWzBdLnZhbHVlcy5sZW5ndGhcIiBjbGFzcz1cImdhdWdlLWNhcmRcIj5cbiAgICAgICAgPGlvbi1jYXJkLWhlYWRlcj5cbiAgICAgICAgICAgIDxpb24tY2FyZC10aXRsZT5cbiAgICAgICAgICAgICAgICA8aW9uLWljb24gbmFtZT1cImFuYWx5dGljcy1vdXRsaW5lXCI+PC9pb24taWNvbj5cbiAgICAgICAgICAgICAgICBTZWxlY3RlZCBHYXVnZSBEYXRhXG4gICAgICAgICAgICA8L2lvbi1jYXJkLXRpdGxlPlxuICAgICAgICA8L2lvbi1jYXJkLWhlYWRlcj5cbiAgICAgICAgPGlvbi1jYXJkLWNvbnRlbnQ+XG4gICAgICAgICAgICA8cmFhaW4tZGF0ZS1mb2N1c1xuICAgICAgICAgICAgICAgICAgICBbY3VycmVudEhlaWdodF09XCIzMDBcIlxuICAgICAgICAgICAgICAgICAgICBbZm9jdXNEYXRlXT1cInBlcmlvZEJlZ2luXCJcbiAgICAgICAgICAgICAgICAgICAgW2ZvY3VzUmFuZ2VdPVwiRGF0ZVJhbmdlLkRBWVwiXG4gICAgICAgICAgICAgICAgICAgIFtwb2ludHNdPVwiZ2F1Z2VTZWxlY3RlZFBvaW50c1wiXG4gICAgICAgICAgICAgICAgICAgIFt3aXRob3V0QWxsXT1cInRydWVcIj5cbiAgICAgICAgICAgIDwvcmFhaW4tZGF0ZS1mb2N1cz5cbiAgICAgICAgPC9pb24tY2FyZC1jb250ZW50PlxuICAgIDwvaW9uLWNhcmQ+XG5cbiAgICA8IS0tIFF1YWxpdHkgUGVyZm9ybWFuY2UgTW9kYWwgLS0+XG4gICAgPGRpdiAoY2xpY2spPVwiY2xvc2VRdWFsaXR5TW9kYWwoKVwiICpuZ0lmPVwic2hvd1F1YWxpdHlNb2RhbFwiIGNsYXNzPVwicXVhbGl0eS1tb2RhbC1vdmVybGF5XCI+XG4gICAgICAgIDxkaXYgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiIGNsYXNzPVwicXVhbGl0eS1tb2RhbC1jb250ZW50XCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwicXVhbGl0eS1tb2RhbC1oZWFkZXJcIj5cbiAgICAgICAgICAgICAgICA8aDI+TW9kZWwgUXVhbGl0eSBQZXJmb3JtYW5jZTwvaDI+XG4gICAgICAgICAgICAgICAgPGlvbi1idXR0b24gKGNsaWNrKT1cImNsb3NlUXVhbGl0eU1vZGFsKClcIiBmaWxsPVwiY2xlYXJcIj5cbiAgICAgICAgICAgICAgICAgICAgPGlvbi1pY29uIG5hbWU9XCJjbG9zZS1vdXRsaW5lXCI+PC9pb24taWNvbj5cbiAgICAgICAgICAgICAgICA8L2lvbi1idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJxdWFsaXR5LW1vZGFsLWJvZHlcIj5cbiAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwicXVhbGl0eUluZGljYXRvcnNMb2FkaW5nXCIgY2xhc3M9XCJxdWFsaXR5LWxvYWRpbmdcIj5cbiAgICAgICAgICAgICAgICAgICAgPGlvbi1zcGlubmVyIG5hbWU9XCJjcmVzY2VudFwiPjwvaW9uLXNwaW5uZXI+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuPkxvYWRpbmcgaW5kaWNhdG9ycy4uLjwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiIXF1YWxpdHlJbmRpY2F0b3JzTG9hZGluZyAmJiBxdWFsaXR5SW5kaWNhdG9ycy5sZW5ndGggPT09IDBcIiBjbGFzcz1cInF1YWxpdHktZW1wdHlcIj5cbiAgICAgICAgICAgICAgICAgICAgTm8gcXVhbGl0eSBpbmRpY2F0b3JzIGF2YWlsYWJsZSBmb3IgdGhpcyB5ZWFyLlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDx0YWJsZSAqbmdJZj1cIiFxdWFsaXR5SW5kaWNhdG9yc0xvYWRpbmcgJiYgcXVhbGl0eUluZGljYXRvcnMubGVuZ3RoID4gMFwiIGNsYXNzPVwicXVhbGl0eS10YWJsZVwiPlxuICAgICAgICAgICAgICAgICAgICA8dGhlYWQ+XG4gICAgICAgICAgICAgICAgICAgIDx0cj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0aD5Nb2RlbDwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGg+Q29tcGFyZTwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGg+R2F1Z2VzPC90aD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0aD5QZXJpb2Q8L3RoPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRoPkF2ZyBRdWFsaXR5PC90aD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0aD5VcGRhdGVkPC90aD5cbiAgICAgICAgICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICAgICAgICAgICAgPC90aGVhZD5cbiAgICAgICAgICAgICAgICAgICAgPHRib2R5PlxuICAgICAgICAgICAgICAgICAgICA8dHIgKm5nRm9yPVwibGV0IGluZGljYXRvciBvZiBxdWFsaXR5SW5kaWNhdG9yc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRkPnt7IGluZGljYXRvci5jb21wdXRpbmdWZXJzaW9uIH19PC90ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0ZD57eyBpbmRpY2F0b3IucXVhbGl0eVZlcnNpb24gfX08L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRkPnt7IGluZGljYXRvci5wcm92aWRlciB9fTxicj57eyBpbmRpY2F0b3IudGltZVN0ZXBJbk1pbnV0ZXMgfX0gbWluPC90ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0ZD57eyBmb3JtYXREYXRlKGluZGljYXRvci5zdGFydERhdGUpIH19PGJyPnt7IGZvcm1hdERhdGUoaW5kaWNhdG9yLmVuZERhdGUpIH19PC90ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0ZD57eyBpbmRpY2F0b3IuYXZlcmFnZVF1YWxpdHkgfCBudW1iZXI6JzEuMi0yJyB9fTwvdGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGQ+e3sgZm9ybWF0RGF0ZShpbmRpY2F0b3IubGFzdFVwZGF0ZWRBdCkgfX08L3RkPlxuICAgICAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgICAgICAgICA8L3Rib2R5PlxuICAgICAgICAgICAgICAgIDwvdGFibGU+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tIEN1bXVsYXRpdmUgU2VsZWN0b3IgTW9kYWwgLS0+XG4gICAgPGN1bXVsYXRpdmUtc2VsZWN0b3IgKm5nSWY9XCJzaG93Q3VtdWxhdGl2ZVNlbGVjdG9yXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICBbcmFpbklkXT1cInJhaW5Ob2RlPy5pZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgW2N1cnJlbnRQZXJpb2RCZWdpbl09XCJwZXJpb2RCZWdpblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgW2N1cnJlbnRQZXJpb2RFbmRdPVwicGVyaW9kRW5kXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICBbcHJvdmlkZXJdPVwic2VsZWN0ZWRQcm92aWRlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgW3RpbWVTdGVwSW5NaW51dGVzXT1cInNlbGVjdGVkVGltZVN0ZXBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgIFtpc0FkbWluXT1cInRvZ2dsZUFkbWluXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAocGVyaW9kU2VsZWN0ZWQpPVwib25DdW11bGF0aXZlUGVyaW9kU2VsZWN0ZWQoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgKGNhbmNlbGxlZCk9XCJvbkN1bXVsYXRpdmVTZWxlY3RvckNhbmNlbGxlZCgpXCI+XG4gICAgPC9jdW11bGF0aXZlLXNlbGVjdG9yPlxuXG48L2Rpdj5cbiJdfQ==