UNPKG

kre-form

Version:

本项目由 Angular8+ 编写的表单设计器和表单应用,所有的配置都是 JSON 结构体组成,PC 端是基于 ANT 组件库封装

515 lines 54.4 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { Component, Output, EventEmitter, Input, } from "@angular/core"; import { NzModalService } from "ng-zorro-antd/modal"; import { NzMessageService } from "ng-zorro-antd/message"; import * as _ from "lodash"; import { ChartsService } from "../../service/charts.service"; import { ChartConditionService } from "../../service/chart-condition.service"; import { ModalColorComponent } from "../modal-color/modal-color.component"; // import { stringify } from "querystring"; export class EchartOptionsDomComponent { /** * @param {?} chartConditionService * @param {?} chartsService * @param {?} modalService * @param {?} message */ constructor(chartConditionService, chartsService, modalService, message) { this.chartConditionService = chartConditionService; this.chartsService = chartsService; this.modalService = modalService; this.message = message; this.echartOptionsChange = new EventEmitter(); // echart只是内部参数稍做变化 // echart只是内部参数稍做变化 this.echartShapeChange = new EventEmitter(); // echart改变形状 // echart改变形状 this.chartConditionChange = new EventEmitter(); this.chartsType = [ { title: "指标", type: "data", icon: "" }, { title: "透视", type: "data", icon: "" }, { title: "柱状", type: "bar", icon: "" }, { title: "条形", type: "barY", icon: "" }, { title: "折线", type: "line", icon: "" }, { title: "雷达", type: "radar", icon: "" }, { title: "饼状", type: "pie", icon: "" }, { title: "地图", type: "map", icon: "" }, ]; this.childChartsType = [ { type: "line", title: "折线", children: [ { title: "折线", type: "line", icon: "" }, { title: "面积", type: "area", icon: "" }, ], }, { type: "pie", title: "饼状", children: [ { title: "饼状", type: "pie", icon: "" }, { title: "环形", type: "doughnut", icon: "" }, ], }, ]; this.input = { nzTabPosition: "setting", lineSmooth: "0", xAxisrRotate: "0", axisLabelInterval: false, title: "", yAxisMax: null, yAxisMin: null, dataLabeChecked: true, isLegend: true, legend: "top", currentColorType: "1", inside: 40, outside: 50, titleX: 0, titleY: 0, }; this.selectedValue = "lucy"; } /** * @return {?} */ ngOnInit() { this.formatterPercent = (/** * @param {?} value * @return {?} */ (value) => `${value} %`); this.parserPercent = (/** * @param {?} value * @return {?} */ (value) => value.replace(" %", "")); } /** * @param {?} changes * @return {?} */ ngOnChanges(changes) { for (const propName in changes) { /** @type {?} */ const chng = changes[propName]; if (propName === "chartCondition" && chng.currentValue) { /** @type {?} */ const option = this.getChartOption(chng.currentValue.type); this.lineSmoothChange(); this.xAxisrRotateChange(); this.intervalChange(); this.isLegendShow(); this.legendChange(); this.titleChange(); this.yAxisMaxBlur(); this.yAxisMinBlur(); this.radiusChange(); this.echartShapeChange.emit({ chartOption: option, }); this.currentChildChartsType = _.find(this.childChartsType, { type: chng.currentValue.charttype, }); this.currentChartType = chng.currentValue.type; } } } /** * @param {?} type * @return {?} */ choiceChart(type) { if (this.currentChartType == type) return; if (this.echartsList.length <= 0) { this.message.create("error", "请先选择数据"); return; } if (type === "data") return; this.currentChildChartsType = _.find(this.childChartsType, { type: type }); if (!this.currentChildChartsType) { this.changeOptions(type); } } /** * @param {?} type * @return {?} */ choiceSubChart(type) { if (this.currentChartType == type) return; this.changeOptions(type); } /** * @param {?} type * @return {?} */ changeOptions(type) { if (this.currentChartType) { this.modalService.confirm({ nzTitle: "更改图形", nzContent: "更改图形将清空当前图形配置,是否确认修改?", nzOnOk: (/** * @return {?} */ () => { this.choiceType(type); }), nzOnCancel: (/** * @return {?} */ () => { }), }); } else { this.choiceType(type); } } /** * @param {?} type * @return {?} */ choiceType(type) { /** @type {?} */ const condition = this.chartConditionService.chartCondition(); this.chartCondition = _.find(condition, { type: type, }); this.chartCondition.input = _.cloneDeep(this.input); this.chartConditionChange.emit(this.chartCondition); this.currentChartType = type; } /** * @param {?} type * @return {?} */ getChartOption(type) { /** @type {?} */ let options; if (type === "pie") { options = this.chartsService.pieOptions(); } else if (type === "doughnut") { options = this.chartsService.doughnutOptions(); } else if (type === "radar") { options = this.chartsService.radarOptions(); } else if (type === "bar") { options = this.chartsService.barOptions(); } else if (type === "barY") { options = this.chartsService.barYOptions(); } else if (type === "area") { options = this.chartsService.areaOptions(); } else if (type === "line") { options = this.chartsService.lineOptions(); } else { options = { series: [ { type: type, }, ], }; } this.chartsService.options.color = this.totalColor(); return options; } /** * @param {?=} change * @return {?} */ lineSmoothChange(change) { /** @type {?} */ let options = this.chartsService.options; options.series.forEach((/** * @param {?} item * @return {?} */ (item) => { if (item.type === "line") { item["smooth"] = Number(this.chartCondition.input.lineSmooth); } })); if (change) { this.echartOptionsChange.emit(options); } } /** * @param {?=} change * @return {?} */ xAxisrRotateChange(change) { /** @type {?} */ let options = this.chartsService.options; if (options && options.xAxis) { if (options.xAxis.axisLabel) { } else { options.xAxis.axisLabel = {}; } Object.assign(options.xAxis.axisLabel, { rotate: this.chartCondition.input.xAxisrRotate, }); if (change) { this.echartOptionsChange.emit(options); } } } /** * @param {?=} change * @return {?} */ intervalChange(change) { /** @type {?} */ let options = this.chartsService.options; if (options.xAxis) { options.xAxis.axisLabel = options.xAxis.axisLabel ? options.xAxis.axisLabel : {}; Object.assign(options.xAxis.axisLabel, { interval: this.chartCondition.input.axisLabelInterval ? 0 : "auto", }); if (change) { this.echartOptionsChange.emit(options); } } } /** * @param {?=} change * @return {?} */ titleChange(change) { /** @type {?} */ let options = this.chartsService.options; options.title = { text: this.chartCondition.input.title, left: this.chartCondition.input.titleX + "%", top: this.chartCondition.input.titleY + "%", textStyle: { fontSize: this.chartCondition.input.titleSize, }, }; if (typeof change !== "undefined") { this.echartOptionsChange.emit(options); } } /** * @param {?=} change * @return {?} */ yAxisMaxBlur(change) { /** @type {?} */ let options = this.chartsService.options; if (options.yAxis) { options.yAxis.max = this.chartCondition.input.yAxisMax; if (change) { this.echartOptionsChange.emit(options); } } } /** * @param {?=} change * @return {?} */ yAxisMinBlur(change) { /** @type {?} */ let options = this.chartsService.options; if (options.yAxis) { options.yAxis.min = this.chartCondition.input.yAxisMin; if (change) { this.echartOptionsChange.emit(options); } } } /** * @param {?=} change * @return {?} */ isLegendShow(change) { /** @type {?} */ let options = this.chartsService.options; options["legend"] = { show: this.chartCondition.input.isLegend ? true : false, [this.chartCondition.input.legend]: "0", }; if (change) { this.echartOptionsChange.emit(options); } } /** * @param {?=} change * @return {?} */ legendChange(change) { /** @type {?} */ let options = this.chartsService.options; options["legend"] = { [this.chartCondition.input.legend]: "0", show: this.chartCondition.input.isLegend, }; if (change) { this.echartOptionsChange.emit(options); } } /** * @param {?=} change * @return {?} */ radiusChange(change) { /** @type {?} */ let options = this.chartsService.options; if (!options.series[0].radius || Object.prototype.toString.call(options.series[0].radius) !== "[object Array]") return; /** @type {?} */ let inside = this.chartCondition.input.inside + "%"; /** @type {?} */ let outside = this.chartCondition.input.outside + "%"; options.series[0].radius.splice(0, 1, inside); options.series[0].radius.splice(1, 1, outside); if (change) { this.echartOptionsChange.emit(options); } } /** * @return {?} */ changeColor() { /** @type {?} */ const modal = this.modalService.create({ nzContent: ModalColorComponent, nzComponentParams: { echartsList: this.echartsList, colorList: this.colorList, currentColorType: this.chartCondition.input.currentColorType, }, nzOnOk: (/** * @param {?} componentInstance * @return {?} */ (componentInstance) => { this.chartCondition.input.currentColorType = componentInstance.currentColorType; // if ( // !( // this.currentChartType == "doughnut" || // this.currentChartType == "pie" // ) // ) { // Object.assign(this.chartsService.options, { // color: this.totalColor(), // visualMap: { // show: false, // categories: _.map(componentInstance.echartsColorList, "value"), // inRange: { // color: _.map(componentInstance.echartsColorList, "color"), // }, // }, // }); // } else { // this.chartsService.options.color = this.totalColor(); // } this.chartsService.options.color = this.totalColor(); this.echartOptionsChange.emit(this.chartsService.options); }), }); } /** * @return {?} */ totalColor() { return this.colorList[Number(this.chartCondition.input.currentColorType) - 1]; } /** * @return {?} */ changeCurrentColor() { this.chartsService.options.color = this.totalColor(); this.echartOptionsChange.emit(this.chartsService.options); } } EchartOptionsDomComponent.decorators = [ { type: Component, args: [{ selector: "echart-options-dom", template: "<h2>\u56FE\u6807\u7C7B\u578B</h2>\n<div class=\"chart-wrap\">\n <ng-container *ngFor=\"let item of chartsType\">\n <div (click)=\"choiceChart(item.type)\" class=\"chart-type\">\n {{ item.title }}\n </div>\n </ng-container>\n</div>\n<ng-container *ngIf=\"currentChildChartsType\">\n <div>{{ currentChildChartsType.title }}\u7C7B\u578B</div>\n <div class=\"chart-wrap\">\n <ng-container *ngFor=\"let item of currentChildChartsType.children\">\n <div (click)=\"choiceSubChart(item.type)\" class=\"chart-type\">\n {{ item.title }}\n </div>\n </ng-container>\n </div>\n</ng-container>\n<ng-container *ngIf=\"chartCondition\">\n <nz-radio-group\n [(ngModel)]=\"chartCondition.input.nzTabPosition\"\n name=\"nzTabPosition\"\n >\n <label nz-radio-button [nzValue]=\"'setting'\">\u529F\u80FD\u914D\u7F6E</label>\n <label nz-radio-button [nzValue]=\"'style'\">\u7EC4\u4EF6\u6837\u5F0F</label>\n </nz-radio-group>\n\n <div *ngIf=\"chartCondition.input.nzTabPosition === 'setting'\">\n <div *ngIf=\"chartCondition?.condition\">\n <!-- \u6298\u7EBF\u56FE \u9762\u79EF\u56FE -->\n <ng-container *ngIf=\"chartCondition?.condition.lineStyle\">\n <h4>\u7EBF\u6761\u6837\u5F0F</h4>\n <div>\n <nz-radio-group\n name=\"lineSmooth\"\n [(ngModel)]=\"chartCondition.input.lineSmooth\"\n (ngModelChange)=\"lineSmoothChange('event')\"\n >\n <label nz-radio nzValue=\"0\">\u666E\u901A</label>\n <label nz-radio nzValue=\"1\">\u66F2\u7EBF</label>\n </nz-radio-group>\n </div>\n <!-- <div>\n \u6807\u8BB0\u70B9 <label nz-checkbox [(ngModel)]=\"checked\">\u663E\u793A\u6570\u636E\u6807\u8BB0\u70B9</label>\n </div> -->\n <hr />\n </ng-container>\n <ng-container *ngIf=\"chartCondition?.condition.x\">\n <h4>\u5750\u6807x\u8F74</h4>\n \u6807\u7B7E\u6587\u5B57\u663E\u793A\u65B9\u5411\n <nz-select\n [ngModelOptions]=\"{ standalone: true }\"\n [(ngModel)]=\"chartCondition.input.xAxisrRotate\"\n (ngModelChange)=\"xAxisrRotateChange($event)\"\n nzAllowClear\n nzPlaceHolder=\"Choose\"\n >\n <nz-option nzValue=\"0\" nzLabel=\"\u6A2A\u5411\"></nz-option>\n <nz-option nzValue=\"90\" nzLabel=\"\u7AD6\u5411\"></nz-option>\n <nz-option nzValue=\"30\" nzLabel=\"\u5DE6\u503E\u659C\"></nz-option>\n <nz-option nzValue=\"-30\" nzLabel=\"\u53F3\u503E\u659C\"></nz-option>\n </nz-select>\n\n <div>\n <label\n nz-checkbox\n name=\"axisLabelInterval\"\n [(ngModel)]=\"chartCondition.input.axisLabelInterval\"\n (ngModelChange)=\"intervalChange('event')\"\n >\u5F3A\u5236\u663E\u793A\u6240\u6709\u6807\u7B7E</label\n >\n </div>\n\n <hr />\n </ng-container>\n <h4>\u6807\u9898</h4>\n <!-- <label\n nz-checkbox\n name=\"dataLabeChecked\"\n [(ngModel)]=\"chartCondition.condition.title\"\n (ngModelChange)=\"isShowTitle($event)\"\n >\u663E\u793A\u6807\u9898</label\n > -->\n <ng-container>\n <input\n nz-input\n placeholder=\"\u6807\u9898\"\n name=\"title\"\n [(ngModel)]=\"chartCondition.input.title\"\n [ngModelOptions]=\"{ updateOn: 'blur' }\"\n (ngModelChange)=\"titleChange($event)\"\n />\n\n <div>\n <span class=\"label\">\u6807\u9898\u5750\u6807X\uFF1A</span>\n <nz-input-number\n [(ngModel)]=\"chartCondition.input.titleX\"\n [nzMin]=\"0\"\n [nzMax]=\"100\"\n [nzStep]=\"1\"\n [nzFormatter]=\"formatterPercent\"\n [nzParser]=\"parserPercent\"\n [ngModelOptions]=\"{ updateOn: 'blur' }\"\n (ngModelChange)=\"titleChange($event)\"\n ></nz-input-number>\n </div>\n <div>\n <span class=\"label\">\u6807\u9898\u5750\u6807Y\uFF1A</span>\n <nz-input-number\n [(ngModel)]=\"chartCondition.input.titleY\"\n [nzMin]=\"0\"\n [nzMax]=\"100\"\n [nzStep]=\"1\"\n [nzFormatter]=\"formatterPercent\"\n [nzParser]=\"parserPercent\"\n [ngModelOptions]=\"{ updateOn: 'blur' }\"\n (ngModelChange)=\"titleChange($event)\"\n ></nz-input-number>\n </div>\n <div>\n <span class=\"label\">\u6807\u9898\u5927\u5C0F\uFF1A</span>\n <nz-input-number\n [(ngModel)]=\"chartCondition.input.titleSize\"\n [nzMin]=\"0\"\n [nzMax]=\"100\"\n [nzStep]=\"1\"\n [ngModelOptions]=\"{ updateOn: 'blur' }\"\n (ngModelChange)=\"titleChange($event)\"\n ></nz-input-number>\n </div>\n </ng-container>\n\n <hr />\n <ng-container *ngIf=\"chartCondition?.condition.y\">\n <h4>\u5750\u6807y\u8F74</h4>\n\n <input\n nz-input\n placeholder=\"\u6700\u5927\u503C\"\n name=\"yAxisMax\"\n [(ngModel)]=\"chartCondition.input.yAxisMax\"\n [ngModelOptions]=\"{ updateOn: 'blur' }\"\n (ngModelChange)=\"yAxisMaxBlur($event)\"\n />\n <input\n nz-input\n placeholder=\"\u6700\u5C0F\u503C\"\n name=\"yAxisMin\"\n [(ngModel)]=\"chartCondition.input.yAxisMin\"\n [ngModelOptions]=\"{ updateOn: 'blur' }\"\n (ngModelChange)=\"yAxisMinBlur($event)\"\n />\n <hr />\n </ng-container>\n\n <ng-container *ngIf=\"chartCondition?.condition.dataLabe\">\n <h4>\u6570\u636E\u6807\u7B7E</h4>\n <label\n nz-checkbox\n name=\"dataLabeChecked\"\n [(ngModel)]=\"chartCondition.input.dataLabeChecked\"\n >\u663E\u793A\u6570\u636E\u6807\u7B7E</label\n >\n <hr />\n </ng-container>\n <ng-container *ngIf=\"chartCondition.condition.radius\">\n <h4>\u534A\u5F84\u8BBE\u7F6E</h4>\n <div>\n <span class=\"label\">\u5185\u5F84\uFF1A</span>\n <nz-input-number\n [(ngModel)]=\"chartCondition.input.inside\"\n [nzMin]=\"0\"\n [nzMax]=\"100\"\n [nzStep]=\"1\"\n [nzFormatter]=\"formatterPercent\"\n [nzParser]=\"parserPercent\"\n [ngModelOptions]=\"{ updateOn: 'blur' }\"\n (ngModelChange)=\"radiusChange($event)\"\n ></nz-input-number>\n </div>\n <div>\n <span class=\"label\">\u5916\u5F84\uFF1A</span>\n <nz-input-number\n [(ngModel)]=\"chartCondition.input.outside\"\n [nzMin]=\"0\"\n [nzMax]=\"100\"\n [nzStep]=\"1\"\n [nzFormatter]=\"formatterPercent\"\n [nzParser]=\"parserPercent\"\n [ngModelOptions]=\"{ updateOn: 'blur' }\"\n (ngModelChange)=\"radiusChange($event)\"\n ></nz-input-number>\n </div>\n <hr />\n </ng-container>\n <ng-container *ngIf=\"chartCondition?.condition.legend\">\n <h4>\u56FE\u4F8B</h4>\n <label\n nz-checkbox\n name=\"isLegend\"\n [(ngModel)]=\"chartCondition.input.isLegend\"\n (ngModelChange)=\"isLegendShow('event')\"\n >\u56FE\u4F8B\u663E\u793A</label\n >\n <div>\n \u56FE\u4F8B\u663E\u793A\u5728\u56FE\u8868\n <nz-select\n name=\"legend\"\n [(ngModel)]=\"chartCondition.input.legend\"\n (ngModelChange)=\"legendChange($event)\"\n nzAllowClear\n nzPlaceHolder=\"Choose\"\n >\n <nz-option nzValue=\"bottom\" nzLabel=\"\u5E95\u90E8\"></nz-option>\n <nz-option nzValue=\"top\" nzLabel=\"\u5934\u90E8\"></nz-option>\n </nz-select>\n </div>\n <hr />\n </ng-container>\n\n <h4>\u6570\u636E\u9884\u8B66</h4>\n <div>\u6DFB\u52A0\u9884\u8B66</div>\n </div>\n </div>\n <div *ngIf=\"chartCondition.input.nzTabPosition === 'style'\">\n <h4>\u6574\u4F53\u6837\u5F0F</h4>\n <div>\u80CC\u666F</div>\n <div>\u6807\u9898\u6837\u5F0F</div>\n\n <hr />\n <h4>\u56FE\u8868\u914D\u8272</h4>\n\n <div class=\"select-color\" (click)=\"changeColor()\">\n \u914D\u8272\u65B9\u6848 {{ chartCondition.input.currentColorType\n }}<i class=\"icon-KT-Close\"></i>\n </div>\n\n <nz-select\n [(ngModel)]=\"chartCondition.input.currentColorType\"\n (ngModelChange)=\"changeCurrentColor()\"\n >\n <nz-option\n *ngFor=\"let item of colorList; let i = index\"\n nzCustomContent\n nzLabel=\"\u914D\u8272\u65B9\u6848{{ i + 1 }}\"\n nzValue=\"{{ i + 1 }}\"\n >\n <div>\n <ng-container *ngFor=\"let element of item; let ii = index\">\n <ng-container *ngIf=\"ii < 9\">\n <span [ngStyle]=\"{ 'background-color': element, color: element }\">\n -\n </span>\n </ng-container>\n </ng-container>\n \u914D\u8272\u65B9\u6848{{ i + 1 }}\n </div>\n </nz-option>\n </nz-select>\n </div>\n</ng-container>\n", styles: [":host{padding:10px 20px;border-left:1px solid #e9e9e9}:host .chart-wrap{display:flex;flex-wrap:wrap}:host .chart-wrap .chart-type{width:44px;height:44px;line-height:44px;text-align:center;cursor:pointer;border:2px solid #0db3a6;vertical-align:middle;margin:0 10px 10px 0}:host .select-color{border:1px solid #d9d9d9;border-radius:4px;height:32px;padding:4px 11px;background-color:#fff;display:flex;justify-content:space-between;align-items:center}:host .ant-input,:host .ant-input-number{margin-bottom:5px}:host span.label{width:80px;display:inline-block}"] }] } ]; /** @nocollapse */ EchartOptionsDomComponent.ctorParameters = () => [ { type: ChartConditionService }, { type: ChartsService }, { type: NzModalService }, { type: NzMessageService } ]; EchartOptionsDomComponent.propDecorators = { colorList: [{ type: Input }], echartsList: [{ type: Input }], chartCondition: [{ type: Input }], echartOptionsChange: [{ type: Output }], echartShapeChange: [{ type: Output }], chartConditionChange: [{ type: Output }] }; if (false) { /** @type {?} */ EchartOptionsDomComponent.prototype.colorList; /** @type {?} */ EchartOptionsDomComponent.prototype.echartsList; /** @type {?} */ EchartOptionsDomComponent.prototype.chartCondition; /** @type {?} */ EchartOptionsDomComponent.prototype.echartOptionsChange; /** @type {?} */ EchartOptionsDomComponent.prototype.echartShapeChange; /** @type {?} */ EchartOptionsDomComponent.prototype.chartConditionChange; /** @type {?} */ EchartOptionsDomComponent.prototype.chartsType; /** @type {?} */ EchartOptionsDomComponent.prototype.childChartsType; /** @type {?} */ EchartOptionsDomComponent.prototype.currentChildChartsType; /** @type {?} */ EchartOptionsDomComponent.prototype.input; /** @type {?} */ EchartOptionsDomComponent.prototype.selectedValue; /** @type {?} */ EchartOptionsDomComponent.prototype.currentChartType; /** @type {?} */ EchartOptionsDomComponent.prototype.formatterPercent; /** @type {?} */ EchartOptionsDomComponent.prototype.parserPercent; /** * @type {?} * @private */ EchartOptionsDomComponent.prototype.chartConditionService; /** * @type {?} * @private */ EchartOptionsDomComponent.prototype.chartsService; /** * @type {?} * @private */ EchartOptionsDomComponent.prototype.modalService; /** * @type {?} * @private */ EchartOptionsDomComponent.prototype.message; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWNoYXJ0LW9wdGlvbnMtZG9tLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0BrcmUtZm9ybS9hYmMvc3JjL2xpYi9ib2FyZC8iLCJzb3VyY2VzIjpbImNvbXBvbmVudHMvZWNoYXJ0LW9wdGlvbnMtZG9tL2VjaGFydC1vcHRpb25zLWRvbS5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE9BQU8sRUFDTCxTQUFTLEVBRVQsTUFBTSxFQUNOLFlBQVksRUFDWixLQUFLLEdBR04sTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUFjLGNBQWMsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ2pFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ3pELE9BQU8sS0FBSyxDQUFDLE1BQU0sUUFBUSxDQUFDO0FBRTVCLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUM3RCxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUM5RSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxzQ0FBc0MsQ0FBQzs7QUFRM0UsTUFBTSxPQUFPLHlCQUF5Qjs7Ozs7OztJQTZEcEMsWUFDVSxxQkFBNEMsRUFDNUMsYUFBNEIsRUFDNUIsWUFBNEIsRUFDNUIsT0FBeUI7UUFIekIsMEJBQXFCLEdBQXJCLHFCQUFxQixDQUF1QjtRQUM1QyxrQkFBYSxHQUFiLGFBQWEsQ0FBZTtRQUM1QixpQkFBWSxHQUFaLFlBQVksQ0FBZ0I7UUFDNUIsWUFBTyxHQUFQLE9BQU8sQ0FBa0I7UUE1RG5DLHdCQUFtQixHQUFHLElBQUksWUFBWSxFQUFFLENBQUMsQ0FBQyxtQkFBbUI7O1FBRTdELHNCQUFpQixHQUFHLElBQUksWUFBWSxFQUFFLENBQUMsQ0FBQyxhQUFhOztRQUMzQyx5QkFBb0IsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO1FBQ3BELGVBQVUsR0FBRztZQUNYLEVBQUUsS0FB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Q0FBQyxPQUFPLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUNyRCxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDNUQsQ0FBQzs7O1lBbFZGLFNBQVMsU0FBQztnQkFDVCxRQUFRLEVBQUUsb0JBQW9CO2dCQUM5Qiw2bVNBQWtEOzthQUVuRDs7OztZQVJRLHFCQUFxQjtZQURyQixhQUFhO1lBSkQsY0FBYztZQUMxQixnQkFBZ0I7Ozt3QkFjdEIsS0FBSzswQkFDTCxLQUFLOzZCQUNMLEtBQUs7a0NBQ0wsTUFBTTtnQ0FFTixNQUFNO21DQUVOLE1BQU07Ozs7SUFQUCw4Q0FBd0I7O0lBQ3hCLGdEQUEwQjs7SUFDMUIsbURBQTZCOztJQUM3Qix3REFDeUM7O0lBQ3pDLHNEQUN1Qzs7SUFDdkMseURBQW9EOztJQUNwRCwrQ0FTRTs7SUFDRixvREFpQkU7O0lBQ0YsMkRBQTRCOztJQUM1QiwwQ0FnQkU7O0lBRUYsa0RBQXVCOztJQUN2QixxREFBeUI7O0lBQ3pCLHFEQUFzQjs7SUFDdEIsa0RBQW1COzs7OztJQUdqQiwwREFBb0Q7Ozs7O0lBQ3BELGtEQUFvQzs7Ozs7SUFDcEMsaURBQW9DOzs7OztJQUNwQyw0Q0FBaUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDb21wb25lbnQsXG4gIE9uSW5pdCxcbiAgT3V0cHV0LFxuICBFdmVudEVtaXR0ZXIsXG4gIElucHV0LFxuICBBZnRlclZpZXdJbml0LFxuICBPbkNoYW5nZXMsXG59IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5cbmltcG9ydCB7IE56TW9kYWxSZWYsIE56TW9kYWxTZXJ2aWNlIH0gZnJvbSBcIm5nLXpvcnJvLWFudGQvbW9kYWxcIjtcbmltcG9ydCB7IE56TWVzc2FnZVNlcnZpY2UgfSBmcm9tIFwibmctem9ycm8tYW50ZC9tZXNzYWdlXCI7XG5pbXBvcnQgKiBhcyBfIGZyb20gXCJsb2Rhc2hcIjtcblxuaW1wb3J0IHsgQ2hhcnRzU2VydmljZSB9IGZyb20gXCIuLi8uLi9zZXJ2aWNlL2NoYXJ0cy5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBDaGFydENvbmRpdGlvblNlcnZpY2UgfSBmcm9tIFwiLi4vLi4vc2VydmljZS9jaGFydC1jb25kaXRpb24uc2VydmljZVwiO1xuaW1wb3J0IHsgTW9kYWxDb2xvckNvbXBvbmVudCB9IGZyb20gXCIuLi9tb2RhbC1jb2xvci9tb2RhbC1jb2xvci5jb21wb25lbnRcIjtcbi8vIGltcG9ydCB7IHN0cmluZ2lmeSB9IGZyb20gXCJxdWVyeXN0cmluZ1wiO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6IFwiZWNoYXJ0LW9wdGlvbnMtZG9tXCIsXG4gIHRlbXBsYXRlVXJsOiBcIi4vZWNoYXJ0LW9wdGlvbnMtZG9tLmNvbXBvbmVudC5odG1sXCIsXG4gIHN0eWxlVXJsczogW1wiLi9lY2hhcnQtb3B0aW9ucy1kb20uY29tcG9uZW50Lmxlc3NcIl0sXG59KVxuZXhwb3J0IGNsYXNzIEVjaGFydE9wdGlvbnNEb21Db21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcyB7XG4gIEBJbnB1dCgpIGNvbG9yTGlzdDogYW55O1xuICBASW5wdXQoKSBlY2hhcnRzTGlzdDogYW55O1xuICBASW5wdXQoKSBjaGFydENvbmRpdGlvbjogYW55O1xuICBAT3V0cHV0KClcbiAgZWNoYXJ0T3B0aW9uc0NoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXIoKTsgLy8gZWNoYXJ05Y+q5piv5YaF6YOo5Y+C5pWw56iN5YGa5Y+Y5YyWXG4gIEBPdXRwdXQoKVxuICBlY2hhcnRTaGFwZUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXIoKTsgLy8gZWNoYXJ05pS55Y+Y5b2i54q2XG4gIEBPdXRwdXQoKSBjaGFydENvbmRpdGlvbkNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgY2hhcnRzVHlwZSA9IFtcbiAgICB7IHRpdGxlOiBcIuaMh+agh1wiLCB0eXBlOiBcImRhdGFcIiwgaWNvbjogXCJcIiB9LFxuICAgIHsgdGl0bGU6IFwi6YCP6KeGXCIsIHR5cGU6IFwiZGF0YVwiLCBpY29uOiBcIlwiIH0sXG4gICAgeyB0aXRsZTogXCLmn7HnirZcIiwgdHlwZTogXCJiYXJcIiwgaWNvbjogXCJcIiB9LFxuICAgIHsgdGl0bGU6IFwi5p2h5b2iXCIsIHR5cGU6IFwiYmFyWVwiLCBpY29uOiBcIlwiIH0sXG4gICAgeyB0aXRsZTogXCLmipjnur9cIiwgdHlwZTogXCJsaW5lXCIsIGljb246IFwiXCIgfSxcbiAgICB7IHRpdGxlOiBcIumbt+i+vlwiLCB0eXBlOiBcInJhZGFyXCIsIGljb246IFwiXCIgfSxcbiAgICB7IHRpdGxlOiBcIumlvOeKtlwiLCB0eXBlOiBcInBpZVwiLCBpY29uOiBcIlwiIH0sXG4gICAgeyB0aXRsZTogXCLlnLDlm75cIiwgdHlwZTogXCJtYXBcIiwgaWNvbjogXCJcIiB9LFxuICBdO1xuICBjaGlsZENoYXJ0c1R5cGUgPSBbXG4gICAge1xuICAgICAgdHlwZTogXCJsaW5lXCIsXG4gICAgICB0aXRsZTogXCLmipjnur9cIixcbiAgICAgIGNoaWxkcmVuOiBbXG4gICAgICAgIHsgdGl0bGU6IFwi5oqY57q/XCIsIHR5cGU6IFwibGluZVwiLCBpY29uOiBcIlwiIH0sXG4gICAgICAgIHsgdGl0bGU6IFwi6Z2i56evXCIsIHR5cGU6IFwiYXJlYVwiLCBpY29uOiBcIlwiIH0sXG4gICAgICBdLFxuICAgIH0sXG4gICAge1xuICAgICAgdHlwZTogXCJwaWVcIixcbiAgICAgIHRpdGxlOiBcIumlvOeKtlwiLFxuICAgICAgY2hpbGRyZW46IFtcbiAgICAgICAgeyB0aXRsZTogXCLppbznirZcIiwgdHlwZTogXCJwaWVcIiwgaWNvbjogXCJcIiB9LFxuICAgICAgICB7IHRpdGxlOiBcIueOr+W9olwiLCB0eXBlOiBcImRvdWdobnV0XCIsIGljb246IFwiXCIgfSxcbiAgICAgIF0sXG4gICAgfSxcbiAgXTtcbiAgY3VycmVudENoaWxkQ2hhcnRzVHlwZTogYW55O1xuICBpbnB1dCA9IHtcbiAgICBuelRhYlBvc2l0aW9uOiBcInNldHRpbmdcIixcbiAgICBsaW5lU21vb3RoOiBcIjBcIixcbiAgICB4QXhpc3JSb3RhdGU6IFwiMFwiLFxuICAgIGF4aXNMYWJlbEludGVydmFsOiBmYWxzZSxcbiAgICB0aXRsZTogXCJcIixcbiAgICB5QXhpc01heDogbnVsbCxcbiAgICB5QXhpc01pbjogbnVsbCxcbiAgICBkYXRhTGFiZUNoZWNrZWQ6IHRydWUsXG4gICAgaXNMZWdlbmQ6IHRydWUsXG4gICAgbGVnZW5kOiBcInRvcFwiLFxuICAgIGN1cnJlbnRDb2xvclR5cGU6IFwiMVwiLFxuICAgIGluc2lkZTogNDAsXG4gICAgb3V0c2lkZTogNTAsXG4gICAgdGl0bGVYOiAwLFxuICAgIHRpdGxlWTogMCxcbiAgfTtcblxuICBzZWxlY3RlZFZhbHVlID0gXCJsdWN5XCI7XG4gIGN1cnJlbnRDaGFydFR5cGU6IHN0cmluZztcbiAgZm9ybWF0dGVyUGVyY2VudDogYW55O1xuICBwYXJzZXJQZXJjZW50OiBhbnk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBjaGFydENvbmRpdGlvblNlcnZpY2U6IENoYXJ0Q29uZGl0aW9uU2VydmljZSxcbiAgICBwcml2YXRlIGNoYXJ0c1NlcnZpY2U6IENoYXJ0c1NlcnZpY2UsXG4gICAgcHJpdmF0ZSBtb2RhbFNlcnZpY2U6IE56TW9kYWxTZXJ2aWNlLFxuICAgIHByaXZhdGUgbWVzc2FnZTogTnpNZXNzYWdlU2VydmljZVxuICApIHt9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5mb3JtYXR0ZXJQZXJjZW50ID0gKHZhbHVlOiBudW1iZXIpID0+IGAke3ZhbHVlfSAlYDtcbiAgICB0aGlzLnBhcnNlclBlcmNlbnQgPSAodmFsdWU6IHN0cmluZykgPT4gdmFsdWUucmVwbGFjZShcIiAlXCIsIFwiXCIpO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogYW55KSB7XG4gICAgZm9yIChjb25zdCBwcm9wTmFtZSBpbiBjaGFuZ2VzKSB7XG4gICAgICBjb25zdCBjaG5nID0gY2hhbmdlc1twcm9wTmFtZV07XG4gICAgICBpZiAocHJvcE5hbWUgPT09IFwiY2hhcnRDb25kaXRpb25cIiAmJiBjaG5nLmN1cnJlbnRWYWx1ZSkge1xuICAgICAgICBjb25zdCBvcHRpb24gPSB0aGlzLmdldENoYXJ0T3B0aW9uKGNobmcuY3VycmVudFZhbHVlLnR5cGUpO1xuICAgICAgICB0aGlzLmxpbmVTbW9vdGhDaGFuZ2UoKTtcbiAgICAgICAgdGhpcy54QXhpc3JSb3RhdGVDaGFuZ2UoKTtcbiAgICAgICAgdGhpcy5pbnRlcnZhbENoYW5nZSgpO1xuICAgICAgICB0aGlzLmlzTGVnZW5kU2hvdygpO1xuICAgICAgICB0aGlzLmxlZ2VuZENoYW5nZSgpO1xuICAgICAgICB0aGlzLnRpdGxlQ2hhbmdlKCk7XG4gICAgICAgIHRoaXMueUF4aXNNYXhCbHVyKCk7XG4gICAgICAgIHRoaXMueUF4aXNNaW5CbHVyKCk7XG4gICAgICAgIHRoaXMucmFkaXVzQ2hhbmdlKCk7XG4gICAgICAgIHRoaXMuZWNoYXJ0U2hhcGVDaGFuZ2UuZW1pdCh7XG4gICAgICAgICAgY2hhcnRPcHRpb246IG9wdGlvbixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuY3VycmVudENoaWxkQ2hhcnRzVHlwZSA9IF8uZmluZCh0aGlzLmNoaWxkQ2hhcnRzVHlwZSwge1xuICAgICAgICAgIHR5cGU6IGNobmcuY3VycmVudFZhbHVlLmNoYXJ0dHlwZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuY3VycmVudENoYXJ0VHlwZSA9IGNobmcuY3VycmVudFZhbHVlLnR5cGU7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgY2hvaWNlQ2hhcnQodHlwZTogYW55KSB7XG4gICAgaWYgKHRoaXMuY3VycmVudENoYXJ0VHlwZSA9PSB0eXBlKSByZXR1cm47XG4gICAgaWYgKHRoaXMuZWNoYXJ0c0xpc3QubGVuZ3RoIDw9IDApIHtcbiAgICAgIHRoaXMubWVzc2FnZS5jcmVhdGUoXCJlcnJvclwiLCBcIuivt+WFiOmAieaLqeaVsOaNrlwiKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHR5cGUgPT09IFwiZGF0YVwiKSByZXR1cm47XG5cbiAgICB0aGlzLmN1cnJlbnRDaGlsZENoYXJ0c1R5cGUgPSBfLmZpbmQodGhpcy5jaGlsZENoYXJ0c1R5cGUsIHsgdHlwZTogdHlwZSB9KTtcblxuICAgIGlmICghdGhpcy5jdXJyZW50Q2hpbGRDaGFydHNUeXBlKSB7XG4gICAgICB0aGlzLmNoYW5nZU9wdGlvbnModHlwZSk7XG4gICAgfVxuICB9XG5cbiAgY2hvaWNlU3ViQ2hhcnQodHlwZTogYW55KSB7XG4gICAgaWYgKHRoaXMuY3VycmVudENoYXJ0VHlwZSA9PSB0eXBlKSByZXR1cm47XG4gICAgdGhpcy5jaGFuZ2VPcHRpb25zKHR5cGUpO1xuICB9XG5cbiAgY2hhbmdlT3B0aW9ucyh0eXBlOiBhbnkpIHtcbiAgICBpZiAodGhpcy5jdXJyZW50Q2hhcnRUeXBlKSB7XG4gICAgICB0aGlzLm1vZGFsU2VydmljZS5jb25maXJtKHtcbiAgICAgICAgbnpUaXRsZTogXCLmm7TmlLnlm77lvaJcIixcbiAgICAgICAgbnpDb250ZW50OiBcIuabtOaUueWbvuW9ouWwhua4heepuuW9k+WJjeWbvuW9oumFjee9ru+8jOaYr+WQpuehruiupOS/ruaUue+8n1wiLFxuICAgICAgICBuek9uT2s6ICgpID0+IHtcbiAgICAgICAgICB0aGlzLmNob2ljZVR5cGUodHlwZSk7XG4gICAgICAgIH0sXG4gICAgICAgIG56T25DYW5jZWw6ICgpID0+IHt9LFxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY2hvaWNlVHlwZSh0eXBlKTtcbiAgICB9XG4gIH1cblxuICBjaG9pY2VUeXBlKHR5cGU6IGFueSkge1xuICAgIGNvbnN0IGNvbmRpdGlvbiA9IHRoaXMuY2hhcnRDb25kaXRpb25TZXJ2aWNlLmNoYXJ0Q29uZGl0aW9uKCk7XG4gICAgdGhpcy5jaGFydENvbmRpdGlvbiA9IF8uZmluZChjb25kaXRpb24sIHtcbiAgICAgIHR5cGU6IHR5cGUsXG4gICAgfSk7XG4gICAgdGhpcy5jaGFydENvbmRpdGlvbi5pbnB1dCA9IF8uY2xvbmVEZWVwKHRoaXMuaW5wdXQpO1xuICAgIHRoaXMuY2hhcnRDb25kaXRpb25DaGFuZ2UuZW1pdCh0aGlzLmNoYXJ0Q29uZGl0aW9uKTtcbiAgICB0aGlzLmN1cnJlbnRDaGFydFR5cGUgPSB0eXBlO1xuICB9XG5cbiAgZ2V0Q2hhcnRPcHRpb24odHlwZTogYW55KSB7XG4gICAgbGV0IG9wdGlvbnM7XG4gICAgaWYgKHR5cGUgPT09IFwicGllXCIpIHtcbiAgICAgIG9wdGlvbnMgPSB0aGlzLmNoYXJ0c1NlcnZpY2UucGllT3B0aW9ucygpO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gXCJkb3VnaG51dFwiKSB7XG4gICAgICBvcHRpb25zID0gdGhpcy5jaGFydHNTZXJ2aWNlLmRvdWdobnV0T3B0aW9ucygpO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gXCJyYWRhclwiKSB7XG4gICAgICBvcHRpb25zID0gdGhpcy5jaGFydHNTZXJ2aWNlLnJhZGFyT3B0aW9ucygpO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gXCJiYXJcIikge1xuICAgICAgb3B0aW9ucyA9IHRoaXMuY2hhcnRzU2VydmljZS5iYXJPcHRpb25zKCk7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSBcImJhcllcIikge1xuICAgICAgb3B0aW9ucyA9IHRoaXMuY2hhcnRzU2VydmljZS5iYXJZT3B0aW9ucygpO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gXCJhcmVhXCIpIHtcbiAgICAgIG9wdGlvbnMgPSB0aGlzLmNoYXJ0c1NlcnZpY2UuYXJlYU9wdGlvbnMoKTtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09IFwibGluZVwiKSB7XG4gICAgICBvcHRpb25zID0gdGhpcy5jaGFydHNTZXJ2aWNlLmxpbmVPcHRpb25zKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG9wdGlvbnMgPSB7XG4gICAgICAgIHNlcmllczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHR5cGU6IHR5cGUsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG4gICAgfVxuICAgIHRoaXMuY2hhcnRzU2VydmljZS5vcHRpb25zLmNvbG9yID0gdGhpcy50b3RhbENvbG9yKCk7XG4gICAgcmV0dXJuIG9wdGlvbnM7XG4gIH1cblxuICBsaW5lU21vb3RoQ2hhbmdlKGNoYW5nZT86IGFueSkge1xuICAgIGxldCBvcHRpb25zID0gdGhpcy5jaGFydHNTZXJ2aWNlLm9wdGlvbnM7XG4gICAgb3B0aW9ucy5zZXJpZXMuZm9yRWFjaCgoaXRlbTogYW55KSA9PiB7XG4gICAgICBpZiAoaXRlbS50eXBlID09PSBcImxpbmVcIikge1xuICAgICAgICBpdGVtW1wic21vb3RoXCJdID0gTnVtYmVyKHRoaXMuY2hhcnRDb25kaXRpb24uaW5wdXQubGluZVNtb290aCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgaWYgKGNoYW5nZSkge1xuICAgICAgdGhpcy5lY2hhcnRPcHRpb25zQ2hhbmdlLmVtaXQob3B0aW9ucyk7XG4gICAgfVxuICB9XG5cbiAgeEF4aXNyUm90YXRlQ2hhbmdlKGNoYW5nZT86IGFueSkge1xuICAgIGxldCBvcHRpb25zID0gdGhpcy5jaGFydHNTZXJ2aWNlLm9wdGlvbnM7XG4gICAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy54QXhpcykge1xuICAgICAgaWYgKG9wdGlvbnMueEF4aXMuYXhpc0xhYmVsKSB7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvcHRpb25zLnhBeGlzLmF4aXNMYWJlbCA9IHt9O1xuICAgICAgfVxuICAgICAgT2JqZWN0LmFzc2lnbihvcHRpb25zLnhBeGlzLmF4aXNMYWJlbCwge1xuICAgICAgICByb3RhdGU6IHRoaXMuY2hhcnRDb25kaXRpb24uaW5wdXQueEF4aXNyUm90YXRlLFxuICAgICAgfSk7XG4gICAgICBpZiAoY2hhbmdlKSB7XG4gICAgICAgIHRoaXMuZWNoYXJ0T3B0aW9uc0NoYW5nZS5lbWl0KG9wdGlvbnMpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGludGVydmFsQ2hhbmdlKGNoYW5nZT86IGFueSkge1xuICAgIGxldCBvcHRpb25zID0gdGhpcy5jaGFydHNTZXJ2aWNlLm9wdGlvbnM7XG4gICAgaWYgKG9wdGlvbnMueEF4aXMpIHtcbiAgICAgIG9wdGlvbnMueEF4aXMuYXhpc0xhYmVsID0gb3B0aW9ucy54QXhpcy5heGlzTGFiZWxcbiAgICAgICAgPyBvcHRpb25zLnhBeGlzLmF4aXNMYWJlbFxuICAgICAgICA6IHt9O1xuICAgICAgT2JqZWN0LmFzc2lnbihvcHRpb25zLnhBeGlzLmF4aXNMYWJlbCwge1xuICAgICAgICBpbnRlcnZhbDogdGhpcy5jaGFydENvbmRpdGlvbi5pbnB1dC5heGlzTGFiZWxJbnRlcnZhbCA/IDAgOiBcImF1dG9cIixcbiAgICAgIH0pO1xuICAgICAgaWYgKGNoYW5nZSkge1xuICAgICAgICB0aGlzLmVjaGFydE9wdGlvbnNDaGFuZ2UuZW1pdChvcHRpb25zKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB0aXRsZUNoYW5nZShjaGFuZ2U/OiBhbnkpIHtcbiAgICBsZXQgb3B0aW9ucyA9IHRoaXMuY2hhcnRzU2VydmljZS5vcHRpb25zO1xuICAgIG9wdGlvbnMudGl0bGUgPSB7XG4gICAgICB0ZXh0OiB0aGlzLmNoYXJ0Q29uZGl0aW9uLmlucHV0LnRpdGxlLFxuICAgICAgbGVmdDogdGhpcy5jaGFydENvbmRpdGlvbi5pbnB1dC50aXRsZVggKyBcIiVcIixcbiAgICAgIHRvcDogdGhpcy5jaGFydENvbmRpdGlvbi5pbnB1dC50aXRsZVkgKyBcIiVcIixcbiAgICAgIHRleHRTdHlsZToge1xuICAgICAgICBmb250U2l6ZTogdGhpcy5jaGFydENvbmRpdGlvbi5pbnB1dC50aXRsZVNpemUsXG4gICAgICB9LFxuICAgIH07XG4gICAgaWYgKHR5cGVvZiBjaGFuZ2UgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgIHRoaXMuZWNoYXJ0T3B0aW9uc0NoYW5nZS5lbWl0KG9wdGlvbnMpO1xuICAgIH1cbiAgfVxuXG4gIHlBeGlzTWF4Qmx1cihjaGFuZ2U/OiBhbnkpIHtcbiAgICBsZXQgb3B0aW9ucyA9IHRoaXMuY2hhcnRzU2VydmljZS5vcHRpb25zO1xuICAgIGlmIChvcHRpb25zLnlBeGl