text: 'use strict';
  
  Object.defineProperty(exports, "__esModule", {
    value: true
  });
  
  var _toConsumableArray2;
  
  function _load_toConsumableArray() {
    return _toConsumableArray2 = _interopRequireDefault(require('babel-runtime/helpers/toConsumableArray'));
  }
  
  var _set;
  
  function _load_set() {
    return _set = _interopRequireDefault(require('babel-runtime/core-js/set'));
  }
  
  exports.sortFilter = sortFilter;
  exports.matchesFilter = matchesFilter;
  exports.ignoreLinesToRegex = ignoreLinesToRegex;
  exports.filterOverridenGitignores = filterOverridenGitignores;
  
  var _misc;
  
  function _load_misc() {
    return _misc = require('./misc.js');
  }
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  
  const mm = require('micromatch');
  const path = require('path');
  
  const WHITESPACE_RE = /^\s+$/;
  
  function sortFilter(files, filters) {
    let keepFiles = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : new (_set || _load_set()).default();
    let possibleKeepFiles = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : new (_set || _load_set()).default();
    let ignoreFiles = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : new (_set || _load_set()).default();
  
    for (const file of files) {
      let keep = false;
  
      // always keep a file if a ! pattern matches it
      for (const filter of filters) {
        if (filter.isNegation && matchesFilter(filter, file.basename, file.relative)) {
          keep = true;
          break;
        }
      }
  
      //
      if (keep) {
        keepFiles.add(file.relative);
        continue;
      }
  
      // otherwise don't keep it if a pattern matches it
      keep = true;
      for (const filter of filters) {
        if (!filter.isNegation && matchesFilter(filter, file.basename, file.relative)) {
          keep = false;
          break;
        }
      }
  
      if (keep) {
        possibleKeepFiles.add(file.relative);
      } else {
        ignoreFiles.add(file.relative);
      }
    }
  
    // exclude file
    for (const file of possibleKeepFiles) {
      const parts = path.dirname(file).split(path.sep);
  
      while (parts.length) {
        const folder = parts.join(path.sep);
        if (ignoreFiles.has(folder)) {
          ignoreFiles.add(file);
          break;
        }
        parts.pop();
      }
    }
  
    //
    for (const file of possibleKeepFiles) {
      if (!ignoreFiles.has(file)) {
        keepFiles.add(file);
      }
    }
  
    //
    for (const file of keepFiles) {
      const parts = path.dirname(file).split(path.sep);
  
      while (parts.length) {
        // deregister this folder from being ignored, any files inside
        // will still be marked as ignored
        ignoreFiles.delete(parts.join(path.sep));
        parts.pop();
      }
    }
  
    return { ignoreFiles: ignoreFiles, keepFiles: keepFiles };
  }
  
  function matchesFilter(filter, basename, loc) {
    if (filter.base && filter.base !== '.') {
      loc = path.relative(filter.base, loc);
    }
    return filter.regex.test(loc) || filter.regex.test(`/${loc}`) || filter.regex.test(basename) || mm.isMatch(loc, filter.pattern);
  }
  
  function ignoreLinesToRegex(lines) {
    let base = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '.';
  
    return lines
    // create regex
    .map(line => {
      // remove empty lines, comments, etc
      if (line === '' || line === '!' || line[0] === '#' || WHITESPACE_RE.test(line)) {
        return null;
      }
  
      let pattern = line;
      let isNegation = false;
  
      // hide the fact that it's a negation from minimatch since we'll handle this specifically
      // ourselves
      if (pattern[0] === '!') {
        isNegation = true;
        pattern = pattern.slice(1);
      }
  
      // remove trailing slash
      pattern = (0, (_misc || _load_misc()).removeSuffix)(pattern, '/');
  
      const regex = mm.makeRe(pattern.trim(), { nocase: true });
  
      if (regex) {
        return {
          base: base,
          isNegation: isNegation,
          pattern: pattern,
          regex: regex
        };
      } else {
        return null;
      }
    }).filter(Boolean);
  }
  
  function filterOverridenGitignores(files) {
    const IGNORE_FILENAMES = ['.yarnignore', '.npmignore', '.gitignore'];
    const GITIGNORE_NAME = IGNORE_FILENAMES[2];
    return files.filter(file => IGNORE_FILENAMES.indexOf(file.basename) !== -1).reduce((acc, file) => {
      if (file.basename !== GITIGNORE_NAME) {
        return [].concat((0, (_toConsumableArray2 || _load_toConsumableArray()).default)(acc), [file]);
      } else {
        //don't include .gitignore if .npmignore or .yarnignore are present
        const dir = path.dirname(file.absolute);
        const higherPriorityIgnoreFilePaths = [`${dir}/${IGNORE_FILENAMES[0]}`, `${dir}/${IGNORE_FILENAMES[1]}`];
        const hasHigherPriorityFiles = files.find(file => higherPriorityIgnoreFilePaths.indexOf(file.absolute) !== -1);
        if (!hasHigherPriorityFiles) {
          return [].concat((0, (_toConsumableArray2 || _load_toConsumableArray()).default)(acc), [file]);
        }
      }
      return acc;
    }, []);
  }