@nowzoo/ngx-firebase-auth
Version:
Angular components for Firebase email-first sign in and out-of-band (oob) actions (reset password, etc).
281 lines (280 loc) • 30.2 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
import { Component, Input, Output, EventEmitter } from '@angular/core';
import { AngularFireAuth } from 'angularfire2/auth';
import { ActivatedRoute, Router } from '@angular/router';
import { auth } from 'firebase/app';
import { FormGroup, FormControl } from '@angular/forms';
import { getOAuthProviderIcon, getOAuthProviderName } from '../../shared';
import { NgxFirebaseAuthService } from '../../ngx-firebase-auth.service';
import { screenAnimation } from '../../shared';
var SignInOauthComponent = /** @class */ (function () {
function SignInOauthComponent(_afAuth, _svc, _route, _router) {
this._afAuth = _afAuth;
this._svc = _svc;
this._route = _route;
this._router = _router;
this.success = new EventEmitter();
this.emailChange = new EventEmitter();
this.rememberChange = new EventEmitter();
this.error = new EventEmitter();
this.screen = 'wait';
this.methodError = null;
this.getOAuthProviderIcon = getOAuthProviderIcon;
this.getOAuthProviderName = getOAuthProviderName;
this.formId = 'ngx-firebase-auth-sign-in-oauth-';
}
Object.defineProperty(SignInOauthComponent.prototype, "auth", {
get: /**
* @return {?}
*/
function () {
return this._afAuth.auth;
},
enumerable: true,
configurable: true
});
Object.defineProperty(SignInOauthComponent.prototype, "authService", {
get: /**
* @return {?}
*/
function () {
return this._svc;
},
enumerable: true,
configurable: true
});
Object.defineProperty(SignInOauthComponent.prototype, "route", {
get: /**
* @return {?}
*/
function () {
return this._route;
},
enumerable: true,
configurable: true
});
Object.defineProperty(SignInOauthComponent.prototype, "router", {
get: /**
* @return {?}
*/
function () {
return this._router;
},
enumerable: true,
configurable: true
});
/**
* @return {?}
*/
SignInOauthComponent.prototype.ngOnInit = /**
* @return {?}
*/
function () {
var _this = this;
this.rememberFc = new FormControl(this.remember);
this.rememberFc.valueChanges.subscribe(function (val) { return _this.rememberChange.emit(val); });
this.fg = new FormGroup({
remember: this.rememberFc
});
if (this.initialError) {
this.handleOAuthError(this.initialError);
}
else {
this.oAuthSignIn(this.providerId);
}
};
/**
* @param {?} id
* @param {?=} forceRedirect
* @return {?}
*/
SignInOauthComponent.prototype.oAuthSignIn = /**
* @param {?} id
* @param {?=} forceRedirect
* @return {?}
*/
function (id, forceRedirect) {
var _this = this;
this.methodError = null;
/** @type {?} */
var cred;
if (this.useOAuthPopup && forceRedirect !== true) {
this.getOAuthProvider(id)
.then(function (provider) {
return _this.auth.signInWithPopup(provider);
})
.then(function (result) {
cred = result;
return _this.authService.setRemembered(_this.rememberFc.value === true, result.user.email);
})
.then(function () {
_this.success.emit(cred);
})
.catch(function (error) { return _this.handleOAuthError(error, id); });
}
else {
this.router.navigate(['.'], { relativeTo: this.route, queryParams: { remember: this.rememberFc.value === true } })
.then(function () {
return _this.getOAuthProvider(id);
})
.then(function (provider) {
return _this.auth.signInWithRedirect(provider);
})
.catch(function (error) { return _this.handleOAuthError(error, id); });
}
};
/**
* @param {?} error
* @param {?=} providerId
* @return {?}
*/
SignInOauthComponent.prototype.handleOAuthError = /**
* @param {?} error
* @param {?=} providerId
* @return {?}
*/
function (error, providerId) {
var _this = this;
if (error['email'] && error['credential']) {
this.emailChange.emit(error['email']);
this.auth.fetchSignInMethodsForEmail(error['email'])
.then(function (results) {
error['methods'] = results;
error['accountHasPassword'] = results.indexOf('password') !== -1;
error['accountOAuthMethods'] = results.filter(function (id) { return id !== 'password'; });
_this.methodError = error;
_this.screen = 'methodError';
});
return;
}
switch (error.code) {
case 'auth/cancelled-popup-request':
case 'auth/popup-closed-by-user':
this.screen = 'retry';
break;
case 'auth/popup-blocked':
this.oAuthSignIn(providerId, true);
break;
default:
this.error.emit(error);
break;
}
};
/**
* @param {?} id
* @return {?}
*/
SignInOauthComponent.prototype.getOAuthProvider = /**
* @param {?} id
* @return {?}
*/
function (id) {
/** @type {?} */
var provider = null;
if (this.oAuthProviderFactory) {
provider = this.oAuthProviderFactory(id);
}
if (!provider) {
switch (id) {
case 'twitter.com':
provider = new auth.TwitterAuthProvider();
break;
case 'facebook.com':
provider = new auth.FacebookAuthProvider();
break;
case 'google.com':
provider = new auth.GoogleAuthProvider();
break;
case 'github.com':
provider = new auth.GithubAuthProvider();
break;
}
}
if (provider) {
return Promise.resolve(provider);
}
else {
return Promise.reject({
code: 'ngx-firebase-auth/no-provider-found',
message: "We could not create an OAuth provider for provider id \"" + id + "\"."
});
}
};
SignInOauthComponent.decorators = [
{ type: Component, args: [{
selector: 'ngx-firebase-auth-sign-in-oauth',
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=\"'methodError' === screen\" [@screen]=\"'in'\">\n <div class=\"alert alert-danger\">\n <i class=\"fas fa-exclamation-triangle fa-fw\" aria-hidden=\"true\"></i>\n We could not sign you in with {{methodError.credential.providerId}}.\n </div>\n\n <p class=\"text-muted\">\n Please sign in with one of the methods associated with\n {{methodError.email}}:\n </p>\n\n <div class=\"list-group\">\n <a\n *ngIf=\"methodError.accountHasPassword\"\n routerLink=\".\"\n [queryParams]=\"{action: 'signInPassword'}\"\n class=\"list-group-item list-group-item-action\">\n <i class=\"fas fa-unlock\" aria-hidden=\"true\"></i>\n <span class=\"ml-2\">Sign In with Your Password</span>\n </a>\n <button\n *ngFor=\"let id of methodError.accountOAuthMethods\"\n (click)=\"oAuthSignIn(id)\"\n class=\"list-group-item list-group-item-action\">\n <i [attr.class]=\"getOAuthProviderIcon(id)\" aria-hidden=\"true\"></i>\n <span class=\"ml-2\">Sign In with {{getOAuthProviderName(id)}}</span>\n </button>\n </div>\n\n <form [formGroup]=\"fg\">\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 </form>\n\n <p class=\"text-muted\">\n Is {{methodError.email}} not your email address?\n <a routerLink=\".\" [queryParams]=\"{action: 'signIn'}\">Start Over</a>\n </p>\n\n</div>\n\n<div *ngIf=\"'retry' === screen\" [@screen]=\"'in'\">\n <div class=\"alert alert-danger\">\n <i class=\"fas fa-exclamation-triangle fa-fw\" aria-hidden=\"true\"></i>\n It looks like you cancelled signing in with\n {{getOAuthProviderName(providerId)}}. Try again:\n </div>\n\n <div class=\"list-group\">\n <button\n (click)=\"oAuthSignIn(providerId)\"\n class=\"list-group-item list-group-item-action\">\n <i [attr.class]=\"getOAuthProviderIcon(providerId)\" aria-hidden=\"true\"></i>\n <span class=\"ml-2\">Sign In with {{getOAuthProviderName(providerId)}}</span>\n </button>\n </div>\n\n <form [formGroup]=\"fg\">\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 </form>\n\n\n <p class=\"text-muted\">\n <a routerLink=\".\" [queryParams]=\"{action: 'signIn'}\">Start Over</a>\n </p>\n\n</div>\n",
styles: [""],
animations: [screenAnimation]
},] },
];
/** @nocollapse */
SignInOauthComponent.ctorParameters = function () { return [
{ type: AngularFireAuth },
{ type: NgxFirebaseAuthService },
{ type: ActivatedRoute },
{ type: Router }
]; };
SignInOauthComponent.propDecorators = {
providerId: [{ type: Input }],
initialError: [{ type: Input }],
useOAuthPopup: [{ type: Input }],
oAuthProviderFactory: [{ type: Input }],
email: [{ type: Input }],
remember: [{ type: Input }],
success: [{ type: Output }],
emailChange: [{ type: Output }],
rememberChange: [{ type: Output }],
error: [{ type: Output }]
};
return SignInOauthComponent;
}());
export { SignInOauthComponent };
if (false) {
/** @type {?} */
SignInOauthComponent.prototype.providerId;
/** @type {?} */
SignInOauthComponent.prototype.initialError;
/** @type {?} */
SignInOauthComponent.prototype.useOAuthPopup;
/** @type {?} */
SignInOauthComponent.prototype.oAuthProviderFactory;
/** @type {?} */
SignInOauthComponent.prototype.email;
/** @type {?} */
SignInOauthComponent.prototype.remember;
/** @type {?} */
SignInOauthComponent.prototype.success;
/** @type {?} */
SignInOauthComponent.prototype.emailChange;
/** @type {?} */
SignInOauthComponent.prototype.rememberChange;
/** @type {?} */
SignInOauthComponent.prototype.error;
/** @type {?} */
SignInOauthComponent.prototype.screen;
/** @type {?} */
SignInOauthComponent.prototype.methodError;
/** @type {?} */
SignInOauthComponent.prototype.getOAuthProviderIcon;
/** @type {?} */
SignInOauthComponent.prototype.getOAuthProviderName;
/** @type {?} */
SignInOauthComponent.prototype.fg;
/** @type {?} */
SignInOauthComponent.prototype.rememberFc;
/** @type {?} */
SignInOauthComponent.prototype.formId;
/** @type {?} */
SignInOauthComponent.prototype._afAuth;
/** @type {?} */
SignInOauthComponent.prototype._svc;
/** @type {?} */
SignInOauthComponent.prototype._route;
/** @type {?} */
SignInOauthComponent.prototype._router;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnbi1pbi1vYXV0aC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9Abm93em9vL25neC1maXJlYmFzZS1hdXRoLyIsInNvdXJjZXMiOlsibGliL3NpZ24taW4vc2lnbi1pbi1vYXV0aC9zaWduLWluLW9hdXRoLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUFFLFNBQVMsRUFBVSxLQUFLLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMvRSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDcEQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3BDLE9BQU8sRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFeEQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLG9CQUFvQixFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQzFFLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ3pFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxjQUFjLENBQUM7O0lBZ0k3Qyw4QkFDVSxTQUNBLE1BQ0EsUUFDQTtRQUhBLFlBQU8sR0FBUCxPQUFPO1FBQ1AsU0FBSSxHQUFKLElBQUk7UUFDSixXQUFNLEdBQU4sTUFBTTtRQUNOLFlBQU8sR0FBUCxPQUFPO3VCQWxCc0MsSUFBSSxZQUFZLEVBQUU7MkJBQzNCLElBQUksWUFBWSxFQUFFOzhCQUNkLElBQUksWUFBWSxFQUFFO3FCQUN4QixJQUFJLFlBQVksRUFBRTtzQkFHbkIsTUFBTTsyQkFDbkIsSUFBSTtvQ0FDWCxvQkFBb0I7b0NBQ3BCLG9CQUFvQjtzQkFHbEMsa0NBQWtDO0tBT3RDO0lBRUwsc0JBQUksc0NBQUk7Ozs7UUFBUjtZQUNFLE1BQU0sQ0FBQyxJ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SUFBSSxDQUFDLENBQUM7WUFDTixNQUFNLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQztnQkFDcEIsSUFBSSxFQUFFLHFDQUFxQztnQkFDM0MsT0FBTyxFQUFFLDZEQUEwRCxFQUFFLFFBQUk7YUFDMUUsQ0FBQyxDQUFDO1NBQ0o7S0FDRjs7Z0JBdFBGLFNBQVMsU0FBQztvQkFDVCxRQUFRLEVBQUUsaUNBQWlDO29CQUMzQyxRQUFRLEVBQUUsMGxHQWlHWDtvQkFDQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLENBQUM7b0JBQ1osVUFBVSxFQUFFLENBQUUsZUFBZSxDQUFFO2lCQUNoQzs7OztnQkFoSFEsZUFBZTtnQkFNZixzQkFBc0I7Z0JBTHRCLGNBQWM7Z0JBQUUsTUFBTTs7OzZCQWtINUIsS0FBSzsrQkFDTCxLQUFLO2dDQUNMLEtBQUs7dUNBQ0wsS0FBSzt3QkFDTCxLQUFLOzJCQUNMLEtBQUs7MEJBQ0wsTUFBTTs4QkFDTixNQUFNO2lDQUNOLE1BQU07d0JBQ04sTUFBTTs7K0JBN0hUOztTQWtIYSxvQkFBb0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgSW5wdXQsIE91dHB1dCwgRXZlbnRFbWl0dGVyIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBBbmd1bGFyRmlyZUF1dGggfSBmcm9tICdhbmd1bGFyZmlyZTIvYXV0aCc7XG5pbXBvcnQgeyBBY3RpdmF0ZWRSb3V0ZSwgUm91dGVyIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7IGF1dGggfSBmcm9tICdmaXJlYmFzZS9hcHAnO1xuaW1wb3J0IHsgRm9ybUdyb3VwLCBGb3JtQ29udHJvbCB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcblxuaW1wb3J0IHsgZ2V0T0F1dGhQcm92aWRlckljb24sIGdldE9BdXRoUHJvdmlkZXJOYW1lIH0gZnJvbSAnLi4vLi4vc2hhcmVkJztcbmltcG9ydCB7IE5neEZpcmViYXNlQXV0aFNlcnZpY2UgfSBmcm9tICcuLi8uLi9uZ3gtZmlyZWJhc2UtYXV0aC5zZXJ2aWNlJztcbmltcG9ydCB7IHNjcmVlbkFuaW1hdGlvbiB9IGZyb20gJy4uLy4uL3NoYXJlZCc7XG5cblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbmd4LWZpcmViYXNlLWF1dGgtc2lnbi1pbi1vYXV0aCcsXG4gIHRlbXBsYXRlOiBgPGRpdiAqbmdJZj1cIid3YWl0JyA9PT0gc2NyZWVuXCIgW0BzY3JlZW5dPVwiJ2luJ1wiPlxuICA8ZGl2IGNsYXNzPVwiYWxlcnQgYWxlcnQtc2Vjb25kYXJ5XCI+XG4gICAgPGkgY2xhc3M9XCJmYXMgZmEtc3BpbiBmYS1zcGlubmVyIGZhLWZ3XCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+PC9pPlxuICAgIFBsZWFzZSB3YWl0Li4uXG4gIDwvZGl2PlxuPC9kaXY+XG5cbjxkaXYgKm5nSWY9XCInbWV0aG9kRXJyb3InID09PSBzY3JlZW5cIiBbQHNjcmVlbl09XCInaW4nXCI+XG4gIDxkaXYgY2xhc3M9XCJhbGVydCBhbGVydC1kYW5nZXJcIj5cbiAgICA8aSBjbGFzcz1cImZhcyBmYS1leGNsYW1hdGlvbi10cmlhbmdsZSBmYS1md1wiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjwvaT5cbiAgICBXZSBjb3VsZCBub3Qgc2lnbiB5b3UgaW4gd2l0aCB7e21ldGhvZEVycm9yLmNyZWRlbnRpYWwucHJvdmlkZXJJZH19LlxuICA8L2Rpdj5cblxuICA8cCBjbGFzcz1cInRleHQtbXV0ZWRcIj5cbiAgICBQbGVhc2Ugc2lnbiBpbiB3aXRoIG9uZSBvZiB0aGUgbWV0aG9kcyBhc3NvY2lhdGVkIHdpdGhcbiAgICB7e21ldGhvZEVycm9yLmVtYWlsfX06XG4gIDwvcD5cblxuICA8ZGl2IGNsYXNzPVwibGlzdC1ncm91cFwiPlxuICAgIDxhXG4gICAgICAqbmdJZj1cIm1ldGhvZEVycm9yLmFjY291bnRIYXNQYXNzd29yZFwiXG4gICAgICByb3V0ZXJMaW5rPVwiLlwiXG4gICAgICBbcXVlcnlQYXJhbXNdPVwie2FjdGlvbjogJ3NpZ25JblBhc3N3b3JkJ31cIlxuICAgICAgY2xhc3M9XCJsaXN0LWdyb3VwLWl0ZW0gbGlzdC1ncm91cC1pdGVtLWFjdGlvblwiPlxuICAgICAgPGkgY2xhc3M9XCJmYXMgZmEtdW5sb2NrXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+PC9pPlxuICAgICAgPHNwYW4gY2xhc3M9XCJtbC0yXCI+U2lnbiBJbiB3aXRoIFlvdXIgUGFzc3dvcmQ8L3NwYW4+XG4gICAgPC9hPlxuICAgIDxidXR0b25cbiAgICAgICpuZ0Zvcj1cImxldCBpZCBvZiBtZXRob2RFcnJvci5hY2NvdW50T0F1dGhNZXRob2RzXCJcbiAgICAgIChjbGljayk9XCJvQXV0aFNpZ25JbihpZClcIlxuICAgICAgY2xhc3M9XCJsaXN0LWdyb3VwLWl0ZW0gbGlzdC1ncm91cC1pdGVtLWFjdGlvblwiPlxuICAgICAgPGkgW2F0dHIuY2xhc3NdPVwiZ2V0T0F1dGhQcm92aWRlckljb24oaWQpXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+PC9pPlxuICAgICAgPHNwYW4gY2xhc3M9XCJtbC0yXCI+U2lnbiBJbiB3aXRoIHt7Z2V0T0F1dGhQcm92aWRlck5hbWUoaWQpfX08L3NwYW4+XG4gICAgPC9idXR0b24+XG4gIDwvZGl2PlxuXG4gIDxmb3JtIFtmb3JtR3JvdXBdPVwiZmdcIj5cbiAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cFwiPlxuICAgICAgPGRpdiBjbGFzcz1cImZvcm0tY2hlY2tcIj5cbiAgICAgICAgPGlucHV0XG4gICAgICAgICAgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0XCJcbiAgICAgICAgICB0eXBlPVwiY2hlY2tib3hcIlxuICAgICAgICAgIFt2YWx1ZV09XCJ0cnVlXCJcbiAgICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJyZW1lbWJlclwiXG4gICAgICAgICAgW2F0dHIuaWRdPVwiZm9ybUlkICsgJ3JlbWVtYmVyJ1wiPlxuICAgICAgICA8bGFiZWwgY2xhc3M9XCJmb3JtLWNoZWNrLWxhYmVsXCIgW2F0dHIuZm9yXT1cImZvcm1JZCArICdyZW1lbWJlcidcIj5cbiAgICAgICAgICBSZW1lbWJlciBtZSBvbiB0aGlzIGRldmljZS5cbiAgICAgICAgPC9sYWJlbD5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Zvcm0+XG5cbiAgPHAgY2xhc3M9XCJ0ZXh0LW11dGVkXCI+XG4gICAgSXMge3ttZXRob2RFcnJvci5lbWFpbH19IG5vdCB5b3VyIGVtYWlsIGFkZHJlc3M/XG4gICAgPGEgcm91dGVyTGluaz1cIi5cIiBbcXVlcnlQYXJhbXNdPVwie2FjdGlvbjogJ3NpZ25Jbid9XCI+U3RhcnQgT3ZlcjwvYT5cbiAgPC9wPlxuXG48L2Rpdj5cblxuPGRpdiAqbmdJZj1cIidyZXRyeScgPT09IHNjcmVlblwiIFtAc2NyZWVuXT1cIidpbidcIj5cbiAgPGRpdiBjbGFzcz1cImFsZXJ0IGFsZXJ0LWRhbmdlclwiPlxuICAgIDxpIGNsYXNzPVwiZmFzIGZhLWV4Y2xhbWF0aW9uLXRyaWFuZ2xlIGZhLWZ3XCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+PC9pPlxuICAgIEl0IGxvb2tzIGxpa2UgeW91IGNhbmNlbGxlZCBzaWduaW5nIGluIHdpdGhcbiAgICB7e2dldE9BdXRoUHJvdmlkZXJOYW1lKHByb3ZpZGVySWQpfX0uIFRyeSBhZ2FpbjpcbiAgPC9kaXY+XG5cbiAgPGRpdiBjbGFzcz1cImxpc3QtZ3JvdXBcIj5cbiAgICA8YnV0dG9uXG4gICAgICAoY2xpY2spPVwib0F1dGhTaWduSW4ocHJvdmlkZXJJZClcIlxuICAgICAgY2xhc3M9XCJsaXN0LWdyb3VwLWl0ZW0gbGlzdC1ncm91cC1pdGVtLWFjdGlvblwiPlxuICAgICAgPGkgW2F0dHIuY2xhc3NdPVwiZ2V0T0F1dGhQcm92aWRlckljb24ocHJvdmlkZXJJZClcIiBhcmlhLWhpZGRlbj1cInRydWVcIj48L2k+XG4gICAgICA8c3BhbiBjbGFzcz1cIm1sLTJcIj5TaWduIEluIHdpdGgge3tnZXRPQXV0aFByb3ZpZGVyTmFtZShwcm92aWRlcklkKX19PC9zcGFuPlxuICAgIDwvYnV0dG9uPlxuICA8L2Rpdj5cblxuICA8Zm9ybSBbZm9ybUdyb3VwXT1cImZnXCI+XG4gICAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXBcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWNoZWNrXCI+XG4gICAgICAgIDxpbnB1dFxuICAgICAgICAgIGNsYXNzPVwiZm9ybS1jaGVjay1pbnB1dFwiXG4gICAgICAgICAgdHlwZT1cImNoZWNrYm94XCJcbiAgICAgICAgICBbdmFsdWVdPVwidHJ1ZVwiXG4gICAgICAgICAgZm9ybUNvbnRyb2xOYW1lPVwicmVtZW1iZXJcIlxuICAgICAgICAgIFthdHRyLmlkXT1cImZvcm1JZCArICdyZW1lbWJlcidcIj5cbiAgICAgICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1jaGVjay1sYWJlbFwiIFthdHRyLmZvcl09XCJmb3JtSWQgKyAncmVtZW1iZXInXCI+XG4gICAgICAgICAgUmVtZW1iZXIgbWUgb24gdGhpcyBkZXZpY2UuXG4gICAgICAgIDwvbGFiZWw+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9mb3JtPlxuXG5cbiAgPHAgY2xhc3M9XCJ0ZXh0LW11dGVkXCI+XG4gICAgPGEgcm91dGVyTGluaz1cIi5cIiBbcXVlcnlQYXJhbXNdPVwie2FjdGlvbjogJ3NpZ25Jbid9XCI+U3RhcnQgT3ZlcjwvYT5cbiAgPC9wPlxuXG48L2Rpdj5cbmAsXG4gIHN0eWxlczogW2BgXSxcbiAgYW5pbWF0aW9uczogWyBzY3JlZW5BbmltYXRpb24gXVxufSlcbmV4cG9ydCBjbGFzcyBTaWduSW5PYXV0aENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG5cbiAgQElucHV0KCkgcHJvdmlkZXJJZDogc3RyaW5nO1xuICBASW5wdXQoKSBpbml0aWFsRXJyb3I6IGF1dGguRXJyb3I7XG4gIEBJbnB1dCgpIHVzZU9BdXRoUG9wdXA6IGJvb2xlYW47XG4gIEBJbnB1dCgpIG9BdXRoUHJvdmlkZXJGYWN0b3J5OiAocHJvdmlkZXJJZDogc3RyaW5nKSA9PiBhdXRoLkF1dGhQcm92aWRlcjtcbiAgQElucHV0KCkgZW1haWw6IHN0cmluZztcbiAgQElucHV0KCkgcmVtZW1iZXI6IGJvb2xlYW47XG4gIEBPdXRwdXQoKSBzdWNjZXNzOiBFdmVudEVtaXR0ZXI8YXV0aC5Vc2VyQ3JlZGVudGlhbD4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIEBPdXRwdXQoKSBlbWFpbENoYW5nZTogRXZlbnRFbWl0dGVyPHN0cmluZz4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIEBPdXRwdXQoKSByZW1lbWJlckNoYW5nZTogRXZlbnRFbWl0dGVyPGJvb2xlYW4+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBAT3V0cHV0KCkgZXJyb3I6IEV2ZW50RW1pdHRlcjxhdXRoLkVycm9yPiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuXG4gIHNjcmVlbjogJ3dhaXQnIHwgJ21ldGhvZEVycm9yJyB8ICdyZXRyeScgPSAnd2FpdCc7XG4gIG1ldGhvZEVycm9yOiBhdXRoLkVycm9yfGFueSA9IG51bGw7XG4gIGdldE9BdXRoUHJvdmlkZXJJY29uID0gZ2V0T0F1dGhQcm92aWRlckljb247XG4gIGdldE9BdXRoUHJvdmlkZXJOYW1lID0gZ2V0T0F1dGhQcm92aWRlck5hbWU7XG4gIGZnOiBGb3JtR3JvdXA7XG4gIHJlbWVtYmVyRmM6IEZvcm1Db250cm9sO1xuICBmb3JtSWQgPSAnbmd4LWZpcmViYXNlLWF1dGgtc2lnbi1pbi1vYXV0aC0nO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgX2FmQXV0aDogQW5ndWxhckZpcmVBdXRoLFxuICAgIHByaXZhdGUgX3N2YzogTmd4RmlyZWJhc2VBdXRoU2VydmljZSxcbiAgICBwcml2YXRlIF9yb3V0ZTogQWN0aXZhdGVkUm91dGUsXG4gICAgcHJpdmF0ZSBfcm91dGVyOiBSb3V0ZXJcbiAgKSB7IH1cblxuICBnZXQgYXV0aCgpOiBhdXRoLkF1dGgge1xuICAgIHJldHVybiB0aGlzLl9hZkF1dGguYXV0aDtcbiAgfVxuXG4gIGdldCBhdXRoU2VydmljZSgpOiBOZ3hGaXJlYmFzZUF1dGhTZXJ2aWNlIHtcbiAgICByZXR1cm4gdGhpcy5fc3ZjO1xuICB9XG5cbiAgZ2V0IHJvdXRlKCk6IEFjdGl2YXRlZFJvdXRlIHtcbiAgICByZXR1cm4gdGhpcy5fcm91dGU7XG4gIH1cblxuICBnZXQgcm91dGVyKCk6IFJvdXRlciB7XG4gICAgcmV0dXJuIHRoaXMuX3JvdXRlcjtcbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIHRoaXMucmVtZW1iZXJGYyA9IG5ldyBGb3JtQ29udHJvbCh0aGlzLnJlbWVtYmVyKTtcbiAgICB0aGlzLnJlbWVtYmVyRmMudmFsdWVDaGFuZ2VzLnN1YnNjcmliZSh2YWwgPT4gdGhpcy5yZW1lbWJlckNoYW5nZS5lbWl0KHZhbCkpO1xuICAgIHRoaXMuZmcgPSBuZXcgRm9ybUdyb3VwKHtcbiAgICAgIHJlbWVtYmVyOiB0aGlzLnJlbWVtYmVyRmNcbiAgICB9KTtcbiAgICBpZiAodGhpcy5pbml0aWFsRXJyb3IpIHtcbiAgICAgIHRoaXMuaGFuZGxlT0F1dGhFcnJvcih0aGlzLmluaXRpYWxFcnJvcik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMub0F1dGhTaWduSW4odGhpcy5wcm92aWRlcklkKTtcbiAgICB9XG4gIH1cblxuXG4gIG9BdXRoU2lnbkluKGlkOiBzdHJpbmcsIGZvcmNlUmVkaXJlY3Q/OiBib29sZWFuKSB7XG4gICAgdGhpcy5tZXRob2RFcnJvciA9IG51bGw7XG4gICAgbGV0IGNyZWQ6IGF1dGguVXNlckNyZWRlbnRpYWw7XG4gICAgaWYgKHRoaXMudXNlT0F1dGhQb3B1cCAgJiYgZm9yY2VSZWRpcmVjdCAhPT0gdHJ1ZSkge1xuICAgICAgdGhpcy5nZXRPQXV0aFByb3ZpZGVyKGlkKVxuICAgICAgICAudGhlbihwcm92aWRlciA9PiB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuYXV0aC5zaWduSW5XaXRoUG9wdXAocHJvdmlkZXIpO1xuICAgICAgICB9KVxuICAgICAgICAudGhlbigocmVzdWx0OiBhdXRoLlVzZXJDcmVkZW50aWFsKSA9PiB7XG4gICAgICAgICAgY3JlZCA9IHJlc3VsdDtcbiAgICAgICAgICByZXR1cm4gdGhpcy5hdXRoU2VydmljZS5zZXRSZW1lbWJlcmVkKHRoaXMucmVtZW1iZXJGYy52YWx1ZSA9PT0gdHJ1ZSwgcmVzdWx0LnVzZXIuZW1haWwpO1xuICAgICAgICB9KVxuICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgdGhpcy5zdWNjZXNzLmVtaXQoY3JlZCk7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB0aGlzLmhhbmRsZU9BdXRoRXJyb3IoZXJyb3IsIGlkKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucm91dGVyLm5hdmlnYXRlKFsnLiddLCB7cmVsYXRpdmVUbzogdGhpcy5yb3V0ZSwgcXVlcnlQYXJhbXM6IHtyZW1lbWJlcjogdGhpcy5yZW1lbWJlckZjLnZhbHVlID09PSB0cnVlfX0pXG4gICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5nZXRPQXV0aFByb3ZpZGVyKGlkKTtcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4ocHJvdmlkZXIgPT4ge1xuICAgICAgICAgIHJldHVybiB0aGlzLmF1dGguc2lnbkluV2l0aFJlZGlyZWN0KHByb3ZpZGVyKTtcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHRoaXMuaGFuZGxlT0F1dGhFcnJvcihlcnJvciwgaWQpKTtcbiAgICB9XG4gIH1cblxuICBoYW5kbGVPQXV0aEVycm9yKGVycm9yOiBhdXRoLkVycm9yLCBwcm92aWRlcklkPzogc3RyaW5nKSB7XG4gICAgaWYgKGVycm9yWydlbWFpbCddICYmIGVycm9yWydjcmVkZW50aWFsJ10pIHtcbiAgICAgIHRoaXMuZW1haWxDaGFuZ2UuZW1pdChlcnJvclsnZW1haWwnXSk7XG4gICAgICB0aGlzLmF1dGguZmV0Y2hTaWduSW5NZXRob2RzRm9yRW1haWwoZXJyb3JbJ2VtYWlsJ10pXG4gICAgICAgIC50aGVuKHJlc3VsdHMgPT4ge1xuICAgICAgICAgIGVycm9yWydtZXRob2RzJ10gPSByZXN1bHRzO1xuICAgICAgICAgIGVycm9yWydhY2NvdW50SGFzUGFzc3dvcmQnXSA9IHJlc3VsdHMuaW5kZXhPZigncGFzc3dvcmQnKSAhPT0gLTE7XG4gICAgICAgICAgZXJyb3JbJ2FjY291bnRPQXV0aE1ldGhvZHMnXSA9IHJlc3VsdHMuZmlsdGVyKGlkID0+IGlkICE9PSAncGFzc3dvcmQnKTtcbiAgICAgICAgICB0aGlzLm1ldGhvZEVycm9yID0gZXJyb3I7XG4gICAgICAgICAgdGhpcy5zY3JlZW4gPSAnbWV0aG9kRXJyb3InO1xuICAgICAgICB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgc3dpdGNoIChlcnJvci5jb2RlKSB7XG4gICAgICBjYXNlICdhdXRoL2NhbmNlbGxlZC1wb3B1cC1yZXF1ZXN0JzpcbiAgICAgIGNhc2UgJ2F1dGgvcG9wdXAtY2xvc2VkLWJ5LXVzZXInOlxuICAgICAgICB0aGlzLnNjcmVlbiA9ICdyZXRyeSc7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnYXV0aC9wb3B1cC1ibG9ja2VkJzpcbiAgICAgICAgdGhpcy5vQXV0aFNpZ25Jbihwcm92aWRlcklkLCB0cnVlKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aGlzLmVycm9yLmVtaXQoZXJyb3IpO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICBnZXRPQXV0aFByb3ZpZGVyKGlkOiBzdHJpbmcpOiBQcm9taXNlPGF1dGguQXV0aFByb3ZpZGVyPiB7XG4gICAgbGV0IHByb3ZpZGVyOiBhdXRoLkF1dGhQcm92aWRlciA9IG51bGw7XG4gICAgaWYgKHRoaXMub0F1dGhQcm92aWRlckZhY3RvcnkpIHtcbiAgICAgIHByb3ZpZGVyID0gdGhpcy5vQXV0aFByb3ZpZGVyRmFjdG9yeShpZCk7XG4gICAgfVxuICAgIGlmICghIHByb3ZpZGVyKSB7XG4gICAgICBzd2l0Y2ggKGlkKSB7XG4gICAgICAgIGNhc2UgJ3R3aXR0ZXIuY29tJzpcbiAgICAgICAgICBwcm92aWRlciA9IG5ldyBhdXRoLlR3aXR0ZXJBdXRoUHJvdmlkZXIoKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnZmFjZWJvb2suY29tJzpcbiAgICAgICAgICBwcm92aWRlciA9IG5ldyBhdXRoLkZhY2Vib29rQXV0aFByb3ZpZGVyKCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ2dvb2dsZS5jb20nOlxuICAgICAgICAgIHByb3ZpZGVyID0gbmV3IGF1dGguR29vZ2xlQXV0aFByb3ZpZGVyKCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ2dpdGh1Yi5jb20nOlxuICAgICAgICAgIHByb3ZpZGVyID0gbmV3IGF1dGguR2l0aHViQXV0aFByb3ZpZGVyKCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChwcm92aWRlcikge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShwcm92aWRlcik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdCh7XG4gICAgICAgIGNvZGU6ICduZ3gtZmlyZWJhc2UtYXV0aC9uby1wcm92aWRlci1mb3VuZCcsXG4gICAgICAgIG1lc3NhZ2U6IGBXZSBjb3VsZCBub3QgY3JlYXRlIGFuIE9BdXRoIHByb3ZpZGVyIGZvciBwcm92aWRlciBpZCBcIiR7aWR9XCIuYFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbn1cbiJdfQ==