UNPKG

@datorama/akita

Version:

State Management Tailored-Made for JS Applications

387 lines 27.4 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { BehaviorSubject } from 'rxjs'; import { distinctUntilChanged, map } from 'rxjs/operators'; import { assertStoreHasName } from './errors'; import { commit, isTransactionInProcess } from './transaction'; import { deepFreeze } from './deepFreeze'; import { configKey } from './storeConfig'; import { getAkitaConfig } from './config'; import { isPlainObject } from './isPlainObject'; import { isFunction } from './isFunction'; import { dispatchAdded, dispatchDeleted, dispatchUpdate } from './dispatchers'; import { __stores__ } from './stores'; import { resetCustomAction, setAction } from './actions'; import { isNotBrowser } from './root'; import { __DEV__, isDev } from './env'; /** * * Store for managing any type of data * * \@example * * export interface SessionState { * token: string; * userDetails: UserDetails * } * * export function createInitialState(): SessionState { * return { * token: '', * userDetails: null * }; * } * * \@StoreConfig({ name: 'session' }) * export class SessionStore extends Store<SessionState> { * constructor() { * super(createInitialState()); * } * } * @template S */ export class Store { /** * @param {?} initialState * @param {?=} options */ constructor(initialState, options = {}) { this.options = options; this.inTransaction = false; this.cache = { active: new BehaviorSubject(false), ttl: null }; this.onInit((/** @type {?} */ (initialState))); } /** * Set the loading state * * \@example * * store.setLoading(true) * * @param {?=} loading * @return {?} */ setLoading(loading = false) { if (loading !== ((/** @type {?} */ (this._value()))).loading) { isDev() && setAction('Set Loading'); this._setState((/** * @param {?} state * @return {?} */ state => ((/** @type {?} */ (Object.assign({}, state, { loading })))))); } } /** * * Set whether the data is cached * * \@example * * store.setHasCache(true) * store.setHasCache(false) * store.setHasCache(true, { restartTTL: true }) * * @param {?} hasCache * @param {?=} options * @return {?} */ setHasCache(hasCache, options = { restartTTL: false }) { if (hasCache !== this.cache.active.value) { this.cache.active.next(hasCache); } if (options.restartTTL) { /** @type {?} */ const ttlConfig = this.cacheConfig && this.cacheConfig.ttl; if (ttlConfig) { if (this.cache.ttl !== null) { clearTimeout(this.cache.ttl); } this.cache.ttl = (/** @type {?} */ (setTimeout((/** * @return {?} */ () => this.setHasCache(false)), ttlConfig))); } } } /** * Set the error state * * \@example * * store.setError({text: 'unable to load data' }) * * @template T * @param {?} error * @return {?} */ setError(error) { if (error !== ((/** @type {?} */ (this._value()))).error) { isDev() && setAction('Set Error'); this._setState((/** * @param {?} state * @return {?} */ state => ((/** @type {?} */ (Object.assign({}, state, { error })))))); } } // @internal /** * @template R * @param {?} project * @return {?} */ _select(project) { return this.store.asObservable().pipe(map(project), distinctUntilChanged()); } // @internal /** * @return {?} */ _value() { return this.storeValue; } // @internal /** * @return {?} */ _cache() { return this.cache.active; } // @internal /** * @return {?} */ get config() { return this.constructor[configKey] || {}; } // @internal /** * @return {?} */ get storeName() { return ((/** @type {?} */ (this.config))).storeName || ((/** @type {?} */ (this.options))).storeName || this.options.name; } // @internal /** * @return {?} */ get deepFreeze() { return this.config.deepFreezeFn || this.options.deepFreezeFn || deepFreeze; } // @internal /** * @return {?} */ get cacheConfig() { return this.config.cache || this.options.cache; } // @internal /** * @return {?} */ get resettable() { return this.config.resettable || this.options.resettable; } // @internal /** * @param {?} newStateFn * @param {?=} _dispatchAction * @return {?} */ _setState(newStateFn, _dispatchAction = true) { this.storeValue = __DEV__ ? this.deepFreeze(newStateFn(this._value())) : newStateFn(this._value()); if (!this.store) { this.store = new BehaviorSubject(this.storeValue); return; } if (isTransactionInProcess()) { this.handleTransaction(); return; } this.dispatch(this.storeValue, _dispatchAction); } /** * * Reset the current store back to the initial value * * \@example * * store.reset() * * @return {?} */ reset() { if (this.isResettable()) { isDev() && setAction('Reset'); this._setState((/** * @return {?} */ () => Object.assign({}, this._initialState))); this.setHasCache(false); } else { isDev() && console.warn(`You need to enable the reset functionality`); } } /** * @param {?} stateOrCallback * @return {?} */ update(stateOrCallback) { isDev() && setAction('Update'); this._setState((/** * @param {?} state * @return {?} */ state => { /** @type {?} */ const newState = isFunction(stateOrCallback) ? stateOrCallback(state) : stateOrCallback; /** @type {?} */ const merged = this.akitaPreUpdate(state, (/** @type {?} */ (Object.assign({}, state, newState)))); return isPlainObject(state) ? merged : new ((/** @type {?} */ (state))).constructor(merged); })); } /** * @param {?} newOptions * @return {?} */ updateStoreConfig(newOptions) { this.options = Object.assign({}, this.options, newOptions); } // @internal /** * @param {?} _ * @param {?} nextState * @return {?} */ akitaPreUpdate(_, nextState) { return nextState; } /** * @return {?} */ ngOnDestroy() { this.destroy(); } /** * * Destroy the store * * \@example * * store.destroy() * * @return {?} */ destroy() { if (isNotBrowser) return; if (!((/** @type {?} */ (window))).hmrEnabled && this === __stores__[this.storeName]) { delete __stores__[this.storeName]; dispatchDeleted(this.storeName); this.setHasCache(false); this.cache.active.complete(); } } /** * @private * @param {?} initialState * @return {?} */ onInit(initialState) { __stores__[this.storeName] = this; this._setState((/** * @return {?} */ () => initialState)); dispatchAdded(this.storeName); if (this.isResettable()) { this._initialState = initialState; } isDev() && assertStoreHasName(this.storeName, this.constructor.name); } /** * @private * @param {?} state * @param {?=} _dispatchAction * @return {?} */ dispatch(state, _dispatchAction = true) { this.store.next(state); if (_dispatchAction) { dispatchUpdate(this.storeName); resetCustomAction(); } } /** * @private * @return {?} */ watchTransaction() { commit().subscribe((/** * @return {?} */ () => { this.inTransaction = false; this.dispatch(this._value()); })); } /** * @private * @return {?} */ isResettable() { if (this.resettable === false) { return false; } return this.resettable || getAkitaConfig().resettable; } /** * @private * @return {?} */ handleTransaction() { if (!this.inTransaction) { this.watchTransaction(); this.inTransaction = true; } } } if (false) { /** * @type {?} * @private */ Store.prototype.store; /** * @type {?} * @private */ Store.prototype.storeValue; /** * @type {?} * @private */ Store.prototype.inTransaction; /** * @type {?} * @private */ Store.prototype._initialState; /** * @type {?} * @protected */ Store.prototype.cache; /** * @type {?} * @protected */ Store.prototype.options; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RvcmUuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9AZGF0b3JhbWEvYWtpdGEvIiwic291cmNlcyI6WyJzcmMvc3RvcmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUNBLE9BQU8sRUFBRSxlQUFlLEVBQWMsTUFBTSxNQUFNLENBQUM7QUFDbkQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzNELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUM5QyxPQUFPLEVBQUUsTUFBTSxFQUFFLHNCQUFzQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQy9ELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDMUMsT0FBTyxFQUFFLFNBQVMsRUFBbUQsTUFBTSxlQUFlLENBQUM7QUFDM0YsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUMxQyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDaEQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUMxQyxPQUFPLEVBQUUsYUFBYSxFQUFFLGVBQWUsRUFBRSxjQUFjLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDL0UsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUN0QyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsU0FBUyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ3pELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxRQUFRLENBQUM7QUFDdEMsT0FBTyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxPQUFPLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQTJCdkMsTUFBTSxPQUFPLEtBQUs7Ozs7O0lBVWhCLFlBQVksWUFBd0IsRUFBWSxVQUF1QyxFQUFFO1FBQXpDLFlBQU8sR0FBUCxPQUFPLENBQWtDO1FBUGpGLGtCQUFhLEdBQUcsS0FB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Uzs7O1FBQUMsR0FBRyxFQUFFO1lBQ3RCLElBQUksQ0FBQyxhQUFhLEdBQUcsS0FBSyxDQUFDO1lBQzNCLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDL0IsQ0FBQyxFQUFDLENBQUM7SUFDTCxDQUFDOzs7OztJQUVPLFlBQVk7UUFDbEIsSUFBSSxJQUFJLENBQUMsVUFBVSxLQUFLLEtBQUssRUFBRTtZQUM3QixPQUFPLEtBQUssQ0FBQztTQUNkO1FBQ0QsT0FBTyxJQUFJLENBQUMsVUFBVSxJQUFJLGNBQWMsRUFBRSxDQUFDLFVBQVUsQ0FBQztJQUN4RCxDQUFDOzs7OztJQUVPLGlCQUFpQjtRQUN2QixJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRTtZQUN2QixJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztZQUN4QixJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQztTQUMzQjtJQUNILENBQUM7Q0FDRjs7Ozs7O0lBdlBDLHNCQUE0Qzs7Ozs7SUFDNUMsMkJBQXNCOzs7OztJQUN0Qiw4QkFBOEI7Ozs7O0lBQzlCLDhCQUF5Qjs7Ozs7SUFDekIsc0JBR0U7Ozs7O0lBRW9DLHdCQUFtRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFN0b3JlQ2FjaGUsIFVwZGF0ZVN0YXRlQ2FsbGJhY2sgfSBmcm9tICcuL3R5cGVzJztcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCwgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZGlzdGluY3RVbnRpbENoYW5nZWQsIG1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IGFzc2VydFN0b3JlSGFzTmFtZSB9IGZyb20gJy4vZXJyb3JzJztcbmltcG9ydCB7IGNvbW1pdCwgaXNUcmFuc2FjdGlvbkluUHJvY2VzcyB9IGZyb20gJy4vdHJhbnNhY3Rpb24nO1xuaW1wb3J0IHsgZGVlcEZyZWV6ZSB9IGZyb20gJy4vZGVlcEZyZWV6ZSc7XG5pbXBvcnQgeyBjb25maWdLZXksIFN0b3JlQ29uZmlnT3B0aW9ucywgVXBkYXRhYmxlU3RvcmVDb25maWdPcHRpb25zIH0gZnJvbSAnLi9zdG9yZUNvbmZpZyc7XG5pbXBvcnQgeyBnZXRBa2l0YUNvbmZpZyB9IGZyb20gJy4vY29uZmlnJztcbmltcG9ydCB7IGlzUGxhaW5PYmplY3QgfSBmcm9tICcuL2lzUGxhaW5PYmplY3QnO1xuaW1wb3J0IHsgaXNGdW5jdGlvbiB9IGZyb20gJy4vaXNGdW5jdGlvbic7XG5pbXBvcnQgeyBkaXNwYXRjaEFkZGVkLCBkaXNwYXRjaERlbGV0ZWQsIGRpc3BhdGNoVXBkYXRlIH0gZnJvbSAnLi9kaXNwYXRjaGVycyc7XG5pbXBvcnQgeyBfX3N0b3Jlc19fIH0gZnJvbSAnLi9zdG9yZXMnO1xuaW1wb3J0IHsgcmVzZXRDdXN0b21BY3Rpb24sIHNldEFjdGlvbiB9IGZyb20gJy4vYWN0aW9ucyc7XG5pbXBvcnQgeyBpc05vdEJyb3dzZXIgfSBmcm9tICcuL3Jvb3QnO1xuaW1wb3J0IHsgX19ERVZfXywgaXNEZXYgfSBmcm9tICcuL2Vudic7XG5cbi8qKlxuICpcbiAqIFN0b3JlIGZvciBtYW5hZ2luZyBhbnkgdHlwZSBvZiBkYXRhXG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKiBleHBvcnQgaW50ZXJmYWNlIFNlc3Npb25TdGF0ZSB7XG4gKiAgIHRva2VuOiBzdHJpbmc7XG4gKiAgIHVzZXJEZXRhaWxzOiBVc2VyRGV0YWlsc1xuICogfVxuICpcbiAqIGV4cG9ydCBmdW5jdGlvbiBjcmVhdGVJbml0aWFsU3RhdGUoKTogU2Vzc2lvblN0YXRlIHtcbiAqICByZXR1cm4ge1xuICogICAgdG9rZW46ICcnLFxuICogICAgdXNlckRldGFpbHM6IG51bGxcbiAqICB9O1xuICogfVxuICpcbiAqIEBTdG9yZUNvbmZpZyh7IG5hbWU6ICdzZXNzaW9uJyB9KVxuICogZXhwb3J0IGNsYXNzIFNlc3Npb25TdG9yZSBleHRlbmRzIFN0b3JlPFNlc3Npb25TdGF0ZT4ge1xuICogICBjb25zdHJ1Y3RvcigpIHtcbiAqICAgIHN1cGVyKGNyZWF0ZUluaXRpYWxTdGF0ZSgpKTtcbiAqICAgfVxuICogfVxuICovXG5leHBvcnQgY2xhc3MgU3RvcmU8UyA9IGFueT4ge1xuICBwcml2YXRlIHN0b3JlOiBCZWhhdmlvclN1YmplY3Q8UmVhZG9ubHk8Uz4+O1xuICBwcml2YXRlIHN0b3JlVmFsdWU6IFM7XG4gIHByaXZhdGUgaW5UcmFuc2FjdGlvbiA9IGZhbHNlO1xuICBwcml2YXRlIF9pbml0aWFsU3RhdGU6IFM7XG4gIHByb3RlY3RlZCBjYWNoZTogU3RvcmVDYWNoZSA9IHtcbiAgICBhY3RpdmU6IG5ldyBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4oZmFsc2UpLFxuICAgIHR0bDogbnVsbFxuICB9O1xuXG4gIGNvbnN0cnVjdG9yKGluaXRpYWxTdGF0ZTogUGFydGlhbDxTPiwgcHJvdGVjdGVkIG9wdGlvbnM6IFBhcnRpYWw8U3RvcmVDb25maWdPcHRpb25zPiA9IHt9KSB7XG4gICAgdGhpcy5vbkluaXQoaW5pdGlhbFN0YXRlIGFzIFMpO1xuICB9XG5cbiAgLyoqXG4gICAqICBTZXQgdGhlIGxvYWRpbmcgc3RhdGVcbiAgICpcbiAgICogIEBleGFtcGxlXG4gICAqXG4gICAqICBzdG9yZS5zZXRMb2FkaW5nKHRydWUpXG4gICAqXG4gICAqL1xuICBzZXRMb2FkaW5nKGxvYWRpbmcgPSBmYWxzZSkge1xuICAgIGlmIChsb2FkaW5nICE9PSAodGhpcy5fdmFsdWUoKSBhcyBTICYgeyBsb2FkaW5nOiBib29sZWFuIH0pLmxvYWRpbmcpIHtcbiAgICAgIGlzRGV2KCkgJiYgc2V0QWN0aW9uKCdTZXQgTG9hZGluZycpO1xuICAgICAgdGhpcy5fc2V0U3RhdGUoc3RhdGUgPT4gKHsgLi4uc3RhdGUsIGxvYWRpbmcgfSBhcyBTICYgeyBsb2FkaW5nOiBib29sZWFuIH0pKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICpcbiAgICogU2V0IHdoZXRoZXIgdGhlIGRhdGEgaXMgY2FjaGVkXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqXG4gICAqIHN0b3JlLnNldEhhc0NhY2hlKHRydWUpXG4gICAqIHN0b3JlLnNldEhhc0NhY2hlKGZhbHNlKVxuICAgKiBzdG9yZS5zZXRIYXNDYWNoZSh0cnVlLCB7IHJlc3RhcnRUVEw6IHRydWUgfSlcbiAgICpcbiAgICovXG4gIHNldEhhc0NhY2hlKGhhc0NhY2hlOiBib29sZWFuLCBvcHRpb25zOiB7IHJlc3RhcnRUVEw6IGJvb2xlYW4gfSA9IHsgcmVzdGFydFRUTDogZmFsc2UgfSkge1xuICAgIGlmIChoYXNDYWNoZSAhPT0gdGhpcy5jYWNoZS5hY3RpdmUudmFsdWUpIHtcbiAgICAgIHRoaXMuY2FjaGUuYWN0aXZlLm5leHQoaGFzQ2FjaGUpO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zLnJlc3RhcnRUVEwpIHtcbiAgICAgIGNvbnN0IHR0bENvbmZpZyA9IHRoaXMuY2FjaGVDb25maWcgJiYgdGhpcy5jYWNoZUNvbmZpZy50dGw7XG4gICAgICBpZiAodHRsQ29uZmlnKSB7XG4gICAgICAgIGlmICh0aGlzLmNhY2hlLnR0bCAhPT0gbnVsbCkge1xuICAgICAgICAgIGNsZWFyVGltZW91dCh0aGlzLmNhY2hlLnR0bCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jYWNoZS50dGwgPSA8YW55PnNldFRpbWVvdXQoKCkgPT4gdGhpcy5zZXRIYXNDYWNoZShmYWxzZSksIHR0bENvbmZpZyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqICBTZXQgdGhlIGVycm9yIHN0YXRlXG4gICAqXG4gICAqICBAZXhhbXBsZVxuICAgKlxuICAgKiAgc3RvcmUuc2V0RXJyb3Ioe3RleHQ6ICd1bmFibGUgdG8gbG9hZCBkYXRhJyB9KVxuICAgKlxuICAgKi9cbiAgc2V0RXJyb3I8VD4oZXJyb3I6IFQpIHtcbiAgICBpZiAoZXJyb3IgIT09ICh0aGlzLl92YWx1ZSgpIGFzIFMgJiB7IGVycm9yOiBhbnkgfSkuZXJyb3IpIHtcbiAgICAgIGlzRGV2KCkgJiYgc2V0QWN0aW9uKCdTZXQgRXJyb3InKTtcbiAgICAgIHRoaXMuX3NldFN0YXRlKHN0YXRlID0+ICh7IC4uLnN0YXRlLCBlcnJvciB9IGFzIFMgJiB7IGVycm9yOiBhbnkgfSkpO1xuICAgIH1cbiAgfVxuXG4gIC8vIEBpbnRlcm5hbFxuICBfc2VsZWN0PFI+KHByb2plY3Q6IChzdG9yZTogUykgPT4gUik6IE9ic2VydmFibGU8Uj4ge1xuICAgIHJldHVybiB0aGlzLnN0b3JlLmFzT2JzZXJ2YWJsZSgpLnBpcGUoXG4gICAgICBtYXAocHJvamVjdCksXG4gICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpXG4gICAgKTtcbiAgfVxuXG4gIC8vIEBpbnRlcm5hbFxuICBfdmFsdWUoKTogUyB7XG4gICAgcmV0dXJuIHRoaXMuc3RvcmVWYWx1ZTtcbiAgfVxuXG4gIC8vIEBpbnRlcm5hbFxuICBfY2FjaGUoKTogQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+IHtcbiAgICByZXR1cm4gdGhpcy5jYWNoZS5hY3RpdmU7XG4gIH1cblxuICAvLyBAaW50ZXJuYWxcbiAgZ2V0IGNvbmZpZygpOiBTdG9yZUNvbmZpZ09wdGlvbnMge1xuICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yW2NvbmZpZ0tleV0gfHwge307XG4gIH1cblxuICAvLyBAaW50ZXJuYWxcbiAgZ2V0IHN0b3JlTmFtZSgpIHtcbiAgICByZXR1cm4gKHRoaXMuY29uZmlnIGFzIFN0b3JlQ29uZmlnT3B0aW9ucyAmIHsgc3RvcmVOYW1lOiBzdHJpbmcgfSkuc3RvcmVOYW1lIHx8ICh0aGlzLm9wdGlvbnMgYXMgU3RvcmVDb25maWdPcHRpb25zICYgeyBzdG9yZU5hbWU6IHN0cmluZyB9KS5zdG9yZU5hbWUgfHwgdGhpcy5vcHRpb25zLm5hbWU7XG4gIH1cblxuICAvLyBAaW50ZXJuYWxcbiAgZ2V0IGRlZXBGcmVlemUoKSB7XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLmRlZXBGcmVlemVGbiB8fCB0aGlzLm9wdGlvbnMuZGVlcEZyZWV6ZUZuIHx8IGRlZXBGcmVlemU7XG4gIH1cblxuICAvLyBAaW50ZXJuYWxcbiAgZ2V0IGNhY2hlQ29uZmlnKCkge1xuICAgIHJldHVybiB0aGlzLmNvbmZpZy5jYWNoZSB8fCB0aGlzLm9wdGlvbnMuY2FjaGU7XG4gIH1cblxuICAvLyBAaW50ZXJuYWxcbiAgZ2V0IHJlc2V0dGFibGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLnJlc2V0dGFibGUgfHwgdGhpcy5vcHRpb25zLnJlc2V0dGFibGU7XG4gIH1cblxuICAvLyBAaW50ZXJuYWxcbiAgX3NldFN0YXRlKG5ld1N0YXRlRm46IChzdGF0ZTogUmVhZG9ubHk8Uz4pID0+IFMsIF9kaXNwYXRjaEFjdGlvbiA9IHRydWUpIHtcbiAgICB0aGlzLnN0b3JlVmFsdWUgPSBfX0RFVl9fID8gdGhpcy5kZWVwRnJlZXplKG5ld1N0YXRlRm4odGhpcy5fdmFsdWUoKSkpIDogbmV3U3RhdGVGbih0aGlzLl92YWx1ZSgpKTtcblxuICAgIGlmICghdGhpcy5zdG9yZSkge1xuICAgICAgdGhpcy5zdG9yZSA9IG5ldyBCZWhhdmlvclN1YmplY3QodGhpcy5zdG9yZVZhbHVlKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoaXNUcmFuc2FjdGlvbkluUHJvY2VzcygpKSB7XG4gICAgICB0aGlzLmhhbmRsZVRyYW5zYWN0aW9uKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5kaXNwYXRjaCh0aGlzLnN0b3JlVmFsdWUsIF9kaXNwYXRjaEFjdGlvbik7XG4gIH1cblxuICAvKipcbiAgICpcbiAgICogUmVzZXQgdGhlIGN1cnJlbnQgc3RvcmUgYmFjayB0byB0aGUgaW5pdGlhbCB2YWx1ZVxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKlxuICAgKiBzdG9yZS5yZXNldCgpXG4gICAqXG4gICAqL1xuICByZXNldCgpIHtcbiAgICBpZiAodGhpcy5pc1Jlc2V0dGFibGUoKSkge1xuICAgICAgaXNEZXYoKSAmJiBzZXRBY3Rpb24oJ1Jlc2V0Jyk7XG4gICAgICB0aGlzLl9zZXRTdGF0ZSgoKSA9PiBPYmplY3QuYXNzaWduKHt9LCB0aGlzLl9pbml0aWFsU3RhdGUpKTtcbiAgICAgIHRoaXMuc2V0SGFzQ2FjaGUoZmFsc2UpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpc0RldigpICYmIGNvbnNvbGUud2FybihgWW91IG5lZWQgdG8gZW5hYmxlIHRoZSByZXNldCBmdW5jdGlvbmFsaXR5YCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqXG4gICAqIFVwZGF0ZSB0aGUgc3RvcmUncyB2YWx1ZVxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKlxuICAgKiB0aGlzLnN0b3JlLnVwZGF0ZShzdGF0ZSA9PiB7XG4gICAqICAgcmV0dXJuIHsuLi59XG4gICAqIH0pXG4gICAqL1xuICB1cGRhdGUoc3RhdGVDYWxsYmFjazogVXBkYXRlU3RhdGVDYWxsYmFjazxTPik7XG4gIC8qKlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKlxuICAgKiAgdGhpcy5zdG9yZS51cGRhdGUoeyB0b2tlbjogdG9rZW4gfSlcbiAgICovXG4gIHVwZGF0ZShzdGF0ZTogUGFydGlhbDxTPik7XG4gIHVwZGF0ZShzdGF0ZU9yQ2FsbGJhY2s6IFBhcnRpYWw8Uz4gfCBVcGRhdGVTdGF0ZUNhbGxiYWNrPFM+KSB7XG4gICAgaXNEZXYoKSAmJiBzZXRBY3Rpb24oJ1VwZGF0ZScpO1xuXG4gICAgdGhpcy5fc2V0U3RhdGUoc3RhdGUgPT4ge1xuICAgICAgY29uc3QgbmV3U3RhdGUgPSBpc0Z1bmN0aW9uKHN0YXRlT3JDYWxsYmFjaykgPyBzdGF0ZU9yQ2FsbGJhY2soc3RhdGUpIDogc3RhdGVPckNhbGxiYWNrO1xuICAgICAgY29uc3QgbWVyZ2VkID0gdGhpcy5ha2l0YVByZVVwZGF0ZShzdGF0ZSwgeyAuLi5zdGF0ZSwgLi4ubmV3U3RhdGUgfSBhcyBTKTtcbiAgICAgIHJldHVybiBpc1BsYWluT2JqZWN0KHN0YXRlKSA/IG1lcmdlZCA6IG5ldyAoc3RhdGUgYXMgYW55KS5jb25zdHJ1Y3RvcihtZXJnZWQpO1xuICAgIH0pO1xuICB9XG5cbiAgdXBkYXRlU3RvcmVDb25maWcobmV3T3B0aW9uczogVXBkYXRhYmxlU3RvcmVDb25maWdPcHRpb25zKSB7XG4gICAgdGhpcy5vcHRpb25zID0geyAuLi50aGlzLm9wdGlvbnMsIC4uLm5ld09wdGlvbnMgfTtcbiAgfVxuXG4gIC8vIEBpbnRlcm5hbFxuICBha2l0YVByZVVwZGF0ZShfOiBSZWFkb25seTxTPiwgbmV4dFN0YXRlOiBSZWFkb25seTxTPik6IFMge1xuICAgIHJldHVybiBuZXh0U3RhdGU7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICB0aGlzLmRlc3Ryb3koKTtcbiAgfVxuXG4gIC8qKlxuICAgKlxuICAgKiBEZXN0cm95IHRoZSBzdG9yZVxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKlxuICAgKiBzdG9yZS5kZXN0cm95KClcbiAgICpcbiAgICovXG4gIGRlc3Ryb3koKSB7XG4gICAgaWYgKGlzTm90QnJvd3NlcikgcmV0dXJuO1xuICAgIGlmICghKHdpbmRvdyBhcyBhbnkpLmhtckVuYWJsZWQgJiYgdGhpcyA9PT0gX19zdG9yZXNfX1t0aGlzLnN0b3JlTmFtZV0pIHtcbiAgICAgIGRlbGV0ZSBfX3N0b3Jlc19fW3RoaXMuc3RvcmVOYW1lXTtcbiAgICAgIGRpc3BhdGNoRGVsZXRlZCh0aGlzLnN0b3JlTmFtZSk7XG4gICAgICB0aGlzLnNldEhhc0NhY2hlKGZhbHNlKTtcbiAgICAgIHRoaXMuY2FjaGUuYWN0aXZlLmNvbXBsZXRlKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBvbkluaXQoaW5pdGlhbFN0YXRlOiBTKSB7XG4gICAgX19zdG9yZXNfX1t0aGlzLnN0b3JlTmFtZV0gPSB0aGlzO1xuICAgIHRoaXMuX3NldFN0YXRlKCgpID0+IGluaXRpYWxTdGF0ZSk7XG4gICAgZGlzcGF0Y2hBZGRlZCh0aGlzLnN0b3JlTmFtZSk7XG4gICAgaWYgKHRoaXMuaXNSZXNldHRhYmxlKCkpIHtcbiAgICAgIHRoaXMuX2luaXRpYWxTdGF0ZSA9IGluaXRpYWxTdGF0ZTtcbiAgICB9XG4gICAgaXNEZXYoKSAmJiBhc3NlcnRTdG9yZUhhc05hbWUodGhpcy5zdG9yZU5hbWUsIHRoaXMuY29uc3RydWN0b3IubmFtZSk7XG4gIH1cblxuICBwcml2YXRlIGRpc3BhdGNoKHN0YXRlOiBTLCBfZGlzcGF0Y2hBY3Rpb24gPSB0cnVlKSB7XG4gICAgdGhpcy5zdG9yZS5uZXh0KHN0YXRlKTtcbiAgICBpZiAoX2Rpc3BhdGNoQWN0aW9uKSB7XG4gICAgICBkaXNwYXRjaFVwZGF0ZSh0aGlzLnN0b3JlTmFtZSk7XG4gICAgICByZXNldEN1c3RvbUFjdGlvbigpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgd2F0Y2hUcmFuc2FjdGlvbigpIHtcbiAgICBjb21taXQoKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgdGhpcy5pblRyYW5zYWN0aW9uID0gZmFsc2U7XG4gICAgICB0aGlzLmRpc3BhdGNoKHRoaXMuX3ZhbHVlKCkpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBpc1Jlc2V0dGFibGUoKSB7XG4gICAgaWYgKHRoaXMucmVzZXR0YWJsZSA9PT0gZmFsc2UpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMucmVzZXR0YWJsZSB8fCBnZXRBa2l0YUNvbmZpZygpLnJlc2V0dGFibGU7XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZVRyYW5zYWN0aW9uKCkge1xuICAgIGlmICghdGhpcy5pblRyYW5zYWN0aW9uKSB7XG4gICAgICB0aGlzLndhdGNoVHJhbnNhY3Rpb24oKTtcbiAgICAgIHRoaXMuaW5UcmFuc2FjdGlvbiA9IHRydWU7XG4gICAgfVxuICB9XG59XG4iXX0=