@iotize/ionic
Version:
Iotize specific building blocks on top of @ionic/angular.
261 lines • 42.4 kB
JavaScript
import { __decorate, __metadata } from "tslib";
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, Inject, Input, NgZone, PLATFORM_ID, ViewChild, } from '@angular/core';
import { ModalController } from '@ionic/angular';
import { BarHorizontalComponent, BarVerticalComponent, BaseChartComponent, LegendPosition, } from '@swimlane/ngx-charts';
import { BehaviorSubject, Subject, combineLatest } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { MonitoringAppGenComponent } from '../../metadata/decorators';
import { ChartDataModel, } from '../ChartDataModel';
import { TapVariableDataPopupComponent } from '../tap-variable-data-popup/tap-variable-data-popup.component';
import * as i0 from "@angular/core";
import * as i1 from "@ionic/angular";
import * as i2 from "@angular/common";
import * as i3 from "@swimlane/ngx-charts";
import * as i4 from "../../ui-directive/export-data.directive";
let TapVariableBarChartComponent = class TapVariableBarChartComponent extends BaseChartComponent {
/**
* @deprecated use xAxis
*/
set showXAxis(v) {
this.xAxis = v;
}
/**
* @deprecated use yAxis
*/
set showYAxis(v) {
this.yAxis = v;
}
set variable(variableOrArray) {
this.input = this.chartModel.initVariable(variableOrArray);
}
set history(enable) {
this._history.next(enable);
}
set valueCountLimit(limit) {
if (limit === undefined) {
limit = 30;
}
this._valueCountLimit.next(limit);
}
set input(inputs) {
this._input.next(inputs);
}
set data(results) {
this.results = results;
}
set label(indexOrArray) {
this.chartModel.initLabel(indexOrArray);
}
constructor(myChartElement, zone, cd, platformId, modalController) {
super(myChartElement, zone, cd, platformId);
this.cd = cd;
this.modalController = modalController;
this.results = [];
this.orientation = 'vertical';
this.legend = false;
this.legendPosition = LegendPosition.Below;
this.showGridLines = false;
this.showDetails = false;
this.xAxis = true;
this.showXAxisLabel = false;
this.xAxisLabel = '';
this.yAxis = true;
this.showYAxisLabel = false;
this.yAxisLabel = '';
this.animations = true;
this.roundEdges = true;
this.noBarWhenZero = false;
this.showExportButton = false;
this.xAxisTickFormatting = this.defaultDateTickFormatting.bind(this);
this.scrollableChart = false;
this.colorScheme = {
domain: [
'#5DADE2',
'#9B59B6',
'#f69b05',
'#5AA454',
'#A10A28',
'#C7B42C',
'#AAAAAA',
],
};
this._history = new BehaviorSubject(true);
this._valueCountLimit = new BehaviorSubject(30);
this._input = new BehaviorSubject([]);
this.destroyed = new Subject();
this.chartModel = new ChartDataModel();
}
ngOnInit() {
combineLatest([this._valueCountLimit, this._input, this._history])
.pipe(takeUntil(this.destroyed))
.subscribe(([valueCountLimit, input, history]) => {
this.chartModel.destroyCurrentSub();
if (history) {
this.oldColorScheme = this.colorScheme;
this.colorScheme = { domain: [this.colorScheme.domain[0]] };
}
else {
if (this.oldColorScheme !== undefined) {
this.colorScheme = this.oldColorScheme;
}
}
this.subscription = this.chartModel
.defineInputStreamSingle(input, history, valueCountLimit)
.subscribe((result) => {
if (this.scrollableChart) {
this.resizeToScroll(result.length);
}
this.results = result;
});
this.cd.detectChanges();
});
}
ngAfterContentChecked() {
this.cd.detectChanges();
if (!this.scrollableChart) {
this.widthChart = this.divContainer.nativeElement.offsetWidth;
this.heightChart = this.divContainer.nativeElement.offsetHeight;
}
}
resizeToScroll(size) {
if (this.orientation === 'vertical') {
if (this.divContainer.nativeElement.offsetWidth <= size * 100) {
this.barChartVer.view = [
size * 100,
this.divContainer.nativeElement.offsetHeight,
];
}
}
else if (this.orientation === 'horizontal') {
if (this.divContainer.nativeElement.offsetHeight <= size * 100) {
this.barChartHor.view = [
this.divContainer.nativeElement.offsetWidth,
size * 100,
];
}
}
}
onSelect(event) {
if (typeof event === 'object') {
if (this.showDetails) {
this.chartModel
.showDetail(event, this.modalController, TapVariableDataPopupComponent)
.catch((err) => {
console.log(err);
});
}
}
}
defaultDateTickFormatting(val) {
if (val.time) {
return new Date(val.time).toLocaleDateString();
}
return val;
}
ngOnDestroy() {
this.subscription?.unsubscribe();
this.chartModel.destroyCurrentSub();
}
};
/** @nocollapse */ TapVariableBarChartComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: TapVariableBarChartComponent, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }, { token: PLATFORM_ID }, { token: i1.ModalController }], target: i0.ɵɵFactoryTarget.Component });
/** @nocollapse */ TapVariableBarChartComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: TapVariableBarChartComponent, selector: "tap-variable-bar-chart", inputs: { orientation: "orientation", legend: "legend", legendTitle: "legendTitle", legendPosition: "legendPosition", showGridLines: "showGridLines", showDetails: "showDetails", showXAxis: "showXAxis", xAxis: "xAxis", showXAxisLabel: "showXAxisLabel", xAxisLabel: "xAxisLabel", showYAxis: "showYAxis", yAxis: "yAxis", showYAxisLabel: "showYAxisLabel", yAxisLabel: "yAxisLabel", trimXAxisTicks: "trimXAxisTicks", maxXAxisTickLength: "maxXAxisTickLength", trimYAxisTicks: "trimYAxisTicks", maxYAxisTickLength: "maxYAxisTickLength", animations: "animations", roundDomains: "roundDomains", roundEdges: "roundEdges", barPadding: "barPadding", noBarWhenZero: "noBarWhenZero", showExportButton: "showExportButton", exportedFileName: "exportedFileName", variable: "variable", xAxisTickFormatting: "xAxisTickFormatting", history: "history", valueCountLimit: "valueCountLimit", input: "input", data: "data", scrollableChart: "scrollableChart", scaleMax: "scaleMax", scaleMin: "scaleMin", label: "label", colorScheme: "colorScheme" }, viewQueries: [{ propertyName: "divContainer", first: true, predicate: ["containerRef"], descendants: true }, { propertyName: "barChartHor", first: true, predicate: ["chartsHor"], descendants: true }, { propertyName: "barChartVer", first: true, predicate: ["chartsVer"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<div\n [ngClass]=\"\n scrollableChart\n ? orientation == 'vertical'\n ? 'verticalContainer'\n : 'horizontalContainer'\n : {}\n \"\n>\n <div\n #containerRef\n [ngClass]=\"\n legendPosition === 'below' && legend ? 'belowLegend' : 'rightLegend'\n \"\n [ngSwitch]=\"orientation\"\n style=\"position: relative\"\n >\n <ngx-charts-bar-horizontal\n *ngSwitchCase=\"'horizontal'\"\n #chartsHor\n [view]=\"[containerRef.offsetWidth, containerRef.offsetHeight]\"\n [scheme]=\"colorScheme\"\n [results]=\"results\"\n [roundEdges]=\"roundEdges\"\n [showXAxisLabel]=\"showXAxisLabel\"\n [showYAxisLabel]=\"showYAxisLabel\"\n [xAxis]=\"xAxis\"\n [yAxisLabel]=\"yAxisLabel\"\n [yAxis]=\"yAxis\"\n [xAxisLabel]=\"xAxisLabel\"\n [legend]=\"legend\"\n [legendTitle]=\"legendTitle\"\n [legendPosition]=\"legendPosition\"\n [noBarWhenZero]=\"noBarWhenZero\"\n [xAxisTickFormatting]=\"xAxisTickFormatting\"\n [xScaleMax]=\"scaleMax\"\n [xScaleMin]=\"scaleMin\"\n [showGridLines]=\"showGridLines\"\n [trimXAxisTicks]=\"trimXAxisTicks\"\n [maxXAxisTickLength]=\"maxXAxisTickLength\"\n [trimYAxisTicks]=\"trimYAxisTicks\"\n [maxYAxisTickLength]=\"maxYAxisTickLength\"\n [animations]=\"animations\"\n [roundDomains]=\"roundDomains\"\n [roundEdges]=\"roundEdges\"\n [barPadding]=\"barPadding\"\n (select)=\"onSelect($event)\"\n >\n </ngx-charts-bar-horizontal>\n <ngx-charts-bar-vertical\n *ngSwitchCase=\"'vertical'\"\n #chartsVer\n [view]=\"[containerRef.offsetWidth, containerRef.offsetHeight]\"\n [noBarWhenZero]=\"noBarWhenZero\"\n [scheme]=\"colorScheme\"\n [results]=\"results\"\n [showXAxisLabel]=\"showXAxisLabel\"\n [showYAxisLabel]=\"showYAxisLabel\"\n [yAxisLabel]=\"yAxisLabel\"\n [xAxisLabel]=\"xAxisLabel\"\n [legend]=\"legend\"\n [legendTitle]=\"legendTitle\"\n [legendPosition]=\"legendPosition\"\n [xAxis]=\"xAxis\"\n [yAxis]=\"yAxis\"\n [yAxisTickFormatting]=\"xAxisTickFormatting\"\n [showGridLines]=\"showGridLines\"\n [trimXAxisTicks]=\"trimXAxisTicks\"\n [maxXAxisTickLength]=\"maxXAxisTickLength\"\n [trimYAxisTicks]=\"trimYAxisTicks\"\n [maxYAxisTickLength]=\"maxYAxisTickLength\"\n [animations]=\"animations\"\n [roundDomains]=\"roundDomains\"\n [roundEdges]=\"roundEdges\"\n [barPadding]=\"barPadding\"\n [yScaleMax]=\"scaleMax\"\n [yScaleMin]=\"scaleMin\"\n (select)=\"onSelect($event)\"\n >\n </ngx-charts-bar-vertical>\n <ion-fab-button\n id=\"exportFabButton\"\n size=\"small\"\n tapExportData\n [dataToExport]=\"results\"\n *ngIf=\"showExportButton\"\n [exportedFileName]=\"exportedFileName\"\n >\n <ion-icon name=\"download\"></ion-icon>\n </ion-fab-button>\n </div>\n</div>\n", styles: ["::ng-deep .horizontal-legend{overflow:auto!important}.belowLegend{max-height:50vh;width:100%;min-width:100%;margin-bottom:60px}.rightLegend{max-height:50vh;min-height:50vh;width:100%}#exportFabButton{position:absolute;top:10px;right:10px}@media (prefers-color-scheme: dark){::ng-deep span.legend-label-text{color:#ccc!important}::ng-deep span.legend-label-text:hover{color:#fff!important}::ng-deep .ngx-charts text{fill:#fff!important}}.verticalContainer{overflow-y:hidden;overflow-x:auto;max-height:60vh}.horizontalContainer{overflow-x:hidden;overflow-y:auto;max-height:60vh}\n"], dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i2.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "component", type: i3.BarHorizontalComponent, selector: "ngx-charts-bar-horizontal", inputs: ["legend", "legendTitle", "legendPosition", "xAxis", "yAxis", "showXAxisLabel", "showYAxisLabel", "xAxisLabel", "yAxisLabel", "tooltipDisabled", "gradient", "showGridLines", "activeEntries", "schemeType", "trimXAxisTicks", "trimYAxisTicks", "rotateXAxisTicks", "maxXAxisTickLength", "maxYAxisTickLength", "xAxisTickFormatting", "yAxisTickFormatting", "xAxisTicks", "yAxisTicks", "barPadding", "roundDomains", "roundEdges", "xScaleMax", "xScaleMin", "showDataLabel", "dataLabelFormatting", "noBarWhenZero", "wrapTicks"], outputs: ["activate", "deactivate"] }, { kind: "component", type: i3.BarVerticalComponent, selector: "ngx-charts-bar-vertical", inputs: ["legend", "legendTitle", "legendPosition", "xAxis", "yAxis", "showXAxisLabel", "showYAxisLabel", "xAxisLabel", "yAxisLabel", "tooltipDisabled", "gradient", "showGridLines", "activeEntries", "schemeType", "trimXAxisTicks", "trimYAxisTicks", "rotateXAxisTicks", "maxXAxisTickLength", "maxYAxisTickLength", "xAxisTickFormatting", "yAxisTickFormatting", "xAxisTicks", "yAxisTicks", "barPadding", "roundDomains", "roundEdges", "yScaleMax", "yScaleMin", "showDataLabel", "dataLabelFormatting", "noBarWhenZero", "wrapTicks"], outputs: ["activate", "deactivate"] }, { kind: "component", type: i1.IonFabButton, selector: "ion-fab-button", inputs: ["activated", "closeIcon", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "show", "size", "target", "translucent", "type"] }, { kind: "component", type: i1.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "directive", type: i4.ExportDataDirective, selector: "[tapExportData]", inputs: ["exportedFileName", "dataToExport", "format"], outputs: ["exportDataError"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
TapVariableBarChartComponent = __decorate([
MonitoringAppGenComponent({
constraints: {
isNumber: 'YES',
},
}),
__metadata("design:paramtypes", [ElementRef,
NgZone,
ChangeDetectorRef, String, ModalController])
], TapVariableBarChartComponent);
export { TapVariableBarChartComponent };
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: TapVariableBarChartComponent, decorators: [{
type: Component,
args: [{ selector: 'tap-variable-bar-chart', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n [ngClass]=\"\n scrollableChart\n ? orientation == 'vertical'\n ? 'verticalContainer'\n : 'horizontalContainer'\n : {}\n \"\n>\n <div\n #containerRef\n [ngClass]=\"\n legendPosition === 'below' && legend ? 'belowLegend' : 'rightLegend'\n \"\n [ngSwitch]=\"orientation\"\n style=\"position: relative\"\n >\n <ngx-charts-bar-horizontal\n *ngSwitchCase=\"'horizontal'\"\n #chartsHor\n [view]=\"[containerRef.offsetWidth, containerRef.offsetHeight]\"\n [scheme]=\"colorScheme\"\n [results]=\"results\"\n [roundEdges]=\"roundEdges\"\n [showXAxisLabel]=\"showXAxisLabel\"\n [showYAxisLabel]=\"showYAxisLabel\"\n [xAxis]=\"xAxis\"\n [yAxisLabel]=\"yAxisLabel\"\n [yAxis]=\"yAxis\"\n [xAxisLabel]=\"xAxisLabel\"\n [legend]=\"legend\"\n [legendTitle]=\"legendTitle\"\n [legendPosition]=\"legendPosition\"\n [noBarWhenZero]=\"noBarWhenZero\"\n [xAxisTickFormatting]=\"xAxisTickFormatting\"\n [xScaleMax]=\"scaleMax\"\n [xScaleMin]=\"scaleMin\"\n [showGridLines]=\"showGridLines\"\n [trimXAxisTicks]=\"trimXAxisTicks\"\n [maxXAxisTickLength]=\"maxXAxisTickLength\"\n [trimYAxisTicks]=\"trimYAxisTicks\"\n [maxYAxisTickLength]=\"maxYAxisTickLength\"\n [animations]=\"animations\"\n [roundDomains]=\"roundDomains\"\n [roundEdges]=\"roundEdges\"\n [barPadding]=\"barPadding\"\n (select)=\"onSelect($event)\"\n >\n </ngx-charts-bar-horizontal>\n <ngx-charts-bar-vertical\n *ngSwitchCase=\"'vertical'\"\n #chartsVer\n [view]=\"[containerRef.offsetWidth, containerRef.offsetHeight]\"\n [noBarWhenZero]=\"noBarWhenZero\"\n [scheme]=\"colorScheme\"\n [results]=\"results\"\n [showXAxisLabel]=\"showXAxisLabel\"\n [showYAxisLabel]=\"showYAxisLabel\"\n [yAxisLabel]=\"yAxisLabel\"\n [xAxisLabel]=\"xAxisLabel\"\n [legend]=\"legend\"\n [legendTitle]=\"legendTitle\"\n [legendPosition]=\"legendPosition\"\n [xAxis]=\"xAxis\"\n [yAxis]=\"yAxis\"\n [yAxisTickFormatting]=\"xAxisTickFormatting\"\n [showGridLines]=\"showGridLines\"\n [trimXAxisTicks]=\"trimXAxisTicks\"\n [maxXAxisTickLength]=\"maxXAxisTickLength\"\n [trimYAxisTicks]=\"trimYAxisTicks\"\n [maxYAxisTickLength]=\"maxYAxisTickLength\"\n [animations]=\"animations\"\n [roundDomains]=\"roundDomains\"\n [roundEdges]=\"roundEdges\"\n [barPadding]=\"barPadding\"\n [yScaleMax]=\"scaleMax\"\n [yScaleMin]=\"scaleMin\"\n (select)=\"onSelect($event)\"\n >\n </ngx-charts-bar-vertical>\n <ion-fab-button\n id=\"exportFabButton\"\n size=\"small\"\n tapExportData\n [dataToExport]=\"results\"\n *ngIf=\"showExportButton\"\n [exportedFileName]=\"exportedFileName\"\n >\n <ion-icon name=\"download\"></ion-icon>\n </ion-fab-button>\n </div>\n</div>\n", styles: ["::ng-deep .horizontal-legend{overflow:auto!important}.belowLegend{max-height:50vh;width:100%;min-width:100%;margin-bottom:60px}.rightLegend{max-height:50vh;min-height:50vh;width:100%}#exportFabButton{position:absolute;top:10px;right:10px}@media (prefers-color-scheme: dark){::ng-deep span.legend-label-text{color:#ccc!important}::ng-deep span.legend-label-text:hover{color:#fff!important}::ng-deep .ngx-charts text{fill:#fff!important}}.verticalContainer{overflow-y:hidden;overflow-x:auto;max-height:60vh}.horizontalContainer{overflow-x:hidden;overflow-y:auto;max-height:60vh}\n"] }]
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }, { type: undefined, decorators: [{
type: Inject,
args: [PLATFORM_ID]
}] }, { type: i1.ModalController }]; }, propDecorators: { divContainer: [{
type: ViewChild,
args: ['containerRef']
}], barChartHor: [{
type: ViewChild,
args: ['chartsHor']
}], barChartVer: [{
type: ViewChild,
args: ['chartsVer']
}], orientation: [{
type: Input
}], legend: [{
type: Input
}], legendTitle: [{
type: Input
}], legendPosition: [{
type: Input
}], showGridLines: [{
type: Input
}], showDetails: [{
type: Input
}], showXAxis: [{
type: Input
}], xAxis: [{
type: Input
}], showXAxisLabel: [{
type: Input
}], xAxisLabel: [{
type: Input
}], showYAxis: [{
type: Input
}], yAxis: [{
type: Input
}], showYAxisLabel: [{
type: Input
}], yAxisLabel: [{
type: Input
}], trimXAxisTicks: [{
type: Input
}], maxXAxisTickLength: [{
type: Input
}], trimYAxisTicks: [{
type: Input
}], maxYAxisTickLength: [{
type: Input
}], animations: [{
type: Input
}], roundDomains: [{
type: Input
}], roundEdges: [{
type: Input
}], barPadding: [{
type: Input
}], noBarWhenZero: [{
type: Input
}], showExportButton: [{
type: Input
}], exportedFileName: [{
type: Input
}], variable: [{
type: Input
}], xAxisTickFormatting: [{
type: Input
}], history: [{
type: Input
}], valueCountLimit: [{
type: Input
}], input: [{
type: Input
}], data: [{
type: Input
}], scrollableChart: [{
type: Input
}], scaleMax: [{
type: Input
}], scaleMin: [{
type: Input
}], label: [{
type: Input
}], colorScheme: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFwLXZhcmlhYmxlLWJhci1jaGFydC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9pb3RpemUtaW9uaWMvbW9uaXRvcmluZy9zcmMvbGliL3VpLWNvbXBvbmVudHMvdGFwLXZhcmlhYmxlLWJhci1jaGFydC90YXAtdmFyaWFibGUtYmFyLWNoYXJ0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2lvdGl6ZS1pb25pYy9tb25pdG9yaW5nL3NyYy9saWIvdWktY29tcG9uZW50cy90YXAtdmFyaWFibGUtYmFyLWNoYXJ0L3RhcC12YXJpYWJsZS1iYXItY2hhcnQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFFTCx1QkFBdUIsRUFDdkIsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxVQUFVLEVBQ1YsTUFBTSxFQUNOLEtBQUssRUFDTCxNQUFNLEVBR04sV0FBVyxFQUNYLFNBQVMsR0FDVixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFakQsT0FBTyxFQUNMLHNCQUFzQixFQUN0QixvQkFBb0IsRUFDcEIsa0JBQWtCLEVBQ2xCLGNBQWMsR0FDZixNQUFNLHNCQUFzQixDQUFDO0FBQzlCLE9BQU8sRUFBRSxlQUFlLEVBQUUsT0FBTyxFQUFnQixhQUFhLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDN0UsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzNDLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ3RFLE9BQU8sRUFDTCxjQUFjLEdBR2YsTUFBTSxtQkFBbUIsQ0FBQztBQUUzQixPQUFPLEVBQUUsNkJBQTZCLEVBQUUsTUFBTSw4REFBOEQsQ0FBQzs7Ozs7O0FBYXRHLElBQU0sNEJB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SztnQkFJTixjQUFjO3NCQURiLEtBQUs7Z0JBSU4sYUFBYTtzQkFEWixLQUFLO2dCQUlOLFdBQVc7c0JBRFYsS0FBSztnQkFPRixTQUFTO3NCQURaLEtBQUs7Z0JBTU4sS0FBSztzQkFESixLQUFLO2dCQUlOLGNBQWM7c0JBRGIsS0FBSztnQkFJTixVQUFVO3NCQURULEtBQUs7Z0JBT0YsU0FBUztzQkFEWixLQUFLO2dCQU1OLEtBQUs7c0JBREosS0FBSztnQkFJTixjQUFjO3NCQURiLEtBQUs7Z0JBSU4sVUFBVTtzQkFEVCxLQUFLO2dCQUdHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBRUcsa0JBQWtCO3NCQUExQixLQUFLO2dCQUVHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBRUcsa0JBQWtCO3NCQUExQixLQUFLO2dCQUVHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBRUcsWUFBWTtzQkFBcEIsS0FBSztnQkFFRyxVQUFVO3NCQUFsQixLQUFLO2dCQUVHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBR04sYUFBYTtzQkFEWixLQUFLO2dCQUlOLGdCQUFnQjtzQkFEZixLQUFLO2dCQUlOLGdCQUFnQjtzQkFEZixLQUFLO2dCQUlGLFFBQVE7c0JBRFgsS0FBSztnQkFPRyxtQkFBbUI7c0JBQTNCLEtBQUs7Z0JBSUYsT0FBTztzQkFEVixLQUFLO2dCQU1GLGVBQWU7c0JBRGxCLEtBQUs7Z0JBU0YsS0FBSztzQkFEUixLQUFLO2dCQUtPLElBQUk7c0JBQWhCLEtBQUs7Z0JBSUcsZUFBZTtzQkFBdkIsS0FBSztnQkFHQyxRQUFRO3NCQURkLEtBQUs7Z0JBSUMsUUFBUTtzQkFEZCxLQUFLO2dCQUlGLEtBQUs7c0JBRFIsS0FBSztnQkFNTixXQUFXO3NCQURWLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBBZnRlckNvbnRlbnRDaGVja2VkLFxuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgRWxlbWVudFJlZixcbiAgSW5qZWN0LFxuICBJbnB1dCxcbiAgTmdab25lLFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgUExBVEZPUk1fSUQsXG4gIFZpZXdDaGlsZCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBNb2RhbENvbnRyb2xsZXIgfSBmcm9tICdAaW9uaWMvYW5ndWxhcic7XG5pbXBvcnQgeyBBYnN0cmFjdFZhcmlhYmxlIH0gZnJvbSAnQGlvdGl6ZS90YXAvZGF0YSc7XG5pbXBvcnQge1xuICBCYXJIb3Jpem9udGFsQ29tcG9uZW50LFxuICBCYXJWZXJ0aWNhbENvbXBvbmVudCxcbiAgQmFzZUNoYXJ0Q29tcG9uZW50LFxuICBMZWdlbmRQb3NpdGlvbixcbn0gZnJvbSAnQHN3aW1sYW5lL25neC1jaGFydHMnO1xuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0LCBTdWJqZWN0LCBTdWJzY3JpcHRpb24sIGNvbWJpbmVMYXRlc3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IE1vbml0b3JpbmdBcHBHZW5Db21wb25lbnQgfSBmcm9tICcuLi8uLi9tZXRhZGF0YS9kZWNvcmF0b3JzJztcbmltcG9ydCB7XG4gIENoYXJ0RGF0YU1vZGVsLFxuICBDaGFydElucHV0U2luZ2xlLFxuICBDaGFydElucHV0U3RyZWFtVmFyLFxufSBmcm9tICcuLi9DaGFydERhdGFNb2RlbCc7XG5pbXBvcnQgeyBPbkNoYXJ0U2VsZWN0RXZlbnQgfSBmcm9tICcuLi9zaGFyZWQtdHlwZXMnO1xuaW1wb3J0IHsgVGFwVmFyaWFibGVEYXRhUG9wdXBDb21wb25lbnQgfSBmcm9tICcuLi90YXAtdmFyaWFibGUtZGF0YS1wb3B1cC90YXAtdmFyaWFibGUtZGF0YS1wb3B1cC5jb21wb25lbnQnO1xuXG5ATW9uaXRvcmluZ0FwcEdlbkNvbXBvbmVudCh7XG4gIGNvbnN0cmFpbnRzOiB7XG4gICAgaXNOdW1iZXI6ICdZRVMnLFxuICB9LFxufSlcbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3RhcC12YXJpYWJsZS1iYXItY2hhcnQnLFxuICB0ZW1wbGF0ZVVybDogJy4vdGFwLXZhcmlhYmxlLWJhci1jaGFydC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3RhcC12YXJpYWJsZS1iYXItY2hhcnQuY29tcG9uZW50LnNjc3MnXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG59KVxuZXhwb3J0IGNsYXNzIFRhcFZhcmlhYmxlQmFyQ2hhcnRDb21wb25lbnRcbiAgZXh0ZW5kcyBCYXNlQ2hhcnRDb21wb25lbnRcbiAgaW1wbGVtZW50cyBBZnRlckNvbnRlbnRDaGVja2VkLCBPbkRlc3Ryb3ksIE9uSW5pdFxue1xuICBAVmlld0NoaWxkKCdjb250YWluZXJSZWYnKSBkaXZDb250YWluZXIhOiBFbGVtZW50UmVmO1xuICBAVmlld0NoaWxkKCdjaGFydHNIb3InKSBiYXJDaGFydEhvciE6IEJhckhvcml6b250YWxDb21wb25lbnQ7XG4gIEBWaWV3Q2hpbGQoJ2NoYXJ0c1ZlcicpIGJhckNoYXJ0VmVyITogQmFyVmVydGljYWxDb21wb25lbnQ7XG5cbiAgcmVzdWx0czogQ2hhcnRJbnB1dFNpbmdsZVtdID0gW107XG5cbiAgQElucHV0KClcbiAgb3JpZW50YXRpb24gPSAndmVydGljYWwnO1xuXG4gIEBJbnB1dCgpXG4gIGxlZ2VuZDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIEBJbnB1dCgpXG4gIGxlZ2VuZFRpdGxlPzogc3RyaW5nO1xuXG4gIEBJbnB1dCgpXG4gIGxlZ2VuZFBvc2l0aW9uOiBMZWdlbmRQb3NpdGlvbiA9IExlZ2VuZFBvc2l0aW9uLkJlbG93O1xuXG4gIEBJbnB1dCgpXG4gIHNob3dHcmlkTGluZXMgPSBmYWxzZTtcblxuICBASW5wdXQoKVxuICBzaG93RGV0YWlscyA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBAZGVwcmVjYXRlZCB1c2UgeEF4aXNcbiAgICovXG4gIEBJbnB1dCgpXG4gIHNldCBzaG93WEF4aXModjogYm9vbGVhbikge1xuICAgIHRoaXMueEF4aXMgPSB2O1xuICB9XG5cbiAgQElucHV0KClcbiAgeEF4aXM6IGJvb2xlYW4gPSB0cnVlO1xuXG4gIEBJbnB1dCgpXG4gIHNob3dYQXhpc0xhYmVsOiBib29sZWFuID0gZmFsc2U7XG5cbiAgQElucHV0KClcbiAgeEF4aXNMYWJlbCA9ICcnO1xuXG4gIC8qKlxuICAgKiBAZGVwcmVjYXRlZCB1c2UgeUF4aXNcbiAgICovXG4gIEBJbnB1dCgpXG4gIHNldCBzaG93WUF4aXModjogYm9vbGVhbikge1xuICAgIHRoaXMueUF4aXMgPSB2O1xuICB9XG5cbiAgQElucHV0KClcbiAgeUF4aXM6IGJvb2xlYW4gPSB0cnVlO1xuXG4gIEBJbnB1dCgpXG4gIHNob3dZQXhpc0xhYmVsOiBib29sZWFuID0gZmFsc2U7XG5cbiAgQElucHV0KClcbiAgeUF4aXNMYWJlbCA9ICcnO1xuXG4gIEBJbnB1dCgpIHRyaW1YQXhpc1RpY2tzPzogYm9vbGVhbjtcblxuICBASW5wdXQoKSBtYXhYQXhpc1RpY2tMZW5ndGg/OiBib29sZWFuO1xuXG4gIEBJbnB1dCgpIHRyaW1ZQXhpc1RpY2tzPzogYm9vbGVhbjtcblxuICBASW5wdXQoKSBtYXhZQXhpc1RpY2tMZW5ndGg/OiBib29sZWFuO1xuXG4gIEBJbnB1dCgpIGFuaW1hdGlvbnM6IGJvb2xlYW4gPSB0cnVlO1xuXG4gIEBJbnB1dCgpIHJvdW5kRG9tYWlucz86IGJvb2xlYW47XG5cbiAgQElucHV0KCkgcm91bmRFZGdlcyA9IHRydWU7XG5cbiAgQElucHV0KCkgYmFyUGFkZGluZz86IG51bWJlcjtcblxuICBASW5wdXQoKVxuICBub0JhcldoZW5aZXJvID0gZmFsc2U7XG5cbiAgQElucHV0KClcbiAgc2hvd0V4cG9ydEJ1dHRvbjogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIEBJbnB1dCgpXG4gIGV4cG9ydGVkRmlsZU5hbWU/OiBzdHJpbmc7XG5cbiAgQElucHV0KClcbiAgc2V0IHZhcmlhYmxlKFxuICAgIHZhcmlhYmxlT3JBcnJheTogQWJzdHJhY3RWYXJpYWJsZTxudW1iZXIgfCBudW1iZXJbXT4gfCB1bmRlZmluZWRcbiAgKSB7XG4gICAgdGhpcy5pbnB1dCA9IHRoaXMuY2hhcnRNb2RlbC5pbml0VmFyaWFibGUodmFyaWFibGVPckFycmF5KTtcbiAgfVxuXG4gIEBJbnB1dCgpIHhBeGlzVGlja0Zvcm1hdHRpbmc6IChpbnB1dDogYW55KSA9PiBzdHJpbmcgPVxuICAgIHRoaXMuZGVmYXVsdERhdGVUaWNrRm9ybWF0dGluZy5iaW5kKHRoaXMpO1xuXG4gIEBJbnB1dCgpXG4gIHNldCBoaXN0b3J5KGVuYWJsZTogYm9vbGVhbikge1xuICAgIHRoaXMuX2hpc3RvcnkubmV4dChlbmFibGUpO1xuICB9XG5cbiAgQElucHV0KClcbiAgc2V0IHZhbHVlQ291bnRMaW1pdChsaW1pdDogbnVtYmVyIHwgdW5kZWZpbmVkKSB7XG4gICAgaWYgKGxpbWl0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGxpbWl0ID0gMzA7XG4gICAgfVxuICAgIHRoaXMuX3ZhbHVlQ291bnRMaW1pdC5uZXh0KGxpbWl0KTtcbiAgfVxuXG4gIEBJbnB1dCgpXG4gIHNldCBpbnB1dChpbnB1dHM6IENoYXJ0SW5wdXRTdHJlYW1WYXJbXSkge1xuICAgIHRoaXMuX2lucHV0Lm5leHQoaW5wdXRzKTtcbiAgfVxuXG4gIEBJbnB1dCgpIHNldCBkYXRhKHJlc3VsdHM6IENoYXJ0SW5wdXRTaW5nbGVbXSkge1xuICAgIHRoaXMucmVzdWx0cyA9IHJlc3VsdHM7XG4gIH1cblxuICBASW5wdXQoKSBzY3JvbGxhYmxlQ2hhcnQgPSBmYWxzZTtcblxuICBASW5wdXQoKVxuICBwdWJsaWMgc2NhbGVNYXg/OiBudW1iZXI7XG5cbiAgQElucHV0KClcbiAgcHVibGljIHNjYWxlTWluPzogbnVtYmVyO1xuXG4gIEBJbnB1dCgpXG4gIHNldCBsYWJlbChpbmRleE9yQXJyYXk6IHN0cmluZyB8IHN0cmluZ1tdIHwgdW5kZWZpbmVkIHwgRnVuY3Rpb24pIHtcbiAgICB0aGlzLmNoYXJ0TW9kZWwuaW5pdExhYmVsKGluZGV4T3JBcnJheSk7XG4gIH1cblxuICBASW5wdXQoKVxuICBjb2xvclNjaGVtZSA9IHtcbiAgICBkb21haW46IFtcbiAgICAgICcjNURBREUyJyxcbiAgICAgICcjOUI1OUI2JyxcbiAgICAgICcjZjY5YjA1JyxcbiAgICAgICcjNUFBNDU0JyxcbiAgICAgICcjQTEwQTI4JyxcbiAgICAgICcjQzdCNDJDJyxcbiAgICAgICcjQUFBQUFBJyxcbiAgICBdLFxuICB9O1xuXG4gIHByaXZhdGUgX2hpc3RvcnkgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KHRydWUpO1xuXG4gIHByaXZhdGUgX3ZhbHVlQ291bnRMaW1pdCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8bnVtYmVyPigzMCk7XG5cbiAgcHJpdmF0ZSBfaW5wdXQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PENoYXJ0SW5wdXRTdHJlYW1WYXJbXT4oW10pO1xuXG4gIHByaXZhdGUgb2xkQ29sb3JTY2hlbWU6IGFueTtcblxuICBwcml2YXRlIGRlc3Ryb3llZCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgd2lkdGhDaGFydD86IG51bWJlcjtcblxuICBoZWlnaHRDaGFydD86IG51bWJlcjtcblxuICBwcml2YXRlIGNoYXJ0TW9kZWw6IENoYXJ0RGF0YU1vZGVsID0gbmV3IENoYXJ0RGF0YU1vZGVsKCk7XG4gIHByaXZhdGUgc3Vic2NyaXB0aW9uPzogU3Vic2NyaXB0aW9uO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIG15Q2hhcnRFbGVtZW50OiBFbGVtZW50UmVmLFxuICAgIHpvbmU6IE5nWm9uZSxcbiAgICBwdWJsaWMgY2Q6IENoYW5nZURldGVjdG9yUmVmLFxuICAgIEBJbmplY3QoUExBVEZPUk1fSUQpIHBsYXRmb3JtSWQ6IHN0cmluZyxcbiAgICBwcml2YXRlIG1vZGFsQ29udHJvbGxlcjogTW9kYWxDb250cm9sbGVyXG4gICkge1xuICAgIHN1cGVyKG15Q2hhcnRFbGVtZW50LCB6b25lLCBjZCwgcGxhdGZvcm1JZCk7XG4gIH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICBjb21iaW5lTGF0ZXN0KFt0aGlzLl92YWx1ZUNvdW50TGltaXQsIHRoaXMuX2lucHV0LCB0aGlzLl9oaXN0b3J5XSlcbiAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3llZCkpXG4gICAgICAuc3Vic2NyaWJlKChbdmFsdWVDb3VudExpbWl0LCBpbnB1dCwgaGlzdG9yeV0pID0+IHtcbiAgICAgICAgdGhpcy5jaGFydE1vZGVsLmRlc3Ryb3lDdXJyZW50U3ViKCk7XG4gICAgICAgIGlmIChoaXN0b3J5KSB7XG4gICAgICAgICAgdGhpcy5vbGRDb2xvclNjaGVtZSA9IHRoaXMuY29sb3JTY2hlbWU7XG4gICAgICAgICAgdGhpcy5jb2xvclNjaGVtZSA9IHsgZG9tYWluOiBbdGhpcy5jb2xvclNjaGVtZS5kb21haW5bMF1dIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKHRoaXMub2xkQ29sb3JTY2hlbWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhpcy5jb2xvclNjaGVtZSA9IHRoaXMub2xkQ29sb3JTY2hlbWU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuc3Vic2NyaXB0aW9uID0gdGhpcy5jaGFydE1vZGVsXG4gICAgICAgICAgLmRlZmluZUlucHV0U3RyZWFtU2luZ2xlKGlucHV0LCBoaXN0b3J5LCB2YWx1ZUNvdW50TGltaXQpXG4gICAgICAgICAgLnN1YnNjcmliZSgocmVzdWx0OiBDaGFydElucHV0U2luZ2xlW10pID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLnNjcm9sbGFibGVDaGFydCkge1xuICAgICAgICAgICAgICB0aGlzLnJlc2l6ZVRvU2Nyb2xsKHJlc3VsdC5sZW5ndGgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5yZXN1bHRzID0gcmVzdWx0IGFzIENoYXJ0SW5wdXRTaW5nbGVbXTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5jZC5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICB9KTtcbiAgfVxuXG4gIG5nQWZ0ZXJDb250ZW50Q2hlY2tlZCgpIHtcbiAgICB0aGlzLmNkLmRldGVjdENoYW5nZXMoKTtcbiAgICBpZiAoIXRoaXMuc2Nyb2xsYWJsZUNoYXJ0KSB7XG4gICAgICB0aGlzLndpZHRoQ2hhcnQgPSB0aGlzLmRpdkNvbnRhaW5lci5uYXRpdmVFbGVtZW50Lm9mZnNldFdpZHRoO1xuICAgICAgdGhpcy5oZWlnaHRDaGFydCA9IHRoaXMuZGl2Q29udGFpbmVyLm5hdGl2ZUVsZW1lbnQub2Zmc2V0SGVpZ2h0O1xuICAgIH1cbiAgfVxuXG4gIHJlc2l6ZVRvU2Nyb2xsKHNpemU6IG51bWJlcikge1xuICAgIGlmICh0aGlzLm9yaWVudGF0aW9uID09PSAndmVydGljYWwnKSB7XG4gICAgICBpZiAodGhpcy5kaXZDb250YWluZXIubmF0aXZlRWxlbWVudC5vZmZzZXRXaWR0aCA8PSBzaXplICogMTAwKSB7XG4gICAgICAgIHRoaXMuYmFyQ2hhcnRWZXIudmlldyA9IFtcbiAgICAgICAgICBzaXplICogMTAwLFxuICAgICAgICAgIHRoaXMuZGl2Q29udGFpbmVyLm5hdGl2ZUVsZW1lbnQub2Zmc2V0SGVpZ2h0LFxuICAgICAgICBdO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodGhpcy5vcmllbnRhdGlvbiA9PT0gJ2hvcml6b250YWwnKSB7XG4gICAgICBpZiAodGhpcy5kaXZDb250YWluZXIubmF0aXZlRWxlbWVudC5vZmZzZXRIZWlnaHQgPD0gc2l6ZSAqIDEwMCkge1xuICAgICAgICB0aGlzLmJhckNoYXJ0SG9yLnZpZXcgPSBbXG4gICAgICAgICAgdGhpcy5kaXZDb250YWluZXIubmF0aXZlRWxlbWVudC5vZmZzZXRXaWR0aCxcbiAgICAgICAgICBzaXplICogMTAwLFxuICAgICAgICBdO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIG9uU2VsZWN0KGV2ZW50OiBPbkNoYXJ0U2VsZWN0RXZlbnQpIHtcbiAgICBpZiAodHlwZW9mIGV2ZW50ID09PSAnb2JqZWN0Jykge1xuICAgICAgaWYgKHRoaXMuc2hvd0RldGFpbHMpIHtcbiAgICAgICAgdGhpcy5jaGFydE1vZGVsXG4gICAgICAgICAgLnNob3dEZXRhaWwoXG4gICAgICAgICAgICBldmVudCxcbiAgICAgICAgICAgIHRoaXMubW9kYWxDb250cm9sbGVyLFxuICAgICAgICAgICAgVGFwVmFyaWFibGVEYXRhUG9wdXBDb21wb25lbnRcbiAgICAgICAgICApXG4gICAgICAgICAgLmNhdGNoKChlcnIpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGVycik7XG4gICAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZGVmYXVsdERhdGVUaWNrRm9ybWF0dGluZyh2YWw6IGFueSk6IHN0cmluZyB7XG4gICAgaWYgKHZhbC50aW1lKSB7XG4gICAgICByZXR1cm4gbmV3IERhdGUodmFsLnRpbWUpLnRvTG9jYWxlRGF0ZVN0cmluZygpO1xuICAgIH1cbiAgICByZXR1cm4gdmFsO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5zdWJzY3JpcHRpb24/LnVuc3Vic2NyaWJlKCk7XG4gICAgdGhpcy5jaGFydE1vZGVsLmRlc3Ryb3lDdXJyZW50U3ViKCk7XG4gIH1cbn1cbiIsIjxkaXZcbiAgW25nQ2xhc3NdPVwiXG4gICAgc2Nyb2xsYWJsZUNoYXJ0XG4gICAgICA/IG9yaWVudGF0aW9uID09ICd2ZXJ0aWNhbCdcbiAgICAgICAgPyAndmVydGljYWxDb250YWluZXInXG4gICAgICAgIDogJ2hvcml6b250YWxDb250YWluZXInXG4gICAgICA6IHt9XG4gIFwiXG4+XG4gIDxkaXZcbiAgICAjY29udGFpbmVyUmVmXG4gICAgW25nQ2xhc3NdPVwiXG4gICAgICBsZWdlbmRQb3NpdGlvbiA9PT0gJ2JlbG93JyAmJiBsZWdlbmQgPyAnYmVsb3dMZWdlbmQnIDogJ3JpZ2h0TGVnZW5kJ1xuICAgIFwiXG4gICAgW25nU3dpdGNoXT1cIm9yaWVudGF0aW9uXCJcbiAgICBzdHlsZT1cInBvc2l0aW9uOiByZWxhdGl2ZVwiXG4gID5cbiAgICA8bmd4LWNoYXJ0cy1iYXItaG9yaXpvbnRhbFxuICAgICAgKm5nU3dpdGNoQ2FzZT1cIidob3Jpem9udGFsJ1wiXG4gICAgICAjY2hhcnRzSG9yXG4gICAgICBbdmlld109XCJbY29udGFpbmVyUmVmLm9mZnNldFdpZHRoLCBjb250YWluZXJSZWYub2Zmc2V0SGVpZ2h0XVwiXG4gICAgICBbc2NoZW1lXT1cImNvbG9yU2NoZW1lXCJcbiAgICAgIFtyZXN1bHRzXT1cInJlc3VsdHNcIlxuICAgICAgW3JvdW5kRWRnZXNdPVwicm91bmRFZGdlc1wiXG4gICAgICBbc2hvd1hBeGlzTGFiZWxdPVwic2hvd1hBeGlzTGFiZWxcIlxuICAgICAgW3Nob3dZQXhpc0xhYmVsXT1cInNob3dZQXhpc0xhYmVsXCJcbiAgICAgIFt4QXhpc109XCJ4QXhpc1wiXG4gICAgICBbeUF4aXNMYWJlbF09XCJ5QXhpc0xhYmVsXCJcbiAgICAgIFt5QXhpc109XCJ5QXhpc1wiXG4gICAgICBbeEF4aXNMYWJlbF09XCJ4QXhpc0xhYmVsXCJcbiAgICAgIFtsZWdlbmRdPVwibGVnZW5kXCJcbiAgICAgIFtsZWdlbmRUaXRsZV09XCJsZWdlbmRUaXRsZVwiXG4gICAgICBbbGVnZW5kUG9zaXRpb25dPVwibGVnZW5kUG9zaXRpb25cIlxuICAgICAgW25vQmFyV2hlblplcm9dPVwibm9CYXJXaGVuWmVyb1wiXG4gICAgICBbeEF4aXNUaWNrRm9ybWF0dGluZ109XCJ4QXhpc1RpY2tGb3JtYXR0aW5nXCJcbiAgICAgIFt4U2NhbGVNYXhdPVwic2NhbGVNYXhcIlxuICAgICAgW3hTY2FsZU1pbl09XCJzY2FsZU1pblwiXG4gICAgICBbc2hvd0dyaWRMaW5lc109XCJzaG93R3JpZExpbmVzXCJcbiAgICAgIFt0cmltWEF4aXNUaWNrc109XCJ0cmltWEF4aXNUaWNrc1wiXG4gICAgICBbbWF4WEF4aXNUaWNrTGVuZ3RoXT1cIm1heFhBeGlzVGlja0xlbmd0aFwiXG4gICAgICBbdHJpbVlBeGlzVGlja3NdPVwidHJpbVlBeGlzVGlja3NcIlxuICAgICAgW21heFlBeGlzVGlja0xlbmd0aF09XCJtYXhZQXhpc1RpY2tMZW5ndGhcIlxuICAgICAgW2FuaW1hdGlvbnNdPVwiYW5pbWF0aW9uc1wiXG4gICAgICBbcm91bmREb21haW5zXT1cInJvdW5kRG9tYWluc1wiXG4gICAgICBbcm91bmRFZGdlc109XCJyb3VuZEVkZ2VzXCJcbiAgICAgIFtiYXJQYWRkaW5nXT1cImJhclBhZGRpbmdcIlxuICAgICAgKHNlbGVjdCk9XCJvblNlbGVjdCgkZXZlbnQpXCJcbiAgICA+XG4gICAgPC9uZ3gtY2hhcnRzLWJhci1ob3Jpem9udGFsPlxuICAgIDxuZ3gtY2hhcnRzLWJhci12ZXJ0aWNhbFxuICAgICAgKm5nU3dpdGNoQ2FzZT1cIid2ZXJ0aWNhbCdcIlxuICAgICAgI2NoYXJ0c1ZlclxuICAgICAgW3ZpZXddPVwiW2NvbnRhaW5lclJlZi5vZmZzZXRXaWR0aCwgY29udGFpbmVyUmVmLm9mZnNldEhlaWdodF1cIlxuICAgICAgW25vQmFyV2hlblplcm9dPVwibm9CYXJXaGVuWmVyb1wiXG4gICAgICBbc2NoZW1lXT1cImNvbG9yU2NoZW1lXCJcbiAgICAgIFtyZXN1bHRzXT1cInJlc3VsdHNcIlxuICAgICAgW3Nob3dYQXhpc0xhYmVsXT1cInNob3dYQXhpc0xhYmVsXCJcbiAgICAgIFtzaG93WUF4aXNMYWJlbF09XCJzaG93WUF4aXNMYWJlbFwiXG4gICAgICBbeUF4aXNMYWJlbF09XCJ5QXhpc0xhYmVsXCJcbiAgICAgIFt4QXhpc0xhYmVsXT1cInhBeGlzTGFiZWxcIlxuICAgICAgW2xlZ2VuZF09XCJsZWdlbmRcIlxuICAgICAgW2xlZ2VuZFRpdGxlXT1cImxlZ2VuZFRpdGxlXCJcbiAgICAgIFtsZWdlbmRQb3NpdGlvbl09XCJsZWdlbmRQb3NpdGlvblwiXG4gICAgICBbeEF4aXNdPVwieEF4aXNcIlxuICAgICAgW3lBeGlzXT1cInlBeGlzXCJcbiAgICAgIFt5QXhpc1RpY2tGb3JtYXR0aW5nXT1cInhBeGlzVGlja0Zvcm1hdHRpbmdcIlxuICAgICAgW3Nob3dHcmlkTGluZXNdPVwic2hvd0dyaWRMaW5lc1wiXG4gICAgICBbdHJpbVhBeGlzVGlja3NdPVwidHJpbVhBeGlzVGlja3NcIlxuICAgICAgW21heFhBeGlzVGlja0xlbmd0aF09XCJtYXhYQXhpc1RpY2tMZW5ndGhcIlxuICAgICAgW3RyaW1ZQXhpc1RpY2tzXT1cInRyaW1ZQXhpc1RpY2tzXCJcbiAgICAgIFttYXhZQXhpc1RpY2tMZW5ndGhdPVwibWF4WUF4aXNUaWNrTGVuZ3RoXCJcbiAgICAgIFthbmltYXRpb25zXT1cImFuaW1hdGlvbnNcIlxuICAgICAgW3JvdW5kRG9tYWluc109XCJyb3VuZERvbWFpbnNcIlxuICAgICAgW3JvdW5kRWRnZXNdPVwicm91bmRFZGdlc1wiXG4gICAgICBbYmFyUGFkZGluZ109XCJiYXJQYWRkaW5nXCJcbiAgICAgIFt5U2NhbGVNYXhdPVwic2NhbGVNYXhcIlxuICAgICAgW3lTY2FsZU1pbl09XCJzY2FsZU1pblwiXG4gICAgICAoc2VsZWN0KT1cIm9uU2VsZWN0KCRldmVudClcIlxuICAgID5cbiAgICA8L25neC1jaGFydHMtYmFyLXZlcnRpY2FsPlxuICAgIDxpb24tZmFiLWJ1dHRvblxuICAgICAgaWQ9XCJleHBvcnRGYWJCdXR0b25cIlxuICAgICAgc2l6ZT1cInNtYWxsXCJcbiAgICAgIHRhcEV4cG9ydERhdGFcbiAgICAgIFtkYXRhVG9FeHBvcnRdPVwicmVzdWx0c1wiXG4gICAgICAqbmdJZj1cInNob3dFeHBvcnRCdXR0b25cIlxuICAgICAgW2V4cG9ydGVkRmlsZU5hbWVdPVwiZXhwb3J0ZWRGaWxlTmFtZVwiXG4gICAgPlxuICAgICAgPGlvbi1pY29uIG5hbWU9XCJkb3dubG9hZFwiPjwvaW9uLWljb24+XG4gICAgPC9pb24tZmFiLWJ1dHRvbj5cbiAgPC9kaXY+XG48L2Rpdj5cbiJdfQ==