UNPKG

foop

Version:

interfaces that describe their intentions.

353 lines (347 loc) 23.5 kB
/** @ignore 🚧 wip */ // const toFunction = require('../cast/toFunction') // const forInUnguarded = require('../loop/each/forInUnguarded') // // function __ehs(args) { // this.__eh = 1 // } // function _ehs(args) { // __ehs.call(this) // this._eh = args // } // // const Ehs = toFunction(_ehs) // function ehs(args) { // return new _ehs(args) // } // // console.log(new Ehs(0)) // // const copy = x => forInUnguarded(x, (value, key) => x[key] = value) // // // https://h3manth.com/new/blog/2014/thisarg-in-javascript/ // // const fpChain = (...chains) => { // // function functionContext() { // // this.store = new Map() // // return this // // } // // function eh() { // // functionContext.call(this, this) // // console.log(this) // // } // // // function inherit(Parent, Child) { // // const ParentPrototype = Object.getPrototypeOf(Parent) // // Object.setPrototypeOf(Child, ParentPrototype) // // Chained.prototype = Object.create(ParentPrototype); // // Chained.prototype.constructor = Chained // // } // function _classCallCheck(instance, Constructor) { // if (!(instance instanceof Constructor)) { // throw new TypeError('Cannot call a class as a function') // } // } // // function _possibleConstructorReturn(self, _super) { // if (!self) { // throw new ReferenceError( // 'this hasn\'t been initialised - super() hasn\'t been called' // ) // } // // const call = _super.call(self) // return call && (typeof call === 'object' || typeof call === 'function') // ? call // : self // } // // function _inherits(subClass, superClass) { // if (typeof superClass !== 'function' && superClass !== null) { // throw new TypeError( // 'Super expression must either be null or a function, not ' + // typeof superClass // ) // } // subClass.prototype = Object.create(superClass && superClass.prototype, { // constructor: { // value: subClass, // enumerable: false, // writable: true, // configurable: true, // }, // }) // if (superClass) // Object.setPrototypeOf // ? Object.setPrototypeOf(subClass, superClass) // : subClass.__proto__ = superClass // // return function callForConstructor(self) { // const call = superClass.call(self) // return call && (typeof call === 'object' || typeof call === 'function') // ? call // : self // } // } // // function eh() { // console.log('what') // this.eh = true // // @NOTE this is an example of constructor returning & not using `this` // var _this = copy(this) // _this._ = 0 // return _this // } // // const _super = eh // const call = _inherits(Chained, _super) // function Chained() { // // _classCallCheck(this, Chained) // // var _this = _super.call(this) || this // var _this = call(this, _super) // // // _super.call(this) // _this.ca = true // console.log('chained') // return _this // } // var Chained = (function(_super) { // const call = _inherits(Chained, _super) // function Chained() { // // _classCallCheck(this, Chained) // // var _this = _super.call(this) || this // var _this = call(this, _super) // // // _super.call(this) // _this.ca = true // console.log('chained') // return _this // } // // return Chained // // return buble(Chained, _super) // }) // Chained = Chained(eh) // console.log(new Chained()) // console.log(protos(Chained), protos(new Chained())) // console.log({Chained}) // console.log(new Chained()) // fpChain([]) // const curry = require('./curry') // // /** // * Returns the first function passed as an argument to the second, // * allowing you to adjust arguments, run code before and after, and // * conditionally execute the original function. // * // * @memberOf fp // * @since 5.0.0-beta.5 // * // * @param {Function} fn function to wrap // * @param {Function} wrap function that wraps `fn` // * // * @symb 🍬 // * @name wrap // * // * {@link http://underscorejs.org/#wrap underscore-wrap} // * {@link https://github.com/jashkenas/underscore/blob/master/underscore.js#L909 underscore-src-wrap} // * @see {@link underscore-wrap} // * @see {@link underscore-src-wrap} // * // * @example // * // * var hello = function(name) { return "hello: " + name; }; // * hello = wrap(hello, function(func) { // * return "before, " + func("moe") + ", after"; // * }) // * // * hello() // * //=> 'before, hello: moe, after' // * // */ // function wrap(fn, wrapper) { // // this just passes `fn` into wrap... // // maybe, instead, add `pre` & `post` // // was `partial(wrapper, fn)` // return curry(3, wrapper, fn) // } // // const argumentor = require('../cast/argumentor') // const isFunction = require('../is/function') // // // @TODO maybe returning `false` will disable the function? // // or returning `noop` ? // // or anything but `nill` ? // function pre(target, subscriber) { // return curry(target.length, function() { // const args = argumentor.apply(null, arguments) // // // call subscriber // const returned = subscriber.apply(this, args) // // if (returned === false) return null // else if (isFunction(returned)) return returned // else return target.apply(this, args) // }) // } // function post(target, subscriber) { // const args = argumentor.apply(null, arguments) // const returned = target.apply(this, args) // // // also original args?? // subscriber.apply(null, returned) // } // // // http://ramdajs.com/docs/#memoizeWith // // // AND THEN, COULD JUST USE `NTH` ON RETURNED // // // HOW CAN THE SUBSCRIBERS GET THE RESULTS? // // LIKE IF WE WANT TO SEE THE RETURNED VALUE? // // // // return result from last? // // @example // // // // const pre = console.log // // const post = console.error // // const multiply = (n, factor) => n * factor // // notifyEach(pre, multiply, post) // function notifyEach(subscribers) { // return function() { // const args = arguments // const results = [] // subscribers.forEach(subscriber => { // results.push(subscriber.apply(null, arguments)) // }) // } // } // // // USE ARRAY OF OBJECTS, TO AN OBJECT WITH INDEXES AS A PROPERTY // function indexBy() {} // // // // Return a random integer between min and max (inclusive). // const random = function(min, max) { // if (isNill(max)) { // max = min // min = 0 // } // return min + Math.floor(Math.random() * (max - min + 1)) // } // // // @NOTE USES LODASH.ORDERBY // function orderByKeys(obj, orderFirst) { // const orderedObj = {} // orderFirst = orderFirst.reverse() // const keys = Object.keys(obj) // _sortBy(keys, key => orderFirst.indexOf(key)) // .reverse() // .forEach(key => { // orderedObj[key] = obj[key] // }) // return orderedObj // } // // // /** // * @example // * // * remapBy(prop('id'), [{'id': 'eh'}]) // * // * @example // * in: [ // * {id: 'eh', val: 'canada'}, // * {id: 'moose', val: 'igloo'} // * ] // * // * out: { // * 'eh': {id: 'eh', val: 'canada'}, // * 'moose': {id: 'moose', val: 'igloo'} // * } // */ // // or INDEXBY // function remapBy(transformer, vals) { // const remapped = {} // // // @TODO: should reload if there is no remap by id vals... // if (!isObj(vals)) return remapped // // var asObj = values(vals) // // // if (isArray(vals)) { // // // if it does not have the prop, add it as the index // // // if it has it, and it is an array, join it // // vals = values.map((data, i) => { // // if (!data[prop]) data[prop] = i // // if (isArray(data[prop])) data[prop] = data[prop].join(',') // // return data // // }) // // // // return arrToObj(values, { // // keyFn: ({i}) => values[i][prop], // // valFn: ({i, val}) => val, // // }) // // } // // // remap to add item id as object property // const props = keys(asObj) // for (let i = 0, len = props.length; i < len; i++) { // const key = props[i] // const val = asObj[key] // // remapped[val.id] = val // } // // console.debug('remapById', {values, asObj}) // // return remapped // } // // // function omit(obj, keys) { // const target = {} // for (let i in obj) { // if (keys.indexOf(i) >= 0 || !hasOwnProperty(obj, i)) continue // target[i] = obj[i] // } // return target // } // // // // http://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-hashcode-method/ // // module.exports = function fliphash(str) { // // // || typeof str !== 'string' // // // if (str === undefined || str === null) { // // // console.log('you passed not real value to fliphash') // // // return str // // // } // // if (isNill(str)) return 'nill' // // let len = str.length // // if (len === 0) return 0 // // // // let hash = 0 // // // // for (let i = 0; i < len; i++) { // // const char = str.charCodeAt(i) // // hash = ((hash << 5) - hash) + char // // hash = hash & hash // Convert to 32bit integer // // } // // return hash // // } // // // // const test = require('ava') // // const fliphash = require('../') // // // // test('hashes a number', t => { // // t.plan(1) // // const txt = 'ehohehoh... wayoh wayoh wayoh-wayoh!' // // t.true(typeof fliphash(txt) === 'number') // // }) // // // // test('hashes are the same', t => { // // t.plan(1) // // const txt = 'hullabaloo000&&&!!!eh' // // t.is(fliphash(txt), fliphash(txt)) // // }) // // // module.exports = curry(2, wrap) //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid3JhcC5qcyIsInNvdXJjZXMiOlsid3JhcC5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiogQGlnbm9yZSDwn5qnIHdpcCAqL1xuXG4vLyBjb25zdCB0b0Z1bmN0aW9uID0gcmVxdWlyZSgnLi4vY2FzdC90b0Z1bmN0aW9uJylcbi8vIGNvbnN0IGZvckluVW5ndWFyZGVkID0gcmVxdWlyZSgnLi4vbG9vcC9lYWNoL2ZvckluVW5ndWFyZGVkJylcbi8vXG4vLyBmdW5jdGlvbiBfX2VocyhhcmdzKSB7XG4vLyAgIHRoaXMuX19laCA9IDFcbi8vIH1cbi8vIGZ1bmN0aW9uIF9laHMoYXJncykge1xuLy8gICBfX2Vocy5jYWxsKHRoaXMpXG4vLyAgIHRoaXMuX2VoID0gYXJnc1xuLy8gfVxuLy9cbi8vIGNvbnN0IEVocyA9IHRvRnVuY3Rpb24oX2Vocylcbi8vIGZ1bmN0aW9uIGVocyhhcmdzKSB7XG4vLyAgIHJldHVybiBuZXcgX2VocyhhcmdzKVxuLy8gfVxuLy9cbi8vIGNvbnNvbGUubG9nKG5ldyBFaHMoMCkpXG4vL1xuLy8gY29uc3QgY29weSA9IHggPT4gZm9ySW5Vbmd1YXJkZWQoeCwgKHZhbHVlLCBrZXkpID0+IHhba2V5XSA9IHZhbHVlKVxuLy9cbi8vIC8vIGh0dHBzOi8vaDNtYW50aC5jb20vbmV3L2Jsb2cvMjAxNC90aGlzYXJnLWluLWphdmFzY3JpcHQvXG4vLyAvLyBjb25zdCBmcENoYWluID0gKC4uLmNoYWlucykgPT4ge1xuLy8gLy8gICBmdW5jdGlvbiBmdW5jdGlvbkNvbnRleHQoKSB7XG4vLyAvLyAgICAgdGhpcy5zdG9yZSA9IG5ldyBNYXAoKVxuLy8gLy8gICAgIHJldHVybiB0aGlzXG4vLyAvLyAgIH1cbi8vIC8vICAgZnVuY3Rpb24gZWgoKSB7XG4vLyAvLyAgICAgZnVuY3Rpb25Db250ZXh0LmNhbGwodGhpcywgdGhpcylcbi8vIC8vICAgICBjb25zb2xlLmxvZyh0aGlzKVxuLy8gLy8gICB9XG4vL1xuLy8gLy8gICBmdW5jdGlvbiBpbmhlcml0KFBhcmVudCwgQ2hpbGQpIHtcbi8vIC8vICAgICBjb25zdCBQYXJlbnRQcm90b3R5cGUgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YoUGFyZW50KVxuLy8gLy8gICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZihDaGlsZCwgUGFyZW50UHJvdG90eXBlKVxuLy8gLy8gICAgIENoYWluZWQucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShQYXJlbnRQcm90b3R5cGUpO1xuLy8gLy8gICAgIENoYWluZWQucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gQ2hhaW5lZFxuLy8gLy8gICB9XG4vLyBmdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7XG4vLyAgIGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7XG4vLyAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uJylcbi8vICAgfVxuLy8gfVxuLy9cbi8vIGZ1bmN0aW9uIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHNlbGYsIF9zdXBlcikge1xuLy8gICBpZiAoIXNlbGYpIHtcbi8vICAgICB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IoXG4vLyAgICAgICAndGhpcyBoYXNuXFwndCBiZWVuIGluaXRpYWxpc2VkIC0gc3VwZXIoKSBoYXNuXFwndCBiZWVuIGNhbGxlZCdcbi8vICAgICApXG4vLyAgIH1cbi8vXG4vLyAgIGNvbnN0IGNhbGwgPSBfc3VwZXIuY2FsbChzZWxmKVxuLy8gICByZXR1cm4gY2FsbCAmJiAodHlwZW9mIGNhbGwgPT09ICdvYmplY3QnIHx8IHR5cGVvZiBjYWxsID09PSAnZnVuY3Rpb24nKVxuLy8gICAgID8gY2FsbFxuLy8gICAgIDogc2VsZlxuLy8gfVxuLy9cbi8vIGZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykge1xuLy8gICBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICdmdW5jdGlvbicgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkge1xuLy8gICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4vLyAgICAgICAnU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAnICtcbi8vICAgICAgICAgdHlwZW9mIHN1cGVyQ2xhc3Ncbi8vICAgICApXG4vLyAgIH1cbi8vICAgc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7XG4vLyAgICAgY29uc3RydWN0b3I6IHtcbi8vICAgICAgIHZhbHVlOiBzdWJDbGFzcyxcbi8vICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuLy8gICAgICAgd3JpdGFibGU6IHRydWUsXG4vLyAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4vLyAgICAgfSxcbi8vICAgfSlcbi8vICAgaWYgKHN1cGVyQ2xhc3MpXG4vLyAgICAgT2JqZWN0LnNldFByb3RvdHlwZU9mXG4vLyAgICAgICA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcylcbi8vICAgICAgIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzc1xuLy9cbi8vICAgcmV0dXJuIGZ1bmN0aW9uIGNhbGxGb3JDb25zdHJ1Y3RvcihzZWxmKSB7XG4vLyAgICAgY29uc3QgY2FsbCA9IHN1cGVyQ2xhc3MuY2FsbChzZWxmKVxuLy8gICAgIHJldHVybiBjYWxsICYmICh0eXBlb2YgY2FsbCA9PT0gJ29iamVjdCcgfHwgdHlwZW9mIGNhbGwgPT09ICdmdW5jdGlvbicpXG4vLyAgICAgICA/IGNhbGxcbi8vICAgICAgIDogc2VsZlxuLy8gICB9XG4vLyB9XG4vL1xuLy8gZnVuY3Rpb24gZWgoKSB7XG4vLyAgIGNvbnNvbGUubG9nKCd3aGF0Jylcbi8vICAgdGhpcy5laCA9IHRydWVcbi8vICAgLy8gQE5PVEUgdGhpcyBpcyBhbiBleGFtcGxlIG9mIGNvbnN0cnVjdG9yIHJldHVybmluZyAmIG5vdCB1c2luZyBgdGhpc2Bcbi8vICAgdmFyIF90aGlzID0gY29weSh0aGlzKVxuLy8gICBfdGhpcy5fID0gMFxuLy8gICByZXR1cm4gX3RoaXNcbi8vIH1cbi8vXG4vLyBjb25zdCBfc3VwZXIgPSBlaFxuLy8gY29uc3QgY2FsbCA9IF9pbmhlcml0cyhDaGFpbmVkLCBfc3VwZXIpXG4vLyBmdW5jdGlvbiBDaGFpbmVkKCkge1xuLy8gICAvLyBfY2xhc3NDYWxsQ2hlY2sodGhpcywgQ2hhaW5lZClcbi8vICAgLy8gdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcykgfHwgdGhpc1xuLy8gICB2YXIgX3RoaXMgPSBjYWxsKHRoaXMsIF9zdXBlcilcbi8vXG4vLyAgIC8vIF9zdXBlci5jYWxsKHRoaXMpXG4vLyAgIF90aGlzLmNhID0gdHJ1ZVxuLy8gICBjb25zb2xlLmxvZygnY2hhaW5lZCcpXG4vLyAgIHJldHVybiBfdGhpc1xuLy8gfVxuXG4vLyB2YXIgQ2hhaW5lZCA9IChmdW5jdGlvbihfc3VwZXIpIHtcbi8vICAgY29uc3QgY2FsbCA9IF9pbmhlcml0cyhDaGFpbmVkLCBfc3VwZXIpXG4vLyAgIGZ1bmN0aW9uIENoYWluZWQoKSB7XG4vLyAgICAgLy8gX2NsYXNzQ2FsbENoZWNrKHRoaXMsIENoYWluZWQpXG4vLyAgICAgLy8gdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcykgfHwgdGhpc1xuLy8gICAgIHZhciBfdGhpcyA9IGNhbGwodGhpcywgX3N1cGVyKVxuLy9cbi8vICAgICAvLyBfc3VwZXIuY2FsbCh0aGlzKVxuLy8gICAgIF90aGlzLmNhID0gdHJ1ZVxuLy8gICAgIGNvbnNvbGUubG9nKCdjaGFpbmVkJylcbi8vICAgICByZXR1cm4gX3RoaXNcbi8vICAgfVxuLy9cbi8vICAgcmV0dXJuIENoYWluZWRcbi8vICAgLy8gcmV0dXJuIGJ1YmxlKENoYWluZWQsIF9zdXBlcilcbi8vIH0pXG4vLyBDaGFpbmVkID0gQ2hhaW5lZChlaClcblxuLy8gY29uc29sZS5sb2cobmV3IENoYWluZWQoKSlcbi8vIGNvbnNvbGUubG9nKHByb3RvcyhDaGFpbmVkKSwgcHJvdG9zKG5ldyBDaGFpbmVkKCkpKVxuLy8gY29uc29sZS5sb2coe0NoYWluZWR9KVxuLy8gY29uc29sZS5sb2cobmV3IENoYWluZWQoKSlcblxuLy8gZnBDaGFpbihbXSlcblxuLy8gY29uc3QgY3VycnkgPSByZXF1aXJlKCcuL2N1cnJ5Jylcbi8vXG4vLyAvKipcbi8vICAqIFJldHVybnMgdGhlIGZpcnN0IGZ1bmN0aW9uIHBhc3NlZCBhcyBhbiBhcmd1bWVudCB0byB0aGUgc2Vjb25kLFxuLy8gICogYWxsb3dpbmcgeW91IHRvIGFkanVzdCBhcmd1bWVudHMsIHJ1biBjb2RlIGJlZm9yZSBhbmQgYWZ0ZXIsIGFuZFxuLy8gICogY29uZGl0aW9uYWxseSBleGVjdXRlIHRoZSBvcmlnaW5hbCBmdW5jdGlvbi5cbi8vICAqXG4vLyAgKiBAbWVtYmVyT2YgZnBcbi8vICAqIEBzaW5jZSA1LjAuMC1iZXRhLjVcbi8vICAqXG4vLyAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBmdW5jdGlvbiB0byB3cmFwXG4vLyAgKiBAcGFyYW0ge0Z1bmN0aW9ufSB3cmFwIGZ1bmN0aW9uIHRoYXQgd3JhcHMgYGZuYFxuLy8gICpcbi8vICAqIEBzeW1iIPCfjaxcbi8vICAqIEBuYW1lIHdyYXBcbi8vICAqXG4vLyAgKiB7QGxpbmsgaHR0cDovL3VuZGVyc2NvcmVqcy5vcmcvI3dyYXAgdW5kZXJzY29yZS13cmFwfVxuLy8gICoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS9qYXNoa2VuYXMvdW5kZXJzY29yZS9ibG9iL21hc3Rlci91bmRlcnNjb3JlLmpzI0w5MDkgdW5kZXJzY29yZS1zcmMtd3JhcH1cbi8vICAqIEBzZWUge0BsaW5rIHVuZGVyc2NvcmUtd3JhcH1cbi8vICAqIEBzZWUge0BsaW5rIHVuZGVyc2NvcmUtc3JjLXdyYXB9XG4vLyAgKlxuLy8gICogQGV4YW1wbGVcbi8vICAqXG4vLyAgKiAgIHZhciBoZWxsbyA9IGZ1bmN0aW9uKG5hbWUpIHsgcmV0dXJuIFwiaGVsbG86IFwiICsgbmFtZTsgfTtcbi8vICAqICAgaGVsbG8gPSB3cmFwKGhlbGxvLCBmdW5jdGlvbihmdW5jKSB7XG4vLyAgKiAgICAgcmV0dXJuIFwiYmVmb3JlLCBcIiArIGZ1bmMoXCJtb2VcIikgKyBcIiwgYWZ0ZXJcIjtcbi8vICAqICAgfSlcbi8vICAqXG4vLyAgKiAgIGhlbGxvKClcbi8vICAqICAgLy89PiAnYmVmb3JlLCBoZWxsbzogbW9lLCBhZnRlcidcbi8vICAqXG4vLyAgKi9cbi8vIGZ1bmN0aW9uIHdyYXAoZm4sIHdyYXBwZXIpIHtcbi8vICAgLy8gdGhpcyBqdXN0IHBhc3NlcyBgZm5gIGludG8gd3JhcC4uLlxuLy8gICAvLyBtYXliZSwgaW5zdGVhZCwgYWRkIGBwcmVgICYgYHBvc3RgXG4vLyAgIC8vIHdhcyBgcGFydGlhbCh3cmFwcGVyLCBmbilgXG4vLyAgIHJldHVybiBjdXJyeSgzLCB3cmFwcGVyLCBmbilcbi8vIH1cbi8vXG4vLyBjb25zdCBhcmd1bWVudG9yID0gcmVxdWlyZSgnLi4vY2FzdC9hcmd1bWVudG9yJylcbi8vIGNvbnN0IGlzRnVuY3Rpb24gPSByZXF1aXJlKCcuLi9pcy9mdW5jdGlvbicpXG4vL1xuLy8gLy8gQFRPRE8gbWF5YmUgcmV0dXJuaW5nIGBmYWxzZWAgd2lsbCBkaXNhYmxlIHRoZSBmdW5jdGlvbj9cbi8vIC8vICAgICAgIG9yIHJldHVybmluZyBgbm9vcGAgP1xuLy8gLy8gICAgICAgb3IgYW55dGhpbmcgYnV0IGBuaWxsYCA/XG4vLyBmdW5jdGlvbiBwcmUodGFyZ2V0LCBzdWJzY3JpYmVyKSB7XG4vLyAgIHJldHVybiBjdXJyeSh0YXJnZXQubGVuZ3RoLCBmdW5jdGlvbigpIHtcbi8vICAgICBjb25zdCBhcmdzID0gYXJndW1lbnRvci5hcHBseShudWxsLCBhcmd1bWVudHMpXG4vL1xuLy8gICAgIC8vIGNhbGwgc3Vic2NyaWJlclxuLy8gICAgIGNvbnN0IHJldHVybmVkID0gc3Vic2NyaWJlci5hcHBseSh0aGlzLCBhcmdzKVxuLy9cbi8vICAgICBpZiAocmV0dXJuZWQgPT09IGZhbHNlKSByZXR1cm4gbnVsbFxuLy8gICAgIGVsc2UgaWYgKGlzRnVuY3Rpb24ocmV0dXJuZWQpKSByZXR1cm4gcmV0dXJuZWRcbi8vICAgICBlbHNlIHJldHVybiB0YXJnZXQuYXBwbHkodGhpcywgYXJncylcbi8vICAgfSlcbi8vIH1cbi8vIGZ1bmN0aW9uIHBvc3QodGFyZ2V0LCBzdWJzY3JpYmVyKSB7XG4vLyAgIGNvbnN0IGFyZ3MgPSBhcmd1bWVudG9yLmFwcGx5KG51bGwsIGFyZ3VtZW50cylcbi8vICAgY29uc3QgcmV0dXJuZWQgPSB0YXJnZXQuYXBwbHkodGhpcywgYXJncylcbi8vXG4vLyAgIC8vIGFsc28gb3JpZ2luYWwgYXJncz8/XG4vLyAgIHN1YnNjcmliZXIuYXBwbHkobnVsbCwgcmV0dXJuZWQpXG4vLyB9XG4vL1xuLy8gLy8gaHR0cDovL3JhbWRhanMuY29tL2RvY3MvI21lbW9pemVXaXRoXG4vL1xuLy8gLy8gQU5EIFRIRU4sIENPVUxEIEpVU1QgVVNFIGBOVEhgIE9OIFJFVFVSTkVEXG4vL1xuLy8gLy8gSE9XIENBTiBUSEUgU1VCU0NSSUJFUlMgR0VUIFRIRSBSRVNVTFRTP1xuLy8gLy8gTElLRSBJRiBXRSBXQU5UIFRPIFNFRSBUSEUgUkVUVVJORUQgVkFMVUU/XG4vLyAvL1xuLy8gLy8gcmV0dXJuIHJlc3VsdCBmcm9tIGxhc3Q/XG4vLyAvLyBAZXhhbXBsZVxuLy8gLy9cbi8vIC8vICBjb25zdCBwcmUgPSBjb25zb2xlLmxvZ1xuLy8gLy8gIGNvbnN0IHBvc3QgPSBjb25zb2xlLmVycm9yXG4vLyAvLyAgY29uc3QgbXVsdGlwbHkgPSAobiwgZmFjdG9yKSA9PiBuICogZmFjdG9yXG4vLyAvLyAgbm90aWZ5RWFjaChwcmUsIG11bHRpcGx5LCBwb3N0KVxuLy8gZnVuY3Rpb24gbm90aWZ5RWFjaChzdWJzY3JpYmVycykge1xuLy8gICByZXR1cm4gZnVuY3Rpb24oKSB7XG4vLyAgICAgY29uc3QgYXJncyA9IGFyZ3VtZW50c1xuLy8gICAgIGNvbnN0IHJlc3VsdHMgPSBbXVxuLy8gICAgIHN1YnNjcmliZXJzLmZvckVhY2goc3Vic2NyaWJlciA9PiB7XG4vLyAgICAgICByZXN1bHRzLnB1c2goc3Vic2NyaWJlci5hcHBseShudWxsLCBhcmd1bWVudHMpKVxuLy8gICAgIH0pXG4vLyAgIH1cbi8vIH1cbi8vXG4vLyAvLyBVU0UgQVJSQVkgT0YgT0JKRUNUUywgVE8gQU4gT0JKRUNUIFdJVEggSU5ERVhFUyBBUyBBIFBST1BFUlRZXG4vLyBmdW5jdGlvbiBpbmRleEJ5KCkge31cbi8vXG4vL1xuLy8gLy8gUmV0dXJuIGEgcmFuZG9tIGludGVnZXIgYmV0d2VlbiBtaW4gYW5kIG1heCAoaW5jbHVzaXZlKS5cbi8vIGNvbnN0IHJhbmRvbSA9IGZ1bmN0aW9uKG1pbiwgbWF4KSB7XG4vLyAgIGlmIChpc05pbGwobWF4KSkge1xuLy8gICAgIG1heCA9IG1pblxuLy8gICAgIG1pbiA9IDBcbi8vICAgfVxuLy8gICByZXR1cm4gbWluICsgTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogKG1heCAtIG1pbiArIDEpKVxuLy8gfVxuLy9cbi8vIC8vIEBOT1RFIFVTRVMgTE9EQVNILk9SREVSQllcbi8vIGZ1bmN0aW9uIG9yZGVyQnlLZXlzKG9iaiwgb3JkZXJGaXJzdCkge1xuLy8gICBjb25zdCBvcmRlcmVkT2JqID0ge31cbi8vICAgb3JkZXJGaXJzdCA9IG9yZGVyRmlyc3QucmV2ZXJzZSgpXG4vLyAgIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhvYmopXG4vLyAgIF9zb3J0Qnkoa2V5cywga2V5ID0+IG9yZGVyRmlyc3QuaW5kZXhPZihrZXkpKVxuLy8gICAgIC5yZXZlcnNlKClcbi8vICAgICAuZm9yRWFjaChrZXkgPT4ge1xuLy8gICAgICAgb3JkZXJlZE9ialtrZXldID0gb2JqW2tleV1cbi8vICAgICB9KVxuLy8gICByZXR1cm4gb3JkZXJlZE9ialxuLy8gfVxuLy9cbi8vXG4vLyAvKipcbi8vICAqIEBleGFtcGxlXG4vLyAgKlxuLy8gICogcmVtYXBCeShwcm9wKCdpZCcpLCBbeydpZCc6ICdlaCd9XSlcbi8vICAqXG4vLyAgKiBAZXhhbXBsZVxuLy8gICogaW46IFtcbi8vICAqICB7aWQ6ICdlaCcsIHZhbDogJ2NhbmFkYSd9LFxuLy8gICogIHtpZDogJ21vb3NlJywgdmFsOiAnaWdsb28nfVxuLy8gICogXVxuLy8gICpcbi8vICAqIG91dDoge1xuLy8gICogICdlaCc6IHtpZDogJ2VoJywgdmFsOiAnY2FuYWRhJ30sXG4vLyAgKiAgJ21vb3NlJzoge2lkOiAnbW9vc2UnLCB2YWw6ICdpZ2xvbyd9XG4vLyAgKiB9XG4vLyAgKi9cbi8vIC8vIG9yIElOREVYQllcbi8vIGZ1bmN0aW9uIHJlbWFwQnkodHJhbnNmb3JtZXIsIHZhbHMpIHtcbi8vICAgY29uc3QgcmVtYXBwZWQgPSB7fVxuLy9cbi8vICAgLy8gQFRPRE86IHNob3VsZCByZWxvYWQgaWYgdGhlcmUgaXMgbm8gcmVtYXAgYnkgaWQgdmFscy4uLlxuLy8gICBpZiAoIWlzT2JqKHZhbHMpKSByZXR1cm4gcmVtYXBwZWRcbi8vXG4vLyAgIHZhciBhc09iaiA9IHZhbHVlcyh2YWxzKVxuLy9cbi8vICAgLy8gaWYgKGlzQXJyYXkodmFscykpIHtcbi8vICAgLy8gICAvLyBpZiBpdCBkb2VzIG5vdCBoYXZlIHRoZSBwcm9wLCBhZGQgaXQgYXMgdGhlIGluZGV4XG4vLyAgIC8vICAgLy8gaWYgaXQgaGFzIGl0LCBhbmQgaXQgaXMgYW4gYXJyYXksIGpvaW4gaXRcbi8vICAgLy8gICB2YWxzID0gdmFsdWVzLm1hcCgoZGF0YSwgaSkgPT4ge1xuLy8gICAvLyAgICAgaWYgKCFkYXRhW3Byb3BdKSBkYXRhW3Byb3BdID0gaVxuLy8gICAvLyAgICAgaWYgKGlzQXJyYXkoZGF0YVtwcm9wXSkpIGRhdGFbcHJvcF0gPSBkYXRhW3Byb3BdLmpvaW4oJywnKVxuLy8gICAvLyAgICAgcmV0dXJuIGRhdGFcbi8vICAgLy8gICB9KVxuLy8gICAvL1xuLy8gICAvLyAgIHJldHVybiBhcnJUb09iaih2YWx1ZXMsIHtcbi8vICAgLy8gICAgIGtleUZuOiAoe2l9KSA9PiB2YWx1ZXNbaV1bcHJvcF0sXG4vLyAgIC8vICAgICB2YWxGbjogKHtpLCB2YWx9KSA9PiB2YWwsXG4vLyAgIC8vICAgfSlcbi8vICAgLy8gfVxuLy9cbi8vICAgLy8gcmVtYXAgdG8gYWRkIGl0ZW0gaWQgYXMgb2JqZWN0IHByb3BlcnR5XG4vLyAgIGNvbnN0IHByb3BzID0ga2V5cyhhc09iailcbi8vICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IHByb3BzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4vLyAgICAgY29uc3Qga2V5ID0gcHJvcHNbaV1cbi8vICAgICBjb25zdCB2YWwgPSBhc09ialtrZXldXG4vL1xuLy8gICAgIHJlbWFwcGVkW3ZhbC5pZF0gPSB2YWxcbi8vICAgfVxuLy8gICAvLyBjb25zb2xlLmRlYnVnKCdyZW1hcEJ5SWQnLCB7dmFsdWVzLCBhc09ian0pXG4vL1xuLy8gICByZXR1cm4gcmVtYXBwZWRcbi8vIH1cbi8vXG4vL1xuLy8gZnVuY3Rpb24gb21pdChvYmosIGtleXMpIHtcbi8vICAgY29uc3QgdGFyZ2V0ID0ge31cbi8vICAgZm9yIChsZXQgaSBpbiBvYmopIHtcbi8vICAgICBpZiAoa2V5cy5pbmRleE9mKGkpID49IDAgfHwgIWhhc093blByb3BlcnR5KG9iaiwgaSkpIGNvbnRpbnVlXG4vLyAgICAgdGFyZ2V0W2ldID0gb2JqW2ldXG4vLyAgIH1cbi8vICAgcmV0dXJuIHRhcmdldFxuLy8gfVxuLy9cbi8vXG4vLyAvLyBodHRwOi8vd2VyeGx0ZC5jb20vd3AvMjAxMC8wNS8xMy9qYXZhc2NyaXB0LWltcGxlbWVudGF0aW9uLW9mLWphdmFzLXN0cmluZy1oYXNoY29kZS1tZXRob2QvXG4vLyAvLyBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGZsaXBoYXNoKHN0cikge1xuLy8gLy8gICAvLyAgfHwgdHlwZW9mIHN0ciAhPT0gJ3N0cmluZydcbi8vIC8vICAgLy8gaWYgKHN0ciA9PT0gdW5kZWZpbmVkIHx8IHN0ciA9PT0gbnVsbCkge1xuLy8gLy8gICAvLyAgIGNvbnNvbGUubG9nKCd5b3UgcGFzc2VkIG5vdCByZWFsIHZhbHVlIHRvIGZsaXBoYXNoJylcbi8vIC8vICAgLy8gICByZXR1cm4gc3RyXG4vLyAvLyAgIC8vIH1cbi8vIC8vICAgaWYgKGlzTmlsbChzdHIpKSByZXR1cm4gJ25pbGwnXG4vLyAvLyAgIGxldCBsZW4gPSBzdHIubGVuZ3RoXG4vLyAvLyAgIGlmIChsZW4gPT09IDApIHJldHVybiAwXG4vLyAvL1xuLy8gLy8gICBsZXQgaGFzaCA9IDBcbi8vIC8vXG4vLyAvLyAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbi8vIC8vICAgICBjb25zdCBjaGFyID0gc3RyLmNoYXJDb2RlQXQoaSlcbi8vIC8vICAgICBoYXNoID0gKChoYXNoIDw8IDUpIC0gaGFzaCkgKyBjaGFyXG4vLyAvLyAgICAgaGFzaCA9IGhhc2ggJiBoYXNoIC8vIENvbnZlcnQgdG8gMzJiaXQgaW50ZWdlclxuLy8gLy8gICB9XG4vLyAvLyAgIHJldHVybiBoYXNoXG4vLyAvLyB9XG4vLyAvL1xuLy8gLy8gY29uc3QgdGVzdCA9IHJlcXVpcmUoJ2F2YScpXG4vLyAvLyBjb25zdCBmbGlwaGFzaCA9IHJlcXVpcmUoJy4uLycpXG4vLyAvL1xuLy8gLy8gdGVzdCgnaGFzaGVzIGEgbnVtYmVyJywgdCA9PiB7XG4vLyAvLyAgIHQucGxhbigxKVxuLy8gLy8gICBjb25zdCB0eHQgPSAnZWhvaGVob2guLi4gd2F5b2ggd2F5b2ggd2F5b2gtd2F5b2ghJ1xuLy8gLy8gICB0LnRydWUodHlwZW9mIGZsaXBoYXNoKHR4dCkgPT09ICdudW1iZXInKVxuLy8gLy8gfSlcbi8vIC8vXG4vLyAvLyB0ZXN0KCdoYXNoZXMgYXJlIHRoZSBzYW1lJywgdCA9PiB7XG4vLyAvLyAgIHQucGxhbigxKVxuLy8gLy8gICBjb25zdCB0eHQgPSAnaHVsbGFiYWxvbzAwMCYmJiEhIWVoJ1xuLy8gLy8gICB0LmlzKGZsaXBoYXNoKHR4dCksIGZsaXBoYXNoKHR4dCkpXG4vLyAvLyB9KVxuLy9cbi8vXG4vLyBtb2R1bGUuZXhwb3J0cyA9IGN1cnJ5KDIsIHdyYXApXG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsifQ==