UNPKG

@activejs/core

Version:

Pragmatic, Reactive State Management for JavaScript Apps

258 lines 32 kB
import { Configuration } from './configuration'; import { NonPrimitiveUnitBase } from './abstract-non-primitive-unit-base'; import { isDict, isObject, isValidKey, IteratorSymbol, makeNonEnumerable } from '../utils/funcs'; import { EventDictUnitAssign, EventDictUnitDelete, EventDictUnitSet, } from '../models'; /** * DictUnit is a reactive storage Unit that is loosely based on `Map`. * * It only accepts plain dictionary `object` as its value. * It ensures that at any point of time the value would always be a dictionary `object`. * * Learn more about Units [here](https://docs.activejs.dev/fundamentals/units). \ * Learn more about DictUnit [here](https://docs.activejs.dev/fundamentals/units/dictunit). * * Just like every other Non-Primitive ActiveJS Unit: * - DictUnit extends {@link NonPrimitiveUnitBase} * - Which further extends {@link UnitBase}, {@link Base} and `Observable` * * @category 1. Units */ export class DictUnit extends NonPrimitiveUnitBase { constructor(config) { super(Object.assign(Object.assign({}, Configuration.DICT_UNIT), config)); makeNonEnumerable(this); } /** * The length of keys of the properties in the dictionary {@link value}. */ get length() { return this.objectKeys().length; } /** * Indicates whether the length of the keys of the properties in the dictionary {@link value} is 0 or not. */ get isEmpty() { return this.length === 0; } /** * @internal please do not use. */ defaultValue() { return {}; } /** * Extends {@link UnitBase.wouldDispatch} and adds additional check for Object dictionary {@link isDict}, * which cannot be bypassed even by using {@link force}. * * @param value The value to be dispatched. * @param force Whether dispatch-checks should be bypassed or not. * @returns A boolean indicating whether the param `value` would pass the dispatch-checks if dispatched. * * @category Common Units */ wouldDispatch(value, force) { return this.isValidValue(value) && super.wouldDispatch(value, force); } /** * Adds a property by setting given property-value on the given key in the dictionary {@link value}. \ * Also, dispatches it as new dictionary, without mutating the current {@link value}. * * It only works if the Unit is not frozen and the `key` is either `string` or `number`. * * @param key The name of the property. * @param value The property-value. * * @triggers {@link EventDictUnitSet} * @category Custom DictUnit */ set(key, value) { var _a; if (this.isFrozen || !isValidKey(key)) { return; } this.checkSerializabilityMaybe(value); const dictShallowCopy = Object.assign({}, this.rawValue()); dictShallowCopy[key] = this.deepCopyMaybe(value); this.updateValueAndCache(dictShallowCopy); if (((_a = this.eventsSubject) === null || _a === void 0 ? void 0 : _a.observers.length) && !this.isMuted) { this.eventsSubject.next(new EventDictUnitSet(key, value)); } } /** * Deletes properties with given keys from the dictionary value. See {@link value}. \ * Deletion is performed on a copy of the value, which is then dispatched, without mutating the current value. * * It only works if the Unit is not frozen, and the value is not empty, \ * and at least one of the passed keys exist in the value. * ie: at least 1 key value pair exists in the dictionary. * * @param keys The names of the properties to be removed. * @returns The removed properties or an empty `object-literal`. * * @triggers {@link EventDictUnitDelete} * @category Custom DictUnit */ delete(...keys) { var _a; keys = keys.filter(key => this.has(key)); if (this.isFrozen || this.isEmpty || !keys.length) { return {}; } const dictShallowCopy = Object.assign({}, this.rawValue()); const removedProps = {}; keys.forEach(key => { removedProps[key] = this.deepCopyMaybe(dictShallowCopy[key]); delete dictShallowCopy[key]; }); this.updateValueAndCache(dictShallowCopy); if (((_a = this.eventsSubject) === null || _a === void 0 ? void 0 : _a.observers.length) && !this.isMuted) { this.eventsSubject.next(new EventDictUnitDelete(removedProps)); } return removedProps; } /** * Deletes properties from the dictionary {@link value} where the predicate returns `true`. \ * Also, dispatches it as new dictionary, without mutating the current {@link value}. * * It only works if the Unit is not frozen, and * the predicate is a function, and the dictionary is not empty. * * @param predicate A callback function that gets called for every property in the dictionary * with the property-value and key as arguments. * @returns The removed properties, or an empty `object-literal`. * * @triggers {@link EventDictUnitDelete} * @category Custom DictUnit */ deleteIf(predicate) { var _a; if (this.isFrozen || typeof predicate !== 'function' || this.isEmpty) { return {}; } const dictShallowCopy = Object.assign({}, this.rawValue()); const removedProps = {}; Object.keys(dictShallowCopy).forEach((key, index) => { if (predicate(this.deepCopyMaybe(dictShallowCopy[key]), key, index)) { removedProps[key] = dictShallowCopy[key]; delete dictShallowCopy[key]; } }); this.updateValueAndCache(dictShallowCopy); if (((_a = this.eventsSubject) === null || _a === void 0 ? void 0 : _a.observers.length) && !this.isMuted) { this.eventsSubject.next(new EventDictUnitDelete(removedProps)); } return removedProps; } /** * Copy the values of all the enumerable own properties from one or more source objects to the dictionary. \ * Also, dispatches it as new dictionary, without mutating the current {@link value}. * * It only works if the Unit is not frozen, and at least 1 source is provided, and it is a non-null object. * eg: `array`, `object` * * @param sources The source objects from which to copy properties. * * @triggers {@link EventDictUnitAssign} * @category Custom DictUnit */ assign(...sources) { var _a; sources = sources.filter(isObject); if (this.isFrozen || !sources.length) { return; } this.checkSerializabilityMaybe(sources); const dictShallowCopy = Object.assign({}, this.rawValue()); const newProps = Object.assign({}, ...sources); this.updateValueAndCache(Object.assign(dictShallowCopy, this.deepCopyMaybe(newProps))); if (((_a = this.eventsSubject) === null || _a === void 0 ? void 0 : _a.observers.length) && !this.isMuted) { this.eventsSubject.next(new EventDictUnitAssign(sources, newProps)); } } /** * Returns the value of the property with the name equal to the given key in the dictionary {@link value}. * * It only returns own-properties, e.g.: key 'toString' would return `undefined`. * * @param key The name of the property. * * @category Custom DictUnit */ get(key) { return this.hasOwnProperty(key) ? this.deepCopyMaybe(this.rawValue()[key]) : undefined; } /** * Returns whether a property with the given key exists in the dictionary {@link value}. * * @param key The name of the property. * * @category Custom DictUnit */ has(key) { return this.hasOwnProperty(key); } /** * Finds direct properties of the dictionary that have a direct child property * that matches with `key` and `value` passed as params. * * @example * ```ts * const initialValue = {'first': {b: 1}, 'second': {b: 1, b2: 2}, 'third': {c: 1}, 'fourth': {b: null}}; * const dict = new DictUnit({initialValue}); * const itemsFound = dict.findByProp('b', 1); * console.log(itemsFound); // logs [['first', {b: 1}], ['second', {b: 1, b2: 2}]] * ``` * * @param key The key of the property whose value needs to be matched against param `value`. * @param value A primitive value that will be matched against every item's prop-value using equality operator. * @param strictEquality A flag governing whether the value be matched using `===` or `==` operator. * Default is `true`, ie: strict equality `===`. Pass `false` to use `==` instead. * @returns An `array` of key/values of the matched properties, an empty `array` otherwise. * * @category Custom DictUnit */ findByProp(key, value, strictEquality = true) { if (this.isEmpty) { return []; } return this.deepCopyMaybe(Object.entries(this.rawValue()).filter(([propKey, prop]) => isObject(prop) && (strictEquality === false ? // tslint:disable-next-line:triple-equals prop[key] == value : prop[key] === value))); } /** * Performs the specified action for each property in the object value. See {@link value}. \ * It's a drop-in replacement for the `forEach` method. * * @param callbackFn A function that accepts up to two arguments. * forEvery calls the callbackFn function one time for each property in the object value. * @param thisArg An object to which this keyword can refer in the callbackFn function. * If thisArg is omitted, undefined is used as this value. * * @category Custom DictUnit */ forEvery(callbackFn, thisArg) { this.objectEntries().forEach(([key, value], i, valueEntries) => callbackFn.call(thisArg, value, key, i, valueEntries)); } /** * @internal please do not use. */ [IteratorSymbol]() { let index = 0; const items = this.objectEntries(); const length = items.length; return { next() { return { value: items[index++], done: index > length }; }, }; } /** * @internal please do not use. */ isValidValue(value) { return isDict(value); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGljdC11bml0LmpzIiwic291cmNlUm9vdCI6Ii9ob21lL3J1bm5lci93b3JrL2FjdGl2ZWpzL2FjdGl2ZWpzL3BhY2thZ2VzL2NvcmUvc3JjLyIsInNvdXJjZXMiOlsibGliL2RpY3QtdW5pdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUMsYUFBYSxFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFFOUMsT0FBTyxFQUFDLG9CQUFvQixFQUFDLE1BQU0sb0NBQW9DLENBQUM7QUFDeEUsT0FBTyxFQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUUsVUFBVSxFQUFFLGNBQWMsRUFBRSxpQkFBaUIsRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBQy9GLE9BQU8sRUFHTCxtQkFBbUIsRUFDbkIsbUJBQW1CLEVBQ25CLGdCQUFnQixHQUdqQixNQUFNLFdBQVcsQ0FBQztBQUVuQjs7Ozs7Ozs7Ozs7Ozs7R0FjRztBQUNILE1BQU0sT0FBTyxRQUlYLFNBQVEsb0JBQXVCO0lBK0IvQixZQUFZLE1BQXNCO1FBQ2hDLEtBQUssaUNBQ0MsYUFBYSxDQUFDLFNBQTJCLEdBQzFDLE1BQU0sRUFDVCxDQUFDO1FBRUgsaUJBQWlCLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDMUIsQ0FBQztJQTVCRDs7T0FFRztJQUNILElBQUksTUFBTTtRQUNSLE9BQU8sSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLE1BQU0sQ0FBQztJQUNsQyxDQUFDO0lBRUQ7O09BRUc7SUFDSCxJQUFJLE9BQU87UUFDVCxPQUFPLElBQUksQ0FBQyxNQUFNLEtBQUssQ0FBQyxDQUFDO0lBQzNCLENBQUM7SUFFRDs7T0FFRztJQUNPLFlBQVk7UUFDcEIsT0FBTyxFQUFPLENBQUM7SUFDakIsQ0FBQztJQVdEOzs7Ozs7Ozs7T0FTRztJQUNILGFBQWEsQ0FBQyxLQUFRLEVBQUUsS0FBZTtRQUNyQyxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLElBQUksS0FBSyxDQUFDLGFBQWEsQ0FBQyxL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QUssRUFBRSxHQUFHLEVBQUUsQ0FBQyxFQUFFLFlBQVksQ0FBQyxDQUN0RCxDQUFDO0lBQ0osQ0FBQztJQUlEOztPQUVHO0lBQ0gsQ0FBQyxjQUFjLENBQUM7UUFDZCxJQUFJLEtBQUssR0FBRyxDQUFDLENBQUM7UUFDZCxNQUFNLEtBQUssR0FBa0IsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ2xELE1BQU0sTUFBTSxHQUFXLEtBQUssQ0FBQyxNQUFNLENBQUM7UUFFcEMsT0FBTztZQUNMLElBQUk7Z0JBQ0YsT0FBTyxFQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsS0FBSyxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsS0FBSyxHQUFHLE1BQU0sRUFBQyxDQUFDO1lBQ3ZELENBQUM7U0FDRixDQUFDO0lBQ0osQ0FBQztJQUVEOztPQUVHO0lBQ08sWUFBWSxDQUFDLEtBQVU7UUFDL0IsT0FBTyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDdkIsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtPYnNlcnZhYmxlLCBTdWJqZWN0fSBmcm9tICdyeGpzJztcbmltcG9ydCB7Q29uZmlndXJhdGlvbn0gZnJvbSAnLi9jb25maWd1cmF0aW9uJztcbmltcG9ydCB7VW5pdEJhc2V9IGZyb20gJy4vYWJzdHJhY3QtdW5pdC1iYXNlJztcbmltcG9ydCB7Tm9uUHJpbWl0aXZlVW5pdEJhc2V9IGZyb20gJy4vYWJzdHJhY3Qtbm9uLXByaW1pdGl2ZS11bml0LWJhc2UnO1xuaW1wb3J0IHtpc0RpY3QsIGlzT2JqZWN0LCBpc1ZhbGlkS2V5LCBJdGVyYXRvclN5bWJvbCwgbWFrZU5vbkVudW1lcmFibGV9IGZyb20gJy4uL3V0aWxzL2Z1bmNzJztcbmltcG9ydCB7XG4gIERpY3RVbml0RXZlbnRzLFxuICBEaWN0VmFsdWUsXG4gIEV2ZW50RGljdFVuaXRBc3NpZ24sXG4gIEV2ZW50RGljdFVuaXREZWxldGUsXG4gIEV2ZW50RGljdFVuaXRTZXQsXG4gIEtPZixcbiAgVW5pdENvbmZpZyxcbn0gZnJvbSAnLi4vbW9kZWxzJztcblxuLyoqXG4gKiBEaWN0VW5pdCBpcyBhIHJlYWN0aXZlIHN0b3JhZ2UgVW5pdCB0aGF0IGlzIGxvb3NlbHkgYmFzZWQgb24gYE1hcGAuXG4gKlxuICogSXQgb25seSBhY2NlcHRzIHBsYWluIGRpY3Rpb25hcnkgYG9iamVjdGAgYXMgaXRzIHZhbHVlLlxuICogSXQgZW5zdXJlcyB0aGF0IGF0IGFueSBwb2ludCBvZiB0aW1lIHRoZSB2YWx1ZSB3b3VsZCBhbHdheXMgYmUgYSBkaWN0aW9uYXJ5IGBvYmplY3RgLlxuICpcbiAqIExlYXJuIG1vcmUgYWJvdXQgVW5pdHMgW2hlcmVdKGh0dHBzOi8vZG9jcy5hY3RpdmVqcy5kZXYvZnVuZGFtZW50YWxzL3VuaXRzKS4gXFxcbiAqIExlYXJuIG1vcmUgYWJvdXQgRGljdFVuaXQgW2hlcmVdKGh0dHBzOi8vZG9jcy5hY3RpdmVqcy5kZXYvZnVuZGFtZW50YWxzL3VuaXRzL2RpY3R1bml0KS5cbiAqXG4gKiBKdXN0IGxpa2UgZXZlcnkgb3RoZXIgTm9uLVByaW1pdGl2ZSBBY3RpdmVKUyBVbml0OlxuICogLSBEaWN0VW5pdCBleHRlbmRzIHtAbGluayBOb25QcmltaXRpdmVVbml0QmFzZX1cbiAqIC0gV2hpY2ggZnVydGhlciBleHRlbmRzIHtAbGluayBVbml0QmFzZX0sIHtAbGluayBCYXNlfSBhbmQgYE9ic2VydmFibGVgXG4gKlxuICogQGNhdGVnb3J5IDEuIFVuaXRzXG4gKi9cbmV4cG9ydCBjbGFzcyBEaWN0VW5pdDxcbiAgVCBleHRlbmRzIERpY3RWYWx1ZTxUPixcbiAgSyBleHRlbmRzIGtleW9mIFQgPSBrZXlvZiBULFxuICBWIGV4dGVuZHMgVFtLXSA9IFRbS11cbj4gZXh0ZW5kcyBOb25QcmltaXRpdmVVbml0QmFzZTxUPiB7XG4gIC8qKlxuICAgKiBAaW50ZXJuYWwgcGxlYXNlIGRvIG5vdCB1c2UuXG4gICAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgZXZlbnRzU3ViamVjdDogU3ViamVjdDxEaWN0VW5pdEV2ZW50czxUPj47XG4gIC8qKlxuICAgKiBPbi1kZW1hbmQgb2JzZXJ2YWJsZSBldmVudHMuXG4gICAqL1xuICByZWFkb25seSBldmVudHMkOiBPYnNlcnZhYmxlPERpY3RVbml0RXZlbnRzPFQ+PjtcblxuICAvKipcbiAgICogVGhlIGxlbmd0aCBvZiBrZXlzIG9mIHRoZSBwcm9wZXJ0aWVzIGluIHRoZSBkaWN0aW9uYXJ5IHtAbGluayB2YWx1ZX0uXG4gICAqL1xuICBnZXQgbGVuZ3RoKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMub2JqZWN0S2V5cygpLmxlbmd0aDtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgbGVuZ3RoIG9mIHRoZSBrZXlzIG9mIHRoZSBwcm9wZXJ0aWVzIGluIHRoZSBkaWN0aW9uYXJ5IHtAbGluayB2YWx1ZX0gaXMgMCBvciBub3QuXG4gICAqL1xuICBnZXQgaXNFbXB0eSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5sZW5ndGggPT09IDA7XG4gIH1cblxuICAvKipcbiAgICogQGludGVybmFsIHBsZWFzZSBkbyBub3QgdXNlLlxuICAgKi9cbiAgcHJvdGVjdGVkIGRlZmF1bHRWYWx1ZSgpOiBUIHtcbiAgICByZXR1cm4ge30gYXMgVDtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKGNvbmZpZz86IFVuaXRDb25maWc8VD4pIHtcbiAgICBzdXBlcih7XG4gICAgICAuLi4oQ29uZmlndXJhdGlvbi5ESUNUX1VOSVQgYXMgVW5pdENvbmZpZzxUPiksXG4gICAgICAuLi5jb25maWcsXG4gICAgfSk7XG5cbiAgICBtYWtlTm9uRW51bWVyYWJsZSh0aGlzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeHRlbmRzIHtAbGluayBVbml0QmFzZS53b3VsZERpc3BhdGNofSBhbmQgYWRkcyBhZGRpdGlvbmFsIGNoZWNrIGZvciBPYmplY3QgZGljdGlvbmFyeSB7QGxpbmsgaXNEaWN0fSxcbiAgICogd2hpY2ggY2Fubm90IGJlIGJ5cGFzc2VkIGV2ZW4gYnkgdXNpbmcge0BsaW5rIGZvcmNlfS5cbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZSB0byBiZSBkaXNwYXRjaGVkLlxuICAgKiBAcGFyYW0gZm9yY2UgV2hldGhlciBkaXNwYXRjaC1jaGVja3Mgc2hvdWxkIGJlIGJ5cGFzc2VkIG9yIG5vdC5cbiAgICogQHJldHVybnMgQSBib29sZWFuIGluZGljYXRpbmcgd2hldGhlciB0aGUgcGFyYW0gYHZhbHVlYCB3b3VsZCBwYXNzIHRoZSBkaXNwYXRjaC1jaGVja3MgaWYgZGlzcGF0Y2hlZC5cbiAgICpcbiAgICogQGNhdGVnb3J5IENvbW1vbiBVbml0c1xuICAgKi9cbiAgd291bGREaXNwYXRjaCh2YWx1ZTogVCwgZm9yY2U/OiBib29sZWFuKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuaXNWYWxpZFZhbHVlKHZhbHVlKSAmJiBzdXBlci53b3VsZERpc3BhdGNoKHZhbHVlLCBmb3JjZSk7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIHByb3BlcnR5IGJ5IHNldHRpbmcgZ2l2ZW4gcHJvcGVydHktdmFsdWUgb24gdGhlIGdpdmVuIGtleSBpbiB0aGUgZGljdGlvbmFyeSB7QGxpbmsgdmFsdWV9LiBcXFxuICAgKiBBbHNvLCBkaXNwYXRjaGVzIGl0IGFzIG5ldyBkaWN0aW9uYXJ5LCB3aXRob3V0IG11dGF0aW5nIHRoZSBjdXJyZW50IHtAbGluayB2YWx1ZX0uXG4gICAqXG4gICAqIEl0IG9ubHkgd29ya3MgaWYgdGhlIFVuaXQgaXMgbm90IGZyb3plbiBhbmQgdGhlIGBrZXlgIGlzIGVpdGhlciBgc3RyaW5nYCBvciBgbnVtYmVyYC5cbiAgICpcbiAgICogQHBhcmFtIGtleSBUaGUgbmFtZSBvZiB0aGUgcHJvcGVydHkuXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgcHJvcGVydHktdmFsdWUuXG4gICAqXG4gICAqIEB0cmlnZ2VycyB7QGxpbmsgRXZlbnREaWN0VW5pdFNldH1cbiAgICogQGNhdGVnb3J5IEN1c3RvbSBEaWN0VW5pdFxuICAgKi9cbiAgc2V0PGsgZXh0ZW5kcyBLPihrZXk6IGssIHZhbHVlOiBUW2tdKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaXNGcm96ZW4gfHwgIWlzVmFsaWRLZXkoa2V5KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmNoZWNrU2VyaWFsaXphYmlsaXR5TWF5YmUodmFsdWUpO1xuXG4gICAgY29uc3QgZGljdFNoYWxsb3dDb3B5ID0gey4uLnRoaXMucmF3VmFsdWUoKX07XG4gICAgZGljdFNoYWxsb3dDb3B5W2tleV0gPSB0aGlzLmRlZXBDb3B5TWF5YmUodmFsdWUpO1xuICAgIHRoaXMudXBkYXRlVmFsdWVBbmRDYWNoZShkaWN0U2hhbGxvd0NvcHkpO1xuXG4gICAgaWYgKHRoaXMuZXZlbnRzU3ViamVjdD8ub2JzZXJ2ZXJzLmxlbmd0aCAmJiAhdGhpcy5pc011dGVkKSB7XG4gICAgICB0aGlzLmV2ZW50c1N1YmplY3QubmV4dChuZXcgRXZlbnREaWN0VW5pdFNldChrZXksIHZhbHVlKSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIERlbGV0ZXMgcHJvcGVydGllcyB3aXRoIGdpdmVuIGtleXMgZnJvbSB0aGUgZGljdGlvbmFyeSB2YWx1ZS4gU2VlIHtAbGluayB2YWx1ZX0uIFxcXG4gICAqIERlbGV0aW9uIGlzIHBlcmZvcm1lZCBvbiBhIGNvcHkgb2YgdGhlIHZhbHVlLCB3aGljaCBpcyB0aGVuIGRpc3BhdGNoZWQsIHdpdGhvdXQgbXV0YXRpbmcgdGhlIGN1cnJlbnQgdmFsdWUuXG4gICAqXG4gICAqIEl0IG9ubHkgd29ya3MgaWYgdGhlIFVuaXQgaXMgbm90IGZyb3plbiwgYW5kIHRoZSB2YWx1ZSBpcyBub3QgZW1wdHksIFxcXG4gICAqIGFuZCBhdCBsZWFzdCBvbmUgb2YgdGhlIHBhc3NlZCBrZXlzIGV4aXN0IGluIHRoZSB2YWx1ZS5cbiAgICogaWU6IGF0IGxlYXN0IDEga2V5IHZhbHVlIHBhaXIgZXhpc3RzIGluIHRoZSBkaWN0aW9uYXJ5LlxuICAgKlxuICAgKiBAcGFyYW0ga2V5cyBUaGUgbmFtZXMgb2YgdGhlIHByb3BlcnRpZXMgdG8gYmUgcmVtb3ZlZC5cbiAgICogQHJldHVybnMgVGhlIHJlbW92ZWQgcHJvcGVydGllcyBvciBhbiBlbXB0eSBgb2JqZWN0LWxpdGVyYWxgLlxuICAgKlxuICAgKiBAdHJpZ2dlcnMge0BsaW5rIEV2ZW50RGljdFVuaXREZWxldGV9XG4gICAqIEBjYXRlZ29yeSBDdXN0b20gRGljdFVuaXRcbiAgICovXG4gIGRlbGV0ZTxrIGV4dGVuZHMgSz4oLi4ua2V5czoga1tdKToge1trZXkgaW4ga106IFRba119IHtcbiAgICBrZXlzID0ga2V5cy5maWx0ZXIoa2V5ID0+IHRoaXMuaGFzKGtleSkpO1xuICAgIGlmICh0aGlzLmlzRnJvemVuIHx8IHRoaXMuaXNFbXB0eSB8fCAha2V5cy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiB7fSBhcyBhbnk7XG4gICAgfVxuXG4gICAgY29uc3QgZGljdFNoYWxsb3dDb3B5OiBUID0gey4uLnRoaXMucmF3VmFsdWUoKX07XG4gICAgY29uc3QgcmVtb3ZlZFByb3BzOiB7W2tleSBpbiBrXTogVFtrXX0gPSB7fSBhcyBhbnk7XG5cbiAgICBrZXlzLmZvckVhY2goa2V5ID0+IHtcbiAgICAgIHJlbW92ZWRQcm9wc1trZXldID0gdGhpcy5kZWVwQ29weU1heWJlKGRpY3RTaGFsbG93Q29weVtrZXldKTtcbiAgICAgIGRlbGV0ZSBkaWN0U2hhbGxvd0NvcHlba2V5XTtcbiAgICB9KTtcblxuICAgIHRoaXMudXBkYXRlVmFsdWVBbmRDYWNoZShkaWN0U2hhbGxvd0NvcHkpO1xuXG4gICAgaWYgKHRoaXMuZXZlbnRzU3ViamVjdD8ub2JzZXJ2ZXJzLmxlbmd0aCAmJiAhdGhpcy5pc011dGVkKSB7XG4gICAgICB0aGlzLmV2ZW50c1N1YmplY3QubmV4dChuZXcgRXZlbnREaWN0VW5pdERlbGV0ZShyZW1vdmVkUHJvcHMpKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlbW92ZWRQcm9wcztcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGVzIHByb3BlcnRpZXMgZnJvbSB0aGUgZGljdGlvbmFyeSB7QGxpbmsgdmFsdWV9IHdoZXJlIHRoZSBwcmVkaWNhdGUgcmV0dXJucyBgdHJ1ZWAuIFxcXG4gICAqIEFsc28sIGRpc3BhdGNoZXMgaXQgYXMgbmV3IGRpY3Rpb25hcnksIHdpdGhvdXQgbXV0YXRpbmcgdGhlIGN1cnJlbnQge0BsaW5rIHZhbHVlfS5cbiAgICpcbiAgICogSXQgb25seSB3b3JrcyBpZiB0aGUgVW5pdCBpcyBub3QgZnJvemVuLCBhbmRcbiAgICogdGhlIHByZWRpY2F0ZSBpcyBhIGZ1bmN0aW9uLCBhbmQgdGhlIGRpY3Rpb25hcnkgaXMgbm90IGVtcHR5LlxuICAgKlxuICAgKiBAcGFyYW0gcHJlZGljYXRlIEEgY2FsbGJhY2sgZnVuY3Rpb24gdGhhdCBnZXRzIGNhbGxlZCBmb3IgZXZlcnkgcHJvcGVydHkgaW4gdGhlIGRpY3Rpb25hcnlcbiAgICogd2l0aCB0aGUgcHJvcGVydHktdmFsdWUgYW5kIGtleSBhcyBhcmd1bWVudHMuXG4gICAqIEByZXR1cm5zIFRoZSByZW1vdmVkIHByb3BlcnRpZXMsIG9yIGFuIGVtcHR5IGBvYmplY3QtbGl0ZXJhbGAuXG4gICAqXG4gICAqIEB0cmlnZ2VycyB7QGxpbmsgRXZlbnREaWN0VW5pdERlbGV0ZX1cbiAgICogQGNhdGVnb3J5IEN1c3RvbSBEaWN0VW5pdFxuICAgKi9cbiAgZGVsZXRlSWYocHJlZGljYXRlOiAodmFsdWU6IFYsIGtleTogSywgaW5kZXg6IG51bWJlcikgPT4gYm9vbGVhbik6IFQge1xuICAgIGlmICh0aGlzLmlzRnJvemVuIHx8IHR5cGVvZiBwcmVkaWNhdGUgIT09ICdmdW5jdGlvbicgfHwgdGhpcy5pc0VtcHR5KSB7XG4gICAgICByZXR1cm4ge30gYXMgYW55O1xuICAgIH1cblxuICAgIGNvbnN0IGRpY3RTaGFsbG93Q29weSA9IHsuLi50aGlzLnJhd1ZhbHVlKCl9O1xuICAgIGNvbnN0IHJlbW92ZWRQcm9wczogVCA9IHt9IGFzIGFueTtcblxuICAgIChPYmplY3Qua2V5cyhkaWN0U2hhbGxvd0NvcHkpIGFzIEtbXSkuZm9yRWFjaCgoa2V5OiBLLCBpbmRleCkgPT4ge1xuICAgICAgaWYgKHByZWRpY2F0ZSh0aGlzLmRlZXBDb3B5TWF5YmUoZGljdFNoYWxsb3dDb3B5W2tleV0pLCBrZXksIGluZGV4KSkge1xuICAgICAgICByZW1vdmVkUHJvcHNba2V5XSA9IGRpY3RTaGFsbG93Q29weVtrZXldO1xuICAgICAgICBkZWxldGUgZGljdFNoYWxsb3dDb3B5W2tleV07XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICB0aGlzLnVwZGF0ZVZhbHVlQW5kQ2FjaGUoZGljdFNoYWxsb3dDb3B5KTtcblxuICAgIGlmICh0aGlzLmV2ZW50c1N1YmplY3Q/Lm9ic2VydmVycy5sZW5ndGggJiYgIXRoaXMuaXNNdXRlZCkge1xuICAgICAgdGhpcy5ldmVudHNTdWJqZWN0Lm5leHQobmV3IEV2ZW50RGljdFVuaXREZWxldGUocmVtb3ZlZFByb3BzKSk7XG4gICAgfVxuICAgIHJldHVybiByZW1vdmVkUHJvcHM7XG4gIH1cblxuICAvKipcbiAgICogQ29weSB0aGUgdmFsdWVzIG9mIGFsbCB0aGUgZW51bWVyYWJsZSBvd24gcHJvcGVydGllcyBmcm9tIG9uZSBvciBtb3JlIHNvdXJjZSBvYmplY3RzIHRvIHRoZSBkaWN0aW9uYXJ5LiBcXFxuICAgKiBBbHNvLCBkaXNwYXRjaGVzIGl0IGFzIG5ldyBkaWN0aW9uYXJ5LCB3aXRob3V0IG11dGF0aW5nIHRoZSBjdXJyZW50IHtAbGluayB2YWx1ZX0uXG4gICAqXG4gICAqIEl0IG9ubHkgd29ya3MgaWYgdGhlIFVuaXQgaXMgbm90IGZyb3plbiwgYW5kIGF0IGxlYXN0IDEgc291cmNlIGlzIHByb3ZpZGVkLCBhbmQgaXQgaXMgYSBub24tbnVsbCBvYmplY3QuXG4gICAqIGVnOiBgYXJyYXlgLCBgb2JqZWN0YFxuICAgKlxuICAgKiBAcGFyYW0gc291cmNlcyBUaGUgc291cmNlIG9iamVjdHMgZnJvbSB3aGljaCB0byBjb3B5IHByb3BlcnRpZXMuXG4gICAqXG4gICAqIEB0cmlnZ2VycyB7QGxpbmsgRXZlbnREaWN0VW5pdEFzc2lnbn1cbiAgICogQGNhdGVnb3J5IEN1c3RvbSBEaWN0VW5pdFxuICAgKi9cbiAgYXNzaWduKC4uLnNvdXJjZXM6IFRbXSk6IHZvaWQge1xuICAgIHNvdXJjZXMgPSBzb3VyY2VzLmZpbHRlcihpc09iamVjdCk7XG4gICAgaWYgKHRoaXMuaXNGcm96ZW4gfHwgIXNvdXJjZXMubGVuZ3RoKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuY2hlY2tTZXJpYWxpemFiaWxpdHlNYXliZShzb3VyY2VzKTtcblxuICAgIGNvbnN0IGRpY3RTaGFsbG93Q29weSA9IHsuLi50aGlzLnJhd1ZhbHVlKCl9O1xuICAgIGNvbnN0IG5ld1Byb3BzID0gT2JqZWN0LmFzc2lnbih7fSwgLi4uc291cmNlcyk7XG4gICAgdGhpcy51cGRhdGVWYWx1ZUFuZENhY2hlKE9iamVjdC5hc3NpZ24oZGljdFNoYWxsb3dDb3B5LCB0aGlzLmRlZXBDb3B5TWF5YmUobmV3UHJvcHMpKSk7XG5cbiAgICBpZiAodGhpcy5ldmVudHNTdWJqZWN0Py5vYnNlcnZlcnMubGVuZ3RoICYmICF0aGlzLmlzTXV0ZWQpIHtcbiAgICAgIHRoaXMuZXZlbnRzU3ViamVjdC5uZXh0KG5ldyBFdmVudERpY3RVbml0QXNzaWduKHNvdXJjZXMsIG5ld1Byb3BzKSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eSB3aXRoIHRoZSBuYW1lIGVxdWFsIHRvIHRoZSBnaXZlbiBrZXkgaW4gdGhlIGRpY3Rpb25hcnkge0BsaW5rIHZhbHVlfS5cbiAgICpcbiAgICogSXQgb25seSByZXR1cm5zIG93bi1wcm9wZXJ0aWVzLCBlLmcuOiBrZXkgJ3RvU3RyaW5nJyB3b3VsZCByZXR1cm4gYHVuZGVmaW5lZGAuXG4gICAqXG4gICAqIEBwYXJhbSBrZXkgVGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5LlxuICAgKlxuICAgKiBAY2F0ZWdvcnkgQ3VzdG9tIERpY3RVbml0XG4gICAqL1xuICBnZXQ8ayBleHRlbmRzIEs+KGtleTogayk6IFRba10gfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLmhhc093blByb3BlcnR5KGtleSkgPyB0aGlzLmRlZXBDb3B5TWF5YmUodGhpcy5yYXdWYWx1ZSgpW2tleV0pIDogdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgd2hldGhlciBhIHByb3BlcnR5IHdpdGggdGhlIGdpdmVuIGtleSBleGlzdHMgaW4gdGhlIGRpY3Rpb25hcnkge0BsaW5rIHZhbHVlfS5cbiAgICpcbiAgICogQHBhcmFtIGtleSBUaGUgbmFtZSBvZiB0aGUgcHJvcGVydHkuXG4gICAqXG4gICAqIEBjYXRlZ29yeSBDdXN0b20gRGljdFVuaXRcbiAgICovXG4gIGhhczxrIGV4dGVuZHMgSz4oa2V5OiBrKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuaGFzT3duUHJvcGVydHkoa2V5KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaW5kcyBkaXJlY3QgcHJvcGVydGllcyBvZiB0aGUgZGljdGlvbmFyeSB0aGF0IGhhdmUgYSBkaXJlY3QgY2hpbGQgcHJvcGVydHlcbiAgICogdGhhdCBtYXRjaGVzIHdpdGggYGtleWAgYW5kIGB2YWx1ZWAgcGFzc2VkIGFzIHBhcmFtcy5cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogYGBgdHNcbiAgICogY29uc3QgaW5pdGlhbFZhbHVlID0geydmaXJzdCc6IHtiOiAxfSwgJ3NlY29uZCc6IHtiOiAxLCBiMjogMn0sICd0aGlyZCc6IHtjOiAxfSwgJ2ZvdXJ0aCc6IHtiOiBudWxsfX07XG4gICAqIGNvbnN0IGRpY3QgPSBuZXcgRGljdFVuaXQoe2luaXRpYWxWYWx1ZX0pO1xuICAgKiBjb25zdCBpdGVtc0ZvdW5kID0gZGljdC5maW5kQnlQcm9wKCdiJywgMSk7XG4gICAqIGNvbnNvbGUubG9nKGl0ZW1zRm91bmQpOyAvLyBsb2dzIFtbJ2ZpcnN0Jywge2I6IDF9XSwgWydzZWNvbmQnLCB7YjogMSwgYjI6IDJ9XV1cbiAgICogYGBgXG4gICAqXG4gICAqIEBwYXJhbSBrZXkgVGhlIGtleSBvZiB0aGUgcHJvcGVydHkgd2hvc2UgdmFsdWUgbmVlZHMgdG8gYmUgbWF0Y2hlZCBhZ2FpbnN0IHBhcmFtIGB2YWx1ZWAuXG4gICAqIEBwYXJhbSB2YWx1ZSBBIHByaW1pdGl2ZSB2YWx1ZSB0aGF0IHdpbGwgYmUgbWF0Y2hlZCBhZ2FpbnN0IGV2ZXJ5IGl0ZW0ncyBwcm9wLXZhbHVlIHVzaW5nIGVxdWFsaXR5IG9wZXJhdG9yLlxuICAgKiBAcGFyYW0gc3RyaWN0RXF1YWxpdHkgQSBmbGFnIGdvdmVybmluZyB3aGV0aGVyIHRoZSB2YWx1ZSBiZSBtYXRjaGVkIHVzaW5nIGA9PT1gIG9yIGA9PWAgb3BlcmF0b3IuXG4gICAqIERlZmF1bHQgaXMgYHRydWVgLCBpZTogc3RyaWN0IGVxdWFsaXR5IGA9PT1gLiBQYXNzIGBmYWxzZWAgdG8gdXNlIGA9PWAgaW5zdGVhZC5cbiAgICogQHJldHVybnMgQW4gYGFycmF5YCBvZiBrZXkvdmFsdWVzIG9mIHRoZSBtYXRjaGVkIHByb3BlcnRpZXMsIGFuIGVtcHR5IGBhcnJheWAgb3RoZXJ3aXNlLlxuICAgKlxuICAgKiBAY2F0ZWdvcnkgQ3VzdG9tIERpY3RVbml0XG4gICAqL1xuICBmaW5kQnlQcm9wPGsgZXh0ZW5kcyBLT2Y8Vj4+KFxuICAgIGtleTogayxcbiAgICB2YWx1ZTogc3RyaW5nIHwgbnVtYmVyIHwgYm9vbGVhbixcbiAgICBzdHJpY3RFcXVhbGl0eSA9IHRydWVcbiAgKTogW0ssIFZdW10ge1xuICAgIGlmICh0aGlzLmlzRW1wdHkpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5kZWVwQ29weU1heWJlKFxuICAgICAgKE9iamVjdC5lbnRyaWVzPFY+KHRoaXMucmF3VmFsdWUoKSkgYXMgW0ssIFZdW10pLmZpbHRlcihcbiAgICAgICAgKFtwcm9wS2V5LCBwcm9wXSkgPT5cbiAgICAgICAgICBpc09iamVjdChwcm9wKSAmJlxuICAgICAgICAgIChzdHJpY3RFcXVhbGl0eSA9PT0gZmFsc2VcbiAgICAgICAgICAgID8gLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOnRyaXBsZS1lcXVhbHNcbiAgICAgICAgICAgICAgcHJvcFtrZXkgYXMgc3RyaW5nIHwgbnVtYmVyXSA9PSB2YWx1ZVxuICAgICAgICAgICAgOiBwcm9wW2tleSBhcyBzdHJpbmcgfCBudW1iZXJdID09PSB2YWx1ZSlcbiAgICAgIClcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFBlcmZvcm1zIHRoZSBzcGVjaWZpZWQgYWN0aW9uIGZvciBlYWNoIHByb3BlcnR5IGluIHRoZSBvYmplY3QgdmFsdWUuIFNlZSB7QGxpbmsgdmFsdWV9LiBcXFxuICAgKiBJdCdzIGEgZHJvcC1pbiByZXBsYWNlbWVudCBmb3IgdGhlIGBmb3JFYWNoYCBtZXRob2QuXG4gICAqXG4gICAqIEBwYXJhbSBjYWxsYmFja0ZuIEEgZnVuY3Rpb24gdGhhdCBhY2NlcHRzIHVwIHRvIHR3byBhcmd1bWVudHMuXG4gICAqIGZvckV2ZXJ5IGNhbGxzIHRoZSBjYWxsYmFja0ZuIGZ1bmN0aW9uIG9uZSB0aW1lIGZvciBlYWNoIHByb3BlcnR5IGluIHRoZSBvYmplY3QgdmFsdWUuXG4gICAqIEBwYXJhbSB0aGlzQXJnIEFuIG9iamVjdCB0byB3aGljaCB0aGlzIGtleXdvcmQgY2FuIHJlZmVyIGluIHRoZSBjYWxsYmFja0ZuIGZ1bmN0aW9uLlxuICAgKiBJZiB0aGlzQXJnIGlzIG9taXR0ZWQsIHVuZGVmaW5lZCBpcyB1c2VkIGFzIHRoaXMgdmFsdWUuXG4gICAqXG4gICAqIEBjYXRlZ29yeSBDdXN0b20gRGljdFVuaXRcbiAgICovXG4gIGZvckV2ZXJ5KFxuICAgIGNhbGxiYWNrRm46ICh2YWx1ZTogViwga2V5OiBLLCBpbmRleDogbnVtYmVyLCBlbnRyaWVzOiBbSywgVl1bXSkgPT4gdm9pZCxcbiAgICB0aGlzQXJnPzogYW55XG4gICk6IHZvaWQge1xuICAgIHRoaXMub2JqZWN0RW50cmllcygpLmZvckVhY2goKFtrZXksIHZhbHVlXSwgaSwgdmFsdWVFbnRyaWVzKSA9PlxuICAgICAgY2FsbGJhY2tGbi5jYWxsKHRoaXNBcmcsIHZhbHVlLCBrZXksIGksIHZhbHVlRW50cmllcylcbiAgICApO1xuICB9XG5cbiAgLyoqIEl0ZXJhdG9yICovXG4gIFtTeW1ib2wuaXRlcmF0b3JdKCk6IEl0ZXJhdG9yPFtzdHJpbmcsIFZdPjtcbiAgLyoqXG4gICAqIEBpbnRlcm5hbCBwbGVhc2UgZG8gbm90IHVzZS5cbiAgICovXG4gIFtJdGVyYXRvclN5bWJvbF0oKTogSXRlcmF0b3I8W3N0cmluZywgVl0+IHtcbiAgICBsZXQgaW5kZXggPSAwO1xuICAgIGNvbnN0IGl0ZW1zOiBbc3RyaW5nLCBWXVtdID0gdGhpcy5vYmplY3RFbnRyaWVzKCk7XG4gICAgY29uc3QgbGVuZ3RoOiBudW1iZXIgPSBpdGVtcy5sZW5ndGg7XG5cbiAgICByZXR1cm4ge1xuICAgICAgbmV4dCgpOiBJdGVyYXRvclJlc3VsdDxbc3RyaW5nLCBWXT4ge1xuICAgICAgICByZXR1cm4ge3ZhbHVlOiBpdGVtc1tpbmRleCsrXSwgZG9uZTogaW5kZXggPiBsZW5ndGh9O1xuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEBpbnRlcm5hbCBwbGVhc2UgZG8gbm90IHVzZS5cbiAgICovXG4gIHByb3RlY3RlZCBpc1ZhbGlkVmFsdWUodmFsdWU6IGFueSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBpc0RpY3QodmFsdWUpO1xuICB9XG59XG4iXX0=