angular-firebase-authorizator
Version:
Beta version of authorizator for angular linked to firebase, it creates a model in firestore to assign permissions to users an roles, and creates a view to update this permissions
182 lines • 29.4 kB
JavaScript
import { __decorate, __metadata, __param } from "tslib";
import { Component, OnInit, Inject, AfterViewInit, ChangeDetectorRef, Output, EventEmitter, Input } from '@angular/core';
import { AUTHORIZATOR_CONFIG } from '../../authorizator.config.token';
import { Operation } from '../../classes/permission-obj';
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
import { MatSnackBarConfig, MatSnackBar } from '@angular/material/snack-bar';
import { BehaviorSubject } from 'rxjs';
import { AuthorizatorService } from '../../services/authorizator.service';
let PermissionManagerComponent = class PermissionManagerComponent {
constructor(authorizatorConfig, cd, data, authorizatorservice, snackbar) {
this.authorizatorConfig = authorizatorConfig;
this.cd = cd;
this.data = data;
this.authorizatorservice = authorizatorservice;
this.snackbar = snackbar;
this.AllowedOperation = Operation;
this.resourceCols = 5;
this.permissionCols = 5;
this.change = new EventEmitter();
this.user = data.user;
this.role = data.role;
}
ngOnInit() {
if (this.authorizatorConfig && this.authorizatorConfig.permissions) {
this.permissionsConfig = this.authorizatorConfig.permissions.map(permission => {
return {
resource: permission.resource,
operations: permission.allowedOperations.map(operation => {
return {
id: operation,
value: this.user ?
(this.user.data.permissions ?
(this.user.data.permissions.find(perm => perm.resource === permission.resource.id) ?
(this.user.data.permissions.find(perm => perm.resource === permission.resource.id).operations.findIndex(oper => oper === operation) > -1) : false) : false) :
this.role ?
(this.role.data.permissions ?
(this.role.data.permissions.find(perm => perm.resource === permission.resource.id) ?
(this.role.data.permissions.find(perm => perm.resource === permission.resource.id).operations.findIndex(oper => oper === operation) > -1) : false) : false) : false
};
})
};
});
}
else {
console.error(`Configuration of module missing, please add the next code in the Module declaration:
AngularFirebaseAuthorizatorModule.forRoot({
permissions: [
{
resource: {
id: 'someid',
data: {
description: 'Resource description'
}
},
allowedOperations: [
Operation.Create,
Operation.Read,
Operation.Update,
Operation.Delete,
Operation.Deny
]
}
]
})`);
}
}
ngAfterViewInit() {
if (this.permissionsConfig) {
const permissionManagerWidth = document.getElementById('permission_manager_container').offsetWidth;
if (permissionManagerWidth <= 400) {
this.resourceCols = 5;
this.permissionCols = 5;
}
else if (permissionManagerWidth > 400 && permissionManagerWidth <= 600) {
this.resourceCols = 6;
this.permissionCols = 4;
}
else if (permissionManagerWidth > 600 && permissionManagerWidth <= 800) {
this.resourceCols = 7;
this.permissionCols = 3;
}
else {
this.resourceCols = 8;
this.permissionCols = 2;
}
}
this.cd.detectChanges();
}
onPermissionChange(resource, operation, event) {
const updatePermissionsMonitor = new BehaviorSubject(null);
const permissions = this.user ? this.user.data.permissions || [] :
this.role ? this.role.data.permissions || [] : [];
const permissionIndex = permissions.findIndex(permission => permission.resource === resource.id);
if (event.checked) {
if (permissionIndex > -1) {
const operationIndex = permissions[permissionIndex].operations.findIndex(oper => oper === operation);
if (operationIndex === -1) {
permissions[permissionIndex].operations.push(operation);
updatePermissionsMonitor.next(permissions);
}
}
else {
permissions.push({
resource: resource.id,
operations: [operation]
});
updatePermissionsMonitor.next(permissions);
}
}
else {
if (permissionIndex > -1) {
const operationIndex = permissions[permissionIndex].operations.findIndex(oper => oper === operation);
if (operationIndex > -1) {
if (permissions[permissionIndex].operations.length > 1) {
permissions[permissionIndex].operations.splice(operationIndex, 1);
}
else {
permissions.splice(permissionIndex, 1);
}
updatePermissionsMonitor.next(permissions);
}
}
}
updatePermissionsMonitor.subscribe(permissionsToUpdate => {
if (permissionsToUpdate) {
if (this.user) {
const userToUpdate = this.data.user;
userToUpdate.data.permissions = permissionsToUpdate;
const config = new MatSnackBarConfig();
config.duration = 2000;
this.authorizatorservice.updateUserPermissions(this.data.rootFirebasePath, userToUpdate).then(() => {
config.panelClass = ['success-bar'];
this.snackbar.open('Permissions updated', null, config);
}).catch(error => {
config.panelClass = ['error-bar'];
this.snackbar.open(error.message, null, config);
});
}
if (this.role) {
const roleToUpdate = this.data.role;
roleToUpdate.data.permissions = permissionsToUpdate;
const config = new MatSnackBarConfig();
config.duration = 2000;
this.authorizatorservice.updateRolePermissions(this.data.rootFirebasePath, roleToUpdate).then(() => {
config.panelClass = ['success-bar'];
this.snackbar.open('Permissions updated', null, config);
}).catch(error => {
console.log('ban5');
console.log(error);
config.panelClass = ['error-bar'];
this.snackbar.open(error.message, null, config);
});
}
updatePermissionsMonitor.unsubscribe();
}
});
}
};
PermissionManagerComponent.ctorParameters = () => [
{ type: undefined, decorators: [{ type: Inject, args: [AUTHORIZATOR_CONFIG,] }] },
{ type: ChangeDetectorRef },
{ type: undefined, decorators: [{ type: Inject, args: [MAT_DIALOG_DATA,] }] },
{ type: AuthorizatorService },
{ type: MatSnackBar }
];
__decorate([
Output(),
__metadata("design:type", EventEmitter)
], PermissionManagerComponent.prototype, "change", void 0);
PermissionManagerComponent = __decorate([
Component({
selector: 'lib-permission-manager',
template: "<h1 mat-dialog-title>User Permissions</h1>\n<div mat-dialog-content>\n <div *ngIf=\"permissionsConfig\" id=\"permission_manager_container\">\n <div>\n <mat-grid-list cols=\"10\" rowHeight=\"48px\" style=\"width: 100%;\">\n <mat-grid-tile [colspan]=\"resourceCols\">\n Resource\n </mat-grid-tile>\n <mat-grid-tile [colspan]=\"permissionCols\">\n Permissions\n </mat-grid-tile>\n </mat-grid-list>\n </div>\n <div *ngFor=\"let permission of permissionsConfig\">\n <mat-grid-list cols=\"10\" rowHeight=\"48px\" style=\"width: 100%;\">\n <mat-grid-tile [rowspan]=\"permission.operations.length\" class=\"permission-grid\" [colspan]=\"resourceCols\">\n {{permission.resource.data.description}}\n </mat-grid-tile>\n <mat-grid-tile *ngFor=\"let operation of permission.operations\" class=\"permission-grid\" [colspan]=\"permissionCols\">\n <mat-slide-toggle [checked]=\"operation.value\"\n (change)=\"onPermissionChange(permission.resource, operation.id, $event)\">\n {{\n operation.id === AllowedOperation.Create ? 'Create' :\n operation.id === AllowedOperation.Read ? 'Read':\n operation.id === AllowedOperation.Update ? 'Update':\n operation.id === AllowedOperation.Delete ? 'Delete':\n operation.id === AllowedOperation.Deny ? 'Deny' : ''\n }}\n </mat-slide-toggle>\n </mat-grid-tile>\n </mat-grid-list>\n </div>\n </div> \n</div>\n<div mat-dialog-actions>\n <button mat-button cdkFocusInitial [mat-dialog-close]>Close</button>\n</div>\n\n",
styles: [".permission-grid{background:#f5f5f5;border:1px solid #d3d3d3}.mat-dialog-actions{-webkit-box-pack:end;justify-content:flex-end}div#permission_manager_container{margin-bottom:5px!important}"]
}),
__param(0, Inject(AUTHORIZATOR_CONFIG)),
__param(2, Inject(MAT_DIALOG_DATA)),
__metadata("design:paramtypes", [Object, ChangeDetectorRef, Object, AuthorizatorService,
MatSnackBar])
], PermissionManagerComponent);
export { PermissionManagerComponent };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGVybWlzc2lvbi1tYW5hZ2VyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL2FuZ3VsYXItZmlyZWJhc2UtYXV0aG9yaXphdG9yLyIsInNvdXJjZXMiOlsibGliL2NvbXBvbmVudHMvcGVybWlzc2lvbi1tYW5hZ2VyL3Blcm1pc3Npb24tbWFuYWdlci5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxhQUFhLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDekgsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFHdEUsT0FBTyxFQUFFLFNBQVMsRUFBaUIsTUFBTSw4QkFBOEIsQ0FBQztBQUN4RSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDM0QsT0FBTyxFQUFFLGlCQUFpQixFQUFFLFdBQVcsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBRzdFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDdkMsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFjMUUsSUFBYSwwQkFBMEIsR0FBdkMsTUFBYSwwQkFBMEI7SUFZckMsWUFDdUMsa0JBQXNDLEVBQVUsRUFBcUIsRUFDMUUsSUFBb0IsRUFDNUMsbUJBQXdDLEVBQ3hDLFFBQXFCO1FBSFEsdUJBQWtCLEdBQWxCLGtCQUFrQixDQUFvQjtRQUFVLE9BQUUsR0FBRixFQUFFLENBQW1CO1FBQzFFLFNBQUksR0FBSixJQUFJLENBQWdCO1FBQzVDLHdCQUFtQixHQUFuQixtQkFBbUIsQ0FBcUI7UUFDeEMsYUFBUSxHQUFSLFFBQVEsQ0FBYTtRQVh4QixxQkFBZ0IsR0FBRyxTQUFTLENBQUM7UUFDN0IsaUJBQVksR0FBRyxDQUFDLENBQUM7UUFDakIs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Q0FBQyxtQkFBbUIsQ0FBQyxDQUFBO0lBQzNCLFdBQUEsTUFBTSxDQUFDLGVBQWUsQ0FBQyxDQUFBOzZDQURpRSxpQkFBaUIsVUFFN0UsbUJBQW1CO1FBQzlCLFdBQVc7R0FoQnBCLDBCQUEwQixDQTBLdEM7U0ExS1ksMEJBQTBCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBPbkluaXQsIEluamVjdCwgQWZ0ZXJWaWV3SW5pdCwgQ2hhbmdlRGV0ZWN0b3JSZWYsIE91dHB1dCwgRXZlbnRFbWl0dGVyLCBJbnB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQVVUSE9SSVpBVE9SX0NPTkZJRyB9IGZyb20gJy4uLy4uL2F1dGhvcml6YXRvci5jb25maWcudG9rZW4nO1xuaW1wb3J0IHsgQXV0aG9yaXphdG9yQ29uZmlnIH0gZnJvbSAnLi4vLi4vYXV0aG9yaXphdG9yLmNvbmZpZyc7XG5pbXBvcnQgeyBSZXNvdXJjZU9iaiB9IGZyb20gJy4uLy4uL2NsYXNzZXMvcmVzb3VyY2Utb2JqJztcbmltcG9ydCB7IE9wZXJhdGlvbiwgUGVybWlzc2lvbk9iaiB9IGZyb20gJy4uLy4uL2NsYXNzZXMvcGVybWlzc2lvbi1vYmonO1xuaW1wb3J0IHsgTUFUX0RJQUxPR19EQVRBIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZGlhbG9nJztcbmltcG9ydCB7IE1hdFNuYWNrQmFyQ29uZmlnLCBNYXRTbmFja0JhciB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3NuYWNrLWJhcic7XG5pbXBvcnQgeyBNYXRTbGlkZVRvZ2dsZUNoYW5nZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3NsaWRlLXRvZ2dsZSc7XG5pbXBvcnQgeyBVc2VyT2JqIH0gZnJvbSAnLi4vLi4vY2xhc3Nlcy91c2VyLW9iaic7XG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IEF1dGhvcml6YXRvclNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9hdXRob3JpemF0b3Iuc2VydmljZSc7XG5pbXBvcnQgeyBSb2xlT2JqIH0gZnJvbSAnLi4vLi4vY2xhc3Nlcy9yb2xlLW9iaic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGVybWlzc2lvbkRhdGEge1xuICByb290RmlyZWJhc2VQYXRoOiBzdHJpbmc7XG4gIHVzZXI/OiBVc2VyT2JqO1xuICByb2xlPzogUm9sZU9iajtcbn1cblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbGliLXBlcm1pc3Npb24tbWFuYWdlcicsXG4gIHRlbXBsYXRlVXJsOiAnLi9wZXJtaXNzaW9uLW1hbmFnZXIuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9wZXJtaXNzaW9uLW1hbmFnZXIuY29tcG9uZW50LnNjc3MnXVxufSlcbmV4cG9ydCBjbGFzcyBQZXJtaXNzaW9uTWFuYWdlckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgQWZ0ZXJWaWV3SW5pdCB7XG4gIHB1YmxpYyBwZXJtaXNzaW9uc0NvbmZpZzoge1xuICAgIHJlc291cmNlOiBSZXNvdXJjZU9iaixcbiAgICBvcGVyYXRpb25zOiB7IGlkOiBPcGVyYXRpb24sIHZhbHVlOiBib29sZWFufVtdXG4gIH1bXTtcbiAgcHVibGljIEFsbG93ZWRPcGVyYXRpb24gPSBPcGVyYXRpb247XG4gIHB1YmxpYyByZXNvdXJjZUNvbHMgPSA1O1xuICBwdWJsaWMgcGVybWlzc2lvbkNvbHMgPSA1O1xuICBwdWJsaWMgdXNlcjogVXNlck9iajtcbiAgcHVibGljIHJvbGU6IFJvbGVPYmo7XG5cbiAgQE91dHB1dCgpIGNoYW5nZTogRXZlbnRFbWl0dGVyPFBlcm1pc3Npb25PYmo+ID0gbmV3IEV2ZW50RW1pdHRlcjxQZXJtaXNzaW9uT2JqPigpO1xuICBjb25zdHJ1Y3RvcihcbiAgICBASW5qZWN0KEFVVEhPUklaQVRPUl9DT05GSUcpIHByaXZhdGUgYXV0aG9yaXphdG9yQ29uZmlnOiBBdXRob3JpemF0b3JDb25maWcsIHByaXZhdGUgY2Q6IENoYW5nZURldGVjdG9yUmVmLFxuICAgIEBJbmplY3QoTUFUX0RJQUxPR19EQVRBKSBwdWJsaWMgZGF0YTogUGVybWlzc2lvbkRhdGEsXG4gICAgcHJpdmF0ZSBhdXRob3JpemF0b3JzZXJ2aWNlOiBBdXRob3JpemF0b3JTZXJ2aWNlLFxuICAgIHByaXZhdGUgc25hY2tiYXI6IE1hdFNuYWNrQmFyXG4gICkge1xuICAgIHRoaXMudXNlciA9IGRhdGEudXNlcjtcbiAgICB0aGlzLnJvbGUgPSBkYXRhLnJvbGU7XG4gIH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICBpZiAodGhpcy5hdXRob3JpemF0b3JDb25maWcgJiYgdGhpcy5hdXRob3JpemF0b3JDb25maWcucGVybWlzc2lvbnMpIHtcbiAgICAgIHRoaXMucGVybWlzc2lvbnNDb25maWcgPSB0aGlzLmF1dGhvcml6YXRvckNvbmZpZy5wZXJtaXNzaW9ucy5tYXAocGVybWlzc2lvbiA9PiB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgcmVzb3VyY2U6IHBlcm1pc3Npb24ucmVzb3VyY2UsXG4gICAgICAgICAgb3BlcmF0aW9uczogcGVybWlzc2lvbi5hbGxvd2VkT3BlcmF0aW9ucy5tYXAob3BlcmF0aW9uID0+IHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIGlkOiBvcGVyYXRpb24sXG4gICAgICAgICAgICAgIHZhbHVlOlxuICAgICAgICAgICAgICAgIHRoaXMudXNlciA/XG4gICAgICAgICAgICAgICAgICAoXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXNlci5kYXRhLnBlcm1pc3Npb25zID9cbiAgICAgICAgICAgICAgICAgICAgKFxuICAgICAgICAgICAgICAgICAgICAgIHRoaXMudXNlci5kYXRhLnBlcm1pc3Npb25zLmZpbmQocGVybSA9PiBwZXJtLnJlc291cmNlID09PSBwZXJtaXNzaW9uLnJlc291cmNlLmlkKSA/XG4gICAgICAgICAgICAgICAgICAgICAgKFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy51c2VyLmRhdGEucGVybWlzc2lvbnMuZmluZChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcGVybSA9PiBwZXJtLnJlc291cmNlID09PSBwZXJtaXNzaW9uLnJlc291cmNlLmlkXG4gICAgICAgICAgICAgICAgICAgICAgICApLm9wZXJhdGlvbnMuZmluZEluZGV4KG9wZXIgPT4gb3BlciA9PT0gb3BlcmF0aW9uKSA+IC0xXG4gICAgICAgICAgICAgICAgICAgICAgKSA6IGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICkgOiBmYWxzZVxuICAgICAgICAgICAgICAgICAgKSA6XG4gICAgICAgICAgICAgICAgdGhpcy5yb2xlID9cbiAgICAgICAgICAgICAgICAgIChcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yb2xlLmRhdGEucGVybWlzc2lvbnMgP1xuICAgICAgICAgICAgICAgICAgICAoXG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5yb2xlLmRhdGEucGVybWlzc2lvbnMuZmluZChwZXJtID0+IHBlcm0ucmVzb3VyY2UgPT09IHBlcm1pc3Npb24ucmVzb3VyY2UuaWQpID9cbiAgICAgICAgICAgICAgICAgICAgICAoXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJvbGUuZGF0YS5wZXJtaXNzaW9ucy5maW5kKFxuICAgICAgICAgICAgICAgICAgICAgICAgICBwZXJtID0+IHBlcm0ucmVzb3VyY2UgPT09IHBlcm1pc3Npb24ucmVzb3VyY2UuaWRcbiAgICAgICAgICAgICAgICAgICAgICAgICkub3BlcmF0aW9ucy5maW5kSW5kZXgob3BlciA9PiBvcGVyID09PSBvcGVyYXRpb24pID4gLTFcbiAgICAgICAgICAgICAgICAgICAgICApIDogZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgKSA6IGZhbHNlXG4gICAgICAgICAgICAgICAgICApIDogZmFsc2VcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSlcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zb2xlLmVycm9yKGBDb25maWd1cmF0aW9uIG9mIG1vZHVsZSBtaXNzaW5nLCBwbGVhc2UgYWRkIHRoZSBuZXh0IGNvZGUgaW4gdGhlIE1vZHVsZSBkZWNsYXJhdGlvbjpcbiAgICAgIEFuZ3VsYXJGaXJlYmFzZUF1dGhvcml6YXRvck1vZHVsZS5mb3JSb290KHtcbiAgICAgICAgcGVybWlzc2lvbnM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICByZXNvdXJjZToge1xuICAgICAgICAgICAgICBpZDogJ3NvbWVpZCcsXG4gICAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogJ1Jlc291cmNlIGRlc2NyaXB0aW9uJ1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYWxsb3dlZE9wZXJhdGlvbnM6IFtcbiAgICAgICAgICAgICAgT3BlcmF0aW9uLkNyZWF0ZSxcbiAgICAgICAgICAgICAgT3BlcmF0aW9uLlJlYWQsXG4gICAgICAgICAgICAgIE9wZXJhdGlvbi5VcGRhdGUsXG4gICAgICAgICAgICAgIE9wZXJhdGlvbi5EZWxldGUsXG4gICAgICAgICAgICAgIE9wZXJhdGlvbi5EZW55XG4gICAgICAgICAgICBdXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9KWApO1xuICAgIH1cbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICBpZiAodGhpcy5wZXJtaXNzaW9uc0NvbmZpZykge1xuICAgICAgY29uc3QgcGVybWlzc2lvbk1hbmFnZXJXaWR0aCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdwZXJtaXNzaW9uX21hbmFnZXJfY29udGFpbmVyJykub2Zmc2V0V2lkdGg7XG4gICAgICBpZiAocGVybWlzc2lvbk1hbmFnZXJXaWR0aCA8PSA0MDApIHtcbiAgICAgICAgdGhpcy5yZXNvdXJjZUNvbHMgPSA1O1xuICAgICAgICB0aGlzLnBlcm1pc3Npb25Db2xzID0gNTtcbiAgICAgIH0gZWxzZSBpZiAocGVybWlzc2lvbk1hbmFnZXJXaWR0aCA+IDQwMCAmJiBwZXJtaXNzaW9uTWFuYWdlcldpZHRoIDw9IDYwMCkge1xuICAgICAgICB0aGlzLnJlc291cmNlQ29scyA9IDY7XG4gICAgICAgIHRoaXMucGVybWlzc2lvbkNvbHMgPSA0O1xuICAgICAgfSBlbHNlIGlmIChwZXJtaXNzaW9uTWFuYWdlcldpZHRoID4gNjAwICYmIHBlcm1pc3Npb25NYW5hZ2VyV2lkdGggPD0gODAwKSB7XG4gICAgICAgIHRoaXMucmVzb3VyY2VDb2xzID0gNztcbiAgICAgICAgdGhpcy5wZXJtaXNzaW9uQ29scyA9IDM7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnJlc291cmNlQ29scyA9IDg7XG4gICAgICAgIHRoaXMucGVybWlzc2lvbkNvbHMgPSAyO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLmNkLmRldGVjdENoYW5nZXMoKTtcbiAgfVxuXG4gIG9uUGVybWlzc2lvbkNoYW5nZShyZXNvdXJjZTogUmVzb3VyY2VPYmosIG9wZXJhdGlvbjogT3BlcmF0aW9uLCBldmVudDogTWF0U2xpZGVUb2dnbGVDaGFuZ2UpIHtcbiAgICBjb25zdCB1cGRhdGVQZXJtaXNzaW9uc01vbml0b3I6IEJlaGF2aW9yU3ViamVjdDxQZXJtaXNzaW9uT2JqW10+ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxQZXJtaXNzaW9uT2JqW10+KG51bGwpO1xuICAgIGNvbnN0IHBlcm1pc3Npb25zID1cbiAgICAgIHRoaXMudXNlciA/IHRoaXMudXNlci5kYXRhLnBlcm1pc3Npb25zIHx8IFtdIDpcbiAgICAgIHRoaXMucm9sZSA/IHRoaXMucm9sZS5kYXRhLnBlcm1pc3Npb25zIHx8IFtdIDogW107XG4gICAgY29uc3QgcGVybWlzc2lvbkluZGV4OiBudW1iZXIgPSBwZXJtaXNzaW9ucy5maW5kSW5kZXgocGVybWlzc2lvbiA9PiBwZXJtaXNzaW9uLnJlc291cmNlID09PSByZXNvdXJjZS5pZCk7XG4gICAgaWYgKGV2ZW50LmNoZWNrZWQpIHtcbiAgICAgIGlmIChwZXJtaXNzaW9uSW5kZXggPiAtMSkge1xuICAgICAgICBjb25zdCBvcGVyYXRpb25JbmRleDogbnVtYmVyID0gcGVybWlzc2lvbnNbcGVybWlzc2lvbkluZGV4XS5vcGVyYXRpb25zLmZpbmRJbmRleChvcGVyID0+IG9wZXIgPT09IG9wZXJhdGlvbik7XG4gICAgICAgIGlmIChvcGVyYXRpb25JbmRleCA9PT0gLTEpIHtcbiAgICAgICAgICBwZXJtaXNzaW9uc1twZXJtaXNzaW9uSW5kZXhdLm9wZXJhdGlvbnMucHVzaChvcGVyYXRpb24pO1xuICAgICAgICAgIHVwZGF0ZVBlcm1pc3Npb25zTW9uaXRvci5uZXh0KHBlcm1pc3Npb25zKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcGVybWlzc2lvbnMucHVzaCh7XG4gICAgICAgICAgcmVzb3VyY2U6IHJlc291cmNlLmlkLFxuICAgICAgICAgIG9wZXJhdGlvbnM6IFtvcGVyYXRpb25dXG4gICAgICAgIH0pO1xuICAgICAgICB1cGRhdGVQZXJtaXNzaW9uc01vbml0b3IubmV4dChwZXJtaXNzaW9ucyk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChwZXJtaXNzaW9uSW5kZXggPiAtMSkge1xuICAgICAgICBjb25zdCBvcGVyYXRpb25JbmRleDogbnVtYmVyID0gcGVybWlzc2lvbnNbcGVybWlzc2lvbkluZGV4XS5vcGVyYXRpb25zLmZpbmRJbmRleChvcGVyID0+IG9wZXIgPT09IG9wZXJhdGlvbik7XG4gICAgICAgIGlmIChvcGVyYXRpb25JbmRleCA+IC0xKSB7XG4gICAgICAgICAgaWYgKHBlcm1pc3Npb25zW3Blcm1pc3Npb25JbmRleF0ub3BlcmF0aW9ucy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICBwZXJtaXNzaW9uc1twZXJtaXNzaW9uSW5kZXhdLm9wZXJhdGlvbnMuc3BsaWNlKG9wZXJhdGlvbkluZGV4LCAxKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcGVybWlzc2lvbnMuc3BsaWNlKHBlcm1pc3Npb25JbmRleCwgMSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHVwZGF0ZVBlcm1pc3Npb25zTW9uaXRvci5uZXh0KHBlcm1pc3Npb25zKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICB1cGRhdGVQZXJtaXNzaW9uc01vbml0b3Iuc3Vic2NyaWJlKHBlcm1pc3Npb25zVG9VcGRhdGUgPT4ge1xuICAgICAgaWYgKHBlcm1pc3Npb25zVG9VcGRhdGUpIHtcbiAgICAgICAgaWYgKHRoaXMudXNlcikge1xuICAgICAgICAgIGNvbnN0IHVzZXJUb1VwZGF0ZTogVXNlck9iaiA9IHRoaXMuZGF0YS51c2VyO1xuICAgICAgICAgIHVzZXJUb1VwZGF0ZS5kYXRhLnBlcm1pc3Npb25zID0gcGVybWlzc2lvbnNUb1VwZGF0ZTtcbiAgICAgICAgICBjb25zdCBjb25maWc6IE1hdFNuYWNrQmFyQ29uZmlnID0gbmV3IE1hdFNuYWNrQmFyQ29uZmlnKCk7XG4gICAgICAgICAgY29uZmlnLmR1cmF0aW9uID0gMjAwMDtcbiAgICAgICAgICB0aGlzLmF1dGhvcml6YXRvcnNlcnZpY2UudXBkYXRlVXNlclBlcm1pc3Npb25zKHRoaXMuZGF0YS5yb290RmlyZWJhc2VQYXRoLCB1c2VyVG9VcGRhdGUpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgY29uZmlnLnBhbmVsQ2xhc3MgPSBbJ3N1Y2Nlc3MtYmFyJ107XG4gICAgICAgICAgICB0aGlzLnNuYWNrYmFyLm9wZW4oJ1Blcm1pc3Npb25zIHVwZGF0ZWQnLCBudWxsLCBjb25maWcpO1xuICAgICAgICAgIH0pLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgIGNvbmZpZy5wYW5lbENsYXNzID0gWydlcnJvci1iYXInXTtcbiAgICAgICAgICAgIHRoaXMuc25hY2tiYXIub3BlbihlcnJvci5tZXNzYWdlLCBudWxsLCBjb25maWcpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnJvbGUpIHtcbiAgICAgICAgICBjb25zdCByb2xlVG9VcGRhdGU6IFJvbGVPYmogPSB0aGlzLmRhdGEucm9sZTtcbiAgICAgICAgICByb2xlVG9VcGRhdGUuZGF0YS5wZXJtaXNzaW9ucyA9IHBlcm1pc3Npb25zVG9VcGRhdGU7XG4gICAgICAgICAgY29uc3QgY29uZmlnOiBNYXRTbmFja0JhckNvbmZpZyA9IG5ldyBNYXRTbmFja0JhckNvbmZpZygpO1xuICAgICAgICAgIGNvbmZpZy5kdXJhdGlvbiA9IDIwMDA7XG4gICAgICAgICAgdGhpcy5hdXRob3JpemF0b3JzZXJ2aWNlLnVwZGF0ZVJvbGVQZXJtaXNzaW9ucyh0aGlzLmRhdGEucm9vdEZpcmViYXNlUGF0aCwgcm9sZVRvVXBkYXRlKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIGNvbmZpZy5wYW5lbENsYXNzID0gWydzdWNjZXNzLWJhciddO1xuICAgICAgICAgICAgdGhpcy5zbmFja2Jhci5vcGVuKCdQZXJtaXNzaW9ucyB1cGRhdGVkJywgbnVsbCwgY29uZmlnKTtcbiAgICAgICAgICB9KS5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZygnYmFuNScpO1xuICAgICAgICAgICAgY29uc29sZS5sb2coZXJyb3IpO1xuICAgICAgICAgICAgY29uZmlnLnBhbmVsQ2xhc3MgPSBbJ2Vycm9yLWJhciddO1xuICAgICAgICAgICAgdGhpcy5zbmFja2Jhci5vcGVuKGVycm9yLm1lc3NhZ2UsIG51bGwsIGNvbmZpZyk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgdXBkYXRlUGVybWlzc2lvbnNNb25pdG9yLnVuc3Vic2NyaWJlKCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn1cbiJdfQ==