UNPKG

foop

Version:

interfaces that describe their intentions.

245 lines (224 loc) 18.8 kB
var TraverseChain = require('../TraverseChain') var curry = require('../deps/fp/curry') var isObj = require('../deps/is/obj') var isTrue = require('../deps/is/true') var isFalsy = require('../deps/is/falsy') var isUndefined = require('../deps/is/undefined') var ObjectKeys = require('../deps/util/keys') var dotPropPaths = require('../deps/dot/paths') var TRANSFORMERS_KEY = require('../deps/meta/TRANSFORMERS_KEY') var OBSERVERS_KEY = require('../deps/meta/OBSERVERS_KEY') /** * @param {Class | Composable} Target composable class * @return {TransformChain} class * @example * compose(class {}) * //=> TransformChain */ module.exports = function (Target) { var set = Target.prototype.set /** * @class TransformChain * @member TransformChain * @extends {ChainedMap} * @memberOf compose * @category Chainable * * @tests TransformChain * @types TransformChain * * @symb 🤖 * @type {Map} * * @see deps/traverse * @see TraverseChain * * {@link https://github.com/iluwatar/java-design-patterns/tree/master/state state-pattern} * {@link https://github.com/iluwatar/java-design-patterns/tree/master/strategy strategy-pattern} */ // class Transform extends Target // ------------------------------------------- /** * @desc traverse `this`, or `this.entries` * @since 1.0.2 * * @param {boolean | traversable} [useThis=false] use the instance properties that are `mapish` as well * @return {TraverseChain} @chainable * * @see TraverseChain * @see js-traverse * * @example * TAKE FROM TRAVERSECHAIN */ Target.prototype.traverse = function traverseChain(useThis) { /* prettier-ignore */ return new TraverseChain(this) .obj( // @NOTE // defaultTo(false, useThis) // defaulting arg to false is shorter // & faster than void 0 inline checks // that mutate arguments (when transpiled) isFalsy(useThis) ? this.entries(true) : isTrue(useThis) ? this : useThis // isFalse(useThis) // ? this.entries(true) // : isTrue(useThis) // ? this // : useThis ) } /** * @since 1.0.2 * @memberOf TransformChain * * @param {string | Function} key currently just string * @param {Function} value callback accepting the value as only arg to transform with * @return {TransformChain} @chainable * * @TODO dot-prop here * * @example * * // coerce values with .id into the value they hold * chain * .transform('dis', val => (typeof val === 'string' ? val : val.id)) * * chain.set('dis', 'eh') * chain.get('dis') * //=> 'eh' * * chain.set('dis', {id: 'eh'}) * chain.get('dis') * //=> 'eh' * * * @example * * import {format} from 'date-fns/esm' * import {Chain} from 'chain-able' * * const chain = new Chain() * chain.transform('created_at', date => format(date, 'MM/DD/YYYY')) * chain.set('created_at', new Date()) * * // is formatted human-readable pretty! * const {created_at} = chain.entries() * //=> '02/11/2014' * */ Target.prototype.transform = function transform(key, value) { return this.meta(TRANSFORMERS_KEY, key, value) } /** * @memberOf TransformChain * * @override * @inheritdoc * @since 1.0.0 * * @TODO curry * * @param {Primitive} key key to set with * @param {any} val value to set for key * @param {undefined | string | Array<string>} dotPropKey special key used for initializing dot prop values in an optimized way to keep reference * @return {Chainable} @chainable * * @see this.observe, this.transform */ Target.prototype.set = function transformSet(key, val, dotPropKey) { var this$1 = this; var value = val // get var transformers = this.meta(TRANSFORMERS_KEY, key) for (var t = 0; t < transformers.length; t++) { value = transformers[t].call(this$1, value, this$1) } // super.set(key, value) set.call(this, key, value) // get var observers = this.meta(OBSERVERS_KEY) // @TODO !isEmpty // skip the below if we have no observers if (!observers.length) { return this } var data = {key: dotPropKey, value: value} if (isUndefined(dotPropKey)) { data.key = isObj(value) ? dotPropPaths(key, value) : key } for (var o = 0; o < observers.length; o++) { observers[o](data) } return this } // @TODO // // https://stackoverflow.com/questions/31158902/is-it-possible-to-sort-a-es6-map-object // ordered(comperator = null) { // // this.set = this.before(this.set) // this.set = (key, value) => { // // have to iterate over the keys before setting // // and then after merging in values, update // if (this.store.has(key)) { // // first // let keys = this.store.keys() // if (isFunction(comperator)) keys = keys.sort(comperator) // // // after // const store = this.store // this.store = new Map() // keys.forEach(keyInOrder => this.store.set(key, store.get(key))) // store.clear() // } // } // } // --- remap --- /** * @desc remap properties from 1 to another, for example, apis with inconsistent naming * @memberOf TransformChain * @since 1.0.0 * @symb 🗺 * * @param {string | Object} from property name string, or {[from]: to} * @param {string} [to=undefined] property name to change key to * @return {Chain} @chainable * * @see TransformChain.transform * @IDEA could also be a function, but then might as well use .transform * * @example * * chain * .remap('dis', 'dat') * .from({dis: true}) * * chain.entries() * //=> {dat: true} * * @example * * chain * .remap({dis: 'dat'}) * .from({dis: 1, other: true}} * * chain.entries() * //=> {dist: 1, other: true} * */ Target.prototype.remap = function chainRemap(from, to) { var this$1 = this; var remap = isObj(from) ? from : {[from]: to} /* prettier-ignore */ ObjectKeys(remap).forEach(function (key) { return this$1.transform(key, function (val) { this$1.set(remap[key], val) return val }); }) return this } return Target } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVHJhbnNmb3JtLmpzIiwic291cmNlcyI6WyJUcmFuc2Zvcm0uanMiXSwic291cmNlc0NvbnRlbnQiOlsiY29uc3QgVHJhdmVyc2VDaGFpbiA9IHJlcXVpcmUoJy4uL1RyYXZlcnNlQ2hhaW4nKVxuY29uc3QgY3VycnkgPSByZXF1aXJlKCcuLi9kZXBzL2ZwL2N1cnJ5JylcbmNvbnN0IGlzT2JqID0gcmVxdWlyZSgnLi4vZGVwcy9pcy9vYmonKVxuY29uc3QgaXNUcnVlID0gcmVxdWlyZSgnLi4vZGVwcy9pcy90cnVlJylcbmNvbnN0IGlzRmFsc3kgPSByZXF1aXJlKCcuLi9kZXBzL2lzL2ZhbHN5JylcbmNvbnN0IGlzVW5kZWZpbmVkID0gcmVxdWlyZSgnLi4vZGVwcy9pcy91bmRlZmluZWQnKVxuY29uc3QgT2JqZWN0S2V5cyA9IHJlcXVpcmUoJy4uL2RlcHMvdXRpbC9rZXlzJylcbmNvbnN0IGRvdFByb3BQYXRocyA9IHJlcXVpcmUoJy4uL2RlcHMvZG90L3BhdGhzJylcbmNvbnN0IFRSQU5TRk9STUVSU19LRVkgPSByZXF1aXJlKCcuLi9kZXBzL21ldGEvVFJBTlNGT1JNRVJTX0tFWScpXG5jb25zdCBPQlNFUlZFUlNfS0VZID0gcmVxdWlyZSgnLi4vZGVwcy9tZXRhL09CU0VSVkVSU19LRVknKVxuXG4vKipcbiAqIEBwYXJhbSB7Q2xhc3MgfCBDb21wb3NhYmxlfSBUYXJnZXQgY29tcG9zYWJsZSBjbGFzc1xuICogQHJldHVybiB7VHJhbnNmb3JtQ2hhaW59IGNsYXNzXG4gKiBAZXhhbXBsZVxuICogICAgY29tcG9zZShjbGFzcyB7fSlcbiAqICAgIC8vPT4gVHJhbnNmb3JtQ2hhaW5cbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBUYXJnZXQgPT4ge1xuICBjb25zdCBzZXQgPSBUYXJnZXQucHJvdG90eXBlLnNldFxuXG4gIC8qKlxuICAgKiBAY2xhc3MgVHJhbnNmb3JtQ2hhaW5cbiAgICogQG1lbWJlciBUcmFuc2Zvcm1DaGFpblxuICAgKiBAZXh0ZW5kcyB7Q2hhaW5lZE1hcH1cbiAgICogQG1lbWJlck9mIGNvbXBvc2VcbiAgICogQGNhdGVnb3J5IENoYWluYWJsZVxuICAgKlxuICAgKiBAdGVzdHMgVHJhbnNmb3JtQ2hhaW5cbiAgICogQHR5cGVzIFRyYW5zZm9ybUNoYWluXG4gICAqXG4gICAqIEBzeW1iIPCfpJZcbiAgICogQHR5cGUge01hcH1cbiAgICpcbiAgICogQHNlZSBkZXBzL3RyYXZlcnNlXG4gICAqIEBzZWUgVHJhdmVyc2VDaGFpblxuICAgKlxuICAgKiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL2lsdXdhdGFyL2phdmEtZGVzaWduLXBhdHRlcm5zL3RyZWUvbWFzdGVyL3N0YXRlIHN0YXRlLXBhdHRlcm59XG4gICAqIHtAbGluayBodHRwczovL2dpdGh1Yi5jb20vaWx1d2F0YXIvamF2YS1kZXNpZ24tcGF0dGVybnMvdHJlZS9tYXN0ZXIvc3RyYXRlZ3kgc3RyYXRlZ3ktcGF0dGVybn1cbiAgICovXG4gIC8vIGNsYXNzIFRyYW5zZm9ybSBleHRlbmRzIFRhcmdldFxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgLyoqXG4gICAqIEBkZXNjIHRyYXZlcnNlIGB0aGlzYCwgb3IgYHRoaXMuZW50cmllc2BcbiAgICogQHNpbmNlIDEuMC4yXG4gICAqXG4gICAqIEBwYXJhbSAge2Jvb2xlYW4gfCB0cmF2ZXJzYWJsZX0gW3VzZVRoaXM9ZmFsc2VdIHVzZSB0aGUgaW5zdGFuY2UgcHJvcGVydGllcyB0aGF0IGFyZSBgbWFwaXNoYCBhcyB3ZWxsXG4gICAqIEByZXR1cm4ge1RyYXZlcnNlQ2hhaW59IEBjaGFpbmFibGVcbiAgICpcbiAgICogQHNlZSBUcmF2ZXJzZUNoYWluXG4gICAqIEBzZWUganMtdHJhdmVyc2VcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogIFRBS0UgRlJPTSBUUkFWRVJTRUNIQUlOXG4gICAqL1xuICBUYXJnZXQucHJvdG90eXBlLnRyYXZlcnNlID0gZnVuY3Rpb24gdHJhdmVyc2VDaGFpbih1c2VUaGlzKSB7XG4gICAgLyogcHJldHRpZXItaWdub3JlICovXG4gICAgcmV0dXJuIG5ldyBUcmF2ZXJzZUNoYWluKHRoaXMpXG4gICAgICAub2JqKFxuICAgICAgICAvLyBATk9URVxuICAgICAgICAvLyBkZWZhdWx0VG8oZmFsc2UsIHVzZVRoaXMpXG4gICAgICAgIC8vICBkZWZhdWx0aW5nIGFyZyB0byBmYWxzZSBpcyBzaG9ydGVyXG4gICAgICAgIC8vICAmIGZhc3RlciB0aGFuIHZvaWQgMCBpbmxpbmUgY2hlY2tzXG4gICAgICAgIC8vICB0aGF0IG11dGF0ZSBhcmd1bWVudHMgKHdoZW4gdHJhbnNwaWxlZClcbiAgICAgICAgaXNGYWxzeSh1c2VUaGlzKVxuICAgICAgICAgID8gdGhpcy5lbnRyaWVzKHRydWUpXG4gICAgICAgICAgOiBpc1RydWUodXNlVGhpcylcbiAgICAgICAgICAgID8gdGhpc1xuICAgICAgICAgICAgOiB1c2VUaGlzXG5cbiAgICAgICAgLy8gaXNGYWxzZSh1c2VUaGlzKVxuICAgICAgICAvLyAgID8gdGhpcy5lbnRyaWVzKHRydWUpXG4gICAgICAgIC8vICAgOiBpc1RydWUodXNlVGhpcylcbiAgICAgICAgLy8gICAgID8gdGhpc1xuICAgICAgICAvLyAgICAgOiB1c2VUaGlzXG4gICAgICApXG4gIH1cblxuICAvKipcbiAgICogQHNpbmNlIDEuMC4yXG4gICAqIEBtZW1iZXJPZiBUcmFuc2Zvcm1DaGFpblxuICAgKlxuICAgKiBAcGFyYW0gIHtzdHJpbmcgfCBGdW5jdGlvbn0ga2V5IGN1cnJlbnRseSBqdXN0IHN0cmluZ1xuICAgKiBAcGFyYW0gIHtGdW5jdGlvbn0gdmFsdWUgY2FsbGJhY2sgYWNjZXB0aW5nIHRoZSB2YWx1ZSBhcyBvbmx5IGFyZyB0byB0cmFuc2Zvcm0gd2l0aFxuICAgKiBAcmV0dXJuIHtUcmFuc2Zvcm1DaGFpbn0gQGNoYWluYWJsZVxuICAgKlxuICAgKiBAVE9ETyBkb3QtcHJvcCBoZXJlXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqXG4gICAqICAgLy8gY29lcmNlIHZhbHVlcyB3aXRoIC5pZCBpbnRvIHRoZSB2YWx1ZSB0aGV5IGhvbGRcbiAgICogICBjaGFpblxuICAgKiAgICAgLnRyYW5zZm9ybSgnZGlzJywgdmFsID0+ICh0eXBlb2YgdmFsID09PSAnc3RyaW5nJyA/IHZhbCA6IHZhbC5pZCkpXG4gICAqXG4gICAqICAgY2hhaW4uc2V0KCdkaXMnLCAnZWgnKVxuICAgKiAgIGNoYWluLmdldCgnZGlzJylcbiAgICogICAvLz0+ICdlaCdcbiAgICpcbiAgICogICBjaGFpbi5zZXQoJ2RpcycsIHtpZDogJ2VoJ30pXG4gICAqICAgY2hhaW4uZ2V0KCdkaXMnKVxuICAgKiAgIC8vPT4gJ2VoJ1xuICAgKlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKlxuICAgKiAgICBpbXBvcnQge2Zvcm1hdH0gZnJvbSAnZGF0ZS1mbnMvZXNtJ1xuICAgKiAgICBpbXBvcnQge0NoYWlufSBmcm9tICdjaGFpbi1hYmxlJ1xuICAgKlxuICAgKiAgICBjb25zdCBjaGFpbiA9IG5ldyBDaGFpbigpXG4gICAqICAgIGNoYWluLnRyYW5zZm9ybSgnY3JlYXRlZF9hdCcsIGRhdGUgPT4gZm9ybWF0KGRhdGUsICdNTS9ERC9ZWVlZJykpXG4gICAqICAgIGNoYWluLnNldCgnY3JlYXRlZF9hdCcsIG5ldyBEYXRlKCkpXG4gICAqXG4gICAqICAgIC8vIGlzIGZvcm1hdHRlZCBodW1hbi1yZWFkYWJsZSBwcmV0dHkhXG4gICAqICAgIGNvbnN0IHtjcmVhdGVkX2F0fSA9IGNoYWluLmVudHJpZXMoKVxuICAgKiAgICAvLz0+ICcwMi8xMS8yMDE0J1xuICAgKlxuICAgKi9cbiAgVGFyZ2V0LnByb3RvdHlwZS50cmFuc2Zvcm0gPSBmdW5jdGlvbiB0cmFuc2Zvcm0oa2V5LCB2YWx1ZSkge1xuICAgIHJldHVybiB0aGlzLm1ldGEoVFJBTlNGT1JNRVJTX0tFWSwga2V5LCB2YWx1ZSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAbWVtYmVyT2YgVHJhbnNmb3JtQ2hhaW5cbiAgICpcbiAgICogQG92ZXJyaWRlXG4gICAqIEBpbmhlcml0ZG9jXG4gICAqIEBzaW5jZSAxLjAuMFxuICAgKlxuICAgKiBAVE9ETyBjdXJyeVxuICAgKlxuICAgKiBAcGFyYW0ge1ByaW1pdGl2ZX0ga2V5IGtleSB0byBzZXQgd2l0aFxuICAgKiBAcGFyYW0ge2FueX0gdmFsIHZhbHVlIHRvIHNldCBmb3Iga2V5XG4gICAqIEBwYXJhbSB7dW5kZWZpbmVkIHwgc3RyaW5nIHwgQXJyYXk8c3RyaW5nPn0gZG90UHJvcEtleSBzcGVjaWFsIGtleSB1c2VkIGZvciBpbml0aWFsaXppbmcgZG90IHByb3AgdmFsdWVzIGluIGFuIG9wdGltaXplZCB3YXkgdG8ga2VlcCByZWZlcmVuY2VcbiAgICogQHJldHVybiB7Q2hhaW5hYmxlfSBAY2hhaW5hYmxlXG4gICAqXG4gICAqIEBzZWUgdGhpcy5vYnNlcnZlLCB0aGlzLnRyYW5zZm9ybVxuICAgKi9cbiAgVGFyZ2V0LnByb3RvdHlwZS5zZXQgPSBmdW5jdGlvbiB0cmFuc2Zvcm1TZXQoa2V5LCB2YWwsIGRvdFByb3BLZXkpIHtcbiAgICBsZXQgdmFsdWUgPSB2YWxcblxuICAgIC8vIGdldFxuICAgIGNvbnN0IHRyYW5zZm9ybWVycyA9IHRoaXMubWV0YShUUkFOU0ZPUk1FUlNfS0VZLCBrZXkpXG4gICAgZm9yIChsZXQgdCA9IDA7IHQgPCB0cmFuc2Zvcm1lcnMubGVuZ3RoOyB0KyspIHtcbiAgICAgIHZhbHVlID0gdHJhbnNmb3JtZXJzW3RdLmNhbGwodGhpcywgdmFsdWUsIHRoaXMpXG4gICAgfVxuXG4gICAgLy8gc3VwZXIuc2V0KGtleSwgdmFsdWUpXG4gICAgc2V0LmNhbGwodGhpcywga2V5LCB2YWx1ZSlcblxuICAgIC8vIGdldFxuICAgIGNvbnN0IG9ic2VydmVycyA9IHRoaXMubWV0YShPQlNFUlZFUlNfS0VZKVxuXG4gICAgLy8gQFRPRE8gIWlzRW1wdHlcbiAgICAvLyBza2lwIHRoZSBiZWxvdyBpZiB3ZSBoYXZlIG5vIG9ic2VydmVyc1xuICAgIGlmICghb2JzZXJ2ZXJzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG5cbiAgICBjb25zdCBkYXRhID0ge2tleTogZG90UHJvcEtleSwgdmFsdWV9XG4gICAgaWYgKGlzVW5kZWZpbmVkKGRvdFByb3BLZXkpKSB7XG4gICAgICBkYXRhLmtleSA9IGlzT2JqKHZhbHVlKSA/IGRvdFByb3BQYXRocyhrZXksIHZhbHVlKSA6IGtleVxuICAgIH1cblxuICAgIGZvciAobGV0IG8gPSAwOyBvIDwgb2JzZXJ2ZXJzLmxlbmd0aDsgbysrKSB7XG4gICAgICBvYnNlcnZlcnNbb10oZGF0YSlcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpc1xuICB9XG5cbiAgLy8gQFRPRE9cbiAgLy8gLy8gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMzExNTg5MDIvaXMtaXQtcG9zc2libGUtdG8tc29ydC1hLWVzNi1tYXAtb2JqZWN0XG4gIC8vIG9yZGVyZWQoY29tcGVyYXRvciA9IG51bGwpIHtcbiAgLy8gICAvLyB0aGlzLnNldCA9IHRoaXMuYmVmb3JlKHRoaXMuc2V0KVxuICAvLyAgIHRoaXMuc2V0ID0gKGtleSwgdmFsdWUpID0+IHtcbiAgLy8gICAgIC8vIGhhdmUgdG8gaXRlcmF0ZSBvdmVyIHRoZSBrZXlzIGJlZm9yZSBzZXR0aW5nXG4gIC8vICAgICAvLyBhbmQgdGhlbiBhZnRlciBtZXJnaW5nIGluIHZhbHVlcywgdXBkYXRlXG4gIC8vICAgICBpZiAodGhpcy5zdG9yZS5oYXMoa2V5KSkge1xuICAvLyAgICAgICAvLyBmaXJzdFxuICAvLyAgICAgICBsZXQga2V5cyA9IHRoaXMuc3RvcmUua2V5cygpXG4gIC8vICAgICAgIGlmIChpc0Z1bmN0aW9uKGNvbXBlcmF0b3IpKSBrZXlzID0ga2V5cy5zb3J0KGNvbXBlcmF0b3IpXG4gIC8vXG4gIC8vICAgICAgIC8vIGFmdGVyXG4gIC8vICAgICAgIGNvbnN0IHN0b3JlID0gdGhpcy5zdG9yZVxuICAvLyAgICAgICB0aGlzLnN0b3JlID0gbmV3IE1hcCgpXG4gIC8vICAgICAgIGtleXMuZm9yRWFjaChrZXlJbk9yZGVyID0+IHRoaXMuc3RvcmUuc2V0KGtleSwgc3RvcmUuZ2V0KGtleSkpKVxuICAvLyAgICAgICBzdG9yZS5jbGVhcigpXG4gIC8vICAgICB9XG4gIC8vICAgfVxuICAvLyB9XG5cbiAgLy8gLS0tIHJlbWFwIC0tLVxuICAvKipcbiAgICogQGRlc2MgcmVtYXAgcHJvcGVydGllcyBmcm9tIDEgdG8gYW5vdGhlciwgZm9yIGV4YW1wbGUsIGFwaXMgd2l0aCBpbmNvbnNpc3RlbnQgbmFtaW5nXG4gICAqIEBtZW1iZXJPZiBUcmFuc2Zvcm1DaGFpblxuICAgKiBAc2luY2UgMS4wLjBcbiAgICogQHN5bWIg8J+XulxuICAgKlxuICAgKiBAcGFyYW0gIHtzdHJpbmcgfCBPYmplY3R9IGZyb20gcHJvcGVydHkgbmFtZSBzdHJpbmcsIG9yIHtbZnJvbV06IHRvfVxuICAgKiBAcGFyYW0gIHtzdHJpbmd9IFt0bz11bmRlZmluZWRdIHByb3BlcnR5IG5hbWUgdG8gY2hhbmdlIGtleSB0b1xuICAgKiBAcmV0dXJuIHtDaGFpbn0gQGNoYWluYWJsZVxuICAgKlxuICAgKiBAc2VlIFRyYW5zZm9ybUNoYWluLnRyYW5zZm9ybVxuICAgKiBASURFQSBjb3VsZCBhbHNvIGJlIGEgZnVuY3Rpb24sIGJ1dCB0aGVuIG1pZ2h0IGFzIHdlbGwgdXNlIC50cmFuc2Zvcm1cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICpcbiAgICogIGNoYWluXG4gICAqICAgIC5yZW1hcCgnZGlzJywgJ2RhdCcpXG4gICAqICAgIC5mcm9tKHtkaXM6IHRydWV9KVxuICAgKlxuICAgKiAgY2hhaW4uZW50cmllcygpXG4gICAqICAvLz0+IHtkYXQ6IHRydWV9XG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqXG4gICAqICBjaGFpblxuICAgKiAgICAucmVtYXAoe2RpczogJ2RhdCd9KVxuICAgKiAgICAuZnJvbSh7ZGlzOiAxLCBvdGhlcjogdHJ1ZX19XG4gICAqXG4gICAqICBjaGFpbi5lbnRyaWVzKClcbiAgICogIC8vPT4ge2Rpc3Q6IDEsIG90aGVyOiB0cnVlfVxuICAgKlxuICAgKi9cbiAgVGFyZ2V0LnByb3RvdHlwZS5yZW1hcCA9IGZ1bmN0aW9uIGNoYWluUmVtYXAoZnJvbSwgdG8pIHtcbiAgICBsZXQgcmVtYXAgPSBpc09iaihmcm9tKSA/IGZyb20gOiB7W2Zyb21dOiB0b31cblxuICAgIC8qIHByZXR0aWVyLWlnbm9yZSAqL1xuICAgIE9iamVjdEtleXMocmVtYXApLmZvckVhY2goa2V5ID0+IHRoaXMudHJhbnNmb3JtKGtleSwgdmFsID0+IHtcbiAgICAgIHRoaXMuc2V0KHJlbWFwW2tleV0sIHZhbClcbiAgICAgIHJldHVybiB2YWxcbiAgICB9KSlcblxuICAgIHJldHVybiB0aGlzXG4gIH1cblxuICByZXR1cm4gVGFyZ2V0XG59XG4iXSwibmFtZXMiOlsiY29uc3QiLCJsZXQiLCJ0aGlzIl0sIm1hcHBpbmdzIjoiQUFBQUEsR0FBSyxDQUFDLGFBQWEsR0FBRyxPQUFPLENBQUMsa0JBQWtCLENBQUM7QUFDakRBLEdBQUssQ0FBQyxLQUFLLEdBQUcsT0FBTyxDQUFDLGtCQUFrQixDQUFDO0FBQ3pDQSxHQUFLLENBQUMsS0FBSyxHQUFHLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQztBQUN2Q0EsR0FBSyxDQUFDLE1BQU0sR0FBRyxPQUFPLENBQUMsaUJBQWlCLENBQUM7QUFDekNBLEdBQUssQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDLGtCQUFrQixDQUFDO0FBQzNDQSxHQUFLLENBQUMsV0FBVyxHQUFHLE9BQU8sQ0FBQyxzQkFBc0IsQ0FBQztBQUNuREEsR0FBSyxDQUFDLFVBQVUsR0FBRyxPQUFPLENBQUMsbUJBQW1CLENBQUM7QUFDL0NBLEdBQUssQ0FBQyxZQUFZLEdBQUcsT0FBTyxDQUFDLG1CQUFtQixDQUFDO0FBQ2pEQSxHQUFLLENBQUMsZ0JBQWdCLEdBQUcsT0FBTyxDQUFDLCtCQUErQixDQUFDO0FBQ2pFQSxHQUFLLENB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