import { Injectable, Inject, Optional, NgZone, PLATFORM_ID, InjectionToken } from '@angular/core'; import { Observable, of, from, merge, Subject } from 'rxjs'; import { switchMap, map, observeOn, shareReplay, first, filter, switchMapTo, subscribeOn } from 'rxjs/operators'; import { ɵAngularFireSchedulers, keepUnstableUntilFirst } from '@angular/fire'; import { ɵlazySDKProxy, ɵapplyMixins } from '@angular/fire/compat'; import { ɵfirebaseAppFactory, FIREBASE_OPTIONS, FIREBASE_APP_NAME, ɵcacheInstance } from '@angular/fire/compat'; import { isPlatformServer } from '@angular/common'; import { proxyPolyfillCompat } from './base'; import { AppCheckInstances } from '@angular/fire/app-check'; import * as i0 from "@angular/core"; import * as i1 from "@angular/fire"; import * as i2 from "@angular/fire/app-check"; export const USE_EMULATOR = new InjectionToken('angularfire2.auth.use-emulator'); export const SETTINGS = new InjectionToken('angularfire2.auth.settings'); export const TENANT_ID = new InjectionToken('angularfire2.auth.tenant-id'); export const LANGUAGE_CODE = new InjectionToken('angularfire2.auth.langugage-code'); export const USE_DEVICE_LANGUAGE = new InjectionToken('angularfire2.auth.use-device-language'); export const PERSISTENCE = new InjectionToken('angularfire.auth.persistence'); export const ɵauthFactory = (app, zone, useEmulator, tenantId, languageCode, useDeviceLanguage, settings, persistence) => ɵcacheInstance(`${app.name}.auth`, 'AngularFireAuth', app.name, () => { const auth = zone.runOutsideAngular(() => app.auth()); if (useEmulator) { auth.useEmulator(...useEmulator); } if (tenantId) { auth.tenantId = tenantId; } auth.languageCode = languageCode; if (useDeviceLanguage) { auth.useDeviceLanguage(); } if (settings) { for (const [k, v] of Object.entries(settings)) { auth.settings[k] = v; } } if (persistence) { auth.setPersistence(persistence); } return auth; }, [useEmulator, tenantId, languageCode, useDeviceLanguage, settings, persistence]); export class AngularFireAuth { constructor(options, name, // tslint:disable-next-line:ban-types platformId, zone, schedulers, useEmulator, // can't use the tuple here settings, // can't use firebase.auth.AuthSettings here tenantId, languageCode, useDeviceLanguage, persistence, _appCheckInstances) { const logins = new Subject(); const auth = of(undefined).pipe(observeOn(schedulers.outsideAngular), switchMap(() => zone.runOutsideAngular(() => import('firebase/compat/auth'))), map(() => ɵfirebaseAppFactory(options, zone, name)), map(app => ɵauthFactory(app, zone, useEmulator, tenantId, languageCode, useDeviceLanguage, settings, persistence)), shareReplay({ bufferSize: 1, refCount: false })); if (isPlatformServer(platformId)) { this.authState = this.user = this.idToken = this.idTokenResult = this.credential = of(null); } else { // HACK, as we're exporting auth.Auth, rather than auth, developers importing firebase.auth // (e.g, `import { auth } from 'firebase/compat/app'`) are getting an undefined auth object unexpectedly // as we're completely lazy. Let's eagerly load the Auth SDK here. // There could potentially be race conditions still... but this greatly decreases the odds while // we reevaluate the API. const _ = auth.pipe(first()).subscribe(); const redirectResult = auth.pipe(switchMap(auth => auth.getRedirectResult().then(it => it, () => null)), keepUnstableUntilFirst, shareReplay({ bufferSize: 1, refCount: false })); const authStateChanged = auth.pipe(switchMap(auth => new Observable(sub => ({ unsubscribe: zone.runOutsideAngular(() => auth.onAuthStateChanged(next => sub.next(next), err => sub.error(err), () => sub.complete())) })))); const idTokenChanged = auth.pipe(switchMap(auth => new Observable(sub => ({ unsubscribe: zone.runOutsideAngular(() => auth.onIdTokenChanged(next => sub.next(next), err => sub.error(err), () => sub.complete())) })))); this.authState = redirectResult.pipe(switchMapTo(authStateChanged), subscribeOn(schedulers.outsideAngular), observeOn(schedulers.insideAngular)); this.user = redirectResult.pipe(switchMapTo(idTokenChanged), subscribeOn(schedulers.outsideAngular), observeOn(schedulers.insideAngular)); this.idToken = this.user.pipe(switchMap(user => user ? from(user.getIdToken()) : of(null))); this.idTokenResult = this.user.pipe(switchMap(user => user ? from(user.getIdTokenResult()) : of(null))); this.credential = merge(redirectResult, logins, // pipe in null authState to make credential zipable, just a weird devexp if // authState and user go null to still have a credential this.authState.pipe(filter(it => !it))).pipe( // handle the { user: { } } when a user is already logged in, rather have null // TODO handle the type corcersion better map(credential => (credential === null || credential === void 0 ? void 0 : credential.user) ? credential : null), subscribeOn(schedulers.outsideAngular), observeOn(schedulers.insideAngular)); } return ɵlazySDKProxy(this, auth, zone, { spy: { apply: (name, _, val) => { // If they call a signIn or createUser function listen into the promise // this will give us the user credential, push onto the logins Subject // to be consumed in .credential if (name.startsWith('signIn') || name.startsWith('createUser')) { // TODO fix the types, the trouble is UserCredential has everything optional val.then((user) => logins.next(user)); } } } }); } } AngularFireAuth.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.3", ngImport: i0, type: AngularFireAuth, deps: [{ token: FIREBASE_OPTIONS }, { token: FIREBASE_APP_NAME, optional: true }, { token: PLATFORM_ID }, { token: i0.NgZone }, { token: i1.ɵAngularFireSchedulers }, { token: USE_EMULATOR, optional: true }, { token: SETTINGS, optional: true }, { token: TENANT_ID, optional: true }, { token: LANGUAGE_CODE, optional: true }, { token: USE_DEVICE_LANGUAGE, optional: true }, { token: PERSISTENCE, optional: true }, { token: i2.AppCheckInstances, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); AngularFireAuth.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.1.3", ngImport: i0, type: AngularFireAuth, providedIn: 'any' }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.3", ngImport: i0, type: AngularFireAuth, decorators: [{ type: Injectable, args: [{ providedIn: 'any' }] }], ctorParameters: function () { return [{ type: undefined, decorators: [{ type: Inject, args: [FIREBASE_OPTIONS] }] }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [FIREBASE_APP_NAME] }] }, { type: Object, decorators: [{ type: Inject, args: [PLATFORM_ID] }] }, { type: i0.NgZone }, { type: i1.ɵAngularFireSchedulers }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [USE_EMULATOR] }] }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [SETTINGS] }] }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [TENANT_ID] }] }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [LANGUAGE_CODE] }] }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [USE_DEVICE_LANGUAGE] }] }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [PERSISTENCE] }] }, { type: i2.AppCheckInstances, decorators: [{ type: Optional }] }]; } }); ɵapplyMixins(AngularFireAuth, [proxyPolyfillCompat]); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9jb21wYXQvYXV0aC9hdXRoLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFFLGNBQWMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNsRyxPQUFPLEVBQUUsVUFBVSxFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUM1RCxPQUFPLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ2pILE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxzQkFBc0IsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMvRSxPQUFPLEVBQUUsYUFBYSxFQUFpQixZQUFZLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNsRixPQUFPLEVBQUUsbUJBQW1CLEVBQUUsZ0JBQWdCLEVBQUUsaUJBQWlCLEVBQWUsY0FBYyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFHN0gsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDbkQsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sUUFBUSxDQUFDO0FBQzdDLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHlCQUF5QixDQUFDOzs7O0FBSzVELE1BQU0sQ0FBQyxNQUFNLFlBQVksR0FBRyxJQUFJLGNBQWMsQ0FBdUIsZ0NBQWdDLENBQUMsQ0FBQztBQUV2RyxNQUFNLENBQUMsTUFBTSxRQUFRLEdBQUcsSUFBSSxjQUFjLENBQTZCLDRCQUE0QixDQUFDLENBQUM7QUFDckcsTUFBTSxDQUFDLE1BQU0sU0FBUyxHQUFHLElBQUksY0FBYyxD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QUE0RTt3QkFDNUUsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQWtDLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBVyxDQUFDLENBQUMsQ0FBQztxQkFDNUU7Z0JBQ0gsQ0FBQzthQUNGLEVBQUMsQ0FBQyxDQUFDO0lBRU4sQ0FBQzs7NEdBN0lVLGVBQWUsa0JBOEJoQixnQkFBZ0IsYUFDSixpQkFBaUIsNkJBRTdCLFdBQVcseUVBR0MsWUFBWSw2QkFDWixRQUFRLDZCQUNSLFNBQVMsNkJBQ1QsYUFBYSw2QkFDYixtQkFBbUIsNkJBQ25CLFdBQVc7Z0hBekN0QixlQUFlLGNBRmQsS0FBSzsyRkFFTixlQUFlO2tCQUgzQixVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxLQUFLO2lCQUNsQjs7MEJBK0JJLE1BQU07MkJBQUMsZ0JBQWdCOzswQkFDdkIsUUFBUTs7MEJBQUksTUFBTTsyQkFBQyxpQkFBaUI7OEJBRUosTUFBTTswQkFBdEMsTUFBTTsyQkFBQyxXQUFXOzswQkFHbEIsUUFBUTs7MEJBQUksTUFBTTsyQkFBQyxZQUFZOzswQkFDL0IsUUFBUTs7MEJBQUksTUFBTTsyQkFBQyxRQUFROzswQkFDM0IsUUFBUTs7MEJBQUksTUFBTTsyQkFBQyxTQUFTOzswQkFDNUIsUUFBUTs7MEJBQUksTUFBTTsyQkFBQyxhQUFhOzswQkFDaEMsUUFBUTs7MEJBQUksTUFBTTsyQkFBQyxtQkFBbUI7OzBCQUN0QyxRQUFROzswQkFBSSxNQUFNOzJCQUFDLFdBQVc7OzBCQUM5QixRQUFROztBQXVHYixZQUFZLENBQUMsZUFBZSxFQUFFLENBQUMsbUJBQW1CLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgSW5qZWN0LCBPcHRpb25hbCwgTmdab25lLCBQTEFURk9STV9JRCwgSW5qZWN0aW9uVG9rZW4gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE9ic2VydmFibGUsIG9mLCBmcm9tLCBtZXJnZSwgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgc3dpdGNoTWFwLCBtYXAsIG9ic2VydmVPbiwgc2hhcmVSZXBsYXksIGZpcnN0LCBmaWx0ZXIsIHN3aXRjaE1hcFRvLCBzdWJzY3JpYmVPbiB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IMm1QW5ndWxhckZpcmVTY2hlZHVsZXJzLCBrZWVwVW5zdGFibGVVbnRpbEZpcnN0IH0gZnJvbSAnQGFuZ3VsYXIvZmlyZSc7XG5pbXBvcnQgeyDJtWxhenlTREtQcm94eSwgybVQcm9taXNlUHJveHksIMm1YXBwbHlNaXhpbnMgfSBmcm9tICdAYW5ndWxhci9maXJlL2NvbXBhdCc7XG5pbXBvcnQgeyDJtWZpcmViYXNlQXBwRmFjdG9yeSwgRklSRUJBU0VfT1BUSU9OUywgRklSRUJBU0VfQVBQX05BTUUsIEZpcmViYXNlQXBwLCDJtWNhY2hlSW5zdGFuY2UgfSBmcm9tICdAYW5ndWxhci9maXJlL2NvbXBhdCc7XG5pbXBvcnQgeyBGaXJlYmFzZU9wdGlvbnMgfSBmcm9tICdmaXJlYmFzZS9hcHAnO1xuaW1wb3J0IGZpcmViYXNlIGZyb20gJ2ZpcmViYXNlL2NvbXBhdC9hcHAnO1xuaW1wb3J0IHsgaXNQbGF0Zm9ybVNlcnZlciB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBwcm94eVBvbHlmaWxsQ29tcGF0IH0gZnJvbSAnLi9iYXNlJztcbmltcG9ydCB7IEFwcENoZWNrSW5zdGFuY2VzIH0gZnJvbSAnQGFuZ3VsYXIvZmlyZS9hcHAtY2hlY2snO1xuXG5leHBvcnQgaW50ZXJmYWNlIEFuZ3VsYXJGaXJlQXV0aCBleHRlbmRzIMm1UHJvbWlzZVByb3h5PGZpcmViYXNlLmF1dGguQXV0aD4ge31cblxudHlwZSBVc2VFbXVsYXRvckFyZ3VtZW50cyA9IFBhcmFtZXRlcnM8ZmlyZWJhc2UuYXV0aC5BdXRoWyd1c2VFbXVsYXRvciddPjtcbmV4cG9ydCBjb25zdCBVU0VfRU1VTEFUT1IgPSBuZXcgSW5qZWN0aW9uVG9rZW48VXNlRW11bGF0b3JBcmd1bWVudHM+KCdhbmd1bGFyZmlyZTIuYXV0aC51c2UtZW11bGF0b3InKTtcblxuZXhwb3J0IGNvbnN0IFNFVFRJTkdTID0gbmV3IEluamVjdGlvblRva2VuPGZpcmViYXNlLmF1dGguQXV0aFNldHRpbmdzPignYW5ndWxhcmZpcmUyLmF1dGguc2V0dGluZ3MnKTtcbmV4cG9ydCBjb25zdCBURU5BTlRfSUQgPSBuZXcgSW5qZWN0aW9uVG9rZW48c3RyaW5nPignYW5ndWxhcmZpcmUyLmF1dGgudGVuYW50LWlkJyk7XG5leHBvcnQgY29uc3QgTEFOR1VBR0VfQ09ERSA9IG5ldyBJbmplY3Rpb25Ub2tlbjxzdHJpbmc+KCdhbmd1bGFyZmlyZTIuYXV0aC5sYW5ndWdhZ2UtY29kZScpO1xuZXhwb3J0IGNvbnN0IFVTRV9ERVZJQ0VfTEFOR1VBR0UgPSBuZXcgSW5qZWN0aW9uVG9rZW48Ym9vbGVhbj4oJ2FuZ3VsYXJmaXJlMi5hdXRoLnVzZS1kZXZpY2UtbGFuZ3VhZ2UnKTtcbmV4cG9ydCBjb25zdCBQRVJTSVNURU5DRSA9IG5ldyBJbmplY3Rpb25Ub2tlbjxzdHJpbmc+KCdhbmd1bGFyZmlyZS5hdXRoLnBlcnNpc3RlbmNlJyk7XG5cbmV4cG9ydCBjb25zdCDJtWF1dGhGYWN0b3J5ID0gKFxuICBhcHA6IEZpcmViYXNlQXBwLCB6b25lOiBOZ1pvbmUsIHVzZUVtdWxhdG9yOiBVc2VFbXVsYXRvckFyZ3VtZW50c3xudWxsLFxuICB0ZW5hbnRJZDogc3RyaW5nLCBsYW5ndWFnZUNvZGU6IHN0cmluZ3xudWxsLCB1c2VEZXZpY2VMYW5ndWFnZTogYm9vbGVhbnxudWxsLFxuICBzZXR0aW5nczogZmlyZWJhc2UuYXV0aC5BdXRoU2V0dGluZ3N8bnVsbCwgcGVyc2lzdGVuY2U6IHN0cmluZ3xudWxsLFxuKSA9PiDJtWNhY2hlSW5zdGFuY2UoYCR7YXBwLm5hbWV9LmF1dGhgLCAnQW5ndWxhckZpcmVBdXRoJywgYXBwLm5hbWUsICgpID0+IHtcbiAgY29uc3QgYXV0aCA9IHpvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4gYXBwLmF1dGgoKSk7XG4gIGlmICh1c2VFbXVsYXRvcikge1xuICAgIGF1dGgudXNlRW11bGF0b3IoLi4udXNlRW11bGF0b3IpO1xuICB9XG4gIGlmICh0ZW5hbnRJZCkge1xuICAgIGF1dGgudGVuYW50SWQgPSB0ZW5hbnRJZDtcbiAgfVxuICBhdXRoLmxhbmd1YWdlQ29kZSA9IGxhbmd1YWdlQ29kZTtcbiAgaWYgKHVzZURldmljZUxhbmd1YWdlKSB7XG4gICAgYXV0aC51c2VEZXZpY2VMYW5ndWFnZSgpO1xuICB9XG4gIGlmIChzZXR0aW5ncykge1xuICAgIGZvciAoY29uc3QgW2ssIHZdIG9mIE9iamVjdC5lbnRyaWVzKHNldHRpbmdzKSkge1xuICAgICAgYXV0aC5zZXR0aW5nc1trXSA9IHY7XG4gICAgfVxuICB9XG4gIGlmIChwZXJzaXN0ZW5jZSkge1xuICAgIGF1dGguc2V0UGVyc2lzdGVuY2UocGVyc2lzdGVuY2UpO1xuICB9XG4gIHJldHVybiBhdXRoO1xufSwgW3VzZUVtdWxhdG9yLCB0ZW5hbnRJZCwgbGFuZ3VhZ2VDb2RlLCB1c2VEZXZpY2VMYW5ndWFnZSwgc2V0dGluZ3MsIHBlcnNpc3RlbmNlXSk7XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ2FueSdcbn0pXG5leHBvcnQgY2xhc3MgQW5ndWxhckZpcmVBdXRoIHtcblxuICAvKipcbiAgICogT2JzZXJ2YWJsZSBvZiBhdXRoZW50aWNhdGlvbiBzdGF0ZTsgYXMgb2YgRmlyZWJhc2UgNC4wIHRoaXMgaXMgb25seSB0cmlnZ2VyZWQgdmlhIHNpZ24taW4vb3V0XG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgYXV0aFN0YXRlOiBPYnNlcnZhYmxlPGZpcmViYXNlLlVzZXJ8bnVsbD47XG5cbiAgLyoqXG4gICAqIE9ic2VydmFibGUgb2YgdGhlIGN1cnJlbnRseSBzaWduZWQtaW4gdXNlcidzIEpXVCB0b2tlbiB1c2VkIHRvIGlkZW50aWZ5IHRoZSB1c2VyIHRvIGEgRmlyZWJhc2Ugc2VydmljZSAob3IgbnVsbCkuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgaWRUb2tlbjogT2JzZXJ2YWJsZTxzdHJpbmd8bnVsbD47XG5cbiAgLyoqXG4gICAqIE9ic2VydmFibGUgb2YgdGhlIGN1cnJlbnRseSBzaWduZWQtaW4gdXNlciAob3IgbnVsbCkuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgdXNlcjogT2JzZXJ2YWJsZTxmaXJlYmFzZS5Vc2VyfG51bGw+O1xuXG4gIC8qKlxuICAgKiBPYnNlcnZhYmxlIG9mIHRoZSBjdXJyZW50bHkgc2lnbmVkLWluIHVzZXIncyBJZFRva2VuUmVzdWx0IG9iamVjdCB3aGljaCBjb250YWlucyB0aGUgSUQgdG9rZW4gSldUIHN0cmluZyBhbmQgb3RoZXJcbiAgICogaGVscGVyIHByb3BlcnRpZXMgZm9yIGdldHRpbmcgZGlmZmVyZW50IGRhdGEgYXNzb2NpYXRlZCB3aXRoIHRoZSB0b2tlbiBhcyB3ZWxsIGFzIGFsbCB0aGUgZGVjb2RlZCBwYXlsb2FkIGNsYWltc1xuICAgKiAob3IgbnVsbCkuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgaWRUb2tlblJlc3VsdDogT2JzZXJ2YWJsZTxmaXJlYmFzZS5hdXRoLklkVG9rZW5SZXN1bHR8bnVsbD47XG5cbiAgLyoqXG4gICAqIE9ic2VydmFibGUgb2YgdGhlIGN1cnJlbnRseSBzaWduZWQtaW4gdXNlcidzIGNyZWRlbnRpYWwsIG9yIG51bGxcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBjcmVkZW50aWFsOiBPYnNlcnZhYmxlPFJlcXVpcmVkPGZpcmViYXNlLmF1dGguVXNlckNyZWRlbnRpYWw+fG51bGw+O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIEBJbmplY3QoRklSRUJBU0VfT1BUSU9OUykgb3B0aW9uczogRmlyZWJhc2VPcHRpb25zLFxuICAgIEBPcHRpb25hbCgpIEBJbmplY3QoRklSRUJBU0VfQVBQX05BTUUpIG5hbWU6IHN0cmluZ3xudWxsfHVuZGVmaW5lZCxcbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6YmFuLXR5cGVzXG4gICAgQEluamVjdChQTEFURk9STV9JRCkgcGxhdGZvcm1JZDogT2JqZWN0LFxuICAgIHpvbmU6IE5nWm9uZSxcbiAgICBzY2hlZHVsZXJzOiDJtUFuZ3VsYXJGaXJlU2NoZWR1bGVycyxcbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KFVTRV9FTVVMQVRPUikgdXNlRW11bGF0b3I6IGFueSwgLy8gY2FuJ3QgdXNlIHRoZSB0dXBsZSBoZXJlXG4gICAgQE9wdGlvbmFsKCkgQEluamVjdChTRVRUSU5HUykgc2V0dGluZ3M6IGFueSwgLy8gY2FuJ3QgdXNlIGZpcmViYXNlLmF1dGguQXV0aFNldHRpbmdzIGhlcmVcbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KFRFTkFOVF9JRCkgdGVuYW50SWQ6IHN0cmluZyB8IG51bGwsXG4gICAgQE9wdGlvbmFsKCkgQEluamVjdChMQU5HVUFHRV9DT0RFKSBsYW5ndWFnZUNvZGU6IHN0cmluZyB8IG51bGwsXG4gICAgQE9wdGlvbmFsKCkgQEluamVjdChVU0VfREVWSUNFX0xBTkdVQUdFKSB1c2VEZXZpY2VMYW5ndWFnZTogYm9vbGVhbiB8IG51bGwsXG4gICAgQE9wdGlvbmFsKCkgQEluamVjdChQRVJTSVNURU5DRSkgcGVyc2lzdGVuY2U6IHN0cmluZyB8IG51bGwsXG4gICAgQE9wdGlvbmFsKCkgX2FwcENoZWNrSW5zdGFuY2VzOiBBcHBDaGVja0luc3RhbmNlcyxcbiAgKSB7XG4gICAgY29uc3QgbG9naW5zID0gbmV3IFN1YmplY3Q8UmVxdWlyZWQ8ZmlyZWJhc2UuYXV0aC5Vc2VyQ3JlZGVudGlhbD4+KCk7XG5cbiAgICBjb25zdCBhdXRoID0gb2YodW5kZWZpbmVkKS5waXBlKFxuICAgICAgb2JzZXJ2ZU9uKHNjaGVkdWxlcnMub3V0c2lkZUFuZ3VsYXIpLFxuICAgICAgc3dpdGNoTWFwKCgpID0+IHpvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4gaW1wb3J0KCdmaXJlYmFzZS9jb21wYXQvYXV0aCcpKSksXG4gICAgICBtYXAoKCkgPT4gybVmaXJlYmFzZUFwcEZhY3Rvcnkob3B0aW9ucywgem9uZSwgbmFtZSkpLFxuICAgICAgbWFwKGFwcCA9PiDJtWF1dGhGYWN0b3J5KGFwcCwgem9uZSwgdXNlRW11bGF0b3IsIHRlbmFudElkLCBsYW5ndWFnZUNvZGUsIHVzZURldmljZUxhbmd1YWdlLCBzZXR0aW5ncywgcGVyc2lzdGVuY2UpKSxcbiAgICAgIHNoYXJlUmVwbGF5KHsgYnVmZmVyU2l6ZTogMSwgcmVmQ291bnQ6IGZhbHNlIH0pLFxuICAgICk7XG5cbiAgICBpZiAoaXNQbGF0Zm9ybVNlcnZlcihwbGF0Zm9ybUlkKSkge1xuXG4gICAgICB0aGlzLmF1dGhTdGF0ZSA9IHRoaXMudXNlciA9IHRoaXMuaWRUb2tlbiA9IHRoaXMuaWRUb2tlblJlc3VsdCA9IHRoaXMuY3JlZGVudGlhbCA9IG9mKG51bGwpO1xuXG4gICAgfSBlbHNlIHtcblxuICAgICAgLy8gSEFDSywgYXMgd2UncmUgZXhwb3J0aW5nIGF1dGguQXV0aCwgcmF0aGVyIHRoYW4gYXV0aCwgZGV2ZWxvcGVycyBpbXBvcnRpbmcgZmlyZWJhc2UuYXV0aFxuICAgICAgLy8gICAgICAgKGUuZywgYGltcG9ydCB7IGF1dGggfSBmcm9tICdmaXJlYmFzZS9jb21wYXQvYXBwJ2ApIGFyZSBnZXR0aW5nIGFuIHVuZGVmaW5lZCBhdXRoIG9iamVjdCB1bmV4cGVjdGVkbHlcbiAgICAgIC8vICAgICAgIGFzIHdlJ3JlIGNvbXBsZXRlbHkgbGF6eS4gTGV0J3MgZWFnZXJseSBsb2FkIHRoZSBBdXRoIFNESyBoZXJlLlxuICAgICAgLy8gICAgICAgVGhlcmUgY291bGQgcG90ZW50aWFsbHkgYmUgcmFjZSBjb25kaXRpb25zIHN0aWxsLi4uIGJ1dCB0aGlzIGdyZWF0bHkgZGVjcmVhc2VzIHRoZSBvZGRzIHdoaWxlXG4gICAgICAvLyAgICAgICB3ZSByZWV2YWx1YXRlIHRoZSBBUEkuXG4gICAgICBjb25zdCBfID0gYXV0aC5waXBlKGZpcnN0KCkpLnN1YnNjcmliZSgpO1xuXG4gICAgICBjb25zdCByZWRpcmVjdFJlc3VsdCA9IGF1dGgucGlwZShcbiAgICAgICAgc3dpdGNoTWFwKGF1dGggPT4gYXV0aC5nZXRSZWRpcmVjdFJlc3VsdCgpLnRoZW4oaXQgPT4gaXQsICgpID0+IG51bGwpKSxcbiAgICAgICAga2VlcFVuc3RhYmxlVW50aWxGaXJzdCxcbiAgICAgICAgc2hhcmVSZXBsYXkoeyBidWZmZXJTaXplOiAxLCByZWZDb3VudDogZmFsc2UgfSksXG4gICAgICApO1xuXG4gICAgICBjb25zdCBhdXRoU3RhdGVDaGFuZ2VkID0gYXV0aC5waXBlKFxuICAgICAgICBzd2l0Y2hNYXAoYXV0aCA9PiBuZXcgT2JzZXJ2YWJsZTxmaXJlYmFzZS5Vc2VyfG51bGw+KHN1YiA9PlxuICAgICAgICAgICh7IHVuc3Vic2NyaWJlOiB6b25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IGF1dGgub25BdXRoU3RhdGVDaGFuZ2VkKFxuICAgICAgICAgICAgbmV4dCA9PiBzdWIubmV4dChuZXh0KSxcbiAgICAgICAgICAgIGVyciA9PiBzdWIuZXJyb3IoZXJyKSxcbiAgICAgICAgICAgICgpID0+IHN1Yi5jb21wbGV0ZSgpXG4gICAgICAgICAgKSl9KVxuICAgICAgICApKSxcbiAgICAgICk7XG5cbiAgICAgIGNvbnN0IGlkVG9rZW5DaGFuZ2VkID0gYXV0aC5waXBlKFxuICAgICAgICBzd2l0Y2hNYXAoYXV0aCA9PiBuZXcgT2JzZXJ2YWJsZTxmaXJlYmFzZS5Vc2VyfG51bGw+KHN1YiA9PlxuICAgICAgICAgICh7IHVuc3Vic2NyaWJlOiB6b25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IGF1dGgub25JZFRva2VuQ2hhbmdlZChcbiAgICAgICAgICAgIG5leHQgPT4gc3ViLm5leHQobmV4dCksXG4gICAgICAgICAgICBlcnIgPT4gc3ViLmVycm9yKGVyciksXG4gICAgICAgICAgICAoKSA9PiBzdWIuY29tcGxldGUoKVxuICAgICAgICAgICkpfSlcbiAgICAgICAgKSlcbiAgICAgICk7XG5cbiAgICAgIHRoaXMuYXV0aFN0YXRlID0gcmVkaXJlY3RSZXN1bHQucGlwZShcbiAgICAgICAgc3dpdGNoTWFwVG8oYXV0aFN0YXRlQ2hhbmdlZCksXG4gICAgICAgIHN1YnNjcmliZU9uKHNjaGVkdWxlcnMub3V0c2lkZUFuZ3VsYXIpLFxuICAgICAgICBvYnNlcnZlT24oc2NoZWR1bGVycy5pbnNpZGVBbmd1bGFyKSxcbiAgICAgICk7XG5cbiAgICAgIHRoaXMudXNlciA9IHJlZGlyZWN0UmVzdWx0LnBpcGUoXG4gICAgICAgIHN3aXRjaE1hcFRvKGlkVG9rZW5DaGFuZ2VkKSxcbiAgICAgICAgc3Vic2NyaWJlT24oc2NoZWR1bGVycy5vdXRzaWRlQW5ndWxhciksXG4gICAgICAgIG9ic2VydmVPbihzY2hlZHVsZXJzLmluc2lkZUFuZ3VsYXIpLFxuICAgICAgKTtcblxuICAgICAgdGhpcy5pZFRva2VuID0gdGhpcy51c2VyLnBpcGUoXG4gICAgICAgIHN3aXRjaE1hcCh1c2VyID0+IHVzZXIgPyBmcm9tKHVzZXIuZ2V0SWRUb2tlbigpKSA6IG9mKG51bGwpKVxuICAgICAgKTtcblxuICAgICAgdGhpcy5pZFRva2VuUmVzdWx0ID0gdGhpcy51c2VyLnBpcGUoXG4gICAgICAgIHN3aXRjaE1hcCh1c2VyID0+IHVzZXIgPyBmcm9tKHVzZXIuZ2V0SWRUb2tlblJlc3VsdCgpKSA6IG9mKG51bGwpKVxuICAgICAgKTtcblxuICAgICAgdGhpcy5jcmVkZW50aWFsID0gbWVyZ2UoXG4gICAgICAgIHJlZGlyZWN0UmVzdWx0LFxuICAgICAgICBsb2dpbnMsXG4gICAgICAgIC8vIHBpcGUgaW4gbnVsbCBhdXRoU3RhdGUgdG8gbWFrZSBjcmVkZW50aWFsIHppcGFibGUsIGp1c3QgYSB3ZWlyZCBkZXZleHAgaWZcbiAgICAgICAgLy8gYXV0aFN0YXRlIGFuZCB1c2VyIGdvIG51bGwgdG8gc3RpbGwgaGF2ZSBhIGNyZWRlbnRpYWxcbiAgICAgICAgdGhpcy5hdXRoU3RhdGUucGlwZShmaWx0ZXIoaXQgPT4gIWl0KSlcbiAgICAgICkucGlwZShcbiAgICAgICAgLy8gaGFuZGxlIHRoZSB7IHVzZXI6IHsgfSB9IHdoZW4gYSB1c2VyIGlzIGFscmVhZHkgbG9nZ2VkIGluLCByYXRoZXIgaGF2ZSBudWxsXG4gICAgICAgIC8vIFRPRE8gaGFuZGxlIHRoZSB0eXBlIGNvcmNlcnNpb24gYmV0dGVyXG4gICAgICAgIG1hcChjcmVkZW50aWFsID0+IGNyZWRlbnRpYWw/LnVzZXIgPyBjcmVkZW50aWFsIGFzIFJlcXVpcmVkPGZpcmViYXNlLmF1dGguVXNlckNyZWRlbnRpYWw+IDogbnVsbCksXG4gICAgICAgIHN1YnNjcmliZU9uKHNjaGVkdWxlcnMub3V0c2lkZUFuZ3VsYXIpLFxuICAgICAgICBvYnNlcnZlT24oc2NoZWR1bGVycy5pbnNpZGVBbmd1bGFyKSxcbiAgICAgICk7XG5cbiAgICB9XG5cbiAgICByZXR1cm4gybVsYXp5U0RLUHJveHkodGhpcywgYXV0aCwgem9uZSwgeyBzcHk6IHtcbiAgICAgIGFwcGx5OiAobmFtZSwgXywgdmFsKSA9PiB7XG4gICAgICAgIC8vIElmIHRoZXkgY2FsbCBhIHNpZ25JbiBvciBjcmVhdGVVc2VyIGZ1bmN0aW9uIGxpc3RlbiBpbnRvIHRoZSBwcm9taXNlXG4gICAgICAgIC8vIHRoaXMgd2lsbCBnaXZlIHVzIHRoZSB1c2VyIGNyZWRlbnRpYWwsIHB1c2ggb250byB0aGUgbG9naW5zIFN1YmplY3RcbiAgICAgICAgLy8gdG8gYmUgY29uc3VtZWQgaW4gLmNyZWRlbnRpYWxcbiAgICAgICAgaWYgKG5hbWUuc3RhcnRzV2l0aCgnc2lnbkluJykgfHwgbmFtZS5zdGFydHNXaXRoKCdjcmVhdGVVc2VyJykpIHtcbiAgICAgICAgICAvLyBUT0RPIGZpeCB0aGUgdHlwZXMsIHRoZSB0cm91YmxlIGlzIFVzZXJDcmVkZW50aWFsIGhhcyBldmVyeXRoaW5nIG9wdGlvbmFsXG4gICAgICAgICAgdmFsLnRoZW4oKHVzZXI6IGZpcmViYXNlLmF1dGguVXNlckNyZWRlbnRpYWwpID0+IGxvZ2lucy5uZXh0KHVzZXIgYXMgYW55KSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9fSk7XG5cbiAgfVxuXG59XG5cbsm1YXBwbHlNaXhpbnMoQW5ndWxhckZpcmVBdXRoLCBbcHJveHlQb2x5ZmlsbENvbXBhdF0pO1xuIl19