UNPKG

@zodiac-ui/ng-observable

Version:

Create powerful reactive components with Angular. AoT compatible and Ivy ready.

247 lines 16.4 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import * as tslib_1 from "tslib"; import { Injectable } from "@angular/core"; import { Subscription, from } from "rxjs"; import { Callable } from "./internals/callable"; import { isTeardownLogic } from "./internals/type-guards"; /** * @param {?} sub * @return {?} */ function createStream(sub) { return (/** * @param {...?} targets * @return {?} */ function stream() { var targets = []; for (var _i = 0; _i < arguments.length; _i++) { targets[_i] = arguments[_i]; } return (/** * @param {...?} sources * @return {?} */ function () { var e_1, _a; var sources = []; for (var _i = 0; _i < arguments.length; _i++) { sources[_i] = arguments[_i]; } try { for (var sources_1 = tslib_1.__values(sources), sources_1_1 = sources_1.next(); !sources_1_1.done; sources_1_1 = sources_1.next()) { var source = sources_1_1.value; sub.add(from(source).subscribe((/** * @param {?} value * @return {?} */ function (value) { var e_2, _a; try { for (var targets_1 = tslib_1.__values(targets), targets_1_1 = targets_1.next(); !targets_1_1.done; targets_1_1 = targets_1.next()) { var target = targets_1_1.value; if (typeof target === "function") { target(value); } else { target.next(value); } } } catch (e_2_1) { e_2 = { error: e_2_1 }; } finally { try { if (targets_1_1 && !targets_1_1.done && (_a = targets_1.return)) _a.call(targets_1); } finally { if (e_2) throw e_2.error; } } }))); } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (sources_1_1 && !sources_1_1.done && (_a = sources_1.return)) _a.call(sources_1); } finally { if (e_1) throw e_1.error; } } }); }); } // WARNING: interface has both a type and a value, skipping emit /** * Automatically subscribes to source observables and forwards their values to target observers while * discarding error and completion events. Cleans up all subscriptions when the stream completes by manually calling `complete` * or when the bound injector is destroyed. * * \@usageNotes * * Basic usage * * ```ts * const stream = new Stream() * const dest = new Subject() * const source = interval(1000) * * stream(dest)(source) * * stream.sink = source * stream.add(source) * * // unsubscribe from all sources * stream.complete() * ``` * * With `State` * * ```typescript * * \@Component({ * viewProviders: [StateFactory] // or providers * }) * export class MyComponent { * count: number * * constructor(stateFactory: StateFactory) { * const state = stateFactory.create(this) * * // update count once per second * // automatically unsubscribe when component is destroyed * stream(state)(interval(1000).pipe( * map(count => ({ count })) * )) * } * } * ``` * * \@publicApi */ var Stream = /** @class */ (function (_super) { tslib_1.__extends(Stream, _super); function Stream() { var _this = this; /** @type {?} */ var sub = new Subscription(); _this = _super.call(this, createStream(sub)) || this; _this.sub = sub; return _this; } Object.defineProperty(Stream.prototype, "sink", { /** * A subscription or an observable of teardown logic that will be cleaned up * when the stream ends. */ set: /** * A subscription or an observable of teardown logic that will be cleaned up * when the stream ends. * @param {?} sinkable * @return {?} */ function (sinkable) { var _this = this; var e_3, _a; if (!sinkable) { return; } if (isTeardownLogic(sinkable)) { this.sub.add(sinkable); } else if (Array.isArray(sinkable)) { try { for (var sinkable_1 = tslib_1.__values(sinkable), sinkable_1_1 = sinkable_1.next(); !sinkable_1_1.done; sinkable_1_1 = sinkable_1.next()) { var stream = sinkable_1_1.value; this.sink = stream; } } catch (e_3_1) { e_3 = { error: e_3_1 }; } finally { try { if (sinkable_1_1 && !sinkable_1_1.done && (_a = sinkable_1.return)) _a.call(sinkable_1); } finally { if (e_3) throw e_3.error; } } } else { this.sink = from(sinkable).subscribe((/** * @param {?} stream * @return {?} */ function (stream) { _this.sink = stream; })); } }, enumerable: true, configurable: true }); /** * Alternative to {@link sink} * * @param sinkables A series of {@link Sinkable} to be cleaned up when the stream ends. */ /** * Alternative to {\@link sink} * * @param {...?} sinkables A series of {\@link Sinkable} to be cleaned up when the stream ends. * @return {?} */ Stream.prototype.add = /** * Alternative to {\@link sink} * * @param {...?} sinkables A series of {\@link Sinkable} to be cleaned up when the stream ends. * @return {?} */ function () { var sinkables = []; for (var _i = 0; _i < arguments.length; _i++) { sinkables[_i] = arguments[_i]; } this.sink = sinkables; }; /** * Completes the stream and unsubscribes from all sources. */ /** * Completes the stream and unsubscribes from all sources. * @return {?} */ Stream.prototype.complete = /** * Completes the stream and unsubscribes from all sources. * @return {?} */ function () { this.sub.unsubscribe(); }; /** * `OnDestroy` hook called by Angular when the bound injector is destroyed */ /** * `OnDestroy` hook called by Angular when the bound injector is destroyed * @return {?} */ Stream.prototype.ngOnDestroy = /** * `OnDestroy` hook called by Angular when the bound injector is destroyed * @return {?} */ function () { this.complete(); }; Stream.decorators = [ { type: Injectable } ]; /** @nocollapse */ Stream.ctorParameters = function () { return []; }; return Stream; }(Callable)); export { Stream }; if (false) { /** * @type {?} * @private */ Stream.prototype.sub; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RyZWFtLmpzIiwic291cmNlUm9vdCI6Im5nOi8vQHpvZGlhYy11aS9uZy1vYnNlcnZhYmxlLyIsInNvdXJjZXMiOlsibGliL3N0cmVhbS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQWEsTUFBTSxlQUFlLENBQUE7QUFDckQsT0FBTyxFQUFFLFlBQVksRUFBaUMsSUFBSSxFQUFFLE1BQU0sTUFBTSxDQUFBO0FBQ3hFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQTtBQUUvQyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0seUJBQXlCLENBQUE7Ozs7O0FBRXpELFNBQVMsWUFBWSxDQUFDLEdBQWlCO0lBQ25DOzs7O0lBQU8sU0FBUyxNQUFNO1FBQUMsaUJBQTBEO2FBQTFELFVBQTBELEVBQTFELHFCQUEwRCxFQUExRCxJQUEwRDtZQUExRCw0QkFBMEQ7O1FBQzdFOzs7O1FBQU87O1lBQVMsaUJBQWtDO2lCQUFsQyxVQUFrQyxFQUFsQyxxQkFBa0MsRUFBbEMsSUFBa0M7Z0JBQWxDLDRCQUFrQzs7O2dCQUM5QyxLQUFxQixJQUFBLFlBQUEsaUJBQUEsT0FBTyxDQUFBLGdDQUFBLHFEQUFFO29CQUF6QixJQUFNLE1BQU0sb0JBQUE7b0JBQ2IsR0FBRyxDQUFDLEdBQUcsQ0FDSCxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsU0FBUzs7OztvQkFBQyxVQUFBLEtBQUs7Ozs0QkFDeEIsS0FBcUIsSUFBQSxZQUFBLGlCQUFBLE9BQU8sQ0FBQSxnQ0FBQSxxREFBRTtnQ0FBekIsSUFBTSxNQUFNLG9CQUFBO2dDQUNiLElBQUksT0FBTyxNQUFNLEtBQUssVUFBVSxFQUFFO29DQUM5QixNQUFNLENBQUMsS0FBSyxDQUFDLENBQUE7aUNBQ2hCO3FDQUFNO29DQUNILE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUE7aUNBQ3JCOzZCQUNKOzs7Ozs7Ozs7b0JBQ0wsQ0FBQyxFQUFDLENBQ0wsQ0FBQTtpQkFDSjs7Ozs7Ozs7O1FBQ0wsQ0FBQyxFQUFBO0lBQ0wsQ0FBQyxFQUFBO0FBQ0wsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQTJERDtJQUM0QixrQ0FBa0I7SUF3QjFDO1FBQUEsaUJBSUM7O1lBSFMsR0FBRyxHQUFHLElBQUksWUFBWSxFQUFFO1FBQzlCLFFBQUEsa0JBQU0sWUFBWSxDQUFDLEdBQUcsQ0FBQyxDQUFDLFNBQUE7UUFDeEIsS0FBSSxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUE7O0lBQ2xCLENBQUM7SUFyQkQsc0JBQVcsd0JBQUk7UUFKZjs7O1dBR0c7Ozs7Ozs7UUFDSCxVQUFnQixRQUErQjtZQUEvQyxpQkFlQzs7WUFkRyxJQUFJLENBQUMsUUFBUSxFQUFFO2dCQUNYLE9BQU07YUFDVDtZQUNELElBQUksZUFBZSxDQUFDLFFBQVEsQ0FBQyxFQUFFO2dCQUMzQixJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQTthQUN6QjtpQkFBTSxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEVBQUU7O29CQUNoQyxLQUFxQixJQUFBLGFBQUEsaUJBQUEsUUFBUSxDQUFBLGtDQUFBLHdEQUFFO3dCQUExQixJQUFNLE1BQU0scUJBQUE7d0JBQ2IsSUFBSSxDQUFDLElBQUksR0FBRyxNQUFNLENBQUE7cUJBQ3JCOzs7Ozs7Ozs7YUFDSjtpQkFBTTtnQkFDSCxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxTQUFTOzs7O2dCQUFDLFVBQUEsTUFBTTtvQkFDdkMsS0FBSSxDQUFDLElBQUksR0FBRyxNQUFNLENBQUE7Z0JBQ3RCLENBQUMsRUFBQyxDQUFBO2FBQ0w7UUFDTCxDQUFDOzs7T0FBQTtJQVFEOzs7O09BSUc7Ozs7Ozs7SUFDSSxvQkFBRzs7Ozs7O0lBQVY7UUFBVyxtQkFBd0I7YUFBeEIsVUFBd0IsRUFBeEIscUJBQXdCLEVBQXhCLElBQXdCO1lBQXhCLDhCQUF3Qjs7UUFDL0IsSUFBSSxDQUFDLElBQUksR0FBRyxTQUFTLENBQUE7SUFDekIsQ0FBQztJQUVEOztPQUVHOzs7OztJQUNJLHlCQUFROzs7O0lBQWY7UUFDSSxJQUFJLENBQUMsR0FBRyxDQUFDLFdBQVcsRUFBRSxDQUFBO0lBQzFCLENBQUM7SUFFRDs7T0FFRzs7Ozs7SUFDSSw0QkFBVzs7OztJQUFsQjtRQUNJLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQTtJQUNuQixDQUFDOztnQkFwREosVUFBVTs7OztJQXFEWCxhQUFDO0NBQUEsQUFyREQsQ0FDNEIsUUFBUSxHQW9EbkM7U0FwRFksTUFBTTs7Ozs7O0lBQ2YscUJBQXlCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgT25EZXN0cm95IH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIlxyXG5pbXBvcnQgeyBTdWJzY3JpcHRpb24sIE5leHRPYnNlcnZlciwgT2JzZXJ2YWJsZUlucHV0LCBmcm9tIH0gZnJvbSBcInJ4anNcIlxyXG5pbXBvcnQgeyBDYWxsYWJsZSB9IGZyb20gXCIuL2ludGVybmFscy9jYWxsYWJsZVwiXHJcbmltcG9ydCB7IFNpbmthYmxlIH0gZnJvbSBcIi4vaW50ZXJmYWNlc1wiXHJcbmltcG9ydCB7IGlzVGVhcmRvd25Mb2dpYyB9IGZyb20gXCIuL2ludGVybmFscy90eXBlLWd1YXJkc1wiXHJcblxyXG5mdW5jdGlvbiBjcmVhdGVTdHJlYW0oc3ViOiBTdWJzY3JpcHRpb24pIHtcclxuICAgIHJldHVybiBmdW5jdGlvbiBzdHJlYW0oLi4udGFyZ2V0czogKE5leHRPYnNlcnZlcjxhbnk+IHwgKCh2YWx1ZTogYW55KSA9PiB2b2lkKSlbXSkge1xyXG4gICAgICAgIHJldHVybiBmdW5jdGlvbiguLi5zb3VyY2VzOiBPYnNlcnZhYmxlSW5wdXQ8YW55PltdKSB7XHJcbiAgICAgICAgICAgIGZvciAoY29uc3Qgc291cmNlIG9mIHNvdXJjZXMpIHtcclxuICAgICAgICAgICAgICAgIHN1Yi5hZGQoXHJcbiAgICAgICAgICAgICAgICAgICAgZnJvbShzb3VyY2UpLnN1YnNjcmliZSh2YWx1ZSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgdGFyZ2V0IG9mIHRhcmdldHMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdGFyZ2V0ID09PSBcImZ1bmN0aW9uXCIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQodmFsdWUpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldC5uZXh0KHZhbHVlKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfSksXHJcbiAgICAgICAgICAgICAgICApXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCB0eXBlIFN0cmVhbUZuID0gPFQ+KFxyXG4gICAgLi4udGFyZ2V0czogKE5leHRPYnNlcnZlcjxUPiB8ICgodmFsdWU6IGFueSkgPT4gdm9pZCkpW11cclxuKSA9PiAoLi4uc291cmNlczogT2JzZXJ2YWJsZUlucHV0PFQ+W10pID0+IHZvaWRcclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgU3RyZWFtIGV4dGVuZHMgU3RyZWFtRm4ge1xyXG4gICAgPFQ+KC4uLnRhcmdldHM6IChOZXh0T2JzZXJ2ZXI8VD4gfCAoKHZhbHVlOiBhbnkpID0+IHZvaWQpKVtdKTogKFxyXG4gICAgICAgIC4uLnNvdXJjZXM6IE9ic2VydmFibGVJbnB1dDxUPltdXHJcbiAgICApID0+IHZvaWRcclxufVxyXG5cclxuLyoqXHJcbiogQXV0b21hdGljYWxseSBzdWJzY3JpYmVzIHRvIHNvdXJjZSBvYnNlcnZhYmxlcyBhbmQgZm9yd2FyZHMgdGhlaXIgdmFsdWVzIHRvIHRhcmdldCBvYnNlcnZlcnMgd2hpbGVcclxuICAgICogZGlzY2FyZGluZyBlcnJvciBhbmQgY29tcGxldGlvbiBldmVudHMuIENsZWFucyB1cCBhbGwgc3Vic2NyaXB0aW9ucyB3aGVuIHRoZSBzdHJlYW0gY29tcGxldGVzIGJ5IG1hbnVhbGx5IGNhbGxpbmcgYGNvbXBsZXRlYFxyXG4qIG9yIHdoZW4gdGhlIGJvdW5kIGluamVjdG9yIGlzIGRlc3Ryb3llZC5cclxuKlxyXG4qIEB1c2FnZU5vdGVzXHJcbipcclxuKiBCYXNpYyB1c2FnZVxyXG4qXHJcbiogYGBgdHNcclxuICogY29uc3Qgc3RyZWFtID0gbmV3IFN0cmVhbSgpXHJcbiAqIGNvbnN0IGRlc3QgPSBuZXcgU3ViamVjdCgpXHJcbiAqIGNvbnN0IHNvdXJjZSA9IGludGVydmFsKDEwMDApXHJcbiAqXHJcbiAqIHN0cmVhbShkZXN0KShzb3VyY2UpXHJcbiAqXHJcbiAqIHN0cmVhbS5zaW5rID0gc291cmNlXHJcbiAqIHN0cmVhbS5hZGQoc291cmNlKVxyXG4gKlxyXG4gKiAvLyB1bnN1YnNjcmliZSBmcm9tIGFsbCBzb3VyY2VzXHJcbiAqIHN0cmVhbS5jb21wbGV0ZSgpXHJcbiAqIGBgYFxyXG4qXHJcbiogV2l0aCBgU3RhdGVgXHJcbipcclxuKiBgYGB0eXBlc2NyaXB0XHJcbiAqXHJcbiAqIEBDb21wb25lbnQoe1xyXG4gKiAgICAgdmlld1Byb3ZpZGVyczogW1N0YXRlRmFjdG9yeV0gLy8gb3IgcHJvdmlkZXJzXHJcbiAqIH0pXHJcbiAqIGV4cG9ydCBjbGFzcyBNeUNvbXBvbmVudCB7XHJcbiAqICAgICBjb3VudDogbnVtYmVyXHJcbiAqXHJcbiAqICAgICBjb25zdHJ1Y3RvcihzdGF0ZUZhY3Rvcnk6IFN0YXRlRmFjdG9yeSkge1xyXG4gKiAgICAgICAgIGNvbnN0IHN0YXRlID0gc3RhdGVGYWN0b3J5LmNyZWF0ZSh0aGlzKVxyXG4gKlxyXG4gKiAgICAgICAgIC8vIHVwZGF0ZSBjb3VudCBvbmNlIHBlciBzZWNvbmRcclxuICogICAgICAgICAvLyBhdXRvbWF0aWNhbGx5IHVuc3Vic2NyaWJlIHdoZW4gY29tcG9uZW50IGlzIGRlc3Ryb3llZFxyXG4gKiAgICAgICAgIHN0cmVhbShzdGF0ZSkoaW50ZXJ2YWwoMTAwMCkucGlwZShcclxuICogICAgICAgICAgICAgbWFwKGNvdW50ID0+ICh7IGNvdW50IH0pKVxyXG4gKiAgICAgICAgICkpXHJcbiAqICAgICB9XHJcbiAqIH1cclxuICogYGBgXHJcbipcclxuKiBAcHVibGljQXBpXHJcbiovXHJcbkBJbmplY3RhYmxlKClcclxuZXhwb3J0IGNsYXNzIFN0cmVhbSBleHRlbmRzIENhbGxhYmxlPFN0cmVhbUZuPiBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XHJcbiAgICBwcml2YXRlIHN1YjogU3Vic2NyaXB0aW9uXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBIHN1YnNjcmlwdGlvbiBvciBhbiBvYnNlcnZhYmxlIG9mIHRlYXJkb3duIGxvZ2ljIHRoYXQgd2lsbCBiZSBjbGVhbmVkIHVwXHJcbiAgICAgKiB3aGVuIHRoZSBzdHJlYW0gZW5kcy5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHNldCBzaW5rKHNpbmthYmxlOiBTaW5rYWJsZSB8IFNpbmthYmxlW10pIHtcclxuICAgICAgICBpZiAoIXNpbmthYmxlKSB7XHJcbiAgICAgICAgICAgIHJldHVyblxyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoaXNUZWFyZG93bkxvZ2ljKHNpbmthYmxlKSkge1xyXG4gICAgICAgICAgICB0aGlzLnN1Yi5hZGQoc2lua2FibGUpXHJcbiAgICAgICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KHNpbmthYmxlKSkge1xyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IHN0cmVhbSBvZiBzaW5rYWJsZSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5zaW5rID0gc3RyZWFtXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLnNpbmsgPSBmcm9tKHNpbmthYmxlKS5zdWJzY3JpYmUoc3RyZWFtID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuc2luayA9IHN0cmVhbVxyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBjb25zdHJ1Y3RvcigpIHtcclxuICAgICAgICBjb25zdCBzdWIgPSBuZXcgU3Vic2NyaXB0aW9uKClcclxuICAgICAgICBzdXBlcihjcmVhdGVTdHJlYW0oc3ViKSlcclxuICAgICAgICB0aGlzLnN1YiA9IHN1YlxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQWx0ZXJuYXRpdmUgdG8ge0BsaW5rIHNpbmt9XHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHNpbmthYmxlcyBBIHNlcmllcyBvZiB7QGxpbmsgU2lua2FibGV9IHRvIGJlIGNsZWFuZWQgdXAgd2hlbiB0aGUgc3RyZWFtIGVuZHMuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBhZGQoLi4uc2lua2FibGVzOiBTaW5rYWJsZVtdKSB7XHJcbiAgICAgICAgdGhpcy5zaW5rID0gc2lua2FibGVzXHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDb21wbGV0ZXMgdGhlIHN0cmVhbSBhbmQgdW5zdWJzY3JpYmVzIGZyb20gYWxsIHNvdXJjZXMuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBjb21wbGV0ZSgpIHtcclxuICAgICAgICB0aGlzLnN1Yi51bnN1YnNjcmliZSgpXHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBgT25EZXN0cm95YCBob29rIGNhbGxlZCBieSBBbmd1bGFyIHdoZW4gdGhlIGJvdW5kIGluamVjdG9yIGlzIGRlc3Ryb3llZFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbmdPbkRlc3Ryb3koKSB7XHJcbiAgICAgICAgdGhpcy5jb21wbGV0ZSgpXHJcbiAgICB9XHJcbn1cclxuIl19