Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Bower components Debian packages RPM packages NuGet packages

vipera-npm-registry / motif-web-admin-core   js

Repository URL to install this package:

Version: 0.3.1 

/ esm5 / lib / sections / Sessions / components / sessions-section-component.js

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
import * as tslib_1 from "tslib";
import { Component, ViewChild, Input } from '@angular/core';
import { PluginView } from 'web-console-core';
import { NGXLogger } from 'web-console-core';
import { SecurityService } from '@wa-motif-open-api/security-service';
import { GridComponent } from '@progress/kendo-angular-grid';
import { MotifQuerySort, MotifQueryResults } from 'web-console-core';
import { ApplicationsService } from '@wa-motif-open-api/platform-service';
import { ComboBoxComponent } from '@progress/kendo-angular-dropdowns';
import * as _ from 'lodash';
import { DomainSelectorComboBoxComponent } from '../../../components/UI/selectors/domain-selector-combobox-component';
import { WCNotificationCenter, NotificationType } from 'web-console-ui-kit';
import { WCSubscriptionHandler } from '../../../components/Commons/wc-subscription-handler';
/** @type {?} */
var LOG_TAG = '[SessionsSection]';
var SessionsSectionComponent = /** @class */ (function () {
    function SessionsSectionComponent(logger, securityService, notificationCenter, applicationsService) {
        this.logger = logger;
        this.securityService = securityService;
        this.notificationCenter = notificationCenter;
        this.applicationsService = applicationsService;
        // Grid Options
        this.sort = [];
        this.groups = [];
        this.type = 'numeric';
        this.pageSize = 15;
        this.skip = 0;
        this.currentPage = 1;
        this.totalPages = 0;
        this.totalRecords = 0;
        this.isFieldSortable = false;
        this.applicationsList = [];
        this._subHandler = new WCSubscriptionHandler();
        this.loading = false;
        this._sessionRows = [];
        this.logger.debug(LOG_TAG, 'Opening...');
    }
    /**
     * Angular ngOnInit
     */
    /**
     * Angular ngOnInit
     * @return {?}
     */
    SessionsSectionComponent.prototype.ngOnInit = /**
     * Angular ngOnInit
     * @return {?}
     */
    function () {
        this.logger.debug(LOG_TAG, 'Initializing...');
    };
    /**
     * @return {?}
     */
    SessionsSectionComponent.prototype.ngOnDestroy = /**
     * @return {?}
     */
    function () {
        this.logger.debug(LOG_TAG, 'ngOnDestroy ');
        this.freeMem();
    };
    /**
     * @return {?}
     */
    SessionsSectionComponent.prototype.freeMem = /**
     * @return {?}
     */
    function () {
        this.sort = null;
        this.groups = null;
        this.gridView = null;
        this.applicationsList = null;
        this._selectedApplication = null;
        this._sessionRows = null;
        this._subHandler.unsubscribe();
        this._subHandler = null;
    };
    /**
     * @private
     * @param {?} domain
     * @param {?} application
     * @param {?} pageIndex
     * @param {?} pageSize
     * @return {?}
     */
    SessionsSectionComponent.prototype.loadData = /**
     * @private
     * @param {?} domain
     * @param {?} application
     * @param {?} pageIndex
     * @param {?} pageSize
     * @return {?}
     */
    function (domain, application, pageIndex, pageSize) {
        var _this = this;
        // tslint:disable-next-line:max-line-length
        this.logger.debug(LOG_TAG, 'loadData domain=\'' + domain + '\' application=\'' + application + '\' pageIndex=', pageIndex, ' pageSize=', pageSize);
        this.loading = true;
        /** @type {?} */
        var sort = this.buildQuerySort();
        /** @type {?} */
        var domainName = (domain ? domain.name : null);
        /** @type {?} */
        var applicationName = (application ? application.name : null);
        this._subHandler.add(this.securityService.getSessions(null, null, domainName, applicationName, null, null, pageIndex, pageSize, 'response').subscribe((/**
         * @param {?} response
         * @return {?}
         */
        function (response) {
            /** @type {?} */
            var results = MotifQueryResults.fromHttpResponse(response);
            _this.logger.debug(LOG_TAG, 'Get session list query results:', results);
            _this._sessionRows = _.forEach(results.data, (/**
             * @param {?} element
             * @return {?}
             */
            function (element) {
                element.lastAccess = new Date(element.lastAccess);
            }));
            _this.totalPages = results.totalPages;
            _this.totalRecords = results.totalRecords;
            _this.currentPage = results.pageIndex;
            _this.gridView = {
                data: _this._sessionRows,
                total: results.totalRecords
            };
            _this.loading = false;
        }), (/**
         * @param {?} error
         * @return {?}
         */
        function (error) {
            _this.logger.error(LOG_TAG, 'Get session list failed: ', error);
            _this.loading = false;
            _this.notificationCenter.post({
                name: 'LoadSessionsError',
                title: 'Load Sessions',
                message: 'Error loading Sessions:',
                type: NotificationType.Error,
                error: error,
                closable: true
            });
        })));
    };
    /**
     * @param {?} __0
     * @return {?}
     */
    SessionsSectionComponent.prototype.pageChange = /**
     * @param {?} __0
     * @return {?}
     */
    function (_a) {
        var skip = _a.skip, take = _a.take;
        this.logger.debug(LOG_TAG, 'pageChange skip=', skip, ' take=', take);
        this.skip = skip;
        this.pageSize = take;
        /** @type {?} */
        var newPageIndex = this.calculatePageIndex(skip, take);
        this.loadData(this.domainSelector.selectedDomain, this._selectedApplication, newPageIndex, this.pageSize);
    };
    /**
     * @private
     * @param {?} skip
     * @param {?} take
     * @return {?}
     */
    SessionsSectionComponent.prototype.calculatePageIndex = /**
     * @private
     * @param {?} skip
     * @param {?} take
     * @return {?}
     */
    function (skip, take) {
        return (skip / take) + 1;
    };
    /**
     * @private
     * @return {?}
     */
    SessionsSectionComponent.prototype.buildQuerySort = /**
     * @private
     * @return {?}
     */
    function () {
        this.logger.debug(LOG_TAG, 'buildQuerySort: ', this.sort);
        /** @type {?} */
        var querySort = new MotifQuerySort();
        if (this.sort) {
            for (var i = 0; i < this.sort.length; i++) {
                /** @type {?} */
                var sortInfo = this.sort[i];
                if (sortInfo.dir && sortInfo.dir === 'asc') {
                    querySort.orderAscendingBy(sortInfo.field);
                }
                else if (sortInfo.dir && sortInfo.dir === 'desc') {
                    querySort.orderDescendingBy(sortInfo.field);
                }
            }
        }
        return querySort;
    };
    Object.defineProperty(SessionsSectionComponent.prototype, "selectedApplication", {
        /**
        * Set the selcted application
        */
        set: /**
         * Set the selcted application
         * @param {?} application
         * @return {?}
         */
        function (application) {
            this._selectedApplication = application;
            this.loadData(this.domainSelector.selectedDomain, this._selectedApplication, 1, this.pageSize);
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Reload the list of the current sessions
     */
    /**
     * Reload the list of the current sessions
     * @return {?}
     */
    SessionsSectionComponent.prototype.refreshData = /**
     * Reload the list of the current sessions
     * @return {?}
     */
    function () {
        this.loadData(this.selectedDomain, this._selectedApplication, this.currentPage, this.pageSize);
    };
    /**
     * @param {?} dataItem
     * @return {?}
     */
    SessionsSectionComponent.prototype.onDeleteOKPressed = /**
     * @param {?} dataItem
     * @return {?}
     */
    function (dataItem) {
        var _this = this;
        this.logger.debug(LOG_TAG, 'onDeleteOKPressed dataItem=', dataItem);
        this._subHandler.add(this.securityService.closeSession(dataItem.id).subscribe((/**
         * @param {?} data
         * @return {?}
         */
        function (data) {
            _this.logger.debug(LOG_TAG, 'onDeleteOKPressed OK:', data);
            _this.refreshData();
            _this.notificationCenter.post({
                name: 'CloseSessionSuccess',
                title: 'Close Session',
                message: 'Session closed successfully.',
                type: NotificationType.Success
            });
        }), (/**
         * @param {?} error
         * @return {?}
         */
        function (error) {
            _this.logger.error(LOG_TAG, 'onDeleteOKPressed error:', error);
            _this.notificationCenter.post({
                name: 'CloseSessionError',
                title: 'Close Session',
                message: 'Error closing session:',
                type: NotificationType.Error,
                error: error,
                closable: true
            });
        })));
    };
    /**
     * @return {?}
     */
    SessionsSectionComponent.prototype.onRefreshClicked = /**
     * @return {?}
     */
    function () {
        this.refreshData();
    };
    SessionsSectionComponent.decorators = [
        { type: Component, args: [{
                    selector: 'wa-sessions-section',
                    template: "<wc-dashboard-header [title]=\"'Sessions'\"></wc-dashboard-header>\n<wc-loading-overlay [visible]='loading'></wc-loading-overlay>\n\n<div class=\"row spread\">\n    <div class=\"flex-toolbar\" style=\"display:flex;align-items: center;\">\n        <div style=\"margin-right:10px;width:60%;max-width: 400px;min-width: 250px;\">\n            <label>Domain</label>\n            <wc-domain-selector-combobox #domainSelector [(ngModel)]=\"selectedDomain\"></wc-domain-selector-combobox>\n        </div>\n\n        <div style=\"margin-left: 40px;margin-right:10px;width:60%;max-width: 400px;min-width: 250px;\">\n            <label>Application</label>\n            <wc-application-selector-combobox #applicationSelector [domain]=\"(selectedDomain ? selectedDomain.name : null)\" [(ngModel)]=\"selectedApplication\"></wc-application-selector-combobox>\n        </div>\n\n\n    </div>\n\n    <div class=\"flex-cmd\">\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\n    <kendo-grid [data]=\"gridView\" [columnMenu]=\"true\" [scrollable]=\"true\" [resizable]=\"true\"\n        [reorderable]=\"true\" [pageSize]=\"pageSize\" [skip]=\"skip\" [pageable]=\"{\n        buttonCount: 5,\n        info: true,\n        type: type,\n        pageSizes: true,\n        previousNext: true\n        }\"\n        [scrollable]=\"'none'\" (pageChange)=\"pageChange($event)\">\n        >\n\n\n        <kendo-grid-column field=\"clientIp\" title=\"Client IP\" width=\"160\">\n        </kendo-grid-column>\n\n        <kendo-grid-column field=\"user\" title=\"User\" width=\"160\">\n        </kendo-grid-column>\n\n        <kendo-grid-column field=\"secure\" title=\"Secure\" width=\"40\">\n            <ng-template kendoGridCellTemplate let-dataItem>\n                <label class=\"k-icon grid-cell-checkbox grid-cell-checkbox-{{dataItem.secure}}\"></label>\n            </ng-template>\n        </kendo-grid-column>\n\n        <kendo-grid-column field=\"shared\" title=\"Shared\" width=\"40\">\n            <ng-template kendoGridCellTemplate let-dataItem>\n                <label class=\"k-icon grid-cell-checkbox grid-cell-checkbox-{{dataItem.shared}}\"></label>\n            </ng-template>\n        </kendo-grid-column>\n\n        <kendo-grid-column field=\"domain\" title=\"Domain\">\n        </kendo-grid-column>\n\n        <kendo-grid-column field=\"application\" title=\"Application\">\n        </kendo-grid-column>\n\n        <kendo-grid-column field=\"service\" title=\"Service\">\n        </kendo-grid-column>\n\n        <kendo-grid-column field=\"channel\" title=\"Channel\">\n        </kendo-grid-column>\n\n        <kendo-grid-column field=\"lastAccess\" title=\"Last Access\" format=\"{0:dd/MM/yyyy HH:mm:ss}\">\n        </kendo-grid-column>\n\n        <kendo-grid-column field=\"lastRequestID\" title=\"Last Request ID\">\n        </kendo-grid-column>\n\n        <kendo-grid-column field=\"expiry\" title=\"Expiry\">\n        </kendo-grid-column>\n\n        <kendo-grid-column title=\"\" width=\"150\" minResizableWidth=\"140\">\n            <ng-template kendoGridCellTemplate let-dataItem let-columnIndex=\"columnIndex\" let-rowIndex=\"rowIndex\" let-column=\"column\">\n                    <wc-grid-editor-command \n                        motif-acl=\"com.vipera.osgi.core.platform.api.rest.SecurityApi:DELETE:closeSession\"\n                        motif-acl-hidden=\"true\"\n                        [alignMode]=\"'end'\"\n                        [hasConfirmation]=\"true\"\n                        [confirmationTitle]=\"'Delete ?'\"\n                        [rowIndex]=\"rowIndex\" \n                        [columnIndex]=\"columnIndex\" \n                        [column]=\"column\" \n                        [commandIcon]=\"'wa-ico-no'\"\n                        [dataItem]=\"dataItem\"\n                        (commandConfirm)=\"onDeleteOKPressed(dataItem)\"  \n                        >\n                    </wc-grid-editor-command>\n            </ng-template>\n        </kendo-grid-column>\n\n    </kendo-grid>\n\n\n\n</div>\n",
                    styles: [":host{display:flex;flex:1;flex-direction:column}:host ::ng-deep .grid-btn-editor.wc-table-delete-command{justify-content:center}"]
                }] }
    ];
    /** @nocollapse */
    SessionsSectionComponent.ctorParameters = function () { return [
        { type: NGXLogger },
        { type: SecurityService },
        { type: WCNotificationCenter },
        { type: ApplicationsService }
    ]; };
    SessionsSectionComponent.propDecorators = {
        _grid: [{ type: ViewChild, args: [GridComponent,] }],
        _appComboBox: [{ type: ViewChild, args: ['applicationsCombo',] }],
        domainSelector: [{ type: ViewChild, args: ['domainSelector',] }],
        selectedDomain: [{ type: Input }],
        selectedApplication: [{ type: Input }]
    };
    SessionsSectionComponent = tslib_1.__decorate([
        PluginView('Sessions', {
            iconName: 'wa-ico-sessions',
            userData: {
                acl: {
                    permissions: ['com.vipera.osgi.core.platform.api.rest.PlatformApi:READ:getDomains',
                        'com.vipera.osgi.core.platform.api.rest.PlatformApi:READ:getApplications',
                        'com.vipera.osgi.core.platform.api.rest.SecurityApi:READ:getSessions']
                }
            }
        }),
        tslib_1.__metadata("design:paramtypes", [NGXLogger,
            SecurityService,
            WCNotificationCenter,
            ApplicationsService])
    ], SessionsSectionComponent);
    return SessionsSectionComponent;
}());
export { SessionsSectionComponent };
if (false) {
    /** @type {?} */
    SessionsSectionComponent.prototype._grid;
    /** @type {?} */
    SessionsSectionComponent.prototype._appComboBox;
    /** @type {?} */
    SessionsSectionComponent.prototype.domainSelector;
    /** @type {?} */
    SessionsSectionComponent.prototype.sort;
    /** @type {?} */
    SessionsSectionComponent.prototype.groups;
    /** @type {?} */
    SessionsSectionComponent.prototype.gridView;
    /** @type {?} */
    SessionsSectionComponent.prototype.type;
    /** @type {?} */
    SessionsSectionComponent.prototype.pageSize;
    /** @type {?} */
    SessionsSectionComponent.prototype.skip;
    /** @type {?} */
    SessionsSectionComponent.prototype.currentPage;
    /** @type {?} */
    SessionsSectionComponent.prototype.totalPages;
    /** @type {?} */
    SessionsSectionComponent.prototype.totalRecords;
    /** @type {?} */
    SessionsSectionComponent.prototype.isFieldSortable;
    /** @type {?} */
    SessionsSectionComponent.prototype.applicationsList;
    /** @type {?} */
    SessionsSectionComponent.prototype._selectedApplication;
    /** @type {?} */
    SessionsSectionComponent.prototype.selectedDomain;
    /**
     * @type {?}
     * @private
     */
    SessionsSectionComponent.prototype._subHandler;
    /** @type {?} */
    SessionsSectionComponent.prototype.loading;
    /**
     * @type {?}
     * @private
     */
    SessionsSectionComponent.prototype._sessionRows;
    /**
     * @type {?}
     * @private
     */
    SessionsSectionComponent.prototype.logger;
    /**
     * @type {?}
     * @private
     */
    SessionsSectionComponent.prototype.securityService;
    /**
     * @type {?}
     * @private
     */
    SessionsSectionComponent.prototype.notificationCenter;
    /**
     * @type {?}
     * @private
     */
    SessionsSectionComponent.prototype.applicationsService;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Vzc2lvbnMtc2VjdGlvbi1jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9tb3RpZi13ZWItYWRtaW4tY29yZS8iLCJzb3VyY2VzIjpbImxpYi9zZWN0aW9ucy9TZXNzaW9ucy9jb21wb25lbnRzL3Nlc3Npb25zLXNlY3Rpb24tY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsT0FBTyxFQUFFLFNBQVMsRUFBVSxTQUFTLEVBQUUsS0FBSyxFQUFhLE1BQU0sZUFBZSxDQUFDO0FBQy9FLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQTtBQUM3QyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sa0JBQWtCLENBQUE7QUFDNUMsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHFDQUFxQyxDQUFBO0FBRXJFLE9BQU8sRUFBRSxhQUFhLEVBQW1CLE1BQU0sOEJBQThCLENBQUM7QUFFOUUsT0FBTyxFQUFFLGNBQWMsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ3JFLE9BQU8sRUFBVSxtQkFBbUIsRUFBZSxNQUFNLHFDQUFxQyxDQUFBO0FBQzlGLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBQ3RFLE9BQU8sS0FBSyxDQUFDLE1BQU0sUUFBUSxDQUFDO0FBQzVCLE9BQU8sRUFBRSwrQkFBK0IsRUFBRSxNQUFNLHFFQUFxRSxDQUFBO0FBQ3JILE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLG9CQUFvQixDQUFBO0FBQzNFLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLHFEQUFxRCxDQUFDOztJQUd0RixPQUFPLEdBQUcsbUJBQW1COztJQTRDL0Isa0NBQW9CLE1BQWlCLEVBQ3pCLGVBQWdDLEVBQ2hDLGtCQUF3QyxFQUN4QyxtQkFBd0M7UUFIaEMsV0FBTSxHQUFOLE1BQU0sQ0FBVztRQUN6QixvQkFBZSxHQUFmLGVBQWUsQ0FBaUI7UUFD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Q0FBQztpQkFDekY7YUFDSjtTQUNKLENBQUM7aURBNEI4QixTQUFTO1lBQ1IsZUFBZTtZQUNaLG9CQUFvQjtZQUNuQixtQkFBbUI7T0E5QjNDLHdCQUF3QixDQXlMcEM7SUFBRCwrQkFBQztDQUFBLElBQUE7U0F6TFksd0JBQXdCOzs7SUFFakMseUNBQStDOztJQUMvQyxnREFBZ0U7O0lBQ2hFLGtEQUE2RTs7SUFHN0Usd0NBQW1DOztJQUNuQywwQ0FBc0M7O0lBQ3RDLDRDQUE0Qjs7SUFDNUIsd0NBQTZDOztJQUM3Qyw0Q0FBcUI7O0lBQ3JCLHdDQUFnQjs7SUFDaEIsK0NBQXVCOztJQUN2Qiw4Q0FBc0I7O0lBQ3RCLGdEQUF3Qjs7SUFDeEIsbURBQStCOztJQUUvQixvREFBaUQ7O0lBQ2pELHdEQUF5Qzs7SUFDekMsa0RBQXVDOzs7OztJQUN2QywrQ0FBeUU7O0lBRXpFLDJDQUF1Qjs7Ozs7SUFFdkIsZ0RBQXdDOzs7OztJQUU1QiwwQ0FBeUI7Ozs7O0lBQ2pDLG1EQUF3Qzs7Ozs7SUFDeEMsc0RBQWdEOzs7OztJQUNoRCx1REFBZ0QiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgVmlld0NoaWxkLCBJbnB1dCwgT25EZXN0cm95IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBQbHVnaW5WaWV3IH0gZnJvbSAnd2ViLWNvbnNvbGUtY29yZSdcbmltcG9ydCB7IE5HWExvZ2dlciB9IGZyb20gJ3dlYi1jb25zb2xlLWNvcmUnXG5pbXBvcnQgeyBTZWN1cml0eVNlcnZpY2UgfSBmcm9tICdAd2EtbW90aWYtb3Blbi1hcGkvc2VjdXJpdHktc2VydmljZSdcbmltcG9ydCB7IFNlc3Npb25Sb3cgfSBmcm9tICcuLi9kYXRhL21vZGVsJ1xuaW1wb3J0IHsgR3JpZENvbXBvbmVudCwgUGFnZUNoYW5nZUV2ZW50IH0gZnJvbSAnQHByb2dyZXNzL2tlbmRvLWFuZ3VsYXItZ3JpZCc7XG5pbXBvcnQgeyBTb3J0RGVzY3JpcHRvciwgR3JvdXBEZXNjcmlwdG9yLCBEYXRhUmVzdWx0IH0gZnJvbSAnQHByb2dyZXNzL2tlbmRvLWRhdGEtcXVlcnknO1xuaW1wb3J0IHsgTW90aWZRdWVyeVNvcnQsIE1vdGlmUXVlcnlSZXN1bHRzIH0gZnJvbSAnd2ViLWNvbnNvbGUtY29yZSc7XG5pbXBvcnQgeyBEb21haW4sIEFwcGxpY2F0aW9uc1NlcnZpY2UsIEFwcGxpY2F0aW9uIH0gZnJvbSAnQHdhLW1vdGlmLW9wZW4tYXBpL3BsYXRmb3JtLXNlcnZpY2UnXG5pbXBvcnQgeyBDb21ib0JveENvbXBvbmVudCB9IGZyb20gJ0Bwcm9ncmVzcy9rZW5kby1hbmd1bGFyLWRyb3Bkb3ducyc7XG5pbXBvcnQgKiBhcyBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgeyBEb21haW5TZWxlY3RvckNvbWJvQm94Q29tcG9uZW50IH0gZnJvbSAnLi4vLi4vLi4vY29tcG9uZW50cy9VSS9zZWxlY3RvcnMvZG9tYWluLXNlbGVjdG9yLWNvbWJvYm94LWNvbXBvbmVudCdcbmltcG9ydCB7IFdDTm90aWZpY2F0aW9uQ2VudGVyLCBOb3RpZmljYXRpb25UeXBlIH0gZnJvbSAnd2ViLWNvbnNvbGUtdWkta2l0J1xuaW1wb3J0IHsgV0NTdWJzY3JpcHRpb25IYW5kbGVyIH0gZnJvbSAnLi4vLi4vLi4vY29tcG9uZW50cy9Db21tb25zL3djLXN1YnNjcmlwdGlvbi1oYW5kbGVyJztcblxuXG5jb25zdCBMT0dfVEFHID0gJ1tTZXNzaW9uc1NlY3Rpb25dJztcblxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICd3YS1zZXNzaW9ucy1zZWN0aW9uJyxcbiAgICBzdHlsZVVybHM6IFsnLi9zZXNzaW9ucy1zZWN0aW9uLmNvbXBvbmVudC5zY3NzJ10sXG4gICAgdGVtcGxhdGVVcmw6ICcuL3Nlc3Npb25zLXNlY3Rpb24uY29tcG9uZW50Lmh0bWwnXG59KVxuQFBsdWdpblZpZXcoJ1Nlc3Npb25zJywge1xuICAgIGljb25OYW1lOiAnd2EtaWNvLXNlc3Npb25zJyxcbiAgICB1c2VyRGF0YToge1xuICAgICAgICBhY2w6IHtcbiAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ2NvbS52aXBlcmEub3NnaS5jb3JlLnBsYXRmb3JtLmFwaS5yZXN0LlBsYXRmb3JtQXBpOlJFQUQ6Z2V0RG9tYWlucycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2NvbS52aXBlcmEub3NnaS5jb3JlLnBsYXRmb3JtLmFwaS5yZXN0LlBsYXRmb3JtQXBpOlJFQUQ6Z2V0QXBwbGljYXRpb25zJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnY29tLnZpcGVyYS5vc2dpLmNvcmUucGxhdGZvcm0uYXBpLnJlc3QuU2VjdXJpdHlBcGk6UkVBRDpnZXRTZXNzaW9ucyddXG4gICAgICAgIH1cbiAgICB9XG59KVxuZXhwb3J0IGNsYXNzIFNlc3Npb25zU2VjdGlvbkNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcblxuICAgIEBWaWV3Q2hpbGQoR3JpZENvbXBvbmVudCkgX2dyaWQ6IEdyaWRDb21wb25lbnQ7XG4gICAgQFZpZXdDaGlsZCgnYXBwbGljYXRpb25zQ29tYm8nKSBfYXBwQ29tYm9Cb3g6IENvbWJvQm94Q29tcG9uZW50O1xuICAgIEBWaWV3Q2hpbGQoJ2RvbWFpblNlbGVjdG9yJykgZG9tYWluU2VsZWN0b3I6IERvbWFpblNlbGVjdG9yQ29tYm9Cb3hDb21wb25lbnQ7XG5cbiAgICAvLyBHcmlkIE9wdGlvbnNcbiAgICBwdWJsaWMgc29ydDogU29ydERlc2NyaXB0b3JbXSA9IFtdO1xuICAgIHB1YmxpYyBncm91cHM6IEdyb3VwRGVzY3JpcHRvcltdID0gW107XG4gICAgcHVibGljIGdyaWRWaWV3OiBEYXRhUmVzdWx0O1xuICAgIHB1YmxpYyB0eXBlOiAnbnVtZXJpYycgfCAnaW5wdXQnID0gJ251bWVyaWMnO1xuICAgIHB1YmxpYyBwYWdlU2l6ZSA9IDE1O1xuICAgIHB1YmxpYyBza2lwID0gMDtcbiAgICBwdWJsaWMgY3VycmVudFBhZ2UgPSAxO1xuICAgIHB1YmxpYyB0b3RhbFBhZ2VzID0gMDtcbiAgICBwdWJsaWMgdG90YWxSZWNvcmRzID0gMDtcbiAgICBwdWJsaWMgaXNGaWVsZFNvcnRhYmxlID0gZmFsc2U7XG5cbiAgICBwdWJsaWMgYXBwbGljYXRpb25zTGlzdDogQXJyYXk8QXBwbGljYXRpb24+ID0gW107XG4gICAgcHVibGljIF9zZWxlY3RlZEFwcGxpY2F0aW9uOiBBcHBsaWNhdGlvbjsgLy8gY29tYm8gYm94IHNlbGVjdGlvblxuICAgIEBJbnB1dCgpIHB1YmxpYyBzZWxlY3RlZERvbWFpbjogRG9tYWluO1xuICAgIHByaXZhdGUgX3N1YkhhbmRsZXI6IFdDU3Vic2NyaXB0aW9uSGFuZGxlciA9IG5ldyBXQ1N1YnNjcmlwdGlvbkhhbmRsZXIoKTtcblxuICAgIHB1YmxpYyBsb2FkaW5nID0gZmFsc2U7XG5cbiAgICBwcml2YXRlIF9zZXNzaW9uUm93czogU2Vzc2lvblJvd1tdID0gW107XG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGxvZ2dlcjogTkdYTG9nZ2VyLFxuICAgICAgICBwcml2YXRlIHNlY3VyaXR5U2VydmljZTogU2VjdXJpdHlTZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIG5vdGlmaWNhdGlvbkNlbnRlcjogV0NOb3RpZmljYXRpb25DZW50ZXIsXG4gICAgICAgIHByaXZhdGUgYXBwbGljYXRpb25zU2VydmljZTogQXBwbGljYXRpb25zU2VydmljZSkge1xuICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhMT0dfVEFHLCAnT3BlbmluZy4uLicpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFuZ3VsYXIgbmdPbkluaXRcbiAgICAgKi9cbiAgICBuZ09uSW5pdCgpIHtcbiAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoTE9HX1RBRywgJ0luaXRpYWxpemluZy4uLicpO1xuICAgIH1cblxuICAgIG5nT25EZXN0cm95KCkge1xuICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhMT0dfVEFHICwgJ25nT25EZXN0cm95ICcpO1xuICAgICAgICB0aGlzLmZyZWVNZW0oKTtcbiAgICB9XG5cbiAgICBmcmVlTWVtKCkge1xuICAgICAgICB0aGlzLnNvcnQgPSBudWxsO1xuICAgICAgICB0aGlzLmdyb3VwcyA9IG51bGw7XG4gICAgICAgIHRoaXMuZ3JpZFZpZXcgPSBudWxsO1xuICAgICAgICB0aGlzLmFwcGxpY2F0aW9uc0xpc3QgPSBudWxsO1xuICAgICAgICB0aGlzLl9zZWxlY3RlZEFwcGxpY2F0aW9uID0gbnVsbDtcbiAgICAgICAgdGhpcy5fc2Vzc2lvblJvd3MgPSBudWxsO1xuICAgICAgICB0aGlzLl9zdWJIYW5kbGVyLnVuc3Vic2NyaWJlKCk7XG4gICAgICAgIHRoaXMuX3N1YkhhbmRsZXIgPSBudWxsO1xuICAgIH1cblxuICAgIHByaXZhdGUgbG9hZERhdGEoZG9tYWluOiBEb21haW4sIGFwcGxpY2F0aW9uOiBBcHBsaWNhdGlvbiwgcGFnZUluZGV4OiBudW1iZXIsIHBhZ2VTaXplOiBudW1iZXIpIHtcbiAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm1heC1saW5lLWxlbmd0aFxuICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhMT0dfVEFHLCAnbG9hZERhdGEgZG9tYWluPVxcJycgKyBkb21haW4gKyAnXFwnIGFwcGxpY2F0aW9uPVxcJycgKyBhcHBsaWNhdGlvbiArICdcXCcgcGFnZUluZGV4PScsIHBhZ2VJbmRleCwgJyBwYWdlU2l6ZT0nLCBwYWdlU2l6ZSk7XG5cbiAgICAgICAgdGhpcy5sb2FkaW5nID0gdHJ1ZTtcblxuICAgICAgICBjb25zdCBzb3J0OiBNb3RpZlF1ZXJ5U29ydCA9IHRoaXMuYnVpbGRRdWVyeVNvcnQoKTtcblxuICAgICAgICBjb25zdCBkb21haW5OYW1lID0gKGRvbWFpbiA/IGRvbWFpbi5uYW1lIDogbnVsbCk7XG4gICAgICAgIGNvbnN0IGFwcGxpY2F0aW9uTmFtZSA9IChhcHBsaWNhdGlvbiA/IGFwcGxpY2F0aW9uLm5hbWUgOiBudWxsKTtcblxuICAgICAgICB0aGlzLl9zdWJIYW5kbGVyLmFkZCh0aGlzLnNlY3VyaXR5U2VydmljZS5nZXRTZXNzaW9ucyhudWxsLCBudWxsLCBkb21haW5OYW1lLCBcbiAgICAgICAgICAgIGFwcGxpY2F0aW9uTmFtZSwgbnVsbCwgbnVsbCwgcGFnZUluZGV4LCBwYWdlU2l6ZSwgJ3Jlc3BvbnNlJykuc3Vic2NyaWJlKChyZXNwb25zZSkgPT4ge1xuXG4gICAgICAgICAgICBjb25zdCByZXN1bHRzOiBNb3RpZlF1ZXJ5UmVzdWx0cyA9IE1vdGlmUXVlcnlSZXN1bHRzLmZyb21IdHRwUmVzcG9uc2UocmVzcG9uc2UpO1xuXG4gICAgICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhMT0dfVEFHLCAnR2V0IHNlc3Npb24gbGlzdCBxdWVyeSByZXN1bHRzOicsIHJlc3VsdHMpO1xuXG4gICAgICAgICAgICB0aGlzLl9zZXNzaW9uUm93cyA9IF8uZm9yRWFjaChyZXN1bHRzLmRhdGEsIGZ1bmN0aW9uIChlbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgZWxlbWVudC5sYXN0QWNjZXNzID0gbmV3IERhdGUoZWxlbWVudC5sYXN0QWNjZXNzKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICB0aGlzLnRvdGFsUGFnZXMgPSByZXN1bHRzLnRvdGFsUGFnZXM7XG4gICAgICAgICAgICB0aGlzLnRvdGFsUmVjb3JkcyA9IHJlc3VsdHMudG90YWxSZWNvcmRzO1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50UGFnZSA9IHJlc3VsdHMucGFnZUluZGV4O1xuICAgICAgICAgICAgdGhpcy5ncmlkVmlldyA9IHtcbiAgICAgICAgICAgICAgICBkYXRhOiB0aGlzLl9zZXNzaW9uUm93cyxcbiAgICAgICAgICAgICAgICB0b3RhbDogcmVzdWx0cy50b3RhbFJlY29yZHNcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHRoaXMubG9hZGluZyA9IGZhbHNlO1xuXG4gICAgICAgIH0sIGVycm9yID0+IHtcbiAgICAgICAgICAgIHRoaXMubG9nZ2VyLmVycm9yKExPR19UQUcsICdHZXQgc2Vzc2lvbiBsaXN0IGZhaWxlZDogJywgZXJyb3IpO1xuICAgICAgICAgICAgdGhpcy5sb2FkaW5nID0gZmFsc2U7XG5cbiAgICAgICAgICAgIHRoaXMubm90aWZpY2F0aW9uQ2VudGVyLnBvc3Qoe1xuICAgICAgICAgICAgICAgIG5hbWU6ICdMb2FkU2Vzc2lvbnNFcnJvcicsXG4gICAgICAgICAgICAgICAgdGl0bGU6ICdMb2FkIFNlc3Npb25zJyxcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiAnRXJyb3IgbG9hZGluZyBTZXNzaW9uczonLFxuICAgICAgICAgICAgICAgIHR5cGU6IE5vdGlmaWNhdGlvblR5cGUuRXJyb3IsXG4gICAgICAgICAgICAgICAgZXJyb3I6IGVycm9yLFxuICAgICAgICAgICAgICAgIGNsb3NhYmxlOiB0cnVlXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICB9KSk7XG4gICAgfVxuXG4gICAgcHVibGljIHBhZ2VDaGFuZ2UoeyBza2lwLCB0YWtlIH06IFBhZ2VDaGFuZ2VFdmVudCk6IHZvaWQge1xuICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhMT0dfVEFHLCAncGFnZUNoYW5nZSBza2lwPScsIHNraXAsICcgdGFrZT0nLCB0YWtlKTtcbiAgICAgICAgdGhpcy5za2lwID0gc2tpcDtcbiAgICAgICAgdGhpcy5wYWdlU2l6ZSA9IHRha2U7XG4gICAgICAgIGNvbnN0IG5ld1BhZ2VJbmRleCA9IHRoaXMuY2FsY3VsYXRlUGFnZUluZGV4KHNraXAsIHRha2UpO1xuICAgICAgICB0aGlzLmxvYWREYXRhKHRoaXMuZG9tYWluU2VsZWN0b3Iuc2VsZWN0ZWREb21haW4sIHRoaXMuX3NlbGVjdGVkQXBwbGljYXRpb24sIG5ld1BhZ2VJbmRleCwgdGhpcy5wYWdlU2l6ZSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjYWxjdWxhdGVQYWdlSW5kZXgoc2tpcDogbnVtYmVyLCB0YWtlOiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gKHNraXAgLyB0YWtlKSArIDE7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBidWlsZFF1ZXJ5U29ydCgpOiBNb3RpZlF1ZXJ5U29ydCB7XG4gICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKExPR19UQUcsICdidWlsZFF1ZXJ5U29ydDogJywgdGhpcy5zb3J0KTtcbiAgICAgICAgY29uc3QgcXVlcnlTb3J0ID0gbmV3IE1vdGlmUXVlcnlTb3J0KCk7XG4gICAgICAgIGlmICh0aGlzLnNvcnQpIHtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5zb3J0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc29ydEluZm8gPSB0aGlzLnNvcnRbaV07XG4gICAgICAgICAgICAgICAgaWYgKHNvcnRJbmZvLmRpciAmJiBzb3J0SW5mby5kaXIgPT09ICdhc2MnKSB7XG4gICAgICAgICAgICAgICAgICAgIHF1ZXJ5U29ydC5vcmRlckFzY2VuZGluZ0J5KHNvcnRJbmZvLmZpZWxkKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHNvcnRJbmZvLmRpciAmJiBzb3J0SW5mby5kaXIgPT09ICdkZXNjJykge1xuICAgICAgICAgICAgICAgICAgICBxdWVyeVNvcnQub3JkZXJEZXNjZW5kaW5nQnkoc29ydEluZm8uZmllbGQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcXVlcnlTb3J0O1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgKiBTZXQgdGhlIHNlbGN0ZWQgYXBwbGljYXRpb25cbiAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIHNldCBzZWxlY3RlZEFwcGxpY2F0aW9uKGFwcGxpY2F0aW9uOiBBcHBsaWNhdGlvbikge1xuICAgICAgICB0aGlzLl9zZWxlY3RlZEFwcGxpY2F0aW9uID0gYXBwbGljYXRpb247XG4gICAgICAgIHRoaXMubG9hZERhdGEodGhpcy5kb21haW5TZWxlY3Rvci5zZWxlY3RlZERvbWFpbiwgdGhpcy5fc2VsZWN0ZWRBcHBsaWNhdGlvbiwgMSwgdGhpcy5wYWdlU2l6ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVsb2FkIHRoZSBsaXN0IG9mIHRoZSBjdXJyZW50IHNlc3Npb25zXG4gICAgICovXG4gICAgcHVibGljIHJlZnJlc2hEYXRhKCk6IHZvaWQge1xuICAgICAgICB0aGlzLmxvYWREYXRhKHRoaXMuc2VsZWN0ZWREb21haW4sIHRoaXMuX3NlbGVjdGVkQXBwbGljYXRpb24sIHRoaXMuY3VycmVudFBhZ2UsIHRoaXMucGFnZVNpemUpO1xuICAgIH1cblxuXG4gICAgb25EZWxldGVPS1ByZXNzZWQoZGF0YUl0ZW06IGFueSk6IHZvaWQge1xuICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhMT0dfVEFHLCAnb25EZWxldGVPS1ByZXNzZWQgZGF0YUl0ZW09JywgZGF0YUl0ZW0pO1xuICAgICAgICB0aGlzLl9zdWJIYW5kbGVyLmFkZCh0aGlzLnNlY3VyaXR5U2VydmljZS5jbG9zZVNlc3Npb24oZGF0YUl0ZW0uaWQpLnN1YnNjcmliZSgoZGF0YSkgPT4ge1xuICAgICAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoTE9HX1RBRywgJ29uRGVsZXRlT0tQcmVzc2VkIE9LOicsIGRhdGEpO1xuICAgICAgICAgICAgdGhpcy5yZWZyZXNoRGF0YSgpO1xuXG5cbiAgICAgICAgICAgIHRoaXMubm90aWZpY2F0aW9uQ2VudGVyLnBvc3Qoe1xuICAgICAgICAgICAgICAgIG5hbWU6ICdDbG9zZVNlc3Npb25TdWNjZXNzJyxcbiAgICAgICAgICAgICAgICB0aXRsZTogJ0Nsb3NlIFNlc3Npb24nLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICdTZXNzaW9uIGNsb3NlZCBzdWNjZXNzZnVsbHkuJyxcbiAgICAgICAgICAgICAgICB0eXBlOiBOb3RpZmljYXRpb25UeXBlLlN1Y2Nlc3NcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIH0sIChlcnJvcikgPT4ge1xuICAgICAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoTE9HX1RBRywgJ29uRGVsZXRlT0tQcmVzc2VkIGVycm9yOicsIGVycm9yKTtcblxuICAgICAgICAgICAgdGhpcy5ub3RpZmljYXRpb25DZW50ZXIucG9zdCh7XG4gICAgICAgICAgICAgICAgbmFtZTogJ0Nsb3NlU2Vzc2lvbkVycm9yJyxcbiAgICAgICAgICAgICAgICB0aXRsZTogJ0Nsb3NlIFNlc3Npb24nLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICdFcnJvciBjbG9zaW5nIHNlc3Npb246JyxcbiAgICAgICAgICAgICAgICB0eXBlOiBOb3RpZmljYXRpb25UeXBlLkVycm9yLFxuICAgICAgICAgICAgICAgIGVycm9yOiBlcnJvcixcbiAgICAgICAgICAgICAgICBjbG9zYWJsZTogdHJ1ZVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgfSkpO1xuICAgIH1cblxuICAgIHB1YmxpYyBvblJlZnJlc2hDbGlja2VkKCk6IHZvaWQge1xuICAgICAgICB0aGlzLnJlZnJlc2hEYXRhKCk7XG4gICAgfVxuXG5cbn1cbiJdfQ==