Repository URL to install this package:
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import * as tslib_1 from "tslib";
import { Component, ViewChild, ElementRef, Renderer2 } from '@angular/core';
import { PluginView } from 'web-console-core';
import { NGXLogger } from 'web-console-core';
import { LogService } from '@wa-motif-open-api/log-service';
import { ClipboardService } from 'ngx-clipboard';
import { faExternalLinkSquareAlt } from '@fortawesome/free-solid-svg-icons';
import { faFileImport, faDownload, faCopy, faPaste } from '@fortawesome/free-solid-svg-icons';
import { WCNotificationCenter, NotificationType } from 'web-console-ui-kit';
import { saveAs } from '@progress/kendo-file-saver';
import { DatarecordsService } from '@wa-motif-open-api/datarecords-service';
import { WCSubscriptionHandler } from '../../../components/Commons/wc-subscription-handler';
import { formatDate } from '@angular/common';
import { WCSlidePanelComponent } from 'web-console-ui-kit';
import { DateRangePopupComponent } from '@progress/kendo-angular-dateinputs';
/** @type {?} */
var LOG_TAG = '[LogSection]';
var LogSectionComponent = /** @class */ (function () {
function LogSectionComponent(logger, notificationCenter, logService, renderer2, clipboardService, datarecordsService) {
this.logger = logger;
this.notificationCenter = notificationCenter;
this.logService = logService;
this.renderer2 = renderer2;
this.clipboardService = clipboardService;
this.datarecordsService = datarecordsService;
this.faFileImport = faFileImport;
this.faDownload = faDownload;
this.faExternalLinkSquareAlt = faExternalLinkSquareAlt;
this.faCopy = faCopy;
this.faPaste = faPaste;
this.linesCount = 100;
this.dataRecordTypes = [];
this.range = { start: null, end: null };
this._subHandler = new WCSubscriptionHandler();
this.logger.debug(LOG_TAG, 'Opening...');
this.logLevels = [];
this.logLevels.push({ level: 'ERROR' });
this.logLevels.push({ level: 'WARN' });
this.logLevels.push({ level: 'INFO' });
this.logLevels.push({ level: 'DEBUG' });
this.logLevels.push({ level: 'TRACE' });
}
/**
* Angular ngOnInit
*/
/**
* Angular ngOnInit
* @return {?}
*/
LogSectionComponent.prototype.ngOnInit = /**
* Angular ngOnInit
* @return {?}
*/
function () {
this.logger.debug(LOG_TAG, 'Initializing...');
this.tailLines = '';
this.loadDatarecordsTypes();
this.refreshData();
};
/**
* @return {?}
*/
LogSectionComponent.prototype.ngOnDestroy = /**
* @return {?}
*/
function () {
this.logger.debug(LOG_TAG, 'ngOnDestroy ');
this.freeMem();
};
/**
* @return {?}
*/
LogSectionComponent.prototype.freeMem = /**
* @return {?}
*/
function () {
this.tailLines = null;
this.logLevels = null;
this.dataRecordTypes = null;
this._subHandler.unsubscribe();
this._subHandler = null;
};
/**
* @return {?}
*/
LogSectionComponent.prototype.onRefreshClicked = /**
* @return {?}
*/
function () {
var _this = this;
this.logger.debug(LOG_TAG, 'linesCount :', this.linesCount);
this.loading = true;
this._subHandler.add(this.logService.tailCurrentLog(this.linesCount).subscribe((/**
* @param {?} logTail
* @return {?}
*/
function (logTail) {
_this.tailLines = logTail.data;
_this.currentTailLinesCount = logTail.lines;
_this.loading = false;
}), (/**
* @param {?} error
* @return {?}
*/
function (error) {
_this.logger.error(LOG_TAG, 'tailCurrentLog error:', error);
_this.notificationCenter.post({
name: 'RefreshLogTailError',
title: 'Tail Log',
message: 'Error refreshing log:',
type: NotificationType.Error,
error: error,
closable: true
});
_this.loading = false;
})));
};
/**
* @return {?}
*/
LogSectionComponent.prototype.onCopyToClipboardClicked = /**
* @return {?}
*/
function () {
this.clipboardService.copyFromContent(this.tailLines);
this.notificationCenter.post({
name: 'LogTailCopy',
title: 'Log tail Copy',
message: 'The current displayed log has been copied to the clipboard.',
type: NotificationType.Info
});
};
Object.defineProperty(LogSectionComponent.prototype, "rootLogLevel", {
get: /**
* @return {?}
*/
function () {
return this._rootLogLevel;
},
set: /**
* @param {?} logLevel
* @return {?}
*/
function (logLevel) {
var _this = this;
if (logLevel) {
this._rootLogLevel = logLevel;
this.logger.debug(LOG_TAG, 'Changing ROOT log level :', logLevel);
this._subHandler.add(this.logService.setRootLogLevel(this._rootLogLevel).subscribe((/**
* @param {?} data
* @return {?}
*/
function (data) {
_this.logger.debug(LOG_TAG, 'Changed ROOT log level :', data);
_this.notificationCenter.post({
name: 'RootLogLevelChangeSuccess',
title: 'Log Management',
message: 'The ROOT Log Level has been changed to ' + logLevel.level,
type: NotificationType.Success
});
}), (/**
* @param {?} error
* @return {?}
*/
function (error) {
_this.logger.error(LOG_TAG, 'Error changing ROOT Log Level:', error);
_this.notificationCenter.post({
name: 'RootLogLevelChangeError',
title: 'Log Management',
message: 'Error changing ROOT Log Level:',
type: NotificationType.Error,
error: error,
closable: true
});
})));
}
},
enumerable: true,
configurable: true
});
/**
* @return {?}
*/
LogSectionComponent.prototype.refreshData = /**
* @return {?}
*/
function () {
var _this = this;
this.logService.getRootLogLevel().subscribe((/**
* @param {?} data
* @return {?}
*/
function (data) {
_this.logger.debug(LOG_TAG, 'Getting ROOT log level :', data);
_this._rootLogLevel = data;
}), (/**
* @param {?} error
* @return {?}
*/
function (error) {
_this.logger.error(LOG_TAG, 'Error Getting ROOT log level :', error);
}));
};
/**
* @return {?}
*/
LogSectionComponent.prototype.onDownloadClicked = /**
* @return {?}
*/
function () {
var _this = this;
this.notificationCenter.post({
name: 'LogDownload',
title: 'Download Log',
message: 'Downloading Log file...',
type: NotificationType.Info
});
this._subHandler.add(this.logService.downloadCurrentLog().subscribe((/**
* @param {?} data
* @return {?}
*/
function (data) {
_this.logger.debug(LOG_TAG, 'Export done.', data);
/** @type {?} */
var blob = new Blob([data], { type: 'application/zip' });
/** @type {?} */
var fileName = 'motif_log_' + new Date().getTime() + '.zip';
_this.logger.debug(LOG_TAG, 'Saving to: ', blob);
saveAs(blob, fileName);
// FileSaver.saveAs(blob, fileName);
_this.logger.debug(LOG_TAG, 'Log saved: ', fileName);
_this.notificationCenter.post({
name: 'LogExportSuccess',
title: 'Download Log',
message: 'The Log file has been downloaded.',
type: NotificationType.Success
});
}), (/**
* @param {?} error
* @return {?}
*/
function (error) {
_this.logger.error(LOG_TAG, 'Log download error:', error);
_this.notificationCenter.post({
name: 'LogExportError',
title: 'Download Log',
message: 'Error downloading the Log file:',
type: NotificationType.Error,
error: error,
closable: true
});
})));
};
/**
* @return {?}
*/
LogSectionComponent.prototype.onExportClicked = /**
* @return {?}
*/
function () {
this.exportSlideDownPanel.toggle();
};
/**
* @return {?}
*/
LogSectionComponent.prototype.onExportConfirm = /**
* @return {?}
*/
function () {
if (this.exportDataRecords()) {
this.exportSlideDownPanel.show(false);
}
};
/**
* @return {?}
*/
LogSectionComponent.prototype.onExportCancel = /**
* @return {?}
*/
function () {
this.exportSlideDownPanel.show(false);
};
/**
* @return {?}
*/
LogSectionComponent.prototype.onSlidePanelClose = /**
* @return {?}
*/
function () {
this.range.start = null;
this.range.end = null;
this.dataRecordType = null;
};
/**
* @private
* @param {?} date
* @return {?}
*/
LogSectionComponent.prototype.convertDate = /**
* @private
* @param {?} date
* @return {?}
*/
function (date) {
return formatDate(date, 'yyyy/MM/dd HH:mm:ss', 'en-US');
};
/**
* @private
* @return {?}
*/
LogSectionComponent.prototype.exportDataRecords = /**
* @private
* @return {?}
*/
function () {
var _this = this;
this.logger.debug(LOG_TAG, 'exportDataRecords: ', this.dataRecordType, this.range.start, this.range.end);
if ((this.dataRecordType == null) || (this.range.start == null) || (this.range.end == null)) {
this.notificationCenter.post({
name: 'ExportDataRecordsProgress',
title: 'DataRecords Export',
message: 'Ivalid export parameters.',
type: NotificationType.Warning,
closable: false
});
return false;
}
this.notificationCenter.post({
name: 'ExportDataRecordsProgress',
title: 'DataRecords Export',
message: 'Exporting datarecords...',
type: NotificationType.Info,
closable: false
});
/** @type {?} */
var startDate = this.range.start;
/** @type {?} */
var endDate = this.range.end;
this.logger.debug(LOG_TAG, 'exportDataRecords: ', this.dataRecordType, startDate, endDate);
this._subHandler.add(this.datarecordsService.exportDatarecords(this.dataRecordType, null, null, null, startDate, endDate).subscribe((/**
* @param {?} data
* @return {?}
*/
function (data) {
_this.logger.debug(LOG_TAG, 'exportDataRecords done: ', data);
/** @type {?} */
var blob = new Blob([data], { type: 'application/zip' });
/** @type {?} */
var fileName = 'motif_datarecords_' + new Date().getTime() + '.zip';
_this.logger.debug(LOG_TAG, 'Saving to: ', blob);
saveAs(blob, fileName);
_this.logger.debug(LOG_TAG, 'Log saved: ', fileName);
_this.notificationCenter.post({
name: 'ExportDataRecordsSuccess',
title: 'DataRecords Export',
message: 'Datarecords exported successfully.',
type: NotificationType.Success,
closable: false
});
}), (/**
* @param {?} error
* @return {?}
*/
function (error) {
_this.logger.error(LOG_TAG, 'exportDataRecords error: ', error);
_this.notificationCenter.post({
name: 'ExportDataRecordsError',
title: 'DataRecord Export',
message: 'Error exporting datarecords:',
type: NotificationType.Error,
error: error,
closable: true
});
})));
return true;
};
/**
* @private
* @return {?}
*/
LogSectionComponent.prototype.loadDatarecordsTypes = /**
* @private
* @return {?}
*/
function () {
var _this = this;
this._subHandler.add(this.datarecordsService.getDatarecordsTypes().subscribe((/**
* @param {?} data
* @return {?}
*/
function (data) {
_this.logger.debug(LOG_TAG, 'loadDatarecordsTypes: ', data);
_this.dataRecordTypes = data;
}), (/**
* @param {?} error
* @return {?}
*/
function (error) {
_this.logger.error(LOG_TAG, 'loadDatarecordsTypes error: ', error);
_this.notificationCenter.post({
name: 'GetDataRecordTypesError',
title: 'Get DataRecord Types',
message: 'Error getting the datarecord types:',
type: NotificationType.Error,
error: error,
closable: true
});
})));
};
/**
* @return {?}
*/
LogSectionComponent.prototype.onDateRangePopupOpen = /**
* @return {?}
*/
function () {
};
LogSectionComponent.decorators = [
{ type: Component, args: [{
selector: 'wa-log-section',
template: "<wc-loading-overlay [visible]='loading'></wc-loading-overlay>\n\n<wc-dashboard-header [title]=\"'Log'\"></wc-dashboard-header>\n\n<div class=\"row spread\">\n\n <div class=\"flex-toolbar\" style=\"display:flex;align-items: center;\">\n <div>\n <label>Lines</label>\n <input type=\"number\" [(ngModel)]=\"linesCount\">\n </div>\n <div>\n <label>ROOT Log Level</label>\n <kendo-dropdownlist \n motif-acl=\"com.vipera.osgi.core.platform.api.rest.LogsApi:UPDATE:setRootLogLevel\"\n [data]=\"logLevels\" [textField]=\"'level'\" [valueField]=\"'level'\" [(ngModel)]=\"rootLogLevel\" [popupSettings]=\"{ 'popupClass' : 'wa-kui-combobox-popup', 'animate' : false }\"\n [valuePrimitive]=\"false\"></kendo-dropdownlist>\n </div>\n </div>\n\n <div class=\"flex-cmd\">\n <kendo-buttongroup look=\"flat\">\n <button kendoButton \n [motif-acl]=\"['com.vipera.osgi.foundation.datarecords.api.rest.DatarecordsApi:READ:exportDatarecords',\n 'com.vipera.osgi.foundation.datarecords.api.rest.DatarecordsApi:READ:verifyDatarecordsExport',\n 'com.vipera.osgi.foundation.datarecords.api.rest.DatarecordsApi:READ:getDatarecordsTypes']\"\n [toggleable]=\"false\" (click)=\"onExportClicked()\">\n <fa-icon [icon]=\"faExternalLinkSquareAlt\"></fa-icon>Export\n </button>\n </kendo-buttongroup>\n <kendo-buttongroup look=\"flat\">\n <button kendoButton \n motif-acl=\"com.vipera.osgi.core.platform.api.rest.LogsApi:READ:downloadCurrentLog\"\n [toggleable]=\"false\" (click)=\"onDownloadClicked()\">\n <fa-icon [icon]=\"faDownload\"></fa-icon>Download\n </button>\n </kendo-buttongroup>\n <kendo-buttongroup look=\"flat\">\n <button kendoButton [toggleable]=\"false\" [icon]=\"'refresh'\" (click)=\"onRefreshClicked()\">Refresh</button>\n </kendo-buttongroup>\n </div>\n\n</div>\n\n<div class=\"row fill\">\n <div>\n\n <!-- Sliding Editor Panel for Export -->\n <wc-slide-panel #exportSlideDownPanel (close)=\"onSlidePanelClose()\">\n <div class=\"wc-slide-down-editor-pane\" style=\"display:flex;\">\n <div>\n <label>Data Record Type</label>\n <kendo-dropdownlist [data]=\"dataRecordTypes\" [(ngModel)]=\"dataRecordType\" [valuePrimitive]=\"true\" [popupSettings]=\"{ 'popupClass' : 'wa-kui-combobox-popup', 'animate' : false }\"></kendo-dropdownlist>\n </div>\n <div>\n <kendo-daterange style=\"display:flex;\">\n <div>\n <label>Start</label>\n <kendo-dateinput kendoDateRangeStartInput [(value)]=\"range.start\"></kendo-dateinput>\n </div>\n <div>\n <label>End</label>\n <kendo-dateinput kendoDateRangeEndInput [(value)]=\"range.end\"></kendo-dateinput>\n </div>\n <kendo-daterange-popup (open)=\"onDateRangePopupOpen()\" #dateRangePopup></kendo-daterange-popup>\n </kendo-daterange>\n </div>\n </div>\n \n <div class=\"cmd\" style=\"align-items: center;margin-top:.5rem;\">\n <label style=\"padding-bottom: 0px;padding-left: 10px;padding-right: 10px;\">Do Export ?</label>\n <a (click)=\"onExportConfirm()\">\n <i data-id=\"ok\" class=\"ok icon wa-ico-ok confirmation-icon\"></i>\n </a>\n <a (click)=\"onExportCancel()\" data-slideup=\"#exportSlideDownPanel\">\n <i data-id=\"ko\" class=\"ko icon wa-ico-ko confirmation-icon\"></i>\n </a>\n </div>\n \n </wc-slide-panel>\n\n <!-- Log Pane -->\n <label>Log <div class=\"cmd\"><button class=\"small small-copy-button\" data-copy=\"#output\" (click)=\"onCopyToClipboardClicked()\">\n <fa-icon [icon]=\"faPaste\" style=\"font-size: 18px;padding-left: 4px;\"></fa-icon>\n </button></div></label>\n <textarea class=\"fill log-pane\" spellcheck=\"false\" id=\"output\" #logPane readonly>{{tailLines}}</textarea>\n </div>\n</div>\n",
styles: [":host{display:flex;flex:1;flex-direction:column}.log-pane{white-space:pre}.editor.slidedown>div>kendo-daterange>div>label,.editor.slidedown>div>label{padding-bottom:5px}.small-copy-button{height:2rem;width:2rem;border-radius:50px}.wc-slide-down-editor-pane label{margin-bottom:4px}.wc-slide-down-editor-pane div{margin-right:8px}"]
}] }
];
/** @nocollapse */
LogSectionComponent.ctorParameters = function () { return [
{ type: NGXLogger },
{ type: WCNotificationCenter },
{ type: LogService },
{ type: Renderer2 },
{ type: ClipboardService },
{ type: DatarecordsService }
]; };
LogSectionComponent.propDecorators = {
logPane: [{ type: ViewChild, args: ['logPane',] }],
exportSlideDownPanel: [{ type: ViewChild, args: ['exportSlideDownPanel',] }],
dateRangePopup: [{ type: ViewChild, args: ['dateRangePopup',] }]
};
LogSectionComponent = tslib_1.__decorate([
PluginView('Log', {
iconName: 'wa-ico-log',
userData: {
acl: {
permissions: ['com.vipera.osgi.core.platform.api.rest.LogsApi:READ:tailCurrentLog',
'com.vipera.osgi.core.platform.api.rest.LogsApi:READ:getRootLogLevel']
}
}
}),
tslib_1.__metadata("design:paramtypes", [NGXLogger,
WCNotificationCenter,
LogService,
Renderer2,
ClipboardService,
DatarecordsService])
], LogSectionComponent);
return LogSectionComponent;
}());
export { LogSectionComponent };
if (false) {
/** @type {?} */
LogSectionComponent.prototype.faFileImport;
/** @type {?} */
LogSectionComponent.prototype.faDownload;
/** @type {?} */
LogSectionComponent.prototype.faExternalLinkSquareAlt;
/** @type {?} */
LogSectionComponent.prototype.faCopy;
/** @type {?} */
LogSectionComponent.prototype.faPaste;
/** @type {?} */
LogSectionComponent.prototype.tailLines;
/** @type {?} */
LogSectionComponent.prototype.linesCount;
/** @type {?} */
LogSectionComponent.prototype.currentTailLinesCount;
/** @type {?} */
LogSectionComponent.prototype.logLevels;
/**
* @type {?}
* @private
*/
LogSectionComponent.prototype._rootLogLevel;
/** @type {?} */
LogSectionComponent.prototype.dataRecordTypes;
/** @type {?} */
LogSectionComponent.prototype.dataRecordType;
/** @type {?} */
LogSectionComponent.prototype.range;
/** @type {?} */
LogSectionComponent.prototype.loading;
/** @type {?} */
LogSectionComponent.prototype.logPane;
/** @type {?} */
LogSectionComponent.prototype.exportSlideDownPanel;
/** @type {?} */
LogSectionComponent.prototype.dateRangePopup;
/**
* @type {?}
* @private
*/
LogSectionComponent.prototype._subHandler;
/**
* @type {?}
* @private
*/
LogSectionComponent.prototype.logger;
/**
* @type {?}
* @private
*/
LogSectionComponent.prototype.notificationCenter;
/**
* @type {?}
* @private
*/
LogSectionComponent.prototype.logService;
/**
* @type {?}
* @private
*/
LogSectionComponent.prototype.renderer2;
/**
* @type {?}
* @private
*/
LogSectionComponent.prototype.clipboardService;
/**
* @type {?}
* @private
*/
LogSectionComponent.prototype.datarecordsService;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nLXNlY3Rpb24tY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vbW90aWYtd2ViLWFkbWluLWNvcmUvIiwic291cmNlcyI6WyJsaWIvc2VjdGlvbnMvTG9nL2NvbXBvbmVudHMvbG9nLXNlY3Rpb24tY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsT0FBTyxFQUFFLFNBQVMsRUFBVSxTQUFTLEVBQWEsVUFBVSxFQUFFLFNBQVMsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUM5RixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDOUMsT0FBTyxFQUFFLFNBQVMsRUFBQyxNQUFNLGtCQUFrQixDQUFDO0FBQzVDLE9BQU8sRUFBRSxVQUFVLEVBQXFCLE1BQU0sZ0NBQWdDLENBQUM7QUFFL0UsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRWpELE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBQzVFLE9BQU8sRUFBRSxZQUFZLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUM5RixPQUFPLEVBQUUsb0JBQW9CLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUM1RSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDcEQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sd0NBQXdDLENBQUM7QUFDNUUsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0scURBQXFELENBQUM7QUFDNUYsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzdDLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQzNELE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLG9DQUFvQyxDQUFDOztJQUV2RSxPQUFPLEdBQUcsY0FBYzs7SUEwQzFCLDZC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cUU7Ozs7O0lBR3JFLDBDQUF5RTs7Ozs7SUFFN0QscUNBQXlCOzs7OztJQUNqQyxpREFBZ0Q7Ozs7O0lBQ2hELHlDQUE4Qjs7Ozs7SUFDOUIsd0NBQTRCOzs7OztJQUM1QiwrQ0FBMEM7Ozs7O0lBQzFDLGlEQUE4QyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgT25Jbml0LCBWaWV3Q2hpbGQsIE9uRGVzdHJveSwgRWxlbWVudFJlZiwgUmVuZGVyZXIyfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFBsdWdpblZpZXcgfSBmcm9tICd3ZWItY29uc29sZS1jb3JlJztcbmltcG9ydCB7IE5HWExvZ2dlcn0gZnJvbSAnd2ViLWNvbnNvbGUtY29yZSc7XG5pbXBvcnQgeyBMb2dTZXJ2aWNlLCBMb2dMZXZlbCwgTG9nVGFpbCB9IGZyb20gJ0B3YS1tb3RpZi1vcGVuLWFwaS9sb2ctc2VydmljZSc7XG5pbXBvcnQgKiBhcyBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgeyBDbGlwYm9hcmRTZXJ2aWNlIH0gZnJvbSAnbmd4LWNsaXBib2FyZCc7XG5pbXBvcnQgKiBhcyBGaWxlU2F2ZXIgZnJvbSAnZmlsZS1zYXZlcic7XG5pbXBvcnQgeyBmYUV4dGVybmFsTGlua1NxdWFyZUFsdCB9IGZyb20gJ0Bmb3J0YXdlc29tZS9mcmVlLXNvbGlkLXN2Zy1pY29ucyc7XG5pbXBvcnQgeyBmYUZpbGVJbXBvcnQsIGZhRG93bmxvYWQsIGZhQ29weSwgZmFQYXN0ZSB9IGZyb20gJ0Bmb3J0YXdlc29tZS9mcmVlLXNvbGlkLXN2Zy1pY29ucyc7XG5pbXBvcnQgeyBXQ05vdGlmaWNhdGlvbkNlbnRlciwgTm90aWZpY2F0aW9uVHlwZSB9IGZyb20gJ3dlYi1jb25zb2xlLXVpLWtpdCc7XG5pbXBvcnQgeyBzYXZlQXMgfSBmcm9tICdAcHJvZ3Jlc3Mva2VuZG8tZmlsZS1zYXZlcic7XG5pbXBvcnQgeyBEYXRhcmVjb3Jkc1NlcnZpY2UgfSBmcm9tICdAd2EtbW90aWYtb3Blbi1hcGkvZGF0YXJlY29yZHMtc2VydmljZSc7XG5pbXBvcnQgeyBXQ1N1YnNjcmlwdGlvbkhhbmRsZXIgfSBmcm9tICcuLi8uLi8uLi9jb21wb25lbnRzL0NvbW1vbnMvd2Mtc3Vic2NyaXB0aW9uLWhhbmRsZXInO1xuaW1wb3J0IHsgZm9ybWF0RGF0ZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBXQ1NsaWRlUGFuZWxDb21wb25lbnQgfSBmcm9tICd3ZWItY29uc29sZS11aS1raXQnO1xuaW1wb3J0IHsgRGF0ZVJhbmdlUG9wdXBDb21wb25lbnQgfSBmcm9tICdAcHJvZ3Jlc3Mva2VuZG8tYW5ndWxhci1kYXRlaW5wdXRzJztcblxuY29uc3QgTE9HX1RBRyA9ICdbTG9nU2VjdGlvbl0nO1xuXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ3dhLWxvZy1zZWN0aW9uJyxcbiAgICBzdHlsZVVybHM6IFsgJy4vbG9nLXNlY3Rpb24tY29tcG9uZW50LnNjc3MnIF0sXG4gICAgdGVtcGxhdGVVcmw6ICcuL2xvZy1zZWN0aW9uLWNvbXBvbmVudC5odG1sJ1xuICB9KVxuICBAUGx1Z2luVmlldygnTG9nJywge1xuICAgIGljb25OYW1lOiAnd2EtaWNvLWxvZycsXG4gICAgdXNlckRhdGE6IHtcbiAgICAgICAgYWNsOiB7XG4gICAgICAgICAgICBwZXJtaXNzaW9uczogWydjb20udmlwZXJhLm9zZ2kuY29yZS5wbGF0Zm9ybS5hcGkucmVzdC5Mb2dzQXBpOlJFQUQ6dGFpbEN1cnJlbnRMb2cnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdjb20udmlwZXJhLm9zZ2kuY29yZS5wbGF0Zm9ybS5hcGkucmVzdC5Mb2dzQXBpOlJFQUQ6Z2V0Um9vdExvZ0xldmVsJ11cbiAgICAgICAgfVxuICAgIH1cbn0pXG5leHBvcnQgY2xhc3MgTG9nU2VjdGlvbkNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcblxuICAgIGZhRmlsZUltcG9ydCA9IGZhRmlsZUltcG9ydDtcbiAgICBmYURvd25sb2FkID0gZmFEb3dubG9hZDtcbiAgICBmYUV4dGVybmFsTGlua1NxdWFyZUFsdCA9IGZhRXh0ZXJuYWxMaW5rU3F1YXJlQWx0O1xuICAgIGZhQ29weSA9IGZhQ29weTtcbiAgICBmYVBhc3RlID0gZmFQYXN0ZTtcblxuICAgIHB1YmxpYyB0YWlsTGluZXM6IHN0cmluZztcbiAgICBwdWJsaWMgbGluZXNDb3VudCA9IDEwMDtcbiAgICBwdWJsaWMgY3VycmVudFRhaWxMaW5lc0NvdW50OiBudW1iZXI7XG4gICAgcHVibGljIGxvZ0xldmVsczogTG9nTGV2ZWxbXTtcbiAgICBwcml2YXRlIF9yb290TG9nTGV2ZWw6IExvZ0xldmVsO1xuICAgIHB1YmxpYyBkYXRhUmVjb3JkVHlwZXM6IHN0cmluZ1tdID0gWyBdO1xuICAgIHB1YmxpYyBkYXRhUmVjb3JkVHlwZTogc3RyaW5nO1xuICAgIHB1YmxpYyByYW5nZSA9IHsgc3RhcnQ6IG51bGwsIGVuZDogbnVsbCB9O1xuXG4gICAgbG9hZGluZzogYm9vbGVhbjtcblxuICAgIEBWaWV3Q2hpbGQoJ2xvZ1BhbmUnKSBsb2dQYW5lOiBFbGVtZW50UmVmO1xuICAgIEBWaWV3Q2hpbGQoJ2V4cG9ydFNsaWRlRG93blBhbmVsJykgZXhwb3J0U2xpZGVEb3duUGFuZWw6IFdDU2xpZGVQYW5lbENvbXBvbmVudDtcbiAgICBAVmlld0NoaWxkKCdkYXRlUmFuZ2VQb3B1cCcpIGRhdGVSYW5nZVBvcHVwOiBEYXRlUmFuZ2VQb3B1cENvbXBvbmVudDtcbiAgICBcblxuICAgIHByaXZhdGUgX3N1YkhhbmRsZXI6IFdDU3Vic2NyaXB0aW9uSGFuZGxlciA9IG5ldyBXQ1N1YnNjcmlwdGlvbkhhbmRsZXIoKTtcblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgbG9nZ2VyOiBOR1hMb2dnZXIsXG4gICAgICAgIHByaXZhdGUgbm90aWZpY2F0aW9uQ2VudGVyOiBXQ05vdGlmaWNhdGlvbkNlbnRlcixcbiAgICAgICAgcHJpdmF0ZSBsb2dTZXJ2aWNlOiBMb2dTZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIHJlbmRlcmVyMjogUmVuZGVyZXIyLFxuICAgICAgICBwcml2YXRlIGNsaXBib2FyZFNlcnZpY2U6IENsaXBib2FyZFNlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgZGF0YXJlY29yZHNTZXJ2aWNlOiBEYXRhcmVjb3Jkc1NlcnZpY2UpIHtcbiAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoTE9HX1RBRyAsICdPcGVuaW5nLi4uJyk7XG5cbiAgICAgICAgdGhpcy5sb2dMZXZlbHMgPSBbXTtcbiAgICAgICAgdGhpcy5sb2dMZXZlbHMucHVzaCh7bGV2ZWw6ICdFUlJPUid9KTtcbiAgICAgICAgdGhpcy5sb2dMZXZlbHMucHVzaCh7bGV2ZWw6ICdXQVJOJ30pO1xuICAgICAgICB0aGlzLmxvZ0xldmVscy5wdXNoKHtsZXZlbDogJ0lORk8nfSk7XG4gICAgICAgIHRoaXMubG9nTGV2ZWxzLnB1c2goe2xldmVsOiAnREVCVUcnfSk7XG4gICAgICAgIHRoaXMubG9nTGV2ZWxzLnB1c2goe2xldmVsOiAnVFJBQ0UnfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQW5ndWxhciBuZ09uSW5pdFxuICAgICAqL1xuICAgIG5nT25Jbml0KCkge1xuICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhMT0dfVEFHICwgJ0luaXRpYWxpemluZy4uLicpO1xuICAgICAgICB0aGlzLnRhaWxMaW5lcyA9ICcnO1xuICAgICAgICB0aGlzLmxvYWREYXRhcmVjb3Jkc1R5cGVzKCk7XG4gICAgICAgIHRoaXMucmVmcmVzaERhdGEoKTtcbiAgICB9XG5cbiAgICBuZ09uRGVzdHJveSgpIHtcbiAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoTE9HX1RBRyAsICduZ09uRGVzdHJveSAnKTtcbiAgICAgICAgdGhpcy5mcmVlTWVtKCk7XG4gICAgfVxuXG4gICAgZnJlZU1lbSgpIHtcbiAgICAgICAgdGhpcy50YWlsTGluZXMgPSBudWxsO1xuICAgICAgICB0aGlzLmxvZ0xldmVscyA9IG51bGw7XG4gICAgICAgIHRoaXMuZGF0YVJlY29yZFR5cGVzID0gbnVsbDtcbiAgICAgICAgdGhpcy5fc3ViSGFuZGxlci51bnN1YnNjcmliZSgpO1xuICAgICAgICB0aGlzLl9zdWJIYW5kbGVyID0gbnVsbDtcbiAgICB9XG5cbiAgICBwdWJsaWMgb25SZWZyZXNoQ2xpY2tlZCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoTE9HX1RBRyAsICdsaW5lc0NvdW50IDonLCB0aGlzLmxpbmVzQ291bnQpO1xuICAgICAgICB0aGlzLmxvYWRpbmcgPSB0cnVlO1xuICAgICAgICB0aGlzLl9zdWJIYW5kbGVyLmFkZCh0aGlzLmxvZ1NlcnZpY2UudGFpbEN1cnJlbnRMb2codGhpcy5saW5lc0NvdW50KS5zdWJzY3JpYmUoKGxvZ1RhaWw6IExvZ1RhaWwpID0+IHtcbiAgICAgICAgICAgIHRoaXMudGFpbExpbmVzID0gbG9nVGFpbC5kYXRhO1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50VGFpbExpbmVzQ291bnQgPSBsb2dUYWlsLmxpbmVzO1xuICAgICAgICAgICAgdGhpcy5sb2FkaW5nID0gZmFsc2U7XG4gICAgICAgIH0sIChlcnJvcikgPT4ge1xuICAgICAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoTE9HX1RBRyAsICd0YWlsQ3VycmVudExvZyBlcnJvcjonLCBlcnJvcik7XG4gICAgICAgICAgICB0aGlzLm5vdGlmaWNhdGlvbkNlbnRlci5wb3N0KHtcbiAgICAgICAgICAgICAgICBuYW1lOiAnUmVmcmVzaExvZ1RhaWxFcnJvcicsXG4gICAgICAgICAgICAgICAgdGl0bGU6ICdUYWlsIExvZycsXG4gICAgICAgICAgICAgICAgbWVzc2FnZTogJ0Vycm9yIHJlZnJlc2hpbmcgbG9nOicsXG4gICAgICAgICAgICAgICAgdHlwZTogTm90aWZpY2F0aW9uVHlwZS5FcnJvcixcbiAgICAgICAgICAgICAgICBlcnJvcjogZXJyb3IsXG4gICAgICAgICAgICAgICAgY2xvc2FibGU6IHRydWVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5sb2FkaW5nID0gZmFsc2U7XG4gICAgICAgIH0pKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgb25Db3B5VG9DbGlwYm9hcmRDbGlja2VkKCk6IHZvaWQge1xuICAgICAgICB0aGlzLmNsaXBib2FyZFNlcnZpY2UuY29weUZyb21Db250ZW50KHRoaXMudGFpbExpbmVzKTtcblxuICAgICAgICB0aGlzLm5vdGlmaWNhdGlvbkNlbnRlci5wb3N0KHtcbiAgICAgICAgICAgIG5hbWU6ICdMb2dUYWlsQ29weScsXG4gICAgICAgICAgICB0aXRsZTogJ0xvZyB0YWlsIENvcHknLFxuICAgICAgICAgICAgbWVzc2FnZTogJ1RoZSBjdXJyZW50IGRpc3BsYXllZCBsb2cgaGFzIGJlZW4gY29waWVkIHRvIHRoZSBjbGlwYm9hcmQuJyxcbiAgICAgICAgICAgIHR5cGU6IE5vdGlmaWNhdGlvblR5cGUuSW5mb1xuICAgICAgICB9KTtcblxuICAgIH1cblxuICAgIHB1YmxpYyBzZXQgcm9vdExvZ0xldmVsKGxvZ0xldmVsOiBMb2dMZXZlbCkge1xuICAgICAgICBpZiAobG9nTGV2ZWwpIHtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3RMb2dMZXZlbCA9IGxvZ0xldmVsO1xuICAgICAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoTE9HX1RBRyAsICdDaGFuZ2luZyBST09UIGxvZyBsZXZlbCA6JywgbG9nTGV2ZWwpO1xuICAgICAgICAgICAgdGhpcy5fc3ViSGFuZGxlci5hZGQodGhpcy5sb2dTZXJ2aWNlLnNldFJvb3RMb2dMZXZlbCh0aGlzLl9yb290TG9nTGV2ZWwpLnN1YnNjcmliZSgoZGF0YSkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKExPR19UQUcgLCAnQ2hhbmdlZCBST09UIGxvZyBsZXZlbCA6JywgZGF0YSk7XG5cbiAgICAgICAgICAgICAgICB0aGlzLm5vdGlmaWNhdGlvbkNlbnRlci5wb3N0KHtcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogJ1Jvb3RMb2dMZXZlbENoYW5nZVN1Y2Nlc3MnLFxuICAgICAgICAgICAgICAgICAgICB0aXRsZTogJ0xvZyBNYW5hZ2VtZW50JyxcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogJ1RoZSBST09UIExvZyBMZXZlbCBoYXMgYmVlbiBjaGFuZ2VkIHRvICcgKyBsb2dMZXZlbC5sZXZlbCxcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogTm90aWZpY2F0aW9uVHlwZS5TdWNjZXNzXG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIH0sIChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmVycm9yKExPR19UQUcgLCAnRXJyb3IgY2hhbmdpbmcgUk9PVCBMb2cgTGV2ZWw6JywgZXJyb3IpO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5ub3RpZmljYXRpb25DZW50ZXIucG9zdCh7XG4gICAgICAgICAgICAgICAgICAgIG5hbWU6ICdSb290TG9nTGV2ZWxDaGFuZ2VFcnJvcicsXG4gICAgICAgICAgICAgICAgICAgIHRpdGxlOiAnTG9nIE1hbmFnZW1lbnQnLFxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiAnRXJyb3IgY2hhbmdpbmcgUk9PVCBMb2cgTGV2ZWw6JyxcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogTm90aWZpY2F0aW9uVHlwZS5FcnJvcixcbiAgICAgICAgICAgICAgICAgICAgZXJyb3I6IGVycm9yLFxuICAgICAgICAgICAgICAgICAgICBjbG9zYWJsZTogdHJ1ZVxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICB9KSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IHJvb3RMb2dMZXZlbCgpOiBMb2dMZXZlbCB7XG4gICAgICAgIHJldHVybiB0aGlzLl9yb290TG9nTGV2ZWw7XG4gICAgfVxuXG4gICAgcHVibGljIHJlZnJlc2hEYXRhKCkge1xuICAgICAgICB0aGlzLmxvZ1NlcnZpY2UuZ2V0Um9vdExvZ0xldmVsKCkuc3Vic2NyaWJlKChkYXRhOiBMb2dMZXZlbCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoTE9HX1RBRyAsICdHZXR0aW5nIFJPT1QgbG9nIGxldmVsIDonLCBkYXRhKTtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3RMb2dMZXZlbCA9IGRhdGE7XG4gICAgICAgIH0sIChlcnJvcikgPT4ge1xuICAgICAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoTE9HX1RBRyAsICdFcnJvciBHZXR0aW5nIFJPT1QgbG9nIGxldmVsIDonLCBlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBvbkRvd25sb2FkQ2xpY2tlZCgpOiB2b2lkIHtcblxuICAgICAgICB0aGlzLm5vdGlmaWNhdGlvbkNlbnRlci5wb3N0KHtcbiAgICAgICAgICAgIG5hbWU6ICdMb2dEb3dubG9hZCcsXG4gICAgICAgICAgICB0aXRsZTogJ0Rvd25sb2FkIExvZycsXG4gICAgICAgICAgICBtZXNzYWdlOiAnRG93bmxvYWRpbmcgTG9nIGZpbGUuLi4nLFxuICAgICAgICAgICAgdHlwZTogTm90aWZpY2F0aW9uVHlwZS5JbmZvXG4gICAgICAgIH0pO1xuXG5cbiAgICAgICAgdGhpcy5fc3ViSGFuZGxlci5hZGQodGhpcy5sb2dTZXJ2aWNlLmRvd25sb2FkQ3VycmVudExvZygpLnN1YnNjcmliZSgoZGF0YSkgPT4ge1xuICAgICAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoTE9HX1RBRyAsICdFeHBvcnQgZG9uZS4nLCBkYXRhKTtcblxuICAgICAgICAgICAgY29uc3QgYmxvYiA9IG5ldyBCbG9iKFtkYXRhXSwge3R5cGU6ICdhcHBsaWNhdGlvbi96aXAnfSk7XG5cbiAgICAgICAgICAgIGNvbnN0IGZpbGVOYW1lID0gJ21vdGlmX2xvZ18nICsgbmV3IERhdGUoKS5nZXRUaW1lKCkgKyAnLnppcCc7XG5cbiAgICAgICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKExPR19UQUcgLCAnU2F2aW5nIHRvOiAnLCBibG9iKTtcblxuICAgICAgICAgICAgc2F2ZUFzKGJsb2IsIGZpbGVOYW1lKTtcbiAgICAgICAgICAgIC8vIEZpbGVTYXZlci5zYXZlQXMoYmxvYiwgZmlsZU5hbWUpO1xuICAgICAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoTE9HX1RBRyAsICdMb2cgc2F2ZWQ6ICcsIGZpbGVOYW1lKTtcblxuICAgICAgICAgICAgdGhpcy5ub3RpZmljYXRpb25DZW50ZXIucG9zdCh7XG4gICAgICAgICAgICAgICAgbmFtZTogJ0xvZ0V4cG9ydFN1Y2Nlc3MnLFxuICAgICAgICAgICAgICAgIHRpdGxlOiAnRG93bmxvYWQgTG9nJyxcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiAnVGhlIExvZyBmaWxlIGhhcyBiZWVuIGRvd25sb2FkZWQuJyxcbiAgICAgICAgICAgICAgICB0eXBlOiBOb3RpZmljYXRpb25UeXBlLlN1Y2Nlc3NcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIH0sIChlcnJvcikgPT4ge1xuICAgICAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoTE9HX1RBRyAsICdMb2cgZG93bmxvYWQgZXJyb3I6JywgZXJyb3IpO1xuXG4gICAgICAgICAgICB0aGlzLm5vdGlmaWNhdGlvbkNlbnRlci5wb3N0KHtcbiAgICAgICAgICAgICAgICBuYW1lOiAnTG9nRXhwb3J0RXJyb3InLFxuICAgICAgICAgICAgICAgIHRpdGxlOiAnRG93bmxvYWQgTG9nJyxcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiAnRXJyb3IgZG93bmxvYWRpbmcgdGhlIExvZyBmaWxlOicsXG4gICAgICAgICAgICAgICAgdHlwZTogTm90aWZpY2F0aW9uVHlwZS5FcnJvcixcbiAgICAgICAgICAgICAgICBlcnJvcjogZXJyb3IsXG4gICAgICAgICAgICAgICAgY2xvc2FibGU6IHRydWVcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIH0pKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgb25FeHBvcnRDbGlja2VkKCk6IHZvaWQge1xuICAgICAgICB0aGlzLmV4cG9ydFNsaWRlRG93blBhbmVsLnRvZ2dsZSgpO1xuICAgIH1cblxuICAgIHB1YmxpYyBvbkV4cG9ydENvbmZpcm0oKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLmV4cG9ydERhdGFSZWNvcmRzKCkpIHtcbiAgICAgICAgICAgIHRoaXMuZXhwb3J0U2xpZGVEb3duUGFuZWwuc2hvdyhmYWxzZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgb25FeHBvcnRDYW5jZWwoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZXhwb3J0U2xpZGVEb3duUGFuZWwuc2hvdyhmYWxzZSk7XG4gICAgfVxuXG4gICAgb25TbGlkZVBhbmVsQ2xvc2UoKXtcbiAgICAgICAgdGhpcy5yYW5nZS5zdGFydCA9IG51bGw7XG4gICAgICAgIHRoaXMucmFuZ2UuZW5kID0gbnVsbDtcbiAgICAgICAgdGhpcy5kYXRhUmVjb3JkVHlwZSA9IG51bGw7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjb252ZXJ0RGF0ZShkYXRlOiBEYXRlKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIGZvcm1hdERhdGUoZGF0ZSwgJ3l5eXkvTU0vZGQgSEg6bW06c3MnLCAnZW4tVVMnKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGV4cG9ydERhdGFSZWNvcmRzKCk6IGJvb2xlYW4ge1xuICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhMT0dfVEFHICwgJ2V4cG9ydERhdGFSZWNvcmRzOiAnLCB0aGlzLmRhdGFSZWNvcmRUeXBlLCB0aGlzLnJhbmdlLnN0YXJ0LCB0aGlzLnJhbmdlLmVuZCk7XG5cbiAgICAgICAgaWYgKCh0aGlzLmRhdGFSZWNvcmRUeXBlPT1udWxsKSB8fCAodGhpcy5yYW5nZS5zdGFydD09bnVsbCkgfHwgKHRoaXMucmFuZ2UuZW5kPT1udWxsKSl7XG4gICAgICAgICAgICB0aGlzLm5vdGlmaWNhdGlvbkNlbnRlci5wb3N0KHtcbiAgICAgICAgICAgICAgICBuYW1lOiAnRXhwb3J0RGF0YVJlY29yZHNQcm9ncmVzcycsXG4gICAgICAgICAgICAgICAgdGl0bGU6ICdEYXRhUmVjb3JkcyBFeHBvcnQnLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICdJdmFsaWQgZXhwb3J0IHBhcmFtZXRlcnMuJyxcbiAgICAgICAgICAgICAgICB0eXBlOiBOb3RpZmljYXRpb25UeXBlLldhcm5pbmcsXG4gICAgICAgICAgICAgICAgY2xvc2FibGU6IGZhbHNlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMubm90aWZpY2F0aW9uQ2VudGVyLnBvc3Qoe1xuICAgICAgICAgICAgbmFtZTogJ0V4cG9ydERhdGFSZWNvcmRzUHJvZ3Jlc3MnLFxuICAgICAgICAgICAgdGl0bGU6ICdEYXRhUmVjb3JkcyBFeHBvcnQnLFxuICAgICAgICAgICAgbWVzc2FnZTogJ0V4cG9ydGluZyBkYXRhcmVjb3Jkcy4uLicsXG4gICAgICAgICAgICB0eXBlOiBOb3RpZmljYXRpb25UeXBlLkluZm8sXG4gICAgICAgICAgICBjbG9zYWJsZTogZmFsc2VcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHN0YXJ0RGF0ZSA9IHRoaXMucmFuZ2Uuc3RhcnQ7XG4gICAgICAgIGNvbnN0IGVuZERhdGUgPSB0aGlzLnJhbmdlLmVuZDtcbiAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoTE9HX1RBRyAsICdleHBvcnREYXRhUmVjb3JkczogJywgdGhpcy5kYXRhUmVjb3JkVHlwZSwgc3RhcnREYXRlLCBlbmREYXRlKTtcbiAgICAgICAgdGhpcy5fc3ViSGFuZGxlci5hZGQodGhpcy5kYXRhcmVjb3Jkc1NlcnZpY2UuZXhwb3J0RGF0YXJlY29yZHModGhpcy5kYXRhUmVjb3JkVHlwZSwgbnVsbCwgbnVsbCwgbnVsbCwgXG4gICAgICAgICAgICBzdGFydERhdGUsIGVuZERhdGUgKS5zdWJzY3JpYmUoIChkYXRhKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoTE9HX1RBRyAsICdleHBvcnREYXRhUmVjb3JkcyBkb25lOiAnLCBkYXRhKTtcblxuICAgICAgICAgICAgICAgIGNvbnN0IGJsb2IgPSBuZXcgQmxvYihbZGF0YV0sIHt0eXBlOiAnYXBwbGljYXRpb24vemlwJ30pO1xuICAgICAgICAgICAgICAgIGNvbnN0IGZpbGVOYW1lID0gJ21vdGlmX2RhdGFyZWNvcmRzXycgKyBuZXcgRGF0ZSgpLmdldFRpbWUoKSArICcuemlwJztcbiAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhMT0dfVEFHICwgJ1NhdmluZyB0bzogJywgYmxvYik7XG4gICAgICAgICAgICAgICAgc2F2ZUFzKGJsb2IsIGZpbGVOYW1lKTtcbiAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhMT0dfVEFHICwgJ0xvZyBzYXZlZDogJywgZmlsZU5hbWUpO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5ub3RpZmljYXRpb25DZW50ZXIucG9zdCh7XG4gICAgICAgICAgICAgICAgICAgIG5hbWU6ICdFeHBvcnREYXRhUmVjb3Jkc1N1Y2Nlc3MnLFxuICAgICAgICAgICAgICAgICAgICB0aXRsZTogJ0RhdGFSZWNvcmRzIEV4cG9ydCcsXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICdEYXRhcmVjb3JkcyBleHBvcnRlZCBzdWNjZXNzZnVsbHkuJyxcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogTm90aWZpY2F0aW9uVHlwZS5TdWNjZXNzLFxuICAgICAgICAgICAgICAgICAgICBjbG9zYWJsZTogZmFsc2VcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgXG4gICAgICAgIH0sIChlcnJvcikgPT4ge1xuXG4gICAgICAgICAgICB0aGlzLmxvZ2dlci5lcnJvcihMT0dfVEFHICwgJ2V4cG9ydERhdGFSZWNvcmRzIGVycm9yOiAnLCBlcnJvcik7XG5cbiAgICAgICAgICAgIHRoaXMubm90aWZpY2F0aW9uQ2VudGVyLnBvc3Qoe1xuICAgICAgICAgICAgICAgIG5hbWU6ICdFeHBvcnREYXRhUmVjb3Jkc0Vycm9yJyxcbiAgICAgICAgICAgICAgICB0aXRsZTogJ0RhdGFSZWNvcmQgRXhwb3J0JyxcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiAnRXJyb3IgZXhwb3J0aW5nIGRhdGFyZWNvcmRzOicsXG4gICAgICAgICAgICAgICAgdHlwZTogTm90aWZpY2F0aW9uVHlwZS5FcnJvcixcbiAgICAgICAgICAgICAgICBlcnJvcjogZXJyb3IsXG4gICAgICAgICAgICAgICAgY2xvc2FibGU6IHRydWVcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIH0pKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBsb2FkRGF0YXJlY29yZHNUeXBlcygpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5fc3ViSGFuZGxlci5hZGQodGhpcy5kYXRhcmVjb3Jkc1NlcnZpY2UuZ2V0RGF0YXJlY29yZHNUeXBlcygpLnN1YnNjcmliZSgoZGF0YSkgPT4ge1xuICAgICAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoTE9HX1RBRyAsICdsb2FkRGF0YXJlY29yZHNUeXBlczogJywgZGF0YSk7XG4gICAgICAgICAgICB0aGlzLmRhdGFSZWNvcmRUeXBlcyA9IGRhdGE7XG4gICAgICAgIH0sIChlcnJvcikgPT4ge1xuICAgICAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoTE9HX1RBRyAsICdsb2FkRGF0YXJlY29yZHNUeXBlcyBlcnJvcjogJywgZXJyb3IpO1xuXG4gICAgICAgICAgICB0aGlzLm5vdGlmaWNhdGlvbkNlbnRlci5wb3N0KHtcbiAgICAgICAgICAgICAgICBuYW1lOiAnR2V0RGF0YVJlY29yZFR5cGVzRXJyb3InLFxuICAgICAgICAgICAgICAgIHRpdGxlOiAnR2V0IERhdGFSZWNvcmQgVHlwZXMnLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICdFcnJvciBnZXR0aW5nIHRoZSBkYXRhcmVjb3JkIHR5cGVzOicsXG4gICAgICAgICAgICAgICAgdHlwZTogTm90aWZpY2F0aW9uVHlwZS5FcnJvcixcbiAgICAgICAgICAgICAgICBlcnJvcjogZXJyb3IsXG4gICAgICAgICAgICAgICAgY2xvc2FibGU6IHRydWVcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIH0pKTtcbiAgICB9XG5cbiAgICBvbkRhdGVSYW5nZVBvcHVwT3BlbigpIHtcblxuICAgIH1cblxufVxuIl19