import { __awaiter } from "tslib"; import { ComponentFactoryResolver, Injectable, NgZone, Optional, Injector } from '@angular/core'; import { of } from 'rxjs'; import { distinctUntilChanged, filter, groupBy, map, mergeMap, pairwise, startWith, switchMap } from 'rxjs/operators'; import { ActivationEnd, Router, ɵEmptyOutletComponent } from '@angular/router'; import { Title } from '@angular/platform-browser'; import { VERSION } from '@angular/fire'; import { registerVersion } from 'firebase/app'; import { Analytics } from './analytics'; import { logEvent, isSupported } from './firebase'; import { UserTrackingService } from './user-tracking.service'; import * as i0 from "@angular/core"; import * as i1 from "@angular/router"; import * as i2 from "@angular/platform-browser"; import * as i3 from "./user-tracking.service"; const FIREBASE_EVENT_ORIGIN_KEY = 'firebase_event_origin'; const FIREBASE_PREVIOUS_SCREEN_CLASS_KEY = 'firebase_previous_class'; const FIREBASE_PREVIOUS_SCREEN_INSTANCE_ID_KEY = 'firebase_previous_id'; const FIREBASE_PREVIOUS_SCREEN_NAME_KEY = 'firebase_previous_screen'; const FIREBASE_SCREEN_CLASS_KEY = 'firebase_screen_class'; const FIREBASE_SCREEN_INSTANCE_ID_KEY = 'firebase_screen_id'; const FIREBASE_SCREEN_NAME_KEY = 'firebase_screen'; const OUTLET_KEY = 'outlet'; const PAGE_PATH_KEY = 'page_path'; const PAGE_TITLE_KEY = 'page_title'; const SCREEN_CLASS_KEY = 'screen_class'; const SCREEN_NAME_KEY = 'screen_name'; const SCREEN_VIEW_EVENT = 'screen_view'; const EVENT_ORIGIN_AUTO = 'auto'; const SCREEN_INSTANCE_DELIMITER = '#'; // this is an INT64 in iOS/Android but use INT32 cause javascript let nextScreenInstanceID = Math.floor(Math.random() * (Math.pow(2, 32) - 1)) - Math.pow(2, 31); const knownScreenInstanceIDs = {}; const getScreenInstanceID = (params) => { // unique the screen class against the outlet name const screenInstanceKey = [ params[SCREEN_CLASS_KEY], params[OUTLET_KEY] ].join(SCREEN_INSTANCE_DELIMITER); if (knownScreenInstanceIDs.hasOwnProperty(screenInstanceKey)) { return knownScreenInstanceIDs[screenInstanceKey]; } else { const ret = nextScreenInstanceID++; knownScreenInstanceIDs[screenInstanceKey] = ret; return ret; } }; export const ɵscreenViewEvent = (router, title, componentFactoryResolver) => { const activationEndEvents = router.events.pipe(filter(e => e instanceof ActivationEnd)); return activationEndEvents.pipe(switchMap(activationEnd => { var _a; // router parseUrl is having trouble with outlets when they're empty // e.g, /asdf/1(bob://sally:asdf), so put another slash in when empty const urlTree = router.parseUrl(router.url.replace(/(?:\().+(?:\))/g, a => a.replace('://', ':///'))); const pagePath = ((_a = urlTree.root.children[activationEnd.snapshot.outlet]) === null || _a === void 0 ? void 0 : _a.toString()) || ''; const actualSnapshot = router.routerState.root.children.map(it => it).find(it => it.outlet === activationEnd.snapshot.outlet); if (!actualSnapshot) { return of(null); } let actualDeep = actualSnapshot; while (actualDeep.firstChild) { actualDeep = actualDeep.firstChild; } const screenName = actualDeep.pathFromRoot.map(s => { var _a; return (_a = s.routeConfig) === null || _a === void 0 ? void 0 : _a.path; }).filter(it => it).join('/') || '/'; const params = { [SCREEN_NAME_KEY]: screenName, [PAGE_PATH_KEY]: `/${pagePath}`, [FIREBASE_EVENT_ORIGIN_KEY]: EVENT_ORIGIN_AUTO, [FIREBASE_SCREEN_NAME_KEY]: screenName, [OUTLET_KEY]: activationEnd.snapshot.outlet }; if (title) { params[PAGE_TITLE_KEY] = title.getTitle(); } let component = actualSnapshot.component; if (component) { if (component === ɵEmptyOutletComponent) { let deepSnapshot = activationEnd.snapshot; // TODO when might there be mutple children, different outlets? explore while (deepSnapshot.firstChild) { deepSnapshot = deepSnapshot.firstChild; } component = deepSnapshot.component; } } else { component = activationEnd.snapshot.component; } if (typeof component === 'string') { return of(Object.assign(Object.assign({}, params), { [SCREEN_CLASS_KEY]: component })); } else if (component) { const componentFactory = componentFactoryResolver.resolveComponentFactory(component); return of(Object.assign(Object.assign({}, params), { [SCREEN_CLASS_KEY]: componentFactory.selector })); } // lazy loads cause extra activations, ignore return of(null); }), filter(it => !!it), map(params => (Object.assign({ [FIREBASE_SCREEN_CLASS_KEY]: params[SCREEN_CLASS_KEY], [FIREBASE_SCREEN_INSTANCE_ID_KEY]: getScreenInstanceID(params) }, params))), groupBy(it => it[OUTLET_KEY]), mergeMap(it => it.pipe(distinctUntilChanged((a, b) => JSON.stringify(a) === JSON.stringify(b)), startWith(undefined), pairwise(), map(([prior, current]) => prior ? Object.assign({ [FIREBASE_PREVIOUS_SCREEN_CLASS_KEY]: prior[SCREEN_CLASS_KEY], [FIREBASE_PREVIOUS_SCREEN_NAME_KEY]: prior[SCREEN_NAME_KEY], [FIREBASE_PREVIOUS_SCREEN_INSTANCE_ID_KEY]: prior[FIREBASE_SCREEN_INSTANCE_ID_KEY] }, current) : current)))); }; export class ScreenTrackingService { constructor(router, title, componentFactoryResolver, zone, userTrackingService, injector) { registerVersion('angularfire', VERSION.full, 'screen-tracking'); // The APP_INITIALIZER that is making isSupported() sync for the sake of convenient DI // may not be done when services are initialized. Guard the functionality by first ensuring // that the (global) promise has resolved, then get Analytics from the injector. isSupported().then(() => { const analytics = injector.get(Analytics); if (!router || !analytics) { return; } zone.runOutsideAngular(() => { this.disposable = ɵscreenViewEvent(router, title, componentFactoryResolver).pipe(switchMap((params) => __awaiter(this, void 0, void 0, function* () { if (userTrackingService) { yield userTrackingService.initialized; } return logEvent(analytics, SCREEN_VIEW_EVENT, params); }))).subscribe(); }); }); } ngOnDestroy() { if (this.disposable) { this.disposable.unsubscribe(); } } } ScreenTrackingService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.3", ngImport: i0, type: ScreenTrackingService, deps: [{ token: i1.Router, optional: true }, { token: i2.Title, optional: true }, { token: i0.ComponentFactoryResolver }, { token: i0.NgZone }, { token: i3.UserTrackingService, optional: true }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable }); ScreenTrackingService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.1.3", ngImport: i0, type: ScreenTrackingService }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.3", ngImport: i0, type: ScreenTrackingService, decorators: [{ type: Injectable }], ctorParameters: function () { return [{ type: i1.Router, decorators: [{ type: Optional }] }, { type: i2.Title, decorators: [{ type: Optional }] }, { type: i0.ComponentFactoryResolver }, { type: i0.NgZone }, { type: i3.UserTrackingService, decorators: [{ type: Optional }] }, { type: i0.Injector }]; } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NyZWVuLXRyYWNraW5nLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvYW5hbHl0aWNzL3NjcmVlbi10cmFja2luZy5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBYSxRQUFRLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzVHLE9BQU8sRUFBRSxFQUFFLEVBQTRCLE1BQU0sTUFBTSxDQUFDO0FBQ3BELE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN0SCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9FLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUNsRCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3hDLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFFL0MsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUN4QyxPQUFPLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUNuRCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQzs7Ozs7QUFFOUQsTUFBTSx5QkFBeUIsR0FBRyx1QkFBdUIsQ0FBQztBQUMxRCxNQUFNLGtDQUFrQyxHQUFHLHlCQUF5QixDQUFDO0FBQ3JFLE1BQU0sd0NBQXdDLEdBQUcsc0JBQXNCLENBQUM7QUFDeEUsTUFBTSxpQ0FBaUMsR0FBRywwQkFBMEIsQ0FBQztBQUNyRSxNQUFNLHlCQUF5QixHQUFHLHVCQUF1QixDQUFD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QUM7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxXQUFXO1FBQ1QsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFO1lBQ25CLElBQUksQ0FBQyxVQUFVLENBQUMsV0FBVyxFQUFFLENBQUM7U0FDL0I7SUFDSCxDQUFDOztrSEFsQ1UscUJBQXFCO3NIQUFyQixxQkFBcUI7MkZBQXJCLHFCQUFxQjtrQkFEakMsVUFBVTs7MEJBTU4sUUFBUTs7MEJBQ1IsUUFBUTs7MEJBR1IsUUFBUSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudEZhY3RvcnlSZXNvbHZlciwgSW5qZWN0YWJsZSwgTmdab25lLCBPbkRlc3Ryb3ksIE9wdGlvbmFsLCBJbmplY3RvciB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgb2YsIFN1YnNjcmlwdGlvbiwgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZGlzdGluY3RVbnRpbENoYW5nZWQsIGZpbHRlciwgZ3JvdXBCeSwgbWFwLCBtZXJnZU1hcCwgcGFpcndpc2UsIHN0YXJ0V2l0aCwgc3dpdGNoTWFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgQWN0aXZhdGlvbkVuZCwgUm91dGVyLCDJtUVtcHR5T3V0bGV0Q29tcG9uZW50IH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7IFRpdGxlIH0gZnJvbSAnQGFuZ3VsYXIvcGxhdGZvcm0tYnJvd3Nlcic7XG5pbXBvcnQgeyBWRVJTSU9OIH0gZnJvbSAnQGFuZ3VsYXIvZmlyZSc7XG5pbXBvcnQgeyByZWdpc3RlclZlcnNpb24gfSBmcm9tICdmaXJlYmFzZS9hcHAnO1xuXG5pbXBvcnQgeyBBbmFseXRpY3MgfSBmcm9tICcuL2FuYWx5dGljcyc7XG5pbXBvcnQgeyBsb2dFdmVudCwgaXNTdXBwb3J0ZWQgfSBmcm9tICcuL2ZpcmViYXNlJztcbmltcG9ydCB7IFVzZXJUcmFja2luZ1NlcnZpY2UgfSBmcm9tICcuL3VzZXItdHJhY2tpbmcuc2VydmljZSc7XG5cbmNvbnN0IEZJUkVCQVNFX0VWRU5UX09SSUdJTl9LRVkgPSAnZmlyZWJhc2VfZXZlbnRfb3JpZ2luJztcbmNvbnN0IEZJUkVCQVNFX1BSRVZJT1VTX1NDUkVFTl9DTEFTU19LRVkgPSAnZmlyZWJhc2VfcHJldmlvdXNfY2xhc3MnO1xuY29uc3QgRklSRUJBU0VfUFJFVklPVVNfU0NSRUVOX0lOU1RBTkNFX0lEX0tFWSA9ICdmaXJlYmFzZV9wcmV2aW91c19pZCc7XG5jb25zdCBGSVJFQkFTRV9QUkVWSU9VU19TQ1JFRU5fTkFNRV9LRVkgPSAnZmlyZWJhc2VfcHJldmlvdXNfc2NyZWVuJztcbmNvbnN0IEZJUkVCQVNFX1NDUkVFTl9DTEFTU19LRVkgPSAnZmlyZWJhc2Vfc2NyZWVuX2NsYXNzJztcbmNvbnN0IEZJUkVCQVNFX1NDUkVFTl9JTlNUQU5DRV9JRF9LRVkgPSAnZmlyZWJhc2Vfc2NyZWVuX2lkJztcbmNvbnN0IEZJUkVCQVNFX1NDUkVFTl9OQU1FX0tFWSA9ICdmaXJlYmFzZV9zY3JlZW4nO1xuY29uc3QgT1VUTEVUX0tFWSA9ICdvdXRsZXQnO1xuY29uc3QgUEFHRV9QQVRIX0tFWSA9ICdwYWdlX3BhdGgnO1xuY29uc3QgUEFHRV9USVRMRV9LRVkgPSAncGFnZV90aXRsZSc7XG5jb25zdCBTQ1JFRU5fQ0xBU1NfS0VZID0gJ3NjcmVlbl9jbGFzcyc7XG5jb25zdCBTQ1JFRU5fTkFNRV9LRVkgPSAnc2NyZWVuX25hbWUnO1xuY29uc3QgU0NSRUVOX1ZJRVdfRVZFTlQgPSAnc2NyZWVuX3ZpZXcnO1xuY29uc3QgRVZFTlRfT1JJR0lOX0FVVE8gPSAnYXV0byc7XG5jb25zdCBTQ1JFRU5fSU5TVEFOQ0VfREVMSU1JVEVSID0gJyMnO1xuXG4vLyB0aGlzIGlzIGFuIElOVDY0IGluIGlPUy9BbmRyb2lkIGJ1dCB1c2UgSU5UMzIgY2F1c2UgamF2YXNjcmlwdFxubGV0IG5leHRTY3JlZW5JbnN0YW5jZUlEID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogKDIgKiogMzIgLSAxKSkgLSAyICoqIDMxO1xuXG5jb25zdCBrbm93blNjcmVlbkluc3RhbmNlSURzOiB7IFtrZXk6IHN0cmluZ106IG51bWJlciB9ID0ge307XG5cbmNvbnN0IGdldFNjcmVlbkluc3RhbmNlSUQgPSAocGFyYW1zOiB7IFtrZXk6IHN0cmluZ106IGFueSB9KSA9PiB7XG4gIC8vIHVuaXF1ZSB0aGUgc2NyZWVuIGNsYXNzIGFnYWluc3QgdGhlIG91dGxldCBuYW1lXG4gIGNvbnN0IHNjcmVlbkluc3RhbmNlS2V5ID0gW1xuICAgIHBhcmFtc1tTQ1JFRU5fQ0xBU1NfS0VZXSxcbiAgICBwYXJhbXNbT1VUTEVUX0tFWV1cbiAgXS5qb2luKFNDUkVFTl9JTlNUQU5DRV9ERUxJTUlURVIpO1xuICBpZiAoa25vd25TY3JlZW5JbnN0YW5jZUlEcy5oYXNPd25Qcm9wZXJ0eShzY3JlZW5JbnN0YW5jZUtleSkpIHtcbiAgICByZXR1cm4ga25vd25TY3JlZW5JbnN0YW5jZUlEc1tzY3JlZW5JbnN0YW5jZUtleV07XG4gIH0gZWxzZSB7XG4gICAgY29uc3QgcmV0ID0gbmV4dFNjcmVlbkluc3RhbmNlSUQrKztcbiAgICBrbm93blNjcmVlbkluc3RhbmNlSURzW3NjcmVlbkluc3RhbmNlS2V5XSA9IHJldDtcbiAgICByZXR1cm4gcmV0O1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgybVzY3JlZW5WaWV3RXZlbnQgPSAoXG4gIHJvdXRlcjogUm91dGVyLFxuICB0aXRsZTogVGl0bGV8bnVsbCxcbiAgY29tcG9uZW50RmFjdG9yeVJlc29sdmVyOiBDb21wb25lbnRGYWN0b3J5UmVzb2x2ZXIsXG4pOiBPYnNlcnZhYmxlPHtcbiAgW1NDUkVFTl9OQU1FX0tFWV06IHN0cmluZyxcbiAgW1BBR0VfUEFUSF9LRVldOiBzdHJpbmcsXG4gIFtGSVJFQkFTRV9FVkVOVF9PUklHSU5fS0VZXTogJ2F1dG8nLFxuICBbRklSRUJBU0VfU0NSRUVOX05BTUVfS0VZXTogc3RyaW5nLFxuICBbT1VUTEVUX0tFWV06IHN0cmluZyxcbiAgW1BBR0VfVElUTEVfS0VZXT86IHN0cmluZyxcbiAgW1NDUkVFTl9DTEFTU19LRVldOiBzdHJpbmcsXG4gIFtGSVJFQkFTRV9TQ1JFRU5fQ0xBU1NfS0VZXTogc3RyaW5nLFxuICBbRklSRUJBU0VfU0NSRUVOX0lOU1RBTkNFX0lEX0tFWV06IG51bWJlcixcbiAgW0ZJUkVCQVNFX1BSRVZJT1VTX1NDUkVFTl9DTEFTU19LRVldOiBzdHJpbmcsXG4gIFtGSVJFQkFTRV9QUkVWSU9VU19TQ1JFRU5fTkFNRV9LRVldOiBzdHJpbmcsXG4gIFtGSVJFQkFTRV9QUkVWSU9VU19TQ1JFRU5fSU5TVEFOQ0VfSURfS0VZXTogbnVtYmVyLFxufT4gPT4ge1xuICBjb25zdCBhY3RpdmF0aW9uRW5kRXZlbnRzID0gcm91dGVyLmV2ZW50cy5waXBlKGZpbHRlcjxBY3RpdmF0aW9uRW5kPihlID0+IGUgaW5zdGFuY2VvZiBBY3RpdmF0aW9uRW5kKSk7XG4gIHJldHVybiBhY3RpdmF0aW9uRW5kRXZlbnRzLnBpcGUoXG4gICAgc3dpdGNoTWFwPEFjdGl2YXRpb25FbmQsIE9ic2VydmFibGU8UmVjb3JkPHN0cmluZywgYW55PnxudWxsPj4oYWN0aXZhdGlvbkVuZCA9PiB7XG4gICAgICAvLyByb3V0ZXIgcGFyc2VVcmwgaXMgaGF2aW5nIHRyb3VibGUgd2l0aCBvdXRsZXRzIHdoZW4gdGhleSdyZSBlbXB0eVxuICAgICAgLy8gZS5nLCAvYXNkZi8xKGJvYjovL3NhbGx5OmFzZGYpLCBzbyBwdXQgYW5vdGhlciBzbGFzaCBpbiB3aGVuIGVtcHR5XG4gICAgICBjb25zdCB1cmxUcmVlID0gcm91dGVyLnBhcnNlVXJsKHJvdXRlci51cmwucmVwbGFjZSgvKD86XFwoKS4rKD86XFwpKS9nLCBhID0+IGEucmVwbGFjZSgnOi8vJywgJzovLy8nKSkpO1xuICAgICAgY29uc3QgcGFnZVBhdGggPSB1cmxUcmVlLnJvb3QuY2hpbGRyZW5bYWN0aXZhdGlvbkVuZC5zbmFwc2hvdC5vdXRsZXRdPy50b1N0cmluZygpIHx8ICcnO1xuICAgICAgY29uc3QgYWN0dWFsU25hcHNob3QgPSByb3V0ZXIucm91dGVyU3RhdGUucm9vdC5jaGlsZHJlbi5tYXAoaXQgPT4gaXQpLmZpbmQoaXQgPT4gaXQub3V0bGV0ID09PSBhY3RpdmF0aW9uRW5kLnNuYXBzaG90Lm91dGxldCk7XG5cbiAgICAgIGlmICghYWN0dWFsU25hcHNob3QpIHtcbiAgICAgICAgcmV0dXJuIG9mKG51bGwpO1xuICAgICAgfVxuXG4gICAgICBsZXQgYWN0dWFsRGVlcCA9IGFjdHVhbFNuYXBzaG90O1xuICAgICAgd2hpbGUgKGFjdHVhbERlZXAuZmlyc3RDaGlsZCkge1xuICAgICAgICBhY3R1YWxEZWVwID0gYWN0dWFsRGVlcC5maXJzdENoaWxkO1xuICAgICAgfVxuICAgICAgY29uc3Qgc2NyZWVuTmFtZSA9IGFjdHVhbERlZXAucGF0aEZyb21Sb290Lm1hcChzID0+IHMucm91dGVDb25maWc/LnBhdGgpLmZpbHRlcihpdCA9PiBpdCkuam9pbignLycpIHx8ICcvJztcblxuICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICBbU0NSRUVOX05BTUVfS0VZXTogc2NyZWVuTmFtZSxcbiAgICAgICAgW1BBR0VfUEFUSF9LRVldOiBgLyR7cGFnZVBhdGh9YCxcbiAgICAgICAgW0ZJUkVCQVNFX0VWRU5UX09SSUdJTl9LRVldOiBFVkVOVF9PUklHSU5fQVVUTyxcbiAgICAgICAgW0ZJUkVCQVNFX1NDUkVFTl9OQU1FX0tFWV06IHNjcmVlbk5hbWUsXG4gICAgICAgIFtPVVRMRVRfS0VZXTogYWN0aXZhdGlvbkVuZC5zbmFwc2hvdC5vdXRsZXRcbiAgICAgIH07XG4gICAgICBpZiAodGl0bGUpIHtcbiAgICAgICAgcGFyYW1zW1BBR0VfVElUTEVfS0VZXSA9IHRpdGxlLmdldFRpdGxlKCk7XG4gICAgICB9XG5cbiAgICAgIGxldCBjb21wb25lbnQgPSBhY3R1YWxTbmFwc2hvdC5jb21wb25lbnQ7XG4gICAgICBpZiAoY29tcG9uZW50KSB7XG4gICAgICAgIGlmIChjb21wb25lbnQgPT09IMm1RW1wdHlPdXRsZXRDb21wb25lbnQpIHtcbiAgICAgICAgICBsZXQgZGVlcFNuYXBzaG90ID0gYWN0aXZhdGlvbkVuZC5zbmFwc2hvdDtcbiAgICAgICAgICAvLyBUT0RPIHdoZW4gbWlnaHQgdGhlcmUgYmUgbXV0cGxlIGNoaWxkcmVuLCBkaWZmZXJlbnQgb3V0bGV0cz8gZXhwbG9yZVxuICAgICAgICAgIHdoaWxlIChkZWVwU25hcHNob3QuZmlyc3RDaGlsZCkge1xuICAgICAgICAgICAgZGVlcFNuYXBzaG90ID0gZGVlcFNuYXBzaG90LmZpcnN0Q2hpbGQ7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbXBvbmVudCA9IGRlZXBTbmFwc2hvdC5jb21wb25lbnQ7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbXBvbmVudCA9IGFjdGl2YXRpb25FbmQuc25hcHNob3QuY29tcG9uZW50O1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZW9mIGNvbXBvbmVudCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgcmV0dXJuIG9mKHsgLi4ucGFyYW1zLCBbU0NSRUVOX0NMQVNTX0tFWV06IGNvbXBvbmVudCB9KTtcbiAgICAgIH0gZWxzZSBpZiAoY29tcG9uZW50KSB7XG4gICAgICAgIGNvbnN0IGNvbXBvbmVudEZhY3RvcnkgPSBjb21wb25lbnRGYWN0b3J5UmVzb2x2ZXIucmVzb2x2ZUNvbXBvbmVudEZhY3RvcnkoY29tcG9uZW50KTtcbiAgICAgICAgcmV0dXJuIG9mKHsgLi4ucGFyYW1zLCBbU0NSRUVOX0NMQVNTX0tFWV06IGNvbXBvbmVudEZhY3Rvcnkuc2VsZWN0b3IgfSk7XG4gICAgICB9XG4gICAgICAvLyBsYXp5IGxvYWRzIGNhdXNlIGV4dHJhIGFjdGl2YXRpb25zLCBpZ25vcmVcbiAgICAgIHJldHVybiBvZihudWxsKTtcbiAgICB9KSxcbiAgICBmaWx0ZXIoaXQgPT4gISFpdCksXG4gICAgbWFwKHBhcmFtcyA9PiAoe1xuICAgICAgW0ZJUkVCQVNFX1NDUkVFTl9DTEFTU19LRVldOiBwYXJhbXNbU0NSRUVOX0NMQVNTX0tFWV0sXG4gICAgICBbRklSRUJBU0VfU0NSRUVOX0lOU1RBTkNFX0lEX0tFWV06IGdldFNjcmVlbkluc3RhbmNlSUQocGFyYW1zKSxcbiAgICAgIC4uLnBhcmFtc1xuICAgIH0pKSxcbiAgICBncm91cEJ5KGl0ID0+IGl0W09VVExFVF9LRVldKSxcbiAgICBtZXJnZU1hcChpdCA9PiBpdC5waXBlKFxuICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKGEsIGIpID0+IEpTT04uc3RyaW5naWZ5KGEpID09PSBKU09OLnN0cmluZ2lmeShiKSksXG4gICAgICBzdGFydFdpdGg8YW55LCBhbnk+KHVuZGVmaW5lZCksXG4gICAgICBwYWlyd2lzZSgpLFxuICAgICAgbWFwKChbcHJpb3IsIGN1cnJlbnRdKSA9PlxuICAgICAgICBwcmlvciA/IHtcbiAgICAgICAgICBbRklSRUJBU0VfUFJFVklPVVNfU0NSRUVOX0NMQVNTX0tFWV06IHByaW9yW1NDUkVFTl9DTEFTU19LRVldLFxuICAgICAgICAgIFtGSVJFQkFTRV9QUkVWSU9VU19TQ1JFRU5fTkFNRV9LRVldOiBwcmlvcltTQ1JFRU5fTkFNRV9LRVldLFxuICAgICAgICAgIFtGSVJFQkFTRV9QUkVWSU9VU19TQ1JFRU5fSU5TVEFOQ0VfSURfS0VZXTogcHJpb3JbRklSRUJBU0VfU0NSRUVOX0lOU1RBTkNFX0lEX0tFWV0sXG4gICAgICAgICAgLi4uY3VycmVudFxuICAgICAgICB9IDogY3VycmVudFxuICAgICAgKSxcbiAgICApKVxuICApO1xufTtcblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIFNjcmVlblRyYWNraW5nU2VydmljZSBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XG5cbiAgcHJpdmF0ZSBkaXNwb3NhYmxlOiBTdWJzY3JpcHRpb24gfCB1bmRlZmluZWQ7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgQE9wdGlvbmFsKCkgcm91dGVyOiBSb3V0ZXIsXG4gICAgQE9wdGlvbmFsKCkgdGl0bGU6IFRpdGxlLFxuICAgIGNvbXBvbmVudEZhY3RvcnlSZXNvbHZlcjogQ29tcG9uZW50RmFjdG9yeVJlc29sdmVyLFxuICAgIHpvbmU6IE5nWm9uZSxcbiAgICBAT3B0aW9uYWwoKSB1c2VyVHJhY2tpbmdTZXJ2aWNlOiBVc2VyVHJhY2tpbmdTZXJ2aWNlLFxuICAgIGluamVjdG9yOiBJbmplY3RvcixcbiAgKSB7XG4gICAgcmVnaXN0ZXJWZXJzaW9uKCdhbmd1bGFyZmlyZScsIFZFUlNJT04uZnVsbCwgJ3NjcmVlbi10cmFja2luZycpO1xuICAgIC8vIFRoZSBBUFBfSU5JVElBTElaRVIgdGhhdCBpcyBtYWtpbmcgaXNTdXBwb3J0ZWQoKSBzeW5jIGZvciB0aGUgc2FrZSBvZiBjb252ZW5pZW50IERJXG4gICAgLy8gbWF5IG5vdCBiZSBkb25lIHdoZW4gc2VydmljZXMgYXJlIGluaXRpYWxpemVkLiBHdWFyZCB0aGUgZnVuY3Rpb25hbGl0eSBieSBmaXJzdCBlbnN1cmluZ1xuICAgIC8vIHRoYXQgdGhlIChnbG9iYWwpIHByb21pc2UgaGFzIHJlc29sdmVkLCB0aGVuIGdldCBBbmFseXRpY3MgZnJvbSB0aGUgaW5qZWN0b3IuXG4gICAgaXNTdXBwb3J0ZWQoKS50aGVuKCgpID0+IHtcbiAgICAgIGNvbnN0IGFuYWx5dGljcyA9IGluamVjdG9yLmdldChBbmFseXRpY3MpO1xuICAgICAgaWYgKCFyb3V0ZXIgfHwgIWFuYWx5dGljcykgeyByZXR1cm47IH1cbiAgICAgIHpvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgICB0aGlzLmRpc3Bvc2FibGUgPSDJtXNjcmVlblZpZXdFdmVudChyb3V0ZXIsIHRpdGxlLCBjb21wb25lbnRGYWN0b3J5UmVzb2x2ZXIpLnBpcGUoXG4gICAgICAgICAgc3dpdGNoTWFwKGFzeW5jIHBhcmFtcyA9PiB7XG4gICAgICAgICAgICBpZiAodXNlclRyYWNraW5nU2VydmljZSkgeyBhd2FpdCB1c2VyVHJhY2tpbmdTZXJ2aWNlLmluaXRpYWxpemVkOyB9XG4gICAgICAgICAgICByZXR1cm4gbG9nRXZlbnQoYW5hbHl0aWNzLCBTQ1JFRU5fVklFV19FVkVOVCwgcGFyYW1zKTtcbiAgICAgICAgICB9KVxuICAgICAgICApLnN1YnNjcmliZSgpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICBpZiAodGhpcy5kaXNwb3NhYmxlKSB7XG4gICAgICB0aGlzLmRpc3Bvc2FibGUudW5zdWJzY3JpYmUoKTtcbiAgICB9XG4gIH1cblxufVxuIl19