@harbor/ui
Version:
Harbor shared UI components based on Clarity and Angular6
434 lines (433 loc) • 44.8 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
import { Component, Input, ChangeDetectionStrategy, Output, EventEmitter, ViewChild, ChangeDetectorRef } from "@angular/core";
import { NgForm } from '@angular/forms';
import { TranslateService } from "@ngx-translate/core";
import { forkJoin, throwError } from "rxjs";
import { finalize, map, catchError } from "rxjs/operators";
import { SystemInfoService } from "../service/index";
import { ErrorHandler } from "../error-handler/error-handler";
import { toPromise, DEFAULT_PAGE_SIZE, downloadFile } from "../utils";
import { HelmChartService } from "../service/helm-chart.service";
import { DefaultHelmIcon } from "../shared/shared.const";
import { Roles } from './../shared/shared.const';
import { OperationService } from "./../operation/operation.service";
import { OperateInfo, OperationState, operateChanges } from "./../operation/operate";
import { ConfirmationDialogComponent, ConfirmationMessage } from "./../confirmation-dialog";
export class HelmChartComponent {
/**
* @param {?} errorHandler
* @param {?} translateService
* @param {?} systemInfoService
* @param {?} helmChartService
* @param {?} operationService
* @param {?} cdr
*/
constructor(errorHandler, translateService, systemInfoService, helmChartService, operationService, cdr) {
this.errorHandler = errorHandler;
this.translateService = translateService;
this.systemInfoService = systemInfoService;
this.helmChartService = helmChartService;
this.operationService = operationService;
this.cdr = cdr;
this.signedCon = {};
this.projectName = "unknown";
this.projectRoleID = Roles.OTHER;
this.chartClickEvt = new EventEmitter();
this.chartDownloadEve = new EventEmitter();
this.chartDefaultIcon = DefaultHelmIcon;
this.charts = [];
this.chartsCopy = [];
this.selectedRows = [];
this.loading = true;
// For Upload
this.isUploading = false;
this.isUploadModalOpen = false;
this.cardHover = false;
this.listHover = false;
this.pageSize = DEFAULT_PAGE_SIZE;
this.currentPage = 1;
this.totalCount = 0;
}
/**
* @return {?}
*/
get registryUrl() {
return this.systemInfo ? this.systemInfo.registry_url : "";
}
/**
* @return {?}
*/
get developerRoleOrAbove() {
return this.projectRoleID === Roles.DEVELOPER || this.hasProjectAdminRole;
}
/**
* @return {?}
*/
ngOnInit() {
// Get system info for tag views
toPromise(this.systemInfoService.getSystemInfo())
.then(systemInfo => (this.systemInfo = systemInfo))
.catch(error => this.errorHandler.error(error));
this.lastFilteredChartName = "";
this.refresh();
}
/**
* @param {?} value
* @return {?}
*/
updateFilterValue(value) {
this.lastFilteredChartName = value;
this.refresh();
}
/**
* @return {?}
*/
refresh() {
this.loading = true;
this.helmChartService
.getHelmCharts(this.projectName)
.pipe(finalize(() => {
/** @type {?} */
let hnd = setInterval(() => this.cdr.markForCheck(), 100);
setTimeout(() => clearInterval(hnd), 3000);
this.loading = false;
}))
.subscribe(charts => {
this.charts = charts.filter(x => x.name.includes(this.lastFilteredChartName));
this.chartsCopy = charts.map(x => Object.assign({}, x));
this.totalCount = charts.length;
}, err => {
this.errorHandler.error(err);
});
}
/**
* @param {?} item
* @return {?}
*/
onChartClick(item) {
this.chartClickEvt.emit(item.name);
}
/**
* @return {?}
*/
resetUploadForm() {
this.chartFile = null;
this.provFile = null;
this.uploadForm.reset();
}
/**
* @return {?}
*/
onChartUpload() {
this.resetUploadForm();
this.isUploadModalOpen = true;
}
/**
* @return {?}
*/
cancelUpload() {
this.resetUploadForm();
this.isUploadModalOpen = false;
}
/**
* @return {?}
*/
upload() {
if (!this.chartFile && !this.provFile) {
return;
}
if (this.isUploading) {
return;
}
this.isUploading = true;
this.helmChartService
.uploadChart(this.projectName, this.chartFile, this.provFile)
.pipe(finalize(() => {
this.isUploading = false;
this.isUploadModalOpen = false;
this.refresh();
}))
.subscribe(() => {
this.translateService
.get("HELM_CHART.FILE_UPLOADED")
.subscribe(res => this.errorHandler.info(res));
}, err => this.errorHandler.error(err));
}
/**
* @param {?} event
* @return {?}
*/
onChartFileChangeEvent(event) {
if (event.target.files && event.target.files.length > 0) {
this.chartFile = event.target.files[0];
}
}
/**
* @param {?} event
* @return {?}
*/
onProvFileChangeEvent(event) {
if (event.target.files && event.target.files.length > 0) {
this.provFile = event.target.files[0];
}
}
/**
* @param {?} chartName
* @return {?}
*/
deleteChart(chartName) {
/** @type {?} */
let operateMsg = new OperateInfo();
operateMsg.name = "OPERATION.DELETE_CHART";
operateMsg.data["id"] = chartName;
operateMsg.state = OperationState.progressing;
operateMsg.data["name"] = chartName;
this.operationService.publishInfo(operateMsg);
return this.helmChartService.deleteHelmChart(this.projectName, chartName)
.pipe(map(() => operateChanges(operateMsg, OperationState.success), err => operateChanges(operateMsg, OperationState.failure, err)));
}
/**
* @param {?} charts
* @return {?}
*/
deleteCharts(charts) {
if (charts && charts.length < 1) {
return;
}
/** @type {?} */
let chartsDelete$ = charts.map(chart => this.deleteChart(chart.name));
forkJoin(chartsDelete$)
.pipe(catchError(err => throwError(err)), finalize(() => {
this.refresh();
this.selectedRows = [];
}))
.subscribe(() => { });
}
/**
* @param {?=} evt
* @param {?=} item
* @return {?}
*/
downloadLatestVersion(evt, item) {
if (evt) {
evt.stopPropagation();
}
/** @type {?} */
let selectedChart;
if (item) {
selectedChart = item;
}
else {
// return if selected version less then 1
if (this.selectedRows.length < 1) {
return;
}
selectedChart = this.selectedRows[0];
}
if (!selectedChart) {
return;
}
/** @type {?} */
let filename = `charts/${selectedChart.name}-${selectedChart.latest_version}.tgz`;
this.helmChartService.downloadChart(this.projectName, filename).subscribe(res => {
downloadFile(res);
}, error => {
this.errorHandler.error(error);
});
}
/**
* @param {?} charts
* @return {?}
*/
openChartDeleteModal(charts) {
/** @type {?} */
let chartNames = charts.map(chart => chart.name).join(",");
/** @type {?} */
let message = new ConfirmationMessage("HELM_CHART.DELETE_CHART_VERSION_TITLE", "HELM_CHART.DELETE_CHART_VERSION", chartNames, charts, 12 /* HELM_CHART */, 2 /* DELETE_CANCEL */);
this.confirmationDialog.open(message);
}
/**
* @param {?} message
* @return {?}
*/
confirmDeletion(message) {
if (message &&
message.source === 12 /* HELM_CHART */ &&
message.state === 1 /* CONFIRMED */) {
/** @type {?} */
let charts = message.data;
this.deleteCharts(charts);
}
}
/**
* @param {?} cardView
* @return {?}
*/
showCard(cardView) {
if (this.isCardView === cardView) {
return;
}
this.isCardView = cardView;
}
/**
* @param {?} itemName
* @return {?}
*/
mouseEnter(itemName) {
if (itemName === "card") {
this.cardHover = true;
}
else {
this.listHover = true;
}
}
/**
* @param {?} itemName
* @return {?}
*/
mouseLeave(itemName) {
if (itemName === "card") {
this.cardHover = false;
}
else {
this.listHover = false;
}
}
/**
* @param {?} itemName
* @return {?}
*/
isHovering(itemName) {
if (itemName === "card") {
return this.cardHover;
}
else {
return this.listHover;
}
}
/**
* @param {?} chart
* @return {?}
*/
getDefaultIcon(chart) {
chart.icon = this.chartDefaultIcon;
}
/**
* @param {?} chart
* @return {?}
*/
getStatusString(chart) {
if (chart.deprecated) {
return "HELM_CHART.DEPRECATED";
}
else {
return "HELM_CHART.ACTIVE";
}
}
}
HelmChartComponent.decorators = [
{ type: Component, args: [{
selector: "hbr-helm-chart",
template: "<div>\n <div class=\"row chart-tool\">\n <div class=\"toolbar\">\n <div class=\"row flex-items-xs-right option-right rightPos\">\n <div class=\"flex-xs-middle\">\n <hbr-filter [withDivider]=\"true\" filterPlaceholder=\"{{'HELM_CHART.FILTER_FOR_CHARTS' | translate}}\"\n [currentValue]=\"lastFilteredChartName\"\n (filterEvt)=\"updateFilterValue($event)\"></hbr-filter>\n <span class=\"card-btn\" (click)=\"showCard(true)\" (mouseenter)=\"mouseEnter('card') \" (mouseleave)=\"mouseLeave('card')\">\n <clr-icon [ngClass]=\"{'is-highlight': isCardView || isHovering('card') }\" shape=\"view-cards\"></clr-icon>\n </span>\n <span class=\"list-btn\" (click)=\"showCard(false)\" (mouseenter)=\"mouseEnter('list') \" (mouseleave)=\"mouseLeave('list')\">\n <clr-icon [ngClass]=\"{'is-highlight': !isCardView || isHovering('list') }\" shape=\"view-list\"></clr-icon>\n </span>\n <span class=\"filter-divider\"></span>\n <span class=\"refresh-btn\" (click)=\"refresh()\">\n <clr-icon shape=\"refresh\"></clr-icon>\n </span>\n </div>\n </div>\n </div>\n </div>\n <div class=\"row\">\n <div *ngIf=\"!isCardView\" class=\"col-lg-12 col-md-12 col-sm-12 col-xs-12\">\n <clr-datagrid (clrDgRefresh)=\"refresh()\" [clrDgLoading]=\"loading\" [(clrDgSelected)]=\"selectedRows\">\n <clr-dg-action-bar>\n <button type=\"button\" class=\"btn btn-sm btn-secondary\" [disabled]=\"!developerRoleOrAbove\" (click)=\"onChartUpload()\">\n <clr-icon shape=\"upload\" size=\"16\"></clr-icon>{{'HELM_CHART.UPLOAD' | translate}}\n </button>\n <button type=\"button\" class=\"btn btn-sm btn-secondary\" [disabled]=\"!hasProjectAdminRole || selectedRows.length<1\" (click)=\"openChartDeleteModal(selectedRows)\">\n <clr-icon shape=\"trash\" size=\"16\"></clr-icon>{{'BUTTON.DELETE' | translate}}\n </button>\n <button type=\"button\" class=\"btn btn-sm btn-secondary\" [disabled]=\"selectedRows.length!==1\" (click)=\"downloadLatestVersion()\">\n <clr-icon shape=\"download\" size=\"16\"></clr-icon>{{'HELM_CHART.DOWNLOAD' | translate}}\n </button>\n </clr-dg-action-bar>\n <clr-dg-column >{{'HELM_CHART.NAME' | translate}}</clr-dg-column>\n <clr-dg-column >{{'HELM_CHART.STATUS' | translate}}</clr-dg-column>\n <clr-dg-column>{{'HELM_CHART.CHARTVERSIONS' | translate}}</clr-dg-column>\n <clr-dg-column>{{'HELM_CHART.CREATED' | translate}}</clr-dg-column>\n <clr-dg-placeholder>{{'HELM_CHART.PLACEHOLDER' | translate }}</clr-dg-placeholder>\n <clr-dg-row *ngFor=\"let chart of charts\" [clrDgItem]=\"chart\">\n <clr-dg-cell>\n <span class=\"list-img\">\n <img class=\"size-24 margin-right-12\" [src]=\"chart.icon ?chart.icon:chartDefaultIcon\" (error)=\"getDefaultIcon(chart);\" />\n </span>\n <a href=\"javascript:void(0)\" (click)=\"onChartClick(chart)\">{{ chart.name }}</a>\n </clr-dg-cell>\n <clr-dg-cell>{{ getStatusString(chart) | translate }}</clr-dg-cell>\n <clr-dg-cell>{{ chart.total_versions }}</clr-dg-cell>\n <clr-dg-cell>{{ chart.created | date }}</clr-dg-cell>\n </clr-dg-row>\n <clr-dg-footer>\n <clr-dg-pagination #pagination [clrDgPageSize]=\"pageSize\" [clrDgTotalItems]=\"totalCount\">\n <span *ngIf=\"pagination.totalItems\">\n {{pagination.firstItem + 1}} - {{pagination.lastItem + 1}} {{'HELM_CHART.OF' | translate}}\n </span>\n {{pagination.totalItems}} {{'HELM_CHART.ITEMS'| translate}}\n </clr-dg-pagination>\n </clr-dg-footer>\n </clr-datagrid>\n </div>\n </div>\n <div *ngIf=\"isCardView\" class=\"row card-container\">\n <div *ngFor=\"let item of charts;\" class=\"chart-card\">\n <a let i=index; class=\"card clickable\" (click)=\"onChartClick(item)\">\n <div class=\"card-header\">\n <div class=\"card-icon\">\n <img class=\"size-60\" [src]=\"item.icon ?item.icon:chartDefaultIcon\" (error)=\"getDefaultIcon(item);\" />\n </div>\n <div class=\"card-title\">{{item.name}}</div>\n </div>\n <div class=\"card-footer\">\n <div class=\"row flex-items-xs-between\">\n <div>\n <span class=\"version-text\">{{item.total_versions}}</span>\n <label class=\"card-label\" *ngIf=\"item.total_versions !== 1\">{{'HELM_CHART.CHARTVERSIONS' | translate}}</label>\n <label class=\"card-label\" *ngIf=\"item.total_versions === 1\">{{'HELM_CHART.VERSION' | translate}}</label>\n </div>\n <div>\n <span class=\"label\"\n [class.label-danger]=\"item.deprecated\"\n [class.label-success]=\"!item.deprecated\"\n >{{getStatusString(item) | translate}}</span>\n </div>\n </div>\n </div>\n </a>\n </div>\n <div *ngIf=\"loading\">\n <span class=\"vertical-helper\"></span>\n <span class=\"spinner\"></span>\n </div>\n </div>\n <confirmation-dialog #confirmationDialog (confirmAction)=\"confirmDeletion($event)\"></confirmation-dialog>\n <clr-modal [(clrModalOpen)]=\"isUploadModalOpen\" [clrModalStaticBackdrop]=\"true\" [clrModalClosable]=\"false\">\n <h3 class=\"modal-title\">{{'HELM_CHART.UPLOAD_TITLE' | translate | titlecase}}</h3>\n <div class=\"modal-body\">\n <form #chartUploadForm=\"ngForm\" enctype=\"multipart/form-data\" (ngSubmit)=\"upload()\">\n <section class=\"form-block\">\n <div class=\"form-group\">\n <label class=\"filename-label\"> {{'HELM_CHART.CHART_FILE' | translate}} </label>\n <input class=\"filename-input\" type=\"text\" placeholder=\"{{this.chartFile?.name || 'BUTTON.NO_FILE' | translate}}\" disabled>\n <label for=\"chart\" class=\"btn btn-secondary btn-sm file-browser-btn\">{{'BUTTON.BROWSE' | translate}}</label>\n <input class=\"file-input\" type=\"file\" id=\"chart\" name=\"chart\" ngModel (change)=\"onChartFileChangeEvent($event)\">\n </div>\n <div class=\"form-group\">\n <label class=\"filename-label\"> {{'HELM_CHART.CHART_PROV' | translate}} </label>\n <input class=\"filename-input\" type=\"text\" placeholder=\"{{this.provFile?.name || 'BUTTON.NO_FILE' | translate}}\" disabled>\n <label for=\"prov\" class=\"btn btn-secondary btn-sm file-browser-btn\">{{'BUTTON.BROWSE' | translate}}</label>\n <input class=\"file-input\" type=\"file\" id=\"prov\" name=\"prov\" ngModel (change)=\"onProvFileChangeEvent($event)\">\n </div>\n </section>\n <div class=\"row flex-items-xs-right\">\n <button class=\"btn btn-secondary\" [disabled]=\"isUploading\" (click)=\"cancelUpload()\">\n <span>{{'BUTTON.CANCEL' | translate}}</span>\n </button>\n <button type=\"submit\" class=\"btn btn-primary\" [disabled]=\"isUploading\">\n <span>{{'HELM_CHART.UPLOAD' | translate}}</span>\n <span *ngIf=\"isUploading\" class=\"spinner spinner-inline\">\n Loading...\n </span>\n </button>\n </div>\n </form>\n </div>\n </clr-modal>\n</div>",
changeDetection: ChangeDetectionStrategy.OnPush,
styles: [".chart-tool{position:relative}.chart-tool .toolbar{overflow:hidden}.chart-tool .toolbar .rightPos{position:absolute;z-index:100;right:35px;margin-top:4px}.chart-tool .toolbar .rightPos .filter-divider{display:inline-block;height:16px;width:2px;background-color:#ccc;padding-top:12px;padding-bottom:12px;position:relative;top:9px;margin-right:6px;margin-left:6px}.card-container{margin-top:21px}.card-container .chart-card{width:200px;margin:10px}.card-container .card-header .card-icon{display:flex;justify-content:center;align-items:center}.card-container .card-header .card-title{overflow:hidden;text-overflow:ellipsis;word-wrap:break-word;white-space:nowrap;text-align:center;margin:15px}.card-container .card-footer{background-color:#d7d7d7}.card-container .card-footer .version-text{font-size:1.1rem}.card-container .card-footer .card-label{width:60px;display:inline-block}.vertical-helper{display:inline-block;height:100%;vertical-align:middle}.size-24{width:24px;height:24px}.size-60{height:60px;max-width:100%}.margin-right-12{margin-right:12px}.file-input{display:none}.filename-span{overflow:hidden;text-overflow:ellipsis;word-wrap:break-word;white-space:nowrap;display:inline-block;width:50%;vertical-align:top}clr-modal .form-group{padding-left:6rem}clr-modal .form-group .filename-label{padding-top:9px}clr-modal .form-group .filename-input{margin-top:12px;width:68%}clr-modal .form-group .file-browser-btn{margin-left:15px;max-width:25%}button clr-icon{margin-right:6px}"]
}] }
];
/** @nocollapse */
HelmChartComponent.ctorParameters = () => [
{ type: ErrorHandler },
{ type: TranslateService },
{ type: SystemInfoService },
{ type: HelmChartService },
{ type: OperationService },
{ type: ChangeDetectorRef }
];
HelmChartComponent.propDecorators = {
projectId: [{ type: Input }],
projectName: [{ type: Input }],
urlPrefix: [{ type: Input }],
hasSignedIn: [{ type: Input }],
projectRoleID: [{ type: Input }],
hasProjectAdminRole: [{ type: Input }],
chartClickEvt: [{ type: Output }],
chartDownloadEve: [{ type: Output }],
chartDefaultIcon: [{ type: Input }],
uploadForm: [{ type: ViewChild, args: ['chartUploadForm',] }],
confirmationDialog: [{ type: ViewChild, args: ["confirmationDialog",] }]
};
if (false) {
/** @type {?} */
HelmChartComponent.prototype.signedCon;
/** @type {?} */
HelmChartComponent.prototype.projectId;
/** @type {?} */
HelmChartComponent.prototype.projectName;
/** @type {?} */
HelmChartComponent.prototype.urlPrefix;
/** @type {?} */
HelmChartComponent.prototype.hasSignedIn;
/** @type {?} */
HelmChartComponent.prototype.projectRoleID;
/** @type {?} */
HelmChartComponent.prototype.hasProjectAdminRole;
/** @type {?} */
HelmChartComponent.prototype.chartClickEvt;
/** @type {?} */
HelmChartComponent.prototype.chartDownloadEve;
/** @type {?} */
HelmChartComponent.prototype.chartDefaultIcon;
/** @type {?} */
HelmChartComponent.prototype.lastFilteredChartName;
/** @type {?} */
HelmChartComponent.prototype.charts;
/** @type {?} */
HelmChartComponent.prototype.chartsCopy;
/** @type {?} */
HelmChartComponent.prototype.systemInfo;
/** @type {?} */
HelmChartComponent.prototype.selectedRows;
/** @type {?} */
HelmChartComponent.prototype.loading;
/** @type {?} */
HelmChartComponent.prototype.isUploading;
/** @type {?} */
HelmChartComponent.prototype.isUploadModalOpen;
/** @type {?} */
HelmChartComponent.prototype.provFile;
/** @type {?} */
HelmChartComponent.prototype.chartFile;
/** @type {?} */
HelmChartComponent.prototype.isCardView;
/** @type {?} */
HelmChartComponent.prototype.cardHover;
/** @type {?} */
HelmChartComponent.prototype.listHover;
/** @type {?} */
HelmChartComponent.prototype.pageSize;
/** @type {?} */
HelmChartComponent.prototype.currentPage;
/** @type {?} */
HelmChartComponent.prototype.totalCount;
/** @type {?} */
HelmChartComponent.prototype.currentState;
/** @type {?} */
HelmChartComponent.prototype.uploadForm;
/** @type {?} */
HelmChartComponent.prototype.confirmationDialog;
/** @type {?} */
HelmChartComponent.prototype.errorHandler;
/** @type {?} */
HelmChartComponent.prototype.translateService;
/** @type {?} */
HelmChartComponent.prototype.systemInfoService;
/** @type {?} */
HelmChartComponent.prototype.helmChartService;
/** @type {?} */
HelmChartComponent.prototype.operationService;
/** @type {?} */
HelmChartComponent.prototype.cdr;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVsbS1jaGFydC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9AaGFyYm9yL3VpLyIsInNvdXJjZXMiOlsic3JjL2hlbG0tY2hhcnQvaGVsbS1jaGFydC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE9BQU8sRUFDTCxTQUFTLEVBQ1QsS0FBSyxFQUVMLHVCQUF1QixFQUN2QixNQUFNLEVBQ04sWUFBWSxFQUNaLFNBQVMsRUFDVCxpQkFBaUIsRUFDbEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3hDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRXZELE9BQU8sRUFBRSxRQUFRLEVBQUUsVUFBVSxFQUFjLE1BQU0sTUFBTSxDQUFDO0FBQ3hELE9BQU8sRUFBRSxRQUFRLEVBQUUsR0FBRyxFQUFFLFVBQVUsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzNELE9BQU8sRUFBYyxpQkFBaUIsRUFBaUIsTUFBTSxrQkFBa0IsQ0FBQztBQUNoRixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDOUQsT0FBTyxFQUFFLFNBQVMsRUFBRSxpQkFBaUIsRUFBRSxZQUFZLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDdEUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDakUsT0FBTyxFQUFFLGVBQWUsRUFBQyxNQUFNLHdCQUF3QixDQUFDO0FBQ3hELE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNqRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUNwRSxPQUFPLEVBQ0wsV0FBVyxFQUNYLGNBQWMsRUFDZCxjQUFjLEVBQ2YsTUFBTSx3QkFBd0IsQ0FBQztBQUNoQyxPQUFPLEVBQStCLDJCQUEyQixFQUFFLG1CQUFtQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFhekgsTUFBTTs7Ozs7Ozs7O0lBdUNKLFlBQ1UsY0FDQSxrQkFDQSxtQkFDQSxrQkFDQSxrQkFDQTtRQUxBLGlCQUFZLEdBQVosWUFBWTtRQUNaLHFCQUFnQixHQUFoQixnQkFBZ0I7UUFDaEIsc0JBQWlCLEdBQWpCLGlCQUFpQjtRQUNqQixxQkFBZ0IsR0FBaEIsZ0JBQWdCO1FBQ2hCLHFCQUFnQixHQUFoQixnQkFBZ0I7UUFDaEIsUUFBRyxHQUFILEdBQUc7eUJBNUNrQyxFQUFFOzJCQUUxQixTQUFTOzZCQUdQLEtBQUssQ0FBQyxLQUFLOzZCQUVWLElBQUksWUFBWSxFQUFPO2dDQUNwQixJQUFJLFlBQVksRUFBVTtnQ0FDbkIsZUFBZTtzQkFHekIsRUFBRTswQkFDRSxFQUFFOzRCQUVBLEVBQUU7dUJBQ3hCLElBQUk7OzJCQUdBLEtBQUs7aUNBQ0MsS0FBSzt5QkFNYixLQUFLO3lCQUNMLEtBQUs7d0JBRUUsaUJBQWlCOzJCQUN0QixDQUFDOzBCQUNGLENBQUM7S0FjVjs7OztRQUVPLFdBQVc7UUFDcEIsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDOzs7OztRQUdsRCxvQkFBb0I7UUFDN0IsT0FBTyxJQUFJLENBQUMsYUFBYSxLQUFLLEtBQUssQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFDLG1CQUFtQixDQUFDOzs7OztJQUc1RSxRQUFROztRQUVOLFNBQVMsQ0FBYSxJQUFJLENBQUMsaUJBQWlCLENBQUMsYUFBYSxFQUFFLENBQUM7YUFDMUQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQyxDQUFDO2FBQ2xELEtBQUssQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDbEQsSUFBSSxDQUFDLHFCQUFxQixHQUFHLEVBQUUsQ0FBQztRQUNoQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7S0FDaEI7Ozs7O0lBRUQsaUJBQWlCLENBQUMsS0FBYTtRQUM3QixJQUFJLENBQUMscUJBQXFCLEdBQUcsS0FBSyxDQUFDO1FBQ25DLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztLQUNoQjs7OztJQUVELE9BQU87UUFDTCxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQztRQUNwQixJQUFJLENBQUMsZ0JBQWdCO2FBQ3BCLGFBQWEsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDO2FBQy9CLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxFQUFFOztZQUNoQixJQUFJLEdBQUcsR0FBRyxXQUFXLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxZQUFZLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQztZQUMxRCxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQzNDLElBQUksQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDO1NBQ3hCLENBQUMsQ0FBQzthQUNGLFNBQVMsQ0FDUixNQUFNLENBQUMsRUFBRTtZQUNQLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUM7WUFDOUUsSUFBSSxDQUFDLFVBQVUsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN4RCxJQUFJLENBQUMsVUFBVSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7U0FDakMsRUFDRCxHQUFHLENBQUMsRUFBRTtZQUNKLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1NBQzlCLENBQ0YsQ0FBQztLQUNIOzs7OztJQUVELFlBQVksQ0FBQyxJQUFtQjtRQUM5QixJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7S0FDcEM7Ozs7SUFFRCxlQUFlO1FBQ2IsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7UUFDdEIsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUM7UUFDckIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztLQUN6Qjs7OztJQUVELGFBQWE7UUFDWCxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDdkIsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksQ0FBQztLQUMvQjs7OztJQUVELFlBQVk7UUFDVixJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDdkIsSUFBSSxDQUFDLGlCQUFpQixHQUFHLEtBQUssQ0FBQztLQUNoQzs7OztJQUVELE1BQU07UUFDSixJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUU7WUFDckMsT0FBTztTQUNSO1FBQ0QsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFO1lBQUUsT0FBTztTQUFFO1FBQ2pDLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO1FBQ3hCLElBQUksQ0FBQyxnQkFBZ0I7YUFDbEIsV0FBVyxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDO2FBQzVELElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxFQUFFO1lBQ2xCLElBQUksQ0FBQyxXQUFXLEdBQUcsS0FBSyxDQUFDO1lBQ3pCLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxLQUFLLENBQUM7WUFDL0IsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1NBQ2hCLENBQUMsQ0FBQzthQUNGLFNBQVMsQ0FBQyxHQUFHLEVBQUU7WUFDWixJQUFJLENBQUMsZ0JBQWdCO2lCQUNsQixHQUFHLENBQUMsMEJBQTBCLENBQUM7aUJBQy9CLFNBQVMsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7U0FDbEQsRUFDRCxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUNwQyxDQUFDO0tBQ0w7Ozs7O0lBRUQsc0JBQXNCLENBQUMsS0FBSztRQUMxQixJQUFJLEtBQUssQ0FBQyxNQUFNLENBQUMsS0FBSyxJQUFJLEtBQUssQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7WUFDdkQsSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUN4QztLQUNGOzs7OztJQUNELHFCQUFxQixDQUFDLEtBQUs7UUFDekIsSUFBSSxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssSUFBSSxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1lBQ3ZELElBQUksQ0FBQyxRQUFRLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDdkM7S0FDRjs7Ozs7SUFHRCxXQUFXLENBQUMsU0FBaUI7O1FBQzNCLElBQUksVUFBVSxHQUFHLElBQUksV0FBVyxFQUFFLENBQUM7UUFDbkMsVUFBVSxDQUFDLElBQUksR0FBRyx3QkFBd0IsQ0FBQztRQUMzQyxVQUFVLENBQUMsSUFBSSxTQUFNLFNBQVMsQ0FBQztRQUMvQixVQUFVLENBQUMsS0FBSyxHQUFHLGNBQWMsQ0FBQyxXQUFXLENBQUM7UUFDOUMsVUFBVSxDQUFDLElBQUksV0FBUSxTQUFTLENBQUM7UUFDakMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUU5QyxPQUFPLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxTQUFTLENBQUM7YUFDeEUsSUFBSSxDQUFDLEdBQUcsQ0FDUCxHQUFHLEVBQUUsQ0FBQyxjQUFjLENBQUMsVUFBVSxFQUFFLGNBQWMsQ0FBQyxPQUFPLENBQUMsRUFDeEQsR0FBRyxDQUFDLEVBQUUsQ0FBQyxjQUFjLENBQUMsVUFBVSxFQUFFLGNBQWMsQ0FBQyxPQUFPLEVBQUUsR0FBRyxDQUFDLENBQy9ELENBQUMsQ0FBQztLQUNKOzs7OztJQUVELFlBQVksQ0FBQyxNQUF1QjtRQUNsQyxJQUFJLE1BQU0sSUFBSSxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtZQUFFLE9BQU87U0FBRTs7UUFDNUMsSUFBSSxhQUFhLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDdEUsUUFBUSxDQUFDLGFBQWEsQ0FBQzthQUN0QixJQUFJLENBQ0gsVUFBVSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQ2xDLFFBQVEsQ0FBQyxHQUFHLEVBQUU7WUFDWixJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDZixJQUFJLENBQUMsWUFBWSxHQUFHLEVBQUUsQ0FBQztTQUN4QixDQUFDLENBQUM7YUFDSixTQUFTLENBQUMsR0FBRyxFQUFFLElBQUcsQ0FBQyxDQUFDO0tBQ3RCOzs7Ozs7SUFFRCxxQkFBcUIsQ0FBQyxHQUFXLEVBQUUsSUFBb0I7UUFDckQsSUFBSSxHQUFHLEVBQUU7WUFDUCxHQUFHLENBQUMsZUFBZSxFQUFFLENBQUM7U0FDdkI7O1FBQ0QsSUFBSSxhQUFhLENBQWdCO1FBRWpDLElBQUksSUFBSSxFQUFFO1lBQ1IsYUFBYSxHQUFHLElBQUksQ0FBQztTQUN0QjthQUFNOztZQUVMLElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO2dCQUNoQyxPQUFPO2FBQ1I7WUFDRCxhQUFhLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUN0QztRQUNELElBQUksQ0FBQyxhQUFhLEVBQUU7WUFDbEIsT0FBTztTQUNSOztRQUNELElBQUksUUFBUSxHQUFHLFVBQVUsYUFBYSxDQUFDLElBQUksSUFBSSxhQUFhLENBQUMsY0FBYyxNQUFNLENBQUM7UUFDbEYsSUFBSSxDQUFDLGdCQUFnQixDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLFFBQVEsQ0FBQyxDQUFDLFNBQVMsQ0FDdkUsR0FBRyxDQUFDLEVBQUU7WUFDSixZQUFZLENBQUMsR0FBRyxDQUFDLENBQUM7U0FDbkIsRUFDRCxLQUFLLENBQUMsRUFBRTtZQUNOLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1NBQ2hDLENBQ0YsQ0FBQztLQUNIOzs7OztJQUVELG9CQUFvQixDQUFDLE1BQXVCOztRQUMxQyxJQUFJLFVBQVUsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQzs7UUFDM0QsSUFBSSxPQUFPLEdBQUcsSUFBSSxtQkFBbUIsQ0FDbkMsdUNBQXVDLEVBQ3ZDLGlDQUFpQyxFQUNqQyxVQUFVLEVBQ1YsTUFBTSw2Q0FHUCxDQUFDO1FBQ0YsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztLQUN2Qzs7Ozs7SUFFRCxlQUFlLENBQUMsT0FBb0M7UUFDbEQsSUFDRSxPQUFPO1lBQ1AsT0FBTyxDQUFDLE1BQU0sd0JBQW1DO1lBQ2pELE9BQU8sQ0FBQyxLQUFLLHNCQUFnQyxFQUM3Qzs7WUFDQSxJQUFJLE1BQU0sR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDO1lBQzFCLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLENBQUM7U0FDM0I7S0FDRjs7Ozs7SUFFRCxRQUFRLENBQUMsUUFBaUI7UUFDeEIsSUFBSSxJQUFJLENBQUMsVUFBVSxLQUFLLFFBQVEsRUFBRTtZQUNoQyxPQUFPO1NBQ1I7UUFDRCxJQUFJLENBQUMsVUFBVSxHQUFHLFFBQVEsQ0FBQztLQUM1Qjs7Ozs7SUFFRCxVQUFVLENBQUMsUUFBZ0I7UUFDekIsSUFBSSxRQUFRLEtBQUssTUFBTSxFQUFFO1lBQ3ZCLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDO1NBQ3ZCO2FBQU07WUFDTCxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztTQUN2QjtLQUNGOzs7OztJQUVELFVBQVUsQ0FBQyxRQUFnQjtRQUN6QixJQUFJLFFBQVEsS0FBSyxNQUFNLEVBQUU7WUFDdkIsSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUM7U0FDeEI7YUFBTTtZQUNMLElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDO1NBQ3hCO0tBQ0Y7Ozs7O0lBRUQsVUFBVSxDQUFDLFFBQWdCO1FBQ3pCLElBQUksUUFBUSxLQUFLLE1BQU0sRUFBRTtZQUN2QixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUM7U0FDdkI7YUFBTTtZQUNMLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQztTQUN2QjtLQUNGOzs7OztJQUVELGNBQWMsQ0FBQyxLQUFvQjtRQUNqQyxLQUFLLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQztLQUNwQzs7Ozs7SUFFRCxlQUFlLENBQUMsS0FBb0I7UUFDbEMsSUFBSSxLQUFLLENBQUMsVUFBVSxFQUFFO1lBQ3BCLE9BQU8sdUJBQXVCLENBQUM7U0FDaEM7YUFBTTtZQUNMLE9BQU8sbUJBQW1CLENBQUM7U0FDNUI7S0FDRjs7O1lBalJGLFNBQVMsU0FBQztnQkFDVCxRQUFRLEVBQUUsZ0JBQWdCO2dCQUMxQix5NVFBQTBDO2dCQUUxQyxlQUFlLEVBQUUsdUJBQXVCLENBQUMsTUFBTTs7YUFDaEQ7Ozs7WUF2QlEsWUFBWTtZQUxaLGdCQUFnQjtZQUlKLGlCQUFpQjtZQUc3QixnQkFBZ0I7WUFHaEIsZ0JBQWdCO1lBYnZCLGlCQUFpQjs7O3dCQWtDaEIsS0FBSzswQkFDTCxLQUFLO3dCQUNMLEtBQUs7MEJBQ0wsS0FBSzs0QkFDTCxLQUFLO2tDQUNMLEtBQUs7NEJBQ0wsTUFBTTsrQkFDTixNQUFNOytCQUNOLEtBQUs7eUJBeUJMLFNBQVMsU0FBQyxpQkFBaUI7aUNBRTNCLFNBQVMsU0FBQyxvQkFBb0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDb21wb25lbnQsXG4gIElucHV0LFxuICBPbkluaXQsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBPdXRwdXQsXG4gIEV2ZW50RW1pdHRlcixcbiAgVmlld0NoaWxkLFxuICBDaGFuZ2VEZXRlY3RvclJlZlxufSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHsgTmdGb3JtIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgVHJhbnNsYXRlU2VydmljZSB9IGZyb20gXCJAbmd4LXRyYW5zbGF0ZS9jb3JlXCI7XG5pbXBvcnQgeyBTdGF0ZSB9IGZyb20gXCJAY2xyL2FuZ3VsYXJcIjtcbmltcG9ydCB7IGZvcmtKb2luLCB0aHJvd0Vycm9yLCBPYnNlcnZhYmxlIH0gZnJvbSBcInJ4anNcIjtcbmltcG9ydCB7IGZpbmFsaXplLCBtYXAsIGNhdGNoRXJyb3IgfSBmcm9tIFwicnhqcy9vcGVyYXRvcnNcIjtcbmltcG9ydCB7IFN5c3RlbUluZm8sIFN5c3RlbUluZm9TZXJ2aWNlLCBIZWxtQ2hhcnRJdGVtIH0gZnJvbSBcIi4uL3NlcnZpY2UvaW5kZXhcIjtcbmltcG9ydCB7IEVycm9ySGFuZGxlciB9IGZyb20gXCIuLi9lcnJvci1oYW5kbGVyL2Vycm9yLWhhbmRsZXJcIjtcbmltcG9ydCB7IHRvUHJvbWlzZSwgREVGQVVMVF9QQUdFX1NJWkUsIGRvd25sb2FkRmlsZSB9IGZyb20gXCIuLi91dGlsc1wiO1xuaW1wb3J0IHsgSGVsbUNoYXJ0U2VydmljZSB9IGZyb20gXCIuLi9zZXJ2aWNlL2hlbG0tY2hhcnQuc2VydmljZVwiO1xuaW1wb3J0IHsgRGVmYXVsdEhlbG1JY29ufSBmcm9tIFwiLi4vc2hhcmVkL3NoYXJlZC5jb25zdFwiO1xuaW1wb3J0IHsgUm9sZXMgfSBmcm9tICcuLy4uL3NoYXJlZC9zaGFyZWQuY29uc3QnO1xuaW1wb3J0IHsgT3BlcmF0aW9uU2VydmljZSB9IGZyb20gXCIuLy4uL29wZXJhdGlvbi9vcGVyYXRpb24uc2VydmljZVwiO1xuaW1wb3J0IHtcbiAgT3BlcmF0ZUluZm8sXG4gIE9wZXJhdGlvblN0YXRlLFxuICBvcGVyYXRlQ2hhbmdlc1xufSBmcm9tIFwiLi8uLi9vcGVyYXRpb24vb3BlcmF0ZVwiO1xuaW1wb3J0IHsgQ29uZmlybWF0aW9uQWNrbm93bGVkZ2VtZW50LCBDb25maXJtYXRpb25EaWFsb2dDb21wb25lbnQsIENvbmZpcm1hdGlvbk1lc3NhZ2UgfSBmcm9tIFwiLi8uLi9jb25maXJtYXRpb24tZGlhbG9nXCI7XG5pbXBvcnQge1xuICBDb25maXJtYXRpb25CdXR0b25zLFxuICBDb25maXJtYXRpb25UYXJnZXRzLFxuICBDb25maXJtYXRpb25TdGF0ZSxcbn0gZnJvbSBcIi4vLi4vc2hhcmVkL3NoYXJlZC5jb25zdFwiO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6IFwiaGJyLWhlbG0tY2hhcnRcIixcbiAgdGVtcGxhdGVVcmw6IFwiLi9oZWxtLWNoYXJ0LmNvbXBvbmVudC5odG1sXCIsXG4gIHN0eWxlVXJsczogW1wiLi9oZWxtLWNoYXJ0LmNvbXBvbmVudC5zY3NzXCJdLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaFxufSlcbmV4cG9ydCBjbGFzcyBIZWxtQ2hhcnRDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICBzaWduZWRDb246IHsgW2tleTogc3RyaW5nXTogYW55IHwgc3RyaW5nW10gfSA9IHt9O1xuICBASW5wdXQoKSBwcm9qZWN0SWQ6IG51bWJlcjtcbiAgQElucHV0KCkgcHJvamVjdE5hbWUgPSBcInVua25vd25cIjtcbiAgQElucHV0KCkgdXJsUHJlZml4OiBzdHJpbmc7XG4gIEBJbnB1dCgpIGhhc1NpZ25lZEluOiBib29sZWFuO1xuICBASW5wdXQoKSBwcm9qZWN0Um9sZUlEID0gUm9sZXMuT1RIRVI7XG4gIEBJbnB1dCgpIGhhc1Byb2plY3RBZG1pblJvbGU6IGJvb2xlYW47XG4gIEBPdXRwdXQoKSBjaGFydENsaWNrRXZ0ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG4gIEBPdXRwdXQoKSBjaGFydERvd25sb2FkRXZlID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG4gIEBJbnB1dCgpIGNoYXJ0RGVmYXVsdEljb246IHN0cmluZyA9IERlZmF1bHRIZWxtSWNvbjtcblxuICBsYXN0RmlsdGVyZWRDaGFydE5hbWU6IHN0cmluZztcbiAgY2hhcnRzOiBIZWxtQ2hhcnRJdGVtW10gPSBbXTtcbiAgY2hhcnRzQ29weTogSGVsbUNoYXJ0SXRlbVtdID0gW107XG4gIHN5c3RlbUluZm86IFN5c3RlbUluZm87XG4gIHNlbGVjdGVkUm93czogSGVsbUNoYXJ0SXRlbVtdID0gW107XG4gIGxvYWRpbmcgPSB0cnVlO1xuXG4gIC8vIEZvciBVcGxvYWRcbiAgaXNVcGxvYWRpbmcgPSBmYWxzZTtcbiAgaXNVcGxvYWRNb2RhbE9wZW4gPSBmYWxzZTtcbiAgcHJvdkZpbGU6IEZpbGU7XG4gIGNoYXJ0RmlsZTogRmlsZTtcblxuICAvLyBGb3IgVmlldyBzd3RpY2hcbiAgaXNDYXJkVmlldzogYm9vbGVhbjtcbiAgY2FyZEhvdmVyID0gZmFsc2U7XG4gIGxpc3RIb3ZlciA9IGZhbHNlO1xuXG4gIHBhZ2VTaXplOiBudW1iZXIgPSBERUZBVUxUX1BBR0VfU0laRTtcbiAgY3VycmVudFBhZ2UgPSAxO1xuICB0b3RhbENvdW50ID0gMDtcbiAgY3VycmVudFN0YXRlOiBTdGF0ZTtcblxuICBAVmlld0NoaWxkKCdjaGFydFVwbG9hZEZvcm0nKSB1cGxvYWRGb3JtOiBOZ0Zvcm07XG5cbiAgQFZpZXdDaGlsZChcImNvbmZpcm1hdGlvbkRpYWxvZ1wiKSBjb25maXJtYXRpb25EaWFsb2c6IENvbmZpcm1hdGlvbkRpYWxvZ0NvbXBvbmVudDtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGVycm9ySGFuZGxlcjogRXJyb3JIYW5kbGVyLFxuICAgIHByaXZhdGUgdHJhbnNsYXRlU2VydmljZTogVHJhbnNsYXRlU2VydmljZSxcbiAgICBwcml2YXRlIHN5c3RlbUluZm9TZXJ2aWNlOiBTeXN0ZW1JbmZvU2VydmljZSxcbiAgICBwcml2YXRlIGhlbG1DaGFydFNlcnZpY2U6IEhlbG1DaGFydFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBvcGVyYXRpb25TZXJ2aWNlOiBPcGVyYXRpb25TZXJ2aWNlLFxuICAgIHByaXZhdGUgY2RyOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgKSB7fVxuXG4gIHB1YmxpYyBnZXQgcmVnaXN0cnlVcmwoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5zeXN0ZW1JbmZvID8gdGhpcy5zeXN0ZW1JbmZvLnJlZ2lzdHJ5X3VybCA6IFwiXCI7XG4gIH1cblxuICBwdWJsaWMgZ2V0IGRldmVsb3BlclJvbGVPckFib3ZlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnByb2plY3RSb2xlSUQgPT09IFJvbGVzLkRFVkVMT1BFUiB8fCB0aGlzLmhhc1Byb2plY3RBZG1pblJvbGU7XG4gIH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICAvLyBHZXQgc3lzdGVtIGluZm8gZm9yIHRhZyB2aWV3c1xuICAgIHRvUHJvbWlzZTxTeXN0ZW1JbmZvPih0aGlzLnN5c3RlbUluZm9TZXJ2aWNlLmdldFN5c3RlbUluZm8oKSlcbiAgICAgIC50aGVuKHN5c3RlbUluZm8gPT4gKHRoaXMuc3lzdGVtSW5mbyA9IHN5c3RlbUluZm8pKVxuICAgICAgLmNhdGNoKGVycm9yID0+IHRoaXMuZXJyb3JIYW5kbGVyLmVycm9yKGVycm9yKSk7XG4gICAgdGhpcy5sYXN0RmlsdGVyZWRDaGFydE5hbWUgPSBcIlwiO1xuICAgIHRoaXMucmVmcmVzaCgpO1xuICB9XG5cbiAgdXBkYXRlRmlsdGVyVmFsdWUodmFsdWU6IHN0cmluZykge1xuICAgIHRoaXMubGFzdEZpbHRlcmVkQ2hhcnROYW1lID0gdmFsdWU7XG4gICAgdGhpcy5yZWZyZXNoKCk7XG4gIH1cblxuICByZWZyZXNoKCkge1xuICAgIHRoaXMubG9hZGluZyA9IHRydWU7XG4gICAgdGhpcy5oZWxtQ2hhcnRTZXJ2aWNlXG4gICAgLmdldEhlbG1DaGFydHModGhpcy5wcm9qZWN0TmFtZSlcbiAgICAucGlwZShmaW5hbGl6ZSgoKSA9PiB7XG4gICAgICAgIGxldCBobmQgPSBzZXRJbnRlcnZhbCgoKSA9PiB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKSwgMTAwKTtcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiBjbGVhckludGVydmFsKGhuZCksIDMwMDApO1xuICAgICAgICB0aGlzLmxvYWRpbmcgPSBmYWxzZTtcbiAgICB9KSlcbiAgICAuc3Vic2NyaWJlKFxuICAgICAgY2hhcnRzID0+IHtcbiAgICAgICAgdGhpcy5jaGFydHMgPSBjaGFydHMuZmlsdGVyKHggPT4geC5uYW1lLmluY2x1ZGVzKHRoaXMubGFzdEZpbHRlcmVkQ2hhcnROYW1lKSk7XG4gICAgICAgIHRoaXMuY2hhcnRzQ29weSA9IGNoYXJ0cy5tYXAoeCA9PiBPYmplY3QuYXNzaWduKHt9LCB4KSk7XG4gICAgICAgIHRoaXMudG90YWxDb3VudCA9IGNoYXJ0cy5sZW5ndGg7XG4gICAgICB9LFxuICAgICAgZXJyID0+IHtcbiAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIuZXJyb3IoZXJyKTtcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgb25DaGFydENsaWNrKGl0ZW06IEhlbG1DaGFydEl0ZW0pIHtcbiAgICB0aGlzLmNoYXJ0Q2xpY2tFdnQuZW1pdChpdGVtLm5hbWUpO1xuICB9XG5cbiAgcmVzZXRVcGxvYWRGb3JtKCkge1xuICAgIHRoaXMuY2hhcnRGaWxlID0gbnVsbDtcbiAgICB0aGlzLnByb3ZGaWxlID0gbnVsbDtcbiAgICB0aGlzLnVwbG9hZEZvcm0ucmVzZXQoKTtcbiAgfVxuXG4gIG9uQ2hhcnRVcGxvYWQoKSB7XG4gICAgdGhpcy5yZXNldFVwbG9hZEZvcm0oKTtcbiAgICB0aGlzLmlzVXBsb2FkTW9kYWxPcGVuID0gdHJ1ZTtcbiAgfVxuXG4gIGNhbmNlbFVwbG9hZCgpIHtcbiAgICB0aGlzLnJlc2V0VXBsb2FkRm9ybSgpO1xuICAgIHRoaXMuaXNVcGxvYWRNb2RhbE9wZW4gPSBmYWxzZTtcbiAgfVxuXG4gIHVwbG9hZCgpIHtcbiAgICBpZiAoIXRoaXMuY2hhcnRGaWxlICYmICF0aGlzLnByb3ZGaWxlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh0aGlzLmlzVXBsb2FkaW5nKSB7IHJldHVybjsgfVxuICAgIHRoaXMuaXNVcGxvYWRpbmcgPSB0cnVlO1xuICAgIHRoaXMuaGVsbUNoYXJ0U2VydmljZVxuICAgICAgLnVwbG9hZENoYXJ0KHRoaXMucHJvamVjdE5hbWUsIHRoaXMuY2hhcnRGaWxlLCB0aGlzLnByb3ZGaWxlKVxuICAgICAgLnBpcGUoZmluYWxpemUoKCkgPT4ge1xuICAgICAgICB0aGlzLmlzVXBsb2FkaW5nID0gZmFsc2U7XG4gICAgICAgIHRoaXMuaXNVcGxvYWRNb2RhbE9wZW4gPSBmYWxzZTtcbiAgICAgICAgdGhpcy5yZWZyZXNoKCk7XG4gICAgICB9KSlcbiAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAgIHRoaXMudHJhbnNsYXRlU2VydmljZVxuICAgICAgICAgICAgLmdldChcIkhFTE1fQ0hBUlQuRklMRV9VUExPQURFRFwiKVxuICAgICAgICAgICAgLnN1YnNjcmliZShyZXMgPT4gdGhpcy5lcnJvckhhbmRsZXIuaW5mbyhyZXMpKTtcbiAgICAgICAgfSxcbiAgICAgICAgZXJyID0+IHRoaXMuZXJyb3JIYW5kbGVyLmVycm9yKGVycilcbiAgICAgICk7XG4gIH1cblxuICBvbkNoYXJ0RmlsZUNoYW5nZUV2ZW50KGV2ZW50KSB7XG4gICAgaWYgKGV2ZW50LnRhcmdldC5maWxlcyAmJiBldmVudC50YXJnZXQuZmlsZXMubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5jaGFydEZpbGUgPSBldmVudC50YXJnZXQuZmlsZXNbMF07XG4gICAgfVxuICB9XG4gIG9uUHJvdkZpbGVDaGFuZ2VFdmVudChldmVudCkge1xuICAgIGlmIChldmVudC50YXJnZXQuZmlsZXMgJiYgZXZlbnQudGFyZ2V0LmZpbGVzLmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMucHJvdkZpbGUgPSBldmVudC50YXJnZXQuZmlsZXNbMF07XG4gICAgfVxuICB9XG5cblxuICBkZWxldGVDaGFydChjaGFydE5hbWU6IHN0cmluZyk6IE9ic2VydmFibGU8YW55PiB7XG4gICAgbGV0IG9wZXJhdGVNc2cgPSBuZXcgT3BlcmF0ZUluZm8oKTtcbiAgICBvcGVyYXRlTXNnLm5hbWUgPSBcIk9QRVJBVElPTi5ERUxFVEVfQ0hBUlRcIjtcbiAgICBvcGVyYXRlTXNnLmRhdGEuaWQgPSBjaGFydE5hbWU7XG4gICAgb3BlcmF0ZU1zZy5zdGF0ZSA9IE9wZXJhdGlvblN0YXRlLnByb2dyZXNzaW5nO1xuICAgIG9wZXJhdGVNc2cuZGF0YS5uYW1lID0gY2hhcnROYW1lO1xuICAgIHRoaXMub3BlcmF0aW9uU2VydmljZS5wdWJsaXNoSW5mbyhvcGVyYXRlTXNnKTtcblxuICAgIHJldHVybiB0aGlzLmhlbG1DaGFydFNlcnZpY2UuZGVsZXRlSGVsbUNoYXJ0KHRoaXMucHJvamVjdE5hbWUsIGNoYXJ0TmFtZSlcbiAgICAucGlwZShtYXAoXG4gICAgICAoKSA9PiBvcGVyYXRlQ2hhbmdlcyhvcGVyYXRlTXNnLCBPcGVyYXRpb25TdGF0ZS5zdWNjZXNzKSxcbiAgICAgIGVyciA9PiBvcGVyYXRlQ2hhbmdlcyhvcGVyYXRlTXNnLCBPcGVyYXRpb25TdGF0ZS5mYWlsdXJlLCBlcnIpXG4gICAgKSk7XG4gIH1cblxuICBkZWxldGVDaGFydHMoY2hhcnRzOiBIZWxtQ2hhcnRJdGVtW10pIHtcbiAgICBpZiAoY2hhcnRzICYmIGNoYXJ0cy5sZW5ndGggPCAxKSB7IHJldHVybjsgfVxuICAgIGxldCBjaGFydHNEZWxldGUkID0gY2hhcnRzLm1hcChjaGFydCA9PiB0aGlzLmRlbGV0ZUNoYXJ0KGNoYXJ0Lm5hbWUpKTtcbiAgICBmb3JrSm9pbihjaGFydHNEZWxldGUkKVxuICAgIC5waXBlKFxuICAgICAgY2F0Y2hFcnJvcihlcnIgPT4gdGhyb3dFcnJvcihlcnIpKSxcbiAgICAgIGZpbmFsaXplKCgpID0+IHtcbiAgICAgICAgdGhpcy5yZWZyZXNoKCk7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRSb3dzID0gW107XG4gICAgICB9KSlcbiAgICAuc3Vic2NyaWJlKCgpID0+IHt9KTtcbiAgfVxuXG4gIGRvd25sb2FkTGF0ZXN0VmVyc2lvbihldnQ/OiBFdmVudCwgaXRlbT86IEhlbG1DaGFydEl0ZW0pIHtcbiAgICBpZiAoZXZ0KSB7XG4gICAgICBldnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfVxuICAgIGxldCBzZWxlY3RlZENoYXJ0OiBIZWxtQ2hhcnRJdGVtO1xuXG4gICAgaWYgKGl0ZW0pIHtcbiAgICAgIHNlbGVjdGVkQ2hhcnQgPSBpdGVtO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyByZXR1cm4gaWYgc2VsZWN0ZWQgdmVyc2lvbiBsZXNzIHRoZW4gMVxuICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRSb3dzLmxlbmd0aCA8IDEpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgc2VsZWN0ZWRDaGFydCA9IHRoaXMuc2VsZWN0ZWRSb3dzWzBdO1xuICAgIH1cbiAgICBpZiAoIXNlbGVjdGVkQ2hhcnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgbGV0IGZpbGVuYW1lID0gYGNoYXJ0cy8ke3NlbGVjdGVkQ2hhcnQubmFtZX0tJHtzZWxlY3RlZENoYXJ0LmxhdGVzdF92ZXJzaW9ufS50Z3pgO1xuICAgIHRoaXMuaGVsbUNoYXJ0U2VydmljZS5kb3dubG9hZENoYXJ0KHRoaXMucHJvamVjdE5hbWUsIGZpbGVuYW1lKS5zdWJzY3JpYmUoXG4gICAgICByZXMgPT4ge1xuICAgICAgICBkb3dubG9hZEZpbGUocmVzKTtcbiAgICAgIH0sXG4gICAgICBlcnJvciA9PiB7XG4gICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyLmVycm9yKGVycm9yKTtcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgb3BlbkNoYXJ0RGVsZXRlTW9kYWwoY2hhcnRzOiBIZWxtQ2hhcnRJdGVtW10pIHtcbiAgICBsZXQgY2hhcnROYW1lcyA9IGNoYXJ0cy5tYXAoY2hhcnQgPT4gY2hhcnQubmFtZSkuam9pbihcIixcIik7XG4gICAgbGV0IG1lc3NhZ2UgPSBuZXcgQ29uZmlybWF0aW9uTWVzc2FnZShcbiAgICAgIFwiSEVMTV9DSEFSVC5ERUxFVEVfQ0hBUlRfVkVSU0lPTl9USVRMRVwiLFxuICAgICAgXCJIRUxNX0NIQVJULkRFTEVURV9DSEFSVF9WRVJTSU9OXCIsXG4gICAgICBjaGFydE5hbWVzLFxuICAgICAgY2hhcnRzLFxuICAgICAgQ29uZmlybWF0aW9uVGFyZ2V0cy5IRUxNX0NIQVJULFxuICAgICAgQ29uZmlybWF0aW9uQnV0dG9ucy5ERUxFVEVfQ0FOQ0VMXG4gICAgKTtcbiAgICB0aGlzLmNvbmZpcm1hdGlvbkRpYWxvZy5vcGVuKG1lc3NhZ2UpO1xuICB9XG5cbiAgY29uZmlybURlbGV0aW9uKG1lc3NhZ2U6IENvbmZpcm1hdGlvbkFja25vd2xlZGdlbWVudCkge1xuICAgIGlmIChcbiAgICAgIG1lc3NhZ2UgJiZcbiAgICAgIG1lc3NhZ2Uuc291cmNlID09PSBDb25maXJtYXRpb25UYXJnZXRzLkhFTE1fQ0hBUlQgJiZcbiAgICAgIG1lc3NhZ2Uuc3RhdGUgPT09IENvbmZpcm1hdGlvblN0YXRlLkNPTkZJUk1FRFxuICAgICkge1xuICAgICAgbGV0IGNoYXJ0cyA9IG1lc3NhZ2UuZGF0YTtcbiAgICAgIHRoaXMuZGVsZXRlQ2hhcnRzKGNoYXJ0cyk7XG4gICAgfVxuICB9XG5cbiAgc2hvd0NhcmQoY2FyZFZpZXc6IGJvb2xlYW4pIHtcbiAgICBpZiAodGhpcy5pc0NhcmRWaWV3ID09PSBjYXJkVmlldykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmlzQ2FyZFZpZXcgPSBjYXJkVmlldztcbiAgfVxuXG4gIG1vdXNlRW50ZXIoaXRlbU5hbWU6IHN0cmluZykge1xuICAgIGlmIChpdGVtTmFtZSA9PT0gXCJjYXJkXCIpIHtcbiAgICAgIHRoaXMuY2FyZEhvdmVyID0gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5saXN0SG92ZXIgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIG1vdXNlTGVhdmUoaXRlbU5hbWU6IHN0cmluZykge1xuICAgIGlmIChpdGVtTmFtZSA9PT0gXCJjYXJkXCIpIHtcbiAgICAgIHRoaXMuY2FyZEhvdmVyID0gZmFsc2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubGlzdEhvdmVyID0gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgaXNIb3ZlcmluZyhpdGVtTmFtZTogc3RyaW5nKSB7XG4gICAgaWYgKGl0ZW1OYW1lID09PSBcImNhcmRcIikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FyZEhvdmVyO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5saXN0SG92ZXI7XG4gICAgfVxuICB9XG5cbiAgZ2V0RGVmYXVsdEljb24oY2hhcnQ6IEhlbG1DaGFydEl0ZW0pIHtcbiAgICBjaGFydC5pY29uID0gdGhpcy5jaGFydERlZmF1bHRJY29uO1xuICB9XG5cbiAgZ2V0U3RhdHVzU3RyaW5nKGNoYXJ0OiBIZWxtQ2hhcnRJdGVtKSB7XG4gICAgaWYgKGNoYXJ0LmRlcHJlY2F0ZWQpIHtcbiAgICAgIHJldHVybiBcIkhFTE1fQ0hBUlQuREVQUkVDQVRFRFwiO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gXCJIRUxNX0NIQVJULkFDVElWRVwiO1xuICAgIH1cbiAgfVxufVxuIl19