UNPKG

foop

Version:

interfaces that describe their intentions.

214 lines (213 loc) 16 kB
// // @TODO could also just have files for .set .has .get .delete .clear... // // // @TODO: // // just pass in as first param! // // var SET = 1 // // var GET = 2 // // var HAS = 4 // // var DELETE = 8 // // const isSet = require('../is/set') // const ArrayFrom = require('../util/from') // const isUndefined = require('../is/undefined') // const concat = require('../concat') // const toarr = require('../to-arr') // // const emptyArray = [] // const store = {} // // const ensureInitialized = (name, value, mapOrSet) => { // if (isUndefined(store[name])) store[name] = new Map() // } // // const has = (key, prop) => { // return isUndefined(prop) ? !!store[key].size : store[key].has(prop) // } // // const get = (key, prop, fallback = emptyArray) => { // return has(key, prop) ? store[key].get(prop) : fallback // } // // const set = (key, prop, value) => { // const storage = store[key] // // when it's a set, we have no `prop`, we just have .add // // so `prop = value` && `value = undefined` // if (isSet(storage)) { // storage.add(prop) // } // else { // const existing = storage.get(prop) // const val = concat(existing, value) // storage.set(prop, val) // } // } // const cache = (key, prop, value) => { // /* prettier-ignore */ // if (isUndefined(value)) { // // when we want to just access the property, return an array // // @example `.meta('transformers')` // if (isUndefined(prop)) { // if (isUndefined(store[key])) return emptyArray // else return store[key].size === 0 ? emptyArray : ArrayFrom(store[key]) // } // // we have `key, prop` // // // // 1: should `prop` be a value, (isSet?) // else if (isSet(store[key])) { // ensureInitialized(key) // set(key, prop) // } // // 2: prop is a key, we want to return the [..] for that specific property // // @example `.meta('transformers', 'eh')` // else if (isUndefined(store[key])) return emptyArray // else return toarr(get(key, prop)) // } // // we have `key, prop, value` // else { // ensureInitialized(key) // // we have a value, let's add it // set(key, prop, value) // } // } // // const scoped = cache('segments', {default: []}) // // // has/get // if (scoped('key')) { // // todo eh // } // // // set // scoped('key', 'value') // // // // /** // // * @since 4.0.0 // // * @param {Chain} _this // // * @return {Chain} // // */ // // function getMeta(_this) { // // // if we already have it, keep it // // if (_this.meta) return _this.meta // // // // // the store // // // shorthands: key -> method // // const store = {} // // // // // --- uglifiable functions // // // // /** @desc initialize the store maps when we need them */ // // /* prettier-ignore */ // // const ensureInitialized = (name, value) => { // // if (!isUndefined(store[name])) return // // // // // if ( // // // name === TRANSFORMERS_KEY || // // // name === SHORTHANDS_KEY || // // // name === DECORATED_KEY // // // ) { // // // store[name] = new Map() // // // } // // // else // // if (isInKeyMapAsSet(name)) { // // store[name] = new Set() // // } // // else { // // store[name] = new Map() // // } // // } // // // // /** // // * @since 4.0.0 // // * @param {Primitive} key // // * @param {Primitive | undefined} [prop=undefined] // // * @return {boolean} // // */ // // const has = (key, prop) => { // // if (isUndefined(prop)) return !!store[key].size // // else return store[key].has(prop) // // } // // /** // // * @since 4.0.0 // // * @param {Primitive} key // // * @param {Primitive | undefined} [prop=undefined] // // * @return {any} // // */ // // const get = (key, prop) => (has(key, prop) ? store[key].get(prop) : emptyArray) // // // // /** // // * @since 4.0.0 // // * @param {Primitive} key // // * @param {Primitive | undefined} [prop=undefined] // // * @param {Primitive | undefined} [value=undefined] // // * @return {void} // // */ // // const set = (key, prop, value) => { // // const storage = store[key] // // // when it's a set, we have no `prop`, we just have .add // // // so `prop = value` && `value = undefined` // // if (isSet(storage)) { // // storage.add(prop) // // } // // else { // // // if (!has(key, prop)) return // // const existing = storage.get(prop) // // const val = concat(existing, value) // // storage.set(prop, val) // // } // // } // // // // /** // // * @since 4.0.0 // // * // // * @desc a single easily minifiable function, // // * dynamically setting & getting depending on arguments // // * to avoid nested property accessing // // * only instantiating when values are **addded** // // * // // * @param {Primitive} key // // * @param {Primitive | undefined} [prop=undefined] // // * @param {undefined | any} [value=undefined] (when no value, it's a getter) // // * @return {Array | Chain} depending on args // // */ // // function meta(key, prop, value) { // // if (process.env.NODE_ENV === 'DEBUG') { // // console.log('USING META', {key, prop, value}) // // } // // // // /* prettier-ignore */ // // if (isUndefined(value)) { // // // when we want to just access the property, return an array // // // @example `.meta('transformers')` // // if (isUndefined(prop)) { // // if (isUndefined(store[key])) return emptyArray // // else return store[key].size === 0 ? emptyArray : ArrayFrom(store[key].values()) // // } // // // we have `key, prop` // // // // // // 1: should `prop` be a value, (isSet?) // // else if (isInKeyMapAsSet(key)) { // // ensureInitialized(key) // // set(key, prop) // // } // // // 2: prop is a key, we want to return the [..] for that specific property // // // @example `.meta('transformers', 'eh')` // // else if (isUndefined(store[key])) return emptyArray // // else return toarr(get(key, prop)) // // } // // // we have `key, prop, value` // // else { // // ensureInitialized(key) // // // we have a value, let's add it // // set(key, prop, value) // // } // // return _this // // } // // // // // for debugging // // meta.store = store // // // meta.debug = false // // // // return meta // // } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NvcGVkLmpzIiwic291cmNlcyI6WyJzY29wZWQuanMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gLy8gQFRPRE8gY291bGQgYWxzbyBqdXN0IGhhdmUgZmlsZXMgZm9yIC5zZXQgLmhhcyAuZ2V0IC5kZWxldGUgLmNsZWFyLi4uXG4vL1xuLy8gLy8gQFRPRE86XG4vLyAvLyBqdXN0IHBhc3MgaW4gYXMgZmlyc3QgcGFyYW0hXG4vLyAvLyB2YXIgU0VUID0gMVxuLy8gLy8gdmFyIEdFVCA9IDJcbi8vIC8vIHZhciBIQVMgPSA0XG4vLyAvLyB2YXIgREVMRVRFID0gOFxuLy9cbi8vIGNvbnN0IGlzU2V0ID0gcmVxdWlyZSgnLi4vaXMvc2V0Jylcbi8vIGNvbnN0IEFycmF5RnJvbSA9IHJlcXVpcmUoJy4uL3V0aWwvZnJvbScpXG4vLyBjb25zdCBpc1VuZGVmaW5lZCA9IHJlcXVpcmUoJy4uL2lzL3VuZGVmaW5lZCcpXG4vLyBjb25zdCBjb25jYXQgPSByZXF1aXJlKCcuLi9jb25jYXQnKVxuLy8gY29uc3QgdG9hcnIgPSByZXF1aXJlKCcuLi90by1hcnInKVxuLy9cbi8vIGNvbnN0IGVtcHR5QXJyYXkgPSBbXVxuLy8gY29uc3Qgc3RvcmUgPSB7fVxuLy9cbi8vIGNvbnN0IGVuc3VyZUluaXRpYWxpemVkID0gKG5hbWUsIHZhbHVlLCBtYXBPclNldCkgPT4ge1xuLy8gICBpZiAoaXNVbmRlZmluZWQoc3RvcmVbbmFtZV0pKSBzdG9yZVtuYW1lXSA9IG5ldyBNYXAoKVxuLy8gfVxuLy9cbi8vIGNvbnN0IGhhcyA9IChrZXksIHByb3ApID0+IHtcbi8vICAgcmV0dXJuIGlzVW5kZWZpbmVkKHByb3ApID8gISFzdG9yZVtrZXldLnNpemUgOiBzdG9yZVtrZXldLmhhcyhwcm9wKVxuLy8gfVxuLy9cbi8vIGNvbnN0IGdldCA9IChrZXksIHByb3AsIGZhbGxiYWNrID0gZW1wdHlBcnJheSkgPT4ge1xuLy8gICByZXR1cm4gaGFzKGtleSwgcHJvcCkgPyBzdG9yZVtrZXldLmdldChwcm9wKSA6IGZhbGxiYWNrXG4vLyB9XG4vL1xuLy8gY29uc3Qgc2V0ID0gKGtleSwgcHJvcCwgdmFsdWUpID0+IHtcbi8vICAgY29uc3Qgc3RvcmFnZSA9IHN0b3JlW2tleV1cbi8vICAgLy8gd2hlbiBpdCdzIGEgc2V0LCB3ZSBoYXZlIG5vIGBwcm9wYCwgd2UganVzdCBoYXZlIC5hZGRcbi8vICAgLy8gc28gYHByb3AgPSB2YWx1ZWAgJiYgYHZhbHVlID0gdW5kZWZpbmVkYFxuLy8gICBpZiAoaXNTZXQoc3RvcmFnZSkpIHtcbi8vICAgICBzdG9yYWdlLmFkZChwcm9wKVxuLy8gICB9XG4vLyAgIGVsc2Uge1xuLy8gICAgIGNvbnN0IGV4aXN0aW5nID0gc3RvcmFnZS5nZXQocHJvcClcbi8vICAgICBjb25zdCB2YWwgPSBjb25jYXQoZXhpc3RpbmcsIHZhbHVlKVxuLy8gICAgIHN0b3JhZ2Uuc2V0KHByb3AsIHZhbClcbi8vICAgfVxuLy8gfVxuLy8gY29uc3QgY2FjaGUgPSAoa2V5LCBwcm9wLCB2YWx1ZSkgPT4ge1xuLy8gICAvKiBwcmV0dGllci1pZ25vcmUgKi9cbi8vICAgaWYgKGlzVW5kZWZpbmVkKHZhbHVlKSkge1xuLy8gICAgIC8vIHdoZW4gd2Ugd2FudCB0byBqdXN0IGFjY2VzcyB0aGUgcHJvcGVydHksIHJldHVybiBhbiBhcnJheVxuLy8gICAgIC8vIEBleGFtcGxlIGAubWV0YSgndHJhbnNmb3JtZXJzJylgXG4vLyAgICAgaWYgKGlzVW5kZWZpbmVkKHByb3ApKSB7XG4vLyAgICAgICBpZiAoaXNVbmRlZmluZWQoc3RvcmVba2V5XSkpIHJldHVybiBlbXB0eUFycmF5XG4vLyAgICAgICBlbHNlIHJldHVybiBzdG9yZVtrZXldLnNpemUgPT09IDAgPyBlbXB0eUFycmF5IDogQXJyYXlGcm9tKHN0b3JlW2tleV0pXG4vLyAgICAgfVxuLy8gICAgIC8vIHdlIGhhdmUgYGtleSwgcHJvcGBcbi8vICAgICAvL1xuLy8gICAgIC8vIDE6IHNob3VsZCBgcHJvcGAgYmUgYSB2YWx1ZSwgKGlzU2V0Pylcbi8vICAgICBlbHNlIGlmIChpc1NldChzdG9yZVtrZXldKSkge1xuLy8gICAgICAgZW5zdXJlSW5pdGlhbGl6ZWQoa2V5KVxuLy8gICAgICAgc2V0KGtleSwgcHJvcClcbi8vICAgICB9XG4vLyAgICAgLy8gMjogcHJvcCBpcyBhIGtleSwgd2Ugd2FudCB0byByZXR1cm4gdGhlIFsuLl0gZm9yIHRoYXQgc3BlY2lmaWMgcHJvcGVydHlcbi8vICAgICAvLyBAZXhhbXBsZSBgLm1ldGEoJ3RyYW5zZm9ybWVycycsICdlaCcpYFxuLy8gICAgIGVsc2UgaWYgKGlzVW5kZWZpbmVkKHN0b3JlW2tleV0pKSByZXR1cm4gZW1wdHlBcnJheVxuLy8gICAgIGVsc2UgcmV0dXJuIHRvYXJyKGdldChrZXksIHByb3ApKVxuLy8gICB9XG4vLyAgIC8vIHdlIGhhdmUgYGtleSwgcHJvcCwgdmFsdWVgXG4vLyAgIGVsc2Uge1xuLy8gICAgIGVuc3VyZUluaXRpYWxpemVkKGtleSlcbi8vICAgICAvLyB3ZSBoYXZlIGEgdmFsdWUsIGxldCdzIGFkZCBpdFxuLy8gICAgIHNldChrZXksIHByb3AsIHZhbHVlKVxuLy8gICB9XG4vLyB9XG4vL1xuLy8gY29uc3Qgc2NvcGVkID0gY2FjaGUoJ3NlZ21lbnRzJywge2RlZmF1bHQ6IFtdfSlcbi8vXG4vLyAvLyBoYXMvZ2V0XG4vLyBpZiAoc2NvcGVkKCdrZXknKSkge1xuLy8gICAvLyB0b2RvIGVoXG4vLyB9XG4vL1xuLy8gLy8gc2V0XG4vLyBzY29wZWQoJ2tleScsICd2YWx1ZScpXG4vL1xuLy9cbi8vIC8vIC8qKlxuLy8gLy8gICogQHNpbmNlICA0LjAuMFxuLy8gLy8gICogQHBhcmFtICB7Q2hhaW59IF90aGlzXG4vLyAvLyAgKiBAcmV0dXJuIHtDaGFpbn1cbi8vIC8vICAqL1xuLy8gLy8gZnVuY3Rpb24gZ2V0TWV0YShfdGhpcykge1xuLy8gLy8gICAvLyBpZiB3ZSBhbHJlYWR5IGhhdmUgaXQsIGtlZXAgaXRcbi8vIC8vICAgaWYgKF90aGlzLm1ldGEpIHJldHVybiBfdGhpcy5tZXRhXG4vLyAvL1xuLy8gLy8gICAvLyB0aGUgc3RvcmVcbi8vIC8vICAgLy8gc2hvcnRoYW5kczoga2V5IC0+IG1ldGhvZFxuLy8gLy8gICBjb25zdCBzdG9yZSA9IHt9XG4vLyAvL1xuLy8gLy8gICAvLyAtLS0gdWdsaWZpYWJsZSBmdW5jdGlvbnNcbi8vIC8vXG4vLyAvLyAgIC8qKiBAZGVzYyBpbml0aWFsaXplIHRoZSBzdG9yZSBtYXBzIHdoZW4gd2UgbmVlZCB0aGVtICovXG4vLyAvLyAgIC8qIHByZXR0aWVyLWlnbm9yZSAqL1xuLy8gLy8gICBjb25zdCBlbnN1cmVJbml0aWFsaXplZCA9IChuYW1lLCB2YWx1ZSkgPT4ge1xuLy8gLy8gICAgIGlmICghaXNVbmRlZmluZWQoc3RvcmVbbmFtZV0pKSByZXR1cm5cbi8vIC8vXG4vLyAvLyAgICAgLy8gaWYgKFxuLy8gLy8gICAgIC8vICAgbmFtZSA9PT0gVFJBTlNGT1JNRVJTX0tFWSB8fFxuLy8gLy8gICAgIC8vICAgbmFtZSA9PT0gU0hPUlRIQU5EU19LRVkgfHxcbi8vIC8vICAgICAvLyAgIG5hbWUgPT09IERFQ09SQVRFRF9LRVlcbi8vIC8vICAgICAvLyApIHtcbi8vIC8vICAgICAvLyAgIHN0b3JlW25hbWVdID0gbmV3IE1hcCgpXG4vLyAvLyAgICAgLy8gfVxuLy8gLy8gICAgIC8vIGVsc2Vcbi8vIC8vICAgICBpZiAoaXNJbktleU1hcEFzU2V0KG5hbWUpKSB7XG4vLyAvLyAgICAgICBzdG9yZVtuYW1lXSA9IG5ldyBTZXQoKVxuLy8gLy8gICAgIH1cbi8vIC8vICAgICBlbHNlIHtcbi8vIC8vICAgICAgIHN0b3JlW25hbWVdID0gbmV3IE1hcCgpXG4vLyAvLyAgICAgfVxuLy8gLy8gICB9XG4vLyAvL1xuLy8gLy8gICAvKipcbi8vIC8vICAgICogQHNpbmNlICA0LjAuMFxuLy8gLy8gICAgKiBAcGFyYW0gIHtQcmltaXRpdmV9IGtleVxuLy8gLy8gICAgKiBAcGFyYW0gIHtQcmltaXRpdmUgfCB1bmRlZmluZWR9IFtwcm9wPXVuZGVmaW5lZF1cbi8vIC8vICAgICogQHJldHVybiB7Ym9vbGVhbn1cbi8vIC8vICAgICovXG4vLyAvLyAgIGNvbnN0IGhhcyA9IChrZXksIHByb3ApID0+IHtcbi8vIC8vICAgICBpZiAoaXNVbmRlZmluZWQocHJvcCkpIHJldHVybiAhIXN0b3JlW2tleV0uc2l6ZVxuLy8gLy8gICAgIGVsc2UgcmV0dXJuIHN0b3JlW2tleV0uaGFzKHByb3ApXG4vLyAvLyAgIH1cbi8vIC8vICAgLyoqXG4vLyAvLyAgICAqIEBzaW5jZSAgNC4wLjBcbi8vIC8vICAgICogQHBhcmFtICB7UHJpbWl0aXZlfSBrZXlcbi8vIC8vICAgICogQHBhcmFtICB7UHJpbWl0aXZlIHwgdW5kZWZpbmVkfSBbcHJvcD11bmRlZmluZWRdXG4vLyAvLyAgICAqIEByZXR1cm4ge2FueX1cbi8vIC8vICAgICovXG4vLyAvLyAgIGNvbnN0IGdldCA9IChrZXksIHByb3ApID0+IChoYXMoa2V5LCBwcm9wKSA/IHN0b3JlW2tleV0uZ2V0KHByb3ApIDogZW1wdHlBcnJheSlcbi8vIC8vXG4vLyAvLyAgIC8qKlxuLy8gLy8gICAgKiBAc2luY2UgIDQuMC4wXG4vLyAvLyAgICAqIEBwYXJhbSAge1ByaW1pdGl2ZX0ga2V5XG4vLyAvLyAgICAqIEBwYXJhbSAge1ByaW1pdGl2ZSB8IHVuZGVmaW5lZH0gW3Byb3A9dW5kZWZpbmVkXVxuLy8gLy8gICAgKiBAcGFyYW0gIHtQcmltaXRpdmUgfCB1bmRlZmluZWR9IFt2YWx1ZT11bmRlZmluZWRdXG4vLyAvLyAgICAqIEByZXR1cm4ge3ZvaWR9XG4vLyAvLyAgICAqL1xuLy8gLy8gICBjb25zdCBzZXQgPSAoa2V5LCBwcm9wLCB2YWx1ZSkgPT4ge1xuLy8gLy8gICAgIGNvbnN0IHN0b3JhZ2UgPSBzdG9yZVtrZXldXG4vLyAvLyAgICAgLy8gd2hlbiBpdCdzIGEgc2V0LCB3ZSBoYXZlIG5vIGBwcm9wYCwgd2UganVzdCBoYXZlIC5hZGRcbi8vIC8vICAgICAvLyBzbyBgcHJvcCA9IHZhbHVlYCAmJiBgdmFsdWUgPSB1bmRlZmluZWRgXG4vLyAvLyAgICAgaWYgKGlzU2V0KHN0b3JhZ2UpKSB7XG4vLyAvLyAgICAgICBzdG9yYWdlLmFkZChwcm9wKVxuLy8gLy8gICAgIH1cbi8vIC8vICAgICBlbHNlIHtcbi8vIC8vICAgICAgIC8vIGlmICghaGFzKGtleSwgcHJvcCkpIHJldHVyblxuLy8gLy8gICAgICAgY29uc3QgZXhpc3RpbmcgPSBzdG9yYWdlLmdldChwcm9wKVxuLy8gLy8gICAgICAgY29uc3QgdmFsID0gY29uY2F0KGV4aXN0aW5nLCB2YWx1ZSlcbi8vIC8vICAgICAgIHN0b3JhZ2Uuc2V0KHByb3AsIHZhbClcbi8vIC8vICAgICB9XG4vLyAvLyAgIH1cbi8vIC8vXG4vLyAvLyAgIC8qKlxuLy8gLy8gICAgKiBAc2luY2UgNC4wLjBcbi8vIC8vICAgICpcbi8vIC8vICAgICogQGRlc2MgYSBzaW5nbGUgZWFzaWx5IG1pbmlmaWFibGUgZnVuY3Rpb24sXG4vLyAvLyAgICAqICAgICAgIGR5bmFtaWNhbGx5IHNldHRpbmcgJiBnZXR0aW5nIGRlcGVuZGluZyBvbiBhcmd1bWVudHNcbi8vIC8vICAgICogICAgICAgdG8gYXZvaWQgbmVzdGVkIHByb3BlcnR5IGFjY2Vzc2luZ1xuLy8gLy8gICAgKiAgICAgICBvbmx5IGluc3RhbnRpYXRpbmcgd2hlbiB2YWx1ZXMgYXJlICoqYWRkZGVkKipcbi8vIC8vICAgICpcbi8vIC8vICAgICogQHBhcmFtIHtQcmltaXRpdmV9IGtleVxuLy8gLy8gICAgKiBAcGFyYW0ge1ByaW1pdGl2ZSB8IHVuZGVmaW5lZH0gW3Byb3A9dW5kZWZpbmVkXVxuLy8gLy8gICAgKiBAcGFyYW0ge3VuZGVmaW5lZCB8IGFueX0gW3ZhbHVlPXVuZGVmaW5lZF0gKHdoZW4gbm8gdmFsdWUsIGl0J3MgYSBnZXR0ZXIpXG4vLyAvLyAgICAqIEByZXR1cm4ge0FycmF5IHwgQ2hhaW59IGRlcGVuZGluZyBvbiBhcmdzXG4vLyAvLyAgICAqL1xuLy8gLy8gICBmdW5jdGlvbiBtZXRhKGtleSwgcHJvcCwgdmFsdWUpIHtcbi8vIC8vICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09ICdERUJVRycpIHtcbi8vIC8vICAgICAgIGNvbnNvbGUubG9nKCdVU0lORyBNRVRBJywge2tleSwgcHJvcCwgdmFsdWV9KVxuLy8gLy8gICAgIH1cbi8vIC8vXG4vLyAvLyAgICAgLyogcHJldHRpZXItaWdub3JlICovXG4vLyAvLyAgICAgaWYgKGlzVW5kZWZpbmVkKHZhbHVlKSkge1xuLy8gLy8gICAgICAgLy8gd2hlbiB3ZSB3YW50IHRvIGp1c3QgYWNjZXNzIHRoZSBwcm9wZXJ0eSwgcmV0dXJuIGFuIGFycmF5XG4vLyAvLyAgICAgICAvLyBAZXhhbXBsZSBgLm1ldGEoJ3RyYW5zZm9ybWVycycpYFxuLy8gLy8gICAgICAgaWYgKGlzVW5kZWZpbmVkKHByb3ApKSB7XG4vLyAvLyAgICAgICAgIGlmIChpc1VuZGVmaW5lZChzdG9yZVtrZXldKSkgcmV0dXJuIGVtcHR5QXJyYXlcbi8vIC8vICAgICAgICAgZWxzZSByZXR1cm4gc3RvcmVba2V5XS5zaXplID09PSAwID8gZW1wdHlBcnJheSA6IEFycmF5RnJvbShzdG9yZVtrZXldLnZhbHVlcygpKVxuLy8gLy8gICAgICAgfVxuLy8gLy8gICAgICAgLy8gd2UgaGF2ZSBga2V5LCBwcm9wYFxuLy8gLy8gICAgICAgLy9cbi8vIC8vICAgICAgIC8vIDE6IHNob3VsZCBgcHJvcGAgYmUgYSB2YWx1ZSwgKGlzU2V0Pylcbi8vIC8vICAgICAgIGVsc2UgaWYgKGlzSW5LZXlNYXBBc1NldChrZXkpKSB7XG4vLyAvLyAgICAgICAgIGVuc3VyZUluaXRpYWxpemVkKGtleSlcbi8vIC8vICAgICAgICAgc2V0KGtleSwgcHJvcClcbi8vIC8vICAgICAgIH1cbi8vIC8vICAgICAgIC8vIDI6IHByb3AgaXMgYSBrZXksIHdlIHdhbnQgdG8gcmV0dXJuIHRoZSBbLi5dIGZvciB0aGF0IHNwZWNpZmljIHByb3BlcnR5XG4vLyAvLyAgICAgICAvLyBAZXhhbXBsZSBgLm1ldGEoJ3RyYW5zZm9ybWVycycsICdlaCcpYFxuLy8gLy8gICAgICAgZWxzZSBpZiAoaXNVbmRlZmluZWQoc3RvcmVba2V5XSkpIHJldHVybiBlbXB0eUFycmF5XG4vLyAvLyAgICAgICBlbHNlIHJldHVybiB0b2FycihnZXQoa2V5LCBwcm9wKSlcbi8vIC8vICAgICB9XG4vLyAvLyAgICAgLy8gd2UgaGF2ZSBga2V5LCBwcm9wLCB2YWx1ZWBcbi8vIC8vICAgICBlbHNlIHtcbi8vIC8vICAgICAgIGVuc3VyZUluaXRpYWxpemVkKGtleSlcbi8vIC8vICAgICAgIC8vIHdlIGhhdmUgYSB2YWx1ZSwgbGV0J3MgYWRkIGl0XG4vLyAvLyAgICAgICBzZXQoa2V5LCBwcm9wLCB2YWx1ZSlcbi8vIC8vICAgICB9XG4vLyAvLyAgICAgcmV0dXJuIF90aGlzXG4vLyAvLyAgIH1cbi8vIC8vXG4vLyAvLyAgIC8vIGZvciBkZWJ1Z2dpbmdcbi8vIC8vICAgbWV0YS5zdG9yZSA9IHN0b3JlXG4vLyAvLyAgIC8vIG1ldGEuZGVidWcgPSBmYWxzZVxuLy8gLy9cbi8vIC8vICAgcmV0dXJuIG1ldGFcbi8vIC8vIH1cbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7In0=