UNPKG

foop

Version:

interfaces that describe their intentions.

178 lines (160 loc) 14.2 kB
/** * @name matcher * @member matcher * @see https://github.com/sindresorhus/matcher/blob/master/index.js * @symb 🎯 * @types matcher * @tests deps/matcher */ var ObjectAssign = require('../util/assign') var isMatcher = require('../is/matcher') var cache = require('../cache') var toarr = require('../to-arr') var newRegExp = require('../construct/regexp') var pipe = require('../fp/pipeTwo') var toEscapedRegExp = require('../cast/toRegExp') var replaceEscapedStar = require('../string/escapedToDotStar') var escapeStringRegExp = require('../string/escapeRegExp') var esc = pipe(escapeStringRegExp, replaceEscapedStar) var m = {} /** * @desc turn any string[], function[], or RegExp[] into a matcher * @memberOf matcher * @since 3.0.0 * @func make * * @param {Array<string> | string | Function | RegExp} pattern a matchable pattern * @param {boolean | undefined} shouldNegate turn into a negated regex * @param {boolean | undefined} alphaOmega should have regex start at the beginning and the end * @return {Array<string> | string | Function | RegExp} matchable * * @example * * matcher.make('*') * //=> RegExp('.*', 'i') * * @example * * var any = new RgExp('.*', 'i') * matcher.make(any) * //=> any * * @example * * var strings = x => typeof x === 'string' * matcher.make(strings) * //=> {test: strings} * * @example * * var tester = {test: x => x === true} * matcher.make(tester) * //=> tester * * @example * * var noName = '!name' * matcher.make(noName, true) * //=> new RegExp('(?:name)', 'i') * * @example * * var noName = '!name' * matcher.make(noName, true, true) * //=> new RegExp('^(?:name)$', 'i') * */ m.make = function (pattern, shouldNegate, alphaOmega) { if (cache.has(pattern)) { return cache.get(pattern) } var matchable = pattern if (isMatcher(matchable) && !matchable.test) { matchable.test = matchable } if (isMatcher(matchable)) { return matchable } // if (!matchable) { // console.log({pattern, shouldNegate, alphaOmega}) // throw new Error('eh') // } var negated = matchable[0] === '!' if (negated) { matchable = matchable.slice(1) } matchable = esc(matchable) if (negated && shouldNegate) { matchable = "(?!" + matchable + ")" } if (alphaOmega) { matchable = "^" + matchable + "$" } matchable = newRegExp(("" + matchable), 'i') matchable.negated = negated cache.set(pattern, matchable) return matchable } /** * @desc same as .make but also accepts inputs, and returns an array * @memberOf matcher * @func match * @since 3.0.0 * * @param {Array<string> | string} inputs input to use patterns as predicates on * @param {Array<string> | string | Function | RegExp} patterns predicates to match with, transformed to Matcher * @param {boolean | undefined} shouldNegate should negate, passed to matcher.make * @param {boolean | undefined} alphaOmega should enforce regex @beginning and end, passed to .matcher * @return {Array<any>} * * @see Matcher.make * @see compose/Observe * * @example * * * matcher(['foo', 'bar', 'moo'], ['*oo', '!foo']); * //=> ['moo'] * * matcher(['foo', 'bar', 'moo'], ['!*oo']); * * * @example * * * matcher('kinga', 'kinga') * //=> ['kinga'] * matcher('k*nga', 'kinga') * //=> ['kinga'] * matcher('kinga', 'nope') * //=> [] * * matcher(new RegExp(/kinga/), 'kinga') * //=> ['kinga'] * matcher(new RegExp(/kinga/), 'nope') * //=> ['nope'] * * matcher(x => x === 'kinga', 'kinga') * //=> ['kinga'] * matcher(x => x === 'kinga', 'nope') * //=> [] * * matcher({test: x => x === 'kinga'}, 'kinga') * //=> ['kinga'] * matcher({test: x => x === 'kinga'}, 'nope') * //=> [] * * */ m.matcher = function (inputs, patterns, shouldNegate, alphaOmega) { patterns = toarr(patterns).map(function (p) { return m.make(p, shouldNegate, alphaOmega); }) inputs = toarr(inputs) var firstNegated = patterns[0].negated var matchesToReturn = [] for (var i = 0; i < inputs.length; i++) { var input = inputs[i] // If first pattern is negated we include everything to match user expectation var matches = firstNegated for (var j = 0; j < patterns.length; j++) { if (patterns[j].test(input)) { matches = !patterns[j].negated } } if (matches) { matchesToReturn.push(input) } } return matchesToReturn } /** * @TODO replace to-test */ // m.test = (inputs, patterns) => m.matcher(inputs, patterns).length !== 0 module.exports = ObjectAssign(m.matcher, m) //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWF0Y2hlci5qcyIsInNvdXJjZXMiOlsibWF0Y2hlci5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBuYW1lIG1hdGNoZXJcbiAqIEBtZW1iZXIgbWF0Y2hlclxuICogQHNlZSBodHRwczovL2dpdGh1Yi5jb20vc2luZHJlc29yaHVzL21hdGNoZXIvYmxvYi9tYXN0ZXIvaW5kZXguanNcbiAqIEBzeW1iIPCfjq9cbiAqIEB0eXBlcyBtYXRjaGVyXG4gKiBAdGVzdHMgZGVwcy9tYXRjaGVyXG4gKi9cblxuY29uc3QgT2JqZWN0QXNzaWduID0gcmVxdWlyZSgnLi4vdXRpbC9hc3NpZ24nKVxuY29uc3QgaXNNYXRjaGVyID0gcmVxdWlyZSgnLi4vaXMvbWF0Y2hlcicpXG5jb25zdCBjYWNoZSA9IHJlcXVpcmUoJy4uL2NhY2hlJylcbmNvbnN0IHRvYXJyID0gcmVxdWlyZSgnLi4vdG8tYXJyJylcbmNvbnN0IG5ld1JlZ0V4cCA9IHJlcXVpcmUoJy4uL2NvbnN0cnVjdC9yZWdleHAnKVxuY29uc3QgcGlwZSA9IHJlcXVpcmUoJy4uL2ZwL3BpcGVUd28nKVxuY29uc3QgdG9Fc2NhcGVkUmVnRXhwID0gcmVxdWlyZSgnLi4vY2FzdC90b1JlZ0V4cCcpXG5jb25zdCByZXBsYWNlRXNjYXBlZFN0YXIgPSByZXF1aXJlKCcuLi9zdHJpbmcvZXNjYXBlZFRvRG90U3RhcicpXG5jb25zdCBlc2NhcGVTdHJpbmdSZWdFeHAgPSByZXF1aXJlKCcuLi9zdHJpbmcvZXNjYXBlUmVnRXhwJylcblxuY29uc3QgZXNjID0gcGlwZShlc2NhcGVTdHJpbmdSZWdFeHAsIHJlcGxhY2VFc2NhcGVkU3RhcilcblxuY29uc3QgbSA9IHt9XG5cbi8qKlxuICogQGRlc2MgdHVybiBhbnkgc3RyaW5nW10sIGZ1bmN0aW9uW10sIG9yIFJlZ0V4cFtdIGludG8gYSBtYXRjaGVyXG4gKiBAbWVtYmVyT2YgbWF0Y2hlclxuICogQHNpbmNlIDMuMC4wXG4gKiBAZnVuYyBtYWtlXG4gKlxuICogQHBhcmFtICB7QXJyYXk8c3RyaW5nPiB8IHN0cmluZyB8IEZ1bmN0aW9uIHwgUmVnRXhwfSBwYXR0ZXJuIGEgbWF0Y2hhYmxlIHBhdHRlcm5cbiAqIEBwYXJhbSAge2Jvb2xlYW4gfCB1bmRlZmluZWR9IHNob3VsZE5lZ2F0ZSB0dXJuIGludG8gYSBuZWdhdGVkIHJlZ2V4XG4gKiBAcGFyYW0gIHtib29sZWFuIHwgdW5kZWZpbmVkfSBhbHBoYU9tZWdhIHNob3VsZCBoYXZlIHJlZ2V4IHN0YXJ0IGF0IHRoZSBiZWdpbm5pbmcgYW5kIHRoZSBlbmRcbiAqIEByZXR1cm4ge0FycmF5PHN0cmluZz4gfCBzdHJpbmcgfCBGdW5jdGlvbiB8IFJlZ0V4cH0gbWF0Y2hhYmxlXG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKiAgICBtYXRjaGVyLm1ha2UoJyonKVxuICogICAgLy89PiBSZWdFeHAoJy4qJywgJ2knKVxuICpcbiAqIEBleGFtcGxlXG4gKlxuICogICAgdmFyIGFueSA9IG5ldyBSZ0V4cCgnLionLCAnaScpXG4gKiAgICBtYXRjaGVyLm1ha2UoYW55KVxuICogICAgLy89PiBhbnlcbiAqXG4gKiBAZXhhbXBsZVxuICpcbiAqICAgIHZhciBzdHJpbmdzID0geCA9PiB0eXBlb2YgeCA9PT0gJ3N0cmluZydcbiAqICAgIG1hdGNoZXIubWFrZShzdHJpbmdzKVxuICogICAgLy89PiB7dGVzdDogc3RyaW5nc31cbiAqXG4gKiBAZXhhbXBsZVxuICpcbiAqICAgIHZhciB0ZXN0ZXIgPSB7dGVzdDogeCA9PiB4ID09PSB0cnVlfVxuICogICAgbWF0Y2hlci5tYWtlKHRlc3RlcilcbiAqICAgIC8vPT4gdGVzdGVyXG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKiAgICB2YXIgbm9OYW1lID0gJyFuYW1lJ1xuICogICAgbWF0Y2hlci5tYWtlKG5vTmFtZSwgdHJ1ZSlcbiAqICAgIC8vPT4gbmV3IFJlZ0V4cCgnKD86bmFtZSknLCAnaScpXG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKiAgICB2YXIgbm9OYW1lID0gJyFuYW1lJ1xuICogICAgbWF0Y2hlci5tYWtlKG5vTmFtZSwgdHJ1ZSwgdHJ1ZSlcbiAqICAgIC8vPT4gbmV3IFJlZ0V4cCgnXig/Om5hbWUpJCcsICdpJylcbiAqXG4gKi9cbm0ubWFrZSA9IChwYXR0ZXJuLCBzaG91bGROZWdhdGUsIGFscGhhT21lZ2EpID0+IHtcbiAgaWYgKGNhY2hlLmhhcyhwYXR0ZXJuKSkgcmV0dXJuIGNhY2hlLmdldChwYXR0ZXJuKVxuXG4gIGxldCBtYXRjaGFibGUgPSBwYXR0ZXJuXG4gIGlmIChpc01hdGNoZXIobWF0Y2hhYmxlKSAmJiAhbWF0Y2hhYmxlLnRlc3QpIG1hdGNoYWJsZS50ZXN0ID0gbWF0Y2hhYmxlXG4gIGlmIChpc01hdGNoZXIobWF0Y2hhYmxlKSkgcmV0dXJuIG1hdGNoYWJsZVxuXG4gIC8vIGlmICghbWF0Y2hhYmxlKSB7XG4gIC8vICAgY29uc29sZS5sb2coe3BhdHRlcm4sIHNob3VsZE5lZ2F0ZSwgYWxwaGFPbWVnYX0pXG4gIC8vICAgdGhyb3cgbmV3IEVycm9yKCdlaCcpXG4gIC8vIH1cbiAgbGV0IG5lZ2F0ZWQgPSBtYXRjaGFibGVbMF0gPT09ICchJ1xuICBpZiAobmVnYXRlZCkgbWF0Y2hhYmxlID0gbWF0Y2hhYmxlLnNsaWNlKDEpXG5cbiAgbWF0Y2hhYmxlID0gZXNjKG1hdGNoYWJsZSlcblxuICBpZiAobmVnYXRlZCAmJiBzaG91bGROZWdhdGUpIG1hdGNoYWJsZSA9IGAoPyEke21hdGNoYWJsZX0pYFxuICBpZiAoYWxwaGFPbWVnYSkgbWF0Y2hhYmxlID0gYF4ke21hdGNoYWJsZX0kYFxuXG4gIG1hdGNoYWJsZSA9IG5ld1JlZ0V4cChgJHttYXRjaGFibGV9YCwgJ2knKVxuICBtYXRjaGFibGUubmVnYXRlZCA9IG5lZ2F0ZWRcblxuICBjYWNoZS5zZXQocGF0dGVybiwgbWF0Y2hhYmxlKVxuICByZXR1cm4gbWF0Y2hhYmxlXG59XG5cbi8qKlxuICogQGRlc2Mgc2FtZSBhcyAubWFrZSBidXQgYWxzbyBhY2NlcHRzIGlucHV0cywgYW5kIHJldHVybnMgYW4gYXJyYXlcbiAqIEBtZW1iZXJPZiBtYXRjaGVyXG4gKiBAZnVuYyBtYXRjaFxuICogQHNpbmNlIDMuMC4wXG4gKlxuICogQHBhcmFtICB7QXJyYXk8c3RyaW5nPiB8IHN0cmluZ30gaW5wdXRzIGlucHV0IHRvIHVzZSBwYXR0ZXJucyBhcyBwcmVkaWNhdGVzIG9uXG4gKiBAcGFyYW0gIHtBcnJheTxzdHJpbmc+IHwgc3RyaW5nIHwgRnVuY3Rpb24gfCBSZWdFeHB9IHBhdHRlcm5zIHByZWRpY2F0ZXMgdG8gbWF0Y2ggd2l0aCwgdHJhbnNmb3JtZWQgdG8gTWF0Y2hlclxuICogQHBhcmFtICB7Ym9vbGVhbiB8IHVuZGVmaW5lZH0gc2hvdWxkTmVnYXRlIHNob3VsZCBuZWdhdGUsIHBhc3NlZCB0byBtYXRjaGVyLm1ha2VcbiAqIEBwYXJhbSAge2Jvb2xlYW4gfCB1bmRlZmluZWR9IGFscGhhT21lZ2Egc2hvdWxkIGVuZm9yY2UgcmVnZXggQGJlZ2lubmluZyBhbmQgZW5kLCBwYXNzZWQgdG8gLm1hdGNoZXJcbiAqIEByZXR1cm4ge0FycmF5PGFueT59XG4gKlxuICogQHNlZSBNYXRjaGVyLm1ha2VcbiAqIEBzZWUgY29tcG9zZS9PYnNlcnZlXG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKlxuICogICBtYXRjaGVyKFsnZm9vJywgJ2JhcicsICdtb28nXSwgWycqb28nLCAnIWZvbyddKTtcbiAqICAgLy89PiBbJ21vbyddXG4gKlxuICogICBtYXRjaGVyKFsnZm9vJywgJ2JhcicsICdtb28nXSwgWychKm9vJ10pO1xuICpcbiAqXG4gKiBAZXhhbXBsZVxuICpcbiAqXG4gKiAgIG1hdGNoZXIoJ2tpbmdhJywgJ2tpbmdhJylcbiAqICAgLy89PiBbJ2tpbmdhJ11cbiAqICAgbWF0Y2hlcignaypuZ2EnLCAna2luZ2EnKVxuICogICAvLz0+IFsna2luZ2EnXVxuICogICBtYXRjaGVyKCdraW5nYScsICdub3BlJylcbiAqICAgLy89PiBbXVxuICpcbiAqICAgbWF0Y2hlcihuZXcgUmVnRXhwKC9raW5nYS8pLCAna2luZ2EnKVxuICogICAvLz0+IFsna2luZ2EnXVxuICogICBtYXRjaGVyKG5ldyBSZWdFeHAoL2tpbmdhLyksICdub3BlJylcbiAqICAgLy89PiBbJ25vcGUnXVxuICpcbiAqICAgbWF0Y2hlcih4ID0+IHggPT09ICdraW5nYScsICdraW5nYScpXG4gKiAgIC8vPT4gWydraW5nYSddXG4gKiAgIG1hdGNoZXIoeCA9PiB4ID09PSAna2luZ2EnLCAnbm9wZScpXG4gKiAgIC8vPT4gW11cbiAqXG4gKiAgIG1hdGNoZXIoe3Rlc3Q6IHggPT4geCA9PT0gJ2tpbmdhJ30sICdraW5nYScpXG4gKiAgIC8vPT4gWydraW5nYSddXG4gKiAgIG1hdGNoZXIoe3Rlc3Q6IHggPT4geCA9PT0gJ2tpbmdhJ30sICdub3BlJylcbiAqICAgLy89PiBbXVxuICpcbiAqXG4gKi9cbm0ubWF0Y2hlciA9IChpbnB1dHMsIHBhdHRlcm5zLCBzaG91bGROZWdhdGUsIGFscGhhT21lZ2EpID0+IHtcbiAgcGF0dGVybnMgPSB0b2FycihwYXR0ZXJucykubWFwKHAgPT4gbS5tYWtlKHAsIHNob3VsZE5lZ2F0ZSwgYWxwaGFPbWVnYSkpXG4gIGlucHV0cyA9IHRvYXJyKGlucHV0cylcblxuICBjb25zdCBmaXJzdE5lZ2F0ZWQgPSBwYXR0ZXJuc1swXS5uZWdhdGVkXG4gIGNvbnN0IG1hdGNoZXNUb1JldHVybiA9IFtdXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBpbnB1dHMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBpbnB1dCA9IGlucHV0c1tpXVxuICAgIC8vIElmIGZpcnN0IHBhdHRlcm4gaXMgbmVnYXRlZCB3ZSBpbmNsdWRlIGV2ZXJ5dGhpbmcgdG8gbWF0Y2ggdXNlciBleHBlY3RhdGlvblxuICAgIGxldCBtYXRjaGVzID0gZmlyc3ROZWdhdGVkXG4gICAgZm9yIChsZXQgaiA9IDA7IGogPCBwYXR0ZXJucy5sZW5ndGg7IGorKykge1xuICAgICAgaWYgKHBhdHRlcm5zW2pdLnRlc3QoaW5wdXQpKSB7XG4gICAgICAgIG1hdGNoZXMgPSAhcGF0dGVybnNbal0ubmVnYXRlZFxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChtYXRjaGVzKSBtYXRjaGVzVG9SZXR1cm4ucHVzaChpbnB1dClcbiAgfVxuXG4gIHJldHVybiBtYXRjaGVzVG9SZXR1cm5cbn1cblxuLyoqXG4gKiBAVE9ETyByZXBsYWNlIHRvLXRlc3RcbiAqL1xuLy8gbS50ZXN0ID0gKGlucHV0cywgcGF0dGVybnMpID0+IG0ubWF0Y2hlcihpbnB1dHMsIHBhdHRlcm5zKS5sZW5ndGggIT09IDBcblxubW9kdWxlLmV4cG9ydHMgPSBPYmplY3RBc3NpZ24obS5tYXRjaGVyLCBtKVxuIl0sIm5hbWVzIjpbImNvbnN0IiwibGV0Il0sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7O0FBU0FBLEdBQUssQ0FBQyxZQUFZLEdBQUcsT0FBTyxDQUFDLGdCQUFnQixDQUFDO0FBQzlDQSxHQUFLLENBQUMsU0FBUyxHQUFHLE9BQU8sQ0FBQyxlQUFlLENBQUM7QUFDMUNBLEdBQUssQ0FBQyxLQUFLLEdBQUcsT0FBTyxDQUFDLFVBQVUsQ0FBQztBQUNqQ0EsR0FBSyxDQUFDLEtBQUssR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFDO0FBQ2xDQSxHQUFLLENBQUMsU0FBUyxHQUFHLE9BQU8sQ0FBQyxxQkFBcUIsQ0FBQztBQUNoREEsR0FBSyxDQUFDLElBQUksR0FBRyxPQUFPLENBQUMsZUFBZSxDQUFDO0FBQ3JDQSxHQUFLLENBQUMsZUFBZSxHQUFHLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQztBQUNuREEsR0FBSyxDQUFDLGtCQUFrQixHQUFHLE9BQU8sQ0FBQyw0QkFBNEIsQ0FBQztBQUNoRUEsR0FBSyxDQUFDLGtCQUFrQixHQUFHLE9BQU8sQ0FBQyx3QkFBd0IsQ0FBQzs7QUFFNURBLEdBQUssQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixFQUFFLGtCQUFrQixDQUFDOztBQUV4REEsR0FBSyxDQUFDLENBQUMsR0FBRyxFQUFFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBaURaLENBQUMsQ0FBQyxJQUFJLEdBQUcsU0FBQSxDQUFDLE9BQU8sRUFBRSxZQUFZLEVBQUUsVUFBVSxFQUFFLEFBQUc7RUFDOUMsSUFBSSxLQUFLLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFFLEVBQUEsT0FBTyxLQUFLLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFBOztFQUVqREMsR0FBRyxDQUFDLFNBQVMsR0FBRyxPQUFPO0VBQ3ZCLElBQUksU0FBUyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSxFQUFBLFNBQVMsQ0FBQyxJQUFJLEdBQUcsU0FBUyxFQUFBO0VBQ3ZFLElBQUksU0FBUyxDQUFDLFNBQVMsQ0FBQyxFQUFFLEVBQUEsT0FBTyxTQUFTLEVBQUE7Ozs7OztFQU0xQ0EsR0FBRyxDQUFDLE9BQU8sR0FBRyxTQUFTLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRztFQUNsQyxJQUFJLE9BQU8sRUFBRSxFQUFBLFNBQVMsR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFBOztFQUUzQyxTQUFTLEdBQUcsR0FBRyxDQUFDLFNBQVMsQ0FBQzs7RUFFMUIsSUFBSSxPQUFPLElBQUksWUFBWSxFQUFFLEVBQUEsU0FBUyxHQUFHLEtBQUksR0FBRSxTQUFTLE1BQUUsQUFBQyxFQUFBO0VBQzNELElBQUksVUFBVSxFQUFFLEVBQUEsU0FBUyxHQUFHLEdBQUUsR0FBRSxTQUFTLE1BQUUsQUFBQyxFQUFBOztFQUU1QyxTQUFTLEdBQUcsU0FBUyxDQUFDLENBQUEsRUFBQyxHQUFFLFNBQVMsQ0FBRSxFQUFFLEdBQUcsQ0FBQztFQUMxQyxTQUFTLENBQUMsT0FBTyxHQUFHLE9BQU87O0VBRTNCLEtBQUssQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLFNBQVMsQ0FBQztFQUM3QixPQUFPLFNBQVM7Q0FDakI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBcURELENBQUMsQ0FBQyxPQUFPLEdBQUcsU0FBQSxDQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUUsWUFBWSxFQUFFLFVBQVUsRUFBRSxBQUFHO0VBQzFELFFBQVEsR0FBRyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUMsR0FBRyxDQUFDLFVBQUEsQ0FBQyxDQUFBLENBQUMsQUFBRyxTQUFBLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLFlBQVksRUFBRSxVQUFVLENBQUMsR0FBQSxDQUFDO0VBQ3hFLE1BQU0sR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDOztFQUV0QkQsR0FBSyxDQUFDLFlBQVksR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTztFQUN4Q0EsR0FBSyxDQUFDLGVBQWUsR0FBRyxFQUFFOztFQUUxQixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtJQUN0Q0EsR0FBSyxDQUFDLEtBQUssR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDOztJQUV2QkMsR0FBRyxDQUFDLE9BQU8sR0FBRyxZQUFZO0lBQzFCLEtBQUtBLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxRQUFRLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO01BQ3hDLElBQUksUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRTtRQUMzQixPQUFPLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTztPQUMvQjtLQUNGOztJQUVELElBQUksT0FBTyxFQUFFLEVBQUEsZUFBZSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBQTtHQUN6Qzs7RUFFRCxPQUFPLGVBQWU7Q0FDdkI7Ozs7Ozs7QUFPRCxNQUFNLENBQUMsT0FBTyxHQUFHLFlBQVksQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQzsifQ==