text: 'use strict';
  
  Object.defineProperty(exports, "__esModule", {
      value: true
  });
  
  var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
  
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  
  // Thanks to https://github.com/mattyork/fuzzy
  var TributeSearch = function () {
      function TributeSearch(tribute) {
          _classCallCheck(this, TributeSearch);
  
          this.tribute = tribute;
          this.tribute.search = this;
      }
  
      _createClass(TributeSearch, [{
          key: 'simpleFilter',
          value: function simpleFilter(pattern, array) {
              var _this = this;
  
              return array.filter(function (string) {
                  return _this.test(pattern, string);
              });
          }
      }, {
          key: 'test',
          value: function test(pattern, string) {
              return this.match(pattern, string) !== null;
          }
      }, {
          key: 'match',
          value: function match(pattern, string, opts) {
              opts = opts || {};
              var patternIdx = 0,
                  result = [],
                  len = string.length,
                  totalScore = 0,
                  currScore = 0,
                  pre = opts.pre || '',
                  post = opts.post || '',
                  compareString = opts.caseSensitive && string || string.toLowerCase(),
                  ch = void 0,
                  compareChar = void 0;
  
              pattern = opts.caseSensitive && pattern || pattern.toLowerCase();
  
              var patternCache = this.traverse(compareString, pattern, 0, 0, []);
              if (!patternCache) {
                  return null;
              }
  
              return {
                  rendered: this.render(string, patternCache.cache, pre, post),
                  score: patternCache.score
              };
          }
      }, {
          key: 'traverse',
          value: function traverse(string, pattern, stringIndex, patternIndex, patternCache) {
              // if the pattern search at end
              if (pattern.length === patternIndex) {
  
                  // calculate score and copy the cache containing the indices where it's found
                  return {
                      score: this.calculateScore(patternCache),
                      cache: patternCache.slice()
                  };
              }
  
              // if string at end or remaining pattern > remaining string
              if (string.length === stringIndex || pattern.length - patternIndex > string.length - stringIndex) {
                  return undefined;
              }
  
              var c = pattern[patternIndex];
              var index = string.indexOf(c, stringIndex);
              var best = void 0,
                  temp = void 0;
  
              while (index > -1) {
                  patternCache.push(index);
                  temp = this.traverse(string, pattern, index + 1, patternIndex + 1, patternCache);
                  patternCache.pop();
  
                  // if downstream traversal failed, return best answer so far
                  if (!temp) {
                      return best;
                  }
  
                  if (!best || best.score < temp.score) {
                      best = temp;
                  }
  
                  index = string.indexOf(c, index + 1);
              }
  
              return best;
          }
      }, {
          key: 'calculateScore',
          value: function calculateScore(patternCache) {
              var score = 0;
              var temp = 1;
  
              patternCache.forEach(function (index, i) {
                  if (i > 0) {
                      if (patternCache[i - 1] + 1 === index) {
                          temp += temp + 1;
                      } else {
                          temp = 1;
                      }
                  }
  
                  score += temp;
              });
  
              return score;
          }
      }, {
          key: 'render',
          value: function render(string, indices, pre, post) {
              var rendered = string.substring(0, indices[0]);
  
              indices.forEach(function (index, i) {
                  rendered += pre + string[index] + post + string.substring(index + 1, indices[i + 1] ? indices[i + 1] : string.length);
              });
  
              return rendered;
          }
      }, {
          key: 'filter',
          value: function filter(pattern, arr, opts) {
              var _this2 = this;
  
              opts = opts || {};
              return arr.reduce(function (prev, element, idx, arr) {
                  var str = element;
  
                  if (opts.extract) {
                      str = opts.extract(element);
  
                      if (!str) {
                          // take care of undefineds / nulls / etc.
                          str = '';
                      }
                  }
  
                  var rendered = _this2.match(pattern, str, opts);
  
                  if (rendered != null) {
                      prev[prev.length] = {
                          string: rendered.rendered,
                          score: rendered.score,
                          index: idx,
                          original: element
                      };
                  }
  
                  return prev;
              }, []).sort(function (a, b) {
                  var compare = b.score - a.score;
                  if (compare) return compare;
                  return a.index - b.index;
              });
          }
      }]);
  
      return TributeSearch;
  }();
  
  exports.default = TributeSearch;
  module.exports = exports['default'];