@nowzoo/ngx-firebase-auth
Version:
Angular components for Firebase email-first sign in and out-of-band (oob) actions (reset password, etc).
159 lines (158 loc) • 24.4 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
import { Component, Input, Output, EventEmitter } from '@angular/core';
import { FormGroup, FormControl, Validators } from '@angular/forms';
import { AngularFireAuth } from 'angularfire2/auth';
import { NgxFirebaseAuthFormHelper } from '../../form-helper';
import { NgxFirebaseAuthService } from '../../ngx-firebase-auth.service';
import { screenAnimation } from '../../shared';
var OobResetPasswordComponent = /** @class */ (function () {
function OobResetPasswordComponent(_afAuth, _authService) {
this._afAuth = _afAuth;
this._authService = _authService;
this.success = new EventEmitter();
this.screen = 'wait';
this.submitting = false;
this.formId = 'ngx-firebase-auth-oob-reset-password-';
this.unhandledError = null;
this.cred = null;
}
Object.defineProperty(OobResetPasswordComponent.prototype, "auth", {
get: /**
* @return {?}
*/
function () {
return this._afAuth.auth;
},
enumerable: true,
configurable: true
});
Object.defineProperty(OobResetPasswordComponent.prototype, "authService", {
get: /**
* @return {?}
*/
function () {
return this._authService;
},
enumerable: true,
configurable: true
});
/**
* @return {?}
*/
OobResetPasswordComponent.prototype.ngOnInit = /**
* @return {?}
*/
function () {
var _this = this;
/** @type {?} */
var remembered = this.authService.getRemembered();
this.emailFc = new FormControl('');
this.passwordFc = new FormControl('', { validators: [Validators.required] });
this.rememberFc = new FormControl(remembered.remember);
this.fg = new FormGroup({ email: this.emailFc, password: this.passwordFc, remember: this.rememberFc });
this.auth.checkActionCode(this.oobCode)
.then(function (result) {
_this.info = result;
_this.emailFc.setValue(result.data.email);
_this.screen = 'form';
})
.catch(function (error) {
_this.unhandledError = error;
_this.screen = 'error';
});
};
/**
* @return {?}
*/
OobResetPasswordComponent.prototype.submit = /**
* @return {?}
*/
function () {
var _this = this;
this.submitting = true;
this.auth.confirmPasswordReset(this.oobCode, this.passwordFc.value)
.then(function () {
return _this.auth.signInWithEmailAndPassword(_this.info.data.email, _this.passwordFc.value);
})
.then(function (cred) {
_this.cred = cred;
return _this.authService.setRemembered(_this.rememberFc.value === true, _this.info.data.email);
})
.then(function () {
_this.screen = 'success';
_this.success.emit({
mode: 'resetPassword',
info: _this.info,
cred: _this.cred,
user: _this.cred.user
});
})
.catch(function (error) {
_this.submitting = false;
_this.passwordFc.markAsDirty();
_this.passwordFc.markAsTouched();
switch (error.code) {
case 'auth/weak-password':
NgxFirebaseAuthFormHelper.setErrorUntilChanged(_this.passwordFc, error.code);
break;
default:
_this.unhandledError = error;
_this.screen = 'error';
break;
}
});
};
OobResetPasswordComponent.decorators = [
{ type: Component, args: [{
selector: 'ngx-firebase-auth-oob-reset-password',
template: "<div *ngIf=\"'wait' === screen\" [@screen]=\"'in'\">\n <div class=\"alert alert-secondary\">\n <i class=\"fas fa-spin fa-spinner fa-fw\" aria-hidden=\"true\"></i>\n Please wait...\n </div>\n</div>\n\n<div *ngIf=\"'success' === screen\" [@screen]=\"'in'\">\n <div class=\"alert alert-success\">\n <i class=\"fas fa-check fa-fw\" aria-hidden=\"true\"></i>\n Welcome, {{cred.user.displayName}}!\n Your new password has been saved and you are signed in.\n </div>\n</div>\n\n<div *ngIf=\"screen === 'error'\" [@screen]=\"'in'\">\n <div class=\"alert alert-danger\">\n <p>\n <i class=\"fas fa-exclamation-triangle fa-fw\" aria-hidden=\"true\"></i>\n Woops! An error occurred.\n </p>\n <div [ngSwitch]=\"unhandledError.code\">\n <p class=\"mb-0\" *ngSwitchCase=\"'auth/expired-action-code'\">\n The reset password link you used has expired.\n </p>\n <p class=\"mb-0\" *ngSwitchCase=\"'auth/invalid-action-code'\">\n The reset password link you used is not valid. This may be because it\n has already been used.\n </p>\n <p class=\"mb-0\" *ngSwitchCase=\"'auth/user-disabled'\">\n The account associated with the reset password link you used has been disabled.\n </p>\n <p class=\"mb-0\" *ngSwitchCase=\"'auth/user-not-found'\">\n The account associated with the reset password link you used has been removed.\n </p>\n <div *ngSwitchDefault>\n <p>Code: {{unhandledError.code}}</p>\n <p class=\"mb-0\">\n Message: {{unhandledError.message}}\n </p>\n </div>\n </div>\n </div>\n</div>\n\n\n<div *ngIf=\"'form' === screen\" [@screen]=\"'in'\">\n <form [formGroup]=\"fg\" (ngSubmit)=\"submit()\">\n <div class=\"form-group\">\n <label [attr.for]=\"formId + 'email'\">Email Address</label>\n\n <input\n readonly\n #emailInput\n [attr.id]=\"formId + 'email'\"\n [attr.aria-describedby]=\"formId + 'email'\"\n type=\"email\"\n autocomplete=\"email\"\n placeholder=\"Email Address\"\n formControlName=\"email\"\n class=\"form-control\">\n <small class=\"text-muted form-text\" [attr.id]=\"formId + 'email'\" >\n You are resetting the password for {{emailFc.value}}.\n </small>\n </div>\n\n <div class=\"form-group\">\n <div class=\"d-flex justify-content-between align-items-end\">\n <label [attr.for]=\"formId + 'password'\">Password</label>\n <small>\n <a (click)=\"$event.preventDefault(); passwordInput.type = 'password' === passwordInput.type ? 'text' : 'password'\"\n href=\"#\" tabindex=\"-1\" class=\"d-inline-block\">\n <span *ngIf=\"'password' === passwordInput.type\">Show</span>\n <span *ngIf=\"'text' === passwordInput.type\">Hide</span>\n </a>\n </small>\n </div>\n <input\n #passwordInput\n [attr.id]=\"formId + 'password'\"\n [attr.aria-describedby]=\"formId + 'password-help'\"\n type=\"password\"\n formControlName=\"password\"\n placeholder=\"Password\"\n autocomplete=\"password\"\n class=\"form-control\"\n [class.is-invalid]=\"passwordFc.touched && passwordFc.invalid\">\n <div class=\"invalid-feedback\" *ngIf=\"passwordFc.touched && passwordFc.hasError('required')\">\n Required.\n </div>\n <div class=\"invalid-feedback\" *ngIf=\"passwordFc.touched && passwordFc.hasError('auth/weak-password')\">\n That password is too weak.\n </div>\n <small [attr.id]=\"formId + 'password-help'\" class=\"form-text text-muted\">\n Please choose a strong password.\n </small>\n </div>\n <div class=\"form-group\">\n <div class=\"form-check\">\n <input\n class=\"form-check-input\"\n type=\"checkbox\"\n [value]=\"true\"\n formControlName=\"remember\"\n [attr.id]=\"formId + 'remember'\">\n <label class=\"form-check-label\" [attr.for]=\"formId + 'remember'\">\n Remember me on this device.\n </label>\n </div>\n </div>\n <div class=\"form-group\">\n <button type=\"submit\"\n class=\"btn btn-success btn-block\"\n [disabled]=\"fg.invalid || submitting\">\n <i class=\"fas fa-save fa-fw\" aria-hidden=\"true\"></i>\n Save Password and Sign In\n </button>\n </div>\n </form>\n</div>\n",
styles: [""],
animations: [screenAnimation]
},] },
];
/** @nocollapse */
OobResetPasswordComponent.ctorParameters = function () { return [
{ type: AngularFireAuth },
{ type: NgxFirebaseAuthService }
]; };
OobResetPasswordComponent.propDecorators = {
oobCode: [{ type: Input }],
success: [{ type: Output }]
};
return OobResetPasswordComponent;
}());
export { OobResetPasswordComponent };
if (false) {
/** @type {?} */
OobResetPasswordComponent.prototype.oobCode;
/** @type {?} */
OobResetPasswordComponent.prototype.success;
/** @type {?} */
OobResetPasswordComponent.prototype.screen;
/** @type {?} */
OobResetPasswordComponent.prototype.info;
/** @type {?} */
OobResetPasswordComponent.prototype.submitting;
/** @type {?} */
OobResetPasswordComponent.prototype.formId;
/** @type {?} */
OobResetPasswordComponent.prototype.fg;
/** @type {?} */
OobResetPasswordComponent.prototype.emailFc;
/** @type {?} */
OobResetPasswordComponent.prototype.passwordFc;
/** @type {?} */
OobResetPasswordComponent.prototype.rememberFc;
/** @type {?} */
OobResetPasswordComponent.prototype.unhandledError;
/** @type {?} */
OobResetPasswordComponent.prototype.cred;
/** @type {?} */
OobResetPasswordComponent.prototype._afAuth;
/** @type {?} */
OobResetPasswordComponent.prototype._authService;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib29iLXJlc2V0LXBhc3N3b3JkLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0Bub3d6b28vbmd4LWZpcmViYXNlLWF1dGgvIiwic291cmNlcyI6WyJsaWIvb29iL29vYi1yZXNldC1wYXNzd29yZC9vb2ItcmVzZXQtcGFzc3dvcmQuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFVLEtBQUssRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQy9FLE9BQU8sRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLFVBQVUsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3BFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUdwRCxPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUM5RCxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUN6RSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sY0FBYyxDQUFDOztJQStJN0MsbUNBQ1UsU0FDRTtRQURGLFlBQU8sR0FBUCxPQUFPO1FBQ0wsaUJBQVksR0FBWixZQUFZO3VCQWRzQyxJQUFJLFlBQVksRUFBRTtzQkFFaEMsTUFBTTswQkFFekMsS0FBSztzQkFDVCx1Q0FBdUM7OEJBS25CLElBQUk7b0JBQ0wsSUFBSTtLQUkzQjtJQUVMLHNCQUFJLDJDQUFJOzs7O1FBQVI7WUFDRSxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUM7U0FDMUI7OztPQUFBO0lBQ0Qsc0JBQUksa0RBQVc7Ozs7UUFBZjtZQUNFLE1BQU0sQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDO1NBQzFCOzs7T0FBQTs7OztJQUVELDRDQUFROzs7SUFBUjtRQUFBLGlCQWdCQzs7UUFmQyxJQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ3BELElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxXQUFXLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDbkMsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLFdBQVcsQ0FBQyxFQUFFLEVBQUUsRUFBQyxVQUFVLEVBQUUsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLEVBQUMsQ0FBQyxDQUFDO1FBQzNFLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxXQUFXLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3ZELElBQUksQ0FBQyxFQUFFLEdBQUcsSUFBSSxTQUFTLENBQUMsRUFBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLFVBQVUsRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLFVBQVUsRUFBQyxDQUFDLENBQUM7UUFDckcsSUFBSSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQzthQUNwQyxJQUFJLENBQUMsVUFBQyxNQUEyQjtZQUNoQyxLQUFJLENBQUMsSUFBSSxHQUFHLE1BQU0sQ0FBQztZQUNuQixLQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3pDLEtBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO1NBQ3RCLENBQUM7YUFDRCxLQUFLLENBQUMsVUFBQyxLQUFpQjtZQUN2QixLQUFJLENBQUMsY0FBYyxHQUFHLEtBQUssQ0FBQztZQUM1QixLQUFJLENBQUMsTUFBTSxHQUFHLE9BQU8sQ0FBQztTQUN2QixDQUFDLENBQUM7S0FDTjs7OztJQUVELDBDQUFNOzs7SUFBTjtRQUFBLGlCQWlDQztRQWhDQyxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQztRQUN2QixJQUFJLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUM7YUFDaEUsSUFBSSxDQUFDO1lBQ0osTUFBTSxDQUFDLEtBQUksQ0FBQyxJQUFJLENBQUMsMEJBQTBCLENBQUMsS0FBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLEtBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUM7U0FDMUYsQ0FBQzthQUNELElBQUksQ0FBQyxVQUFDLElBQXlCO1lBQzlCLEtBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1lBQ2pCLE1BQU0sQ0FBQyxLQUFJLENBQUMsV0FBVyxDQUFDLGFBQWEsQ0FBQyxLQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssS0FBSyxJQUFJLEVBQUUsS0FBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7U0FDN0YsQ0FBQzthQUNELElBQUksQ0FBQztZQUNKLEtBQUksQ0FBQyxNQUFNLEdBQUcsU0FBUyxDQUFDO1lBQ3hCLEtBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDO2dCQUNoQixJQUFJLEVBQUUsZUFBZTtnQkFDckIsSUFBSSxFQUFFLEtBQUksQ0FBQyxJQUFJO2dCQUNmLElBQUksRUFBRSxLQUFJLENBQUMsSUFBSTtnQkFDZixJQUFJLEVBQUUsS0FBSSxDQUFDLElBQUksQ0FBQyxJQUFJO2FBQ3JCLENBQUMsQ0FBQztTQUNKLENBQUM7YUFDRCxLQUFLLENBQUMsVUFBQyxLQUFpQjtZQUN2QixLQUFJLENBQUMsVUFBVSxHQUFHLEtBQUssQ0FBQztZQUN4QixLQUFJLENBQUMsVUFBVSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQzlCLEtBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDaEMsTUFBTSxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7Z0JBQ25CLEtBQUssb0JBQW9CO29CQUN2Qix5QkFBeUIsQ0FBQyxvQkFBb0IsQ0FBQyxLQUFJLENBQUMsVUFBVSxFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztvQkFDNUUsS0FBSyxDQUFDO2dCQUNSO29CQUNFLEtBQUksQ0FBQyxjQUFjLEdBQUcsS0FBSyxDQUFDO29CQUM1QixLQUFJLENBQUMsTUFBTSxHQUFHLE9BQU8sQ0FBQztvQkFDdEIsS0FBSyxDQUFDO2FBQ1Q7U0FDRixDQUFDLENBQUM7S0FDTjs7Z0JBNU1GLFNBQVMsU0FBQztvQkFDVCxRQUFRLEVBQUUsc0NBQXNDO29CQUNoRCxRQUFRLEVBQUUsNDNJQXdIWDtvQkFDQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLENBQUM7b0JBQ1osVUFBVSxFQUFFLENBQUMsZUFBZSxDQUFDO2lCQUM5Qjs7OztnQkFwSVEsZUFBZTtnQkFJZixzQkFBc0I7OzswQkFtSTVCLEtBQUs7MEJBQ0wsTUFBTTs7b0NBMUlUOztTQXVJYSx5QkFBeUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgSW5wdXQsIE91dHB1dCwgRXZlbnRFbWl0dGVyIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBGb3JtR3JvdXAsIEZvcm1Db250cm9sLCBWYWxpZGF0b3JzIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgQW5ndWxhckZpcmVBdXRoIH0gZnJvbSAnYW5ndWxhcmZpcmUyL2F1dGgnO1xuaW1wb3J0IHsgYXV0aCwgVXNlciB9IGZyb20gJ2ZpcmViYXNlL2FwcCc7XG5pbXBvcnQgeyBJTmd4RmlyZWJhc2VBdXRoT29iU3VjY2VzcyB9IGZyb20gJy4uLy4uL3NoYXJlZCc7XG5pbXBvcnQgeyBOZ3hGaXJlYmFzZUF1dGhGb3JtSGVscGVyIH0gZnJvbSAnLi4vLi4vZm9ybS1oZWxwZXInO1xuaW1wb3J0IHsgTmd4RmlyZWJhc2VBdXRoU2VydmljZSB9IGZyb20gJy4uLy4uL25neC1maXJlYmFzZS1hdXRoLnNlcnZpY2UnO1xuaW1wb3J0IHsgc2NyZWVuQW5pbWF0aW9uIH0gZnJvbSAnLi4vLi4vc2hhcmVkJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbmd4LWZpcmViYXNlLWF1dGgtb29iLXJlc2V0LXBhc3N3b3JkJyxcbiAgdGVtcGxhdGU6IGA8ZGl2ICpuZ0lmPVwiJ3dhaXQnID09PSBzY3JlZW5cIiBbQHNjcmVlbl09XCInaW4nXCI+XG4gIDxkaXYgY2xhc3M9XCJhbGVydCBhbGVydC1zZWNvbmRhcnlcIj5cbiAgICA8aSBjbGFzcz1cImZhcyBmYS1zcGluIGZhLXNwaW5uZXIgZmEtZndcIiBhcmlhLWhpZGRlbj1cInRydWVcIj48L2k+XG4gICAgUGxlYXNlIHdhaXQuLi5cbiAgPC9kaXY+XG48L2Rpdj5cblxuPGRpdiAqbmdJZj1cIidzdWNjZXNzJyA9PT0gc2NyZWVuXCIgW0BzY3JlZW5dPVwiJ2luJ1wiPlxuICA8ZGl2IGNsYXNzPVwiYWxlcnQgYWxlcnQtc3VjY2Vzc1wiPlxuICAgIDxpIGNsYXNzPVwiZmFzIGZhLWNoZWNrIGZhLWZ3XCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+PC9pPlxuICAgIFdlbGNvbWUsIHt7Y3JlZC51c2VyLmRpc3BsYXlOYW1lfX0hXG4gICAgWW91ciBuZXcgcGFzc3dvcmQgaGFzIGJlZW4gc2F2ZWQgYW5kIHlvdSBhcmUgc2lnbmVkIGluLlxuICA8L2Rpdj5cbjwvZGl2PlxuXG48ZGl2ICpuZ0lmPVwic2NyZWVuID09PSAnZXJyb3InXCIgW0BzY3JlZW5dPVwiJ2luJ1wiPlxuICA8ZGl2IGNsYXNzPVwiYWxlcnQgYWxlcnQtZGFuZ2VyXCI+XG4gICAgPHA+XG4gICAgICA8aSBjbGFzcz1cImZhcyBmYS1leGNsYW1hdGlvbi10cmlhbmdsZSBmYS1md1wiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjwvaT5cbiAgICAgIFdvb3BzISBBbiBlcnJvciBvY2N1cnJlZC5cbiAgICA8L3A+XG4gICAgPGRpdiBbbmdTd2l0Y2hdPVwidW5oYW5kbGVkRXJyb3IuY29kZVwiPlxuICAgICAgPHAgY2xhc3M9XCJtYi0wXCIgKm5nU3dpdGNoQ2FzZT1cIidhdXRoL2V4cGlyZWQtYWN0aW9uLWNvZGUnXCI+XG4gICAgICAgIFRoZSByZXNldCBwYXNzd29yZCBsaW5rIHlvdSB1c2VkIGhhcyBleHBpcmVkLlxuICAgICAgPC9wPlxuICAgICAgPHAgY2xhc3M9XCJtYi0wXCIgKm5nU3dpdGNoQ2FzZT1cIidhdXRoL2ludmFsaWQtYWN0aW9uLWNvZGUnXCI+XG4gICAgICAgIFRoZSByZXNldCBwYXNzd29yZCBsaW5rIHlvdSB1c2VkIGlzIG5vdCB2YWxpZC4gVGhpcyBtYXkgYmUgYmVjYXVzZSBpdFxuICAgICAgICBoYXMgYWxyZWFkeSBiZWVuIHVzZWQuXG4gICAgICA8L3A+XG4gICAgICA8cCBjbGFzcz1cIm1iLTBcIiAqbmdTd2l0Y2hDYXNlPVwiJ2F1dGgvdXNlci1kaXNhYmxlZCdcIj5cbiAgICAgICAgVGhlIGFjY291bnQgYXNzb2NpYXRlZCB3aXRoIHRoZSByZXNldCBwYXNzd29yZCBsaW5rIHlvdSB1c2VkIGhhcyBiZWVuIGRpc2FibGVkLlxuICAgICAgPC9wPlxuICAgICAgPHAgY2xhc3M9XCJtYi0wXCIgKm5nU3dpdGNoQ2FzZT1cIidhdXRoL3VzZXItbm90LWZvdW5kJ1wiPlxuICAgICAgICBUaGUgYWNjb3VudCBhc3NvY2lhdGVkIHdpdGggdGhlIHJlc2V0IHBhc3N3b3JkIGxpbmsgeW91IHVzZWQgaGFzIGJlZW4gcmVtb3ZlZC5cbiAgICAgIDwvcD5cbiAgICAgIDxkaXYgKm5nU3dpdGNoRGVmYXVsdD5cbiAgICAgICAgPHA+Q29kZToge3t1bmhhbmRsZWRFcnJvci5jb2RlfX08L3A+XG4gICAgICAgIDxwIGNsYXNzPVwibWItMFwiPlxuICAgICAgICAgIE1lc3NhZ2U6IHt7dW5oYW5kbGVkRXJyb3IubWVzc2FnZX19XG4gICAgICAgIDwvcD5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvZGl2PlxuXG5cbjxkaXYgKm5nSWY9XCInZm9ybScgPT09IHNjcmVlblwiIFtAc2NyZWVuXT1cIidpbidcIj5cbiAgPGZvcm0gW2Zvcm1Hcm91cF09XCJmZ1wiIChuZ1N1Ym1pdCk9XCJzdWJtaXQoKVwiPlxuICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwXCI+XG4gICAgICA8bGFiZWwgW2F0dHIuZm9yXT1cImZvcm1JZCArICdlbWFpbCdcIj5FbWFpbCBBZGRyZXNzPC9sYWJlbD5cblxuICAgICAgPGlucHV0XG4gICAgICAgIHJlYWRvbmx5XG4gICAgICAgICNlbWFpbElucHV0XG4gICAgICAgIFthdHRyLmlkXT1cImZvcm1JZCArICdlbWFpbCdcIlxuICAgICAgICBbYXR0ci5hcmlhLWRlc2NyaWJlZGJ5XT1cImZvcm1JZCArICdlbWFpbCdcIlxuICAgICAgICB0eXBlPVwiZW1haWxcIlxuICAgICAgICBhdXRvY29tcGxldGU9XCJlbWFpbFwiXG4gICAgICAgIHBsYWNlaG9sZGVyPVwiRW1haWwgQWRkcmVzc1wiXG4gICAgICAgIGZvcm1Db250cm9sTmFtZT1cImVtYWlsXCJcbiAgICAgICAgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIj5cbiAgICAgIDxzbWFsbCBjbGFzcz1cInRleHQtbXV0ZWQgZm9ybS10ZXh0XCIgW2F0dHIuaWRdPVwiZm9ybUlkICsgJ2VtYWlsJ1wiID5cbiAgICAgICAgWW91IGFyZSByZXNldHRpbmcgdGhlIHBhc3N3b3JkIGZvciB7e2VtYWlsRmMudmFsdWV9fS5cbiAgICAgIDwvc21hbGw+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cFwiPlxuICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBhbGlnbi1pdGVtcy1lbmRcIj5cbiAgICAgICAgPGxhYmVsIFthdHRyLmZvcl09XCJmb3JtSWQgKyAncGFzc3dvcmQnXCI+UGFzc3dvcmQ8L2xhYmVsPlxuICAgICAgICA8c21hbGw+XG4gICAgICAgICAgPGEgKGNsaWNrKT1cIiRldmVudC5wcmV2ZW50RGVmYXVsdCgpOyBwYXNzd29yZElucHV0LnR5cGUgPSAncGFzc3dvcmQnID09PSBwYXNzd29yZElucHV0LnR5cGUgID8gJ3RleHQnIDogJ3Bhc3N3b3JkJ1wiXG4gICAgICAgICAgICBocmVmPVwiI1wiIHRhYmluZGV4PVwiLTFcIiBjbGFzcz1cImQtaW5saW5lLWJsb2NrXCI+XG4gICAgICAgICAgICA8c3BhbiAqbmdJZj1cIidwYXNzd29yZCcgPT09IHBhc3N3b3JkSW5wdXQudHlwZVwiPlNob3c8L3NwYW4+XG4gICAgICAgICAgICA8c3BhbiAqbmdJZj1cIid0ZXh0JyA9PT0gcGFzc3dvcmRJbnB1dC50eXBlXCI+SGlkZTwvc3Bhbj5cbiAgICAgICAgICA8L2E+XG4gICAgICAgIDwvc21hbGw+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxpbnB1dFxuICAgICAgICAjcGFzc3dvcmRJbnB1dFxuICAgICAgICBbYXR0ci5pZF09XCJmb3JtSWQgKyAncGFzc3dvcmQnXCJcbiAgICAgICAgW2F0dHIuYXJpYS1kZXNjcmliZWRieV09XCJmb3JtSWQgKyAncGFzc3dvcmQtaGVscCdcIlxuICAgICAgICB0eXBlPVwicGFzc3dvcmRcIlxuICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJwYXNzd29yZFwiXG4gICAgICAgIHBsYWNlaG9sZGVyPVwiUGFzc3dvcmRcIlxuICAgICAgICBhdXRvY29tcGxldGU9XCJwYXNzd29yZFwiXG4gICAgICAgIGNsYXNzPVwiZm9ybS1jb250cm9sXCJcbiAgICAgICAgW2NsYXNzLmlzLWludmFsaWRdPVwicGFzc3dvcmRGYy50b3VjaGVkICYmIHBhc3N3b3JkRmMuaW52YWxpZFwiPlxuICAgICAgPGRpdiBjbGFzcz1cImludmFsaWQtZmVlZGJhY2tcIiAqbmdJZj1cInBhc3N3b3JkRmMudG91Y2hlZCAmJiBwYXNzd29yZEZjLmhhc0Vycm9yKCdyZXF1aXJlZCcpXCI+XG4gICAgICAgIFJlcXVpcmVkLlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwiaW52YWxpZC1mZWVkYmFja1wiICpuZ0lmPVwicGFzc3dvcmRGYy50b3VjaGVkICYmIHBhc3N3b3JkRmMuaGFzRXJyb3IoJ2F1dGgvd2Vhay1wYXNzd29yZCcpXCI+XG4gICAgICAgIFRoYXQgcGFzc3dvcmQgaXMgdG9vIHdlYWsuXG4gICAgICA8L2Rpdj5cbiAgICAgIDxzbWFsbCBbYXR0ci5pZF09XCJmb3JtSWQgKyAncGFzc3dvcmQtaGVscCdcIiBjbGFzcz1cImZvcm0tdGV4dCB0ZXh0LW11dGVkXCI+XG4gICAgICAgIFBsZWFzZSBjaG9vc2UgYSBzdHJvbmcgcGFzc3dvcmQuXG4gICAgICA8L3NtYWxsPlxuICAgIDwvZGl2PlxuICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1jaGVja1wiPlxuICAgICAgICA8aW5wdXRcbiAgICAgICAgICBjbGFzcz1cImZvcm0tY2hlY2staW5wdXRcIlxuICAgICAgICAgIHR5cGU9XCJjaGVja2JveFwiXG4gICAgICAgICAgW3ZhbHVlXT1cInRydWVcIlxuICAgICAgICAgIGZvcm1Db250cm9sTmFtZT1cInJlbWVtYmVyXCJcbiAgICAgICAgICBbYXR0ci5pZF09XCJmb3JtSWQgKyAncmVtZW1iZXInXCI+XG4gICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tY2hlY2stbGFiZWxcIiBbYXR0ci5mb3JdPVwiZm9ybUlkICsgJ3JlbWVtYmVyJ1wiPlxuICAgICAgICAgIFJlbWVtYmVyIG1lIG9uIHRoaXMgZGV2aWNlLlxuICAgICAgICA8L2xhYmVsPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXBcIj5cbiAgICAgIDxidXR0b24gdHlwZT1cInN1Ym1pdFwiXG4gICAgICAgIGNsYXNzPVwiYnRuIGJ0bi1zdWNjZXNzIGJ0bi1ibG9ja1wiXG4gICAgICAgIFtkaXNhYmxlZF09XCJmZy5pbnZhbGlkIHx8IHN1Ym1pdHRpbmdcIj5cbiAgICAgICAgPGkgY2xhc3M9XCJmYXMgZmEtc2F2ZSBmYS1md1wiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjwvaT5cbiAgICAgICAgU2F2ZSBQYXNzd29yZCBhbmQgU2lnbiBJblxuICAgICAgPC9idXR0b24+XG4gICAgPC9kaXY+XG4gIDwvZm9ybT5cbjwvZGl2PlxuYCxcbiAgc3R5bGVzOiBbYGBdLFxuICBhbmltYXRpb25zOiBbc2NyZWVuQW5pbWF0aW9uXVxufSlcbmV4cG9ydCBjbGFzcyBPb2JSZXNldFBhc3N3b3JkQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcblxuICBASW5wdXQoKSBvb2JDb2RlOiBzdHJpbmc7XG4gIEBPdXRwdXQoKSBzdWNjZXNzOiBFdmVudEVtaXR0ZXI8SU5neEZpcmViYXNlQXV0aE9vYlN1Y2Nlc3M+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gIHNjcmVlbjogJ3dhaXQnIHwgJ2Zvcm0nIHwgJ2Vycm9yJyB8ICdzdWNjZXNzJyA9ICd3YWl0JztcbiAgaW5mbzogYXV0aC5BY3Rpb25Db2RlSW5mbztcbiAgc3VibWl0dGluZyA9IGZhbHNlO1xuICBmb3JtSWQgPSAnbmd4LWZpcmViYXNlLWF1dGgtb29iLXJlc2V0LXBhc3N3b3JkLSc7XG4gIGZnOiBGb3JtR3JvdXA7XG4gIGVtYWlsRmM6IEZvcm1Db250cm9sO1xuICBwYXNzd29yZEZjOiBGb3JtQ29udHJvbDtcbiAgcmVtZW1iZXJGYzogRm9ybUNvbnRyb2w7XG4gIHVuaGFuZGxlZEVycm9yOiBhdXRoLkVycm9yID0gbnVsbDtcbiAgY3JlZDogYXV0aC5Vc2VyQ3JlZGVudGlhbCA9IG51bGw7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgX2FmQXV0aDogQW5ndWxhckZpcmVBdXRoLFxuICAgICAgcHJpdmF0ZSBfYXV0aFNlcnZpY2U6IE5neEZpcmViYXNlQXV0aFNlcnZpY2UsXG4gICkgeyB9XG5cbiAgZ2V0IGF1dGgoKTogYXV0aC5BdXRoIHtcbiAgICByZXR1cm4gdGhpcy5fYWZBdXRoLmF1dGg7XG4gIH1cbiAgZ2V0IGF1dGhTZXJ2aWNlKCk6IE5neEZpcmViYXNlQXV0aFNlcnZpY2Uge1xuICAgIHJldHVybiB0aGlzLl9hdXRoU2VydmljZTtcbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIGNvbnN0IHJlbWVtYmVyZWQgPSB0aGlzLmF1dGhTZXJ2aWNlLmdldFJlbWVtYmVyZWQoKTtcbiAgICB0aGlzLmVtYWlsRmMgPSBuZXcgRm9ybUNvbnRyb2woJycpO1xuICAgIHRoaXMucGFzc3dvcmRGYyA9IG5ldyBGb3JtQ29udHJvbCgnJywge3ZhbGlkYXRvcnM6IFtWYWxpZGF0b3JzLnJlcXVpcmVkXX0pO1xuICAgIHRoaXMucmVtZW1iZXJGYyA9IG5ldyBGb3JtQ29udHJvbChyZW1lbWJlcmVkLnJlbWVtYmVyKTtcbiAgICB0aGlzLmZnID0gbmV3IEZvcm1Hcm91cCh7ZW1haWw6IHRoaXMuZW1haWxGYywgcGFzc3dvcmQ6IHRoaXMucGFzc3dvcmRGYywgcmVtZW1iZXI6IHRoaXMucmVtZW1iZXJGY30pO1xuICAgIHRoaXMuYXV0aC5jaGVja0FjdGlvbkNvZGUodGhpcy5vb2JDb2RlKVxuICAgICAgLnRoZW4oKHJlc3VsdDogYXV0aC5BY3Rpb25Db2RlSW5mbykgPT4ge1xuICAgICAgICB0aGlzLmluZm8gPSByZXN1bHQ7XG4gICAgICAgIHRoaXMuZW1haWxGYy5zZXRWYWx1ZShyZXN1bHQuZGF0YS5lbWFpbCk7XG4gICAgICAgIHRoaXMuc2NyZWVuID0gJ2Zvcm0nO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaCgoZXJyb3I6IGF1dGguRXJyb3IpID0+IHtcbiAgICAgICAgdGhpcy51bmhhbmRsZWRFcnJvciA9IGVycm9yO1xuICAgICAgICB0aGlzLnNjcmVlbiA9ICdlcnJvcic7XG4gICAgICB9KTtcbiAgfVxuXG4gIHN1Ym1pdCgpIHtcbiAgICB0aGlzLnN1Ym1pdHRpbmcgPSB0cnVlO1xuICAgIHRoaXMuYXV0aC5jb25maXJtUGFzc3dvcmRSZXNldCh0aGlzLm9vYkNvZGUsIHRoaXMucGFzc3dvcmRGYy52YWx1ZSlcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXV0aC5zaWduSW5XaXRoRW1haWxBbmRQYXNzd29yZCh0aGlzLmluZm8uZGF0YS5lbWFpbCwgdGhpcy5wYXNzd29yZEZjLnZhbHVlKTtcbiAgICAgIH0pXG4gICAgICAudGhlbigoY3JlZDogYXV0aC5Vc2VyQ3JlZGVudGlhbCkgPT4ge1xuICAgICAgICB0aGlzLmNyZWQgPSBjcmVkO1xuICAgICAgICByZXR1cm4gdGhpcy5hdXRoU2VydmljZS5zZXRSZW1lbWJlcmVkKHRoaXMucmVtZW1iZXJGYy52YWx1ZSA9PT0gdHJ1ZSwgdGhpcy5pbmZvLmRhdGEuZW1haWwpO1xuICAgICAgfSlcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgdGhpcy5zY3JlZW4gPSAnc3VjY2Vzcyc7XG4gICAgICAgIHRoaXMuc3VjY2Vzcy5lbWl0KHtcbiAgICAgICAgICBtb2RlOiAncmVzZXRQYXNzd29yZCcsXG4gICAgICAgICAgaW5mbzogdGhpcy5pbmZvLFxuICAgICAgICAgIGNyZWQ6IHRoaXMuY3JlZCxcbiAgICAgICAgICB1c2VyOiB0aGlzLmNyZWQudXNlclxuICAgICAgICB9KTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goKGVycm9yOiBhdXRoLkVycm9yKSA9PiB7XG4gICAgICAgIHRoaXMuc3VibWl0dGluZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLnBhc3N3b3JkRmMubWFya0FzRGlydHkoKTtcbiAgICAgICAgdGhpcy5wYXNzd29yZEZjLm1hcmtBc1RvdWNoZWQoKTtcbiAgICAgICAgc3dpdGNoIChlcnJvci5jb2RlKSB7XG4gICAgICAgICAgY2FzZSAnYXV0aC93ZWFrLXBhc3N3b3JkJzpcbiAgICAgICAgICAgIE5neEZpcmViYXNlQXV0aEZvcm1IZWxwZXIuc2V0RXJyb3JVbnRpbENoYW5nZWQodGhpcy5wYXNzd29yZEZjLCBlcnJvci5jb2RlKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICB0aGlzLnVuaGFuZGxlZEVycm9yID0gZXJyb3I7XG4gICAgICAgICAgICB0aGlzLnNjcmVlbiA9ICdlcnJvcic7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cblxufVxuIl19