ng-zorro-antd
Version:
An enterprise-class UI components based on Ant Design and Angular
519 lines • 50.3 kB
JavaScript
/**
* @fileoverview added by tsickle
* Generated from: progress.component.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { __decorate, __metadata } from "tslib";
/**
* @license
* Copyright Alibaba.com All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
*/
import { ChangeDetectionStrategy, Component, Input, ViewEncapsulation } from '@angular/core';
import { NzConfigService, WithConfig } from 'ng-zorro-antd/core/config';
import { InputNumber, isNotNil } from 'ng-zorro-antd/core/util';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { handleCircleGradient, handleLinearGradient } from './utils';
/** @type {?} */
var gradientIdSeed = 0;
/** @type {?} */
var NZ_CONFIG_COMPONENT_NAME = 'progress';
/** @type {?} */
var statusIconNameMap = new Map([
['success', 'check'],
['exception', 'close']
]);
/** @type {?} */
var statusColorMap = new Map([
['normal', '#108ee9'],
['exception', '#ff5500'],
['success', '#87d068']
]);
/** @type {?} */
var defaultFormatter = (/**
* @param {?} p
* @return {?}
*/
function (p) { return p + "%"; });
var ɵ0 = defaultFormatter;
var NzProgressComponent = /** @class */ (function () {
function NzProgressComponent(nzConfigService) {
this.nzConfigService = nzConfigService;
this.nzShowInfo = true;
this.nzWidth = 132;
this.nzStrokeColor = undefined;
this.nzSize = 'default';
this.nzPercent = 0;
this.nzStrokeWidth = undefined;
this.nzGapDegree = undefined;
this.nzType = 'line';
this.nzGapPosition = 'top';
this.nzStrokeLinecap = 'round';
this.steps = [];
/**
* Gradient style when `nzType` is `line`.
*/
this.lineGradient = null;
/**
* If user uses gradient color.
*/
this.isGradient = false;
/**
* If the linear progress is a step progress.
*/
this.isSteps = false;
/**
* Each progress whose `nzType` is circle or dashboard should have unique id to
* define `<linearGradient>`.
*/
this.gradientId = gradientIdSeed++;
/**
* Paths to rendered in the template.
*/
this.progressCirclePath = [];
this.trailPathStyle = null;
this.trackByFn = (/**
* @param {?} index
* @return {?}
*/
function (index) { return "" + index; });
this.cachedStatus = 'normal';
this.inferredStatus = 'normal';
this.destroy$ = new Subject();
}
Object.defineProperty(NzProgressComponent.prototype, "formatter", {
get: /**
* @return {?}
*/
function () {
return this.nzFormat || defaultFormatter;
},
enumerable: true,
configurable: true
});
Object.defineProperty(NzProgressComponent.prototype, "status", {
get: /**
* @return {?}
*/
function () {
return this.nzStatus || this.inferredStatus;
},
enumerable: true,
configurable: true
});
Object.defineProperty(NzProgressComponent.prototype, "strokeWidth", {
get: /**
* @return {?}
*/
function () {
return this.nzStrokeWidth || (this.nzType === 'line' && this.nzSize !== 'small' ? 8 : 6);
},
enumerable: true,
configurable: true
});
Object.defineProperty(NzProgressComponent.prototype, "isCircleStyle", {
get: /**
* @return {?}
*/
function () {
return this.nzType === 'circle' || this.nzType === 'dashboard';
},
enumerable: true,
configurable: true
});
/**
* @param {?} changes
* @return {?}
*/
NzProgressComponent.prototype.ngOnChanges = /**
* @param {?} changes
* @return {?}
*/
function (changes) {
var nzSteps = changes.nzSteps, nzGapPosition = changes.nzGapPosition, nzStrokeLinecap = changes.nzStrokeLinecap, nzStrokeColor = changes.nzStrokeColor, nzGapDegree = changes.nzGapDegree, nzType = changes.nzType, nzStatus = changes.nzStatus, nzPercent = changes.nzPercent, nzSuccessPercent = changes.nzSuccessPercent;
if (nzStatus) {
this.cachedStatus = this.nzStatus || this.cachedStatus;
}
if (nzPercent || nzSuccessPercent) {
/** @type {?} */
var fillAll = parseInt(this.nzPercent.toString(), 10) >= 100;
if (fillAll) {
if ((isNotNil(this.nzSuccessPercent) && (/** @type {?} */ (this.nzSuccessPercent)) >= 100) || this.nzSuccessPercent === undefined) {
this.inferredStatus = 'success';
}
}
else {
this.inferredStatus = this.cachedStatus;
}
}
if (nzStatus || nzPercent || nzSuccessPercent) {
this.updateIcon();
}
if (nzStrokeColor) {
this.setStrokeColor();
}
if (nzGapPosition || nzStrokeLinecap || nzGapDegree || nzType || nzPercent || nzStrokeColor) {
this.getCirclePaths();
}
if (nzSteps) {
this.isSteps = isNotNil(nzSteps.currentValue);
this.getSteps();
}
};
/**
* @return {?}
*/
NzProgressComponent.prototype.ngOnInit = /**
* @return {?}
*/
function () {
var _this = this;
this.nzConfigService
.getConfigChangeEventForComponent(NZ_CONFIG_COMPONENT_NAME)
.pipe(takeUntil(this.destroy$))
.subscribe((/**
* @return {?}
*/
function () {
_this.updateIcon();
_this.setStrokeColor();
_this.getCirclePaths();
}));
};
/**
* @return {?}
*/
NzProgressComponent.prototype.ngOnDestroy = /**
* @return {?}
*/
function () {
this.destroy$.next();
this.destroy$.complete();
};
/**
* @private
* @return {?}
*/
NzProgressComponent.prototype.updateIcon = /**
* @private
* @return {?}
*/
function () {
/** @type {?} */
var ret = statusIconNameMap.get(this.status);
this.icon = ret ? ret + (this.isCircleStyle ? '-o' : '-circle-fill') : '';
};
/**
* Calculate step render configs.
*/
/**
* Calculate step render configs.
* @private
* @return {?}
*/
NzProgressComponent.prototype.getSteps = /**
* Calculate step render configs.
* @private
* @return {?}
*/
function () {
/** @type {?} */
var current = Math.floor((/** @type {?} */ (this.nzSteps)) * (this.nzPercent / 100));
/** @type {?} */
var stepWidth = this.nzSize === 'small' ? 2 : 14;
for (var i = 0; i < (/** @type {?} */ (this.nzSteps)); i++) {
/** @type {?} */
var color = void 0;
if (i <= current - 1) {
color = this.nzStrokeColor;
}
/** @type {?} */
var stepStyle = {
backgroundColor: "" + color,
width: stepWidth + "px",
height: this.strokeWidth + "px"
};
this.steps.push(stepStyle);
}
};
/**
* Calculate paths when the type is circle or dashboard.
*/
/**
* Calculate paths when the type is circle or dashboard.
* @private
* @return {?}
*/
NzProgressComponent.prototype.getCirclePaths = /**
* Calculate paths when the type is circle or dashboard.
* @private
* @return {?}
*/
function () {
var _this = this;
if (!this.isCircleStyle) {
return;
}
/** @type {?} */
var values = isNotNil(this.nzSuccessPercent) ? [(/** @type {?} */ (this.nzSuccessPercent)), this.nzPercent] : [this.nzPercent];
// Calculate shared styles.
/** @type {?} */
var radius = 50 - this.strokeWidth / 2;
/** @type {?} */
var gapPosition = this.nzGapPosition || (this.nzType === 'circle' ? 'top' : 'bottom');
/** @type {?} */
var len = Math.PI * 2 * radius;
/** @type {?} */
var gapDegree = this.nzGapDegree || (this.nzType === 'circle' ? 0 : 75);
/** @type {?} */
var beginPositionX = 0;
/** @type {?} */
var beginPositionY = -radius;
/** @type {?} */
var endPositionX = 0;
/** @type {?} */
var endPositionY = radius * -2;
switch (gapPosition) {
case 'left':
beginPositionX = -radius;
beginPositionY = 0;
endPositionX = radius * 2;
endPositionY = 0;
break;
case 'right':
beginPositionX = radius;
beginPositionY = 0;
endPositionX = radius * -2;
endPositionY = 0;
break;
case 'bottom':
beginPositionY = radius;
endPositionY = radius * 2;
break;
default:
}
this.pathString = "M 50,50 m " + beginPositionX + "," + beginPositionY + "\n a " + radius + "," + radius + " 0 1 1 " + endPositionX + "," + -endPositionY + "\n a " + radius + "," + radius + " 0 1 1 " + -endPositionX + "," + endPositionY;
this.trailPathStyle = {
strokeDasharray: len - gapDegree + "px " + len + "px",
strokeDashoffset: "-" + gapDegree / 2 + "px",
transition: 'stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s'
};
// Calculate styles for each path.
this.progressCirclePath = values
.map((/**
* @param {?} value
* @param {?} index
* @return {?}
*/
function (value, index) {
/** @type {?} */
var isSuccessPercent = values.length === 2 && index === 0;
return {
stroke: _this.isGradient && !isSuccessPercent ? "url(#gradient-" + _this.gradientId + ")" : null,
strokePathStyle: {
stroke: !_this.isGradient ? (isSuccessPercent ? statusColorMap.get('success') : ((/** @type {?} */ (_this.nzStrokeColor)))) : null,
transition: 'stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s',
strokeDasharray: ((value || 0) / 100) * (len - gapDegree) + "px " + len + "px",
strokeDashoffset: "-" + gapDegree / 2 + "px"
}
};
}))
.reverse();
};
/**
* @private
* @return {?}
*/
NzProgressComponent.prototype.setStrokeColor = /**
* @private
* @return {?}
*/
function () {
/** @type {?} */
var color = this.nzStrokeColor;
/** @type {?} */
var isGradient = (this.isGradient = !!color && typeof color !== 'string');
if (isGradient && !this.isCircleStyle) {
this.lineGradient = handleLinearGradient((/** @type {?} */ (color)));
}
else if (isGradient && this.isCircleStyle) {
this.circleGradient = handleCircleGradient((/** @type {?} */ (this.nzStrokeColor)));
}
else {
this.lineGradient = null;
this.circleGradient = [];
}
};
NzProgressComponent.decorators = [
{ type: Component, args: [{
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
selector: 'nz-progress',
exportAs: 'nzProgress',
preserveWhitespaces: false,
template: "\n <ng-template #progressInfoTemplate>\n <span class=\"ant-progress-text\" *ngIf=\"nzShowInfo\">\n <ng-container *ngIf=\"(status === 'exception' || status === 'success') && !nzFormat; else formatTemplate\">\n <i nz-icon [nzType]=\"icon\"></i>\n </ng-container>\n <ng-template #formatTemplate>\n <ng-container *nzStringTemplateOutlet=\"formatter; context: { $implicit: nzPercent }; let formatter\">\n {{ formatter(nzPercent) }}\n </ng-container>\n </ng-template>\n </span>\n </ng-template>\n\n <div\n [ngClass]=\"'ant-progress ant-progress-status-' + status\"\n [class.ant-progress-line]=\"nzType == 'line'\"\n [class.ant-progress-small]=\"nzSize == 'small'\"\n [class.ant-progress-show-info]=\"nzShowInfo\"\n [class.ant-progress-circle]=\"isCircleStyle\"\n [class.ant-progress-steps]=\"isSteps\"\n >\n <!-- line progress -->\n <div *ngIf=\"nzType === 'line'\">\n <ng-container *ngIf=\"!isSteps\">\n <div class=\"ant-progress-outer\" *ngIf=\"!isSteps\">\n <div class=\"ant-progress-inner\">\n <div\n class=\"ant-progress-bg\"\n [style.width.%]=\"nzPercent\"\n [style.border-radius]=\"nzStrokeLinecap === 'round' ? '100px' : '0'\"\n [style.background]=\"!isGradient ? nzStrokeColor : null\"\n [style.background-image]=\"isGradient ? lineGradient : null\"\n [style.height.px]=\"strokeWidth\"\n ></div>\n <div\n *ngIf=\"nzSuccessPercent || nzSuccessPercent === 0\"\n class=\"ant-progress-success-bg\"\n [style.width.%]=\"nzSuccessPercent\"\n [style.border-radius]=\"nzStrokeLinecap === 'round' ? '100px' : '0'\"\n [style.height.px]=\"strokeWidth\"\n ></div>\n </div>\n </div>\n <ng-template [ngTemplateOutlet]=\"progressInfoTemplate\"></ng-template>\n </ng-container>\n <!-- Step style progress -->\n <div class=\"ant-progress-steps-outer\" *ngIf=\"isSteps\">\n <div *ngFor=\"let step of steps; let i = index\" class=\"ant-progress-steps-item\" [ngStyle]=\"step\"></div>\n <ng-template [ngTemplateOutlet]=\"progressInfoTemplate\"></ng-template>\n </div>\n </div>\n\n <!-- circle / dashboard progress -->\n <div\n [style.width.px]=\"this.nzWidth\"\n [style.height.px]=\"this.nzWidth\"\n [style.fontSize.px]=\"this.nzWidth * 0.15 + 6\"\n class=\"ant-progress-inner\"\n [class.ant-progress-circle-gradient]=\"isGradient\"\n *ngIf=\"isCircleStyle\"\n >\n <svg class=\"ant-progress-circle \" viewBox=\"0 0 100 100\">\n <defs *ngIf=\"isGradient\">\n <linearGradient [id]=\"'gradient-' + gradientId\" x1=\"100%\" y1=\"0%\" x2=\"0%\" y2=\"0%\">\n <stop *ngFor=\"let i of circleGradient\" [attr.offset]=\"i.offset\" [attr.stop-color]=\"i.color\"></stop>\n </linearGradient>\n </defs>\n <path\n class=\"ant-progress-circle-trail\"\n stroke=\"#f3f3f3\"\n fill-opacity=\"0\"\n [attr.stroke-width]=\"strokeWidth\"\n [attr.d]=\"pathString\"\n [ngStyle]=\"trailPathStyle\"\n ></path>\n <path\n *ngFor=\"let p of progressCirclePath; trackBy: trackByFn\"\n class=\"ant-progress-circle-path\"\n fill-opacity=\"0\"\n [attr.d]=\"pathString\"\n [attr.stroke-linecap]=\"nzStrokeLinecap\"\n [attr.stroke]=\"p.stroke\"\n [attr.stroke-width]=\"nzPercent ? strokeWidth : 0\"\n [ngStyle]=\"p.strokePathStyle\"\n ></path>\n </svg>\n <ng-template [ngTemplateOutlet]=\"progressInfoTemplate\"></ng-template>\n </div>\n </div>\n "
}] }
];
/** @nocollapse */
NzProgressComponent.ctorParameters = function () { return [
{ type: NzConfigService }
]; };
NzProgressComponent.propDecorators = {
nzShowInfo: [{ type: Input }],
nzWidth: [{ type: Input }],
nzStrokeColor: [{ type: Input }],
nzSize: [{ type: Input }],
nzFormat: [{ type: Input }],
nzSuccessPercent: [{ type: Input }],
nzPercent: [{ type: Input }],
nzStrokeWidth: [{ type: Input }],
nzGapDegree: [{ type: Input }],
nzStatus: [{ type: Input }],
nzType: [{ type: Input }],
nzGapPosition: [{ type: Input }],
nzStrokeLinecap: [{ type: Input }],
nzSteps: [{ type: Input }]
};
__decorate([
WithConfig(NZ_CONFIG_COMPONENT_NAME),
__metadata("design:type", Boolean)
], NzProgressComponent.prototype, "nzShowInfo", void 0);
__decorate([
WithConfig(NZ_CONFIG_COMPONENT_NAME),
__metadata("design:type", Object)
], NzProgressComponent.prototype, "nzStrokeColor", void 0);
__decorate([
WithConfig(NZ_CONFIG_COMPONENT_NAME),
__metadata("design:type", String)
], NzProgressComponent.prototype, "nzSize", void 0);
__decorate([
InputNumber(),
__metadata("design:type", Number)
], NzProgressComponent.prototype, "nzSuccessPercent", void 0);
__decorate([
InputNumber(),
__metadata("design:type", Number)
], NzProgressComponent.prototype, "nzPercent", void 0);
__decorate([
WithConfig(NZ_CONFIG_COMPONENT_NAME), InputNumber(),
__metadata("design:type", Number)
], NzProgressComponent.prototype, "nzStrokeWidth", void 0);
__decorate([
WithConfig(NZ_CONFIG_COMPONENT_NAME), InputNumber(),
__metadata("design:type", Number)
], NzProgressComponent.prototype, "nzGapDegree", void 0);
__decorate([
WithConfig(NZ_CONFIG_COMPONENT_NAME),
__metadata("design:type", String)
], NzProgressComponent.prototype, "nzGapPosition", void 0);
__decorate([
WithConfig(NZ_CONFIG_COMPONENT_NAME),
__metadata("design:type", String)
], NzProgressComponent.prototype, "nzStrokeLinecap", void 0);
__decorate([
InputNumber(),
__metadata("design:type", Number)
], NzProgressComponent.prototype, "nzSteps", void 0);
return NzProgressComponent;
}());
export { NzProgressComponent };
if (false) {
/** @type {?} */
NzProgressComponent.ngAcceptInputType_nzSuccessPercent;
/** @type {?} */
NzProgressComponent.ngAcceptInputType_nzPercent;
/** @type {?} */
NzProgressComponent.ngAcceptInputType_nzStrokeWidth;
/** @type {?} */
NzProgressComponent.ngAcceptInputType_nzGapDegree;
/** @type {?} */
NzProgressComponent.ngAcceptInputType_nzSteps;
/** @type {?} */
NzProgressComponent.prototype.nzShowInfo;
/** @type {?} */
NzProgressComponent.prototype.nzWidth;
/** @type {?} */
NzProgressComponent.prototype.nzStrokeColor;
/** @type {?} */
NzProgressComponent.prototype.nzSize;
/** @type {?} */
NzProgressComponent.prototype.nzFormat;
/** @type {?} */
NzProgressComponent.prototype.nzSuccessPercent;
/** @type {?} */
NzProgressComponent.prototype.nzPercent;
/** @type {?} */
NzProgressComponent.prototype.nzStrokeWidth;
/** @type {?} */
NzProgressComponent.prototype.nzGapDegree;
/** @type {?} */
NzProgressComponent.prototype.nzStatus;
/** @type {?} */
NzProgressComponent.prototype.nzType;
/** @type {?} */
NzProgressComponent.prototype.nzGapPosition;
/** @type {?} */
NzProgressComponent.prototype.nzStrokeLinecap;
/** @type {?} */
NzProgressComponent.prototype.nzSteps;
/** @type {?} */
NzProgressComponent.prototype.steps;
/**
* Gradient style when `nzType` is `line`.
* @type {?}
*/
NzProgressComponent.prototype.lineGradient;
/**
* If user uses gradient color.
* @type {?}
*/
NzProgressComponent.prototype.isGradient;
/**
* If the linear progress is a step progress.
* @type {?}
*/
NzProgressComponent.prototype.isSteps;
/**
* Each progress whose `nzType` is circle or dashboard should have unique id to
* define `<linearGradient>`.
* @type {?}
*/
NzProgressComponent.prototype.gradientId;
/**
* Paths to rendered in the template.
* @type {?}
*/
NzProgressComponent.prototype.progressCirclePath;
/** @type {?} */
NzProgressComponent.prototype.circleGradient;
/** @type {?} */
NzProgressComponent.prototype.trailPathStyle;
/** @type {?} */
NzProgressComponent.prototype.pathString;
/** @type {?} */
NzProgressComponent.prototype.icon;
/** @type {?} */
NzProgressComponent.prototype.trackByFn;
/**
* @type {?}
* @private
*/
NzProgressComponent.prototype.cachedStatus;
/**
* @type {?}
* @private
*/
NzProgressComponent.prototype.inferredStatus;
/**
* @type {?}
* @private
*/
NzProgressComponent.prototype.destroy$;
/** @type {?} */
NzProgressComponent.prototype.nzConfigService;
}
export { ɵ0 };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvZ3Jlc3MuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vbmctem9ycm8tYW50ZC9wcm9ncmVzcy8iLCJzb3VyY2VzIjpbInByb2dyZXNzLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7O0FBUUEsT0FBTyxFQUFFLHVCQUF1QixFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQStDLGlCQUFpQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzFJLE9BQU8sRUFBRSxlQUFlLEVBQUUsVUFBVSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFFeEUsT0FBTyxFQUFFLFdBQVcsRUFBRSxRQUFRLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQy9CLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQWMzQyxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxTQUFTLENBQUM7O0lBRWpFLGNBQWMsR0FBRyxDQUFDOztJQUVoQix3QkFBd0IsR0FBRyxVQUFVOztJQUNyQyxpQkFBaUIsR0FBRyxJQUFJLEdBQUcsQ0FBQztJQUNoQyxDQUFDLFNBQVMsRUFBRSxPQUFPLENBQUM7SUFDcEIsQ0FBQyxXQUFXLEVBQUUsT0FBTyxDQUFDO0NBQ3ZCLENBQUM7O0lBQ0ksY0FBYyxHQUFHLElBQUksR0FBRyxDQUFDO0lBQzdCLENBQUMsUUFBUSxFQUFFLFNBQVMsQ0FBQztJQUNyQixDQUFDLFdBQVcsRUFBRSxTQUFTLENBQUM7SUFDeEIsQ0FBQyxTQUFTLEVBQUUsU0FBUyxDQUFDO0NBQ3ZCLENBQUM7O0lBQ0ksZ0JBQWdCOzs7O0FBQXdCLFVBQUMsQ0FBUyxJQUFhLE9BQUcsQ0FBQyxNQUFHLEVBQVAsQ0FBTyxDQUFBOztBQUU1RTtJQXVLRSw2QkFBbUIsZUFBZ0M7UUFBaEMsb0JBQWUsR0FBZixlQUFlLENBQWlCO1FBOURKLGVBQVUs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Ozs7O0lBQ3hELHVDQUF1Qzs7SUFFM0IsOENBQXVDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEFsaWJhYmEuY29tIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9naXRodWIuY29tL05HLVpPUlJPL25nLXpvcnJvLWFudGQvYmxvYi9tYXN0ZXIvTElDRU5TRVxuICovXG5cbmltcG9ydCB7IENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDb21wb25lbnQsIElucHV0LCBPbkNoYW5nZXMsIE9uRGVzdHJveSwgT25Jbml0LCBTaW1wbGVDaGFuZ2VzLCBWaWV3RW5jYXBzdWxhdGlvbiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgTnpDb25maWdTZXJ2aWNlLCBXaXRoQ29uZmlnIH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL2NvbmZpZyc7XG5pbXBvcnQgeyBOZ1N0eWxlSW50ZXJmYWNlLCBOdW1iZXJJbnB1dCB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZS90eXBlcyc7XG5pbXBvcnQgeyBJbnB1dE51bWJlciwgaXNOb3ROaWwgfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvdXRpbCc7XG5pbXBvcnQgeyBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7XG4gIE56UHJvZ3Jlc3NDaXJjbGVQYXRoLFxuICBOelByb2dyZXNzQ29sb3JHcmFkaWVudCxcbiAgTnpQcm9ncmVzc0Zvcm1hdHRlcixcbiAgTnpQcm9ncmVzc0dhcFBvc2l0aW9uVHlwZSxcbiAgTnpQcm9ncmVzc0dyYWRpZW50UHJvZ3Jlc3MsXG4gIE56UHJvZ3Jlc3NTdGF0dXNUeXBlLFxuICBOelByb2dyZXNzU3RlcEl0ZW0sXG4gIE56UHJvZ3Jlc3NTdHJva2VDb2xvclR5cGUsXG4gIE56UHJvZ3Jlc3NTdHJva2VMaW5lY2FwVHlwZSxcbiAgTnpQcm9ncmVzc1R5cGVUeXBlXG59IGZyb20gJy4vdHlwaW5ncyc7XG5pbXBvcnQgeyBoYW5kbGVDaXJjbGVHcmFkaWVudCwgaGFuZGxlTGluZWFyR3JhZGllbnQgfSBmcm9tICcuL3V0aWxzJztcblxubGV0IGdyYWRpZW50SWRTZWVkID0gMDtcblxuY29uc3QgTlpfQ09ORklHX0NPTVBPTkVOVF9OQU1FID0gJ3Byb2dyZXNzJztcbmNvbnN0IHN0YXR1c0ljb25OYW1lTWFwID0gbmV3IE1hcChbXG4gIFsnc3VjY2VzcycsICdjaGVjayddLFxuICBbJ2V4Y2VwdGlvbicsICdjbG9zZSddXG5dKTtcbmNvbnN0IHN0YXR1c0NvbG9yTWFwID0gbmV3IE1hcChbXG4gIFsnbm9ybWFsJywgJyMxMDhlZTknXSxcbiAgWydleGNlcHRpb24nLCAnI2ZmNTUwMCddLFxuICBbJ3N1Y2Nlc3MnLCAnIzg3ZDA2OCddXG5dKTtcbmNvbnN0IGRlZmF1bHRGb3JtYXR0ZXI6IE56UHJvZ3Jlc3NGb3JtYXR0ZXIgPSAocDogbnVtYmVyKTogc3RyaW5nID0+IGAke3B9JWA7XG5cbkBDb21wb25lbnQoe1xuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgc2VsZWN0b3I6ICduei1wcm9ncmVzcycsXG4gIGV4cG9ydEFzOiAnbnpQcm9ncmVzcycsXG4gIHByZXNlcnZlV2hpdGVzcGFjZXM6IGZhbHNlLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxuZy10ZW1wbGF0ZSAjcHJvZ3Jlc3NJbmZvVGVtcGxhdGU+XG4gICAgICA8c3BhbiBjbGFzcz1cImFudC1wcm9ncmVzcy10ZXh0XCIgKm5nSWY9XCJuelNob3dJbmZvXCI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIoc3RhdHVzID09PSAnZXhjZXB0aW9uJyB8fCBzdGF0dXMgPT09ICdzdWNjZXNzJykgJiYgIW56Rm9ybWF0OyBlbHNlIGZvcm1hdFRlbXBsYXRlXCI+XG4gICAgICAgICAgPGkgbnotaWNvbiBbbnpUeXBlXT1cImljb25cIj48L2k+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8bmctdGVtcGxhdGUgI2Zvcm1hdFRlbXBsYXRlPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm56U3RyaW5nVGVtcGxhdGVPdXRsZXQ9XCJmb3JtYXR0ZXI7IGNvbnRleHQ6IHsgJGltcGxpY2l0OiBuelBlcmNlbnQgfTsgbGV0IGZvcm1hdHRlclwiPlxuICAgICAgICAgICAge3sgZm9ybWF0dGVyKG56UGVyY2VudCkgfX1cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgIDwvc3Bhbj5cbiAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgPGRpdlxuICAgICAgW25nQ2xhc3NdPVwiJ2FudC1wcm9ncmVzcyBhbnQtcHJvZ3Jlc3Mtc3RhdHVzLScgKyBzdGF0dXNcIlxuICAgICAgW2NsYXNzLmFudC1wcm9ncmVzcy1saW5lXT1cIm56VHlwZSA9PSAnbGluZSdcIlxuICAgICAgW2NsYXNzLmFudC1wcm9ncmVzcy1zbWFsbF09XCJuelNpemUgPT0gJ3NtYWxsJ1wiXG4gICAgICBbY2xhc3MuYW50LXByb2dyZXNzLXNob3ctaW5mb109XCJuelNob3dJbmZvXCJcbiAgICAgIFtjbGFzcy5hbnQtcHJvZ3Jlc3MtY2lyY2xlXT1cImlzQ2lyY2xlU3R5bGVcIlxuICAgICAgW2NsYXNzLmFudC1wcm9ncmVzcy1zdGVwc109XCJpc1N0ZXBzXCJcbiAgICA+XG4gICAgICA8IS0tIGxpbmUgcHJvZ3Jlc3MgLS0+XG4gICAgICA8ZGl2ICpuZ0lmPVwibnpUeXBlID09PSAnbGluZSdcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFpc1N0ZXBzXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImFudC1wcm9ncmVzcy1vdXRlclwiICpuZ0lmPVwiIWlzU3RlcHNcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhbnQtcHJvZ3Jlc3MtaW5uZXJcIj5cbiAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgIGNsYXNzPVwiYW50LXByb2dyZXNzLWJnXCJcbiAgICAgICAgICAgICAgICBbc3R5bGUud2lkdGguJV09XCJuelBlcmNlbnRcIlxuICAgICAgICAgICAgICAgIFtzdHlsZS5ib3JkZXItcmFkaXVzXT1cIm56U3Ryb2tlTGluZWNhcCA9PT0gJ3JvdW5kJyA/ICcxMDBweCcgOiAnMCdcIlxuICAgICAgICAgICAgICAgIFtzdHlsZS5iYWNrZ3JvdW5kXT1cIiFpc0dyYWRpZW50ID8gbnpTdHJva2VDb2xvciA6IG51bGxcIlxuICAgICAgICAgICAgICAgIFtzdHlsZS5iYWNrZ3JvdW5kLWltYWdlXT1cImlzR3JhZGllbnQgPyBsaW5lR3JhZGllbnQgOiBudWxsXCJcbiAgICAgICAgICAgICAgICBbc3R5bGUuaGVpZ2h0LnB4XT1cInN0cm9rZVdpZHRoXCJcbiAgICAgICAgICAgICAgPjwvZGl2PlxuICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgKm5nSWY9XCJuelN1Y2Nlc3NQZXJjZW50IHx8IG56U3VjY2Vzc1BlcmNlbnQgPT09IDBcIlxuICAgICAgICAgICAgICAgIGNsYXNzPVwiYW50LXByb2dyZXNzLXN1Y2Nlc3MtYmdcIlxuICAgICAgICAgICAgICAgIFtzdHlsZS53aWR0aC4lXT1cIm56U3VjY2Vzc1BlcmNlbnRcIlxuICAgICAgICAgICAgICAgIFtzdHlsZS5ib3JkZXItcmFkaXVzXT1cIm56U3Ryb2tlTGluZWNhcCA9PT0gJ3JvdW5kJyA/ICcxMDBweCcgOiAnMCdcIlxuICAgICAgICAgICAgICAgIFtzdHlsZS5oZWlnaHQucHhdPVwic3Ryb2tlV2lkdGhcIlxuICAgICAgICAgICAgICA+PC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8bmctdGVtcGxhdGUgW25nVGVtcGxhdGVPdXRsZXRdPVwicHJvZ3Jlc3NJbmZvVGVtcGxhdGVcIj48L25nLXRlbXBsYXRlPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPCEtLSBTdGVwIHN0eWxlIHByb2dyZXNzIC0tPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiYW50LXByb2dyZXNzLXN0ZXBzLW91dGVyXCIgKm5nSWY9XCJpc1N0ZXBzXCI+XG4gICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgc3RlcCBvZiBzdGVwczsgbGV0IGkgPSBpbmRleFwiIGNsYXNzPVwiYW50LXByb2dyZXNzLXN0ZXBzLWl0ZW1cIiBbbmdTdHlsZV09XCJzdGVwXCI+PC9kaXY+XG4gICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ1RlbXBsYXRlT3V0bGV0XT1cInByb2dyZXNzSW5mb1RlbXBsYXRlXCI+PC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBjaXJjbGUgLyBkYXNoYm9hcmQgcHJvZ3Jlc3MgLS0+XG4gICAgICA8ZGl2XG4gICAgICAgIFtzdHlsZS53aWR0aC5weF09XCJ0aGlzLm56V2lkdGhcIlxuICAgICAgICBbc3R5bGUuaGVpZ2h0LnB4XT1cInRoaXMubnpXaWR0aFwiXG4gICAgICAgIFtzdHlsZS5mb250U2l6ZS5weF09XCJ0aGlzLm56V2lkdGggKiAwLjE1ICsgNlwiXG4gICAgICAgIGNsYXNzPVwiYW50LXByb2dyZXNzLWlubmVyXCJcbiAgICAgICAgW2NsYXNzLmFudC1wcm9ncmVzcy1jaXJjbGUtZ3JhZGllbnRdPVwiaXNHcmFkaWVudFwiXG4gICAgICAgICpuZ0lmPVwiaXNDaXJjbGVTdHlsZVwiXG4gICAgICA+XG4gICAgICAgIDxzdmcgY2xhc3M9XCJhbnQtcHJvZ3Jlc3MtY2lyY2xlIFwiIHZpZXdCb3g9XCIwIDAgMTAwIDEwMFwiPlxuICAgICAgICAgIDxkZWZzICpuZ0lmPVwiaXNHcmFkaWVudFwiPlxuICAgICAgICAgICAgPGxpbmVhckdyYWRpZW50IFtpZF09XCInZ3JhZGllbnQtJyArIGdyYWRpZW50SWRcIiB4MT1cIjEwMCVcIiB5MT1cIjAlXCIgeDI9XCIwJVwiIHkyPVwiMCVcIj5cbiAgICAgICAgICAgICAgPHN0b3AgKm5nRm9yPVwibGV0IGkgb2YgY2lyY2xlR3JhZGllbnRcIiBbYXR0ci5vZmZzZXRdPVwiaS5vZmZzZXRcIiBbYXR0ci5zdG9wLWNvbG9yXT1cImkuY29sb3JcIj48L3N0b3A+XG4gICAgICAgICAgICA8L2xpbmVhckdyYWRpZW50PlxuICAgICAgICAgIDwvZGVmcz5cbiAgICAgICAgICA8cGF0aFxuICAgICAgICAgICAgY2xhc3M9XCJhbnQtcHJvZ3Jlc3MtY2lyY2xlLXRyYWlsXCJcbiAgICAgICAgICAgIHN0cm9rZT1cIiNmM2YzZjNcIlxuICAgICAgICAgICAgZmlsbC1vcGFjaXR5PVwiMFwiXG4gICAgICAgICAgICBbYXR0ci5zdHJva2Utd2lkdGhdPVwic3Ryb2tlV2lkdGhcIlxuICAgICAgICAgICAgW2F0dHIuZF09XCJwYXRoU3RyaW5nXCJcbiAgICAgICAgICAgIFtuZ1N0eWxlXT1cInRyYWlsUGF0aFN0eWxlXCJcbiAgICAgICAgICA+PC9wYXRoPlxuICAgICAgICAgIDxwYXRoXG4gICAgICAgICAgICAqbmdGb3I9XCJsZXQgcCBvZiBwcm9ncmVzc0NpcmNsZVBhdGg7IHRyYWNrQnk6IHRyYWNrQnlGblwiXG4gICAgICAgICAgICBjbGFzcz1cImFudC1wcm9ncmVzcy1jaXJjbGUtcGF0aFwiXG4gICAgICAgICAgICBmaWxsLW9wYWNpdHk9XCIwXCJcbiAgICAgICAgICAgIFthdHRyLmRdPVwicGF0aFN0cmluZ1wiXG4gICAgICAgICAgICBbYXR0ci5zdHJva2UtbGluZWNhcF09XCJuelN0cm9rZUxpbmVjYXBcIlxuICAgICAgICAgICAgW2F0dHIuc3Ryb2tlXT1cInAuc3Ryb2tlXCJcbiAgICAgICAgICAgIFthdHRyLnN0cm9rZS13aWR0aF09XCJuelBlcmNlbnQgPyBzdHJva2VXaWR0aCA6IDBcIlxuICAgICAgICAgICAgW25nU3R5bGVdPVwicC5zdHJva2VQYXRoU3R5bGVcIlxuICAgICAgICAgID48L3BhdGg+XG4gICAgICAgIDwvc3ZnPlxuICAgICAgICA8bmctdGVtcGxhdGUgW25nVGVtcGxhdGVPdXRsZXRdPVwicHJvZ3Jlc3NJbmZvVGVtcGxhdGVcIj48L25nLXRlbXBsYXRlPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIGBcbn0pXG5leHBvcnQgY2xhc3MgTnpQcm9ncmVzc0NvbXBvbmVudCBpbXBsZW1lbnRzIE9uQ2hhbmdlcywgT25Jbml0LCBPbkRlc3Ryb3kge1xuICBzdGF0aWMgbmdBY2NlcHRJbnB1dFR5cGVfbnpTdWNjZXNzUGVyY2VudDogTnVtYmVySW5wdXQ7XG4gIHN0YXRpYyBuZ0FjY2VwdElucHV0VHlwZV9uelBlcmNlbnQ6IE51bWJlcklucHV0O1xuICBzdGF0aWMgbmdBY2NlcHRJbnB1dFR5cGVfbnpTdHJva2VXaWR0aDogTnVtYmVySW5wdXQ7XG4gIHN0YXRpYyBuZ0FjY2VwdElucHV0VHlwZV9uekdhcERlZ3JlZTogTnVtYmVySW5wdXQ7XG4gIHN0YXRpYyBuZ0FjY2VwdElucHV0VHlwZV9uelN0ZXBzOiBOdW1iZXJJbnB1dDtcblxuICBASW5wdXQoKSBAV2l0aENvbmZpZyhOWl9DT05GSUdfQ09NUE9ORU5UX05BTUUpIG56U2hvd0luZm86IGJvb2xlYW4gPSB0cnVlO1xuICBASW5wdXQoKSBueldpZHRoID0gMTMyO1xuICBASW5wdXQoKSBAV2l0aENvbmZpZyhOWl9DT05GSUdfQ09NUE9ORU5UX05BTUUpIG56U3Ryb2tlQ29sb3I/OiBOelByb2dyZXNzU3Ryb2tlQ29sb3JUeXBlID0gdW5kZWZpbmVkO1xuICBASW5wdXQoKSBAV2l0aENvbmZpZyhOWl9DT05GSUdfQ09NUE9ORU5UX05BTUUpIG56U2l6ZTogJ2RlZmF1bHQnIHwgJ3NtYWxsJyA9ICdkZWZhdWx0JztcbiAgQElucHV0KCkgbnpGb3JtYXQ/OiBOelByb2dyZXNzRm9ybWF0dGVyO1xuICBASW5wdXQoKSBASW5wdXROdW1iZXIoKSBuelN1Y2Nlc3NQZXJjZW50PzogbnVtYmVyO1xuICBASW5wdXQoKSBASW5wdXROdW1iZXIoKSBuelBlcmNlbnQ6IG51bWJlciA9IDA7XG4gIEBJbnB1dCgpIEBXaXRoQ29uZmlnKE5aX0NPTkZJR19DT01QT05FTlRfTkFNRSkgQElucHV0TnVtYmVyKCkgbnpTdHJva2VXaWR0aD86IG51bWJlciA9IHVuZGVmaW5lZDtcbiAgQElucHV0KCkgQFdpdGhDb25maWcoTlpfQ09ORklHX0NPTVBPTkVOVF9OQU1FKSBASW5wdXROdW1iZXIoKSBuekdhcERlZ3JlZT86IG51bWJlciA9IHVuZGVmaW5lZDtcbiAgQElucHV0KCkgbnpTdGF0dXM/OiBOelByb2dyZXNzU3RhdHVzVHlwZTtcbiAgQElucHV0KCkgbnpUeXBlOiBOelByb2dyZXNzVHlwZVR5cGUgPSAnbGluZSc7XG4gIEBJbnB1dCgpIEBXaXRoQ29uZmlnKE5aX0NPTkZJR19DT01QT05FTlRfTkFNRSkgbnpHYXBQb3NpdGlvbjogTnpQcm9ncmVzc0dhcFBvc2l0aW9uVHlwZSA9ICd0b3AnO1xuICBASW5wdXQoKSBAV2l0aENvbmZpZyhOWl9DT05GSUdfQ09NUE9ORU5UX05BTUUpIG56U3Ryb2tlTGluZWNhcDogTnpQcm9ncmVzc1N0cm9rZUxpbmVjYXBUeXBlID0gJ3JvdW5kJztcblxuICBASW5wdXQoKSBASW5wdXROdW1iZXIoKSBuelN0ZXBzPzogbnVtYmVyO1xuXG4gIHN0ZXBzOiBOelByb2dyZXNzU3RlcEl0ZW1bXSA9IFtdO1xuXG4gIC8qKiBHcmFkaWVudCBzdHlsZSB3aGVuIGBuelR5cGVgIGlzIGBsaW5lYC4gKi9cbiAgbGluZUdyYWRpZW50OiBzdHJpbmcgfCBudWxsID0gbnVsbDtcblxuICAvKiogSWYgdXNlciB1c2VzIGdyYWRpZW50IGNvbG9yLiAqL1xuICBpc0dyYWRpZW50ID0gZmFsc2U7XG5cbiAgLyoqIElmIHRoZSBsaW5lYXIgcHJvZ3Jlc3MgaXMgYSBzdGVwIHByb2dyZXNzLiAqL1xuICBpc1N0ZXBzID0gZmFsc2U7XG5cbiAgLyoqXG4gICAqIEVhY2ggcHJvZ3Jlc3Mgd2hvc2UgYG56VHlwZWAgaXMgY2lyY2xlIG9yIGRhc2hib2FyZCBzaG91bGQgaGF2ZSB1bmlxdWUgaWQgdG9cbiAgICogZGVmaW5lIGA8bGluZWFyR3JhZGllbnQ+YC5cbiAgICovXG4gIGdyYWRpZW50SWQgPSBncmFkaWVudElkU2VlZCsrO1xuXG4gIC8qKiBQYXRocyB0byByZW5kZXJlZCBpbiB0aGUgdGVtcGxhdGUuICovXG4gIHByb2dyZXNzQ2lyY2xlUGF0aDogTnpQcm9ncmVzc0NpcmNsZVBhdGhbXSA9IFtdO1xuICBjaXJjbGVHcmFkaWVudD86IEFycmF5PHsgb2Zmc2V0OiBzdHJpbmc7IGNvbG9yOiBzdHJpbmcgfT47XG4gIHRyYWlsUGF0aFN0eWxlOiBOZ1N0eWxlSW50ZXJmYWNlIHwgbnVsbCA9IG51bGw7XG4gIHBhdGhTdHJpbmc/OiBzdHJpbmc7XG4gIGljb24hOiBzdHJpbmc7XG5cbiAgdHJhY2tCeUZuID0gKGluZGV4OiBudW1iZXIpID0+IGAke2luZGV4fWA7XG5cbiAgZ2V0IGZvcm1hdHRlcigpOiBOelByb2dyZXNzRm9ybWF0dGVyIHtcbiAgICByZXR1cm4gdGhpcy5uekZvcm1hdCB8fCBkZWZhdWx0Rm9ybWF0dGVyO1xuICB9XG5cbiAgZ2V0IHN0YXR1cygpOiBOelByb2dyZXNzU3RhdHVzVHlwZSB7XG4gICAgcmV0dXJuIHRoaXMubnpTdGF0dXMgfHwgdGhpcy5pbmZlcnJlZFN0YXR1cztcbiAgfVxuXG4gIGdldCBzdHJva2VXaWR0aCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLm56U3Ryb2tlV2lkdGggfHwgKHRoaXMubnpUeXBlID09PSAnbGluZScgJiYgdGhpcy5uelNpemUgIT09ICdzbWFsbCcgPyA4IDogNik7XG4gIH1cblxuICBnZXQgaXNDaXJjbGVTdHlsZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5uelR5cGUgPT09ICdjaXJjbGUnIHx8IHRoaXMubnpUeXBlID09PSAnZGFzaGJvYXJkJztcbiAgfVxuXG4gIHByaXZhdGUgY2FjaGVkU3RhdHVzOiBOelByb2dyZXNzU3RhdHVzVHlwZSA9ICdub3JtYWwnO1xuICBwcml2YXRlIGluZmVycmVkU3RhdHVzOiBOelByb2dyZXNzU3RhdHVzVHlwZSA9ICdub3JtYWwnO1xuICBwcml2YXRlIGRlc3Ryb3kkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICBjb25zdHJ1Y3RvcihwdWJsaWMgbnpDb25maWdTZXJ2aWNlOiBOekNvbmZpZ1NlcnZpY2UpIHt9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGNvbnN0IHsgbnpTdGVwcywgbnpHYXBQb3NpdGlvbiwgbnpTdHJva2VMaW5lY2FwLCBuelN0cm9rZUNvbG9yLCBuekdhcERlZ3JlZSwgbnpUeXBlLCBuelN0YXR1cywgbnpQZXJjZW50LCBuelN1Y2Nlc3NQZXJjZW50IH0gPSBjaGFuZ2VzO1xuXG4gICAgaWYgKG56U3RhdHVzKSB7XG4gICAgICB0aGlzLmNhY2hlZFN0YXR1cyA9IHRoaXMubnpTdGF0dXMgfHwgdGhpcy5jYWNoZWRTdGF0dXM7XG4gICAgfVxuXG4gICAgaWYgKG56UGVyY2VudCB8fCBuelN1Y2Nlc3NQZXJjZW50KSB7XG4gICAgICBjb25zdCBmaWxsQWxsID0gcGFyc2VJbnQodGhpcy5uelBlcmNlbnQudG9TdHJpbmcoKSwgMTApID49IDEwMDtcbiAgICAgIGlmIChmaWxsQWxsKSB7XG4gICAgICAgIGlmICgoaXNOb3ROaWwodGhpcy5uelN1Y2Nlc3NQZXJjZW50KSAmJiB0aGlzLm56U3VjY2Vzc1BlcmNlbnQhID49IDEwMCkgfHwgdGhpcy5uelN1Y2Nlc3NQZXJjZW50ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aGlzLmluZmVycmVkU3RhdHVzID0gJ3N1Y2Nlc3MnO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmluZmVycmVkU3RhdHVzID0gdGhpcy5jYWNoZWRTdGF0dXM7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKG56U3RhdHVzIHx8IG56UGVyY2VudCB8fCBuelN1Y2Nlc3NQZXJjZW50KSB7XG4gICAgICB0aGlzLnVwZGF0ZUljb24oKTtcbiAgICB9XG5cbiAgICBpZiAobnpTdHJva2VDb2xvcikge1xuICAgICAgdGhpcy5zZXRTdHJva2VDb2xvcigpO1xuICAgIH1cblxuICAgIGlmIChuekdhcFBvc2l0aW9uIHx8IG56U3Ryb2tlTGluZWNhcCB8fCBuekdhcERlZ3JlZSB8fCBuelR5cGUgfHwgbnpQZXJjZW50IHx8IG56U3Ryb2tlQ29sb3IpIHtcbiAgICAgIHRoaXMuZ2V0Q2lyY2xlUGF0aHMoKTtcbiAgICB9XG5cbiAgICBpZiAobnpTdGVwcykge1xuICAgICAgdGhpcy5pc1N0ZXBzID0gaXNOb3ROaWwobnpTdGVwcy5jdXJyZW50VmFsdWUpO1xuICAgICAgdGhpcy5nZXRTdGVwcygpO1xuICAgIH1cbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMubnpDb25maWdTZXJ2aWNlXG4gICAgICAuZ2V0Q29uZmlnQ2hhbmdlRXZlbnRGb3JDb21wb25lbnQoTlpfQ09ORklHX0NPTVBPTkVOVF9OQU1FKVxuICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKVxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIHRoaXMudXBkYXRlSWNvbigpO1xuICAgICAgICB0aGlzLnNldFN0cm9rZUNvbG9yKCk7XG4gICAgICAgIHRoaXMuZ2V0Q2lyY2xlUGF0aHMoKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5kZXN0cm95JC5uZXh0KCk7XG4gICAgdGhpcy5kZXN0cm95JC5jb21wbGV0ZSgpO1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVJY29uKCk6IHZvaWQge1xuICAgIGNvbnN0IHJldCA9IHN0YXR1c0ljb25OYW1lTWFwLmdldCh0aGlzLnN0YXR1cyk7XG4gICAgdGhpcy5pY29uID0gcmV0ID8gcmV0ICsgKHRoaXMuaXNDaXJjbGVTdHlsZSA/ICctbycgOiAnLWNpcmNsZS1maWxsJykgOiAnJztcbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxjdWxhdGUgc3RlcCByZW5kZXIgY29uZmlncy5cbiAgICovXG4gIHByaXZhdGUgZ2V0U3RlcHMoKTogdm9pZCB7XG4gICAgY29uc3QgY3VycmVudCA9IE1hdGguZmxvb3IodGhpcy5uelN0ZXBzISAqICh0aGlzLm56UGVyY2VudCAvIDEwMCkpO1xuICAgIGNvbnN0IHN0ZXBXaWR0aCA9IHRoaXMubnpTaXplID09PSAnc21hbGwnID8gMiA6IDE0O1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm56U3RlcHMhOyBpKyspIHtcbiAgICAgIGxldCBjb2xvcjtcbiAgICAgIGlmIChpIDw9IGN1cnJlbnQgLSAxKSB7XG4gICAgICAgIGNvbG9yID0gdGhpcy5uelN0cm9rZUNvbG9yO1xuICAgICAgfVxuICAgICAgY29uc3Qgc3RlcFN0eWxlID0ge1xuICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IGAke2NvbG9yfWAsXG4gICAgICAgIHdpZHRoOiBgJHtzdGVwV2lkdGh9cHhgLFxuICAgICAgICBoZWlnaHQ6IGAke3RoaXMuc3Ryb2tlV2lkdGh9cHhgXG4gICAgICB9O1xuICAgICAgdGhpcy5zdGVwcy5wdXNoKHN0ZXBTdHlsZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENhbGN1bGF0ZSBwYXRocyB3aGVuIHRoZSB0eXBlIGlzIGNpcmNsZSBvciBkYXNoYm9hcmQuXG4gICAqL1xuICBwcml2YXRlIGdldENpcmNsZVBhdGhzKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5pc0NpcmNsZVN0eWxlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgdmFsdWVzID0gaXNOb3ROaWwodGhpcy5uelN1Y2Nlc3NQZXJjZW50KSA/IFt0aGlzLm56U3VjY2Vzc1BlcmNlbnQhLCB0aGlzLm56UGVyY2VudF0gOiBbdGhpcy5uelBlcmNlbnRdO1xuXG4gICAgLy8gQ2FsY3VsYXRlIHNoYXJlZCBzdHlsZXMuXG4gICAgY29uc3QgcmFkaXVzID0gNTAgLSB0aGlzLnN0cm9rZVdpZHRoIC8gMjtcbiAgICBjb25zdCBnYXBQb3NpdGlvbiA9IHRoaXMubnpHYXBQb3NpdGlvbiB8fCAodGhpcy5uelR5cGUgPT09ICdjaXJjbGUnID8gJ3RvcCcgOiAnYm90dG9tJyk7XG4gICAgY29uc3QgbGVuID0gTWF0aC5QSSAqIDIgKiByYWRpdXM7XG4gICAgY29uc3QgZ2FwRGVncmVlID0gdGhpcy5uekdhcERlZ3JlZSB8fCAodGhpcy5uelR5cGUgPT09ICdjaXJjbGUnID8gMCA6IDc1KTtcblxuICAgIGxldCBiZWdpblBvc2l0aW9uWCA9IDA7XG4gICAgbGV0IGJlZ2luUG9zaXRpb25ZID0gLXJhZGl1cztcbiAgICBsZXQgZW5kUG9zaXRpb25YID0gMDtcbiAgICBsZXQgZW5kUG9zaXRpb25ZID0gcmFkaXVzICogLTI7XG5cbiAgICBzd2l0Y2ggKGdhcFBvc2l0aW9uKSB7XG4gICAgICBjYXNlICdsZWZ0JzpcbiAgICAgICAgYmVnaW5Qb3NpdGlvblggPSAtcmFkaXVzO1xuICAgICAgICBiZWdpblBvc2l0aW9uWSA9IDA7XG4gICAgICAgIGVuZFBvc2l0aW9uWCA9IHJhZGl1cyAqIDI7XG4gICAgICAgIGVuZFBvc2l0aW9uWSA9IDA7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAncmlnaHQnOlxuICAgICAgICBiZWdpblBvc2l0aW9uWCA9IHJhZGl1cztcbiAgICAgICAgYmVnaW5Qb3NpdGlvblkgPSAwO1xuICAgICAgICBlbmRQb3NpdGlvblggPSByYWRpdXMgKiAtMjtcbiAgICAgICAgZW5kUG9zaXRpb25ZID0gMDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdib3R0b20nOlxuICAgICAgICBiZWdpblBvc2l0aW9uWSA9IHJhZGl1cztcbiAgICAgICAgZW5kUG9zaXRpb25ZID0gcmFkaXVzICogMjtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgIH1cblxuICAgIHRoaXMucGF0aFN0cmluZyA9IGBNIDUwLDUwIG0gJHtiZWdpblBvc2l0aW9uWH0sJHtiZWdpblBvc2l0aW9uWX1cbiAgICAgICBhICR7cmFkaXVzfSwke3JhZGl1c30gMCAxIDEgJHtlbmRQb3NpdGlvblh9LCR7LWVuZFBvc2l0aW9uWX1cbiAgICAgICBhICR7cmFkaXVzfSwke3JhZGl1c30gMCAxIDEgJHstZW5kUG9zaXRpb25YfSwke2VuZFBvc2l0aW9uWX1gO1xuXG4gICAgdGhpcy50cmFpbFBhdGhTdHlsZSA9IHtcbiAgICAgIHN0cm9rZURhc2hhcnJheTogYCR7bGVuIC0gZ2FwRGVncmVlfXB4ICR7bGVufXB4YCxcbiAgICAgIHN0cm9rZURhc2hvZmZzZXQ6IGAtJHtnYXBEZWdyZWUgLyAyfXB4YCxcbiAgICAgIHRyYW5zaXRpb246ICdzdHJva2UtZGFzaG9mZnNldCAuM3MgZWFzZSAwcywgc3Ryb2tlLWRhc2hhcnJheSAuM3MgZWFzZSAwcywgc3Ryb2tlIC4zcydcbiAgICB9O1xuXG4gICAgLy8gQ2FsY3VsYXRlIHN0eWxlcyBmb3IgZWFjaCBwYXRoLlxuICAgIHRoaXMucHJvZ3Jlc3NDaXJjbGVQYXRoID0gdmFsdWVzXG4gICAgICAubWFwKCh2YWx1ZSwgaW5kZXgpID0+IHtcbiAgICAgICAgY29uc3QgaXNTdWNjZXNzUGVyY2VudCA9IHZhbHVlcy5sZW5ndGggPT09IDIgJiYgaW5kZXggPT09IDA7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgc3Ryb2tlOiB0aGlzLmlzR3JhZGllbnQgJiYgIWlzU3VjY2Vzc1BlcmNlbnQgPyBgdXJsKCNncmFkaWVudC0ke3RoaXMuZ3JhZGllbnRJZH0pYCA6IG51bGwsXG4gICAgICAgICAgc3Ryb2tlUGF0aFN0eWxlOiB7XG4gICAgICAgICAgICBzdHJva2U6ICF0aGlzLmlzR3JhZGllbnQgPyAoaXNTdWNjZXNzUGVyY2VudCA/IHN0YXR1c0NvbG9yTWFwLmdldCgnc3VjY2VzcycpIDogKHRoaXMubnpTdHJva2VDb2xvciBhcyBzdHJpbmcpKSA6IG51bGwsXG4gICAgICAgICAgICB0cmFuc2l0aW9uOiAnc3Ryb2tlLWRhc2hvZmZzZXQgLjNzIGVhc2UgMHMsIHN0cm9rZS1kYXNoYXJyYXkgLjNzIGVhc2UgMHMsIHN0cm9rZSAuM3MsIHN0cm9rZS13aWR0aCAuMDZzIGVhc2UgLjNzJyxcbiAgICAgICAgICAgIHN0cm9rZURhc2hhcnJheTogYCR7KCh2YWx1ZSB8fCAwKSAvIDEwMCkgKiAobGVuIC0gZ2FwRGVncmVlKX1weCAke2xlbn1weGAsXG4gICAgICAgICAgICBzdHJva2VEYXNob2Zmc2V0OiBgLSR7Z2FwRGVncmVlIC8gMn1weGBcbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICB9KVxuICAgICAgLnJldmVyc2UoKTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0U3Ryb2tlQ29sb3IoKTogdm9pZCB7XG4gICAgY29uc3QgY29sb3IgPSB0aGlzLm56U3Ryb2tlQ29sb3I7XG4gICAgY29uc3QgaXNHcmFkaWVudCA9ICh0aGlzLmlzR3JhZGllbnQgPSAhIWNvbG9yICYmIHR5cGVvZiBjb2xvciAhPT0gJ3N0cmluZycpO1xuICAgIGlmIChpc0dyYWRpZW50ICYmICF0aGlzLmlzQ2lyY2xlU3R5bGUpIHtcbiAgICAgIHRoaXMubGluZUdyYWRpZW50ID0gaGFuZGxlTGluZWFyR3JhZGllbnQoY29sb3IgYXMgTnpQcm9ncmVzc0NvbG9yR3JhZGllbnQpO1xuICAgIH0gZWxzZSBpZiAoaXNHcmFkaWVudCAm