@harbor/ui
Version:
Harbor shared UI components based on Clarity and Angular6
276 lines (275 loc) • 30.2 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
import { Component, ViewChild, ChangeDetectionStrategy, ChangeDetectorRef } from "@angular/core";
import { forkJoin } from "rxjs";
import { TranslateService } from "@ngx-translate/core";
import { EndpointService } from "../service/endpoint.service";
import { ErrorHandler } from "../error-handler/index";
import { ConfirmationMessage } from "../confirmation-dialog/confirmation-message";
import { ConfirmationDialogComponent } from "../confirmation-dialog/confirmation-dialog.component";
import { CreateEditEndpointComponent } from "../create-edit-endpoint/create-edit-endpoint.component";
import { toPromise, CustomComparator } from "../utils";
import { operateChanges, OperateInfo, OperationState } from "../operation/operate";
import { OperationService } from "../operation/operation.service";
export class EndpointComponent {
/**
* @param {?} endpointService
* @param {?} errorHandler
* @param {?} translateService
* @param {?} operationService
* @param {?} ref
*/
constructor(endpointService, errorHandler, translateService, operationService, ref) {
this.endpointService = endpointService;
this.errorHandler = errorHandler;
this.translateService = translateService;
this.operationService = operationService;
this.ref = ref;
this.loading = false;
this.creationTimeComparator = new CustomComparator("creation_time", "date");
this.selectedRow = [];
this.forceRefreshView(1000);
}
/**
* @return {?}
*/
get initEndpoint() {
return {
endpoint: "",
name: "",
username: "",
password: "",
insecure: false,
type: 0
};
}
/**
* @return {?}
*/
ngOnInit() {
this.targetName = "";
this.retrieve();
}
/**
* @return {?}
*/
ngOnDestroy() {
if (this.subscription) {
this.subscription.unsubscribe();
}
}
/**
* @return {?}
*/
selectedChange() {
this.forceRefreshView(5000);
}
/**
* @return {?}
*/
retrieve() {
this.loading = true;
this.selectedRow = [];
toPromise(this.endpointService.getEndpoints(this.targetName))
.then(targets => {
this.targets = targets || [];
this.forceRefreshView(1000);
this.loading = false;
})
.catch(error => {
this.errorHandler.error(error);
this.loading = false;
});
}
/**
* @param {?} targetName
* @return {?}
*/
doSearchTargets(targetName) {
this.targetName = targetName;
this.retrieve();
}
/**
* @return {?}
*/
refreshTargets() {
this.retrieve();
}
/**
* @param {?} $event
* @return {?}
*/
reload($event) {
this.targetName = "";
this.retrieve();
}
/**
* @return {?}
*/
openModal() {
this.createEditEndpointComponent.openCreateEditTarget(true);
this.target = this.initEndpoint;
}
/**
* @param {?} targets
* @return {?}
*/
editTargets(targets) {
if (targets && targets.length === 1) {
/** @type {?} */
let target = targets[0];
/** @type {?} */
let editable = true;
if (!target.id) {
return;
}
/** @type {?} */
let id = target.id;
this.createEditEndpointComponent.openCreateEditTarget(editable, id);
}
}
/**
* @param {?} targets
* @return {?}
*/
deleteTargets(targets) {
if (targets && targets.length) {
/** @type {?} */
let targetNames = [];
targets.forEach(target => {
targetNames.push(target.name);
});
/** @type {?} */
let deletionMessage = new ConfirmationMessage('REPLICATION.DELETION_TITLE_TARGET', 'REPLICATION.DELETION_SUMMARY_TARGET', targetNames.join(', ') || '', targets, 6 /* TARGET */, 2 /* DELETE_CANCEL */);
this.confirmationDialogComponent.open(deletionMessage);
}
}
/**
* @param {?} message
* @return {?}
*/
confirmDeletion(message) {
if (message &&
message.source === 6 /* TARGET */ &&
message.state === 1 /* CONFIRMED */) {
/** @type {?} */
let targetLists = message.data;
if (targetLists && targetLists.length) {
/** @type {?} */
let promiseLists = [];
targetLists.forEach(target => {
promiseLists.push(this.delOperate(target));
});
Promise.all(promiseLists).then((item) => {
this.selectedRow = [];
this.reload(true);
this.forceRefreshView(2000);
});
}
}
}
/**
* @param {?} target
* @return {?}
*/
delOperate(target) {
/** @type {?} */
let operMessage = new OperateInfo();
operMessage.name = 'OPERATION.DELETE_REGISTRY';
operMessage.data["id"] = target.id;
operMessage.state = OperationState.progressing;
operMessage.data["name"] = target.name;
this.operationService.publishInfo(operMessage);
return toPromise(this.endpointService
.deleteEndpoint(target.id))
.then(response => {
this.translateService.get('BATCH.DELETED_SUCCESS')
.subscribe(res => {
operateChanges(operMessage, OperationState.success);
});
}).catch(error => {
if (error && error.status === 412) {
forkJoin(this.translateService.get('BATCH.DELETED_FAILURE'), this.translateService.get('DESTINATION.FAILED_TO_DELETE_TARGET_IN_USED')).subscribe(res => {
operateChanges(operMessage, OperationState.failure, res[1]);
});
}
else {
this.translateService.get('BATCH.DELETED_FAILURE').subscribe(res => {
operateChanges(operMessage, OperationState.failure, res);
});
}
});
}
/**
* @param {?} duration
* @return {?}
*/
forceRefreshView(duration) {
// Reset timer
if (this.timerHandler) {
clearInterval(this.timerHandler);
}
this.timerHandler = setInterval(() => this.ref.markForCheck(), 100);
setTimeout(() => {
if (this.timerHandler) {
clearInterval(this.timerHandler);
this.timerHandler = null;
}
}, duration);
}
}
EndpointComponent.decorators = [
{ type: Component, args: [{
selector: "hbr-endpoint",
template: "<div>\n <div class=\"row\" style=\"position:relative;\">\n <div>\n <div class=\"row flex-items-xs-between rightPos\">\n <div class=\"flex-items-xs-middle option-right\">\n <hbr-filter [withDivider]=\"true\" filterPlaceholder='{{\"REPLICATION.FILTER_TARGETS_PLACEHOLDER\" | translate}}' (filterEvt)=\"doSearchTargets($event)\" [currentValue]=\"targetName\"></hbr-filter>\n <span class=\"refresh-btn\" (click)=\"refreshTargets()\">\n <clr-icon shape=\"refresh\"></clr-icon>\n </span>\n </div>\n </div>\n </div>\n <div class=\"col-lg-12 col-md-12 col-sm-12 col-xs-12\">\n <clr-datagrid [clrDgLoading]=\"loading\" [(clrDgSelected)]=\"selectedRow\" (clrDgSelectedChange)=\"selectedChange()\">\n <clr-dg-action-bar>\n <button type=\"button\" class=\"btn btn-sm btn-secondary\" (click)=\"openModal()\"><clr-icon shape=\"plus\" size=\"16\"></clr-icon> {{'DESTINATION.NEW_ENDPOINT' | translate}}</button>\n <button type=\"button\" class=\"btn btn-sm btn-secondary\" [disabled]=\"!(selectedRow.length ===1)\" (click)=\"editTargets(selectedRow)\" ><clr-icon shape=\"pencil\" size=\"16\"></clr-icon> {{'DESTINATION.EDIT' | translate}}</button>\n <button type=\"button\" class=\"btn btn-sm btn-secondary\" [disabled]=\"!selectedRow.length\" (click)=\"deleteTargets(selectedRow)\"><clr-icon shape=\"times\" size=\"16\"></clr-icon> {{'DESTINATION.DELETE' | translate}}</button>\n </clr-dg-action-bar>\n <clr-dg-column [clrDgField]=\"'name'\">{{'DESTINATION.NAME' | translate}}</clr-dg-column>\n <clr-dg-column [clrDgField]=\"'endpoint'\">{{'DESTINATION.URL' | translate}}</clr-dg-column>\n <clr-dg-column [clrDgField]=\"'insecure'\">{{'CONFIG.VERIFY_REMOTE_CERT' | translate }}</clr-dg-column>\n <clr-dg-column [clrDgSortBy]=\"creationTimeComparator\">{{'DESTINATION.CREATION_TIME' | translate}}</clr-dg-column>\n <clr-dg-placeholder>{{'DESTINATION.PLACEHOLDER' | translate }}</clr-dg-placeholder>\n <clr-dg-row *clrDgItems=\"let t of targets\" [clrDgItem]='t'>\n <clr-dg-cell>{{t.name}}</clr-dg-cell>\n <clr-dg-cell>{{t.endpoint}}</clr-dg-cell>\n <clr-dg-cell>\n {{!t.insecure}}\n </clr-dg-cell>\n <clr-dg-cell>{{t.creation_time | date: 'short'}}</clr-dg-cell>\n </clr-dg-row>\n <clr-dg-footer>\n <span *ngIf=\"pagination.totalItems\">{{pagination.firstItem + 1}} - {{pagination.lastItem + 1}} {{'DESTINATION.OF' | translate}}</span>\n {{pagination.totalItems}} {{'DESTINATION.ITEMS' | translate}}\n <clr-dg-pagination #pagination [clrDgPageSize]=\"15\"></clr-dg-pagination>\n </clr-dg-footer>\n </clr-datagrid>\n </div>\n </div>\n <confirmation-dialog #confirmationDialog (confirmAction)=\"confirmDeletion($event)\"></confirmation-dialog>\n <hbr-create-edit-endpoint (reload)=\"reload($event)\"></hbr-create-edit-endpoint>\n</div>",
changeDetection: ChangeDetectionStrategy.OnPush,
styles: [".option-left{padding-left:16px;margin-top:-6px}.option-right{padding-right:16px}.refresh-btn{cursor:pointer}.refresh-btn:hover{color:#007cbb}.rightPos{position:absolute;z-index:100;right:35px;margin-top:4px;height:24px}"]
}] }
];
/** @nocollapse */
EndpointComponent.ctorParameters = () => [
{ type: EndpointService },
{ type: ErrorHandler },
{ type: TranslateService },
{ type: OperationService },
{ type: ChangeDetectorRef }
];
EndpointComponent.propDecorators = {
createEditEndpointComponent: [{ type: ViewChild, args: [CreateEditEndpointComponent,] }],
confirmationDialogComponent: [{ type: ViewChild, args: ["confirmationDialog",] }]
};
if (false) {
/** @type {?} */
EndpointComponent.prototype.createEditEndpointComponent;
/** @type {?} */
EndpointComponent.prototype.confirmationDialogComponent;
/** @type {?} */
EndpointComponent.prototype.targets;
/** @type {?} */
EndpointComponent.prototype.target;
/** @type {?} */
EndpointComponent.prototype.targetName;
/** @type {?} */
EndpointComponent.prototype.subscription;
/** @type {?} */
EndpointComponent.prototype.loading;
/** @type {?} */
EndpointComponent.prototype.creationTimeComparator;
/** @type {?} */
EndpointComponent.prototype.timerHandler;
/** @type {?} */
EndpointComponent.prototype.selectedRow;
/** @type {?} */
EndpointComponent.prototype.endpointService;
/** @type {?} */
EndpointComponent.prototype.errorHandler;
/** @type {?} */
EndpointComponent.prototype.translateService;
/** @type {?} */
EndpointComponent.prototype.operationService;
/** @type {?} */
EndpointComponent.prototype.ref;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW5kcG9pbnQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vQGhhcmJvci91aS8iLCJzb3VyY2VzIjpbInNyYy9lbmRwb2ludC9lbmRwb2ludC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQWFBLE9BQU8sRUFDSCxTQUFTLEVBR1QsU0FBUyxFQUNULHVCQUF1QixFQUN2QixpQkFBaUIsRUFDcEIsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLE1BQU0sQ0FBQztBQUM5QixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUl2RCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFFOUQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRXRELE9BQU8sRUFBQyxtQkFBbUIsRUFBQyxNQUFNLDZDQUE2QyxDQUFDO0FBRWhGLE9BQU8sRUFBQywyQkFBMkIsRUFBQyxNQUFNLHNEQUFzRCxDQUFDO0FBUWpHLE9BQU8sRUFBRSwyQkFBMkIsRUFBRSxNQUFNLHdEQUF3RCxDQUFDO0FBQ3JHLE9BQU8sRUFBRSxTQUFTLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFFdkQsT0FBTyxFQUFDLGNBQWMsRUFBRSxXQUFXLEVBQUUsY0FBYyxFQUFDLE1BQU0sc0JBQXNCLENBQUM7QUFDakYsT0FBTyxFQUFDLGdCQUFnQixFQUFDLE1BQU0sZ0NBQWdDLENBQUM7QUFRaEUsTUFBTTs7Ozs7Ozs7SUFrQ0YsWUFBb0IsZUFBZ0MsRUFDaEMsY0FDQSxrQkFDQSxrQkFDQTtRQUpBLG9CQUFlLEdBQWYsZUFBZSxDQUFpQjtRQUNoQyxpQkFBWSxHQUFaLFlBQVk7UUFDWixxQkFBZ0IsR0FBaEIsZ0JBQWdCO1FBQ2hCLHFCQUFnQixHQUFoQixnQkFBZ0I7UUFDaEIsUUFBRyxHQUFILEdBQUc7dUJBekJKLEtBQUs7c0NBRXVCLElBQUksZ0JBQWdCLENBQy9ELGVBQWUsRUFDZixNQUFNLENBQ1Q7MkJBR3lCLEVBQUU7UUFrQnhCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztLQUMvQjs7OztJQWpCRCxJQUFJLFlBQVk7UUFDWixPQUFPO1lBQ0gsUUFBUSxFQUFFLEVBQUU7WUFDWixJQUFJLEVBQUUsRUFBRTtZQUNSLFFBQVEsRUFBRSxFQUFFO1lBQ1osUUFBUSxFQUFFLEVBQUU7WUFDWixRQUFRLEVBQUUsS0FBSztZQUNmLElBQUksRUFBRSxDQUFDO1NBQ1YsQ0FBQztLQUNMOzs7O0lBVUQsUUFBUTtRQUNKLElBQUksQ0FBQyxVQUFVLEdBQUcsRUFBRSxDQUFDO1FBQ3JCLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztLQUNuQjs7OztJQUVELFdBQVc7UUFDUCxJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUU7WUFDbkIsSUFBSSxDQUFDLFlBQVksQ0FBQyxXQUFXLEVBQUUsQ0FBQztTQUNuQztLQUNKOzs7O0lBRUQsY0FBYztRQUNWLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztLQUMvQjs7OztJQUVELFFBQVE7UUFDSixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQztRQUNwQixJQUFJLENBQUMsV0FBVyxHQUFHLEVBQUUsQ0FBQztRQUN0QixTQUFTLENBQWEsSUFBSSxDQUFDLGVBQWUsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO2FBQ3BFLElBQUksQ0FBQyxPQUFPLENBQUMsRUFBRTtZQUNaLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxJQUFJLEVBQUUsQ0FBQztZQUM3QixJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDNUIsSUFBSSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7U0FDeEIsQ0FBQzthQUNELEtBQUssQ0FBQyxLQUFLLENBQUMsRUFBRTtZQUNYLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQy9CLElBQUksQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDO1NBQ3hCLENBQUMsQ0FBQztLQUNWOzs7OztJQUVELGVBQWUsQ0FBQyxVQUFrQjtRQUM5QixJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQztRQUM3QixJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7S0FDbkI7Ozs7SUFFRCxjQUFjO1FBQ1YsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO0tBQ25COzs7OztJQUVELE1BQU0sQ0FBQyxNQUFXO1FBQ2QsSUFBSSxDQUFDLFVBQVUsR0FBRyxFQUFFLENBQUM7UUFDckIsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO0tBQ25COzs7O0lBRUQsU0FBUztRQUNMLElBQUksQ0FBQywyQkFBMkIsQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM1RCxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUM7S0FDbkM7Ozs7O0lBRUQsV0FBVyxDQUFDLE9BQW1CO1FBQzNCLElBQUksT0FBTyxJQUFJLE9BQU8sQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFOztZQUNqQyxJQUFJLE1BQU0sR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7O1lBQ3hCLElBQUksUUFBUSxHQUFHLElBQUksQ0FBQztZQUNwQixJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRTtnQkFDWixPQUFPO2FBQ1Y7O1lBQ0QsSUFBSSxFQUFFLEdBQW9CLE1BQU0sQ0FBQyxFQUFFLENBQUM7WUFDcEMsSUFBSSxDQUFDLDJCQUEyQixDQUFDLG9CQUFvQixDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsQ0FBQztTQUN2RTtLQUNKOzs7OztJQUVELGFBQWEsQ0FBQyxPQUFtQjtRQUM3QixJQUFJLE9BQU8sSUFBSSxPQUFPLENBQUMsTUFBTSxFQUFFOztZQUMzQixJQUFJLFdBQVcsR0FBYSxFQUFFLENBQUM7WUFDL0IsT0FBTyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRTtnQkFDckIsV0FBVyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7YUFDakMsQ0FBQyxDQUFDOztZQUNILElBQUksZUFBZSxHQUFHLElBQUksbUJBQW1CLENBQ3pDLG1DQUFtQyxFQUNuQyxxQ0FBcUMsRUFDckMsV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLEVBQzVCLE9BQU8sd0NBRTJCLENBQUM7WUFDdkMsSUFBSSxDQUFDLDJCQUEyQixDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQztTQUMxRDtLQUNKOzs7OztJQUVELGVBQWUsQ0FBQyxPQUFvQztRQUNoRCxJQUFJLE9BQU87WUFDUCxPQUFPLENBQUMsTUFBTSxtQkFBK0I7WUFDN0MsT0FBTyxDQUFDLEtBQUssc0JBQWdDLEVBQUU7O1lBQy9DLElBQUksV0FBVyxHQUFlLE9BQU8sQ0FBQyxJQUFJLENBQUM7WUFDM0MsSUFBSSxXQUFXLElBQUksV0FBVyxDQUFDLE1BQU0sRUFBRTs7Z0JBQ25DLElBQUksWUFBWSxHQUFVLEVBQUUsQ0FBQztnQkFDN0IsV0FBVyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRTtvQkFDekIsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7aUJBQzlDLENBQUMsQ0FBQztnQkFDSCxPQUFPLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFO29CQUNwQyxJQUFJLENBQUMsV0FBVyxHQUFHLEVBQUUsQ0FBQztvQkFDdEIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztvQkFDbEIsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDO2lCQUMvQixDQUFDLENBQUM7YUFDTjtTQUNKO0tBQ0o7Ozs7O0lBRUQsVUFBVSxDQUFDLE1BQWdCOztRQUV2QixJQUFJLFdBQVcsR0FBRyxJQUFJLFdBQVcsRUFBRSxDQUFDO1FBQ3BDLFdBQVcsQ0FBQyxJQUFJLEdBQUcsMkJBQTJCLENBQUM7UUFDL0MsV0FBVyxDQUFDLElBQUksU0FBTSxNQUFNLENBQUMsRUFBRSxDQUFDO1FBQ2hDLFdBQVcsQ0FBQyxLQUFLLEdBQUcsY0FBYyxDQUFDLFdBQVcsQ0FBQztRQUMvQyxXQUFXLENBQUMsSUFBSSxXQUFRLE1BQU0sQ0FBQyxJQUFJLENBQUM7UUFDcEMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUUvQyxPQUFPLFNBQVMsQ0FBUyxJQUFJLENBQUMsZUFBZTthQUN4QyxjQUFjLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO2FBQzFCLElBQUksQ0FDRCxRQUFRLENBQUMsRUFBRTtZQUNQLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsdUJBQXVCLENBQUM7aUJBQzdDLFNBQVMsQ0FBQyxHQUFHLENBQUMsRUFBRTtnQkFDYixjQUFjLENBQUMsV0FBVyxFQUFFLGNBQWMsQ0FBQyxPQUFPLENBQUMsQ0FBQzthQUN2RCxDQUFDLENBQUM7U0FDVixDQUFDLENBQUMsS0FBSyxDQUNSLEtBQUssQ0FBQyxFQUFFO1lBQ0osSUFBSSxLQUFLLElBQUksS0FBSyxDQUFDLE1BQU0sS0FBSyxHQUFHLEVBQUU7Z0JBQy9CLFFBQVEsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLHVCQUF1QixDQUFDLEVBQ3ZELElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsNkNBQTZDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsRUFBRTtvQkFDMUYsY0FBYyxDQUFDLFdBQVcsRUFBRSxjQUFjLENBQUMsT0FBTyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2lCQUMvRCxDQUFDLENBQUM7YUFDTjtpQkFBTTtnQkFDSCxJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLHVCQUF1QixDQUFDLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxFQUFFO29CQUMvRCxjQUFjLENBQUMsV0FBVyxFQUFFLGNBQWMsQ0FBQyxPQUFPLEVBQUUsR0FBRyxDQUFDLENBQUM7aUJBQzVELENBQUMsQ0FBQzthQUNOO1NBQ0osQ0FBQyxDQUFDO0tBQ2Q7Ozs7O0lBR0QsZ0JBQWdCLENBQUMsUUFBZ0I7O1FBRTdCLElBQUksSUFBSSxDQUFDLFlBQVksRUFBRTtZQUNuQixhQUFhLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1NBQ3BDO1FBQ0QsSUFBSSxDQUFDLFlBQVksR0FBRyxXQUFXLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxZQUFZLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUNwRSxVQUFVLENBQUMsR0FBRyxFQUFFO1lBQ1osSUFBSSxJQUFJLENBQUMsWUFBWSxFQUFFO2dCQUNuQixhQUFhLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO2dCQUNqQyxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQzthQUM1QjtTQUNKLEVBQUUsUUFBUSxDQUFDLENBQUM7S0FDaEI7OztZQTlMSixTQUFTLFNBQUM7Z0JBQ1AsUUFBUSxFQUFFLGNBQWM7Z0JBQ3hCLDB3R0FBd0M7Z0JBRXhDLGVBQWUsRUFBRSx1QkFBdUIsQ0FBQyxNQUFNOzthQUNsRDs7OztZQXpCUSxlQUFlO1lBRWYsWUFBWTtZQU5aLGdCQUFnQjtZQXNCakIsZ0JBQWdCO1lBMUJwQixpQkFBaUI7OzswQ0FtQ2hCLFNBQVMsU0FBQywyQkFBMkI7MENBR3JDLFNBQVMsU0FBQyxvQkFBb0IiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgKGMpIDIwMTcgVk13YXJlLCBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4vL1xuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbi8vIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbi8vIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuLy9cbi8vICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuLy9cbi8vIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbi8vIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbi8vIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuLy8gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuLy8gbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5pbXBvcnQge1xuICAgIENvbXBvbmVudCxcbiAgICBPbkluaXQsXG4gICAgT25EZXN0cm95LFxuICAgIFZpZXdDaGlsZCxcbiAgICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgICBDaGFuZ2VEZXRlY3RvclJlZlxufSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHsgU3Vic2NyaXB0aW9ufSBmcm9tIFwicnhqc1wiO1xuaW1wb3J0IHtmb3JrSm9pbn0gZnJvbSBcInJ4anNcIjtcbmltcG9ydCB7IFRyYW5zbGF0ZVNlcnZpY2UgfSBmcm9tIFwiQG5neC10cmFuc2xhdGUvY29yZVwiO1xuaW1wb3J0IHsgQ29tcGFyYXRvciB9IGZyb20gXCJAY2xyL2FuZ3VsYXJcIjtcblxuaW1wb3J0IHsgRW5kcG9pbnQgfSBmcm9tIFwiLi4vc2VydmljZS9pbnRlcmZhY2VcIjtcbmltcG9ydCB7IEVuZHBvaW50U2VydmljZSB9IGZyb20gXCIuLi9zZXJ2aWNlL2VuZHBvaW50LnNlcnZpY2VcIjtcblxuaW1wb3J0IHsgRXJyb3JIYW5kbGVyIH0gZnJvbSBcIi4uL2Vycm9yLWhhbmRsZXIvaW5kZXhcIjtcblxuaW1wb3J0IHtDb25maXJtYXRpb25NZXNzYWdlfSBmcm9tIFwiLi4vY29uZmlybWF0aW9uLWRpYWxvZy9jb25maXJtYXRpb24tbWVzc2FnZVwiO1xuaW1wb3J0IHtDb25maXJtYXRpb25BY2tub3dsZWRnZW1lbnR9IGZyb20gXCIuLi9jb25maXJtYXRpb24tZGlhbG9nL2NvbmZpcm1hdGlvbi1zdGF0ZS1tZXNzYWdlXCI7XG5pbXBvcnQge0NvbmZpcm1hdGlvbkRpYWxvZ0NvbXBvbmVudH0gZnJvbSBcIi4uL2NvbmZpcm1hdGlvbi1kaWFsb2cvY29uZmlybWF0aW9uLWRpYWxvZy5jb21wb25lbnRcIjtcblxuaW1wb3J0IHtcbiAgICBDb25maXJtYXRpb25UYXJnZXRzLFxuICAgIENvbmZpcm1hdGlvblN0YXRlLFxuICAgIENvbmZpcm1hdGlvbkJ1dHRvbnNcbn0gZnJvbSBcIi4uL3NoYXJlZC9zaGFyZWQuY29uc3RcIjtcblxuaW1wb3J0IHsgQ3JlYXRlRWRpdEVuZHBvaW50Q29tcG9uZW50IH0gZnJvbSBcIi4uL2NyZWF0ZS1lZGl0LWVuZHBvaW50L2NyZWF0ZS1lZGl0LWVuZHBvaW50LmNvbXBvbmVudFwiO1xuaW1wb3J0IHsgdG9Qcm9taXNlLCBDdXN0b21Db21wYXJhdG9yIH0gZnJvbSBcIi4uL3V0aWxzXCI7XG5cbmltcG9ydCB7b3BlcmF0ZUNoYW5nZXMsIE9wZXJhdGVJbmZvLCBPcGVyYXRpb25TdGF0ZX0gZnJvbSBcIi4uL29wZXJhdGlvbi9vcGVyYXRlXCI7XG5pbXBvcnQge09wZXJhdGlvblNlcnZpY2V9IGZyb20gXCIuLi9vcGVyYXRpb24vb3BlcmF0aW9uLnNlcnZpY2VcIjtcblxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6IFwiaGJyLWVuZHBvaW50XCIsXG4gICAgdGVtcGxhdGVVcmw6IFwiLi9lbmRwb2ludC5jb21wb25lbnQuaHRtbFwiLFxuICAgIHN0eWxlVXJsczogW1wiLi9lbmRwb2ludC5jb21wb25lbnQuc2Nzc1wiXSxcbiAgICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaFxufSlcbmV4cG9ydCBjbGFzcyBFbmRwb2ludENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgICBAVmlld0NoaWxkKENyZWF0ZUVkaXRFbmRwb2ludENvbXBvbmVudClcbiAgICBjcmVhdGVFZGl0RW5kcG9pbnRDb21wb25lbnQ6IENyZWF0ZUVkaXRFbmRwb2ludENvbXBvbmVudDtcblxuICAgIEBWaWV3Q2hpbGQoXCJjb25maXJtYXRpb25EaWFsb2dcIilcbiAgICBjb25maXJtYXRpb25EaWFsb2dDb21wb25lbnQ6IENvbmZpcm1hdGlvbkRpYWxvZ0NvbXBvbmVudDtcblxuICAgIHRhcmdldHM6IEVuZHBvaW50W107XG4gICAgdGFyZ2V0OiBFbmRwb2ludDtcblxuICAgIHRhcmdldE5hbWU6IHN0cmluZztcbiAgICBzdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbjtcblxuICAgIGxvYWRpbmc6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAgIGNyZWF0aW9uVGltZUNvbXBhcmF0b3I6IENvbXBhcmF0b3I8RW5kcG9pbnQ+ID0gbmV3IEN1c3RvbUNvbXBhcmF0b3I8RW5kcG9pbnQ+KFxuICAgICAgICBcImNyZWF0aW9uX3RpbWVcIixcbiAgICAgICAgXCJkYXRlXCJcbiAgICApO1xuXG4gICAgdGltZXJIYW5kbGVyOiBhbnk7XG4gICAgc2VsZWN0ZWRSb3c6IEVuZHBvaW50W10gPSBbXTtcblxuICAgIGdldCBpbml0RW5kcG9pbnQoKTogRW5kcG9pbnQge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZW5kcG9pbnQ6IFwiXCIsXG4gICAgICAgICAgICBuYW1lOiBcIlwiLFxuICAgICAgICAgICAgdXNlcm5hbWU6IFwiXCIsXG4gICAgICAgICAgICBwYXNzd29yZDogXCJcIixcbiAgICAgICAgICAgIGluc2VjdXJlOiBmYWxzZSxcbiAgICAgICAgICAgIHR5cGU6IDBcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGVuZHBvaW50U2VydmljZTogRW5kcG9pbnRTZXJ2aWNlLFxuICAgICAgICAgICAgICAgIHByaXZhdGUgZXJyb3JIYW5kbGVyOiBFcnJvckhhbmRsZXIsXG4gICAgICAgICAgICAgICAgcHJpdmF0ZSB0cmFuc2xhdGVTZXJ2aWNlOiBUcmFuc2xhdGVTZXJ2aWNlLFxuICAgICAgICAgICAgICAgIHByaXZhdGUgb3BlcmF0aW9uU2VydmljZTogT3BlcmF0aW9uU2VydmljZSxcbiAgICAgICAgICAgICAgICBwcml2YXRlIHJlZjogQ2hhbmdlRGV0ZWN0b3JSZWYpIHtcbiAgICAgICAgdGhpcy5mb3JjZVJlZnJlc2hWaWV3KDEwMDApO1xuICAgIH1cblxuICAgIG5nT25Jbml0KCk6IHZvaWQge1xuICAgICAgICB0aGlzLnRhcmdldE5hbWUgPSBcIlwiO1xuICAgICAgICB0aGlzLnJldHJpZXZlKCk7XG4gICAgfVxuXG4gICAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN1YnNjcmlwdGlvbikge1xuICAgICAgICAgICAgdGhpcy5zdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHNlbGVjdGVkQ2hhbmdlKCk6IHZvaWQge1xuICAgICAgICB0aGlzLmZvcmNlUmVmcmVzaFZpZXcoNTAwMCk7XG4gICAgfVxuXG4gICAgcmV0cmlldmUoKTogdm9pZCB7XG4gICAgICAgIHRoaXMubG9hZGluZyA9IHRydWU7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRSb3cgPSBbXTtcbiAgICAgICAgdG9Qcm9taXNlPEVuZHBvaW50W10+KHRoaXMuZW5kcG9pbnRTZXJ2aWNlLmdldEVuZHBvaW50cyh0aGlzLnRhcmdldE5hbWUpKVxuICAgICAgICAgICAgLnRoZW4odGFyZ2V0cyA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy50YXJnZXRzID0gdGFyZ2V0cyB8fCBbXTtcbiAgICAgICAgICAgICAgICB0aGlzLmZvcmNlUmVmcmVzaFZpZXcoMTAwMCk7XG4gICAgICAgICAgICAgICAgdGhpcy5sb2FkaW5nID0gZmFsc2U7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmVycm9ySGFuZGxlci5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgdGhpcy5sb2FkaW5nID0gZmFsc2U7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBkb1NlYXJjaFRhcmdldHModGFyZ2V0TmFtZTogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMudGFyZ2V0TmFtZSA9IHRhcmdldE5hbWU7XG4gICAgICAgIHRoaXMucmV0cmlldmUoKTtcbiAgICB9XG5cbiAgICByZWZyZXNoVGFyZ2V0cygpIHtcbiAgICAgICAgdGhpcy5yZXRyaWV2ZSgpO1xuICAgIH1cblxuICAgIHJlbG9hZCgkZXZlbnQ6IGFueSkge1xuICAgICAgICB0aGlzLnRhcmdldE5hbWUgPSBcIlwiO1xuICAgICAgICB0aGlzLnJldHJpZXZlKCk7XG4gICAgfVxuXG4gICAgb3Blbk1vZGFsKCkge1xuICAgICAgICB0aGlzLmNyZWF0ZUVkaXRFbmRwb2ludENvbXBvbmVudC5vcGVuQ3JlYXRlRWRpdFRhcmdldCh0cnVlKTtcbiAgICAgICAgdGhpcy50YXJnZXQgPSB0aGlzLmluaXRFbmRwb2ludDtcbiAgICB9XG5cbiAgICBlZGl0VGFyZ2V0cyh0YXJnZXRzOiBFbmRwb2ludFtdKSB7XG4gICAgICAgIGlmICh0YXJnZXRzICYmIHRhcmdldHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICBsZXQgdGFyZ2V0ID0gdGFyZ2V0c1swXTtcbiAgICAgICAgICAgIGxldCBlZGl0YWJsZSA9IHRydWU7XG4gICAgICAgICAgICBpZiAoIXRhcmdldC5pZCkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxldCBpZDogbnVtYmVyIHwgc3RyaW5nID0gdGFyZ2V0LmlkO1xuICAgICAgICAgICAgdGhpcy5jcmVhdGVFZGl0RW5kcG9pbnRDb21wb25lbnQub3BlbkNyZWF0ZUVkaXRUYXJnZXQoZWRpdGFibGUsIGlkKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGRlbGV0ZVRhcmdldHModGFyZ2V0czogRW5kcG9pbnRbXSkge1xuICAgICAgICBpZiAodGFyZ2V0cyAmJiB0YXJnZXRzLmxlbmd0aCkge1xuICAgICAgICAgICAgbGV0IHRhcmdldE5hbWVzOiBzdHJpbmdbXSA9IFtdO1xuICAgICAgICAgICAgdGFyZ2V0cy5mb3JFYWNoKHRhcmdldCA9PiB7XG4gICAgICAgICAgICAgICAgdGFyZ2V0TmFtZXMucHVzaCh0YXJnZXQubmFtZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGxldCBkZWxldGlvbk1lc3NhZ2UgPSBuZXcgQ29uZmlybWF0aW9uTWVzc2FnZShcbiAgICAgICAgICAgICAgICAnUkVQTElDQVRJT04uREVMRVRJT05fVElUTEVfVEFSR0VUJyxcbiAgICAgICAgICAgICAgICAnUkVQTElDQVRJT04uREVMRVRJT05fU1VNTUFSWV9UQVJHRVQnLFxuICAgICAgICAgICAgICAgIHRhcmdldE5hbWVzLmpvaW4oJywgJykgfHwgJycsXG4gICAgICAgICAgICAgICAgdGFyZ2V0cyxcbiAgICAgICAgICAgICAgICBDb25maXJtYXRpb25UYXJnZXRzLlRBUkdFVCxcbiAgICAgICAgICAgICAgICBDb25maXJtYXRpb25CdXR0b25zLkRFTEVURV9DQU5DRUwpO1xuICAgICAgICAgICAgdGhpcy5jb25maXJtYXRpb25EaWFsb2dDb21wb25lbnQub3BlbihkZWxldGlvbk1lc3NhZ2UpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgY29uZmlybURlbGV0aW9uKG1lc3NhZ2U6IENvbmZpcm1hdGlvbkFja25vd2xlZGdlbWVudCkge1xuICAgICAgICBpZiAobWVzc2FnZSAmJlxuICAgICAgICAgICAgbWVzc2FnZS5zb3VyY2UgPT09IENvbmZpcm1hdGlvblRhcmdldHMuVEFSR0VUICYmXG4gICAgICAgICAgICBtZXNzYWdlLnN0YXRlID09PSBDb25maXJtYXRpb25TdGF0ZS5DT05GSVJNRUQpIHtcbiAgICAgICAgICAgIGxldCB0YXJnZXRMaXN0czogRW5kcG9pbnRbXSA9IG1lc3NhZ2UuZGF0YTtcbiAgICAgICAgICAgIGlmICh0YXJnZXRMaXN0cyAmJiB0YXJnZXRMaXN0cy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBsZXQgcHJvbWlzZUxpc3RzOiBhbnlbXSA9IFtdO1xuICAgICAgICAgICAgICAgIHRhcmdldExpc3RzLmZvckVhY2godGFyZ2V0ID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcHJvbWlzZUxpc3RzLnB1c2godGhpcy5kZWxPcGVyYXRlKHRhcmdldCkpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIFByb21pc2UuYWxsKHByb21pc2VMaXN0cykudGhlbigoaXRlbSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdGVkUm93ID0gW107XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucmVsb2FkKHRydWUpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcmNlUmVmcmVzaFZpZXcoMjAwMCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBkZWxPcGVyYXRlKHRhcmdldDogRW5kcG9pbnQpIHtcbiAgICAgICAgLy8gaW5pdCBvcGVyYXRpb24gaW5mb1xuICAgICAgICBsZXQgb3Blck1lc3NhZ2UgPSBuZXcgT3BlcmF0ZUluZm8oKTtcbiAgICAgICAgb3Blck1lc3NhZ2UubmFtZSA9ICdPUEVSQVRJT04uREVMRVRFX1JFR0lTVFJZJztcbiAgICAgICAgb3Blck1lc3NhZ2UuZGF0YS5pZCA9IHRhcmdldC5pZDtcbiAgICAgICAgb3Blck1lc3NhZ2Uuc3RhdGUgPSBPcGVyYXRpb25TdGF0ZS5wcm9ncmVzc2luZztcbiAgICAgICAgb3Blck1lc3NhZ2UuZGF0YS5uYW1lID0gdGFyZ2V0Lm5hbWU7XG4gICAgICAgIHRoaXMub3BlcmF0aW9uU2VydmljZS5wdWJsaXNoSW5mbyhvcGVyTWVzc2FnZSk7XG5cbiAgICAgICAgcmV0dXJuIHRvUHJvbWlzZTxudW1iZXI+KHRoaXMuZW5kcG9pbnRTZXJ2aWNlXG4gICAgICAgICAgICAuZGVsZXRlRW5kcG9pbnQodGFyZ2V0LmlkKSlcbiAgICAgICAgICAgIC50aGVuKFxuICAgICAgICAgICAgICAgIHJlc3BvbnNlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50cmFuc2xhdGVTZXJ2aWNlLmdldCgnQkFUQ0guREVMRVRFRF9TVUNDRVNTJylcbiAgICAgICAgICAgICAgICAgICAgICAgIC5zdWJzY3JpYmUocmVzID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcGVyYXRlQ2hhbmdlcyhvcGVyTWVzc2FnZSwgT3BlcmF0aW9uU3RhdGUuc3VjY2Vzcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9KS5jYXRjaChcbiAgICAgICAgICAgICAgICBlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvciAmJiBlcnJvci5zdGF0dXMgPT09IDQxMikge1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9ya0pvaW4odGhpcy50cmFuc2xhdGVTZXJ2aWNlLmdldCgnQkFUQ0guREVMRVRFRF9GQUlMVVJFJyksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy50cmFuc2xhdGVTZXJ2aWNlLmdldCgnREVTVElOQVRJT04uRkFJTEVEX1RPX0RFTEVURV9UQVJHRVRfSU5fVVNFRCcpKS5zdWJzY3JpYmUocmVzID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcGVyYXRlQ2hhbmdlcyhvcGVyTWVzc2FnZSwgT3BlcmF0aW9uU3RhdGUuZmFpbHVyZSwgcmVzWzFdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy50cmFuc2xhdGVTZXJ2aWNlLmdldCgnQkFUQ0guREVMRVRFRF9GQUlMVVJFJykuc3Vic2NyaWJlKHJlcyA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3BlcmF0ZUNoYW5nZXMob3Blck1lc3NhZ2UsIE9wZXJhdGlvblN0YXRlLmZhaWx1cmUsIHJlcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIEZvcmNlbHkgcmVmcmVzaCB0aGUgdmlld1xuICAgIGZvcmNlUmVmcmVzaFZpZXcoZHVyYXRpb246IG51bWJlcik6IHZvaWQge1xuICAgICAgICAvLyBSZXNldCB0aW1lclxuICAgICAgICBpZiAodGhpcy50aW1lckhhbmRsZXIpIHtcbiAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy50aW1lckhhbmRsZXIpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudGltZXJIYW5kbGVyID0gc2V0SW50ZXJ2YWwoKCkgPT4gdGhpcy5yZWYubWFya0ZvckNoZWNrKCksIDEwMCk7XG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMudGltZXJIYW5kbGVyKSB7XG4gICAgICAgICAgICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLnRpbWVySGFuZGxlcik7XG4gICAgICAgICAgICAgICAgdGhpcy50aW1lckhhbmRsZXIgPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LCBkdXJhdGlvbik7XG4gICAgfVxufVxuIl19