UNPKG

@datorama/akita

Version:

State Management Tailored-Made for JS Applications

283 lines 22 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { AkitaPlugin } from '../plugin'; import { QueryEntity } from '../../queryEntity'; import { BehaviorSubject, combineLatest, Subject } from 'rxjs'; import { distinctUntilChanged, map, skip } from 'rxjs/operators'; import { isUndefined } from '../../isUndefined'; import { coerceArray } from '../../coerceArray'; import { isFunction } from '../../isFunction'; import { logAction } from '../../actions'; /** @type {?} */ export const dirtyCheckDefaultParams = { comparator: (/** * @param {?} head * @param {?} current * @return {?} */ (head, current) => JSON.stringify(head) !== JSON.stringify(current)) }; /** * @param {?} nestedObj * @param {?} path * @return {?} */ export function getNestedPath(nestedObj, path) { /** @type {?} */ const pathAsArray = path.split('.'); return pathAsArray.reduce((/** * @param {?} obj * @param {?} key * @return {?} */ (obj, key) => (obj && obj[key] !== 'undefined' ? obj[key] : undefined)), nestedObj); } /** * @template State */ export class DirtyCheckPlugin extends AkitaPlugin { /** * @param {?} query * @param {?=} params * @param {?=} _entityId */ constructor(query, params, _entityId) { super(query); this.query = query; this.params = params; this._entityId = _entityId; this.dirty = new BehaviorSubject(false); this.active = false; this._reset = new Subject(); this.isDirty$ = this.dirty.asObservable().pipe(distinctUntilChanged()); this.reset$ = this._reset.asObservable(); this.params = Object.assign({}, dirtyCheckDefaultParams, params); if (this.params.watchProperty) { /** @type {?} */ let watchProp = (/** @type {?} */ (coerceArray(this.params.watchProperty))); if (query instanceof QueryEntity && watchProp.includes('entities') && !watchProp.includes('ids')) { watchProp.push('ids'); } this.params.watchProperty = watchProp; } } /** * @param {?=} params * @return {?} */ reset(params = {}) { /** @type {?} */ let currentValue = this.head; if (isFunction(params.updateFn)) { if (this.isEntityBased(this._entityId)) { currentValue = params.updateFn(this.head, ((/** @type {?} */ (this.getQuery()))).getEntity(this._entityId)); } else { currentValue = params.updateFn(this.head, ((/** @type {?} */ (this.getQuery()))).getValue()); } } logAction(`@DirtyCheck - Revert`); this.updateStore(currentValue, this._entityId); this._reset.next(); } /** * @template THIS * @this {THIS} * @return {THIS} */ setHead() { if (!(/** @type {?} */ (this)).active) { (/** @type {?} */ (this)).activate(); (/** @type {?} */ (this)).active = true; } else { (/** @type {?} */ (this)).head = (/** @type {?} */ (this))._getHead(); } (/** @type {?} */ (this)).updateDirtiness(false); return (/** @type {?} */ (this)); } /** * @return {?} */ isDirty() { return !!this.dirty.value; } /** * @return {?} */ hasHead() { return !!this.getHead(); } /** * @return {?} */ destroy() { this.head = null; this.subscription && this.subscription.unsubscribe(); this._reset && this._reset.complete(); } /** * @param {?} path * @return {?} */ isPathDirty(path) { /** @type {?} */ const head = this.getHead(); /** @type {?} */ const current = ((/** @type {?} */ (this.getQuery()))).getValue(); /** @type {?} */ const currentPathValue = getNestedPath(current, path); /** @type {?} */ const headPathValue = getNestedPath(head, path); return this.params.comparator(currentPathValue, headPathValue); } /** * @protected * @return {?} */ getHead() { return this.head; } /** * @private * @return {?} */ activate() { this.head = this._getHead(); /** * if we are tracking specific properties select only the relevant ones * @type {?} */ const source = this.params.watchProperty ? ((/** @type {?} */ (this.params.watchProperty))).map((/** * @param {?} prop * @return {?} */ prop => this.query .select((/** * @param {?} state * @return {?} */ state => state[prop])) .pipe(map((/** * @param {?} val * @return {?} */ val => ({ val, __akitaKey: prop })))))) : [this.selectSource(this._entityId)]; this.subscription = combineLatest(...source) .pipe(skip(1)) .subscribe((/** * @param {?} currentState * @return {?} */ (currentState) => { if (isUndefined(this.head)) return; /** * __akitaKey is used to determine if we are tracking a specific property or a store change * @type {?} */ const isChange = currentState.some((/** * @param {?} state * @return {?} */ state => { /** @type {?} */ const head = state.__akitaKey ? this.head[(/** @type {?} */ (state.__akitaKey))] : this.head; /** @type {?} */ const compareTo = state.__akitaKey ? state.val : state; return this.params.comparator(head, compareTo); })); this.updateDirtiness(isChange); })); } /** * @private * @param {?} isDirty * @return {?} */ updateDirtiness(isDirty) { this.dirty.next(isDirty); } /** * @private * @return {?} */ _getHead() { /** @type {?} */ let head = this.getSource(this._entityId); if (this.params.watchProperty) { head = this.getWatchedValues((/** @type {?} */ (head))); } return head; } /** * @private * @param {?} source * @return {?} */ getWatchedValues(source) { return ((/** @type {?} */ (this.params.watchProperty))).reduce((/** * @param {?} watched * @param {?} prop * @return {?} */ (watched, prop) => { watched[prop] = source[prop]; return watched; }), (/** @type {?} */ ({}))); } } if (false) { /** * @type {?} * @private */ DirtyCheckPlugin.prototype.head; /** * @type {?} * @private */ DirtyCheckPlugin.prototype.dirty; /** * @type {?} * @private */ DirtyCheckPlugin.prototype.subscription; /** * @type {?} * @private */ DirtyCheckPlugin.prototype.active; /** * @type {?} * @private */ DirtyCheckPlugin.prototype._reset; /** @type {?} */ DirtyCheckPlugin.prototype.isDirty$; /** @type {?} */ DirtyCheckPlugin.prototype.reset$; /** * @type {?} * @protected */ DirtyCheckPlugin.prototype.query; /** * @type {?} * @private */ DirtyCheckPlugin.prototype.params; /** * @type {?} * @private */ DirtyCheckPlugin.prototype._entityId; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlydHlDaGVja1BsdWdpbi5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0BkYXRvcmFtYS9ha2l0YS8iLCJzb3VyY2VzIjpbInNyYy9wbHVnaW5zL2RpcnR5Q2hlY2svZGlydHlDaGVja1BsdWdpbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUFFLFdBQVcsRUFBVyxNQUFNLFdBQVcsQ0FBQztBQUNqRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDaEQsT0FBTyxFQUFFLGVBQWUsRUFBRSxhQUFhLEVBQWMsT0FBTyxFQUFnQixNQUFNLE1BQU0sQ0FBQztBQUN6RixPQUFPLEVBQUUsb0JBQW9CLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ2pFLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUVoRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDaEQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7O0FBVzFDLE1BQU0sT0FBTyx1QkFBdUIsR0FBRztJQUNyQyxVQUFVOzs7OztJQUFFLENBQUMsSUFBSSxFQUFFLE9BQU8sRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsS0FBSyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFBO0NBQ2hGOzs7Ozs7QUFFRCxNQUFNLFVBQVUsYUFBYSxDQUFDLFNBQVMsRUFBRSxJQUFZOztVQUM3QyxXQUFXLEdBQWEsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUM7SUFDN0MsT0FBTyxXQUFXLENBQUMsTUFBTTs7Ozs7SUFBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxHQUFHLENBQUMs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LENBQUM7Ozs7OztJQUVPLGVBQWUsQ0FBQyxPQUFnQjtRQUN0QyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUMzQixDQUFDOzs7OztJQUVPLFFBQVE7O1lBQ1YsSUFBSSxHQUFnQixJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUM7UUFDdEQsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsRUFBRTtZQUM3QixJQUFJLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLG1CQUFBLElBQUksRUFBUyxDQUFDLENBQUM7U0FDN0M7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7Ozs7OztJQUVPLGdCQUFnQixDQUFDLE1BQWE7UUFDcEMsT0FBTyxDQUFDLG1CQUFBLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxFQUFtQixDQUFDLENBQUMsTUFBTTs7Ozs7UUFDMUQsQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLEVBQUU7WUFDaEIsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUM3QixPQUFPLE9BQU8sQ0FBQztRQUNqQixDQUFDLEdBQ0QsbUJBQUEsRUFBRSxFQUFrQixDQUNyQixDQUFDO0lBQ0osQ0FBQztDQUNGOzs7Ozs7SUE3SEMsZ0NBQTBCOzs7OztJQUMxQixpQ0FBMkM7Ozs7O0lBQzNDLHdDQUFtQzs7Ozs7SUFDbkMsa0NBQXVCOzs7OztJQUN2QixrQ0FBK0I7O0lBRS9CLG9DQUF1Rjs7SUFDdkYsa0NBQW9DOzs7OztJQUV4QixpQ0FBK0I7Ozs7O0lBQUUsa0NBQXdDOzs7OztJQUFFLHFDQUF1QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFraXRhUGx1Z2luLCBRdWVyaWVzIH0gZnJvbSAnLi4vcGx1Z2luJztcbmltcG9ydCB7IFF1ZXJ5RW50aXR5IH0gZnJvbSAnLi4vLi4vcXVlcnlFbnRpdHknO1xuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0LCBjb21iaW5lTGF0ZXN0LCBPYnNlcnZhYmxlLCBTdWJqZWN0LCBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IGRpc3RpbmN0VW50aWxDaGFuZ2VkLCBtYXAsIHNraXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBpc1VuZGVmaW5lZCB9IGZyb20gJy4uLy4uL2lzVW5kZWZpbmVkJztcbmltcG9ydCB7IFF1ZXJ5IH0gZnJvbSAnLi4vLi4vcXVlcnknO1xuaW1wb3J0IHsgY29lcmNlQXJyYXkgfSBmcm9tICcuLi8uLi9jb2VyY2VBcnJheSc7XG5pbXBvcnQgeyBpc0Z1bmN0aW9uIH0gZnJvbSAnLi4vLi4vaXNGdW5jdGlvbic7XG5pbXBvcnQgeyBsb2dBY3Rpb24gfSBmcm9tICcuLi8uLi9hY3Rpb25zJztcblxudHlwZSBIZWFkPFN0YXRlID0gYW55PiA9IFN0YXRlIHwgUGFydGlhbDxTdGF0ZT47XG5cbmV4cG9ydCB0eXBlIERpcnR5Q2hlY2tDb21wYXJhdG9yPFN0YXRlPiA9IChoZWFkOiBTdGF0ZSwgY3VycmVudDogU3RhdGUpID0+IGJvb2xlYW47XG5cbmV4cG9ydCB0eXBlIERpcnR5Q2hlY2tQYXJhbXM8U3RvcmVTdGF0ZSA9IGFueT4gPSB7XG4gIGNvbXBhcmF0b3I/OiBEaXJ0eUNoZWNrQ29tcGFyYXRvcjxTdG9yZVN0YXRlPjtcbiAgd2F0Y2hQcm9wZXJ0eT86IGtleW9mIFN0b3JlU3RhdGUgfCAoa2V5b2YgU3RvcmVTdGF0ZSlbXTtcbn07XG5cbmV4cG9ydCBjb25zdCBkaXJ0eUNoZWNrRGVmYXVsdFBhcmFtcyA9IHtcbiAgY29tcGFyYXRvcjogKGhlYWQsIGN1cnJlbnQpID0+IEpTT04uc3RyaW5naWZ5KGhlYWQpICE9PSBKU09OLnN0cmluZ2lmeShjdXJyZW50KVxufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldE5lc3RlZFBhdGgobmVzdGVkT2JqLCBwYXRoOiBzdHJpbmcpIHtcbiAgY29uc3QgcGF0aEFzQXJyYXk6IHN0cmluZ1tdID0gcGF0aC5zcGxpdCgnLicpO1xuICByZXR1cm4gcGF0aEFzQXJyYXkucmVkdWNlKChvYmosIGtleSkgPT4gKG9iaiAmJiBvYmpba2V5XSAhPT0gJ3VuZGVmaW5lZCcgPyBvYmpba2V5XSA6IHVuZGVmaW5lZCksIG5lc3RlZE9iaik7XG59XG5cbmV4cG9ydCB0eXBlIERpcnR5Q2hlY2tSZXNldFBhcmFtczxTdG9yZVN0YXRlID0gYW55PiA9IHtcbiAgdXBkYXRlRm4/OiBTdG9yZVN0YXRlIHwgKChoZWFkOiBTdG9yZVN0YXRlLCBjdXJyZW50OiBTdG9yZVN0YXRlKSA9PiBhbnkpO1xufTtcblxuZXhwb3J0IGNsYXNzIERpcnR5Q2hlY2tQbHVnaW48U3RhdGUgPSBhbnk+IGV4dGVuZHMgQWtpdGFQbHVnaW48U3RhdGU+IHtcbiAgcHJpdmF0ZSBoZWFkOiBIZWFkPFN0YXRlPjtcbiAgcHJpdmF0ZSBkaXJ0eSA9IG5ldyBCZWhhdmlvclN1YmplY3QoZmFsc2UpO1xuICBwcml2YXRlIHN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uO1xuICBwcml2YXRlIGFjdGl2ZSA9IGZhbHNlO1xuICBwcml2YXRlIF9yZXNldCA9IG5ldyBTdWJqZWN0KCk7XG5cbiAgaXNEaXJ0eSQ6IE9ic2VydmFibGU8Ym9vbGVhbj4gPSB0aGlzLmRpcnR5LmFzT2JzZXJ2YWJsZSgpLnBpcGUoZGlzdGluY3RVbnRpbENoYW5nZWQoKSk7XG4gIHJlc2V0JCA9IHRoaXMuX3Jlc2V0LmFzT2JzZXJ2YWJsZSgpO1xuXG4gIGNvbnN0cnVjdG9yKHByb3RlY3RlZCBxdWVyeTogUXVlcmllczxTdGF0ZT4sIHByaXZhdGUgcGFyYW1zPzogRGlydHlDaGVja1BhcmFtczxTdGF0ZT4sIHByaXZhdGUgX2VudGl0eUlkPzogYW55KSB7XG4gICAgc3VwZXIocXVlcnkpO1xuICAgIHRoaXMucGFyYW1zID0geyAuLi5kaXJ0eUNoZWNrRGVmYXVsdFBhcmFtcywgLi4ucGFyYW1zIH07XG4gICAgaWYgKHRoaXMucGFyYW1zLndhdGNoUHJvcGVydHkpIHtcbiAgICAgIGxldCB3YXRjaFByb3AgPSBjb2VyY2VBcnJheSh0aGlzLnBhcmFtcy53YXRjaFByb3BlcnR5KSBhcyBhbnlbXTtcbiAgICAgIGlmIChxdWVyeSBpbnN0YW5jZW9mIFF1ZXJ5RW50aXR5ICYmIHdhdGNoUHJvcC5pbmNsdWRlcygnZW50aXRpZXMnKSAmJiAhd2F0Y2hQcm9wLmluY2x1ZGVzKCdpZHMnKSkge1xuICAgICAgICB3YXRjaFByb3AucHVzaCgnaWRzJyk7XG4gICAgICB9XG4gICAgICB0aGlzLnBhcmFtcy53YXRjaFByb3BlcnR5ID0gd2F0Y2hQcm9wO1xuICAgIH1cbiAgfVxuXG4gIHJlc2V0KHBhcmFtczogRGlydHlDaGVja1Jlc2V0UGFyYW1zID0ge30pIHtcbiAgICBsZXQgY3VycmVudFZhbHVlID0gdGhpcy5oZWFkO1xuICAgIGlmIChpc0Z1bmN0aW9uKHBhcmFtcy51cGRhdGVGbikpIHtcbiAgICAgIGlmICh0aGlzLmlzRW50aXR5QmFzZWQodGhpcy5fZW50aXR5SWQpKSB7XG4gICAgICAgIGN1cnJlbnRWYWx1ZSA9IHBhcmFtcy51cGRhdGVGbih0aGlzLmhlYWQsICh0aGlzLmdldFF1ZXJ5KCkgYXMgUXVlcnlFbnRpdHk8U3RhdGU+KS5nZXRFbnRpdHkodGhpcy5fZW50aXR5SWQpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGN1cnJlbnRWYWx1ZSA9IHBhcmFtcy51cGRhdGVGbih0aGlzLmhlYWQsICh0aGlzLmdldFF1ZXJ5KCkgYXMgUXVlcnk8U3RhdGU+KS5nZXRWYWx1ZSgpKTtcbiAgICAgIH1cbiAgICB9XG4gICAgbG9nQWN0aW9uKGBARGlydHlDaGVjayAtIFJldmVydGApO1xuICAgIHRoaXMudXBkYXRlU3RvcmUoY3VycmVudFZhbHVlLCB0aGlzLl9lbnRpdHlJZCk7XG4gICAgdGhpcy5fcmVzZXQubmV4dCgpO1xuICB9XG5cbiAgc2V0SGVhZCgpIHtcbiAgICBpZiAoIXRoaXMuYWN0aXZlKSB7XG4gICAgICB0aGlzLmFjdGl2YXRlKCk7XG4gICAgICB0aGlzLmFjdGl2ZSA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuaGVhZCA9IHRoaXMuX2dldEhlYWQoKTtcbiAgICB9XG4gICAgdGhpcy51cGRhdGVEaXJ0aW5lc3MoZmFsc2UpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgaXNEaXJ0eSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISF0aGlzLmRpcnR5LnZhbHVlO1xuICB9XG5cbiAgaGFzSGVhZCgpIHtcbiAgICByZXR1cm4gISF0aGlzLmdldEhlYWQoKTtcbiAgfVxuXG4gIGRlc3Ryb3koKSB7XG4gICAgdGhpcy5oZWFkID0gbnVsbDtcbiAgICB0aGlzLnN1YnNjcmlwdGlvbiAmJiB0aGlzLnN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMuX3Jlc2V0ICYmIHRoaXMuX3Jlc2V0LmNvbXBsZXRlKCk7XG4gIH1cblxuICBpc1BhdGhEaXJ0eShwYXRoOiBzdHJpbmcpIHtcbiAgICBjb25zdCBoZWFkID0gdGhpcy5nZXRIZWFkKCk7XG4gICAgY29uc3QgY3VycmVudCA9ICh0aGlzLmdldFF1ZXJ5KCkgYXMgUXVlcnk8U3RhdGU+KS5nZXRWYWx1ZSgpO1xuICAgIGNvbnN0IGN1cnJlbnRQYXRoVmFsdWUgPSBnZXROZXN0ZWRQYXRoKGN1cnJlbnQsIHBhdGgpO1xuICAgIGNvbnN0IGhlYWRQYXRoVmFsdWUgPSBnZXROZXN0ZWRQYXRoKGhlYWQsIHBhdGgpO1xuXG4gICAgcmV0dXJuIHRoaXMucGFyYW1zLmNvbXBhcmF0b3IoY3VycmVudFBhdGhWYWx1ZSwgaGVhZFBhdGhWYWx1ZSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0SGVhZCgpIHtcbiAgICByZXR1cm4gdGhpcy5oZWFkO1xuICB9XG5cbiAgcHJpdmF0ZSBhY3RpdmF0ZSgpIHtcbiAgICB0aGlzLmhlYWQgPSB0aGlzLl9nZXRIZWFkKCk7XG4gICAgLyoqIGlmIHdlIGFyZSB0cmFja2luZyBzcGVjaWZpYyBwcm9wZXJ0aWVzIHNlbGVjdCBvbmx5IHRoZSByZWxldmFudCBvbmVzICovXG4gICAgY29uc3Qgc291cmNlID0gdGhpcy5wYXJhbXMud2F0Y2hQcm9wZXJ0eVxuICAgICAgPyAodGhpcy5wYXJhbXMud2F0Y2hQcm9wZXJ0eSBhcyAoa2V5b2YgU3RhdGUpW10pLm1hcChwcm9wID0+XG4gICAgICAgICAgdGhpcy5xdWVyeVxuICAgICAgICAgICAgLnNlbGVjdChzdGF0ZSA9PiBzdGF0ZVtwcm9wXSlcbiAgICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgICBtYXAodmFsID0+ICh7XG4gICAgICAgICAgICAgICAgdmFsLFxuICAgICAgICAgICAgICAgIF9fYWtpdGFLZXk6IHByb3BcbiAgICAgICAgICAgICAgfSkpXG4gICAgICAgICAgICApXG4gICAgICAgIClcbiAgICAgIDogW3RoaXMuc2VsZWN0U291cmNlKHRoaXMuX2VudGl0eUlkKV07XG4gICAgdGhpcy5zdWJzY3JpcHRpb24gPSBjb21iaW5lTGF0ZXN0KC4uLnNvdXJjZSlcbiAgICAgIC5waXBlKHNraXAoMSkpXG4gICAgICAuc3Vic2NyaWJlKChjdXJyZW50U3RhdGU6IGFueVtdKSA9PiB7XG4gICAgICAgIGlmIChpc1VuZGVmaW5lZCh0aGlzLmhlYWQpKSByZXR1cm47XG4gICAgICAgIC8qKiBfX2FraXRhS2V5IGlzIHVzZWQgdG8gZGV0ZXJtaW5lIGlmIHdlIGFyZSB0cmFja2luZyBhIHNwZWNpZmljIHByb3BlcnR5IG9yIGEgc3RvcmUgY2hhbmdlICovXG4gICAgICAgIGNvbnN0IGlzQ2hhbmdlID0gY3VycmVudFN0YXRlLnNvbWUoc3RhdGUgPT4ge1xuICAgICAgICAgIGNvbnN0IGhlYWQgPSBzdGF0ZS5fX2FraXRhS2V5ID8gdGhpcy5oZWFkW3N0YXRlLl9fYWtpdGFLZXkgYXMgYW55XSA6IHRoaXMuaGVhZDtcbiAgICAgICAgICBjb25zdCBjb21wYXJlVG8gPSBzdGF0ZS5fX2FraXRhS2V5ID8gc3RhdGUudmFsIDogc3RhdGU7XG5cbiAgICAgICAgICByZXR1cm4gdGhpcy5wYXJhbXMuY29tcGFyYXRvcihoZWFkLCBjb21wYXJlVG8pO1xuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLnVwZGF0ZURpcnRpbmVzcyhpc0NoYW5nZSk7XG4gICAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlRGlydGluZXNzKGlzRGlydHk6IGJvb2xlYW4pIHtcbiAgICB0aGlzLmRpcnR5Lm5leHQoaXNEaXJ0eSk7XG4gIH1cblxuICBwcml2YXRlIF9nZXRIZWFkKCk6IEhlYWQ8U3RhdGU+IHtcbiAgICBsZXQgaGVhZDogSGVhZDxTdGF0ZT4gPSB0aGlzLmdldFNvdXJjZSh0aGlzLl9lbnRpdHlJZCk7XG4gICAgaWYgKHRoaXMucGFyYW1zLndhdGNoUHJvcGVydHkpIHtcbiAgICAgIGhlYWQgPSB0aGlzLmdldFdhdGNoZWRWYWx1ZXMoaGVhZCBhcyBTdGF0ZSk7XG4gICAgfVxuICAgIHJldHVybiBoZWFkO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRXYXRjaGVkVmFsdWVzKHNvdXJjZTogU3RhdGUpOiBQYXJ0aWFsPFN0YXRlPiB7XG4gICAgcmV0dXJuICh0aGlzLnBhcmFtcy53YXRjaFByb3BlcnR5IGFzIChrZXlvZiBTdGF0ZSlbXSkucmVkdWNlKFxuICAgICAgKHdhdGNoZWQsIHByb3ApID0+IHtcbiAgICAgICAgd2F0Y2hlZFtwcm9wXSA9IHNvdXJjZVtwcm9wXTtcbiAgICAgICAgcmV0dXJuIHdhdGNoZWQ7XG4gICAgICB9LFxuICAgICAge30gYXMgUGFydGlhbDxTdGF0ZT5cbiAgICApO1xuICB9XG59XG4iXX0=