UNPKG

@nowzoo/ngx-firebase-auth

Version:

Angular components for Firebase email-first sign in and out-of-band (oob) actions (reset password, etc).

346 lines (333 loc) 28.5 kB
/** * @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'; export class SignInOauthComponent { /** * @param {?} _afAuth * @param {?} _svc * @param {?} _route * @param {?} _router */ constructor(_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-'; } /** * @return {?} */ get auth() { return this._afAuth.auth; } /** * @return {?} */ get authService() { return this._svc; } /** * @return {?} */ get route() { return this._route; } /** * @return {?} */ get router() { return this._router; } /** * @return {?} */ ngOnInit() { this.rememberFc = new FormControl(this.remember); this.rememberFc.valueChanges.subscribe(val => 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 {?} */ oAuthSignIn(id, forceRedirect) { this.methodError = null; /** @type {?} */ let cred; if (this.useOAuthPopup && forceRedirect !== true) { this.getOAuthProvider(id) .then(provider => { return this.auth.signInWithPopup(provider); }) .then((result) => { cred = result; return this.authService.setRemembered(this.rememberFc.value === true, result.user.email); }) .then(() => { this.success.emit(cred); }) .catch(error => this.handleOAuthError(error, id)); } else { this.router.navigate(['.'], { relativeTo: this.route, queryParams: { remember: this.rememberFc.value === true } }) .then(() => { return this.getOAuthProvider(id); }) .then(provider => { return this.auth.signInWithRedirect(provider); }) .catch(error => this.handleOAuthError(error, id)); } } /** * @param {?} error * @param {?=} providerId * @return {?} */ handleOAuthError(error, providerId) { if (error['email'] && error['credential']) { this.emailChange.emit(error['email']); this.auth.fetchSignInMethodsForEmail(error['email']) .then(results => { error['methods'] = results; error['accountHasPassword'] = results.indexOf('password') !== -1; error['accountOAuthMethods'] = results.filter(id => 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 {?} */ getOAuthProvider(id) { /** @type {?} */ let 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'"> <div class="alert alert-secondary"> <i class="fas fa-spin fa-spinner fa-fw" aria-hidden="true"></i> Please wait... </div> </div> <div *ngIf="'methodError' === screen" [@screen]="'in'"> <div class="alert alert-danger"> <i class="fas fa-exclamation-triangle fa-fw" aria-hidden="true"></i> We could not sign you in with {{methodError.credential.providerId}}. </div> <p class="text-muted"> Please sign in with one of the methods associated with {{methodError.email}}: </p> <div class="list-group"> <a *ngIf="methodError.accountHasPassword" routerLink="." [queryParams]="{action: 'signInPassword'}" class="list-group-item list-group-item-action"> <i class="fas fa-unlock" aria-hidden="true"></i> <span class="ml-2">Sign In with Your Password</span> </a> <button *ngFor="let id of methodError.accountOAuthMethods" (click)="oAuthSignIn(id)" class="list-group-item list-group-item-action"> <i [attr.class]="getOAuthProviderIcon(id)" aria-hidden="true"></i> <span class="ml-2">Sign In with {{getOAuthProviderName(id)}}</span> </button> </div> <form [formGroup]="fg"> <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> </form> <p class="text-muted"> Is {{methodError.email}} not your email address? <a routerLink="." [queryParams]="{action: 'signIn'}">Start Over</a> </p> </div> <div *ngIf="'retry' === screen" [@screen]="'in'"> <div class="alert alert-danger"> <i class="fas fa-exclamation-triangle fa-fw" aria-hidden="true"></i> It looks like you cancelled signing in with {{getOAuthProviderName(providerId)}}. Try again: </div> <div class="list-group"> <button (click)="oAuthSignIn(providerId)" class="list-group-item list-group-item-action"> <i [attr.class]="getOAuthProviderIcon(providerId)" aria-hidden="true"></i> <span class="ml-2">Sign In with {{getOAuthProviderName(providerId)}}</span> </button> </div> <form [formGroup]="fg"> <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> </form> <p class="text-muted"> <a routerLink="." [queryParams]="{action: 'signIn'}">Start Over</a> </p> </div> `, styles: [``], animations: [screenAnimation] },] }, ]; /** @nocollapse */ SignInOauthComponent.ctorParameters = () => [ { 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 }] }; 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnbi1pbi1vYXV0aC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9Abm93em9vL25neC1maXJlYmFzZS1hdXRoLyIsInNvdXJjZXMiOlsibGliL3NpZ24taW4vc2lnbi1pbi1vYXV0aC9zaWduLWluLW9hdXRoLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUFFLFNBQVMsRUFBVSxLQUFLLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMvRSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDcEQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3BDLE9BQU8sRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFeEQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLG9CQUFvQixFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQzFFLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ3pFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxjQUFjLENBQUM7QUEwRy9DLE1BQU07Ozs7Ozs7SUFzQkosWUFDVSxTQUNBLE1BQ0EsUUFDQTtRQUhBLFlBQU8sR0FBUCxPQUFPO1FBQ1AsU0FBSSxHQUFKLElBQUk7UUFDSixXQUFNLEdBQU4sTUFBTTtRQUNOLFlBQU8sR0FBUCxPQUFPO3VCQWxCc0MsSUFBSSxZQUFZLEVBQUU7MkJBQzNCLElBQUksWUFBWSxFQUFFOzhCQUNkLElBQUksWUFBWSxFQUFFO3FCQUN4QixJQUFJLFlBQVksRUFBRTtzQkFHbkIsTUFBTTsyQkFDbkIsSUFBSTtvQ0FDWCxvQkFBb0I7b0NBQ3BCLG9CQUFvQjtzQkFHbEMsa0NBQWtDO0tBT3RDOzs7O0lBRUwsSUFBSSxJQUFJO1FBQ04sTUFB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QUFDO1NBQ0o7S0FDRjs7O1lBdFBGLFNBQVMsU0FBQztnQkFDVCxRQUFRLEVBQUUsaUNBQWlDO2dCQUMzQyxRQUFRLEVBQUU7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Q0FpR1g7Z0JBQ0MsTUFBTSxFQUFFLENBQUMsRUFBRSxDQUFDO2dCQUNaLFVBQVUsRUFBRSxDQUFFLGVBQWUsQ0FBRTthQUNoQzs7OztZQWhIUSxlQUFlO1lBTWYsc0JBQXNCO1lBTHRCLGNBQWM7WUFBRSxNQUFNOzs7eUJBa0g1QixLQUFLOzJCQUNMLEtBQUs7NEJBQ0wsS0FBSzttQ0FDTCxLQUFLO29CQUNMLEtBQUs7dUJBQ0wsS0FBSztzQkFDTCxNQUFNOzBCQUNOLE1BQU07NkJBQ04sTUFBTTtvQkFDTixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBPbkluaXQsIElucHV0LCBPdXRwdXQsIEV2ZW50RW1pdHRlciB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQW5ndWxhckZpcmVBdXRoIH0gZnJvbSAnYW5ndWxhcmZpcmUyL2F1dGgnO1xuaW1wb3J0IHsgQWN0aXZhdGVkUm91dGUsIFJvdXRlciB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBhdXRoIH0gZnJvbSAnZmlyZWJhc2UvYXBwJztcbmltcG9ydCB7IEZvcm1Hcm91cCwgRm9ybUNvbnRyb2wgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5cbmltcG9ydCB7IGdldE9BdXRoUHJvdmlkZXJJY29uLCBnZXRPQXV0aFByb3ZpZGVyTmFtZSB9IGZyb20gJy4uLy4uL3NoYXJlZCc7XG5pbXBvcnQgeyBOZ3hGaXJlYmFzZUF1dGhTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vbmd4LWZpcmViYXNlLWF1dGguc2VydmljZSc7XG5pbXBvcnQgeyBzY3JlZW5BbmltYXRpb24gfSBmcm9tICcuLi8uLi9zaGFyZWQnO1xuXG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ25neC1maXJlYmFzZS1hdXRoLXNpZ24taW4tb2F1dGgnLFxuICB0ZW1wbGF0ZTogYDxkaXYgKm5nSWY9XCInd2FpdCcgPT09IHNjcmVlblwiIFtAc2NyZWVuXT1cIidpbidcIj5cbiAgPGRpdiBjbGFzcz1cImFsZXJ0IGFsZXJ0LXNlY29uZGFyeVwiPlxuICAgIDxpIGNsYXNzPVwiZmFzIGZhLXNwaW4gZmEtc3Bpbm5lciBmYS1md1wiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjwvaT5cbiAgICBQbGVhc2Ugd2FpdC4uLlxuICA8L2Rpdj5cbjwvZGl2PlxuXG48ZGl2ICpuZ0lmPVwiJ21ldGhvZEVycm9yJyA9PT0gc2NyZWVuXCIgW0BzY3JlZW5dPVwiJ2luJ1wiPlxuICA8ZGl2IGNsYXNzPVwiYWxlcnQgYWxlcnQtZGFuZ2VyXCI+XG4gICAgPGkgY2xhc3M9XCJmYXMgZmEtZXhjbGFtYXRpb24tdHJpYW5nbGUgZmEtZndcIiBhcmlhLWhpZGRlbj1cInRydWVcIj48L2k+XG4gICAgV2UgY291bGQgbm90IHNpZ24geW91IGluIHdpdGgge3ttZXRob2RFcnJvci5jcmVkZW50aWFsLnByb3ZpZGVySWR9fS5cbiAgPC9kaXY+XG5cbiAgPHAgY2xhc3M9XCJ0ZXh0LW11dGVkXCI+XG4gICAgUGxlYXNlIHNpZ24gaW4gd2l0aCBvbmUgb2YgdGhlIG1ldGhvZHMgYXNzb2NpYXRlZCB3aXRoXG4gICAge3ttZXRob2RFcnJvci5lbWFpbH19OlxuICA8L3A+XG5cbiAgPGRpdiBjbGFzcz1cImxpc3QtZ3JvdXBcIj5cbiAgICA8YVxuICAgICAgKm5nSWY9XCJtZXRob2RFcnJvci5hY2NvdW50SGFzUGFzc3dvcmRcIlxuICAgICAgcm91dGVyTGluaz1cIi5cIlxuICAgICAgW3F1ZXJ5UGFyYW1zXT1cInthY3Rpb246ICdzaWduSW5QYXNzd29yZCd9XCJcbiAgICAgIGNsYXNzPVwibGlzdC1ncm91cC1pdGVtIGxpc3QtZ3JvdXAtaXRlbS1hY3Rpb25cIj5cbiAgICAgIDxpIGNsYXNzPVwiZmFzIGZhLXVubG9ja1wiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjwvaT5cbiAgICAgIDxzcGFuIGNsYXNzPVwibWwtMlwiPlNpZ24gSW4gd2l0aCBZb3VyIFBhc3N3b3JkPC9zcGFuPlxuICAgIDwvYT5cbiAgICA8YnV0dG9uXG4gICAgICAqbmdGb3I9XCJsZXQgaWQgb2YgbWV0aG9kRXJyb3IuYWNjb3VudE9BdXRoTWV0aG9kc1wiXG4gICAgICAoY2xpY2spPVwib0F1dGhTaWduSW4oaWQpXCJcbiAgICAgIGNsYXNzPVwibGlzdC1ncm91cC1pdGVtIGxpc3QtZ3JvdXAtaXRlbS1hY3Rpb25cIj5cbiAgICAgIDxpIFthdHRyLmNsYXNzXT1cImdldE9BdXRoUHJvdmlkZXJJY29uKGlkKVwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjwvaT5cbiAgICAgIDxzcGFuIGNsYXNzPVwibWwtMlwiPlNpZ24gSW4gd2l0aCB7e2dldE9BdXRoUHJvdmlkZXJOYW1lKGlkKX19PC9zcGFuPlxuICAgIDwvYnV0dG9uPlxuICA8L2Rpdj5cblxuICA8Zm9ybSBbZm9ybUdyb3VwXT1cImZnXCI+XG4gICAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXBcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWNoZWNrXCI+XG4gICAgICAgIDxpbnB1dFxuICAgICAgICAgIGNsYXNzPVwiZm9ybS1jaGVjay1pbnB1dFwiXG4gICAgICAgICAgdHlwZT1cImNoZWNrYm94XCJcbiAgICAgICAgICBbdmFsdWVdPVwidHJ1ZVwiXG4gICAgICAgICAgZm9ybUNvbnRyb2xOYW1lPVwicmVtZW1iZXJcIlxuICAgICAgICAgIFthdHRyLmlkXT1cImZvcm1JZCArICdyZW1lbWJlcidcIj5cbiAgICAgICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1jaGVjay1sYWJlbFwiIFthdHRyLmZvcl09XCJmb3JtSWQgKyAncmVtZW1iZXInXCI+XG4gICAgICAgICAgUmVtZW1iZXIgbWUgb24gdGhpcyBkZXZpY2UuXG4gICAgICAgIDwvbGFiZWw+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9mb3JtPlxuXG4gIDxwIGNsYXNzPVwidGV4dC1tdXRlZFwiPlxuICAgIElzIHt7bWV0aG9kRXJyb3IuZW1haWx9fSBub3QgeW91ciBlbWFpbCBhZGRyZXNzP1xuICAgIDxhIHJvdXRlckxpbms9XCIuXCIgW3F1ZXJ5UGFyYW1zXT1cInthY3Rpb246ICdzaWduSW4nfVwiPlN0YXJ0IE92ZXI8L2E+XG4gIDwvcD5cblxuPC9kaXY+XG5cbjxkaXYgKm5nSWY9XCIncmV0cnknID09PSBzY3JlZW5cIiBbQHNjcmVlbl09XCInaW4nXCI+XG4gIDxkaXYgY2xhc3M9XCJhbGVydCBhbGVydC1kYW5nZXJcIj5cbiAgICA8aSBjbGFzcz1cImZhcyBmYS1leGNsYW1hdGlvbi10cmlhbmdsZSBmYS1md1wiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjwvaT5cbiAgICBJdCBsb29rcyBsaWtlIHlvdSBjYW5jZWxsZWQgc2lnbmluZyBpbiB3aXRoXG4gICAge3tnZXRPQXV0aFByb3ZpZGVyTmFtZShwcm92aWRlcklkKX19LiBUcnkgYWdhaW46XG4gIDwvZGl2PlxuXG4gIDxkaXYgY2xhc3M9XCJsaXN0LWdyb3VwXCI+XG4gICAgPGJ1dHRvblxuICAgICAgKGNsaWNrKT1cIm9BdXRoU2lnbkluKHByb3ZpZGVySWQpXCJcbiAgICAgIGNsYXNzPVwibGlzdC1ncm91cC1pdGVtIGxpc3QtZ3JvdXAtaXRlbS1hY3Rpb25cIj5cbiAgICAgIDxpIFthdHRyLmNsYXNzXT1cImdldE9BdXRoUHJvdmlkZXJJY29uKHByb3ZpZGVySWQpXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+PC9pPlxuICAgICAgPHNwYW4gY2xhc3M9XCJtbC0yXCI+U2lnbiBJbiB3aXRoIHt7Z2V0T0F1dGhQcm92aWRlck5hbWUocHJvdmlkZXJJZCl9fTwvc3Bhbj5cbiAgICA8L2J1dHRvbj5cbiAgPC9kaXY+XG5cbiAgPGZvcm0gW2Zvcm1Hcm91cF09XCJmZ1wiPlxuICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1jaGVja1wiPlxuICAgICAgICA8aW5wdXRcbiAgICAgICAgICBjbGFzcz1cImZvcm0tY2hlY2staW5wdXRcIlxuICAgICAgICAgIHR5cGU9XCJjaGVja2JveFwiXG4gICAgICAgICAgW3ZhbHVlXT1cInRydWVcIlxuICAgICAgICAgIGZvcm1Db250cm9sTmFtZT1cInJlbWVtYmVyXCJcbiAgICAgICAgICBbYXR0ci5pZF09XCJmb3JtSWQgKyAncmVtZW1iZXInXCI+XG4gICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tY2hlY2stbGFiZWxcIiBbYXR0ci5mb3JdPVwiZm9ybUlkICsgJ3JlbWVtYmVyJ1wiPlxuICAgICAgICAgIFJlbWVtYmVyIG1lIG9uIHRoaXMgZGV2aWNlLlxuICAgICAgICA8L2xhYmVsPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvZm9ybT5cblxuXG4gIDxwIGNsYXNzPVwidGV4dC1tdXRlZFwiPlxuICAgIDxhIHJvdXRlckxpbms9XCIuXCIgW3F1ZXJ5UGFyYW1zXT1cInthY3Rpb246ICdzaWduSW4nfVwiPlN0YXJ0IE92ZXI8L2E+XG4gIDwvcD5cblxuPC9kaXY+XG5gLFxuICBzdHlsZXM6IFtgYF0sXG4gIGFuaW1hdGlvbnM6IFsgc2NyZWVuQW5pbWF0aW9uIF1cbn0pXG5leHBvcnQgY2xhc3MgU2lnbkluT2F1dGhDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuXG4gIEBJbnB1dCgpIHByb3ZpZGVySWQ6IHN0cmluZztcbiAgQElucHV0KCkgaW5pdGlhbEVycm9yOiBhdXRoLkVycm9yO1xuICBASW5wdXQoKSB1c2VPQXV0aFBvcHVwOiBib29sZWFuO1xuICBASW5wdXQoKSBvQXV0aFByb3ZpZGVyRmFjdG9yeTogKHByb3ZpZGVySWQ6IHN0cmluZykgPT4gYXV0aC5BdXRoUHJvdmlkZXI7XG4gIEBJbnB1dCgpIGVtYWlsOiBzdHJpbmc7XG4gIEBJbnB1dCgpIHJlbWVtYmVyOiBib29sZWFuO1xuICBAT3V0cHV0KCkgc3VjY2VzczogRXZlbnRFbWl0dGVyPGF1dGguVXNlckNyZWRlbnRpYWw+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBAT3V0cHV0KCkgZW1haWxDaGFuZ2U6IEV2ZW50RW1pdHRlcjxzdHJpbmc+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBAT3V0cHV0KCkgcmVtZW1iZXJDaGFuZ2U6IEV2ZW50RW1pdHRlcjxib29sZWFuPiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgQE91dHB1dCgpIGVycm9yOiBFdmVudEVtaXR0ZXI8YXV0aC5FcnJvcj4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cblxuICBzY3JlZW46ICd3YWl0JyB8ICdtZXRob2RFcnJvcicgfCAncmV0cnknID0gJ3dhaXQnO1xuICBtZXRob2RFcnJvcjogYXV0aC5FcnJvcnxhbnkgPSBudWxsO1xuICBnZXRPQXV0aFByb3ZpZGVySWNvbiA9IGdldE9BdXRoUHJvdmlkZXJJY29uO1xuICBnZXRPQXV0aFByb3ZpZGVyTmFtZSA9IGdldE9BdXRoUHJvdmlkZXJOYW1lO1xuICBmZzogRm9ybUdyb3VwO1xuICByZW1lbWJlckZjOiBGb3JtQ29udHJvbDtcbiAgZm9ybUlkID0gJ25neC1maXJlYmFzZS1hdXRoLXNpZ24taW4tb2F1dGgtJztcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIF9hZkF1dGg6IEFuZ3VsYXJGaXJlQXV0aCxcbiAgICBwcml2YXRlIF9zdmM6IE5neEZpcmViYXNlQXV0aFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBfcm91dGU6IEFjdGl2YXRlZFJvdXRlLFxuICAgIHByaXZhdGUgX3JvdXRlcjogUm91dGVyXG4gICkgeyB9XG5cbiAgZ2V0IGF1dGgoKTogYXV0aC5BdXRoIHtcbiAgICByZXR1cm4gdGhpcy5fYWZBdXRoLmF1dGg7XG4gIH1cblxuICBnZXQgYXV0aFNlcnZpY2UoKTogTmd4RmlyZWJhc2VBdXRoU2VydmljZSB7XG4gICAgcmV0dXJuIHRoaXMuX3N2YztcbiAgfVxuXG4gIGdldCByb3V0ZSgpOiBBY3RpdmF0ZWRSb3V0ZSB7XG4gICAgcmV0dXJuIHRoaXMuX3JvdXRlO1xuICB9XG5cbiAgZ2V0IHJvdXRlcigpOiBSb3V0ZXIge1xuICAgIHJldHVybiB0aGlzLl9yb3V0ZXI7XG4gIH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLnJlbWVtYmVyRmMgPSBuZXcgRm9ybUNvbnRyb2wodGhpcy5yZW1lbWJlcik7XG4gICAgdGhpcy5yZW1lbWJlckZjLnZhbHVlQ2hhbmdlcy5zdWJzY3JpYmUodmFsID0+IHRoaXMucmVtZW1iZXJDaGFuZ2UuZW1pdCh2YWwpKTtcbiAgICB0aGlzLmZnID0gbmV3IEZvcm1Hcm91cCh7XG4gICAgICByZW1lbWJlcjogdGhpcy5yZW1lbWJlckZjXG4gICAgfSk7XG4gICAgaWYgKHRoaXMuaW5pdGlhbEVycm9yKSB7XG4gICAgICB0aGlzLmhhbmRsZU9BdXRoRXJyb3IodGhpcy5pbml0aWFsRXJyb3IpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm9BdXRoU2lnbkluKHRoaXMucHJvdmlkZXJJZCk7XG4gICAgfVxuICB9XG5cblxuICBvQXV0aFNpZ25JbihpZDogc3RyaW5nLCBmb3JjZVJlZGlyZWN0PzogYm9vbGVhbikge1xuICAgIHRoaXMubWV0aG9kRXJyb3IgPSBudWxsO1xuICAgIGxldCBjcmVkOiBhdXRoLlVzZXJDcmVkZW50aWFsO1xuICAgIGlmICh0aGlzLnVzZU9BdXRoUG9wdXAgICYmIGZvcmNlUmVkaXJlY3QgIT09IHRydWUpIHtcbiAgICAgIHRoaXMuZ2V0T0F1dGhQcm92aWRlcihpZClcbiAgICAgICAgLnRoZW4ocHJvdmlkZXIgPT4ge1xuICAgICAgICAgIHJldHVybiB0aGlzLmF1dGguc2lnbkluV2l0aFBvcHVwKHByb3ZpZGVyKTtcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oKHJlc3VsdDogYXV0aC5Vc2VyQ3JlZGVudGlhbCkgPT4ge1xuICAgICAgICAgIGNyZWQgPSByZXN1bHQ7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuYXV0aFNlcnZpY2Uuc2V0UmVtZW1iZXJlZCh0aGlzLnJlbWVtYmVyRmMudmFsdWUgPT09IHRydWUsIHJlc3VsdC51c2VyLmVtYWlsKTtcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgIHRoaXMuc3VjY2Vzcy5lbWl0KGNyZWQpO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4gdGhpcy5oYW5kbGVPQXV0aEVycm9yKGVycm9yLCBpZCkpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnJvdXRlci5uYXZpZ2F0ZShbJy4nXSwge3JlbGF0aXZlVG86IHRoaXMucm91dGUsIHF1ZXJ5UGFyYW1zOiB7cmVtZW1iZXI6IHRoaXMucmVtZW1iZXJGYy52YWx1ZSA9PT0gdHJ1ZX19KVxuICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T0F1dGhQcm92aWRlcihpZCk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKHByb3ZpZGVyID0+IHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5hdXRoLnNpZ25JbldpdGhSZWRpcmVjdChwcm92aWRlcik7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB0aGlzLmhhbmRsZU9BdXRoRXJyb3IoZXJyb3IsIGlkKSk7XG4gICAgfVxuICB9XG5cbiAgaGFuZGxlT0F1dGhFcnJvcihlcnJvcjogYXV0aC5FcnJvciwgcHJvdmlkZXJJZD86IHN0cmluZykge1xuICAgIGlmIChlcnJvclsnZW1haWwnXSAmJiBlcnJvclsnY3JlZGVudGlhbCddKSB7XG4gICAgICB0aGlzLmVtYWlsQ2hhbmdlLmVtaXQoZXJyb3JbJ2VtYWlsJ10pO1xuICAgICAgdGhpcy5hdXRoLmZldGNoU2lnbkluTWV0aG9kc0ZvckVtYWlsKGVycm9yWydlbWFpbCddKVxuICAgICAgICAudGhlbihyZXN1bHRzID0+IHtcbiAgICAgICAgICBlcnJvclsnbWV0aG9kcyddID0gcmVzdWx0cztcbiAgICAgICAgICBlcnJvclsnYWNjb3VudEhhc1Bhc3N3b3JkJ10gPSByZXN1bHRzLmluZGV4T2YoJ3Bhc3N3b3JkJykgIT09IC0xO1xuICAgICAgICAgIGVycm9yWydhY2NvdW50T0F1dGhNZXRob2RzJ10gPSByZXN1bHRzLmZpbHRlcihpZCA9PiBpZCAhPT0gJ3Bhc3N3b3JkJyk7XG4gICAgICAgICAgdGhpcy5tZXRob2RFcnJvciA9IGVycm9yO1xuICAgICAgICAgIHRoaXMuc2NyZWVuID0gJ21ldGhvZEVycm9yJztcbiAgICAgICAgfSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHN3aXRjaCAoZXJyb3IuY29kZSkge1xuICAgICAgY2FzZSAnYXV0aC9jYW5jZWxsZWQtcG9wdXAtcmVxdWVzdCc6XG4gICAgICBjYXNlICdhdXRoL3BvcHVwLWNsb3NlZC1ieS11c2VyJzpcbiAgICAgICAgdGhpcy5zY3JlZW4gPSAncmV0cnknO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2F1dGgvcG9wdXAtYmxvY2tlZCc6XG4gICAgICAgIHRoaXMub0F1dGhTaWduSW4ocHJvdmlkZXJJZCwgdHJ1ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhpcy5lcnJvci5lbWl0KGVycm9yKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgZ2V0T0F1dGhQcm92aWRlcihpZDogc3RyaW5nKTogUHJvbWlzZTxhdXRoLkF1dGhQcm92aWRlcj4ge1xuICAgIGxldCBwcm92aWRlcjogYXV0aC5BdXRoUHJvdmlkZXIgPSBudWxsO1xuICAgIGlmICh0aGlzLm9BdXRoUHJvdmlkZXJGYWN0b3J5KSB7XG4gICAgICBwcm92aWRlciA9IHRoaXMub0F1dGhQcm92aWRlckZhY3RvcnkoaWQpO1xuICAgIH1cbiAgICBpZiAoISBwcm92aWRlcikge1xuICAgICAgc3dpdGNoIChpZCkge1xuICAgICAgICBjYXNlICd0d2l0dGVyLmNvbSc6XG4gICAgICAgICAgcHJvdmlkZXIgPSBuZXcgYXV0aC5Ud2l0dGVyQXV0aFByb3ZpZGVyKCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ2ZhY2Vib29rLmNvbSc6XG4gICAgICAgICAgcHJvdmlkZXIgPSBuZXcgYXV0aC5GYWNlYm9va0F1dGhQcm92aWRlcigpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdnb29nbGUuY29tJzpcbiAgICAgICAgICBwcm92aWRlciA9IG5ldyBhdXRoLkdvb2dsZUF1dGhQcm92aWRlcigpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdnaXRodWIuY29tJzpcbiAgICAgICAgICBwcm92aWRlciA9IG5ldyBhdXRoLkdpdGh1YkF1dGhQcm92aWRlcigpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAocHJvdmlkZXIpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocHJvdmlkZXIpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3Qoe1xuICAgICAgICBjb2RlOiAnbmd4LWZpcmViYXNlLWF1dGgvbm8tcHJvdmlkZXItZm91bmQnLFxuICAgICAgICBtZXNzYWdlOiBgV2UgY291bGQgbm90IGNyZWF0ZSBhbiBPQXV0aCBwcm92aWRlciBmb3IgcHJvdmlkZXIgaWQgXCIke2lkfVwiLmBcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG59XG4iXX0=