@nowzoo/ngx-firebase-auth
Version:
Angular components for Firebase email-first sign in and out-of-band (oob) actions (reset password, etc).
265 lines (263 loc) • 23.7 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
import { Component, Input, Output, EventEmitter, ViewChild, ElementRef } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { AngularFireAuth } from 'angularfire2/auth';
import { fadeInOutAnimation } from '../../shared';
import { NgxFirebaseAuthFormHelper } from '../../form-helper';
import { NgxFirebaseAuthService } from '../../ngx-firebase-auth.service';
export class SignUpFormComponent {
/**
* @param {?} _afAuth
* @param {?} _authService
*/
constructor(_afAuth, _authService) {
this._afAuth = _afAuth;
this._authService = _authService;
this.rememberChange = new EventEmitter();
this.success = new EventEmitter();
this.error = new EventEmitter();
this.formId = 'ngx-firebase-auth-sign-up-form-';
this.submitting = false;
}
/**
* @return {?}
*/
get auth() {
return this._afAuth.auth;
}
/**
* @return {?}
*/
get authService() {
return this._authService;
}
/**
* @return {?}
*/
ngOnInit() {
this.emailFc = new FormControl(this.email, { validators: [Validators.required, Validators.email] });
this.passwordFc = new FormControl('', { validators: [Validators.required] });
this.nameFc = new FormControl('', { validators: [Validators.required, NgxFirebaseAuthFormHelper.requiredNonEmpty] });
this.rememberFc = new FormControl(this.remember);
this.rememberFc.valueChanges.subscribe(val => this.rememberChange.emit(val));
this.fg = new FormGroup({
email: this.emailFc,
password: this.passwordFc,
name: this.nameFc,
remember: this.rememberFc
});
}
/**
* @return {?}
*/
ngAfterViewInit() {
this.passwordInput.nativeElement.focus();
}
/**
* @return {?}
*/
submit() {
this.submitting = true;
/** @type {?} */
let cred;
this.auth.fetchSignInMethodsForEmail(this.email)
.then((results) => {
if (results.length > 0) {
return Promise.reject({
code: 'ngx-firebase-auth/account-exists'
});
}
return this.auth.createUserWithEmailAndPassword(this.email, this.passwordFc.value);
})
.then(result => {
cred = result;
return cred.user.updateProfile({ displayName: this.nameFc.value.trim(), photoURL: null });
})
.then(() => {
return this.authService.setRemembered(this.rememberFc.value === true, this.email);
})
.then(() => {
this.success.emit(cred);
})
.catch(error => {
this.submitting = false;
this.emailFc.markAsDirty();
this.emailFc.markAsTouched();
this.passwordFc.markAsDirty();
this.passwordFc.markAsTouched();
switch (error.code) {
case 'auth/invalid-email':
case 'ngx-firebase-auth/account-exists':
NgxFirebaseAuthFormHelper.setErrorUntilChanged(this.emailFc, error.code);
break;
case 'auth/weak-password':
NgxFirebaseAuthFormHelper.setErrorUntilChanged(this.passwordFc, error.code);
break;
default:
this.error.emit(error);
break;
}
});
}
}
SignUpFormComponent.decorators = [
{ type: Component, args: [{
selector: 'ngx-firebase-auth-sign-up-form',
template: `<form [formGroup]="fg" (ngSubmit)="submit()">
<div class="form-group">
<label [attr.for]="formId + 'email'">Email Address</label>
<input
readonly
#emailInput
[attr.id]="formId + 'email'"
[attr.aria-describedby]="formId + 'email'"
type="email"
autocomplete="email"
placeholder="Email Address"
formControlName="email"
class="form-control">
<div class="invalid-feedback" []="'in'"
*ngIf="emailFc.hasError('required')">
Required.
</div>
<div class="invalid-feedback" []="'in'"
*ngIf="emailFc.hasError('email')">
Invalid email.
</div>
<div class="invalid-feedback" []="'in'"
*ngIf="emailFc.hasError('auth/invalid-email')">
Invalid email.
</div>
<div class="invalid-feedback" []="'in'"
*ngIf="emailFc.hasError('ngx-firebase-auth/account-exists')">
We found an account with that email address.
<a routerLink="." [queryParams]="{action: 'signIn'}">Sign In</a>
</div>
<small class="text-muted form-text" [attr.id]="formId + 'email'" >
Not your email address?
<a routerLink="." [queryParams]="{action: 'signIn'}">Go Back</a>
</small>
</div>
<div class="form-group">
<div class="d-flex justify-content-between align-items-end">
<label [attr.for]="formId + 'password'">Choose Password</label>
<small>
<a (click)="$event.preventDefault(); passwordInput.type = 'password' === passwordInput.type ? 'text' : 'password'"
href="#" tabindex="-1" class="d-inline-block">
<span *ngIf="'password' === passwordInput.type">Show</span>
<span *ngIf="'text' === passwordInput.type">Hide</span>
</a>
</small>
</div>
<input
#passwordInput
[attr.id]="formId + 'password'"
[attr.aria-describedby]="formId + 'password-help'"
type="password"
formControlName="password"
placeholder="Choose Password"
autocomplete="password"
class="form-control"
[class.is-invalid]="passwordFc.touched && passwordFc.invalid">
<div class="invalid-feedback" []="'in'"
*ngIf="passwordFc.touched && passwordFc.hasError('required')">
Required.
</div>
<div class="invalid-feedback" []="'in'"
*ngIf="passwordFc.touched && passwordFc.hasError('auth/wrong-password')">
Wrong password.
</div>
<small [attr.id]="formId + 'password-help'" class="form-text text-muted">
Please choose a strong password.
</small>
</div>
<div class="form-group">
<label [attr.for]="formId + 'name'">Your Name</label>
<input
[attr.id]="formId + 'name'"
type="text"
formControlName="name"
placeholder="Your Name"
class="form-control"
[class.is-invalid]="nameFc.touched && nameFc.invalid">
<div class="invalid-feedback" []="'in'"
*ngIf="nameFc.touched && nameFc.hasError('required')">
Required.
</div>
</div>
<div class="form-group">
<div class="form-check">
<input
class="form-check-input"
type="checkbox"
[value]="true"
formControlName="remember"
[attr.id]="formId + 'remember'">
<label class="form-check-label" [attr.for]="formId + 'remember'">
Remember me on this device.
</label>
</div>
</div>
<div class="form-group">
<button type="submit"
class="btn btn-success btn-block"
[disabled]="fg.invalid || submitting">
<i class="fas fa-lock fa-fw" aria-hidden="true"></i>
Create Account
</button>
</div>
</form>
`,
styles: [``],
animations: [fadeInOutAnimation]
},] },
];
/** @nocollapse */
SignUpFormComponent.ctorParameters = () => [
{ type: AngularFireAuth },
{ type: NgxFirebaseAuthService }
];
SignUpFormComponent.propDecorators = {
passwordInput: [{ type: ViewChild, args: ['passwordInput',] }],
email: [{ type: Input }],
remember: [{ type: Input }],
rememberChange: [{ type: Output }],
success: [{ type: Output }],
error: [{ type: Output }]
};
if (false) {
/** @type {?} */
SignUpFormComponent.prototype.passwordInput;
/** @type {?} */
SignUpFormComponent.prototype.email;
/** @type {?} */
SignUpFormComponent.prototype.remember;
/** @type {?} */
SignUpFormComponent.prototype.rememberChange;
/** @type {?} */
SignUpFormComponent.prototype.success;
/** @type {?} */
SignUpFormComponent.prototype.error;
/** @type {?} */
SignUpFormComponent.prototype.formId;
/** @type {?} */
SignUpFormComponent.prototype.submitting;
/** @type {?} */
SignUpFormComponent.prototype.fg;
/** @type {?} */
SignUpFormComponent.prototype.emailFc;
/** @type {?} */
SignUpFormComponent.prototype.passwordFc;
/** @type {?} */
SignUpFormComponent.prototype.nameFc;
/** @type {?} */
SignUpFormComponent.prototype.rememberFc;
/** @type {?} */
SignUpFormComponent.prototype._afAuth;
/** @type {?} */
SignUpFormComponent.prototype._authService;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnbi11cC1mb3JtLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0Bub3d6b28vbmd4LWZpcmViYXNlLWF1dGgvIiwic291cmNlcyI6WyJsaWIvc2lnbi1pbi9zaWduLXVwLWZvcm0vc2lnbi11cC1mb3JtLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUFFLFNBQVMsRUFBeUIsS0FBSyxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNySCxPQUFPLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNwRSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFHcEQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ2xELE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQzlELE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBZ0h6RSxNQUFNOzs7OztJQWdCSixZQUNVLFNBQ0E7UUFEQSxZQUFPLEdBQVAsT0FBTztRQUNQLGlCQUFZLEdBQVosWUFBWTs4QkFiNEIsSUFBSSxZQUFZLEVBQUU7dUJBQ2IsSUFBSSxZQUFZLEVBQUU7cUJBQzdCLElBQUksWUFBWSxFQUFFO3NCQUVyRCxpQ0FBaUM7MEJBQzdCLEtBQUs7S0FTYjs7OztJQUVMLElBQUksSUFBSTtRQUNOLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQztLQUMxQjs7OztJQUVELElBQUksV0FBVztRQUNiLE1BQU0sQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDO0tBQzFCOzs7O0lBR0QsUUFBUTtRQUNOLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxXQUFXLENBQzVCLElBQUksQ0FBQyxLQUFLLEVBQ1YsRUFBQyxVQUFVLEVB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Q0FBQyxhQUFhLEVBQUUsQ0FBQztZQUNoQyxNQUFNLENBQUMsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztnQkFDbkIsS0FBSyxvQkFBb0IsQ0FBQztnQkFDMUIsS0FBSyxrQ0FBa0M7b0JBQ3JDLHlCQUF5QixDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO29CQUN6RSxLQUFLLENBQUM7Z0JBQ1IsS0FBSyxvQkFBb0I7b0JBQ3ZCLHlCQUF5QixDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO29CQUM1RSxLQUFLLENBQUM7Z0JBQ1I7b0JBQ0UsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7b0JBQ3ZCLEtBQUssQ0FBQzthQUNUO1NBQ0YsQ0FBQyxDQUFDO0tBQ047OztZQTNNRixTQUFTLFNBQUM7Z0JBQ1QsUUFBUSxFQUFFLGdDQUFnQztnQkFDMUMsUUFBUSxFQUFFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Q0F5R1g7Z0JBQ0MsTUFBTSxFQUFFLENBQUMsRUFBRSxDQUFDO2dCQUNaLFVBQVUsRUFBRSxDQUFFLGtCQUFrQixDQUFFO2FBQ25DOzs7O1lBcEhRLGVBQWU7WUFLZixzQkFBc0I7Ozs0QkFrSDVCLFNBQVMsU0FBQyxlQUFlO29CQUN6QixLQUFLO3VCQUNMLEtBQUs7NkJBQ0wsTUFBTTtzQkFDTixNQUFNO29CQUNOLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgQWZ0ZXJWaWV3SW5pdCwgSW5wdXQsIE91dHB1dCwgRXZlbnRFbWl0dGVyLCBWaWV3Q2hpbGQsIEVsZW1lbnRSZWYgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZvcm1Db250cm9sLCBGb3JtR3JvdXAsIFZhbGlkYXRvcnMgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBBbmd1bGFyRmlyZUF1dGggfSBmcm9tICdhbmd1bGFyZmlyZTIvYXV0aCc7XG5pbXBvcnQgeyBhdXRoIH0gZnJvbSAnZmlyZWJhc2UvYXBwJztcblxuaW1wb3J0IHsgZmFkZUluT3V0QW5pbWF0aW9uIH0gZnJvbSAnLi4vLi4vc2hhcmVkJztcbmltcG9ydCB7IE5neEZpcmViYXNlQXV0aEZvcm1IZWxwZXIgfSBmcm9tICcuLi8uLi9mb3JtLWhlbHBlcic7XG5pbXBvcnQgeyBOZ3hGaXJlYmFzZUF1dGhTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vbmd4LWZpcmViYXNlLWF1dGguc2VydmljZSc7XG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICduZ3gtZmlyZWJhc2UtYXV0aC1zaWduLXVwLWZvcm0nLFxuICB0ZW1wbGF0ZTogYDxmb3JtIFtmb3JtR3JvdXBdPVwiZmdcIiAobmdTdWJtaXQpPVwic3VibWl0KClcIj5cbiAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXBcIj5cbiAgICA8bGFiZWwgW2F0dHIuZm9yXT1cImZvcm1JZCArICdlbWFpbCdcIj5FbWFpbCBBZGRyZXNzPC9sYWJlbD5cbiAgICA8aW5wdXRcbiAgICAgIHJlYWRvbmx5XG4gICAgICAjZW1haWxJbnB1dFxuICAgICAgW2F0dHIuaWRdPVwiZm9ybUlkICsgJ2VtYWlsJ1wiXG4gICAgICBbYXR0ci5hcmlhLWRlc2NyaWJlZGJ5XT1cImZvcm1JZCArICdlbWFpbCdcIlxuICAgICAgdHlwZT1cImVtYWlsXCJcbiAgICAgIGF1dG9jb21wbGV0ZT1cImVtYWlsXCJcbiAgICAgIHBsYWNlaG9sZGVyPVwiRW1haWwgQWRkcmVzc1wiXG4gICAgICBmb3JtQ29udHJvbE5hbWU9XCJlbWFpbFwiXG4gICAgICBjbGFzcz1cImZvcm0tY29udHJvbFwiPlxuICAgIDxkaXYgY2xhc3M9XCJpbnZhbGlkLWZlZWRiYWNrXCIgW0BmYWRlSW5PdXRdPVwiJ2luJ1wiXG4gICAgICAqbmdJZj1cImVtYWlsRmMuaGFzRXJyb3IoJ3JlcXVpcmVkJylcIj5cbiAgICAgIFJlcXVpcmVkLlxuICAgIDwvZGl2PlxuICAgIDxkaXYgY2xhc3M9XCJpbnZhbGlkLWZlZWRiYWNrXCIgW0BmYWRlSW5PdXRdPVwiJ2luJ1wiXG4gICAgICAqbmdJZj1cImVtYWlsRmMuaGFzRXJyb3IoJ2VtYWlsJylcIj5cbiAgICAgIEludmFsaWQgZW1haWwuXG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cImludmFsaWQtZmVlZGJhY2tcIiBbQGZhZGVJbk91dF09XCInaW4nXCJcbiAgICAgICpuZ0lmPVwiZW1haWxGYy5oYXNFcnJvcignYXV0aC9pbnZhbGlkLWVtYWlsJylcIj5cbiAgICAgIEludmFsaWQgZW1haWwuXG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cImludmFsaWQtZmVlZGJhY2tcIiBbQGZhZGVJbk91dF09XCInaW4nXCJcbiAgICAgICpuZ0lmPVwiZW1haWxGYy5oYXNFcnJvcignbmd4LWZpcmViYXNlLWF1dGgvYWNjb3VudC1leGlzdHMnKVwiPlxuICAgICAgV2UgZm91bmQgYW4gYWNjb3VudCB3aXRoIHRoYXQgZW1haWwgYWRkcmVzcy5cbiAgICAgIDxhIHJvdXRlckxpbms9XCIuXCIgW3F1ZXJ5UGFyYW1zXT1cInthY3Rpb246ICdzaWduSW4nfVwiPlNpZ24gSW48L2E+XG4gICAgPC9kaXY+XG4gICAgPHNtYWxsIGNsYXNzPVwidGV4dC1tdXRlZCBmb3JtLXRleHRcIiBbYXR0ci5pZF09XCJmb3JtSWQgKyAnZW1haWwnXCIgPlxuICAgICAgTm90IHlvdXIgZW1haWwgYWRkcmVzcz9cbiAgICAgIDxhIHJvdXRlckxpbms9XCIuXCIgW3F1ZXJ5UGFyYW1zXT1cInthY3Rpb246ICdzaWduSW4nfVwiPkdvIEJhY2s8L2E+XG4gICAgPC9zbWFsbD5cbiAgPC9kaXY+XG5cbiAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXBcIj5cbiAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIGFsaWduLWl0ZW1zLWVuZFwiPlxuICAgICAgPGxhYmVsIFthdHRyLmZvcl09XCJmb3JtSWQgKyAncGFzc3dvcmQnXCI+Q2hvb3NlIFBhc3N3b3JkPC9sYWJlbD5cbiAgICAgIDxzbWFsbD5cbiAgICAgICAgPGEgKGNsaWNrKT1cIiRldmVudC5wcmV2ZW50RGVmYXVsdCgpOyBwYXNzd29yZElucHV0LnR5cGUgPSAncGFzc3dvcmQnID09PSBwYXNzd29yZElucHV0LnR5cGUgID8gJ3RleHQnIDogJ3Bhc3N3b3JkJ1wiXG4gICAgICAgICAgaHJlZj1cIiNcIiB0YWJpbmRleD1cIi0xXCIgY2xhc3M9XCJkLWlubGluZS1ibG9ja1wiPlxuICAgICAgICAgIDxzcGFuICpuZ0lmPVwiJ3Bhc3N3b3JkJyA9PT0gcGFzc3dvcmRJbnB1dC50eXBlXCI+U2hvdzwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiAqbmdJZj1cIid0ZXh0JyA9PT0gcGFzc3dvcmRJbnB1dC50eXBlXCI+SGlkZTwvc3Bhbj5cbiAgICAgICAgPC9hPlxuICAgICAgPC9zbWFsbD5cbiAgICA8L2Rpdj5cbiAgICA8aW5wdXRcbiAgICAgICNwYXNzd29yZElucHV0XG4gICAgICBbYXR0ci5pZF09XCJmb3JtSWQgKyAncGFzc3dvcmQnXCJcbiAgICAgIFthdHRyLmFyaWEtZGVzY3JpYmVkYnldPVwiZm9ybUlkICsgJ3Bhc3N3b3JkLWhlbHAnXCJcbiAgICAgIHR5cGU9XCJwYXNzd29yZFwiXG4gICAgICBmb3JtQ29udHJvbE5hbWU9XCJwYXNzd29yZFwiXG4gICAgICBwbGFjZWhvbGRlcj1cIkNob29zZSBQYXNzd29yZFwiXG4gICAgICBhdXRvY29tcGxldGU9XCJwYXNzd29yZFwiXG4gICAgICBjbGFzcz1cImZvcm0tY29udHJvbFwiXG4gICAgICBbY2xhc3MuaXMtaW52YWxpZF09XCJwYXNzd29yZEZjLnRvdWNoZWQgJiYgcGFzc3dvcmRGYy5pbnZhbGlkXCI+XG4gICAgPGRpdiBjbGFzcz1cImludmFsaWQtZmVlZGJhY2tcIiBbQGZhZGVJbk91dF09XCInaW4nXCJcbiAgICAgICpuZ0lmPVwicGFzc3dvcmRGYy50b3VjaGVkICYmIHBhc3N3b3JkRmMuaGFzRXJyb3IoJ3JlcXVpcmVkJylcIj5cbiAgICAgIFJlcXVpcmVkLlxuICAgIDwvZGl2PlxuICAgIDxkaXYgY2xhc3M9XCJpbnZhbGlkLWZlZWRiYWNrXCIgW0BmYWRlSW5PdXRdPVwiJ2luJ1wiXG4gICAgICAqbmdJZj1cInBhc3N3b3JkRmMudG91Y2hlZCAmJiBwYXNzd29yZEZjLmhhc0Vycm9yKCdhdXRoL3dyb25nLXBhc3N3b3JkJylcIj5cbiAgICAgIFdyb25nIHBhc3N3b3JkLlxuICAgIDwvZGl2PlxuICAgIDxzbWFsbCBbYXR0ci5pZF09XCJmb3JtSWQgKyAncGFzc3dvcmQtaGVscCdcIiBjbGFzcz1cImZvcm0tdGV4dCB0ZXh0LW11dGVkXCI+XG4gICAgICBQbGVhc2UgY2hvb3NlIGEgc3Ryb25nIHBhc3N3b3JkLlxuICAgIDwvc21hbGw+XG4gIDwvZGl2PlxuICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cFwiPlxuICAgIDxsYWJlbCBbYXR0ci5mb3JdPVwiZm9ybUlkICsgJ25hbWUnXCI+WW91ciBOYW1lPC9sYWJlbD5cbiAgICA8aW5wdXRcbiAgICAgIFthdHRyLmlkXT1cImZvcm1JZCArICduYW1lJ1wiXG4gICAgICB0eXBlPVwidGV4dFwiXG4gICAgICBmb3JtQ29udHJvbE5hbWU9XCJuYW1lXCJcbiAgICAgIHBsYWNlaG9sZGVyPVwiWW91ciBOYW1lXCJcbiAgICAgIGNsYXNzPVwiZm9ybS1jb250cm9sXCJcbiAgICAgIFtjbGFzcy5pcy1pbnZhbGlkXT1cIm5hbWVGYy50b3VjaGVkICYmIG5hbWVGYy5pbnZhbGlkXCI+XG4gICAgPGRpdiBjbGFzcz1cImludmFsaWQtZmVlZGJhY2tcIiBbQGZhZGVJbk91dF09XCInaW4nXCJcbiAgICAgICpuZ0lmPVwibmFtZUZjLnRvdWNoZWQgJiYgbmFtZUZjLmhhc0Vycm9yKCdyZXF1aXJlZCcpXCI+XG4gICAgICBSZXF1aXJlZC5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwXCI+XG4gICAgPGRpdiBjbGFzcz1cImZvcm0tY2hlY2tcIj5cbiAgICAgIDxpbnB1dFxuICAgICAgICBjbGFzcz1cImZvcm0tY2hlY2staW5wdXRcIlxuICAgICAgICB0eXBlPVwiY2hlY2tib3hcIlxuICAgICAgICBbdmFsdWVdPVwidHJ1ZVwiXG4gICAgICAgIGZvcm1Db250cm9sTmFtZT1cInJlbWVtYmVyXCJcbiAgICAgICAgW2F0dHIuaWRdPVwiZm9ybUlkICsgJ3JlbWVtYmVyJ1wiPlxuICAgICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1jaGVjay1sYWJlbFwiIFthdHRyLmZvcl09XCJmb3JtSWQgKyAncmVtZW1iZXInXCI+XG4gICAgICAgIFJlbWVtYmVyIG1lIG9uIHRoaXMgZGV2aWNlLlxuICAgICAgPC9sYWJlbD5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwXCI+XG4gICAgPGJ1dHRvbiB0eXBlPVwic3VibWl0XCJcbiAgICAgIGNsYXNzPVwiYnRuIGJ0bi1zdWNjZXNzIGJ0bi1ibG9ja1wiXG4gICAgICBbZGlzYWJsZWRdPVwiZmcuaW52YWxpZCB8fCBzdWJtaXR0aW5nXCI+XG4gICAgICA8aSBjbGFzcz1cImZhcyBmYS1sb2NrIGZhLWZ3XCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+PC9pPlxuICAgICAgQ3JlYXRlIEFjY291bnRcbiAgICA8L2J1dHRvbj5cbiAgPC9kaXY+XG48L2Zvcm0+XG5gLFxuICBzdHlsZXM6IFtgYF0sXG4gIGFuaW1hdGlvbnM6IFsgZmFkZUluT3V0QW5pbWF0aW9uIF1cbn0pXG5leHBvcnQgY2xhc3MgU2lnblVwRm9ybUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgQWZ0ZXJWaWV3SW5pdCB7XG5cbiAgQFZpZXdDaGlsZCgncGFzc3dvcmRJbnB1dCcpIHBhc3N3b3JkSW5wdXQ6IEVsZW1lbnRSZWY7XG4gIEBJbnB1dCgpIGVtYWlsOiBzdHJpbmc7XG4gIEBJbnB1dCgpIHJlbWVtYmVyOiBib29sZWFuO1xuICBAT3V0cHV0KCkgcmVtZW1iZXJDaGFuZ2U6IEV2ZW50RW1pdHRlcjxib29sZWFuPiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgQE91dHB1dCgpIHN1Y2Nlc3M6IEV2ZW50RW1pdHRlcjxhdXRoLlVzZXJDcmVkZW50aWFsPiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgQE91dHB1dCgpIGVycm9yOiBFdmVudEVtaXR0ZXI8YXV0aC5FcnJvcj4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgZm9ybUlkID0gJ25neC1maXJlYmFzZS1hdXRoLXNpZ24tdXAtZm9ybS0nO1xuICBzdWJtaXR0aW5nID0gZmFsc2U7XG4gIGZnOiBGb3JtR3JvdXA7XG4gIGVtYWlsRmM6IEZvcm1Db250cm9sO1xuICBwYXNzd29yZEZjOiBGb3JtQ29udHJvbDtcbiAgbmFtZUZjOiBGb3JtQ29udHJvbDtcbiAgcmVtZW1iZXJGYzogRm9ybUNvbnRyb2w7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgX2FmQXV0aDogQW5ndWxhckZpcmVBdXRoLFxuICAgIHByaXZhdGUgX2F1dGhTZXJ2aWNlOiBOZ3hGaXJlYmFzZUF1dGhTZXJ2aWNlXG4gICkgeyB9XG5cbiAgZ2V0IGF1dGgoKTogYXV0aC5BdXRoIHtcbiAgICByZXR1cm4gdGhpcy5fYWZBdXRoLmF1dGg7XG4gIH1cblxuICBnZXQgYXV0aFNlcnZpY2UoKTogTmd4RmlyZWJhc2VBdXRoU2VydmljZSB7XG4gICAgcmV0dXJuIHRoaXMuX2F1dGhTZXJ2aWNlO1xuICB9XG5cblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLmVtYWlsRmMgPSBuZXcgRm9ybUNvbnRyb2woXG4gICAgICB0aGlzLmVtYWlsLFxuICAgICAge3ZhbGlkYXRvcnM6IFtWYWxpZGF0b3JzLnJlcXVpcmVkLCBWYWxpZGF0b3JzLmVtYWlsXX1cbiAgICApO1xuICAgIHRoaXMucGFzc3dvcmRGYyA9IG5ldyBGb3JtQ29udHJvbCgnJywge3ZhbGlkYXRvcnM6IFtWYWxpZGF0b3JzLnJlcXVpcmVkXX0pO1xuICAgIHRoaXMubmFtZUZjID0gbmV3IEZvcm1Db250cm9sKCcnLCB7dmFsaWRhdG9yczogW1ZhbGlkYXRvcnMucmVxdWlyZWQsIE5neEZpcmViYXNlQXV0aEZvcm1IZWxwZXIucmVxdWlyZWROb25FbXB0eV19KTtcbiAgICB0aGlzLnJlbWVtYmVyRmMgPSBuZXcgRm9ybUNvbnRyb2wodGhpcy5yZW1lbWJlcik7XG4gICAgdGhpcy5yZW1lbWJlckZjLnZhbHVlQ2hhbmdlcy5zdWJzY3JpYmUodmFsID0+IHRoaXMucmVtZW1iZXJDaGFuZ2UuZW1pdCh2YWwpKTtcbiAgICB0aGlzLmZnID0gbmV3IEZvcm1Hcm91cCh7XG4gICAgICBlbWFpbDogdGhpcy5lbWFpbEZjLFxuICAgICAgcGFzc3dvcmQ6IHRoaXMucGFzc3dvcmRGYyxcbiAgICAgIG5hbWU6IHRoaXMubmFtZUZjLFxuICAgICAgcmVtZW1iZXI6IHRoaXMucmVtZW1iZXJGY1xuICAgIH0pO1xuICB9XG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICB0aGlzLnBhc3N3b3JkSW5wdXQubmF0aXZlRWxlbWVudC5mb2N1cygpO1xuICB9XG5cbiAgc3VibWl0KCkge1xuXG4gICAgdGhpcy5zdWJtaXR0aW5nID0gdHJ1ZTtcbiAgICBsZXQgY3JlZDogYXV0aC5Vc2VyQ3JlZGVudGlhbDtcbiAgICB0aGlzLmF1dGguZmV0Y2hTaWduSW5NZXRob2RzRm9yRW1haWwodGhpcy5lbWFpbClcbiAgICAgIC50aGVuKChyZXN1bHRzKSA9PiB7XG4gICAgICAgIGlmIChyZXN1bHRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3Qoe1xuICAgICAgICAgICAgY29kZTogJ25neC1maXJlYmFzZS1hdXRoL2FjY291bnQtZXhpc3RzJ1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmF1dGguY3JlYXRlVXNlcldpdGhFbWFpbEFuZFBhc3N3b3JkKHRoaXMuZW1haWwsIHRoaXMucGFzc3dvcmRGYy52YWx1ZSk7XG4gICAgICB9KVxuICAgICAgLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgICAgY3JlZCA9IHJlc3VsdDtcbiAgICAgICAgcmV0dXJuIGNyZWQudXNlci51cGRhdGVQcm9maWxlKHtkaXNwbGF5TmFtZTogdGhpcy5uYW1lRmMudmFsdWUudHJpbSgpLCBwaG90b1VSTDogbnVsbH0pO1xuICAgICAgfSlcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXV0aFNlcnZpY2Uuc2V0UmVtZW1iZXJlZCh0aGlzLnJlbWVtYmVyRmMudmFsdWUgPT09IHRydWUsIHRoaXMuZW1haWwpO1xuICAgICAgfSlcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgdGhpcy5zdWNjZXNzLmVtaXQoY3JlZCk7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgdGhpcy5zdWJtaXR0aW5nID0gZmFsc2U7XG4gICAgICAgIHRoaXMuZW1haWxGYy5tYXJrQXNEaXJ0eSgpO1xuICAgICAgICB0aGlzLmVtYWlsRmMubWFya0FzVG91Y2hlZCgpO1xuICAgICAgICB0aGlzLnBhc3N3b3JkRmMubWFya0FzRGlydHkoKTtcbiAgICAgICAgdGhpcy5wYXNzd29yZEZjLm1hcmtBc1RvdWNoZWQoKTtcbiAgICAgICAgc3dpdGNoIChlcnJvci5jb2RlKSB7XG4gICAgICAgICAgY2FzZSAnYXV0aC9pbnZhbGlkLWVtYWlsJzpcbiAgICAgICAgICBjYXNlICduZ3gtZmlyZWJhc2UtYXV0aC9hY2NvdW50LWV4aXN0cyc6XG4gICAgICAgICAgICBOZ3hGaXJlYmFzZUF1dGhGb3JtSGVscGVyLnNldEVycm9yVW50aWxDaGFuZ2VkKHRoaXMuZW1haWxGYywgZXJyb3IuY29kZSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdhdXRoL3dlYWstcGFzc3dvcmQnOlxuICAgICAgICAgICAgTmd4RmlyZWJhc2VBdXRoRm9ybUhlbHBlci5zZXRFcnJvclVudGlsQ2hhbmdlZCh0aGlzLnBhc3N3b3JkRmMsIGVycm9yLmNvZGUpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHRoaXMuZXJyb3IuZW1pdChlcnJvcik7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cblxufVxuIl19