@angular/fire
Version:
The official library for Firebase and Angular
276 lines • 22.2 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { asyncScheduler, queueScheduler } from 'rxjs';
import { observeOn, subscribeOn, tap } from 'rxjs/operators';
/**
* @return {?}
*/
function noop() {
}
/**
* Schedules tasks so that they are invoked inside the Zone that is passed in the constructor.
*/
// tslint:disable-next-line:class-name
export class ɵZoneScheduler {
/**
* @param {?} zone
* @param {?=} delegate
*/
constructor(zone, delegate = queueScheduler) {
this.zone = zone;
this.delegate = delegate;
}
/**
* @return {?}
*/
now() {
return this.delegate.now();
}
/**
* @param {?} work
* @param {?=} delay
* @param {?=} state
* @return {?}
*/
schedule(work, delay, state) {
/** @type {?} */
const targetZone = this.zone;
// Wrap the specified work function to make sure that if nested scheduling takes place the
// work is executed in the correct zone
/** @type {?} */
const workInZone = (/**
* @this {?}
* @param {?} state
* @return {?}
*/
function (state) {
targetZone.runGuarded((/**
* @return {?}
*/
() => {
work.apply(this, [state]);
}));
});
// Scheduling itself needs to be run in zone to ensure setInterval calls for async scheduling are done
// inside the correct zone. This scheduler needs to schedule asynchronously always to ensure that
// firebase emissions are never synchronous. Specifying a delay causes issues with the queueScheduler delegate.
return this.delegate.schedule(workInZone, delay, state);
}
}
if (false) {
/**
* @type {?}
* @private
*/
ɵZoneScheduler.prototype.zone;
/**
* @type {?}
* @private
*/
ɵZoneScheduler.prototype.delegate;
}
// tslint:disable-next-line:class-name
/**
* @template T
*/
export class ɵBlockUntilFirstOperator {
/**
* @param {?} zone
*/
constructor(zone) {
this.zone = zone;
this.task = null;
}
/**
* @param {?} subscriber
* @param {?} source
* @return {?}
*/
call(subscriber, source) {
/** @type {?} */
const unscheduleTask = this.unscheduleTask.bind(this);
this.task = this.zone.run((/**
* @return {?}
*/
() => Zone.current.scheduleMacroTask('firebaseZoneBlock', noop, {}, noop, noop)));
return source.pipe(tap({ next: unscheduleTask, complete: unscheduleTask, error: unscheduleTask })).subscribe(subscriber).add(unscheduleTask);
}
/**
* @private
* @return {?}
*/
unscheduleTask() {
// maybe this is a race condition, invoke in a timeout
// hold for 10ms while I try to figure out what is going on
setTimeout((/**
* @return {?}
*/
() => {
if (this.task != null && this.task.state === 'scheduled') {
this.task.invoke();
this.task = null;
}
}), 10);
}
}
if (false) {
/**
* @type {?}
* @private
*/
ɵBlockUntilFirstOperator.prototype.task;
/**
* @type {?}
* @private
*/
ɵBlockUntilFirstOperator.prototype.zone;
}
// tslint:disable-next-line:class-name
export class ɵAngularFireSchedulers {
/**
* @param {?} ngZone
*/
constructor(ngZone) {
this.ngZone = ngZone;
this.outsideAngular = ngZone.runOutsideAngular((/**
* @return {?}
*/
() => new ɵZoneScheduler(Zone.current)));
this.insideAngular = ngZone.run((/**
* @return {?}
*/
() => new ɵZoneScheduler(Zone.current, asyncScheduler)));
}
}
if (false) {
/** @type {?} */
ɵAngularFireSchedulers.prototype.outsideAngular;
/** @type {?} */
ɵAngularFireSchedulers.prototype.insideAngular;
/** @type {?} */
ɵAngularFireSchedulers.prototype.ngZone;
}
/**
* Operator to block the zone until the first value has been emitted or the observable
* has completed/errored. This is used to make sure that universal waits until the first
* value from firebase but doesn't block the zone forever since the firebase subscription
* is still alive.
* @param {?} schedulers
* @return {?}
*/
export function ɵkeepUnstableUntilFirstFactory(schedulers) {
return (/**
* @template T
* @param {?} obs$
* @return {?}
*/
function keepUnstableUntilFirst(obs$) {
obs$ = obs$.lift(new ɵBlockUntilFirstOperator(schedulers.ngZone));
return obs$.pipe(
// Run the subscribe body outside of Angular (e.g. calling Firebase SDK to add a listener to a change event)
subscribeOn(schedulers.outsideAngular),
// Run operators inside the angular zone (e.g. side effects via tap())
observeOn(schedulers.insideAngular)
// INVESTIGATE https://github.com/angular/angularfire/pull/2315
// share()
);
});
}
// DEBUG quick debugger function for inline logging that typescript doesn't complain about
// wrote it for debugging the ɵlazySDKProxy, commenting out for now; should consider exposing a
// verbose mode for AngularFire in a future release that uses something like this in multiple places
// usage: () => log('something') || returnValue
// const log = (...args: any[]): false => { console.log(...args); return false }
// The problem here are things like ngOnDestroy are missing, then triggering the service
// rather than dig too far; I'm capturing these as I go.
/** @type {?} */
const noopFunctions = ['ngOnDestroy'];
// INVESTIGATE should we make the Proxy revokable and do some cleanup?
// right now it's fairly simple but I'm sure this will grow in complexity
/** @type {?} */
export const ɵlazySDKProxy = (/**
* @param {?} klass
* @param {?} observable
* @param {?} zone
* @return {?}
*/
(klass, observable, zone) => {
return new Proxy(klass, {
get: (/**
* @param {?} _
* @param {?} name
* @return {?}
*/
(_, name) => zone.runOutsideAngular((/**
* @return {?}
*/
() => {
if (klass[name]) {
return klass[name];
}
if (noopFunctions.includes(name)) {
return (/**
* @return {?}
*/
() => {
});
}
/** @type {?} */
const promise = observable.toPromise().then((/**
* @param {?} mod
* @return {?}
*/
mod => {
/** @type {?} */
const ret = mod && mod[name];
// TODO move to proper type guards
if (typeof ret === 'function') {
return ret.bind(mod);
}
else if (ret && ret.then) {
return ret.then((/**
* @param {?} res
* @return {?}
*/
(res) => zone.run((/**
* @return {?}
*/
() => res))));
}
else {
return zone.run((/**
* @return {?}
*/
() => ret));
}
}));
// recurse the proxy
return new Proxy((/**
* @return {?}
*/
() => undefined), {
get: (/**
* @param {?} _
* @param {?} name
* @return {?}
*/
(_, name) => promise[name]),
// TODO handle callbacks as transparently as I can
apply: (/**
* @param {?} self
* @param {?} _
* @param {?} args
* @return {?}
*/
(self, _, args) => promise.then((/**
* @param {?} it
* @return {?}
*/
it => it && it(...args))))
});
})))
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5ndWxhcmZpcmUyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvcmUvYW5ndWxhcmZpcmUyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFDQSxPQUFPLEVBQ0wsY0FBYyxFQUdkLGNBQWMsRUFNZixNQUFNLE1BQU0sQ0FBQztBQUNkLE9BQU8sRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDOzs7O0FBRTdELFNBQVMsSUFBSTtBQUNiLENBQUM7Ozs7O0FBTUQsTUFBTSxPQUFPLGNBQWM7Ozs7O0lBQ3pCLFlBQW9CLElBQVMsRUFBVSxXQUFnQixjQUFjO1FBQWpELFNBQUksR0FBSixJQUFJLENBQUs7UUFBVSxhQUFRLEdBQVIsUUFBUSxDQUFzQjtJQUNyRSxDQUFDOzs7O0lBRUQsR0FBRztRQUNELE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQztJQUM3QixDQUFDOzs7Ozs7O0lBRUQsUUFBUSxDQUFDLElBQXVELEVBQUUsS0FBYyxFQUFFLEtBQVc7O2NBQ3JGLFVBQVUsR0FBRyxJQUFJLENBQUMsSUFBSTs7OztjQUd0QixVQUFVOzs7OztRQUFHLFVBQXFDLEtBQVU7WUFDaEUsVUFBVSxDQUFDLFVBQVU7OztZQUFDLEdBQUcsRUFBRTtnQkFDekIsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1lBQzVCLENBQUMsRUFBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFBO1FBRUQsc0dBQXNHO1FBQ3RHLGlHQUFpRztRQUNqRywrR0FBK0c7UUFDL0csT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxVQUFVLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQzFELENBQUM7Q0FDRjs7Ozs7O0lBdEJhLDhCQUFpQjs7Ozs7SUFBRSxrQ0FBc0M7Ozs7OztBQXlCdkUsTUFBTSxPQUFPLHdC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QUFFLElBQUksRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLEVBQUMsQ0FBQTthQUNoRSxDQUNGLENBQUM7UUFDSixDQUFDLEVBQUMsQ0FBQTtLQUNILENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IE5nWm9uZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtcbiAgYXN5bmNTY2hlZHVsZXIsXG4gIE9ic2VydmFibGUsXG4gIE9wZXJhdG9yLFxuICBxdWV1ZVNjaGVkdWxlcixcbiAgU2NoZWR1bGVyQWN0aW9uLFxuICBTY2hlZHVsZXJMaWtlLFxuICBTdWJzY3JpYmVyLFxuICBTdWJzY3JpcHRpb24sXG4gIFRlYXJkb3duTG9naWNcbn0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBvYnNlcnZlT24sIHN1YnNjcmliZU9uLCB0YXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmZ1bmN0aW9uIG5vb3AoKSB7XG59XG5cbi8qKlxuICogU2NoZWR1bGVzIHRhc2tzIHNvIHRoYXQgdGhleSBhcmUgaW52b2tlZCBpbnNpZGUgdGhlIFpvbmUgdGhhdCBpcyBwYXNzZWQgaW4gdGhlIGNvbnN0cnVjdG9yLlxuICovXG4vLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6Y2xhc3MtbmFtZVxuZXhwb3J0IGNsYXNzIMm1Wm9uZVNjaGVkdWxlciBpbXBsZW1lbnRzIFNjaGVkdWxlckxpa2Uge1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHpvbmU6IGFueSwgcHJpdmF0ZSBkZWxlZ2F0ZTogYW55ID0gcXVldWVTY2hlZHVsZXIpIHtcbiAgfVxuXG4gIG5vdygpIHtcbiAgICByZXR1cm4gdGhpcy5kZWxlZ2F0ZS5ub3coKTtcbiAgfVxuXG4gIHNjaGVkdWxlKHdvcms6ICh0aGlzOiBTY2hlZHVsZXJBY3Rpb248YW55Piwgc3RhdGU/OiBhbnkpID0+IHZvaWQsIGRlbGF5PzogbnVtYmVyLCBzdGF0ZT86IGFueSk6IFN1YnNjcmlwdGlvbiB7XG4gICAgY29uc3QgdGFyZ2V0Wm9uZSA9IHRoaXMuem9uZTtcbiAgICAvLyBXcmFwIHRoZSBzcGVjaWZpZWQgd29yayBmdW5jdGlvbiB0byBtYWtlIHN1cmUgdGhhdCBpZiBuZXN0ZWQgc2NoZWR1bGluZyB0YWtlcyBwbGFjZSB0aGVcbiAgICAvLyB3b3JrIGlzIGV4ZWN1dGVkIGluIHRoZSBjb3JyZWN0IHpvbmVcbiAgICBjb25zdCB3b3JrSW5ab25lID0gZnVuY3Rpb24odGhpczogU2NoZWR1bGVyQWN0aW9uPGFueT4sIHN0YXRlOiBhbnkpIHtcbiAgICAgIHRhcmdldFpvbmUucnVuR3VhcmRlZCgoKSA9PiB7XG4gICAgICAgIHdvcmsuYXBwbHkodGhpcywgW3N0YXRlXSk7XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgLy8gU2NoZWR1bGluZyBpdHNlbGYgbmVlZHMgdG8gYmUgcnVuIGluIHpvbmUgdG8gZW5zdXJlIHNldEludGVydmFsIGNhbGxzIGZvciBhc3luYyBzY2hlZHVsaW5nIGFyZSBkb25lXG4gICAgLy8gaW5zaWRlIHRoZSBjb3JyZWN0IHpvbmUuIFRoaXMgc2NoZWR1bGVyIG5lZWRzIHRvIHNjaGVkdWxlIGFzeW5jaHJvbm91c2x5IGFsd2F5cyB0byBlbnN1cmUgdGhhdFxuICAgIC8vIGZpcmViYXNlIGVtaXNzaW9ucyBhcmUgbmV2ZXIgc3luY2hyb25vdXMuIFNwZWNpZnlpbmcgYSBkZWxheSBjYXVzZXMgaXNzdWVzIHdpdGggdGhlIHF1ZXVlU2NoZWR1bGVyIGRlbGVnYXRlLlxuICAgIHJldHVybiB0aGlzLmRlbGVnYXRlLnNjaGVkdWxlKHdvcmtJblpvbmUsIGRlbGF5LCBzdGF0ZSk7XG4gIH1cbn1cblxuLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOmNsYXNzLW5hbWVcbmV4cG9ydCBjbGFzcyDJtUJsb2NrVW50aWxGaXJzdE9wZXJhdG9yPFQ+IGltcGxlbWVudHMgT3BlcmF0b3I8VCwgVD4ge1xuICBwcml2YXRlIHRhc2s6IE1hY3JvVGFzayB8IG51bGwgPSBudWxsO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgem9uZTogYW55KSB7XG4gIH1cblxuICBjYWxsKHN1YnNjcmliZXI6IFN1YnNjcmliZXI8VD4sIHNvdXJjZTogT2JzZXJ2YWJsZTxUPik6IFRlYXJkb3duTG9naWMge1xuICAgIGNvbnN0IHVuc2NoZWR1bGVUYXNrID0gdGhpcy51bnNjaGVkdWxlVGFzay5iaW5kKHRoaXMpO1xuICAgIHRoaXMudGFzayA9IHRoaXMuem9uZS5ydW4oKCkgPT4gWm9uZS5jdXJyZW50LnNjaGVkdWxlTWFjcm9UYXNrKCdmaXJlYmFzZVpvbmVCbG9jaycsIG5vb3AsIHt9LCBub29wLCBub29wKSk7XG5cbiAgICByZXR1cm4gc291cmNlLnBpcGUoXG4gICAgICB0YXAoeyBuZXh0OiB1bnNjaGVkdWxlVGFzaywgY29tcGxldGU6IHVuc2NoZWR1bGVUYXNrLCBlcnJvcjogdW5zY2hlZHVsZVRhc2sgfSlcbiAgICApLnN1YnNjcmliZShzdWJzY3JpYmVyKS5hZGQodW5zY2hlZHVsZVRhc2spO1xuICB9XG5cbiAgcHJpdmF0ZSB1bnNjaGVkdWxlVGFzaygpIHtcbiAgICAvLyBtYXliZSB0aGlzIGlzIGEgcmFjZSBjb25kaXRpb24sIGludm9rZSBpbiBhIHRpbWVvdXRcbiAgICAvLyBob2xkIGZvciAxMG1zIHdoaWxlIEkgdHJ5IHRvIGZpZ3VyZSBvdXQgd2hhdCBpcyBnb2luZyBvblxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgaWYgKHRoaXMudGFzayAhPSBudWxsICYmIHRoaXMudGFzay5zdGF0ZSA9PT0gJ3NjaGVkdWxlZCcpIHtcbiAgICAgICAgdGhpcy50YXNrLmludm9rZSgpO1xuICAgICAgICB0aGlzLnRhc2sgPSBudWxsO1xuICAgICAgfVxuICAgIH0sIDEwKTtcbiAgfVxufVxuXG4vLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6Y2xhc3MtbmFtZVxuZXhwb3J0IGNsYXNzIMm1QW5ndWxhckZpcmVTY2hlZHVsZXJzIHtcbiAgcHVibGljIHJlYWRvbmx5IG91dHNpZGVBbmd1bGFyOiDJtVpvbmVTY2hlZHVsZXI7XG4gIHB1YmxpYyByZWFkb25seSBpbnNpZGVBbmd1bGFyOiDJtVpvbmVTY2hlZHVsZXI7XG5cbiAgY29uc3RydWN0b3IocHVibGljIG5nWm9uZTogTmdab25lKSB7XG4gICAgdGhpcy5vdXRzaWRlQW5ndWxhciA9IG5nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiBuZXcgybVab25lU2NoZWR1bGVyKFpvbmUuY3VycmVudCkpO1xuICAgIHRoaXMuaW5zaWRlQW5ndWxhciA9IG5nWm9uZS5ydW4oKCkgPT4gbmV3IMm1Wm9uZVNjaGVkdWxlcihab25lLmN1cnJlbnQsIGFzeW5jU2NoZWR1bGVyKSk7XG4gIH1cbn1cblxuLyoqXG4gKiBPcGVyYXRvciB0byBibG9jayB0aGUgem9uZSB1bnRpbCB0aGUgZmlyc3QgdmFsdWUgaGFzIGJlZW4gZW1pdHRlZCBvciB0aGUgb2JzZXJ2YWJsZVxuICogaGFzIGNvbXBsZXRlZC9lcnJvcmVkLiBUaGlzIGlzIHVzZWQgdG8gbWFrZSBzdXJlIHRoYXQgdW5pdmVyc2FsIHdhaXRzIHVudGlsIHRoZSBmaXJzdFxuICogdmFsdWUgZnJvbSBmaXJlYmFzZSBidXQgZG9lc24ndCBibG9jayB0aGUgem9uZSBmb3JldmVyIHNpbmNlIHRoZSBmaXJlYmFzZSBzdWJzY3JpcHRpb25cbiAqIGlzIHN0aWxsIGFsaXZlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gybVrZWVwVW5zdGFibGVVbnRpbEZpcnN0RmFjdG9yeShzY2hlZHVsZXJzOiDJtUFuZ3VsYXJGaXJlU2NoZWR1bGVycykge1xuICByZXR1cm4gZnVuY3Rpb24ga2VlcFVuc3RhYmxlVW50aWxGaXJzdDxUPihvYnMkOiBPYnNlcnZhYmxlPFQ+KTogT2JzZXJ2YWJsZTxUPiB7XG4gICAgb2JzJCA9IG9icyQubGlmdChcbiAgICAgIG5ldyDJtUJsb2NrVW50aWxGaXJzdE9wZXJhdG9yKHNjaGVkdWxlcnMubmdab25lKVxuICAgICk7XG5cbiAgICByZXR1cm4gb2JzJC5waXBlKFxuICAgICAgLy8gUnVuIHRoZSBzdWJzY3JpYmUgYm9keSBvdXRzaWRlIG9mIEFuZ3VsYXIgKGUuZy4gY2FsbGluZyBGaXJlYmFzZSBTREsgdG8gYWRkIGEgbGlzdGVuZXIgdG8gYSBjaGFuZ2UgZXZlbnQpXG4gICAgICBzdWJzY3JpYmVPbihzY2hlZHVsZXJzLm91dHNpZGVBbmd1bGFyKSxcbiAgICAgIC8vIFJ1biBvcGVyYXRvcnMgaW5zaWRlIHRoZSBhbmd1bGFyIHpvbmUgKGUuZy4gc2lkZSBlZmZlY3RzIHZpYSB0YXAoKSlcbiAgICAgIG9ic2VydmVPbihzY2hlZHVsZXJzLmluc2lkZUFuZ3VsYXIpXG4gICAgICAvLyBJTlZFU1RJR0FURSBodHRwczovL2dpdGh1Yi5jb20vYW5ndWxhci9hbmd1bGFyZmlyZS9wdWxsLzIzMTVcbiAgICAgIC8vIHNoYXJlKClcbiAgICApO1xuICB9O1xufVxuXG4vLyB0c2xpbnQ6ZGlzYWJsZTpiYW4tdHlwZXNcbnR5cGUgRnVuY3Rpb25Qcm9wZXJ0eU5hbWVzPFQ+ID0geyBbSyBpbiBrZXlvZiBUXTogVFtLXSBleHRlbmRzIEZ1bmN0aW9uID8gSyA6IG5ldmVyIH1ba2V5b2YgVF07XG50eXBlIFByb21pc2VSZXR1cm5pbmdGdW5jdGlvblByb3BlcnR5TmFtZXM8VD4gPSB7XG4gIFtLIGluIEZ1bmN0aW9uUHJvcGVydHlOYW1lczxUPl06IFJldHVyblR5cGU8VFtLXT4gZXh0ZW5kcyBQcm9taXNlPGFueT4gPyBLIDogbmV2ZXJcbn1bRnVuY3Rpb25Qcm9wZXJ0eU5hbWVzPFQ+XTtcbnR5cGUgTm9uUHJvbWlzZVJldHVybmluZ0Z1bmN0aW9uUHJvcGVydHlOYW1lczxUPiA9IHtcbiAgW0sgaW4gRnVuY3Rpb25Qcm9wZXJ0eU5hbWVzPFQ+XTogUmV0dXJuVHlwZTxUW0tdPiBleHRlbmRzIFByb21pc2U8YW55PiA/IG5ldmVyIDogS1xufVtGdW5jdGlvblByb3BlcnR5TmFtZXM8VD5dO1xudHlwZSBOb25GdW5jdGlvblByb3BlcnR5TmFtZXM8VD4gPSB7IFtLIGluIGtleW9mIFRdOiBUW0tdIGV4dGVuZHMgRnVuY3Rpb24gPyBuZXZlciA6IEsgfVtrZXlvZiBUXTtcbi8vIHRzbGludDplbmFibGU6YmFuLXR5cGVzXG5cbmV4cG9ydCB0eXBlIMm1UHJvbWlzZVByb3h5PFQ+ID0geyBbSyBpbiBOb25GdW5jdGlvblByb3BlcnR5TmFtZXM8VD5dOiBQcm9taXNlPFRbS10+IH0gJlxuICB7IFtLIGluIE5vblByb21pc2VSZXR1cm5pbmdGdW5jdGlvblByb3BlcnR5TmFtZXM8VD5dOiAoLi4uYXJnczogUGFyYW1ldGVyczxUW0tdPikgPT4gUHJvbWlzZTxSZXR1cm5UeXBlPFRbS10+PiB9ICZcbiAgeyBbSyBpbiBQcm9taXNlUmV0dXJuaW5nRnVuY3Rpb25Qcm9wZXJ0eU5hbWVzPFQ+XTogKC4uLmFyZ3M6IFBhcmFtZXRlcnM8VFtLXT4pID0+IFJldHVyblR5cGU8VFtLXT4gfTtcblxuXG4vLyBERUJVRyBxdWljayBkZWJ1Z2dlciBmdW5jdGlvbiBmb3IgaW5saW5lIGxvZ2dpbmcgdGhhdCB0eXBlc2NyaXB0IGRvZXNuJ3QgY29tcGxhaW4gYWJvdXRcbi8vICAgICAgIHdyb3RlIGl0IGZvciBkZWJ1Z2dpbmcgdGhlIMm1bGF6eVNES1Byb3h5LCBjb21tZW50aW5nIG91dCBmb3Igbm93OyBzaG91bGQgY29uc2lkZXIgZXhwb3NpbmcgYVxuLy8gICAgICAgdmVyYm9zZSBtb2RlIGZvciBBbmd1bGFyRmlyZSBpbiBhIGZ1dHVyZSByZWxlYXNlIHRoYXQgdXNlcyBzb21ldGhpbmcgbGlrZSB0aGlzIGluIG11bHRpcGxlIHBsYWNlc1xuLy8gICAgICAgdXNhZ2U6ICgpID0+IGxvZygnc29tZXRoaW5nJykgfHwgcmV0dXJuVmFsdWVcbi8vIGNvbnN0IGxvZyA9ICguLi5hcmdzOiBhbnlbXSk6IGZhbHNlID0+IHsgY29uc29sZS5sb2coLi4uYXJncyk7IHJldHVybiBmYWxzZSB9XG5cbi8vIFRoZSBwcm9ibGVtIGhlcmUgYXJlIHRoaW5ncyBsaWtlIG5nT25EZXN0cm95IGFyZSBtaXNzaW5nLCB0aGVuIHRyaWdnZXJpbmcgdGhlIHNlcnZpY2Vcbi8vIHJhdGhlciB0aGFuIGRpZyB0b28gZmFyOyBJJ20gY2FwdHVyaW5nIHRoZXNlIGFzIEkgZ28uXG5jb25zdCBub29wRnVuY3Rpb25zID0gWyduZ09uRGVzdHJveSddO1xuXG4vLyBJTlZFU1RJR0FURSBzaG91bGQgd2UgbWFrZSB0aGUgUHJveHkgcmV2b2thYmxlIGFuZCBkbyBzb21lIGNsZWFudXA/XG4vLyAgICAgICAgICAgICByaWdodCBub3cgaXQncyBmYWlybHkgc2ltcGxlIGJ1dCBJJ20gc3VyZSB0aGlzIHdpbGwgZ3JvdyBpbiBjb21wbGV4aXR5XG5leHBvcnQgY29uc3QgybVsYXp5U0RLUHJveHkgPSAoa2xhc3M6IGFueSwgb2JzZXJ2YWJsZTogT2JzZXJ2YWJsZTxhbnk+LCB6b25lOiBOZ1pvbmUpID0+IHtcbiAgcmV0dXJuIG5ldyBQcm94eShrbGFzcywge1xuICAgIGdldDogKF8sIG5hbWU6IHN0cmluZykgPT4gem9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XG4gICAgICBpZiAoa2xhc3NbbmFtZV0pIHtcbiAgICAgICAgcmV0dXJuIGtsYXNzW25hbWVdO1xuICAgICAgfVxuICAgICAgaWYgKG5vb3BGdW5jdGlvbnMuaW5jbHVkZXMobmFtZSkpIHtcbiAgICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHByb21pc2UgPSBvYnNlcnZhYmxlLnRvUHJvbWlzZSgpLnRoZW4obW9kID0+IHtcbiAgICAgICAgY29uc3QgcmV0ID0gbW9kICYmIG1vZFtuYW1lXTtcbiAgICAgICAgLy8gVE9ETyBtb3ZlIHRvIHByb3BlciB0eXBlIGd1YXJkc1xuICAgICAgICBpZiAodHlwZW9mIHJldCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIHJldHVybiByZXQuYmluZChtb2QpO1xuICAgICAgICB9IGVsc2UgaWYgKHJldCAmJiByZXQudGhlbikge1xuICAgICAgICAgIHJldHVybiByZXQudGhlbigocmVzOiBhbnkpID0+IHpvbmUucnVuKCgpID0+IHJlcykpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiB6b25lLnJ1bigoKSA9PiByZXQpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIC8vIHJlY3Vyc2UgdGhlIHByb3h5XG4gICAgICByZXR1cm4gbmV3IFByb3h5KCgpID0+IHVuZGVmaW5lZCwge1xuICAgICAgICAgIGdldDogKF8sIG5hbWUpID0+IHByb21pc2VbbmFtZV0sXG4gICAgICAgICAgLy8gVE9ETyBoYW5kbGUgY2FsbGJhY2tzIGFzIHRyYW5zcGFyZW50bHkgYXMgSSBjYW5cbiAgICAgICAgICBhcHBseTogKHNlbGYsIF8sIGFyZ3MpID0+IHByb21pc2UudGhlbihpdCA9PiBpdCAmJiBpdCguLi5hcmdzKSlcbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KVxuICB9KTtcbn07XG4iXX0=