@nebular/auth
Version:
@nebular/auth
70 lines • 28.5 kB
JavaScript
/**
* @license
* Copyright Akveo. All Rights Reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*/
import { ChangeDetectionStrategy, Component, Inject } from '@angular/core';
import { NB_AUTH_OPTIONS } from '../../auth.options';
import { getDeepFromObject } from '../../helpers';
import * as i0 from "@angular/core";
import * as i1 from "../../services/auth.service";
import * as i2 from "@angular/router";
import * as i3 from "@angular/common";
import * as i4 from "@nebular/theme";
import * as i5 from "@angular/forms";
export class NbLoginComponent {
constructor(service, options = {}, cd, router) {
this.service = service;
this.options = options;
this.cd = cd;
this.router = router;
this.redirectDelay = 0;
this.showMessages = {};
this.strategy = '';
this.errors = [];
this.messages = [];
this.user = {};
this.submitted = false;
this.socialLinks = [];
this.rememberMe = false;
this.redirectDelay = this.getConfigValue('forms.login.redirectDelay');
this.showMessages = this.getConfigValue('forms.login.showMessages');
this.strategy = this.getConfigValue('forms.login.strategy');
this.socialLinks = this.getConfigValue('forms.login.socialLinks');
this.rememberMe = this.getConfigValue('forms.login.rememberMe');
}
login() {
this.errors = [];
this.messages = [];
this.submitted = true;
this.service.authenticate(this.strategy, this.user).subscribe((result) => {
this.submitted = false;
if (result.isSuccess()) {
this.messages = result.getMessages();
}
else {
this.errors = result.getErrors();
}
const redirect = result.getRedirect();
if (redirect) {
setTimeout(() => {
return this.router.navigateByUrl(redirect);
}, this.redirectDelay);
}
this.cd.detectChanges();
});
}
getConfigValue(key) {
return getDeepFromObject(this.options, key, null);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.3", ngImport: i0, type: NbLoginComponent, deps: [{ token: i1.NbAuthService }, { token: NB_AUTH_OPTIONS }, { token: i0.ChangeDetectorRef }, { token: i2.Router }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.1.3", type: NbLoginComponent, selector: "nb-login", ngImport: i0, template: "<h1 id=\"title\" class=\"title\">Login</h1>\n<p class=\"sub-title\">Hello! Log in with your email.</p>\n\n<nb-alert *ngIf=\"showMessages.error && errors?.length && !submitted\" outline=\"danger\" role=\"alert\">\n <p class=\"alert-title\"><b>Oh snap!</b></p>\n <ul class=\"alert-message-list\">\n <li *ngFor=\"let error of errors\" class=\"alert-message\">{{ error }}</li>\n </ul>\n</nb-alert>\n\n<nb-alert *ngIf=\"showMessages.success && messages?.length && !submitted\" outline=\"success\" role=\"alert\">\n <p class=\"alert-title\"><b>Hooray!</b></p>\n <ul class=\"alert-message-list\">\n <li *ngFor=\"let message of messages\" class=\"alert-message\">{{ message }}</li>\n </ul>\n</nb-alert>\n\n<form (ngSubmit)=\"login()\" #form=\"ngForm\" aria-labelledby=\"title\">\n\n <div class=\"form-control-group\">\n <label class=\"label\" for=\"input-email\">Email address:</label>\n <input nbInput\n fullWidth\n [(ngModel)]=\"user.email\"\n #email=\"ngModel\"\n name=\"email\"\n id=\"input-email\"\n pattern=\".+@.+\\..+\"\n placeholder=\"Email address\"\n fieldSize=\"large\"\n autofocus\n [status]=\"email.dirty ? (email.invalid ? 'danger' : 'success') : 'basic'\"\n [required]=\"getConfigValue('forms.validation.email.required')\"\n [attr.aria-invalid]=\"email.invalid && email.touched ? true : null\">\n <ng-container *ngIf=\"email.invalid && email.touched\">\n <p class=\"caption status-danger\" *ngIf=\"email.errors?.required\">\n Email is required!\n </p>\n <p class=\"caption status-danger\" *ngIf=\"email.errors?.pattern\">\n Email should be the real one!\n </p>\n </ng-container>\n </div>\n\n <div class=\"form-control-group\">\n <span class=\"label-with-link\">\n <label class=\"label\" for=\"input-password\">Password:</label>\n <a class=\"forgot-password caption-2\" routerLink=\"../request-password\">Forgot Password?</a>\n </span>\n <input nbInput\n fullWidth\n [(ngModel)]=\"user.password\"\n #password=\"ngModel\"\n name=\"password\"\n type=\"password\"\n id=\"input-password\"\n placeholder=\"Password\"\n fieldSize=\"large\"\n [status]=\"password.dirty ? (password.invalid ? 'danger' : 'success') : 'basic'\"\n [required]=\"getConfigValue('forms.validation.password.required')\"\n [minlength]=\"getConfigValue('forms.validation.password.minLength')\"\n [maxlength]=\"getConfigValue('forms.validation.password.maxLength')\"\n [attr.aria-invalid]=\"password.invalid && password.touched ? true : null\">\n <ng-container *ngIf=\"password.invalid && password.touched \">\n <p class=\"caption status-danger\" *ngIf=\"password.errors?.required\">\n Password is required!\n </p>\n <p class=\"caption status-danger\" *ngIf=\"password.errors?.minlength || password.errors?.maxlength\">\n Password should contain\n from {{ getConfigValue('forms.validation.password.minLength') }}\n to {{ getConfigValue('forms.validation.password.maxLength') }}\n characters\n </p>\n </ng-container>\n </div>\n\n <div class=\"form-control-group accept-group\">\n <nb-checkbox name=\"rememberMe\" [(ngModel)]=\"user.rememberMe\" *ngIf=\"rememberMe\">Remember me</nb-checkbox>\n </div>\n\n <button nbButton\n fullWidth\n status=\"primary\"\n size=\"large\"\n [disabled]=\"submitted || !form.valid\"\n [class.btn-pulse]=\"submitted\">\n Log In\n </button>\n</form>\n\n<section *ngIf=\"socialLinks && socialLinks.length > 0\" class=\"links\" aria-label=\"Social sign in\">\n or enter with:\n <div class=\"socials\">\n <ng-container *ngFor=\"let socialLink of socialLinks\">\n <a *ngIf=\"socialLink.link\"\n [routerLink]=\"socialLink.link\"\n [attr.target]=\"socialLink.target\"\n [attr.class]=\"socialLink.icon\"\n [class.with-icon]=\"socialLink.icon\">\n <nb-icon *ngIf=\"socialLink.icon; else title\" [icon]=\"socialLink.icon\"></nb-icon>\n <ng-template #title>{{ socialLink.title }}</ng-template>\n </a>\n <a *ngIf=\"socialLink.url\"\n [attr.href]=\"socialLink.url\"\n [attr.target]=\"socialLink.target\"\n [attr.class]=\"socialLink.icon\"\n [class.with-icon]=\"socialLink.icon\">\n <nb-icon *ngIf=\"socialLink.icon; else title\" [icon]=\"socialLink.icon\"></nb-icon>\n <ng-template #title>{{ socialLink.title }}</ng-template>\n </a>\n </ng-container>\n </div>\n</section>\n\n<section class=\"another-action\" aria-label=\"Register\">\n Don't have an account? <a class=\"text-link\" routerLink=\"../register\">Register</a>\n</section>\n", dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.NbCheckboxComponent, selector: "nb-checkbox", inputs: ["checked", "disabled", "status", "indeterminate"], outputs: ["checkedChange"] }, { kind: "component", type: i4.NbAlertComponent, selector: "nb-alert", inputs: ["size", "status", "accent", "outline", "closable"], outputs: ["close"] }, { kind: "directive", type: i4.NbInputDirective, selector: "input[nbInput],textarea[nbInput]", inputs: ["fieldSize", "status", "shape", "fullWidth"] }, { kind: "component", type: i4.NbButtonComponent, selector: "button[nbButton],a[nbButton],input[type=\"button\"][nbButton],input[type=\"submit\"][nbButton]", inputs: ["hero"] }, { kind: "directive", type: i2.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i5.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: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i5.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i5.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { kind: "directive", type: i5.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i5.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i5.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i4.NbIconComponent, selector: "nb-icon", inputs: ["icon", "pack", "options", "status", "config"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.3", ngImport: i0, type: NbLoginComponent, decorators: [{
type: Component,
args: [{ selector: 'nb-login', changeDetection: ChangeDetectionStrategy.OnPush, template: "<h1 id=\"title\" class=\"title\">Login</h1>\n<p class=\"sub-title\">Hello! Log in with your email.</p>\n\n<nb-alert *ngIf=\"showMessages.error && errors?.length && !submitted\" outline=\"danger\" role=\"alert\">\n <p class=\"alert-title\"><b>Oh snap!</b></p>\n <ul class=\"alert-message-list\">\n <li *ngFor=\"let error of errors\" class=\"alert-message\">{{ error }}</li>\n </ul>\n</nb-alert>\n\n<nb-alert *ngIf=\"showMessages.success && messages?.length && !submitted\" outline=\"success\" role=\"alert\">\n <p class=\"alert-title\"><b>Hooray!</b></p>\n <ul class=\"alert-message-list\">\n <li *ngFor=\"let message of messages\" class=\"alert-message\">{{ message }}</li>\n </ul>\n</nb-alert>\n\n<form (ngSubmit)=\"login()\" #form=\"ngForm\" aria-labelledby=\"title\">\n\n <div class=\"form-control-group\">\n <label class=\"label\" for=\"input-email\">Email address:</label>\n <input nbInput\n fullWidth\n [(ngModel)]=\"user.email\"\n #email=\"ngModel\"\n name=\"email\"\n id=\"input-email\"\n pattern=\".+@.+\\..+\"\n placeholder=\"Email address\"\n fieldSize=\"large\"\n autofocus\n [status]=\"email.dirty ? (email.invalid ? 'danger' : 'success') : 'basic'\"\n [required]=\"getConfigValue('forms.validation.email.required')\"\n [attr.aria-invalid]=\"email.invalid && email.touched ? true : null\">\n <ng-container *ngIf=\"email.invalid && email.touched\">\n <p class=\"caption status-danger\" *ngIf=\"email.errors?.required\">\n Email is required!\n </p>\n <p class=\"caption status-danger\" *ngIf=\"email.errors?.pattern\">\n Email should be the real one!\n </p>\n </ng-container>\n </div>\n\n <div class=\"form-control-group\">\n <span class=\"label-with-link\">\n <label class=\"label\" for=\"input-password\">Password:</label>\n <a class=\"forgot-password caption-2\" routerLink=\"../request-password\">Forgot Password?</a>\n </span>\n <input nbInput\n fullWidth\n [(ngModel)]=\"user.password\"\n #password=\"ngModel\"\n name=\"password\"\n type=\"password\"\n id=\"input-password\"\n placeholder=\"Password\"\n fieldSize=\"large\"\n [status]=\"password.dirty ? (password.invalid ? 'danger' : 'success') : 'basic'\"\n [required]=\"getConfigValue('forms.validation.password.required')\"\n [minlength]=\"getConfigValue('forms.validation.password.minLength')\"\n [maxlength]=\"getConfigValue('forms.validation.password.maxLength')\"\n [attr.aria-invalid]=\"password.invalid && password.touched ? true : null\">\n <ng-container *ngIf=\"password.invalid && password.touched \">\n <p class=\"caption status-danger\" *ngIf=\"password.errors?.required\">\n Password is required!\n </p>\n <p class=\"caption status-danger\" *ngIf=\"password.errors?.minlength || password.errors?.maxlength\">\n Password should contain\n from {{ getConfigValue('forms.validation.password.minLength') }}\n to {{ getConfigValue('forms.validation.password.maxLength') }}\n characters\n </p>\n </ng-container>\n </div>\n\n <div class=\"form-control-group accept-group\">\n <nb-checkbox name=\"rememberMe\" [(ngModel)]=\"user.rememberMe\" *ngIf=\"rememberMe\">Remember me</nb-checkbox>\n </div>\n\n <button nbButton\n fullWidth\n status=\"primary\"\n size=\"large\"\n [disabled]=\"submitted || !form.valid\"\n [class.btn-pulse]=\"submitted\">\n Log In\n </button>\n</form>\n\n<section *ngIf=\"socialLinks && socialLinks.length > 0\" class=\"links\" aria-label=\"Social sign in\">\n or enter with:\n <div class=\"socials\">\n <ng-container *ngFor=\"let socialLink of socialLinks\">\n <a *ngIf=\"socialLink.link\"\n [routerLink]=\"socialLink.link\"\n [attr.target]=\"socialLink.target\"\n [attr.class]=\"socialLink.icon\"\n [class.with-icon]=\"socialLink.icon\">\n <nb-icon *ngIf=\"socialLink.icon; else title\" [icon]=\"socialLink.icon\"></nb-icon>\n <ng-template #title>{{ socialLink.title }}</ng-template>\n </a>\n <a *ngIf=\"socialLink.url\"\n [attr.href]=\"socialLink.url\"\n [attr.target]=\"socialLink.target\"\n [attr.class]=\"socialLink.icon\"\n [class.with-icon]=\"socialLink.icon\">\n <nb-icon *ngIf=\"socialLink.icon; else title\" [icon]=\"socialLink.icon\"></nb-icon>\n <ng-template #title>{{ socialLink.title }}</ng-template>\n </a>\n </ng-container>\n </div>\n</section>\n\n<section class=\"another-action\" aria-label=\"Register\">\n Don't have an account? <a class=\"text-link\" routerLink=\"../register\">Register</a>\n</section>\n" }]
}], ctorParameters: () => [{ type: i1.NbAuthService }, { type: undefined, decorators: [{
type: Inject,
args: [NB_AUTH_OPTIONS]
}] }, { type: i0.ChangeDetectorRef }, { type: i2.Router }] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9naW4uY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2ZyYW1ld29yay9hdXRoL2NvbXBvbmVudHMvbG9naW4vbG9naW4uY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vc3JjL2ZyYW1ld29yay9hdXRoL2NvbXBvbmVudHMvbG9naW4vbG9naW4uY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7R0FJRztBQUNILE9BQU8sRUFBRSx1QkFBdUIsRUFBcUIsU0FBUyxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUU5RixPQUFPLEVBQUUsZUFBZSxFQUFvQixNQUFNLG9CQUFvQixDQUFDO0FBQ3ZFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGVBQWUsQ0FBQzs7Ozs7OztBQVVsRCxNQUFNLE9BQU8sZ0JBQWdCO0lBYTNCLFlBQXNCLE9BQXNCLEVBQ0csVUFBVSxFQUFFLEVBQ3JDLEVBQXFCLEVBQ3JCLE1BQWM7UUFIZCxZQUFPLEdBQVAsT0FBTyxDQUFlO1FBQ0csWUFBTyxHQUFQLE9BQU8sQ0FBSztRQUNyQyxPQUFFLEdBQUYsRUFBRSxDQUFtQjtRQUNyQixXQUFNLEdBQU4sTUFBTSxDQUFRO1FBZHBDLGtCQUFhLEdBQVcsQ0FBQyxDQUFDO1FBQzFCLGlCQUFZLEdBQVEsRUFBRSxDQUFDO1FBQ3ZCLGFBQVEsR0FBVyxFQUFFLENBQUM7UUFFdEIsV0FBTSxHQUFhLEVBQUUsQ0FBQztRQUN0QixhQUFRLEdBQWEsRUFBRSxDQUFDO1FBQ3hCLFNBQUksR0FBUSxFQUFFLENBQUM7UUFDZixjQUFTLEdBQVksS0FBSyxDQUFDO1FBQzNCLGdCQUFXLEdBQXVCLEVBQUUsQ0FBQztRQUNyQyxlQUFVLEdBQUcsS0FBSyxDQUFDO1FBT2pCLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQywyQkFBMkIsQ0FBQyxDQUFDO1FBQ3RFLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO1FBQ3BFLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1FBQzVELElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO1FBQ2xFLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO0lBQ2xFLENBQUM7SUFFRCxLQUFLO1FBQ0gsSUFBSSxDQUFDLE1BQU0sR0FBRyxFQUFFLENBQUM7UUFDakIsSUFBSSxDQUFDLFFBQVEsR0FBRyxFQUFFLENBQUM7UUFDbkIsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7UUFFdEIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsTUFBb0IsRUFBRSxFQUFFO1lBQ3JGLElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDO1lBRXZCLElBQUksTUFBTSxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQUM7Z0JBQ3ZCLElBQUksQ0FBQyxRQUFRLEdBQUcsTUFBTSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ3ZDLENBQUM7aUJBQU0sQ0FBQztnQkFDTixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNuQyxDQUFDO1lBRUQsTUFBTSxRQUFRLEdBQUcsTUFBTSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ3RDLElBQUksUUFBUSxFQUFFLENBQUM7Z0JBQ2IsVUFBVSxDQUFDLEdBQUcsRUFBRTtvQkFDZCxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUM3QyxDQUFDLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBQ3pCLENBQUM7WUFDRCxJQUFJLENBQUMsRUFBRSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQzFCLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELGNBQWMsQ0FBQyxHQUFXO1FBQ3hCLE9BQU8saUJBQWlCLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDcEQsQ0FBQzs4R0FuRFUsZ0JBQWdCLCtDQWNQLGVBQWU7a0dBZHhCLGdCQUFnQixnRENsQjdCLGd5SkFxSEE7OzJGRG5HYSxnQkFBZ0I7a0JBTDVCLFNBQVM7K0JBQ0UsVUFBVSxtQkFFSCx1QkFBdUIsQ0FBQyxNQUFNOzswQkFnQmxDLE1BQU07MkJBQUMsZUFBZSIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBBa3Zlby4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS4gU2VlIExpY2Vuc2UudHh0IGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXG4gKi9cbmltcG9ydCB7IENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDaGFuZ2VEZXRlY3RvclJlZiwgQ29tcG9uZW50LCBJbmplY3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFJvdXRlciB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBOQl9BVVRIX09QVElPTlMsIE5iQXV0aFNvY2lhbExpbmsgfSBmcm9tICcuLi8uLi9hdXRoLm9wdGlvbnMnO1xuaW1wb3J0IHsgZ2V0RGVlcEZyb21PYmplY3QgfSBmcm9tICcuLi8uLi9oZWxwZXJzJztcblxuaW1wb3J0IHsgTmJBdXRoU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL2F1dGguc2VydmljZSc7XG5pbXBvcnQgeyBOYkF1dGhSZXN1bHQgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9hdXRoLXJlc3VsdCc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ25iLWxvZ2luJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2xvZ2luLmNvbXBvbmVudC5odG1sJyxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG59KVxuZXhwb3J0IGNsYXNzIE5iTG9naW5Db21wb25lbnQge1xuXG4gIHJlZGlyZWN0RGVsYXk6IG51bWJlciA9IDA7XG4gIHNob3dNZXNzYWdlczogYW55ID0ge307XG4gIHN0cmF0ZWd5OiBzdHJpbmcgPSAnJztcblxuICBlcnJvcnM6IHN0cmluZ1tdID0gW107XG4gIG1lc3NhZ2VzOiBzdHJpbmdbXSA9IFtdO1xuICB1c2VyOiBhbnkgPSB7fTtcbiAgc3VibWl0dGVkOiBib29sZWFuID0gZmFsc2U7XG4gIHNvY2lhbExpbmtzOiBOYkF1dGhTb2NpYWxMaW5rW10gPSBbXTtcbiAgcmVtZW1iZXJNZSA9IGZhbHNlO1xuXG4gIGNvbnN0cnVjdG9yKHByb3RlY3RlZCBzZXJ2aWNlOiBOYkF1dGhTZXJ2aWNlLFxuICAgICAgICAgICAgICBASW5qZWN0KE5CX0FVVEhfT1BUSU9OUykgcHJvdGVjdGVkIG9wdGlvbnMgPSB7fSxcbiAgICAgICAgICAgICAgcHJvdGVjdGVkIGNkOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICAgICAgICAgICAgcHJvdGVjdGVkIHJvdXRlcjogUm91dGVyKSB7XG5cbiAgICB0aGlzLnJlZGlyZWN0RGVsYXkgPSB0aGlzLmdldENvbmZpZ1ZhbHVlKCdmb3Jtcy5sb2dpbi5yZWRpcmVjdERlbGF5Jyk7XG4gICAgdGhpcy5zaG93TWVzc2FnZXMgPSB0aGlzLmdldENvbmZpZ1ZhbHVlKCdmb3Jtcy5sb2dpbi5zaG93TWVzc2FnZXMnKTtcbiAgICB0aGlzLnN0cmF0ZWd5ID0gdGhpcy5nZXRDb25maWdWYWx1ZSgnZm9ybXMubG9naW4uc3RyYXRlZ3knKTtcbiAgICB0aGlzLnNvY2lhbExpbmtzID0gdGhpcy5nZXRDb25maWdWYWx1ZSgnZm9ybXMubG9naW4uc29jaWFsTGlua3MnKTtcbiAgICB0aGlzLnJlbWVtYmVyTWUgPSB0aGlzLmdldENvbmZpZ1ZhbHVlKCdmb3Jtcy5sb2dpbi5yZW1lbWJlck1lJyk7XG4gIH1cblxuICBsb2dpbigpOiB2b2lkIHtcbiAgICB0aGlzLmVycm9ycyA9IFtdO1xuICAgIHRoaXMubWVzc2FnZXMgPSBbXTtcbiAgICB0aGlzLnN1Ym1pdHRlZCA9IHRydWU7XG5cbiAgICB0aGlzLnNlcnZpY2UuYXV0aGVudGljYXRlKHRoaXMuc3RyYXRlZ3ksIHRoaXMudXNlcikuc3Vic2NyaWJlKChyZXN1bHQ6IE5iQXV0aFJlc3VsdCkgPT4ge1xuICAgICAgdGhpcy5zdWJtaXR0ZWQgPSBmYWxzZTtcblxuICAgICAgaWYgKHJlc3VsdC5pc1N1Y2Nlc3MoKSkge1xuICAgICAgICB0aGlzLm1lc3NhZ2VzID0gcmVzdWx0LmdldE1lc3NhZ2VzKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmVycm9ycyA9IHJlc3VsdC5nZXRFcnJvcnMoKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVkaXJlY3QgPSByZXN1bHQuZ2V0UmVkaXJlY3QoKTtcbiAgICAgIGlmIChyZWRpcmVjdCkge1xuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5yb3V0ZXIubmF2aWdhdGVCeVVybChyZWRpcmVjdCk7XG4gICAgICAgIH0sIHRoaXMucmVkaXJlY3REZWxheSk7XG4gICAgICB9XG4gICAgICB0aGlzLmNkLmRldGVjdENoYW5nZXMoKTtcbiAgICB9KTtcbiAgfVxuXG4gIGdldENvbmZpZ1ZhbHVlKGtleTogc3RyaW5nKTogYW55IHtcbiAgICByZXR1cm4gZ2V0RGVlcEZyb21PYmplY3QodGhpcy5vcHRpb25zLCBrZXksIG51bGwpO1xuICB9XG59XG4iLCI8aDEgaWQ9XCJ0aXRsZVwiIGNsYXNzPVwidGl0bGVcIj5Mb2dpbjwvaDE+XG48cCBjbGFzcz1cInN1Yi10aXRsZVwiPkhlbGxvISBMb2cgaW4gd2l0aCB5b3VyIGVtYWlsLjwvcD5cblxuPG5iLWFsZXJ0ICpuZ0lmPVwic2hvd01lc3NhZ2VzLmVycm9yICYmIGVycm9ycz8ubGVuZ3RoICYmICFzdWJtaXR0ZWRcIiBvdXRsaW5lPVwiZGFuZ2VyXCIgcm9sZT1cImFsZXJ0XCI+XG4gIDxwIGNsYXNzPVwiYWxlcnQtdGl0bGVcIj48Yj5PaCBzbmFwITwvYj48L3A+XG4gIDx1bCBjbGFzcz1cImFsZXJ0LW1lc3NhZ2UtbGlzdFwiPlxuICAgIDxsaSAqbmdGb3I9XCJsZXQgZXJyb3Igb2YgZXJyb3JzXCIgY2xhc3M9XCJhbGVydC1tZXNzYWdlXCI+e3sgZXJyb3IgfX08L2xpPlxuICA8L3VsPlxuPC9uYi1hbGVydD5cblxuPG5iLWFsZXJ0ICpuZ0lmPVwic2hvd01lc3NhZ2VzLnN1Y2Nlc3MgJiYgbWVzc2FnZXM/Lmxlbmd0aCAmJiAhc3VibWl0dGVkXCIgb3V0bGluZT1cInN1Y2Nlc3NcIiByb2xlPVwiYWxlcnRcIj5cbiAgPHAgY2xhc3M9XCJhbGVydC10aXRsZVwiPjxiPkhvb3JheSE8L2I+PC9wPlxuICA8dWwgY2xhc3M9XCJhbGVydC1tZXNzYWdlLWxpc3RcIj5cbiAgICA8bGkgKm5nRm9yPVwibGV0IG1lc3NhZ2Ugb2YgbWVzc2FnZXNcIiBjbGFzcz1cImFsZXJ0LW1lc3NhZ2VcIj57eyBtZXNzYWdlIH19PC9saT5cbiAgPC91bD5cbjwvbmItYWxlcnQ+XG5cbjxmb3JtIChuZ1N1Ym1pdCk9XCJsb2dpbigpXCIgI2Zvcm09XCJuZ0Zvcm1cIiBhcmlhLWxhYmVsbGVkYnk9XCJ0aXRsZVwiPlxuXG4gIDxkaXYgY2xhc3M9XCJmb3JtLWNvbnRyb2wtZ3JvdXBcIj5cbiAgICA8bGFiZWwgY2xhc3M9XCJsYWJlbFwiIGZvcj1cImlucHV0LWVtYWlsXCI+RW1haWwgYWRkcmVzczo8L2xhYmVsPlxuICAgIDxpbnB1dCBuYklucHV0XG4gICAgICAgICAgIGZ1bGxXaWR0aFxuICAgICAgICAgICBbKG5nTW9kZWwpXT1cInVzZXIuZW1haWxcIlxuICAgICAgICAgICAjZW1haWw9XCJuZ01vZGVsXCJcbiAgICAgICAgICAgbmFtZT1cImVtYWlsXCJcbiAgICAgICAgICAgaWQ9XCJpbnB1dC1lbWFpbFwiXG4gICAgICAgICAgIHBhdHRlcm49XCIuK0AuK1xcLi4rXCJcbiAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJFbWFpbCBhZGRyZXNzXCJcbiAgICAgICAgICAgZmllbGRTaXplPVwibGFyZ2VcIlxuICAgICAgICAgICBhdXRvZm9jdXNcbiAgICAgICAgICAgW3N0YXR1c109XCJlbWFpbC5kaXJ0eSA/IChlbWFpbC5pbnZhbGlkICA/ICdkYW5nZXInIDogJ3N1Y2Nlc3MnKSA6ICdiYXNpYydcIlxuICAgICAgICAgICBbcmVxdWlyZWRdPVwiZ2V0Q29uZmlnVmFsdWUoJ2Zvcm1zLnZhbGlkYXRpb24uZW1haWwucmVxdWlyZWQnKVwiXG4gICAgICAgICAgIFthdHRyLmFyaWEtaW52YWxpZF09XCJlbWFpbC5pbnZhbGlkICYmIGVtYWlsLnRvdWNoZWQgPyB0cnVlIDogbnVsbFwiPlxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJlbWFpbC5pbnZhbGlkICYmIGVtYWlsLnRvdWNoZWRcIj5cbiAgICAgIDxwIGNsYXNzPVwiY2FwdGlvbiBzdGF0dXMtZGFuZ2VyXCIgKm5nSWY9XCJlbWFpbC5lcnJvcnM/LnJlcXVpcmVkXCI+XG4gICAgICAgIEVtYWlsIGlzIHJlcXVpcmVkIVxuICAgICAgPC9wPlxuICAgICAgPHAgY2xhc3M9XCJjYXB0aW9uIHN0YXR1cy1kYW5nZXJcIiAqbmdJZj1cImVtYWlsLmVycm9ycz8ucGF0dGVyblwiPlxuICAgICAgICBFbWFpbCBzaG91bGQgYmUgdGhlIHJlYWwgb25lIVxuICAgICAgPC9wPlxuICAgIDwvbmctY29udGFpbmVyPlxuICA8L2Rpdj5cblxuICA8ZGl2IGNsYXNzPVwiZm9ybS1jb250cm9sLWdyb3VwXCI+XG4gICAgPHNwYW4gY2xhc3M9XCJsYWJlbC13aXRoLWxpbmtcIj5cbiAgICAgIDxsYWJlbCBjbGFzcz1cImxhYmVsXCIgZm9yPVwiaW5wdXQtcGFzc3dvcmRcIj5QYXNzd29yZDo8L2xhYmVsPlxuICAgICAgPGEgY2xhc3M9XCJmb3Jnb3QtcGFzc3dvcmQgY2FwdGlvbi0yXCIgcm91dGVyTGluaz1cIi4uL3JlcXVlc3QtcGFzc3dvcmRcIj5Gb3Jnb3QgUGFzc3dvcmQ/PC9hPlxuICAgIDwvc3Bhbj5cbiAgICA8aW5wdXQgbmJJbnB1dFxuICAgICAgICAgICBmdWxsV2lkdGhcbiAgICAgICAgICAgWyhuZ01vZGVsKV09XCJ1c2VyLnBhc3N3b3JkXCJcbiAgICAgICAgICAgI3Bhc3N3b3JkPVwibmdNb2RlbFwiXG4gICAgICAgICAgIG5hbWU9XCJwYXNzd29yZFwiXG4gICAgICAgICAgIHR5cGU9XCJwYXNzd29yZFwiXG4gICAgICAgICAgIGlkPVwiaW5wdXQtcGFzc3dvcmRcIlxuICAgICAgICAgICBwbGFjZWhvbGRlcj1cIlBhc3N3b3JkXCJcbiAgICAgICAgICAgZmllbGRTaXplPVwibGFyZ2VcIlxuICAgICAgICAgICBbc3RhdHVzXT1cInBhc3N3b3JkLmRpcnR5ID8gKHBhc3N3b3JkLmludmFsaWQgID8gJ2RhbmdlcicgOiAnc3VjY2VzcycpIDogJ2Jhc2ljJ1wiXG4gICAgICAgICAgIFtyZXF1aXJlZF09XCJnZXRDb25maWdWYWx1ZSgnZm9ybXMudmFsaWRhdGlvbi5wYXNzd29yZC5yZXF1aXJlZCcpXCJcbiAgICAgICAgICAgW21pbmxlbmd0aF09XCJnZXRDb25maWdWYWx1ZSgnZm9ybXMudmFsaWRhdGlvbi5wYXNzd29yZC5taW5MZW5ndGgnKVwiXG4gICAgICAgICAgIFttYXhsZW5ndGhdPVwiZ2V0Q29uZmlnVmFsdWUoJ2Zvcm1zLnZhbGlkYXRpb24ucGFzc3dvcmQubWF4TGVuZ3RoJylcIlxuICAgICAgICAgICBbYXR0ci5hcmlhLWludmFsaWRdPVwicGFzc3dvcmQuaW52YWxpZCAmJiBwYXNzd29yZC50b3VjaGVkID8gdHJ1ZSA6IG51bGxcIj5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwicGFzc3dvcmQuaW52YWxpZCAmJiBwYXNzd29yZC50b3VjaGVkIFwiPlxuICAgICAgPHAgY2xhc3M9XCJjYXB0aW9uIHN0YXR1cy1kYW5nZXJcIiAqbmdJZj1cInBhc3N3b3JkLmVycm9ycz8ucmVxdWlyZWRcIj5cbiAgICAgICAgUGFzc3dvcmQgaXMgcmVxdWlyZWQhXG4gICAgICA8L3A+XG4gICAgICA8cCBjbGFzcz1cImNhcHRpb24gc3RhdHVzLWRhbmdlclwiICpuZ0lmPVwicGFzc3dvcmQuZXJyb3JzPy5taW5sZW5ndGggfHwgcGFzc3dvcmQuZXJyb3JzPy5tYXhsZW5ndGhcIj5cbiAgICAgICAgUGFzc3dvcmQgc2hvdWxkIGNvbnRhaW5cbiAgICAgICAgZnJvbSB7eyBnZXRDb25maWdWYWx1ZSgnZm9ybXMudmFsaWRhdGlvbi5wYXNzd29yZC5taW5MZW5ndGgnKSB9fVxuICAgICAgICB0byB7eyBnZXRDb25maWdWYWx1ZSgnZm9ybXMudmFsaWRhdGlvbi5wYXNzd29yZC5tYXhMZW5ndGgnKSB9fVxuICAgICAgICBjaGFyYWN0ZXJzXG4gICAgICA8L3A+XG4gICAgPC9uZy1jb250YWluZXI+XG4gIDwvZGl2PlxuXG4gIDxkaXYgY2xhc3M9XCJmb3JtLWNvbnRyb2wtZ3JvdXAgYWNjZXB0LWdyb3VwXCI+XG4gICAgPG5iLWNoZWNrYm94IG5hbWU9XCJyZW1lbWJlck1lXCIgWyhuZ01vZGVsKV09XCJ1c2VyLnJlbWVtYmVyTWVcIiAqbmdJZj1cInJlbWVtYmVyTWVcIj5SZW1lbWJlciBtZTwvbmItY2hlY2tib3g+XG4gIDwvZGl2PlxuXG4gIDxidXR0b24gbmJCdXR0b25cbiAgICAgICAgICBmdWxsV2lkdGhcbiAgICAgICAgICBzdGF0dXM9XCJwcmltYXJ5XCJcbiAgICAgICAgICBzaXplPVwibGFyZ2VcIlxuICAgICAgICAgIFtkaXNhYmxlZF09XCJzdWJtaXR0ZWQgfHwgIWZvcm0udmFsaWRcIlxuICAgICAgICAgIFtjbGFzcy5idG4tcHVsc2VdPVwic3VibWl0dGVkXCI+XG4gICAgTG9nIEluXG4gIDwvYnV0dG9uPlxuPC9mb3JtPlxuXG48c2VjdGlvbiAqbmdJZj1cInNvY2lhbExpbmtzICYmIHNvY2lhbExpbmtzLmxlbmd0aCA+IDBcIiBjbGFzcz1cImxpbmtzXCIgYXJpYS1sYWJlbD1cIlNvY2lhbCBzaWduIGluXCI+XG4gIG9yIGVudGVyIHdpdGg6XG4gIDxkaXYgY2xhc3M9XCJzb2NpYWxzXCI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgc29jaWFsTGluayBvZiBzb2NpYWxMaW5rc1wiPlxuICAgICAgPGEgKm5nSWY9XCJzb2NpYWxMaW5rLmxpbmtcIlxuICAgICAgICAgW3JvdXRlckxpbmtdPVwic29jaWFsTGluay5saW5rXCJcbiAgICAgICAgIFthdHRyLnRhcmdldF09XCJzb2NpYWxMaW5rLnRhcmdldFwiXG4gICAgICAgICBbYXR0ci5jbGFzc109XCJzb2NpYWxMaW5rLmljb25cIlxuICAgICAgICAgW2NsYXNzLndpdGgtaWNvbl09XCJzb2NpYWxMaW5rLmljb25cIj5cbiAgICAgICAgPG5iLWljb24gKm5nSWY9XCJzb2NpYWxMaW5rLmljb247IGVsc2UgdGl0bGVcIiBbaWNvbl09XCJzb2NpYWxMaW5rLmljb25cIj48L25iLWljb24+XG4gICAgICAgIDxuZy10ZW1wbGF0ZSAjdGl0bGU+e3sgc29jaWFsTGluay50aXRsZSB9fTwvbmctdGVtcGxhdGU+XG4gICAgICA8L2E+XG4gICAgICA8YSAqbmdJZj1cInNvY2lhbExpbmsudXJsXCJcbiAgICAgICAgIFthdHRyLmhyZWZdPVwic29jaWFsTGluay51cmxcIlxuICAgICAgICAgW2F0dHIudGFyZ2V0XT1cInNvY2lhbExpbmsudGFyZ2V0XCJcbiAgICAgICAgIFthdHRyLmNsYXNzXT1cInNvY2lhbExpbmsuaWNvblwiXG4gICAgICAgICBbY2xhc3Mud2l0aC1pY29uXT1cInNvY2lhbExpbmsuaWNvblwiPlxuICAgICAgICA8bmItaWNvbiAqbmdJZj1cInNvY2lhbExpbmsuaWNvbjsgZWxzZSB0aXRsZVwiIFtpY29uXT1cInNvY2lhbExpbmsuaWNvblwiPjwvbmItaWNvbj5cbiAgICAgICAgPG5nLXRlbXBsYXRlICN0aXRsZT57eyBzb2NpYWxMaW5rLnRpdGxlIH19PC9uZy10ZW1wbGF0ZT5cbiAgICAgIDwvYT5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgPC9kaXY+XG48L3NlY3Rpb24+XG5cbjxzZWN0aW9uIGNsYXNzPVwiYW5vdGhlci1hY3Rpb25cIiBhcmlhLWxhYmVsPVwiUmVnaXN0ZXJcIj5cbiAgRG9uJ3QgaGF2ZSBhbiBhY2NvdW50PyA8YSBjbGFzcz1cInRleHQtbGlua1wiIHJvdXRlckxpbms9XCIuLi9yZWdpc3RlclwiPlJlZ2lzdGVyPC9hPlxuPC9zZWN0aW9uPlxuIl19