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 

/ esm2015 / lib / sections / OAuth2 / components / oauth2-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 { GridComponent } from '@progress/kendo-angular-grid';
import { MotifQuerySort, MotifQueryResults } from 'web-console-core';
import { Oauth2Service } from '@wa-motif-open-api/oauth2-service';
import { HttpParams } from '@angular/common/http';
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 {?} */
const LOG_TAG = "[OAuth2Section]";
let OAuth2SectionComponent = class OAuth2SectionComponent {
    /**
     * @param {?} logger
     * @param {?} oauth2Service
     * @param {?} notificationCenter
     */
    constructor(logger, oauth2Service, notificationCenter) {
        this.logger = logger;
        this.oauth2Service = oauth2Service;
        this.notificationCenter = notificationCenter;
        //Data
        this.refreshTokenList = [];
        this.accessTokenList = [];
        //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._subHandler = new WCSubscriptionHandler();
        this.logger.debug(LOG_TAG, 'Opening...');
    }
    /**
     * @return {?}
     */
    ngOnInit() {
        this.logger.debug(LOG_TAG, 'Initializing...');
    }
    /**
     * @return {?}
     */
    ngOnDestroy() {
        this.logger.debug(LOG_TAG, 'ngOnDestroy ');
        this.freeMem();
    }
    /**
     * @return {?}
     */
    freeMem() {
        this.refreshTokenList = null;
        this.accessTokenList = null;
        this.sort = null;
        this.groups = null;
        this.gridView = null;
        this._subHandler.unsubscribe();
        this._subHandler = null;
    }
    /**
     * @param {?} __0
     * @return {?}
     */
    pageChange({ skip, take }) {
        this.logger.debug(LOG_TAG, 'pageChange skip=', skip, ' take=', take);
        this.skip = skip;
        this.pageSize = take;
        /** @type {?} */
        const newPageIndex = this.calculatePageIndex(skip, take);
        this.loadData(this.domainSelector.selectedDomain.name, newPageIndex, this.pageSize);
    }
    /**
     * @private
     * @param {?} domain
     * @param {?} pageIndex
     * @param {?} pageSize
     * @return {?}
     */
    loadData(domain, pageIndex, pageSize) {
        if (this.domainSelector.selectedDomain) {
            this.logger.debug(LOG_TAG, 'loadData pageIndex=', pageIndex, ' pageSize=', pageSize);
            this.loading = true;
            /** @type {?} */
            const sort = this.buildQuerySort();
            this._subHandler.add(this.oauth2Service.getRefreshTokenList(this.domainSelector.selectedDomain.name, pageIndex, pageSize, sort.encode(new HttpParams()).get('sort'), 'response', false).subscribe((/**
             * @param {?} response
             * @return {?}
             */
            (response) => {
                /** @type {?} */
                const results = MotifQueryResults.fromHttpResponse(response);
                this.refreshTokenList = _.forEach(results.data, (/**
                 * @param {?} element
                 * @return {?}
                 */
                function (element) {
                    element.createTime = new Date(element.createTime);
                    element.expiryTime = new Date(element.expiryTime);
                }));
                this.totalPages = results.totalPages;
                this.totalRecords = results.totalRecords;
                this.currentPage = results.pageIndex;
                this.gridView = {
                    data: this.refreshTokenList,
                    total: results.totalRecords
                };
                this.currentPage = results.pageIndex;
                this.loading = false;
            }), (/**
             * @param {?} error
             * @return {?}
             */
            error => {
                this.logger.error(LOG_TAG, 'getRefreshTokenList failed: ', error);
                this.loading = false;
            })));
        }
    }
    /**
     * @private
     * @param {?} skip
     * @param {?} take
     * @return {?}
     */
    calculatePageIndex(skip, take) {
        return (skip / take) + 1;
    }
    /**
     * @private
     * @return {?}
     */
    buildQuerySort() {
        this.logger.debug(LOG_TAG, 'buildQuerySort: ', this.sort);
        /** @type {?} */
        let querySort = new MotifQuerySort();
        if (this.sort) {
            for (let i = 0; i < this.sort.length; i++) {
                /** @type {?} */
                let 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;
    }
    /**
     * Reload the list of users for the selected domain
     * @return {?}
     */
    refreshData() {
        this.logger.debug(LOG_TAG, 'refreshData domain=', this.domainSelector.selectedDomain.name, ' currentPage=', this.currentPage, ' pageSize=', this.pageSize);
        this.loadData(this.domainSelector.selectedDomain.name, this.currentPage, this.pageSize);
    }
    /**
     * Set the selcted domain
     * @param {?} domain
     * @return {?}
     */
    set selectedDomain(domain) {
        if (this.domainSelector.selectedDomain) {
            this.logger.debug(LOG_TAG, 'selectedDomain domain=', this.domainSelector.selectedDomain);
            this.loadData(this.domainSelector.selectedDomain.name, 1, this.pageSize);
        }
        else {
            this.gridView = undefined;
        }
    }
    /**
     * @param {?} sort
     * @return {?}
     */
    sortChange(sort) {
        this.logger.debug(LOG_TAG, 'sortChange sort=', this.sort);
        this.sort = sort;
        this.refreshData();
    }
    /**
     * @return {?}
     */
    doSort() {
        //this.gridView = process(orderBy(this.usersList, this.sort), { group: this.groups });
    }
    /**
     * @param {?} dataItem
     * @return {?}
     */
    onDeleteOKPressed(dataItem) {
        this.logger.debug(LOG_TAG, 'onDeleteOKPressed token=', dataItem.token);
        this._subHandler.add(this.oauth2Service.revokeRefreshToken(dataItem.token).subscribe((/**
         * @param {?} value
         * @return {?}
         */
        value => {
            this.refreshData();
            this.notificationCenter.post({
                name: 'RevokeRefreshTokenSuccess',
                title: 'Revoke Refresh Token',
                message: 'The Refresh Token has been successfully revoked',
                type: NotificationType.Success
            });
        }), (/**
         * @param {?} error
         * @return {?}
         */
        (error) => {
            this.notificationCenter.post({
                name: 'RevokeRefreshTokenError',
                title: 'Revoke Refresh Token',
                message: 'Refresh token could not be removed.',
                type: NotificationType.Error,
                error: error,
                closable: true
            });
        })));
    }
    /**
     * @param {?} dataItem
     * @return {?}
     */
    onDeleteCancelPressed(dataItem) {
        this.logger.debug(LOG_TAG, 'onDeleteCancelPressed');
    }
    /**
     * @param {?} domain
     * @return {?}
     */
    onDomainSelected(domain) {
        if (domain) {
            this.loadData(domain.name, 1, this.pageSize);
        }
        else {
            this.gridView = undefined;
        }
    }
    /**
     * @return {?}
     */
    onRefreshClicked() {
        this.refreshData();
    }
    /**
     * @return {?}
     */
    get canRefresh() {
        return (this.domainSelector.selectedDomain != null);
    }
};
OAuth2SectionComponent.decorators = [
    { type: Component, args: [{
                selector: 'wa-oauth2-section',
                template: "<wc-dashboard-header [title]=\"'OAuth2 Management'\"></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 (domainSelected)=\"onDomainSelected($event)\" (selectionCancelled)=\"onDomainSelected(null)\"></wc-domain-selector-combobox>\n        </div>\n    </div>\n\n    <div class=\"flex-cmd\">\n        <kendo-buttongroup look=\"flat\">\n          <button\n            kendoButton\n            [toggleable]=\"false\"\n            [icon]=\"'refresh'\"\n            (click)=\"onRefreshClicked()\"\n            [disabled]=\"!canRefresh\"\n          >\n            Refresh\n          </button>\n        </kendo-buttongroup>\n      </div>\n    \n</div>\n\n<div class=\"row fill\">\n\n    <div style=\"height: 98%;\">\n\n        <kendo-grid style=\"flex:1;\" [data]=\"gridView\" [columnMenu]=\"true\" [resizable]=\"true\" [reorderable]=\"true\" [sort]=\"sort\" (sortChange)=\"sortChange($event)\" [sortable]=\"{ allowUnsort: true, mode: 'multiple' }\"\n            [scrollable]=\"true\" [pageSize]=\"pageSize\" [skip]=\"skip\" [pageable]=\"{\n                buttonCount: 5,\n                info: true,\n                type: type,\n                pageSizes: true,\n                previousNext: true\n                }\" (pageChange)=\"pageChange($event)\">\n            <kendo-grid-column field=\"createTime\" title=\"Created\" sortable=\"isFieldSortable\" format=\"{0:dd/MM/yyyy HH:mm:ss}\">\n            </kendo-grid-column>\n            <kendo-grid-column field=\"expiryTime\" title=\"Expiry Time\" format=\"{0:dd/MM/yyyy HH:mm:ss}\">\n            </kendo-grid-column>\n            <kendo-grid-column field=\"clientId\" title=\"Client ID\">\n            </kendo-grid-column>\n            <kendo-grid-column field=\"tokenType\" title=\"Type\">\n            </kendo-grid-column>\n            <kendo-grid-column field=\"token\" title=\"Token\">\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.foundation.oauth2.api.rest.Oauth2Api:CREATE:revoke\"\n                            motif-acl-hidden=\"true\" \n                            [alignMode]=\"'end'\"\n                            [hasConfirmation]=\"true\"\n                            [confirmationTitle]=\"'Revoke ?'\"\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            <div *kendoGridDetailTemplate=\"let dataItem\">\n                <wa-refresh-token-details [refreshToken]=\"dataItem\"></wa-refresh-token-details>\n            </div>\n        </kendo-grid>\n\n    </div>\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}:host ::ng-deep tr.k-grid-norecords.ng-star-inserted{text-align:left;display:contents}"]
            }] }
];
/** @nocollapse */
OAuth2SectionComponent.ctorParameters = () => [
    { type: NGXLogger },
    { type: Oauth2Service },
    { type: WCNotificationCenter }
];
OAuth2SectionComponent.propDecorators = {
    _grid: [{ type: ViewChild, args: [GridComponent,] }],
    domainSelector: [{ type: ViewChild, args: ['domainSelector',] }],
    selectedDomain: [{ type: Input }]
};
OAuth2SectionComponent = tslib_1.__decorate([
    PluginView("OAuth2", {
        iconName: "wa-ico-users",
        userData: {
            acl: {
                permissions: ['com.vipera.osgi.core.platform.api.rest.PlatformApi:READ:getDomains',
                    'com.vipera.osgi.foundation.oauth2.api.rest.Oauth2Api:READ:getRefreshTokenList',
                    'com.vipera.osgi.foundation.oauth2.api.rest.Oauth2Api:READ:getAccessTokenList']
            }
        }
    }),
    tslib_1.__metadata("design:paramtypes", [NGXLogger,
        Oauth2Service,
        WCNotificationCenter])
], OAuth2SectionComponent);
export { OAuth2SectionComponent };
if (false) {
    /** @type {?} */
    OAuth2SectionComponent.prototype._grid;
    /** @type {?} */
    OAuth2SectionComponent.prototype.domainSelector;
    /** @type {?} */
    OAuth2SectionComponent.prototype.refreshTokenList;
    /** @type {?} */
    OAuth2SectionComponent.prototype.accessTokenList;
    /** @type {?} */
    OAuth2SectionComponent.prototype.sort;
    /** @type {?} */
    OAuth2SectionComponent.prototype.groups;
    /** @type {?} */
    OAuth2SectionComponent.prototype.gridView;
    /** @type {?} */
    OAuth2SectionComponent.prototype.type;
    /** @type {?} */
    OAuth2SectionComponent.prototype.pageSize;
    /** @type {?} */
    OAuth2SectionComponent.prototype.skip;
    /** @type {?} */
    OAuth2SectionComponent.prototype.currentPage;
    /** @type {?} */
    OAuth2SectionComponent.prototype.totalPages;
    /** @type {?} */
    OAuth2SectionComponent.prototype.totalRecords;
    /** @type {?} */
    OAuth2SectionComponent.prototype.isFieldSortable;
    /** @type {?} */
    OAuth2SectionComponent.prototype.loading;
    /**
     * @type {?}
     * @private
     */
    OAuth2SectionComponent.prototype._subHandler;
    /**
     * @type {?}
     * @private
     */
    OAuth2SectionComponent.prototype.logger;
    /**
     * @type {?}
     * @private
     */
    OAuth2SectionComponent.prototype.oauth2Service;
    /**
     * @type {?}
     * @private
     */
    OAuth2SectionComponent.prototype.notificationCenter;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib2F1dGgyLXNlY3Rpb24uY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vbW90aWYtd2ViLWFkbWluLWNvcmUvIiwic291cmNlcyI6WyJsaWIvc2VjdGlvbnMvT0F1dGgyL2NvbXBvbmVudHMvb2F1dGgyLXNlY3Rpb24uY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsT0FBTyxFQUFFLFNBQVMsRUFBVSxTQUFTLEVBQUUsS0FBSyxFQUFhLE1BQU0sZUFBZSxDQUFDO0FBQy9FLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUM5QyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFN0MsT0FBTyxFQUFtQixhQUFhLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUM5RSxPQUFPLEVBQUUsY0FBYyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDckUsT0FBTyxFQUFFLGFBQWEsRUFBdUMsTUFBTSxtQ0FBbUMsQ0FBQztBQUN2RyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDbEQsT0FBTyxLQUFLLENBQUMsTUFBTSxRQUFRLENBQUM7QUFDNUIsT0FBTyxFQUFFLCtCQUErQixFQUFFLE1BQU0scUVBQXFFLENBQUM7QUFFdEgsT0FBTyxFQUFFLG9CQUFvQixFQUFFLGdCQUFnQixFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDNUUsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0scURBQXFELENBQUM7O01BRXRGLE9BQU8sR0FBRyxpQkFBaUI7SUFpQnBCLHNCQUFzQixTQUF0QixzQkFBc0I7Ozs7OztJQXlCakMsWUFBb0IsTUFBaUIsRUFDM0IsYUFBNEIsRUFDNUIsa0JBQXdDO1FBRjlCLFdBQU0sR0FBTixNQUFNLENBQVc7UUFDM0Isa0JBQWEsR0FBYixhQUFhLENBQWU7UUFDNUIsdUJBQWtCLEdBQWxCLGtCQUFrQixDQUFzQjs7UUFyQjND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Z0I7NkJBeUgxQixLQUFLOztBQTVISyxzQkFBc0I7SUFWbEMsVUFBVSxDQUFDLFFBQVEsRUFBRTtRQUNwQixRQUFRLEVBQUUsY0FBYztRQUN4QixRQUFRLEVBQUU7WUFDTixHQUFHLEVBQUU7Z0JBQ0QsV0FBVyxFQUFFLENBQUMsb0VBQW9FO29CQUNwRSwrRUFBK0U7b0JBQy9FLDhFQUE4RSxDQUFDO2FBQ2hHO1NBQ0o7S0FDRixDQUFDOzZDQTBCNEIsU0FBUztRQUNaLGFBQWE7UUFDUixvQkFBb0I7R0EzQnZDLHNCQUFzQixDQTZMbEM7U0E3TFksc0JBQXNCOzs7SUFFakMsdUNBQStDOztJQUMvQyxnREFBNkU7O0lBRzdFLGtEQUFrRDs7SUFDbEQsaURBQWdEOztJQUdoRCxzQ0FBbUM7O0lBQ25DLHdDQUFzQzs7SUFDdEMsMENBQTRCOztJQUM1QixzQ0FBNkM7O0lBQzdDLDBDQUFxQjs7SUFDckIsc0NBQWdCOztJQUNoQiw2Q0FBdUI7O0lBQ3ZCLDRDQUFzQjs7SUFDdEIsOENBQXdCOztJQUN4QixpREFBK0I7O0lBRS9CLHlDQUFpQjs7Ozs7SUFFakIsNkNBQXlFOzs7OztJQUU3RCx3Q0FBeUI7Ozs7O0lBQ25DLCtDQUFvQzs7Ozs7SUFDcEMsb0RBQWdEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBPbkluaXQsIFZpZXdDaGlsZCwgSW5wdXQsIE9uRGVzdHJveSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgUGx1Z2luVmlldyB9IGZyb20gJ3dlYi1jb25zb2xlLWNvcmUnO1xuaW1wb3J0IHsgTkdYTG9nZ2VyIH0gZnJvbSAnd2ViLWNvbnNvbGUtY29yZSc7XG5pbXBvcnQgeyBTb3J0RGVzY3JpcHRvciwgR3JvdXBEZXNjcmlwdG9yLCBEYXRhUmVzdWx0IH0gZnJvbSAnQHByb2dyZXNzL2tlbmRvLWRhdGEtcXVlcnknO1xuaW1wb3J0IHsgUGFnZUNoYW5nZUV2ZW50LCBHcmlkQ29tcG9uZW50IH0gZnJvbSAnQHByb2dyZXNzL2tlbmRvLWFuZ3VsYXItZ3JpZCc7XG5pbXBvcnQgeyBNb3RpZlF1ZXJ5U29ydCwgTW90aWZRdWVyeVJlc3VsdHMgfSBmcm9tICd3ZWItY29uc29sZS1jb3JlJztcbmltcG9ydCB7IE9hdXRoMlNlcnZpY2UsIFZhbGlkYXRlLCBSZWZyZXNoVG9rZW4sIEFjY2Vzc1Rva2VuIH0gZnJvbSAnQHdhLW1vdGlmLW9wZW4tYXBpL29hdXRoMi1zZXJ2aWNlJztcbmltcG9ydCB7IEh0dHBQYXJhbXMgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5pbXBvcnQgKiBhcyBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgeyBEb21haW5TZWxlY3RvckNvbWJvQm94Q29tcG9uZW50IH0gZnJvbSAnLi4vLi4vLi4vY29tcG9uZW50cy9VSS9zZWxlY3RvcnMvZG9tYWluLXNlbGVjdG9yLWNvbWJvYm94LWNvbXBvbmVudCc7XG5pbXBvcnQgeyBEb21haW4gfSBmcm9tICdAd2EtbW90aWYtb3Blbi1hcGkvcGxhdGZvcm0tc2VydmljZSc7XG5pbXBvcnQgeyBXQ05vdGlmaWNhdGlvbkNlbnRlciwgTm90aWZpY2F0aW9uVHlwZSB9IGZyb20gJ3dlYi1jb25zb2xlLXVpLWtpdCc7XG5pbXBvcnQgeyBXQ1N1YnNjcmlwdGlvbkhhbmRsZXIgfSBmcm9tICcuLi8uLi8uLi9jb21wb25lbnRzL0NvbW1vbnMvd2Mtc3Vic2NyaXB0aW9uLWhhbmRsZXInO1xuXG5jb25zdCBMT0dfVEFHID0gXCJbT0F1dGgyU2VjdGlvbl1cIjtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnd2Etb2F1dGgyLXNlY3Rpb24nLFxuICBzdHlsZVVybHM6IFsnLi9vYXV0aDItc2VjdGlvbi5jb21wb25lbnQuc2NzcyddLFxuICB0ZW1wbGF0ZVVybDogJy4vb2F1dGgyLXNlY3Rpb24uY29tcG9uZW50Lmh0bWwnXG59KVxuQFBsdWdpblZpZXcoXCJPQXV0aDJcIiwge1xuICBpY29uTmFtZTogXCJ3YS1pY28tdXNlcnNcIixcbiAgdXNlckRhdGE6IHtcbiAgICAgIGFjbDoge1xuICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ2NvbS52aXBlcmEub3NnaS5jb3JlLnBsYXRmb3JtLmFwaS5yZXN0LlBsYXRmb3JtQXBpOlJFQUQ6Z2V0RG9tYWlucycsXG4gICAgICAgICAgICAgICAgICAgICAgICAnY29tLnZpcGVyYS5vc2dpLmZvdW5kYXRpb24ub2F1dGgyLmFwaS5yZXN0Lk9hdXRoMkFwaTpSRUFEOmdldFJlZnJlc2hUb2tlbkxpc3QnLFxuICAgICAgICAgICAgICAgICAgICAgICAgJ2NvbS52aXBlcmEub3NnaS5mb3VuZGF0aW9uLm9hdXRoMi5hcGkucmVzdC5PYXV0aDJBcGk6UkVBRDpnZXRBY2Nlc3NUb2tlbkxpc3QnXVxuICAgICAgfVxuICB9XG59KVxuZXhwb3J0IGNsYXNzIE9BdXRoMlNlY3Rpb25Db21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XG5cbiAgQFZpZXdDaGlsZChHcmlkQ29tcG9uZW50KSBfZ3JpZDogR3JpZENvbXBvbmVudDtcbiAgQFZpZXdDaGlsZCgnZG9tYWluU2VsZWN0b3InKSBkb21haW5TZWxlY3RvcjogRG9tYWluU2VsZWN0b3JDb21ib0JveENvbXBvbmVudDtcblxuICAvL0RhdGFcbiAgcHVibGljIHJlZnJlc2hUb2tlbkxpc3Q6IEFycmF5PFJlZnJlc2hUb2tlbj4gPSBbXTtcbiAgcHVibGljIGFjY2Vzc1Rva2VuTGlzdDogQXJyYXk8QWNjZXNzVG9rZW4+ID0gW107XG5cbiAgLy9HcmlkIE9wdGlvbnNcbiAgcHVibGljIHNvcnQ6IFNvcnREZXNjcmlwdG9yW10gPSBbXTtcbiAgcHVibGljIGdyb3VwczogR3JvdXBEZXNjcmlwdG9yW10gPSBbXTtcbiAgcHVibGljIGdyaWRWaWV3OiBEYXRhUmVzdWx0O1xuICBwdWJsaWMgdHlwZTogJ251bWVyaWMnIHwgJ2lucHV0JyA9ICdudW1lcmljJztcbiAgcHVibGljIHBhZ2VTaXplID0gMTU7XG4gIHB1YmxpYyBza2lwID0gMDtcbiAgcHVibGljIGN1cnJlbnRQYWdlID0gMTtcbiAgcHVibGljIHRvdGFsUGFnZXMgPSAwO1xuICBwdWJsaWMgdG90YWxSZWNvcmRzID0gMDtcbiAgcHVibGljIGlzRmllbGRTb3J0YWJsZSA9IGZhbHNlO1xuXG4gIGxvYWRpbmc6IGJvb2xlYW47XG5cbiAgcHJpdmF0ZSBfc3ViSGFuZGxlcjogV0NTdWJzY3JpcHRpb25IYW5kbGVyID0gbmV3IFdDU3Vic2NyaXB0aW9uSGFuZGxlcigpO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgbG9nZ2VyOiBOR1hMb2dnZXIsXG4gICAgcHJpdmF0ZSBvYXV0aDJTZXJ2aWNlOiBPYXV0aDJTZXJ2aWNlLFxuICAgIHByaXZhdGUgbm90aWZpY2F0aW9uQ2VudGVyOiBXQ05vdGlmaWNhdGlvbkNlbnRlclxuICAgICAgICApIHtcblxuICAgIHRoaXMubG9nZ2VyLmRlYnVnKExPR19UQUcsICdPcGVuaW5nLi4uJyk7XG4gIH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhMT0dfVEFHLCAnSW5pdGlhbGl6aW5nLi4uJyk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhMT0dfVEFHICwgJ25nT25EZXN0cm95ICcpO1xuICAgIHRoaXMuZnJlZU1lbSgpO1xuIH1cblxuZnJlZU1lbSgpIHtcbiAgdGhpcy5yZWZyZXNoVG9rZW5MaXN0ID0gbnVsbDtcbiAgdGhpcy5hY2Nlc3NUb2tlbkxpc3QgPSBudWxsO1xuICB0aGlzLnNvcnQgPSBudWxsO1xuICB0aGlzLmdyb3VwcyA9IG51bGw7XG4gIHRoaXMuZ3JpZFZpZXcgPSBudWxsO1xuICB0aGlzLl9zdWJIYW5kbGVyLnVuc3Vic2NyaWJlKCk7XG4gIHRoaXMuX3N1YkhhbmRsZXIgPSBudWxsO1xufVxuXG4gIHB1YmxpYyBwYWdlQ2hhbmdlKHsgc2tpcCwgdGFrZSB9OiBQYWdlQ2hhbmdlRXZlbnQpOiB2b2lkIHtcbiAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhMT0dfVEFHLCAncGFnZUNoYW5nZSBza2lwPScsIHNraXAsICcgdGFrZT0nLCB0YWtlKTtcbiAgICB0aGlzLnNraXAgPSBza2lwO1xuICAgIHRoaXMucGFnZVNpemUgPSB0YWtlO1xuICAgIGNvbnN0IG5ld1BhZ2VJbmRleCA9IHRoaXMuY2FsY3VsYXRlUGFnZUluZGV4KHNraXAsIHRha2UpO1xuICAgIHRoaXMubG9hZERhdGEodGhpcy5kb21haW5TZWxlY3Rvci5zZWxlY3RlZERvbWFpbi5uYW1lLCBuZXdQYWdlSW5kZXgsIHRoaXMucGFnZVNpemUpO1xuICB9XG5cbiAgcHJpdmF0ZSBsb2FkRGF0YShkb21haW46IHN0cmluZywgcGFnZUluZGV4OiBudW1iZXIsIHBhZ2VTaXplOiBudW1iZXIpIHtcbiAgICBpZiAodGhpcy5kb21haW5TZWxlY3Rvci5zZWxlY3RlZERvbWFpbikge1xuICAgICAgdGhpcy5sb2dnZXIuZGVidWcoTE9HX1RBRywgJ2xvYWREYXRhIHBhZ2VJbmRleD0nLCBwYWdlSW5kZXgsICcgcGFnZVNpemU9JywgcGFnZVNpemUpO1xuXG4gICAgICB0aGlzLmxvYWRpbmcgPSB0cnVlO1xuICAgICAgY29uc3Qgc29ydDogTW90aWZRdWVyeVNvcnQgPSB0aGlzLmJ1aWxkUXVlcnlTb3J0KCk7XG5cbiAgICB0aGlzLl9zdWJIYW5kbGVyLmFkZCh0aGlzLm9hdXRoMlNlcnZpY2UuZ2V0UmVmcmVzaFRva2VuTGlzdChcbiAgICAgICAgdGhpcy5kb21haW5TZWxlY3Rvci5zZWxlY3RlZERvbWFpbi5uYW1lLFxuICAgICAgICBwYWdlSW5kZXgsIHBhZ2VTaXplLCBzb3J0LmVuY29kZShuZXcgSHR0cFBhcmFtcygpKS5nZXQoJ3NvcnQnKSwgJ3Jlc3BvbnNlJywgZmFsc2UpLnN1YnNjcmliZSgocmVzcG9uc2UpID0+IHtcblxuICAgICAgICBjb25zdCByZXN1bHRzOiBNb3RpZlF1ZXJ5UmVzdWx0cyA9IE1vdGlmUXVlcnlSZXN1bHRzLmZyb21IdHRwUmVzcG9uc2UocmVzcG9uc2UpO1xuICAgICAgICB0aGlzLnJlZnJlc2hUb2tlbkxpc3QgPSBfLmZvckVhY2gocmVzdWx0cy5kYXRhLCBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgICAgICAgIGVsZW1lbnQuY3JlYXRlVGltZSA9IG5ldyBEYXRlKGVsZW1lbnQuY3JlYXRlVGltZSk7XG4gICAgICAgICAgZWxlbWVudC5leHBpcnlUaW1lID0gbmV3IERhdGUoZWxlbWVudC5leHBpcnlUaW1lKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMudG90YWxQYWdlcyA9IHJlc3VsdHMudG90YWxQYWdlcztcbiAgICAgICAgdGhpcy50b3RhbFJlY29yZHMgPSByZXN1bHRzLnRvdGFsUmVjb3JkcztcbiAgICAgICAgdGhpcy5jdXJyZW50UGFnZSA9IHJlc3VsdHMucGFnZUluZGV4O1xuICAgICAgICB0aGlzLmdyaWRWaWV3ID0ge1xuICAgICAgICAgIGRhdGE6IHRoaXMucmVmcmVzaFRva2VuTGlzdCxcbiAgICAgICAgICB0b3RhbDogcmVzdWx0cy50b3RhbFJlY29yZHNcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5jdXJyZW50UGFnZSA9IHJlc3VsdHMucGFnZUluZGV4O1xuICAgICAgICB0aGlzLmxvYWRpbmcgPSBmYWxzZTtcblxuICAgICAgfSwgZXJyb3IgPT4ge1xuICAgICAgICB0aGlzLmxvZ2dlci5lcnJvcihMT0dfVEFHLCAnZ2V0UmVmcmVzaFRva2VuTGlzdCBmYWlsZWQ6ICcsIGVycm9yKTtcbiAgICAgICAgdGhpcy5sb2FkaW5nID0gZmFsc2U7XG4gICAgICB9KSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBjYWxjdWxhdGVQYWdlSW5kZXgoc2tpcDogbnVtYmVyLCB0YWtlOiBudW1iZXIpOiBudW1iZXIge1xuICAgIHJldHVybiAoc2tpcCAvIHRha2UpICsgMTtcbiAgfVxuXG4gIHByaXZhdGUgYnVpbGRRdWVyeVNvcnQoKTogTW90aWZRdWVyeVNvcnQge1xuICAgIHRoaXMubG9nZ2VyLmRlYnVnKExPR19UQUcsICdidWlsZFF1ZXJ5U29ydDogJywgdGhpcy5zb3J0KTtcbiAgICBsZXQgcXVlcnlTb3J0ID0gbmV3IE1vdGlmUXVlcnlTb3J0KCk7XG4gICAgaWYgKHRoaXMuc29ydCkge1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnNvcnQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgbGV0IHNvcnRJbmZvID0gdGhpcy5zb3J0W2ldO1xuICAgICAgICBpZiAoc29ydEluZm8uZGlyICYmIHNvcnRJbmZvLmRpciA9PT0gJ2FzYycpIHtcbiAgICAgICAgICBxdWVyeVNvcnQub3JkZXJBc2NlbmRpbmdCeShzb3J0SW5mby5maWVsZCk7XG4gICAgICAgIH0gZWxzZSBpZiAoc29ydEluZm8uZGlyICYmIHNvcnRJbmZvLmRpciA9PT0gJ2Rlc2MnKSB7XG4gICAgICAgICAgcXVlcnlTb3J0Lm9yZGVyRGVzY2VuZGluZ0J5KHNvcnRJbmZvLmZpZWxkKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcXVlcnlTb3J0O1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbG9hZCB0aGUgbGlzdCBvZiB1c2VycyBmb3IgdGhlIHNlbGVjdGVkIGRvbWFpblxuICAgKi9cbiAgcHVibGljIHJlZnJlc2hEYXRhKCk6IHZvaWQge1xuICAgIHRoaXMubG9nZ2VyLmRlYnVnKExPR19UQUcsICdyZWZyZXNoRGF0YSBkb21haW49JywgdGhpcy5kb21haW5TZWxlY3Rvci5zZWxlY3RlZERvbWFpbi5uYW1lLCAnIGN1cnJlbnRQYWdlPScsIHRoaXMuY3VycmVudFBhZ2UsICcgcGFnZVNpemU9JywgdGhpcy5wYWdlU2l6ZSk7XG4gICAgdGhpcy5sb2FkRGF0YSh0aGlzLmRvbWFpblNlbGVjdG9yLnNlbGVjdGVkRG9tYWluLm5hbWUsIHRoaXMuY3VycmVudFBhZ2UsIHRoaXMucGFnZVNpemUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldCB0aGUgc2VsY3RlZCBkb21haW5cbiAgICovXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBzZXQgc2VsZWN0ZWREb21haW4oZG9tYWluOiBEb21haW4pIHtcbiAgICBpZiAodGhpcy5kb21haW5TZWxlY3Rvci5zZWxlY3RlZERvbWFpbikge1xuICAgICAgdGhpcy5sb2dnZXIuZGVidWcoTE9HX1RBRywgJ3NlbGVjdGVkRG9tYWluIGRvbWFpbj0nLCB0aGlzLmRvbWFpblNlbGVjdG9yLnNlbGVjdGVkRG9tYWluKTtcbiAgICAgIHRoaXMubG9hZERhdGEodGhpcy5kb21haW5TZWxlY3Rvci5zZWxlY3RlZERvbWFpbi5uYW1lLCAxLCB0aGlzLnBhZ2VTaXplKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5ncmlkVmlldyA9IHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgc29ydENoYW5nZShzb3J0OiBTb3J0RGVzY3JpcHRvcltdKTogdm9pZCB7XG4gICAgdGhpcy5sb2dnZXIuZGVidWcoTE9HX1RBRywgJ3NvcnRDaGFuZ2Ugc29ydD0nLCB0aGlzLnNvcnQpO1xuICAgIHRoaXMuc29ydCA9IHNvcnQ7XG4gICAgdGhpcy5yZWZyZXNoRGF0YSgpXG4gIH1cblxuICBwdWJsaWMgZG9Tb3J0KCkge1xuICAgIC8vdGhpcy5ncmlkVmlldyA9IHByb2Nlc3Mob3JkZXJCeSh0aGlzLnVzZXJzTGlzdCwgdGhpcy5zb3J0KSwgeyBncm91cDogdGhpcy5ncm91cHMgfSk7XG4gIH1cblxuICBvbkRlbGV0ZU9LUHJlc3NlZChkYXRhSXRlbTogYW55KTogdm9pZCB7XG4gICAgdGhpcy5sb2dnZXIuZGVidWcoTE9HX1RBRywgJ29uRGVsZXRlT0tQcmVzc2VkIHRva2VuPScsIGRhdGFJdGVtLnRva2VuKTtcblxuICAgIHRoaXMuX3N1YkhhbmRsZXIuYWRkKHRoaXMub2F1dGgyU2VydmljZS5yZXZva2VSZWZyZXNoVG9rZW4oZGF0YUl0ZW0udG9rZW4pLnN1YnNjcmliZSh2YWx1ZSA9PiB7XG4gICAgICB0aGlzLnJlZnJlc2hEYXRhKCk7XG4gICAgICB0aGlzLm5vdGlmaWNhdGlvbkNlbnRlci5wb3N0KHtcbiAgICAgICAgbmFtZTogJ1Jldm9rZVJlZnJlc2hUb2tlblN1Y2Nlc3MnLFxuICAgICAgICB0aXRsZTogJ1Jldm9rZSBSZWZyZXNoIFRva2VuJyxcbiAgICAgICAgbWVzc2FnZTogJ1RoZSBSZWZyZXNoIFRva2VuIGhhcyBiZWVuIHN1Y2Nlc3NmdWxseSByZXZva2VkJyxcbiAgICAgICAgdHlwZTogTm90aWZpY2F0aW9uVHlwZS5TdWNjZXNzXG4gICAgfSk7XG5cbiAgICB9LCAoZXJyb3IpID0+IHtcbiAgICAgIHRoaXMubm90aWZpY2F0aW9uQ2VudGVyLnBvc3Qoe1xuICAgICAgICBuYW1lOiAnUmV2b2tlUmVmcmVzaFRva2VuRXJyb3InLFxuICAgICAgICB0aXRsZTogJ1Jldm9rZSBSZWZyZXNoIFRva2VuJyxcbiAgICAgICAgbWVzc2FnZTogJ1JlZnJlc2ggdG9rZW4gY291bGQgbm90IGJlIHJlbW92ZWQuJyxcbiAgICAgICAgdHlwZTogTm90aWZpY2F0aW9uVHlwZS5FcnJvcixcbiAgICAgICAgZXJyb3I6IGVycm9yLFxuICAgICAgICBjbG9zYWJsZTogdHJ1ZVxuICAgICAgfSk7XG4gICAgfSkpO1xuICB9XG5cbiAgb25EZWxldGVDYW5jZWxQcmVzc2VkKGRhdGFJdGVtOiBhbnkpOiB2b2lkIHtcbiAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhMT0dfVEFHLCAnb25EZWxldGVDYW5jZWxQcmVzc2VkJyk7XG4gIH1cblxuICBwdWJsaWMgb25Eb21haW5TZWxlY3RlZChkb21haW46IERvbWFpbikge1xuICAgIGlmIChkb21haW4pIHtcbiAgICAgIHRoaXMubG9hZERhdGEoZG9tYWluLm5hbWUsIDEsIHRoaXMucGFnZVNpemUpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmdyaWRWaWV3ID0gdW5kZWZpbmVkO1xuICAgIH1cblxuICB9XG5cbiAgb25SZWZyZXNoQ2xpY2tlZCgpIHtcbiAgICB0aGlzLnJlZnJlc2hEYXRhKCk7XG4gIH1cblxuICBwdWJsaWMgZ2V0IGNhblJlZnJlc2goKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICh0aGlzLmRvbWFpblNlbGVjdG9yLnNlbGVjdGVkRG9tYWluIT1udWxsKTtcbiAgfVxuXG59XG4iXX0=