@tangential/admin-console
Version:
A basic administration console
102 lines • 22.3 kB
JavaScript
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, ViewEncapsulation } from '@angular/core';
import { AuthRole } from '@tangential/authorization-service';
import { Observable } from 'rxjs';
import { debounceTime, distinctUntilChanged, filter, map } from 'rxjs/operators';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
import * as i2 from "@angular/forms";
import * as i3 from "@angular/material/button";
import * as i4 from "@angular/material/icon";
import * as i5 from "@angular/material/form-field";
import * as i6 from "@angular/material/input";
export class RoleComponent {
constructor() {
this.collapsed = true;
this.remove = new EventEmitter(false);
this._focusDebouncer = new EventEmitter(false);
this.addRolePermission = new EventEmitter(false);
this.removeRolePermission = new EventEmitter(false);
this.submitted = false;
let distinct = this._focusDebouncer.asObservable();
distinct = distinct.pipe(debounceTime(10), distinctUntilChanged());
this.focus = distinct.pipe(filter((focused) => focused === true), map(() => {
return new Event('focus');
}));
this.blur = distinct.pipe(filter((focused) => focused === false), map(() => {
return new Event('blur');
}));
this.change = distinct.pipe(filter((focused) => focused === false && this._changed), map(() => {
this.collapsed = false;
const change = {
previous: this._previous,
current: this.role
};
this._previous = AuthRole.from(this.role);
this._changed = false;
return change;
}));
}
ngOnChanges(changes) {
if (changes.role) {
this._previous = AuthRole.from(this.role);
this._changed = false;
}
}
fireRemove() {
this.remove.emit(this.role);
}
onChange() {
this._changed = true;
}
onBlur() {
this._focusDebouncer.emit(false);
}
onFocus() {
this._focusDebouncer.emit(true);
}
onSubmit() {
this.submitted = true;
}
hasPermission(perm) {
return this.rolePermissions.some(rolePerm => rolePerm.$key === perm.$key);
}
doTogglePermission(permission) {
const rolePermission = {
permission: permission,
role: this.role
};
if (this.rolePermissions.some(entry => entry.$key === permission.$key)) {
this.removeRolePermission.emit(rolePermission);
}
else {
this.addRolePermission.emit(rolePermission);
}
}
}
RoleComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.10", ngImport: i0, type: RoleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
RoleComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.10", type: RoleComponent, selector: "tanj-role", inputs: { role: "role", allPermissions: "allPermissions", rolePermissions: "rolePermissions", collapsed: "collapsed" }, outputs: { change: "change", remove: "remove", addRolePermission: "addRolePermission", removeRolePermission: "removeRolePermission", focus: "focus", blur: "blur" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"tanj-role-form-wrapper\" flex layout=\"column\" layout-align=\"start\">\n <form *ngIf=\"role != null\" (ngSubmit)=\"onSubmit($event)\" #theForm=\"ngForm\" flex layout=\"row\"\n layout-align=\"space-between\">\n\n <div class=\"tanj-role-inputs-wrapper\" layout=\"row\" flex=\"80\" layout-align=\"space-between start\">\n <mat-form-field flex=\"40\">\n <input matInput [(ngModel)]=\"role.$key\" name=\"name\" #fName=\"ngModel\"\n class=\"tanj-input\"\n dividerColor=\"accent\"\n [type]=\"'text'\"\n required minlength=\"2\"\n value=\"{{role.$key}}\"\n placeholder=\"Name\"\n (change)=\"$event.stopPropagation(); onChange()\"\n (focus)=\"$event.stopPropagation(); onFocus()\"\n (blur)=\"$event.stopPropagation(); onBlur()\"\n /></mat-form-field>\n <mat-form-field flex=\"60\">\n <input matInput [(ngModel)]=\"role.description\" name=\"description\" #fDescription=\"ngModel\"\n class=\"tanj-description tanj-input\"\n dividerColor=\"accent\"\n [type]=\"'text'\"\n value=\"{{role.description}}\"\n (change)=\"$event.stopPropagation(); onChange()\"\n (focus)=\"$event.stopPropagation(); onFocus()\"\n (blur)=\"$event.stopPropagation(); onBlur()\"\n placeholder=\"Description\"/>\n </mat-form-field>\n </div>\n <div class=\"tanj-delete-button\" flex layout=\"row\" layout-align=\"end center\">\n <button mat-mini-fab\n type=\"button\"\n aria-label=\"Delete Role\"\n (focus)=\"$event.stopPropagation(); onFocus()\"\n (blur)=\"$event.stopPropagation(); onBlur()\"\n (click)=\"fireRemove()\"\n [disabled]=\"false\">\n <mat-icon class=\"mat-24\">delete</mat-icon>\n </button>\n </div>\n </form>\n</div>\n\n\n\n", dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i2.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i2.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i5.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.10", ngImport: i0, type: RoleComponent, decorators: [{
type: Component,
args: [{ selector: 'tanj-role', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div class=\"tanj-role-form-wrapper\" flex layout=\"column\" layout-align=\"start\">\n <form *ngIf=\"role != null\" (ngSubmit)=\"onSubmit($event)\" #theForm=\"ngForm\" flex layout=\"row\"\n layout-align=\"space-between\">\n\n <div class=\"tanj-role-inputs-wrapper\" layout=\"row\" flex=\"80\" layout-align=\"space-between start\">\n <mat-form-field flex=\"40\">\n <input matInput [(ngModel)]=\"role.$key\" name=\"name\" #fName=\"ngModel\"\n class=\"tanj-input\"\n dividerColor=\"accent\"\n [type]=\"'text'\"\n required minlength=\"2\"\n value=\"{{role.$key}}\"\n placeholder=\"Name\"\n (change)=\"$event.stopPropagation(); onChange()\"\n (focus)=\"$event.stopPropagation(); onFocus()\"\n (blur)=\"$event.stopPropagation(); onBlur()\"\n /></mat-form-field>\n <mat-form-field flex=\"60\">\n <input matInput [(ngModel)]=\"role.description\" name=\"description\" #fDescription=\"ngModel\"\n class=\"tanj-description tanj-input\"\n dividerColor=\"accent\"\n [type]=\"'text'\"\n value=\"{{role.description}}\"\n (change)=\"$event.stopPropagation(); onChange()\"\n (focus)=\"$event.stopPropagation(); onFocus()\"\n (blur)=\"$event.stopPropagation(); onBlur()\"\n placeholder=\"Description\"/>\n </mat-form-field>\n </div>\n <div class=\"tanj-delete-button\" flex layout=\"row\" layout-align=\"end center\">\n <button mat-mini-fab\n type=\"button\"\n aria-label=\"Delete Role\"\n (focus)=\"$event.stopPropagation(); onFocus()\"\n (blur)=\"$event.stopPropagation(); onBlur()\"\n (click)=\"fireRemove()\"\n [disabled]=\"false\">\n <mat-icon class=\"mat-24\">delete</mat-icon>\n </button>\n </div>\n </form>\n</div>\n\n\n\n" }]
}], ctorParameters: function () { return []; }, propDecorators: { role: [{
type: Input
}], allPermissions: [{
type: Input
}], rolePermissions: [{
type: Input
}], collapsed: [{
type: Input
}], change: [{
type: Output
}], remove: [{
type: Output
}], addRolePermission: [{
type: Output
}], removeRolePermission: [{
type: Output
}], focus: [{
type: Output
}], blur: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm9sZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy90YW5nZW50aWFsL2FkbWluLWNvbnNvbGUvc3JjL2xpYi9wYWdlcy9yb2xlcy9yb2xlLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3RhbmdlbnRpYWwvYWRtaW4tY29uc29sZS9zcmMvbGliL3BhZ2VzL3JvbGVzL3JvbGUuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLHVCQUF1QixFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFhLE1BQU0sRUFBZ0IsaUJBQWlCLEVBQUMsTUFBTSxlQUFlLENBQUE7QUFDekksT0FBTyxFQUFpQixRQUFRLEVBQUMsTUFBTSxtQ0FBbUMsQ0FBQTtBQUMxRSxPQUFPLEVBQUMsVUFBVSxFQUFDLE1BQU0sTUFBTSxDQUFBO0FBQy9CLE9BQU8sRUFBQyxZQUFZLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBQyxNQUFNLGdCQUFnQixDQUFBOzs7Ozs7OztBQVM5RSxNQUFNLE9BQU8sYUFBYTtJQTBCeEI7UUFwQlMsY0FBUyxHQUFZLElBQUksQ0FBQTtRQUd4QixXQUFNLEdBQTJCLElBQUksWUFBWSxDQUFXLEtBQUssQ0FBQyxDQUFBO1FBRXBFLG9CQUFlLEdBQTBCLElBQUksWUFBWSxDQUFVLEtBQUssQ0FBQyxDQUFDO1FBRXhFLHNCQUFpQixHQUN2QixJQUFJLFlBQVksQ0FBaUQsS0FBSyxDQUFDLENBQUE7UUFDakUseUJBQW9CLEdBQzFCLElBQUksWUFBWSxDQUFpRCxLQUFLLENBQUMsQ0FBQTtRQUszRSxjQUFTLEdBQVksS0FBSyxDQUFDO1FBTXpCLElBQUksUUFBUSxHQUF3QixJQUFJLENBQUMsZUFBZSxDQUFDLFlBQVksRUFBRSxDQUFBO1FBQ3ZFLFFBQVEsR0FBRyxRQUFRLENB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U0FDL0M7YUFBTTtZQUNMLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUE7U0FDNUM7SUFDSCxDQUFDOzsyR0FuR1UsYUFBYTsrRkFBYixhQUFhLG1XQ1oxQixvOURBNkNBOzRGRGpDYSxhQUFhO2tCQU56QixTQUFTOytCQUNTLFdBQVcsbUJBRVgsdUJBQXVCLENBQUMsTUFBTSxpQkFDOUIsaUJBQWlCLENBQUMsSUFBSTswRUFLOUIsSUFBSTtzQkFBWixLQUFLO2dCQUNHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBQ0csZUFBZTtzQkFBdkIsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUVJLE1BQU07c0JBQWYsTUFBTTtnQkFDRyxNQUFNO3NCQUFmLE1BQU07Z0JBSUcsaUJBQWlCO3NCQUExQixNQUFNO2dCQUVHLG9CQUFvQjtzQkFBN0IsTUFBTTtnQkFFRyxLQUFLO3NCQUFkLE1BQU07Z0JBQ0csSUFBSTtzQkFBYixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIElucHV0LCBPbkNoYW5nZXMsIE91dHB1dCwgU2ltcGxlQ2hhbmdlLCBWaWV3RW5jYXBzdWxhdGlvbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSdcbmltcG9ydCB7QXV0aFBlcm1pc3Npb24sIEF1dGhSb2xlfSBmcm9tICdAdGFuZ2VudGlhbC9hdXRob3JpemF0aW9uLXNlcnZpY2UnXG5pbXBvcnQge09ic2VydmFibGV9IGZyb20gJ3J4anMnXG5pbXBvcnQge2RlYm91bmNlVGltZSwgZGlzdGluY3RVbnRpbENoYW5nZWQsIGZpbHRlciwgbWFwfSBmcm9tICdyeGpzL29wZXJhdG9ycydcblxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICAgICAgICAndGFuai1yb2xlJyxcbiAgdGVtcGxhdGVVcmw6ICAgICAnLi9yb2xlLmNvbXBvbmVudC5odG1sJyxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIGVuY2Fwc3VsYXRpb246ICAgVmlld0VuY2Fwc3VsYXRpb24uTm9uZVxufSlcbmV4cG9ydCBjbGFzcyBSb2xlQ29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzIHtcblxuXG4gIEBJbnB1dCgpIHJvbGU6IEF1dGhSb2xlXG4gIEBJbnB1dCgpIGFsbFBlcm1pc3Npb25zOiBBdXRoUGVybWlzc2lvbltdXG4gIEBJbnB1dCgpIHJvbGVQZXJtaXNzaW9uczogQXV0aFBlcm1pc3Npb25bXVxuICBASW5wdXQoKSBjb2xsYXBzZWQ6IGJvb2xlYW4gPSB0cnVlXG5cbiAgQE91dHB1dCgpIGNoYW5nZTogT2JzZXJ2YWJsZTx7IGN1cnJlbnQ6IEF1dGhSb2xlLCBwcmV2aW91czogQXV0aFJvbGUgfT5cbiAgQE91dHB1dCgpIHJlbW92ZTogRXZlbnRFbWl0dGVyPEF1dGhSb2xlPiA9IG5ldyBFdmVudEVtaXR0ZXI8QXV0aFJvbGU+KGZhbHNlKVxuXG4gIHByaXZhdGUgX2ZvY3VzRGVib3VuY2VyOiBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4gPSBuZXcgRXZlbnRFbWl0dGVyPGJvb2xlYW4+KGZhbHNlKTtcblxuICBAT3V0cHV0KCkgYWRkUm9sZVBlcm1pc3Npb246IEV2ZW50RW1pdHRlcjx7IHJvbGU6IEF1dGhSb2xlLCBwZXJtaXNzaW9uOiBBdXRoUGVybWlzc2lvbiB9PlxuICAgID0gbmV3IEV2ZW50RW1pdHRlcjx7IHJvbGU6IEF1dGhSb2xlLCBwZXJtaXNzaW9uOiBBdXRoUGVybWlzc2lvbiB9PihmYWxzZSlcbiAgQE91dHB1dCgpIHJlbW92ZVJvbGVQZXJtaXNzaW9uOiBFdmVudEVtaXR0ZXI8eyByb2xlOiBBdXRoUm9sZSwgcGVybWlzc2lvbjogQXV0aFBlcm1pc3Npb24gfT5cbiAgICA9IG5ldyBFdmVudEVtaXR0ZXI8eyByb2xlOiBBdXRoUm9sZSwgcGVybWlzc2lvbjogQXV0aFBlcm1pc3Npb24gfT4oZmFsc2UpXG4gIEBPdXRwdXQoKSBmb2N1czogT2JzZXJ2YWJsZTxFdmVudD5cbiAgQE91dHB1dCgpIGJsdXI6IE9ic2VydmFibGU8RXZlbnQ+XG5cblxuICBzdWJtaXR0ZWQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgcHJpdmF0ZSBfY2hhbmdlZDogYm9vbGVhblxuICBwcml2YXRlIF9wcmV2aW91czogQXV0aFJvbGVcblxuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIGxldCBkaXN0aW5jdDogT2JzZXJ2YWJsZTxib29sZWFuPiA9IHRoaXMuX2ZvY3VzRGVib3VuY2VyLmFzT2JzZXJ2YWJsZSgpXG4gICAgZGlzdGluY3QgPSBkaXN0aW5jdC5waXBlKGRlYm91bmNlVGltZSgxMCksIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCkpXG5cbiAgICB0aGlzLmZvY3VzID0gZGlzdGluY3QucGlwZShcbiAgICAgIGZpbHRlcigoZm9jdXNlZCkgPT4gZm9jdXNlZCA9PT0gdHJ1ZSksXG4gICAgICBtYXAoKCkgPT4ge1xuICAgICAgICByZXR1cm4gbmV3IEV2ZW50KCdmb2N1cycpXG4gICAgICB9KSlcblxuICAgIHRoaXMuYmx1ciA9IGRpc3RpbmN0LnBpcGUoXG4gICAgICBmaWx0ZXIoKGZvY3VzZWQpID0+IGZvY3VzZWQgPT09IGZhbHNlKSxcbiAgICAgIG1hcCgoKSA9PiB7XG4gICAgICAgIHJldHVybiBuZXcgRXZlbnQoJ2JsdXInKVxuICAgICAgfSkpXG5cbiAgICB0aGlzLmNoYW5nZSA9IGRpc3RpbmN0LnBpcGUoXG4gICAgICBmaWx0ZXIoKGZvY3VzZWQpID0+IGZvY3VzZWQgPT09IGZhbHNlICYmIHRoaXMuX2NoYW5nZWQpLFxuICAgICAgbWFwKCgpID0+IHtcbiAgICAgICAgdGhpcy5jb2xsYXBzZWQgPSBmYWxzZVxuXG4gICAgICAgIGNvbnN0IGNoYW5nZSA9IHtcbiAgICAgICAgICBwcmV2aW91czogdGhpcy5fcHJldmlvdXMsXG4gICAgICAgICAgY3VycmVudDogIHRoaXMucm9sZVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3ByZXZpb3VzID0gQXV0aFJvbGUuZnJvbSh0aGlzLnJvbGUpXG4gICAgICAgIHRoaXMuX2NoYW5nZWQgPSBmYWxzZVxuICAgICAgICByZXR1cm4gY2hhbmdlXG4gICAgICB9KSlcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IHsgcm9sZTogU2ltcGxlQ2hhbmdlLCBwZXJtaXNzaW9uczogU2ltcGxlQ2hhbmdlIH0pIHtcbiAgICBpZiAoY2hhbmdlcy5yb2xlKSB7XG4gICAgICB0aGlzLl9wcmV2aW91cyA9IEF1dGhSb2xlLmZyb20odGhpcy5yb2xlKVxuICAgICAgdGhpcy5fY2hhbmdlZCA9IGZhbHNlXG4gICAgfVxuICB9XG5cbiAgZmlyZVJlbW92ZSgpIHtcbiAgICB0aGlzLnJlbW92ZS5lbWl0KHRoaXMucm9sZSlcbiAgfVxuXG4gIG9uQ2hhbmdlKCkge1xuICAgIHRoaXMuX2NoYW5nZWQgPSB0cnVlXG4gIH1cblxuICBvbkJsdXIoKSB7XG4gICAgdGhpcy5fZm9jdXNEZWJvdW5jZXIuZW1pdChmYWxzZSlcbiAgfVxuXG4gIG9uRm9jdXMoKSB7XG4gICAgdGhpcy5fZm9jdXNEZWJvdW5jZXIuZW1pdCh0cnVlKVxuXG4gIH1cblxuICBvblN1Ym1pdCgpIHtcbiAgICB0aGlzLnN1Ym1pdHRlZCA9IHRydWU7XG4gIH1cblxuICBoYXNQZXJtaXNzaW9uKHBlcm06IEF1dGhQZXJtaXNzaW9uKSB7XG4gICAgcmV0dXJuIHRoaXMucm9sZVBlcm1pc3Npb25zLnNvbWUocm9sZVBlcm0gPT4gcm9sZVBlcm0uJGtleSA9PT0gcGVybS4ka2V5KVxuICB9XG5cbiAgZG9Ub2dnbGVQZXJtaXNzaW9uKHBlcm1pc3Npb246IEF1dGhQZXJtaXNzaW9uKSB7XG4gICAgY29uc3Qgcm9sZVBlcm1pc3Npb246IHsgcm9sZTogQXV0aFJvbGUsIHBlcm1pc3Npb246IEF1dGhQZXJtaXNzaW9uIH0gPSB7XG4gICAgICBwZXJtaXNzaW9uOiBwZXJtaXNzaW9uLFxuICAgICAgcm9sZTogICAgICAgdGhpcy5yb2xlXG4gICAgfVxuICAgIGlmICh0aGlzLnJvbGVQZXJtaXNzaW9ucy5zb21lKGVudHJ5ID0+IGVudHJ5LiRrZXkgPT09IHBlcm1pc3Npb24uJGtleSkpIHtcbiAgICAgIHRoaXMucmVtb3ZlUm9sZVBlcm1pc3Npb24uZW1pdChyb2xlUGVybWlzc2lvbilcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5hZGRSb2xlUGVybWlzc2lvbi5lbWl0KHJvbGVQZXJtaXNzaW9uKVxuICAgIH1cbiAgfVxufVxuIiwiPGRpdiBjbGFzcz1cInRhbmotcm9sZS1mb3JtLXdyYXBwZXJcIiBmbGV4IGxheW91dD1cImNvbHVtblwiIGxheW91dC1hbGlnbj1cInN0YXJ0XCI+XG4gIDxmb3JtICpuZ0lmPVwicm9sZSAhPSBudWxsXCIgKG5nU3VibWl0KT1cIm9uU3VibWl0KCRldmVudClcIiAjdGhlRm9ybT1cIm5nRm9ybVwiIGZsZXggbGF5b3V0PVwicm93XCJcbiAgICAgICAgbGF5b3V0LWFsaWduPVwic3BhY2UtYmV0d2VlblwiPlxuXG4gICAgPGRpdiBjbGFzcz1cInRhbmotcm9sZS1pbnB1dHMtd3JhcHBlclwiIGxheW91dD1cInJvd1wiIGZsZXg9XCI4MFwiIGxheW91dC1hbGlnbj1cInNwYWNlLWJldHdlZW4gc3RhcnRcIj5cbiAgICAgIDxtYXQtZm9ybS1maWVsZCBmbGV4PVwiNDBcIj5cbiAgICAgICAgPGlucHV0IG1hdElucHV0IFsobmdNb2RlbCldPVwicm9sZS4ka2V5XCIgbmFtZT1cIm5hbWVcIiAjZk5hbWU9XCJuZ01vZGVsXCJcbiAgICAgICAgICAgICAgIGNsYXNzPVwidGFuai1pbnB1dFwiXG4gICAgICAgICAgICAgICBkaXZpZGVyQ29sb3I9XCJhY2NlbnRcIlxuICAgICAgICAgICAgICAgW3R5cGVdPVwiJ3RleHQnXCJcbiAgICAgICAgICAgICAgIHJlcXVpcmVkIG1pbmxlbmd0aD1cIjJcIlxuICAgICAgICAgICAgICAgdmFsdWU9XCJ7e3JvbGUuJGtleX19XCJcbiAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiTmFtZVwiXG4gICAgICAgICAgICAgICAoY2hhbmdlKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKTsgb25DaGFuZ2UoKVwiXG4gICAgICAgICAgICAgICAoZm9jdXMpPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOyBvbkZvY3VzKClcIlxuICAgICAgICAgICAgICAgKGJsdXIpPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOyBvbkJsdXIoKVwiXG4gICAgICAgIC8+PC9tYXQtZm9ybS1maWVsZD5cbiAgICAgIDxtYXQtZm9ybS1maWVsZCBmbGV4PVwiNjBcIj5cbiAgICAgICAgPGlucHV0IG1hdElucHV0IFsobmdNb2RlbCldPVwicm9sZS5kZXNjcmlwdGlvblwiIG5hbWU9XCJkZXNjcmlwdGlvblwiICNmRGVzY3JpcHRpb249XCJuZ01vZGVsXCJcbiAgICAgICAgICAgICAgIGNsYXNzPVwidGFuai1kZXNjcmlwdGlvbiB0YW5qLWlucHV0XCJcbiAgICAgICAgICAgICAgIGRpdmlkZXJDb2xvcj1cImFjY2VudFwiXG4gICAgICAgICAgICAgICBbdHlwZV09XCIndGV4dCdcIlxuICAgICAgICAgICAgICAgdmFsdWU9XCJ7e3JvbGUuZGVzY3JpcHRpb259fVwiXG4gICAgICAgICAgICAgICAoY2hhbmdlKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKTsgb25DaGFuZ2UoKVwiXG4gICAgICAgICAgICAgICAoZm9jdXMpPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOyBvbkZvY3VzKClcIlxuICAgICAgICAgICAgICAgKGJsdXIpPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOyBvbkJsdXIoKVwiXG4gICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIkRlc2NyaXB0aW9uXCIvPlxuICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwidGFuai1kZWxldGUtYnV0dG9uXCIgZmxleCBsYXlvdXQ9XCJyb3dcIiBsYXlvdXQtYWxpZ249XCJlbmQgY2VudGVyXCI+XG4gICAgICA8YnV0dG9uIG1hdC1taW5pLWZhYlxuICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgYXJpYS1sYWJlbD1cIkRlbGV0ZSBSb2xlXCJcbiAgICAgICAgICAgICAgKGZvY3VzKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKTsgb25Gb2N1cygpXCJcbiAgICAgICAgICAgICAgKGJsdXIpPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOyBvbkJsdXIoKVwiXG4gICAgICAgICAgICAgIChjbGljayk9XCJmaXJlUmVtb3ZlKClcIlxuICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiZmFsc2VcIj5cbiAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwibWF0LTI0XCI+ZGVsZXRlPC9tYXQtaWNvbj5cbiAgICAgIDwvYnV0dG9uPlxuICAgIDwvZGl2PlxuICA8L2Zvcm0+XG48L2Rpdj5cblxuXG5cbiJdfQ==