UNPKG

chain-able

Version:

interfaces that describe their intentions.

291 lines (271 loc) 22.4 kB
var Chainable = require('./Chainable') var dopemerge = require('./deps/dopemerge') var reduce = require('./deps/reduce') var reduceEntries = require('./deps/reduce/entries') var isFunction = require('./deps/is/function') var ObjectKeys = require('./deps/util/keys') var getMeta = require('./deps/meta') var SHORTHANDS_KEY = require('./deps/meta/shorthands') /** * @desc ChainedMapBase composer * @alias ComposeMap * @type {Composer} * @method compose * @memberOf ChainedMapBase * * @param {Class | Object | Composable} [SuperClass=Chainable] class to extend * @return {Class} ChainedMapBase * * @example * * const heh = class {} * const composed = ChainedMapBase.compose(heh) * const hehchain = new Composed() * hehchain instanceof heh * //=> true * */ var CMC = function (SuperClass) { /** * @classdesc this is to avoid circular requires * because MergeChain & MethodChain extend this * yet .method & .merge use those chains * * @since 4.0.0-alpha.1 * @inheritdoc * @class ChainedMapBase * @member ChainedMapBase * @category Chainable * @extends {Chainable} * @type {Chainable} * * @types ChainedMapBase * @tests ChainedMap * * @prop {Meta} meta * @prop {Map} store * * {@link https://ponyfoo.com/articles/es6-maps-in-depth pony-map} * {@link https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Map mozilla-map} * @see {@link pony-map} * @see {@link mozilla-map} * * @see ChainedMap * @see Chainable * @see MergeChain * @see MethodChain * @see ChainedMap * */ return (function (SuperClass) { function ChainedMapBase(parent) { SuperClass.call(this, parent) this.store = new Map() this.meta = getMeta(this) } if ( SuperClass ) ChainedMapBase.__proto__ = SuperClass; ChainedMapBase.prototype = Object.create( SuperClass && SuperClass.prototype ); ChainedMapBase.prototype.constructor = ChainedMapBase; /** * @desc tap a value with a function * @modifies this.store.get(name) * @memberOf ChainedMapBase * @since 0.7.0 * @since 4.0.0-alpha.1 <- moved from transform & shorthands * * @param {string | any} name key to `.get` * @param {Function} fn function to tap with * @return {Chain} @chainable * * {@link https://github.com/sindresorhus/awesome-tap awesome-tap} * {@link https://github.com/midknight41/map-factory map-factory} * {@link https://github.com/webpack/tapable tapable} * @see {@link tapable} * * @see ChainedMapBase.set * @see ChainedMapBase.get * * @example * * chain * .set('moose', {eh: true}) * .tap('moose', moose => {moose.eh = false; return moose}) * .get('moose') * * // => {eh: false} * * @example * * const entries = new Chain() * .set('str', 'emptyish') * .tap('str', str => str + '+') * .set('arr', [1]) * .tap('arr', arr => arr.concat([2])) * .entries() * * //=> {str: 'emptyish+', arr: [1, 2]} * */ ChainedMapBase.prototype.tap = function tap (name, fn) { return this.set(name, fn(this.get(name), dopemerge)) }; /** * @desc checks each property of the object * calls the chains accordingly * * @memberOf ChainedMapBase * @since 0.5.0 * * @param {Object} obj object with functions to hydrate from * @return {Chainable} @chainable * * @TODO could also add parsing stringified * * @example * * const from = new Chain().from({eh: true}) * const eh = new Chain().set('eh', true) * eq(from, eh) * // => true * */ ChainedMapBase.prototype.from = function from (obj) { var this$1 = this; var keys = ObjectKeys(obj) for (var k = 0; k < keys.length; k++) { var key = keys[k] var val = obj[key] var fn = this$1[key] if (fn && fn.merge) { fn.merge(val) } else if (isFunction(fn)) { fn.call(this$1, val) } else { this$1.set(key, val) } } return this }; /** * @desc shorthand methods, from strings to functions that call .set * @since 0.4.0 * @memberOf ChainedMapBase * * @param {Array<string>} methods decorates/extends an object with new shorthand functions to get/set * @return {ChainedMapBase} @chainable * * @example * * const chain1 = new Chain() * chain1.extend(['eh']) * * const chain2 = new Chain() * chain2.eh = val => this.set('eh', val) * * eq(chain2.eh, chain1.eh) * //=> true * */ ChainedMapBase.prototype.extend = function extend (methods) { var this$1 = this; methods.forEach(function (method) { this$1.meta(SHORTHANDS_KEY, method) this$1[method] = function (value) { return this$1.set(method, value); } }) return this }; /** * @desc spreads the entries from ChainedMapBase.store (Map) * return store.entries, plus all chain properties if they exist * @memberOf ChainedMapBase * * @since 4.0.0 <- improved reducing * @since 0.4.0 * * @param {boolean} [chains=false] if true, returns all properties that are chains * @return {Object} * * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/entries mozilla-map-entries} * @see {@link mozilla-map-entries} * * @example * * map.set('a', 'alpha').set('b', 'beta').entries() * //=> {a: 'alpha', b: 'beta'} * */ ChainedMapBase.prototype.entries = function entries (chains) { if ( chains === void 0 ) chains = false; var reduced = reduce(this.store) if (chains === false) { return reduced } var reducer = reduceEntries(reduced) reducer(this) reducer(reduced) return reduced }; /** * @desc get value for key path in the Map store * ❗ `debug` is a special key and is *not* included into .store * it goes onto .meta * * @memberOf ChainedMapBase * @since 4.0.0 <- moved debug here * @since 0.4.0 * * @param {Primitive} key Primitive data key used as map property to reference the value * @return {any} value in .store at key * * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/get mozilla-map-get} * @see {@link mozilla-map-get} * * @example * * const chain = new Chain() * chain.set('eh', true) * chain.get('eh') * //=> true * * chain.get('nope') * //=> undefined * */ ChainedMapBase.prototype.get = function get (key) { if (key === 'debug') { return this.meta.debug } return this.store.get(key) }; /** * @desc sets the value using the key on store * adds or updates an element with a specified key and value * * @memberOf ChainedMapBase * @since 0.4.0 * * @param {Primitive} key Primitive to reference the value * @param {any} value any data to store * @return {ChainedMapBase} @chainable * * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/set mozilla-map-set} * @see {@link mozilla-map-set} * @see ChainedMapBase.store * * @example * * const chain = new Chain() * chain.set('eh', true) * chain.get('eh') * //=> true * */ ChainedMapBase.prototype.set = function set (key, value) { this.store.set(key, value) return this }; return ChainedMapBase; }(SuperClass)) } var cmc = CMC(Chainable) cmc.compose = CMC module.exports = cmc //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ2hhaW5lZE1hcEJhc2UuanMiLCJzb3VyY2VzIjpbIkNoYWluZWRNYXBCYXNlLmpzIl0sInNvdXJjZXNDb250ZW50IjpbImNvbnN0IENoYWluYWJsZSA9IHJlcXVpcmUoJy4vQ2hhaW5hYmxlJylcbmNvbnN0IGRvcGVtZXJnZSA9IHJlcXVpcmUoJy4vZGVwcy9kb3BlbWVyZ2UnKVxuY29uc3QgcmVkdWNlID0gcmVxdWlyZSgnLi9kZXBzL3JlZHVjZScpXG5jb25zdCByZWR1Y2VFbnRyaWVzID0gcmVxdWlyZSgnLi9kZXBzL3JlZHVjZS9lbnRyaWVzJylcbmNvbnN0IGlzRnVuY3Rpb24gPSByZXF1aXJlKCcuL2RlcHMvaXMvZnVuY3Rpb24nKVxuY29uc3QgT2JqZWN0S2V5cyA9IHJlcXVpcmUoJy4vZGVwcy91dGlsL2tleXMnKVxuY29uc3QgZ2V0TWV0YSA9IHJlcXVpcmUoJy4vZGVwcy9tZXRhJylcbmNvbnN0IFNIT1JUSEFORFNfS0VZID0gcmVxdWlyZSgnLi9kZXBzL21ldGEvc2hvcnRoYW5kcycpXG5cbi8qKlxuICogQGRlc2MgQ2hhaW5lZE1hcEJhc2UgY29tcG9zZXJcbiAqIEBhbGlhcyBDb21wb3NlTWFwXG4gKiBAdHlwZSB7Q29tcG9zZXJ9XG4gKiBAbWV0aG9kIGNvbXBvc2VcbiAqIEBtZW1iZXJPZiBDaGFpbmVkTWFwQmFzZVxuICpcbiAqIEBwYXJhbSB7Q2xhc3MgfCBPYmplY3QgfCBDb21wb3NhYmxlfSBbU3VwZXJDbGFzcz1DaGFpbmFibGVdIGNsYXNzIHRvIGV4dGVuZFxuICogQHJldHVybiB7Q2xhc3N9IENoYWluZWRNYXBCYXNlXG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKiAgICBjb25zdCBoZWggPSBjbGFzcyB7fVxuICogICAgY29uc3QgY29tcG9zZWQgPSBDaGFpbmVkTWFwQmFzZS5jb21wb3NlKGhlaClcbiAqICAgIGNvbnN0IGhlaGNoYWluID0gbmV3IENvbXBvc2VkKClcbiAqICAgIGhlaGNoYWluIGluc3RhbmNlb2YgaGVoXG4gKiAgICAvLz0+IHRydWVcbiAqXG4gKi9cbmNvbnN0IENNQyA9IFN1cGVyQ2xhc3MgPT4ge1xuICAvKipcbiAgICogQGNsYXNzZGVzYyB0aGlzIGlzIHRvIGF2b2lkIGNpcmN1bGFyIHJlcXVpcmVzXG4gICAqICAgICAgIGJlY2F1c2UgTWVyZ2VDaGFpbiAmIE1ldGhvZENoYWluIGV4dGVuZCB0aGlzXG4gICAqICAgICAgIHlldCAubWV0aG9kICYgLm1lcmdlIHVzZSB0aG9zZSBjaGFpbnNcbiAgICpcbiAgICogQHNpbmNlIDQuMC4wLWFscGhhLjFcbiAgICogQGluaGVyaXRkb2NcbiAgICogQGNsYXNzIENoYWluZWRNYXBCYXNlXG4gICAqIEBtZW1iZXIgQ2hhaW5lZE1hcEJhc2VcbiAgICogQGNhdGVnb3J5IENoYWluYWJsZVxuICAgKiBAZXh0ZW5kcyB7Q2hhaW5hYmxlfVxuICAgKiBAdHlwZSB7Q2hhaW5hYmxlfVxuICAgKlxuICAgKiBAdHlwZXMgQ2hhaW5lZE1hcEJhc2VcbiAgICogQHRlc3RzIENoYWluZWRNYXBcbiAgICpcbiAgICogQHByb3Age01ldGF9IG1ldGFcbiAgICogQHByb3Age01hcH0gc3RvcmVcbiAgICpcbiAgICoge0BsaW5rIGh0dHBzOi8vcG9ueWZvby5jb20vYXJ0aWNsZXMvZXM2LW1hcHMtaW4tZGVwdGggcG9ueS1tYXB9XG4gICAqIHtAbGluayBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9NYXAgbW96aWxsYS1tYXB9XG4gICAqIEBzZWUge0BsaW5rIHBvbnktbWFwfVxuICAgKiBAc2VlIHtAbGluayBtb3ppbGxhLW1hcH1cbiAgICpcbiAgICogQHNlZSBDaGFpbmVkTWFwXG4gICAqIEBzZWUgQ2hhaW5hYmxlXG4gICAqIEBzZWUgTWVyZ2VDaGFpblxuICAgKiBAc2VlIE1ldGhvZENoYWluXG4gICAqIEBzZWUgQ2hhaW5lZE1hcFxuICAgKlxuICAgKi9cbiAgcmV0dXJuIGNsYXNzIENoYWluZWRNYXBCYXNlIGV4dGVuZHMgU3VwZXJDbGFzcyB7XG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtDaGFpbmVkTWFwQmFzZSB8IENoYWluYWJsZSB8IFBhcmVudFR5cGUgfCBhbnl9IHBhcmVudCBQYXJlbnRUeXBlXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogICAgY2xhc3MgRWggZXh0ZW5kcyBDaGFpbmVkTWFwQmFzZSB7fVxuICAgICAqICAgIE9iamVjdC5rZXlzKGVoKVxuICAgICAqICAgIC8vPT4gWydzdG9yZScsICdtZXRhJ11cbiAgICAgKlxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHBhcmVudCkge1xuICAgICAgc3VwZXIocGFyZW50KVxuXG4gICAgICB0aGlzLnN0b3JlID0gbmV3IE1hcCgpXG4gICAgICB0aGlzLm1ldGEgPSBnZXRNZXRhKHRoaXMpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGRlc2MgICB0YXAgYSB2YWx1ZSB3aXRoIGEgZnVuY3Rpb25cbiAgICAgKiAgICAgICAgIEBtb2RpZmllcyB0aGlzLnN0b3JlLmdldChuYW1lKVxuICAgICAqIEBtZW1iZXJPZiBDaGFpbmVkTWFwQmFzZVxuICAgICAqIEBzaW5jZSAwLjcuMFxuICAgICAqIEBzaW5jZSA0LjAuMC1hbHBoYS4xIDwtIG1vdmVkIGZyb20gdHJhbnNmb3JtICYgc2hvcnRoYW5kc1xuICAgICAqXG4gICAgICogQHBhcmFtICB7c3RyaW5nIHwgYW55fSBuYW1lIGtleSB0byBgLmdldGBcbiAgICAgKiBAcGFyYW0gIHtGdW5jdGlvbn0gZm4gZnVuY3Rpb24gdG8gdGFwIHdpdGhcbiAgICAgKiBAcmV0dXJuIHtDaGFpbn0gQGNoYWluYWJsZVxuICAgICAqXG4gICAgICoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS9zaW5kcmVzb3JodXMvYXdlc29tZS10YXAgYXdlc29tZS10YXB9XG4gICAgICoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS9taWRrbmlnaHQ0MS9tYXAtZmFjdG9yeSBtYXAtZmFjdG9yeX1cbiAgICAgKiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3dlYnBhY2svdGFwYWJsZSB0YXBhYmxlfVxuICAgICAqIEBzZWUge0BsaW5rIHRhcGFibGV9XG4gICAgICpcbiAgICAgKiBAc2VlIENoYWluZWRNYXBCYXNlLnNldFxuICAgICAqIEBzZWUgQ2hhaW5lZE1hcEJhc2UuZ2V0XG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogICAgY2hhaW5cbiAgICAgKiAgICAgIC5zZXQoJ21vb3NlJywge2VoOiB0cnVlfSlcbiAgICAgKiAgICAgIC50YXAoJ21vb3NlJywgbW9vc2UgPT4ge21vb3NlLmVoID0gZmFsc2U7IHJldHVybiBtb29zZX0pXG4gICAgICogICAgICAuZ2V0KCdtb29zZScpXG4gICAgICpcbiAgICAgKiAgICAvLyA9PiB7ZWg6IGZhbHNlfVxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqICAgY29uc3QgZW50cmllcyA9IG5ldyBDaGFpbigpXG4gICAgICogICAgIC5zZXQoJ3N0cicsICdlbXB0eWlzaCcpXG4gICAgICogICAgIC50YXAoJ3N0cicsIHN0ciA9PiBzdHIgKyAnKycpXG4gICAgICogICAgIC5zZXQoJ2FycicsIFsxXSlcbiAgICAgKiAgICAgLnRhcCgnYXJyJywgYXJyID0+IGFyci5jb25jYXQoWzJdKSlcbiAgICAgKiAgICAgLmVudHJpZXMoKVxuICAgICAqXG4gICAgICogICAvLz0+IHtzdHI6ICdlbXB0eWlzaCsnLCBhcnI6IFsxLCAyXX1cbiAgICAgKlxuICAgICAqL1xuICAgIHRhcChuYW1lLCBmbikge1xuICAgICAgcmV0dXJuIHRoaXMuc2V0KG5hbWUsIGZuKHRoaXMuZ2V0KG5hbWUpLCBkb3BlbWVyZ2UpKVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBkZXNjIGNoZWNrcyBlYWNoIHByb3BlcnR5IG9mIHRoZSBvYmplY3RcbiAgICAgKiAgICAgICBjYWxscyB0aGUgY2hhaW5zIGFjY29yZGluZ2x5XG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgQ2hhaW5lZE1hcEJhc2VcbiAgICAgKiBAc2luY2UgMC41LjBcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmogb2JqZWN0IHdpdGggZnVuY3Rpb25zIHRvIGh5ZHJhdGUgZnJvbVxuICAgICAqIEByZXR1cm4ge0NoYWluYWJsZX0gQGNoYWluYWJsZVxuICAgICAqXG4gICAgICogQFRPRE8gY291bGQgYWxzbyBhZGQgcGFyc2luZyBzdHJpbmdpZmllZFxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqICAgICBjb25zdCBmcm9tID0gbmV3IENoYWluKCkuZnJvbSh7ZWg6IHRydWV9KVxuICAgICAqICAgICBjb25zdCBlaCA9IG5ldyBDaGFpbigpLnNldCgnZWgnLCB0cnVlKVxuICAgICAqICAgICBlcShmcm9tLCBlaClcbiAgICAgKiAgICAgLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICovXG4gICAgZnJvbShvYmopIHtcbiAgICAgIGNvbnN0IGtleXMgPSBPYmplY3RLZXlzKG9iailcblxuICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCBrZXlzLmxlbmd0aDsgaysrKSB7XG4gICAgICAgIGNvbnN0IGtleSA9IGtleXNba11cbiAgICAgICAgY29uc3QgdmFsID0gb2JqW2tleV1cbiAgICAgICAgY29uc3QgZm4gPSB0aGlzW2tleV1cblxuICAgICAgICBpZiAoZm4gJiYgZm4ubWVyZ2UpIHtcbiAgICAgICAgICBmbi5tZXJnZSh2YWwpXG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaXNGdW5jdGlvbihmbikpIHtcbiAgICAgICAgICBmbi5jYWxsKHRoaXMsIHZhbClcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICB0aGlzLnNldChrZXksIHZhbClcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpc1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBkZXNjIHNob3J0aGFuZCBtZXRob2RzLCBmcm9tIHN0cmluZ3MgdG8gZnVuY3Rpb25zIHRoYXQgY2FsbCAuc2V0XG4gICAgICogQHNpbmNlIDAuNC4wXG4gICAgICogQG1lbWJlck9mIENoYWluZWRNYXBCYXNlXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtBcnJheTxzdHJpbmc+fSBtZXRob2RzIGRlY29yYXRlcy9leHRlbmRzIGFuIG9iamVjdCB3aXRoIG5ldyBzaG9ydGhhbmQgZnVuY3Rpb25zIHRvIGdldC9zZXRcbiAgICAgKiBAcmV0dXJuIHtDaGFpbmVkTWFwQmFzZX0gQGNoYWluYWJsZVxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqICAgIGNvbnN0IGNoYWluMSA9IG5ldyBDaGFpbigpXG4gICAgICogICAgY2hhaW4xLmV4dGVuZChbJ2VoJ10pXG4gICAgICpcbiAgICAgKiAgICBjb25zdCBjaGFpbjIgPSBuZXcgQ2hhaW4oKVxuICAgICAqICAgIGNoYWluMi5laCA9IHZhbCA9PiB0aGlzLnNldCgnZWgnLCB2YWwpXG4gICAgICpcbiAgICAgKiAgICBlcShjaGFpbjIuZWgsIGNoYWluMS5laClcbiAgICAgKiAgICAvLz0+IHRydWVcbiAgICAgKlxuICAgICAqL1xuICAgIGV4dGVuZChtZXRob2RzKSB7XG4gICAgICBtZXRob2RzLmZvckVhY2gobWV0aG9kID0+IHtcbiAgICAgICAgdGhpcy5tZXRhKFNIT1JUSEFORFNfS0VZLCBtZXRob2QpXG4gICAgICAgIHRoaXNbbWV0aG9kXSA9IHZhbHVlID0+IHRoaXMuc2V0KG1ldGhvZCwgdmFsdWUpXG4gICAgICB9KVxuICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAZGVzYyBzcHJlYWRzIHRoZSBlbnRyaWVzIGZyb20gQ2hhaW5lZE1hcEJhc2Uuc3RvcmUgKE1hcClcbiAgICAgKiAgICAgICByZXR1cm4gc3RvcmUuZW50cmllcywgcGx1cyBhbGwgY2hhaW4gcHJvcGVydGllcyBpZiB0aGV5IGV4aXN0XG4gICAgICogQG1lbWJlck9mIENoYWluZWRNYXBCYXNlXG4gICAgICpcbiAgICAgKiBAc2luY2UgNC4wLjAgPC0gaW1wcm92ZWQgcmVkdWNpbmdcbiAgICAgKiBAc2luY2UgMC40LjBcbiAgICAgKlxuICAgICAqIEBwYXJhbSAge2Jvb2xlYW59IFtjaGFpbnM9ZmFsc2VdIGlmIHRydWUsIHJldHVybnMgYWxsIHByb3BlcnRpZXMgdGhhdCBhcmUgY2hhaW5zXG4gICAgICogQHJldHVybiB7T2JqZWN0fVxuICAgICAqXG4gICAgICoge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL01hcC9lbnRyaWVzIG1vemlsbGEtbWFwLWVudHJpZXN9XG4gICAgICogQHNlZSB7QGxpbmsgbW96aWxsYS1tYXAtZW50cmllc31cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiAgICBtYXAuc2V0KCdhJywgJ2FscGhhJykuc2V0KCdiJywgJ2JldGEnKS5lbnRyaWVzKClcbiAgICAgKiAgICAvLz0+IHthOiAnYWxwaGEnLCBiOiAnYmV0YSd9XG4gICAgICpcbiAgICAgKi9cbiAgICBlbnRyaWVzKGNoYWlucyA9IGZhbHNlKSB7XG4gICAgICBjb25zdCByZWR1Y2VkID0gcmVkdWNlKHRoaXMuc3RvcmUpXG4gICAgICBpZiAoY2hhaW5zID09PSBmYWxzZSkgcmV0dXJuIHJlZHVjZWRcblxuICAgICAgY29uc3QgcmVkdWNlciA9IHJlZHVjZUVudHJpZXMocmVkdWNlZClcbiAgICAgIHJlZHVjZXIodGhpcylcbiAgICAgIHJlZHVjZXIocmVkdWNlZClcbiAgICAgIHJldHVybiByZWR1Y2VkXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGRlc2MgZ2V0IHZhbHVlIGZvciBrZXkgcGF0aCBpbiB0aGUgTWFwIHN0b3JlXG4gICAgICogICAgICAg4p2XIGBkZWJ1Z2AgaXMgYSBzcGVjaWFsIGtleSBhbmQgaXMgKm5vdCogaW5jbHVkZWQgaW50byAuc3RvcmVcbiAgICAgKiAgICAgICAgICBpdCBnb2VzIG9udG8gLm1ldGFcbiAgICAgKlxuICAgICAqIEBtZW1iZXJPZiBDaGFpbmVkTWFwQmFzZVxuICAgICAqIEBzaW5jZSA0LjAuMCA8LSBtb3ZlZCBkZWJ1ZyBoZXJlXG4gICAgICogQHNpbmNlIDAuNC4wXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtQcmltaXRpdmV9IGtleSBQcmltaXRpdmUgZGF0YSBrZXkgdXNlZCBhcyBtYXAgcHJvcGVydHkgdG8gcmVmZXJlbmNlIHRoZSB2YWx1ZVxuICAgICAqIEByZXR1cm4ge2FueX0gdmFsdWUgaW4gLnN0b3JlIGF0IGtleVxuICAgICAqXG4gICAgICoge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL01hcC9nZXQgbW96aWxsYS1tYXAtZ2V0fVxuICAgICAqIEBzZWUge0BsaW5rIG1vemlsbGEtbWFwLWdldH1cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiAgICBjb25zdCBjaGFpbiA9IG5ldyBDaGFpbigpXG4gICAgICogICAgY2hhaW4uc2V0KCdlaCcsIHRydWUpXG4gICAgICogICAgY2hhaW4uZ2V0KCdlaCcpXG4gICAgICogICAgLy89PiB0cnVlXG4gICAgICpcbiAgICAgKiAgICBjaGFpbi5nZXQoJ25vcGUnKVxuICAgICAqICAgIC8vPT4gdW5kZWZpbmVkXG4gICAgICpcbiAgICAgKi9cbiAgICBnZXQoa2V5KSB7XG4gICAgICBpZiAoa2V5ID09PSAnZGVidWcnKSByZXR1cm4gdGhpcy5tZXRhLmRlYnVnXG4gICAgICByZXR1cm4gdGhpcy5zdG9yZS5nZXQoa2V5KVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBkZXNjIHNldHMgdGhlIHZhbHVlIHVzaW5nIHRoZSBrZXkgb24gc3RvcmVcbiAgICAgKiAgICAgICBhZGRzIG9yIHVwZGF0ZXMgYW4gZWxlbWVudCB3aXRoIGEgc3BlY2lmaWVkIGtleSBhbmQgdmFsdWVcbiAgICAgKlxuICAgICAqIEBtZW1iZXJPZiBDaGFpbmVkTWFwQmFzZVxuICAgICAqIEBzaW5jZSAwLjQuMFxuICAgICAqXG4gICAgICogQHBhcmFtIHtQcmltaXRpdmV9IGtleSBQcmltaXRpdmUgdG8gcmVmZXJlbmNlIHRoZSB2YWx1ZVxuICAgICAqIEBwYXJhbSB7YW55fSB2YWx1ZSBhbnkgZGF0YSB0byBzdG9yZVxuICAgICAqIEByZXR1cm4ge0NoYWluZWRNYXBCYXNlfSBAY2hhaW5hYmxlXG4gICAgICpcbiAgICAgKiB7QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvTWFwL3NldCBtb3ppbGxhLW1hcC1zZXR9XG4gICAgICogQHNlZSB7QGxpbmsgbW96aWxsYS1tYXAtc2V0fVxuICAgICAqIEBzZWUgQ2hhaW5lZE1hcEJhc2Uuc3RvcmVcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiAgICBjb25zdCBjaGFpbiA9IG5ldyBDaGFpbigpXG4gICAgICogICAgY2hhaW4uc2V0KCdlaCcsIHRydWUpXG4gICAgICogICAgY2hhaW4uZ2V0KCdlaCcpXG4gICAgICogICAgLy89PiB0cnVlXG4gICAgICpcbiAgICAgKi9cbiAgICBzZXQoa2V5LCB2YWx1ZSkge1xuICAgICAgdGhpcy5zdG9yZS5zZXQoa2V5LCB2YWx1ZSlcbiAgICAgIHJldHVybiB0aGlzXG4gICAgfVxuICB9XG59XG5cbmNvbnN0IGNtYyA9IENNQyhDaGFpbmFibGUpXG5jbWMuY29tcG9zZSA9IENNQ1xuXG5tb2R1bGUuZXhwb3J0cyA9IGNtY1xuIl0sIm5hbWVzIjpbImNvbnN0Iiwic3VwZXIiLCJsZXQiLCJ0aGlzIl0sIm1hcHBpbmdz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