UNPKG

@datorama/akita

Version:

State Management Tailored-Made for JS Applications

398 lines 31.5 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import * as tslib_1 from "tslib"; import { filter, skip } from 'rxjs/operators'; import { from, isObservable, of } from 'rxjs'; import { isFunction } from './isFunction'; import { AkitaError } from './errors'; import { __stores__ } from './stores'; import { getValue } from './getValueByString'; import { setAction } from './actions'; import { setValue } from './setValueByString'; import { $$addStore, $$deleteStore } from './dispatchers'; import { isNotBrowser } from './root'; import { isNil } from './isNil'; import { isObject } from './isObject'; /** @type {?} */ var skipStorageUpdate = false; /** * @param {?} skip * @return {?} */ export function setSkipStorageUpdate(skip) { skipStorageUpdate = skip; } /** * @return {?} */ export function getSkipStorageUpdate() { return skipStorageUpdate; } /** * @record */ export function PersistStateStorage() { } if (false) { /** * @param {?} key * @return {?} */ PersistStateStorage.prototype.getItem = function (key) { }; /** * @param {?} key * @param {?} value * @return {?} */ PersistStateStorage.prototype.setItem = function (key, value) { }; /** * @return {?} */ PersistStateStorage.prototype.clear = function () { }; } /** * @param {?} v * @return {?} */ function isPromise(v) { return v && isFunction(v.then); } /** * @param {?} asyncOrValue * @return {?} */ function observify(asyncOrValue) { if (isPromise(asyncOrValue) || isObservable(asyncOrValue)) { return from(asyncOrValue); } return of(asyncOrValue); } /** * @record */ export function PersistStateParams() { } if (false) { /** * The storage key * @type {?} */ PersistStateParams.prototype.key; /** * Storage strategy to use. This defaults to LocalStorage but you can pass SessionStorage or anything that implements the StorageEngine API. * @type {?} */ PersistStateParams.prototype.storage; /** * Custom deserializer. Defaults to JSON.parse * @type {?} */ PersistStateParams.prototype.deserialize; /** * Custom serializer, defaults to JSON.stringify * @type {?} */ PersistStateParams.prototype.serialize; /** * By default the whole state is saved to storage, use this param to include only the stores you need. * Pay attention that you can't use both include and exclude * @type {?} */ PersistStateParams.prototype.include; /** * By default the whole state is saved to storage, use this param to exclude stores that you don't need. * Pay attention that you can't use both include and exclude * @type {?} */ PersistStateParams.prototype.exclude; /** @type {?} */ PersistStateParams.prototype.skipStorageUpdate; /** @type {?} */ PersistStateParams.prototype.preStorageUpdateOperator; /** * Whether to persist a dynamic store upon destroy * @type {?} */ PersistStateParams.prototype.persistOnDestroy; /** * @param {?} storeName * @param {?} state * @return {?} */ PersistStateParams.prototype.preStorageUpdate = function (storeName, state) { }; /** * @param {?} storeName * @param {?} state * @return {?} */ PersistStateParams.prototype.preStoreUpdate = function (storeName, state) { }; } /** * @param {?=} params * @return {?} */ export function persistState(params) { if (isNotBrowser) return; /** @type {?} */ var defaults = { key: 'AkitaStores', storage: typeof localStorage === 'undefined' ? params.storage : localStorage, deserialize: JSON.parse, serialize: JSON.stringify, include: [], // @deprecated exclude: [], persistOnDestroy: false, preStorageUpdate: (/** * @param {?} storeName * @param {?} state * @return {?} */ function (storeName, state) { return state; }), preStoreUpdate: (/** * @param {?} storeName * @param {?} state * @return {?} */ function (storeName, state) { return state; }), skipStorageUpdate: getSkipStorageUpdate, preStorageUpdateOperator: (/** * @return {?} */ function () { return (/** * @param {?} source * @return {?} */ function (source) { return source; }); }) }; var _a = Object.assign({}, defaults, params), storage = _a.storage, deserialize = _a.deserialize, serialize = _a.serialize, include = _a.include, exclude = _a.exclude, key = _a.key, preStorageUpdate = _a.preStorageUpdate, persistOnDestroy = _a.persistOnDestroy, preStorageUpdateOperator = _a.preStorageUpdateOperator, preStoreUpdate = _a.preStoreUpdate, skipStorageUpdate = _a.skipStorageUpdate; /** @type {?} */ var hasInclude = include.length > 0; /** @type {?} */ var hasExclude = exclude.length > 0; /** @type {?} */ var includeStores; if (hasInclude && hasExclude) { throw new AkitaError("You can't use both include and exclude"); } if (hasInclude) { includeStores = include.reduce((/** * @param {?} acc * @param {?} path * @return {?} */ function (acc, path) { if (isFunction(path)) { acc.fns.push(path); } else { /** @type {?} */ var storeName = path.split('.')[0]; acc[storeName] = path; } return acc; }), { fns: [] }); } /** @type {?} */ var stores = {}; /** @type {?} */ var acc = {}; /** @type {?} */ var subscriptions = []; /** @type {?} */ var buffer = []; /** * @param {?} v * @return {?} */ function _save(v) { observify(v).subscribe((/** * @return {?} */ function () { /** @type {?} */ var next = buffer.shift(); next && _save(next); })); } // when we use the local/session storage we perform the serialize, otherwise we let the passed storage implementation to do it /** @type {?} */ var isLocalStorage = typeof localStorage !== 'undefined' && (storage === localStorage || storage === sessionStorage); observify(storage.getItem(key)).subscribe((/** * @param {?} value * @return {?} */ function (value) { /** @type {?} */ var storageState = isObject(value) ? value : deserialize(value || '{}'); /** * @param {?} storeCache * @return {?} */ function save(storeCache) { storageState['$cache'] = tslib_1.__assign({}, (storageState['$cache'] || {}), storeCache); /** @type {?} */ var storageValue = Object.assign({}, storageState, acc); buffer.push(storage.setItem(key, isLocalStorage ? serialize(storageValue) : storageValue)); _save(buffer.shift()); } /** * @param {?} storeName * @param {?} path * @return {?} */ function subscribe(storeName, path) { stores[storeName] = __stores__[storeName] ._select((/** * @param {?} state * @return {?} */ function (state) { return getValue(state, path); })) .pipe(skip(1), filter((/** * @return {?} */ function () { return skipStorageUpdate() === false; })), preStorageUpdateOperator()) .subscribe((/** * @param {?} data * @return {?} */ function (data) { acc[storeName] = preStorageUpdate(storeName, data); Promise.resolve().then((/** * @return {?} */ function () { var _a; return save((_a = {}, _a[storeName] = __stores__[storeName]._cache().getValue(), _a)); })); })); } /** * @param {?} storeName * @param {?} store * @param {?} path * @return {?} */ function setInitial(storeName, store, path) { if (storeName in storageState) { setAction('@PersistState'); store._setState((/** * @param {?} state * @return {?} */ function (state) { return setValue(state, path, preStoreUpdate(storeName, storageState[storeName])); })); /** @type {?} */ var hasCache = storageState['$cache'] ? storageState['$cache'][storeName] : false; __stores__[storeName].setHasCache(hasCache); } } subscriptions.push($$deleteStore.subscribe((/** * @param {?} storeName * @return {?} */ function (storeName) { if (stores[storeName]) { if (persistOnDestroy === false) { save(false); } stores[storeName].unsubscribe(); delete stores[storeName]; } }))); subscriptions.push($$addStore.subscribe((/** * @param {?} storeName * @return {?} */ function (storeName) { if (hasExclude && exclude.includes(storeName)) { return; } /** @type {?} */ var store = __stores__[storeName]; if (hasInclude) { /** @type {?} */ var path = includeStores[storeName]; if (!path) { /** @type {?} */ var passPredicate = includeStores.fns.some((/** * @param {?} fn * @return {?} */ function (fn) { return fn(storeName); })); if (passPredicate) { path = storeName; } else { return; } } setInitial(storeName, store, path); subscribe(storeName, path); } else { setInitial(storeName, store, storeName); subscribe(storeName, storeName); } }))); })); return { destroy: /** * @return {?} */ function () { subscriptions.forEach((/** * @param {?} s * @return {?} */ function (s) { return s.unsubscribe(); })); for (var i = 0, keys = Object.keys(stores); i < keys.length; i++) { /** @type {?} */ var storeName = keys[i]; stores[storeName].unsubscribe(); } stores = {}; }, clear: /** * @return {?} */ function () { storage.clear(); }, clearStore: /** * @param {?=} storeName * @return {?} */ function (storeName) { if (isNil(storeName)) { /** @type {?} */ var value_1 = observify(storage.setItem(key, '{}')); value_1.subscribe(); return; } /** @type {?} */ var value = storage.getItem(key); observify(value).subscribe((/** * @param {?} v * @return {?} */ function (v) { /** @type {?} */ var storageState = deserialize(v || '{}'); if (storageState[storeName]) { delete storageState[storeName]; /** @type {?} */ var value_2 = observify(storage.setItem(key, serialize(storageState))); value_2.subscribe(); } })); } }; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGVyc2lzdFN0YXRlLmpzIiwic291cmNlUm9vdCI6Im5nOi8vQGRhdG9yYW1hL2FraXRhLyIsInNvdXJjZXMiOlsic3JjL3BlcnNpc3RTdGF0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDOUMsT0FBTyxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsRUFBRSxFQUFrQyxNQUFNLE1BQU0sQ0FBQztBQUU5RSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQzFDLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDdEMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUN0QyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDOUMsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUN0QyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDOUMsT0FBTyxFQUFFLFVBQVUsRUFBRSxhQUFhLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDMUQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLFFBQVEsQ0FBQztBQUN0QyxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQ2hDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxZQUFZLENBQUM7O0lBRWxDLGlCQUFpQixHQUFHLEtBQUs7Ozs7O0FBRTdCLE1BQU0sVUFBVSxvQkFBb0IsQ0FBQyxJQUFhO0lBQ2hELGlCQUFpQixHQUFHLElBQUksQ0FBQztBQUMzQixDQUFDOzs7O0FBRUQsTUFBTSxVQUFVLG9CQUFvQjtJQUNsQyxPQUFPLGlCQUFpQixDQUFDO0FBQzNCLENBQUM7Ozs7QUFFRCx5Q0FNQzs7Ozs7O0lBTEMsMkRBQWlDOzs7Ozs7SUFFakMsa0VBQTZDOzs7O0lBRTdDLHNEQUFjOzs7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SUFBSSxDQUFDO2dCQUUzQyxJQUFJLFlBQVksQ0FBQyxTQUFTLENBQUMsRUFBRTtvQkFDM0IsT0FBTyxZQUFZLENBQUMsU0FBUyxDQUFDLENBQUM7O3dCQUN6QixPQUFLLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLFNBQVMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDO29CQUN0RSxPQUFLLENBQUMsU0FBUyxFQUFFLENBQUM7aUJBQ25CO1lBQ0gsQ0FBQyxFQUFDLENBQUM7UUFDTCxDQUFDO0tBQ0YsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBmaWx0ZXIsIHNraXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBmcm9tLCBpc09ic2VydmFibGUsIG9mLCBPcGVyYXRvckZ1bmN0aW9uLCBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IEhhc2hNYXAsIE1heWJlQXN5bmMgfSBmcm9tICcuL3R5cGVzJztcbmltcG9ydCB7IGlzRnVuY3Rpb24gfSBmcm9tICcuL2lzRnVuY3Rpb24nO1xuaW1wb3J0IHsgQWtpdGFFcnJvciB9IGZyb20gJy4vZXJyb3JzJztcbmltcG9ydCB7IF9fc3RvcmVzX18gfSBmcm9tICcuL3N0b3Jlcyc7XG5pbXBvcnQgeyBnZXRWYWx1ZSB9IGZyb20gJy4vZ2V0VmFsdWVCeVN0cmluZyc7XG5pbXBvcnQgeyBzZXRBY3Rpb24gfSBmcm9tICcuL2FjdGlvbnMnO1xuaW1wb3J0IHsgc2V0VmFsdWUgfSBmcm9tICcuL3NldFZhbHVlQnlTdHJpbmcnO1xuaW1wb3J0IHsgJCRhZGRTdG9yZSwgJCRkZWxldGVTdG9yZSB9IGZyb20gJy4vZGlzcGF0Y2hlcnMnO1xuaW1wb3J0IHsgaXNOb3RCcm93c2VyIH0gZnJvbSAnLi9yb290JztcbmltcG9ydCB7IGlzTmlsIH0gZnJvbSAnLi9pc05pbCc7XG5pbXBvcnQgeyBpc09iamVjdCB9IGZyb20gJy4vaXNPYmplY3QnO1xuXG5sZXQgc2tpcFN0b3JhZ2VVcGRhdGUgPSBmYWxzZTtcblxuZXhwb3J0IGZ1bmN0aW9uIHNldFNraXBTdG9yYWdlVXBkYXRlKHNraXA6IGJvb2xlYW4pIHtcbiAgc2tpcFN0b3JhZ2VVcGRhdGUgPSBza2lwO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0U2tpcFN0b3JhZ2VVcGRhdGUoKSB7XG4gIHJldHVybiBza2lwU3RvcmFnZVVwZGF0ZTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQZXJzaXN0U3RhdGVTdG9yYWdlIHtcbiAgZ2V0SXRlbShrZXk6IHN0cmluZyk6IE1heWJlQXN5bmM7XG5cbiAgc2V0SXRlbShrZXk6IHN0cmluZywgdmFsdWU6IGFueSk6IE1heWJlQXN5bmM7XG5cbiAgY2xlYXIoKTogdm9pZDtcbn1cblxuZnVuY3Rpb24gaXNQcm9taXNlKHY6IGFueSkge1xuICByZXR1cm4gdiAmJiBpc0Z1bmN0aW9uKHYudGhlbik7XG59XG5cbmZ1bmN0aW9uIG9ic2VydmlmeShhc3luY09yVmFsdWU6IGFueSkge1xuICBpZiAoaXNQcm9taXNlKGFzeW5jT3JWYWx1ZSkgfHwgaXNPYnNlcnZhYmxlKGFzeW5jT3JWYWx1ZSkpIHtcbiAgICByZXR1cm4gZnJvbShhc3luY09yVmFsdWUpO1xuICB9XG5cbiAgcmV0dXJuIG9mKGFzeW5jT3JWYWx1ZSk7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGVyc2lzdFN0YXRlUGFyYW1zIHtcbiAgLyoqIFRoZSBzdG9yYWdlIGtleSAqL1xuICBrZXk6IHN0cmluZztcbiAgLyoqIFN0b3JhZ2Ugc3RyYXRlZ3kgdG8gdXNlLiBUaGlzIGRlZmF1bHRzIHRvIExvY2FsU3RvcmFnZSBidXQgeW91IGNhbiBwYXNzIFNlc3Npb25TdG9yYWdlIG9yIGFueXRoaW5nIHRoYXQgaW1wbGVtZW50cyB0aGUgU3RvcmFnZUVuZ2luZSBBUEkuICovXG4gIHN0b3JhZ2U6IFBlcnNpc3RTdGF0ZVN0b3JhZ2U7XG4gIC8qKiBDdXN0b20gZGVzZXJpYWxpemVyLiBEZWZhdWx0cyB0byBKU09OLnBhcnNlICovXG4gIGRlc2VyaWFsaXplOiBGdW5jdGlvbjtcbiAgLyoqIEN1c3RvbSBzZXJpYWxpemVyLCBkZWZhdWx0cyB0byBKU09OLnN0cmluZ2lmeSAqL1xuICBzZXJpYWxpemU6IEZ1bmN0aW9uO1xuICAvKipcbiAgICogQnkgZGVmYXVsdCB0aGUgd2hvbGUgc3RhdGUgaXMgc2F2ZWQgdG8gc3RvcmFnZSwgdXNlIHRoaXMgcGFyYW0gdG8gaW5jbHVkZSBvbmx5IHRoZSBzdG9yZXMgeW91IG5lZWQuXG4gICAqIFBheSBhdHRlbnRpb24gdGhhdCB5b3UgY2FuJ3QgdXNlIGJvdGggaW5jbHVkZSBhbmQgZXhjbHVkZVxuICAgKi9cbiAgaW5jbHVkZTogKHN0cmluZyB8ICgoc3RvcmVOYW1lOiBzdHJpbmcpID0+IGJvb2xlYW4pKVtdO1xuICAvKipcbiAgICogIEJ5IGRlZmF1bHQgdGhlIHdob2xlIHN0YXRlIGlzIHNhdmVkIHRvIHN0b3JhZ2UsIHVzZSB0aGlzIHBhcmFtIHRvIGV4Y2x1ZGUgc3RvcmVzIHRoYXQgeW91IGRvbid0IG5lZWQuXG4gICAqICBQYXkgYXR0ZW50aW9uIHRoYXQgeW91IGNhbid0IHVzZSBib3RoIGluY2x1ZGUgYW5kIGV4Y2x1ZGVcbiAgICovXG4gIGV4Y2x1ZGU6IHN0cmluZ1tdO1xuXG4gIHByZVN0b3JhZ2VVcGRhdGUoc3RvcmVOYW1lOiBzdHJpbmcsIHN0YXRlOiBhbnkpOiBhbnk7XG5cbiAgcHJlU3RvcmVVcGRhdGUoc3RvcmVOYW1lOiBzdHJpbmcsIHN0YXRlOiBhbnkpOiBhbnk7XG5cbiAgc2tpcFN0b3JhZ2VVcGRhdGU6ICgpID0+IGJvb2xlYW47XG4gIHByZVN0b3JhZ2VVcGRhdGVPcGVyYXRvcjogKCkgPT4gT3BlcmF0b3JGdW5jdGlvbjxhbnksIGFueT47XG4gIC8qKiBXaGV0aGVyIHRvIHBlcnNpc3QgYSBkeW5hbWljIHN0b3JlIHVwb24gZGVzdHJveSAqL1xuICBwZXJzaXN0T25EZXN0cm95OiBib29sZWFuO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcGVyc2lzdFN0YXRlKHBhcmFtcz86IFBhcnRpYWw8UGVyc2lzdFN0YXRlUGFyYW1zPikge1xuICBpZiAoaXNOb3RCcm93c2VyKSByZXR1cm47XG5cbiAgY29uc3QgZGVmYXVsdHM6IFBlcnNpc3RTdGF0ZVBhcmFtcyA9IHtcbiAgICBrZXk6ICdBa2l0YVN0b3JlcycsXG4gICAgc3RvcmFnZTogdHlwZW9mIGxvY2FsU3RvcmFnZSA9PT0gJ3VuZGVmaW5lZCcgPyBwYXJhbXMuc3RvcmFnZSA6IGxvY2FsU3RvcmFnZSxcbiAgICBkZXNlcmlhbGl6ZTogSlNPTi5wYXJzZSxcbiAgICBzZXJpYWxpemU6IEpTT04uc3RyaW5naWZ5LFxuICAgIGluY2x1ZGU6IFtdLFxuICAgIC8vIEBkZXByZWNhdGVkXG4gICAgZXhjbHVkZTogW10sXG4gICAgcGVyc2lzdE9uRGVzdHJveTogZmFsc2UsXG4gICAgcHJlU3RvcmFnZVVwZGF0ZTogZnVuY3Rpb24oc3RvcmVOYW1lLCBzdGF0ZSkge1xuICAgICAgcmV0dXJuIHN0YXRlO1xuICAgIH0sXG4gICAgcHJlU3RvcmVVcGRhdGU6IGZ1bmN0aW9uKHN0b3JlTmFtZSwgc3RhdGUpIHtcbiAgICAgIHJldHVybiBzdGF0ZTtcbiAgICB9LFxuICAgIHNraXBTdG9yYWdlVXBkYXRlOiBnZXRTa2lwU3RvcmFnZVVwZGF0ZSxcbiAgICBwcmVTdG9yYWdlVXBkYXRlT3BlcmF0b3I6ICgpID0+IHNvdXJjZSA9PiBzb3VyY2VcbiAgfTtcblxuICBjb25zdCB7IHN0b3JhZ2UsIGRlc2VyaWFsaXplLCBzZXJpYWxpemUsIGluY2x1ZGUsIGV4Y2x1ZGUsIGtleSwgcHJlU3RvcmFnZVVwZGF0ZSwgcGVyc2lzdE9uRGVzdHJveSwgcHJlU3RvcmFnZVVwZGF0ZU9wZXJhdG9yLCBwcmVTdG9yZVVwZGF0ZSwgc2tpcFN0b3JhZ2VVcGRhdGUgfSA9IE9iamVjdC5hc3NpZ24oXG4gICAge30sXG4gICAgZGVmYXVsdHMsXG4gICAgcGFyYW1zXG4gICk7XG5cbiAgY29uc3QgaGFzSW5jbHVkZSA9IGluY2x1ZGUubGVuZ3RoID4gMDtcbiAgY29uc3QgaGFzRXhjbHVkZSA9IGV4Y2x1ZGUubGVuZ3RoID4gMDtcbiAgbGV0IGluY2x1ZGVTdG9yZXM6IHsgZm5zOiBGdW5jdGlvbltdOyBba2V5OiBzdHJpbmddOiBGdW5jdGlvbltdIHwgc3RyaW5nIH07XG5cbiAgaWYgKGhhc0luY2x1ZGUgJiYgaGFzRXhjbHVkZSkge1xuICAgIHRocm93IG5ldyBBa2l0YUVycm9yKFwiWW91IGNhbid0IHVzZSBib3RoIGluY2x1ZGUgYW5kIGV4Y2x1ZGVcIik7XG4gIH1cblxuICBpZiAoaGFzSW5jbHVkZSkge1xuICAgIGluY2x1ZGVTdG9yZXMgPSBpbmNsdWRlLnJlZHVjZShcbiAgICAgIChhY2MsIHBhdGgpID0+IHtcbiAgICAgICAgaWYgKGlzRnVuY3Rpb24ocGF0aCkpIHtcbiAgICAgICAgICBhY2MuZm5zLnB1c2gocGF0aCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3Qgc3RvcmVOYW1lID0gcGF0aC5zcGxpdCgnLicpWzBdO1xuICAgICAgICAgIGFjY1tzdG9yZU5hbWVdID0gcGF0aDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgfSxcbiAgICAgIHsgZm5zOiBbXSB9XG4gICAgKTtcbiAgfVxuXG4gIGxldCBzdG9yZXM6IEhhc2hNYXA8U3Vic2NyaXB0aW9uPiA9IHt9O1xuICBsZXQgYWNjID0ge307XG4gIGxldCBzdWJzY3JpcHRpb25zOiBTdWJzY3JpcHRpb25bXSA9IFtdO1xuXG4gIGNvbnN0IGJ1ZmZlciA9IFtdO1xuXG4gIGZ1bmN0aW9uIF9zYXZlKHY6IGFueSkge1xuICAgIG9ic2VydmlmeSh2KS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgY29uc3QgbmV4dCA9IGJ1ZmZlci5zaGlmdCgpO1xuICAgICAgbmV4dCAmJiBfc2F2ZShuZXh0KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8vIHdoZW4gd2UgdXNlIHRoZSBsb2NhbC9zZXNzaW9uIHN0b3JhZ2Ugd2UgcGVyZm9ybSB0aGUgc2VyaWFsaXplLCBvdGhlcndpc2Ugd2UgbGV0IHRoZSBwYXNzZWQgc3RvcmFnZSBpbXBsZW1lbnRhdGlvbiB0byBkbyBpdFxuICBjb25zdCBpc0xvY2FsU3RvcmFnZSA9IHR5cGVvZiBsb2NhbFN0b3JhZ2UgIT09ICd1bmRlZmluZWQnICYmIChzdG9yYWdlID09PSBsb2NhbFN0b3JhZ2UgfHwgc3RvcmFnZSA9PT0gc2Vzc2lvblN0b3JhZ2UpO1xuXG4gIG9ic2VydmlmeShzdG9yYWdlLmdldEl0ZW0oa2V5KSkuc3Vic2NyaWJlKCh2YWx1ZTogYW55KSA9PiB7XG4gICAgY29uc3Qgc3RvcmFnZVN0YXRlID0gaXNPYmplY3QodmFsdWUpID8gdmFsdWUgOiBkZXNlcmlhbGl6ZSh2YWx1ZSB8fCAne30nKTtcblxuICAgIGZ1bmN0aW9uIHNhdmUoc3RvcmVDYWNoZSkge1xuICAgICAgc3RvcmFnZVN0YXRlWyckY2FjaGUnXSA9IHsgLi4uKHN0b3JhZ2VTdGF0ZVsnJGNhY2hlJ10gfHwge30pLCAuLi5zdG9yZUNhY2hlIH07XG4gICAgICBjb25zdCBzdG9yYWdlVmFsdWUgPSBPYmplY3QuYXNzaWduKHt9LCBzdG9yYWdlU3RhdGUsIGFjYyk7XG5cbiAgICAgIGJ1ZmZlci5wdXNoKHN0b3JhZ2Uuc2V0SXRlbShrZXksIGlzTG9jYWxTdG9yYWdlID8gc2VyaWFsaXplKHN0b3JhZ2VWYWx1ZSkgOiBzdG9yYWdlVmFsdWUpKTtcbiAgICAgIF9zYXZlKGJ1ZmZlci5zaGlmdCgpKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzdWJzY3JpYmUoc3RvcmVOYW1lLCBwYXRoKSB7XG4gICAgICBzdG9yZXNbc3RvcmVOYW1lXSA9IF9fc3RvcmVzX19bc3RvcmVOYW1lXVxuICAgICAgICAuX3NlbGVjdChzdGF0ZSA9PiBnZXRWYWx1ZShzdGF0ZSwgcGF0aCkpXG4gICAgICAgIC5waXBlKFxuICAgICAgICAgIHNraXAoMSksXG4gICAgICAgICAgZmlsdGVyKCgpID0+IHNraXBTdG9yYWdlVXBkYXRlKCkgPT09IGZhbHNlKSxcbiAgICAgICAgICBwcmVTdG9yYWdlVXBkYXRlT3BlcmF0b3IoKVxuICAgICAgICApXG4gICAgICAgIC5zdWJzY3JpYmUoZGF0YSA9PiB7XG4gICAgICAgICAgYWNjW3N0b3JlTmFtZV0gPSBwcmVTdG9yYWdlVXBkYXRlKHN0b3JlTmFtZSwgZGF0YSk7XG4gICAgICAgICAgUHJvbWlzZS5yZXNvbHZlKCkudGhlbigoKSA9PiBzYXZlKHsgW3N0b3JlTmFtZV06IF9fc3RvcmVzX19bc3RvcmVOYW1lXS5fY2FjaGUoKS5nZXRWYWx1ZSgpIH0pKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc2V0SW5pdGlhbChzdG9yZU5hbWUsIHN0b3JlLCBwYXRoKSB7XG4gICAgICBpZiAoc3RvcmVOYW1lIGluIHN0b3JhZ2VTdGF0ZSkge1xuICAgICAgICBzZXRBY3Rpb24oJ0BQZXJzaXN0U3RhdGUnKTtcbiAgICAgICAgc3RvcmUuX3NldFN0YXRlKHN0YXRlID0+IHtcbiAgICAgICAgICByZXR1cm4gc2V0VmFsdWUoc3RhdGUsIHBhdGgsIHByZVN0b3JlVXBkYXRlKHN0b3JlTmFtZSwgc3RvcmFnZVN0YXRlW3N0b3JlTmFtZV0pKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IGhhc0NhY2hlID0gc3RvcmFnZVN0YXRlWyckY2FjaGUnXSA/IHN0b3JhZ2VTdGF0ZVsnJGNhY2hlJ11bc3RvcmVOYW1lXSA6IGZhbHNlO1xuICAgICAgICBfX3N0b3Jlc19fW3N0b3JlTmFtZV0uc2V0SGFzQ2FjaGUoaGFzQ2FjaGUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHN1YnNjcmlwdGlvbnMucHVzaChcbiAgICAgICQkZGVsZXRlU3RvcmUuc3Vic2NyaWJlKHN0b3JlTmFtZSA9PiB7XG4gICAgICAgIGlmIChzdG9yZXNbc3RvcmVOYW1lXSkge1xuICAgICAgICAgIGlmIChwZXJzaXN0T25EZXN0cm95ID09PSBmYWxzZSkge1xuICAgICAgICAgICAgc2F2ZShmYWxzZSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHN0b3Jlc1tzdG9yZU5hbWVdLnVuc3Vic2NyaWJlKCk7XG4gICAgICAgICAgZGVsZXRlIHN0b3Jlc1tzdG9yZU5hbWVdO1xuICAgICAgICB9XG4gICAgICB9KVxuICAgICk7XG5cbiAgICBzdWJzY3JpcHRpb25zLnB1c2goXG4gICAgICAkJGFkZFN0b3JlLnN1YnNjcmliZShzdG9yZU5hbWUgPT4ge1xuICAgICAgICBpZiAoaGFzRXhjbHVkZSAmJiBleGNsdWRlLmluY2x1ZGVzKHN0b3JlTmFtZSkpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzdG9yZSA9IF9fc3RvcmVzX19bc3RvcmVOYW1lXTtcbiAgICAgICAgaWYgKGhhc0luY2x1ZGUpIHtcbiAgICAgICAgICBsZXQgcGF0aCA9IGluY2x1ZGVTdG9yZXNbc3RvcmVOYW1lXTtcblxuICAgICAgICAgIGlmICghcGF0aCkge1xuICAgICAgICAgICAgY29uc3QgcGFzc1ByZWRpY2F0ZSA9IGluY2x1ZGVTdG9yZXMuZm5zLnNvbWUoZm4gPT4gZm4oc3RvcmVOYW1lKSk7XG4gICAgICAgICAgICBpZiAocGFzc1ByZWRpY2F0ZSkge1xuICAgICAgICAgICAgICBwYXRoID0gc3RvcmVOYW1lO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBzZXRJbml0aWFsKHN0b3JlTmFtZSwgc3RvcmUsIHBhdGgpO1xuICAgICAgICAgIHN1YnNjcmliZShzdG9yZU5hbWUsIHBhdGgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHNldEluaXRpYWwoc3RvcmVOYW1lLCBzdG9yZSwgc3RvcmVOYW1lKTtcbiAgICAgICAgICBzdWJzY3JpYmUoc3RvcmVOYW1lLCBzdG9yZU5hbWUpO1xuICAgICAgICB9XG4gICAgICB9KVxuICAgICk7XG4gIH0pO1xuXG4gIHJldHVybiB7XG4gICAgZGVzdHJveSgpIHtcbiAgICAgIHN1YnNjcmlwdGlvbnMuZm9yRWFjaChzID0+IHMudW5zdWJzY3JpYmUoKSk7XG4gICAgICBmb3IgKGxldCBpID0gMCwga2V5cyA9IE9iamVjdC5rZXlzKHN0b3Jlcyk7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IHN0b3JlTmFtZSA9IGtleXNbaV07XG4gICAgICAgIHN0b3Jlc1tzdG9yZU5hbWVdLnVuc3Vic2NyaWJlKCk7XG4gICAgICB9XG4gICAgICBzdG9yZXMgPSB7fTtcbiAgICB9LFxuICAgIGNsZWFyKCkge1xuICAgICAgc3RvcmFnZS5jbGVhcigpO1xuICAgIH0sXG4gICAgY2xlYXJTdG9yZShzdG9yZU5hbWU/OiBzdHJpbmcpIHtcbiAgICAgIGlmIChpc05pbChzdG9yZU5hbWUpKSB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gb2JzZXJ2aWZ5KHN0b3JhZ2Uuc2V0SXRlbShrZXksICd7fScpKTtcbiAgICAgICAgdmFsdWUuc3Vic2NyaWJlKCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHZhbHVlID0gc3RvcmFnZS5nZXRJdGVtKGtleSk7XG4gICAgICBvYnNlcnZpZnkodmFsdWUpLnN1YnNjcmliZSh2ID0+IHtcbiAgICAgICAgY29uc3Qgc3RvcmFnZVN0YXRlID0gZGVzZXJpYWxpemUodiB8fCAne30nKTtcblxuICAgICAgICBpZiAoc3RvcmFnZVN0YXRlW3N0b3JlTmFtZV0pIHtcbiAgICAgICAgICBkZWxldGUgc3RvcmFnZVN0YXRlW3N0b3JlTmFtZV07XG4gICAgICAgICAgY29uc3QgdmFsdWUgPSBvYnNlcnZpZnkoc3RvcmFnZS5zZXRJdGVtKGtleSwgc2VyaWFsaXplKHN0b3JhZ2VTdGF0ZSkpKTtcbiAgICAgICAgICB2YWx1ZS5zdWJzY3JpYmUoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9O1xufVxuIl19